VHDL · Chapter 5.3 · Sequential Statements & Processes
How a Process Executes
This is the anchor for the whole module. Every sequential construct that follows, if, case, loops, variables, wait, and sequential signal assignment, is just statements inside a process, and to use any of them correctly you need one precise mental model of how a process actually executes. A process stays suspended until a trigger fires, then runs its body top to bottom in zero simulated time, updating variables immediately and scheduling signals one delta later. It suspends, and the scheduled updates take effect, waking whatever reads them. Get this model exact and the rest of the module becomes obvious, including the bugs, like stale signals and accidental latches, that all trace back to it.
Foundation22 min readVHDLProcessExecution ModelDelta CycleSchedulerVariablesSignals
1. Engineering intuition — a triggered, run-to-completion engine
A process is a small engine with three states: asleep, running, asleep again. It sleeps
until a trigger (a sensitivity-list signal changing, or a wait condition) fires; it then runs its
body from top to bottom all at once, in zero simulated time; then it goes back to sleep. Nothing
in the body "takes time" by itself — time only passes between wake-ups. The two things that make
this subtle are: (1) variables change the instant you assign them, but signals do not — they
are scheduled and only update after the process suspends; and (2) the ordered, top-to-bottom
reading is a description, not a sequence of clock ticks. Hold those two ideas and every sequential
statement in this module behaves predictably.
2. Historical context — VHDL is an event-driven simulator
VHDL began (in the 1980s, for the US DoD) as a language to document and simulate digital systems, not primarily to synthesise them. That heritage is why the execution model is an event-driven discrete-event simulation: time advances from event to event, signals carry values that change at scheduled times, and processes react to those changes. Synthesis came later and layered a "this subset describes hardware" interpretation on top. So when a process's behaviour seems surprising, remember it is first a simulator obeying event-driven rules — and the synthesisable subset is the part of those rules that maps cleanly to gates and flip-flops.
3. The execution model, formally — the suspend/resume cycle
A process repeats one cycle for its entire life:
4. The simulator interpretation — the scheduler and delta cycles
Zoom out from one process to the whole simulation. The simulator runs a loop: at the current time it updates the signals scheduled for now, resumes every process sensitive to those changes, lets each run to suspension (scheduling new signal updates one delta ahead), and repeats. When a pass produces no further signal changes at this time, time advances to the next event. The infinitesimal, ordered steps within one instant are delta cycles (lesson 3.4).
5. Variables vs signals during execution — the crux
The single most important consequence of the model: inside a process, a variable assignment
(:=) takes effect immediately, so a later line sees the new value; a signal assignment (<=)
is scheduled, so a later line in the same wake-up still reads the old value, and the update
appears only after the process suspends.
Same computation, variable vs signal: the variable result is one cycle earlier
8 cycles6. Hardware interpretation — settling vs capture
The same execution model produces two kinds of hardware depending on how the body is written:
7. Synthesizer interpretation — order is description, not time
Synthesis reads the process body as a specification of logic, not a sequence of timed steps. The top-to-bottom order and last-assignment-wins semantics (lesson 5.9) define what the final value of each signal is as a function of the inputs; the synthesiser then builds combinational logic (or, at a clock edge, registers) that computes those values in parallel. So "sequential" in synthesis means "evaluate the body's data flow to a result," collapsed into a single combinational cone or a register update — no stepping exists in the gates.
-- The ordered body specifies the FINAL value of y; synthesis builds it as parallel logic.
process (sel, a, b)
begin
y <= a; -- default
if sel = '1' then
y <= b; -- override (last assignment wins)
end if;
end process;
-- Synthesises to: y = (sel = '1') ? b : a — a single 2:1 mux, evaluated in parallel.8. Production RTL — the canonical process patterns
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;
-- (A) Combinational process: complete sensitivity, default-then-override, no latch.
comb : process (all) -- VHDL-2008: every read signal
begin
y <= (others => '0'); -- default assignment covers all paths
if sel = "01" then y <= a;
elsif sel = "10" then y <= b;
end if; -- no else needed: default already drives y
end process;
-- (B) Clocked process with synchronous reset: registers.
sync : process (clk)
begin
if rising_edge(clk) then
if rst = '1' then count <= (others => '0');
else count <= count + 1; -- numeric_std arithmetic on unsigned
end if;
end if;
end process;
-- (C) Local computation with a variable, registered result (immediate intermediate).
acc : process (clk)
variable sum_v : unsigned(7 downto 0);
begin
if rising_edge(clk) then
sum_v := unsigned(a) + unsigned(b); -- immediate
result <= std_logic_vector(sum_v + 1); -- uses THIS cycle's sum_v
end if;
end process;What hardware does this become? (A) a multiplexer feeding y with a guaranteed default (latch-
free); (B) an 8-bit counter register with synchronous reset; (C) an adder whose result is registered,
with sum_v realised as combinational logic feeding the final register — the variable is intermediate
wiring, not a separate storage element.
9. Debugging examples — every classic bug traces to this model
(i) The stale-signal "extra cycle." Expected: a two-step computation completes in one cycle. Observed: the result is a cycle late. Root cause: an intermediate signal was read right after being assigned, returning its old value (Section 5). Fix: use a variable for the intermediate. Takeaway: signals update after suspend; variables update immediately.
(ii) The accidental latch. Expected: combinational logic. Observed: synthesis infers a latch. Root cause: a path through the process leaves an output unassigned, so it must "hold" — memory (lesson 6.3). Fix: a default assignment at the top so every path drives the output. Takeaway: the model holds the old value when you do not assign; defaults prevent that.
(iii) The hung simulation. Expected: the process runs. Observed: the simulator never
advances. Root cause: no sensitivity list and no wait — the process never suspends, looping in
zero time (lesson 5.1). Fix: add a trigger. Takeaway: a process must be able to suspend.
-- BUG: intermediate SIGNAL read after write → old value → extra cycle.
process (clk) begin
if rising_edge(clk) then
tmp_s <= unsigned(a) + unsigned(b); -- scheduled
y <= std_logic_vector(tmp_s + 1); -- reads OLD tmp_s
end if;
end process;
-- FIX: VARIABLE intermediate → immediate, same-cycle result.
process (clk)
variable tmp_v : unsigned(7 downto 0);
begin
if rising_edge(clk) then
tmp_v := unsigned(a) + unsigned(b); -- immediate
y <= std_logic_vector(tmp_v + 1); -- uses NEW tmp_v
end if;
end process;10. Engineering tradeoffs
- Variables vs signals for intermediates. Variables give immediate, same-cycle computation and fewer registers; signals are visible across processes and to waveforms but cost a delta of latency per stage. Use variables for local math, signals for inter-process communication and observable state.
- One big process vs several small ones. A large process can express complex ordered behaviour but is harder to read and review; several focused processes (one per register bank or function) are clearer and compose through signals. Prefer small, single-purpose processes.
- Combinational process vs concurrent assignment. A process scales to multi-step logic and
casedecode; a concurrentwhen/else/with/selectis terser for simple selection. Choose by complexity. - Sensitivity list discipline.
process(all)removes the incomplete-list bug class for combinational logic at the cost of requiring VHDL-2008; explicit lists are portable but error-prone.
11. Interview framing
Interviewers probe this model because it separates engineers who understand VHDL from those who pattern-match syntax. Expect to explain: why a signal read after assignment gives the old value; why a variable does not; what a delta cycle is; why statement order in a process does not mean clock steps; and how the same process becomes combinational or registered. A crisp answer references the suspend/run/suspend cycle and immediate-vs-scheduled updates — exactly this page.
Q&A
- Q: Inside a process, you assign
s <= x;then readson the next line. What do you get? A: The old value ofs. Signal assignments are scheduled;supdates one delta after the process suspends, so the same wake-up still sees the previous value. - Q: How would you get the new value immediately? A: Use a variable (
v := x;), which updates in place, then readv. - Q: Does statement order in a process imply timing? A: No. The body runs in zero simulated time; order defines the final value of each signal (last-assignment-wins), which synthesis builds as parallel logic. Time passes only between wake-ups.
- Q: What is a delta cycle and why does it exist? A: An infinitesimal, ordered step within one simulation time so zero-delay logic settles deterministically; scheduled signal updates are applied on the next delta.
- Q: Why does an unassigned output in a combinational process infer a latch? A: The model holds a signal's value when no driver updates it; an unassigned path means "keep the old value" — memory. A default assignment fixes it.
12. Practice exercises
- Trace it. For a clocked process with
tmp_s <= a; y <= tmp_s;versustmp_v := a; y <= tmp_v;, draw the waveforms ofyfor a changingaand state the cycle difference. - Latch hunt. Write a combinational
caseprocess that assignsyin only three of four branches; identify the inferred latch and fix it two ways (default assignment; full coverage). - Delta count. Given
b <= a; c <= b;as two concurrent assignments, how many delta cycles for a change onato reachc? Now put both in one process with variables — what changes? - Reset styles. Convert the counter in Section 8(B) to an asynchronous reset and adjust the sensitivity list correctly.
- Refactor. Take a 40-line single process mixing combinational and clocked logic and split it into a combinational process and a clocked process communicating by signal; verify identical behaviour.
13. Key takeaways
- A process is a suspend → run-to-completion (zero time) → suspend engine, coordinated by an event-driven scheduler using delta cycles.
- Variables update immediately; signals are scheduled and update one delta after the process suspends — the source of stale-signal bugs and the reason variables are used for intermediates.
- Order in the body is description, not time: it defines each signal's final value (last-assignment-wins), which synthesis builds as parallel logic — combinational settling without a clock guard, registered capture with one.
- The classic bugs — extra-cycle latency, inferred latches, hung simulations — are all direct consequences of this model, and each fix follows from it.
- This is the reference model for the rest of Module 5:
if,case, loops, variables,wait, and sequential signal assignment are all just statements executing inside this cycle.
14. Summary & next step
You now have the complete execution model: how a process wakes, runs its body in zero time with
variables immediate and signals scheduled, suspends, and lets the scheduler apply updates over delta
cycles — and how that single model yields combinational or registered hardware. With this anchor in
place, the remaining sequential statements are straightforward applications of it. The module
continues with the body's decision constructs — the if statement and the case statement —
then loops, variables in processes, the wait statement, and sequential signal
assignment with last-assignment-wins, each building on the model established here.