synth/first/alu.vhdl

71 lines
1.7 KiB
VHDL
Raw Normal View History

2021-02-17 21:20:30 +00:00
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity alu is
port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
sel: in std_logic_vector(3 downto 0);
flag: out std_logic;
q: out std_logic_vector(15 downto 0)
);
end alu;
architecture behavior of alu is
begin
process(a, b, sel) is
variable tmp: std_logic_vector(31 downto 0);
variable idx: natural;
begin
q <= x"0000";
flag <= '0';
tmp := x"00000000";
idx := 0;
case sel is
when "0011" => -- q = a + b, flag is carry
tmp(16 downto 0) := std_logic_vector(unsigned('0' & a) + unsigned(b));
q <= tmp(15 downto 0);
flag <= tmp(16);
when "0100" => -- q = a - b, flag if a < b
tmp(16 downto 0) := std_logic_vector(unsigned('1' & a) - unsigned(b));
q <= tmp(15 downto 0);
flag <= not tmp(16);
when "0101" => q <= a or b;
when "0110" => q <= a and b;
when "0111" => q <= not a;
when "1000" => q <= a xor b;
when "1001" => -- left shift by 1
q <= a(14 downto 0) & '0';
flag <= a(15);
when "1010" => -- right shift by b(3 downto 0)
idx := to_integer(unsigned(b(3 downto 0)));
tmp(15 - idx downto 0) := a(15 downto idx);
q <= tmp(15 downto 0);
flag <= a(0);
when "1011" => -- q = a * b
--tmp := std_logic_vector(unsigned(a) * unsigned(b));
q <= tmp(15 downto 0);
when "1100" => -- flag if a = b
if (a = b) then
flag <= '1';
else
flag <= '0';
end if;
--- room for a few more things:
-- - rotate
-- - not / nand
-- - gt...
when others =>
-- do nothing
end case;
end process;
end behavior;