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.
Practice
Solution
Step 1: Understand the role of state diagrams
State diagrams show states and how the system moves between them, making design clearer.Step 2: Connect to Verilog design
They help plan the Verilog code but do not generate code or replace hardware elements.Final Answer:
To visually represent states and transitions for easier coding -> Option AQuick Check:
State diagram = Visual design aid [OK]
- Thinking state diagrams generate code automatically
- Confusing state diagrams with testing tools
- Believing state diagrams replace clock signals
Solution
Step 1: Recall Verilog enum syntax
In SystemVerilog (modern Verilog), enums are declared with 'typedef enum {states} name;'.Step 2: Check variable declarations
Variables of enum type are declared as 'state_t current_state, next_state;'.Final Answer:
typedef enum {IDLE, READ, WRITE} state_t; state_t current_state, next_state; -> Option CQuick Check:
Enum typedef syntax = typedef enum {IDLE, READ, WRITE} state_t; state_t current_state, next_state; [OK]
- Using 'enum' without typedef
- Incorrect order of keywords
- Missing variable type for state variables
current_state after two clock cycles if the reset is deasserted and start is 1?
typedef enum {IDLE, BUSY, DONE} state_t;
state_t current_state, next_state;
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: next_state = start ? BUSY : IDLE;
BUSY: next_state = DONE;
DONE: next_state = IDLE;
default: next_state = IDLE;
endcase
endSolution
Step 1: Analyze state transitions per clock
At reset, current_state = IDLE. On first clock, start=1, so next_state = BUSY.Step 2: Follow second clock update
On second clock, current_state = BUSY, so next_state = DONE.Final Answer:
DONE -> Option BQuick Check:
Two clocks after start=1: IDLE -> BUSY -> DONE [OK]
- Assuming immediate state change without clock
- Confusing next_state with current_state
- Ignoring reset effect
typedef enum {S0, S1, S2} state_t;
state_t current_state, next_state;
always_ff @(posedge clk or posedge reset) begin
if (reset)
current_state <= S0;
else
current_state = next_state;
end
always_comb begin
case (current_state)
S0: next_state = S1;
S1: next_state = S2;
S2: next_state = S0;
endcase
endSolution
Step 1: Check assignment types in always_ff block
Inside always_ff, non-blocking assignment '<=' must be used for sequential logic.Step 2: Identify incorrect assignment
Line 'current_state = next_state;' uses blocking '=', which is incorrect here.Final Answer:
Change 'current_state = next_state;' to 'current_state <= next_state;' -> Option DQuick Check:
Sequential logic uses '<=' [OK]
- Using '=' instead of '<=' in sequential blocks
- Forgetting default case (not critical here)
- Misunderstanding sensitivity list for reset
x. State A transitions to B if x=1, else stays in A. State B transitions to C unconditionally. State C transitions back to A if x=0, else stays in C. Which Verilog code snippet correctly implements the next state logic using a case statement?Solution
Step 1: Translate each transition from the diagram
State A: if x=1 go to B else stay A; State B: always go to C; State C: if x=0 go to A else stay C.Step 2: Match transitions to code options
always_comb begin case (current_state) A: next_state = (x == 1) ? B : A; B: next_state = C; C: next_state = (x == 0) ? A : C; default: next_state = A; endcase end matches all conditions exactly with correct ternary expressions and default case.Final Answer:
Option A code snippet -> Option AQuick Check:
Transitions match diagram = always_comb begin case (current_state) A: next_state = (x == 1) ? B : A; B: next_state = C; C: next_state = (x == 0) ? A : C; default: next_state = A; endcase end [OK]
- Swapping conditions for x in transitions
- Missing default case in case statement
- Incorrect unconditional transitions
Ready to prove it?
Pass the test and this pattern moves unknown
