How to Encode States in FSM Verilog: Syntax and Examples
In Verilog, states in an FSM are encoded using
parameter or localparam constants with binary, one-hot, or gray code values. You define each state as a unique bit pattern and use a reg variable to hold the current state, updating it in a case statement inside an always block.Syntax
To encode states in Verilog FSM, you declare each state as a named constant using parameter or localparam. Then, use a reg variable to store the current state. The state transitions happen inside an always block with a case statement.
- parameter/localparam: Define state names and their binary codes.
- reg [width-1:0] state: Holds the current state value.
- always @(posedge clk or posedge reset): Updates state on clock or reset.
- case(state): Controls transitions based on current state.
verilog
localparam IDLE = 2'b00, STATE1 = 2'b01, STATE2 = 2'b10; reg [1:0] state, next_state; always @(posedge clk or posedge reset) begin if (reset) state <= IDLE; else state <= next_state; end always @(*) begin case(state) IDLE: next_state = STATE1; STATE1: next_state = STATE2; STATE2: next_state = IDLE; default: next_state = IDLE; endcase end
Example
This example shows a simple FSM with three states encoded in binary. The FSM cycles through states IDLE, STATE1, and STATE2 on each clock cycle, resetting to IDLE when reset is high.
verilog
module fsm_example( input wire clk, input wire reset, output reg [1:0] state ); localparam IDLE = 2'b00; localparam STATE1 = 2'b01; localparam STATE2 = 2'b10; reg [1:0] next_state; always @(posedge clk or posedge reset) begin if (reset) state <= IDLE; else state <= next_state; end always @(*) begin case(state) IDLE: next_state = STATE1; STATE1: next_state = STATE2; STATE2: next_state = IDLE; default: next_state = IDLE; endcase end endmodule
Common Pitfalls
Common mistakes when encoding FSM states include:
- Using overlapping or non-unique codes for states, causing unpredictable behavior.
- Not resetting the state register properly, leading to unknown start states.
- Using too few bits for state encoding, which can cause truncation or incorrect state representation.
- Mixing encoding styles without consistency (e.g., some states binary, others one-hot).
Always ensure each state has a unique code and the state register is reset.
verilog
/* Wrong: overlapping states */ localparam IDLE = 2'b00; localparam STATE1 = 2'b00; // Error: same as IDLE /* Right: unique states */ localparam IDLE = 2'b00; localparam STATE1 = 2'b01;
Quick Reference
| Encoding Style | Description | Bit Width | Use Case |
|---|---|---|---|
| Binary | States encoded as binary numbers | Minimum bits to cover states | Most common, compact |
| One-hot | Each state has one bit set high | Number of states | Simpler logic, faster but uses more bits |
| Gray code | Only one bit changes between states | Minimum bits | Reduces glitches in some hardware |
Key Takeaways
Define each FSM state as a unique constant using parameter or localparam.
Use a reg variable to hold the current state and update it in an always block.
Choose an encoding style (binary, one-hot, gray) based on design needs.
Always reset the state register to a known state to avoid undefined behavior.
Avoid overlapping or non-unique state codes to prevent logic errors.