A race occurs when a result depends on an execution order that the design or testbench has not specified reliably. Processes that drive and sample the same signal on the same edge are a common source. Avoid relying on source ordering, simulator luck or a particular waveform viewer's display order.

Worked example

The testbench changes d while the clock is low, waits, then creates the sampling edge. A later delay allows nonblocking updates to settle before q is checked. This deliberately separates driving, sampling and observation.

Verilog
module reg1(input clk,d,output reg q);
  always @(posedge clk) q<=d;
endmodule
module tb;
  reg clk,d;wire q;
  reg1 dut(.clk(clk),.d(d),.q(q));
  initial begin
    clk=0;d=0;#2;d=1;#2;clk=1;#1;
    $display("q=%b",q); // 1
    $finish;
  end
endmodule

What to watch for

Using nonblocking assignments in RTL does not automatically make arbitrary same-edge testbench stimulus race-free. The driver and checker still need a sampling agreement.

Try it yourself

Why is changing d in one posedge process while another samples it risky?

Answer: Both processes react to the same event. Without a defined discipline, the sampled value may depend on their relative execution order.

How to study this topic

Save the example in a .v file and identify its top module before compiling. Separate stimulus and observation from synthesizable RTL. Change one input, width or boundary condition at a time, predict the result, and compare that prediction with simulation. A syntax check does not establish synthesis support or timing closure.

Continue learning

Previous: Intra-assignment versus inter-assignment delays

Next: Simulation versus synthesis semantics

Browse the complete Verilog index

Explore related programmes

These recorded programmes are upcoming. This article is general educational content, not a syllabus or course sample.

Verilog