FIX: fixed file headers, added licence, formated code

This commit is contained in:
Dominik Meyer 2013-12-30 14:56:42 +01:00
parent 2ff599262a
commit aa3ed4c103
5 changed files with 727 additions and 740 deletions

View File

@ -1,116 +1,116 @@
---------------------------------------------------------------------------------- -------------------------------------------------------
-- Company: --! @file
-- Engineer: --! @brief Simple ALU for the Simple Processor Core (Geraffel Processor)
-- --! @author Dominik Meyer/ Marcel Eckert
-- Create Date: 15:13:27 05/10/2011 --! @email dmeyer@federationhq.de
-- Design Name: --! @licence GPLv2
-- Module Name: ALU - Behavioral --! @date unknown
-- Project Name: -------------------------------------------------------
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE; library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_UNSIGNED.all;
library work; library work;
use work.cpupkg.all; use work.cpupkg.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.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.
--!
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ALU is entity ALU is
Port( port(
idOperand1 : in DATA; idOperand1 : in DATA; --! first Operand for any operation
idOperand2 : in DATA; idOperand2 : in DATA; --! second Operand for any operation
idCarryIn : in std_logic; idCarryIn : in std_logic; --! Carry Input for any arithmetical operation
idImmidiate : in DATA; idImmidiate : in DATA; --! Immediate input for operation requiring an immediat
odResult : out DATA; --! Result output of any operation
odResult : out DATA; odCarryOut : out std_logic; --! Output of the Carry, if generated by an operation
odCarryOut : out std_logic; odZeroOut : out std_logic; --! is the result zero flag output
odZeroOut : out std_logic; icOperation : in OPTYPE --! which Operation to perform
);
icOperation : in OPTYPE
);
end ALU; end ALU;
architecture Behavioral of ALU is
signal sdTempResult, sdOp1, sdOp2 : std_logic_vector(32 downto 0);
begin
sdOp1 <= '0' & idOperand1;
sdOp2 <= '0' & idOperand2;
process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1) --! Architectural description of the ALU
begin architecture Behavioral of ALU is
if (icOperation = shl) then signal sdTempResult, sdOp1, sdOp2 : std_logic_vector(32 downto 0);
sdTempResult <= sdOp1(31 downto 0) & "0"; begin
elsif (icOperation = shr) then -- extend the operand by one bit, to be able to get the overflow
sdTempResult <= sdOp1(0) & "0" & sdOp1(31 downto 1); -- of an operation
sdOp1 <= '0' & idOperand1;
elsif (icOperation = sto) then sdOp2 <= '0' & idOperand2;
sdTempResult <= (others => '-');
elsif (icOperation = loa) then --! process to do the actual computation
sdTempResult <= '0' & idImmidiate; process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1)
elsif (icOperation = li) then begin
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = add) then -- TODO: convert to case structure for improved space usege and speed
sdTempResult <= sdOp1 + sdOp2;
if (icOperation = shl) then
elsif (icOperation = sub) then sdTempResult <= sdOp1(31 downto 0) & "0";
sdTempResult <= sdOp1 - sdOp2;
elsif (icOperation = shr) then
elsif (icOperation = addc) then sdTempResult <= sdOp1(0) & "0" & sdOp1(31 downto 1);
sdTempResult <= sdOp1 + sdOp2 + ("0000000000000000" & idCarryIn);
elsif (icOperation = sto) then
elsif (icOperation = subc) then sdTempResult <= (others => '-');
sdTempResult <= sdOp1 - sdOp2 - ("0000000000000000" & idCarryIn);
elsif (icOperation = loa) then
elsif (icOperation = opor) then sdTempResult <= '0' & idImmidiate;
sdTempResult <= sdOp1 or sdOp2; elsif (icOperation = li) then
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = opand) then elsif (icOperation = add) then
sdTempResult <= sdOp1 and sdOp2; sdTempResult <= sdOp1 + sdOp2;
elsif (icOperation = opxor) then elsif (icOperation = sub) then
sdTempResult <= sdOp1 xor sdOp2; sdTempResult <= sdOp1 - sdOp2;
elsif (icOperation = opnot) then elsif (icOperation = addc) then
sdTempResult <= not sdOp1; sdTempResult <= sdOp1 + sdOp2 + ("0000000000000000" & idCarryIn);
elsif (icOperation = jpz) then elsif (icOperation = subc) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 - sdOp2 - ("0000000000000000" & idCarryIn);
elsif (icOperation = jpc) then elsif (icOperation = opor) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 or sdOp2;
elsif (icOperation = jmp) then elsif (icOperation = opand) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 and sdOp2;
else -- (icOperation = hlt) elsif (icOperation = opxor) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 xor sdOp2;
end if; elsif (icOperation = opnot) then
end process; sdTempResult <= not sdOp1;
odResult <= sdTempResult(31 downto 0); elsif (icOperation = jpz) then
odCarryOut <= sdTempResult(32); sdTempResult <= (others => '-');
odZeroOut <= '1' when sdTempResult(31 downto 0) = 0 else
'0'; 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; end Behavioral;

