Interview Question · Concept
Why Synthesis Builds a Latch
The Question
The interviewer asks
What makes synthesis infer a latch from combinational code, and how do you stop it?
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
A combinational block must give every output a value on every path. If one path assigns nothing, the output must keep its old value. Keeping a value needs memory, so synthesis builds a level-sensitive latch. Fix it by assigning every output on every path: a default at the top, an else, or a default arm. Then write the block as always_comb, so lint and synthesis report any path you missed.
- Enable high
en is 1: the latch is open, y follows the shift. Every test cycle looked like this.
Follow the calls, values and waits
- data 1000: 1 << sel → latch x4
- data 1000: latch x4 → y[3:0]
- Enable falls
en is 0: the latch closes and keeps the last one-hot value. sel can change; nothing reaches y.
Follow the calls, values and waits
- call 1000: en → latch x4
- With the else
The fixed block has a value for en = 0, so the latch is gone: six gates decode en and sel, and y is 0000.
Read the diagram as text
- sel[1:0]: input
- en: input
- 1 << sel: four gates: the one-hot value
- latch x4: enable = en; holds when en is 0
- y[3:0]: output
- sel[1:0] → 1 << sel: select
- 1 << sel → latch x4: data
- en → latch x4: enable
- latch x4 → y[3:0]: held or following
The latch is the direct picture of "keep the old value". Removing the hold from the code removes the cell from the netlist.
Find the paths
Each
ifwithoutelse, and eachcasevalue with no arm, is a path through the block.Check every output on every path
An output with no assignment on a path must hold its value there.
Hold means memory
In a block with no clock, that memory is a latch: transparent while its enable is active.
Close the paths
Assign a default first, or add the missing
elseor arm. The latch count goes to zero.
Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Fresher)
A good fresher answer traces each path of a small if or case block. It names the output that some path leaves unassigned.
What Interviewers Listen For (Mid-Level)
A good mid-level answer picks the fix from the intent. That is a default at the top, a full case, or always_latch for a wanted latch. It checks the latch count in the synthesis report.
Cross-Questions
Where the interviewer goes next. Open a node to practise that follow-up.
WhyWhat IfProve ItBreak ItCompareScale It
- Why Synthesis Builds a Latch
-
WhyWhy an Unwanted Latch Is a ProblemL1 JuniorL2 Mid-Level
Why is an unintended latch a real problem and not just a lint warning?
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 latch is memory the spec never asked for, so the output can show a stale value. While its enable is active the latch is transparent, so glitches on its input pass straight through. Static timing and test tools treat latches specially, so many teams avoid them to keep those steps simple. The design may work in RTL simulation and still fail in the lab.
Self-Check
Tick each key point you covered in your answer.
Missed Corner
"It passed the tests, so the latch is harmless."
Tests pass when they never take the unassigned path. In lesson R1.3 the bench never dropped the enable, so the stale output was never seen.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 9.2 Unintentional latch inference
-
CompareA Latch Next to a Flip-FlopL1 JuniorL2 Mid-Level
Compare a latch and a flip-flop fed the same data. What does this print?
systemverilog module tb; logic clk = 0, d = 0, q_latch, q_flop; always_latch if (clk) q_latch = d; // transparent while clk is high always_ff @(posedge clk) q_flop <= d; // samples only at the rising edge always #10 clk = ~clk; // rising edges at 10, 30 initial begin #12 d = 1; // d rises while clk is high #1 $display("t=13 (clk high): latch=%b flop=%b", q_latch, q_flop); #4 d = 0; #1 $display("t=18 (clk high): latch=%b flop=%b", q_latch, q_flop); #4 d = 1; // t=22: clk is low now #1 $display("t=23 (clk low): latch=%b flop=%b", q_latch, q_flop); #8 $display("t=31 (after edge): latch=%b flop=%b", q_latch, q_flop); $finish; 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
The latch follows
dwhile the clock is high, so it shows 1 at t=13 and 0 at t=18. The flop changes only at rising edges. It took 0 at t=10 and holds it until t=30, when it takes 1. When the clock is low, the latch holds. Designers use latches on purpose in clock gating cells and in some latch-based pipelines.RUNIcarus Verilog · in your browserExpected:t=13 (clk high): latch=1 flop=0t=18 (clk high): latch=0 flop=0t=23 (clk low): latch=0 flop=0t=31 (after edge): latch=1 flop=1Self-Check
Tick each key point you covered in your answer.
Misconception
"A latch is a flop that triggers on a level."
A flop samples once per edge. A latch passes its input through for the whole active level, so several changes in one phase all reach the output.
Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 9.1 Modeling latches
-
What IfAlways_comb and a Missing AssignmentL1 JuniorL2 Mid-Level
Asked if they say
always_combprevents latchesWhat if the decoder is written with
always_combinstead ofalways @*? Is the latch gone?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
No. Simulation behaves the same, and the output still holds its value when
enis low. The difference is in the tools that read the intent. Lint names the latch, and many synthesizers warn or stop. On this site's flow, synthesis refuses the block with a logic-loop error. Either way, you still have to add the missing assignment yourself.Self-Check
Tick each key point you covered in your answer.
Misconception
"
always_combandalways @*simulate differently here."For this code both wake on any input change and both hold
ywhen nothing assigns it. The difference shows only in lint and synthesis.Source Sutherland, RTL Modeling with SystemVerilog (2017) ch. 7.2 The always and always_comb procedures
Tool as Truth
"Our synthesizer accepted it, so it is not a latch."
Tools differ: some build the latch and only warn. The report, not a clean exit, tells you what was built.
Source Lesson R1.3 claims: the plain Yosys front end stops with "Latch inferred"; the slang front end reports a logic loop
-
Break ItWhen a Default Assignment Hides a BugL2 Mid-Level
How can the "assign a default at the top" fix itself hide a functional bug?
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 default removes the latch, but it also gives a value to any arm you forgot. A missing arm then outputs the default quietly, often zero, and no tool complains. Choose a default that the spec allows, and make the testbench cover every input value. Some teams use
unique case, so that simulation reports a value no arm matches.Self-Check
Tick each key point you covered in your answer.
Half-Truth
"No latch in the report means the decode is complete."
The report only says every path assigns something. It cannot say the value on each path is the right one.
-
Scale ItA Team Rule for Latch-Free Combinational CodeL3 Senior
You lead an RTL team. What rules and checks keep unintended latches out of every block?
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
Make
always_combmandatory for combinational blocks andalways_latchfor the rare intended latch. Run lint on every commit, with a latch inference message as an error. Make the synthesis latch count a gate in the flow, with a reviewed waiver list for intended latches. Review default values against the spec, because removing a latch can hide a missing case.Self-Check
Tick each key point you covered in your answer.
What Interviewers Listen For (Senior)
A good senior answer turns the coding rule into automatic gates: lint severity, a latch-count check in synthesis, and a waiver review. It names who owns each gate.
Wrong Altitude
"We tell people to be careful with
ifstatements."Advice does not scale. A senior answer puts the check in the flow, so a latch fails the build before review.
-
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
"A missing else only matters in simulation. Synthesis fills in zero."
Synthesis builds exactly the hold that simulation shows. The twin synthesizes four latches, and with en low the output keeps its last value.
Run It
A 2-to-4 decoder with no else: simulated, and synthesized on the pinned Yosys flow.
en=0: y=0100 FAIL: synthesis does not fill in zero; y held 0100, the latch keeps the old valueSee the Fix
module dec (input logic en, input logic [1:0] sel, output logic [3:0] y);
always @* begin
if (en) y = 4'b0001 << sel;
else y = 4'b0000; // the fix: every path assigns y
end
endmodule
module tb;
logic en; logic [1:0] sel; logic [3:0] y;
dec d (.en(en), .sel(sel), .y(y));
initial begin
en = 1; sel = 2; #1;
en = 0; #1;
$display("en=0: y=%b", y);
if (y !== 4'b0000) $display("FAIL: synthesis does not fill in zero; y held 0100, the latch keeps the old value");
else $display("PASS: y is 0000 whenever en is 0");
end
endmodule
Prints: en=0: y=0000 PASS: y is 0000 whenever en is 0
Half-Truth
"Writing always_comb stops latches."
always_comb states an intent that tools can check. It does not add the missing assignment, and simulation still holds the value. The fix is still your code.
Source IEEE 1800-2017 §9.2.2.2
Buzzword Without Mechanism
"Latches are bad because they are asynchronous."
That names a word, not a problem. The real costs are a transparent path that passes glitches, harder timing and test, and memory nobody asked for.