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

📄 fp.vhd

📁 sparc org, vhdl rtl code
💻 VHD
📖 第 1 页 / 共 3 页
字号:
variable rs : std_logic_vector(4 downto 0);
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 is
variable 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;

⌨️ 快捷键说明

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