-- adfsm.vhd: analog/digital control FSM -- 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 adfsm is port ( clk, start : in std_logic; reset : in std_logic; timerClk : in std_logic; busy : out std_logic; ADCRead, n_DACEnable : out std_logic; ADCStatus : in std_logic; ramwe : out std_logic; cntenable : out std_logic); end adfsm; architecture behavioral of adfsm is type StateType is (s_Idle, s_WaitForTimer, s_DACWrite, s_ADCEnable, s_ADCWait, s_ADCRead, s_AddrInc, s_CountInc); signal curState, nextState : StateType := s_Idle; signal i, nexti : std_logic_vector(3 downto 0); -- iterator for multi-cycle waits signal count : std_logic_vector(10 downto 0); begin -- behavioral -- purpose: select next state -- type : combinational -- inputs : curState, ADCStatus, start -- outputs: nextState, nexti next_state: process (curState, ADCStatus, start, i) begin -- process next_state if reset = '1' then nextState <= s_Idle; else case curState is when s_Idle => if start = '1' then nextState <= s_WaitForTimer; else nextState <= s_Idle; end if; when s_WaitForTimer => if timerClk = '1' then nextState <= s_DACWrite; nexti <= "0010"; else nextState <= s_WaitForTimer; end if; when s_DACWrite => if i = 0 then nextState <= s_ADCEnable; else nextState <= s_DACWrite; nexti <= i-i; end if; when s_ADCEnable => if ADCStatus = '1' then nextState <= s_ADCWait; nexti <= "0011"; 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 <= "0011"; end if; when s_ADCRead => nextState <= s_AddrInc; nexti <= "0001"; when s_AddrInc => if i = 0 then nextState <= s_CountInc; else nexti <= i-1; nextState <= s_AddrInc; end if; when s_CountInc => if count = 0 then nextState <= s_Idle; else nextState <= s_WaitForTimer; end if; when others => nextState <= s_Idle; end case; end if; end process next_state; -- purpose: update state 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_CountInc then count <= count + 1; elsif nextState = s_Idle then count <= (others => '0'); end if; end if; end process state_clocked; n_DACEnable <= '0' when curState = s_DACWrite else '1'; cntenable <= '1' when curState = s_AddrInc else '0'; ramwe <= '1' when curState = s_ADCRead else '0'; ADCRead <= '0' when curState = s_ADCEnable else '1'; busy <= '0' when curState = s_Idle else '1'; end behavioral;