Finite State Machine (FSM) using Verilog
Introduction¶
Finite State Machines (FSMs) are at the heart of digital control systems. They describe sequential logic where outputs and next states depend on current inputs and previous states. FSMs are widely used in communication protocols, control units, and embedded systems.
This article provides a detailed guide to modeling FSMs in Verilog — from fundamentals and types to step-by-step examples and best practices.
What is a Finite State Machine?¶
An FSM is a mathematical model of computation that transitions between a finite number of states based on input signals. Each state represents a specific mode or condition of operation.
FSMs consist of:
- States – Distinct modes of operation.
 - Inputs – Control signals affecting state transitions.
 - Outputs – Generated based on current state and/or inputs.
 - State Transition Logic – Defines movement from one state to another.
 
Types of FSMs¶
There are two main categories of FSMs in Verilog design:
Moore Machine¶
- Outputs depend only on the current state.
 - More stable output, less prone to glitches.
 - Slightly more latency as outputs update only after a state transition.
 
Mealy Machine¶
- Outputs depend on both current state and inputs.
 - Responds faster since outputs can change immediately with inputs.
 
3. FSM Design Steps¶
Designing an FSM in Verilog typically follows these steps:
- Identify states and give them meaningful names.
 - Assign binary codes to each state (manually or automatically by synthesis tools).
 - Define state transitions using input conditions.
 - Decide on output logic (Moore or Mealy type).
 - Write Verilog code using 
alwaysblocks. - Test using a testbench.
 
4. FSM Structure in Verilog¶
A synthesizable FSM usually has three main blocks:
- State register (sequential logic) – Stores the current state.
 - Next-state logic (combinational) – Determines the next state.
 - Output logic (combinational) – Generates outputs based on state or inputs.
 
module fsm_template (input clk, reset, input [1:0] in, output reg [1:0] out);
  // State encoding
  typedef enum reg [1:0] {S0, S1, S2, S3} state_t;
  state_t state, next_state;
  // State register
  always @(posedge clk or posedge reset) begin
    if (reset)
      state <= S0;
    else
      state <= next_state;
  end
  // Next state logic
  always @(*) begin
    case (state)
      S0: next_state = (in == 2'b00) ? S1 : S2;
      S1: next_state = (in == 2'b01) ? S3 : S0;
      S2: next_state = S3;
      S3: next_state = S0;
      default: next_state = S0;
    endcase
  end
  // Output logic (Moore type)
  always @(*) begin
    case (state)
      S0: out = 2'b00;
      S1: out = 2'b01;
      S2: out = 2'b10;
      S3: out = 2'b11;
      default: out = 2'b00;
    endcase
  end
endmodule
Moore FSM Example – Sequence Detector¶
Let’s design a 101 sequence detector that outputs 1 when the input sequence 101 is detected.
State Diagram¶
S0 → S1 → S2 → S3
S0: Initial state (no valid bits yet) - S1: Detected 1 - S2: Detected 10 - S3: Detected 101 → Output 1 Verilog Code¶
module seq_detector_101 (input clk, reset, in, output reg out);
  typedef enum reg [1:0] {S0, S1, S2, S3} state_t;
  state_t state, next_state;
  // Sequential block
  always @(posedge clk or posedge reset) begin
    if (reset)
      state <= S0;
    else
      state <= next_state;
  end
  // Next state logic
  always @(*) begin
    case (state)
      S0: next_state = in ? S1 : S0;
      S1: next_state = in ? S1 : S2;
      S2: next_state = in ? S3 : S0;
      S3: next_state = in ? S1 : S2;
      default: next_state = S0;
    endcase
  end
  // Output logic (Moore type)
  always @(*) begin
    case (state)
      S3: out = 1;
      default: out = 0;
    endcase
  end
endmodule
Testbench Example¶
module tb_seq_detector_101;
  reg clk, reset, in;
  wire out;
  seq_detector_101 uut (.clk(clk), .reset(reset), .in(in), .out(out));
  initial begin
    clk = 0; forever #5 clk = ~clk; // clock generation
  end
  initial begin
    reset = 1; in = 0;
    #10 reset = 0;
    #10 in = 1; #10 in = 0; #10 in = 1; #10 in = 1; #10 in = 0; #10 in = 1;
    #50 $finish;
  end
  initial begin
    $monitor("Time=%0t, in=%b, out=%b, state=%0d", $time, in, out, uut.state);
  end
endmodule
This testbench drives input sequences and observes the FSM’s output transitions.
Mealy FSM Example – 101 Detector (Faster Output)¶
module seq_detector_101_mealy (input clk, reset, in, output reg out);
  typedef enum reg [1:0] {S0, S1, S2} state_t;
  state_t state, next_state;
  // Sequential block
  always @(posedge clk or posedge reset) begin
    if (reset)
      state <= S0;
    else
      state <= next_state;
  end
  // Next state and output logic (Mealy)
  always @(*) begin
    case (state)
      S0: begin
        next_state = in ? S1 : S0;
        out = 0;
      end
      S1: begin
        next_state = in ? S1 : S2;
        out = 0;
      end
      S2: begin
        next_state = in ? S1 : S0;
        out = in ? 1 : 0; // Output 1 when sequence 101 detected
      end
      default: begin
        next_state = S0;
        out = 0;
      end
    endcase
  end
endmodule
Synthesis Considerations¶
- Synchronous Reset – Prefer synchronous reset for FPGA-based designs.
 - Non-blocking assignments (
<=) – Use for sequentialalways@(posedge xyz)blocks. - Blocking assignments (
=) – Use in combinationalalways@(*)blocks. - Enumerated types – Improve code readability and synthesis compatibility.
 - Avoid latches – Ensure all state transitions are fully defined.
 
FSM State Encoding Styles¶
- Binary encoding – Compact representation using minimal bits.
 - One-hot encoding – Each state represented by a single high bit. Fast and synthesis-friendly.
 - Gray encoding – Only one bit changes between transitions; used for reducing glitches.
 
Example: One-hot Encoding¶
parameter S0=4'b0001, S1=4'b0010, S2=4'b0100, S3=4'b1000;
Best Practices for FSM Design¶
- Use meaningful state names (avoid numeric literals).
 - Separate sequential, next-state, and output logic.
 - Include default cases in 
casestatements. - Use 
typedef enumfor readability. - Initialize FSM properly during reset.
 - Simulate thoroughly before synthesis.
 - Document state diagrams and transitions clearly.
 
Advantages and Limitations¶
Advantages¶
- Well-structured representation of control logic.
 - Easy to simulate and debug.
 - Synthesis-friendly for digital designs.
 
Limitations¶
- Becomes complex for very large systems.
 - Requires careful encoding to optimize area and timing.
 
Comparison of Moore vs. Mealy FSMs¶
| Feature | Moore | Mealy | 
|---|---|---|
| Output Depends On | Current State | Current State + Input | 
| Response Speed | One Clock Cycle Delay | Immediate | 
| Complexity | Simpler | Slightly Complex | 
| Glitch Probability | Lower | Higher | 
| Use Case | Stable control outputs | Fast response systems | 
Summary¶
FSMs form the foundation of sequential circuit design. By dividing functionality into states and transitions, designers can create predictable, modular, and testable control systems.
- Moore FSMs: Output depends only on current state.
 - Mealy FSMs: Output depends on both state and input.
 - FSMs are modeled using three 
alwaysblocks — for state register, next-state logic, and output logic.