View File

@ -1,396 +1,401 @@
------------------------------------------------------- -------------------------------------------------------
--! @file --! @file
--! @brief the control unit of the IIB2 Akkumulator machine --! @brief the control unit for the Simple Processor Core (Geraffel Processor)
--! @author Dominik Meyer --! @author Dominik Meyer
--! @email dmeyer@hsu-hh.de --! @email dmeyer@hsu-hh.de
--! @licence GPLv2
--! @date 2010-11-19 --! @date 2010-11-19
------------------------------------------------------- -------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.std_logic_unsigned.all;
library work; library work;
use work.cpupkg.all; use work.cpupkg.all;
entity Steuerwerk is
--! the control unit for the Simple Processor Core (Geraffel Processor)
--!
--! This Code is based on a processor core used at the Helmut Schmidt University for
--! educational purposes.
--!
entity ControlUnit is
port ( port (
iClk : in std_logic; --! iClk signal iClk : in std_logic; --! iClk signal
iReset : in std_logic; --! iReset signal iReset : in std_logic; --! iReset signal
icOpCode : in optype; --! icOpCode bus icOpCode : in optype; --! icOpCode bus
idCarry : in std_logic; --! carry from register file idCarry : in std_logic; --! carry from register file
idZero : in std_logic; --! zero flag from register file idZero : in std_logic; --! zero flag from register file
ocRnotWRam : out std_logic; --! r_notw to RAM ocRnotWRam : out std_logic; --! r_notw to RAM
ocLoadEn : out std_logic; --! safe result of alu ocLoadEn : out std_logic; --! safe result of alu
ocEnableRAM : out std_logic; --! put akku on databus ocEnableRAM : out std_logic; --! put akku on databus
ocLoadInstr : out std_logic; --! load instruction control signal ocLoadInstr : out std_logic; --! load instruction control signal
ocNextPC : out std_logic; --! increment pc ocNextPC : out std_logic; --! increment pc
ocAddrSel : out std_logic; --! pc on addressbus ocAddrSel : out std_logic; --! pc on addressbus
ocJump : out std_logic; --! do a ocJump ocJump : out std_logic; --! do a ocJump
ocPCregister : out std_logic; --! put PC to register File ocPCregister : out std_logic; --! put PC to register File
ocUsePC : out std_logic; --! use Register to fill in the PC ocUsePC : out std_logic; --! use Register to fill in the PC
ocLoad : out std_logic --! put databus to ALU immediate port ocLoad : out std_logic --! put databus to ALU immediate port
); );
end Steuerwerk; end ControlUnit;
architecture arch of Steuerwerk is architecture arch of ControlUnit is
type STATES is (load, decode, exshl, exshr, exsto, exloa, exli, exadd, exsub, exaddc, exsubc, type STATES is (load, decode, exshl, exshr, exsto, exloa, exloa2, exli, exadd, exsub, exaddc, exsubc,
exopor, exopand, exopxor, exopnot, exjpz, exjpc, exjmp, exhlt, exjmc, exret); exopor, exopand, exopxor, exopnot, exjpz, exjpc, exjmp, exhlt, exjmc, exret);
signal sState, sState_next : STATES; signal sState, sState_next : STATES;
begin begin
-- switch sStates if needed
sState_change: process(iClk,iReset) --! switch sStates if needed
begin sState_change : process(iClk,iReset)
if (iReset = '1') then begin
sState <= load; if (iReset = '1') then
elsif (rising_edge(iClk)) then sState <= load;
sState <= sState_next;
end if; elsif (rising_edge(iClk)) then
end process; sState <= sState_next;
end if;
end process;
calc_sState_next: process(sState, icOpCode, idCarry, idZero) --! calculate the next state of the FSM
begin calc_sState_next : process(sState, icOpCode, idCarry, idZero)
begin
case sState is
when load =>
sState_next <= decode;
when decode =>
case icOpCode is
when shl => sState_next <= exshl;
when shr => sState_next <= exshr;
when sto => sState_next <= exsto;
when loa => sState_next <= exloa;
when li => sState_next <= exli;
when add => sState_next <= exadd;
when sub => sState_next <= exsub;
when addc => sState_next <= exaddc;
when subc => sState_next <= exsubc;
when opand => sState_next <= exopand;
when opor => sState_next <= exopor;
when opxor => sState_next <= exopxor;
when opnot => sState_next <= exopnot;
when jpz => if (idZero = '1') then
sState_next <= exjpz;
else
sState_next <= load;
end if;
when jpc => if (idCarry = '1') then
sState_next <= exjpc;
else
sState_next <= load;
end if;
when jmp => sState_next <= exjmp;
when jmc => sState_next <= exjmc;
when ret => sState_next <= exret;
when hlt => sState_next <= exhlt;
end case;
when exhlt => sState_next <= exhlt;
when others => sState_next <= load;
end case;
end process; case sState is
when load =>
sState_next <= decode;
when decode =>
case icOpCode is
when shl => sState_next <= exshl;
when shr => sState_next <= exshr;
when sto => sState_next <= exsto;
when loa => sState_next <= exloa;
when li => sState_next <= exli;
when add => sState_next <= exadd;
when sub => sState_next <= exsub;
when addc => sState_next <= exaddc;
when subc => sState_next <= exsubc;
when opand => sState_next <= exopand;
when opor => sState_next <= exopor;
when opxor => sState_next <= exopxor;
when opnot => sState_next <= exopnot;
when jpz =>
if (idZero = '1') then
sState_next <= exjpz;
else
sState_next <= load;
end if;
when jpc =>
if (idCarry = '1') then
sState_next <= exjpc;
else
sState_next <= load;
end if;
when jmp => sState_next <= exjmp;
when jmc => sState_next <= exjmc;
when ret => sState_next <= exret;
when hlt => sState_next <= exhlt;
end case;
when exhlt => sState_next <= exhlt;
when exloa => sState_next <= exloa2;
when others => sState_next <= load;
end case;
end process;
--! calculate the output in each sState --! calculate the output in each sState
calc_output: process(sState) calc_output : process(sState)
begin begin
case sState is
when load =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- load instruction
ocNextPC <= '0'; -- do not increment pc
ocAddrSel <= '1'; -- pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when decode =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '1'; -- load instruction
ocNextPC <= '1'; -- do not increment pc
ocAddrSel <= '0'; -- pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exshl =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exshr =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exsto =>
ocRnotWRam <= '0'; -- write to RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exloa =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '1';
when exli =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exadd =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exsub =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exaddc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exsubc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopor =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopand =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopxor =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopnot =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjpz =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjpc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjmp =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjmc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister<= '1'; -- put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exret =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- ocJump
ocPCregister<= '0'; -- put PC to register File
ocUsePC <= '1';
ocLoad <= '0';
when exhlt =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when others =>
ocRnotWRam <= '-'; -- read from RAM
ocLoadEn <= '-'; -- save result
ocEnableRAM <= '-'; -- do not put akku on databus
ocLoadInstr <= '-'; -- do not load instruction
ocNextPC <= '-'; -- increment pc
ocAddrSel <= '-'; -- no pc on addressbus
ocJump <= '-'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
end case;
end process; case sState is
when load =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- load instruction
ocNextPC <= '0'; -- do not increment pc
ocAddrSel <= '1'; -- pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when decode =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '1'; -- load instruction
ocNextPC <= '1'; -- do not increment pc
ocAddrSel <= '0'; -- pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exshl =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exshr =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exsto =>
ocRnotWRam <= '0'; -- write to RAM
ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exloa =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exli =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exadd =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exsub =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exaddc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exloa2 =>
ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '1';
when exsubc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopor =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopand =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopxor =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exopnot =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjpz =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjpc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjmp =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exjmc =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump
ocPCregister <= '1'; -- put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when exret =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- ocJump
ocPCregister <= '0'; -- put PC to register File
ocUsePC <= '1';
ocLoad <= '0';
when exhlt =>
ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
when others =>
ocRnotWRam <= '-'; -- read from RAM
ocLoadEn <= '-'; -- save result
ocEnableRAM <= '-'; -- do not put akku on databus
ocLoadInstr <= '-'; -- do not load instruction
ocNextPC <= '-'; -- increment pc
ocAddrSel <= '-'; -- no pc on addressbus
ocJump <= '-'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0';
ocLoad <= '0';
end case;
end process;
end arch; end arch;

