Table of Contents

    state machine exemple

    Mastering State Machines in VHDL

    State machines are a fundamental concept in digital design, often used to manage the sequence of operations in a system. VHDL (VHSIC Hardware Description Language) is a powerful language that allows you to describe state machines concisely and effectively. In this article, we will explore the basics of state machines, how to implement them in VHDL, and provide example code and exercises to reinforce your understanding.

    What is a State Machine?

    A state machine (or finite state machine, FSM) is a mathematical model of computation used to design both computer programs and sequential logic circuits. It consists of a finite number of states, transitions between these states, and actions. State machines can be classified into two types:

    1. Moore State Machine: Outputs depend only on the current state.

    2. Mealy State Machine: Outputs depend on the current state and the current inputs.

    More and Mealy machines

    Implementing State Machines in VHDL

    To implement a state machine in VHDL, follow these steps:

    1. Define the states.
    2. Create a process for state transitions.
    3. Create a process for output logic.

    Here are template VHDL codes for both Moore and Mealy state machines. These templates can be adapted to various applications by modifying the states, transitions, and outputs as needed.

    Moore State Machine Template

    In a Moore state machine, the outputs depend only on the current state. Here's a template VHDL code for a Moore state machine:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity moore_fsm is
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               input_signal : in STD_LOGIC;
               output_signal : out STD_LOGIC);
    end moore_fsm;
    
    architecture Behavioral of moore_fsm is
        type state_type is (STATE1, STATE2, STATE3);
        signal state, next_state : state_type;
    begin
    
        -- State transition process
        process(clk, reset)
        begin
            if reset = '1' then
                state <= STATE1;
            elsif rising_edge(clk) then
                state <= next_state;
            end if;
        end process;
    
        -- Next state logic
        process(state, input_signal)
        begin
            case state is
                when STATE1 =>
                    if input_signal = '1' then
                        next_state <= STATE2;
                    else
                        next_state <= STATE1;
                    end if;
                when STATE2 =>
                    if input_signal = '1' then
                        next_state <= STATE3;
                    else
                        next_state <= STATE1;
                    end if;
                when STATE3 =>
                    next_state <= STATE1;
                when others =>
                    next_state <= STATE1;
            end case;
        end process;
    
        -- Output logic (Moore machine: output depends only on state)
        process(state)
        begin
            case state is
                when STATE1 =>
                    output_signal <= '0';
                when STATE2 =>
                    output_signal <= '0';
                when STATE3 =>
                    output_signal <= '1';
                when others =>
                    output_signal <= '0';
            end case;
        end process;
    
    end Behavioral;
    

    Mealy State Machine Template

    In a Mealy state machine, the outputs depend on both the current state and the current inputs. Here's a template VHDL code for a Mealy state machine:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity mealy_fsm is
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               input_signal : in STD_LOGIC;
               output_signal : out STD_LOGIC);
    end mealy_fsm;
    
    architecture Behavioral of mealy_fsm is
        type state_type is (STATE1, STATE2, STATE3);
        signal state, next_state : state_type;
    begin
    
        -- State transition process
        process(clk, reset)
        begin
            if reset = '1' then
                state <= STATE1;
            elsif rising_edge(clk) then
                state <= next_state;
            end if;
        end process;
    
        -- Next state logic
        process(state, input_signal)
        begin
            case state is
                when STATE1 =>
                    if input_signal = '1' then
                        next_state <= STATE2;
                    else
                        next_state <= STATE1;
                    end if;
                when STATE2 =>
                    if input_signal = '1' then
                        next_state <= STATE3;
                    else
                        next_state <= STATE1;
                    end if;
                when STATE3 =>
                    next_state <= STATE1;
                when others =>
                    next_state <= STATE1;
            end case;
        end process;
    
        -- Output logic (Mealy machine: output depends on state and input)
        process(state, input_signal)
        begin
            case state is
                when STATE1 =>
                    output_signal <= '0';
                when STATE2 =>
                    if input_signal = '1' then
                        output_signal <= '1';
                    else
                        output_signal <= '0';
                    end if;
                when STATE3 =>
                    output_signal <= '1';
                when others =>
                    output_signal <= '0';
            end case;
        end process;
    
    end Behavioral;
    

    How to Use These Templates

    1. Define States: Update the state_type with your specific states.
    2. State Transitions: Modify the next_state logic to reflect the transitions based on your inputs and conditions.
    3. Output Logic: For Moore machines, adjust the output logic based on states. For Mealy machines, adjust it based on both states and inputs.

    These templates should serve as a starting point for implementing your own Moore and Mealy state machines in VHDL. Adjust the state types, transitions, and output logic to fit your specific design requirements.

    Here’s an example of a simple state machine implemented in VHDL. This example uses a Moore state machine to control a traffic light system.

    Example: Traffic Light Controller

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;
    
    entity traffic_light is
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               red, yellow, green : out STD_LOGIC);
    end traffic_light;
    
    architecture Behavioral of traffic_light is
        type state_type is (S_RED, S_GREEN, S_YELLOW);
        signal state, next_state : state_type;
    begin
    
        -- State transition process
        process(clk, reset)
        begin
            if reset = '1' then
                state <= S_RED;
            elsif rising_edge(clk) then
                state <= next_state;
            end if;
        end process;
    
        -- Next state logic
        process(state)
        begin
            case state is
                when S_RED =>
                    next_state <= S_GREEN;
                when S_GREEN =>
                    next_state <= S_YELLOW;
                when S_YELLOW =>
                    next_state <= S_RED;
                when others =>
                    next_state <= S_RED;
            end case;
        end process;
    
        -- Output logic
        process(state)
        begin
            case state is
                when S_RED =>
                    red <= '1';
                    yellow <= '0';
                    green <= '0';
                when S_GREEN =>
                    red <= '0';
                    yellow <= '0';
                    green <= '1';
                when S_YELLOW =>
                    red <= '0';
                    yellow <= '1';
                    green <= '0';
                when others =>
                    red <= '0';
                    yellow <= '0';
                    green <= '0';
            end case;
        end process;
    
    end Behavioral;
    

    fsm

    Example: Traffic Light Controller Test bench

    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    
    ENTITY traffic_light_testbench IS
    END traffic_light_testbench;
    
    ARCHITECTURE behavior OF traffic_light_testbench IS
    
        COMPONENT traffic_light
        Port ( clk : in STD_LOGIC;
               reset : in STD_LOGIC;
               red, yellow, green : out STD_LOGIC);
        END COMPONENT;
    
        SIGNAL m_clk : std_logic := '0';
        SIGNAL m_reset : std_logic := '0';
        SIGNAL m_red, m_yellow, m_green : std_logic := '0';
    
    BEGIN
    
        uut: traffic_light PORT MAP (
            clk => m_clk,
            reset => m_reset,
            red => m_red,
            yellow => m_yellow,
              green => m_green
        );
    
        clk_process :process
        begin
            m_clk <= '0';
            wait for 10 ns;
            m_clk <= '1';
            wait for 10 ns;
        end process;
    
        stim_proc: process
        begin       
            m_reset <= '1';
            wait for 20 ns; 
            m_reset <= '0';
            wait;
        end process;
    
    END behavior;
    

    traffic light testbench

    Exercises

    Modify the Traffic Light Controller:

    • Add a pedestrian crossing signal that turns on a 'walk' signal when the traffic light is red.
    • Ensure the pedestrian signal has appropriate timing.
    @startuml
    !define RECTANGLE class
    skinparam class {
        BackgroundColor<<S_RED>> LightCoral
        BackgroundColor<<S_GREEN>> LightGreen
        BackgroundColor<<S_YELLOW>> LightYellow
    }
    
    RECTANGLE S_RED <<S_RED>> {
        * Red light ON
        * Yellow and Green lights OFF
        * Walk signal ON
        * Timer expires, transition to S_GREEN
    }
    
    RECTANGLE S_GREEN <<S_GREEN>> {
        * Green light ON
        * Red and Yellow lights OFF
        * Walk signal OFF
        * Timer expires, transition to S_YELLOW
    }
    
    RECTANGLE S_YELLOW <<S_YELLOW>> {
        * Yellow light ON
        * Red and Green lights OFF
        * Walk signal OFF
        * Timer expires, transition to S_RED
    }
    
    S_RED -down-> S_GREEN : Timer expires
    S_GREEN -down-> S_YELLOW : Timer expires
    S_YELLOW -down-> S_RED : Timer expires
    @enduml
    

    🔗Traffic light Solutionde VHDL code

    🔗Traffic light Test Bench VHDL code

    Design a Vending Machine Controller:

    • Implement a state machine that controls a vending machine. The machine should accept coins, dispense an item, and provide change.
    • States: IDLE, ACCEPTING_COINS, DISPENSE_ITEM, GIVE_CHANGE.
    • Inputs: Coin (each coin adds to the total amount), Item_Select (selects the item), and Cancel (returns to IDLE).
    • Outputs: Dispense_Item, Return_Coins.
    @startuml
    !define RECTANGLE class
    skinparam class {
        BackgroundColor<<IDLE>> LightBlue
        BackgroundColor<<ACCEPTING_COINS>> LightGreen
        BackgroundColor<<DISPENSE_ITEM>> LightYellow
        BackgroundColor<<GIVE_CHANGE>> LightCoral
    }
    
    RECTANGLE IDLE <<IDLE>> {
        * Waiting for a coin to be inserted
        * If Cancel is pressed, remain in IDLE
    }
    
    RECTANGLE ACCEPTING_COINS <<ACCEPTING_COINS>> {
        * Continue accepting coins until an item is selected
        * If total amount >= item price, move to DISPENSE_ITEM
        * If Cancel is pressed, move to GIVE_CHANGE
    }
    
    RECTANGLE DISPENSE_ITEM <<DISPENSE_ITEM>> {
        * Dispense the selected item
        * After dispensing, move to GIVE_CHANGE if change is needed, otherwise move to IDLE
    }
    
    RECTANGLE GIVE_CHANGE <<GIVE_CHANGE>> {
        * Return the change
        * After returning change, move to IDLE
    }
    
    IDLE -down-> ACCEPTING_COINS : Coin inserted
    ACCEPTING_COINS -down-> DISPENSE_ITEM : Total amount >= Item price
    ACCEPTING_COINS -down-> GIVE_CHANGE : Cancel pressed
    DISPENSE_ITEM -down-> GIVE_CHANGE : Dispense complete
    GIVE_CHANGE -down-> IDLE : Change returned
    ACCEPTING_COINS -right-> ACCEPTING_COINS : Coin inserted
    @enduml
    
    

    🔗Vending Machine Controller VHDL code

    🔗Vending Machine Controller VHDL Test Bench code

    Modelsime simulation

    Vinding test machine

    Elevator Controller:

    • Design a state machine for a simple two-floor elevator.
    • States: FLOOR1, FLOOR2, MOVING_UP, MOVING_DOWN.
    • Inputs: Call_Floor1, Call_Floor2, Door_Close.
    • Outputs: Move_Up, Move_Down, Open_Door.
    @startuml
    !define RECTANGLE class
    skinparam class {
        BackgroundColor<<FLOOR1>> LightBlue
        BackgroundColor<<FLOOR2>> LightGreen
        BackgroundColor<<MOVING_UP>> LightYellow
        BackgroundColor<<MOVING_DOWN>> LightCoral
    }
    
    RECTANGLE FLOOR1 <<FLOOR1>> {
        * Elevator at Floor 1
        * Move_Up = 0, Move_Down = 0, Open_Door = 1
    }
    
    RECTANGLE FLOOR2 <<FLOOR2>> {
        * Elevator at Floor 2
        * Move_Up = 0, Move_Down = 0, Open_Door = 1
    }
    
    RECTANGLE MOVING_UP <<MOVING_UP>> {
        * Elevator moving up
        * Move_Up = 1, Move_Down = 0, Open_Door = 0
    }
    
    RECTANGLE MOVING_DOWN <<MOVING_DOWN>> {
        * Elevator moving down
        * Move_Up = 0, Move_Down = 1, Open_Door = 0
    }
    
    FLOOR1 -down-> MOVING_UP : Call_Floor2 and Door_Close
    MOVING_UP -down-> FLOOR2 : Reached Floor 2
    FLOOR2 -up-> MOVING_DOWN : Call_Floor1 and Door_Close
    MOVING_DOWN -up-> FLOOR1 : Reached Floor 1
    
    @enduml
    
    

    🔗Elevator controller VHDL code

    🔗Elevator control Test VHDL Bench code

    Modelsime simulation

    elvator test bench

    Sequence Detector:

    • Create a state machine that detects a specific sequence of bits (e.g., 1011) in a serial input stream.
    • Outputs: Sequence_Detected.
    @startuml
    !define RECTANGLE class
    skinparam class {
        BackgroundColor<<IDLE>> LightBlue
        BackgroundColor<<S1>> LightGreen
        BackgroundColor<<S10>> LightYellow
        BackgroundColor<<S101>> LightCoral
        BackgroundColor<<S1011>> LightGray
    }
    
    RECTANGLE IDLE <<IDLE>> {
        * Waiting for first bit (1)
    }
    
    RECTANGLE S1 <<S1>> {
        * Detected 1
    }
    
    RECTANGLE S10 <<S10>> {
        * Detected 10
    }
    
    RECTANGLE S101 <<S101>> {
        * Detected 101
    }
    
    RECTANGLE S1011 <<S1011>> {
        * Detected 1011
        * Sequence_Detected = 1
    }
    
    IDLE -down-> S1 : 1
    IDLE -down-> IDLE : 0
    
    S1 -down-> S10 : 0
    S1 -down-> S1 : 1
    
    S10 -down-> S101 : 1
    S10 -down-> IDLE : 0
    
    S101 -down-> S1011 : 1
    S101 -down-> S10 : 0
    
    S1011 -down-> S1 : 1
    S1011 -down-> IDLE : 0
    
    @enduml
    
    

    🔗Sequence Detector VHDL code

    🔗Sequence Detector Test VHDL Bench code

    Modelsime simulation

    sequence detection

    Conclusion

    State machines are a vital part of digital design, enabling complex control logic to be broken down into manageable states and transitions. By practicing with VHDL and the examples provided, you can gain a deeper understanding of how to implement state machines effectively in your projects.

    📝 Article Author : SEMRADE Tarik
    🏷️ Author position : Embedded Software Engineer
    🔗 Author LinkedIn : LinkedIn profile

    Comments