Ch442 review fixes: fs_edge parity, dest snap_valid, sync attrs + SDC
Codex review containment/observability fixes (no behavior change, no redesign):
- scanout_lb: add !fs_edge_v to the diagnostic predicate so capture
matches the underflow latch's frame-start CLEAR priority exactly
(no capture on an fs_edge cycle the real latch suppresses).
- bridge: expose a destination snap_valid_q as 0x120[0] — set ON the
payload-capture edge, cleared on synced source-valid deassert — so
valid never leads the bundle by a cycle (was the middle sync stage).
- bridge: forced-synchronizer (SYNCHRONIZER_IDENTIFICATION FORCED) +
dont_merge/preserve on the underflow/read-error/valid chains;
preserve on the bundle capture regs (both domains).
- SDC: stage-0 async cuts on the three sync[0] inputs + the 37-bit
stable bundle hold-false-path + 2ns max_skew + 2ns net_delay, with
fail-closed src==37 / dst!=0 count checks (tile_ram_cdc idiom).
- tb_gs_scanout_diag: +fs_edge-suppression monitor (with coverage that
the coincidence is exercised), +valid-ordering monitor, +snapshot
stability after later misses, +production DUT (V_SOURCE_START=32,
stretch, linear) proving cold-start scan_y=32, +cause/phase packing.
32/32 checks pass.
- doc: production cold start is source row 32 (not 0), base+lookahead
may both assert, and one snapshot narrows but does not prove
starvation vs next_fetch CDC-lag.
Sim set all PASS: focused TB, tb_ps2_hps_bridge, scanout_lb
{binomial,hstretch,psm32_256}, complete f52 replay (FB byte-identical
Z 0/307200, COLOR 0/245760). No Quartus, board, push, or scanout
behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -353,6 +353,44 @@ set osd_dst_n [get_collection_size $osd_cfg_dst]
|
||||
if { $osd_src_n == 0 } { post_message -type warning "Ch357 SDC WARN: osd_cfg src pattern matched 0 keepers (renamed? osd_cfg false-path NOT applied)" }
|
||||
if { $osd_dst_n == 0 } { post_message -type warning "Ch357 SDC WARN: osd_cfg dst pattern matched 0 keepers (renamed? osd_cfg false-path NOT applied)" }
|
||||
set_false_path -from $osd_cfg_src -to $osd_cfg_dst
|
||||
|
||||
# ============================================================================
|
||||
# Ch442 (Codex) — scanout A+B diagnostic CDC. gs_lpddr_scanout_lb (u_lpddr_scan_lb)
|
||||
# drives the diagnostic into ps2_hps_bridge (u_hps_bridge) across async domains:
|
||||
# (a) THREE single-bit synchronizer chains — underflow (video_clk), read-error
|
||||
# (emif_clk), valid (video_clk) — 2/3-FF (* FORCED, dont_merge, preserve *).
|
||||
# Cut the async INTO stage 0 only (setup+hold); the sync[0]->sync[1..] MTBF
|
||||
# leg stays timed. Nonzero-check WARN (the whole path is absent in non-LPDDR
|
||||
# profiles), not fatal.
|
||||
# (b) the 37-bit STABLE first-failure bundle {scan_y[10], nf_v[10], nf_s0[10],
|
||||
# vphase[4], base, lookahead, line_valid}. It is written once per enabled
|
||||
# session and held quiescent until the bridge captures it on the synced-valid
|
||||
# edge -> the raw HOLD check is false; cut HOLD only + bound bit spread
|
||||
# (set_max_skew 2ns) + bound net arrival (set_net_delay -max 2ns), same recipe
|
||||
# as the tile_ram_cdc bundle above. FATAL count checks so a rename can't
|
||||
# silently orphan the exception (src==37 exact; dst nonzero).
|
||||
foreach s {scan_diag_uf_sync scan_diag_rderr_sync scan_diag_valid_sync} {
|
||||
set s0 [get_keepers -nowarn "*u_hps_bridge|$s\[0\]"]
|
||||
if { [get_collection_size $s0] == 0 } {
|
||||
post_message -type warning "Ch442 SDC WARN: $s\[0\] matched 0 keepers (renamed / no LPDDR scanout in profile) — stage-0 cut NOT applied"
|
||||
} else {
|
||||
set_false_path -to $s0
|
||||
}
|
||||
}
|
||||
set scan_diag_src [get_keepers -nowarn {*u_lpddr_scan_lb|diag_scan_y_q[*] *u_lpddr_scan_lb|diag_nf_v_q[*] *u_lpddr_scan_lb|diag_nf_s0_q[*] *u_lpddr_scan_lb|diag_vphase_q[*] *u_lpddr_scan_lb|diag_base_q *u_lpddr_scan_lb|diag_look_q *u_lpddr_scan_lb|diag_lv_q}]
|
||||
set scan_diag_dst [get_keepers -nowarn {*u_hps_bridge|scan_diag_scan_y_q[*] *u_hps_bridge|scan_diag_nf_v_q[*] *u_hps_bridge|scan_diag_nf_s0_q[*] *u_hps_bridge|scan_diag_vphase_q[*] *u_hps_bridge|scan_diag_base_q *u_hps_bridge|scan_diag_look_q *u_hps_bridge|scan_diag_lv_q}]
|
||||
set scan_diag_src_n [get_collection_size $scan_diag_src]
|
||||
set scan_diag_dst_n [get_collection_size $scan_diag_dst]
|
||||
if { $scan_diag_src_n == 0 } {
|
||||
post_message -type info "Ch442 SDC: scanout diagnostic CDC inactive in this profile (0 src -> no LPDDR scanout)"
|
||||
} else {
|
||||
if { $scan_diag_src_n != 37 } { error "Ch442 SDC FATAL: scanout diag bundle source count $scan_diag_src_n != 37 (10+10+10+4+1+1+1; renamed/optimized? hold cut + net_delay would orphan)" }
|
||||
if { $scan_diag_dst_n == 0 } { error "Ch442 SDC FATAL: scanout diag bundle dest u_hps_bridge|scan_diag_*_q EMPTY (renamed? hold cut would orphan)" }
|
||||
set_false_path -hold -from $scan_diag_src -to $scan_diag_dst
|
||||
set_max_skew -from $scan_diag_src -to $scan_diag_dst 2.0
|
||||
set_net_delay -max -from $scan_diag_src -to $scan_diag_dst 2.0
|
||||
post_message -type info "Ch442 SDC: scanout diag bundle hold-false-path + 2ns max_skew + 2ns net_delay ($scan_diag_src_n src -> $scan_diag_dst_n dst)"
|
||||
}
|
||||
post_message -type info "Ch357 SDC: osd_cfg refclk->design_clk synchronizer false-path ($osd_src_n src -> $osd_dst_n stage0 dst)"
|
||||
|
||||
# Ch357 (Codex) — OSD MENU-STATE synchronizers (same quasi-static class as osd_cfg): cursor_row + osd_active cross
|
||||
|
||||
Reference in New Issue
Block a user