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 + -
显示快捷键?