library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.procdefs.all; entity alu is port ( clk : in std_logic; rst : in std_logic; -- Test enable signal ten : in std_logic; -- Test data input tdi : in std_logic; -- Test data output tdo : out std_logic; -- enables the alu en : in std_logic; -- result selector rss : in std_logic_vector(1 downto 0); -- indicates whether to perform a subtraction sub : in std_logic; -- data input din : in std_logic_vector(bit_wd-1 downto 0); -- accumulator value acc : out std_logic_vector(bit_wd-1 downto 0) ); end entity alu; architecture RTL of alu is signal int_acc : std_logic_vector(bit_wd-1 downto 0); -- TODO: Define range of input register signal int_input_reg : std_logic_vector(...); constant extension : std_logic_vector(bit_wd-2 downto 0) := (others => '0'); begin acc <= int_acc; -- TODO: assign last bit of the scan chain (acc or int_input_reg depending on your solution) tdo <= name : process (clk, rst) is -- adder result variable addrs : unsigned(bit_wd-1 downto 0); -- adder input for variable addri : unsigned(bit_wd-1 downto 0); -- Variables for the ease of variable int_din : std_logic_vector(din'range); variable int_rss : std_logic_vector(rss'range); variable int_en : std_logic; variable int_sub : std_logic; begin if rst = '1' then int_acc <= (others => '0'); int_input_reg <= (others => '0'); elsif rising_edge(clk) then if ten = '0' then -- TODO: Assign the input to the input register int_input_reg <= ... -- TODO: Assign variables according to the above assignment int_din := ... int_rss := ... int_sub := ... int_en := ... if int_input_reg(1) = '1' then addri := not unsigned(int_din); else addri := unsigned(int_din); end if; addrs := unsigned(int_acc) + addri + unsigned(extension & int_sub); if int_en = '1' then case int_rss is when "00" => int_acc <= int_din; when "01" => -- update acc with adder result int_acc <= std_logic_vector(addrs); when "10" => int_acc(bit_wd-1 downto bit_wd/2) <= int_din(bit_wd/2-1 downto 0); int_acc(bit_wd/2-1 downto 0) <= (others => '0'); when others => -- perform OR of acc and lower bits of din int_acc(bit_wd/2-1 downto 0) <= int_acc(bit_wd/2-1 downto 0) or int_din(bit_wd/2-1 downto 0); end case; end if; else -- TODO: connect both input register and the accumulator to a shift register, perform left-shift where the rightmost bit is the tdi end if; -- ten = '0' end if; end process name; end architecture RTL;