VHDL · Chapter 9.2 · Finite State Machines
Moore vs Mealy Machines
State machines come in two flavours, distinguished by where their outputs come from. In a Moore machine, outputs depend only on the current state, so they change only when the state changes and are stable and glitch-free, but they respond one cycle after the input that caused the transition. In a Mealy machine, outputs depend on both the state and the inputs, so they respond immediately within the same cycle, but because they are combinational from the inputs they can glitch and may need registering. This is a real timing trade-off between latency, responsiveness, and glitch behaviour. This lesson shows both styles, the timing difference on a waveform, and how to choose, including registering a Mealy output to get fast logic with a clean edge.
Foundation14 min readVHDLMooreMealyFSMOutputsTiming
1. Engineering intuition — outputs from the state, or from the state and inputs
The only structural difference between Moore and Mealy is what feeds the output logic. Moore outputs read only the state: the machine is in a state, and that state determines the outputs — so outputs are as stable as the state (they change once per clock, when the state does). Mealy outputs read the state and the current inputs: an input can change the output immediately, within the same cycle, without waiting for the state to advance. Moore trades a cycle of latency for stability; Mealy trades stability for immediacy. Most real controllers use a mix, choosing per output.
2. Formal explanation — the two output forms
library ieee; use ieee.std_logic_1164.all;
-- MOORE output: a function of STATE only → changes when state changes; glitch-free, +1 cycle latency.
ack_moore <= '1' when state = SEND else '0';
-- MEALY output: a function of STATE and INPUTS → responds to inputs immediately; can glitch.
out_mealy : process (all)
begin
grant <= '0'; -- default (latch-free)
case state is
when IDLE => if req = '1' then grant <= '1'; end if; -- grant follows req in IDLE — same cycle
when BUSY => null;
end case;
end process;A Moore output is derived from the state alone, so it is steady between transitions. A Mealy output is derived from the state and the inputs, so within a state it can change as the inputs change. Both are combinational output logic (Module 6 patterns — default every output to avoid latches); the difference is only whether inputs are in the expression.
3. Production RTL — the same controller, two output styles
library ieee; use ieee.std_logic_1164.all;
-- Moore: 'busy' depends only on state (stable for the whole BUSY state).
busy <= '1' when state = BUSY else '0';
-- Mealy: 'start_pulse' asserts the moment 'go' arrives in IDLE (same cycle), one-cycle pulse.
sp : process (all)
begin
start_pulse <= '0';
if state = IDLE and go = '1' then start_pulse <= '1'; end if; -- responds immediately to go
end process;
-- Registered Mealy (best of both): clean, glitch-free edge, but decided from state+input.
process (clk) begin
if rising_edge(clk) then
start_pulse_r <= '1' when (state = IDLE and go = '1') else '0'; -- registered → no glitch
end if;
end process;What hardware does this become? busy is combinational logic on the state register's outputs (Moore) —
stable while in BUSY. start_pulse is combinational logic on the state and go (Mealy) — it asserts the
instant go arrives, before the state advances. The registered version adds a flip-flop so the Mealy decision
drives a clean, glitch-free output one cycle later — a common compromise.
4. Hardware interpretation — the output path
5. Simulation interpretation — the one-cycle difference
Same input event: Mealy output responds this cycle; Moore responds next cycle
8 cycles6. Debugging example — the Mealy glitch and the Moore latency surprise
Expected: an output that asserts at the right time and is clean. Observed: either a Mealy output that glitches when its input glitches (a spurious pulse downstream), or a Moore output that is one cycle later than the spec expected. Root cause: the Mealy output is combinational from the inputs, so input glitches pass through; the Moore output only changes when the state changes, adding the inherent one-cycle latency. Fix: if a clean edge matters (e.g. it drives another clock domain or a critical strobe), register the Mealy output (or use Moore); if same-cycle response matters, use Mealy and ensure the input is glitch-free. Engineering takeaway: Mealy buys a cycle of response at the cost of glitch exposure; Moore buys stability at the cost of a cycle — register a Mealy output when you need both speed-of-decision and a clean edge.
-- Decide from state+input (Mealy), but register for a clean, glitch-free edge.
process (clk) begin
if rising_edge(clk) then
grant <= '1' when (state = ARB and req = '1') else '0'; -- registered Mealy
end if;
end process;7. Common mistakes & what to watch for
- Using a raw Mealy output where a clean edge is needed. It can glitch with the input; register it or use Moore.
- Forgetting Moore's one-cycle latency. A Moore output reflects an input only after the state advances; account for that cycle.
- Latches in the output logic. Default every output (Moore or Mealy) at the top of the combinational logic (Module 6).
- Driving another clock domain with a raw Mealy output. Treat it as a CDC source — register and synchronise.
- Choosing one style dogmatically. Pick per output: Moore for stable status/handshake levels, Mealy (often registered) for fast responses.
8. Engineering insight & continuity
Moore and Mealy are not competing machines but two output disciplines you mix within one FSM: read the state alone for stable, glitch-free outputs that lag a cycle, or read the state and inputs for immediate outputs that can glitch — and register a Mealy output when you want fast decision plus a clean edge. The choice is a latency- versus-stability trade made per output. With the output styles understood, the next lesson addresses how the states themselves are represented in hardware — State Encoding (binary, one-hot, gray and their area/speed/power trade-offs) — before the coding-style lessons organise the three FSM blocks into clean, reviewable processes.