I'm basically aware that the Verilog scheduler is inherently indeterminate, but I really don't understand why that's the case with the following code (I've simulated both cases with Icarus and Incisive on EDA Playground). The differences between the TB_A
and TB_B
is in the order of the initial
and always
blocks.
Case A:
module TB_A ();
reg nrst;
reg signal;
initial
nrst = 1'b0;
always @(negedge nrst)
signal = 1'b1;
initial
#10 $display("value is: %b",signal);
endmodule
Case B:
module TB_B ();
reg nrst;
reg signal;
always @(negedge nrst)
signal = 1'b1;
initial
nrst = 1'b0;
initial
#10 $display("value is: %b",signal);
endmodule
I would expect that at T=0 the transition on nrst
occurs and inevitably triggers the always
block, putting signal
at 1. This happens in Case B but not in Case A, where is displayed the value x for signal
. In other words I wouldn't expect indeterminacy in this case, but evidently I'm missing something. Switching to SystemVerilog doesn't change anything.
-
\$\begingroup\$ I'm a little surprised that it's interpreting an X -> 0 transition as "negedge". I wouldn't say it's indeterminate either if it's taking actions on blocks based on their order in the program. The real lesson is to avoid at all costs depending on this kind of behaviour. \$\endgroup\$pjc50– pjc502017年10月26日 15:28:33 +00:00Commented Oct 26, 2017 at 15:28
-
\$\begingroup\$ The outcome for both should be the same as the outcome for case A. No idea why case B is giving you the output it is. The reason why in A you get signal being 'x' is because it doesn't know whether to clock signal or not - an 'x' to 0 transition might be a negedge (1 to 0), or it might not be (0 to 0), so signal will become unknown 'x' even if it wasn't previously. \$\endgroup\$Tom Carpenter– Tom Carpenter2017年10月26日 16:13:51 +00:00Commented Oct 26, 2017 at 16:13
1 Answer 1
People misunderstand the simulation behavior of always
blocks. It does not execute at every negedge. It is a process just like an initial
block that executes procedural statements. It the same as if you wrote
initial begin
nrst = 1'b0;
end
initial begin
@(negedge nrst) // this means suspend the process and wait for a negedge
signal = 1'b1;
@(negedge nrst)
signal = 1'b1;
... // repeats infinitely for an always block
end
This is a race condition because the order that initial
blocks start their processes determine if the assignment to nrst
in one process is seen by the other process that suspends waiting for a negedge transition. A NBA assignment to nrst
as well as moving the assignment after time 0 would solve this race.
-
-
\$\begingroup\$ Yes, the sensitivity list is a low-level coding pattern that synthesis tool recognize to implement hardware. \$\endgroup\$dave_59– dave_592017年10月28日 18:46:05 +00:00Commented Oct 28, 2017 at 18:46