-- interfacefsm.vhd: FSM for controlling parallel bus interface -- Dan R. K. Ports -- 6.111 final project, 2003/12/01 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity interfacefsm is port ( start : in std_logic; reset : in std_logic; busy : out std_logic; clk : in std_logic; fftsending : out std_logic; procsending : in std_logic; rdy : inout std_logic; ack1 : inout std_logic; ack2 : in std_logic; ctrenable : out std_logic; readenable, writeenable : out std_logic); end interfacefsm; architecture behavioral of interfacefsm is type StateType is (s_Idle, s_SendStart, s_SendAddrSelect, s_SendRAMWait, s_SendReady, s_SendAck, s_SendComplete, s_RecvWait, s_WriteAddrSelect, s_Write, s_RecvAck); signal curState, nextState : StateType := s_Idle; signal count : std_logic_vector(1 downto 0); begin -- behavioral -- purpose: determine next state -- type : combinational -- inputs : curState, count, procsending, rdy, ack1, ack2, reset -- outputs: nextState newState: process (curState, count, procsending, rdy, ack1, ack2, reset) begin -- process newState if reset = '1' then nextState <= s_Idle; else case curState is when s_Idle => if start = '1' then nextState <= s_SendStart; else nextState <= s_Idle; end if; when s_SendStart => nextState <= s_SendRAMWait; when s_SendRAMWait => nextState <= s_SendReady; when s_SendReady => if ack1 = '1' and ack2 = '1' then nextState <= s_SendAck; else nextState <= s_SendReady; end if; when s_SendAck => if ack1 = '0' and ack2 = '0' then nextState <= s_SendAddrSelect; else nextState <= s_SendAck; end if; when s_SendAddrSelect => -- if count = "1111111111" then if count = "00" then nextState <= s_SendComplete; else nextState <= s_SendReady; end if; when s_SendComplete => if procsending = '1' then nextState <= s_RecvWait; else nextState <= s_SendComplete; end if; when s_RecvWait => if procsending = '0' then nextState <= s_Idle; else if rdy = '1' then nextState <= s_WriteAddrSelect; else nextState <= s_RecvWait; end if; end if; when s_WriteAddrSelect => nextState <= s_Write; when s_Write => nextState <= s_RecvAck; when s_RecvAck => if rdy = '0' then if procsending = '0' then nextState <= s_Idle; else nextState <= s_RecvWait; end if; else nextState <= s_RecvAck; end if; when others => nextState <= s_Idle; end case; end if; end process newState; -- purpose: update current state on clock rising edge -- type : combinational -- inputs : clk, nextState -- outputs: curState state_clocked: process (clk) begin -- process state_clocked if rising_edge(clk) then curState <= nextState; if nextState = s_SendAddrSelect or nextState = s_WriteAddrSelect then count <= count + 1; elsif nextState = s_Idle then count <= (others => '0'); end if; end if; end process state_clocked; -- purpose: generate output values -- type : combinational -- inputs : curState -- outputs: busy, fftsending, ctrenable, readenable, writeenable -- gen_outputs: process (curState) -- begin -- process gen_outputs busy <= '0' when curState = s_Idle else '1'; fftsending <= '1' when curState = s_SendStart or curState = s_SendAddrSelect or curState = s_SendReady or curState = s_SendAck or curState = s_SendRAMWait else '0'; readenable <= '1' when curState = s_SendStart or curState = s_SendAddrSelect or curState = s_SendReady or curState = s_SendAck or curState = s_SendRAMWait else '0'; with curState select rdy <= '0' when s_SendStart, '0' when s_SendRAMWait, '0' when s_SendAck, '0' when s_SendAddrSelect, '1' when s_SendReady, 'Z' when others; with curState select ack1 <= '0' when s_WriteAddrSelect, '0' when s_Write, '0' when s_RecvWait, '1' when s_RecvAck, 'Z' when others; ctrenable <= '1' when curState = s_SendAddrSelect or curState = s_WriteAddrSelect else '0'; writeenable <= '1' when curState = s_Write else '0'; -- end process gen_outputs; end behavioral;