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

📄 fp.vhd

📁 经典的浮点运算VHDL源代码,是FPGA开发和VHDL学习的好资料!
💻 VHD
📖 第 1 页 / 共 3 页
字号:
begin  lock := '0'; rs := rsin;  if (eu.wreg = '1')  and (rs(4 downto 1) = eu.rd(4 downto 1)) then    if ((dbl or eu.rdd) = '1') or (rs(0) = eu.rd(0)) then lock := '1'; end if;  end if;  return(lock);end;function ddepcheck (rs1, rs2 : std_logic_vector; 	rreg1, rreg2, rs1d, rs2d : std_logic; eu : unit_ctrl_arr_arr;         euo : euo_arr_arr) return std_logic isvariable ddep : std_logic;variable r1, r2 : std_logic_vector(4 downto 0);begin  ddep := '0'; r1 := rs1; r2 := rs2;  for i in 0 to EUTYPES-1 loop    for j in 0 to euconf(i) loop      if (eu(i)(j).status = started) or (eu(i)(j).status = ready) then        if rreg1 = '1' then ddep := ddep or srccheck(r1, rs1d, eu(i)(j)); end if;        if rreg2 = '1' then ddep := ddep or srccheck(r2, rs2d, eu(i)(j)); end if;      end if;    end loop;  end loop;  return(ddep);end;begin  vcc <= '1'; gnd <= '1';-- instruction decoding  pipeline : process(cpi, ex, me, wr, eu, euin, r, rx, rfi, rfo, holdn, xholdn,			euo, euf, euq, rst)  variable op     : std_logic_vector(1 downto 0);  variable op3    : std_logic_vector(5 downto 0);  variable opc    : std_logic_vector(8 downto 0);  variable stdata : std_logic_vector(31 downto 0);  variable rs1, rs2, rd : std_logic_vector(4 downto 0);  variable ctrl   : pl_ctrl;  variable ldlock : std_logic;  variable wren   : std_logic_vector(1 downto 0);  variable waddr  : std_logic_vector(3 downto 0);  variable rtaddr : std_logic_vector(3 downto 0);  variable wrdata : std_logic_vector(63 downto 0);  variable rtdata : std_logic_vector(63 downto 0);  variable rv : reg_type;  variable rxv : regx_type;  variable euv : unit_ctrl_arr_arr;  variable euqv : euq_arr;  variable euiv : eui_arr_arr;  variable eufv : eu_fifo_type;  variable euti : eumindex;  variable euqi : euindex;  variable ddep     : std_logic;  variable cpexc    : std_logic;  variable fpill    : std_logic;  variable ccv      : std_logic;  variable qne      : std_logic;  variable op1      : std_logic_vector (63 downto 0); -- operand1  variable op2      : std_logic_vector (63 downto 0); -- operand2  variable opcode   : std_logic_vector (9 downto 0); -- FP opcode  begin--------------------------------------------------------------- decode stage-------------------------------------------------------------    op    := cpi.dinst(31 downto 30);    op3   := cpi.dinst(24 downto 19);    opc   := cpi.dinst(13 downto 5);    rs1   := cpi.dinst(18 downto 14);    rs2   := cpi.dinst(4 downto 0);    rd    := cpi.dinst(29 downto 25);    rv := r; rxv := rx; ctrl.first := ex.first;    ctrl.cpins := none; ctrl.wreg := '0'; ctrl.rdd := '0';    ctrl.wrcc := '0'; ctrl.acsr := '0'; ldlock := '0';    ctrl.rreg1 := '0'; ctrl.rreg2 := '0';    ctrl.rs1d := '0'; ctrl.rs2d := '0'; fpill := '0';    stdata := (others => '-'); wren := "00"; cpexc := '0';    ccv := '0'; rv.start := '0';    rv.weut := r.eut; rv.weui := r.eui;    rxv.start := '0'; rv.eut := 0; rv.eui := 0; rv.sdep := '0';    euv := eu; euqv := euq; eufv := euf;    euti := euf.fifo(euf.last); euqi := euq(euti).last;    if (euf.last /= euf.first) or (eu(euti)(euqi).status = exception)    then qne := '1'; else qne := '0'; end if;    for i in 0 to EUTYPES-1 loop      for j in 0 to euconf(i) loop        euiv(i)(j).opcode := cpi.ex.inst(19) & cpi.ex.inst(13 downto 5);	euiv(i)(j).start := '0'; euiv(i)(j).load := '0';	euiv(i)(j).flush := eu(i)(j).rst or euin(i)(j).rst;	euv(i)(j).wb := '0';	euv(i)(j).rst := not rst;	if (eu(i)(j).status = started) and (euo(i)(j).busy = '0') then	  euv(i)(j).status := ready;	end if;	if (eu(i)(j).status > free) then	  ccv := ccv or eu(i)(j).wrcc;	end if;      end loop;    end loop;    -- decode CP instructions      case op is      when FMT3 =>        case op3 is        when FPOP1 => 	  if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100";          elsif rx.state = nominal then	    ctrl.cpins := cpop; ctrl.wreg := '1';            case opc is            when FMOVS | FABSS | FNEGS => ctrl.rreg2 := '1';            when FITOS | FSTOI => ctrl.rreg2 := '1';            when FITOD | FSTOD => ctrl.rreg2 := '1'; ctrl.rdd := '1';            when FDTOI | FDTOS => ctrl.rreg2 := '1'; ctrl.rs2d  := '1';            when FSQRTS => ctrl.rreg2 := '1';            when FSQRTD => ctrl.rreg2 := '1'; ctrl.rs2d  := '1'; ctrl.rdd := '1';            when FADDS | FSUBS | FMULS | FDIVS => 	      ctrl.rreg1 := '1'; ctrl.rreg2 := '1';            when FADDD | FSUBD | FMULD | FDIVD => 	      ctrl.rreg1 := '1'; ctrl.rreg2 := '1'; ctrl.rs1d  := '1'; 	      ctrl.rs2d  := '1'; ctrl.rdd := '1';            when others => fpill := '1'; -- illegal instuction            end case;	  end if;        when FPOP2 => 	  if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100";          elsif rx.state = nominal then	    ctrl.cpins := cpop; ctrl.wrcc := '1';	    ctrl.rreg1 := '1'; ctrl.rreg2 := '1';            case opc is            when FCMPD | FCMPED => 	      ctrl.rs1d := '1'; ctrl.rs2d := '1';            when others => fpill := '1'; -- illegal instuction            end case;	  end if;        when others => null;        end case;        if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and	  (ex.wreg = '1')        then	  if (ctrl.rreg1 = '1') and	   (rs1(4 downto 1) = cpi.ex.inst(29 downto 26)) and	   (((ctrl.rs1d or ex.rdd) = '1') or (rs1(0) = cpi.ex.inst(25)))	  then ldlock := '1'; end if;	  if (ctrl.rreg2 = '1') and	   (rs2(4 downto 1) = cpi.ex.inst(29 downto 26)) and	   (((ctrl.rs2d or ex.rdd) = '1') or (rs2(0) = cpi.ex.inst(25)))	  then ldlock := '1'; end if;        end if;      when LDST =>        case op3 is        when LDF | LDDF =>	  if rx.state = exception then rxv.state := excpend; rxv.csr.tt := "100";          elsif rx.state = nominal then	    ctrl.rdd := op3(1) and op3(0);	    ctrl.cpins := load; ctrl.wreg := '1';            for i in 0 to EUTYPES-1 loop	-- dst interlock	      for j in 0 to euconf(i) loop	        ldlock := ldlock or ldcheck(rd, ctrl.rdd, euin(i)(j)); 	      end loop;            end loop; 	  end if;        when STF | STDF =>	  -- check for CP register dependencies	  if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and	     (cpi.ex.cnt = "00") and 	       ((rd = cpi.ex.inst(29 downto 25)) or	       ((rd(4 downto 1) = cpi.ex.inst(29 downto 26)) and 		  (ex.rdd = '1')))	  then ldlock := '1'; end if;          if rx.state = nominal then	    for i in 0 to EUTYPES-1 loop	      for j in 0 to euconf(i) loop	        ldlock := ldlock or stcheck(rd, (op3(1) and op3(0)), euin(i)(j)); 	      end loop; 	    end loop;	  end if;	  if (ldlock = '0') then ctrl.cpins := store; end if;        when STFSR | LDFSR =>	  if (rx.state = exception) and (op3 = LDFSR) then 	    rxv.state := excpend;  rxv.csr.tt := "100";          else	    if (ex.cpins = load) and ((cpi.ex.annul or cpi.ex.trap) = '0') and	     (cpi.ex.cnt = "00") and (op3 = STFSR) and (ex.acsr = '1')	    then ldlock := '1'; end if;	    if (rx.state = nominal) then 	      for i in 0 to EUTYPES-1 loop	        for j in 0 to euconf(i) loop                  if eu(i)(j).status > free then ldlock := '1'; end if; 	        end loop; 	      end loop;	    end if;	  end if;-- FIX ME - add check for not yet commited cpins in pipeline	  if (ldlock = '0') then	    ctrl.acsr := '1';	    if op3 = STFSR then ctrl.cpins := store; 	    else ctrl.cpins := load; end if;	  end if;        when STDFQ => 	  if (rx.state = nominal) then 	    rxv.state := excpend; rxv.csr.tt := "100";	  else ctrl.cpins := store; end if;        when others => null;        end case;      when others => null;      end case;    if ((cpi.flush or cpi.dtrap or cpi.dannul) = '1') then      ctrl.cpins := none;      rxv.state := rx.state; rxv.csr.tt := rx.csr.tt;    end if;--------------------------------------------------------------- execute stage-------------------------------------------------------------    -- generate regfile addresses    if holdn = '0' then      op  := cpi.me.inst(31 downto 30);      rd  := cpi.me.inst(29 downto 25);      op3 := cpi.me.inst(24 downto 19);      rs1 := cpi.me.inst(18 downto 14);      rs2 := cpi.me.inst(4 downto 0);    else      op  := cpi.ex.inst(31 downto 30);      rd  := cpi.ex.inst(29 downto 25);      op3 := cpi.ex.inst(24 downto 19);      rs1 := cpi.ex.inst(18 downto 14);      rs2 := cpi.ex.inst(4 downto 0);    end if;    if (op = LDST) and (op3(2) = '1') then rs1 := rd; end if;    rfi.raddr1 <= rs1(4 downto 1); rfi.raddr2 <= rs2(4 downto 1);    cpo.ldlock <= ldlock;    op1 := rfo.rdata1; op2 := rfo.rdata2;    -- generate store data    if  (cpi.ex.inst(20 downto 19) = "10") then  -- STDFQ      if (cpi.ex.cnt /= "10") then stdata := eu(euti)(euqi).pc;      else stdata := eu(euti)(euqi).inst; end if;    elsif  ((cpi.ex.inst(25) = '0') and (cpi.ex.cnt /= "10")) then  -- STF/STDF      stdata := op1(63 downto 32);    else stdata := op1(31 downto 0); end if;    if (ex.cpins = store) and (ex.acsr = '1') then		-- STFSR      stdata :=  rx.csr.rd & "00" & rx.csr.tem & "000" & FPUVER &	rx.csr.tt & qne & '0' & rx.csr.cc & rx.csr.aexc & rx.csr.cexc;    end if;    cpo.data <= stdata;    -- check for source operand dependency with scheduled instructions    if (ex.cpins = cpop) then      rv.sdep := ddepcheck(cpi.ex.inst(18 downto 14), cpi.ex.inst(4 downto 0),		ex.rreg1, ex.rreg2, ex.rs1d, ex.rs2d, eu, euo);    end if;    -- select execution unit type    if (cpi.ex.inst(12 downto 9) = "0000") and (EUTYPES > 1) then       rv.eut := EUTYPES-1;	-- use exection unit 1    else       rv.eut := 0;	-- use exection unit 0    end if;    -- check if an execution unit is available    if (ex.cpins = cpop) and (holdn = '1') and (cpi.flush = '0') then      rv.eui := euq(rv.eut).first;      ccv := ccv or ex.wrcc;      if (rv.sdep = '0') and (eu(rv.eut)(euq(rv.eut).first).status = free)       then	rxv.start := '1';         euiv(rv.eut)(rv.eui).start := '1';	euv(rv.eut)(rv.eui).status := started;	euv(rv.eut)(rv.eui).rd := cpi.ex.inst(29 downto 25);        euv(rv.eut)(rv.eui).rs1 := cpi.ex.inst(18 downto 14);        euv(rv.eut)(rv.eui).rs2 := cpi.ex.inst(4 downto 0);	euv(rv.eut)(rv.eui).wreg := ex.wreg;	euv(rv.eut)(rv.eui).rreg1 := ex.rreg1;	euv(rv.eut)(rv.eui).rreg2 := ex.rreg2;	euv(rv.eut)(rv.eui).rs1d := ex.rs1d;	euv(rv.eut)(rv.eui).rs2d := ex.rs2d;	euv(rv.eut)(rv.eui).rdd := ex.rdd;	euv(rv.eut)(rv.eui).wrcc := ex.wrcc;      else rxv.holdn := '0'; rv.start := '1'; end if;      ctrl.first := euf.first;      eufv.fifo(euf.first) := rv.eut;      if euq(rv.eut).first = euconf(rv.eut) then euqv(rv.eut).first := 0;      else euqv(rv.eut).first := euqv(rv.eut).first + 1; end if;      if euf.first = (EUTOT-1) then eufv.first := 0;      else eufv.first := eufv.first + 1; end if;    end if;  --------------------------------------------------------------- memory stage-------------------------------------------------------------    ddep  := ddepcheck(cpi.me.inst(18 downto 14), cpi.me.inst(4 downto 0),		me.rreg1, me.rreg2, me.rs1d, me.rs2d, eu, euo);    euiv(r.eut)(r.eui).load := rx.start or rx.starty;    if (rx.holdn = '0') and  (xholdn = '1') and (cpi.flush = '0') and        ((r.sdep and ddep) = '0') and (euo(r.eut)(euq(r.eut).first).busy = '0')

⌨️ 快捷键说明

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