library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity alu is Port ( inp_a : in signed(3 downto 0); inp_b : in signed(3 downto 0); --- sel = M S3 S2 S1 S0 */ sel : in STD_LOGIC_VECTOR (3 downto 0); carry_in : in std_logic; --- carry_out O3 O2 O1 O0 */ out_alu_tmp : buffer signed(4 downto 0); out_alu : out signed(4 downto 0); --- fast carry */ p : out std_logic; --- propagate */ g : out std_logic --- generate */ ); end alu; architecture Behavioral of alu is begin process(inp_a, inp_b, sel) begin --- ACTIVE HIGH DATA */ --- sel = M S3 S2 S1 S0 */ case sel is --- LOGIC */ when "00000" => out_alu <= not inp_a; when "00001" => out_alu <= not (inp_a or inp_b); when "00010" => out_alu <= (not inp_a) and inp_b; when "00011" => out_alu <= "0000"; when "00100" => out_alu <= not (inp_a and inp_b); when "00101" => out_alu <= not(inp_b); when "00110" => out_alu <= inp_a xor inp_b; when "00111" => out_alu <= inp_a and not(inp_b); when "01000" => out_alu <= not(inp_a) + inp_b; when "01001" => out_alu <= not(inp_a xor inp_b); when "01010" => out_alu <= inp_b; when "01011" => out_alu <= inp_a and inp_b; when "01100" => out_alu <= "1111"; when "01101" => out_alu <= inp_a or not(inp_b); when "01110" => out_alu <= inp_a or inp_b; when "01111" => out_alu <= inp_a; --- ARITHMETIC - M=0*/ --- assuming carry_in is low */ when "10000" => out_alu <= inp_a; when "10001" => out_alu <= inp_a or inp_b; when "10010" => out_alu <= inp_a or not(inp_b); when "10011" => out_alu <= "1111"; --- -1, 2sCompl*/ when "10100" => out_alu <= inp_a + (inp_a and not(inp_b)); when "10101" => out_alu <= (inp_a or inp_b) + (inp_a and not(inp_b)); when "10110" => out_alu <= inp_a - inp_b - 1; when "10111" => out_alu <= (inp_a and not(inp_b)) - 1; when "11000" => out_alu <= inp_a + (inp_a and inp_b); when "11001" => out_alu <= inp_a + inp_b; when "11010" => out_alu <= (inp_a or not(inp_b)) + (inp_a and inp_b); when "11011" => out_alu <= (inp_a and inp_b) - 1; when "11100" => out_alu <= (inp_a + (inp_a sll 1)); -- A plus shited_A */ when "11101" => out_alu <= (inp_a or inp_b) + inp_a; when "11110" => out_alu <= (inp_a or not(inp_b)) + inp_a; when "11111" => out_alu <= inp_a - 1; when others => NULL; end case; --- add potential carry_in */ if carry_in = '1' then out_alu <= out_alu_tmp + 1; end if; p <= inp_a or inp_b; g <= inp_a and inp_b; end process; end Behavioral;