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

📄 iu.vhd

📁 ARM7的源代码
💻 VHD
📖 第 1 页 / 共 5 页
字号:
-- PC generation    branch := '0'; annul_next := '0'; annul_current := '0';    inull := not Rst; hold_pc := '0'; ticc_exception := '0';    fpop := '0'; fpld := '0';    if ((ldlock or de.annul) = '0') then      case op is      when CALL =>        branch := '1';	if mein.inull = '1' then 	  hold_pc := '1'; annul_current := '1';	end if;      when FMT2 =>        if (op2 = BICC) or (FPEN and (op2 = FBFCC)) or (CPEN and (op2 = CBCCC)) then          if (FPEN and (op2 = FBFCC)) then 	    branch := fbranch_true;	    if (FPIFTYPE = parallel) and (fpo.ccv /= '1') then 	      hold_pc := '1'; annul_current := '1';	    end if;          elsif (CPEN and (op2 = CBCCC)) then 	    branch := cbranch_true;	    if cpo.ccv /= '1' then hold_pc := '1'; annul_current := '1'; end if;	  else branch := branch_true; end if;	  if hold_pc = '0' then  	    if (branch = '1') then              if (cond = BA) and (annul = '1') then annul_next := '1'; end if;            else annul_next := annul; end if;	    if mein.inull = '1' then -- contention with JMPL	      hold_pc := '1'; annul_current := '1'; annul_next := '0';	    end if;	  end if;        end if;      when FMT3 =>        case op3 is	when FPOP1 | FPOP2 =>	  if ((FPIFTYPE = serial) and FPEN) then            case de.cnt is            when "00" =>	      if (opf(1) or fpexin.dsz) = '1' then 		hold_pc := '1'; pv := '0'; cnt := "01";	      end if;	      if (opf(1) or fpmov) = '0' then fpop := holdn; end if;	      if op3 = FPOP1 then write_reg := not (opf(1) and not fpexin.dsz); end if;            when others =>	      if op3 = FPOP1 then write_reg := '1'; end if;	      fpop := opf(1) and holdn; cnt := "00";	    end case;	  end if;        when UMUL | SMUL | UMULCC | SMULCC =>	  if MULTIPLIER = iterative then            case de.cnt is            when "00" => 	      cnt := "01"; hold_pc := '1'; mulcnt := (others => '0'); pv := '0';            when "01" => 	      hold_pc := '1'; pv := '0'; cnt := "01"; mulcnt := mulcnt + 1; 	      if (de.mulcnt = "11111") then cnt := "10"; end if;            when "10" => 	      cnt := "11"; pv := '0'; hold_pc := '1';            when "11" => 	      cnt := "00";             when others => null;	    end case;	  end if;	  if (MULTIPLIER > iterative) and (MULTIPLIER /= m32x32) then            case de.cnt is            when "00" => 	      cnt := "01"; hold_pc := '1'; mulcnt := (others => '0'); pv := '0';	      mulstart := '1';            when "01" => 	      if mulo.ready = '1' then cnt := "00";               else cnt := "01"; pv := '0'; hold_pc := '1'; end if;            when others => null;	    end case;	  end if;        when UDIV | SDIV | UDIVCC | SDIVCC =>	  if DIVIDER /= none then            case de.cnt is            when "00" => 	      cnt := "01"; hold_pc := '1'; mulcnt := (others => '0'); pv := '0';	      divstart := '1';            when "01" => 	      if divo.ready = '1' then cnt := "00";               else cnt := "01"; pv := '0'; hold_pc := '1'; end if;            when others => null;	    end case;	  end if;        when TICC =>	  if branch_true = '1' then ticc_exception := '1'; end if;        when RETT =>          ctrl.rett := '1'; su := sregs.ps;         when others => null;        end case;      when LDST =>        case de.cnt is        when "00" =>          if (op3(2) = '1') or (op3(1 downto 0) = "11") then -- ST/LDST/SWAP/LDD 	    cnt := "01"; hold_pc := '1'; pv := '0';          end if;        when "01" =>          if (op3(2 downto 0) = "111") or (op3(3 downto 0) = "1101") or             ((CPEN or FPEN) and ((op3(5) & op3(2 downto 0)) = "1110"))	  then	-- LDD/STD/LDSTUB/SWAP 	    cnt := "10"; pv := '0'; hold_pc := '1';	  else 	    cnt := "00";          end if;        when "10" => 	  cnt := "00";        when others => null;	end case;      when others => null;      end case;    end if;    muli.start  <= mulstart;    divi.start  <= divstart;-- instruction watchpoints    watchpoint_exc := '0';    for i in 0 to WATCHPOINTS-1 loop      if ((tr(i).exec and not de.annul) = '1') then         if (((tr(i).addr xor de.pc(31 downto 2)) and tr(i).mask) = Zero32(31 downto 2)) then           watchpoint_exc := '1';	 end if;      end if;    end loop;    if DEBUG_UNIT then      if  ((iui.debug.dsuen and iui.debug.bwatch and not de.annul) = '1') then        watchpoint_exc := de.pv and (watchpoint_exc or iui.debug.dbreak or de.step);      end if;    end if;--  prioritise traps    ctrl.trap := de.mexc or privileged_inst or illegal_inst or fp_disabled or	cp_disabled or ticc_exception or winunf_exception or	winovf_exception or fp_exception or watchpoint_exc;    if de.mexc = '1' then ctrl.tt := IAEX_TT;    elsif privileged_inst = '1' then ctrl.tt := PRIV_TT;     elsif illegal_inst = '1' then ctrl.tt := IINST_TT;    elsif fp_disabled = '1' then ctrl.tt := FPDIS_TT;    elsif cp_disabled = '1' then ctrl.tt := CPDIS_TT;    elsif watchpoint_exc = '1' then ctrl.tt := WATCH_TT;    elsif winovf_exception = '1' then ctrl.tt := WINOF_TT;    elsif winunf_exception = '1' then ctrl.tt := WINUF_TT;    elsif fp_exception = '1' then ctrl.tt := FPEXC_TT;    elsif ticc_exception = '1' then ctrl.tt := TICC_TT;    end if;    hold_pc := (hold_pc or ldlock) and not wr.annul_all;    if hold_pc = '1' then dein.pc <= de.pc;    else dein.pc <= fe.pc; end if;    annul_current_cp := annul_current;    annul_current := (annul_current or ldlock or wr.annul_all);    ctrl.annul := de.annul or wr.annul_all or annul_current;    pv := pv and not ((mein.inull and not hold_pc) or wr.annul_all);    annul_next := (mein.inull and not hold_pc) or annul_next or wr.annul_all                  or (ldlock and de.annul);                                        if (annul_next = '1') or (rst = '0') then      cnt := (others => '0'); mulcnt := (others => '0');    end if;    if DEBUG_UNIT then      step := iui.debug.step and pv and not de.annul;    end if;    fecomb.hold_pc <= hold_pc;    fecomb.branch <= branch;    dein.annul <= annul_next;    dein.cnt <= cnt;    dein.mulcnt <= mulcnt;    dein.step <= step;    dein.pv <= pv;    -- pv means that the corresponding pc can be save on a trap    ctrl.pv := de.pv and 		not ((de.annul and not de.pv) or wr.annul_all or annul_current);    inull := inull or mein.inull or hold_pc or wr.annul_all;    ici.nullify <= inull;    ici.su <= su;    exin.ctrl <= ctrl;    exin.write_reg <= write_reg;-- latch next cwp    if wr.trapping = '1' then      dein.cwp <= sregsin.cwp;    elsif (write_cwp and not ctrl.annul) = '1' then      dein.cwp <= cwp_new;    elsif (ex.write_cwp and not ex.ctrl.annul) = '1' then      dein.cwp <= ex.cwp;    elsif (me.write_cwp and not me.ctrl.annul) = '1' then      dein.cwp <= me.cwp;    elsif (wr.write_cwp and not wr.ctrl.annul) = '1' then      dein.cwp <= wr.cwp;    else      dein.cwp <= sregs.cwp;    end if;-- y-register write select and forwarding    rst_mey := '0';    case op is    when FMT3 =>      case op3 is      when MULSCC => write_y := '1';      when WRY => if rd = "00000" then write_y := '1'; end if;      when  UMAC | SMAC  =>	if MACEN then write_y := '1'; end if;      when  UMUL | SMUL | UMULCC | SMULCC =>	if MULTIPLIER = iterative then          if de.cnt = "00" then rst_mey := '1'; end if;	  if de.cnt = "11" then write_y := '1'; end if;	end if;	if MULTIPLIER = m32x32 then write_y := '1'; end if;      when others => null;      end case;    when others => null;    end case;-- debug unit diagnostic regfile read    if DEBUG_UNIT and (dsur.dmode and iui.debug.denable) = '1' then      read_addr1 := iui.debug.daddr(RABITS+1 downto 2); rfenable1 := '1';    end if;    exin.write_y <= write_y;    exin.rst_mey <= rst_mey;    exin.rs1data <= rs1data;    exin.rs2data <= rs2data;    exin.ymsb <= ymsb;    rfi.rd1addr <= read_addr1; rfi.rd2addr <= read_addr2;-- CP/FPU interface    if (FPIFTYPE = serial) then      fpu_regin.fpop <= fpop and (not fpu_reg.fpld) and not ctrl.annul;      fpexin.ldfsr := fsr_ld;      fpu_regin.ex <= fpexin;    end if;    if CPEN then      cpi.dannul <= annul_current_cp or cpldlock or wr.annul_all or de.annul;      cpi.dtrap  <= ctrl.trap;    end if;    if FPIFTYPE = parallel then      fpi.dannul <= annul_current_cp or fpldlock or wr.annul_all or de.annul;      fpi.dtrap  <= ctrl.trap;      fpi.fdata  <= ico.data;      fpi.frdy <= (not ico.mds) or (holdn and not hold_pc);                end if;    if RF_LOWPOW = false then rfenable1 := '1'; rfenable2 := '1';  end if;    rfi.ren1 <= rfenable1; rfi.ren2 <= rfenable2;  end process;--------------------------------------------------------------------------------- execute stage-------------------------------------------------------------------------------  execute_stage : process(rst, de, ex, me, wr, wrin, sregs, fpu_reg, fpu_regin, 			  fpo, cpo, fpuo, mulo, divo, tr, iui, dsur, sum32)  variable op     : std_logic_vector(1 downto 0);  variable op3    : std_logic_vector(5 downto 0);  variable opf    : std_logic_vector(8 downto 0);  variable rs1    : std_logic_vector(4 downto 0);  variable inull, jump, link_pc : std_logic;  variable dcache_write : std_logic;	-- Load or store cycle  variable memory_load : std_logic;  variable signed           : std_logic;  variable enaddr           : std_logic;  variable force_a2         : std_logic;     -- force A(2) in second LDD cycle  variable addr_misal       : std_logic;     -- misaligned address (JMPL/RETT)  variable ld_size          : std_logic_vector(1 downto 0); -- Load size  variable read             : std_logic;  variable su      : std_logic;			-- Local supervisor bit  variable asi              : std_logic_vector(7 downto 0); -- Local ASI  variable ctrl : pipeline_control_type;  variable res, y : std_logic_vector(31 downto 0);  variable icc, licc, micc : std_logic_vector(3 downto 0);  variable addout : std_logic_vector(31 downto 0);  variable shiftout : std_logic_vector(31 downto 0);  variable logicout : std_logic_vector(31 downto 0);  variable miscout : std_logic_vector(31 downto 0);  variable edata : std_logic_vector(31 downto 0);  variable aluresult : std_logic_vector(31 downto 0);  variable eaddress : std_logic_vector(31 downto 0);  variable nexty : std_logic_vector(31 downto 0);  variable aluin1, aluin2 : std_logic_vector(31 downto 0);  variable shiftin : std_logic_vector(63 downto 0);  variable shiftcnt : std_logic_vector(4 downto 0);  variable ymsb : std_logic;		-- next msb of Y during MUL  variable write_reg, write_icc, write_y : std_logic;  variable lock : std_logic;  variable dsu_cache : std_logic;  variable fpmein : fpu_ctrl2_type;  variable mulop1, mulop2 : std_logic_vector(32 downto 0);  variable wpi : integer range 0 to 3;  -- watchpoint index  variable addin2 : std_logic_vector(31 downto 0);  variable cin : std_logic;  begin-- op-code decoding    op    := ex.ctrl.inst(31 downto 30);    op3   := ex.ctrl.inst(24 downto 19);    opf   := ex.ctrl.inst(13 downto 5);    rs1   := ex.ctrl.inst(18 downto 14);-- common initialisation    ctrl := ex.ctrl; memory_load := '0';    ctrl.annul := ctrl.annul or wr.annul_all;    read := not op3(2);    dcache_write := '0'; enaddr := '0'; wpi := 0;    ld_size := LDWORD; signed := '0'; addr_misal := '0'; lock := '0';    write_reg := ex.write_reg;    write_icc := ex.write_icc;    write_y := ex.write_y;    fpmein.fpop := fpu_reg.ex.fpop;    fpmein.dsz := fpu_reg.ex.dsz;    fpmein.ldfsr := fpu_reg.ex.ldfsr;    fpmein.cexc := fpuo.excep(4 downto 0);    fpmein.fcc := fpuo.ConditionCodes;    muli.mac <= op3(5);    dsu_cache := '0';-- load/store size decoding    case op is    when LDST =>      case op3 is      when LDUB | LDUBA => ld_size := LDBYTE;      when LDSTUB | LDSTUBA => ld_size := LDBYTE; lock := '1';      when LDUH | LDUHA => ld_size := LDHALF;      when LDSB | LDSBA => ld_size := LDBYTE; signed := '1';      when LDSH | LDSHA => ld_size := LDHALF; signed := '1';      when LD | LDA | LDF | LDC => ld_size := LDWORD;      when SWAP | SWAPA => ld_size := LDWORD; lock := '1';      when LDD | LDDA | LDDF | LDDC => ld_size := LDDBL;      when STB | STBA => ld_size := LDBYTE;      when STH | STHA => ld_size := LDHALF;      when ST | STA | STF => ld_size := LDWORD;      when ISTD | STDA => ld_size := LDDBL;      when STDF | STDFQ => if FPEN then ld_size := LDDBL; end if;      when STDC | STDCQ => if CPEN then ld_size := LDDBL; end if;      when others => null;      end case;    when others => null;    end case;    link_pc := '0'; jump:= '0'; inull :='0'; force_a2 := '0';-- load/store control decoding    if (ctrl.annul = '0') then      case op is      when CALL =>        link_pc := '1';      when FMT3 =>        case op3 is        when JMPL =>          jump := '1'; link_pc := '1'; 

⌨️ 快捷键说明

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