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

📄 iu3.vhd

📁 leon3 source code 虽然gaisler网站上有下载
💻 VHD
📖 第 1 页 / 共 5 页
字号:
  function imm_data (r : registers; insn : word) 	return word is  variable immediate_data, inst : word;  begin    immediate_data := (others => '0'); inst := insn;    case inst(31 downto 30) is    when FMT2 =>      immediate_data := inst(21 downto 0) & "0000000000";    when others =>	-- LDST      immediate_data(31 downto 13) := (others => inst(12));      immediate_data(12 downto 0) := inst(12 downto 0);    end case;    return(immediate_data);  end;-- read special registers  function get_spr (r : registers) return word is  variable spr : word;  begin    spr := (others => '0');      case r.e.ctrl.inst(24 downto 19) is      when RDPSR => spr(31 downto 5) := conv_std_logic_vector(IMPL,4) &        conv_std_logic_vector(VER,4) & r.m.icc & "000000" & r.w.s.ec & r.w.s.ef & 	r.w.s.pil & r.e.su & r.w.s.ps & r.e.et;	spr(NWINLOG2-1 downto 0) := r.e.cwp;      when RDTBR => spr(31 downto 4) := r.w.s.tba & r.w.s.tt;      when RDWIM => spr(NWIN-1 downto 0) := r.w.s.wim;      when others =>      end case;    return(spr);  end;-- immediate data select  function imm_select(inst : word) return boolean is  variable imm : boolean;  begin    imm := false;    case inst(31 downto 30) is    when FMT2 =>      case inst(24 downto 22) is      when SETHI => imm := true;      when others =>       end case;    when FMT3 =>      case inst(24 downto 19) is      when RDWIM | RDPSR | RDTBR => imm := true;      when others => if (inst(13) = '1') then imm := true; end if;      end case;    when LDST =>       if (inst(13) = '1') then imm := true; end if;    when others =>     end case;    return(imm);  end;-- EXE operation  procedure alu_op(r : in registers; iop1, iop2 : in word; me_icc : std_logic_vector(3 downto 0);	my, ldbp : std_ulogic; aop1, aop2 : out word; aluop  : out std_logic_vector(2 downto 0);	alusel : out std_logic_vector(1 downto 0); aluadd : out std_ulogic;	shcnt : out std_logic_vector(4 downto 0); sari, shleft, ymsb, 	mulins, divins, mulstep, macins, ldbp2, invop2 : 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 rd  : std_logic_vector(4 downto 0);  variable icc : std_logic_vector(3 downto 0);  variable y0  : std_ulogic;  begin    op   := r.a.ctrl.inst(31 downto 30);    op2  := r.a.ctrl.inst(24 downto 22);    op3  := r.a.ctrl.inst(24 downto 19);    aop1 := iop1; aop2 := iop2; ldbp2 := ldbp;    aluop := EXE_NOP; alusel := EXE_RES_MISC; aluadd := '1';     shcnt := iop2(4 downto 0); sari := '0'; shleft := '0'; invop2 := '0';    ymsb := iop1(0); mulins := '0'; divins := '0'; mulstep := '0';    macins := '0';    if r.e.ctrl.wy = '1' then y0 := my;    elsif r.m.ctrl.wy = '1' then y0 := r.m.y(0);    elsif r.x.ctrl.wy = '1' then y0 := r.x.y(0);    else y0 := r.w.s.y(0); end if;    if r.e.ctrl.wicc = '1' then icc := me_icc;    elsif r.m.ctrl.wicc = '1' then icc := r.m.icc;    elsif r.x.ctrl.wicc = '1' then icc := r.x.icc;    else icc := r.w.s.icc; end if;    case op is    when CALL =>      aluop := EXE_LINK;    when FMT2 =>      case op2 is      when SETHI => aluop := EXE_PASS2;      when others =>      end case;    when FMT3 =>      case op3 is      when IADD | ADDX | ADDCC | ADDXCC | TADDCC | TADDCCTV | SAVE | RESTORE |	   TICC | JMPL | RETT  => alusel := EXE_RES_ADD;      when ISUB | SUBX | SUBCC | SUBXCC | TSUBCC | TSUBCCTV  => 	alusel := EXE_RES_ADD; aluadd := '0'; aop2 := not iop2; invop2 := '1';      when MULSCC => alusel := EXE_RES_ADD;	aop1 := (icc(3) xor icc(1)) & iop1(31 downto 1);	if y0 = '0' then aop2 := (others => '0'); ldbp2 := '0'; end if;	mulstep := '1';      when UMUL | UMULCC | SMUL | SMULCC => 	if MULEN then mulins := '1'; end if;      when UMAC | SMAC => 	if MACEN then mulins := '1'; macins := '1'; end if;      when UDIV | UDIVCC | SDIV | SDIVCC => 	if DIVEN then 	  aluop := EXE_DIV; alusel := EXE_RES_LOGIC; divins := '1';        end if;      when IAND | ANDCC => aluop := EXE_AND; alusel := EXE_RES_LOGIC;      when ANDN | ANDNCC => aluop := EXE_ANDN; alusel := EXE_RES_LOGIC;      when IOR | ORCC  => aluop := EXE_OR; alusel := EXE_RES_LOGIC;      when ORN | ORNCC  => aluop := EXE_ORN; alusel := EXE_RES_LOGIC;      when IXNOR | XNORCC  => aluop := EXE_XNOR; alusel := EXE_RES_LOGIC;      when XORCC | IXOR | WRPSR | WRWIM | WRTBR | WRY  => 	aluop := EXE_XOR; alusel := EXE_RES_LOGIC;      when RDPSR | RDTBR | RDWIM => aluop := EXE_SPR;      when RDY => aluop := EXE_RDY;      when ISLL => aluop := EXE_SLL; alusel := EXE_RES_SHIFT; shleft := '1'; 		   shcnt := not iop2(4 downto 0); invop2 := '1';      when ISRL => aluop := EXE_SRL; alusel := EXE_RES_SHIFT;       when ISRA => aluop := EXE_SRA; alusel := EXE_RES_SHIFT; sari := iop1(31);      when FPOP1 | FPOP2 =>      when others =>      end case;    when others =>	-- LDST      case r.a.ctrl.cnt is      when "00" =>        alusel := EXE_RES_ADD;      when "01" =>	case op3 is	when LDD | LDDA | LDDC => alusel := EXE_RES_ADD;	when LDDF => alusel := EXE_RES_ADD;	when SWAP | SWAPA | LDSTUB | LDSTUBA => alusel := EXE_RES_ADD;	when STF | STDF =>	when others =>          aluop := EXE_PASS1;	  if op3(2) = '1' then 	    if op3(1 downto 0) = "01" then aluop := EXE_STB;	    elsif op3(1 downto 0) = "10" then aluop := EXE_STH; end if;          end if;        end case;      when "10" =>        aluop := EXE_PASS1;        if op3(2) = '1' then  -- ST          if (op3(3) and not op3(1))= '1' then aluop := EXE_ONES; end if; -- LDSTUB/A        end if;      when others =>      end case;    end case;  end;  function ra_inull_gen(r, v : registers) return std_ulogic is  variable de_inull : std_ulogic;  begin    de_inull := '0';    if ((v.e.jmpl or v.e.ctrl.rett) and not v.e.ctrl.annul and not (r.e.jmpl and not r.e.ctrl.annul)) = '1' then de_inull := '1'; end if;    if ((v.a.jmpl or v.a.ctrl.rett) and not v.a.ctrl.annul and not (r.a.jmpl and not r.a.ctrl.annul)) = '1' then de_inull := '1'; end if;    return(de_inull);  end;-- operand generation  procedure op_mux(r : in registers; rfd, ed, md, xd, im : in word; 	rsel : in std_logic_vector(2 downto 0); 	ldbp : out std_ulogic; d : out word) is  begin    ldbp := '0';    case rsel is    when "000" => d := rfd;    when "001" => d := ed;    when "010" => d := md; if lddel = 1 then ldbp := r.m.ctrl.ld; end if;    when "011" => d := xd;    when "100" => d := im;    when "101" => d := (others => '0');    when "110" => d := r.w.result;    when others => d := (others => '-');    end case;  end;  procedure op_find(r : in registers; ldchkra : std_ulogic; ldchkex : std_ulogic;	 rs1 : std_logic_vector(4 downto 0); ra : rfatype; im : boolean; rfe : out std_ulogic; 	osel : out std_logic_vector(2 downto 0); ldcheck : std_ulogic) is  begin    rfe := '0';    if im then osel := "100";    elsif rs1 = "00000" then osel := "101";	-- %g0    elsif ((r.a.ctrl.wreg and ldchkra) = '1') and (ra = r.a.ctrl.rd) then osel := "001";    elsif ((r.e.ctrl.wreg and ldchkex) = '1') and (ra = r.e.ctrl.rd) then osel := "010";    elsif r.m.ctrl.wreg = '1' and (ra = r.m.ctrl.rd) then osel := "011";    elsif (irfwt = 0) and r.x.ctrl.wreg = '1' and (ra = r.x.ctrl.rd) then osel := "110";    else  osel := "000"; rfe := ldcheck; end if;  end;-- generate carry-in for alu  procedure cin_gen(r : registers; me_cin : in std_ulogic; cin : out std_ulogic) is  variable op : std_logic_vector(1 downto 0);  variable op3 : std_logic_vector(5 downto 0);  variable ncin : std_ulogic;  begin    op := r.a.ctrl.inst(31 downto 30); op3 := r.a.ctrl.inst(24 downto 19);    if r.e.ctrl.wicc = '1' then ncin := me_cin;    else ncin := r.m.icc(0); end if;    cin := '0';    case op is    when FMT3 =>      case op3 is      when ISUB | SUBCC | TSUBCC | TSUBCCTV => cin := '1';      when ADDX | ADDXCC => cin := ncin;       when SUBX | SUBXCC => cin := not ncin;       when others => null;      end case;    when others => null;    end case;  end;  procedure logic_op(r : registers; aluin1, aluin2, mey : word; 	ymsb : std_ulogic; logicres, y : out word) is  variable logicout : word;  begin    case r.e.aluop is    when EXE_AND   => logicout := aluin1 and aluin2;    when EXE_ANDN  => logicout := aluin1 and not aluin2;    when EXE_OR    => logicout := aluin1 or aluin2;    when EXE_ORN   => logicout := aluin1 or not aluin2;    when EXE_XOR   => logicout := aluin1 xor aluin2;    when EXE_XNOR  => logicout := aluin1 xor not aluin2;    when EXE_DIV   =>       if DIVEN then logicout := aluin2;      else logicout := (others => '-'); end if;    when others => logicout := (others => '-');    end case;    if (r.e.ctrl.wy and r.e.mulstep) = '1' then       y := ymsb & r.m.y(31 downto 1);     elsif r.e.ctrl.wy = '1' then y := logicout;    elsif r.m.ctrl.wy = '1' then y := mey;     elsif MACPIPE and (r.x.mac = '1') then y := mulo.result(63 downto 32);    elsif r.x.ctrl.wy = '1' then y := r.x.y;     else y := r.w.s.y; end if;    logicres := logicout;  end;  procedure misc_op(r : registers; wpr : watchpoint_registers; 	aluin1, aluin2, ldata, mey : word; 	mout, edata : out word) is  variable miscout, bpdata, stdata : word;  variable wpi : integer;  begin    wpi := 0; miscout := r.e.ctrl.pc(31 downto 2) & "00";     edata := aluin1; bpdata := aluin1;    if ((r.x.ctrl.wreg and r.x.ctrl.ld and not r.x.ctrl.annul) = '1') and       (r.x.ctrl.rd = r.e.ctrl.rd) and (r.e.ctrl.inst(31 downto 30) = LDST) and	(r.e.ctrl.cnt /= "10")    then bpdata := ldata; end if;    case r.e.aluop is    when EXE_STB   => miscout := bpdata(7 downto 0) & bpdata(7 downto 0) &			     bpdata(7 downto 0) & bpdata(7 downto 0);		      edata := miscout;    when EXE_STH   => miscout := bpdata(15 downto 0) & bpdata(15 downto 0);		      edata := miscout;    when EXE_PASS1 => miscout := bpdata; edata := miscout;    when EXE_PASS2 => miscout := aluin2;    when EXE_ONES  => miscout := (others => '1');		      edata := miscout;    when EXE_RDY  =>       if MULEN and (r.m.ctrl.wy = '1') then miscout := mey;      else miscout := r.m.y; end if;      if (NWP > 0) and (r.e.ctrl.inst(18 downto 17) = "11") then 	wpi := conv_integer(r.e.ctrl.inst(16 downto 15)); 	if r.e.ctrl.inst(14) = '0' then miscout := wpr(wpi).addr & '0' & wpr(wpi).exec; 	else miscout := wpr(wpi).mask & wpr(wpi).load & wpr(wpi).store; end if;      end if;      if (r.e.ctrl.inst(18 downto 17) = "10") and (r.e.ctrl.inst(14) = '1') then --%ASR17        miscout := asr17_gen(r);      end if;      if MACEN then        if (r.e.ctrl.inst(18 downto 14) = "10010") then --%ASR18          if ((r.m.mac = '1') and not MACPIPE) or ((r.x.mac = '1') and MACPIPE) then            miscout := mulo.result(31 downto 0);	-- data forward of asr18	  else miscout := r.w.s.asr18; end if;        else          if ((r.m.mac = '1') and not MACPIPE) or ((r.x.mac = '1') and MACPIPE) then            miscout := mulo.result(63 downto 32);   -- data forward Y	  end if;        end if;      end if;    when EXE_SPR  =>       miscout := get_spr(r);    when others => null;    end case;    mout := miscout;  end;  procedure alu_select(r : registers; addout : std_logic_vector(32 downto 0);	op1, op2 : word; shiftout, logicout, miscout : word; res : out word; 	me_icc : std_logic_vector(3 downto 0);	icco : out std_logic_vector(3 downto 0); divz : out std_ulogic) is  variable op : std_logic_vector(1 downto 0);  variable op3 : std_logic_vector(5 downto 0);  variable icc : std_logic_vector(3 downto 0);  variable aluresult : word;  begin    op   := r.e.ctrl.inst(31 downto 30); op3  := r.e.ctrl.inst(24 downto 19);    icc := (others => '0');    case r.e.alusel is    when EXE_RES_ADD =>       aluresult := addout(32 downto 1);      if r.e.aluadd = '0' then        icc(0) := ((not op1(31)) and not op2(31)) or 	-- Carry		 (addout(32) and ((not op1(31)) or not op2(31)));        icc(1) := (op1(31) and (op2(31)) and not addout(32)) or 	-- Overflow                 (addout(32) and (not op1(31)) and not op2(31));      else        icc(0) := (op1(31) and op2(31)) or 	-- Carry		 ((not addout(32)) and (op1(31) or op2(31)));        icc(1) := (op1(31) and op2(31) and not addout(32)) or 	-- Overflow		 (addout(32) and (not op1(31)) and (not op2(31)));      end if;      if notag = 0 then        case op is         when FMT3 =>          case op3 is          when TADDCC | TADDCCTV =>            icc(1) := op1(0) or op1(1) or op2(0) or op2(1) or icc(1);          when TSUBCC | TSUBCCTV =>            icc(1) := op1(0) or op1(1) or (not op2(0)) or (not op2(1)) or icc(1);          when others => null;          end case;        when others => null;        end case;      end if;      if aluresult = zero32 then icc(2) := '1'; end if;    when EXE_RES_SHIFT => aluresult := shiftout;    when EXE_RES_LOGIC => aluresult := logicout;      if aluresult = zero32 then icc(2) := '1'; end if;    when others => aluresult := miscout;    end case;    if r.e.jmpl = '1' then aluresult := r.e.ctrl.pc(31 downto 2) & "00"; end if;    icc(3) := aluresult(31);

⌨️ 快捷键说明

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