5.3 Verilog Parameterized Instantiation
Category Verilog Tutorial
Keywords: defparam, parameter, instantiation, ram
When a module is instantiated by another module, the higher-level module can override the parameter values of the lower-level module. This allows different parameters to be passed to multiple modules with the same name at compile time without creating new files for modules that differ only in parameters.
There are two ways to override parameters: 1) using the defparam keyword, 2) parameterized module instantiation.
defparam Statement
The defparam keyword can be used to override the parameter values of lower-level modules through hierarchical module calls.
For example, to override the MASK parameter of a ram module with both address and data lines of 4 bits:
Example
//instantiation
defparam u_ram_4x4.MASK = 7 ;
ram_4x4 u_ram_4x4
(
.CLK (clk),
.A (a[4-1:0]),
.D (d),
.EN (en),
.WR (wr), //1 for write and 0 for read
.Q (q)
);
The model for ram_4x4 is as follows:
Example
module ram_4x4
(
input CLK,
input [4-1:0] A,
input [4-1:0] D,
input EN,
input WR, //1 for write and 0 for read
output reg [4-1:0] Q
);
parameter MASK = 3 ;
reg [4-1:0] mem [0:(1<<4)-1] ;
always @(posedge CLK) begin
if (EN && WR) begin
mem[A] <= D & MASK;
end
else if (EN && !WR) begin
Q <= mem[A] & MASK;
end
end
endmodule
A simple simulation testbench is written as follows:
Example
`timescale 1ns/1ns
module test ;
parameter AW = 4 ;
parameter DW = 4 ;
reg clk ;
reg [AW:0] a ;
reg [DW-1:0] d ;
reg en ;
reg wr ;
wire [DW-1:0] q ;
//clock generating
always begin
#15 ; clk = 0 ;
#15 ; clk = 1 ;
end
initial begin
a = 10 ;
d = 2 ;
en = 'b0 ;
wr = 'b0 ;
repeat(10) begin
@(negedge clk) ;
en = 1'b1;
a = a + 1 ;
wr = 1'b1 ; //write command
d = d + 1 ;
end
a = 10 ;
repeat(10) begin
@(negedge clk) ;
a = a + 1 ;
wr = 1'b0 ; //read command
end
end // initial begin
//instantiation
defparam u_ram_4x4.MASK = 7 ;
ram_4x4 u_ram_4x4
(
.CLK (clk),
.A (a[AW-1:0]),
.D (d),
.EN (en),
.WR (wr), //1 for write and 0 for read
.Q (q)
);
//stop simulation
initial begin
forever begin
#100;
if ($time >= 1000) $finish ;
end
end
endmodule // test
Simulation results are as follows:
In the yellow section of the diagram, when the address is first c, data 4 is written, and when the address is c again, data 4 is read; it can be seen that the ram behavior is correct, and MASK is not 3. Because the bit2 of the ram's Q terminal is not masked.
When the first address is 1, the data written is 9, and the data read when the second address is 1 is 1, because the MASK is 7, and the bit3 of the ram's Q terminal signal is masked. It can be seen that the MASK parameter is correctly overridden.
Parameterized Module Instantiation
The second method is to write the new parameter values into the module instantiation statement when instantiating the module, thereby overriding the original module's parameter values.
For example, to instantiate a ram module with variable address and data widths:
Example
ram #(.AW(4), .DW(4))
u_ram
(
.CLK (clk),
.A (a[AW-1:0]),
.D (d),
.EN (en),
.WR (wr), //1 for write and 0 for read
.Q (q)
);
The model for ram is as follows:
Example
module ram
#( parameter AW = 2 ,
parameter DW = 3 )
(
input CLK,
input [AW-1:0] A,
input [DW-1:0] D,
input EN,
input WR, //1 for write and 0 for read
output reg [DW-1:0] Q
);
reg [DW-1:0] mem [0:(1<<AW)-1] ;
always @(posedge CLK) begin
if (EN && WR) begin
mem[A] <= D ;
end
else if (EN && !WR) begin
Q <= mem[A] ;
end
end
endmodule
For simulation, simply replace the instantiated module u_ram_4x4 with u_ram in the previous testbench, or add it anew.
Simulation results are as follows. It can be seen from the diagram that the parameters AW and DW of the ram module are both changed to 4, and the ram behavior is correct.
Differences and Recommendations
(1) Similar to module port instantiation, parameterized instantiation can also omit the original parameter names and instantiate parameters in order. For example, u_ram can be described as:
ram #(4, 4) u_ram (......) ;
(2) Of course, defparam can also override parameters declared in the module port, and parameterized instantiation can also override parameters declared in the module entity. For example, u_ram and u_ram_4x4 can be instantiated as:
Example
defparam u_ram.AW = 4 ;
defparam u_ram.DW = 4 ;
ram u_ram (......);
ram_4x4 #(.MASK(7)) u_ram_4x4 (......);
(3) Can these two methods of modifying module parameters be mixed? Of course! The premise is that all parameters are declared in the module port or all parameters are declared in the module entity. For example, the declaration of u_ram can also be expressed as (parameters in the module entity can be verified experimentally):
Example
defparam u_ram.AW = 4 ;
ram #(.DW(4)) u_ram (......); //Only I would experiment with this boring way of writing
(4) What if a module has both parameters declared in the module port and parameters declared in the module entity? Can these two types of parameters be overridden simultaneously? For example, adding the MASK parameter to the ram module, the model is as follows:
Example
module ram
#( parameter AW = 2 ,
parameter DW = 3 )
(
input CLK,
input [AW-1:0] A,
input [DW-1:0] D,
input EN,
input WR, //1 for write and 0 for read
output reg [DW-1:0] Q
);
parameter MASK = 3 ;
reg [DW-1:0] mem [0:(1<<AW)-1] ;
always @(posedge CLK) begin
if (EN && WR) begin
mem[A] <= D ;
end
else if (EN && !WR) begin
Q <= mem[A] ;
end
end
endmodule
When using defparam to override the MASK parameter value, the compilation reports an Error:
Example
//Error when both defparam are used
defparam u_ram.AW = 4 ;
defparam u_ram.DW = 4 ;
defparam u_ram.MASK = 7 ;
ram u_ram (......);
This is a Chinese to English translation. Here is the English translation for the text:
// Using defparam to rewrite parameters in module instances also reports an Error
defparam u_ram.MASK = 7;
ram #(.AW(4), .DW(4)) u_ram (......);
The key point is that if you use parameterized module instantiation to rewrite the value of parameter MASK, the compilation will not report an error, and MASK will be successfully rewritten!
ram #(.AW(4), .DW(4), .MASK(7)) u_ram (......);
Possible explanations include that, in the compiler's view, if a module has parameters declared at the port, then the parameters in the instance will be considered as localparam type, and using defparam will not be able to rewrite the parameters declared in the module instance.
It may also be related to the compiler, so you can also experiment with other compilers.
(5) It is recommended not to use the defparam method when instantiating existing modules and rewriting their related parameters. Apart from the above disadvantages, defparam is generally not synthesizable.
(6) It is also recommended that when writing modules, if you anticipate that they will be instantiated and have parameters that need to be rewritten, include these parameters in the module port declaration (using the hash symbol #
). This coding format not only has good readability but also facilitates debugging.
Source Code Download
Stage Summary
By now, you can use the Verilog language knowledge you've learned to build a small thatched cottage for hardware circuits. Yes, a small thatched cottage. Because of the specificity of hardware language corresponding to actual hardware circuits, when using Verilog to establish various models, you must consider what the actual generated circuit looks like and whether it meets the actual requirements. Sometimes RTL simulation can pass, but the final actual circuit may malfunction.
So, to add bricks and tiles to your small thatched cottage, you need to learn the advanced section. Of course, the advanced section can only turn your small thatched cottage into a sturdy brick-and-tile house, able to withstand wind and snow, but may still collapse in an earthquake.
If you want to reinforce your brick-and-tile house and build a villa, you need to learn more about advanced Verilog knowledge, such as PLI (Programming Language Interface), UDP (User-Defined Primitives), timing constraints and analysis, and gain more project experience, especially paying attention to some design techniques, such as low-power design, asynchronous design, etc. Learning to use SystemVerilog for comprehensive verification will also add a layer of protection to your building.
But if you want to learn all the knowledge of digital circuits and Verilog to build a presidential palace that can withstand artillery, that's really beyond my help. Because, the sea of learning is boundless, and there's no turning back.
Due to space limitations, only the advanced section is introduced here. If there is an opportunity, the advanced section, techniques section, will also be supplemented.
-1.3 Verilog Environment Setup
-2.2 Verilog Numerical Representation
-2.5 Verilog Compile Instructions
-3.1 Verilog Continuous Assignment
-4.1 Verilog Process Structure
-4.2 Verilog Process Assignment
-4.5 Verilog Conditional Statements
-4.6 Verilog Multi-branch Statements
-4.8 Verilog Process Continuous Assignment
-5.1 Verilog Modules and Ports
-5.2 Verilog Module Instantiation
- 5.3 Verilog Parameterized Instantiation
-6.4 Verilog Competition and Hazard
-6.6 Verilog Simulation Stimulus
-7.2 Verilog Parallel FIR Filter Design
-7.3 Verilog Serial FIR Filter Design
-7.4 Verilog CIC Filter Design
-8.1 Verilog Numerical Conversion
-Verilog Tutorial Advanced Section
WeChat Subscription
English: