I am trying to write a testbench for systemverilog module and I realized a strange behaviour depending on order of the always begin and initial begin block. Here is my code block which works correctly.
top test(clk, reset, writedata, dataadr, pc, instr, readdata, memwrite);
always begin
reset = 0;
clk = 0;
#10;
reset = 0;
clk = 1;
#10;
end
initial begin
clk = 0;
reset = 1; #10;
end
If the always begin block written before the initial begin block the code works perfectly fine and outputs this
But if we change the order of the always begin and initial begin blocks
top test(clk, reset, writedata, dataadr, pc, instr, readdata, memwrite);
initial begin
clk = 0;
reset = 1; #10;
end
always begin
reset = 0;
clk = 0;
#10;
reset = 0;
clk = 1;
#10;
end
In which the values are set to undetermined. Don't these two blocks work independently? Why does their order of writing cause a problem here?
You have a simulation race condition. The always
block and the initial
block assign the reset
signal to different values at the same simulation time (0ns).
Your first code sets reset
to 1 at time 0, then to 0 at time 10ns. Your design presumably has an active-high reset, and it properly reset the internal design signals to known value at time 0.
The waveforms for your 2nd code appear to keep the reset
signal at 0 for the whole simulation; I assume the signal below the clock is reset
. In this case, the internal design signals are not properly reset, and they retain their initial unknown values.
In the 2nd block, the simulator sets reset=1 in the initial
block at time 0, then the value of reset
is overwritten by the always
block at time 0, setting reset=0.
In any case, I recommend you simplify the code like this to avoid the race condition:
always #10 clk = ~clk;
initial begin
clk = 0;
reset = 1;
#10;
reset = 0;
end
Due to nondeterminism, even your 1st code could produce the bad result. There is no guarantee that the simulator will execute the always
block before the initial
block.