VHDL · Chapter 4.3 · Concurrent Statements
Conditional Signal Assignment (when/else)
The bare concurrent assignment computes one expression, but real logic usually has to choose, and the when-else form adds that. It lets a target take one value when the first condition holds, another when the second holds, and so on. The conditions are tested in order, and the first true one selects its value, so this is precisely a priority multiplexer. It is still a single concurrent statement, a single driver, and pure combinational logic. This lesson shows how the textual order becomes hardware priority, why you must end with a final else to avoid inferring a latch, and how to read the priority-mux network the construct describes.
Foundation14 min readVHDLwhen/elseConditional AssignmentPriority MuxLatchCombinational
1. Engineering intuition — choose by priority
Often a signal should take one of several values depending on conditions, and those conditions
have a precedence: "if an error, show the error code; else if busy, show busy; else show idle."
The when/else assignment captures that directly — it walks the conditions top to bottom and uses
the first that is true. That ordering is not cosmetic: it is the priority of a real multiplexer
network, where earlier conditions override later ones.
2. Formal explanation — first true condition wins
The conditional signal assignment has the form:
target <= expr1 when cond1 else
expr2 when cond2 else
expr3; -- final 'else' value (no condition) — REQUIRED for completenessThe conditions cond1, cond2, … are boolean and are evaluated in order; the first true one
selects its expression. It remains a single concurrent statement — one driver, combinational
(lesson 4.2) — re-evaluated whenever any signal in any condition or expression changes. The
trailing else with no condition supplies the default; omit it and some input combinations leave
the target unassigned.
3. Production-quality RTL — a priority encoder of behaviour
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
-- Priority: error beats busy beats normal. Order = precedence.
status <= ERR_CODE when fault = '1' else
BUSY_CODE when unsigned(pending) /= 0 else
IDLE_CODE;
-- A simple 2:1 mux is the degenerate case:
y <= a when sel = '1' else b;What hardware does this become? The status line synthesises to a priority multiplexer: a
chain of 2:1 muxes where fault selects at the top, then the pending /= 0 test, then the
default — earlier conditions win. The y line is a single 2:1 mux. Comparisons use numeric_std
so the pending /= 0 test is well-defined.
4. Hardware interpretation — a chain of priority muxes
5. Simulation interpretation — re-evaluate, pick first true
Like any concurrent assignment, it is event-driven: a change on any signal in the conditions or expressions wakes it, it scans the conditions in order, and it schedules the first-true expression onto the target one delta later.
Priority in action: fault overrides busy, which overrides idle
8 cycles6. Debugging example — the missing else that becomes a latch
Expected: combinational output. Observed: synthesis reports an inferred latch, and in gate
simulation the output unexpectedly holds a stale value for some input combinations. Root
cause: the when/else had no final unconditional else, so when no condition was true the target
was left unassigned — VHDL keeps its previous value, which is memory (a latch). Fix: always end
with an unconditional else that supplies a default for every uncovered case. Engineering
takeaway: an inferred latch from a conditional assignment almost always means an uncovered case —
add the final else; never leave a combinational output undriven for any input.
-- WRONG: no final else → if sel is neither "00" nor "01", y holds (latch).
y <= a when sel = "00" else
b when sel = "01"; -- uncovered cases leave y unassigned → latch
-- RIGHT: an unconditional else covers everything.
y <= a when sel = "00" else
b when sel = "01" else
(others => '0'); -- default for all other sel values → pure combinational7. Common mistakes & what to watch for
- Omitting the final
else. Uncovered cases leave the target unassigned → latch. Always supply an unconditional default. - Wrong condition order. Order is priority; putting the broad condition first masks the specific one. Most-specific/highest-priority conditions go first.
- Expecting parallel (non-priority) selection.
when/elseis a priority mux; for a balanced, mutually-exclusive decode by one selector, usewith/select(next lesson). - Side-effect-free but overlapping conditions assumed exclusive. If two conditions can be true at once, the first wins — make sure that is the intent.
- Comparing vectors without
numeric_stdfor arithmetic intent. Usenumeric_stdfor magnitude comparisons; plain=//=are fine for pattern matches.
8. Engineering insight
The when/else assignment is the concurrent way to say "choose by priority," and its single most
important property is that textual order equals hardware precedence. That makes it perfect for
naturally-prioritised logic (interrupts, error-over-status, default fallthrough) and a poor fit for
balanced selection, where the priority chain wastes logic depth and obscures intent. Pair it with
the discipline of always ending in an unconditional else, and it gives concise, latch-free
combinational logic whose structure — a priority mux — you can read straight off the source.
9. Summary
target <= e1 when c1 else e2 when c2 else eN; is a concurrent, single-driver, combinational
assignment that selects the first true condition's value — a priority multiplexer whose
clause order is its precedence. A missing final unconditional else leaves some cases unassigned
and infers a latch, so always provide the default.
10. Learning continuity
when/else selects by arbitrary conditions, with priority. The companion form selects by the value
of a single expression, with no priority — every choice mutually exclusive. The next lesson,
Selected Signal Assignment (with/select), builds that balanced, case-style multiplexer and
contrasts it with the priority mux you just learned, so you can pick the right form for each kind of
selection.