⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iu.vhd

📁 一个航天航空用的Sparc处理器(配美国欧洲宇航局用的R_tems嵌入式操作系统)的VHDL源代码
💻 VHD
📖 第 1 页 / 共 4 页
字号:
-----------------------------------------------------------------------------
--  This file is a part of the LEON VHDL model
--  Copyright (C) 1999  European Space Agency (ESA)
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU 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 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.
------------------------------------------------------------------------------
-- Version control:
-- 07-11-1997:	First implemetation
-- 26-09-1999:	Release 1.0
------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned."+";
use IEEE.std_logic_unsigned."-";
use IEEE.std_logic_unsigned.conv_integer;
use work.config.all;
use work.sparcv8.all;
use work.iface.all;
use work.macro.all;

entity iu is
port (
    Rst    : in  std_logic;			-- reset
    Clk    : in  std_logic;			-- main clock
    iclk   : in  std_logic;			-- missed instruction clock
    dclk   : in  std_logic;			-- missed data clock
    holdn  : in  std_logic;			-- pipeline hold
    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
    rfi    : out rf_in_type;			-- register-file input
    rfo    : in  rf_out_type;			-- register-file output
    sysi   : in  sys_in_type;			-- system input
    syso   : out sys_out_type			-- system output
-- pragma translate_off
    ;debug  : out iu_debug_type
-- pragma translate_on
);
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 (multi-cycle inst)
  pv      : std_logic;			    -- PC valid flag
  cwp     : std_logic_vector(NWINLOG2-1 downto 0);	-- current window pointer
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
  ycarry : std_logic;				-- MULSCC 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;
  addr_misal : std_logic;
  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);
  y : std_logic_vector(31 downto 0);
  memory_load : std_logic;
  ld_size      : std_logic_vector(1 downto 0); -- Load size
  ctrl : pipeline_control_type;
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);
  annul_all : std_logic;
  trapping : std_logic;
  error : std_logic;
  mexc : std_logic;
  wexc : std_logic;
  intack : std_logic;
  tpcsel           : std_logic_vector(1 downto 0); -- Trap pc select
  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;

-- registers

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;

begin

-------------------------------------------------------------------------------
-- Instruction fetch stage
-------------------------------------------------------------------------------

  fetch_stage : process(fecomb, fe, rst, de, mein)
  variable v : fetch_stage_registers;
  begin

    v := fe;

-- pc generation

    if (rst = '0') then
      v.pc := (others => '0'); v.branch := '0';
    elsif fecomb.exception = '1' then	-- exception: use tbr
      v.branch := '1'; v.pc := fecomb.trap_address;
    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';
    elsif fecomb.branch = '1' then
      v.pc := fecomb.branch_address; v.branch := '1';
    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
    end if;

-- drive register inputs

    fein <= v;

-- drive some icache inputs

    ici.rpc(31 downto PCLOW) <= v.pc(31 downto PCLOW);
    ici.rpc(1 downto 0) <= "00";
    ici.fpc(31 downto PCLOW) <= fe.pc(31 downto PCLOW);
    ici.fpc(1 downto 0) <= "00";
    ici.branch <= fe.branch;

  end process;

-------------------------------------------------------------------------------
-- Instruction decode stage
-------------------------------------------------------------------------------

  decode_stage : process(fe, de, Rst, ex, me, mein, wr, sregs, ico, rfo)
  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 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 : 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_vector(1 downto 0);
  variable read_addr1 : std_logic_vector(RABITS-1 downto 0);
  variable read_addr2 : std_logic_vector(RABITS-1 downto 0);
  variable hold_pc : std_logic;		-- Hold PC during multi-cycle ops
  variable pv : std_logic;		-- PC valid
  variable ldlock, ldcheck1, ldcheck2 : std_logic;  -- load interlock signals
  variable ldchkex, ldchkme : std_logic;  	-- load interlock for ex and me
  variable illegal_inst : std_logic;  	-- illegal instruction
  variable privileged_inst : std_logic;  	-- privileged instruction trap
  variable cp_disabled  : std_logic;  	-- CP disable trap
  variable fp_disabled  : std_logic;  	-- FP disable trap
  variable winovf_exception : std_logic;  	-- window overflow trap
  variable winunf_exception : std_logic;  	-- window underflow trap
  variable fp_exception : std_logic;  	-- window underflow trap
  variable ticc_exception : std_logic;  	-- TICC trap
  variable ctrl : pipeline_control_type;
  variable ldbp1, ldbp2 : std_logic;		-- load bypass enable
  variable mulcnt  : std_logic_vector(4 downto 0);   -- multiply cycle number
  variable ymsb : std_logic;		-- next msb of Y during MUL
  variable rst_mey : std_logic;		-- reset me stage Y register

begin

-- instruction bit-field decoding

    op    := de.inst(31 downto 30);
    op2   := de.inst(24 downto 22);
    op3   := de.inst(24 downto 19);
    cond  := de.inst(28 downto 25);
    annul := de.inst(29);
    rs1   := de.inst(18 downto 14);
    rs2   := de.inst(4 downto 0);
    rd    := de.inst(29 downto 25);
    i     := de.inst(13);

-- reset handling

    if Rst = '0' then
      ctrl.annul := '0'; ctrl.cnt := "00";
      ctrl.pv := '0'; pv := '0';
    else
      ctrl.annul := de.annul; ctrl.cnt := de.cnt;
      ctrl.pv := de.pv; pv := '1';
    end if;

-- common initialisation

    cnt := "00"; ctrl.tt := "000000"; ctrl.ld := '0'; ctrl.rett := '0';
    ctrl.pc := de.pc; ctrl.inst := de.inst; mulcnt := de.mulcnt;
    write_y := '0';

    winovf_exception := '0'; winunf_exception := '0';
    write_cwp := '0'; cwp_new := de.cwp;

-- detect RETT instruction in the pipeline and set the local psr.su and psr.et

    if ((ex.ctrl.rett and not ex.ctrl.annul) or (me.ctrl.rett and not me.ctrl.annul) or 
        (wr.ctrl.rett and not wr.ctrl.annul)) = '1' 
    then 
      su := sregs.ps; et := '1';
    else 
      su := sregs.s; et := sregs.et;
    end if;

-- Check for illegal and privileged instructions

    illegal_inst := '0'; privileged_inst := '0'; cp_disabled := '0'; 
    fp_disabled := '0'; fp_exception := '0';
    case op is
    when CALL => null;
    when FMT2 =>
      case op2 is
      when SETHI | BICC => null;
      when FBFCC => fp_disabled := FPDIS or not sregs.ef;
      when CBCCC => cp_disabled := '1';
      when others => illegal_inst := '1';
      end case;
    when FMT3 =>
      case op3 is
      when IAND | ANDCC | ANDN | ANDNCC | IOR | ORCC | ORN | ORNCC | IXOR |
        XORCC | IXNOR | XNORCC | ISLL | ISRL | ISRA | MULSCC | IADD | ADDX |
	ADDCC | ADDXCC | TADDCC | TADDCCTV | ISUB | SUBX | SUBCC | SUBXCC |
	TSUBCC | TSUBCCTV  | FLUSH | JMPL | TICC | SAVE | RESTORE | RDY => null;
      when UMUL | SMUL | UMULCC | SMULCC => 
	if MULTIPLIER = none then illegal_inst := '1'; end if;
      when RETT => illegal_inst := et; privileged_inst := not su;
      when RDPSR | RDTBR | RDWIM => privileged_inst := not su;
      when WRY  => 
	if rd /= "00000" then illegal_inst := '1'; end if;
	privileged_inst := not su;
      when WRPSR => 
	privileged_inst := not su; 
      when WRWIM | WRTBR  => privileged_inst := not su;
      when FPOP1 | FPOP2 => fp_disabled := FPDIS or not sregs.ef;
      when CPOP1 | CPOP2 => cp_disabled := '1';
      when others => illegal_inst := '1';
      end case;
    when others =>	-- LDST
      case op3 is
      when LDD | ISTD => illegal_inst := rd(0);	-- trap if odd destination register
      when LD | LDUB | LDSTUB | LDUH | LDSB | LDSH | ST | STB | STH | SWAP =>
	null;
      when LDDA | STDA =>
	illegal_inst := i or rd(0); privileged_inst := not su;
      when LDA | LDUBA| LDSTUBA | LDUHA | LDSBA | LDSHA | STA | STBA | STHA |
	   SWAPA => 
	illegal_inst := i; privileged_inst := not su;
      when LDDF | STDF => 
	fp_disabled := FPDIS or not sregs.ef; fp_exception := rd(0);
      when STDFQ => 
	privileged_inst := not su; fp_disabled := FPDIS or not sregs.ef;
      when LDF | LDFSR | STF | STFSR => 
	fp_disabled := FPDIS or not sregs.ef;
      when STDCQ => 
	privileged_inst := not su; cp_disabled := '1';
      when LDC | LDCSR | LDDC | STC | STCSR | STDC => 
	cp_disabled := '1';
      when others => illegal_inst := '1';
      end case;
    end case;

-- branch address adder

    branch_address := (others => '0');
    if op = CALL then branch_address(31 downto 2) := de.inst(29 downto 0);
    else branch_address(31 downto 2) := de.inst(21) & de.inst(21) & de.inst(21) & 
            de.inst(21) & de.inst(21) & de.inst(21) & de.inst(21) & 
            de.inst(21) & de.inst(21 downto 0);
    end if;

-- pragma translate_off
    if not (is_x(branch_address) or is_x(de.pc)) then
-- pragma translate_on
      branch_address := branch_address + de.pc;	-- address adder (branch)
-- pragma translate_off
    else
      branch_address := (others => 'X');
    end if;
-- pragma translate_on

    fecomb.branch_address <= branch_address;

-- Load decoding

    if de.annul = '0' then
      case op is
      when LDST => ctrl.ld := not op3(2);
      when others => null;
      end case;
    end if;

-- ICC pipeline and forwarding

    if (ex.write_icc and not ex.ctrl.annul) = '1' then
      icc := ex.icc;
    elsif (me.write_icc and not me.ctrl.annul) = '1' then
      icc := me.icc;
    elsif (wr.write_icc and not wr.ctrl.annul) = '1' then
      icc := wr.icc;
    else
      icc := sregs.icc;
    end if;

    write_icc := '0'; alu_cin := '0';

    case op is
    when FMT3 =>
      case op3 is
      when SUBCC | TSUBCC | TSUBCCTV => 
	write_icc := '1';
      when ADDCC | ANDCC | ORCC | XORCC | ANDNCC | ORNCC | XNORCC | MULSCC |
           TADDCC | TADDCCTV => 
	write_icc := '1';
      when UMULCC | SMULCC =>
	if MULTIPLIER = iterative then
	  if de.cnt /= "11" then write_icc := '1'; end if;
	end if;
      when ADDX | SUBX => 
	alu_cin := icc(0);
      when  ADDXCC | SUBXCC => 
	write_icc := '1'; alu_cin := icc(0);
      when others => null;
      end case;
    when others => null;
    end case;

    exin.write_icc <= write_icc;
    exin.alu_cin <= alu_cin;

-- BICC/TICC evaluation

    n := icc(3); z := icc(2); v := icc(1); c := icc(0);
    case cond(2 downto 0) is
    when "000" => bres := '0';				-- bn, ba
    when "001" => bres := z;      			-- be, bne
    when "010" => bres := z or (n xor v);             	-- ble, bg
    when "011" => bres := n xor v; 	            	-- bl, bge
    when "100" => bres := c or z;   	           	-- blue, bgu
    when "101" => bres := c;		              	-- bcs, bcc 
    when "110" => bres := n;		              	-- bneg, bpos
    when others => bres := v;		              	-- bvs. bvc   
    end case;
    branch_true := cond(3) xor bres;

-- Alu operation generation

    aluop := ALU_NOP; alusel := ALU_RES_MISC; aluadd := '1'; 
    mulstep := '0'; mulinsn := '0';
    case op is
    when FMT2 =>
      case op2 is
      when SETHI => aluop := ALU_PASS2;
      when others => aluop := ALU_NOP;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -