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.

\$\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\$
    – pjc50
    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.

\$\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\$
    – simonstar
    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\$
    – dave_59
    Commented Oct 28, 2017 at 18:46

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.