Verilog-Parameter
Parameter sind Verilog-Konstrukte, die es ermöglichen, ein Modul mit einer anderen Spezifikation wiederzuverwenden. Beispielsweise kann ein 4-Bit-Addierer so parametriert werden, dass er einen Wert für die Anzahl der Bits akzeptiert, und neue Parameterwerte können während der Modulinstanziierung übergeben werden. So kann ein N-Bit-Addierer zu einem 4-Bit-, 8-Bit- oder 16-Bit-Addierer werden. Sie sind wie Argumente für eine Funktion, die während eines Funktionsaufrufs übergeben werden.
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
Parameter sind im Grunde Konstanten und daher ist es illegal, ihren Wert zur Laufzeit zu ändern. Es ist illegal, einen Namen neu zu deklarieren, der bereits von einem Netz, einer Variablen oder einem anderen Parameter verwendet wird.
Es gibt zwei Haupttypen von Parametern, Modul und angeben und beide akzeptieren eine Bereichsspezifikation. Sie werden jedoch normalerweise so breit gemacht, wie es der zu speichernde Wert erfordert, und daher ist eine Bereichsangabe nicht erforderlich.
Modulparameter
Modulparameter können verwendet werden, um Parameterdefinitionen innerhalb eines Moduls zu überschreiben, wodurch das Modul zur Kompilierzeit über einen anderen Parametersatz verfügt. Mit dem defparam
kann ein Parameter geändert werden -Anweisung oder in der Modulinstanz-Anweisung. Es ist üblich, Großbuchstaben in Namen für die Parameter zu verwenden, damit sie sofort erkennbar sind.
Das unten gezeigte Modul verwendet Parameter, um die Busbreite, Datenbreite und die Tiefe des FIFO innerhalb des Designs anzugeben, und kann mit neuen Werten überschrieben werden, wenn das Modul instanziiert wird oder indem defparam
verwendet wird Aussagen.
// 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
Im neuen ANSI-Stil der Verilog-Portdeklaration können Sie Parameter wie unten gezeigt deklarieren.
module design_ip
#(parameter BUS_WIDTH=32,
parameter DATA_WIDTH=64) (
input [BUS_WIDTH-1:0] addr,
// Other port declarations
);
Überschreiben von Parametern
Parameter können während der Modulinstanziierung mit neuen Werten überschrieben werden. Der erste Teil instanziiert das Modul namens design_ip mit dem Namen d0, wo neue Parameter innerhalb von #( )
übergeben werden . Der zweite Teil verwendet ein Verilog-Konstrukt namens defparam
um die neuen Parameterwerte einzustellen. Die erste Methode ist die am häufigsten verwendete Methode, um neue Parameter in RTL-Designs zu übergeben. Die zweite Methode wird häufig in Testbench-Simulationen verwendet, um die Designparameter schnell zu aktualisieren, ohne das Modul erneut zu instanziieren.
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
Beispiel
Der Modulzähler hat zwei Parameter N und DOWN, die mit einem Standardwert von 2 bzw. 0 deklariert sind. N steuert die Anzahl der Bits in der Ausgabe, die effektiv die Breite des Zählers steuert. Standardmäßig ist es ein 2-Bit-Zähler. Der Parameter DOWN steuert, ob der Zähler inkrementieren oder dekrementieren soll. Standardmäßig wird der Zähler dekrementiert, da der Parameter auf 0 gesetzt ist.
2-Bit-Aufwärtszähler
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
Der Modulzähler wird mit N als 2 instanziiert, obwohl dies nicht erforderlich ist, da der Standardwert sowieso 2 ist. DOWN wird während der Modulinstanziierung nicht übergeben und nimmt daher den Standardwert 0 an, was ihn zu einem Aufwärtszähler macht.
module design_top ( input clk,
input rstn,
input en,
output [1:0] out);
counter #(.N(2)) u0 ( .clk(clk),
.rstn(rstn),
.en(en));
endmodule
Beachten Sie, dass Standardparameter verwendet werden, um den Zähler zu implementieren, wobei N gleich zwei ist, was ihn zu einem 2-Bit-Zähler macht, und DOWN gleich Null, was ihn zu einem Aufwärtszähler macht. Der Ausgang des Zählers bleibt auf der obersten Ebene unverbunden.
4-Bit-Abwärtszähler
In diesem Fall wird der Modulzähler mit N als 4 instanziiert, was ihn zu einem 4-Bit-Zähler macht. DOWN wird während der Modulinstanzierung der Wert 1 übergeben und somit wird ein Abwärtszähler implementiert.
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
Parameter angeben
Diese werden hauptsächlich zum Bereitstellen von Timing- und Verzögerungswerten verwendet und mit specparam
deklariert Stichwort. Es darf sowohl innerhalb des specify verwendet werden Block und dem Hauptmodulkörper.
// 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
Unterschied zwischen spezifizierten und Modulparametern
Parameter angeben | Modulparameter |
---|---|
Erklärt von specparam | Erklärt von parameter |
Kann in specify deklariert werden Block oder innerhalb des Hauptmoduls | Kann nur innerhalb des Hauptmoduls deklariert werden |
Können Specparams und Parameter zugewiesen werden | Dürfen keine Specparams zugewiesen werden |
SDF kann zum Überschreiben von Werten verwendet werden | Parameterwerte der Instanzdeklaration oder defparam kann zum Überschreiben verwendet werden |
Verilog