Parameters and Delay Control Using Verilog - Part 24
2025-09-08 | By DWARAKAN RAMANATHAN
Introduction:
Verilog is a programmable hardware description language and is generally employed to simulate digital systems. Parameters and delay specifications are two of its most beneficial features that can greatly increase the testability and scalability of a design. Here in this tutorial, we will see how parameters can be utilized to design reusable and configurable modules and how inter- and intra-delay specifications become a crucial part of simulations and test benches to simulate hardware behavior in the physical world.
Why Parameters are Useful in Verilog
Verilog parameters are constants that can be defined inside a module and can be overridden during instantiation time. They provide flexible hardware descriptions without modifying the underlying logic, thereby encouraging modularity and reusability in many areas of a digital system.
For example, in memory modules, arithmetic circuits, or buses, bit-widths can be different depending on the requirements of the system. Instead of designing individual modules for each such configuration, we can design a parameterized module and vary the parameters at instantiation time. It avoids redundancy to a large degree and facilitates ease of maintenance.
Parameters increase portability across projects. It becomes simple to reuse the same design in many different situations by modifying the parameter values.
Syntax and Use of Parameters
In Verilog, a parameter is defined with the parameter keyword inside a module. The parameters can be overridden at instantiation with positional or named assignments.
Parameterized Module Example:
module adder #(parameter WIDTH = 8) ( input [WIDTH-1:0] a, input b [WIDTH-1:0] output [WIDTH:0] sum ); let sum = a + b; endmodule
In the above example, the adder module can be instantiated for any bit-width. This makes it possible for a designer to use the same module on an 8-bit, a 16-bit, or even a 32-bit system.
Overriding Parameters during Instantiation
adder #(16) u1 ( .a(data1), .b(data2), .sum(result) );
Or, alternatively, named parameter assignment may be used for readability where multiple parameters are concerned:
adder #(.WIDTH(16)) u1 ( .a(data1), .b(data2), .sum(result );
Inter-Delay and Intra-Delay in Verilog Simulations
In digital design simulation, particularly functional and timing verification, delays need to be simulated in order to represent real hardware behavior. Delays are useful in the verification of signal propagation times, data arrival sequences, and synchronization mechanisms.Verilog, too, has two broad categories of delay specifications:
Inter-Delay (Path Delay)
Inter-delay, or path delay, or simply path, is the duration a signal takes to travel from one module port to another, from input to output. It is specified in the specify block in Verilog and is mainly used in gate-level simulations or timing-aware netlists generated post-synthesis.
Example:
(a * y) = 3;
Here, it signifies that any variation in input a will affect output y after a time lag of 3 time units. This comes in handy when modeling propagation delay in combinational circuits, buffers, or logic gates.
Use Cases:
- Gate-level netlist simulations after synthesis.
- ASIC or FPGA timing verification.
- Timing closure and static timing analysis.
Note: The specify block is not synthesizable and is intended to be used only in post-synthesis simulation environments.
Intra-Delay (Transport/Propagation Delay)
Intra-delay is the delay used within a signal assignment or an expression. It captures the response of combinational or sequential logic that inherently takes time due to transistor-level or interconnect-level behavior.
Example:
assign #5 y = a & b;
Here, the output of a & b is sent to y with a delay of 5 time units. Delay is typically employed for waveform generation or functional verification in testbenches. It enables you to see how output changes in response to changes in input over time, which is helpful in debugging data races or issues related to glitches.
Additional Example using Procedural Block:
always @(*) begin #3 out = in1 ^ in2; end
This is particularly helpful for modeling behavioral circuits in testbenches or for coding small delay models to model signal propagation.
Practical Testbench Example with Parameters and Delay
By combining the parameters and delays, scalable, simulation-capable modules can be generated.
Parameterized Adder Module with Delay
module adder #(parameter WIDTH = 4) ( input [WIDTH-1:0] a input [WIDTH-1:0] b, output reg [WIDTH:0] sum ); always @(*) begin #2 sum = a + b; // 2 units delay end endmodule
Testbench for the Adder
module tb; parameter WIDTH = 4; reg [WIDTH-1:0] a, b; wire WIDTH:0 sum; adder #(WIDTH) uut ( .a(a), .b(b), .sum(sum) ); initial begin a = 4'd3; b = 4'd5; #10; a = 4'd7; b = 4'd2; #10; end endmodule
This testbench applies different values to a and b, reads back the resulting sum, and contains a delay for simulating hardware behavior in real life. Changing the data width across the testbench and the module is quite easy using the WIDTH parameter.
Best Practices
To create clean, scalable, and simulation-friendly Verilog code, apply the following practices:
- Use default parameter values to provide backward compatibility.
- Use named parameter assignments for readability.
- Limit the use of explicit delays in synthesizable RTL since the majority of synthesis tools disregard such delays.
- Use localparam to declare internal constants that are not meant to be overridden elsewhere outside the module.
- Segregate delay-based behavior in testbenches and simulation models rather than production-quality RTL directed to synthesis.
Conclusion:
Using parameters in Verilog helps you to create reusable and scalable modules with less redundancy and more modularity. Parallelly, inter-delay and intra-delay specifications allow you to model actual-world timing and test and verify more accurately. Getting familiar with them provides you with the power to write more professional, strong, and flexible Verilog code, whether creating an academic project or a commercial FPGA design. Learning and using these methods not only makes your code more versatile but also conditions it for the types of simulation and synthesis steps that take place in actual chip design and verification flows.