-- convolver.vhd: convolver finite state machine -- Dan R. K. Ports -- 6.111 Lab 3, 2003/10/22 library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity convolver is port ( clk : in std_logic; start : in std_logic; reset : in std_logic; busy : out std_logic; inputaddr : in std_logic_vector(3 downto 0); multstart : out std_logic; multbusy : in std_logic; multresult : in std_logic_vector(14 downto 0); romaddr, ramaddr : out std_logic_vector(3 downto 0); result : out std_logic_vector(7 downto 0)); end convolver; architecture behavioral of convolver is type statetype is (s_idle, s_addrselect, s_startmult, s_waitmult, s_output); signal curState, nextState : statetype; signal baseaddr : std_logic_vector(3 downto 0); signal i : std_logic_vector(3 downto 0); signal accumulator : std_logic_vector(14 downto 0); begin -- behavioral -- purpose: generate next state -- type : combinational -- inputs : curState, multbusy, start, i -- outputs: nextState gennextstate: process (curState, multbusy, start, i) begin -- process nextstate if reset = '1' then nextState <= s_idle; else case curState is when s_idle => if start = '1' then nextState <= s_addrselect; else nextState <= s_idle; end if; when s_addrselect => nextState <= s_startmult; when s_startmult => if multbusy = '1' then nextState <= s_waitmult; else nextState <= s_startmult; end if; when s_waitmult => if multbusy = '0' then if i = 15 then nextState <= s_output; else nextState <= s_addrselect; end if; else nextState <= s_waitmult; end if; when s_output => nextState <= s_idle; when others => nextState <= s_idle; end case; end if; end process gennextstate; -- purpose: perform state transitions and outputs -- type : combinational -- inputs : clk -- outputs: curState, i, accumulator, romaddr, ramaddr state_clocked: process (clk) begin -- process state_clocked if rising_edge(clk) then curState <= nextState; case nextState is when s_idle => i <= (others => '0'); accumulator <= (others => '0'); multstart <= '0'; busy <= '0'; ramaddr <= (others => '0'); when s_addrselect => multstart <= '0'; busy <= '1'; if curState = s_waitmult then i <= i + 1; ramaddr <= baseaddr - i - 1; romaddr <= i + 1; accumulator <= accumulator + multresult; else i <= (others => '0'); baseaddr <= inputaddr; romaddr <= (others => '0'); ramaddr <= inputaddr; end if; when s_startmult => multstart <= '1'; busy <= '1'; when s_waitmult => multstart <= '0'; busy <= '1'; when s_output => multstart <= '0'; busy <= '1'; result <= accumulator(14 downto 7); ramaddr <= (others => '0'); when others => null; end case; end if; end process state_clocked; end behavioral;