Altifigence Academy

28 / 37 · Concept

State machines: separating state, transitions and outputs

Build an FSM from a specification table and compare Moore/Mealy outputs, illegal states and request policies.

State summarizes only the history that matters

Define stored state when present inputs alone do not determine outputs. Instead of retaining all input history, distinguish only the past differences needed to determine future behavior.

Sk+1=F(Sk,Xk)S_{k+1}=F(S_k,X_k)

Consider a controller for starting and completing work. IDLE waits for requests, BUSY processes work, and DONE indicates completion for one cycle.

Current stateConditionNext statebusydone
IDLEstart=0IDLE00
IDLEstart=1BUSY00
BUSYwork_done=0BUSY10
BUSYwork_done=1DONE10
DONEAlwaysIDLE01

busy and done are outputs of the current state. For example, after the edge that observes completion in BUSY, state becomes DONE and done becomes 1. These are Moore outputs.

Each column below records a rising edgeRising edge The instant at which the clock changes from 0 to 1. Distinguish it from a level, which refers to the entire interval during which CLK=1. Learn more. Inputs are pre-edge; states labeled “after” are post-update. Alignment shows sample order, not physical propagation delayPropagation delay The time from an input change until the output settles to the correct value. Logical equivalence and timing behavior are separate properties. Learn more. Starting in IDLE, the edge accepting work_done leads to DONE and done=1. DONE always leads to IDLE, regardless of start.

Moore outputs follow the current state
View waveform data
Wave data: each character is one interval; a dot holds the previous state; p is a clock cycle.
SignalWaveBus values
edge2345E0 → E1 → E2 → E3
start10.1
work_done0.10
state after2.34BUSY → DONE → IDLE
busy after1.0.
done after0.10

RTL separating transitions from storage

SystemVerilog
typedef enum logic [1:0] {IDLE, BUSY, DONE} state_t;
state_t state, next_state;
always_comb begin
  next_state = state;
  case (state)
    IDLE: if (start) next_state = BUSY;
    BUSY: if (work_done) next_state = DONE;
    DONE: next_state = IDLE;
    default: next_state = IDLE;
  endcase
end
always_ff @(posedge clk)
  if (rst) state <= IDLE;
  else state <= next_state;
assign busy = (state == BUSY);
assign done = (state == DONE);

This SystemVerilog example illustrates the control structure. The connected worker's work_done generation and input synchronization must be implemented separately.

Questions easily omitted from a specification

This circuit ignores start in BUSY and DONE. To accept a new request at completion, revise the transition table first. A Mealy output uses both state and current input and can respond quickly, but its combinational timing and glitches need review. Choosing binary versus one-hotOne-hot A representation with exactly one bit set to 1. A condition that also permits all zeros is called one-hot-or-zero. Learn more state encoding is independent of choosing Moore versus Mealy outputs.

Try it yourself

A one-cycle start=1 arrives in DONE. Does this FSM immediately start new work? What must change to allow consecutive jobs?

Read the explanation

No: the table specifies DONE→IDLE, so that request is not accepted. Change DONE to transition to BUSY on start, or design a protocol that retains requests. Verify done pulse width and request-acceptance timing against the revised specification.

Your choice applies to this browser. Change it any time using the footer.