0
\$\begingroup\$

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.

asked Oct 26, 2017 at 15:13
\$\endgroup\$
2
  • \$\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\$ Commented 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\$ Commented Oct 26, 2017 at 16:13

1 Answer 1

3
\$\begingroup\$

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.

answered Oct 26, 2017 at 17:26
\$\endgroup\$
2
  • \$\begingroup\$ It's clear now. I was searching for other references and found this one from Sutherland himself, who comments on "sensitivity list" at the bottom of page 24. \$\endgroup\$ Commented Oct 28, 2017 at 17:54
  • \$\begingroup\$ Yes, the sensitivity list is a low-level coding pattern that synthesis tool recognize to implement hardware. \$\endgroup\$ Commented Oct 28, 2017 at 18:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.