Files
retroDE_ps2/docs/ch436_linear_scanout_prefit.md
T
thejayman77 ba74bbd5aa Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder
XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog
TBs, fidelity attribution tooling. Functional baseline before removing the dead
bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 19:56:46 -04:00

8.2 KiB

Ch436 — vertical-linear authentic-display reconstruction prefit

Root cause

The accepted Ch435 framebuffer is byte-identical between production RTL and the DE25, and its mean RGB is already close to the PCSX2 frame. The remaining high-frequency defect is also present in the independent software reconstruction, so it is not a board-transfer or framebuffer-write error.

The Ch418 presentation path reduced the captured 512x448 display to the board's 640x480 raster with nearest-neighbour selection:

  • source_x = floor(output_x * 4 / 5);
  • source_y = 32 + floor(output_y * 14 / 15).

That repeats source samples at both axes and exposes the already-granular base scene more harshly than linear display reconstruction.

RTL correction

gs_lpddr_scanout_lb now optionally uses the existing 15-state vertical presentation phase as the exact interpolation numerator. It reads the current and already-prefetched next row from the two alternating line buffers. This adds no LPDDR traffic, line-buffer storage, or scheduler/render ordering change.

The AXI prefetch side is notified of a source-row advance during horizontal blanking. This gives it the full blank interval to refill the retired parity buffer before the next active line requires the adjacent row. The directed test explicitly models that interval and checks all 600 samples against the same rounded separable equations as RTL, with zero errors or underflow.

Legacy profiles retain nearest/1:1 behavior through a default-off parameter. Only the full-frame SH3 profile enables vertical linear reconstruction. Horizontal presentation retains the proven Ch418 nearest mapper.

An initially simulated horizontal-linear extension duplicated the line-buffer storage to obtain an x+1 read port. Quartus implemented those mirrors as 30,720 registers instead of M20Ks, making the design require 6,270 LABs on a 4,680-LAB device. That architecture was removed completely before this prefit candidate; none of the mirrored arrays or horizontal blend logic remain.

Measured preview and regression evidence

On the accepted Ch435 board framebuffer, the exact RTL presentation model improves the PCSX2 comparison from nearest MAE/RMSE 14.7226/22.3097 to 14.2678/21.3085. Mean RGB remains effectively unchanged at (26.38, 23.33, 21.19), so this is a spatial reconstruction improvement, not a brightness retune.

Passing directed regressions:

  • tb_gs_lpddr_scanout_lb_hstretch: 600 checked, zero errors, zero underflow;
  • tb_gs_lpddr_scanout_lb: pass;
  • tb_gs_lpddr_scanout_lb_psm32: 49,152 checked, zero errors/underflow;
  • tb_gs_lpddr_scanout_lb_psm32_256: 196,608 checked, zero errors/underflow.

The framebuffer itself remains unchanged by construction, so the existing Ch435 22-epoch native-FBMSK and 311-epoch full-scene scoreboards remain the render-data acceptance baselines. The next owner GUI fit must establish RAM cost and signoff timing before board deployment.

First owner fit — resources recovered, narrow EMIF setup miss

The vertical-only candidate fit successfully and recovered the exact Ch435 memory/DSP budget: 5,327,792 block-memory bits, 344 / 358 RAM blocks, and 160 / 376 DSPs. The 25 MHz presentation domain was comfortably clean at +4.611 ns; hold, recovery, removal, and minimum-pulse checks were also clean.

The RBF is not deployable because EMIF setup finished at -0.086 ns. The actual post-fit top paths contained two unrelated 310 MHz routing families:

  • the high-fanout synchronized EMIF calibration reset driving duplicated texture-cache drain_idx_q payload registers (-0.086 ns);
  • one request-FIFO raddr_q copy driving the complete 93-bit by 16K physical RAM address network (-0.073 ns / -0.062 ns).

Neither path contains the vertical filter or its 25 MHz arithmetic. This is therefore a structural timing repair, not a presentation rollback or another placement-only reroll.

First timing-repair fit — rejected RAM banking

The texture fill's selected word/index boundary is now control-free and unreset. F_WRITE is reachable only after F_DRAIN has loaded both payload registers, so their reset values were unobservable; removing reset eliminates the EMIF calibration-reset launch family without changing fill ordering.

The first repair also split the production request memory into three explicit 31-bit by 16K banks. Although the logical storage remained 1,523,712 bits, each bank rounded up to 25 physical M20Ks. The request memory therefore used 75 blocks instead of the packed macro's 59, raising the complete design from 344 to 360 / 358 blocks. Fitter correctly rejected it before routing. This banked-memory architecture has been removed completely.

Current zero-RAM-cost compile candidate

The request FIFO is back to its original single packed 93-bit by 16K memory, restoring the proven 59-block request-macro shape and expected 344 / 358 total RAM budget. Its existing unreset RAM-facing raddr_q now carries a maxfan=64 synthesis directive. Quartus therefore duplicates only the address launch register as needed; the storage remains one efficiently packed memory and the pointer/read latency are unchanged.

Verification after both cuts:

  • asynchronous FIFO: 3,284 writes/reads exact, zero errors;
  • texture cache: 64 words exact, refill error injection exact;
  • Z/color emitter: 1,500 fragments across three epochs, zero errors;
  • complete 311-epoch zsrt139f52 production replay: 2,339,914 fragments fed, 2,286,292 passed Z, zero drops/overflows/AXI errors, final Z mismatch 0 / 307,200, final color mismatch 0 / 245,760;
  • framebuffer SHA-256 remains exactly d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b, byte-identical to both accepted Ch435 board dumps;
  • relevant git diff --check: PASS.

This zero-RAM-cost RTL is ready for a new owner-controlled Quartus 26.1 GUI compile. Acceptance requires all timing classes nonnegative, the request FIFO to return to the 59-block packed macro / 344-block total design budget, and the retired reset-to-drain_idx_q / high-fanout request-address families to be absent. Do not deploy either prior Ch436 RBF.

Accepted fit

The owner-controlled Quartus 26.1 GUI compile completed successfully on 2026-07-19. The packed request-memory shape and the complete Ch435 memory/DSP budget were restored. All timing classes are nonnegative:

  • EMIF setup WNS +0.050 ns, TNS 0.000 ns;
  • 25 MHz design setup WNS +2.387 ns, TNS 0.000 ns;
  • reference-clock setup WNS +8.985 ns, TNS 0.000 ns;
  • hold minimum 0.000 ns, with zero TNS;
  • recovery minimum +1.054 ns;
  • removal minimum +0.163 ns;
  • minimum-pulse-width minimum +0.200 ns.

Final resources are 38,522 / 46,800 ALMs (82%), 5,327,792 / 7,331,840 block-memory bits (73%), 344 / 358 RAM blocks (96%), and 160 / 376 DSPs (43%). Quartus explicitly ignored the maxfan directive because every load is a RAM address. The request-address family remains the clean EMIF limiter at +0.050 ns; the reset-to-drain_idx_q family is absent. Closure therefore comes from the valid reset cut and the resulting legal placement, not from a claimed address-register duplication.

The accepted RBF is 4,100,096 bytes with SHA-256 1c8945e3e8ad85d91a682aa7a068cee487a1459a7f2b899600b24ff7d9751294.

Hardware acceptance

The RBF checksum was verified on the DE25-Nano, the accepted Ch435 image was preserved as retroDE_ps2.pre_ch436.core.rbf, and core_loader.sh loaded the new artifact successfully with fpga0: operating. Live preflight passed:

  • CORE_ID=0x50533200, ABI 0x00000100, status 0x0000001f;
  • HDMI initialization complete and no I2C error;
  • frame counter advanced from 0x0000117c to 0x00001302;
  • raster-overflow count remained zero.

The complete 311-epoch zsrt139f52 scene then passed every texture CRC, runtime-palette sum, staged-record count, fresh-drain, and zero-fragment-drop gate. The scheduler dumped all 307,200 framebuffer words and ended DONE rc=0. Board SHA-256 is d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b, byte-identical to the complete production simulation and both accepted Ch435 board dumps. HDMI is live on the Ch436 vertical-linear presentation of that accepted f52 framebuffer. Ch436 is timing-, simulation-, and hardware-accepted.