Three Process FSM in VHDL: Syntax and Example
A
three process FSM in VHDL separates the design into three parts: state_register for storing the current state, next_state_logic for deciding the next state, and output_logic for generating outputs. This modular approach improves clarity and makes debugging easier.Syntax
A three process FSM in VHDL typically includes:
- State Register Process: Updates the current state on clock edge.
- Next State Logic Process: Determines the next state based on inputs and current state.
- Output Logic Process: Produces outputs based on the current state.
This separation helps organize the FSM clearly.
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; process(current_state, inputs) begin case current_state is when IDLE => if start = '1' then next_state <= WORK; else next_state <= IDLE; end if; when WORK => if done = '1' then next_state <= IDLE; else next_state <= WORK; end if; when others => next_state <= IDLE; end case; end process; process(current_state) begin case current_state is when IDLE => output_signal <= '0'; when WORK => output_signal <= '1'; when others => output_signal <= '0'; end case; end process;
Example
This example shows a simple FSM with three states: IDLE, WORK, and DONE. It uses three processes to handle state register, next state logic, and output logic.
vhdl
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity three_process_fsm is
Port (
clk : in STD_LOGIC;
reset : in STD_LOGIC;
start : in STD_LOGIC;
done : in STD_LOGIC;
output_signal: out STD_LOGIC
);
end three_process_fsm;
architecture Behavioral of three_process_fsm is
type state_type is (IDLE, WORK, DONE);
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 process
process(current_state, start, done)
begin
case current_state is
when IDLE =>
if start = '1' then
next_state <= WORK;
else
next_state <= IDLE;
end if;
when WORK =>
if done = '1' then
next_state <= DONE;
else
next_state <= WORK;
end if;
when DONE =>
next_state <= IDLE;
when others =>
next_state <= IDLE;
end case;
end process;
-- Output logic process
process(current_state)
begin
case current_state is
when IDLE => output_signal <= '0';
when WORK => output_signal <= '1';
when DONE => output_signal <= '0';
when others => output_signal <= '0';
end case;
end process;
end Behavioral;Common Pitfalls
Common mistakes when writing a three process FSM in VHDL include:
- Mixing next state logic and output logic in the same process, which reduces clarity.
- Forgetting to include all inputs in the sensitivity list of combinational processes, causing simulation mismatches.
- Not handling the
resetsignal properly in the state register process, leading to undefined states. - Using blocking assignments (
:=) instead of signal assignments (<=) in processes.
Always keep processes clearly separated and sensitivity lists complete.
vhdl
process(current_state) -- Missing inputs in sensitivity list begin if start = '1' then -- start not in sensitivity list next_state <= WORK; end if; end process; -- Correct version: process(current_state, start) begin if start = '1' then next_state <= WORK; else next_state <= IDLE; end if; end process;
Quick Reference
Three Process FSM Tips:
- Use one process for state register with clock and reset.
- Use one combinational process for next state logic with all inputs in sensitivity list.
- Use one combinational process for output logic based on current state.
- Always define all states and handle
otherscase. - Keep signal assignments (
<=) inside processes.
Key Takeaways
Separate state register, next state logic, and output logic into three distinct processes for clarity.
Include all relevant signals in sensitivity lists of combinational processes to avoid simulation issues.
Properly handle asynchronous reset in the state register process to initialize the FSM.
Use signal assignments (<=) inside processes, never variable assignments for state signals.
Always cover all states and use the 'others' clause in case statements to avoid latches.