library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity alu is port( a: in std_logic_vector(15 downto 0); b: in std_logic_vector(15 downto 0); sel: in std_logic_vector(3 downto 0); flag: out std_logic; q: out std_logic_vector(15 downto 0) ); end alu; architecture behavior of alu is begin process(a, b, sel) is variable tmp: std_logic_vector(31 downto 0); variable idx: natural; begin q <= x"0000"; flag <= '0'; tmp := x"00000000"; idx := 0; case sel is when "0011" => -- q = a + b, flag is carry tmp(16 downto 0) := std_logic_vector(unsigned('0' & a) + unsigned(b)); q <= tmp(15 downto 0); flag <= tmp(16); when "0100" => -- q = a - b, flag if a < b tmp(16 downto 0) := std_logic_vector(unsigned('1' & a) - unsigned(b)); q <= tmp(15 downto 0); flag <= not tmp(16); when "0101" => q <= a or b; when "0110" => q <= a and b; when "0111" => q <= not a; when "1000" => q <= a xor b; when "1001" => -- left shift by 1 q <= a(14 downto 0) & '0'; flag <= a(15); when "1010" => -- right shift by b(3 downto 0) idx := to_integer(unsigned(b(3 downto 0))); tmp(15 - idx downto 0) := a(15 downto idx); q <= tmp(15 downto 0); flag <= a(0); when "1011" => -- q = a * b --tmp := std_logic_vector(unsigned(a) * unsigned(b)); q <= tmp(15 downto 0); when "1100" => -- flag if a = b if (a = b) then flag <= '1'; else flag <= '0'; end if; --- room for a few more things: -- - rotate -- - not / nand -- - gt... when others => -- do nothing end case; end process; end behavior;