📄 iu3.vhd
字号:
end; signal r, rin : registers; signal wpr, wprin : watchpoint_registers; signal dsur, dsuin : dsu_registers; signal ir, irin : irestart_register; signal rp, rpin : pwd_register_type;-- execute stage operations constant EXE_AND : std_logic_vector(2 downto 0) := "000"; constant EXE_XOR : std_logic_vector(2 downto 0) := "001"; -- must be equal to EXE_PASS2 constant EXE_OR : std_logic_vector(2 downto 0) := "010"; constant EXE_XNOR : std_logic_vector(2 downto 0) := "011"; constant EXE_ANDN : std_logic_vector(2 downto 0) := "100"; constant EXE_ORN : std_logic_vector(2 downto 0) := "101"; constant EXE_DIV : std_logic_vector(2 downto 0) := "110"; constant EXE_PASS1 : std_logic_vector(2 downto 0) := "000"; constant EXE_PASS2 : std_logic_vector(2 downto 0) := "001"; constant EXE_STB : std_logic_vector(2 downto 0) := "010"; constant EXE_STH : std_logic_vector(2 downto 0) := "011"; constant EXE_ONES : std_logic_vector(2 downto 0) := "100"; constant EXE_RDY : std_logic_vector(2 downto 0) := "101"; constant EXE_SPR : std_logic_vector(2 downto 0) := "110"; constant EXE_LINK : std_logic_vector(2 downto 0) := "111"; constant EXE_SLL : std_logic_vector(2 downto 0) := "001"; constant EXE_SRL : std_logic_vector(2 downto 0) := "010"; constant EXE_SRA : std_logic_vector(2 downto 0) := "100"; constant EXE_NOP : std_logic_vector(2 downto 0) := "000";-- EXE result select constant EXE_RES_ADD : std_logic_vector(1 downto 0) := "00"; constant EXE_RES_SHIFT : std_logic_vector(1 downto 0) := "01"; constant EXE_RES_LOGIC : std_logic_vector(1 downto 0) := "10"; constant EXE_RES_MISC : std_logic_vector(1 downto 0) := "11";-- Load types constant SZBYTE : std_logic_vector(1 downto 0) := "00"; constant SZHALF : std_logic_vector(1 downto 0) := "01"; constant SZWORD : std_logic_vector(1 downto 0) := "10"; constant SZDBL : std_logic_vector(1 downto 0) := "11";-- calculate register file address procedure regaddr(cwp : std_logic_vector; reg : std_logic_vector(4 downto 0); rao : out rfatype) is variable ra : rfatype; constant globals : std_logic_vector(RFBITS-5 downto 0) := conv_std_logic_vector(NWIN, RFBITS-4); begin ra := (others => '0'); ra(4 downto 0) := reg; if reg(4 downto 3) = "00" then ra(RFBITS -1 downto 4) := globals; else ra(NWINLOG2+3 downto 4) := cwp + ra(4); if ra(RFBITS-1 downto 4) = globals then ra(RFBITS-1 downto 4) := (others => '0'); end if; end if; rao := ra; end;-- branch adder function branch_address(inst : word; pc : pctype) return std_logic_vector is variable baddr, caddr, tmp : pctype; begin caddr := (others => '0'); caddr(31 downto 2) := inst(29 downto 0); caddr(31 downto 2) := caddr(31 downto 2) + pc(31 downto 2); baddr := (others => '0'); baddr(31 downto 24) := (others => inst(21)); baddr(23 downto 2) := inst(21 downto 0); baddr(31 downto 2) := baddr(31 downto 2) + pc(31 downto 2); if inst(30) = '1' then tmp := caddr; else tmp := baddr; end if; return(tmp); end;-- evaluate branch condition function branch_true(icc : std_logic_vector(3 downto 0); inst : word) return std_ulogic is variable n, z, v, c, branch : std_ulogic; begin n := icc(3); z := icc(2); v := icc(1); c := icc(0); case inst(27 downto 25) is when "000" => branch := inst(28) xor '0'; -- bn, ba when "001" => branch := inst(28) xor z; -- be, bne when "010" => branch := inst(28) xor (z or (n xor v)); -- ble, bg when "011" => branch := inst(28) xor (n xor v); -- bl, bge when "100" => branch := inst(28) xor (c or z); -- bleu, bgu when "101" => branch := inst(28) xor c; -- bcs, bcc when "110" => branch := inst(28) xor n; -- bneg, bpos when others => branch := inst(28) xor v; -- bvs, bvc end case; return(branch); end;-- detect RETT instruction in the pipeline and set the local psr.su and psr.et procedure su_et_select(r : in registers; xc_ps, xc_s, xc_et : in std_ulogic; su, et : out std_ulogic) is begin if ((r.a.ctrl.rett or r.e.ctrl.rett or r.m.ctrl.rett or r.x.ctrl.rett) = '1') and (r.x.annul_all = '0') then su := xc_ps; et := '1'; else su := xc_s; et := xc_et; end if; end;-- detect watchpoint trap function wphit(r : registers; wpr : watchpoint_registers; debug : l3_debug_in_type) return std_ulogic is variable exc : std_ulogic; begin exc := '0'; for i in 1 to NWP loop if ((wpr(i-1).exec and r.a.ctrl.pv and not r.a.ctrl.annul) = '1') then if (((wpr(i-1).addr xor r.a.ctrl.pc(31 downto 2)) and wpr(i-1).mask) = Zero32(31 downto 2)) then exc := '1'; end if; end if; end loop; if DBGUNIT then if (debug.dsuen and not r.a.ctrl.annul) = '1' then exc := exc or (r.a.ctrl.pv and ((debug.dbreak and debug.bwatch) or r.a.step)); end if; end if; return(exc); end;-- 32-bit shifter function shift3(r : registers; aluin1, aluin2 : word) return word is variable shiftin : unsigned(63 downto 0); variable shiftout : unsigned(63 downto 0); variable cnt : natural range 0 to 31; begin cnt := conv_integer(r.e.shcnt); if r.e.shleft = '1' then shiftin(30 downto 0) := (others => '0'); shiftin(63 downto 31) := '0' & unsigned(aluin1); else shiftin(63 downto 32) := (others => r.e.sari); shiftin(31 downto 0) := unsigned(aluin1); end if; shiftout := SHIFT_RIGHT(shiftin, cnt); return(std_logic_vector(shiftout(31 downto 0))); end; function shift2(r : registers; aluin1, aluin2 : word) return word is variable ushiftin : unsigned(31 downto 0); variable sshiftin : signed(32 downto 0); variable cnt : natural range 0 to 31; begin cnt := conv_integer(r.e.shcnt); ushiftin := unsigned(aluin1); sshiftin := signed('0' & aluin1); if r.e.shleft = '1' then return(std_logic_vector(SHIFT_LEFT(ushiftin, cnt))); else if r.e.sari = '1' then sshiftin(32) := aluin1(31); end if; sshiftin := SHIFT_RIGHT(sshiftin, cnt); return(std_logic_vector(sshiftin(31 downto 0)));-- else -- ushiftin := SHIFT_RIGHT(ushiftin, cnt);-- return(std_logic_vector(ushiftin));-- end if; end if; end; function shift(r : registers; aluin1, aluin2 : word; shiftcnt : std_logic_vector(4 downto 0); sari : std_ulogic ) return word is variable shiftin : std_logic_vector(63 downto 0); begin shiftin := zero32 & aluin1; if r.e.shleft = '1' then shiftin(31 downto 0) := zero32; shiftin(63 downto 31) := '0' & aluin1; else shiftin(63 downto 32) := (others => sari); end if; if shiftcnt (4) = '1' then shiftin(47 downto 0) := shiftin(63 downto 16); end if; if shiftcnt (3) = '1' then shiftin(39 downto 0) := shiftin(47 downto 8); end if; if shiftcnt (2) = '1' then shiftin(35 downto 0) := shiftin(39 downto 4); end if; if shiftcnt (1) = '1' then shiftin(33 downto 0) := shiftin(35 downto 2); end if; if shiftcnt (0) = '1' then shiftin(31 downto 0) := shiftin(32 downto 1); end if; return(shiftin(31 downto 0)); end;-- Check for illegal and privileged instructionsprocedure exception_detect(r : registers; wpr : watchpoint_registers; dbgi : l3_debug_in_type; trapin : in std_ulogic; ttin : in std_logic_vector(5 downto 0); trap : out std_ulogic; tt : out std_logic_vector(5 downto 0)) isvariable illegal_inst, privileged_inst : std_ulogic;variable cp_disabled, fp_disabled, fpop : std_ulogic;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 rd : std_logic_vector(4 downto 0);variable inst : word;variable wph : std_ulogic;begin inst := r.a.ctrl.inst; trap := trapin; tt := ttin; if r.a.ctrl.annul = '0' then op := inst(31 downto 30); op2 := inst(24 downto 22); op3 := inst(24 downto 19); rd := inst(29 downto 25); illegal_inst := '0'; privileged_inst := '0'; cp_disabled := '0'; fp_disabled := '0'; fpop := '0'; case op is when CALL => null; when FMT2 => case op2 is when SETHI | BICC => null; when FBFCC => if FPEN then fp_disabled := not r.w.s.ef; else fp_disabled := '1'; end if; when CBCCC => if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if; 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 | ISUB | SUBX | SUBCC | SUBXCC | FLUSH | JMPL | TICC | SAVE | RESTORE | RDY => null; when TADDCC | TADDCCTV | TSUBCC | TSUBCCTV => if notag = 1 then illegal_inst := '1'; end if; when UMAC | SMAC => if not MACEN then illegal_inst := '1'; end if; when UMUL | SMUL | UMULCC | SMULCC => if not MULEN then illegal_inst := '1'; end if; when UDIV | SDIV | UDIVCC | SDIVCC => if not DIVEN then illegal_inst := '1'; end if; when RETT => illegal_inst := r.a.et; privileged_inst := not r.a.su; when RDPSR | RDTBR | RDWIM => privileged_inst := not r.a.su; when WRY => null; when WRPSR => privileged_inst := not r.a.su; when WRWIM | WRTBR => privileged_inst := not r.a.su; when FPOP1 | FPOP2 => if FPEN then fp_disabled := not r.w.s.ef; fpop := '1'; else fp_disabled := '1'; fpop := '0'; end if; when CPOP1 | CPOP2 => if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if; 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 := inst(13) or rd(0); privileged_inst := not r.a.su; when LDA | LDUBA| LDSTUBA | LDUHA | LDSBA | LDSHA | STA | STBA | STHA | SWAPA => illegal_inst := inst(13); privileged_inst := not r.a.su; when LDDF | STDF | LDF | LDFSR | STF | STFSR => if FPEN then fp_disabled := not r.w.s.ef; else fp_disabled := '1'; end if; when STDFQ => privileged_inst := not r.a.su; if (not FPEN) or (r.w.s.ef = '0') then fp_disabled := '1'; end if; when STDCQ => privileged_inst := not r.a.su; if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if; when LDC | LDCSR | LDDC | STC | STCSR | STDC => if (not CPEN) or (r.w.s.ec = '0') then cp_disabled := '1'; end if; when others => illegal_inst := '1'; end case; end case; wph := wphit(r, wpr, dbgi); trap := '1'; if r.a.ctrl.trap = '1' then tt := TT_IAEX; elsif privileged_inst = '1' then tt := TT_PRIV; elsif illegal_inst = '1' then tt := TT_IINST; elsif fp_disabled = '1' then tt := TT_FPDIS; elsif cp_disabled = '1' then tt := TT_CPDIS; elsif wph = '1' then tt := TT_WATCH; elsif r.a.wovf= '1' then tt := TT_WINOF; elsif r.a.wunf= '1' then tt := TT_WINUF; elsif r.a.ticc= '1' then tt := TT_TICC; else trap := '0'; tt:= (others => '0'); end if; end if;end;-- instructions that write the condition codes (psr.icc)procedure wicc_y_gen(inst : word; wicc, wy : out std_ulogic) isbegin wicc := '0'; wy := '0'; if inst(31 downto 30) = FMT3 then case inst(24 downto 19) is when SUBCC | TSUBCC | TSUBCCTV | ADDCC | ANDCC | ORCC | XORCC | ANDNCC | ORNCC | XNORCC | TADDCC | TADDCCTV | ADDXCC | SUBXCC | WRPSR => wicc := '1'; when WRY => if r.d.inst(conv_integer(r.d.set))(29 downto 25) = "00000" then wy := '1'; end if; when MULSCC => wicc := '1'; wy := '1'; when UMAC | SMAC => if MACEN then wy := '1'; end if; when UMULCC | SMULCC => if MULEN and (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then wicc := '1'; wy := '1'; end if; when UMUL | SMUL => if MULEN and (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then wy := '1'; end if; when UDIVCC | SDIVCC => if DIVEN and (divo.nready = '1') and (r.d.cnt /= "00") then wicc := '1'; end if; when others => end case; end if;end;-- select cwp procedure cwp_gen(r, v : registers; annul, wcwp : std_ulogic; ncwp : cwptype; cwp : out cwptype) isbegin if (r.x.rstate = trap) or (r.x.rstate = dsu2) or (rstn = '0') then cwp := v.w.s.cwp; elsif (wcwp = '1') and (annul = '0') then cwp := ncwp; elsif r.m.wcwp = '1' then cwp := r.m.result(NWINLOG2-1 downto 0); else cwp := r.d.cwp; end if;end;-- generate wcwp in ex stageprocedure cwp_ex(r : in registers; wcwp : out std_ulogic) isbegin if (r.e.ctrl.inst(31 downto 30) = FMT3) and (r.e.ctrl.inst(24 downto 19) = WRPSR) then wcwp := not r.e.ctrl.annul; else wcwp := '0'; end if;end;-- generate next cwp & window under- and overflow trapsprocedure cwp_ctrl(r : in registers; xc_wim : in std_logic_vector(NWIN-1 downto 0); inst : word; de_cwp : out cwptype; wovf_exc, wunf_exc, wcwp : out std_ulogic) isvariable op : std_logic_vector(1 downto 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -