Skip to content

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

sensitivity_rules.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- 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

correct_sensitivity.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
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

combinational process lists all inputs; clocked process lists only clk and resetmust be completeclock/reset onlycombinational processreacts to all inputslist: every readsignala, b, sel, … (orprocess(all))clocked processreacts only at the edgelist: clk (+ asyncrst)data inputs excluded12
The sensitivity list should mirror what triggers the hardware. A combinational block reacts to ALL its inputs, so a combinational process must list every signal it reads. A flip-flop reacts only to its clock edge (and an asynchronous reset), so a clocked process lists only clk and rst, never the data inputs. The list itself is not synthesised — synthesis infers logic from the body — but an incomplete combinational list makes RTL simulation fail to react where the real hardware would.

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.

engine wakes process only on listed-signal events; unlisted reads cause stale outputsSignal changesis it in the list?Listed → processwakesbody re-runs, outputupdatesNot listed → no wakeoutput stays stale in simSynthesis reactsanywayreal gate has no blind spot→ mismatch12
How the sensitivity list gates simulation. The engine wakes the process only on events of LISTED signals; it then runs the body, reading whatever the current values are. If the body reads a signal that is not listed, changes to that signal do not wake the process, so the output goes stale in simulation — even though the synthesised gate reacts to it. A complete list (or process(all)) keeps simulation faithful to the hardware.

Incomplete list process(a): output ignores b's changes (the sim/synth mismatch)

8 cycles
Incomplete list process(a): output ignores b's changes (the sim/synth mismatch)a changes → process(a) wakes; a and b = 1 and 0 = 0a changes → process(a)…b changes to 1, but process(a) does NOT wake → y_bug stays stale at 0b changes to 1, but pr…y_ok (complete list / synth) correctly becomes 1y_ok (complete list / …a01111111b00011001y_bug00000000y_ok00011001t0t1t2t3t4t5t6t7
With 'process(a)' computing y <= a and b, a change on b does not wake the process, so y_bug stays stale (here stuck at 0) even though a and b is now 1. The correctly-sensitised process — y_ok, equivalently the synthesised gate — reacts to b and gives the right value. This divergence is the classic incomplete-sensitivity sim-versus-synthesis bug.

6. 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.

incomplete_then_fixed.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- 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 async rst); listing d does 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.