computer/firmware/alu/main.vhd
Max Braungardt a1bebb977e Fix INC and DEC by specifying if alu is the first one
If it is not the first, only increment or decrement when carry or
borrow is set.
2018-04-26 20:09:04 +02:00

106 lines
3.0 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
entity main 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 main;
architecture rtl of main 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;