-- fsm.vhd: finite state machine controller for traffic signal -- Dan R. K. Ports -- 6.111 Lab 2, 2003/10/01 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity fsm is port ( reset, l0, l1, f0, f1 : in std_logic; gosync, senssync, wreqlatch, expire, clk : in std_logic; mr, my, mg, sr, sy, sg : out std_logic; -- light outputs stateout : out std_logic_vector (3 downto 0); a0, a1, n_we, latchreset, starttimer, resettimer : out std_logic ); end fsm; architecture behavioral of fsm is type StateType is (s_idle, s_read, s_write, s_maing1, s_maing2, s_mainy, s_walk, s_sideg, s_sideext, s_sidey, s_blinkon, s_blinkoff); signal curState, nextState : StateType := s_idle; signal nexta0, nexta1 : std_logic := '0'; begin -- behavioral -- purpose: determine next state and timer address bits -- type : combinational -- inputs : curState, gosync, senssync, wreqlatch, expire, f0, f1 -- outputs: nextState, nexta0, nexta1 fsm: process (curState, gosync, senssync, wreqlatch, expire, f0, f1) begin -- process fsm if reset = '1' then nextState <= s_idle; else if gosync = '1' then if (f0 = '0') and (f1 = '0') then nextState <= s_read; nexta0 <= l0; nexta1 <= l1; elsif (f0 = '1') and (f1 = '0') then nextState <= s_write; nexta0 <= l0; nexta1 <= l1; elsif (f0 = '0') and (f1 = '1') then nextState <= s_maing1; nexta0 <= '1'; nexta1 <= '0'; else nextState <= s_blinkon; nexta0 <= '1'; nexta1 <= '1'; end if; else case curState is when s_idle => nextState <= s_idle; nexta0 <= '0'; nexta1 <= '0'; when s_read => nextState <= s_read; nexta0 <= l0; nexta1 <= l1; when s_write => nextState <= s_read; when s_maing1 => nextState <= s_maing2; nexta0 <= '0'; nexta1 <= '1'; when s_maing2 => nextState <= s_mainy; nexta0 <= '0'; nexta1 <= '0'; when s_mainy => if wreqlatch = '1' then nextState <= s_walk; nexta1 <= '1'; nexta0 <= '0'; else nextState <= s_sideg; nexta1 <= '0'; nexta0 <= '1'; end if; when s_walk => nextState <= s_sideg; nexta1 <= '0'; nexta0 <= '1'; when s_sideg => if senssync = '1' then nextState <= s_sideext; nexta1 <= '0'; nexta0 <= '1'; else nextState <= s_sidey; nexta1 <= '0'; nexta0 <= '0'; end if; when s_sideext => nextState <= s_sidey; nexta1 <= '0'; nexta0 <= '0'; when s_sidey => nextState <= s_maing1; nexta1 <= '0'; nexta0 <= '1'; when s_blinkon => nextState <= s_blinkoff; nexta1 <= '1'; nexta0 <= '1'; when s_blinkoff => nextState <= s_blinkon; nexta1 <= '1'; nexta0 <= '1'; when others => nextState <= s_blinkon; nexta1 <= '1'; nexta0 <= '1'; end case; end if; end if; end process fsm; -- purpose: transition states on rising edge and start timer when expired -- type : combinational -- inputs : clk, exp -- outputs: curState, starttimer state_clocked: process (clk) begin -- process state_clocked if rising_edge(clk) then if expire = '1' or gosync = '1' or reset = '1' or curState = s_idle or curState = s_read or curstate = s_write then curState <= nextState; a0 <= nexta0; a1 <= nexta1; if nextState = s_idle or nextState = s_read or nextState = s_write then resettimer <= '1'; starttimer <= '0'; else starttimer <= '1'; resettimer <= '0'; end if; else starttimer <= '0'; end if; end if; end process state_clocked; -- purpose: set outputs for current state -- type : combinational -- inputs : curState -- outputs: mr, my, mg, sr, sy, sg, n_we, latchreset set_outputs: process (curState) begin -- process set_outputs case curState is when s_idle => mr <= '0'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '1'; stateout <= "0000"; when s_read => mr <= '0'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '1'; stateout <= "0001"; when s_write => mr <= '0'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '0'; n_we <= '0'; latchreset <= '1'; stateout <= "0010"; when s_maing1 => mr <= '0'; my <= '0'; mg <= '1'; sr <= '1'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "0011"; when s_maing2 => mr <= '0'; my <= '0'; mg <= '1'; sr <= '1'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "0100"; when s_mainy => mr <= '0'; my <= '1'; mg <= '0'; sr <= '1'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "0101"; when s_walk => mr <= '1'; my <= '1'; mg <= '0'; sr <= '1'; sy <= '1'; sg <= '0'; n_we <= '1'; latchreset <= '1'; stateout <= "0110"; when s_sideg => mr <= '1'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '1'; n_we <= '1'; latchreset <= '0'; stateout <= "0111"; when s_sideext => mr <= '1'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '1'; n_we <= '1'; latchreset <= '0'; stateout <= "1000"; when s_sidey => mr <= '1'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '1'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "1001"; when s_blinkon => mr <= '0'; my <= '1'; mg <= '0'; sr <= '1'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "1010"; when s_blinkoff => mr <= '0'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "1011"; when others => mr <= '0'; my <= '0'; mg <= '0'; sr <= '0'; sy <= '0'; sg <= '0'; n_we <= '1'; latchreset <= '0'; stateout <= "1100"; end case; end process set_outputs; end behavioral;