View File

@ -1,175 +1,169 @@
---------------------------------------------------------------------------------- -------------------------------------------------------
-- Company: --! @file
-- Engineer: --! @brief Fetch/Decode Component for the Simple Processor Core (Geraffel Processor)
-- --! @author Dominik Meyer/ Marcel Eckert
-- Create Date: 16:16:43 05/10/2011 --! @email dmeyer@federationhq.de
-- Design Name: --! @licence GPLv2
-- Module Name: FetchDecode - Behavioral --! @date unknown
-- Project Name: -------------------------------------------------------
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE; library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.STD_LOGIC_UNSIGNED.all;
library work; library work;
use work.cpupkg.all; use work.cpupkg.all;
-- Uncomment the following library declaration if using --! Fetch/Decode Component for the Simple Processor Core (Geraffel Processor)
-- arithmetic functions with Signed or Unsigned values --!
--use IEEE.NUMERIC_STD.ALL; --! This Code is based on a processor core used at the Helmut Schmidt University for
--! educational purposes.
-- Uncomment the following library declaration if instantiating --!
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity FetchDecode is entity FetchDecode is
Port( port(
iClk : in std_logic;
iReset : in std_logic; iClk : in std_logic; --! main system clock
iReset : in std_logic; --! system active high reset
idData : in DATA;
icAddrSel : in std_logic; idData : in DATA; --! Data input coming from the RAM with instruction
icLoadInstr : in std_logic; icAddrSel : in std_logic; --! Put AddressRegister to Address BUS
icJump : in std_logic; icDecodeInstr : in std_logic; --! Decode the loaded instrcution
icNextPC : in std_logic; icJump : in std_logic; --! executed instruction is a jump, put jump register to address bus
odPC : out ADDRESS; icNextPC : in std_logic; --! increment the PC
idPC : in ADDRESS; odPC : out ADDRESS; --! put out the current PC
icUsePC : in std_logic; idPC : in ADDRESS; --! input for a new PC from extern
odAddress : out ADDRESS; icUsePC : in std_logic; --! use the external PC
odImmidiate : out DATA; odAddress : out ADDRESS; --! output to the address bus
odRegAsel : out std_logic_vector(4 downto 0); odImmidiate : out DATA; --! output the loaded immediate
odRegBsel : out std_logic_vector(4 downto 0); odRegAsel : out std_logic_vector(4 downto 0); --! output the decoded register addr
odRegINsel : out std_logic_vector(4 downto 0); odRegBsel : out std_logic_vector(4 downto 0); --! output the decoded register addr
ocOperation : out OPTYPE odRegINsel : out std_logic_vector(4 downto 0); --! output the decoded result register addr
ocOperation : out OPTYPE --! output which operation to perform
);
);
end FetchDecode; end FetchDecode;
architecture Behavioral of FetchDecode is architecture Behavioral of FetchDecode is
signal sdPC, sdPC_next : ADDRESS; signal sdPC, sdPC_next : ADDRESS;
signal sdAdr, sdAdr_next : ADDRESS; signal sdAdr, sdAdr_next : ADDRESS;
signal sdImmidate, sdImmidiate_next : DATA; signal sdImmidate, sdImmidiate_next : DATA;
signal sdRegAsel, sdRegAsel_next : std_logic_vector(4 downto 0); signal sdRegAsel, sdRegAsel_next : std_logic_vector(4 downto 0);
signal sdRegBsel, sdRegBsel_next : std_logic_vector(4 downto 0); signal sdRegBsel, sdRegBsel_next : std_logic_vector(4 downto 0);
signal sdRegINsel, sdRegINsel_next : std_logic_vector(4 downto 0); signal sdRegINsel, sdRegINsel_next : std_logic_vector(4 downto 0);
signal scOp, scOp_next : OPTYPE; signal scOp, scOp_next : OPTYPE;
begin begin
Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel, icUsePC, idPC)
begin Transition : process(idData, sdImmidate, icDecodeInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel, icUsePC, idPC)
-- defaults begin
sdAdr_next <= sdAdr;
sdPC_next <= sdPC; -- default values for all signals/registers
scOp_next <= scOp; sdAdr_next <= sdAdr;
sdImmidiate_next <= sdImmidate; sdPC_next <= sdPC;
scOp_next <= scOp;
sdImmidiate_next <= sdImmidate;
-- fill the next register values with the old ones
sdRegAsel_next <= sdRegAsel; sdRegAsel_next <= sdRegAsel;
sdRegBsel_next <= sdRegBsel; sdRegBsel_next <= sdRegBsel;
sdRegINsel_next <= sdRegINsel; sdRegINsel_next <= sdRegINsel;
--! ISA Definition --! ISA Definition, for the Decode run
if (icLoadInstr = '1') then if (icDecodeInstr = '1') then
sdAdr_next <= idData(15 downto 0);
sdImmidiate_next <= "0000000000000000" & idData(15 downto 0); -- because of the fixed bit positions we can fill in the correct values to the next register values
sdRegINsel_next <= idData(25 downto 21); sdAdr_next <= idData(15 downto 0);
sdRegAsel_next <= idData(20 downto 16); sdImmidiate_next <= "0000000000000000" & idData(15 downto 0);
sdRegBsel_next <= idData(15 downto 11); sdRegINsel_next <= idData(25 downto 21);
sdRegAsel_next <= idData(20 downto 16);
case idData(31 downto 26) is sdRegBsel_next <= idData(15 downto 11);
when "000000" => scOp_next <= shl;
when "000001" => scOp_next <= shr;
when "000010" => scOp_next <= sto; -- select the operation to do according to the decoded opcode
when "000011" => scOp_next <= loa; case idData(31 downto 26) is
when "000100" => scOp_next <= add; when "000000" => scOp_next <= shl;
when "000101" => scOp_next <= sub; when "000001" => scOp_next <= shr;
when "000110" => scOp_next <= addc; when "000010" => scOp_next <= sto;
when "000111" => scOp_next <= subc; when "000011" => scOp_next <= loa;
when "001000" => scOp_next <= opor; when "000100" => scOp_next <= add;
when "001001" => scOp_next <= opand; when "000101" => scOp_next <= sub;
when "001010" => scOp_next <= opxor; when "000110" => scOp_next <= addc;
when "001011" => scOp_next <= opnot; when "000111" => scOp_next <= subc;
when "001100" => scOp_next <= jpz; when "001000" => scOp_next <= opor;
when "001101" => scOp_next <= jpc; when "001001" => scOp_next <= opand;
when "001110" => scOp_next <= jmp; when "001010" => scOp_next <= opxor;
when "001111" => scOP_next <= li; when "001011" => scOp_next <= opnot;
when "010000" => scOp_next <= jmc; when "001100" => scOp_next <= jpz;
when "010001" => scOp_next <= ret; when "001101" => scOp_next <= jpc;
when others => scOp_next <= hlt; when "001110" => scOp_next <= jmp;
end case; when "001111" => scOP_next <= li;
end if; when "010000" => scOp_next <= jmc;
when "010001" => scOp_next <= ret;
if (icUsePC = '1') then when others => scOp_next <= hlt;
sdPC_next <= idPC; end case;
end if;
-- set registers according of some special external control signals
if (icUsePC = '1') then
sdPC_next <= idPC;
end if;
if (icJump = '1') then
sdPC_next <= sdAdr;
end if;
if (icNextPC = '1') then
sdPC_next <= sdPC + '1';
end if; end if;
if (icJump = '1') then
sdPC_next <= sdAdr;
end if;
if (icNextPC = '1') then
sdPC_next <= sdPC + '1';
end if;
end process;
-- Execute Transition end process;
process(iClk, iReset)
begin
if (iReset = '1') then -- Execute Transition, set register values to the calculated next register values
sdPC <= (others => '0'); process(iClk, iReset)
sdAdr <= (others => '0'); begin
sdImmidate <= (others=>'0'); if (iReset = '1') then
sdRegAsel <= (others=>'0'); sdPC <= (others => '0');
sdRegBsel <= (others=>'0'); sdAdr <= (others => '0');
sdRegINsel <= (others=>'0'); sdImmidate <= (others => '0');
sdRegAsel <= (others => '0');
scOp <= hlt; sdRegBsel <= (others => '0');
sdRegINsel <= (others => '0');
elsif (rising_edge(iClk)) then
sdPC <= sdPC_next; scOp <= hlt;
sdAdr <= sdAdr_next;
scOp <= scOp_next; elsif (rising_edge(iClk)) then
sdImmidate <= sdImmidiate_next; sdPC <= sdPC_next;
sdRegAsel <= sdRegAsel_next; sdAdr <= sdAdr_next;
sdRegBsel <= sdRegBsel_next; scOp <= scOp_next;
sdRegINsel <= sdRegINsel_next; sdImmidate <= sdImmidiate_next;
end if; sdRegAsel <= sdRegAsel_next;
sdRegBsel <= sdRegBsel_next;
end process; sdRegINsel <= sdRegINsel_next;
end if;
end process;
-- Output everything to the correct output signal
odAddress <= idPC when icUsePC = '1' else
sdAdr when icAddrSel = '0' and icLoadInstr = '0' else
sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else
sdPC; -- addr_sel = '1'
odPC <= sdPC;
ocOperation <= scOp when icLoadInstr = '0' else
scOp_next;
-- Output
odAddress <= idPC when icUsePC = '1' else
sdAdr when icAddrSel = '0' and icLoadInstr = '0' else
sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else
sdPC; -- addr_sel = '1'
odPC <= sdPC;
ocOperation <= scOp when icLoadInstr = '0' else
scOp_next;
odImmidiate <= sdImmidate when icLoadInstr = '0' else sdImmidiate_next; odImmidiate <= sdImmidate when icLoadInstr = '0' else sdImmidiate_next;
odRegAsel <= sdRegAsel when icLoadInstr = '0' else sdRegAsel_next;
odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next;
odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next;
end Behavioral;
odRegAsel <= sdRegAsel when icLoadInstr = '0' else sdRegAsel_next;
odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next;
odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next;
end Behavioral;

