mirror of
https://github.com/Lemonochrme/vhdl_processor.git
synced 2025-06-08 08:50:49 +02:00
86 lines
2.8 KiB
VHDL
86 lines
2.8 KiB
VHDL
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
use IEEE.STD_LOGIC_ARITH.ALL;
|
|
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
|
|
|
entity alu is
|
|
port(
|
|
a: in STD_LOGIC_VECTOR(7 downto 0);
|
|
b: in STD_LOGIC_VECTOR(7 downto 0);
|
|
op: in STD_LOGIC_VECTOR(2 downto 0);
|
|
s: out STD_LOGIC_VECTOR(7 downto 0);
|
|
flags : out STD_LOGIC_VECTOR(3 downto 0)
|
|
);
|
|
end alu;
|
|
|
|
-- Flags
|
|
-- C -> Carry (bit 0)
|
|
-- N -> Negative (bit 1)
|
|
-- Z -> Zero (bit 2)
|
|
-- O -> Overflow (when using MUL) (bit 3)
|
|
|
|
-- Operation Bits (OP2, OP1, OP0) Operation
|
|
-- 000 ADD
|
|
-- 001 SUB
|
|
-- 010 AND
|
|
-- 011 OR
|
|
-- 100 XOR
|
|
-- 101 NOT (return 0x1 if true, else return 0x0)
|
|
-- 110 MUL
|
|
|
|
architecture behavior_alu of alu is
|
|
-- Internal variables
|
|
shared variable buffer_s_16 : STD_LOGIC_VECTOR(15 downto 0);
|
|
shared variable buffer_s : STD_LOGIC_VECTOR(7 downto 0);
|
|
shared variable carry_s : STD_LOGIC_VECTOR(8 downto 0);
|
|
shared variable buffer_flags : STD_LOGIC_VECTOR(3 downto 0);
|
|
|
|
begin
|
|
process(a, b, op) is
|
|
begin
|
|
buffer_flags := "0000";
|
|
case op is
|
|
when "000" =>
|
|
-- calculcating a + b by concatening 8 bits to 9 bits and checking the MSB
|
|
carry_s := ('0' & a) + ('0' & b);
|
|
buffer_s := carry_s(7 downto 0);
|
|
buffer_flags(0) := carry_s(8);
|
|
-- Checking negative
|
|
if (SIGNED(buffer_s) < (0)) then
|
|
buffer_flags(1) := '1';
|
|
end if;
|
|
when "001" =>
|
|
carry_s := ('0' & a) - ('0' & b);
|
|
buffer_s := carry_s(7 downto 0);
|
|
-- borrowing when negative
|
|
buffer_flags(1) := carry_s(8);
|
|
when "010" =>
|
|
buffer_s := a AND b;
|
|
when "011" =>
|
|
buffer_s := a OR b;
|
|
when "100" =>
|
|
buffer_s := a XOR b;
|
|
when "101" =>
|
|
buffer_s := NOT a;
|
|
when "110" =>
|
|
buffer_s_16 := (a * b);
|
|
buffer_s := buffer_s_16(7 downto 0);
|
|
-- In the context of a multiplication overflow can be interpreted in two manners
|
|
-- A basic overflow for both signed/unsigned. A negative flag for signed.
|
|
if (buffer_s_16 > X"FF") then
|
|
buffer_flags(3) := '1';
|
|
end if;
|
|
when others =>
|
|
buffer_s := "00000000";
|
|
end case;
|
|
|
|
-- checking for 0 value
|
|
if (buffer_s = 0) then
|
|
buffer_flags(2) := '1';
|
|
end if;
|
|
|
|
-- Writing from the buffer to the output
|
|
s <= buffer_s;
|
|
flags <= buffer_flags;
|
|
end process;
|
|
end behavior_alu;
|