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

📄 iu.vhd

📁 宇航级微处理器LEON2 2.2 VHDL源代码,很难找的.
💻 VHD
📖 第 1 页 / 共 5 页
字号:
    winovf_exception := '0'; winunf_exception := '0';    write_cwp := '0'; cwp_new := de.cwp; rs1mod := '0';-- 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';    case op is    when CALL => null;    when FMT2 =>      case op2 is      when SETHI | BICC => null;      when FBFCC => 	if FPEN then fp_disabled := not sregs.ef;	else fp_disabled := '1'; end if;      when CBCCC =>	if (not CPEN) or (sregs.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 | 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 not (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 => 	if FPEN then fp_disabled := not sregs.ef; fpop := '1';	else fp_disabled := '1'; fpop := '0'; end if;      when CPOP1 | CPOP2 =>	if (not CPEN) or (sregs.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 := 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 | LDF | LDFSR | STF | STFSR => 	if FPEN then fp_disabled := not sregs.ef;	else fp_disabled := '1'; end if;      when STDFQ => 	privileged_inst := not su; 	if (not FPEN) or (sregs.ef = '0') then fp_disabled := '1'; end if;	if (FPTYPE = meiko) then fp_exception := '1'; end if;      when STDCQ => 	privileged_inst := not su;	if (not CPEN) or (sregs.ec = '0') then cp_disabled := '1'; end if;      when LDC | LDCSR | LDDC | STC | STCSR | STDC => 	if (not CPEN) or (sregs.ec = '0') then cp_disabled := '1'; end if;      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;-- ICC pipeline and forwarding    if (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;    br_icc := icc;    if ((ex.write_icc and not ex.ctrl.annul) = '1') then      icc := ex.icc;      if not ICC_HOLD then br_icc := icc; end if;    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 := br_icc(3); z := br_icc(2); v := br_icc(1); c := br_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;-- FBFCC evaluation    if FPEN then      if FPTYPE = meiko then        if (fpu_reg.me.fpop = "10") and (me.ctrl.annul = '0') then 	  fcc := fpu_reg.me.fcc;        elsif (fpu_reg.wr.fpop = "10") and (wr.ctrl.annul = '0') then 	  fcc := fpu_reg.wr.fcc;        else fcc := fpu_reg.fsr.fcc; end if;      else fcc := fpo.cc; end if;      case cond(2 downto 0) is      when "000" => fbres := '0';			-- fba, fbn      when "001" => fbres := fcc(1) or fcc(0);      when "010" => fbres := fcc(1) xor fcc(0);      when "011" => fbres := fcc(0);      when "100" => fbres := (not fcc(1)) and fcc(0);      when "101" => fbres := fcc(1);      when "110" => fbres := fcc(1) and not fcc(0);      when others => fbres := fcc(1) and fcc(0);      end case;      fbranch_true := cond(3) xor fbres;-- decode some FPU instruction types      case opf is      when FMOVS | FABSS | FNEGS => fpmov := '1';      when FITOD | FSTOD | FSQRTD | FADDD | FSUBD | FMULD | FDIVD => 	fpexin.dsz := '1';      when others => null;      end case;    end if;-- CBCCC evaluation    if CPEN then      ccc := cpo.cc;      case cond(2 downto 0) is      when "000" => cbres := '0';      when "001" => cbres := ccc(1) or ccc(0);      when "010" => cbres := ccc(1) xor ccc(0);      when "011" => cbres := ccc(0);      when "100" => cbres := (not ccc(1)) and ccc(0);      when "101" => cbres := ccc(1);      when "110" => cbres := ccc(1) and not ccc(0);      when others => cbres := ccc(1) and ccc(0);      end case;      cbranch_true := cond(3) xor cbres;    end if;-- 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 =>      end case;    when FMT3 =>      case op3 is      when IADD | ADDX | ADDCC | ADDXCC | TADDCC | TADDCCTV | SAVE | RESTORE |	   TICC | JMPL | RETT  => alusel := ALU_RES_ADD;      when ISUB | SUBX | SUBCC | SUBXCC | TSUBCC | TSUBCCTV  => 	alusel := ALU_RES_ADD; aluadd := '0';      when MULSCC => alusel := ALU_RES_ADD; mulstep := '1';      when UMUL | UMULCC => 	if MULTIPLIER = iterative then          case de.cnt is	  when "00" => aluop := ALU_XOR; alusel := ALU_RES_MISC;	  when "01" | "10" => alusel := ALU_RES_ADD; mulinsn := '1';	  when others => alusel := ALU_RES_ADD;	  end case;	end if;      when SMUL | SMULCC => 	if MULTIPLIER = iterative then          case de.cnt is	  when "00" => aluop := ALU_XOR; alusel := ALU_RES_MISC;	  when "01" | "10" => alusel := ALU_RES_ADD; mulinsn := '1';	  when others => alusel := ALU_RES_ADD; aluadd := '0';	  end case;	end if;      when IAND | ANDCC => aluop := ALU_AND; alusel := ALU_RES_LOGIC;      when ANDN | ANDNCC => aluop := ALU_ANDN; alusel := ALU_RES_LOGIC;      when IOR | ORCC  => aluop := ALU_OR; alusel := ALU_RES_LOGIC;      when ORN | ORNCC  => aluop := ALU_ORN; alusel := ALU_RES_LOGIC;      when IXNOR | XNORCC  => aluop := ALU_XNOR; alusel := ALU_RES_LOGIC;      when XORCC | IXOR | WRPSR | WRWIM | WRTBR | WRY  => 	aluop := ALU_XOR; alusel := ALU_RES_LOGIC;      when RDPSR | RDTBR | RDWIM => aluop := ALU_PASS2;      when RDY => aluop := ALU_RDY;      when ISLL => aluop := ALU_SLL; alusel := ALU_RES_SHIFT;      when ISRL => aluop := ALU_SRL; alusel := ALU_RES_SHIFT;      when ISRA => aluop := ALU_SRA; alusel := ALU_RES_SHIFT;      when FPOP1 | FPOP2 =>	if ((FPTYPE = meiko) and FPEN) then          if de.cnt /= "00" then 	    if opf(1) = '1' then rs1(0) := '1'; rs2(0) := '1'; end if;	    if fpexin.dsz = '1' then rd(0) := '1'; end if;	  end if;	  if op3 = FPOP1 then fpexin.fpop := "01"; else fpexin.fpop := "10"; end if;	  if fpmov = '1' then aluop := ALU_FOP; fpexin.fpop := "11";	  else aluop := ALU_PASS2; end if;	end if;      when others =>      end case;    when others =>	-- LDST      case de.cnt is      when "00" =>        alusel := ALU_RES_ADD;	if FPEN then fpld := (op3(5) and not op3(2));	else fpld := '0'; end if;      when "01" =>	if (op3(2) and not op3(3)) = '1' then  -- ST	  rs1 := rd; rs1mod := '1';	end if;	case op3 is	when LDD | LDDA =>          rd(0) := '1'; alusel := ALU_RES_ADD;	when LDDF =>           rd(0) := '1'; alusel := ALU_RES_ADD;	  if FPEN then fpld := '1'; end if;	when STFSR => if ((FPTYPE = meiko) and FPEN) then aluop := ALU_FSR; end if;	when SWAP | SWAPA | LDSTUB | LDSTUBA =>          alusel := ALU_RES_ADD;	when STF | STDF =>	  if ((FPTYPE = meiko) and FPEN) then            aluop := ALU_PASS1; fpst := '1'; 	  end if;	when others =>          aluop := ALU_PASS1;	  if op3(2) = '1' then  -- ST	    if op3(1 downto 0) = "01" then	-- store byte	      aluop := ALU_STB;	    elsif op3(1 downto 0) = "10" then	-- store halfword	      aluop := ALU_STH;	    end if;          end if;        end case;      when "10" =>        aluop := ALU_PASS1;	rs1 := rd;  rs1mod := '1';        if op3(2) = '1' then  -- ST          if (op3(3) and not op3(1))= '1' then aluop := ALU_ONES;  -- LDSTUB/A          elsif op3(1 downto 0) = "11" then	    rs1(0) := '1';  -- STD/F/A	    if ((FPTYPE = meiko) and FPEN) and (op3(5) = '1') then fpst := '1'; end if;          end if;        end if;      when others =>      end case;    end case;    exin.aluop <= aluop; exin.alusel <= alusel; exin.aluadd <= aluadd;    exin.mulstep <= mulstep; exin.mulinsn <= mulinsn;-- Alu operand select    operand2_select := ALU_SIMM;    case op is    when FMT2 =>      case op2 is      when SETHI => operand2_select := ALU_SIMM;      when others => operand2_select := ALU_RS2;      end case;    when FMT3 =>      case op3 is      when RDWIM | RDPSR | RDTBR => operand2_select := ALU_SIMM;      when FPOP1 | FPOP2 => if ((FPTYPE = meiko) and FPEN) then operand2_select := ALU_RS2; end if;      when others =>        if (de.inst(13) = '1') then operand2_select := ALU_SIMM;	else operand2_select := ALU_RS2; end if;      end case;    when LDST =>       if (de.inst(13) = '1') then operand2_select := ALU_SIMM;      else operand2_select := ALU_RS2; end if;    when others => operand2_select := ALU_RS2;    end case;-- CWP generation, pipelinig and forwarding-- Also check for window underflow/overflow conditions    if (op = FMT3) and ((op3 = RETT) or (op3 = RESTORE) or (op3 = SAVE)) then      write_cwp := '1';      if (op3 = SAVE) then-- pragma translate_off        if not is_x(de.cwp) then-- pragma translate_on	  if (not CWPOPT) and (de.cwp = CWPMIN) then cwp_new := CWPMAX;          else cwp_new := de.cwp - 1 ; end if;-- pragma translate_off	end if;-- pragma translate_on      else-- pragma translate_off        if not is_x(de.cwp) then-- pragma translate_on	  if (not CWPOPT) and (de.cwp = CWPMAX) then cwp_new := CWPMIN;          else cwp_new := de.cwp + 1; end if;-- pragma translate_off        end if;-- pragma translate_on      end if;      if sregs.wim(conv_integer('0' & cwp_new)) = '1' then	if op3 = SAVE then winovf_exception := '1';	else winunf_exception := '1'; end if;      end if;    end if;      exin.write_cwp <= write_cwp;    exin.cwp <= cwp_new;-- Immediate data generation    case op is    when FMT2 =>      immediate_data := de.inst(21 downto 0) & "0000000000";    when FMT3 =>      case op3 is      when RDPSR => immediate_data := std_logic_vector(IMPL) &        std_logic_vector(VER) & icc & "000000" & sregs.ec & sregs.ef & 	sregs.pil & su & sregs.ps & et & CWPFILL & de.cwp;      when RDTBR => immediate_data := sregs.tba & sregs.tt & "0000";      when RDWIM => immediate_data := WIMFILL & sregs.wim;      when others =>

⌨️ 快捷键说明

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