A state diagram shows how a system moves between steps. Translating it to Verilog lets us build that system in hardware.
State diagram to Verilog translation
module state_machine(
input clk,
input reset,
input in_signal,
output reg out_signal
);
typedef enum logic [1:0] {
IDLE = 2'b00,
STATE1 = 2'b01,
STATE2 = 2'b10
} state_t;
state_t current_state, next_state;
// State register
always_ff @(posedge clk or posedge reset) begin
if (reset)
current_state <= IDLE;
else
current_state <= next_state;
end
// Next state logic
always_comb begin
case (current_state)
IDLE: if (in_signal) next_state = STATE1; else next_state = IDLE;
STATE1: next_state = STATE2;
STATE2: next_state = IDLE;
default: next_state = IDLE;
endcase
end
// Output logic
always_comb begin
case (current_state)
IDLE: out_signal = 0;
STATE1: out_signal = 1;
STATE2: out_signal = 0;
default: out_signal = 0;
endcase
end
endmoduleUse typedef enum to name states clearly.
Separate state register, next state logic, and output logic for clarity.
typedef enum logic [1:0] {IDLE=2'b00, WAIT=2'b01, DONE=2'b10} state_t;
always_ff @(posedge clk or posedge reset) begin if (reset) current_state <= IDLE; else current_state <= next_state; end
always_comb begin
case (current_state)
IDLE: if (start) next_state = WAIT; else next_state = IDLE;
WAIT: if (done) next_state = DONE; else next_state = WAIT;
DONE: next_state = IDLE;
default: next_state = IDLE;
endcase
endThis example shows a simple FSM with three states: IDLE, PROCESS, and FINISH. It starts processing when start is high, then moves to finish, and signals done.
module simple_fsm(
input logic clk,
input logic reset,
input logic start,
output logic done
);
typedef enum logic [1:0] {
IDLE = 2'b00,
PROCESS = 2'b01,
FINISH = 2'b10
} state_t;
state_t current_state, next_state;
// State register
always_ff @(posedge clk or posedge reset) begin
if (reset)
current_state <= IDLE;
else
current_state <= next_state;
end
// Next state logic
always_comb begin
case (current_state)
IDLE: if (start) next_state = PROCESS; else next_state = IDLE;
PROCESS: next_state = FINISH;
FINISH: next_state = IDLE;
default: next_state = IDLE;
endcase
end
// Output logic
always_comb begin
done = (current_state == FINISH);
end
endmoduleAlways reset your state machine to a known state to avoid unpredictable behavior.
Use meaningful state names to make your code easier to read.
Separate combinational logic (next state, outputs) from sequential logic (state register) for clarity and correctness.
State diagrams show steps and transitions; Verilog code makes hardware follow those steps.
Use enums for states and separate blocks for state update, next state, and outputs.
Reset state machines to a safe start state to keep behavior predictable.