FIX: fixed file headers, added licence, formated code
This commit is contained in:
parent
2ff599262a
commit
aa3ed4c103
174
src/ALU.vhd
174
src/ALU.vhd
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
129
src/RegFile.vhd
129
src/RegFile.vhd
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user