View File

@ -2,31 +2,27 @@
--! @file --! @file
--! @brief Maps memory devices to a given memory space --! @brief Maps memory devices to a given memory space
--! @author Dominik Meyer --! @author Dominik Meyer
--! @email dmeyer@hsu-hh.de --! @email dmeyer@federationhq.de
--! @date 2010-06-03 --! @date 2010-06-03
------------------------------------------------------- -------------------------------------------------------
library ieee; library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; use ieee.std_logic_unsigned.all;
--! Maps memory devices to a given memory space --! Maps memory devices to a given memory space
entity MemoryMapper is entity MemoryMapper is
port( port(
start : in std_logic_vector(15 downto 0); --! start of memory space start : in std_logic_vector(15 downto 0); --! start of memory space
stop : in std_logic_vector(15 downto 0); --! end of mempry space stop : in std_logic_vector(15 downto 0); --! end of mempry space
adr_in : in std_logic_vector(15 downto 0);
adr_in : in std_logic_vector(15 downto 0); req_in : in std_logic; --! ram request type
req_out : out std_logic; --! ram request type
req_in : in std_logic; --! ram request type
req_out : out std_logic; --! ram request type enable : out std_logic;
enable : out std_logic; adr_out : out std_logic_vector(15 downto 0)
adr_out : out std_logic_vector(15 downto 0)
); );
end MemoryMapper; end MemoryMapper;
@ -38,17 +34,16 @@ begin
process(adr_in, req_in, start, stop) process(adr_in, req_in, start, stop)
begin begin
if (adr_in >= start and adr_in <= stop) then if (adr_in >= start and adr_in <= stop) then
req_out <= req_in; req_out <= req_in;
adr_out <= adr_in-start; adr_out <= adr_in-start;
enable <= '1'; enable <= '1';
else else
req_out <= '0'; req_out <= '0';
enable <= '0'; enable <= '0';
adr_out <= (others => 'Z'); adr_out <= (others => 'Z');
end if; end if;
end process; end process;
end arch; end arch;

View File

@ -1,102 +1,95 @@
---------------------------------------------------------------------------------- -------------------------------------------------------
-- Company: --! @file
-- Engineer: --! @brief RegisterFile for the Simple Processor Core (Geraffel Processor)
-- --! @author Dominik Meyer
-- Create Date: 16:05:19 05/10/2011 --! @email dmeyer@federationhq.de
-- Design Name: --! @licence GPLv2
-- Module Name: RegFile - Behavioral --! @date unknown
-- Project Name: -------------------------------------------------------
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE; library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_1164.all;
library work; library work;
use work.cpupkg.all; use work.cpupkg.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
--! RegisterFile for the Simple Processor Core (Geraffel Processor)
--!
--! This Code is based on a processor core used at the Helmut Schmidt University for
--! educational purposes.
--!
entity RegFile is entity RegFile is
Port( port(
iClk : in std_logic; iClk : in std_logic; --! main sytem clock signal
iReset : in std_logic; iReset : in std_logic; --! main system active high reset
icRegAsel : in std_logic_vector(4 downto 0); icRegAsel : in std_logic_vector(4 downto 0); --! address of register A
icRegBsel : in std_logic_vector(4 downto 0); icRegBsel : in std_logic_vector(4 downto 0); --! address of register B
odRegA : out DATA; odRegA : out DATA; --! output of the register A Value
odRegB : out DATA; odRegB : out DATA; --! output of the register B Value
icPC : in std_logic; -- select PC as input to RegisterFile icPC : in std_logic; --! select the PC Input as the input value, required for ret instruction
idPC : in DATA; idPC : in DATA; --! input of the PC, required for the ret instruction
icRegINsel : in std_logic_vector(4 downto 0); icRegINsel : in std_logic_vector(4 downto 0); --! address of the register to which to save the input
idDataIn : in DATA; idDataIn : in DATA; --! data input, normally from the ALU
idCarryIn : in std_logic; idCarryIn : in std_logic; --! Carry Flag of the last Operation
idZeroIn : in std_logic; idZeroIn : in std_logic; --! Zero Flag of the last Operation
icLoadEn : in std_logic; icLoadEn : in std_logic; --! actually save the input Data to the selected register
odCarryOut : out std_logic; odCarryOut : out std_logic; --! output of the currently saved carry flag
odZeroOut : out std_logic odZeroOut : out std_logic --! output of the currently saved zero flag
); );
end RegFile; end RegFile;
architecture Behavioral of RegFile is architecture Behavioral of RegFile is
type registerFileType is array (0 to 31) of DATA; type registerFileType is array (0 to 31) of DATA;
signal registerFile : registerFileType; signal registerFile : registerFileType;
signal sdData : DATA; signal sdData : DATA;
signal sdCarry : std_logic; signal sdCarry : std_logic;
signal sdZero : std_logic; signal sdZero : std_logic;
begin begin
-- Execute Transition -- Execute Transition
process(iClk, iReset) process(iClk, iReset)
begin begin
if (iReset = '1') then if (iReset = '1') then
for i in 31 downto 0 loop for i in 31 downto 0 loop
registerFile(i) <= (others=>'0'); registerFile(i) <= (others => '0');
end loop; end loop;
sdCarry <= '0'; sdCarry <= '0';
sdZero <= '0'; sdZero <= '0';
elsif (rising_edge(iClk)) then elsif (rising_edge(iClk)) then
if (icLoadEn = '1') then if (icLoadEn = '1') then
if (icPC = '0') then if (icPC = '0') then
registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn; registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn;
else else
registerFile(to_integer(unsigned(icRegINsel))) <= idPC; registerFile(to_integer(unsigned(icRegINsel))) <= idPC;
end if; end if;
sdCarry <= idCarryIn; sdCarry <= idCarryIn;
sdZero <= idZeroIn; sdZero <= idZeroIn;
end if; end if;
end if; end if;
end process; end process;
odRegA <= registerFile(to_integer(unsigned(icRegAsel))); odRegA <= registerFile(to_integer(unsigned(icRegAsel)));
odRegB <= registerFile(to_integer(unsigned(icRegBsel))); odRegB <= registerFile(to_integer(unsigned(icRegBsel)));
odCarryOut <= sdCarry; odCarryOut <= sdCarry;
odZeroOut <= sdZero; odZeroOut <= sdZero;
end Behavioral; end Behavioral;