iu.vhd
来自「sparc org, vhdl rtl code」· VHDL 代码 · 共 1,813 行 · 第 1/5 页
VHD
1,813 行
----------------------------------------------------------------------------
-- This file is a part of the LEON VHDL model
-- Copyright (C) 1999 European Space Agency (ESA)
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2 of the License, or (at your option) any later version.
--
-- See the file COPYING.LGPL for the full details of the license.
-----------------------------------------------------------------------------
-- Entity: iu
-- File: iu.vhd
-- Author: Jiri Gaisler - ESA/ESTEC
-- Description: LEON integer unit. Consists of 5 pipline stages: fetch,
-- decode, execute, memory and write-back. Each stage is
-- implemented in a separate process.
------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned.conv_integer;
use work.leon_target.all;
use work.leon_config.all;
use work.mmuconfig.all;
use work.sparcv8.all;
use work.leon_iface.all;
use work.macro.all;
use work.tech_map.all;
use work.multlib.all;
entity iu is
port (
rst : in std_logic;
clk : in clk_type;
holdn : in std_logic;
ici : out icache_in_type; -- icache input
ico : in icache_out_type; -- icache output
dci : out dcache_in_type; -- dcache input
dco : in dcache_out_type; -- dcache output
fpui : out fpu_in_type; -- FPU input
fpuo : in fpu_out_type; -- FPU output
iui : in iu_in_type; -- system input
iuo : out iu_out_type; -- system output
rfi : out rf_in_type; -- register-file input
rfo : in rf_out_type; -- register-file output
cpi : out cp_in_type; -- CP input
cpo : in cp_out_type; -- CP output
fpi : out cp_in_type; -- FP input
fpo : in cp_out_type -- FP output
);
end;
architecture rtl of iu is
-- pipeline_control type is defined in package iface
type fetch_stage_inputs is record
branch : std_logic; -- select branch address
jump : std_logic; -- select jump address
exception : std_logic; -- select exception address
hold_pc : std_logic; -- hold PC (multi-cycle inst.)
branch_address : std_logic_vector(31 downto PCLOW); -- branch address
jump_address : std_logic_vector(31 downto PCLOW); -- jump address
trap_address : std_logic_vector(31 downto PCLOW); -- trap address
end record;
type fetch_stage_registers is record
pc : std_logic_vector(31 downto PCLOW); -- program counter
branch : std_logic; -- branch indicator
end record;
type decode_stage_type is record
inst : std_logic_vector(31 downto 0); -- instruction
pc : std_logic_vector(31 downto PCLOW); -- program counter
mexc : std_logic; -- memory exception (fetch)
annul : std_logic; -- instruction annul bit
cnt : std_logic_vector(1 downto 0); -- cycle number (multi-cycle inst)
mulcnt : std_logic_vector(4 downto 0); -- cycle number (multiplier)
pv : std_logic; -- PC valid flag
cwp : std_logic_vector(NWINLOG2-1 downto 0); -- current window pointer
step : std_logic; -- single step
end record;
type execute_stage_type is record
write_cwp, write_icc, write_reg, write_y, rst_mey : std_logic;
cwp : std_logic_vector(NWINLOG2-1 downto 0); -- current window pointer
icc : std_logic_vector(3 downto 0); -- integer condition codes
alu_cin : std_logic; -- ALU carry-in
ymsb : std_logic; -- MULSCC Y(msb)
rs1data : std_logic_vector(31 downto 0); -- source operand 1
rs2data : std_logic_vector(31 downto 0); -- source operand 2
aluop : std_logic_vector(2 downto 0); -- Alu operation
alusel : std_logic_vector(1 downto 0); -- Alu result select
aluadd : std_logic; -- add/sub select
mulstep : std_logic; -- MULSCC
mulinsn : std_logic; -- SMUL/UMUL
ldbp1, ldbp2 : std_logic; -- load bypass enable
ctrl : pipeline_control_type;
result : std_logic_vector(31 downto 0); -- data forward from execute stage
micc : std_logic_vector(3 downto 0); -- icc for multiply insn
licc : std_logic_vector(3 downto 0); -- icc to me stage
end record;
type memory_stage_type is record
inull : std_logic;
signed : std_logic; -- signed load
addr_misal : std_logic; -- misaligned address
write_cwp, write_icc, write_reg, write_y : std_logic;
cwp : std_logic_vector(NWINLOG2-1 downto 0);
icc : std_logic_vector(3 downto 0);
result : std_logic_vector(31 downto 0);
bpresult : std_logic_vector(31 downto 0); -- result for bypass to de & me
y : std_logic_vector(31 downto 0); -- pipeline Y register
my : std_logic_vector(31 downto 0); -- me stage Y feedback
memory_load : std_logic;
mulinsn : std_logic; -- SMUL/UMUL
ld_size : std_logic_vector(1 downto 0); -- memory load size
ctrl : pipeline_control_type;
jmpl_rett : std_logic;
irqen : std_logic;
ipend : std_logic;
werr : std_logic; -- store error
su : std_logic; -- supervisor mode
end record;
type write_stage_type is record
write_cwp, write_icc, write_reg : std_logic;
cwp : std_logic_vector(NWINLOG2-1 downto 0);
icc : std_logic_vector(3 downto 0);
result : std_logic_vector(31 downto 0);
y : std_logic_vector(31 downto 0);
asr18 : std_logic_vector(31 downto 0);
annul_all : std_logic;
trapping : std_logic;
error : std_logic;
nerror : std_logic;
mexc : std_logic;
intack : std_logic;
tpcsel : std_logic_vector(1 downto 0); -- Trap pc select
dsutrap : std_logic; -- debug unit trap (optional)
ctrl : pipeline_control_type;
end record;
type special_register_type is record
cwp : std_logic_vector(NWINLOG2-1 downto 0); -- current window pointer
icc : std_logic_vector(3 downto 0); -- integer condition codes
tt : std_logic_vector(7 downto 0); -- trap type
tba : std_logic_vector(19 downto 0); -- trap base address
wim : std_logic_vector(NWINDOWS-1 downto 0); -- window invalid mask
pil : std_logic_vector(3 downto 0); -- processor interrupt level
ec : std_logic; -- enable CP
ef : std_logic; -- enable FP
ps : std_logic; -- previous supervisor flag
s : std_logic; -- supervisor flag
et : std_logic; -- enable traps
end record;
type fsr_type is record
cexc : std_logic_vector(4 downto 0); -- current exceptions
aexc : std_logic_vector(4 downto 0); -- accrued exceptions
fcc : std_logic_vector(1 downto 0); -- FPU condition codes
ftt : std_logic_vector(2 downto 0); -- FPU trap type
tem : std_logic_vector(4 downto 0); -- trap enable mask
rd : std_logic_vector(1 downto 0); -- rounding mode
end record;
type fpu_ctrl1_type is record
fpop : std_logic_vector(1 downto 0); -- FPOP type
dsz : std_logic; -- destination size (0=single, 1=double)
ldfsr : std_logic; -- LDFSR in progress
end record;
type fpu_ctrl2_type is record
fpop : std_logic_vector(1 downto 0);
dsz : std_logic;
fcc : std_logic_vector(1 downto 0);
cexc : std_logic_vector(4 downto 0); -- current FPU excetion bits
ldfsr : std_logic;
end record;
type fpu_reg_type is record
fsr : fsr_type;
fpop : std_logic;
reset : std_logic;
rstdel : std_logic_vector(1 downto 0);
fpbusy : std_logic;
fpld : std_logic;
fpexc : std_logic;
op1h : std_logic_vector(31 downto 0);
ex : fpu_ctrl1_type;
me, wr : fpu_ctrl2_type;
end record;
constant WPALEN : integer := 30;
type watchpoint_register is record
addr : std_logic_vector(WPALEN+1 downto 2); -- watchpoint address
mask : std_logic_vector(WPALEN+1 downto 2); -- watchpoint mask
exec : std_logic; -- trap on instruction
load : std_logic; -- trap on load
store : std_logic; -- trap on store
end record;
type watchpoint_registers is array (0 to 3) of watchpoint_register;
type dsu_registers is record
pc : std_logic_vector(31 downto PCLOW); -- program counter
dmode : std_logic; -- debug mode active
dmode2 : std_logic; -- debug mode active (delayed)
dstate : std_logic; -- debug state
tt : std_logic_vector(7 downto 0); -- trap type
error : std_logic; -- trap would cause error
dsuen : std_logic;
end record;
component div
port (
rst : in std_logic;
clk : in clk_type;
holdn : in std_logic;
divi : in div_in_type;
divo : out div_out_type
);
end component;
component mul
port (
rst : in std_logic;
clk : in clk_type;
holdn : in std_logic;
muli : in mul_in_type;
mulo : out mul_out_type
);
end component;
-- registers
constant FASTADD : boolean := false;
constant PILOPT : boolean := FASTDECODE;
constant Zero32: std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal fecomb : fetch_stage_inputs;
signal fe, fein : fetch_stage_registers;
signal de, dein : decode_stage_type;
signal ex, exin : execute_stage_type;
signal me, mein : memory_stage_type;
signal wr, wrin : write_stage_type;
signal sregsin, sregs : special_register_type;
signal dciin : dcache_in_type;
signal fpu_reg, fpu_regin : fpu_reg_type;
signal tr, trin : watchpoint_registers;
signal dsur, dsurin : dsu_registers;
signal muli : mul_in_type; -- multiplier input
signal mulo : mul_out_type; -- muliplier output
signal divi : div_in_type; -- divider input
signal divo : div_out_type; -- divider output
signal sum32, add32in1, add32in2 : std_logic_vector(31 downto 0);
signal add32cin : std_logic;
begin
-------------------------------------------------------------------------------
-- Instruction fetch stage
-------------------------------------------------------------------------------
fetch_stage : process(fecomb, fe, rst, de, mein)
variable v : fetch_stage_registers;
variable npc : std_logic_vector(31 downto PCLOW);
begin
v := fe;
-- pc generation
npc := fe.pc;
if (rst = '0') then
v.pc := (others => '0'); v.branch := '0';
elsif fecomb.exception = '1' then -- exception
v.branch := '1'; v.pc := fecomb.trap_address;
npc := v.pc;
elsif (not mein.inull and fecomb.hold_pc) = '1' then
v.pc := fe.pc; v.branch := fe.branch;
elsif fecomb.jump = '1' then
v.pc := fecomb.jump_address; v.branch := '1';
npc := v.pc;
elsif fecomb.branch = '1' then
v.pc := fecomb.branch_address; v.branch := '1';
npc := v.pc;
else
v.branch := '0';
-- pragma translate_off
if not is_x(fe.pc) then
-- pragma translate_on
v.pc(31 downto 2) := fe.pc(31 downto 2) + 1; -- Address incrementer
-- pragma translate_off
else
v.pc := (others => 'X');
end if;
-- pragma translate_on
npc := v.pc;
end if;
-- drive register inputs
fein <= v;
-- drive some icache inputs
-- ici.rpc(31 downto PCLOW) <= v.pc(31 downto PCLOW);
ici.rpc(31 downto PCLOW) <= npc;
ici.fpc(31 downto PCLOW) <= fe.pc(31 downto PCLOW);
ici.dpc(31 downto PCLOW) <= de.pc(31 downto PCLOW);
ici.fbranch <= fe.branch;
ici.rbranch <= v.branch;
end process;
-------------------------------------------------------------------------------
-- Instruction decode stage
-------------------------------------------------------------------------------
decode_stage : process(rst, fe, de, ex, me, mein, wrin, wr, sregs, ico, rfo,
sregsin, fpo, cpo, dco, holdn, fpu_reg, mulo, divo, tr,
iui, dsur)
variable rfenable1, rfenable2 : std_logic; -- regfile enable strobes
variable op : std_logic_vector(1 downto 0);
variable op2 : std_logic_vector(2 downto 0);
variable op3 : std_logic_vector(5 downto 0);
variable opf : std_logic_vector(8 downto 0);
variable cond : std_logic_vector(3 downto 0);
variable rs1, rs2, rd : std_logic_vector(4 downto 0);
variable write_cwp, write_icc, write_reg, write_y : std_logic;
variable cnt : std_logic_vector(1 downto 0); -- cycle number
variable cwp_new : std_logic_vector(NWINLOG2-1 downto 0);
variable icc, br_icc : std_logic_vector(3 downto 0);
variable alu_cin : std_logic;
variable immediate_data : std_logic_vector(31 downto 0);
variable n, z, v, c : std_logic; -- temporary condition codes
variable i : std_logic; -- immidiate data bit
variable su : std_logic; -- local supervisor bit;
variable et : std_logic; -- local enable trap bit
variable inull, annul, annul_current : std_logic;
variable branch, annul_next, bres, branch_true: std_logic;
variable aluop : std_logic_vector(2 downto 0);
variable alusel : std_logic_vector(1 downto 0);
variable aluadd : std_logic;
variable mulstep : std_logic;
variable mulinsn : std_logic;
variable y0 : std_logic;
variable branch_address : std_logic_vector(31 downto PCLOW);
variable rs1data, rs2data : std_logic_vector(31 downto 0);
variable operand2_select : std_logic;
variable read_addr1, read_addr2, chkrd : std_logic_vector(RABITS-1 downto 0);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?