71 lines
1.7 KiB
VHDL
71 lines
1.7 KiB
VHDL
|
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;
|