117 lines
3.7 KiB
VHDL
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;
|