computer/firmware/alu/alu.vhd

106 lines
3.0 KiB
VHDL
Raw Permalink Normal View History

2018-02-15 19:23:44 +01:00
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
entity alu is
2018-02-15 19:23:44 +01:00
generic (
WIDTH: integer := 8;
FIRST: boolean := true
2018-02-15 19:23:44 +01:00
);
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;
2018-02-15 19:23:44 +01:00
architecture rtl of alu is
2018-02-15 19:23:44 +01:00
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;
2018-02-15 19:23:44 +01:00
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;
2018-02-15 19:23:44 +01:00
result <= sum;
carry_out <= not cout;
when "1011" => -- ZERO
result <= (others => '0');
when others => -- NOPs
result <= (others => '-');
end case;
end process;
end rtl;