I am trying to get a handle of how simulators treat delay control (via #<delay>
) and I am unable to explain the observed difference in the following two snippets:
(1)
module top ();
reg a,b;
initial begin
$monitor("At time %d a=%b b=%b", $time,a,b);
a = 1'b0;
b = 1'b0;
#10 a = 1'b1;
#10 b = 1'b1;
a <= #5 1'b0;
b <= #5 1'b0;
end
endmodule
(2)
module top ();
reg a,b;
initial begin
$monitor("At time %d a=%b b=%b", $time,a,b);
a = 1'b0;
b = 1'b0;
#10 a = 1'b1;
#10 b = 1'b1;
a = #5 1'b0;
b = #5 1'b0;
end
endmodule
Note the only difference is between the final two statements in each snippet. The output is such that in the first snippet, both a,b are set to 0 at t=25, whereas in the second we have a=0 at t=25 but b=0 only at t=30. Why is this?
Based on my (clearly limited) understanding, I had thought that a simulator should arrive at the a <= #5 1'b0;
statement and then trivially evaluate the 1'b0
RHS, wait 5 time units, and then update a
in the non-blocking assignment (NBA) region. In particular, I thought this would mean that the simulator only deals with the b <= #5 1'b0;
starting at t=25, as is the case clearly in the blocking case. Why with non-blocking assignments does the simulator proceed? I had thought the difference between blocking and non-blocking assignments was merely that NBA gets done in the NBA region of the stratified Verilog queue, whereas blocking assignment gets done in the active region of the given time slot. Is there another difference of which I am unaware?