VHDL · Chapter 5.2 · Sequential Statements & Processes
The Sensitivity List
A process re-runs whenever a signal in its sensitivity list changes, so the list is the set of triggers, and getting it wrong is the most common bug in VHDL. For combinational logic the rule is strict: the list must contain every signal the process reads, because a missing signal means the process does not re-run when that input changes, and then RTL simulation disagrees with the synthesised hardware, which has no such blind spot. For clocked logic the list is the opposite, holding only the clock and any asynchronous reset, because you sample only on the edge. This lesson explains why the incomplete-sensitivity mismatch happens, how to read the trigger set as hardware, and how the VHDL-2008 process-all form removes the guesswork entirely.
Foundation14 min readVHDLSensitivity ListCombinationalSim vs Synthesisprocess(all)RTL
1. Engineering intuition — the list is the trigger set
A sensitivity-list process is asleep until one of its listed signals changes. So the list answers a single question: what should wake this logic? For combinational logic the honest answer is "any input I look at" — a gate reacts to all its inputs, so the process must too. For a register the honest answer is "only the clock edge" — a flip-flop ignores its data input except at the edge. Mismatch the list to that intent and your simulation models logic that does not exist.
2. Formal explanation — complete for combinational, clock-only for sequential
-- COMBINATIONAL: list EVERY signal the body reads (a, b, and sel here).
comb : process (a, b, sel)
begin
if sel = '1' then y <= a; else y <= b; end if;
end process;
-- CLOCKED: list ONLY the clock (plus async reset if used).
reg : process (clk)
begin
if rising_edge(clk) then q <= d; end if; -- 'd' is NOT in the list — sampled at the edge
end process;
-- VHDL-2008: 'all' includes every read signal automatically (combinational safety).
comb2 : process (all)
begin
if sel = '1' then y <= a; else y <= b; end if;
end process;For a combinational process, the list must be complete — every signal read in the body. For
a clocked process, the list contains only the clock and any asynchronous reset; the data
inputs are deliberately absent because they matter only at the edge. VHDL-2008's process(all)
fills the list automatically, eliminating omissions for combinational logic.
3. Production-quality RTL — the two correct patterns
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
-- combinational adder/compare: every read signal listed
cmp : process (a, b)
begin
ge <= '1' when unsigned(a) >= unsigned(b) else '0';
end process;
-- register with asynchronous reset: clk and rst only
ff : process (clk, rst)
begin
if rst = '1' then q <= (others => '0'); -- async reset reacts immediately → in the list
elsif rising_edge(clk) then q <= d; -- d sampled on the edge → NOT in the list
end if;
end process;What hardware does this become? cmp is a magnitude comparator (combinational), correct only
because both a and b are listed. ff is a flip-flop with asynchronous reset — clk and rst
in the list (both can trigger it), d absent (sampled at the edge). The list mirrors what actually
triggers the hardware.
4. Hardware interpretation — what triggers the logic
5. Simulation interpretation — the list decides what wakes the process
In simulation the list is literally the trigger set: the engine wakes the process only when a listed signal has an event. A signal the process reads but that is not listed will change without waking the process, so the output keeps a stale value — until some listed signal happens to wake it later. Synthesis, by contrast, builds the real gate, which reacts to that input regardless. That gap is the sim-versus-synthesis mismatch.
Incomplete list process(a): output ignores b's changes (the sim/synth mismatch)
8 cycles6. Debugging example — RTL passes, gate-level fails
Expected: RTL simulation and the synthesised netlist agree. Observed: a combinational output
behaves correctly in RTL simulation but wrong in gate-level simulation (or in hardware) — it reacts
to one input but not another. Root cause: the combinational process's sensitivity list omitted a
signal the body reads, so RTL sim never re-evaluated on that input's change, while the real gate
does. RTL "looked fine" only because the test happened to change a listed signal afterward. Fix:
list every read signal, or use process(all). Engineering takeaway: when RTL and gate-level
disagree on combinational logic, suspect an incomplete sensitivity list first — and adopt
process(all) to make the whole class of bug impossible.
-- WRONG: 'b' is read but not listed → RTL ignores b's changes; synthesis does not.
process (a)
begin
y <= a and b; -- missing 'b' → sim/synth mismatch
end process;
-- RIGHT: complete list (or VHDL-2008 process(all)).
process (a, b) begin y <= a and b; end process; -- or: process(all)7. Common mistakes & what to watch for
- Incomplete combinational sensitivity list. Any read signal missing → RTL sim diverges from
synthesis. List them all, or use
process(all). - Adding data signals to a clocked process's list. A clocked process lists only
clk(and asyncrst); listingddoes not change synthesis but signals confused intent and can add spurious sim wake-ups. - Forgetting the asynchronous reset in the list. An async reset must be in the list (it triggers the process immediately); omit it and the reset will not simulate correctly.
- Assuming the list affects synthesis. Synthesis infers logic from the body; the list only affects simulation — which is exactly why an incomplete one is dangerous (silent in synthesis, wrong in sim).
- Relying on
process(all)without enabling VHDL-2008. It needs the 2008 standard; otherwise list signals explicitly.
8. Engineering insight
The sensitivity list is a simulation-only construct with an outsized impact on correctness, because
it is the one place where simulation can silently disagree with the hardware it is supposed to
model. The discipline is simple and worth making automatic: combinational processes get every
read signal (or process(all)); clocked processes get only the clock and async reset. Adopting
process(all) for combinational logic eliminates the entire incomplete-list bug class and is the
modern default. Reading the list as "what triggers this hardware" keeps the model honest and your
gate-level results matching your RTL.
9. Summary
The sensitivity list is the set of signals whose change wakes a process. A combinational process must
list every signal it reads — an omission makes RTL simulation stale where real hardware reacts,
causing a sim-versus-synthesis mismatch. A clocked process lists only the clock and any asynchronous
reset. The list does not affect synthesis; VHDL-2008 process(all) auto-completes it for
combinational logic and is the safest default.
10. Learning continuity
You can now trigger a process correctly. The next lessons fill in its sequential body: How a
Process Executes details the run-to-suspend cycle and variable-versus-signal timing in depth, then
the if and case statements give the body its decision-making — the combinational and
control logic that processes are built to express.