Skip to main content
Logo image

Section 12.2 VHDL template for state machines

A state machine, Figure 12.1.1, always has a state register and a block of combinational logic. In VHDL, we will represent these by two processes. A state diagram, e.g., Figure 12.1.2, is a very regular structure. Each state contains transitions from that state to other states, which may or may not be conditional on inputs, and outputs that are asserted while in that state. The regularity lends itself to a very regular structure for the two processes in the VHDL model.
architecture behavior of example is
    type state_type is (idle, run, flash, finish);  -- 1
    signal curr_state, next_state: state_type;      -- 2

    -- Input go and outputs red and green are declared as std_logic.

begin

FSM_reg: process(clk)                               -- 3
begin
    if rising_edge(clk) then
       curr_state <= next_state;
    end if;
end process FSM_reg;

FSM_logic: process(curr_state, go)
begin
    next_state <= curr_state;                      -- 4
    red <= '0';
    green <= '0';

    case curr_state is
       when idle => red <= '1';                    -- 5
          if go = '1' then
             next_state <= run;
          end if;                                  -- 6

       when run =>
          if go = '1' then                         -- 7
             next_state <= flash; 
          else
             next_state <= finish;
          end if;

       when flash => green <= '1';                 -- 8
          next_state <= run;

       when finish => red <= '1';
          next_state <= idle;
    end case;                                      -- 9
end process FSM_logic;
end behavior;
Listing 12.2.1. VHDL model derived from the state diagram in Figure 12.1.2. Comments are keyed to explanations in the text.
The only new VHDL in the model are noted by comments 1 and 2. Everything else is a construct we have used before.
  1. Rather than assign binary codes to each state, VHDL allows us to work with the symbolic names of the states. The line type state_type is (idle, run, flash, finish); declares an enumerated type. The name of the type is state_type (you can call it whatever you want, but this is descriptive). An item declared to be of type state_type may take on one of four values: idle, run, flash, and finish.
  2. In particular, we want two signals, curr_state and next_state, to be of type state_type.
  3. The state register process always looks like this, for any state machine.
  4. The combinational logic begins by assigning default values to next_state and to the outputs, red and green. These are the values that these signals will take if they are not changed by logic farther down the process. Using defaults simplifies the rest of the logic.
  5. Each state gets its own when line in the case statement. It is conventional first to assert the outputs that are active in the state, and then to write the logic for the next state assignment.
  6. Because next_state is assigned curr_state by default, we don’t have to explicitly write the logic for staying in state idle if input go is false.
  7. Outputs red and green are '0' by default, so we don’t have to explicitly deassert them in state run. There are two paths out of the state. Both are written into the if-then-else logic.
  8. State flash transitions unconditionally to state run. Likewise, state finish transitions unconditionally to state idle.
  9. A when others is not needed. The only possible values for curr_state are accounted for by their own when lines.
You can use this state machine as a guide for any other state machine that you write in this course. The VHDL model for a state machine will always have this structure.
architecture behavior of my_design is
    type state_type is ( [list of states] );  
    signal curr_state, next_state: state_type;      
    ...

begin

FSM_reg: process(clk)                               
begin
    if rising_edge(clk) then
       curr_state <= next_state;
    end if;
end process FSM_reg;

FSM_logic: process(curr_state, [list of inputs])
begin
    next_state <= curr_state;                      
    -- Assign defaults for all outputs

    case curr_state is
       -- Write a when line for each state
       when [state name] => -- assert outputs
          -- if-then-else logic for next_state assignments      

       ...

    end case;                                      
end process FSM_logic;
Listing 12.2.2. Template for writing a state machine in VHDL.