library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.ALL; entity alu is generic ( WIDTH: integer := 8; FIRST: boolean := true ); port ( func: in std_logic_vector(3 downto 0); accu: in std_logic_vector(WIDTH-1 downto 0); ram: in std_logic_vector(WIDTH-1 downto 0); carry_in: in std_logic; result: out std_logic_vector(WIDTH-1 downto 0); carry_out: out std_logic ); end alu; architecture rtl of alu is signal x: std_logic_vector(WIDTH-1 downto 0); signal y: std_logic_vector(WIDTH-1 downto 0); signal cin: std_logic; signal sum: std_logic_vector(WIDTH-1 downto 0); signal cout: std_logic; begin adder: entity work.adder generic map ( WIDTH => WIDTH ) port map ( x => x, y => y, cin => cin, sum => sum, cout => cout ); process(func, accu, ram, carry_in, sum, cout) variable carry: std_logic; begin -- This default value will be overwritten in the add/sub cases carry_out <= '0'; -- Avoid generating latches by leaving the adder inputs unspecified -- when it is not beeing used (otherwise these are overwritten) x <= (others => '-'); y <= (others => '-'); cin <= '-'; case func is when "0000" => -- STORE result <= accu; when "0001" => -- LOAD result <= ram; when "0010" => -- JMP result <= (others => '-'); when "0011" => -- ADD x <= accu; y <= ram; cin <= carry_in; result <= sum; carry_out <= cout; when "0100" => -- SUB x <= accu; y <= not ram; cin <= not carry_in; result <= sum; carry_out <= not cout; when "0101" => -- OR result <= accu or ram; when "0110" => -- AND result <= accu and ram; when "0111" => -- XOR result <= accu xor ram; when "1000" => -- NOT result <= not accu; when "1001" => -- INC x <= accu; y <= (others => '0'); if FIRST then cin <= '1'; else cin <= carry_in; end if; result <= sum; carry_out <= cout; when "1010" => -- DEC x <= accu; y <= (others => '1'); if FIRST then cin <= '0'; else cin <= not carry_in; end if; result <= sum; carry_out <= not cout; when "1011" => -- ZERO result <= (others => '0'); when others => -- NOPs result <= (others => '-'); end case; end process; end rtl;