------------------------------------------------------------------------------- -- -- control.vhd: control finite state machine -- Dan R. K. Ports -- 6.111 final project, 2003/12/08 -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_signed.all; entity control is port ( reset, clk : in std_logic; adtest, ffttest : in std_logic; adstart, fftstart, ifstart : out std_logic; adbusy, fftbusy, ifbusy : in std_logic; fftinverse : out std_logic; adcbufsel, dacbufsel, fftinbufsel, fftoutbufsel, ifsendbufsel, ifrecvbufsel : out std_logic_vector(2 downto 0)); end control; architecture behavioral of control is type StateType is (s_Idle, s_Start, s_Wait1, s_StartIFFT, s_Wait2, s_Rotate); signal curState, nextState : StateType := s_Idle; signal adcbuf, dacbuf, fftinbuf, fftoutbuf, ifftinbuf, ifftoutbuf, ifsendbuf, ifrecvbuf : std_logic_vector(2 downto 0); signal rotatestate : std_logic := '0'; begin -- behavioral -- purpose: determine next state -- type : combinational -- inputs : curState, adbusy, fftbusy, ifbusy -- outputs: nextState next_state: process (curState, adbusy, fftbusy, ifbusy) begin -- process next_state if reset = '1' then nextState <= s_Rotate; else case curState is when s_Idle => nextState <= s_Start; when s_Start => if adbusy = '1' and (fftbusy = '1' or adtest = '1') and (ifbusy = '1' or adtest = '1' or ffttest = '1') then nextState <= s_Wait1; else nextState <= s_Start; end if; when s_Wait1 => if fftbusy = '0' or adtest = '1' then nextState <= s_StartIFFT; else nextState <= s_Wait1; end if; when s_StartIFFT => if fftbusy = '1' or adtest = '1' then nextState <= s_Wait2; else nextState <= s_StartIFFT; end if; when s_Wait2 => if adbusy = '0' and (fftbusy = '0' or adtest = '1') and (ifbusy = '0' or adtest = '1' or ffttest = '1') then nextState <= s_Rotate; else nextState <= s_Wait2; end if; when s_Rotate => nextState <= s_Start; when others => nextState <= s_Idle; end case; end if; end process next_state; -- purpose: perform state transitions and buffer rotations -- type : combinational -- inputs : clk -- outputs: curState, bufsels state_clocked: process (clk) begin -- process state_clocked if rising_edge(clk) then curState <= nextState; if nextState = s_Rotate then if adtest = '1' then if rotatestate = '0' or reset = '1' then adcbuf <= "000"; dacbuf <= "001"; rotatestate <= '1'; else adcbuf <= "001"; dacbuf <= "000"; rotatestate <= '0'; end if; elsif ffttest = '1' then if rotatestate = '0' or reset = '1' then adcbuf <= "000"; dacbuf <= "001"; fftinbuf <= "111"; fftoutbuf <= "011"; ifftinbuf <= "100"; ifftoutbuf <= "010"; rotatestate <= '1'; else adcbuf <= "111"; dacbuf <= "010"; fftinbuf <= "000"; fftoutbuf <= "100"; ifftinbuf <= "011"; ifftoutbuf <= "001"; rotatestate <= '0'; end if; else if rotatestate = '0' or reset = '1' then adcbuf <= "000"; dacbuf <= "001"; fftinbuf <= "111"; fftoutbuf <= "110"; ifftinbuf <= "100"; ifftoutbuf <= "010"; ifsendbuf <= "101"; ifrecvbuf <= "011"; rotatestate <= '1'; else adcbuf <= "111"; dacbuf <= "010"; fftinbuf <= "000"; fftoutbuf <= "101"; ifftinbuf <= "011"; ifftoutbuf <= "001"; ifsendbuf <= "110"; ifrecvbuf <= "100"; rotatestate <= '0'; end if; end if; end if; end if; end process state_clocked; adcbufsel <= adcbuf; dacbufsel <= dacbuf; fftinbufsel <= ifftinbuf when curState = s_StartIFFT or curState = s_Wait2 else fftinbuf; fftoutbufsel <= ifftoutbuf when curState = s_StartIFFT or curState = s_Wait2 else fftoutbuf; fftinverse <= '1' when curState = s_StartIFFT or curState = s_Wait2 else '0'; ifsendbufsel <= ifsendbuf; ifrecvbufsel <= ifrecvbuf; adstart <= '1' when curState = s_Start else '0'; ifstart <= '1' when curState = s_Start and adtest = '0' and ffttest = '0' else '0'; fftstart <= '1' when (curState = s_Start or curState = s_StartIFFT) and adtest = '0' else '0'; end behavioral;