Skip to content

VHDL · Chapter 4.4 · Concurrent Statements

Selected Signal Assignment (with/select)

The with-select concurrent assignment chooses a value by the single value of one selector expression, giving one result per selector value and closing the list with a when-others clause. The choices are mutually exclusive and there is no priority, so the hardware is a balanced, case-style multiplexer or decoder rather than a priority chain. Because the choices must cover every possible selector value, VHDL requires the list to be exhaustive, which is why the when-others clause is mandatory. This lesson builds that balanced multiplexer, contrasts it structurally with the priority multiplexer of the previous form, and shows how to choose between the two for decoders, lookup tables, and general selection logic.

Foundation14 min readVHDLwith/selectSelected AssignmentMultiplexerDecoderCombinational

1. Engineering intuition — choose by value, in parallel

Sometimes selection is not a priority chain but a clean lookup: "for selector value 00 use A, for 01 use B, for 10 use C." There is no precedence — exactly one selector value applies at a time, and all the choices are equal-rank alternatives. The with/select assignment expresses that as a balanced multiplexer: the selector picks one of N inputs in a single, flat decision rather than a ladder of priority tests.

2. Formal explanation — exhaustive, mutually exclusive choices

The selected signal assignment has the form:

with_select_form.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
with selector select
  target <= expr1 when choice1,
            expr2 when choice2,
            exprN when others;     -- 'others' covers all remaining selector values — REQUIRED

The selector is evaluated once and compared against each choice; the matching choice supplies the value. The choices must be mutually exclusive and cover every possible selector value — VHDL enforces this, so a when others (or an explicit full enumeration) is mandatory; otherwise it will not compile. It is still one concurrent statement, one driver, combinational (lesson 4.2).

3. Production-quality RTL — decoders and muxes

mux_and_decoder.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
-- 4:1 multiplexer selected by a 2-bit code:
with sel select
  y <= d0 when "00",
       d1 when "01",
       d2 when "10",
       d3 when others;            -- "11" (and any meta-values) → covered
 
-- a one-hot decoder from a 2-bit input:
with code select
  onehot <= "0001" when "00",
            "0010" when "01",
            "0100" when "10",
            "1000" when others;

What hardware does this become? The first is a 4:1 multiplexer — sel drives the select lines of a single balanced mux. The second is a 2-to-4 decoder. Neither has a priority chain; the selector fans out to a flat selection network. when others also handles non-'0'/'1' selector bits, keeping the logic defined for metavalues in simulation.

4. Hardware interpretation — a balanced mux, not a ladder

balanced multiplexer selecting one of N expressions by selector valueselects one-of-N (no priority)selectsone-of-N (no…selectorevaluated onceexpr / choice1when "00"expr / choice2when "01"expr / otherswhen otherstargetthe one matching choice12
A with/select assignment builds a BALANCED multiplexer/decoder. The selector value is compared against all choices simultaneously and exactly one matches, routing its expression to the target — a flat one-of-N selection with no priority. Contrast the priority-mux ladder of when/else: here all choices are equal rank, so reordering them changes nothing, and the logic depth is a single select layer rather than a chain.

5. Simulation interpretation — match the selector, drive the target

In simulation it behaves like a concurrent assignment sensitive to the selector and the chosen expressions: when any changes, it matches the selector against the choices and schedules the matching expression onto the target one delta later.

event flow matching selector to one exhaustive choice and updating the targetSelector / exprchangesimplicit sensitivity firesMatch selector to achoiceexhaustive, mutuallyexclusiveExactly one matchesflat decode — no prioritySchedule targetonto its single driverDelta update + fanouttarget takes the value12
Event flow of a with/select assignment. A change in the selector or a selected expression wakes the statement; the selector is matched against the (exhaustive, mutually exclusive) choices; exactly one matches and its expression is scheduled onto the single driver; one delta later the target updates and its fanout wakes. There is no ordered scan — the match is a flat decode, which is why there is no priority.

A 4:1 mux: the selector value routes the matching input to y

8 cycles
A 4:1 mux: the selector value routes the matching input to ysel=00 → y=d0sel=00 → y=d0sel=01 → y=d1 (no priority — pure value decode)sel=01 → y=d1 (no prio…sel=11 → others → y=d3sel=11 → others → y=d3sel0000010110101111yd0d0d1d1d2d2d3d3t0t1t2t3t4t5t6t7
The selector value alone determines the output — each value maps to exactly one input, with no ordering between choices. This is the balanced-mux behaviour: reordering the when-clauses would not change anything, unlike the priority when/else where order is precedence.

6. Debugging example — the incomplete coverage error

Expected: a clean decode compiles and synthesises to a mux. Observed: a compile error about choices not covering all cases, or (in process-style code) an inferred latch for the uncovered values. Root cause: the selector's full value space was not covered — a std_logic_vector(1 downto 0) has more than four cases once metavalues are considered, so without when others the choices are incomplete. Fix: always close the list with when others. Engineering takeaway: with/select demands exhaustive choices by design; when others both satisfies that and defines behaviour for metavalues, keeping the logic latch-free and simulation-clean.

incomplete_choices.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- WRONG: only the four "expected" patterns — std_logic has more values, so this is incomplete.
with sel select
  y <= d0 when "00", d1 when "01", d2 when "10", d3 when "11";   -- no 'others' → error/latch
-- RIGHT: 'when others' makes the choices exhaustive and defines metavalue behaviour.
with sel select
  y <= d0 when "00", d1 when "01", d2 when "10", d3 when others;

7. Common mistakes & what to watch for

  • Forgetting when others. std_logic_vector selectors are never fully covered by the "expected" patterns alone; omit others and it will not compile (or infers a latch in process form).
  • Using with/select where priority is needed. It is balanced — no precedence. For prioritised conditions use when/else (lesson 4.3).
  • Overlapping choices. Choices must be mutually exclusive; duplicate or overlapping values are an error.
  • Selecting on multiple independent conditions. with/select keys on one selector value; if the decision depends on several unrelated conditions, when/else fits better.
  • Assuming choice order matters. It does not — only the selector value does.

8. Engineering insight

with/select and when/else are the two structured concurrent assignments, and choosing between them is choosing the hardware: a balanced mux/decoder versus a priority mux. Reach for with/select when the decision is "based on the value of this one thing" — opcode decode, mux select, small ROM — because it is exhaustive by construction (no missing-case latch surprises) and synthesises to a single, flat selection layer. Reach for when/else when the decision is a prioritised set of conditions. Both stay concurrent, single-driver, and combinational; the form you pick should mirror the structure you intend.

9. Summary

with selector select target <= … when choice, … when others; is a concurrent, single-driver, combinational assignment that selects by the selector's value — a balanced multiplexer/decoder with no priority and mutually exclusive choices. The choices must be exhaustive, so when others is required; it also defines behaviour for metavalue selectors.

10. Learning continuity

You now have both structured concurrent assignments — priority (when/else) and balanced (with/select). Both are built from expressions, and those expressions are made of operators. The next lesson, Logical and Boolean Operators, covers the gate-level building blocks that fill these assignments — and/or/xor/not, vector operations, relational operators, and the VHDL precedence rule that forces parentheses — completing the toolkit for concurrent combinational logic.