106 lines
3.0 KiB
VHDL
106 lines
3.0 KiB
VHDL
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;
|