Interview Question · Debug
RTL Passes, Gate-Level Simulation Fails
- Likely at Arm
The Question
The interviewer asks
All 412 RTL tests pass. Zero-delay gate-level simulation fails three. Here is the summary. Where do you look first?
RTL regression (zero delay): 412 tests, 412 pass
Gate-level, zero delay: 412 tests, 3 fail
tst_scale_mode @ 1240 ns: y = 4'd6, expected 4'd3 ... (gates) RTL showed 4'd3
tst_boot @ 80 ns: cnt = 4'bxxxx ... (gates) RTL showed 4'd0
tst_err_inject @ 2210 ns: grant = 2'bxx ... (gates) RTL showed 2'd0You 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
Zero delay rules out timing, so these are mismatches between RTL and netlist. A wrong value where RTL was right points to a sensitivity problem, such as always @* with a function. An X in gates where RTL showed 0 points to a missing reset. Either an inline initializer acted as the reset, or X optimism hid an unreset flop. Fix the RTL, not the netlist.
always @(a or b).- Simulation
Both simulators obey the list, so
yis stale wheneverselchanges alone. - Lint
Lint reads the block and prints nothing at all about the list.
- Synthesis
The synthesizer warns
non-edge sensitivity on a signal will be synthesized as @* sensitivityand builds the full mux. It gives that warning for a complete list too.
Read the diagram as text
- always @(a or b): reads a, b and sel
- Simulators: Icarus 12, Verilator 5.052
- Lint: Verilator -Wall
- Synthesizer: Yosys 0.70, slang
- Stale y: edges 3, 4 and 6
- 8 MUX + 8 flops: the full choice
- always @(a or b) → Simulators: obey the list
- always @(a or b) → Lint: no message
- always @(a or b) → Synthesizer: treats it as @*
- Simulators → Stale y: run
- Synthesizer → 8 MUX + 8 flops: netlist
Measured in lesson R7.4: the simulators obey a short sensitivity list, but synthesis builds the full mux. That is one way RTL and gates disagree.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer notes that zero delay rules out timing. It maps each failing line to a likely RTL construct.
What Interviewers Listen For (Senior)
A good senior answer turns the three fixes into lint rules and a reset rule. Then the same kind of bug cannot come back. It keeps a small gate-level set in regression.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfProve ItBreak ItCompare
- RTL Passes, Gate-Level Simulation Fails
-
WhyWhy One Simulator Did Not Show the MismatchL2 Mid-Level
A colleague reruns the
always @*test on Verilator and it passes. Why might one simulator hide the mismatch?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
Verilator does not follow every event rule of the standard. On this example it recomputed
yas plain logic, so it printed 6. Icarus follows the@*rule and keeps 3. A design whose result depends on the simulator is depending on code the gates do not have. Fix the code.Self-Check
Tick each key point you covered in your answer.
Tool as Truth
"Verilator passes, so the RTL matches the gates."
Here Verilator happens to agree with the gates. Another team's event-driven simulator will not, and the code still has the mismatch.
Source Measured: the root twin on Verilator: y=6, Verilator 5.052
-
CompareLint vs Gate-Level Simulation for MismatchesL2 Mid-LevelL3 Senior
Compare lint with gate-level simulation as ways to catch simulation-synthesis mismatches.
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 RTL and flags risky constructs, such as short sensitivity lists, inline initializers and blocking writes in clocked blocks. It runs in seconds and needs no test. Gate-level simulation finds a mismatch only when a test exercises it, and it runs slowly. Use lint as the gate on every commit, and a small gate-level set as the net.
Self-Check
Tick each key point you covered in your answer.
Half-Truth
"Lint is clean, so gate-level simulation is not needed."
Lint finds patterns it knows. Some mismatches, such as X behaviour in reset paths, show only when a real netlist runs a real test.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 1.7 SystemVerilog lint checkers
-
Break ItWhat Zero-Delay Gate Simulation MissesL3 Senior
How can a design pass both RTL and zero-delay gate-level simulation and still fail in silicon?
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
Zero-delay gates still have no setup or hold time, so metastability and clock crossings look perfect. Real timing faults need static timing analysis, not simulation. Power-up values and analog effects are absent too. Gate simulation catches netlist mismatches, not the physics.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer lists what each sign-off step proves and what it cannot. It covers simulation, equivalence, static timing and CDC analysis.
Half-Truth
"Gate-level sim with SDF covers all timing."
It checks only the paths and cases your tests happen to exercise. Static timing analysis checks every path in every corner.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 8.1.6 Multiple clocks and clock domain crossing
-
What IfSimulation-Only Code Inside RTLL1 JuniorL2 Mid-Level
What if the RTL also contains
$displaycalls and checks? How do they behave in synthesis?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
Synthesis cannot build a print or a check as logic. Tools ignore such code, reject it, or keep it as a cell with no output. Wrap simulation-only code in
translate_offandtranslate_onpragmas, or in anifndef SYNTHESISguard. Then synthesis sees exactly the design.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"A
$displayin the RTL changes nothing in the gates."Usually true, but a check written around a design signal can keep extra logic alive or confuse a tool. Guard it so the netlist is predictable.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 2.2 SystemVerilog language rules (synthesis pragmas)
-
Prove ItSolve R1.3.1: The Decoder That RememberedSimulator-graded
Show it, don't just say it: this Silicon Lab problem is graded by the simulator.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"always @* wakes on everything the block reads."
It misses signals read inside a called function. The twin keeps y=3 after shift_en changes, like the first failing test.
Run It
A function that reads shift_en, called from always @*, then from always_comb. Both synthesize to the same 4 cells.
a=3, shift_en=1: y=3 FAIL: always @* did not wake on shift_en, which is read only inside the functionSee the Fix
module scale (input logic [3:0] a, input logic shift_en, output logic [3:0] y);
function automatic logic [3:0] f(input logic [3:0] x);
return shift_en ? x << 1 : x; // reads shift_en, which is not an argument
endfunction
always_comb y = f(a);
endmodule
module tb;
logic [3:0] a = 4'd2, y; logic shift_en = 0;
scale dut (.a(a), .shift_en(shift_en), .y(y));
initial begin
#1 a = 4'd3; // y = 3
#1 shift_en = 1; #1; // y should become 6
$display("a=3, shift_en=1: y=%0d", y);
if (y === 4'd6) $display("PASS: always_comb also wakes on signals read inside the function");
end
endmodule
Prints: a=3, shift_en=1: y=6 PASS: always_comb also wakes on signals read inside the function
Misconception
"logic [3:0] cnt = 0; resets the counter."
An inline initializer sets the value once at simulation start. ASIC flops power up unknown, so the gates show X, as in the second failing test.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 3.4 Variable types, Best Practice Guidelines 3-5 and 3-6
Half-Truth
"Gate-level failures are timing problems. Check the SDF."
This run has zero delay, so there is no timing to blame. These are RTL constructs that simulate differently from what synthesis built.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. appendix C.3 An optimistic X
Delivery
Opens the netlist first and starts tracing gates.
The fast path is the RTL construct behind each failure. Gate tracing is the last resort, after the likely RTL causes are ruled out.