fd03_two_branch: Two Branches in One Block¶
Runs Surfer in the browser, with nothing to install. The signal setup takes a few seconds to apply.
fd03_two_branch is the FD-3 demonstration scenario. It is a demo, not a
verification test. It runs a loop through two blocks, X and Y, each
holding two conditional branches within its first 32 bytes. Once the
predictors are trained, the p1 prediction (uBTB) and the p2 slot group
(FTB) for each block carry both prediction slots. The run passes if the
FTQ accepts at least one p1 prediction or p2 slot group with both slots
valid.
The scenario needs two prediction slots and runs on the two-slot model
(Makefile SCEN_2S, DOC-006); on the one-slot model both counts are 0
and it fails. A recorded run:
-I: fd03_two_branch: PASS, blocks with both slots valid at p1 78, at p2 74,
cyc 539
1. The program¶
Source: programs/fd03_two_branch.svh, task prog_fd03 (tb_fe_top's
twocond). X = RESET_VECTOR + 0x400, Y = RESET_VECTOR + 0x440,
top = RESET_VECTOR + 8.
RESET_VECTOR+0 mixed(3) 8 bytes
top c.addi
top+2 jal x0,X
top+6 (back) c.addi
top+8 bne x6,x0,top back edge: taken on passes 0..22
top+12 mixed(3)
top+20 jal x0,0 halt (demo_go -> W.halt)
X+0 c.addi
X+2 X.c1 bne x6,x0,X+8 never taken pos 1
X+6 c.addi
X+8 X.c2 bne x6,x0,X+14 always taken pos 4
X+12 c.addi skipped (written dry)
X+14 c.addi
X+16 jal x0,Y pos 8
Y+0 c.addi
Y+2 Y.c1 bne x6,x0,Y+8 taken on odd passes pos 1
Y+6 c.addi skipped when Y.c1 taken
Y+8 Y.c2 bne x6,x0,Y+14 never taken pos 4
Y+12 c.addi
Y+14 c.addi
Y+16 jal x0,back pos 8
- 24 passes. Each pass resets
W.wp = topand writes the same bytes;cskip(tk, 1)writes the skippedc.addiin dry mode when taken, so the code is fixed and only the expected stream changes. - Outcomes come from the writer (
bcc,fe_tb_writer.svh:412-419), not from x6: the backend retires against the expected stream. posis the halfword position from the lookup PC (X or Y, both 32-byte aligned).
2. Why the program fills both slots¶
- Two branch fields per entry. On the two-slot model a prediction
block has
NUM_PRED_SLOTS= 2 slots (bp_defines_pkg.sv:65), each abp_ftq_slot_t(bp_structs_pkg.sv:405-418). The FTB and the uBTB store a block's branches in position order,br0the lower: the update sorts the stored fields and the resolving branch by position (rtl/core/frontend/bpu/rtl/ftb_cntrl.sv, THE UPDATE, lines 464 to 615;ubtb.sv,apply_upd, lines 291 to 376). - Both conditionals of X and of Y are on the path in every pass: X.c1 is never taken, so X.c2 is reached; Y.c1 when not taken falls into Y.c2, and when taken jumps to Y+8, which is Y.c2. The FST shows both in the block's two slots (below).
- Slot order.
bp_cluster.sv:861-867swaps the two p1 slots when slot 1'sposis below slot 0's, so slot 0 is always the earlier branch. Since the uBTB stores in position order the swap does not fire for its entries (the comment at lines 853 to 860).
From the FST, the accepted two-slot p2 groups, by block:
block slot 0 slot 1 groups
X pos 1 COND nt TAGE pos 4 COND tk TAGE 26
X pos 1 COND tk TAGE pos 4 COND tk TAGE 1
Y pos 1 COND nt TAGE pos 4 COND nt TAGE 5
Y pos 1 COND nt TAGE pos 4 COND tk TAGE 1
Y pos 1 COND tk TAGE pos 4 COND nt TAGE 7
Y pos 1 COND tk TAGE pos 4 COND tk TAGE 13
Y+6 pos 1 COND nt TAGE pos 5 JAL tk FTB 3
Y+8 pos 0 COND nt TAGE pos 4 JAL tk FTB 15
Y+8 pos 0 COND tk TAGE pos 4 JAL tk FTB 3
(COND is br_type COND, JAL DIRECT_UNC; TAGE and FTB are
pred_src PRED_TAGE and PRED_FTB, which the waveform shows by name;
nt and tk are taken 0 and 1.) Y+8 is the block fetched after Y.c1 is
taken: Y.c2 at its position 0 and the JAL to back at position 4. Y+6
is the block fetched after the backend corrects a Y.c1 predicted
taken: Y.c2 at its position 1 and the JAL at position 5.
3. What the monitor counts¶
The counts come from tb/fe_demo_mon.svh:415-423, taken inside the
meas window.
n_two_p1 u_ftq.w_ok_pred_p1 && bpu_pred_slot_p1[0].slot_valid
&& bpu_pred_slot_p1[1].slot_valid
a p1 prediction the FTQ accepted, both slots valid
n_two_p2 u_ftq.w_ok_slot_p2 && bpu_slot_p2[0].slot_valid
&& bpu_slot_p2[1].slot_valid
a p2 slot group the FTQ accepted, both slots valid
The proof (tb/fe_demo_proofs.svh:55-59) is
n_two_p1 + n_two_p2 > 0. tb_fe_demo.sv also requires the whole
stream to retire with no errors before it accepts the proof.
4. Reading the numbers¶
- The counts are of groups the FTQ accepted. X is executed once per pass, 24 times, and shows 27 two-slot p2 groups; the count includes repeated predictions of the same block.
- The counters do not check the slot types. Of the 78 p1 groups (FST),
27 are X, 27 are Y, 21 are Y+8 and 3 are Y+6. The block at
top(0x80000008) holds only the JAL, and its entry, which is its own since each block start has one (BP-140), has one slot. - Departure from
planning/showcase/fe_demo_scenarios.mdFD-3: the program is "two conditional branches within one 32-byte block, in a loop"; as built there are two such blocks, X (not taken, then taken) and Y (alternating, then not taken). The proof "a block predicted with both slots valid" is met by any two valid slots, including a JAL in one of them, as the Y+6 and Y+8 counts show.
5. Waveform¶
The saved view is waves/fd03_two_branch.sucl, which make view
S=fd03_two_branch opens in Surfer. Look at:
- group
bp_cluster_p1_ubtb:r_ubtb_blk_p1.hitwithbpu_pred_slot_p1.[0]and.[1]bothslot_valid,pos1 and 4, atbpu_pred_idx_p1of the X and Y blocks. - group
bp_cluster_p2_ftb:w_ftb_valid_p2,bpu_slot_val_p2andbpu_slot_p2.[0]/.[1]both valid, each a conditional (br_typeCOND) at its ownpos,pred_srcPRED_TAGE. - group
ftq:w_ok_pred_p1andw_ok_slot_p2accepting them.
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 fd03_two_branch runs the scenario; make view S=fd03_two_branch opens its waveform in Surfer.
Files: programs/fd03_two_branch.svh, waves/fd03_two_branch.sucl.