An FSM is the standard way to express control: a finite set of states, transitions on inputs/clock, and outputs that depend on state (and maybe inputs).
Three-process style (recommended)
- State register —
always_ffupdatesstate_q - Next-state combo —
always_combcomputesstate_dfromstate_q+ inputs - Output combo (or registered outputs) — decode
state_q(+ inputs for Mealy)
This keeps timing and simulation clear, and matches how most textbooks and lint rules think.
When to use an FSM
- Protocols and handshakes (ready/valid bursts)
- Multi-cycle operations (load → compute → writeback)
- Mode sequencers (idle / run / done / error)
If the control is a single counter or a trivial flag, a full FSM may be overkill.
Topics in this section
- Moore & Mealy — where outputs come from
- State encoding — binary, one-hot, gray
See also
- Registers — datapath beside the FSM
- Synthesizable RTL