Verilog parameter usage
how do we use parameter keyword in verilog?
In Verilog, the parameter keyword is used to define constants that can be customized when
the module is instantiated. It allows for parameterized modules, making your design
flexible and reusable.
🔹 Syntax
verilog
module module_name #(parameter PARAM_NAME = default_value) (
input wire a,
output wire b
);
// Use PARAM_NAME in the module
endmodule
✅ Example: Parameterized Adder
verilog
module adder #(parameter WIDTH = 4)(
input [WIDTH-1:0] A,
input [WIDTH-1:0] B,
output [WIDTH-1:0] SUM
);
assign SUM = A + B;
endmodule
🧪 Instantiate with Custom Width
verilog
1/8
adder #(8) my_adder (
.A(a_input),
.B(b_input),
.SUM(sum_output)
);
This instantiates an 8-bit adder using the same module.
🔍 Where is parameter used?
Use Case Why Use parameter ?
Bus width, data size To make modules scalable
Delay values, loop bounds To avoid hardcoding values
Number of states, counters Useful in FSMs and counters
Easily reused & tested code Change behavior without editing source
🔐 Immutable During Simulation
Once simulation starts, parameter values cannot be changed. For run-time changes, you
would use reg or input .
Let me know if you’d like an example with testbench too!
why do we # while writing parameter?
Great question!
We use # when writing parameterized module instantiation in Verilog to override the
default parameter values of a module. This syntax allows customizing a module at the
2/8
time of instantiation.
🔹 Why #?
The #(...) syntax is used to pass parameter values to a module when you're instantiating
it — similar to how function arguments work in other programming languages, but specific
to compile-time constants.
🔹 Without # : Use Default Parameter
verilog
module counter #(parameter WIDTH = 4) (
input clk,
output reg [WIDTH-1:0] count
);
// ...logic
endmodule
// Instantiation using default WIDTH = 4
counter c1 (
.clk(clk),
.count(count)
);
🔹 With # : Override the Parameter
verilog
// Instantiate with WIDTH = 8
counter #(8) c2 (
.clk(clk),
.count(count)
);
3/8
This tells the compiler:
"Instantiate counter with WIDTH set to 8", instead of using the default 4.
🔹 Named Parameter Override (Verilog-2001 and later)
You can also name the parameters during instantiation:
verilog
counter #(.WIDTH(8)) c3 (
.clk(clk),
.count(count)
);
✅ This is clearer and avoids errors if multiple parameters exist.
📌 Summary
Syntax Purpose
#(...) Override default parameter values
#(8) Positional override
#(.WIDTH(8)) Named override (clear and safe)
Let me know if you want a full working code with parameter and instantiation examples!
what is localparam?
🔹 What is localparam in Verilog?
4/8
localparam is similar to parameter , but with one key difference:
🔒 localparam cannot be overridden during module instantiation.
✅ Syntax
verilog
module my_module #(parameter SIZE = 8) ();
localparam HALF = SIZE / 2;
// ... use HALF internally
endmodule
parameter → Can be overridden when instantiating the module
localparam → Strictly local to the module, cannot be changed from outside
🔄 parameter vs localparam
Feature parameter localparam
Overridable? ✅ Yes ❌ No
Scope Inside & outside Only inside module
Use Case Configurable values Internal constants
🔧 Example: Using Both
verilog
module fifo #(parameter DEPTH = 16) ();
// internal derived constant
localparam ADDR_WIDTH = $clog2(DEPTH);
5/8
// logic uses ADDR_WIDTH but it cannot be changed from outside
endmodule
Here:
DEPTH can be changed during instantiation ( fifo #(32) )
ADDR_WIDTH is automatically calculated and locked with localparam
🔒 Why Use localparam ?
To protect internal constants from being accidentally modified
For derived values from other parameters
Makes the module more robust and self-contained
Let me know if you’d like a code example using localparam and parameter together in a
working design!
do we use # while writing localparam?
❌ No, we do not use # with localparam — because localparam is not intended to be
overridden.
🔹 Explanation:
The #(...) syntax is used only when instantiating a module to override its parameter
values:
verilog
// Valid for parameters
my_module #(.SIZE(8)) u1 ();
6/8
But for localparam , this makes no sense because it is:
Internal to the module
Constant and read-only
Cannot be modified from outside
🔧 Example: Correct Usage of localparam
verilog
module my_module #(parameter WIDTH = 8) ();
localparam HALF_WIDTH = WIDTH / 2; // internal use only
// ... logic using HALF_WIDTH
endmodule
🟢 You can override WIDTH using # during instantiation:
verilog
my_module #(.WIDTH(16)) u1 ();
❌ But you cannot and should not try to override HALF_WIDTH .
🔑 Summary:
Keyword Overridable? Use #(...) ? Purpose
parameter ✅ Yes ✅ Yes External customization
localparam ❌ No ❌ No Internal constant (locked)
7/8
Let me know if you'd like a full example module using both for better clarity!
8/8