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:
-- 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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;