-- fsm.vhd: finite state machine controller -- Dan R. K. Ports -- 6.111 Lab 3, 2003/10/22 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity fsm is port ( n_ADCEnable, ADCRead : out std_logic; -- ADC control ADCStatus : in std_logic; -- ADC status n_DACEnable : out std_logic; -- DAC control reset : in std_logic; clk : in std_logic; timerClk : in std_logic; convolverstart : out std_logic; convolverbusy : in std_logic; convolverresult : in std_logic_vector(7 downto 0); convolverstartaddr : out std_logic_vector(3 downto 0); ramaddr : out std_logic_vector(3 downto 0); ramdata : out std_logic_vector(7 downto 0); ramwe : out std_logic; bypass : in std_logic; D : inout std_logic_vector(7 downto 0)); -- ADC/DAC data bus end fsm; architecture behavioral of fsm is type StateType is (s_WaitForTimer, s_DACWrite, s_ADCEnable, s_ADCWait, s_ADCRead, s_RAMWrite); signal curState, nextState : StateType := s_WaitForTimer; signal i, nexti : std_logic_vector(7 downto 0); -- iterator for multi-cycle waits signal addr : std_logic_vector(3 downto 0); signal inputdata,outputdata : std_logic_vector(7 downto 0); begin -- behavioral -- purpose: determine next state -- type : combinational -- inputs : curState, i, ADCStatus -- outputs: nextState newState: process (curState, i, ADCStatus) begin -- process newState if reset = '1' then nextState <= s_WaitForTimer; else case curState is when s_WaitForTimer => if timerClk = '1' then nextState <= s_DACWrite; nexti <= "00000010"; else nextState <= s_WaitForTimer; end if; when s_DACWrite => if i = 0 then nextState <= s_ADCEnable; else nexti <= i-1; nextState <= s_DACWrite; end if; when s_ADCEnable => if ADCStatus = '1' and convolverbusy = '1' then nextState <= s_ADCWait; nexti <= "00000011"; else nextState <= s_ADCEnable; end if; when s_ADCWait => if ADCStatus = '0' and convolverbusy = '0' then if i = 0 then nextState <= s_ADCRead; else nextState <= s_ADCWait; nexti <= i - 1; end if; else nextState <= s_ADCWait; nexti <= "00000011"; end if; when s_ADCRead => -- nextState <= s_ADCDisable; -- when s_ADCDisable => nextState <= s_RAMWrite; when s_RAMWrite => nextState <= s_WaitForTimer; when others => nextState <= s_WaitForTimer; end case; end if; end process newState; -- purpose: grab input value -- type : combinational -- inputs : curState, D -- outputs: inputdata getinput: process (curState, D) begin -- process getinput if curState = s_ADCRead then inputdata <= D; outputdata <= (not (convolverresult(7)) & convolverresult(6 downto 0)); end if; end process getinput; -- purpose: update current state and i on clock -- type : combinational -- inputs : clk, nextState, nexti -- outputs: curState, i state_clocked: process (clk) begin -- process state_clocked if rising_edge(clk) then curState <= nextState; i <= nexti; if nextState = s_DACWrite and nexti=0 then addr <= addr+1; elsif reset = '1' then addr <= (others => '0'); end if; end if; end process state_clocked; -- purpose: generate output values -- type : combinational -- inputs : curState, D -- outputs: ADCRead, n_ADCEnable, n_DACEnable, D gen_outputs: process (curState) begin -- process gen_outputs case curState is when s_WaitForTimer => ADCRead <= '1'; n_DACEnable <= '1'; n_ADCEnable <= '1'; D <= (others => 'Z'); convolverstart <= '0'; ramwe <= '0'; ramaddr <= (others => '0'); ramdata <= (others => '0'); when s_DACWrite => ADCRead <= '1'; n_DACEnable <= '0'; n_ADCEnable <= '1'; if bypass = '0' then D <= outputdata; else D <= inputdata; end if; convolverstart <= '0'; ramwe <= '0'; ramaddr <= (others => '0'); ramdata <= (others => '0'); when s_ADCEnable => ADCRead <= '0'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; convolverstart <= '1'; convolverstartaddr <= addr - 1; ramwe <= '0'; ramaddr <= (others => '0'); ramdata <= (others => '0'); when s_ADCWait => ADCRead <= '1'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; convolverstart <= '0'; ramwe <= '0'; ramaddr <= (others => '0'); ramdata <= (others => '0'); when s_ADCRead => ADCRead <= '1'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; -- Dbuf <= D; convolverstart <= '0'; ramwe <= '0'; ramaddr <= (others => '0'); ramdata <= (others => '0'); when s_RAMWrite => ADCRead <= '1'; n_DACEnable <= '1'; n_ADCEnable <= '0'; convolverstart <= '0'; ramwe <= '1'; ramaddr <= addr; ramdata <= inputdata; when others => ADCRead <= '1'; n_DACEnable <= '1'; n_ADCEnable <= '1'; D <= (others => 'Z'); end case; end process gen_outputs; end behavioral;