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

📄 iu.vhd

📁 ARM7的源代码
💻 VHD
📖 第 1 页 / 共 5 页
字号:
	  inull := me.ctrl.annul or not me.jmpl_rett;        when RETT =>          jump := '1'; inull := me.ctrl.annul or not me.jmpl_rett;        when others => null;        end case;      when LDST =>	if (ctrl.trap or (wrin.ctrl.trap and not wrin.ctrl.annul)) = '0' then          case ex.ctrl.cnt is	  when "00" =>            memory_load := op3(3) or not op3(2);	-- LD/LDST/SWAP	    read := memory_load; enaddr := '1';          when "01" =>            memory_load := not op3(2);	-- LDD	    enaddr := memory_load; 	    force_a2 := memory_load;            if op3(3 downto 2) = "01" then		-- ST/STD	      dcache_write := '1';            end if;            if op3(3 downto 2) = "11" then		-- LDST/SWAP	      enaddr := '1';            end if;          when "10" => 					-- STD/LDST/SWAP            dcache_write := '1';          when others => null;	  end case;	end if;      when others => null;      end case;    end if;-- supervisor bit generation    if ((wr.ctrl.rett and not wr.ctrl.annul) = '1') then su := sregs.ps;    else su := sregs.s; end if;    if su = '1' then asi := "00001011"; else asi := "00001010"; end if;    if (op3(4) = '1') and ((op3(5) = '0') or not CPEN) then      asi := ex.ctrl.inst(12 downto 5);    end if;-- load data bypass in case (LDDELAY = 1)    aluin1 := ex.rs1data; aluin2 := ex.rs2data; ymsb := ex.ymsb;    if LDDELAY = 1 then      if ex.ldbp1 = '1' then aluin1 := wr.result; ymsb := wr.result(0); end if;      if ex.ldbp2 = '1' then aluin2 := wr.result; end if;    end if;-- bypassed operands to multiplier    muli.signed <= op3(0); divi.signed <= op3(0);    mulop1 := (aluin1(31) and op3(0))  & aluin1;    mulop2 := (aluin2(31) and op3(0))  & aluin2;    if (ex.mulinsn = '0') and not INFER_MULT then  -- try to minimise power      mulop1 := (others => '0'); mulop2 := (others => '0');    end if;    muli.op1 <= mulop1; muli.op2 <= mulop2;    divi.op1 <= (aluin1(31) and op3(0)) & aluin1;    divi.op2 <= (aluin2(31) and op3(0)) & aluin2;-- ALU add/sub    icc := "0000";-- pragma translate_off    if not (is_x(aluin1) or is_x(aluin2)) then-- pragma translate_on      cin := ex.alu_cin; addin2 := aluin2;      if ex.aluadd = '0' then      addin2 := not aluin2; cin := not cin;      end if;--      addout := aluin1 + addin2 + cin;      if FASTADD then addout := sum32;      else        if ex.aluadd = '0' then addout := aluin1 - aluin2 - ex.alu_cin;        else addout := aluin1 + aluin2 + ex.alu_cin; end if;      end if;-- pragma translate_off    end if;-- pragma translate_on    add32in1 <= aluin1;    add32in2 <= addin2;    add32cin <= cin;-- fast address adders if enabled    if FASTJUMP then-- pragma translate_off      if not (is_x(aluin1) or is_x(aluin2)) then-- pragma translate_on        fecomb.jump_address <= aluin1(31 downto PCLOW) + aluin2(31 downto PCLOW);	if (aluin1(1 downto 0) + aluin2(1 downto 0)) = "00" then	  addr_misal := '0';	else	  addr_misal := '1';	end if;-- pragma translate_off      else        fecomb.jump_address <= (others => 'X');      end if;-- pragma translate_on    else      fecomb.jump_address(31 downto PCLOW) <= addout(31 downto PCLOW);      if addout(1 downto 0) = "00" then	addr_misal := '0';      else	addr_misal := '1';      end if;    end if;    res := (others => '-');-- alu ops which set icc    case ex.aluop is    when ALU_OR    => logicout := aluin1 or aluin2;    when ALU_ORN   => logicout := aluin1 or not aluin2;    when ALU_AND   => logicout := aluin1 and aluin2;    when ALU_ANDN  => logicout := aluin1 and not aluin2;    when ALU_XOR   => logicout := aluin1 xor aluin2;    when ALU_XNOR  => logicout := aluin1 xor not aluin2;    when ALU_DIV   =>       if DIVIDER /= none then logicout := aluin2;      else logicout := (others => '-'); end if;    when others    => logicout := (others => '-');    end case;-- generate condition codes    if (ex.alusel(1) = '0') then      res := addout;      if ex.aluadd = '0' then        icc(0) := ((not aluin1(31)) and aluin2(31)) or 	-- Carry		 (addout(31) and ((not aluin1(31)) or aluin2(31)));        icc(1) := (aluin1(31) and (not aluin2(31)) and not addout(31)) or 	-- Overflow                 (addout(31) and (not aluin1(31)) and aluin2(31));      else        icc(0) := (aluin1(31) and aluin2(31)) or 	-- Carry		 ((not addout(31)) and (aluin1(31) or aluin2(31)));        icc(1) := (aluin1(31) and aluin2(31) and not addout(31)) or 	-- Overflow		 (addout(31) and (not aluin1(31)) and (not aluin2(31)));      end if;    else      res := logicout;      icc(1 downto 0) := "00";    end if;    if res = zero32 then	-- Zero      icc(2) := '1';    else      icc(2) := '0';    end if;    icc(3) := res(31);		-- Negative-- select Y    if (me.write_y and not (me.ctrl.annul or me.ctrl.trap)) = '1'     then y := me.my; else y := wr.y; end if;-- alu ops which dont set icc    miscout := (others => '-'); edata := (others => '-');    case ex.aluop is    when ALU_STB   => edata := aluin1(7 downto 0) & aluin1(7 downto 0) &			     aluin1(7 downto 0) & aluin1(7 downto 0);		      miscout := edata;    when ALU_STH   => edata := aluin1(15 downto 0) & aluin1(15 downto 0);		      miscout := edata;    when ALU_PASS1 => miscout := aluin1; edata := aluin1;    when ALU_PASS2 => miscout := aluin2;    when ALU_ONES  => miscout := (others => '1'); edata := (others => '1');    when ALU_RDY  =>       miscout := y;       if (WATCHPOINTS > 0) and (rs1(4 downto 3) = "11") then	wpi := conv_integer(unsigned(rs1(2 downto 1)));	if rs1(0) = '0' then miscout := tr(wpi).addr & '0' & tr(wpi).exec;	else miscout := tr(wpi).mask & tr(wpi).load & tr(wpi).store; end if;      end if;    when ALU_FSR  =>       if ((FPIFTYPE = serial) and FPEN) then        edata := fpu_reg.fsr.rd & "00" & fpu_reg.fsr.tem & "000" & 	std_logic_vector(FPUVER) & fpu_reg.fsr.ftt & "00" & fpu_reg.fsr.fcc &	fpu_reg.fsr.aexc & fpu_reg.fsr.cexc;	miscout := edata;      end if;    when ALU_FOP   =>       if ((FPIFTYPE = serial) and FPEN) then	miscout := aluin2;	case opf(3 downto 2) is	when "01" => miscout(31) := not miscout(31);	when "10" => miscout(31) := '0';	when others => null;	end case;      end if;    when others => null;    end case;-- shifter    shiftin := zero32 & aluin1;    shiftcnt := aluin2(4 downto 0);    if ex.aluop = ALU_SLL then      shiftin(31 downto 0) := zero32;      shiftin(63 downto 31) := '0' & aluin1;      shiftcnt := not shiftcnt;    elsif ex.aluop = ALU_SRA then      if aluin1(31) = '1' then	shiftin(63 downto 32) := (others => '1');      else	shiftin(63 downto 32) := zero32;      end if;    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;    shiftout := shiftin(31 downto 0);-- generate overflow for tagged add/sub    case op is     when FMT3 =>      case op3 is      when TADDCC | TADDCCTV | TSUBCC | TSUBCCTV =>        icc(1) := aluin1(0) or aluin1(1) or aluin2(0) or aluin2(1) or icc(1);      when others => null;      end case;    when others => null;    end case;-- select alu output    aluresult := (others => '0');    if link_pc = '1' then      aluresult := ex.ctrl.pc(31 downto 2) & "00";  -- save PC during jmpl    else      case ex.alusel is      when ALU_RES_ADD => aluresult := addout;      when ALU_RES_SHIFT => aluresult := shiftout;      when ALU_RES_LOGIC => aluresult := logicout;      when others => aluresult := miscout;      end case;    end if;    ex.icc <= icc;-- FPU interface    if ((FPIFTYPE = serial) and FPEN) then-- pragma translate_off      if is_x(aluin1) then aluin1 := (others => '0'); end if;      if is_x(aluin2) then aluin2 := (others => '0'); end if;      if is_x(de.inst(19) & de.inst(13 downto 5)) then        fpui.FpInst <= (others => '0');      else-- pragma translate_on        fpui.FpInst <= de.inst(19) & de.inst(13 downto 5);-- pragma translate_off      end if;      if is_x(fpu_reg.fsr.rd) then fpui.RoundingMode <= (others => '0');      else -- pragma translate_on        fpui.RoundingMode <= fpu_reg.fsr.rd;-- pragma translate_off      end if;-- pragma translate_on      if (ex.ctrl.cnt = "00") or (opf(1) = '0') then        fpui.fprf_dout1 <= aluin1 & aluin1;        fpui.fprf_dout2 <= aluin2 & aluin2;      else        fpui.fprf_dout1 <= fpu_reg.op1h & aluin1;        fpui.fprf_dout2 <= me.result & aluin2;      end if;      fpu_regin.op1h <= aluin1;      if fpu_reg.ex.fpop = "01" and (ex.write_reg = '1') then        if fpu_reg.ex.dsz = '1' then	  if (ex.ctrl.cnt /= "00") then            aluresult := fpuo.FracResult(34 downto 3);	  end if;        else          aluresult := fpuo.SignResult & fpuo.ExpResult(7 downto 0) &                   fpuo.FracResult(54 downto 32);        end if;      end if;      fpu_regin.me <= fpmein;    end if;    if (MULTIPLIER = m32x32) and (ex.mulinsn = '1') then      aluresult := mulo.result(31 downto 0);    end if;    if MACEN then      if ex.aluop = ALU_RDY then	if rs1 = "10010" then	  if ((me.mulinsn and me.ctrl.inst(24)) = '1') then	    aluresult := mulo.result(31 downto 0);	  else aluresult := wr.asr18; end if;	else	  if ((me.mulinsn and me.ctrl.inst(24)) = '1') then	    aluresult := mulo.result(63 downto 32);          end if;        end if;      end if;     end if;          ex.result <= aluresult;-- generate Y    micc := icc;    licc := icc;    nexty := y;    if ex.mulstep = '1' then      nexty := ymsb & y(31 downto 1);    elsif (ex.mulinsn = '1') and (MULTIPLIER = iterative) then        case ex.ctrl.cnt is        when "00" => nexty := y;        when "01" => nexty := ymsb & me.y(31 downto 1);        when "10" =>	  aluresult := ymsb & me.y(31 downto 1); 	  licc(3) := ymsb; licc(1 downto 0) := "00";	  if aluresult = zero32 then 	    licc(2) := '1'; else licc(2) := '0';	  end if;	  nexty := me.y;        when others => null;        end case;    elsif ((ex.rst_mey or ex.write_y) = '1') and (MULTIPLIER = iterative) then      if ex.ctrl.cnt = "11" then nexty := addout;      else nexty := logicout; end if;    elsif ex.write_y = '1' then      nexty := logicout;     end if;    if (MULTIPLIER = iterative) then      micc(3) := icc(3) and not ex.rst_mey;      micc(1) := icc(1) and not ex.rst_mey;    end if;-- data address generation    eaddress := miscout;    if ex.alusel = ALU_RES_ADD then       addout(2) := addout(2) or force_a2; eaddress := addout;    end if;    if CPEN and (op = LDST) and ((op3(5 downto 4) & op3(2)) = "111") and      (ex.ctrl.cnt /= "00")    then      dci.edata <= cpo.data;	-- store co-processor      aluresult := cpo.data;    elsif (FPIFTYPE = parallel) and (op = LDST) and 	((op3(5 downto 4) & op3(2)) = "101") and (ex.ctrl.cnt /= "00")    then      dci.edata <= fpo.data;	-- store fpu co-processor    

⌨️ 快捷键说明

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