ba74bbd5aa
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>
169 lines
8.2 KiB
Markdown
169 lines
8.2 KiB
Markdown
# 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.
|