There are many different ways to model a Finite State Machine in VHDL. A common approach is to use two VHDL processes:

List

  • Clocked Process — stores present state in flip-flops and applies any reset or set controls.

  • Combinational Process — uses inputs and present state to determine next state and outputs.

centre


State Declaration

We build our state representation at the top of our architecture; we define all the possible states in an enumerated type list (called state_type).

Concept bq

Enumerated type is a custom data type defined by listing every valid (symbolic or numberical) value it can hold.

Then, declare our present state (PS) and next state (NS) signals using the enumerated state type we have declared.

-- General form: enumerated type listing the state names 
type state_type_name is (state_name_1, ..., state_name_n); 
signal state_signal_name : state_type_name; 

For example:

type state_type is (EVEN, ODD);
signal PS,NS : state_type;

Now we can assign a state from our list to these signals (e.g. PS <= EVEN), to implement the combinatorial logic for our design.

Quote bq

The synthesis tool picks the binary code for each state, unless explicitly defined through state assignment.


FSM Modelling Examples

Comment bq

An asynchronous reset is used to place the FSM in a known initial state.

Clocked Process Example:

begin 
  -- asynchronous reset
  if (RESET = '1') then
	PS <= INITIAL_STATE;
  elsif (rising_edge(CLK)) then
	PS <= NS;
  end if;

Quote bq

There are many different ways to model a FSM. A distinct process could be used for the output logic, or everything could be written in one process.

Output Process Example:

-- Combinational process computes the output 
OUTPUT_LOGIC : process(PS) 
begin 
  case PS is 
    when S4           => Z <= '1'; 
    when S1 | S2 | S3 => Z <= '0'; 
  end case; 
end process OUTPUT_LOGIC;

Here is a full example of a parity checker implementation:

clocked_process: process (CLK, RESET)
begin
  if (RESET = '1') then
    PS <= EVEN;
  elsif (rising_edge(CLK)) then
    PS <= NS;
  end if;
end process;
 
comb_process: process (PS, X)
begin
  case PS is
    when EVEN =>
      PARITY <= '0';                       -- Moore output
      if (X = '1') then NS <= ODD;
      else NS <= EVEN;
      end if;
    when ODD =>
      PARITY <= '1';
      if (X = '1') then NS <= EVEN;
      else NS <= ODD;
      end if;
  end case;
end process;

await dv.view("Scripts/topic-backlinks");