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;
--! Architectural description of the ALU
architecture Behavioral of ALU is architecture Behavioral of ALU is
signal sdTempResult, sdOp1, sdOp2 : std_logic_vector(32 downto 0); signal sdTempResult, sdOp1, sdOp2 : std_logic_vector(32 downto 0);
begin begin
sdOp1 <= '0' & idOperand1;
sdOp2 <= '0' & idOperand2;
process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1) -- extend the operand by one bit, to be able to get the overflow
begin -- of an operation
if (icOperation = shl) then sdOp1 <= '0' & idOperand1;
sdTempResult <= sdOp1(31 downto 0) & "0"; sdOp2 <= '0' & idOperand2;
elsif (icOperation = shr) then
sdTempResult <= sdOp1(0) & "0" & sdOp1(31 downto 1);
elsif (icOperation = sto) then --! process to do the actual computation
sdTempResult <= (others => '-'); process (sdOp1, sdOp2, idCarryIn, icOperation, idImmidiate, idOperand1)
begin
elsif (icOperation = loa) then -- TODO: convert to case structure for improved space usege and speed
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = li) then
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = add) then
sdTempResult <= sdOp1 + sdOp2;
elsif (icOperation = sub) then if (icOperation = shl) then
sdTempResult <= sdOp1 - sdOp2; sdTempResult <= sdOp1(31 downto 0) & "0";
elsif (icOperation = addc) then elsif (icOperation = shr) then
sdTempResult <= sdOp1 + sdOp2 + ("0000000000000000" & idCarryIn); sdTempResult <= sdOp1(0) & "0" & sdOp1(31 downto 1);
elsif (icOperation = subc) then elsif (icOperation = sto) then
sdTempResult <= sdOp1 - sdOp2 - ("0000000000000000" & idCarryIn); sdTempResult <= (others => '-');
elsif (icOperation = opor) then elsif (icOperation = loa) then
sdTempResult <= sdOp1 or sdOp2; sdTempResult <= '0' & idImmidiate;
elsif (icOperation = li) then
sdTempResult <= '0' & idImmidiate;
elsif (icOperation = add) then
sdTempResult <= sdOp1 + sdOp2;
elsif (icOperation = opand) then elsif (icOperation = sub) then
sdTempResult <= sdOp1 and sdOp2; sdTempResult <= sdOp1 - sdOp2;
elsif (icOperation = opxor) then elsif (icOperation = addc) then
sdTempResult <= sdOp1 xor sdOp2; sdTempResult <= sdOp1 + sdOp2 + ("0000000000000000" & idCarryIn);
elsif (icOperation = opnot) then elsif (icOperation = subc) then
sdTempResult <= not sdOp1; sdTempResult <= sdOp1 - sdOp2 - ("0000000000000000" & idCarryIn);
elsif (icOperation = jpz) then elsif (icOperation = opor) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 or sdOp2;
elsif (icOperation = jpc) then elsif (icOperation = opand) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 and sdOp2;
elsif (icOperation = jmp) then elsif (icOperation = opxor) then
sdTempResult <= (others => '-'); sdTempResult <= sdOp1 xor sdOp2;
else -- (icOperation = hlt) elsif (icOperation = opnot) then
sdTempResult <= (others => '-'); sdTempResult <= not sdOp1;
end if; elsif (icOperation = jpz) then
end process; sdTempResult <= (others => '-');
odResult <= sdTempResult(31 downto 0); elsif (icOperation = jpc) then
odCarryOut <= sdTempResult(32); sdTempResult <= (others => '-');
odZeroOut <= '1' when sdTempResult(31 downto 0) = 0 else
'0'; 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)
begin
if (iReset = '1') then
sState <= load;
elsif (rising_edge(iClk)) then --! switch sStates if needed
sState <= sState_next; sState_change : process(iClk,iReset)
end if; begin
end process; if (iReset = '1') then
sState <= load;
elsif (rising_edge(iClk)) then
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 case sState is
when load => when load =>
sState_next <= decode; sState_next <= decode;
when decode => when decode =>
case icOpCode is case icOpCode is
when shl => sState_next <= exshl; when shl => sState_next <= exshl;
when shr => sState_next <= exshr; when shr => sState_next <= exshr;
when sto => sState_next <= exsto; when sto => sState_next <= exsto;
when loa => sState_next <= exloa; when loa => sState_next <= exloa;
when li => sState_next <= exli; when li => sState_next <= exli;
when add => sState_next <= exadd; when add => sState_next <= exadd;
when sub => sState_next <= exsub; when sub => sState_next <= exsub;
when addc => sState_next <= exaddc; when addc => sState_next <= exaddc;
when subc => sState_next <= exsubc; when subc => sState_next <= exsubc;
when opand => sState_next <= exopand; when opand => sState_next <= exopand;
when opor => sState_next <= exopor; when opor => sState_next <= exopor;
when opxor => sState_next <= exopxor; when opxor => sState_next <= exopxor;
when opnot => sState_next <= exopnot; when opnot => sState_next <= exopnot;
when jpz => if (idZero = '1') then when jpz =>
sState_next <= exjpz; if (idZero = '1') then
else sState_next <= exjpz;
sState_next <= load; else
end if; sState_next <= load;
when jpc => if (idCarry = '1') then end if;
sState_next <= exjpc; when jpc =>
else if (idCarry = '1') then
sState_next <= load; sState_next <= exjpc;
end if; else
when jmp => sState_next <= exjmp; sState_next <= load;
when jmc => sState_next <= exjmc; end if;
when ret => sState_next <= exret; when jmp => sState_next <= exjmp;
when hlt => sState_next <= exhlt; when jmc => sState_next <= exjmc;
end case; when ret => sState_next <= exret;
when exhlt => sState_next <= exhlt; when hlt => sState_next <= exhlt;
when others => sState_next <= load; end case;
end case; when exhlt => sState_next <= exhlt;
when exloa => sState_next <= exloa2;
when others => sState_next <= load;
end case;
end process; 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 case sState is
when load => when load =>
ocRnotWRam <= '1'; -- read from RAM ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- do not put akku on databus ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- load instruction ocLoadInstr <= '0'; -- load instruction
ocNextPC <= '0'; -- do not increment pc ocNextPC <= '0'; -- do not increment pc
ocAddrSel <= '1'; -- pc on addressbus ocAddrSel <= '1'; -- pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when decode => when decode =>
ocRnotWRam <= '1'; -- read from RAM ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '0'; -- do not save result ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '1'; -- load instruction ocLoadInstr <= '1'; -- load instruction
ocNextPC <= '1'; -- do not increment pc ocNextPC <= '1'; -- do not increment pc
ocAddrSel <= '0'; -- pc on addressbus ocAddrSel <= '0'; -- pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exshl => when exshl =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exshr => when exshr =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exsto => when exsto =>
ocRnotWRam <= '0'; -- write to RAM ocRnotWRam <= '0'; -- write to RAM
ocLoadEn <= '0'; -- do not save result ocLoadEn <= '0'; -- do not save result
ocEnableRAM <= '1'; -- put akku on databus ocEnableRAM <= '1'; -- put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exloa => when exloa =>
ocRnotWRam <= '1'; -- read from RAM ocRnotWRam <= '1'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '1'; -- do not put akku on databus ocEnableRAM <= '1'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '1'; 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 => when exli =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exsub => when exadd =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exaddc => when exsub =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exsubc => when exaddc =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '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 exopor => when exsubc =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exopand => when exopor =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exopxor => when exopand =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exopnot => when exopxor =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exjpz => when exopnot =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exjpc => when exjpz =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exjmp => when exjpc =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump ocJump <= '1'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exjmc => when exjmp =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '1'; -- save result ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '1'; -- ocJump ocJump <= '1'; -- ocJump
ocPCregister<= '1'; -- put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exret => when exjmc =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result ocLoadEn <= '1'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- ocJump ocJump <= '1'; -- ocJump
ocPCregister<= '0'; -- put PC to register File ocPCregister <= '1'; -- put PC to register File
ocUsePC <= '1'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
when exhlt => when exret =>
ocRnotWRam <= '0'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '0'; -- save result ocLoadEn <= '0'; -- save result
ocEnableRAM <= '0'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '0'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '0'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '0'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '0'; -- no ocJump ocJump <= '0'; -- ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- put PC to register File
ocUsePC <= '0'; ocUsePC <= '1';
ocLoad <= '0'; ocLoad <= '0';
when others => when exhlt =>
ocRnotWRam <= '-'; -- read from RAM ocRnotWRam <= '0'; -- read from RAM
ocLoadEn <= '-'; -- save result ocLoadEn <= '0'; -- save result
ocEnableRAM <= '-'; -- do not put akku on databus ocEnableRAM <= '0'; -- do not put akku on databus
ocLoadInstr <= '-'; -- do not load instruction ocLoadInstr <= '0'; -- do not load instruction
ocNextPC <= '-'; -- increment pc ocNextPC <= '0'; -- increment pc
ocAddrSel <= '-'; -- no pc on addressbus ocAddrSel <= '0'; -- no pc on addressbus
ocJump <= '-'; -- no ocJump ocJump <= '0'; -- no ocJump
ocPCregister <= '0'; -- do not put PC to register File ocPCregister <= '0'; -- do not put PC to register File
ocUsePC <= '0'; ocUsePC <= '0';
ocLoad <= '0'; ocLoad <= '0';
end case; 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 process; 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;
idData : in DATA; iClk : in std_logic; --! main system clock
icAddrSel : in std_logic; iReset : in std_logic; --! system active high reset
icLoadInstr : in std_logic;
icJump : in std_logic;
icNextPC : in std_logic;
odPC : out ADDRESS;
idPC : in ADDRESS;
icUsePC : in std_logic;
odAddress : out ADDRESS;
odImmidiate : out DATA;
odRegAsel : out std_logic_vector(4 downto 0);
odRegBsel : out std_logic_vector(4 downto 0);
odRegINsel : out std_logic_vector(4 downto 0);
ocOperation : out OPTYPE
); idData : in DATA; --! Data input coming from the RAM with instruction
icAddrSel : in std_logic; --! Put AddressRegister to Address BUS
icDecodeInstr : in std_logic; --! Decode the loaded instrcution
icJump : in std_logic; --! executed instruction is a jump, put jump register to address bus
icNextPC : in std_logic; --! increment the PC
odPC : out ADDRESS; --! put out the current PC
idPC : in ADDRESS; --! input for a new PC from extern
icUsePC : in std_logic; --! use the external PC
odAddress : out ADDRESS; --! output to the address bus
odImmidiate : out DATA; --! output the loaded immediate
odRegAsel : out std_logic_vector(4 downto 0); --! output the decoded register addr
odRegBsel : out std_logic_vector(4 downto 0); --! output the decoded register addr
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
-- defaults
sdAdr_next <= sdAdr;
sdPC_next <= sdPC;
scOp_next <= scOp;
sdImmidiate_next <= sdImmidate;
Transition : process(idData, sdImmidate, icDecodeInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel, icUsePC, idPC)
begin
-- default values for all signals/registers
sdAdr_next <= sdAdr;
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);
sdRegINsel_next <= idData(25 downto 21);
sdRegAsel_next <= idData(20 downto 16);
sdRegBsel_next <= idData(15 downto 11);
case idData(31 downto 26) is -- because of the fixed bit positions we can fill in the correct values to the next register values
when "000000" => scOp_next <= shl; sdAdr_next <= idData(15 downto 0);
when "000001" => scOp_next <= shr; sdImmidiate_next <= "0000000000000000" & idData(15 downto 0);
when "000010" => scOp_next <= sto; sdRegINsel_next <= idData(25 downto 21);
when "000011" => scOp_next <= loa; sdRegAsel_next <= idData(20 downto 16);
when "000100" => scOp_next <= add; sdRegBsel_next <= idData(15 downto 11);
when "000101" => scOp_next <= sub;
when "000110" => scOp_next <= addc;
when "000111" => scOp_next <= subc;
when "001000" => scOp_next <= opor;
when "001001" => scOp_next <= opand;
when "001010" => scOp_next <= opxor;
when "001011" => scOp_next <= opnot;
when "001100" => scOp_next <= jpz;
when "001101" => scOp_next <= jpc;
when "001110" => scOp_next <= jmp;
when "001111" => scOP_next <= li;
when "010000" => scOp_next <= jmc;
when "010001" => scOp_next <= ret;
when others => scOp_next <= hlt;
end case;
end if;
if (icUsePC = '1') then
sdPC_next <= idPC; -- select the operation to do according to the decoded opcode
case idData(31 downto 26) is
when "000000" => scOp_next <= shl;
when "000001" => scOp_next <= shr;
when "000010" => scOp_next <= sto;
when "000011" => scOp_next <= loa;
when "000100" => scOp_next <= add;
when "000101" => scOp_next <= sub;
when "000110" => scOp_next <= addc;
when "000111" => scOp_next <= subc;
when "001000" => scOp_next <= opor;
when "001001" => scOp_next <= opand;
when "001010" => scOp_next <= opxor;
when "001011" => scOp_next <= opnot;
when "001100" => scOp_next <= jpz;
when "001101" => scOp_next <= jpc;
when "001110" => scOp_next <= jmp;
when "001111" => scOP_next <= li;
when "010000" => scOp_next <= jmc;
when "010001" => scOp_next <= ret;
when others => scOp_next <= hlt;
end case;
end if; end if;
if (icJump = '1') then -- set registers according of some special external control signals
sdPC_next <= sdAdr; if (icUsePC = '1') then
sdPC_next <= idPC;
end if;
end if; if (icJump = '1') then
sdPC_next <= sdAdr;
if (icNextPC = '1') then end if;
sdPC_next <= sdPC + '1';
end if; if (icNextPC = '1') then
sdPC_next <= sdPC + '1';
end if;
end process; end process;
-- Execute Transition -- Execute Transition, set register values to the calculated next register values
process(iClk, iReset) process(iClk, iReset)
begin begin
if (iReset = '1') then if (iReset = '1') then
sdPC <= (others => '0'); sdPC <= (others => '0');
sdAdr <= (others => '0'); sdAdr <= (others => '0');
sdImmidate <= (others=>'0'); sdImmidate <= (others => '0');
sdRegAsel <= (others=>'0'); sdRegAsel <= (others => '0');
sdRegBsel <= (others=>'0'); sdRegBsel <= (others => '0');
sdRegINsel <= (others=>'0'); sdRegINsel <= (others => '0');
scOp <= hlt; scOp <= hlt;
elsif (rising_edge(iClk)) then elsif (rising_edge(iClk)) then
sdPC <= sdPC_next; sdPC <= sdPC_next;
sdAdr <= sdAdr_next; sdAdr <= sdAdr_next;
scOp <= scOp_next; scOp <= scOp_next;
sdImmidate <= sdImmidiate_next; sdImmidate <= sdImmidiate_next;
sdRegAsel <= sdRegAsel_next; sdRegAsel <= sdRegAsel_next;
sdRegBsel <= sdRegBsel_next; sdRegBsel <= sdRegBsel_next;
sdRegINsel <= sdRegINsel_next; sdRegINsel <= sdRegINsel_next;
end if; end if;
end process; end process;
-- Output -- Output everything to the correct output signal
odAddress <= idPC when icUsePC = '1' else odAddress <= idPC when icUsePC = '1' else
sdAdr when icAddrSel = '0' and icLoadInstr = '0' else sdAdr when icAddrSel = '0' and icLoadInstr = '0' else
sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else
sdPC; -- addr_sel = '1' sdPC; -- addr_sel = '1'
odPC <= sdPC; odPC <= sdPC;
ocOperation <= scOp when icLoadInstr = '0' else ocOperation <= scOp when icLoadInstr = '0' else
scOp_next; 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; odRegAsel <= sdRegAsel when icLoadInstr = '0' else sdRegAsel_next;
odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next; odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next;
odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next; odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next;
end Behavioral; end Behavioral;

View File

@ -2,30 +2,26 @@
--! @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);
req_in : in std_logic; --! ram request type
req_out : out std_logic; --! ram request type
adr_in : in std_logic_vector(15 downto 0); enable : out std_logic;
req_in : in std_logic; --! ram request type adr_out : out std_logic_vector(15 downto 0)
req_out : out std_logic; --! ram request type
enable : out std_logic;
adr_out : out std_logic_vector(15 downto 0)
); );
end MemoryMapper; end MemoryMapper;
@ -40,15 +36,14 @@ begin
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;