Difficulty: Medium · Puzzle 1 of 6 · Topic: Race Condition Puzzles
Predict post-NBA values of x and y on each edge. Is behavior deterministic across simulators?
module tb;
bit clk = 0;
int x = 0;
int y = 0;
always #5 clk = ~clk;
always @(posedge clk) begin
x = x + 1;
y <= x;
end
always @(posedge clk) begin
x = x + 10;
end
initial begin
repeat (2) begin
@(posedge clk);
$strobe("[%0t] x=%0d y=%0d", $time, x, y);
end
#1 $finish;
end
endmoduleBoth blocks write x in active with no ordering guarantee.
1) x ends each edge as old_x + 11 regardless of order.
2) y<=x samples x in whichever intermediate active state Process A sees.
3) If A runs first on first edge, y becomes 1; if B runs first, y becomes 11.
4) Same ambiguity repeats each edge, so y is race-dependent.Answer: x is deterministic per edge (+11), but y is nondeterministic because it samples race-dependent active-state x before NBA update.
Checked by running the code in Verilator 5 and Icarus Verilog 13; the printed output supports the answer above. x is +11 per edge in any order; y here comes from one legal process order (the other order gives y=12 at t=15). Icarus runs the two writers in the other order, so x is identical but y differs at t=15: the LRM leaves the order undefined.
Using NBA on y does not sanitize the active-region race on x.
How would you refactor to a single writer while preserving intended math?
The x result is deterministic, plus eleven per edge, but y is not. Both blocking writers run in Active in an order the LRM does not define, and y takes x from whatever intermediate state its process sees, so y can be 1 or 11 on the first edge. The trap is thinking the NBA on y cleans it up, when the race is on x before the NBA. I would remove the second writer or fix the ordering, and check with a different tool or a source reorder.