Skip to content

VHDL · Chapter 9.1 · Finite State Machines

FSM Fundamentals

Almost every controller is a finite state machine: a design that is always in one of a finite set of named states, moves between them based on its inputs, and drives its outputs from where it currently is. An FSM is built from three cooperating parts, a clocked state register that resets to a known start, next-state logic that computes where to go from the current state and inputs, and output logic that produces the outputs. This module opener establishes that structure, introduces states as an enumerated type, and previews the Moore versus Mealy output distinction and the standard coding styles. It frames the FSM as the organising pattern that ties together all the clocked state and reset you have learned so far.

Foundation16 min readVHDLFSMState MachineMooreMealyController

1. Engineering intuition — a controller that is always somewhere

A finite state machine formalises a simple idea: the design is always in exactly one of a handful of named situations — idle, waiting, transferring, done — and what it does next depends on which situation it is in and what its inputs say. That is how humans describe controllers ("when idle, if start arrives, begin transferring; when transferring, if the last byte goes, finish"), and an FSM turns that description directly into hardware. The power is that arbitrarily complex sequential behaviour reduces to a finite list of states and the transitions between them — easy to specify, draw, review, and verify.

2. Formal explanation — the three parts of an FSM

fsm_structure.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all;
-- States as an ENUMERATED type (lesson 2.7) — named, type-safe, tool-encoded.
type state_t is (IDLE, RUN, DONE);
signal state, next_state : state_t;
 
-- (1) STATE REGISTER: clocked, reset to a known start (Module 8).
state_reg : process (clk, rst_n)
begin
  if rst_n = '0' then        state <= IDLE;
  elsif rising_edge(clk) then state <= next_state;
  end if;
end process;
 
-- (2) NEXT-STATE LOGIC: combinational; where to go from (state, inputs).
next_logic : process (all)
begin
  next_state <= state;                       -- default: stay (latch-free)
  case state is
    when IDLE => if go  = '1' then next_state <= RUN;  end if;
    when RUN  => if fin = '1' then next_state <= DONE; end if;
    when DONE =>                    next_state <= IDLE;
  end case;
end process;
 
-- (3) OUTPUT LOGIC: combinational; outputs from the state (Moore) here.
busy <= '1' when state = RUN else '0';
done <= '1' when state = DONE else '0';

An FSM has three cooperating parts: a state register (clocked, reset), next-state logic (combinational case on the current state and inputs, defaulting to "stay" to avoid latches), and output logic (combinational). States are an enumerated type so they are named and the tool chooses the encoding (lesson 9.3). This three-block view is the foundation for every coding style and machine type in the module.

3. Production RTL — a complete small FSM

handshake_fsm.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
library ieee; use ieee.std_logic_1164.all;
-- A simple request/ack handshake controller.
type st_t is (IDLE, REQ, WAIT_ACK, DONE);
signal st, st_n : st_t;
 
reg : process (clk, rst_n)
begin
  if rst_n = '0' then        st <= IDLE;
  elsif rising_edge(clk) then st <= st_n;
  end if;
end process;
 
nxt : process (all)
begin
  st_n <= st;                                -- default: hold
  case st is
    when IDLE     => if start = '1' then st_n <= REQ;      end if;
    when REQ      =>                     st_n <= WAIT_ACK;
    when WAIT_ACK => if ack = '1'   then st_n <= DONE;     end if;
    when DONE     =>                     st_n <= IDLE;
  end case;
end process;
 
req  <= '1' when st = REQ or st = WAIT_ACK else '0';   -- Moore outputs
busy <= '0' when st = IDLE else '1';

What hardware does this become? A state register (two flip-flops for four states, or more with one-hot), combinational next-state logic (a case decode), and combinational output logic. It asserts req while requesting/waiting and de-asserts in idle — a clean handshake controller. This state-register + next-state + output structure is exactly the same as the generic FSM above, just with the states of this protocol.

4. Hardware interpretation — register, next-state, output

FSM as state register fed by next-state logic, with output logicnext statecurrent state (feedback)currentstate…inputsgo, ack, ...next-state logiccombinational casestate registerclocked + resetoutput logiccombinationaloutputsbusy, req, done12
The three-block structure of every FSM. The state register holds the current state (clocked, reset to a known start). Next-state logic is combinational: it reads the current state and the inputs and computes the next state, which the register captures on the clock edge. Output logic is combinational: it derives the outputs from the state (Moore) or from the state and inputs (Mealy). The feedback from the state register back into the next-state logic is controlled feedback through a register — sequential, not a combinational loop.

5. Simulation interpretation — stepping through states

The handshake FSM stepping through its states on the clock

8 cycles
The handshake FSM stepping through its states on the clockstart seen → IDLE moves to REQ; req assertsstart seen → IDLE move…ack seen → WAIT_ACK moves to DONE; req de-assertsack seen → WAIT_ACK mo…clkstart01100000ack00001100stIDLEIDLEREQWAIT_ACKWAIT_ACKDONEIDLEIDLEreq00111000t0t1t2t3t4t5t6t7
The FSM advances one state per clock based on its inputs: IDLE waits for start, REQ/WAIT_ACK drive the request and wait for ack, DONE returns to IDLE. The Moore output req depends only on the state (high while requesting/waiting). Each transition is the state register capturing the next-state logic's result on the clock edge.

6. Debugging example — the FSM stuck or starting wrong

Expected: a controller that advances correctly and starts in idle. Observed: it never leaves a state, or powers up in a wrong/illegal state, or an output latches. Root cause: stuck usually means a transition condition that never becomes true (or a missing transition); a wrong start means the state register was not reset to a known state; a latched output means the next-state or output logic left a signal unassigned on some path. Fix: reset the state register to a defined start (Module 8), default next_state <= state and every output at the top of the combinational logic (Module 6), and check each state has a reachable exit. Engineering takeaway: most FSM bugs are a missing reset, a missing default (latch), or a missing/unreachable transition — the three-block structure makes each easy to locate.

fsm_defaults_and_reset.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- Reset to a known state; default next_state to 'stay' so every path is covered (latch-free).
if rst_n = '0' then state <= IDLE; elsif rising_edge(clk) then state <= next_state; end if;
-- next_state logic:  next_state <= state;  case state is ... end case;   -- default = hold

7. Common mistakes & what to watch for

  • Not resetting the state register. The FSM can power up in an illegal state; reset it to a defined start.
  • Missing the default in next-state/output logic. Default next_state <= state and every output to avoid latches (Module 6).
  • Unreachable or dead-end states. Ensure every state has a reachable entry and a way out.
  • Encoding the state by hand as bits. Use an enumerated type and let the tool encode (lesson 9.3); manual bit patterns are error-prone.
  • Confusing Moore and Mealy outputs. Decide whether an output depends only on the state (Moore) or also on inputs (Mealy) — the next lesson covers the difference and its timing.

8. Engineering insight & continuity

The FSM is where everything in the foundation comes together: enumerated states (Module 2), combinational next-state and output logic (Module 6), a clocked, reset state register (Modules 7–8), all organised into the controller pattern. Its three-block structure — register, next-state, output — is the mental model for the whole module and for real controllers in industry. With the fundamentals set, the next lessons make the choices precise: Moore vs Mealy (where outputs come from and the timing difference), State Encoding (binary, one-hot, gray and their trade-offs), and the one-, two-, and three-process coding styles, before output logic, safe states, and the common bugs that complete a robust FSM methodology.