-- fsm-analog.vhd: controller finite state machine for analog checkoff -- Dan R. K. Ports -- 6.111 Lab 3, 2003/10/15 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; Dout : out std_logic_vector(7 downto 0); 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); signal curState, nextState : StateType := s_WaitForTimer; signal i, nexti : std_logic_vector(7 downto 0); -- iterator for multi-cycle waits signal Dbuf : std_logic_vector(7 downto 0); begin -- behavioral Dout <= Dbuf; -- 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' then nextState <= s_ADCWait; nexti <= "00000011"; else nextState <= s_ADCEnable; end if; when s_ADCWait => if ADCStatus = '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_WaitForTimer; when others => nextState <= s_WaitForTimer; end case; end if; end process newState; -- purpose: grab input value -- type : combinational -- inputs : curState, D -- outputs: Dbuf getinput: process (curState, D) begin -- process getinput if curState = s_ADCRead then Dbuf <= D; 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; 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'); when s_DACWrite => ADCRead <= '1'; n_DACEnable <= '0'; n_ADCEnable <= '1'; D <= Dbuf; when s_ADCEnable => ADCRead <= '0'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; when s_ADCWait => ADCRead <= '1'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; when s_ADCRead => ADCRead <= '1'; n_DACEnable <= '1'; D <= (others => 'Z'); n_ADCEnable <= '0'; -- Dbuf <= D; when others => ADCRead <= '1'; n_DACEnable <= '1'; n_ADCEnable <= '1'; D <= (others => 'Z'); end case; end process gen_outputs; end behavioral;