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:
@@ -339,6 +339,7 @@ module ps2_hps_bridge (
|
||||
input logic scan_diag_valid_i, // first-failure captured, held to !enable (video_clk level; bundled-data valid)
|
||||
input logic [29:0] scan_diag_first_i, // SNAPSHOT {nf_s0[9:0],nf_v[9:0],scan_y[9:0]} (stable while valid -> 0x124)
|
||||
input logic [6:0] scan_diag_stat_i, // SNAPSHOT {vphase[3:0],line_valid,lookahead,base} (stable while valid -> 0x120)
|
||||
input logic [3:0] scan_diag_pmax_i, // Ch443f LIVE per-frame max miss streak (2-FF synced -> 0x120[15:12])
|
||||
|
||||
// ---- Ch322: LPDDR write-probe (HPS stages texture words) + texture-cache fill ----
|
||||
// 0x040 LPDDR_WRADDR (W): set the LPDDR byte address (auto-increments +4 per data write).
|
||||
@@ -657,6 +658,7 @@ module ps2_hps_bridge (
|
||||
logic [1:0] scan_diag_uf_sync;
|
||||
(* altera_attribute = "-name SYNCHRONIZER_IDENTIFICATION FORCED", dont_merge, preserve *)
|
||||
logic [1:0] scan_diag_rderr_sync;
|
||||
logic [3:0] scan_diag_pmax_s0, scan_diag_pmax_s1; // Ch443f — 2-FF sync of the live pmax magnitude
|
||||
(* altera_attribute = "-name SYNCHRONIZER_IDENTIFICATION FORCED", dont_merge, preserve *)
|
||||
logic [2:0] scan_diag_valid_sync; // 3-deep so the RISING synced edge latches the snapshot
|
||||
logic scan_diag_snap_valid_q; // DEST valid: set WITH payload capture, cleared on synced source-valid deassert
|
||||
@@ -954,7 +956,10 @@ module ps2_hps_bridge (
|
||||
case (addr[4:2])
|
||||
// 0x120 SCAN_DIAG_STATUS: [0]valid [1]underflow [2]read-error-nonzero
|
||||
// [3]cause_base(scan_y>=nf_v) [4]cause_lookahead [5]line_valid [11:8]filter vphase.
|
||||
3'h0: reg_read = {20'd0, scan_diag_vphase_q, 2'd0,
|
||||
// Ch443f: [15:12] = live per-frame max miss streak (pmax); [0] valid now = a
|
||||
// QUALIFIED (persistent) miss captured. Classify: valid=0 + small pmax => CDC-lag
|
||||
// transient; valid=1 / large pmax => real starvation.
|
||||
3'h0: reg_read = {16'd0, scan_diag_pmax_s1, scan_diag_vphase_q, 2'd0,
|
||||
scan_diag_lv_q, scan_diag_look_q, scan_diag_base_q,
|
||||
scan_diag_rderr_sync[1], scan_diag_uf_sync[1], scan_diag_snap_valid_q};
|
||||
// 0x124 SCAN_DIAG_FIRST: [9:0]scan_y [19:10]nf_v [29:20]nf_s0.
|
||||
@@ -1122,6 +1127,8 @@ module ps2_hps_bridge (
|
||||
lpddr_scan_err_sync <= 2'b00;
|
||||
scan_diag_uf_sync <= 2'b00;
|
||||
scan_diag_rderr_sync <= 2'b00;
|
||||
scan_diag_pmax_s0 <= 4'd0;
|
||||
scan_diag_pmax_s1 <= 4'd0;
|
||||
scan_diag_valid_sync <= 3'b000;
|
||||
scan_diag_snap_valid_q<= 1'b0;
|
||||
scan_diag_base_q <= 1'b0;
|
||||
@@ -1167,6 +1174,8 @@ module ps2_hps_bridge (
|
||||
// Ch442 — independent 2-FF syncs of the two split live flags (never the raw counter).
|
||||
scan_diag_uf_sync <= {scan_diag_uf_sync[0], scan_diag_uf_i};
|
||||
scan_diag_rderr_sync <= {scan_diag_rderr_sync[0], scan_diag_rderr_nz_i};
|
||||
scan_diag_pmax_s0 <= scan_diag_pmax_i; // Ch443f — 2-FF sync of the small live magnitude
|
||||
scan_diag_pmax_s1 <= scan_diag_pmax_s0;
|
||||
// Bundled-data capture: sync the valid, and on its RISING synced edge the snapshot
|
||||
// (held stable in the video domain since first-failure) is quiescent -> latch coherently.
|
||||
scan_diag_valid_sync <= {scan_diag_valid_sync[1:0], scan_diag_valid_i};
|
||||
|
||||
Reference in New Issue
Block a user