How to Apply Stimulus in Verilog Testbench: Simple Guide
In Verilog testbenches, you apply stimulus by assigning values to input signals inside an
initial or always block. Use procedural statements like blocking/non-blocking assignments to change inputs over time and simulate different scenarios.Syntax
Stimulus in a Verilog testbench is usually applied inside an initial block where you set and change input signals over simulation time. You use procedural assignments like = (blocking) or <= (non-blocking) to drive inputs.
Example parts explained:
initial begin ... end: Runs once at simulation start.signal = value;: Assigns a value immediately (blocking).#delay;: Waits for specified time units before next statement.
verilog
initial begin
input_signal = 0; // Set initial value
#10 input_signal = 1; // Change after 10 time units
#20 input_signal = 0; // Change after 20 more time units
endExample
This example shows a simple testbench applying stimulus to a 1-bit input clk and reset signals. It toggles the clock every 5 time units and asserts reset at the start.
verilog
module testbench(); reg clk; reg reset; // Instantiate the design under test (DUT) // my_module dut(.clk(clk), .reset(reset)); initial begin clk = 0; reset = 1; // Assert reset #15 reset = 0; // Deassert reset after 15 time units end // Clock generation: toggle every 5 time units always #5 clk = ~clk; initial begin // Run simulation for 50 time units #50 $finish; end endmodule
Common Pitfalls
Common mistakes when applying stimulus include:
- Not using
initialoralwaysblocks, so stimulus never runs. - Forgetting delays (
#) causing all assignments to happen instantly. - Using
assignstatements inside procedural blocks (illegal). - Driving signals declared as
wireinstead ofregin procedural blocks.
Correct signal declaration and timing control are essential for proper stimulus application.
verilog
/* Wrong: assigning to wire inside initial block */ wire input_signal; initial begin // input_signal = 1; // Error: cannot assign to wire procedurally end /* Right: declare as reg for procedural assignment */ reg input_signal; initial begin input_signal = 1; // Correct end
Quick Reference
| Concept | Description | Example |
|---|---|---|
| initial block | Runs once at simulation start to apply stimulus | initial begin signal = 0; #10 signal = 1; end |
| always block | Used for repetitive stimulus like clocks | always #5 clk = ~clk; |
| reg type | Signals assigned in procedural blocks must be reg | reg input_signal; |
| delay (#) | Wait time before next statement executes | #10 signal = 1; |
| blocking assignment (=) | Assigns value immediately in sequence | signal = 0; |
| non-blocking assignment (<=) | Schedules assignment for end of time step | signal <= 1; |
Key Takeaways
Use initial or always blocks to apply stimulus in Verilog testbenches.
Declare signals as reg if you assign to them inside procedural blocks.
Use delays (#) to space out stimulus changes over simulation time.
Avoid assigning to wires inside procedural blocks; use reg instead.
Clock signals are commonly generated with an always block toggling every fixed time.