next up previous contents index

[ENGN3213 Home]

Sequential Machines in VHDL

    There are many ways of describing sequential machines in VHDL. The VHDL code specifies how the state changes in response to the clock signal and inputs, and how the output signals are determined. Some ways of writing sequential VHDL code directly use next state/output tables.

Here is an example from CLAB4.

-- up/down/stop counter
--udsv.vhd created by Xilinx from udsv.asf

library IEEE;
use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

library SYNOPSYS;
use SYNOPSYS.attributes.all;

entity udsv is
  port (clk: in STD_LOGIC;
        reset: in STD_LOGIC;
        stop: in STD_LOGIC;
        ud: in STD_LOGIC;
        cnt: out STD_LOGIC_VECTOR (1 downto 0));
end;

architecture udsv_arch of udsv is


-- SYMBOLIC ENCODED state machine: Sreg0
type Sreg0_type is (S1, S2, S3, S4);
signal Sreg0: Sreg0_type;

begin
-- concurrent signals assignments


Sreg0_machine: process (clk)

begin

if clk'event and clk = '1' then
        if reset='1' then
                Sreg0 <= S1;
        else
        case Sreg0 is
                when S1 =>
                        if (ud='0' and stop='0') then
                                Sreg0 <= S4;
                        elsif stop='1' then
                                Sreg0 <= S1;
                        elsif (ud='1' and stop='0') then
                                Sreg0 <= S2;
                        end if;
                when S2 =>
                        if (ud='0' and stop='0') then
                                Sreg0 <= S1;
                        elsif stop='1' then
                                Sreg0 <= S2;
                        elsif (ud='1' and stop='0') then
                                Sreg0 <= S3;
                        end if;
                when S3 =>
                        if (ud='0' and stop='0') then
                                Sreg0 <= S2;
                        elsif stop='1' then
                                Sreg0 <= S3;
                        elsif (ud='1' and stop='0') then
                                Sreg0 <= S4;
                        end if;
                when S4 =>
                        if (ud='0' and stop='0') then
                                Sreg0 <= S3;
                        elsif stop='1' then
                                Sreg0 <= S4;
                        elsif (ud='1' and stop='0') then
                                Sreg0 <= S1;
                        end if;
                when others =>
                        null;
        end case;
        end if;
end if;
end process;

-- signal assignment statements for combinatorial outputs
cnt_1_assignment:
cnt(1) <= '0' when (Sreg0 = S1 and (ud='0' and stop='0')) else
          '0' when (Sreg0 = S1 and stop='1') else
          '0' when (Sreg0 = S1 and (ud='1' and stop='0')) else
          '0' when (Sreg0 = S2 and (ud='0' and stop='0')) else
          '0' when (Sreg0 = S2 and stop='1') else
          '0' when (Sreg0 = S2 and (ud='1' and stop='0')) else
          '1' when (Sreg0 = S3 and (ud='0' and stop='0')) else
          '1' when (Sreg0 = S3 and stop='1') else
          '1' when (Sreg0 = S3 and (ud='1' and stop='0')) else
          '1' when (Sreg0 = S4 and (ud='0' and stop='0')) else
          '1' when (Sreg0 = S4 and stop='1') else
          '1' when (Sreg0 = S4 and (ud='1' and stop='0')) else
          '1';

cnt_0_assignment:
cnt(0) <= '0' when (Sreg0 = S1 and (ud='0' and stop='0')) else
          '0' when (Sreg0 = S1 and stop='1') else
          '0' when (Sreg0 = S1 and (ud='1' and stop='0')) else
          '1' when (Sreg0 = S2 and (ud='0' and stop='0')) else
          '1' when (Sreg0 = S2 and stop='1') else
          '1' when (Sreg0 = S2 and (ud='1' and stop='0')) else
          '0' when (Sreg0 = S3 and (ud='0' and stop='0')) else
          '0' when (Sreg0 = S3 and stop='1') else
          '0' when (Sreg0 = S3 and (ud='1' and stop='0')) else
          '1' when (Sreg0 = S4 and (ud='0' and stop='0')) else
          '1' when (Sreg0 = S4 and stop='1') else
          '1' when (Sreg0 = S4 and (ud='1' and stop='0')) else
          '1';

end udsv_arch;

This style of coding is used in Section 9.2 (pp813) of Wakerly (see Example 9-13), and is straightforward to use (see also Wakerly, Section 7.12 (pp641)). In most of our laboratory work, we will be using the Xilinx state editor to produce state machine VHDL code. We do this to ensure implementability; see the warnings in CLAB 2 and Wakerly, Section 4.7.10 (pp297).

Note:

  FPGA synthesis software is used to take a VHDL source file like this and produce a bit stream file for download to the target FPGA hardware. The software has algorithms which map the design into a form appropriate for the FPGA architecture, and this process may involve Boolean simplification, state reduction, optimization, and other operations.

Because of the complexity of this procedure, we will not go into details. We will however learn some traditional techniques for synthesizing state machines described by state diagrams and/or next state/output tables using some standard memory elements.


next up previous contents index

[ENGN3213 Home]

ANU Engineering - ENGN3213