From aa3ed4c1039ae21e0a9f4b18a58f9cddd6625a9c Mon Sep 17 00:00:00 2001 From: Dominik Meyer Date: Mon, 30 Dec 2013 14:56:42 +0100 Subject: [PATCH] FIX: fixed file headers, added licence, formated code --- src/ALU.vhd | 210 ++++++------ src/ControlUnit.vhd | 739 ++++++++++++++++++++++--------------------- src/FetchDecode.vhd | 306 +++++++++--------- src/MemoryMapper.vhd | 43 ++- src/RegFile.vhd | 169 +++++----- 5 files changed, 727 insertions(+), 740 deletions(-) diff --git a/src/ALU.vhd b/src/ALU.vhd index c9eb1f2..88a284d 100644 --- a/src/ALU.vhd +++ b/src/ALU.vhd @@ -1,116 +1,116 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 15:13:27 05/10/2011 --- Design Name: --- Module Name: ALU - Behavioral --- Project Name: --- Target Devices: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ----------------------------------------------------------------------------------- +------------------------------------------------------- +--! @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; + use IEEE.STD_LOGIC_1164.all; + use IEEE.STD_LOGIC_UNSIGNED.all; library work; -use work.cpupkg.all; --- Uncomment the following library declaration if using --- arithmetic functions with Signed or Unsigned values ---use IEEE.NUMERIC_STD.ALL; + 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. +--! --- Uncomment the following library declaration if instantiating --- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; entity ALU is - Port( - idOperand1 : in DATA; - idOperand2 : in DATA; - idCarryIn : in std_logic; - idImmidiate : in DATA; - - odResult : out DATA; - odCarryOut : out std_logic; - odZeroOut : out std_logic; - - icOperation : in OPTYPE - ); + 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; -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) - begin - 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; - - odResult <= sdTempResult(31 downto 0); - odCarryOut <= sdTempResult(32); - odZeroOut <= '1' when sdTempResult(31 downto 0) = 0 else - '0'; +--! 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; - diff --git a/src/ControlUnit.vhd b/src/ControlUnit.vhd index 6652d08..565b595 100644 --- a/src/ControlUnit.vhd +++ b/src/ControlUnit.vhd @@ -1,396 +1,401 @@ ------------------------------------------------------- --! @file ---! @brief the control unit of the IIB2 Akkumulator machine +--! @brief the control unit for the Simple Processor Core (Geraffel Processor) --! @author Dominik Meyer --! @email dmeyer@hsu-hh.de +--! @licence GPLv2 --! @date 2010-11-19 ------------------------------------------------------- - - library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; 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 ( - iClk : in std_logic; --! iClk signal - iReset : in std_logic; --! iReset signal - icOpCode : in optype; --! icOpCode bus - idCarry : in std_logic; --! carry from register file - idZero : in std_logic; --! zero flag from register file - ocRnotWRam : out std_logic; --! r_notw to RAM - ocLoadEn : out std_logic; --! safe result of alu - ocEnableRAM : out std_logic; --! put akku on databus - ocLoadInstr : out std_logic; --! load instruction control signal - ocNextPC : out std_logic; --! increment pc - ocAddrSel : out std_logic; --! pc on addressbus - ocJump : out std_logic; --! do a ocJump - ocPCregister : out std_logic; --! put PC to register File - ocUsePC : out std_logic; --! use Register to fill in the PC - ocLoad : out std_logic --! put databus to ALU immediate port + iClk : in std_logic; --! iClk signal + iReset : in std_logic; --! iReset signal + icOpCode : in optype; --! icOpCode bus + idCarry : in std_logic; --! carry from register file + idZero : in std_logic; --! zero flag from register file + ocRnotWRam : out std_logic; --! r_notw to RAM + ocLoadEn : out std_logic; --! safe result of alu + ocEnableRAM : out std_logic; --! put akku on databus + ocLoadInstr : out std_logic; --! load instruction control signal + ocNextPC : out std_logic; --! increment pc + ocAddrSel : out std_logic; --! pc on addressbus + ocJump : out std_logic; --! do a ocJump + ocPCregister : out std_logic; --! put PC to register File + ocUsePC : out std_logic; --! use Register to fill in the PC + 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, - exopor, exopand, exopxor, exopnot, exjpz, exjpc, exjmp, exhlt, exjmc, exret); + 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); -signal sState, sState_next : STATES; + signal sState, sState_next : STATES; begin --- switch sStates if needed -sState_change: process(iClk,iReset) -begin - if (iReset = '1') then - sState <= load; - - elsif (rising_edge(iClk)) then - sState <= sState_next; - end if; -end process; + +--! switch sStates if needed + sState_change : process(iClk,iReset) + begin + 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) -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; +--! calculate the next state of the FSM + calc_sState_next : process(sState, icOpCode, idCarry, idZero) + begin -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 -calc_output: process(sState) -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; + calc_output : process(sState) + begin -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; - - - - - - - - - - - - - - - - - - - diff --git a/src/FetchDecode.vhd b/src/FetchDecode.vhd index 17cc06f..2f4905a 100644 --- a/src/FetchDecode.vhd +++ b/src/FetchDecode.vhd @@ -1,175 +1,169 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 16:16:43 05/10/2011 --- Design Name: --- Module Name: FetchDecode - Behavioral --- Project Name: --- Target Devices: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ----------------------------------------------------------------------------------- +------------------------------------------------------- +--! @file +--! @brief Fetch/Decode Component 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; + use IEEE.STD_LOGIC_1164.all; + use IEEE.STD_LOGIC_UNSIGNED.all; 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; - --- Uncomment the following library declaration if instantiating --- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; +--! Fetch/Decode Component 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 FetchDecode is - Port( - iClk : in std_logic; - iReset : in std_logic; - - idData : in DATA; - icAddrSel : in std_logic; - 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 - - ); + port( + + iClk : in std_logic; --! main system clock + iReset : in std_logic; --! system active high reset + + 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; architecture Behavioral of FetchDecode is - signal sdPC, sdPC_next : ADDRESS; - signal sdAdr, sdAdr_next : ADDRESS; - signal sdImmidate, sdImmidiate_next : DATA; - - signal sdRegAsel, sdRegAsel_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 scOp, scOp_next : OPTYPE; - + signal sdPC, sdPC_next : ADDRESS; + signal sdAdr, sdAdr_next : ADDRESS; + signal sdImmidate, sdImmidiate_next : DATA; + + signal sdRegAsel, sdRegAsel_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 scOp, scOp_next : OPTYPE; + 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; sdRegBsel_next <= sdRegBsel; sdRegINsel_next <= sdRegINsel; - - --! ISA Definition - if (icLoadInstr = '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 - 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; - - if (icUsePC = '1') then - sdPC_next <= idPC; + + --! ISA Definition, for the Decode run + if (icDecodeInstr = '1') then + + -- because of the fixed bit positions we can fill in the correct values to the next register values + 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); + + + -- 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; + + -- 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; - - if (icJump = '1') then - sdPC_next <= sdAdr; - - end if; - - if (icNextPC = '1') then - sdPC_next <= sdPC + '1'; - end if; - - - end process; - -- Execute Transition - process(iClk, iReset) - begin - if (iReset = '1') then - sdPC <= (others => '0'); - sdAdr <= (others => '0'); - sdImmidate <= (others=>'0'); - sdRegAsel <= (others=>'0'); - sdRegBsel <= (others=>'0'); - sdRegINsel <= (others=>'0'); - - scOp <= hlt; - - elsif (rising_edge(iClk)) then - sdPC <= sdPC_next; - sdAdr <= sdAdr_next; - scOp <= scOp_next; - sdImmidate <= sdImmidiate_next; - sdRegAsel <= sdRegAsel_next; - sdRegBsel <= sdRegBsel_next; - sdRegINsel <= sdRegINsel_next; - end if; - - end process; + end process; + + + -- Execute Transition, set register values to the calculated next register values + process(iClk, iReset) + begin + if (iReset = '1') then + sdPC <= (others => '0'); + sdAdr <= (others => '0'); + sdImmidate <= (others => '0'); + sdRegAsel <= (others => '0'); + sdRegBsel <= (others => '0'); + sdRegINsel <= (others => '0'); + + scOp <= hlt; + + elsif (rising_edge(iClk)) then + sdPC <= sdPC_next; + sdAdr <= sdAdr_next; + scOp <= scOp_next; + sdImmidate <= sdImmidiate_next; + sdRegAsel <= sdRegAsel_next; + sdRegBsel <= sdRegBsel_next; + 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; - - 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; diff --git a/src/MemoryMapper.vhd b/src/MemoryMapper.vhd index 20e98bc..3a50750 100644 --- a/src/MemoryMapper.vhd +++ b/src/MemoryMapper.vhd @@ -2,31 +2,27 @@ --! @file --! @brief Maps memory devices to a given memory space --! @author Dominik Meyer ---! @email dmeyer@hsu-hh.de +--! @email dmeyer@federationhq.de --! @date 2010-06-03 ------------------------------------------------------- - - library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; --! Maps memory devices to a given memory space entity MemoryMapper is - port( - start : in std_logic_vector(15 downto 0); --! start of memory 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 - - enable : out std_logic; - - adr_out : out std_logic_vector(15 downto 0) - + port( + start : in std_logic_vector(15 downto 0); --! start of memory 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 + + enable : out std_logic; + + adr_out : out std_logic_vector(15 downto 0) + ); end MemoryMapper; @@ -38,17 +34,16 @@ begin process(adr_in, req_in, start, stop) begin - + if (adr_in >= start and adr_in <= stop) then - req_out <= req_in; - adr_out <= adr_in-start; - enable <= '1'; + req_out <= req_in; + adr_out <= adr_in-start; + enable <= '1'; else req_out <= '0'; - enable <= '0'; + enable <= '0'; adr_out <= (others => 'Z'); end if; end process; end arch; - diff --git a/src/RegFile.vhd b/src/RegFile.vhd index d585481..77de909 100644 --- a/src/RegFile.vhd +++ b/src/RegFile.vhd @@ -1,102 +1,95 @@ ----------------------------------------------------------------------------------- --- Company: --- Engineer: --- --- Create Date: 16:05:19 05/10/2011 --- Design Name: --- Module Name: RegFile - Behavioral --- Project Name: --- Target Devices: --- Tool versions: --- Description: --- --- Dependencies: --- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: --- ----------------------------------------------------------------------------------- +------------------------------------------------------- +--! @file +--! @brief RegisterFile for the Simple Processor Core (Geraffel Processor) +--! @author Dominik Meyer +--! @email dmeyer@federationhq.de +--! @licence GPLv2 +--! @date unknown +------------------------------------------------------- library IEEE; -use IEEE.STD_LOGIC_1164.ALL; + use IEEE.STD_LOGIC_1164.all; library work; -use work.cpupkg.all; -use ieee.numeric_std.all; + use work.cpupkg.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 - Port( - iClk : in std_logic; - iReset : in std_logic; - - icRegAsel : in std_logic_vector(4 downto 0); - icRegBsel : in std_logic_vector(4 downto 0); - odRegA : out DATA; - odRegB : out DATA; - - icPC : in std_logic; -- select PC as input to RegisterFile - idPC : in DATA; - - icRegINsel : in std_logic_vector(4 downto 0); - - idDataIn : in DATA; - idCarryIn : in std_logic; - idZeroIn : in std_logic; - - icLoadEn : in std_logic; - - odCarryOut : out std_logic; - odZeroOut : out std_logic - ); + port( + iClk : in std_logic; --! main sytem clock signal + iReset : in std_logic; --! main system active high reset + + icRegAsel : in std_logic_vector(4 downto 0); --! address of register A + icRegBsel : in std_logic_vector(4 downto 0); --! address of register B + odRegA : out DATA; --! output of the register A Value + odRegB : out DATA; --! output of the register B Value + + icPC : in std_logic; --! select the PC Input as the input value, required for ret instruction + idPC : in DATA; --! input of the PC, required for the ret instruction + + icRegINsel : in std_logic_vector(4 downto 0); --! address of the register to which to save the input + + idDataIn : in DATA; --! data input, normally from the ALU + idCarryIn : in std_logic; --! Carry Flag of the last Operation + idZeroIn : in std_logic; --! Zero Flag of the last Operation + + icLoadEn : in std_logic; --! actually save the input Data to the selected register + + odCarryOut : out std_logic; --! output of the currently saved carry flag + odZeroOut : out std_logic --! output of the currently saved zero flag + ); end RegFile; 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 sdData : DATA; - signal sdCarry : std_logic; - signal sdZero : std_logic; + + signal sdData : DATA; + signal sdCarry : std_logic; + signal sdZero : std_logic; begin - - - - - - -- Execute Transition - process(iClk, iReset) - begin - if (iReset = '1') then - for i in 31 downto 0 loop - registerFile(i) <= (others=>'0'); + + + + + + -- Execute Transition + process(iClk, iReset) + begin + if (iReset = '1') then + for i in 31 downto 0 loop + registerFile(i) <= (others => '0'); end loop; - - sdCarry <= '0'; - sdZero <= '0'; - - elsif (rising_edge(iClk)) then - if (icLoadEn = '1') then - if (icPC = '0') then - registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn; - else - registerFile(to_integer(unsigned(icRegINsel))) <= idPC; - end if; - sdCarry <= idCarryIn; - sdZero <= idZeroIn; - - end if; - - end if; - - end process; - - - odRegA <= registerFile(to_integer(unsigned(icRegAsel))); - odRegB <= registerFile(to_integer(unsigned(icRegBsel))); - odCarryOut <= sdCarry; - odZeroOut <= sdZero; + + sdCarry <= '0'; + sdZero <= '0'; + + elsif (rising_edge(iClk)) then + if (icLoadEn = '1') then + if (icPC = '0') then + registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn; + else + registerFile(to_integer(unsigned(icRegINsel))) <= idPC; + end if; + sdCarry <= idCarryIn; + sdZero <= idZeroIn; + + end if; + + end if; + + end process; + + + odRegA <= registerFile(to_integer(unsigned(icRegAsel))); + odRegB <= registerFile(to_integer(unsigned(icRegBsel))); + odCarryOut <= sdCarry; + odZeroOut <= sdZero; end Behavioral; -