Interview Question · Debug
Two Simulators, Two Answers
The Question
The interviewer asks
The same RTL gives b=0 on Icarus and b=1 on Verilator. The code is in the depth panel. Which simulator has the bug?
$ iverilog -g2012 counter_pair.sv && vvp a.out
after one edge: a=1 b=0
$ verilator --binary counter_pair.sv && obj_dir/Vcounter_pair
after one edge: a=1 b=1You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Neither simulator has a bug. The design has a race. Both blocks wake at the same edge, and the standard lets a simulator run them in any order. Because a is written with =, the reader sees the old or the new value depending on that order. Write a with <=, so every reader at that edge sees the old value in any tool.
always @(posedge clk) a = a + 1; // block 1 writes a
always @(posedge clk) b = a; // block 2 reads aa; block 2 reads it.- Both wake
The clock edge wakes block 1 and block 2 in the same time step.
- Order is free
The standard lets the simulator run them in any order. With
=,achanges at once, so block 2 sees the old or the new value. - The fix
With
<=, the write toawaits for the NBA region. Every reader in the Active region sees the olda.
Read the diagram as text
- posedge clk: wakes both blocks
- Block 1: a = a + 1
- Block 2: b = a
- Active region: runs the blocks in any order
- NBA region: with <=, a changes here
- posedge clk → Block 1: wake
- posedge clk → Block 2: wake
- Block 1 → Active region
- Block 2 → Active region
- Active region → NBA region: then
Icarus and Verilator may pick different orders. Neither is wrong; the code is.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer calls it a race straight away. It points at the blocking write to a and fixes it with <=.
What Interviewers Listen For (Senior)
A good senior answer treats any disagreement between two simulators as a warning. It runs lint to find blocking writes in clocked blocks. It also compares two simulators in regression to catch code that depends on order.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfCompareScale It
- Two Simulators, Two Answers
-
WhyWhy Nonblocking Removes the RaceL1 JuniorL2 Mid-Level
Why does changing
a = a + 1toa <= a + 1remove the race, even though the block order is still open?2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
With
<=, the write toawaits for the NBA region. Every block that wakes at the edge runs before that, in the Active region. So the reader always sees the olda, whichever block runs first. The order still varies, but it no longer changes the result.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Nonblocking fixes every race."
It fixes races between a write and reads at the same edge. Two blocks that both write one variable still race. The last update wins.
Source IEEE 1800-2017 §4.7
-
Scale ItAuditing a Large Code Base for RacesL3 Senior
You inherit 200 RTL files written over ten years. How do you find and stop races?
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Start with lint: report blocking writes in clocked blocks and variables written by more than one process. Convert clocked blocks to
always_ff, so the compiler rejects a second writer. Run regressions on two simulators and treat any difference as a bug. Then make the lint rules a commit gate, so new code stays clean.Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer orders the work by cost. Automatic lint comes first, then conversion to
always_ff, then a two-simulator regression. It ends with a commit gate so the cleanup lasts.Wrong Altitude
"Review every file by hand."
Manual review of 200 files is slow and misses cases. A lint rule finds every blocking write in a clocked block in minutes.
-
CompareLint vs a Second Simulator for Finding RacesL2 Mid-Level
Compare lint and running a second simulator as ways to find races like this one.
2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
Lint reads the code and flags the pattern, such as a blocking write in a clocked block. It works even if no test shows a wrong value. A second simulator finds only races that change a result in the tests you run. Lint is cheaper and more complete for coding races. Two simulators also catch other order-dependent behaviour.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"If both simulators agree, the code has no race."
Two tools can pick the same order by chance. Agreement is not proof; only the coding rule removes the race.
Source IEEE 1800-2017 §4.7
-
What IfA Testbench That Drives at the Clock EdgeL1 JuniorL2 Mid-Level
Asked if they mention the testbench
What if the race is between the testbench and the design? The bench writes
din = 1atposedge clk, and a flop samplesdinthere.2:30You have two and a half minutes. Speak or type, then press Get Feedback under your answer. No credits needed.
Speech-to-text runs in your browser. Chrome and Edge may send audio to their own speech service.
You can edit your answer before you send it. Feedback uses AI and checks your answer only against our written answer. No credits are used and your answer is not saved.
Reveal the Model Answer
It is the same race. The bench write and the flop read both run in the Active region. So the flop may capture the old or the new
din. Drive inputs away from the sampling edge, for example on the falling edge or through a clocking block. Then the design always samples a settled value.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Use
<=in the testbench and the problem is gone."It does remove this race. But the inputs still change exactly at the edge, and later reads in the bench can race. A clocking block fixes the boundary.
Source Spear & Tumbush, SystemVerilog for Verification (3rd ed.) ch. 4.3 Stimulus Timing (clocking block default skews)
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"Blocks run in the order they appear in the file."
The standard leaves the order open. In the twin the reader is listed first, yet Icarus runs the writer first and b gets the new a.
Run It
The pair with the reader listed first, then the fix with <=.
after one edge: a=1 b=1 FAIL: blocks do not run in source order; the writer ran first and b got the new aSee the Fix
module tb;
logic clk = 0;
int a = 0, b = 0;
always @(posedge clk) b <= a; // reads a (listed first this time)
always @(posedge clk) a <= a + 1; // writes a
initial begin
#5 clk = 1; #1;
$display("after one edge: a=%0d b=%0d", a, b);
if (b == 0) $display("PASS: with <= every reader sees the old a, in any block order");
$finish;
end
endmodule
Prints: after one edge: a=1 b=0 PASS: with <= every reader sees the old a, in any block order
Tool as Truth
"Verilator is the more accurate simulator, so b=1 is right."
Both results are legal. The value depends on scheduling order, which the standard does not fix. The code is wrong, not either tool.
Source IEEE 1800-2017 §4.7
Delivery
Starts by filing a bug against one of the simulators.
A two-tool disagreement on zero-delay code is most often a race. Check the code for a blocking write that another block reads first.