🧩 What Are Parameterized Modules?
A parameterized module in Verilog is a module that uses parameters to make certain values (like bus width, delay, or size) configurable when you instantiate it.
This helps you reuse the same module for different configurations without rewriting code.
🧠Why Use Parameters?
✅ To make designs scalable (e.g., same adder for 4-bit, 8-bit, or 16-bit).
✅ To improve code reusability.
✅ To make designs easier to maintain and modify.
✅ To avoid hardcoding constants.
⚙️ Syntax of a Parameterized Module
module module_name #(parameter PARAM_NAME = value) (port_list);
// Module body
endmodule
Example:
module adder #(parameter N = 4) (
input [N-1:0] A, B,
output [N-1:0] SUM
);
assign SUM = A + B;
endmodule
Here:
N is a parameter that defines the bit-width.
Default value is 4.
You can change N when you instantiate the module.
🧾 Instantiating a Parameterized Module
Default instantiation (uses N=4)
adder a1 (.A(A), .B(B), .SUM(SUM));
Custom parameter value (override N)
adder #(8) a2 (.A(A), .B(B), .SUM(SUM)); // 8-bit adder
or named parameter style:
adder #(.N(16)) a3 (.A(A), .B(B), .SUM(SUM)); // 16-bit adder
🧰 Multiple Parameters Example
module counter #(parameter WIDTH = 8, parameter MAX = 255) (
input clk,
input reset,
output reg [WIDTH-1:0] count
);
always @(posedge clk or posedge reset) begin
if (reset)
count <= 0;
else if (count == MAX)
count <= 0;
else
count <= count + 1;
end
endmodule
Instantiation examples
counter #(4, 9) c1 (clk, reset, count4); // 4-bit counter up to 9
counter #(.WIDTH(10), .MAX(1023)) c2 (clk, reset, count10); // 10-bit counter
🧮 Example: Parameterized Multiplexer
module mux #(parameter WIDTH = 8) (
input [WIDTH-1:0] in0, in1,
input sel,
output [WIDTH-1:0] out
);
assign out = sel ? in1 : in0;
endmodule
Instantiation:
mux #(16) m1 (.in0(a16), .in1(b16), .sel(sel), .out(y16)); // 16-bit MUX
⚖️ Key Points to Remember
Concept Description
Parameter Constant value that can be changed during instantiation
Default value Used if no override is provided
Override styles Positional (#(value)) or named (#(.NAME(value)))
Compile-time constant Parameters are evaluated at compile time, not runtime
Reusability Makes modules more flexible and portable
🧠Bonus: Local Parameters
You can also define local parameters inside a module using localparam.
These cannot be overridden from outside — they are fixed constants used internally.
localparam HALF = WIDTH / 2;
🚀 Summary
Feature Parameter Localparam
Can be changed at instantiation ✅ Yes ❌ No
Used for internal constants ⚠️ Sometimes ✅ Commonly
Declared using parameter localparam
✅ Example Summary
module shift_reg #(parameter WIDTH = 8, parameter DEPTH = 4) (
input clk, reset, shift_en,
input [WIDTH-1:0] data_in,
output reg [WIDTH-1:0] data_out
);
reg [WIDTH-1:0] shift_reg [0:DEPTH-1];
integer i;
always @(posedge clk or posedge reset) begin
if (reset)
for (i=0; i<DEPTH; i=i+1)
shift_reg[i] <= 0;
else if (shift_en) begin
shift_reg[0] <= data_in;
for (i=1; i<DEPTH; i=i+1)
shift_reg[i] <= shift_reg[i-1];
end
data_out <= shift_reg[DEPTH-1];
end
endmodule
This same module can become a 4-bit × 4-stage or 16-bit × 8-stage shift register by changing parameters.
Learn VLSI Training in Hyderabad
Read More
Writing a 4-bit Adder in Verilog
First Verilog Code: Hello World
Visit Our Training Institute in Hyderabad
Subscribe by Email
Follow Updates Articles from This Blog via Email
No Comments