------------------------------------------------------------------------------- -- -- 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; n_ADCEnable : out std_logic; ADCStatus : in std_logic; ramwe : out std_logic; ramaddr : out std_logic_vector(13 downto 0); ramdatain : in std_logic_vector(7 downto 0); ramdataout : out std_logic_vector(7 downto 0); adcbufsel : in std_logic_vector(2 downto 0); dacbufsel : in std_logic_vector(2 downto 0); ramreq : out std_logic; ramdone : in std_logic; adbus : inout std_logic_vector(7 downto 0)); end adfsm; architecture behavioral of adfsm is type StateType is (s_Idle, s_WaitForTimer, s_RAMRead, s_DACWrite, s_ADCEnable, s_ADCWait, s_ADCRead, s_RAMWrite, s_AddrInc, s_RAMWrite2, s_AddrInc2); 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); signal buf : std_logic_vector(7 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_RAMRead; else nextState <= s_WaitForTimer; end if; when s_RAMRead => if ramdone = '1' then nextState <= s_DACWrite; nexti <= "0010"; else nextState <= s_RAMRead; nexti <= i; 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_RAMWrite; nexti <= "0001"; when s_AddrInc => nextState <= s_RAMWrite2; when s_RAMWrite => if ramdone = '1' then nextState <= s_AddrInc; else nextState <= s_RAMWrite; end if; when s_RAMWrite2 => if ramdone = '1' then nextState <= s_AddrInc2; else nextState <= s_RAMWrite2; end if; when s_AddrInc2 => 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_AddrInc or nextState = s_AddrInc2 then count <= count + 1; elsif nextState = s_Idle then count <= (others => '0'); end if; if curState = s_RAMRead then buf <= ramdatain; elsif curState = s_ADCRead then buf <= adbus; elsif curState = s_AddrInc then buf <= (others => '0'); end if; end if; end process state_clocked; n_DACEnable <= '0' when curState = s_DACWrite else '1'; ramwe <= '1' when curState = s_RAMWrite or curState = s_RAMWrite2 else '0'; ADCRead <= '0' when curState = s_ADCEnable else '1'; busy <= '0' when curState = s_Idle else '1'; n_ADCEnable <= '0' when curState = s_ADCEnable or curState = s_ADCWait or curState = s_ADCRead else '1'; ramdataout <= buf; -- purpose: generate adbus output -- type : combinational -- inputs : curState -- outputs: adbus adbusout: process (curState) begin -- process adbusout if curState = s_DACWrite then adbus <= (not buf(7)) & buf(6 downto 0); else adbus <= (others => 'Z'); end if; end process adbusout; ramaddr <= dacbufsel & count when curState = s_RAMRead else adcbufsel & count; ramreq <= '1' when curState = s_RAMRead or curState = s_RAMWrite or curState = s_RAMWrite2 else '0'; end behavioral;