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>
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_qpayload registers (-0.086 ns); - one request-FIFO
raddr_qcopy 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
zsrt139f52production replay: 2,339,914 fragments fed, 2,286,292 passed Z, zero drops/overflows/AXI errors, final Z mismatch0 / 307,200, final color mismatch0 / 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, TNS0.000 ns; - 25 MHz design setup WNS
+2.387 ns, TNS0.000 ns; - reference-clock setup WNS
+8.985 ns, TNS0.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, ABI0x00000100, status0x0000001f;- HDMI initialization complete and no I2C error;
- frame counter advanced from
0x0000117cto0x00001302; - 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.