Files
retroDE_ps2/docs/hardware/ch443_board_validation/ch443_ab_verdict.md
T
thejayman77 846eee06b6 Ch443c: per-frame scanout diagnostic + frame-restart latency fix
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>
2026-07-22 18:10:55 -04:00

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 error0x120 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.