Difficulty: Medium · Puzzle 2 of 6 · Topic: Race Condition Puzzles
For each edge, determine the active print and the final post-NBA value of s.
module tb;
bit clk = 0;
int s = 9;
always #5 clk = ~clk;
always @(posedge clk) begin
s = 1;
$display("[%0t A ACTIVE] s=%0d", $time, s);
end
always @(posedge clk) begin
s <= 0;
$display("[%0t B ACTIVE] scheduled s<=0", $time);
end
initial begin
repeat (2) begin
@(posedge clk);
$strobe("[%0t POST] s=%0d", $time, s);
end
#1 $finish;
end
endmoduleBlocking updates active state; NBA commits at end of slot.
1) The two always blocks run in the Active region in undefined order, so the A and B lines can appear in either order (Icarus printed B first at t=5 and A first at t=15).
2) A's print happens right after its own blocking write s = 1, and B's s <= 0 is only scheduled (NBA), so it cannot have changed s yet: A prints s=1 on every edge in every order.
3) B always schedules s<=0 for the NBA region, which commits after all Active work.
4) The $strobe (Postponed) therefore prints s=0 at t=5 and t=15. The #1 before $finish keeps the last strobe out of the slot where $finish runs.
5) Verified: Icarus and Verilator print A s=1 at both edges and POST s=0 at both edges; only the A/B line order differs.Answer: A's active print is always s=1 at both t=5 and t=15 (its own blocking write; B's s<=0 is still pending); the order of the A and B lines is undefined. The final post-NBA value is deterministically s=0 at t=5 and t=15.
Checked by running the code in Verilator 5 and Icarus Verilog 13; the printed output supports the answer above. A always prints s=1 and the end-of-slot value is always 0; only the order of the A and B lines is undefined. Icarus prints B before A at t=5: same values, different (legal) order of the two Active-region blocks.
Confusing unstable active snapshots with final end-of-slot state causes wrong conclusions.
If B used blocking s = 0 instead, would final value stay deterministic? Model answer: no. Two Active-region blocking writes race, so the last writer wins and the final s is 1 or 0 depending on process order (A still prints its own s=1 right after its write).
A's active print is always s equal to 1, because its own blocking write has happened and B's NBA is still pending. The order of the A and B lines is not defined by the LRM, so I would say so out loud. At the end of the slot s is 0 because the NBA commits after all Active work, which is what the strobe shows. The trap is mixing the unstable active snapshot with the final end-of-slot value; I would check that both are never mixed in the checker.