VHDL · Chapter 19.3 · Interview and Industry Readiness
Latch Inference — Interview Deep Dive
Latch inference is one of the most-asked RTL interview topics, because it tests whether you understand what actually creates storage. The rule: in a combinational process, if a signal is not assigned on every path, it must hold its previous value, and synthesis implements that hold as a level-sensitive latch. The classic triggers are an if without an else, a case missing its final catch-all branch, and a signal assigned in only one branch. The failure mode is real, since latches make static timing analysis hard, are glitch-prone, and are almost never intended, so a stray one is a genuine bug. The fixes are mechanical: a default assignment before the logic, or assigning the output in every branch. This lesson works the exact spot-it, explain-it, fix-it drill interviewers use.
Foundation15 min readVHDLInterviewLatchCombinationalInferenceRTL
1. Engineering intuition — an unassigned path means 'remember', and remembering needs a latch
The whole concept rests on one question the synthesizer asks: for every possible set of inputs, is this output given a fresh value? If yes, it is pure combinational logic. If no — if some input combination leaves the output unassigned — then the hardware must keep the old value, and keeping a value requires a storage element. In a combinational process (no clock), that storage is a transparent latch: it passes the input through while the controlling condition holds and freezes the value when it does not. So a latch is not something you typed — it is the synthesizer's only way to honor "this output is sometimes not assigned." The interview skill is reading a process and instantly spotting the path where the output goes unassigned.
2. Formal explanation — why latches appear, and the triggers
-- RULE: combinational process + an output unassigned on SOME path -> it must HOLD -> level-sensitive latch.
-- TRIGGER 1: if with no else (y unassigned when en = '0'):
process (all) begin
if en = '1' then y <= d; end if; -- y holds when en='0' -> LATCH
end process;
-- TRIGGER 2: case missing coverage (y unassigned for uncovered sel):
process (all) begin
case sel is
when "00" => y <= a;
when "01" => y <= b; -- "10"/"11" unassigned -> LATCH (and a coverage error w/o others)
when others => null; -- 'null' still leaves y unassigned -> LATCH
end case;
end process;
-- TRIGGER 3: branch-only / partial assignment (output set in just one path):
process (all) begin
if cond then y <= a; end if; -- y unassigned when cond is false -> LATCH
end process;The rule: a combinational output not assigned on every path infers a level-sensitive latch. The triggers
are if without else, case without full coverage that actually assigns the output, and partial/branch-only
assignment. The latch is the hardware that holds the value on the unassigned paths.
3. Production usage — the fixes and why latches are bad
-- WHY LATCHES ARE UNDESIRABLE (the failure mode to state in the interview):
-- * level-sensitive (transparent while enabled) -> hard to do static timing analysis on
-- * glitch-prone and timing-fragile vs edge-triggered flip-flops
-- * almost always UNINTENDED -> a real bug; synthesis warns 'inferred latch'
-- FIX 1: DEFAULT ASSIGNMENT before the logic (covers all paths) -> pure combinational, no latch:
process (all) begin
y <= '0'; -- default
if en = '1' then y <= d; end if; -- now y is assigned on every path
end process;
-- FIX 2: assign the output in EVERY branch (if/else, all case choices):
process (all) begin
if en = '1' then y <= d; else y <= '0'; end if;
end process;
-- FIX 3: full case coverage + process(all):
process (all) begin
case sel is
when "00" => y <= a;
when others => y <= '0'; -- catch-all ASSIGNS y -> no latch
end case;
end process;What hardware does this become? With the fix, combinational logic with no storage; without it, a transparent latch. State the failure clearly in the interview: a latch is level-sensitive (transparent while its condition holds), which makes timing analysis hard and the design glitch-prone, and it is almost always unintended — that is why the tool warns. The fixes all do the same thing: ensure the output is assigned on every path (a leading default is the simplest, most robust habit). Showing the trigger, naming the latch, and applying a default is precisely the spot-explain-fix drill interviewers run.
4. Structural interpretation — incomplete assignment vs default
5. Simulation interpretation — transparent-then-hold vs clean logic
Latch (transparent while en, holds when en=0) vs clean combinational output
8 cycles6. Debugging example — the inferred-latch warning
Expected: a combinational mux/decoder with no storage. Observed: the synthesis report says inferred
latch on an output, and sometimes timing analysis flags an unconstrained level-sensitive path. Root cause:
the combinational process leaves the output unassigned on some path — an if with no else, a case missing
others, or a branch that does not assign it (including when others => null) — so the output must hold,
which becomes a latch. Fix: add a default assignment to the output at the top of the process (or assign
it in every branch / cover every case choice with a value), so it is assigned on all paths and synthesizes as
pure logic. Engineering takeaway: an inferred-latch warning means a combinational output can go unassigned —
default-assign it first or cover every branch; never ignore the warning, since the latch is almost always a real
bug.
-- BUG: y unassigned when en='0' -> inferred latch.
-- process (all) begin if en='1' then y <= d; end if; end process;
-- FIX: default assignment -> assigned on all paths -> combinational logic.
process (all) begin
y <= '0'; -- default first
if en = '1' then y <= d; end if;
end process;7. Common mistakes & what to watch for
- Ignoring the inferred-latch warning. It almost always signals a real bug; find the unassigned path and cover it.
when others => null'covering' a case. It satisfies coverage but leaves the output unassigned — still a latch; assign a value instead.- Relying on a clock to fix it. A latch is a combinational problem; adding a clock makes a flip-flop (a different design), not a fix for the missing assignment.
- Partial defaults. Default-assign every output the process drives, not just one; a forgotten output latches.
- Stopping at the rule. Finish the interview answer with the hardware (level-sensitive latch, hard to time) and the fix (default/full coverage).
8. Engineering insight & continuity
Latch inference is the interview favorite because the rule is sharp and the hardware is concrete: a
combinational output unassigned on some path must hold, which synthesis builds as a level-sensitive latch —
undesirable because it is hard to time, glitch-prone, and unintended. The fixes all ensure assignment on every
path: a leading default, assignment in every branch, or full case coverage. Answer as rule → hardware →
failure, and you nail it. The next deep dive moves from accidental storage to the storage you do want and how to
initialize it — the next lesson, Reset and Clocking Interview Questions, worked in the same structure.