0
0
Verilogprogramming~5 mins

Three-block FSM coding style in Verilog

Choose your learning style9 modes available
Introduction

The three-block FSM coding style helps you write clear and organized state machines. It separates the logic into three parts: state register, next state logic, and output logic.

When designing a digital controller that changes behavior based on inputs over time.
When you want your state machine to be easy to read and debug.
When you need to clearly separate state updates, decisions, and outputs.
When working on FPGA or ASIC designs that require reliable state machines.
Syntax
Verilog
always_ff @(posedge clk or posedge reset) begin
  if (reset) state <= IDLE;
  else state <= next_state;
end

always_comb begin
  case(state)
    IDLE: if (start) next_state = RUN;
          else next_state = IDLE;
    RUN:  if (stop) next_state = IDLE;
          else next_state = RUN;
    default: next_state = IDLE;
  endcase
end

always_comb begin
  case(state)
    IDLE: output_signal = 0;
    RUN:  output_signal = 1;
    default: output_signal = 0;
  endcase
end

The first block updates the current state on clock edges.

The second block decides the next state based on current state and inputs.

Examples
Define states using an enum for clarity and type safety.
Verilog
typedef enum logic [1:0] {IDLE, RUN, STOP} state_t;
state_t state, next_state;
State register block updates the current state on clock or reset.
Verilog
always_ff @(posedge clk or posedge reset) begin
  if (reset) state <= IDLE;
  else state <= next_state;
end
Next state logic block decides what the next state will be.
Verilog
always_comb begin
  case(state)
    IDLE: next_state = start ? RUN : IDLE;
    RUN: next_state = stop ? IDLE : RUN;
    default: next_state = IDLE;
  endcase
end
Output logic block sets outputs based on the current state.
Verilog
always_comb begin
  case(state)
    IDLE: output_signal = 0;
    RUN: output_signal = 1;
    default: output_signal = 0;
  endcase
end
Sample Program

This example shows a simple FSM with two states: IDLE and RUN. It starts running when start is high and stops when stop is high. The output running is 1 only in the RUN state.

Verilog
module fsm_three_block(
  input logic clk, reset, start, stop,
  output logic running
);

  typedef enum logic [1:0] {IDLE, RUN} state_t;
  state_t state, next_state;

  // State register block
  always_ff @(posedge clk or posedge reset) begin
    if (reset) state <= IDLE;
    else state <= next_state;
  end

  // Next state logic block
  always_comb begin
    case(state)
      IDLE: next_state = start ? RUN : IDLE;
      RUN: next_state = stop ? IDLE : RUN;
      default: next_state = IDLE;
    endcase
  end

  // Output logic block
  always_comb begin
    case(state)
      IDLE: running = 0;
      RUN: running = 1;
      default: running = 0;
    endcase
  end

endmodule
OutputSuccess
Important Notes

Use always_ff for sequential logic (state updates) and always_comb for combinational logic (next state and outputs).

Keep the three blocks separate to avoid mixing logic and make debugging easier.

Resetting the state ensures the FSM starts in a known state.

Summary

The three-block FSM style splits your state machine into state register, next state logic, and output logic.

This separation makes your code easier to read, maintain, and debug.

Use always_ff for state updates and always_comb for next state and output decisions.