📄 fp.vhd
字号:
then euiv(r.eut)(r.eui).start := not rx.startx; euiv(r.eut)(r.eui).opcode := cpi.me.inst(19) & cpi.me.inst(13 downto 5); end if; if (rx.holdn = '0') and (cpi.flush = '0') and (not ((r.sdep = '1') and (ddep = '1'))) and ((eu(r.eut)(r.eui).status <= free) or (euin(r.eut)(r.eui).wb = '1')) then euiv(r.eut)(r.eui).load := rx.starty; euiv(r.eut)(r.eui).start := not (rx.starty or rx.startx); if eu(r.eut)(r.eui).status /= exception then euv(r.eut)(r.eui).status := started; end if; euv(r.eut)(r.eui).rs1 := cpi.me.inst(18 downto 14); euv(r.eut)(r.eui).rs2 := cpi.me.inst(4 downto 0); euv(r.eut)(r.eui).rd := cpi.me.inst(29 downto 25); euv(r.eut)(r.eui).wreg := me.wreg; euv(r.eut)(r.eui).rreg1 := me.rreg1; euv(r.eut)(r.eui).rreg2 := me.rreg2; euv(r.eut)(r.eui).rs1d := me.rs1d; euv(r.eut)(r.eui).rs2d := me.rs2d; euv(r.eut)(r.eui).rdd := me.rdd; euv(r.eut)(r.eui).wrcc := me.wrcc; euiv(r.eut)(r.eui).opcode := cpi.me.inst(19) & cpi.me.inst(13 downto 5); rxv.holdn := '1'; end if; rxv.starty := euiv(r.eut)(r.eui).start; rxv.startx := (rx.startx or euiv(r.eut)(r.eui).start) and not holdn; ccv := ccv or me.wrcc; if cpi.flush = '1' then rxv.holdn := '1'; end if; -- regfile bypass if (rx.waddr = cpi.me.inst(18 downto 15)) then if (rx.wren(0) = '1') then op1(63 downto 32) := rx.res(63 downto 32); end if; if (rx.wren(1) = '1') then op1(31 downto 0) := rx.res(31 downto 0); end if; end if; if (rx.waddr = cpi.me.inst(4 downto 1)) then if (rx.wren(0) = '1') then op2(63 downto 32) := rx.res(63 downto 32); end if; if (rx.wren(1) = '1') then op2(31 downto 0) := rx.res(31 downto 0); end if; end if; -- optionally forward data from write stage if rfi.wren(0) = '1' then if cpi.me.inst(18 downto 15) = rfi.waddr then op1(63 downto 32) := rfi.wdata(63 downto 32); end if; if cpi.me.inst(4 downto 1) = rfi.waddr then op2(63 downto 32) := rfi.wdata(63 downto 32); end if; end if; if rfi.wren(1) = '1' then if cpi.me.inst(18 downto 15) = rfi.waddr then op1(31 downto 0) := rfi.wdata(31 downto 0); end if; if cpi.me.inst(4 downto 1) = rfi.waddr then op2(31 downto 0) := rfi.wdata(31 downto 0); end if; end if; -- align single operands if me.rs1d = '0' then if cpi.me.inst(14) = '0' then op1 := op1(63 downto 32) & op1(63 downto 32); else op1 := op1(31 downto 0) & op1(31 downto 0); end if; end if; if me.rs2d = '0' then if cpi.me.inst(0) = '0' then op2 := op2(63 downto 32) & op2(63 downto 32); else op2 := op2(31 downto 0) & op2(31 downto 0); end if; end if; -- drive EU operand inputs for i in 0 to EUTYPES-1 loop for j in 0 to euconf(i) loop euiv(i)(j).op1 := op1; euiv(i)(j).op2 := op2; end loop; end loop; cpo.holdn <= rx.holdn;--------------------------------------------------------------- write stage------------------------------------------------------------- wrdata := cpi.lddata & cpi.lddata; if cpi.flush = '0' then case wr.cpins is when load => if (wr.wreg = '1') then if cpi.wr.cnt = "00" then wren(0) := not cpi.wr.inst(25); wren(1) := cpi.wr.inst(25); else wren(1) := '1'; end if; end if; if (wr.acsr and holdn) = '1' then rxv.csr.cexc := cpi.lddata(4 downto 0); rxv.csr.aexc := cpi.lddata(9 downto 5); rxv.csr.cc := cpi.lddata(11 downto 10); rxv.csr.tem := cpi.lddata(27 downto 23); rxv.csr.rd := cpi.lddata(31 downto 30); end if; when store => if wr.acsr = '1' then rxv.csr.tt := (others => '0'); end if; if (cpi.wr.inst(20 downto 19) = "10") then -- STDFQ if qne = '1'then euv(euti)(euqi).status := free; euv(euti)(euqi).rst := '1'; if euq(euti).last = euconf(euti) then euqv(euti).last := 0; else euqv(euti).last := euqv(euti).last + 1; end if; if (euf.last /= euf.first) then if euf.last = (EUTOT-1) then eufv.last := 0; else eufv.last := eufv.last + 1; end if; end if; else rxv.state := nominal; end if; end if; when cpop => -- dont assign PC and inst until here in case previous cpop trapped euv(r.weut)(r.weui).inst := cpi.wr.inst; euv(r.weut)(r.weui).pc := cpi.wr.pc; when others => null; end case; end if;-- flush EU if trap was taken if ((holdn and cpi.flush) = '1') and (EUTOT > 1) then case wr.cpins is when cpop => if eu(r.weut)(r.weui).status /= exception then euv(r.weut)(r.weui).rst := '1'; euv(r.weut)(r.weui).status := free; end if; eufv.first := wr.first; euqv(r.eut).first := r.eut; euqv(r.weut).first := r.weut; when others => null; end case; end if; waddr := cpi.wr.inst(29 downto 26);--------------------------------------------------------------- retire stage------------------------------------------------------------- rtaddr := eu(euti)(euqi).rd(4 downto 1); if eu(euti)(euqi).rdd = '1' then rtdata := euo(euti)(euqi).res; else rtdata(63 downto 32) := euo(euti)(euqi).res(63) & euo(euti)(euqi).res(59 downto 29); rtdata(31 downto 0) := rtdata(63 downto 32); end if; wren := wren and (holdn & holdn); if ((euo(euti)(euqi).exc(4 downto 0) and rx.csr.tem) /= "00000") or (euo(euti)(euqi).exc(5) = '1') then cpexc := '1'; end if; if (wren = "00") and (eu(euti)(euqi).status = ready) and (rx.state = nominal) then waddr := rtaddr; wrdata := rtdata; if cpexc = '0' then if (eu(euti)(euqi).wreg) = '1' then if (eu(euti)(euqi).rdd) = '1' then wren := "11"; else wren(0) := not eu(euti)(euqi).rd(0); wren(1) := eu(euti)(euqi).rd(0); end if; end if; if eu(euti)(euqi).wrcc = '1' then rxv.csr.cc := euo(euti)(euqi).cc; end if; rxv.csr.aexc := rx.csr.aexc or euo(euti)(euqi).exc(4 downto 0); if euv(euti)(euqi).status = ready then euv(euti)(euqi).status := free; end if; euv(euti)(euqi).wb := '1'; rxv.csr.cexc := euo(euti)(euqi).exc(4 downto 0); if euq(euti).last = euconf(euti) then euqv(euti).last := 0; else euqv(euti).last := euqv(euti).last + 1; end if; if euf.last = (EUTOT-1) then eufv.last := 0; else eufv.last := eufv.last + 1; end if; else euv(euti)(euqi).status := exception; rxv.state := excpend; if (euo(euti)(euqi).exc(5) = '1') then rxv.csr.tt := "011"; else rxv.csr.tt := "001"; end if; end if; end if; if cpi.exack = '1' then rxv.state := exception; end if; if rxv.state = excpend then cpo.exc <= '1'; else cpo.exc <= '0'; end if; cpo.ccv <= not ccv; cpo.cc <= rx.csr.cc; rxv.res := wrdata; rxv.waddr := waddr; rxv.wren := wren; rfi.waddr <= waddr; rfi.wren <= wren; rfi.wdata <= wrdata;-- reset if rst = '0' then for i in 0 to EUTYPES-1 loop for j in 0 to euconf(i) loop euv(i)(j).status := free; end loop; euqv(i).first := 0; euqv(i).last := 0; end loop; eufv.first := 0; eufv.last := 0; rxv.holdn := '1'; rv.start := '0'; rxv.state := nominal; rxv.csr.tt := (others => '0'); rxv.startx := '0'; ctrl.first := 0; end if; euin <= euv; eui <= euiv; eufin <= eufv; euqin <= euqv; exin <= ctrl; rin <= rv; rxin <= rxv; end process;-- registers regs : process(clk) variable pc : std_logic_vector(31 downto 0); begin if rising_edge(clk(0)) then if holdn = '1' then ex <= exin; me <= ex; wr <= me; r <= rin; end if; euq <= euqin; euf <= eufin; rx <= rxin; eu <= euin;-- pragma translate_off if DEBUGFPU then if euin(euf.fifo(euf.last))(euq(euf.fifo(euf.last)).last).wb = '1' then pc := eu(euf.fifo(euf.last))(euq(euf.fifo(euf.last)).last).pc; else pc := cpi.wr.pc; end if; if (rfi.wren(0) = '1') then print(tost(pc) & ": %f" & tost("000" & rfi.waddr & '0') & " = " & tost(rfi.wdata(63 downto 32))); end if; if (rfi.wren(1) = '1') then print(tost(pc) & ": %f" & tost("000" & rfi.waddr & '1') & " = " & tost(rfi.wdata(31 downto 0))); end if; end if;-- pragma translate_on end if; end process;-- simple 3-port register file made up of 4 parallel dprams dp00: dpram_synp_ss generic map (4, 32, 16) port map (rfi.wdata(63 downto 32), rfi.raddr1, rfi.waddr, vcc, rfi.wren(0), clk(0), vcc, rfo.rdata1(63 downto 32)); dp01: dpram_synp_ss generic map (4, 32, 16) port map (rfi.wdata(31 downto 0), rfi.raddr1, rfi.waddr, vcc, rfi.wren(1), clk(0), vcc, rfo.rdata1(31 downto 0)); dp10: dpram_synp_ss generic map (4, 32, 16) port map (rfi.wdata(63 downto 32), rfi.raddr2, rfi.waddr, vcc, rfi.wren(0), clk(0), vcc, rfo.rdata2(63 downto 32)); dp11: dpram_synp_ss generic map (4, 32, 16) port map (rfi.wdata(31 downto 0), rfi.raddr2, rfi.waddr, vcc, rfi.wren(1), clk(0), vcc, rfo.rdata2(31 downto 0)); gl0 : for i in 0 to euconf(0) generate fpu0 : fpu port map ( ss_clock => clk(0), FpInst => eui(0)(i).opcode, FpOp => eui(0)(i).start, FpLd => eui(0)(i).load, Reset => eui(0)(i).flush, fprf_dout1 => eui(0)(i).op1, fprf_dout2 => eui(0)(i).op2, RoundingMode => rx.csr.rd, FpBusy => euo(0)(i).busy, FracResult => euo(0)(i).res(51 downto 0), ExpResult => euo(0)(i).res(62 downto 52), SignResult => euo(0)(i).res(63), SNnotDB => open, Excep => euo(0)(i).exc, ConditionCodes => euo(0)(i).cc, ss_scan_mode => gnd, fp_ctl_scan_in => gnd, fp_ctl_scan_out => open); end generate; fpauxgen : if EUTYPES > 1 generate gl1 : for i in 0 to euconf(1) generate eu1 : fpaux port map (rst, clk(0), eui(1)(i), euo(1)(i)); end generate; end generate;end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -