Skip to content

fb/dual-rate SDRAM: CDC request-path crossing is not timing-verified (word-granularity corruption hazard) #52

Description

@edanuff

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.

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_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

  1. Backpressure, so the request path can't tear or drop under sustained bursts.
  2. 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.
  3. Hardware acceptance test: sustained video + concurrent disk I/O (the workload that caught SDRAM correctness (fb/dual-rate): self-timed CDC request path, per-client read latch, drive_ii fetch gate #48's regression — games with hires loading while the drive runs) plus a floppy write/INIT/SAVE/power-cycle integrity check (the corruption family's own signature), on a known-good machine.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions