📄 iu.vhd
字号:
------------------------------------------------------------------------------ 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.-------------------------------------------------------------------------------- Version control:-- 07-11-1997: First implemetation-- 26-09-1999: Release 1.0-- 15-10-1999: Fixed data dependecy problem for store data when two load-- delay cycles are configured.-- 28-12-1999: Improved data cache interface timing-- 29-12-1999: Added Meiko FPU interface-- 11-02-2000: Release 2.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.target.all;use work.config.all;use work.sparcv8.all;use work.iface.all;use work.macro.all;entity iu isport ( rst : std_logic; clk : in clk_type; iclk : in clk_type; dclk : 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 rfi : out rf_in_type; -- register-file input rfo : in rf_out_type; -- register-file 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 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 ifacetype 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 addressend record;type fetch_stage_registers is record pc : std_logic_vector(31 downto PCLOW); -- program counter branch : std_logic; -- branch indicatorend 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 pointerend 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 stageend 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 memory_load : std_logic; ld_size : std_logic_vector(1 downto 0); -- memory load size ctrl : pipeline_control_type; jmpl_rett : std_logic; irqen : std_logic; werr : std_logic; -- store errorend 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; 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 trapsend 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 modeend 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 progressend 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;-- reset2 : std_logic; 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;-- registersconstant PILOPT : boolean := FASTDECODE;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;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 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.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, wr, sregs, ico, rfo, sregsin, fpo, cpo, dco, holdn, fpu_reg) 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); variable hold_pc : std_logic; -- Hold PC during multi-cycle ops variable pv : std_logic; -- PC valid variable ldlock, ldcheck1, ldcheck2, ldcheck3 : std_logic; -- load interlock 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 ticc_exception : std_logic; -- TICC trap variable fp_exception : std_logic; -- STDFQ 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 variable fpld, fpst, fpop : std_logic; -- FPU instructions variable fpmov : std_logic; -- FPU instructions variable fbres, fbranch_true : std_logic; -- FBCC branch result variable cbres, cbranch_true : std_logic; -- CBCC branch result variable fcc : std_logic_vector(1 downto 0); -- FPU condition codes variable ccc : std_logic_vector(1 downto 0); -- CP condition codes variable echeck1, echeck2 : std_logic; -- regfile EDAC check enable variable bicc_hold, icc_check : std_logic; variable fsr_ld, fsr_ld_check, fsr_check, fsr_lock : std_logic; variable fpexin : fpu_ctrl1_type; variable rs1mod : std_logic; variable cpldlock, fpldlock, annul_current_cp : std_logic; constant RDOPT : boolean := FASTDECODE;-- optimise dest reg address generation constant RS1OPT : boolean := FASTDECODE;-- optimise src1 reg address generation function regdec(cwp, regin : std_logic_vector; fp : std_logic) return std_logic_vector is variable reg : std_logic_vector(4 downto 0); variable ra : std_logic_vector(RABITS -1 downto 0); begin reg := regin; ra(4 downto 0) := reg; if ((FPTYPE = meiko) and FPEN) and (fp = '1') then ra(RABITS -1 downto 5) := F0ADDR(RABITS-5 downto 1); elsif reg(4 downto 3) = "00" then ra(RABITS -1 downto 4) := R0ADDR; else-- pragma translate_off if not (is_x(cwp & ra(4))) then-- pragma translate_on ra(NWINLOG2+3 downto 4) := (cwp + ra(4)); if CWPOPT then ra(RABITS-1) := '0'; elsif ra(RABITS-1 downto 4) = R0ADDR then ra(RABITS-1 downto 4) := (others => '0'); end if;-- pragma translate_off end if;-- pragma translate_on end if; return(ra); end;begin-- instruction bit-field decoding op := de.inst(31 downto 30); op2 := de.inst(24 downto 22); op3 := de.inst(24 downto 19); opf := de.inst(13 downto 5); 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);-- common initialisation ctrl.annul := de.annul; ctrl.cnt := de.cnt; ctrl.pv := de.pv; pv := '1'; 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'; fpld := '0'; fpst := '0'; fpop := '0'; fp_exception := '0'; fpmov := '0'; fpexin.fpop := "00"; fpexin.dsz := '0'; fpexin.ldfsr := '0';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -