How to Design FSM in VHDL: Simple Guide with Example
To design a finite state machine (FSM) in
VHDL, define states using an enumeration type, create a process triggered by clock and reset signals, and use a case statement to describe state transitions and outputs. This structure models the FSM behavior clearly and synchronously.Syntax
An FSM in VHDL typically includes these parts:
- State type: Define states as an
enumeration type. - Signal for current state: Holds the current FSM state.
- Process block: Sensitive to clock and reset, updates state and outputs.
- Case statement: Describes transitions and outputs based on current state and inputs.
vhdl
type state_type is (IDLE, STATE1, STATE2); signal current_state, next_state: state_type; process(clk, reset) begin if reset = '1' then current_state <= IDLE; elsif rising_edge(clk) then current_state <= next_state; end if; end process; process(current_state, input_signal) begin case current_state is when IDLE => if input_signal = '1' then next_state <= STATE1; else next_state <= IDLE; end if; when STATE1 => -- define transitions when others => next_state <= IDLE; end case; end process;
Example
This example shows a simple FSM with three states: IDLE, STATE1, and STATE2. It changes states based on an input signal and resets to IDLE.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity simple_fsm is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
input_signal : in STD_LOGIC;
output_signal : out STD_LOGIC
);
end simple_fsm;
architecture Behavioral of simple_fsm is
type state_type is (IDLE, STATE1, STATE2);
signal current_state, next_state: state_type;
begin
-- State register process
process(clk, reset)
begin
if reset = '1' then
current_state <= IDLE;
elsif rising_edge(clk) then
current_state <= next_state;
end if;
end process;
-- Next state logic and output
process(current_state, input_signal)
begin
output_signal <= '0';
case current_state is
when IDLE =>
if input_signal = '1' then
next_state <= STATE1;
else
next_state <= IDLE;
end if;
when STATE1 =>
output_signal <= '1';
if input_signal = '0' then
next_state <= STATE2;
else
next_state <= STATE1;
end if;
when STATE2 =>
output_signal <= '0';
next_state <= IDLE;
when others =>
next_state <= IDLE;
end case;
end process;
end Behavioral;Common Pitfalls
Common mistakes when designing FSMs in VHDL include:
- Not using a synchronous reset, which can cause unpredictable states.
- Forgetting to cover all states in the
casestatement, leading to latches or inferred memory. - Mixing combinational and sequential logic improperly inside processes.
- Not initializing the state signal, causing simulation mismatches.
vhdl
process(clk, reset) begin if reset = '1' then current_state <= IDLE; elsif rising_edge(clk) then current_state <= next_state; end if; end process; -- Wrong: Missing others clause in case process(current_state, input_signal) begin case current_state is when IDLE => next_state <= STATE1; when STATE1 => next_state <= STATE2; -- Missing when STATE2 and others end case; end process; -- Right: Include all states and others process(current_state, input_signal) begin case current_state is when IDLE => next_state <= STATE1; when STATE1 => next_state <= STATE2; when STATE2 => next_state <= IDLE; when others => next_state <= IDLE; end case; end process;
Quick Reference
- Define states as an
enumeration type. - Use a clocked process for state updates.
- Use a combinational process for next state and output logic.
- Always include a reset to initialize the FSM.
- Cover all states in your
casestatements to avoid latches.
Key Takeaways
Define FSM states using an enumeration type for clarity and safety.
Use a synchronous clocked process to update the current state on clock edges.
Implement next state and output logic in a separate combinational process.
Always include a reset condition to initialize the FSM state.
Cover all states in case statements to prevent unintended latches.