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.
Standards & specifications
- Governing standard
- IEEE Std 1076 (VHDL)(opens IEEE in a new tab)
Defines the VHDL language — types, the simulation cycle, and the semantics a conforming analyser and simulator must implement. Synthesis restrictions and vendor coding rules are tool behaviour, not language rules.
This page also covers RTL structure, verification approach and debugging technique. Those are engineering practice built on the standard, not requirements the standard itself imposes.
Where this fits
Part of the VHDL curriculum.
