SimpleProcessorCore/src/ALU.vhd

117 lines
3.7 KiB
VHDL

-------------------------------------------------------
--! @file
--! @brief Simple ALU for the Simple Processor Core (Geraffel Processor)
--! @author Dominik Meyer/ Marcel Eckert
--! @email dmeyer@federationhq.de
--! @licence GPLv2
--! @date unknown
-------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
library work;
use work.cpupkg.all;
--! A very Simple ALU to support all the arithmetical and logical operation of the
--! Simple Processor Core (Geraffel Processor Core)
--!
--! This Code is based on a processor core used at the Helmut Schmidt University for
--! educational purposes.
--!
entity ALU is
port(
idOperand1 : in DATA; --! first Operand for any operation
idOperand2 : in DATA; --! second Operand for any operation
idCarryIn : in std_logic; --! Carry Input for any arithmetical operation
idImmidiate : in DATA; --! Immediate input for operation requiring an immediat
odResult : out DATA; --! Result output of any operation
odCarryOut : out std_logic; --! Output of the Carry, if generated by an operation
odZeroOut : out std_logic; --! is the result zero flag output
icOperation : in OPTYPE --! which Operation to perform
);
end ALU;
--! Architectural description of the ALU
architecture Behavioral of ALU is
signal sdTempResult, sdOp1, sdOp2 : std_logic_vector(32 downto 0);
begin
-- extend the operand by one bit, to be able to get the overflow
-- of an operation
sdOp1 <= '0' & idOperand1;
sdOp2 <= '0' & idOperand2;
--! process to do the actual computation
process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1)
begin
-- TODO: convert to case structure for improved space usege and speed
if (icOperation = shl) then
sdTempResult <= sdOp1(31 downto 0) & "0";
elsif (icOperation = shr) then
sdTempResult <= sdOp1(0) & "0" & sdOp1(31 downto 1);
elsif (icOperation = sto) then
sdTempResult <= (others => '-');
elsif (icOperation = loa) then
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = li) then
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = add) then
sdTempResult <= sdOp1 + sdOp2;
elsif (icOperation = sub) then
sdTempResult <= sdOp1 - sdOp2;
elsif (icOperation = addc) then
sdTempResult <= sdOp1 + sdOp2 + ("0000000000000000" & idCarryIn);
elsif (icOperation = subc) then
sdTempResult <= sdOp1 - sdOp2 - ("0000000000000000" & idCarryIn);
elsif (icOperation = opor) then
sdTempResult <= sdOp1 or sdOp2;
elsif (icOperation = opand) then
sdTempResult <= sdOp1 and sdOp2;
elsif (icOperation = opxor) then
sdTempResult <= sdOp1 xor sdOp2;
elsif (icOperation = opnot) then
sdTempResult <= not sdOp1;
elsif (icOperation = jpz) then
sdTempResult <= (others => '-');
elsif (icOperation = jpc) then
sdTempResult <= (others => '-');
elsif (icOperation = jmp) then
sdTempResult <= (others => '-');
else -- (icOperation = hlt)
sdTempResult <= (others => '-');
end if;
end process;
-- output the generated signals
odResult <= sdTempResult(31 downto 0);
odCarryOut <= sdTempResult(32);
odZeroOut <= '1' when sdTempResult(31 downto 0) = 0 else
'0';
end Behavioral;