The Ch443 board A+B diagnostic captured a WARM-UP miss, not a displayed-
frame miss: the line-buffer reader is enabled by video_src_emif
immediately, but the HDMI mux only switches to it at the next vsync, and
the diagnostic (cleared only on !enable) froze that pre-display capture.
scan_y=32/nf=32 was the expected pre-display warm-up, and line_valid is
sticky so it only meant SOME row had loaded, not that row 32 was valid.
Two fixes (all accepted Ch443 timing repairs kept: AW buffer, F_SETTLE +
drain multicycle, tile max-skew, monolithic tex_mem):
1. Per-frame diagnostic: clear diag_valid_q on fs_edge_v as well as
!enable (mirrors underflow_v). Discards the warm-up capture and
records the first miss, if any, AFTER the real frame boundary.
2. Frame-restart latency: in L_R, after the single-beat response is
accepted, if fs_pending || fs_edge_e, abandon the remainder of the
obsolete row -- no beat commit, no next old-row AR, no publish/
increment -- and return to L_IDLE, which restarts at V_SOURCE_START.
Protocol-safe (the accepted AXI transaction is complete); removes up
to a full row of restart latency during vertical blanking, so the
restarted prefetch leads the first displayed row.
New tb_gs_scanout_restart proves: mid-fetch frame-start accepts the
in-flight response, issues NO further old-row AR, restarts at row 32,
loads rows 32/33 before active consumption, and no post-restart
underflow. Regressions green: scanout_lb {,_binomial,_hstretch,
_psm32_256,_fb}, scanout_diag (per-frame), ps2_hps_bridge, and the
complete f52 replay BYTE-IDENTICAL (Z 0/307200, COLOR 0/245760).
Also commits the previously-untracked Ch443 board A+B evidence
(docs/hardware/ch443_board_validation/: verdict, 3-session raw, board
FB, RBF sha). No Quartus/board/push from here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.0 KiB
Ch443 board A+B diagnostic — verdict (zsrt139f52, 2026-07-22)
Image: retroDE_ps2.ch443.core.rbf SHA d15deb42c99212d49715335d460357dc3f2487e14cf49bd60c7ad63ba52b9990
(26.1.0 Build 110 GUI fit of commit 4358bc3; non-canonical diagnostic candidate). Canonical
retroDE_ps2.core.rbf untouched; Ch441 restored after capture.
Fit acceptance (all met)
Timing: 0 violated setup/hold paths, EMIF setup +0.177; AWREADY family absent; drain multicycle
bound (Ch443 SDC: texture drain_idx_q -> tex_mem 2-cycle setup / 1-cycle hold (16 src -> 2053 dst));
monolithic 128-M20K tex_mem; RAM 317/358 (89%), ALM 85%.
Board render
f52 replay DONE rc=0, zero drops, texture CRC 0x13cfe390 == expected, FB byte-identical to
golden (SHA d0047677…, sum32 0xaad0b94d). The AW buffer + F_SETTLE 2-cycle drain + monolithic
tex_mem are all functionally correct on silicon.
A+B diagnostic — 3 independent source-enable sessions, BIT-IDENTICAL each time
| reg | raw | decode |
|---|---|---|
| 0x02C LPDDR_STATUS | 0x000000F1 |
idle, scan_cache_valid, scan_rd_err(bit5)=1, frame_drained, clear_done |
| 0x120 SCAN_DIAG_STATUS | 0x0000003B |
valid=1, underflow=1, read-error-nonzero=0, cause_base=1, cause_lookahead=1, line_valid=1, vphase=0 |
| 0x124 SCAN_DIAG_FIRST | 0x02008020 |
scan_y=32, nf_v=32, nf_s0=32 |
VERDICT
The LPDDR_STATUS[5] 0xF1 symptom is definitively a line-buffer prefetch UNDERFLOW, NOT an AXI
read error — 0x120 shows underflow=1 with read-error-nonzero=0. This resolves the three-way
ambiguity Codex flagged: it is cause #1 (starvation-class), not cause #2 (AXI read errors).
The first failure is pinned to scan_y = 32 = V_SOURCE_START (SH3 DISPFB2.DBY=32, the first
displayed source row) — exactly the production cold-start row-32 miss predicted. nf_v = nf_s0 = 32
= next_fetch at its frame-start reset value, i.e. the prefetch had not advanced past row 32 when
row 32 was first displayed. Both cause bits assert (base + lookahead), consistent with the vertical
filter. line_valid=1 confirms the EMIF read path works — this is a first-displayed-row ordering race,
not total starvation. Deterministic across 3 independent sessions ⇒ a reproducible STRUCTURAL
first-row prefetch boundary, not a random glitch.
Caveat (per Codex) + next
A single snapshot NARROWS but does not by itself PROVE sustained starvation vs a next_fetch CDC-lag
at reset (nf_v=32 is exactly the reset value). What is now PROVEN: (a) not an AXI read error; (b) the
first miss is the cold-start row-32 boundary; (c) deterministic. Definitive starvation-vs-CDC
separation needs the deferred follow-up (gray-code next_fetch across the sync, or a 2-cycle
compare-agreement, or multi-frame captures). The FB (memory) is byte-perfect; whether this scanout
underflow produces visible HDMI top-row corruption needs an actual HDMI capture (not a memory dump).
Evidence: ch443_ab_3session_raw.txt, sh3_zsrt139f52_ch443_board_fb.mem, ch443_rbf.sha256.