Ch443f: coherent Gray readiness CDC + qualified scanout underflow detector

Harden the LPDDR scanout underflow diagnostic (Codex direction). Keeps the
Ch443e 4-buffer + lead-2 fix; adds no 5th buffer.

RTL (gs_lpddr_scanout_lb):
- Replace the raw-binary next_fetch readiness sync with a reset-aware GRAY
  code. next_fetch is monotonic between frames, so one Gray bit changes per
  increment; the 2-FF-synced + decoded nf_v is always a real prior frontier
  (monotone, burst-safe), never a torn multi-bit combination. (A plain
  toggle-per-change handshake dropped bursts when two increments landed in one
  sync window; that is why the earlier attempt under-read nf_v and false-tripped.)
  fs_edge_v overrides the lone multi-bit reset transient.
- Qualify the underflow: only a miss persisting >= QUAL_CYCLES (4) sets sticky
  underflow. uf_pmax_q records the longest streak and uf_qual_q whether any
  qualified, so a host can distinguish a 1-cycle CDC lag from a real late row.
- Atomic snapshot: scan_y/nf_v/pmax/causes/vphase/line_valid all latched the
  same video cycle on the first qualified miss.

ABI: 0x120 adds [15:12]=live pmax (2-FF synced via scan_diag_pmax_i). 0x124
[29:20] now carries pmax-at-capture (was nf_s0). Bridge dst reg kept 10-bit.

SDC: scanout diag bundle source count 37 -> 31 (nf_s0[10] -> pmax[4]); new
async-in cut + max_skew/net_delay for the next_fetch Gray CDC; stage-0 cut for
the live pmax sync.

Tests: new tb_gs_scanout_cdc_qual (async-clock focused: no false event from the
readiness transition or ordinary sync latency; sub-QUAL transient does not
qualify; genuine late row qualifies with a self-consistent atomic snapshot;
frame reset + mod-4 reuse re-arm the detector). tb_gs_scanout_diag updated for
the pmax field. Tie off scan_diag_pmax_i (+ pre-existing clut_* gap from the
fog baseline) in the four .* bridge/integration TBs.

Regressions green: scanout (cdc_qual, binomial_lookahead, diag, restart,
lpddr_scanout_lb x3), regbuf (r/aw/w), bridge + 3 pad integration TBs, and the
f52 top-level golden FB (Z 0/307200, COLOR 0/245760 mismatch, drops=0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 23:17:41 -04:00
parent 2e2c1e9ca6
commit 064484c50d
11 changed files with 418 additions and 63 deletions
+5 -3
View File
@@ -527,6 +527,7 @@ module de25_nano_psmct32_raster_demo_top (
wire scan_diag_uf_w, scan_diag_rderr_nz_w, scan_diag_valid_w;
wire [29:0] scan_diag_first_w;
wire [6:0] scan_diag_stat_w;
wire [3:0] scan_diag_pmax_w; // Ch443f — live per-frame max miss streak
// Ch320/Ch321 — LPDDR scanout frame-cache size: 256 beats (8 KiB, 64x64) by default,
// 1024 beats (32 KiB, 128x128) for the Ch321 larger-frame demo.
`ifdef GS_TILE_LPDDR128_DEMO
@@ -2681,7 +2682,7 @@ module de25_nano_psmct32_raster_demo_top (
.r(lb_r_w), .g(lb_g_w), .b(lb_b_w),
.line_valid(lb_valid_w), .underflow(lb_underflow_w), .rd_errs(lb_rd_errs_w),
.diag_rderr_nz(scan_diag_rderr_nz_w), .diag_valid(scan_diag_valid_w),
.diag_first(scan_diag_first_w), .diag_stat(scan_diag_stat_w),
.diag_first(scan_diag_first_w), .diag_stat(scan_diag_stat_w), .diag_pmax(scan_diag_pmax_w),
.araddr(lb_araddr), .arburst(lb_arburst), .arid(lb_arid),
.arlen(lb_arlen), .arsize(lb_arsize), .arvalid(lb_arvalid),
.arready(scan_ar_arready & scanout_lb_eff),
@@ -2846,7 +2847,7 @@ module de25_nano_psmct32_raster_demo_top (
assign scan_r_w=8'd0; assign scan_g_w=8'd0; assign scan_b_w=8'd0;
assign scan_cache_valid_w=1'b0; assign scan_err_w=1'b0; // no LPDDR scanout
assign scan_diag_uf_w=1'b0; assign scan_diag_rderr_nz_w=1'b0; assign scan_diag_valid_w=1'b0;
assign scan_diag_first_w=30'd0; assign scan_diag_stat_w=7'd0; // Ch442 diag tie-off (no LPDDR scanout)
assign scan_diag_first_w=30'd0; assign scan_diag_stat_w=7'd0; assign scan_diag_pmax_w=4'd0; // Ch442/443f diag tie-off (no LPDDR scanout)
assign tex_fill_done_w=1'b0; assign tex_fill_beats_w=32'd0; assign tex_fill_bytes_w=32'd0;
assign tex_rd_errs_w=32'd0; assign tex_fill_crc_w=32'd0;
assign lpddr_wr_busy_w=1'b0; assign lpddr_wr_done_w=1'b0; assign lpddr_wr_bresp_err_w=32'd0;
@@ -2868,7 +2869,7 @@ module de25_nano_psmct32_raster_demo_top (
assign scan_r_w=8'd0; assign scan_g_w=8'd0; assign scan_b_w=8'd0;
assign scan_cache_valid_w=1'b0; assign scan_err_w=1'b0; // no LPDDR scanout
assign scan_diag_uf_w=1'b0; assign scan_diag_rderr_nz_w=1'b0; assign scan_diag_valid_w=1'b0;
assign scan_diag_first_w=30'd0; assign scan_diag_stat_w=7'd0; // Ch442 diag tie-off (no LPDDR scanout)
assign scan_diag_first_w=30'd0; assign scan_diag_stat_w=7'd0; assign scan_diag_pmax_w=4'd0; // Ch442/443f diag tie-off (no LPDDR scanout)
assign tex_fill_done_w=1'b0; assign tex_fill_beats_w=32'd0; assign tex_fill_bytes_w=32'd0;
assign tex_rd_errs_w=32'd0; assign tex_fill_crc_w=32'd0;
assign lpddr_wr_busy_w=1'b0; assign lpddr_wr_done_w=1'b0; assign lpddr_wr_bresp_err_w=32'd0;
@@ -3139,6 +3140,7 @@ module de25_nano_psmct32_raster_demo_top (
.scan_diag_valid_i (scan_diag_valid_w),
.scan_diag_first_i (scan_diag_first_w),
.scan_diag_stat_i (scan_diag_stat_w),
.scan_diag_pmax_i (scan_diag_pmax_w),
// Ch322 — LPDDR write-probe (HPS stages texture words) + texture-cache fill.
.lpddr_wr_addr_o (lpddr_wr_addr_w),
.lpddr_wr_data_o (lpddr_wr_data_w),