Verilog-parameters
Parameters zijn Verilog-constructies waarmee een module opnieuw kan worden gebruikt met een andere specificatie. Een 4-bits opteller kan bijvoorbeeld worden geparametriseerd om een waarde voor het aantal bits te accepteren en nieuwe parameterwaarden kunnen worden doorgegeven tijdens het aanmaken van de module. Een N-bit opteller kan dus een 4-bit, 8-bit of 16-bit opteller worden. Ze zijn als argumenten voor een functie die worden doorgegeven tijdens een functieaanroep.
parameter MSB = 7; // MSB is a parameter with a constant value 7
parameter REAL = 4.5; // REAL holds a real number
parameter FIFO_DEPTH = 256,
MAX_WIDTH = 32; // Declares two parameters
parameter [7:0] f_const = 2'b3; // 2 bit value is converted to 8 bits; 8'b3
Parameters zijn in feite constanten en daarom is het illegaal om hun waarde tijdens runtime te wijzigen. Het is illegaal om een naam opnieuw te declareren die al wordt gebruikt door een net, variabele of een andere parameter.
Er zijn twee belangrijke soorten parameters, module en specificeer en beide accepteren een bereikspecificatie. Maar ze worden normaal gesproken zo breed gemaakt als de op te slaan waarde vereist en daarom is een bereikspecificatie niet nodig.
Moduleparameters
Moduleparameters kunnen worden gebruikt om parameterdefinities binnen een module te overschrijven en dit zorgt ervoor dat de module een andere set parameters heeft tijdens het compileren. Een parameter kan worden gewijzigd met de defparam
statement of in de module instance statement. Het is gebruikelijk om hoofdletters in namen voor de parameter te gebruiken, zodat ze direct opvallen.
De hieronder getoonde module gebruikt parameters om de busbreedte, gegevensbreedte en de diepte van FIFO binnen het ontwerp te specificeren, en kan worden overschreven met nieuwe waarden wanneer de module wordt geïnstantieerd of door defparam
te gebruiken verklaringen.
// Verilog 1995 style port declaration
module design_ip ( addr,
wdata,
write,
sel,
rdata);
parameter BUS_WIDTH = 32,
DATA_WIDTH = 64,
FIFO_DEPTH = 512;
input addr;
input wdata;
input write;
input sel;
output rdata;
wire [BUS_WIDTH-1:0] addr;
wire [DATA_WIDTH-1:0] wdata;
reg [DATA_WIDTH-1:0] rdata;
reg [7:0] fifo [FIFO_DEPTH];
// Design code goes here ...
endmodule
In de nieuwe ANSI-stijl van Verilog-poortdeclaratie kunt u parameters declareren zoals hieronder weergegeven.
module design_ip
#(parameter BUS_WIDTH=32,
parameter DATA_WIDTH=64) (
input [BUS_WIDTH-1:0] addr,
// Other port declarations
);
Parameters overschrijven
Parameters kunnen worden overschreven met nieuwe waarden tijdens het maken van modules. Het eerste deel instantieert de module genaamd design_ip met de naam d0 waar nieuwe parameters worden doorgegeven binnen #( )
. Het tweede deel gebruikt een Verilog-constructie genaamd defparam
om de nieuwe parameterwaarden in te stellen. De eerste methode is de meest gebruikte manier om nieuwe parameters door te geven in RTL-ontwerpen. De tweede methode wordt vaak gebruikt in testbench-simulaties om de ontwerpparameters snel bij te werken zonder de module opnieuw te hoeven installeren.
module tb;
// Module instantiation override
design_ip #(BUS_WIDTH = 64, DATA_WIDTH = 128) d0 ( [port list]);
// Use of defparam to override
defparam d0.FIFO_DEPTH = 128;
endmodule
Voorbeeld
De moduleteller heeft twee parameters N en DOWN die respectievelijk een standaardwaarde van 2 en 0 hebben. N bestuurt het aantal bits in de uitvoer en bestuurt effectief de breedte van de teller. Standaard is het een 2-bit teller. Parameter DOWN bepaalt of de teller moet verhogen of verlagen. Standaard wordt de teller verlaagd omdat de parameter is ingesteld op 0.
2-bit up-counter
module counter
#( parameter N = 2,
parameter DOWN = 0)
( input clk,
input rstn,
input en,
output reg [N-1:0] out);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end else begin
if (en)
if (DOWN)
out <= out - 1;
else
out <= out + 1;
else
out <= out;
end
end
endmodule
De moduleteller wordt geïnstantieerd met N als 2, hoewel dit niet vereist is omdat de standaardwaarde sowieso 2 is. DOWN wordt niet doorgegeven tijdens het starten van de module en neemt daarom de standaardwaarde 0 aan, waardoor het een up-counter wordt.
module design_top ( input clk,
input rstn,
input en,
output [1:0] out);
counter #(.N(2)) u0 ( .clk(clk),
.rstn(rstn),
.en(en));
endmodule
Zie dat standaardparameters worden gebruikt om de teller te implementeren waarbij N gelijk is aan twee, waardoor het een 2-bits teller wordt en DOWN gelijk is aan nul, waardoor het een up-counter wordt. De uitgang van de teller is op het hoogste niveau niet aangesloten.
4-bits down-counter
In dit geval wordt de moduleteller geïnstantieerd met N als 4 waardoor het een 4-bits teller wordt. DOWN krijgt een waarde van 1 tijdens het aanmaken van de module en daarom wordt een down-counter geïmplementeerd.
module design_top ( input clk,
input rstn,
input en,
output [3:0] out);
counter #(.N(4), .DOWN(1))
u1 ( .clk(clk),
.rstn(rstn),
.en(en));
endmodule
Specificeer parameters
Deze worden voornamelijk gebruikt voor het leveren van timing- en vertragingswaarden en worden gedeclareerd met de specparam
trefwoord. Het is toegestaan om beide te gebruiken binnen de specificeer blok en de hoofdmodule.
// Use of specify block
specify
specparam t_rise = 200, t_fall = 150;
specparam clk_to_q = 70, d_to_q = 100;
endspecify
// Within main module
module my_block ( ... );
specparam dhold = 2.0;
specparam ddly = 1.5;
parameter WIDTH = 32;
endmodule
Verschil tussen specificeren en moduleparameters
Specificeer parameter | Moduleparameter |
---|---|
Verklaard door specparam | Verklaard door parameter |
Kan worden gedeclareerd binnen specify blok of binnen hoofdmodule | Kan alleen gedeclareerd worden binnen de hoofdmodule |
Kan specparams en parameters worden toegewezen | Mogelijk geen specparams toegewezen |
SDF kan worden gebruikt om waarden te overschrijven | Instance declaratie parameterwaarden of defparam kan worden gebruikt om te overschrijven |
Verilog