0
0
VhdlHow-ToBeginner · 4 min read

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 case statement, 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 case statements 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.