📄 fp.vhd
字号:
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 + -