Interview Question · Code Reading
The Mux with a Short Sensitivity List
The Question
The interviewer asks
What does simulation show when sel changes here? What does synthesis build?
module mux2 (input logic a, b, sel, output logic y);
always @(a or b)
y = sel ? b : a;
endmodule
You 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
Simulation re-runs the block only when a or b changes. So when only sel changes, y stays stale. Synthesis builds logic from the expression, not from the list, so it gives a plain 2:1 mux. The RTL simulation now shows behaviour the chip does not have. Use always_comb, which wakes on every signal the block reads.
y (old) is the Verilog-2001 block with always @(a or b); y (new) is its translation with always_comb.- Cycle 0
Edge 2:
aandbchanged, so the old block ran. Both versions show 11. - Cycle 1
Edge 3: only
selchanged. The old block never woke, soystill showsa; the new one shows 22. - Cycle 3
Edge 5:
achanged, the old block woke at last, and now showsb, two edges late. - Cycle 4
Edge 6:
selalone again, and the oldyis stale again.
Icarus 12 and Verilator 5.052 print the same old lines. Synthesize builds 16 cells for both versions.
The snippet on the pinned Yosys flow: one mux cell, no latch.
module mux2 (input logic a, b, sel, output logic y);
always @(a or b)
y = sel ? b : a;
endmodule
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Junior)
A good junior answer says y goes stale when only sel changes, while the netlist is a full mux. It names this as a mismatch between simulation and synthesis.
What Interviewers Listen For (Senior)
A good senior answer bans hand-written sensitivity lists in the coding rules. It makes a lint check for them a gate on legacy code.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfCompareScale It
- The Mux with a Short Sensitivity List
-
WhyWhy Synthesis Ignores the Sensitivity ListL1 Junior
Why does synthesis build a full mux when the list leaves
selout?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
Gates have no event list. A gate output follows its inputs all the time. Synthesis reads the assignments to learn the function, and the function of
sel ? b : ais a mux. A sensitivity list only tells a simulator when to re-run the code.Self-Check
Tick each key point you covered in your answer.
Misconception
"The sensitivity list tells synthesis which inputs to connect."
The inputs come from the expressions in the block. A signal used in the block but left out of the list is still wired in.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.2 The always and always_comb procedures
-
What IfAn Extra Signal in the Sensitivity ListL1 Junior
What if the list has an extra signal that the block never reads?
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
The block runs more often than needed, which costs a little simulation time. Each run computes the same value, so the output never goes stale. There is no mismatch with the gates. The real danger is always a missing signal, never an extra one.
Self-Check
Tick each key point you covered in your answer.
Misconception
"An extra signal adds an input to the gates."
Synthesis wires only signals the assignments use. An unread signal in the list connects to nothing.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.2 The always and always_comb procedures
-
CompareAlways @* vs Always_combL1 JuniorL2 Mid-Level
Compare
always @*withalways_comb. Here the block calls a function that readsshift_en. What does Icarus print?systemverilog 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 @* 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("FAIL: always @* did not wake on shift_en, which is read only inside the function"); end endmodule2: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
Icarus prints
y=3and the FAIL line.always @*waits only on what the block names, including function arguments, andshift_enis read inside the function.always_combalso waits on signals read inside called functions, so it gives 6. It also runs once at time zero, and it forbids other writers.RUNIcarus Verilog · in your browserExpected:a=3, shift_en=1: y=3FAIL: always @* did not wake on shift_en, which is read only inside the functionSelf-Check
Tick each key point you covered in your answer.
Tool as Truth
"Verilator gives 6, so
always @*is fine."Verilator updated
yhere, but Icarus follows the event rule and keeps 3. One tool's result does not make the code correct.Source Measured: the snippet on both tools: Verilator printed y=6, Icarus Verilog 12; Verilator 5.052
-
Scale ItFixing Sensitivity Lists in Legacy RTLL2 Mid-LevelL3 Senior
You own a legacy Verilog-2001 IP with hundreds of hand-written sensitivity lists. How do you remove this class of bug safely?
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
Run lint to list every incomplete sensitivity list. Convert combinational blocks to
always_comb, which also checks for latches and second writers. Re-run the full regression, because a fixed list can change what the old tests saw. Then run an equivalence check of the old netlist against the new one, which should match.Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer plans the change as a risk. It takes a lint inventory and converts the blocks mechanically. Then regression and an equivalence check prove the netlist did not change.
Wrong Altitude
"Replace each list with
@*and ship it."@*misses signals read inside functions, as thealways @*question shows. And without a regression and an equivalence check, you cannot show nothing broke.
What People Get Wrong
Common wrong answers and why they fail. Run It shows the wrong belief failing on a real simulator.
Misconception
"If the RTL simulation passes, the gates do the same thing."
The list controls simulation only. In the twin, simulation keeps y at 0 after sel rises, while the netlist is the same one-mux circuit as the fix.
Run It
The snippet with a bench, then always_comb. Both synthesize to the same single mux.
sel=1, a=0, b=1: y=0 FAIL: simulation is not the gates; y stayed stale because sel is not in the listSee the Fix
module mux2 (input logic a, b, sel, output logic y);
always_comb
y = sel ? b : a;
endmodule
module tb;
logic a = 1, b = 1, sel = 0, y;
mux2 dut (.a(a), .b(b), .sel(sel), .y(y));
initial begin
#1 a = 0; // y follows a: 0
#1 sel = 1; #1; // y should now follow b: 1
$display("sel=1, a=0, b=1: y=%b", y);
if (y !== 1'b1) $display("FAIL: simulation is not the gates; y stayed stale because sel is not in the list");
else $display("PASS: y follows sel");
end
endmodule
Prints: sel=1, a=0, b=1: y=1 PASS: y follows sel
Tool as Truth
"Synthesis would reject a wrong sensitivity list."
Many synthesizers build the full logic and at most warn. A clean synthesis run says nothing about what your simulation showed.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.2 The always and always_comb procedures
Misconception
"The stale output means synthesis builds a latch."
Nothing in the code holds a value on a path; the hold comes only from the simulator not waking. The run shows one mux and zero latches.
Source Measured: the run on this question, Yosys 0.70+290 (OSS CAD Suite 2026-11-02), slang front end, synth -flatten with ABC, ltp -noff