You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Splitting out the still-open half of #48 as a tracking issue. The storage-port fixes from that PR (per-client read latch + drive_ii fetch-completion gate) landed in main via #51; this issue captures the remaining, unfixed hazard so it isn't lost.
The hazard
In the dual-rate build, hdl/sdram/mem_port_cdc.sv re-registers the full ~60-bit request tuple {addr, data, byte_en, wr, rd, burst} across the 54 MHz → 108 MHz crossing on a single fast-domain edge. The dual-rate SDC (boards/a2n20v2-Enhanced/a2n20v2_enhanced_dualrate.sdc) declares set_false_path in both directions between clk_logic and clk_sdram, so the ~18.5 ns routing budget the module's own header assumes is never verified by any tool — correctness rests on unconstrained routing luck. One address bit routed slow lets the 108 MHz capture mix that bit from the previous request on the port, sending a read/write one word off or into another client's region.
Fingerprint match: produces corruption at exactly 32-bit-word granularity, matches the write-back corruption previously observed on hardware (the reason mount_hdd forces read-only; comment introduced in 85004ab, the same commit that added the VIDEO_FRAMEBUFFER/dual-rate config). PnR-seed-dependent routing explains "deterministic per build, symptom shifts when the build changes."
Scope: dual-rate/fb only. The single-clock classic build has no such crossing.
The response path is already gray-pointer-safe; only the request path is exposed.
#48 replaced the request crossing with a 4-entry gray-pointer FIFO (self-timed atomicity). It was timing-clean on all variants, but failed hardware verification with video artifacts — because mem_port_cdc is shared by every logic-domain port including the video/framebuffer fetches, and the added per-request latency + assert/gap shaping pushed the known-tight video prefetch (see the PIXEL_START_TICK line-priming history) past its deadline. set_max_delay was rejected on the SDC's own recorded evidence that it squeezes Fmax to ~0.3% margin and destabilizes SDRAM. Detail in #48 and its FAIL comment.
Requirements for a correct fix
Backpressure, so the request path can't tear or drop under sustained bursts.
A latency budget derived from the video prefetch timing — any added crossing latency must stay within the framebuffer fetch deadline. This is the constraint the FIFO approach violated.
Splitting out the still-open half of #48 as a tracking issue. The storage-port fixes from that PR (per-client read latch + drive_ii fetch-completion gate) landed in main via #51; this issue captures the remaining, unfixed hazard so it isn't lost.
The hazard
In the dual-rate build,
hdl/sdram/mem_port_cdc.svre-registers the full ~60-bit request tuple{addr, data, byte_en, wr, rd, burst}across the 54 MHz → 108 MHz crossing on a single fast-domain edge. The dual-rate SDC (boards/a2n20v2-Enhanced/a2n20v2_enhanced_dualrate.sdc) declaresset_false_pathin both directions betweenclk_logicandclk_sdram, so the ~18.5 ns routing budget the module's own header assumes is never verified by any tool — correctness rests on unconstrained routing luck. One address bit routed slow lets the 108 MHz capture mix that bit from the previous request on the port, sending a read/write one word off or into another client's region.mount_hddforces read-only; comment introduced in 85004ab, the same commit that added the VIDEO_FRAMEBUFFER/dual-rate config). PnR-seed-dependent routing explains "deterministic per build, symptom shifts when the build changes."Why the first attempt (#48) failed
#48 replaced the request crossing with a 4-entry gray-pointer FIFO (self-timed atomicity). It was timing-clean on all variants, but failed hardware verification with video artifacts — because
mem_port_cdcis shared by every logic-domain port including the video/framebuffer fetches, and the added per-request latency + assert/gap shaping pushed the known-tight video prefetch (see the PIXEL_START_TICK line-priming history) past its deadline.set_max_delaywas rejected on the SDC's own recorded evidence that it squeezes Fmax to ~0.3% margin and destabilizes SDRAM. Detail in #48 and its FAIL comment.Requirements for a correct fix
References
pr/fb-sdram-correctnessretained on the edanuff fork for the analysis and the failed approach)