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

📄 iu3.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 5 页
字号:
variable op3 : std_logic_vector(5 downto 0);variable wim : word;variable ncwp : cwptype;begin  op := inst(31 downto 30); op3 := inst(24 downto 19);   wovf_exc := '0'; wunf_exc := '0'; wim := (others => '0');   wim(NWIN-1 downto 0) := xc_wim; ncwp := r.d.cwp; wcwp := '0';  if (op = FMT3) and ((op3 = RETT) or (op3 = RESTORE) or (op3 = SAVE)) then    wcwp := '1';    if (op3 = SAVE) then      if (not CWPOPT) and (r.d.cwp = CWPMIN) then ncwp := CWPMAX;      else ncwp := r.d.cwp - 1 ; end if;    else      if (not CWPOPT) and (r.d.cwp = CWPMAX) then ncwp := CWPMIN;      else ncwp := r.d.cwp + 1; end if;    end if;    if wim(conv_integer(ncwp)) = '1' then      if op3 = SAVE then wovf_exc := '1'; else wunf_exc := '1'; end if;    end if;  end if;  de_cwp := ncwp;end;-- generate register read address 1procedure rs1_gen(r : registers; inst : word;  rs1 : out std_logic_vector(4 downto 0);	rs1mod : out std_ulogic) isvariable op : std_logic_vector(1 downto 0);variable op3 : std_logic_vector(5 downto 0);begin  op := inst(31 downto 30); op3 := inst(24 downto 19);   rs1 := inst(18 downto 14); rs1mod := '0';  if (op = LDST) then    if ((r.d.cnt = "01") and ((op3(2) and not op3(3)) = '1')) or        (r.d.cnt = "10")     then rs1mod := '1'; rs1 := inst(29 downto 25); end if;    if ((r.d.cnt = "10") and (op3(3 downto 0) = "0111")) then      rs1(0) := '1';    end if;  end if;end;-- load/icc interlock detection  procedure lock_gen(r : registers; rs2, rd : std_logic_vector(4 downto 0);	rfa1, rfa2, rfrd : rfatype; inst : word; fpc_lock, mulinsn, divinsn : std_ulogic;        lldcheck1, lldcheck2, lldlock, lldchkra, lldchkex : out std_ulogic) is  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 cond : std_logic_vector(3 downto 0);  variable rs1  : std_logic_vector(4 downto 0);  variable i, ldcheck1, ldcheck2, ldchkra, ldchkex, ldcheck3 : std_ulogic;  variable ldlock, icc_check, bicc_hold, chkmul, y_check : std_ulogic;  variable lddlock : boolean;  begin    op := inst(31 downto 30); op3 := inst(24 downto 19);     op2 := inst(24 downto 22); cond := inst(28 downto 25);     rs1 := inst(18 downto 14); lddlock := false; i := inst(13);    ldcheck1 := '0'; ldcheck2 := '0'; ldcheck3 := '0'; ldlock := '0';    ldchkra := '1'; ldchkex := '1'; icc_check := '0'; bicc_hold := '0';    y_check := '0';    if (r.d.annul = '0') then      case op is      when FMT2 =>	if (op2 = BICC) and (cond(2 downto 0) /= "000") then 	  icc_check := '1';	end if;      when FMT3 =>        ldcheck1 := '1'; ldcheck2 := not i;        case op3 is	when TICC =>	  if (cond(2 downto 0) /= "000") then icc_check := '1'; end if;        when RDY =>           ldcheck1 := '0'; ldcheck2 := '0';	  if MACPIPE then y_check := '1'; end if;        when RDWIM | RDTBR =>           ldcheck1 := '0'; ldcheck2 := '0';        when RDPSR =>           ldcheck1 := '0'; ldcheck2 := '0'; icc_check := '1';	  if MULEN then icc_check := '1'; end if;--	when ADDX | ADDXCC | SUBX | SUBXCC =>--	  if MULEN then icc_check := '1'; end if;	when SDIV | SDIVCC | UDIV | UDIVCC =>	  if DIVEN then y_check := '1'; end if;        when FPOP1 | FPOP2 => ldcheck1:= '0'; ldcheck2 := '0';        when others =>         end case;      when LDST =>        ldcheck1 := '1'; ldchkra := '0';	case r.d.cnt is	when "00" =>          if (lddel = 2) and (op3(2) = '1') then ldcheck3 := '1'; end if;           ldcheck2 := not i; ldchkra := '1';	when "01" => ldcheck2 := not i;	when others => ldchkex := '0';        end case;        if  (op3(2 downto 0) = "011") then lddlock := true; end if;      when others => null;      end case;    end if;    if MULEN or DIVEN then       chkmul := mulinsn;      bicc_hold := bicc_hold or (icc_check and r.m.ctrl.wicc and (r.m.ctrl.cnt(0) or r.m.mul));    else chkmul := '0'; end if;    if DIVEN then       bicc_hold := bicc_hold or (y_check and (r.a.ctrl.wy or r.e.ctrl.wy));      chkmul := chkmul or divinsn;    end if;    bicc_hold := bicc_hold or (icc_check and (r.a.ctrl.wicc or r.e.ctrl.wicc));    if (((r.a.ctrl.ld or chkmul) and r.a.ctrl.wreg and ldchkra) = '1') and       (((ldcheck1 = '1') and (r.a.ctrl.rd = rfa1)) or        ((ldcheck2 = '1') and (r.a.ctrl.rd = rfa2)) or        ((ldcheck3 = '1') and (r.a.ctrl.rd = rfrd)))    then ldlock := '1'; end if;    if (((r.e.ctrl.ld or r.e.mac) and r.e.ctrl.wreg and ldchkex) = '1') and         ((lddel = 2) or (MACPIPE and (r.e.mac = '1')) or ((MULTYPE = 3) and (r.e.mul = '1'))) and       (((ldcheck1 = '1') and (r.e.ctrl.rd = rfa1)) or        ((ldcheck2 = '1') and (r.e.ctrl.rd = rfa2)))    then ldlock := '1'; end if;    ldlock := ldlock or bicc_hold or fpc_lock;    lldcheck1 := ldcheck1; lldcheck2:= ldcheck2; lldlock := ldlock;    lldchkra := ldchkra; lldchkex := ldchkex;  end;  procedure fpbranch(inst : in word; fcc  : in std_logic_vector(1 downto 0);                      branch : out std_ulogic) is  variable cond : std_logic_vector(3 downto 0);  variable fbres : std_ulogic;  begin    cond := inst(28 downto 25);    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;    branch := cond(3) xor fbres;       end;-- PC generation  procedure ic_ctrl(r : registers; inst : word; annul_all, ldlock, branch_true, 	fbranch_true, cbranch_true, fccv, cccv : in std_ulogic; 	cnt : out std_logic_vector(1 downto 0); 	de_pc : out pctype; de_branch, ctrl_annul, de_annul, jmpl_inst, inull, 	de_pv, ctrl_pv, de_hold_pc, ticc_exception, rett_inst, mulstart,	divstart : out std_ulogic) is  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 cond : std_logic_vector(3 downto 0);  variable hold_pc, annul_current, annul_next, branch, annul, pv : std_ulogic;  variable de_jmpl : std_ulogic;  begin    branch := '0'; annul_next := '0'; annul_current := '0'; pv := '1';    hold_pc := '0'; ticc_exception := '0'; rett_inst := '0';    op := inst(31 downto 30); op3 := inst(24 downto 19);     op2 := inst(24 downto 22); cond := inst(28 downto 25);     annul := inst(29); de_jmpl := '0'; cnt := "00";    mulstart := '0'; divstart := '0';     if r.d.annul = '0' then      case inst(31 downto 30) is      when CALL =>        branch := '1';	if r.d.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 fccv /= '1' then hold_pc := '1'; annul_current := '1'; end if;          elsif (CPEN and (op2 = CBCCC)) then 	    branch := cbranch_true;	    if cccv /= '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 r.d.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 UMUL | SMUL | UMULCC | SMULCC =>	  if MULEN and (MULTYPE /= 0) then mulstart := '1'; end if;	  if MULEN and (MULTYPE = 0) then            case r.d.cnt is            when "00" => 	      cnt := "01"; hold_pc := '1'; pv := '0'; mulstart := '1';            when "01" => 	      if mulo.nready = '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 DIVEN then            case r.d.cnt is            when "00" => 	      cnt := "01"; hold_pc := '1'; pv := '0';	      divstart := '1';            when "01" => 	      if divo.nready = '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 =>          rett_inst := '1'; --su := sregs.ps;         when JMPL =>          de_jmpl := '1';        when WRY =>          if PWRD1 then             if inst(29 downto 25) = "10011" then -- %ASR19              case r.d.cnt is              when "00" =>                pv := '0'; cnt := "00"; hold_pc := '1';                if r.x.ipend = '1' then cnt := "01"; end if;                            when "01" =>                cnt := "00";              when others =>              end case;            end if;          end if;        when others => null;        end case;      when others =>  -- LDST         case r.d.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;      end case;    end if;    if ldlock = '1' then      cnt := r.d.cnt; annul_next := '0'; pv := '1';    end if;    hold_pc := (hold_pc or ldlock) and not annul_all;    if hold_pc = '1' then de_pc := r.d.pc; else de_pc := r.f.pc; end if;    annul_current := (annul_current or ldlock or annul_all);    ctrl_annul := r.d.annul or annul_all or annul_current;    pv := pv and not ((r.d.inull and not hold_pc) or annul_all);    jmpl_inst := de_jmpl and not annul_current;    annul_next := (r.d.inull and not hold_pc) or annul_next or annul_all;    if (annul_next = '1') or (rstn = '0') then      cnt := (others => '0');     end if;    de_hold_pc := hold_pc; de_branch := branch; de_annul := annul_next;    de_pv := pv; ctrl_pv := r.d.pv and 	not ((r.d.annul and not r.d.pv) or annul_all or annul_current);    inull := (not rstn) or r.d.inull or hold_pc or annul_all;  end;-- register write address generation  procedure rd_gen(r : registers; inst : word; wreg, ld : out std_ulogic; 	rdo : out std_logic_vector(4 downto 0)) is  variable write_reg : 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);  begin    op    := inst(31 downto 30);    op2   := inst(24 downto 22);    op3   := inst(24 downto 19);    write_reg := '0'; rd := inst(29 downto 25); ld := '0';    case op is    when CALL =>        write_reg := '1'; rd := "01111";    -- CALL saves PC in r[15] (%o7)    when FMT2 =>         if (op2 = SETHI) then write_reg := '1'; end if;    when FMT3 =>        case op3 is	when UMUL | SMUL | UMULCC | SMULCC => 	  if MULEN then	    if (((mulo.nready = '1') and (r.d.cnt /= "00")) or (MULTYPE /= 0)) then	      write_reg := '1'; 	    end if;	  else write_reg := '1'; end if;	when UDIV | SDIV | UDIVCC | SDIVCC => 	  if DIVEN then	    if (divo.nready = '1') and (r.d.cnt /= "00") then	      write_reg := '1'; 	    end if;	  else write_reg := '1'; end if;        when RETT | WRPSR | WRY | WRWIM | WRTBR | TICC | FLUSH => null;	when FPOP1 | FPOP2 => null;	when CPOP1 | CPOP2 => null;        when others => write_reg := '1';        end case;      when others =>   -- LDST        ld := not op3(2);        if (op3(2) = '0') and not ((CPEN or FPEN) and (op3(5) = '1'))         then write_reg := '1'; end if;        case op3 is        when SWAP | SWAPA | LDSTUB | LDSTUBA =>	  if r.d.cnt = "00" then write_reg := '1'; ld := '1'; end if;        when others => null;        end case;        if r.d.cnt = "01" then	  case op3 is	  when LDD | LDDA | LDDC | LDDF => rd(0) := '1';          when others =>          end case;      	end if;    end case;    if (rd = "00000") then write_reg := '0'; end if;    wreg := write_reg; rdo := rd;  end;-- immediate data generation

⌨️ 快捷键说明

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