fd20_backpressure: Backpressure¶
Runs Surfer in the browser, with nothing to install. The signal setup takes a few seconds to apply.
fd20_backpressure is the FD-20 demonstration scenario. It is a demo,
not a verification test. The backend takes decode's output one cycle in
four. Decode stalls first, the ibuf fills and refuses the IFU, the
IFU stops draining the FTQ, the FTQ fills, and the FTQ stops issuing
p0 requests. The run passes if each of the four stalls occurs.
The scenario runs on the one-slot model (Makefile SCEN_2S, DOC-006).
A recorded run:
-I: fd20_backpressure: PASS, stall cycles with the instruction buffer full 378,
FTQ full 324, decode held 368, no p0 request 331, cyc 537
1. The program¶
Source: programs/fd20_backpressure.svh, task prog_fd20. M-mode,
bare. Offsets from RESET_VECTOR 0x8000_0000.
+0x00 mixed(3)
top = +0x08
mixed(23) 15 c.addi and 8 addi, 62 bytes
top+62 bne x6,x0,top taken on passes 0..38, 40 passes
mixed(3), then jal x0,0 (halt)
be_rdy_pat = 4(programs/fd20_backpressure.svh:24, FD-U2): the backend drivesdec_ibuf_rdyonly in cycles withcyc % 4 == 0(rtl/core/frontend/fe_top/tb/models/fe_tb_backend.svh:463-465).- The stream is 3 + 40 x 24 + 3 = 966 instructions plus the halt (derived from the source).
2. Why the program produces the behavior¶
- Decode. With
dec_ibuf_rdylow three cycles in four, the ibuf's read port presents a bundle that is not taken. - The ibuf. Its ready is registered occupancy:
ibuf_ifu_rdyis high whiler_count <= DEPTH - FTQ_PD_WIDTH(rtl/core/frontend/ibuf/rtl/ibuf.sv:114). DEPTH is 64 (ibuf.sv:57; fe_top instantiates it without an override,rtl/core/frontend/fe_top/rtl/fe_top.sv:802) and FTQ_PD_WIDTH 16 (rtl/core/frontend/bpu/rtl/bp_defines_pkg.sv:237), so it refuses above 48 slots. - The IFU. F3 holds its block, payload and all, while
ibuf_ifu_rdyis low (rtl/core/frontend/ifu/rtl/ifu_f3.sv:56-57, IB-7). Fetch and retirement slow to the backend's rate while p0 keeps allocating, so the FTQ fills. - The FTQ.
ftq_fullis set when the age of alloc_ptr over commit_ptr reaches FTQ_ALLOC_LIMIT (rtl/core/frontend/ftq/rtl/ftq_ptr.sv:247), which is FTQ_DEPTH, 64 (ftq_ptr.sv:196,bp_defines_pkg.sv:30). It is hold condition H2 of ftq_npc:w_holdincludesh2_ftq_full(rtl/core/frontend/ftq/rtl/ftq_npc.sv:306-309) andftq_pred_val_p0 = ~w_hold(ftq_npc.sv:377). - Seen in the run (fst2vcd on
out/fd20_backpressure/fd20_backpressure.fst): the first cycle withpd_out[0].validanddec_ibuf_rdylow is 18; the firstifu_ibuf_valwithibuf_ifu_rdylow is 71, withu_ibuf.r_count52; the firstftq_fullis 138 (tb.cyc values).
3. What the monitor counts¶
The counts come from tb/fe_demo_mon.svh:571-576, sampled every cycle
while meas is set. All four are counts of CYCLES in which the
condition holds, not of stall events.
n_ibuf_full ifu_ibuf_val && !ibuf_ifu_rdy the IFU offers, the ibuf
refuses
n_ftq_full ftq_full (tb's ftq_full, fe_top's
port, fe_tb_dut.svh:98,
:101)
n_dec_stall pd_out[0].valid && !dec_ibuf_rdy
n_p0_held !ftq_pred_val_p0 for any hold reason
The proof (tb/fe_demo_proofs.svh:160-161) is that each count is above
zero. tb_fe_demo.sv also requires the whole stream to retire with no
errors.
4. Reading the numbers¶
cyc 537is the measured window, so the stall counts are fractions of it: the ibuf refuses the IFU in 378 of 537 cycles, the FTQ is full in 324, decode holds a bundle in 368.no p0 request 331counts every hold, not only backpressure. From the run: of the 331 cycles, 324 haveftq_fulland 7 haveu_ftq.u_npc.h3_ftb_upd(the FTB update hold, H3) without it.- The order of onset (18, 71, 138) is the propagation from decode back to the FTQ; the counts alone do not show it.
- Departures from
planning/showcase/fe_demo_scenarios.mdFD-20: - FD-20's program is "a long run with the backend accepting slowly"; the program fixes the rate at one cycle in four (be_rdy_pat 4, FD-U2 closed).
- FD-20's proof is "each stall occurs". The proof as built also
counts
n_p0_held, which includes the FTB update holds; it does not separate the p0 stall caused by the full FTQ.n_ftq_fullis the count of that cause.
5. Waveform¶
The saved view is waves/fd20_backpressure.sucl, which make view
S=fd20_backpressure opens in Surfer. Look at:
- decode group:
dec_ibuf_rdyhigh one cycle in four andpd_out.[0].validheld, from cycle 18. - ibuf group:
ifu_ibuf_valwithibuf_ifu_rdylow from cycle 71;u_ibuf.w_n_presandw_n_pop, the slots presented and taken. - ftq group:
ftq_fullfrom cycle 138, withw_commit_ptr,ftq_pred_idx_p0andftq_ifu_idx. - bp_cluster_p0 group:
ftq_pred_val_p0low whileftq_fullis set;u_npc.w_holdhigh with it. u_ibuf.r_countin the ibuf group, the occupancy the ready is computed from: 52 at cyc 71, whenibuf_ifu_rdyfirst refuses.
Runs Surfer in the browser, with nothing to install. The signal setup takes a few seconds to apply.
Run it from examples/fe_demo/: make fd20_backpressure runs the scenario; make view S=fd20_backpressure opens its waveform in Surfer.
Files: programs/fd20_backpressure.svh, waves/fd20_backpressure.sucl.