0
0
VerilogHow-ToBeginner · 4 min read

How to Write One Hot Encoding FSM in Verilog

To write a one hot encoding FSM in Verilog, define each state as a separate bit in a register so only one bit is high at a time. Use a case statement to transition between states by setting the corresponding bit high, ensuring only one state is active.
📐

Syntax

A one hot FSM uses a register where each bit represents a unique state. Only one bit is set to 1 at any time, indicating the current state.

The basic syntax includes:

  • reg [N-1:0] state; to hold the state bits.
  • parameter STATE_NAME = 1 << n; to define each state as a single bit.
  • A case statement inside an always @(posedge clk) block to update the state.
verilog
parameter IDLE = 3'b001;
parameter STATE1 = 3'b010;
parameter STATE2 = 3'b100;

reg [2:0] state;

always @(posedge clk or posedge reset) begin
  if (reset)
    state <= IDLE;
  else begin
    case(state)
      IDLE: state <= STATE1;
      STATE1: state <= STATE2;
      STATE2: state <= IDLE;
      default: state <= IDLE;
    endcase
  end
end
💻

Example

This example shows a simple three-state one hot FSM cycling through states IDLE, STATE1, and STATE2 on each clock cycle. The state register uses one hot encoding where only one bit is high at a time.

verilog
module one_hot_fsm(
  input wire clk,
  input wire reset,
  output reg [2:0] state
);

  parameter IDLE = 3'b001;
  parameter STATE1 = 3'b010;
  parameter STATE2 = 3'b100;

  always @(posedge clk or posedge reset) begin
    if (reset)
      state <= IDLE;
    else begin
      case(state)
        IDLE: state <= STATE1;
        STATE1: state <= STATE2;
        STATE2: state <= IDLE;
        default: state <= IDLE;
      endcase
    end
  end

endmodule
Output
At reset: state = 3'b001 (IDLE) Next clock: state = 3'b010 (STATE1) Next clock: state = 3'b100 (STATE2) Next clock: state = 3'b001 (IDLE) ... and repeats
⚠️

Common Pitfalls

Common mistakes when writing one hot FSMs include:

  • Setting multiple bits high at once, breaking one hot encoding.
  • Not defining states as powers of two (one bit set).
  • Forgetting to handle the default case in the case statement, which can cause latches or unknown states.
  • Not resetting the state register properly.

Always ensure only one bit is set in the state register and transitions are clearly defined.

verilog
/* Wrong: multiple bits set */
parameter IDLE = 3'b001;
parameter STATE1 = 3'b011; // Incorrect, two bits set

/* Correct: one bit set */
parameter STATE1 = 3'b010;

/* Wrong: no default case */
always @(posedge clk) begin
  case(state)
    IDLE: state <= STATE1;
    STATE1: state <= IDLE;
  endcase
end

/* Correct: with default */
always @(posedge clk) begin
  case(state)
    IDLE: state <= STATE1;
    STATE1: state <= IDLE;
    default: state <= IDLE;
  endcase
end
📊

Quick Reference

ConceptDescription
State RegisterUse a reg with one bit per state (e.g., reg [2:0] state)
State DefinitionDefine states as powers of two (e.g., 3'b001, 3'b010)
State TransitionUse case statement to set exactly one bit high
ResetInitialize state to a known one hot state
Default CaseAlways include default to avoid latches

Key Takeaways

Define each FSM state as a single bit in a register for one hot encoding.
Use a case statement to transition states by setting only one bit high at a time.
Always include a reset and a default case to keep the FSM in a valid state.
Avoid setting multiple bits high simultaneously to maintain one hot encoding.
Test your FSM to ensure it cycles through states correctly and predictably.