In Verilog sind Parameter Konstanten und gehören keinem anderen Datentyp wie Register- oder Netzdatentypen an.
Ein konstanter Ausdruck bezieht sich auf eine konstante Zahl oder einen zuvor definierten Parameter. Wir können Parameterwerte nicht zur Laufzeit ändern, aber wir können einen Parameterwert mithilfe von ändern defparam Stellungnahme.
Der defparam Die Anweisung kann Parameter nur zur Kompilierungszeit ändern. Parameterwerte können mithilfe der # Verzögerungsspezifikation mit Modulinstanziierung geändert werden.
In Verilog gibt es zwei Methoden, um einen Modulparameterwert während einer Modulinstanziierung zu überschreiben.
- Durch die Verwendung des Schlüsselworts defparam.
- Und Zuweisung von Parameterwerten für Modulinstanzen.
Nach dem Schlüsselwort defparam wird der hierarchische Pfad zum Parameter und der neue Wert des Parameters angegeben. Dieser neue Wert sollte ein konstanter Ausdruck sein. Wenn der Ausdruck auf der rechten Seite auf Parameter verweist, sollte er innerhalb des Moduls deklariert werden, in dem defparam aufgerufen wird.
Die Zuweisungsmethode für Parameterwerte der Modulinstanz scheint eine Zuweisung der Verzögerung zur Gate-Instanz zu sein. Diese Methode überschreibt Parameter in instanziierten Modulen, so wie sie im Modul erscheinen. Bei Verwendung dieses Formats können Parameter nicht übersprungen werden.
Konstante Ausdrücke können zuvor deklarierte Parameter enthalten. Wenn Änderungen an den zuvor deklarierten Parametern erkannt werden, werden alle Parameter, die von diesem Wert abhängen, automatisch aktualisiert.
Bedenken Sie, dass ein 4-Bit-Addierer so parametrisiert werden kann, dass er einen Wert für die Anzahl der Bits akzeptiert, und dass neue Parameterwerte während der Modulinstanziierung übergeben werden können. Ein N-Bit-Addierer wird also in einen 4-Bit-, 8-Bit- oder 16-Bit-Addierer umgewandelt. Sie sind wie Argumente für eine Funktion, die während eines Funktionsaufrufs übergeben werden.
parameter MSB = 7; // MSB is a parameter with the constant value 7 parameter REAL = 4.5; // REAL holds the real number parameter FIFO_DEPTH = 256, MAX_WIDTH = 32; // Declares two parameters parameter [7:0] f_const = 2'b3; // 2 bit value is converted into 8 bits; 8'b3
Es gibt zwei Arten von Parametern: Modul Und angeben , und beide akzeptieren eine Bereichsangabe. Sie sind jedoch so breit wie der zu speichernde Wert, sodass eine Bereichsangabe nicht erforderlich ist.
Modulparameter
Es kann verwendet werden, um Parameterdefinitionen innerhalb eines Moduls zu überschreiben und sorgt dafür, dass das Modul zur Kompilierungszeit über einen anderen Parametersatz verfügt. Ein Parameter kann mit geändert werden defparam Stellungnahme. Es ist üblich, in Namen Großbuchstaben zu verwenden, damit der Parameter sie sofort erkennt.
Das folgende 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-Anweisungen verwendet werden.
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]; endmodule
Im neuen ANSI-Stil der Verilog-Portdeklaration können wir Parameter deklarieren wie:
module design_ip #(parameter BUS_WIDTH=32, parameter DATA_WIDTH=64) (input [BUS_WIDTH-1:0] addr, // other port declarations );
Überschreibende Parameter
Parameter können während der Modulinstanziierung mit neuen Werten überschrieben werden. Der erste Teil ist das aufgerufene Modul design_ip mit dem Namen d0, wobei neue Parameter innerhalb von #() übergeben werden.
Der zweite Teil ist die Verwendung eines Verilog-Konstrukts namens defparam um die neuen Parameterwerte festzulegen. Die erste Methode wird üblicherweise zur Übergabe neuer Parameter in RTL-Designs verwendet. Und die zweite Methode wird in Testbench-Simulationen verwendet, um die Designparameter schnell zu aktualisieren, ohne das Modul neu instanziieren zu müssen.
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
Der Modulzähler hat zwei Parameter N Und RUNTER , das mit den Standardwerten 2 und 0 deklariert ist.
N Steuert die Anzahl der Bits in der Ausgabe und steuert damit effektiv die Breite des Zählers. Es handelt sich standardmäßig um einen 2-Bit-Zähler.
Parameter RUNTER steuert, ob der Zähler erhöht oder verringert werden soll. Der Zähler wird dekrementiert, da der Parameter auf 0 gesetzt ist.
2-Bit-Aufwärtszähler
vergleiche mit Strings in Java
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) (down) out <="out" - 1; + endmodule pre> <p>The module counter is instantiated with <strong> <em>N</em> </strong> as 2 even though it is not required because the default value is anyway 2.</p> <p> <strong> <em>DOWN</em> </strong> is not passed during module instantiation. And it takes the default value of 0 making it an up-counter.</p> <pre> module design_top (input clk, input rstn, input en, output [1:0] out); counter #(.N(2)) u0 (.clk(clk), .rstn(rstn), .en(en)); endmodule </pre> <p>The default parameters are used to implement the counter where <strong> <em>N</em> </strong> equals two, making it a 2-bit counter, and <strong> <em>DOWN</em> </strong> equals zero, making it an up-counter. The output from the counter is left unconnected at the top level.</p> <img src="//techcodeview.com/img/verilog-tutorial/47/verilog-parameters.webp" alt="Verilog Parameters"> <p> <strong>4-bit down Counter</strong> </p> <p>In this case, the module counter is instantiated with N as 4 making it a 4-bit counter. DOWN is passed a value of 1 during the module instantiation and hence a down-counter is implemented.</p> <pre> 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 </pre> <br> <img src="//techcodeview.com/img/verilog-tutorial/47/verilog-parameters-2.webp" alt="Verilog Parameters"> <h3>Specify Parameters</h3> <p>These parameters are used to provide time and delay values and declared using the <strong> <em>specparam</em> </strong> keyword. It is allowed to use both within the specified block and the main module body.</p> <pre> // 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 </pre> <h3>Difference between Specify and Module Parameters</h3> <table class="table"> <tr> <th>Specify parameter</th> <th>Module parameter</th> </tr> <tr> <td>Specify the specparam keyword declares parameter.</td> <td>The module parameter is declared by parameter.</td> </tr> <tr> <td>It can be declared inside a specific block or within the main module.</td> <td>It can only be declared within the main module.</td> </tr> <tr> <td>This parameter may be assigned specparams and parameters.</td> <td>This may not be assigned specparams.</td> </tr> <tr> <td>SDF can be used to override values.</td> <td>Instance declaration parameter values or defparam can be used to override.</td> </tr> </table> <p> <strong>Notes</strong> </p> <p>Here are some important notes for the Verilog parameters, such as:</p> <ul> <li>If we are using the <strong> <em>defparam</em> </strong> statement, we must specify a hierarchical path to the parameter.</li> <li>We cannot skip over a parameter in a <strong> <em>module instance parameter value assignment</em> </strong> . If we need to do this, use the initial value for a not overwritten parameter.</li> <li>When one parameter depends on the other, then the second will automatically be updated if we change the first one.</li> </ul> <hr></=>
Die Standardparameter werden verwendet, um den Zähler wo zu implementieren N gleich zwei, was es zu einem 2-Bit-Zähler macht, und RUNTER gleich Null, was es 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 erhält während der Modulinstanziierung den Wert 1 und daher 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
Geben Sie Parameter an
Diese Parameter werden zur Bereitstellung von Zeit- und Verzögerungswerten verwendet und mit deklariert specparam Stichwort. Die Verwendung ist sowohl innerhalb des angegebenen Blocks als auch im Hauptmodulkörper zulässig.
// 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 Specify- und Modulparametern
Parameter angeben | Modulparameter |
---|---|
Geben Sie den Deklarationsparameter des Schlüsselworts specparam an. | Der Modulparameter wird per Parameter deklariert. |
Es kann innerhalb eines bestimmten Blocks oder innerhalb des Hauptmoduls deklariert werden. | Es kann nur innerhalb des Hauptmoduls deklariert werden. |
Diesem Parameter können Specparams und Parameter zugewiesen werden. | Diesem dürfen keine Specparams zugewiesen werden. |
SDF kann zum Überschreiben von Werten verwendet werden. | Parameterwerte der Instanzdeklaration oder Defparam können zum Überschreiben verwendet werden. |
Anmerkungen
Hier sind einige wichtige Hinweise zu den Verilog-Parametern, wie zum Beispiel:
- Wenn wir das verwenden defparam Anweisung müssen wir einen hierarchischen Pfad zum Parameter angeben.
- Wir können einen Parameter in a nicht überspringen Zuweisung von Parameterwerten für Modulinstanzen . Wenn dies erforderlich ist, verwenden Sie den Anfangswert für einen nicht überschriebenen Parameter.
- Wenn ein Parameter vom anderen abhängt, wird der zweite automatisch aktualisiert, wenn wir den ersten ändern.
=>