# Ch443d board verdict — per-frame scanout diagnostic (zsrt139f52, 2026-07-23) Image: `retroDE_ps2.ch443d.core.rbf` SHA `87c382f1...` (26.1 GUI compile of `0c9b2bf` = `6319d7c` RTL + SEED 3). Non-canonical candidate; Ch441 restored after capture. ## Fit + render (accepted) Seed-3 GUI compile: EMIF setup +0.132, all timing classes >=0, 0 violated, no AWREADY/texcache-fill/drain/scanout-diag families, RAM 317/358. Board f52 replay byte-identical to golden (FB `d0047677`, texture CRC `0x13cfe390`, 0 drops). ## Per-frame diagnostic (8 samples over many displayed frames, stable) | reg | raw | decode | |-----|-----|--------| | 0x02C | `0xF1` | scan underflow (bit5)=1, bresp=0 | | 0x120 | `0x0D33` | valid=1, **underflow=1**, **read-error=0**, cause_base=**0**, **cause_lookahead=1**, line_valid=1, **vphase=13** | | 0x124 | `0x02208821` | **scan_y=33, nf_v=34, nf_s0=34** | ## VERDICT — the REAL displayed-frame failure (NOT the warm-up, NOT a read error) The Ch443c per-frame clear + restart-latency fix worked as intended: the pre-display warm-up capture (previously scan_y=32/nf=32/base) is GONE. The diagnostic now reports the true steady-state failure, and it is a **vertical LINEAR-FILTER LOOKAHEAD starvation**: - scan_y=33 is resident (33 < nf_v=34 -> base cause correctly 0). - At vphase=13 the V_LINEAR_FILTER interpolates between source rows 33 and 34, so it needs the LOOKAHEAD row scan_y+1 = 34. But nf_v=34 means next_fetch is AT row 34 -> row 34 is being fetched, NOT yet resident -> `scan_y+1 >= nf_v` -> lookahead cause fires -> underflow. - read-error=0: not an AXI error. Deterministic every frame: structural, not a CDC glitch. Root cause: the prefetch throttle leads by exactly ONE row (`next_fetch <= disp_row+1`), but the vertical linear filter needs the lookahead row (disp_row+1) FULLY resident. The prefetch is one row short of the filter's requirement, so displaying row 33 while row 34 is still loading races the filter's read of row 34. ## Open question + fix direction (for Codex) - Leading by 2 (`disp_row+2`) would make the lookahead row resident in time, but V_LINEAR uses only 2 line buffers (parity) -- disp_row and disp_row+2 share a buffer, so leading by 2 needs a 3rd line buffer (as BINOMIAL already has) or a different prefetch/latency structure. - The FB (memory) is byte-perfect; whether this lookahead underflow is HDMI-VISIBLE (a subtle artifact at inter-row filter boundaries) needs an actual HDMI capture -- the flag is conservative (fires when the lookahead row's fetch is in-flight, which may still complete before the specific pixels are read). Evidence: `ch443d_perframe_diag_8samples.txt`, `sh3_zsrt139f52_ch443d_board_fb.mem`, `ch443d_rbf.sha256`.