-- state.vhdl convert a state transition table to VHDL -- unoptimized code, needs D flip flop, dff, in WORK -- -- Given: State transition table (Only in one state at a time, -- only one of the inputs may be '1' at a time) -- -- state | inputs -- | a b c -- ------+------------ -- S1 | S2 S1 S1 -- S2 | S2 S3 S2 -- S3 | S2 S1 S1 -- library IEEE; use IEEE.std_logic_1164.all; entity dff is -- D flip flop port(d : in std_logic; -- input read on rising clock clk : in std_logic; -- standard clock signal reset : in std_logic; -- normally high, low to reset set : in std_logic; -- normally high, low to set q : inout std_logic); -- output end entity dff; architecture behavior of dff is begin model: process (clk, reset, set) is begin if set='0' then q <= '1' after 1 ns; elsif reset='0' then q <= '0' after 1 ns; else if clk='1' then q <= d after 1 ns; end if; end if; end process model; end architecture behavior; -- of dff library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_textio.all; use STD.textio.all; entity state_test is -- test bench end entity state_test; architecture test of state_test is signal a, b, c : std_logic := '0'; -- inputs signal S1, S2, S3 : std_logic; -- states, exactly one is '1' signal S1_next, S2_next, S3_next : std_logic; -- next state value signal start : std_logic := '0' ; -- one shot signal clk : std_logic := '0'; -- clock begin -- test of state_test clk <= not clk after 5 ns; start <= '1' after 2 ns; -- combinational logic to compute next state S1_next <= (S1 and b) or (S1 and c) or (S3 and b) or (S3 and c) after 1 ns; S2_next <= (S2 and a) or (S2 and c) or (S1 and a) or (S3 and a) after 1 ns; S3_next <= (S2 and b) after 1 ns; -- sequential circuits, hold state S1_dff: entity work.dff port map(S1_next, clk, '1', start, S1); S2_dff: entity work.dff port map(S2_next, clk, start, '1', S2); S3_dff: entity work.dff port map(S3_next, clk, start, '1', S3); driver: process is -- update a,b and c, wait for state transition -- then print variable my_line : line; variable inputs : string(1 to 10) := "abcbcacaba"; variable input : character := ' '; variable new_state : string(1 to 2) := "S1"; variable old_state : string(1 to 2) := "S1"; begin for count in 1 to 10 loop old_state := new_state; input := inputs(count); if input='a' then a <= '1'; b <= '0'; c <= '0'; elsif input='b' then a <= '0'; b <= '1'; c <= '0'; elsif input='c' then a <= '0'; b <= '0'; c <= '1'; end if; wait for 7 ns; if S1='1' then new_state := "S1"; elsif S2='1' then new_state := "S2"; elsif S3='1' then new_state := "S3"; end if; write(my_line, string'("from "&old_state)); write(my_line, string'(" on input "&input)); write(my_line, string'(" to "&new_state)); write(my_line, string'(" at ")); write(my_line, now); write(my_line, string'(" count= ")); write(my_line, count); writeline(output, my_line); wait for 3 ns; -- now waited one clock cycle end loop; wait; end process driver; end architecture test; -- of state_test