fd18_uncached: Uncached Fetch¶
Runs Surfer in the browser, with nothing to install. The signal setup takes a few seconds to apply.
fd18_uncached is the FD-18 demonstration scenario. It is a demo, not
a verification test. Code runs from a page whose Sv39 leaf has PBMT NC,
then from one whose leaf has PBMT IO (DOC-003). The IFU fetches each one
instruction per FTQ entry, each block only after every older entry has
committed, with uncached L1I requests that are answered from memory and
never written into the array. The run passes if the L1I takes uncached
requests from each page and no line of either page is filled into the
L1I.
The scenario runs on the one-slot model (Makefile SCEN_2S, DOC-006).
A recorded run:
-I: fd18_uncached: PASS, uncached requests from the NC page 28,
from the IO page 10, uncached lines filled 0, cyc 797
1. The program¶
Source: programs/fd18_uncached.svh, task prog_fd18, ported from
tb_fe_top's uc_nc. S-mode under satp Sv39. The pages
(map4k, and map4k_pbmt at
rtl/core/frontend/fe_top/tb/models/fe_tb_writer.svh:770):
RESET_VECTOR 0x8000_0000 -> PA 0x8000_0000 cacheable
c 0x8001_0000 -> PA 0x8100_0000 cacheable
u 0x8001_1000 -> PA 0x8120_3000 PBMT 1 (NC)
io 0x8001_2000 -> PA 0x8120_4000 PBMT 2 (IO)
RESET mixed(3); jal x0, c
c mixed(4); jal x0, u+0x10
u+0x10 mixed(3) +0x10 +0x12 +0x16
u+0x18 bne (cskip, taken) to +0x22; +0x1C..+0x21 written dry
u+0x22 mixed(2) +0x22 +0x24
u+0x28 bne (cskip, not taken)
u+0x2C c.addi
u+0x2E jal x0, u+0x200
u+0x200 mixed(2); bne x6 at +0x206 back to +0x200, 3 iterations
u+0x20A mixed(2); jal x0, c+0x200 at +0x210
c+0x200 mixed(3); jal x1, u+0x400 at c+0x208 (link c+0x20C)
u+0x400 mixed(2); ret at +0x406
c+0x20C mixed(2); jal x0, io+0x10 at c+0x212
io+0x10 mixed(3) +0x10 +0x12 +0x16
io+0x18 bne (cskip, taken) to +0x22; +0x1C..+0x21 written dry
io+0x22 mixed(2); jal x0, c+0x300 at io+0x28
c+0x300 mixed(2), then jal x0,0 (halt)
- 24 instructions execute on page u (derived from the source): 9 at u+0x10..u+0x2E, 12 at u+0x200..u+0x210, 3 at u+0x400..u+0x406. 7 execute on page io, at io+0x10..io+0x28.
- The program records the IO page's PPN in
io_ppn(tb/fe_demo_mon.svhline 160), which the monitor uses to split the uncached requests between the two pages. map4k_pbmtwith a non-zero PBMT also records the PA and VA pages inuc_ppnanduc_vpn(fe_tb_writer.svh:774-776), which the monitor reads.- The program sets the backend's eager mode (
eager = 1'b1,programs/fd18_uncached.svh:31). With nothing presented, the backend then resolves a branch that ended its block against the block the FTQ fetched after it, and commits the entry of the last retired instruction (rtl/core/frontend/fe_top/tb/models/fe_tb_backend.svh:162-191).
2. Why the program produces the behavior¶
- Uncached marking. On an ITLB hit the IFU translation queue marks
the page uncached when its effective attributes are not both
cacheable and idempotent (
rtl/core/frontend/ifu/rtl/ifu_xlate.sv:226). The ITLB passes the leaf's PBMT to the PMA check (rtl/mmu/itlb/rtl/itlb.sv:420,:435); NC is not cacheable, and IO is neither cacheable nor idempotent.xq_uccarries the mark (ifu_xlate.sv:324). - The commit gate. F0 does not match an uncached block until
commit_ptrequals its FTQ index (w_uc_gate,rtl/core/frontend/ifu/rtl/ifu_fetch.sv:278, IFU-22). Its requests carryifu_l1i_req_uncached(ifu_fetch.sv:316). - One instruction per entry. F3 delivers only the block's first valid
instruction; when more would follow (
w_uc_cut), it ends the block there withmis_valandifu_ftq_uc_end, so the FTQ redirects to the next sequential instruction, a new entry (rtl/core/frontend/ifu/rtl/ifu_f3.sv:368-373, the writeback at lines 421 to 431; the rule is described atifu_f3.sv:94-114). A JALR is delivered alone with no redirect. - No allocation. An uncached lookup is a miss whatever the tags hold
(
rtl/core/frontend/icache/rtl/l1i_ctrl.sv:229-230, L1I-24). A free MSHR register taken by an uncached request is marked not to allocate (e_alloc <= !req_uncached,rtl/core/frontend/icache/rtl/l1i_mshr.sv:486), and a fill is installed only whenfil_allocis set (l1i_mshr.sv:350-360).
3. What the monitor counts¶
The counts come from tb/fe_demo_mon.svh:540-554, sampled every cycle
while meas is set.
n_uc_req_nc ifu_l1i_req_val && ifu_l1i_req_rdy && ifu_l1i_req_uncached,
with the request's PA page not in io_ppn
an uncached request the L1I took from the NC page (one per
line requested)
n_uc_req_io the same, with the PA page in io_ppn: from the IO page
n_uc_alloc per bank b: u_l1i.u_mshr.b_fil_valid[b] and the filled
line's PA page is in W.uc_ppn
a line of an uncached page written into the array
n_uc_alloc sums the two banks of a cycle into n_ucal and adds the
sum once (DOC-002; it counted a cycle with both banks once before). It
is 0 in this run either way.
The proof (tb/fe_demo_proofs.svh:144) is
n_uc_req_nc > 0 && n_uc_req_io > 0 && n_uc_alloc == 0.
tb_fe_demo.sv also requires the whole stream to retire with no
errors.
4. Reading the numbers¶
uncached requests from the NC page 28counts lines requested, not instructions. From the run (fst2vcd onout/fd18_uncached/fd18_uncached.fst, requests withifu_l1i_req_uncachedtaken):- 14 for the 9 instructions at u+0x10..u+0x2E: the 4 in the lower half of the line request PA 0x8120_3000 alone; the 5 in the upper half (u+0x22 onward) request 0x8120_3000 and 0x8120_3040 in consecutive cycles (IFU-7);
- 11 for the 12 instructions at u+0x200..u+0x210 (line 0x8120_3200). Which instruction was served without a request of its own was not traced;
- 3 for the 3 instructions at u+0x400 (line 0x8120_3400).
from the IO page 10: the 7 instructions at io+0x10..io+0x28. The 4 in the lower half of the line request PA 0x8120_4000 alone; the 3 in the upper half (io+0x22 onward) request 0x8120_4000 and 0x8120_4040 (IFU-7). The first is at cyc 647.- The requests are about 19 to 25 cycles apart (cycles 111, 130, 149, 168, ... in the run): each waits at F0 for the previous entry to commit.
uncached lines filled 0is the proof's last term: no fill of a line of PA page 0x81203 or 0x81204.- FD-18 of
planning/showcase/fe_demo_scenarios.mdcovers NC and IO (DOC-003); the program runs both. The commit gate FD-18's waveform names isw_uc_gate, in theifu_fetchgroup withxq_uc.
5. Waveform¶
The saved view is waves/fd18_uncached.sucl, which make view
S=fd18_uncached opens in Surfer. Look at:
u_xlate.xq_ucset for the blocks on the two uncached pages, and the commit gateu_fetch.w_uc_gateopening for each block.ftq_ifu_commit_ptrreaching each uncached block'sftq_ifu_idxbefore itsifu_l1i_req_valwithifu_l1i_req_uncached.- each uncached block closing after one instruction, and the next block
starting at the next instruction (
ftq_ifu_start_pc). The writeback that closes it,ifu_ftq_mis_val, is not in this command file;waves/fd10_pd_redirect.suclshows it. - In the l1i group:
b_mis_validfor each uncached request, an MSHRe_val,l1i_mem_a_validandl1i_mem_d_valid, and nob_fil_validfor the 0x8120_3xxx or 0x8120_4xxx lines.
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 fd18_uncached runs the scenario; make view S=fd18_uncached opens its waveform in Surfer.
Files: programs/fd18_uncached.svh, waves/fd18_uncached.sucl.