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;
The only new VHDL in the model are noted by comments 1 and 2. Everything else is a construct we have used before.
- 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 isstate_type(you can call it whatever you want, but this is descriptive). An item declared to be of typestate_typemay take on one of four values:idle,run,flash, andfinish. - In particular, we want two signals,
curr_stateandnext_state, to be of typestate_type. - The state register process always looks like this, for any state machine.
- The combinational logic begins by assigning default values to
next_stateand to the outputs,redandgreen. 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. - Each state gets its own
whenline in thecasestatement. 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. - Because
next_stateis assignedcurr_stateby default, we don’t have to explicitly write the logic for staying in stateidleif inputgois false. - Outputs
redandgreenare'0'by default, so we don’t have to explicitly deassert them in staterun. There are two paths out of the state. Both are written into theif-then-elselogic. - State
flashtransitions unconditionally to staterun. Likewise, statefinishtransitions unconditionally to stateidle. - A
when othersis not needed. The only possible values forcurr_stateare accounted for by their ownwhenlines.
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;

