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.
ANU Engineering - ENGN3213