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>
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
# Ch353 audit log — full SH3 draw on an LPDDR-only direct PSMCT32 framebuffer
|
||||
|
||||
Purpose: complete, auditable trail of every change + verification for Codex review.
|
||||
Scope (Codex-approved): **Path A — LPDDR-only direct PSMCT32 framebuffer**, replacing the 256×120 BRAM crop with
|
||||
the full 256×334 draw bounding box rendered to LPDDR and scanned out. Path B (tile-spill) deferred.
|
||||
Labeling note (Codex): this is the **uncropped draw bounding box at origin**, NOT the full SH3 game framebuffer.
|
||||
|
||||
## Numbers (pre-edit, reported to Codex)
|
||||
- dump 224139, `full_h = 334`; full frame **256 × 334 PSMCT32** = 342,016 B = **334 KiB** (0x53800) = **10,688** 256-bit beats.
|
||||
- row stride 1024 B. LPDDR ranges (disjoint): **FB 0x000000..0x053800 (334 KiB)**; **TEX 0x200000..0x240000 (256 KiB)**.
|
||||
- 334 KiB > 128 KiB BRAM and > 256 KiB read2 cap → LPDDR required.
|
||||
|
||||
---
|
||||
|
||||
## Brick 1a — widen `gs_lpddr_axi_master` to PSMCT32 + end-of-scene flush [DONE, verified]
|
||||
|
||||
RTL: `rtl/gif_gs/gs_lpddr_axi_master.sv`
|
||||
- Added `parameter int PIX_BYTES = 2` (2 = PSMCT16 default, byte-identical to Ch318; 4 = PSMCT32).
|
||||
- Derived: `PIX_BITS = PIX_BYTES*8`, `LANE_LO = (PIX_BYTES==4)?2:1`, `STRB1 = '1` (per-pixel byte-strobe mask).
|
||||
- Generalized the packer: `lane = px_addr[4:0]>>LANE_LO`; data shift `lane*PIX_BITS`; strobe `lane*PIX_BYTES` wide.
|
||||
The `&ns` beat-complete test is UNCHANGED (a full 32-byte beat is always 32 strobe bits either way).
|
||||
- Port `px_pix16[15:0]` → `px_pix32[31:0]` (PSMCT16 callers drive `{16'd0, pix16}`).
|
||||
- New input `flush`: end-of-scene partial-beat flush — sparse triangle coverage won't fill every beat; pulse it
|
||||
after the last `px_emit` to push the dangling partial beat. PSMCT16 tile path ties it to 0 (tile-rows always
|
||||
complete beats). Branch: `else if (enable && arm_gs && flush && has_data)` pushes `{cur_addr,cur_data,cur_strb}`.
|
||||
|
||||
Callers updated: `rtl/top/de25_nano_psmct32_raster_demo_top.sv` (2 instantiations) → `.px_pix32({16'd0, demo_flush_pix16}), .flush(1'b0)`.
|
||||
|
||||
TB: `sim/tb/gif_gs/tb_gs_lpddr_axi_master.sv` — PSMCT16 instantiations updated; added a PSMCT32 DUT (`PIX_BYTES=4`)
|
||||
with an always-ready capturing slave + tests: 8 px → 1 full beat; 5 px + flush → 1 partial beat; unstrobed lanes 5–7
|
||||
untouched. Result: `[axi32] PSMCT32 ok ...`, `[axi] DISARMED/CANARY/STABILITY ok` (PSMCT16 byte-identical), **PASS**.
|
||||
|
||||
**Verification:** full regression **272 PASS / 0 FAIL** (writer touches the de25 top, so regression confirms nothing broke).
|
||||
|
||||
---
|
||||
|
||||
## Brick 1c — LPDDR-only direct-FB proof [DONE, verified]
|
||||
|
||||
Recon finding (big de-risk): the bram-top ALREADY has the pieces — no new bram-top logic:
|
||||
- `FB_LPDDR_ONLY` (Ch326, `top_psmct32_raster_demo_bram.sv:1170`): `vram_we_pre = xfer_busy ? xfer_we : (raster_pixel_emit && !FB_LPDDR_ONLY)` — suppresses the BRAM raster mirror, keeps xfer/CLUT writes. = Codex's "suppress raster, keep CLUT".
|
||||
- `flush_color32_o`/`flush_addr_o`/`flush_emit_o`/`flush_psm_o` (Ch323): the full PSMCT32 raster stream, already exposed.
|
||||
- `feeder_ready_o` (C_READY): render-done, for the flush pulse.
|
||||
|
||||
TB: `sim/tb/top/tb_top_psmct32_sh3_lpddr_fb.sv` (NEW; Makefile target added; dump-derived, NOT in regression):
|
||||
- bram-top with `FB_LPDDR_ONLY=1`; the exposed PSMCT32 stream (gated `flush_psm_o==6'h00`) drives
|
||||
`gs_lpddr_axi_master#(.FIFO_DEPTH(64),.PIX_BYTES(4))` → a behavioral, strobe-honouring LPDDR FB.
|
||||
- Separate faster `axi_clk2` (#2 vs design #5) models the board's emif_clk and exercises the real async-FIFO CDC.
|
||||
- "ideal" frame captured straight off the raster stream; PROOF asserts LPDDR == ideal for every emitted pixel.
|
||||
- End-of-scene `flush` pulse + a STABLE-idle drain gate before asserting.
|
||||
|
||||
**Verification:** `[fbproof] covered=14730 words, mismatches=0, writer beats=5572` → **PASS** (cropped 256×120 data;
|
||||
full-frame is a fixture swap, Brick 1b).
|
||||
|
||||
Two findings worth auditing:
|
||||
1. Same-clock drain can't keep up with line-change-flush bursts → use a faster AXI clock (board emif_clk is ~12×
|
||||
faster, drains fine) + `FIFO_DEPTH=64`. (No RTL backpressure added; the board clock ratio makes it unnecessary.)
|
||||
2. **Drain gate must be STABLE-idle**: a single `idle` sample RACES the async-FIFO CDC (flush-pushed beat's gray
|
||||
pointer needs ~2 axi cycles to cross; `fifo_rempty` reads empty meanwhile) → asserted before the last overdraw
|
||||
pixel drained (1 stranded pixel). Fix: settle + require idle for 8 consecutive cycles. **This validates Codex's
|
||||
"gate scanout on render-done AND writer-drained/B-response" — the board gate must be stable-idle, not transient.**
|
||||
|
||||
---
|
||||
|
||||
## Brick 1b — full-frame fixture (256×334) + re-run proof [DONE, verified]
|
||||
|
||||
Tooling: `tools/gs_make_sh3_real_draw_fixture.py` — added `--full-frame`:
|
||||
- `global CH`; after the crop search, `if full_frame: CH=full_h; CY0=0; CX0=0` (render the whole 256×334 bounding box).
|
||||
- Crop-dependent outputs written with a `tag` (`full` vs `real`): `feeder_sh3_{tag}.mem`, `sh3_{tag}_params.vh`,
|
||||
`sh3_{tag}_refmap*.mem`, `bios_sh3_{tag}.mem`, `payload_sh3_{tag}.mem`. Shared texture/CLUT/idx/pal stay `sh3_real_*`.
|
||||
→ the Ch352 cropped build (`sh3_real_*`) is byte-untouched.
|
||||
- CBP stays 480 (CLUT in BRAM; with FB_LPDDR_ONLY the FB is in LPDDR so it doesn't collide). CLUT→0 relocation is
|
||||
deferred to Brick 3 (a fit-side BRAM-shrink optimization, not needed for the sim proof).
|
||||
|
||||
Verification:
|
||||
- default run → `sh3_real_*` FBH=120/CY0=188 (unchanged); `--full-frame` → `sh3_full_*` FBH=334/CY0=0.
|
||||
- **Cropped oracle still bit-identical: `tb_top_psmct32_sh3_real_draw_demo` 96.2% PASS** (Ch352 build intact).
|
||||
- proof TB: `\`ifdef SH3_FULL_FRAME` selects `sh3_full_params.vh`; Makefile target `tb_top_psmct32_sh3_lpddr_fb_full`
|
||||
points BIOS/PAYLOAD/FEEDER at the `_full` files.
|
||||
- **Full-frame proof: `[fbproof] covered=16571 words, mismatches=0, writer beats=6502` → PASS.**
|
||||
|
||||
## Status: Brick 1 (render to LPDDR) COMPLETE + verified at full frame (16571 px, 0 mismatches).
|
||||
|
||||
---
|
||||
|
||||
## Codex audit corrections (all 5 resolved before Brick 2)
|
||||
|
||||
**#1 (High) — full-frame oracle distinction.** The transport proof (LPDDR == raster-captured ideal) proves *transport*,
|
||||
not *render correctness*. Added the full-frame equivalent of the bounded oracle to the proof TB: loads the reference
|
||||
texel map (`sh3_{tag}_refmap.mem`) + palette/indices, scores the rendered frame `<=1 texel` (same acceptance as
|
||||
`tb_top_psmct32_sh3_real_draw_demo`). Cropped reads **96.2% / INT 97.5% / clut_bad=0 — EXACTLY matching the standalone
|
||||
oracle**; full-frame **96.1% / INT 97.6% / clut_bad=0**. (Also init `ideal[]`=0 to model the Brick-3 FB preclear, so
|
||||
refmap-covered-but-unrendered edge pixels read as the cleared color, not X.)
|
||||
|
||||
**#2 (High) — production-safe drain ack (replaces the stable-idle heuristic).** `gs_lpddr_axi_master`: FIFO word
|
||||
widened to 321 (marker bit). A `flush` now pushes any partial beat **then an ordered EOF marker**; the AXI FSM sets a
|
||||
new `frame_drained` output when it POPS the marker — which, by the in-order FIFO + per-beat B handshake, happens only
|
||||
AFTER the last data beat's BRESP. Coherent in the axi domain (no GS-domain `idle` sampling, no pointer-in-flight race).
|
||||
The proof TB now waits on `frame_drained` (a stable level), not the heuristic. PSMCT16 path byte-identical (flush tied 0).
|
||||
|
||||
**#3 (Medium) — PSMCT32 AXI backpressure.** `tb_gs_lpddr_axi_master`: the PSMCT32 DUT now has LFSR AW/W backpressure +
|
||||
a delayed B response; asserts full beat + partial-flush survive stalls, **ovf=0, bresp_err=0**, and the ordered drain
|
||||
ack fires. PASS.
|
||||
|
||||
**#4 (Medium) — tagged generated PNGs.** `gs_make_sh3_real_draw_fixture.py` now writes `sh3_{tag}_ref.png`; the stale
|
||||
idx8 recip render is written as `STALE_idx8_sh3_{tag}_ref_recip.png` (clearly marked). A `--full-frame` run no longer
|
||||
clobbers crop references; restored the crop `sh3_real_ref.png` (256×120) and created `sh3_full_ref.png` (256×334).
|
||||
|
||||
**#5 (Hygiene) — gitignore.** Added `/synth/**/tmp-clearbox/`, `/synth/**/sta_*.txt`, `*.tdf` so STA scratch +
|
||||
clearbox temp are excluded from the next commit (the committed tmp-clearbox is already pending-deleted on disk).
|
||||
|
||||
## Verification (post-corrections)
|
||||
- `tb_gs_lpddr_axi_master` PASS (PSMCT16 byte-identical, PSMCT32 + backpressure, ordered ack).
|
||||
- `tb_top_psmct32_sh3_lpddr_fb` (cropped) PASS: transport 0 mism + oracle 96.2%/97.5%/clut_bad=0.
|
||||
- `tb_top_psmct32_sh3_lpddr_fb_full` (256×334) PASS: transport 0 mism + oracle 96.1%/97.6%/clut_bad=0.
|
||||
- Cropped oracle `tb_top_psmct32_sh3_real_draw_demo` still 96.2% PASS (Ch352 build intact).
|
||||
- Full regression: re-running to confirm the writer-width/marker change stays green.
|
||||
|
||||
## Codex audit round 2 (two real items + integration note)
|
||||
|
||||
**(High) EOF/partial dropped when FIFO full.** The flush branches cleared `has_data`/`flush_pending` on scheduling
|
||||
`fifo_wr`, but the FIFO write is `fifo_wr && !fifo_wfull` — if full, the partial/marker vanished. Fix in
|
||||
`gs_lpddr_axi_master`: (a) gate the flush branches on `!fifo_wfull` so state is RETAINED (retried) until accepted;
|
||||
(b) `fifo_wfull` is REGISTERED (asserts 1 cycle after the FIFO fills), so the partial push could make the FIFO full
|
||||
while the marker branch still saw stale `!wfull` and fired early → its write then dropped. Added a 1-cycle `flush_gap`
|
||||
between the partial and marker pushes so `wfull` reflects the partial's write first. **Saturation test added**
|
||||
(`tb_gs_lpddr_axi_master`): hold AXI fully off until the FIFO is full, flush, release → asserts the partial beat
|
||||
survives, `frame_drained` asserts only after release/BRESP, EOF never popped while stalled. PASS.
|
||||
|
||||
**(Hygiene) tracked tmp-clearbox deletions.** `git rm --cached` on the 51 tracked `tmp-clearbox/*.tdf` files (gitignore
|
||||
only affects untracked) → now 0 tracked, 51 staged deletions; the next commit removes them. No other STA/tdf scratch
|
||||
tracked.
|
||||
|
||||
**Integration note (Codex, for Brick 2).** `frame_drained` is coherent in the AXI/EMIF domain — Brick 2's scanout
|
||||
gate must consume it THERE (gs_lpddr_scanout* run on emif_clk). Any design-clock use needs a synchronizer. The proof
|
||||
TB's direct cross-domain poll of `frame_drained`/`fbw_idle` is sim convenience, not a hardware CDC.
|
||||
|
||||
## Codex audit round 3 (enqueue edge case)
|
||||
|
||||
**(High) a prior NORMAL `fifo_wr` leaves `fifo_wfull` stale at a flush branch.** Cases: a scene ending on a full
|
||||
beat (no partial), or a partial right after a line-change push — the previous registered `fifo_wr` is consuming the
|
||||
final slot, so the flush branch's `!fifo_wfull` check is stale. The round-2 `flush_gap` only covered partial→marker.
|
||||
Fix: gate BOTH flush enqueue branches on **`!fifo_wr && !fifo_wfull`** — no push in flight AND not full, so the
|
||||
`!wfull` check is accurate; state is retained/retried until accepted. This also subsumes the partial→marker gap
|
||||
(the marker waits for the partial's `fifo_wr` to clear and `wfull` to settle), so `flush_gap` was removed.
|
||||
|
||||
**NEAR-FULL test added** (`tb_gs_lpddr_axi_master`): scene ends on a FULL beat, no partial, flush immediately after the
|
||||
final normal beat under a saturated FIFO → the EOF marker survives and `frame_drained` asserts only after release/BRESP.
|
||||
PASS (alongside the saturation test).
|
||||
|
||||
## Verification (round 2)
|
||||
- `tb_gs_lpddr_axi_master` PASS (+ saturation: FIFO-full flush, partial+EOF retained, frame_drained after BRESP).
|
||||
- both proofs still PASS (cropped 96.2%/clut_bad=0; full-frame 96.1%/clut_bad=0; transport 0 mism).
|
||||
- full regression re-running (writer gap fix).
|
||||
|
||||
Remaining (Brick 2 / 3): PSMCT32 line-buffer scanout proof (`gs_lpddr_scanout_lb` already PSMCT32, reads the LPDDR FB
|
||||
back out, gated on `frame_drained` IN THE EMIF DOMAIN); board (HPS preclear, static line-buffer scanout, CLUT→CBP 0 to
|
||||
shrink BRAM, fit).
|
||||
|
||||
## Brick 2 — PSMCT32 LPDDR-FB line-buffer scanout proof (`tb_gs_lpddr_scanout_fb`)
|
||||
|
||||
Full write→read loop: the Ch353 writer (`gs_lpddr_axi_master #(.PIX_BYTES(4))`) fills a behavioral 256×334 PSMCT32 FB
|
||||
(STRIDE=1024B, ROW_BEATS=32, BEATS_PER_FRAME=10688) → `frame_drained` → `gs_lpddr_scanout_lb #(.STRIDE_BYTES(1024),
|
||||
.ROW_BEATS(32),.N_ROWS(334),.PSMCT32(1))` with `enable=frame_drained` reads the FB back → video raster serves r/g/b →
|
||||
compared against `exp_word(x,y)`. Three independent clocks (gs #5 / emif #2 / video #7). Real cadence: H_BP=32/H_FP=8,
|
||||
V_BP=16/V_FP=8; active-relative px/py; `in_win`/`vsync` gating. FB precleared to 0 (models HPS preclear). Read model
|
||||
has variable AR/R latency (LFSR). All 256×334 pixels compared **including the x≥128 black half**.
|
||||
|
||||
Codex acceptance gates — all met:
|
||||
- **All pixels correct incl. black**: `errors=0` (checked=105968 ≥ 256×334 active).
|
||||
- **underflow=0** (row always ready before its pixel — required the vertical/horizontal back porch so the prefetch
|
||||
leads the display; the first run without a back porch raced and asserted underflow).
|
||||
- **rd_errs=0** (no read-response errors).
|
||||
- **valid through the final row**: `checked ≥ H_ACT*V_ACT`.
|
||||
- **frame_drained gate consumed in the EMIF domain** (scanout runs on emif_clk).
|
||||
|
||||
Read-beats/frame: measured in the **EMIF domain** per prefetch frame (counter reset on the emif-synced vsync rising
|
||||
edge) = **10720 = 334 rows + 1 row re-fetched at the vblank boundary**. Root cause (a real scanout behavior, not a TB
|
||||
bug): the scanout's `fs_edge_e` is a *both-edge* detector, so a 1-cycle vsync pulse fires two prefetch resets
|
||||
(rising+falling), re-fetching row 0 once. Harmless — every row is read correctly (pixels match). The TB accepts 10688
|
||||
(ideal) OR 10720 (+1 boundary row) and hard-fails anything else. **FLAG FOR CODEX:** is the exact-10688 gate strict, or
|
||||
is the ~1-row/frame vblank-boundary re-fetch acceptable (it wastes 32 beats/frame ≈ 0.3% of read bandwidth)? If it must
|
||||
be exactly 10688, the fix is on the scanout/top side (drive frame_start so the both-edge doesn't double-reset), not the
|
||||
proof.
|
||||
|
||||
Result: `tb_gs_lpddr_scanout_fb` **PASS**; added to both `sim/Makefile` master run lists.
|
||||
|
||||
Remaining (Brick 3 / board): HPS preclear FB, static line-buffer scanout wired at the de25 top, CLUT→CBP 0 to shrink
|
||||
BRAM, fit.
|
||||
|
||||
## Codex round 4 — beat-count fix (production RTL) + Brick 3 start-ordering gate
|
||||
|
||||
**(Resolved) both-edge → rising-edge in `gs_lpddr_scanout_lb`.** The 10720-vs-10688 was a real production-RTL issue,
|
||||
not test noise. Both frame-start edge detectors were both-edge:
|
||||
- `fs_edge_v` (video domain, line 88): `fs_sync_v[2] != fs_sync_v[1]` → `fs_sync_v[1] && !fs_sync_v[2]`
|
||||
- `fs_edge_e` (emif domain, line 132): `fs_sync_e[2] != fs_sync_e[1]` → `fs_sync_e[1] && !fs_sync_e[2]`
|
||||
A 1-cycle `frame_start` pulse fired rising+falling → two prefetch resets → row 0 re-fetched once. Rising-edge only =
|
||||
exactly one reset per frame. TB assertion tightened back to **exactly 10688** (`!== BEATS_PER_FRAME` is a hard fail).
|
||||
|
||||
Verification: `tb_gs_lpddr_scanout_fb` → **10688/frame, underflow=0, rd_errs=0, errors=0, PASS**. Focused scanout
|
||||
suite all PASS (scanout_lb, scanout_lb_psm32, scanout_lb_psm32_256, scanout_concurrency, scanout, scanout_psm32).
|
||||
Full regression re-run for the RTL change.
|
||||
|
||||
## Brick 3 — start-ordering gate (Codex, mandatory sequence)
|
||||
|
||||
The de25 top must enforce this host-start order; the boot CLUT payload must NOT auto-start rendering before 1–4:
|
||||
1. HPS preclears the framebuffer.
|
||||
2. HPS uploads the texture.
|
||||
3. Texture cache fill completes successfully.
|
||||
4. CLUT boot upload/load completes.
|
||||
5. Arm the PSMCT32 writer.
|
||||
6. Start the feeder render.
|
||||
7. Send EOF; await EMIF-domain `frame_drained`.
|
||||
8. Enable the static LPDDR scanout.
|
||||
|
||||
## Codex round 5 — Brick 3 build rulings (board path)
|
||||
|
||||
1. **No hardware preclear engine for v1.** Extend the HPS write-probe (`ps2_sh3_tex_upload.c`) to zero
|
||||
0x000000–0x0537FF (85,504 words) — only ~30% more traffic than the proven 65,536-word texture upload — polling
|
||||
`write_pending` and checking BRESP. A new AXI engine + arbiter are unjustified before measuring this path.
|
||||
2. **Dedicated `GS_SH3_LPDDR_FB` profile**, separate from `GS_TILE_SPILL`, static PSMCT32 line-buffer scanout,
|
||||
profile-specific geometry (256×334).
|
||||
3. **`frame_drained` as a HARD gate, no timeout.** A timeout can display a partial FB — recreating the bug the
|
||||
handshake fixes. Failure stays BLACK with diagnostics; a manual debug override is acceptable only if explicit.
|
||||
4. **Feeder auto-start-once correction (CRITICAL).** `top_psmct32_raster_demo_bram.sv:807` C_SETUP asserts `fdr_start`
|
||||
when the boot upload finishes → the disarmed boot render leaves a pending EOF that would assert `frame_drained` the
|
||||
instant the host later arms the writer. Fix: **`FEEDER_AUTOSTART` param (default 1'b1), 0 only for this profile** →
|
||||
C_SETUP goes straight to C_READY (no boot render); every render then waits for an explicit 0x0E8 GO.
|
||||
5. **Expose `frame_drained` as a host-readable diagnostic** if a spare status bit exists.
|
||||
|
||||
Required host sequence (GS_SH3_LPDDR_FB): (1) wait setup/CLUT complete + feeder ready → (2) preclear LPDDR FB →
|
||||
(3) upload texture → (4) fill + verify texture cache → (5) configure base 0, full mode, arm writer → (6) issue 0x0E8 GO
|
||||
→ (7) await ordered `frame_drained` → (8) enable scanout automatically from that ack.
|
||||
|
||||
### Landed this round
|
||||
- **`FEEDER_AUTOSTART` param + FSM** in `top_psmct32_raster_demo_bram.sv` (param after FEEDER_STG_WORDS; C_SETUP
|
||||
branches on it → auto boot render when 1, straight to C_READY when 0). Additive, default 1'b1. Verified
|
||||
byte-identical: tb_top_psmct32_sh3_lpddr_fb / feeder_runtime_demo / feeder_scene_retrigger_demo all PASS.
|
||||
|
||||
### Design clarification (derived)
|
||||
`GS_SH3_LPDDR_FB` is a **feeder-based** profile: the host streams the SH3 draw list into the feeder (0x0DC/0x0E4) and
|
||||
GOes (0x0E8) — matching Codex's host sequence. So its inner-instance config mirrors `GS_SH3_REAL_DRAW_DEMO`
|
||||
(FEEDER_ENABLE=1, CLUT_CSM1_ENABLE=1, PERSPECTIVE_CORRECT=1, PERSP_RECIP_IDX_BITS=11, GS_LPDDR_TEX cache) but with:
|
||||
FEEDER_AUTOSTART=0, FB_LPDDR_ONLY=1 (Ch326, suppress BRAM FB mirror), the full 256×334 PSMCT32 FB in LPDDR (not the
|
||||
128 KiB crop), and the line-buffer scanout at 256×334.
|
||||
|
||||
### Remaining Brick 3 build (precise)
|
||||
- **(RTL, board top)** add `elsif GS_SH3_LPDDR_FB` inner-instance param block (SH3 config + FEEDER_AUTOSTART=0 +
|
||||
FB_LPDDR_ONLY=1); activate the GS_LPDDR4B_FB writer/scanout blocks for this profile; reconfigure the writer instance
|
||||
to PIX_BYTES=4 / px_pix32=demo_flush_color32 / px_emit on psm==6'h00 / flush=end-of-scene / route `frame_drained`;
|
||||
set scanout geometry (STRIDE=1024, ROW_BEATS=32, N_ROWS=334, PSMCT32); `frame_ready_emif = frame_drained` (hard gate,
|
||||
no timeout).
|
||||
- **(RTL, bridge)** expose `frame_drained` as a status bit (mind the `.*`-port-add trap: update every bridge
|
||||
instantiation/TB).
|
||||
- **(host)** `ps2_sh3_tex_upload.c` FB-preclear loop (zero 0x000000–0x0537FF via write-probe, poll write_pending + BRESP).
|
||||
- **(build)** add the `GS_SH3_LPDDR_FB` profile to `select_de25_profile.sh` + QSF VERILOG_MACRO (also defines
|
||||
GS_LPDDR4B_FB + GS_LPDDR_TEX + the SH3 fixture macros).
|
||||
- **(sim, MANDATORY before fit)** integration sim proving the sequence: FEEDER_AUTOSTART=0 → no boot render → arm →
|
||||
GO → EOF → `frame_drained` fires exactly once (NOT prematurely from a boot render) → scanout serves the correct
|
||||
full-frame. This is the correctness proof for Codex's round-5 item 4.
|
||||
|
||||
## Brick 3 — host-start SEQUENCE proof (integration sim) — PASS
|
||||
|
||||
`sim/tb/top/tb_top_psmct32_sh3_lpddr_fb_seq.sv` (full-frame fixtures; the mandatory pre-fit gate). Instantiates the
|
||||
bram-top with **FEEDER_AUTOSTART=0** + FB_LPDDR_ONLY + the SH3 feeder config, the PSMCT32 writer, the behavioral
|
||||
(precleared) LPDDR FB, and `gs_lpddr_scanout_lb` reading it back to a real video raster — with the **render-epoch**
|
||||
flush logic (Codex round 5) driving the writer's EOF. Clocks: design/gs #5, emif #2, video #7, bridge #11.
|
||||
|
||||
Render epoch (mirrors what wires into the board top): `render_inflight` set by an accepted host GO (feeder_go while
|
||||
ready); `flush = render_inflight && feeder_ready_rise`; cleared on flush. So the FEEDER_AUTOSTART=0 setup→C_READY edge
|
||||
(render_inflight=0) can NOT enqueue a false EOF.
|
||||
|
||||
Codex acceptance — ALL met on the first run:
|
||||
- Boot setup reaches C_READY. **Before GO: raster_emits=0, writer_beats=0, eof=0, frame_drained=0** (no boot render).
|
||||
- Texture fill verifies (fill_crc=fbdeaa32, tex_rd_errs=0). FB precleared to 0; idle BRESP errors=0.
|
||||
- Host sets base 0 / canary off / arms writer (latched via ctrl_commit).
|
||||
- **GO → feeder_ready drops then re-rises** after render+drain.
|
||||
- **Exactly ONE EOF → exactly ONE frame_drained.** Writer beats=6502, FIFO overflow=0, BRESP errors=0.
|
||||
- Synchronized `frame_drained` reaches the bridge domain.
|
||||
- Scanout auto-enabled from the ack: **exactly 10688 read beats/frame**, all 256×334 pixels match (incl. black),
|
||||
underflow=0, rd_errs=0.
|
||||
- Bounded oracle: 96.1% ≤1-texel ALL / 97.6% interior / clut_bad=0 (correct SH3 render).
|
||||
- `errors=0` → **PASS**.
|
||||
|
||||
The SH3 fixture TBs are dump-derived/LOCAL, so this is run manually (like its siblings) — NOT added to the master
|
||||
`run:` list. Full regression re-run for the widely-used inner-module FEEDER_AUTOSTART change (additive, default 1'b1).
|
||||
|
||||
REMAINING Brick 3 (board plumbing, then owner fit): board-top GS_SH3_LPDDR_FB profile (param block + writer reconfig +
|
||||
scanout geom + frame_ready_emif=frame_drained + the render-epoch logic wired in design_clk); bridge frame_drained
|
||||
status bit; host preclear loop in ps2_sh3_tex_upload.c; select_de25_profile.sh + QSF profile. No fit until the board
|
||||
build compiles clean under the profile and this sequence proof stays green.
|
||||
|
||||
## Brick 3 board plumbing — COMPLETE (awaiting owner fit)
|
||||
|
||||
All board-side wiring for GS_SH3_LPDDR_FB is landed and verified in sim; the fit itself is owner-gated.
|
||||
|
||||
**Board top (`de25_nano_psmct32_raster_demo_top.sv`), all gated on `GS_SH3_LPDDR_FB` (inert for every other profile):**
|
||||
- Inner-instance param block `elsif GS_SH3_LPDDR_FB` — mirrors GS_SH3_REAL_DRAW_DEMO (FEEDER_ENABLE, CLUT_CSM1,
|
||||
PERSPECTIVE_CORRECT, PERSP_RECIP=11, VRAM 128 KiB, GRAD_SEQ_DIVIDER=0) + **FEEDER_AUTOSTART=0** + **FB_LPDDR_ONLY=1**.
|
||||
- TEXC block: `elsif GS_SH3_LPDDR_FB` → the same 512×512 PSMT8 LPDDR texture geometry as the crop.
|
||||
- Render epoch (design_clk): `sh3_render_inflight` set by an accepted feeder GO; `sh3_fb_flush = inflight && feeder_ready
|
||||
rise`; cleared on flush → exactly one EOF per render (Codex round 5 — the setup→C_READY edge can't leak an EOF).
|
||||
- frame_ready gate: `frame_ready_emif = sh3_frame_drained` (EMIF prefetch enable) + `frame_ready_r` = design-synced
|
||||
sh3_frame_drained (HDMI mux blanks black until drained). HARD gate, no timeout.
|
||||
- Writer (u_lpddr_axi, the active GS_LPDDR4B_FB instance): `PIX_BYTES(4)`, `px_emit` on psm==6'h00,
|
||||
`px_pix32=demo_flush_color32`, `flush=sh3_fb_flush`, `.frame_drained(sh3_frame_drained)`.
|
||||
- Scanout: `SCANOUT_LB_NROWS=334` (STRIDE 1024 / ROW_BEATS 32), `SCANOUT_FB_BASE=0`, `SCANOUT_PSMCT32=1`,
|
||||
`scanout_lb_eff` forced 1 (line-buffer; a 256×334 frame-cache would be 334 KiB).
|
||||
- Verified: patched-copy iverilog elaboration under GS_SH3_LPDDR_FB+GS_LPDDR4B_FB+GS_LPDDR_TEX = exit 0 (the only
|
||||
standalone-sim gap is the Quartus-only EMIF_Qsys IP + a pre-existing `lpddr_ctrl_commit_w` forward-ref, both
|
||||
fit-proven). Default board-top TB still builds+passes (edits inert for non-SH3).
|
||||
|
||||
**Drain diagnostic:** used existing `LPDDR_STATUS 0x02C[0]` (writer idle, stable post-render) + `LPDDR_BYTES 0x030`
|
||||
(beats!=0) — the narrowest path (Codex), avoiding a bridge port-add that would break 4 `.*` regression TBs.
|
||||
`frame_drained` still gates the scanout internally.
|
||||
|
||||
**Build profile:** `scripts/select_de25_profile.sh sh3_lpddr_fb` case added (SCENE = GS_SH3_LPDDR_FB + GS_LPDDR_TEX +
|
||||
feeder_sh3_full; FIXTURE = bios/payload_sh3_full). Ran it myself + verified the QSF: SCENE/FIXTURE blocks correct,
|
||||
markers balanced (2×), static GS_LPDDR4B_FB=1 / GS_LPDDR_FB=1 / USE_QSYS_TOP=1 / EMIF IP intact.
|
||||
|
||||
**Host app:** `tools/ps2_sh3_tex_upload.c` extended with `--lpddr-fb` mode (Codex's no-hw-clear path): wait feeder
|
||||
ready → PRECLEAR FB 0x000000..0x0537FF (85504 words) via the write-probe (poll write_pending, check BRESP) → upload
|
||||
texture → fill+verify cache → set base 0 / canary off / arm writer → feeder GO → await drain (idle + bytes!=0) →
|
||||
raise video_src. Compiles clean (-Wall); dry-run OK (tex sum32=fbdeaa32). Crop path byte-unchanged.
|
||||
|
||||
**Verification:** seq proof `tb_top_psmct32_sh3_lpddr_fb_seq` still PASS (10688 beats, 1 EOF→1 frame_drained, oracle
|
||||
96.1%). Regression re-running after the board-top edits.
|
||||
|
||||
**Owner fit order:** (1) `python3 tools/gs_make_sh3_real_draw_fixture.py --full-frame` (regenerate LOCAL fixtures if
|
||||
absent); (2) `./scripts/select_de25_profile.sh sh3_lpddr_fb` (DONE — QSF already set); (3) fit in Quartus; (4) on the
|
||||
board: `gcc -O2 -o ps2_sh3_tex_upload tools/ps2_sh3_tex_upload.c && sudo ./ps2_sh3_tex_upload sh3_real_tex_lpddr.mem
|
||||
--lpddr-fb`.
|
||||
|
||||
## Ch353 follow-up — host-visible frame_drained diagnostic bit (Codex-approved after silicon)
|
||||
|
||||
Silicon showed the host's `idle`-based drain confirmation reads a mid-render count (idle pulses between the feeder's
|
||||
render batches → the board printed "beats=44"). The DISPLAY was correct (scanout gated on the ordered frame_drained),
|
||||
but the host couldn't READ a stable drain signal. Added it (the `.*`-port-add done carefully):
|
||||
|
||||
- **Bridge (`ps2_hps_bridge.sv`):** new `input frame_drained_i` + `frame_drained_sync` (2-FF into the bridge clock) +
|
||||
**LPDDR_STATUS 0x02C[6] = frame_drained_sync[1]** (STABLE — asserts only after the EOF marker's last BRESP).
|
||||
- **Board top:** `sh3_frame_drained` now defined in both ifdef branches (driven by the writer under GS_SH3_LPDDR_FB,
|
||||
tied 0 otherwise); bridge `.frame_drained_i(sh3_frame_drained)`.
|
||||
- **`.*`-trap handled:** the 4 `.*` bridge TBs (tb_ps2_hps_bridge, tb_bridge_iop_pad_input, tb_pad_state_via_sif_to_ee,
|
||||
tb_ee_pad_buffer_branch) each got a tied `logic frame_drained_i = 1'b0;` (matched by name). tb_lpddr_tex_staging is
|
||||
explicit/partial — the new input floats like its other unconnected inputs (no change). null bridge unaffected
|
||||
(its port list is a strict subset). All 5 bridge TBs PASS.
|
||||
- **Host (`ps2_sh3_tex_upload.c --lpddr-fb`):** step 7 now polls **0x02C[6] frame_drained** (not [0]idle) and reports
|
||||
`frame_drained=1, FB beats written=~6500`. Compiles clean (-Wall).
|
||||
|
||||
Verified: board top elaborates clean under GS_SH3_LPDDR_FB+GS_LPDDR4B_FB+GS_LPDDR_TEX (exit 0); seq proof still PASS
|
||||
(10688, 1 EOF→1 frame_drained); full regression re-running. This is a diagnostic-only change — the functional path
|
||||
(silicon-verified) is unchanged; it re-fits into the same profile.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Ch354 audit log — draw-list expansion: multiple SH3 draws composited into one LPDDR framebuffer
|
||||
|
||||
Purpose: auditable trail for Codex. Builds directly on Ch353 (the LPDDR-only PSMCT32 framebuffer, silicon-verified).
|
||||
Brick 1 scope (Codex, conservative): the SAME-TEXTURE trio idx89548/89761/89974 (tbp=9216/cbp=13952, frame f1)
|
||||
composited into one FB — ONE new variable: multiple authentic draws accumulating into one LPDDR framebuffer. NOT in
|
||||
Brick 1: multi-texture residency, full 640x480, large Z-buffer.
|
||||
|
||||
## Fixture generator (tools/gs_make_sh3_multidraw_fixture.py) — all guardrails fail-CLOSED
|
||||
- #4 mechanical: the trio is one frame (f1), one texture key (9216,0x13,8,TRI_STRIP,tme=1,abe=0), ascending dump order.
|
||||
- #2 ALL feeder-visible state identical: TEX0(all fields), PRIM/fst/tme/abe, TEST, ZBUF, CLAMP, ALPHA, TEXA.
|
||||
- #3 CONTENT (epoch-aware): texture @tbp=9216 (256 KB) + CLUT @cbp=13952 (1 KB) byte-identical across all three
|
||||
(per-draw local-memory reconstruction; a same-byte re-upload passes, a changed payload FAILS).
|
||||
- #1 capacity: 204 clipped tris -> 1843 staging words. Correctly fail-closed at 768; Codex approved FEEDER_STG_WORDS
|
||||
=2048 (16-bit tri count + 12-bit staging addr cover it). Feeder .mem padded to 2048.
|
||||
- #3 union bbox: origin (243,52), 248x338 -> FB 256x338, stride 1024B, size 0x54800 (338 KiB).
|
||||
- #5 INDEPENDENT oracle from reconstructed GS local memory (not feeder records); #6 overlap scored: 10370 overlap px.
|
||||
|
||||
## Integration sim (tb_top_psmct32_sh3_multidraw) — PASS on the accumulation acceptance
|
||||
Combined list through the SAME Ch353 LPDDR-FB path (FEEDER_AUTOSTART=0 + render-epoch EOF + frame_drained hard gate +
|
||||
line-buffer scanout). PASS: records_emitted=204, ONE frame_drained after all batches, writer overflow/BRESP=0,
|
||||
raster_overflow=0, scanout 256x338 = 10816 beats/frame exact, underflow=0, transport exact, clut_bad=0, overlap
|
||||
exercised (10370 px). Fidelity is REPORTED, not gated (Codex: not part of accumulation acceptance).
|
||||
|
||||
## Codex diagnostic branch — RESOLVED (two SEPARATE claims)
|
||||
Isolation + per-draw + RTL-composition (tool --tag/--only/owner-map; TB +TAG/+FBDUMP; scratch compose_check.py):
|
||||
- **89761 isolated through the new path: INTERIOR 97.5%** == Ch353's 97.6% -> the multidraw tool/origin translation
|
||||
is CORRECT (not the source of the drop).
|
||||
- Per-draw <=1-texel INTERIOR: 89761=97.5%, 89548=95.6%, 89974=93.2% (draw-dependent).
|
||||
- **RTL-paint-order composition: combined RTL == overlay of the three isolated single RTL renders, 0/86528 px differ.**
|
||||
|
||||
**CLAIM 1 (accumulation/order/coalescing): bit-exact — 0/86528 px different from RTL-composed singles.**
|
||||
**CLAIM 2 (authentic-reference fidelity): draw-dependent (97.5/95.6/93.2%), the EXISTING perspective-sampling
|
||||
fidelity limitation — NOT part of the accumulation acceptance, NOT independently attributed to the reciprocal curve.**
|
||||
The combined interior (94.4%) is the coverage-weighted mix; the overlap region is dominated by the least-accurate
|
||||
draw (89974 owns the most covered pixels), which is why OVERLAP-INTERIOR looks lowest.
|
||||
|
||||
## Board prep (Codex-directed) — verified in sim, owner-gated for the fit
|
||||
- Board top: `GS_SH3_LPDDR_FB_MULTI` overrides FEEDER_STG_WORDS 768->2048 and SCANOUT_LB_NROWS 334->338; everything
|
||||
else shared with GS_SH3_LPDDR_FB. Elaborates clean (exit 0) under GS_SH3_LPDDR_FB+_MULTI+GS_LPDDR4B_FB+GS_LPDDR_TEX.
|
||||
- Framebuffer 256x338, stride 1024, size 0x54800; scanout 10816 beats/frame.
|
||||
- Host ps2_sh3_tex_upload.c: `--fb-rows N` -> preclears the exact 256xN range (338 => 0..0x54800). -Wall clean.
|
||||
- frame_drained diagnostic (0x02C[6], Ch353 follow-up) is BUNDLED into this fit.
|
||||
- Build profile `sh3_lpddr_fb_multi` (select_de25_profile.sh + QSF): SCENE GS_SH3_LPDDR_FB + GS_SH3_LPDDR_FB_MULTI +
|
||||
GS_LPDDR_TEX + feeder_sh3_multi; FIXTURE bios/payload_sh3_multi. Ran profile-select + verified the QSF.
|
||||
- BOARD RUN: `sudo ./ps2_sh3_tex_upload sh3_real_tex_lpddr.mem --lpddr-fb --fb-rows 338`.
|
||||
@@ -0,0 +1,101 @@
|
||||
# Ch355 audit log — MULTI-TEXTURE composition (different-texture draws accumulate into one LPDDR framebuffer)
|
||||
|
||||
Codex rung after Ch354. Brick 1 (narrow): TWO authentic SH3 draws with DIFFERENT TEX0/CLUT composited into one FB via
|
||||
SCENE-LEVEL texture rebind + staged-list retriggering. Dump order (authentic): A=idx19562 (tbp=11264/cbp=14080) THEN
|
||||
B=idx89761 (tbp=9216/cbp=13952). NOT Brick 1: per-primitive TEX0, multi-resident cache, 640x480, cross-draw Z.
|
||||
|
||||
## Preflight (gs_make_sh3_multitex_fixture.py) — fail-CLOSED, PASS
|
||||
- authentic dump order (A idx < B idx); same frame f1; DIFFERENT texture keys (11264 vs 9216).
|
||||
- on-screen overlap: A[203..340]x[10..282] ∩ B[245..490]x[57..390] = [245..340]x[57..282].
|
||||
- each texture+CLUT INDEPENDENTLY RESIDENT at its draw-time epoch (per-draw local-mem reconstruction); the two
|
||||
textures differ (real multi-texture, not aliasing); the two CLUTs differ.
|
||||
- CLUTs RELOCATED to distinct, non-overlapping, in-BRAM CBPs: A->CBP=480 (0x1E000), B->CBP=484 (0x1E400).
|
||||
|
||||
## Emit — union geometry (Codex's numbers) + two of everything + independent A->B reference
|
||||
- union origin (202,9), content 289x381 -> stored FB 320x381 (FBW=5), stride 1280 B, size 0x77100, scanout 15240
|
||||
beats/frame; HDMI shows all 320 cols (31 right cols precleared-black beyond the 289px content).
|
||||
- two feeder lists (dump order): A (TEX0 CBP_A) 68 tris/619 words; B (TEX0 CBP_B) 68 tris/619 words; max staging addr
|
||||
618 < 12-bit 4096.
|
||||
- two textures de-swizzled -> LPDDR + per-texture CRC: A sum32=0x95a83cbc, B sum32=0xfbdeaa32 (=Ch354's tbp=9216).
|
||||
- two relocated CLUTs; bootlet uploads BOTH (A->CBP_A, B->CBP_B); each list's scene-level TEX0 (CLD=1) selects its CBP.
|
||||
- independent A->B composed reference (dump order, DECAL paint-order, B over A): 27455 covered, 9849 A&B overlap px.
|
||||
|
||||
## Integration sim (tb_top_psmct32_sh3_multitex) — PASS on ALL Codex gates
|
||||
- TWO cache fills, each a FRESH fill_done low->high (rearm), correct beats(8192)/bytes(262144)/0 rd_errs, texture-
|
||||
specific CRC: A=0x95a83cbc THEN B=0xfbdeaa32.
|
||||
- NO stale-frame_drained race: scene A = fresh low->high; scene B = high->low->high (an observed FALL proves B's beats
|
||||
flowed and cleared A's stale high before the fresh rise). Enforced by a fd_before-aware run_scene task.
|
||||
- preclear EXACTLY once; scanout (video_src) disabled until the SECOND fresh drain.
|
||||
- records_emitted = 68 per list; writer ovf/BRESP = 0; scanout 15240 beats/frame EXACT; underflow=0.
|
||||
- final FB scored vs the independent A->B reference: OVERLAP(A&B) COMPOSITE = 96.7% <=1-texel (gated >=95%) — proves B
|
||||
(tex B + relocated CLUT B) correctly overwrote A. clut_bad=0 (every covered px in palette A or B).
|
||||
|
||||
## Two SEPARATE claims (as Ch354)
|
||||
- CLAIM 1 multi-texture accumulation/composite: PROVEN — overlap composite 96.7% >=95%, clut_bad=0, cache rearmed with
|
||||
correct per-texture CRCs, anti-stale drains, exact scanout beats.
|
||||
- CLAIM 2 fidelity: ALL=69.3% (REPORTED, not gated) — dragged by the A-only region = draw 19562's OWN per-draw
|
||||
perspective-sampling fidelity (the parked limit; B/89761 renders fine, hence the 96.7% B-dominated overlap). Whether
|
||||
to independently verify 19562-alone is an open question for Codex.
|
||||
|
||||
## Remaining before board fit (Codex: no fit until runtime staging also passes)
|
||||
- Host two-group RUNTIME-STAGING flow: preclear once; upload+fill+CRC tex A; STREAM list A (report words/records, 12-bit
|
||||
bound); GO A + observe fresh drain; REFILL+CRC tex B; STREAM list B; GO B + observe high->low->high; video_src after
|
||||
the 2nd drain. Then board fit (owner-gated).
|
||||
|
||||
## Codex round 2 — NEGATIVE-Q root cause + exact canonicalization (RESOLVED)
|
||||
The combined ALL=69.3% was masking a real defect, NOT the parked perspective limit. Diagnostic (ONLY=A/B/AB +
|
||||
FBDUMP + compose_mt.py):
|
||||
- A→B RTL composition == combined AB, 0/121920 px BIT-EXACT (accumulation/order correct).
|
||||
- CLUT relocation CORRECT: A rendered 100% in palette A, B 100% in palette B (palA ∩ palB = ∅).
|
||||
- ONLY=B (89761, positive Q) = 95.6%; ONLY=A (19562) = 27.4% with a CORRECT CLUT.
|
||||
- ROOT CAUSE: idx19562 has NEGATIVE q/s/t (q[-0.00039..-0.00024]); 89761 positive. Codex confirmed the RTL
|
||||
perspective reciprocal input/products are UNSIGNED -> negative Q is unsupported (not merely imprecise).
|
||||
|
||||
FIX (Codex) — exact host-side homogeneous-coordinate canonicalization in the fixture tool, BEFORE fixed-point pack:
|
||||
per triangle, all-Q-positive unchanged; all-Q-negative -> negate every vertex's S,T,Q (EXACT: (-s)/(-q)=s/q, and the
|
||||
negation of a linear attribute interpolates identically); mixed-sign/zero Q -> FAIL CLOSED. Overflow-checked.
|
||||
- SYNTHETIC GATE: a positive-Q triangle and its all-negated twin pack BIT-IDENTICALLY (self-test PASS).
|
||||
- 19562-alone re-rendered vs the UNCHANGED reference: 27.4% -> 93.0%, clut_bad=0 (oracle fixed to not count
|
||||
RTL-unwritten coverage-edge pixels as clut_bad).
|
||||
- A→B composition re-run: still 0/121920 BIT-EXACT.
|
||||
- Default AB acceptance: ALL 69.3% -> 95.1%, OVERLAP composite 96.4% (>=95%), clut_bad=0, 15240 beats, PASS.
|
||||
|
||||
RECORDED: the feeder CANONICALIZES homogeneous coordinates to positive Q. This is NOT native signed-Q hardware
|
||||
support; a true signed reciprocal path remains a later platform extension for mixed-sign triangles.
|
||||
|
||||
## Ch355 Brick 1 status: integration PROVEN. Remaining before fit = host two-group runtime-staging flow.
|
||||
|
||||
## Board prep (Ch355 multi-texture) — verified in sim, owner-gated for the fit
|
||||
- Board top: `GS_SH3_LPDDR_FB_MULTITEX` overrides SCANOUT_LB to STRIDE=1280/ROW_BEATS=40/NROWS=381 (320x381, FBW=5) and
|
||||
FEEDER_STG_WORDS->2048; everything else shared with GS_SH3_LPDDR_FB. Elaborates clean (exit 0) under
|
||||
GS_SH3_LPDDR_FB + GS_SH3_LPDDR_FB_MULTITEX + GS_LPDDR4B_FB + GS_LPDDR_TEX.
|
||||
- FB 320x381, stride 1280, size 0x77100, scanout 15240 beats/frame.
|
||||
- Bootlet (bios/payload_sh3_mt) uploads BOTH relocated CLUTs (CBP_A=480, CBP_B=484). RUNTIME staging -> NO
|
||||
FEEDER_STG_INIT_FILE (feeder starts empty; the host streams each per-scene list).
|
||||
- Host `tools/ps2_sh3_multitex.c` (the two-group runtime flow): wait feeder ready -> FB base 0 -> preclear ONCE
|
||||
(121920 words, 0..0x77100) -> fill+CRC tex A (fresh fill_done, crc 0x95a83cbc, 8192 beats/262144 bytes/0 rd_errs) ->
|
||||
STREAM list A (reset 0x0D8, per-word LO 0x0DC/HI 0x0E4; report words/records + 12-bit bound) -> arm writer, GO A,
|
||||
fresh drain (0x02C[6]) -> REFILL+CRC tex B (0xfbdeaa32) -> STREAM list B -> GO B, frame_drained HIGH->LOW->HIGH ->
|
||||
video_src after the 2nd fresh drain. Compiles -Wall clean; dry-run parses texA/texB CRCs + 68 tris/619 words each.
|
||||
- Build profile `sh3_lpddr_fb_multitex` (select_de25_profile.sh + QSF): SCENE GS_SH3_LPDDR_FB + GS_SH3_LPDDR_FB_MULTITEX
|
||||
+ GS_LPDDR_TEX (no bitstream feeder init); FIXTURE bios/payload_sh3_mt. Ran profile-select + verified the QSF.
|
||||
- BOARD RUN: `sudo ./ps2_sh3_multitex sh3_mtA_tex_lpddr.mem sh3_mtB_tex_lpddr.mem feeder_sh3_mtA.mem feeder_sh3_mtB.mem`.
|
||||
|
||||
## Codex round 3 — bridge-streaming sim test (closes the gap that hid the board bug)
|
||||
BOARD RUN #1 rendered 0 beats: the host wrote 0x0D8=1 (SET staging addr) instead of 0, so word0/header landed at
|
||||
slot 1 -> feeder read ntris=0. Root cause is RTL: ps2_hps_bridge.sv:1171 `feeder_addr_q <= wdata_lane` (0x0D8 W SETS
|
||||
the address to the written value). Host fixed to write 0 (matches ps2_feeder.c); BOARD RUN #2 = full success.
|
||||
The gap: BOTH the multi-texture TB and tb_top_psmct32_feeder_bridge_demo drove feeder_stg via $readmemh / direct
|
||||
waddr — neither exercised the real 0x0D8/0x0DC/0x0E4 protocol.
|
||||
|
||||
Closed in tb_ps2_hps_bridge (joins the full regression): a model_stg captures the bridge's commit strobe
|
||||
(feeder_stg_we_tgl_o + waddr/wdata), and the test stages TWO complete lists EXCLUSIVELY via bridge register writes:
|
||||
- Scene A (10 words): 0x0D8=0, per-word 0x0DC(lo)/0x0E4(hi) -> every word checked at its slot, ESPECIALLY word0;
|
||||
final 0x0DC readback == nwords.
|
||||
- NEGATIVE test: 0x0D8=1 -> word0 mis-slots to slot 1 (reproduces the exact board failure; pins the addr-set semantics).
|
||||
- Scene B (6 words, different): re-stage after 0x0D8=0 (A->B, no $readmemh) -> every word + word0 + final addr.
|
||||
- records_emitted readback (0x0E4 R) == 68.
|
||||
tb_ps2_hps_bridge PASS. This exercises the exact host<->bridge address path that failed on silicon; the render/drain
|
||||
per scene is silicon-verified (BOARD RUN #2) + covered by tb_top_psmct32_sh3_multitex.
|
||||
|
||||
## Ch355 Brick 1: BANKED — multi-texture composition on silicon + the runtime-staging gap closed.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Ch356 audit log — N-TEXTURE SCHEDULER (data-driven epoch descriptors)
|
||||
|
||||
Codex rung after Ch355. Generalizes Ch355's hard-coded two-group flow to a DATA-DRIVEN scheduler over ordered authentic
|
||||
draw epochs, each with a DIFFERENT TEX0/CLUT, accumulating into ONE LPDDR framebuffer via scene-level texture rebind +
|
||||
runtime staged-list retriggering. Default N_EPOCHS=3 (dump order): E0=idx11671 (tbp=10240) E1=idx19562 (tbp=11264)
|
||||
E2=idx89761 (tbp=9216). Runtime CLUT UPLOAD is OUT of scope (Codex): the scheduler operates over a PRELOADED CLUT table
|
||||
(the bootlet uploads all N relocated CLUTs); each epoch SELECTS its palette via its list's scene-level TEX0 CBP.
|
||||
|
||||
## Preflight (gs_make_sh3_scheduler_fixture.py) — fail-CLOSED, PASS
|
||||
- >=3 epochs; authentic ascending dump order; single frame f1.
|
||||
- >=3 DISTINCT textures (tbp 10240/11264/9216); each PSMT8 512x512 perspective TME (fst=0) — supported format/state.
|
||||
- each texture + CLUT INDEPENDENTLY RESIDENT at its draw-time epoch (per-epoch local-memory reconstruction).
|
||||
- palettes pairwise-DISTINCT (real multi-texture, no aliasing).
|
||||
- CLUTs relocated to distinct, non-overlapping, in-BRAM CBPs: E0->480 E1->484 E2->488 (each 1 KiB / 4 blocks, VRAM 512 blocks).
|
||||
- per-triangle Q-canonicalization: all-neg -> negate S/T/Q (exact); mixed-sign/zero -> FAIL CLOSED. neg-Q per epoch: 68/68/0.
|
||||
- each list fits staging (619 words < 2048); deterministic union framebuffer geometry.
|
||||
|
||||
## Emit — union geometry + N of everything + composed + per-epoch references
|
||||
- union origin (170,9), content 321x381 -> stored FB **384x381 (FBW=6), stride 1536 B, size 0x8ee00, scanout 18288
|
||||
beats/frame**.
|
||||
- N feeder lists (canonicalized): feeder_sh3_sched{k}.mem, each 68 tris / 619 words. Each list's TEX0 CBP = its relocated palette.
|
||||
- N textures de-swizzled (LINEAR) -> LPDDR single region 0x200000: sh3_sched{k}_tex_lpddr.mem. Per-epoch CRC (the cache-fill CRCs):
|
||||
E0=0x26a88b77 E1=0x95a83cbc E2=0xfbdeaa32 (E1/E2 == Ch355's texA/texB).
|
||||
- N relocated CLUTs; bootlet (bios/payload_sh3_sched) preloads ALL N via N 256x1 BITBLTs; DISPLAY1 = 384x381.
|
||||
- composed reference (paint-order DECAL) sh3_sched_refmap.mem: [31]cov [30]int [28]multi(>=2) [26:24]owner_epoch [17:9]tu [8:0]tv.
|
||||
42414 covered px, 6124 multi-epoch (>=2 distinct) px. Per-epoch refmaps sh3_sched{k}_refmap.mem carry each epoch's OWN (tu,tv).
|
||||
- descriptor table sh3_sched_epochs.txt (META line + one row/epoch: k idx tbp cbp tex_file lpddr size crc list_file words records) — the host reads it.
|
||||
- params sh3_sched_params.vh (FBW/FBPXW/FBH, TEX_*, N_EPOCHS, EPk_CRC/EPk_NTRIS/EPk_CBP).
|
||||
- canonicalization self-test PASS: a positive-Q triangle and its all-negated twin pack BIT-IDENTICALLY.
|
||||
|
||||
## Integration sim (tb_top_psmct32_sh3_sched) — PASS. All Codex acceptance gates:
|
||||
- preclear EXACTLY once (fb precleared in the initial block, never between epochs).
|
||||
- 3 FRESH cache fills, each fill_done low->high (rearm), beats=8192 bytes=262144 rd_errs=0, epoch CRC exact (0x26a88b77/0x95a83cbc/0xfbdeaa32).
|
||||
- 3 lists STREAMED through the feeder staging WRITE PORT (feeder_stg_we/waddr/wdata), NOT the $readmemh backdoor — closes
|
||||
the Ch355 sim gap where the write-port sequencing was untested. Each streams the full 2048 STG words (staging fully reset);
|
||||
word0 (ntris header) verified in the DUT staging = 68 per epoch.
|
||||
- 3 FRESH ORDERED drains: E0 low->high (first render, falls 0->0 rises 0->1); E1 high->low->high (falls 0->1 rises 1->2);
|
||||
E2 high->low->high (falls 1->2 rises 2->3). records_emitted=68 each; writer ovf=0 bresp=0.
|
||||
- scanout held OFF until the last fresh drain; scanout beats/frame = **18288 EXACT**; underflow=0 rd_errs=0; 171720 px checked.
|
||||
- oracle (per-pixel, multi-texture correctness): each covered px must equal ONE covering epoch's texel (each epoch's own
|
||||
(tu,tv) from refmap_ep[k]) within <=1 texel; clut_bad = colour in NO epoch palette. Result: ALL=94.1% <=1texel, MULTI(>=2)=92.2%,
|
||||
clut_bad=0. The <=1texel % is RTL reciprocal-LUT fidelity (per-epoch isolated ONLY=k: 93.3/93.0/95.6% — matches Ch355), NOT
|
||||
accumulation. Gated at the documented 90% reciprocal floor.
|
||||
|
||||
## Accumulation correctness — 100% BIT-FOR-BIT (the decisive proof; make tb_top_psmct32_sh3_sched_compose)
|
||||
- render each epoch ALONE (+ONLY=k +FBDUMP) over a precleared FB, then composite the isolation dumps in paint order
|
||||
(nonzero-wins DECAL) and compare to the joint ALL render.
|
||||
- **compose_sched.py: 146304/146304 px, 0 mismatch — 100.0000% BIT-FOR-BIT.** The scheduler drawing the epochs together
|
||||
produces exactly the same FB as compositing the individually-rendered epochs: no cache bleed, no stale pixels, correct rebind.
|
||||
- (An earlier 365-px discrepancy was a bug in MY compose heuristic — a reference-covered-but-RTL-unwritten epoch-2 pixel
|
||||
wrongly "owned" a value-0 slot, masking the lower epoch that actually drew. Pure nonzero-wins DECAL is the correct operator.)
|
||||
|
||||
## Host (ps2_sh3_sched.c) — data-driven, builds -Wall clean, dry-run OK
|
||||
- reads sh3_sched_epochs.txt (META + rows); loads each epoch's texture+list; verifies local CRC per epoch.
|
||||
- flow: wait ready -> FB base 0 -> preclear ONCE (146304 words) -> for each epoch: upload tex -> LPDDR 0x200000, FRESH fill
|
||||
+ verify CRC/beats/rd_errs -> STREAM list (0x0D8=0 reset, 0x0DC/0x0E4 commit) -> arm writer (k==0) -> GO + fresh ordered
|
||||
drain (k==0 low->high; k>0 high->low->high anti-stale) -> records==tris -> enable scanout after the LAST drain.
|
||||
- register map identical to ps2_sh3_multitex (frame_drained 0x02C[6], staging 0x0D8/0x0DC/0x0E4, GO 0x0E8).
|
||||
- BOARD RUN: `sudo ./ps2_sh3_sched sh3_sched_epochs.txt` (all fixtures in the cwd).
|
||||
|
||||
## Board prep — fit-ready, owner-gated
|
||||
- de25 top: new `GS_SH3_LPDDR_FB_SCHED` branch -> SCANOUT_LB 1536/48/381 (384x381, 18288 beats/frame) + FEEDER_STG_WORDS=2048.
|
||||
Elaborates clean under GS_SH3_LPDDR_FB+_SCHED+GS_LPDDR4B_FB+GS_LPDDR_TEX+USE_QSYS_TOP (only the known Quartus-only EMIF_Qsys
|
||||
is unresolved in iverilog — same status as multitex; Quartus has the real IP).
|
||||
- profile `sh3_lpddr_fb_sched` (select_de25_profile.sh): fixtures bios/payload_sh3_sched; macros GS_SH3_LPDDR_FB +
|
||||
GS_SH3_LPDDR_FB_SCHED + GS_LPDDR_TEX. QSF verified (macros + fixtures applied; MULTITEX cleared). NO FEEDER_STG_INIT_FILE
|
||||
(runtime-staged, feeder starts empty).
|
||||
|
||||
## Copyright — all SH3-derived data LOCAL/gitignored
|
||||
- fixtures (*.mem/.vh), the epoch descriptor table (sh3_sched_epochs.txt), and rendered FB dumps (sim/build/sched_fb_*.hex,
|
||||
dump-derived per-pixel data) are gitignored. Added `*sh3*.txt` to .gitignore for the descriptor table. Only OWN code
|
||||
(tb_top_psmct32_sh3_sched.sv, gs_make_sh3_scheduler_fixture.py, compose_sched.py, ps2_sh3_sched.c) is trackable.
|
||||
|
||||
## Two claims
|
||||
1. **Accumulation/scheduling PROVEN EXACT**: joint N-epoch render == composited isolation dumps 100% bit-for-bit; 3 fresh
|
||||
cache rearms with per-epoch CRCs; 3 write-port-streamed lists (word0 verified); 3 fresh ordered anti-stale drains; exact
|
||||
18288 scanout beats; clut_bad=0; 6124 multi-epoch overlap px exercised.
|
||||
2. **Fidelity** = 94.1% ALL / 92.2% MULTI <=1texel, i.e. the RTL 11-bit reciprocal floor (per-epoch isolated 93.0-95.6%,
|
||||
consistent with Ch355). Signed reciprocal for mixed-sign triangles remains a later platform extension.
|
||||
|
||||
Next rungs (Codex earlier): 640x480; persistent cross-draw Z (only if a census shows the chosen draws need it — no speculative Z).
|
||||
@@ -0,0 +1,59 @@
|
||||
# Ch357 audit log — NATIVE 640×480 LPDDR framebuffer
|
||||
|
||||
Codex rung after Ch356. The Ch356 N-texture scheduler on a **native 640×480** LPDDR framebuffer. Draws land at their
|
||||
**authentic screen coordinates** (the Ch356 union-origin translation is removed). The scheduler and host are **unchanged**
|
||||
from Ch356 — only the framebuffer geometry differs. Same 3 epochs (dump order): E0=idx11671, E1=idx19562, E2=idx89761.
|
||||
|
||||
## Geometry (Codex's spec — all gated in the fixture generator, fail-closed)
|
||||
- FBW=10, stride **2560 B**, FB size **0x12C000** (1,228,800 B), **80 beats/row**, **38,400 beats/frame**.
|
||||
- authentic coords (no union translation): draws span x[170..490] y[9..390] — fit inside 640×480 (gated: fail-closed if any vertex escapes).
|
||||
- FB region **[0, 0x12C000) disjoint** from the texture region **[0x200000, 0x240000)** (gated).
|
||||
- texture kept at 0x200000 (single-region cache), unchanged from Ch356.
|
||||
|
||||
## Tooling — `gs_make_sh3_scheduler_fixture.py --fb640 --emit`
|
||||
- new `--fb640` mode: native 640×480, OX=OY=0 (no translation), geometry/fit/disjoint gates, distinct fixture prefix
|
||||
`sh3_s640` so Ch356 (`sh3_sched`) and Ch357 (`sh3_s640`) fixtures coexist. Ch356 output byte-identical (verified).
|
||||
- emits: feeder_sh3_s640{k}.mem, sh3_s640{k}_tex_lpddr/idx/pal/refmap.mem, composed sh3_s640_refmap.mem, bootlet
|
||||
bios/payload_sh3_s640 (preloads all N relocated CLUTs), sh3_s640_params.vh, descriptor table sh3_s640_epochs.txt.
|
||||
- composed-reference pixel counts (42414 covered / 6124 multi-epoch) MATCH Ch356 exactly — translation-invariant, a good cross-check.
|
||||
- Q-canonicalization self-test PASS.
|
||||
|
||||
## Integration sim (tb_top_psmct32_sh3_sched640) — PASS
|
||||
- preclear once; 3 FRESH cache fills (CRC 0x26a88b77/0x95a83cbc/0xfbdeaa32, beats=8192, rd_errs=0); 3 lists STREAMED via
|
||||
the feeder write port (word0=68 each); 3 FRESH ORDERED drains (E0 low→high; E1/E2 high→low→high); records=68 each; ovf=0.
|
||||
- scanout held off until the last drain; **scanout beats/frame = 38400 EXACT** (the PASS verdict gates on this `$error` check);
|
||||
underflow=0, rd_errs=0; full 640×480 frame scored.
|
||||
- oracle: ALL=94.1% ≤1texel, MULTI(≥2)=92.7%, **clut_bad=0** (reciprocal-limited fidelity, same as Ch356; not accumulation).
|
||||
|
||||
## Accumulation correctness — 100% BIT-FOR-BIT on the FULL 640×480 frame (`make tb_top_psmct32_sh3_sched640_compose`)
|
||||
- render ALL + each epoch in isolation (+ONLY=k +FBDUMP), composite (nonzero-wins DECAL, compose_sched.py --width 640),
|
||||
compare to the joint ALL render.
|
||||
- **307200/307200 px, 0 mismatch — 100.0000% BIT-FOR-BIT.** Full-frame reference; accumulation exact on the native FB.
|
||||
|
||||
## Host — UNCHANGED (proves "scheduler unchanged")
|
||||
- the SAME `ps2_sh3_sched` binary drives the 640 descriptor table: reads `fbwords` from the META line (307200), preclears
|
||||
0..0x12C000, iterates the same per-epoch flow. Dry-run green (all 3 CRCs, 619 words each, rc=0).
|
||||
- BOARD RUN: `sudo ./ps2_sh3_sched sh3_s640_epochs.txt`.
|
||||
|
||||
## Board prep — fit-ready, owner-gated
|
||||
- de25 top: new `GS_SH3_LPDDR_FB_640` branch → SCANOUT_LB 2560/80/480 + FEEDER_STG_WORDS=2048. Elaborates clean under
|
||||
GS_SH3_LPDDR_FB+_640+GS_LPDDR4B_FB+GS_LPDDR_TEX+USE_QSYS_TOP (only the known Quartus-only EMIF_Qsys unresolved in iverilog).
|
||||
- profile `sh3_lpddr_fb_640`: fixtures bios/payload_sh3_s640; macros GS_SH3_LPDDR_FB + GS_SH3_LPDDR_FB_640 + GS_LPDDR_TEX.
|
||||
QSF verified (macros + fixtures applied; no stale SCHED/MULTITEX). NO FEEDER_STG_INIT_FILE (runtime-staged).
|
||||
|
||||
## Copyright
|
||||
- `sh3_s640_epochs.txt` added to the exact-path ignore rule; all `sh3_s640*` fixtures + build FB dumps gitignored; only own
|
||||
code (TB, generator, host, compose) trackable.
|
||||
|
||||
## Regression — strict tally (full `make run`)
|
||||
- `make` exit **0**; completion marker `=== all testbenches complete ===` present.
|
||||
- **272 / 272** run-list TBs → PASS verdict (the 7 "missing" are name-aliases; their `_stub` targets confirmed PASS).
|
||||
- **0** `] FAIL` verdicts (the 2 `FAIL-pix` hits are per-pixel diagnostic fields; both TBs verdict PASS, errors=0).
|
||||
- **0** `$fatal` / assertion failures. The lone `errors=128` is the pre-existing `tb_gs_lpddr_scanout_lb` internal diagnostic
|
||||
counter (unmodified by Ch357; TB verdicts PASS). The many "error" grep hits are benign iverilog lint (`$error` un-synthesizable).
|
||||
- Identical tally to the Ch356 regression → Ch357 introduced **zero regressions**.
|
||||
|
||||
## Claim
|
||||
- Ch356 scheduler on a **native 640×480 framebuffer with authentic screen coordinates**. Accumulation 100% bit-for-bit on the
|
||||
full frame; exact 38400 scanout beats; FB/texture ranges disjoint. Fidelity ~92–94% (reciprocal floor, unchanged). Census
|
||||
Z usage next; no speculative Z.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Ch357 ZSCHED integer-XY closeout
|
||||
|
||||
This note pins the persistent-Z ZSCHED signoff contract after the float-oracle mismatch was isolated.
|
||||
|
||||
## Contract
|
||||
|
||||
- The RTL renderer consumes integer screen coordinates from XYZ2. `gs_stub.sv` takes the integer X/Y fields and has no GS 12.4 subpixel raster path in this milestone.
|
||||
- The ZSCHED fixture generator also emits integer XYZ2 coordinates via `quant_xy` before packing vertices. The subpixel geometry from the dump is not present in the feeder data.
|
||||
- Therefore the signoff reference maps must use the same quantized XY vertices. For ZSCHED, `gs_make_sh3_scheduler_fixture.py` defaults `--authz --tag zsched` to integer-XY reference. Use `--float-ref-xy` only as a report-only fidelity-debt diagnostic.
|
||||
|
||||
Canonical fixture emit:
|
||||
|
||||
```sh
|
||||
make -C sim sh3_zsched_fixture
|
||||
```
|
||||
|
||||
Equivalent explicit command:
|
||||
|
||||
```sh
|
||||
python3 tools/gs_make_sh3_scheduler_fixture.py \
|
||||
--draw-list 8634,12757,145742 --authz --tag zsched \
|
||||
--pscale auto,auto,384 --xy-quant round,round,round --ref-xy-quant --emit
|
||||
```
|
||||
|
||||
## Current Gates
|
||||
|
||||
- `tb_top_psmct32_sh3_zsched` gates the integer-XY oracle at the documented 90% MULTI <=1 texel reciprocal floor.
|
||||
- `tb_top_psmct32_sh3_zrop` replays the captured fragment trace through the clamp16 persistent-Z scoreboard.
|
||||
- `tb_top_psmct32_sh3_zint` drives the real raster into the persistent-Z/color LPDDR path and gates zero fragment drops.
|
||||
- `sh3_zsched_board_compare` regenerates the fragment trace and zint framebuffer dump, requires the pulled board framebuffer to match zint byte-for-byte, then replays emitted fragment colors through clamp16 GEQUAL and requires exact framebuffer color agreement.
|
||||
- These three targets are now prerequisites of the default `make -C sim run`.
|
||||
|
||||
Measured integer-XY fixture result: ALL=20227/21645 (93.4%), MULTI=7111/7587 (93.7%), with `tb_top_psmct32_sh3_zsched` PASS. The old float-XY diagnostic stayed below the 90% MULTI floor because it compared against geometry that the hardware was not fed.
|
||||
|
||||
Measured board readback result from the refreshed fixture: `sh3_zsched_board_fb.mem` and `sh3_zsched_zint_fb.mem` both hash to `acd4076dfe3843a384f8fa885613484c5e62a9bbcbb5dff4d5bf78b168a22e2f`; `cmp` reports no byte differences. `--owner replay-color` also reports `53760/53760 (100.00%)` exact for both board and zint, with 50184 replayed fragments, 29937 Z-pass updates, and 21590 covered pixels.
|
||||
|
||||
## Board Readback
|
||||
|
||||
After a board dump:
|
||||
|
||||
```sh
|
||||
sudo ./ps2_sh3_sched --zbuf sh3_zsched_epochs.txt --dump-fb sh3_zsched_board_fb.mem
|
||||
scp terasic@192.168.50.161:~/sh3_zsched_board_fb.mem sim/data/top_psmct32_raster_demo/
|
||||
python3 tools/gs_fb_to_png.py sim/data/top_psmct32_raster_demo/sh3_zsched_board_fb.mem \
|
||||
sim/data/top_psmct32_raster_demo/sh3_zsched_board_fb.png 256 210 3
|
||||
make -C sim sh3_zsched_board_compare
|
||||
```
|
||||
|
||||
Optional oracle diagnostic maps:
|
||||
|
||||
```sh
|
||||
make -C sim tb_top_psmct32_sh3_zsched
|
||||
python3 tools/analyze_zsched_fb.py sim/data/top_psmct32_raster_demo/sh3_zsched_board_fb.mem \
|
||||
--owner replay-color --frags sim/traces/rtl/zsched_frags.txt
|
||||
python3 tools/analyze_zsched_fb.py sim/data/top_psmct32_raster_demo/sh3_zsched_board_fb.mem \
|
||||
--owner replay --frags sim/traces/rtl/zsched_frags.txt --maps
|
||||
```
|
||||
|
||||
The `--owner replay` texture/refmap radius score and `sh3_zsched_board_fb_*oracle_*.png` images are diagnostic only. The hard hardware-vs-RTL readback gate is `make -C sim sh3_zsched_board_compare`; the hard emitted-fragment content check is `--owner replay-color`.
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
CODEX INDEPENDENT VERIFICATION + CLOSE (2026-07-10): Codex re-verified the artifacts himself — RBF sha 9e9c5910
|
||||
matches board provenance; board FB and fresh zint640 FB share sha256 fd21e43f (cmp clean); replay-color
|
||||
307200/307200, 0 mismatches, 0 stray. "Call it closed." TWO WORDING CORRECTIONS (precision): hold slack is
|
||||
exactly 0.000 (met, NOT positive margin); "first-of-its-kind" is a project claim the local evidence cannot
|
||||
prove — state the verified fact instead: native 640x480 persistent-Z for THIS three-draw strong-reject scene
|
||||
on silicon, with scanout/texture/writer/depth paths all participating in the proof. NEXT CHAPTER (Codex):
|
||||
draw-count scaling BEFORE motion — densify toward an SH3 texture cluster while preserving the board-vs-zint
|
||||
gate.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Ch359 audit log — zs640c6: shared-texture RESIDENCY, 2x204-tri lists, native 640x480 persistent Z
|
||||
|
||||
Codex-locked chapter: six SH3 draws sharing ONE PSMT8 texture (tbp=8192/cbp=13888), grouped into TWO ordered
|
||||
204-triangle feeder lists (1843 words each), authentic GEQUAL/ZMSK=0/PSMZ16S, native 640x480. NEW capability:
|
||||
EXPLICIT texture-cache residency — one upload+fill (epoch 0); epoch 1 carries reuse=1 in the descriptor and runs
|
||||
on the resident cache. 408 tris vs Ch358's 122 (3.3x density).
|
||||
|
||||
## Fixture/host/TB stack
|
||||
- Generator --group-size (per-member strip expansion, no phantom bridging tris); shared-texture fail-closed gates
|
||||
(tex idxw + CLUT BYTE-identical across draws; list-local state equality; ZTE=1/ZTST=GEQUAL/ZMSK=0/PSMZ16S decode;
|
||||
native bounds; <=2048 words); ONE relocated CLUT; reuse in descs/params/epochs.txt. EMIT: 2x204/1843 EXACT
|
||||
(Codex's numbers to the digit), crc 0xcf4cae27, ref 21071 covered / 6129 multi px.
|
||||
- Census lesson: strip draws' triangles = nprim-2 (my verts//3 probe was wrong; proven vs zsched 46/58/18).
|
||||
- Host: optional trailing reuse column (back-compat verified); reuse epoch = no tex file, no upload/fill,
|
||||
fail-closed resident CRC/beats register verify. Dry-run rc=0 (zs640c6 AND legacy tables).
|
||||
- TBs zs640c6_cap / zint640c6: 2-epoch arrays + EP_REUSE, reuse-epoch residency assert (fill_crc register),
|
||||
fills==1 hard assert. LESSON: per-scene TB wait budgets scale with tris/epoch (204-tri epochs blew the
|
||||
zs640-calibrated 800k-cycle budgets -> records=172/204 cut-off, cascading counter errors + phantom 65% fidelity).
|
||||
|
||||
## THE FINDING — cold-Z burst vs request FIFO (and the Ch359 RTL change)
|
||||
- zint640c6 @ REQ_DEPTH=256 (Ch358 silicon config): **424 fragment drops, ALL epoch 0** (empty-Z phase: every
|
||||
z_rmw miss = dirty evict = 2x AXI), zero in epoch 1 (Z-reject heavy = clean misses). Scoreboard mismatches
|
||||
(Z 320 / COLOR 316) == drop effects. High-water probe (Codex-corrected: write-domain wbin - gray2bin(rgray_s2),
|
||||
parameterized modulus) saturated 256/256.
|
||||
- Codex-authorized sim-only sweep: depth 512 -> zero drops, ep0 peak **478** (34 slots margin), scoreboard EXACT;
|
||||
depth 1024 -> identical (bounded deterministic burst, not rate-bound).
|
||||
- CODEX DECISION: **REQ_DEPTH=1024** (2.1x headroom for the next density rung; no Z-RMW/scene/SDC/clock change).
|
||||
Changed: de25 top u_zc_emit + the 3 production-equivalent zint TBs; unit/replay depths (16/32) untouched.
|
||||
|
||||
## Verification at depth 1024 (2026-07-10)
|
||||
- Parse audit (QSF file list, exact macro set): clean (only pll/EMIF_Qsys/qsys_top IP).
|
||||
- zc_emit unit PASS; zrop PASS (zsched 93.4/93.7); baseline zint PASS (Z 0/53760, drops=0, golden-identical);
|
||||
zint640 PASS (Z 0/307200, golden-identical); **zint640c6 PASS (ZERO drops, Z 0/307200 + COLOR 0/21032 exact,
|
||||
204/204 records, ONE fill + REUSE verified)**; zs640c6_cap PASS (MULTI=90.2% >= 90 floor, ALL=85.3%
|
||||
scene-dependent reciprocal floor, clut_bad=0 — flagged: floor margin is thin for future regenerations).
|
||||
- Full regression: **282/282 PASS, 0 FAIL** (280 baseline + the two C6 gates now in the run list).
|
||||
|
||||
## Board Proof And Provenance Correction
|
||||
- The first depth-1024 GUI fit met timing, and its board host run passed every transport/runtime gate: 204/204 records
|
||||
in both epochs, one fill plus verified reuse, and zero drops. The board framebuffer nevertheless differed from zint
|
||||
at all 21032 covered pixels while retaining the exact C6 bounds=(84,101)..(340,301). This isolated the failure to
|
||||
color provenance, not geometry, persistent Z, LPDDR transport, or FIFO depth.
|
||||
- Root cause, verified in that fit's synthesis report: the QSF still selected Ch358 `bios_sh3_zs640.mem` and
|
||||
`payload_sh3_zs640.mem`, so the board booted the old CLUT rather than C6's CBP=13888 palette. The C6 fixture and
|
||||
host files were correct; the RBF's boot-image inputs were not.
|
||||
- Corrected fit inputs: `sh3_lpddr_fb_z640c6` now selects `bios_sh3_zs640c6.mem` and
|
||||
`payload_sh3_zs640c6.mem` through `scripts/select_de25_profile.sh`. The REQ_DEPTH=1024 top change remains part of
|
||||
the same compile. No SDC, clock, or Z-RMW change is needed.
|
||||
|
||||
## Handoff
|
||||
Owner: run one full 26.1 GUI compile with the corrected C6 profile, then check STA before loading the RBF. Only after
|
||||
timing is clean: run `scp_zs640c6_to_board.sh` (five files including the reuse-modified `ps2_sh3_sched.c`, recompile
|
||||
on board), then `sudo ./ps2_sh3_sched --zbuf sh3_zs640c6_epochs.txt --dump-fb sh3_zs640c6_board_fb.mem`. Expect
|
||||
`bounds=(84,101)..(340,301)`, retrieve the dump, and run `make -C sim sh3_zs640c6_board_compare`.
|
||||
|
||||
## Closure (2026-07-10)
|
||||
- Quartus 26.1 GUI RBF `ad4e8c9627520dcaba9babf2019ca5b28892799e0500f8f3300f4f2a29b5218c` compiled the corrected
|
||||
`bios_sh3_zs640c6.mem` and `payload_sh3_zs640c6.mem` inputs. STA met: setup +0.095 ns, hold 0.000 ns, recovery
|
||||
+1.042 ns, removal +0.185 ns, minimum pulse width +0.200 ns.
|
||||
- On silicon: both 204-record epochs drained; epoch 0 uploaded/filled the texture and epoch 1 verified resident reuse;
|
||||
zero fragment drops; output bounds `(84,101)..(340,301)`; 21032 nonzero pixels.
|
||||
- `make -C sim sh3_zs640c6_board_compare` passed. The board and zint framebuffers had identical SHA-256
|
||||
`948d9c45df84ccf180faebe7b24e3e4445bcce390c8bfab91fb3b50885fcaa4`, and replay-color was exact at
|
||||
307200/307200 pixels. Ch359 is closed.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Ch360 audit log - zs640c12: 12-draw shared-texture residency at native 640x480 persistent Z
|
||||
|
||||
## Scope
|
||||
|
||||
Scale Ch359's six-draw shared-texture proof to twelve authentic SH3 draws without increasing feeder-list size:
|
||||
|
||||
`119471,119684,119897 / 120110,120323,120536 / 120749,120962,121175 / 121388,121601,121814`
|
||||
|
||||
All draws are PSMT8 `tbp=8192`, share the byte-identical resident CLUT at `cbp=13888`, have identical feeder-visible
|
||||
state, and use authentic `ZTE=1`, `GEQUAL`, `ZMSK=0`, `PSMZ16S`. They form four ordered 204-triangle / 1843-word
|
||||
epochs: one LPDDR texture upload/fill followed by three fail-closed cache reuses.
|
||||
|
||||
## Fixture And Fidelity Decision
|
||||
|
||||
- The generator preflight passed native 640x480 bounds, signed-Q legality, state equality, shared texture/CLUT bytes,
|
||||
and all four feeder-list capacities.
|
||||
- Per-triangle auto PSCALE failed the content fidelity gate: isolated epochs 2/3 were 79.4%/81.5% and the full
|
||||
multi-epoch score was 83.6%.
|
||||
- Fixed `PSCALE=1024` for every C12 epoch corrected that host-fixture range choice without RTL: isolated epochs 2/3
|
||||
reached 92.0%/91.1%, while the full capture gate reached ALL=93.4% and MULTI=95.0%, with `clut_bad=0`.
|
||||
- C12's BIOS and payload comment lines differ from C6, but their non-comment memory words hash identically. The
|
||||
existing Ch359 signoff RBF therefore already contains the correct C12 bootlet contents; no QSF change or GUI fit.
|
||||
|
||||
## Simulation Proof
|
||||
|
||||
- Capture/residency: four `204/204` records, one fill, three verified reuses, four fresh drains, no writer overflow,
|
||||
exact 38400 scanout beats/frame.
|
||||
- Real-raster Z integration at `REQ_DEPTH=1024`: 151160 accepted fragments, 70796 Z passes, zero drops, four ordered
|
||||
scene markers/drains, and exact scoreboards (Z 0/307200, COLOR 0/36022).
|
||||
- Request-FIFO high-water by epoch: 478, 27, 416, 225. The 1024-depth production FIFO remains sufficient; no depth,
|
||||
Z-RMW, LPDDR, clock, SDC, or RTL change is warranted.
|
||||
|
||||
## Board Closure (2026-07-10)
|
||||
|
||||
- The Ch359 signoff RBF `ad4e8c9627520dcaba9babf2019ca5b28892799e0500f8f3300f4f2a29b5218c` remained loaded and was
|
||||
provenance-valid for C12 because the bootlet memory words are identical.
|
||||
- Board host gates: four `204/204` drains, one fill plus three verified reuses, zero drops, 27041 framebuffer beats,
|
||||
and output bounds `(84,94)..(367,385)` with 36022 nonzero pixels.
|
||||
- Board and zint framebuffer SHA-256 matched exactly:
|
||||
`1309fa4f307b9313231797c75973e5a42108460c19ec0a0c576d4da597d6303e`.
|
||||
- Replay-color: 151160 fragments, 70796 persistent-Z updates, 36022 covered pixels, no stray coverage, and
|
||||
`307200/307200` exact framebuffer pixels. Ch360 is closed.
|
||||
|
||||
## Next Direction
|
||||
|
||||
Keep draw-count scaling before motion, but first turn the C12 four-epoch test copies into one parameterized
|
||||
shared-texture residency harness. The next density rung should then be selected from the same census and must retain
|
||||
the fixed-1024 fixture contract unless a measured sweep proves another scale better for the chosen draws.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Ch361 audit log -- C18 draw-count scaling
|
||||
|
||||
## Scope
|
||||
|
||||
Eighteen authentic, in-bounds SH3 PSMT8 draws were grouped into six ordered 204-triangle epochs at native 640x480. They share `tbp=8192`, `cbp=13888`, byte-identical texture/CLUT contents, and authentic `ZTE=1`, `GEQUAL`, `ZMSK=0`, `PSMZ16S` state.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Fixture preflight passed; fixed `PSCALE=1024` and rounded XY were retained.
|
||||
- Capture gate passed: ALL `44890/49149` (91.3%), MULTI `24969/26680` (93.6%), `clut_bad=0`, one fill plus five reuses, six fresh drains, no overflow or underflow.
|
||||
- Real Z integration passed: 205744 fragments, 103300 Z passes, zero drops, exact Z `0/307200` and color `0/49071`.
|
||||
- Board host gate passed: six 204-record epochs, one fill, five resident reuses, zero drops, 49071 nonzero pixels.
|
||||
- Board framebuffer and Z integration framebuffer SHA-256: `a0eda56ef0140749451078a0fc82d85ea6e3342734dacdc22dd93f0a56dbb539`.
|
||||
- Replay-color is exact: `307200/307200`; 205744 fragments, 103300 Z-pass updates, 49071 covered pixels.
|
||||
|
||||
## Result
|
||||
|
||||
Ch361 is closed on silicon with no RTL, SDC, QSF, or RBF change from the C6-signoff core.
|
||||
@@ -0,0 +1,19 @@
|
||||
# Ch362 audit log -- C24 draw-count scaling
|
||||
|
||||
## Scope
|
||||
|
||||
Twenty-four authentic SH3 draws were grouped into eight ordered 204-triangle epochs at native 640x480. The original next candidate `idx131306` was rejected before emission because its authentic Y extent reached 610; `idx132158` replaced it. The retained list stays in-bounds (`x=82..569`, `y=84..400`) and shares the C18 texture, CLUT, and authentic depth state.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Fixture preflight passed with one shared texture/CLUT, fixed `PSCALE=1024`, and rounded XY.
|
||||
- Capture gate passed: ALL `69277/73473` (94.3%), MULTI `34636/36352` (95.3%), `clut_bad=0`, one fill plus seven reuses, eight fresh drains, no overflow or underflow.
|
||||
- Real Z integration passed: 346425 fragments, 167247 Z passes, zero drops, exact Z `0/307200` and color `0/73330`.
|
||||
- New epoch request highs: epoch 6 = 330, epoch 7 = 234; both are bounded below the 1024-entry request FIFO.
|
||||
- Board host gate passed: eight 204-record epochs, one fill, seven resident reuses, zero drops, 73330 nonzero pixels.
|
||||
- Board framebuffer and Z integration framebuffer SHA-256: `6614d7211b9a668cfeda12e4fa2d6f469d3ee4d3a10bdf56c0119b35f93c7803`.
|
||||
- Replay-color is exact: `307200/307200`; 346425 fragments, 167247 Z-pass updates, 73330 covered pixels.
|
||||
|
||||
## Result
|
||||
|
||||
Ch362 is closed on silicon with no RTL, SDC, QSF, or RBF change from the C6-signoff core.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Ch363 Audit Log - Five-Texture Persistent-Z Scheduler
|
||||
|
||||
## Scope
|
||||
|
||||
- Native 640x480 persistent-Z scene with five ordered authentic SH3 draws:
|
||||
`5328,11671,77112,89164,119471`.
|
||||
- Five distinct texture/CLUT bindings, relocated at CBP `480,484,488,492,496`.
|
||||
- The cache is intentionally refilled for every epoch; this chapter proves rebinds rather than shared-texture residency.
|
||||
|
||||
## Root Cause And Fix
|
||||
|
||||
- The generated five-CLUT bootlet is 350 qwords. The shared simulation harness had inherited the 256-qword EE RAM default, so `$readmemh` truncated the payload. Epoch 3 consequently read partial CLUT data and produced 195 palette-invalid pixels.
|
||||
- The production `GS_SH3_LPDDR_FB` board profile already allocates 32 KiB of EE RAM. Both shared 640 harnesses now explicitly use that same `RAM_SIZE_BYTES(32 * 1024)` capacity.
|
||||
- The earlier CLAMP investigation was rejected by trace evidence: all sampled epoch-2/3/4 coordinates were within the 512x512 texture bounds. No feeder or sampler RTL change is retained.
|
||||
|
||||
## Simulation Gates
|
||||
|
||||
- `tb_top_psmct32_sh3_zs640mt5_cap`: PASS.
|
||||
- Five texture CRC fills: `55070afa`, `26a88b77`, `a727234d`, `fbdeaa32`, `cf4cae27`.
|
||||
- Five fresh drains, records `54,68,68,68,68`, no writer overflow or scanout underflow.
|
||||
- Scanout: exactly 38,400 beats/frame.
|
||||
- Oracle: ALL `61595/63749` (96.6%), MULTI `7701/7877` (97.8%), `clut_bad=0`.
|
||||
- `tb_top_psmct32_sh3_zint640mt5`: PASS.
|
||||
- Z preclear: 19,200 beats.
|
||||
- 129,752 fragments fed, 118,355 Z passes, zero fragment drops.
|
||||
- Exact final scoreboards: Z `0/307200` mismatch; COLOR `0/63617` mismatch.
|
||||
- Request FIFO depth 1024 high-water by epoch: `415,401,64,222,47`.
|
||||
|
||||
## GUI Fit And Board Closure
|
||||
|
||||
- The authoritative QSF points to `bios_sh3_zs640mt5.mem` and `payload_sh3_zs640mt5.mem`; the Quartus 26.1 flow report and synthesis report both resolve those exact images.
|
||||
- The July 11 GUI compile is signoff-clean: setup `+0.095 ns`, hold `0.000 ns`, recovery `+1.042 ns`, removal `+0.185 ns`, and minimum pulse width `+0.200 ns`. The generated `retroDE_ps2.core.rbf` was written after the QSF update.
|
||||
- The RBF loaded successfully on the DE25 (`fpga0: operating`). The five-epoch host run passed all transfer, CRC, preclear, drain, and zero-drop gates. Its final framebuffer summary was `nonzero=63617`, bounds `(36,10)..(562,360)`.
|
||||
- The board framebuffer and a fresh `tb_top_psmct32_sh3_zint640mt5` dump have identical SHA-256: `9e87678c0c88e3e2e90a187e69991069d58e88187d360d560df59f25219b99c5`.
|
||||
- Independent replay-color verification is exact: `307200/307200` pixels, zero mismatches. Ch363 is closed: five authentic SH3 draws, five texture/CLUT rebinds, native 640x480 scanout, and persistent-Z are proven on silicon for this fixture.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Ch364 Audit Log - Mixed Texture Rebind And Residency
|
||||
|
||||
## Scope
|
||||
|
||||
- Native 640x480 persistent-Z composite of 28 ordered authentic SH3 draws.
|
||||
- Four early single-draw texture/CLUT rebind epochs (`5328`, `11671`, `77112`, `89164`) followed by the 24-draw
|
||||
`tbp=8192` cluster in eight 204-triangle feeder lists.
|
||||
- Twelve epochs total: five upload/fill operations and seven consecutive, fail-closed verified reuses of the final
|
||||
resident texture.
|
||||
|
||||
## Fixture Contract
|
||||
|
||||
- `gs_make_sh3_scheduler_fixture.py` now accepts `--group-sizes`, an explicit ordered epoch partition. Every
|
||||
multi-draw group must have identical feeder-visible state and byte-identical texture/CLUT data; reuse is emitted
|
||||
only when the immediately preceding descriptor leaves those same bytes resident.
|
||||
- The selected partition is `1,1,1,1,3,3,3,3,3,3,3,3`. It passed authentic ordering, native bounds, state,
|
||||
texture/CLUT, staging-capacity, and depth-state gates.
|
||||
- The Ch364 BIOS and payload memory words hash identically to Ch363 MT5. The existing GUI-fitted RBF is therefore
|
||||
provenance-valid; no RTL, QSF, SDC, GUI compile, or RBF reload was required.
|
||||
|
||||
## Simulation Proof
|
||||
|
||||
- Capture/residency: PASS. Five CRC-verified fills, seven verified reuses, 12 ordered fresh drains, no writer
|
||||
overflow or scanout underflow, and exactly 38,400 scanout beats/frame.
|
||||
- Texture oracle: ALL `105761/110544` (95.7%), MULTI `40756/42861` (95.1%), `clut_bad=0`.
|
||||
- Real Z integration: PASS. 465,250 fragments fed, 214,897 persistent-Z updates, zero drops, 12 markers/drains,
|
||||
exact Z `0/307200`, and exact color `0/110324`.
|
||||
- Request FIFO high-water by epoch: `415,401,64,222,341,21,112,166,72,176,311,240`; all remain bounded below the
|
||||
1024-entry production FIFO.
|
||||
|
||||
## Board Closure
|
||||
|
||||
- Board host gate: all five texture uploads passed CRC, all seven cache reuses verified the resident CRC, all 12
|
||||
drains returned their expected records, and every epoch reported zero fragment drops.
|
||||
- Final board framebuffer: 110,324 nonzero pixels, bounds `(36,10)..(568,399)`, sum `0x61884052`, xor `0x802cf68e`.
|
||||
- Board and zint framebuffer SHA-256 match exactly:
|
||||
`fdff2f34eac22ee140b64d8fac129627549bbb0f6db37d4b91807a9058e47a04`.
|
||||
- Replay-color is exact: 465,250 fragments, 214,897 Z-pass updates, 110,324 covered pixels, no stray coverage, and
|
||||
`307200/307200` exact framebuffer pixels.
|
||||
|
||||
## Result
|
||||
|
||||
Ch364 is closed on silicon: 28 authentic SH3 draws, five texture/CLUT bindings, seven verified residency reuses,
|
||||
native 640x480 scanout, and persistent depth all agree with integration simulation and the independent replay oracle.
|
||||
@@ -0,0 +1,44 @@
|
||||
# Ch365 Audit Log - Two-Frame Motion Sequence
|
||||
|
||||
## Scope
|
||||
|
||||
- Native 640x480 persistent-Z presentation of two adjacent authentic SH3 capture states.
|
||||
- Frame A is Ch364's 28-draw mixed-rebind/residency composite (`zs640m28`); frame B is the adjacent capture's
|
||||
24-draw texture cluster (`zs640b24`).
|
||||
- The production bootlet preloads the union of their six relocated CLUTs at CBPs `480,484,488,492,496,500`.
|
||||
- The host sequencer clears color and Z at every frame boundary, then presents the A/B tables in order.
|
||||
|
||||
## Compile Provenance
|
||||
|
||||
- The GUI build loaded `bios_sh3_zs640motionab.mem` and `payload_sh3_zs640motionab.mem`.
|
||||
- Quartus reports `Timing requirements were met`: setup `+0.095 ns`, hold `0.000 ns`, recovery `+1.042 ns`,
|
||||
removal `+0.185 ns`, and minimum pulse width `+0.200 ns`.
|
||||
- The loaded RBF was produced after the motion bootlet and QSF inputs.
|
||||
|
||||
## Frame-B Simulation And Board Proof
|
||||
|
||||
- Capture/residency: PASS. One CRC-verified fill, seven verified reuses, eight ordered fresh drains, no writer
|
||||
overflow or scanout underflow, and 38,400 scanout beats/frame.
|
||||
- Texture oracle: ALL `101111/108647` (93.1%), MULTI `66968/69063` (97.0%), `clut_bad=0`.
|
||||
- Persistent-Z integration: PASS. 664,865 fragments fed, 252,657 Z updates, zero drops, exact Z `0/307200`, and
|
||||
exact color `0/108435`. Per-epoch request-FIFO high-water was `546,297,393,498,32,572,617,592`, below the
|
||||
1024-entry production depth.
|
||||
- Board host gate: all eight drains were fresh with 204 records, the one fill and all seven reuses passed CRC,
|
||||
and every epoch reported zero fragment drops.
|
||||
- Board framebuffer: 108,435 nonzero pixels, bounds `(12,128)..(633,469)`, sum `0xdd9faa5a`, xor `0x80e70a5e`.
|
||||
- Board and integration-simulation framebuffer SHA-256 match exactly:
|
||||
`3191d75983e72a158f91f15cc1f57b6ff7c5e40d5bbb4a49957db06db4e2fded`.
|
||||
- Replay-color is exact: 664,865 fragments, 252,657 Z-pass updates, 108,435 covered pixels, no stray coverage,
|
||||
and `307200/307200` exact framebuffer pixels.
|
||||
|
||||
## Two-Way Sequencer Gate
|
||||
|
||||
- A one-loop run established the A-to-B boundary and captured the final B framebuffer above.
|
||||
- A subsequent two-loop run exercised A-to-B, B-to-A, A-to-B again. All 40 epoch drains were fresh, all expected
|
||||
record counts matched, every texture fill/reuse CRC gate passed, and every fragment-drop gate remained zero.
|
||||
|
||||
## Result
|
||||
|
||||
Ch365 is closed on silicon: two authentic 640x480 persistent-Z frame states are sequenced in both directions by the
|
||||
host without reconfiguration. Each endpoint has independent integration-simulation and replay-oracle framebuffer
|
||||
proof, and the hardware frame-boundary protocol has passed across a full A/B/A/B loop.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Ch367 Audit Log - Runtime CLUT At 24 Draws
|
||||
|
||||
## Scope
|
||||
|
||||
Join the established native-640x480 24-draw shared-texture cluster to the runtime CLUT transport. The fixture has
|
||||
eight ordered 204-record epochs, one texture fill, seven CRC-verified residency reuses, and a host runtime palette
|
||||
copy before every epoch.
|
||||
|
||||
## FIFO Sizing
|
||||
|
||||
- At request depth 1024, the runtime fixture removes the boot-time CLUT-loader throttle and epoch 2 dropped 19
|
||||
fragments after the high-water counter saturated at 1024.
|
||||
- At depth 2048, epoch 2 accepted all 58,861 fragments at high-water 1041. Integration simulation also passed
|
||||
epochs 0 through 6 with zero drops; epoch 5 was the largest observed simulation burst at 1855.
|
||||
- The DE25 top therefore changes only `u_zc_emit` request depth from 1024 to 2048. No clock, SDC, or protocol
|
||||
change is involved; `zc_g_drops` remains the fail-closed hardware guard.
|
||||
|
||||
## GUI Fit And Board Gate (2026-07-12)
|
||||
|
||||
- Quartus 26.1 STA finished at 08:40:47 and met every requirement: setup +0.090 ns, hold 0.000 ns, recovery
|
||||
+1.043 ns, removal +0.201 ns, and minimum pulse width +0.200 ns.
|
||||
- The 08:41 core RBF SHA-256 is `8e3fa2b8b14de9b4660a542ec7ffed5c59353ec8583458f31339a4b4183f42d2`; fit reports
|
||||
the request FIFO as a 2048 x 74 dual-clock M20K implementation.
|
||||
- The RBF was SHA-verified on the DE25 and loaded through `core_loader.sh`; `fpga0` reported `operating` and the
|
||||
overlay reported `applied`.
|
||||
- Board scheduler gate: all eight 204-record epochs drained freshly; one texture CRC-verified fill and seven
|
||||
resident CRC checks passed; every runtime palette sum was `0x47097d4c`; every epoch reported zero drops.
|
||||
- Board dump: 73,330 nonzero pixels, bounds `(84,85)..(568,399)`, sum `0xc521381a`, xor `0x8021455e`.
|
||||
|
||||
## Exact Closure
|
||||
|
||||
- The trace-enabled integration run passed all eight epochs: 346,425 accepted fragments, 167,247 persistent-Z
|
||||
updates, eight scene markers/drains, zero drops, and exact local scoreboards (Z `0/307200`, color `0/73330`).
|
||||
- The highest simulated request-FIFO occupancy was 1855 in epoch 5; the final epoch reached 1156. Both remain below
|
||||
the production 2048 entries and agree with the board's zero-drop counters.
|
||||
- Board and integration-simulation framebuffers are byte-identical with SHA-256
|
||||
`6614d7211b9a668cfeda12e4fa2d6f469d3ee4d3a10bdf56c0119b35f93c7803`.
|
||||
- Replay-color is exact at `307200/307200` pixels: 346,425 fragments, 167,247 Z-pass updates, 73,330 covered
|
||||
pixels, and zero uncovered writes.
|
||||
|
||||
## Result
|
||||
|
||||
Ch367 is closed on silicon: 24 authentic SH3 draws, runtime CLUT staging on every epoch, one texture fill plus
|
||||
seven verified resident reuses, native 640x480 scanout, and persistent depth all agree with integration simulation
|
||||
and the independent replay oracle.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Ch368 Audit Log - Runtime CLUT Adjacent-Frame Motion
|
||||
|
||||
## Scope
|
||||
|
||||
Add the adjacent SH3 capture frame to the established 24-draw runtime-CLUT path, then prove A/B motion with the
|
||||
same native-640x480 persistent-Z, board-versus-simulation, and replay-color gates used by Ch367.
|
||||
|
||||
## Frame-B Capacity Measurement
|
||||
|
||||
- Frame B is the 24-draw shared-texture cluster from capture `20260624224121`, emitted as `zsrtb24`: eight ordered
|
||||
204-record epochs, one texture fill, seven CRC-verified reuses, and runtime palette staging before every epoch.
|
||||
- At request depth 2048, epoch 3 saturated the request FIFO and dropped 151 fragments. This is a bounded-capacity
|
||||
failure, not a board candidate.
|
||||
- A complete depth-4096 integration run passed all eight epochs with exact Z and color scoreboards: Z `0/307200`,
|
||||
color `0/108435`, zero drops, and 664,865 accepted fragments.
|
||||
- Per-epoch request-FIFO high water: 1060, 1074, 1431, 2198, 68, 3610, 2993, and 3340. The measured maximum is
|
||||
3610, leaving 486 entries of headroom at depth 4096.
|
||||
|
||||
## Production Change
|
||||
|
||||
- The DE25 top changes only `u_zc_emit` request depth from 2048 to 4096. No clock, SDC, or protocol change is
|
||||
involved. The existing `zc_g_drops` counter remains the fail-closed board guard.
|
||||
- Focused regressions pass after the source change: `tb_gs_lpddr_zc_emit`, `tb_clut_stage_cdc`, and
|
||||
`tb_top_psmct32_runtime_clut`. The complete `zsrtb24` depth-4096 integration run is the capacity and exactness
|
||||
proof for this value.
|
||||
|
||||
## First GUI Fit And Response-Ready Cut
|
||||
|
||||
- The first 4096-entry GUI fit failed setup only: WNS `-0.063 ns`, TNS `-0.126 ns`; hold and every other signoff
|
||||
class remained clean. The six failing paths terminated at the EMIF write-response FIFO.
|
||||
- The two launch families were the Z-RMW `bready` and write-arbiter `grant` controls, both feeding the arbiter's
|
||||
live `m_bready` mux. The arbiter now registers response-ready from the final W handshake, removing that live
|
||||
grant/client-ready cone while retaining the selected transaction through B acceptance.
|
||||
- The response-path regression is clean: `tb_gs_lpddr_wr_arb` passes its priority/transaction checks and
|
||||
`tb_gs_lpddr_zc_emit` passes three complete Z/color drains. The full `zsrtb24` depth-4096 integration gate also
|
||||
passes after the cut: 664,865 accepted fragments, zero drops, Z `0/307200`, and color `0/108435`.
|
||||
- At that point, the pending gate was one full Quartus 26.1 GUI compile; the board remained on the Ch367-proven RBF
|
||||
until STA was clean.
|
||||
|
||||
## Corrective GUI Fit And Silicon Proof
|
||||
|
||||
- Quartus 26.1 STA completed at 15:53 with timing requirements met: setup `+0.076 ns`, hold `0.000 ns`, recovery
|
||||
`+1.045 ns`, minimum pulse width `+0.200 ns`, and zero TNS. The fitted request FIFO is a 4096 x 74 dual-clock
|
||||
M20K implementation using 16 M20Ks. Core SHA-256: `b146503317ba8268fee06a83b2650cdf57cb79e64da3b6b5aa6a22e9b356cf60`.
|
||||
- The RBF was SHA-verified on the DE25 and loaded through `core_loader.sh`; `fpga0` reported `operating`.
|
||||
- Frame B board gate passed all eight 204-record epochs: one texture fill plus seven resident CRC reuses, eight
|
||||
runtime palette copies, fresh drains, and zero drops. Its board framebuffer is byte-identical to integration
|
||||
simulation at SHA-256 `3191d75983e72a158f91f15cc1f57b6ff7c5e40d5bbb4a49957db06db4e2fded`; replay-color is exact
|
||||
at `307200/307200` pixels.
|
||||
|
||||
## A/B Motion Closure
|
||||
|
||||
- The host ran `A -> B -> A -> B` with a fresh color/Z preclear, texture fill, runtime palette staging, and eight
|
||||
ordered drains for every frame. All 32 epochs reported zero drops.
|
||||
- The four board boundary dumps alternate exactly: A dumps 0 and 2 hash to
|
||||
`6614d7211b9a668cfeda12e4fa2d6f469d3ee4d3a10bdf56c0119b35f93c7803`; B dumps 1 and 3 hash to
|
||||
`3191d75983e72a158f91f15cc1f57b6ff7c5e40d5bbb4a49957db06db4e2fded`. Each equals its matching integration
|
||||
framebuffer byte-for-byte.
|
||||
- Independent replay-color checks are exact for both alternating frames: A is `307200/307200` over 346,425
|
||||
fragments and B is `307200/307200` over 664,865 fragments.
|
||||
|
||||
## Result
|
||||
|
||||
Ch368 is closed on silicon: native-640x480 persistent-Z runtime-CLUT motion between two adjacent authentic SH3
|
||||
captures, with deterministic A/B/A/B board outputs, exact integration framebuffers, and exact replay-color evidence.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Ch369 Audit Log - Runtime CLUT Mixed-Residency Expansion
|
||||
|
||||
## Scope
|
||||
|
||||
Extend the Ch368 runtime-CLUT motion content ladder with the native-640x480 28-draw mixed-residency SH3 frame:
|
||||
four distinct texture/CLUT rebinds followed by the established eight-epoch shared-texture cluster.
|
||||
|
||||
## Fixture Preflight
|
||||
|
||||
- `zsrtm28` contains 28 authentic draws in 12 ordered epochs: four single-draw rebinds, then eight 204-triangle
|
||||
shared-texture epochs.
|
||||
- Native coordinates remain in bounds at x `35..569`, y `9..400`; every feeder list is within the 2048-word staging
|
||||
capacity.
|
||||
- Runtime palette staging is enabled for every epoch. The candidate is simulation-only until request pressure and
|
||||
exact Z/color scoreboards pass at the Ch368 production depth.
|
||||
|
||||
## Integration Gate
|
||||
|
||||
- The full 12-epoch runtime-CLUT integration passes at request depth 4096: 465,250 accepted fragments, 214,897
|
||||
persistent-Z updates, 12 fresh drains, zero drops, Z `0/307200`, and color `0/110324`.
|
||||
- Per-epoch request-FIFO high-water values are 1895, 1468, 110, 432, 797, 85, 650, 381, 184, 1669, 616, and 1125.
|
||||
The measured maximum is 1895, so the Ch368 core requires no RTL, timing, or fit change for this candidate.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- The board host gate passes all 12 epochs: four texture fills/rebinds, eight resident reuses, twelve runtime palette
|
||||
copies, fresh ordered drains, and zero fragment drops.
|
||||
- Board and integration framebuffers are byte-identical at SHA-256
|
||||
`fdff2f34eac22ee140b64d8fac129627549bbb0f6db37d4b91807a9058e47a04`.
|
||||
- Replay-color is exact at `307200/307200`: 465,250 fragments, 214,897 Z-pass updates, 110,324 covered pixels, and
|
||||
no stray uncovered writes.
|
||||
|
||||
## Result
|
||||
|
||||
Ch369 is closed on silicon: 28 authentic SH3 draws at native 640x480 with runtime CLUT updates, four real texture
|
||||
rebinds, persistent Z, and exact board/simulation/replay agreement, all on the Ch368 core with no further fit.
|
||||
|
||||
## Mixed-Residency Motion Extension
|
||||
|
||||
- The same core ran `zsrtm28 -> zsrtb24 -> zsrtm28 -> zsrtb24`, resetting color/Z and staging the appropriate
|
||||
textures and runtime palettes for every frame boundary. All 40 epoch drains were fresh and all drop gates stayed
|
||||
zero.
|
||||
- The four boundary dumps alternate exactly: mixed-residency dumps 0 and 2 equal
|
||||
`fdff2f34eac22ee140b64d8fac129627549bbb0f6db37d4b91807a9058e47a04`; adjacent-frame dumps 1 and 3 equal
|
||||
`3191d75983e72a158f91f15cc1f57b6ff7c5e40d5bbb4a49957db06db4e2fded`. Each matches its independently closed
|
||||
integration framebuffer byte-for-byte.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Ch370 Audit Log - Runtime CLUT Frame C
|
||||
|
||||
## Scope
|
||||
|
||||
Convert the established 24-draw Frame C cluster to host-staged runtime CLUT updates, retaining its distinct relocated
|
||||
CBP `504` and proving it on the fitted Ch368 depth-4096 core.
|
||||
|
||||
## Fixture and Integration
|
||||
|
||||
- `zsrtc24` contains eight ordered 204-triangle epochs from the authentic Frame C draw set. Epoch 0 fills texture CRC
|
||||
`0xcf4cae27`; epochs 1 through 7 verify that CRC as resident texture reuses. Every epoch stages its palette through
|
||||
the runtime HPS path.
|
||||
- Native geometry stays within x `35..569`, y `9..400`; each feeder list is 1,843 words, below the 2,048-word
|
||||
staging capacity.
|
||||
- The depth-4096 traced integration gate passes: 346,425 accepted fragments, 167,247 persistent-Z updates, eight
|
||||
fresh drains, zero drops, Z `0/307200`, and color `0/73330`. Per-epoch request FIFO high-water values are 948,
|
||||
131, 1041, 374, 377, 1855, 606, and 1156. The maximum 1855 stays well below the fitted 4096-entry depth.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- The board host run completed all eight runtime palette copies, one texture fill, seven resident-CRC reuses, fresh
|
||||
ordered drains, and zero fragment drops.
|
||||
- Board and traced-integration framebuffers are byte-identical at SHA-256
|
||||
`6614d7211b9a668cfeda12e4fa2d6f469d3ee4d3a10bdf56c0119b35f93c7803`.
|
||||
- Replay-color is exact at `307200/307200`: 346,425 fragments, 167,247 Z-pass updates, 73,330 covered pixels, and
|
||||
no uncovered writes.
|
||||
|
||||
## Result
|
||||
|
||||
Ch370 closes Frame C on silicon with runtime CLUT staging and persistent Z. No RTL, constraint, or Quartus fit change
|
||||
was required; the current Ch368 core carries this third runtime scene within its measured request-FIFO envelope.
|
||||
|
||||
## Three-State Motion Extension
|
||||
|
||||
- The same loaded core ran `zsrtm28 -> zsrtc24 -> zsrtb24 -> zsrtm28 -> zsrtc24 -> zsrtb24`, with color/Z reset and
|
||||
the appropriate texture and runtime palette staged at every frame boundary.
|
||||
- The six boundary dumps match the independently closed integration framebuffers exactly: M28 dumps 0 and 3 hash to
|
||||
`fdff2f34eac22ee140b64d8fac129627549bbb0f6db37d4b91807a9058e47a04`; Frame C dumps 1 and 4 hash to
|
||||
`6614d7211b9a668cfeda12e4fa2d6f469d3ee4d3a10bdf56c0119b35f93c7803`; Frame B dumps 2 and 5 hash to
|
||||
`3191d75983e72a158f91f15cc1f57b6ff7c5e40d5bbb4a49957db06db4e2fded`.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Ch371 Audit Log - Earlier-Capture Runtime CLUT Probe
|
||||
|
||||
## Scope
|
||||
|
||||
Qualify the first on-screen PSMT8/perspective cluster from the earlier SH3 capture (`20260624224047`) through the
|
||||
runtime CLUT, persistent-Z, and depth-4096 request path.
|
||||
|
||||
## Fixture and Integration
|
||||
|
||||
- `zsrte3` retains three authentic chronological draws as two ordered epochs: 68 triangles followed by 136 triangles.
|
||||
It fills texture CRC `0x2d9a2fda` once, then proves a resident reuse. The relocated runtime CLUT base is CBP `508`.
|
||||
- Geometry is in bounds at x `64..440`, y `44..471`; feeder lists are 619 and 1,231 words, both below the 2,048-word
|
||||
staging limit.
|
||||
- The traced integration gate passes at depth 4096: 279,804 accepted fragments, 251,464 Z-pass updates, two fresh
|
||||
drains, zero drops, Z `0/307200`, and color `0/106017`. Request FIFO high-water is 454 then 2,055, below the fitted
|
||||
4096-entry capacity.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- The board completed one runtime palette copy, one texture fill, one verified resident reuse, two fresh drains, and
|
||||
zero fragment drops.
|
||||
- Board and traced-integration framebuffers are byte-identical at SHA-256
|
||||
`1f060fc17bd0a41e02ae79303b1ffef88a05ff53b2cddde400de1ff2b796bbf4`.
|
||||
- Replay-color is exact at `307200/307200`: 279,804 fragments, 251,464 Z-pass updates, 106,017 covered pixels, and
|
||||
no uncovered writes.
|
||||
|
||||
## Result
|
||||
|
||||
Ch371 closes the first earlier-capture runtime-CLUT probe on silicon. The 2,055-entry peak retains substantial margin
|
||||
inside the fitted 4,096-entry request FIFO, so the next rung is an in-cluster draw-count expansion rather than RTL.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Ch372 Audit Log - Earlier-Capture Six-Draw Expansion
|
||||
|
||||
## Integration
|
||||
|
||||
- `zsrte6` groups six chronological authentic draws from capture `20260624224047` into two 204-triangle epochs.
|
||||
It performs one runtime palette/texture fill followed by one CRC-verified resident reuse at CBP `508`.
|
||||
- Native geometry remains in bounds at x `63..443`, y `40..471`; both feeder lists are 1,843 words.
|
||||
- Depth-4096 traced integration passes: 446,447 accepted fragments, 373,770 persistent-Z updates, two fresh drains,
|
||||
zero drops, Z `0/307200`, and color `0/123384`. Request-FIFO high-water is 2,090 then 940.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- The board completed the runtime palette copy, one texture fill, one verified resident reuse, two fresh drains, and
|
||||
zero fragment drops.
|
||||
- Board and integration framebuffers are byte-identical at SHA-256
|
||||
`1b82b94c232907acd037a47c22cbf6262eba6ba73ed25399cb0a4373ef388869`.
|
||||
- Replay-color is exact at `307200/307200`: 446,447 fragments, 373,770 Z-pass updates, 123,384 covered pixels, and
|
||||
no uncovered writes.
|
||||
|
||||
## Result
|
||||
|
||||
Ch372 closes the six-draw earlier-capture expansion on silicon with no RTL, constraint, or fit change.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Ch373 Audit Log - Earlier-Capture Eight-Draw Expansion
|
||||
|
||||
## Fixture
|
||||
|
||||
- `zsrte8` groups eight chronological authentic draws from capture `20260624224047` into three
|
||||
runtime-CLUT epochs: 204, 204, and 90 triangles.
|
||||
- Epoch 0 performs the texture fill; epochs 1 and 2 perform CRC-verified resident reuse at CBP `508`.
|
||||
- Native geometry is bounded by x `63..443`, y `40..471`. The feeder lists are 1,843, 1,843, and 817 words.
|
||||
|
||||
## Integration Gate
|
||||
|
||||
- Depth-4096 integration and independent trace runs both pass with 520,733 accepted fragments,
|
||||
429,471 persistent-Z updates, three fresh drains, and zero drops.
|
||||
- The exact scoreboards report Z `0/307200` and color `0/128277` mismatches.
|
||||
- Request-FIFO high-water is bounded at 2,090, 940, and 1,757 requests across the three epochs,
|
||||
below the production depth of 4,096.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- The DE25 completed one texture fill, two CRC-verified resident reuses, all 498 expected draw records, and
|
||||
zero fragment drops. Its framebuffer reports 128,277 nonzero pixels in bounds `(65,41)..(443,470)`.
|
||||
- Board and integration framebuffers are byte-identical at SHA-256
|
||||
`3a2395cc0d4829560016aeac852b029ba46248ee1dcae3d74d541a64688b2a32`.
|
||||
- The complete 520,733-fragment trace independently replays to the board framebuffer exactly:
|
||||
429,471 Z-pass updates, 128,277 covered pixels, zero uncovered writes, and `307200/307200` exact colors.
|
||||
|
||||
## Result
|
||||
|
||||
Ch373 closes the earlier-capture eight-draw expansion on silicon with no RTL, constraint, or fit change.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Ch374 Audit Log - Earlier-Capture Eleven-Draw Rebind Expansion
|
||||
|
||||
## Fixture
|
||||
|
||||
- `zsrte11` keeps Ch373's eight chronological draws as three runtime-CLUT epochs, then adds draws
|
||||
`11698`, `11911`, and `11938` as a fourth 142-triangle epoch.
|
||||
- The scene runs at native 640x480 and allocates two runtime palette banks: CBP `504` for epochs 0-2
|
||||
and CBP `508` for epoch 3. The residency pattern is `fill, reuse, reuse, fresh fill`.
|
||||
- Feeder lists contain 1,843, 1,843, 817, and 1,285 words, each below the 4,096-word bridge capacity.
|
||||
|
||||
## Integration Gate
|
||||
|
||||
- Depth-4096 integration passes with 524,145 accepted fragments, 431,666 persistent-Z updates, four fresh drains,
|
||||
and zero drops.
|
||||
- Epoch request-FIFO high-water is 2,090, 940, 1,757, and 100. Exact scoreboards report Z `0/307200` and
|
||||
color `0/129883` mismatches.
|
||||
|
||||
## Board Host Gate
|
||||
|
||||
- The DE25 completed the two texture fills, two resident CRC checks, four runtime palette copies, all 640 expected
|
||||
records, and zero fragment drops.
|
||||
- The board framebuffer has 129,883 nonzero words in bounds `(65,41)..(462,470)`.
|
||||
|
||||
## Silicon Closure
|
||||
|
||||
- Board and traced-integration framebuffers are byte-identical at SHA-256
|
||||
`b44f5e98d79ffa2f451238182f798432edb5c413ea80fea2da6c231a0b4be151`.
|
||||
- The complete trace independently replays to the board framebuffer exactly: 524,145 fragments,
|
||||
431,666 Z-pass updates, 129,883 covered pixels, zero uncovered writes, and `307200/307200` exact colors.
|
||||
|
||||
## Result
|
||||
|
||||
Ch374 closes the first two-palette, eleven-draw earlier-capture expansion on silicon with no RTL, constraint,
|
||||
or fit change.
|
||||
@@ -0,0 +1,13 @@
|
||||
# Ch375 Audit Log - Fourteen-Draw Post-Rebind Residency
|
||||
|
||||
- `zsrte14` extends Ch374 with three later, on-screen draws using CBP `508`, producing a five-epoch
|
||||
`fill, reuse, reuse, rebind, reuse` runtime-CLUT sequence at native 640x480.
|
||||
- Integration passes with 529,836 accepted fragments, 434,596 Z-pass updates, five fresh drains, zero drops,
|
||||
exact Z `0/307200`, and exact color `0/132063`. Request-FIFO high-water is 2,090, 940, 1,757, 100, and 81.
|
||||
- On the DE25, both palette banks, both texture fills, all 816 expected records, and all drop gates pass.
|
||||
- Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`3a4b8f12a08dd0a5e9872675a1dd7cf2d767b76c71def1c1f4398f8c89da104d`.
|
||||
- Replay-color is exact at `307200/307200`: 529,836 fragments, 434,596 Z-pass updates, 132,063 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch375 closes the fourteen-draw post-rebind residency expansion on silicon without RTL, constraint, or fit changes.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Ch376 Audit Log - Seventeen-Draw Second-Palette Residency
|
||||
|
||||
- `zsrte17` extends Ch375 with three later, on-screen CBP `508` draws, producing a six-epoch
|
||||
`fill, reuse, reuse, rebind, reuse, reuse` runtime-CLUT sequence at native 640x480.
|
||||
- Local depth-4096 integration passes with 531,922 accepted fragments, 436,186 Z-pass updates, six fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/132810`. Request-FIFO high-water is 2,090, 940, 1,757,
|
||||
100, 81, and 84.
|
||||
- On the DE25, both palette banks, both texture fills, all 934 expected records, and every drop gate pass.
|
||||
- Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`9101f42e3e575653a7e62c9dd5760fef69427b04cb45187e7a1697a5a0e0e864`.
|
||||
- Replay-color is exact at `307200/307200`: 531,922 fragments, 436,186 Z-pass updates, 132,810 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch376 closes the seventeen-draw second-palette residency expansion on silicon without RTL, constraint, or fit changes.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Ch377 Audit Log - Eighteen-Draw Second-Palette Residency
|
||||
|
||||
- `zsrte18` adds the final later, on-screen CBP `508` candidate to Ch376, producing a seven-epoch
|
||||
`fill, reuse, reuse, rebind, reuse, reuse, reuse` runtime-CLUT sequence at native 640x480.
|
||||
- Local depth-4096 integration passes with 532,162 accepted fragments, 436,333 Z-pass updates, seven fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/132936`. Request-FIFO high-water is 2,090, 940, 1,757,
|
||||
100, 81, 84, and 21.
|
||||
- On the DE25, both palette banks, both texture fills, all 956 expected records, and every drop gate pass.
|
||||
- Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`9b49a9b56cb99296d09b12c535145b64dd8ae80b32f06e2a9934801567fe95bb`.
|
||||
- Replay-color is exact at `307200/307200`: 532,162 fragments, 436,333 Z-pass updates, 132,936 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch377 closes the eighteen-draw two-palette residency expansion on silicon without RTL, constraint, or fit changes.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Ch378 Audit Log - Nineteen-Draw Third-Binding Expansion
|
||||
|
||||
- `zsrte19` extends the frame-pure Ch377 scene with draw `93634` (`TBP=3072`, authentic CBP `14080`), adding a
|
||||
third texture and runtime-CLUT binding in an eighth epoch at native 640x480.
|
||||
- The initial three-bank layout at relocated CBPs `504/508/512` was rejected before simulation because `512` is
|
||||
beyond the 512-block BRAM. The fixture is instead deliberately relocated to `500/504/508`; no RTL, constraint,
|
||||
or fit change is involved.
|
||||
- Local depth-4096 integration passes with 543,715 accepted fragments, 444,244 Z-pass updates, eight fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/139585`. Request-FIFO high-water is 2,090, 940, 1,757,
|
||||
100, 81, 84, 21, and 733.
|
||||
- On the DE25, all three palette banks, all three texture fills, all 1,024 expected records, and every drop gate pass.
|
||||
- Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`941ee4579c220a82240f30aae86f74ae9c0873923c0749835e75f49a089d6186`.
|
||||
- Replay-color is exact at `307200/307200`: 543,715 fragments, 444,244 Z-pass updates, 139,585 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch378 closes the three-palette, three-texture native-640x480 persistent-Z expansion on silicon without RTL,
|
||||
constraint, or fit changes.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Ch383 Audit Log - Thirty-Four-Draw Third-Binding Extension
|
||||
|
||||
- `zsrte34` extends the native-640x480 persistent-Z scene to 34 authenticated draws in 13 epochs, retaining the
|
||||
three runtime texture/CLUT bindings at relocated CBPs `500/504/508`.
|
||||
- Local depth-4096 integration passes with 647,303 accepted fragments, 500,072 Z-pass updates, 13 fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/166963`.
|
||||
- The DE25 host run completed all 1,899 expected records with all palette and texture-fill checks passing and no
|
||||
fragment drops. Its framebuffer bounds were `(46,3)..(634,473)` with 166,963 nonzero pixels.
|
||||
- The board dump and the independently traced integration framebuffer are byte-identical at SHA-256
|
||||
`61169f615b327f235405cabb19fff38d3b336c359cd30c498357b6b16338bd19`.
|
||||
- Replay-color is exact at `307200/307200`: 647,303 replay fragments, 500,072 Z-pass updates, 166,963 covered
|
||||
pixels, and zero uncovered writes.
|
||||
|
||||
Ch383 closes the 34-draw, 13-epoch extension on the timing-closed core. No RTL, SDC, QSF, or Quartus fit changed.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Ch384 Audit Log - Forty-Three-Draw Fourth-Palette Expansion
|
||||
|
||||
- `zsrte43` expands the native-640x480 persistent-Z scene to 43 authenticated draws in 16 ordered epochs.
|
||||
- A fourth runtime palette initially exceeded the old monotonic relocation window. Rebasing the fixture to
|
||||
`496/500/504/508` kept all four palette banks inside the 512-block BRAM without an RTL, SDC, QSF, or fit change.
|
||||
- Local depth-4096 integration passes with 715,304 accepted fragments, 561,898 Z-pass updates, 16 fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/168654`.
|
||||
- The DE25 completed all 2,103 expected records, four texture fills, four runtime-palette checks, and every drop
|
||||
gate. Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`fb4bce9ad6307960308d1d1c7624c5d18e560854eb1b82fa7f95e7dbc6e7356e`.
|
||||
- Replay-color is exact at `307200/307200`: 715,304 fragments, 561,898 Z-pass updates, 168,654 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch384 closes the 43-draw, four-runtime-palette scene on the timing-closed core.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Ch385 Audit Log - Runtime-CLUT Reuse and Seventeen-Epoch Scaling
|
||||
|
||||
- The old 16-epoch cap lived only in the HPS scheduler and common integration testbench. Both descriptor capacities
|
||||
were raised to 32; the FPGA RTL, constraints, and RBF were not changed.
|
||||
- Runtime CLUT staging is serialized before each GO and each GO completes its drain before the next epoch begins.
|
||||
The fixture generator now reuses one legal four-block CLUT slot in runtime mode, while preloaded fixtures retain
|
||||
distinct-bank allocation. This removes the artificial four-palette scene cap.
|
||||
- `zsrte45` carries 45 authenticated draws in 17 epochs, all using runtime CBP 500. Local depth-4096 integration
|
||||
passes with 725,545 accepted fragments, 570,196 Z-pass updates, 17 fresh drains, zero drops, exact Z `0/307200`,
|
||||
and exact color `0/168654`.
|
||||
- The DE25 completed all 1,972 expected records, texture fills, palette copies, residency checks, and drop gates.
|
||||
Board and traced integration framebuffers are byte-identical at SHA-256
|
||||
`a374ba18b05994f3223cd6b79139effc184ea35b436a6fece4e7733c1c0a03b8`.
|
||||
- Replay-color is exact at `307200/307200`: 725,545 fragments, 570,196 Z-pass updates, 168,654 covered pixels,
|
||||
and zero uncovered writes.
|
||||
|
||||
Ch385 closes reusable runtime-CLUT staging and host-side 32-epoch capacity on the timing-closed core.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Ch386 Audit Log - Frame-3 Eighteen-Draw Native Scene
|
||||
|
||||
- Frame 1's remaining in-bounds PSMT8 candidates were rejected by the existing supported-state gates, so Ch386
|
||||
starts a fresh, authentic frame-3 scene rather than weakening those gates.
|
||||
- `zsrtf3e18` contains 18 draws from `TBP=12288/CBP=14208`, partitioned into five ordered staging-safe epochs
|
||||
(70, 106, 58, 97, and 192 records) with one texture fill and four CRC-verified reuses.
|
||||
- Local depth-4096 integration passes with 67,295 accepted fragments, 32,435 Z-pass updates, five fresh drains,
|
||||
zero drops, exact Z `0/307200`, and exact color `0/20276`.
|
||||
- The DE25 completed every record, runtime-palette copy, texture residency check, and zero-drop gate. Board and
|
||||
traced integration framebuffers are byte-identical at SHA-256
|
||||
`8a905aa968f252fdc029832a5a66ee910c93053f791132c5ebf35ddbd4c08818`.
|
||||
- Replay-color is exact at `307200/307200`: 67,295 fragments, 32,435 Z-pass updates, 20,276 covered pixels, and
|
||||
zero uncovered writes.
|
||||
|
||||
Ch386 closes the first fresh frame-3 native scene on the Ch368 timing-closed core.
|
||||
@@ -0,0 +1,132 @@
|
||||
# Ch397 — 224139 LPDDR alpha integration plan
|
||||
|
||||
## Established state
|
||||
|
||||
- `zsrt139a2` is the current live 640x480 opaque board composite from the
|
||||
matching 224139 capture: six epochs, 98,163 written pixels, zero board drops.
|
||||
- The first in-bounds blended draw family is PSMT8 perspective triangles
|
||||
(`idx31075+`, `TBP=13824`, `CBP=14282`, 128x128, `PRIM.ABE=1`).
|
||||
- Its recorded `ALPHA_1` state is `0x0000008000000062`; this is a generic
|
||||
selector/FIX blend, not the existing source-over-only shortcut.
|
||||
|
||||
## Implemented cut (local RTL)
|
||||
|
||||
The current SH3 renderer sends final opaque pixels directly to
|
||||
`gs_lpddr_zc_emit`. Its full-frame colour lives only in LPDDR, while the
|
||||
existing combined triangle alpha path reads destination colour from BRAM.
|
||||
Therefore a full-frame alpha implementation must extend the LPDDR emitter:
|
||||
|
||||
1. carry `ABE` plus ALPHA selector/FIX metadata with each fragment packet;
|
||||
2. issue a single-pixel colour read after a Z-pass (or immediately for a
|
||||
non-Z alpha fragment);
|
||||
3. apply the existing `gs_alpha_blend` generic selector equation in the
|
||||
emitter's AXI domain;
|
||||
4. enqueue that blended colour through the existing colour writer, preserving
|
||||
the ordered scene-marker drain contract.
|
||||
|
||||
Implemented in the local RTL:
|
||||
|
||||
- `gs_lpddr_zc_emit` now carries `{ABE,A,B,C,D,FIX}` through its request and
|
||||
colour-align FIFOs;
|
||||
- `gs_lpddr_color_blend` bypasses opaque pixels and, for ABE pixels, reads the
|
||||
containing 256-bit LPDDR beat, selects the addressed 32-bit lane, invokes
|
||||
generic `gs_alpha_blend`, and emits the ordered write payload;
|
||||
- `gs_lpddr_rd_arb` has a fifth client for that destination read, below
|
||||
scanout and Z/reload traffic;
|
||||
- the real raster wrapper forwards the per-primitive alpha snapshot.
|
||||
|
||||
`make -C sim tb_gs_lpddr_color_blend` passes the actual `0x62` selector
|
||||
pattern: source `0x80402010` over destination `0x40203020` produces
|
||||
`0x80001010` (`Cd - Cs`, clamped), proving the LPDDR read lane and blend
|
||||
datapath together.
|
||||
|
||||
The complete three-epoch integration replay is exact: 102,493 fragments,
|
||||
102,479 Z passes, three ordered drains, zero drops/overflows/BRESP errors,
|
||||
Z `0/307200` mismatches, and color `0/51525` mismatches. The final
|
||||
640x480 simulation framebuffer is
|
||||
`sh3_zsrt139a3_sim_fb.mem` (SHA-256
|
||||
`a331fd9d68aaccb35310051ad9091f6c02acafcc4b86391cecedaea8f08ce28f`).
|
||||
|
||||
## Timing closure and deploy artifact (2026-07-15)
|
||||
|
||||
The first alpha fit exposed the destination-read/blend arithmetic as an
|
||||
unregistered 310 MHz cone. The final implementation uses a registered
|
||||
shift/add blend engine (no new DSPs), a registered generic async-FIFO write
|
||||
port, and registered request-head control. The last 42 ps setup family was
|
||||
the staged scene-marker bit feeding the color-align RAM write enable; fragment
|
||||
valid and marker valid are now separate registered controls, removing that
|
||||
decode from color writes.
|
||||
|
||||
The final Quartus 25.3.1 build is signoff-clean: setup `+0.012 ns`, hold
|
||||
`0.000 ns`, zero setup TNS, and synthesis/fit/STA/assembler all completed with
|
||||
zero errors. The split loader artifact is
|
||||
`output_files/retroDE_ps2.core.rbf`, SHA-256
|
||||
`f921f0bcde7fc9a8fe01bf39166327101e6dcbf0faf68398082207c8498ca349`.
|
||||
`build_quartus.sh` now explicitly runs `post_flow.tcl` after its direct
|
||||
`quartus_asm` step, because direct assembler invocation does not dispatch the
|
||||
QSF post-flow hook by itself.
|
||||
|
||||
The RBF and all `zsrt139a3` host assets were copied to the DE25 and SHA-checked.
|
||||
The first runtime load hit an SDM service-buffer timeout and left configfs in
|
||||
an uninterruptible write. A controlled remote reboot restored network ping,
|
||||
but SSH had not restarted at closeout time; a physical power cycle is the
|
||||
remaining prerequisite before retrying the load and taking the board FB dump.
|
||||
|
||||
## First silicon run and request-FIFO correction (2026-07-16)
|
||||
|
||||
The authoritative Quartus 26.1 GUI RBF loaded successfully and all three
|
||||
texture uploads, readback CRCs, runtime palettes, staging counts, Z preclear,
|
||||
and zero-drop checks passed. The render itself did not drain: epoch 0 reached
|
||||
36,958 framebuffer beats after 120 seconds and `frame_drained` remained low.
|
||||
The resulting interrupted composite was 298,888/307,200 pixels equal to the
|
||||
simulation framebuffer, with 8,312 mismatches caused by rebinding texture and
|
||||
palette state while old fragments were still executing.
|
||||
|
||||
Root cause was the Ch397 timing cut in generic `gs_async_fifo`: the allocation
|
||||
pointer was published to the read clock when the write was accepted, one
|
||||
writer cycle before the staged RAM write committed. The production request
|
||||
FIFO crosses a 40 MHz writer into a roughly 310 MHz reader, so the consumer
|
||||
could observe the pointer about 19 ns before the data existed and replay stale
|
||||
RAM entries. The earlier FIFO regression used a faster writer than reader and
|
||||
therefore did not exercise this CDC ordering failure.
|
||||
|
||||
The FIFO now maintains separate allocation and commit pointers. Full
|
||||
accounting uses allocation, while only the pointer advanced by an actual
|
||||
staged RAM commit crosses into the reader. A production-ratio stress test
|
||||
(40 MHz write, 312.5 MHz read) transfers 3,284/3,284 ordered words with zero
|
||||
duplicates/drops. The full `zsrt139a3` integration replay remains exact:
|
||||
102,493 fragments, all three drains, zero drops/errors, and Z/color scoreboards
|
||||
at zero mismatches. This correction is ready for the owner-controlled
|
||||
Quartus 26.1 GUI compile and subsequent silicon rerun.
|
||||
|
||||
## Corrected FIFO silicon acceptance (2026-07-16)
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI compile completed successfully. The
|
||||
final fit used 37,153/46,800 ALMs and 284/358 RAM blocks; setup slack was
|
||||
`+0.064 ns`, hold slack was `0.000 ns`, and every reported TNS was zero. The
|
||||
fresh split RBF is `output_files/retroDE_ps2.core.rbf`, 3,915,776 bytes,
|
||||
SHA-256 `a1adf0a706465709e3078dedc053433e34807a40a57733c1cd2e14c9d64461fa`.
|
||||
Its hash was checked again on the DE25 before `core_loader.sh` loaded it, and
|
||||
`fpga0` reported `operating`.
|
||||
|
||||
The corrected request FIFO is now proven on silicon. Epochs 0, 1, and 2
|
||||
completed with 54, 68, and 10 records respectively; all texture CRC, runtime
|
||||
palette, staging, Z-preclear, and zero-drop gates passed. The 10-record alpha
|
||||
epoch is short enough for `frame_drained` to clear and rise entirely between
|
||||
HPS bridge polls, so the host now accepts that missed-low case only if both the
|
||||
new per-GO record count and framebuffer-beat count prove forward progress. A
|
||||
one-second low-observation window replaces the old 120-second delay; the
|
||||
full board run now completes in about 23 seconds with `rc=0`.
|
||||
|
||||
The final board framebuffer and simulation framebuffer are byte-for-byte
|
||||
identical across all 307,200 PSMCT32 words (zero mismatches), both with
|
||||
SHA-256 `a331fd9d68aaccb35310051ad9091f6c02acafcc4b86391cecedaea8f08ce28f`.
|
||||
|
||||
## First acceptance scope
|
||||
|
||||
The generated `zsrt139a3` fixture carries two opaque setup epochs followed by
|
||||
authentic blended draw `32391` (10 triangles, safely within the 2048-word
|
||||
staging limit). The six-draw family remains the next scale-up target; its
|
||||
first four draws exceed that current staging window and must be split across
|
||||
ordered epochs before board replay. Do not claim frame fidelity until the
|
||||
subset is locally replayed and board-read back against its own trace.
|
||||
@@ -0,0 +1,83 @@
|
||||
# Ch400 — chronological base geometry plus bounded alpha tail
|
||||
|
||||
## Goal
|
||||
|
||||
Move fidelity forward by replaying the missing in-bounds opaque draws before a
|
||||
small authentic alpha-blended tail, rather than darkening the incomplete Ch399
|
||||
base with the full alpha family.
|
||||
|
||||
## Fixture
|
||||
|
||||
- Tag: `sh3_zsrt139a6`
|
||||
- 35 authentic draws in chronological order
|
||||
- 20 epochs: 17 base epochs followed by 3 alpha epochs
|
||||
- Independent reference coverage: 83,596 framebuffer pixels
|
||||
- Simulation target: `make -C sim tb_top_psmct32_sh3_zint640rt139a6`
|
||||
- Board loader: `tools/scp_zsrt139a6_to_board.sh`
|
||||
|
||||
## Blend ordering correction
|
||||
|
||||
The first full replay found two wrong color pixels with exact Z. Repeated ABE
|
||||
fragments could begin their destination read after the previous blended result
|
||||
entered the color writer, but before that partial beat received an AXI BRESP.
|
||||
Waiting on the writer's raw `idle` signal is not sufficient because the elastic
|
||||
packer may retain a partial beat while its AXI FIFO is empty.
|
||||
|
||||
`gs_lpddr_zc_emit` now treats each ABE result as an ordered dependency:
|
||||
|
||||
1. accept one ABE input and hold subsequent color inputs;
|
||||
2. enqueue its blended output and pulse the color writer flush;
|
||||
3. wait for the ordered drain acknowledgement to transition low then high;
|
||||
4. admit the next color input only after the preceding write is memory-visible.
|
||||
|
||||
Opaque flow remains unrestricted outside an active ABE dependency.
|
||||
|
||||
## Simulation acceptance
|
||||
|
||||
Final full replay:
|
||||
|
||||
- fragments fed: 279,134
|
||||
- fragments passing Z: 234,373
|
||||
- scene markers: 20
|
||||
- request drops: 0
|
||||
- color FIFO overflows: 0
|
||||
- AXI BRESP errors: 0
|
||||
- Z mismatches: 0 / 307,200
|
||||
- color mismatches: 0 / 83,596
|
||||
- framebuffer MEM SHA-256:
|
||||
`38095a6c9136eb6618876c4cf2bf9a72c494a6f8161c247f2e1a36dcd0474bb8`
|
||||
|
||||
## Hardware gate
|
||||
|
||||
The RTL correction postdates the 2026-07-16 06:17 Quartus artifact. A fresh
|
||||
owner-run Quartus 26.1 GUI compile is required before board deployment. After
|
||||
that compile, accept Ch400 only if timing is clean, the RBF is fresh, the board
|
||||
run completes all 20 epochs with zero drops/errors, and the board framebuffer is
|
||||
byte-exact to `sh3_zsrt139a6_sim_fb.mem`.
|
||||
|
||||
## Silicon acceptance (2026-07-16)
|
||||
|
||||
The owner-run Quartus 26.1 GUI compile completed successfully after the final
|
||||
RTL correction. The fit used 37,148/46,800 ALMs and 284/358 RAM blocks. Setup
|
||||
slack was `+0.107 ns`, hold slack was `0.000 ns`, and all reported TNS values
|
||||
were zero.
|
||||
|
||||
The fresh deploy RBF was written at 08:34:52, is 3,919,872 bytes, and has
|
||||
SHA-256
|
||||
`4619653217c8946b7ba4cd847a17f5e5b020c449ac4837784f72f9a7abed0b7d`.
|
||||
The hash matched on the DE25 before loading, and `fpga0` reported `operating`.
|
||||
|
||||
The board completed all 20 epochs with every texture CRC, palette checksum,
|
||||
staged-word count, triangle-record count, preclear, drain, and zero-drop gate
|
||||
passing. The host returned `rc=0` and dumped all 307,200 framebuffer words.
|
||||
|
||||
Board and simulation are byte-exact across the complete framebuffer:
|
||||
|
||||
- board MEM SHA-256:
|
||||
`38095a6c9136eb6618876c4cf2bf9a72c494a6f8161c247f2e1a36dcd0474bb8`
|
||||
- simulation MEM SHA-256: same
|
||||
- board PNG SHA-256:
|
||||
`1785875df7c4c17fbf94ce1543fa3777be5601c874f5319ce4e2a20c828cecd0`
|
||||
- simulation PNG SHA-256: same
|
||||
|
||||
Ch400 is accepted on silicon.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Ch401 — fuller 56-draw static frame
|
||||
|
||||
Ch401 retains the accepted Ch400 chronological base, one correctly paired ABE
|
||||
draw, two later-scene anchors, and the proven 24-draw central cluster. The
|
||||
result is 56 authentic draws in 28 bounded epochs, within the existing 32-epoch
|
||||
host/testbench limit.
|
||||
|
||||
## Simulation
|
||||
|
||||
- 638,022 fragments fed
|
||||
- 321,817 fragments passed Z
|
||||
- 28 ordered drains
|
||||
- zero request drops, color FIFO overflows, or AXI BRESP errors
|
||||
- Z mismatches: 0 / 307,200
|
||||
- color mismatches: 0 / 128,998
|
||||
|
||||
## Silicon
|
||||
|
||||
No RTL changed after the accepted Ch400 RBF. The 28-epoch board run passed all
|
||||
texture CRC, runtime palette, staging, record-count, drain, and zero-drop gates
|
||||
and returned `rc=0`.
|
||||
|
||||
- nonzero pixels: 128,998
|
||||
- bounds: `(36,10)..(599,399)`
|
||||
- board/simulation MEM SHA-256:
|
||||
`0383cc739aa8e9b921489a3fc1ffca7ab2a48763cb57028d4a90e3ae9a34142f`
|
||||
- board/simulation PNG SHA-256:
|
||||
`a4806d0ba39fcea1b904375f715d11f7a81d1364c78f201f40c1bb5906ac008b`
|
||||
|
||||
Board and simulation are byte-exact over all 307,200 framebuffer words.
|
||||
Ch401 is accepted on silicon and remains displayed through the LPDDR HDMI
|
||||
scanout.
|
||||
@@ -0,0 +1,74 @@
|
||||
# Ch402 — character draws through runtime CLAMP state
|
||||
|
||||
Ch402 extends the accepted Ch401 56-draw scene with twelve authentic draws from
|
||||
the character family, each in its own epoch. These draws use GS region clamp
|
||||
mode 2 with exact full-texture bounds (`MINU/MINV=0`, `MAXU/MAXV=511`). For a
|
||||
512x512 texture that state is mathematically identical to ordinary clamp, so the
|
||||
fixture generator proves those bounds and normalizes only the mode bits. Any
|
||||
other region-clamp bounds continue to fail closed.
|
||||
|
||||
The feeder format is backward-compatible. Legacy lists retain the seven-word
|
||||
header. Extended lists advertise word 8 with count-word bit 34 and emit
|
||||
`CLAMP_1` between `TEX0_1` and `PRIM`. A focused feeder regression proves both
|
||||
formats and the new vertex base.
|
||||
|
||||
An initial four-epoch grouping required 2,294 to 3,410 staging words and doubled
|
||||
the allocated RAM. Although functionally exact in simulation, that placement
|
||||
pressure moved the previously marginal color-address FIFO family to -0.233 ns.
|
||||
Ch402 therefore uses twelve single-draw character epochs, retains the accepted
|
||||
2,048-word staging allocation, and raises only the software epoch-table ceiling
|
||||
from 32 to 64.
|
||||
|
||||
## Simulation
|
||||
|
||||
- 68 authentic draws in 40 ordered epochs
|
||||
- 649,189 fragments fed
|
||||
- 332,984 fragments passed Z
|
||||
- 40 fresh ordered drains
|
||||
- zero request drops, color FIFO overflows, or AXI BRESP errors
|
||||
- Z mismatches: 0 / 307,200
|
||||
- color mismatches: 0 / 131,618
|
||||
- reference coverage: 131,830 pixels
|
||||
- largest staging list: 1,844 / 2,048 words
|
||||
- maximum measured request FIFO high-water: 1,753 / 4,096
|
||||
- simulated framebuffer MEM SHA-256:
|
||||
`d3a211671a444991e8032c97d3ba16c66621de1e9d3ad1432442bdb8be585010`
|
||||
- simulated framebuffer PNG SHA-256:
|
||||
`ae1b8fbdf1748723eede478d4ca349245920c32836df94cdf076cc6b983047b6`
|
||||
|
||||
The simulated image now includes the central character silhouette and reaches
|
||||
the bottom of the 640x480 frame. It remains visibly short of the PCSX2 image in
|
||||
lighting, fog/compositing, and precision; Ch402 closes the missing-character
|
||||
state/capacity blocker, not the remaining fidelity debt.
|
||||
|
||||
## Timing gate
|
||||
|
||||
The first owner GUI fit used a 4,096-word staging allocation. It fit at 291 RAM
|
||||
blocks but failed setup at -0.233 ns / -1.287 ns TNS on the known
|
||||
`u_zc_emit|ca_tail/ca_head -> ca_mem` family; hold remained clean. The failure
|
||||
was a placement regression rather than a new logical path through the feeder.
|
||||
The 40-epoch repartition removes the seven added RAM blocks and restores the
|
||||
accepted 2,048-word allocation. The follow-up owner GUI fit recovered timing at
|
||||
+0.041 ns setup / 0.000 TNS; hold remained clean. It used 37,279 / 46,800 ALMs
|
||||
and restored RAM usage to 284 / 358 blocks.
|
||||
|
||||
## Silicon
|
||||
|
||||
The timing-clean RBF (SHA-256
|
||||
`a7691ff9203bc1a9097da88f0a341f6c14ed96910bb2d6f3fb46349e02b0fcce`)
|
||||
was hash-verified on the board and loaded through `core_loader.sh`; `fpga0`
|
||||
reported `operating`.
|
||||
|
||||
All 40 epochs passed texture/CLUT CRC, staging count, record count, ordered
|
||||
drain, and zero-drop gates with `rc=0`.
|
||||
|
||||
- nonzero pixels: 131,618
|
||||
- bounds: `(36,10)..(599,463)`
|
||||
- board/simulation MEM SHA-256:
|
||||
`d3a211671a444991e8032c97d3ba16c66621de1e9d3ad1432442bdb8be585010`
|
||||
- board/simulation PNG SHA-256:
|
||||
`ae1b8fbdf1748723eede478d4ca349245920c32836df94cdf076cc6b983047b6`
|
||||
|
||||
Board and simulation are byte-exact over all 307,200 framebuffer words.
|
||||
Ch402 is accepted on silicon and remains displayed through the LPDDR HDMI
|
||||
scanout.
|
||||
@@ -0,0 +1,91 @@
|
||||
# Ch403 — authentic vertex-color modulation
|
||||
|
||||
## Objective
|
||||
|
||||
Make the 224139 static-frame fixture use the captured GS lighting state instead
|
||||
of drawing every texture at raw DECAL brightness. Geometry, draw order,
|
||||
runtime CLUT handling, persistent Z, and the Ch402 40-epoch staging partition
|
||||
remain unchanged.
|
||||
|
||||
## Finding
|
||||
|
||||
The selected draws carry `TEX0.TFX=MODULATE` and non-unity per-vertex RGB.
|
||||
Ch402 deliberately forced `TFX=DECAL` and emitted zero placeholder RGB, which
|
||||
made the composite much brighter than the PCSX2 frame.
|
||||
|
||||
The first Ch403 fixture proved a second, narrower gap: the existing MODULATE
|
||||
implementation was only connected to the combined affine texture path. These
|
||||
SH3 triangles use the five-cycle perspective path, whose emit was explicitly
|
||||
hardwired to the raw texel. Consequently the live board completed every gate
|
||||
but produced a framebuffer byte-identical to Ch402.
|
||||
|
||||
## Implementation
|
||||
|
||||
- `tools/gs_make_sh3_scheduler_fixture.py`
|
||||
- adds opt-in `--auth-color-tfx`;
|
||||
- preserves authentic `TEX0.TFX` and per-vertex RGB;
|
||||
- interpolates RGB when clipping triangles;
|
||||
- applies the same GS `texel * vertex / 128` saturation rule in the
|
||||
independent reference.
|
||||
- `rtl/gif_gs/gs_stub.sv`
|
||||
- aligns the already-computed S2 Gouraud color with the perspective texel by
|
||||
four registers;
|
||||
- applies MODULATE at the perspective S1+5 emit;
|
||||
- shares the existing three-channel modulation datapath between affine and
|
||||
perspective paths, avoiding a duplicate multiplier set;
|
||||
- leaves DECAL output byte-identical.
|
||||
- `sim/tb/top/tb_top_psmct32_sh3_zint640_shared.sv`
|
||||
- verifies the full 64-bit staged header and committed TEX0 state;
|
||||
- fixes late-epoch diagnostic fill accounting.
|
||||
|
||||
## Fixture
|
||||
|
||||
`zsrt139a9` retains all 68 Ch402 draws in 40 staging-safe epochs. The largest
|
||||
list is 1844 of 2048 words (204 words headroom).
|
||||
|
||||
The independent modulated reference is:
|
||||
|
||||
`captures/gs/silenthill3/extracted/recon/sh3_zsrt139a9_ref.png`
|
||||
|
||||
Against the PCSX2 224139 image resized to the same 640x480 comparison grid,
|
||||
the fixture-only reference improves RGB MAE from 31.34 to 23.31 and RMSE from
|
||||
45.94 to 33.61. This does not claim full fidelity: missing draws/fog and the
|
||||
perspective/XY precision deficit remain visible.
|
||||
|
||||
## Verification
|
||||
|
||||
- Generator preflight: 40 epochs, max 1844 words, no staging overflow.
|
||||
- Focused epoch 39 MODULATE proof:
|
||||
- old DECAL hash: `37401414dd6ee3b2888d4ddb4aff98903900475e6cf2a47d973959ee05d05fb8`
|
||||
- MODULATE hash: `c85edea3d42e983a31f630b7fffc1457c26233492c332860b7913c20ad7613c0`
|
||||
- average nonblack RGB sum: 258.49 -> 113.23; geometry remains present.
|
||||
- Focused Ch402 DECAL regression remains byte-identical at the old hash.
|
||||
- Full 40-epoch RTL:
|
||||
- 649,189 fragments fed; 332,984 passed persistent Z;
|
||||
- 40 markers, 40 rises / 39 falls, zero drops/overflows/BRESP errors;
|
||||
- Z mismatch `0/307200`; color mismatch `0/131618`;
|
||||
- framebuffer SHA-256
|
||||
`d286e9d5839fc7ab63ae6bc1aa3c26fa867397171ad3d1a5e5edc3b6c5b14964`;
|
||||
- PASS.
|
||||
- The final shared-multiplier implementation reproduces the focused MODULATE
|
||||
hash exactly and its late-epoch diagnostic passes with zero errors.
|
||||
- Owner Quartus 26.1 GUI fit:
|
||||
- setup worst slack `+0.080 ns`, TNS `0`;
|
||||
- hold passes, worst reported slack `0.000 ns`, TNS `0`;
|
||||
- 37,353 / 46,800 ALMs, 53,238 registers, 284 / 358 RAM blocks,
|
||||
4,177,064 memory bits, and 153 / 376 DSP blocks;
|
||||
- core RBF SHA-256
|
||||
`28659ebfccb19f03478fcd105904cc1b03195e8cc0907fad3903f56d7821975b`.
|
||||
- Live-board acceptance:
|
||||
- all 40 epochs completed with every texture CRC, palette checksum, staged
|
||||
word/record count, fresh-drain, fragment-drop, and bus-response gate clean;
|
||||
- host runner returned `0`;
|
||||
- the 307,200-word board framebuffer compares byte-for-byte with RTL;
|
||||
- board and RTL framebuffer SHA-256
|
||||
`d286e9d5839fc7ab63ae6bc1aa3c26fa867397171ad3d1a5e5edc3b6c5b14964`.
|
||||
|
||||
## Status
|
||||
|
||||
Complete and accepted on silicon. The current HDMI image is the authentic
|
||||
vertex-color-modulated 40-epoch composite; the next fidelity work is geometry
|
||||
precision and remaining GS effects/draw coverage, not Ch403 correctness.
|
||||
@@ -0,0 +1,39 @@
|
||||
# Ch404 — chronological character-detail tail
|
||||
|
||||
Ch404 appends the next 36 authentic opaque draws after the accepted Ch403
|
||||
frame. Thirty-five staging-safe epochs preserve dump order and cover the
|
||||
character/lower-body region without changing RTL or requiring another fit.
|
||||
|
||||
## Fixture and infrastructure
|
||||
|
||||
- `zsrt139b1`: generated 35-epoch detail tail.
|
||||
- `zsrt139b2`: merged Ch403 base plus the tail, 75 epochs total.
|
||||
- `tools/merge_runtime_sched.py`: concatenates accepted runtime-CLUT fixtures
|
||||
without regenerating or changing their staged records.
|
||||
- Host and shared-testbench epoch ceilings increase from 64 to 128; staging RAM
|
||||
remains 2,048 words and the FPGA image is unchanged.
|
||||
|
||||
## RTL verification
|
||||
|
||||
- 667,279 fragments fed; 351,074 passed persistent Z.
|
||||
- 75 ordered markers and drains.
|
||||
- Zero request drops, color FIFO overflows, or AXI response errors.
|
||||
- Z mismatch `0/307200`; color mismatch `0/132783` written pixels.
|
||||
- RTL framebuffer SHA-256:
|
||||
`8715381278c2b0a6e527329fb02aaaaf53edbaefd637f115723a3425bbd1b209`.
|
||||
|
||||
The tail adds 1,003 nonblack pixels over Ch403. Against the resized PCSX2
|
||||
frame, RGB MAE improves from 23.8474 to 23.7846 and RMSE from 34.8791 to
|
||||
34.6956. This is a bounded character-detail gain, not the missing environment
|
||||
or fog solution.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
The timing-clean Ch403 RBF was retained. The board completed all 75 epochs
|
||||
with every texture CRC, runtime palette checksum, staging count, record count,
|
||||
fresh drain, zero-drop, and bus-error gate clean; the host returned `0`.
|
||||
|
||||
The 307,200-word board framebuffer is byte-for-byte identical to RTL and has
|
||||
the same SHA-256
|
||||
`8715381278c2b0a6e527329fb02aaaaf53edbaefd637f115723a3425bbd1b209`.
|
||||
The 75-epoch composite is live on HDMI.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Ch405 — authentic alpha-fan overlays (pre-fit gate)
|
||||
|
||||
## Objective
|
||||
|
||||
Add the 53 chronological PSMT8 alpha-fan draws at capture indices 196494
|
||||
through 198058 after the accepted 75-epoch Ch404 opaque composite. These are
|
||||
large translucent overlays using authentic `ZTE=1`, `GEQUAL`, `ZMSK=1`, and
|
||||
`PSMZ16S`: they test the accumulated depth buffer, blend on pass, and must not
|
||||
modify Z.
|
||||
|
||||
## RTL change
|
||||
|
||||
- Carry architectural `TEST.ZTE` and `ZBUF.ZMSK` alongside each perspective
|
||||
fragment through `gs_stub` and `top_psmct32_raster_demo_bram` into the
|
||||
existing external LPDDR Z/color ROP.
|
||||
- Replace the de25 wrapper's former `ZTE=1/ZMSK=0` constants with those
|
||||
sidebands.
|
||||
- Increase the production async request FIFO from 4,096 to 16,384 entries.
|
||||
The alpha writer preserves exact destination order and can be slower than
|
||||
the unthrottled raster producer, so the fixture bounds each epoch to one
|
||||
triangle. Measured worst-triangle occupancy is 12,953 entries, leaving
|
||||
3,431 entries of observed headroom.
|
||||
|
||||
## Fixture
|
||||
|
||||
- `zsrt139c3`: 212 one-triangle alpha epochs, preserving all 212 triangles
|
||||
expanded from the 53 authentic fan draws.
|
||||
- `zsrt139c4`: Ch403 base + Ch404 detail tail + Ch405 alpha tail, 287 epochs.
|
||||
- Authentic TEST/ZBUF header words are restored in the accepted base fixtures;
|
||||
their geometry, colors, textures, palettes, and record counts are unchanged.
|
||||
- Host/testbench epoch ceilings rise from 128 to 512.
|
||||
|
||||
## Pre-fit evidence
|
||||
|
||||
- The unbounded three-epoch diagnostic correctly failed closed at epoch 75:
|
||||
169,213 request drops and FIFO high-water 4,096/4,096. It is retained only
|
||||
as the measurement that justified bounded bursts.
|
||||
- Worst-tail three-epoch test (empty Z): 43,680 fed/passed, zero drops,
|
||||
high-water 12,953/16,384, exact color and Z, PASS.
|
||||
- Checkerboard-Z test: 43,680 fed, 21,839 passed, zero drops, high-water
|
||||
11,389/16,384, exact color, exact unchanged Z at all 307,200 pixels, PASS.
|
||||
- Full Ch404 baseline replay with authentic headers reached its exact accepted
|
||||
epoch-74 counts (667,279 fed / 351,074 passed) with zero drops before the
|
||||
intentionally unbounded diagnostic alpha epoch.
|
||||
- Host runner compiles cleanly; generated production assets total about 174 MiB.
|
||||
|
||||
## Status
|
||||
|
||||
Ready for owner Quartus 26.1 GUI compile. Do not deploy the prior
|
||||
`28659ebf...` RBF as Ch405; the new RBF must contain the 16K request FIFO and
|
||||
TEST/ZMSK sidebands. After a timing/resource-clean fit, deploy and run
|
||||
`zsrt139c4`, then compare the board framebuffer byte-for-byte with RTL.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Ch406 — deep request-FIFO timing repair (pre-fit gate)
|
||||
|
||||
## Trigger
|
||||
|
||||
The owner Quartus 26.1 GUI compile for Ch405 fit in the device but failed the
|
||||
310 MHz EMIF clock by 0.267 ns, with design-wide TNS of -4.802 ns. All 77
|
||||
failing endpoints belong to `u_zc_emit|u_req`. The leading path is the
|
||||
registered empty flag through the 15-bit binary-pointer increment, Gray
|
||||
conversion, equality reduction, and back into the empty flag. Secondary
|
||||
violations are the same empty/pointer cone feeding the 16K FIFO RAM address,
|
||||
plus the asynchronous RAM bank mux feeding request-head decode.
|
||||
|
||||
This is a local consequence of increasing the Ch405 request FIFO from 4K to
|
||||
16K. Hold timing, Gray-pointer skew constraints, and all other clock domains
|
||||
pass.
|
||||
|
||||
## Structural repair
|
||||
|
||||
- Treat `gs_async_fifo.rd` according to its existing interface contract: it is
|
||||
an accepted read, already qualified by `!rempty` in each wrapper. Remove the
|
||||
redundant internal `!rempty` gate from the read-pointer increment. This
|
||||
removes the empty-to-pointer feedback and the empty-to-RAM-address fanout.
|
||||
- Add an optional synchronous/registered read port to `gs_async_fifo`.
|
||||
- Enable that port only for the 16K x 92-bit Z/color request FIFO. Keep the
|
||||
smaller existing users on their original FWFT interface.
|
||||
- Add a one-cycle pending bit in `gs_lpddr_zc_emit` so its request-head stage
|
||||
captures the registered FIFO word on the following cycle and cannot issue a
|
||||
second pop while a word is in flight.
|
||||
- Make the standalone FIFO testbench explicitly qualify its randomized read
|
||||
requests, matching the documented production interface.
|
||||
|
||||
No clock, SDC, FIFO depth, fixture, draw, texture, blend, or Z behavior changes.
|
||||
|
||||
## Pre-fit proof
|
||||
|
||||
- Async FIFO scoreboard: 3,284 writes / 3,284 reads, zero order, duplicate, or
|
||||
drop errors, final empty asserted, PASS.
|
||||
- Ch405 worst three epochs, empty Z: 43,680 fed and passed, zero drops,
|
||||
high-water 12,953/16,384, exact color, exact Z, PASS.
|
||||
- Ch405 worst three epochs, checkerboard Z: 43,680 fed, 21,839 passed, zero
|
||||
drops, high-water 11,389/16,384, exact color, exact unchanged Z at all
|
||||
307,200 pixels, PASS.
|
||||
- A sequential production sweep additionally replayed epochs 0 through 19:
|
||||
291,597 fragments, zero drops, and every scene drain completed. It was
|
||||
stopped after this redundant prefix because the complete 287-epoch run would
|
||||
consume more than an hour; the maximum-pressure tail and both Z outcomes had
|
||||
already passed exact comparisons above.
|
||||
- Production RTL elaborates with the 16K request FIFO and registered-read path.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Run the next compile only in the owner-controlled Quartus 26.1 GUI. The fit
|
||||
must confirm that the request RAM remains inferred in device memory, resources
|
||||
still fit, setup and hold both pass, and the previous `rempty` feedback family
|
||||
is absent. Do not deploy an RBF unless those checks pass.
|
||||
@@ -0,0 +1,111 @@
|
||||
# Ch415 — authentic fog fold and indexed perspective bilinear filtering
|
||||
|
||||
## Objective
|
||||
|
||||
Move the 224139 board image toward the PCSX2 reference through real captured
|
||||
GS state rather than further draw-count expansion. Every selected draw has
|
||||
`PRIM.FGE=1`, every vertex arrives through `XYZF2`, `FOGCOL=0`, and every
|
||||
selected texture requests linear magnification.
|
||||
|
||||
## Changes
|
||||
|
||||
- Preserve the captured vertex fog factor and fold the zero fog color into
|
||||
fixture vertex RGB as `RGB * F >> 8`. This is exact at vertices and uses
|
||||
the existing Gouraud interpolator across each triangle.
|
||||
- Preserve four fractional texel bits from the perspective reciprocal path.
|
||||
- Serialize indexed perspective pixels through the existing four-tap texture
|
||||
sampler, performing CLUT lookup before interpolation as required.
|
||||
- Hold the raster walker while the single-port texture cache fetches four
|
||||
taps, then release exactly once after emitting the completed pixel.
|
||||
- Add bounded `START_EPOCH`/`END_EPOCH` integration runs and explicit cold
|
||||
shared-asset selection so late reuse epochs can be tested independently.
|
||||
|
||||
## Reference evidence
|
||||
|
||||
Against the 640x480 PCSX2 frame, the full software reconstruction improved
|
||||
from MAE 22.55 / RMSE 34.96 with nearest sampling to MAE 21.17 / RMSE 32.47
|
||||
with bilinear sampling. The fog fold alone was smaller (MAE 22.51 / RMSE
|
||||
34.88), so both are retained but filtering is the principal visual change.
|
||||
|
||||
## RTL evidence
|
||||
|
||||
- Texture sampler: PSMT8/PSMT4 CLUT-before-interpolation, clamp, repeat,
|
||||
nearest fallback, and edge cases all pass.
|
||||
- Perspective feeder and palette-bilinear tile integration pass.
|
||||
- Legacy raster pipeline remains passing.
|
||||
- Real fixture epoch 1: 3,949 accepted/passing fragments, zero drops, exact Z
|
||||
and color-memory comparisons.
|
||||
- Dense shared-texture epoch 75: 7,304 accepted/passing fragments, zero drops,
|
||||
exact Z and color-memory comparisons.
|
||||
|
||||
## First-fit hardware correction
|
||||
|
||||
The first signoff-clean Ch415 fit (`91087214...`) passed all 124 board epochs,
|
||||
but its capture exposed regular missing-pixel stripes: only 84,294 pixels had
|
||||
nonzero RGB, versus 146,399 in the preceding board frame. The DONE cycle had
|
||||
been reopened inside the normal pipeline-advance block, so both DONE and
|
||||
PB_RELEASE advanced the held walker and skipped alternate samples.
|
||||
|
||||
The corrected RTL emits DONE outside the advance gate, keeps the walker frozen
|
||||
that cycle, and advances exactly once on PB_RELEASE. Focused RTL coverage rose
|
||||
from 2,889 to 3,949 fragments on epoch 1 and from 4,994 to 7,304 on dense epoch
|
||||
75, with exact color/Z comparisons and all sampler, tile, feeder, and legacy
|
||||
raster regressions passing.
|
||||
|
||||
## Second-fit timing repair
|
||||
|
||||
The walker-release fit succeeded but STA was unclean in two isolated families:
|
||||
|
||||
- Setup `-0.128 ns`, two endpoints: the registered request-pop pulse entered
|
||||
the 15-bit read-pointer carry chain before Gray conversion and `rempty`.
|
||||
- Hold `-4.817 ns`, two endpoints: the asynchronous CLUT-commit and tile-write
|
||||
toggles were timed directly into their explicit first synchronizer stages.
|
||||
|
||||
The FIFO now precomputes hold/pop pointer and empty results independently, so
|
||||
the pop pulse selects only the final mux rather than driving the carry chain.
|
||||
The SDC now cuts only the two asynchronous source-to-stage-0 synchronizer paths,
|
||||
with fatal one-register target-count checks; stages 1 and 2 remain timed. Both
|
||||
synchronizers are explicitly identified to Quartus. The FIFO scoreboard,
|
||||
CLUT CDC, tile CDC, and dense 7,304-fragment integration test all pass exactly.
|
||||
|
||||
## Third-fit setup repair
|
||||
|
||||
The next owner fit (`ae9729fb...`) proved the CDC/FIFO repair: hold closed at
|
||||
0.000 ns. Setup remained unclean at `-0.220 ns` / `-1.193 ns` TNS across eight
|
||||
310 MHz endpoints. The failing paths were now three concrete datapath cones:
|
||||
|
||||
- EMIF 256-bit read data through the 8:1 lane mux into `u_lpddr_rd|rd_data`;
|
||||
- EMIF read data and address-selected blend operands into `diff_r_q`/`diff_g_q`;
|
||||
- `u_zc_emit|ca_tail` through the color-alignment RAM write-address cone.
|
||||
|
||||
The read probe now captures the complete EMIF beat in `rdata_q`, then selects
|
||||
the requested 32-bit lane in a new `S_SEL` stage. The color blender similarly
|
||||
separates beat capture, lane selection, and operand/difference preparation into
|
||||
`R`, `SEL`, and `PREP` states. The color-alignment RAM write enable, address,
|
||||
and data are also registered before the memory write. This removes all three
|
||||
reported source-to-endpoint combinational cones without adding timing
|
||||
exceptions.
|
||||
|
||||
Directed read-probe, color-blend, and Z/color-emitter tests pass. Dense real
|
||||
scene epoch 75 still accepts and passes 7,304 fragments with zero drops and
|
||||
exact comparisons: 0/307,200 Z mismatches and 0/7,304 color mismatches.
|
||||
|
||||
## Hardware acceptance and fidelity finding
|
||||
|
||||
The owner-controlled GUI fit closed cleanly: setup slack `+0.052 ns`, hold
|
||||
slack `0.000 ns`, zero setup/hold TNS, and clean recovery, removal, and minimum
|
||||
pulse checks. The deployed RBF SHA-256 is
|
||||
`6fd81615af95cf51e1a893e04ca34fa1bad7a69c933efcb7fca5c9c091e18a65`.
|
||||
|
||||
All 124 board epochs passed with every texture CRC, palette, staging-record,
|
||||
drain, and drop gate clean. The captured framebuffer reported 114,231
|
||||
nonzero words and bounds `(1,11)..(512,478)`; its MEM SHA-256 is
|
||||
`e31820cfad1d550bb1ea9adf217e21cb59a02be76c6318ce0b34022307bc91ec`.
|
||||
|
||||
The hardware result did not realize the software-reference gain. Against the
|
||||
bilinearly resized PCSX2 frame, the preceding board capture measured MAE
|
||||
21.9782 / RMSE 32.5912, while Ch415 measured MAE 23.6438 / RMSE 35.0255.
|
||||
Ch415 board versus its own software reconstruction measured MAE 12.2877 /
|
||||
RMSE 26.4442. This isolates geometry/coverage precision, rather than
|
||||
scheduler capacity, as the next fidelity boundary. Ch416 therefore preserves
|
||||
the captured XYZ 12.4 fractions and moves coverage to GS pixel centers.
|
||||
@@ -0,0 +1,113 @@
|
||||
# Ch416 — native XYZ 12.4 coverage
|
||||
|
||||
## Objective
|
||||
|
||||
Carry the captured GS fractional screen coordinates through the fixture,
|
||||
primitive FIFO, and raster coverage test. This is a fidelity chapter: draw
|
||||
population, texture state, fog fold, bilinear filtering, Z behavior, and
|
||||
chronological ordering remain the Ch415 baseline.
|
||||
|
||||
## RTL cut
|
||||
|
||||
- `gs_stub` has an opt-in `SUBPIXEL_XY` path that retains each vertex's four
|
||||
X/Y fractional bits alongside the existing small primitive FIFO.
|
||||
- Edge equations use 12.4 endpoints and sample the pixel center at `+8` in
|
||||
that domain. The operands are bounded to signed 17-bit coordinates and
|
||||
signed 35-bit edge results.
|
||||
- The production `GS_SH3_LPDDR_FB` profile enables the path. Legacy profiles
|
||||
retain integer corner-sampled coverage.
|
||||
- Attribute gradients remain on the proven integer coordinate basis for this
|
||||
first structural cut. Moving gradient setup to 12.4 is explicitly deferred
|
||||
and is not hidden inside this coverage change.
|
||||
|
||||
## Fixture and generator controls
|
||||
|
||||
`--subpixel-xy` emits native XYZ2 low-half 12.4 coordinates. Capacity
|
||||
scheduling measures the same 12.4 pixel-center coverage so narrow visible
|
||||
triangles cannot be discarded after integer collapse. Runtime-CLUT fixtures
|
||||
retain the proven single staging CBP and adjacent identical assets without the
|
||||
obsolete preloaded-palette uniqueness gate.
|
||||
|
||||
The full `zsrt139f17` fixture uses `--legacy-strip-kicks` to preserve the exact
|
||||
Ch415 strip population. This makes the experiment one-variable: changing the
|
||||
newer strip-population interpretation at the same time would remove broad
|
||||
scene layers and invalidate the A/B comparison.
|
||||
|
||||
## Evidence so far
|
||||
|
||||
- Legacy raster regression: 16/16 pixels PASS.
|
||||
- Directed subpixel raster regression: 3/3 pixel-center samples PASS.
|
||||
- Authentic three-draw integration: 5,909 fragments fed, 5,907 Z-passing,
|
||||
zero drops, 0/307,200 Z mismatches, and 0/5,858 color mismatches.
|
||||
- Full software reconstruction versus PCSX2 improves from Ch415 MAE 21.0852 /
|
||||
RMSE 32.3385 to Ch416 MAE 19.8099 / RMSE 28.8334. Lit RGB pixels rise from
|
||||
174,167 to 212,915.
|
||||
- Full 263-epoch RTL integration PASS: 1,139,213 fragments fed, 969,301
|
||||
Z-passing, zero drops, 263 markers and ordered drains, no color FIFO or AXI
|
||||
response errors, 0/307,200 final Z mismatches, and 0/235,942 final color
|
||||
mismatches.
|
||||
- The Ch416 RTL framebuffer improves against PCSX2 to MAE 20.4941 / RMSE
|
||||
30.0163 with 199,104 lit RGB pixels. This is a large improvement over the
|
||||
Ch415 board result at MAE 23.6438 / RMSE 35.0255 and 110,329 lit RGB pixels.
|
||||
- RTL versus the Ch416 software reconstruction measures MAE 10.1578 / RMSE
|
||||
19.1650. Native coverage closes a substantial part of the hardware/software
|
||||
gap, but fractional attribute-gradient setup remains visible fidelity debt.
|
||||
|
||||
Artifact SHA-256 identities:
|
||||
|
||||
- full epoch descriptor: `ba1484d23cc9a0caba9d4f82af7ed157fbe692c54a9138d5c0aa02f5ca9f3d87`;
|
||||
- RTL framebuffer MEM: `6aa98a68ee59b5df8457b651baf12decbbb7b71c70c4029ff2cb144a3defa1de`;
|
||||
- RTL framebuffer PNG: `709d6a1438355531b38723654f27b0b07e49524af10d33388fdbb744739cf7b3`;
|
||||
- software reference PNG: `63944f31b8c5f55b70bbddbb89db4ac0ed782a4daf8bd6dad8bb8ad8ec9ad006`.
|
||||
|
||||
## First owner fit and timing repair
|
||||
|
||||
The first owner-controlled Quartus 26.1 GUI fit completed, but is not eligible
|
||||
for deployment. EMIF user-clock setup was -0.433 ns WNS / -6.069 ns TNS;
|
||||
hold was 0.000 ns with zero TNS, and recovery, removal, and minimum-pulse checks
|
||||
were clean. The top-ten setup failures were one physical family from the EMIF
|
||||
`lock_sync_inst|dreg[1]` reset source into duplicated
|
||||
`u_zc_emit|u_req|...|address_reg_b[2]` registers. This was reset routing into
|
||||
the request FIFO's synchronous-read RAM implementation, not the new subpixel
|
||||
coverage datapath.
|
||||
|
||||
`gs_async_fifo` no longer resets `rdata_q` in `REGISTERED_READ` mode. That
|
||||
value is invalid until an accepted read and every consumer already qualifies it
|
||||
with the read transaction, so the reset value had no functional meaning. The
|
||||
cut removes the 5,331-fanout EMIF lock/reset route from the duplicated RAM
|
||||
registers without adding a timing exception or changing FIFO latency.
|
||||
|
||||
Post-repair evidence:
|
||||
|
||||
- generic asynchronous FIFO scoreboard PASS: 3,284 writes and reads, zero
|
||||
duplicate/drop/order errors;
|
||||
- Z/color emitter PASS: 1,500 fragments across three epochs plus directed
|
||||
`ZTST=ALWAYS`, exact final Z/color, `col_ovf=0`, `bresp_err=0`;
|
||||
- three-epoch native-subpixel integration PASS: 5,909 fed, 5,907 passed, zero
|
||||
drops, exact 0/307,200 Z and 0/5,858 color mismatches.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
The repaired owner-controlled Quartus 26.1 GUI fit closed cleanly: EMIF setup
|
||||
is +0.047 ns WNS / 0.000 ns TNS, hold is 0.000 ns WNS / 0.000 ns TNS, and
|
||||
recovery, removal, and minimum-pulse checks are clean. The fit uses 37,959 /
|
||||
46,800 ALMs (81%), 5,261,744 / 7,331,840 memory bits (72%), 336 / 358 RAM
|
||||
blocks (94%), and 157 / 376 DSP blocks (42%). The deployed RBF SHA-256 is
|
||||
`965e15eabdba5260a8d3c795b39a39bebc707d31fee70e3af857ec7e03f94f82`.
|
||||
|
||||
## Board acceptance
|
||||
|
||||
The full 263-epoch board run passed every texture CRC, runtime-palette sum,
|
||||
staging-record count, ordered drain, and fragment-drop gate. The scheduler
|
||||
finished `rc=0`; the FPGA manager remained `operating`. The captured board
|
||||
framebuffer has 235,346 nonzero words, bounds `(0,0)..(511,479)`, sum32
|
||||
`0x19291e79`, and xor32 `0x05d6395b`.
|
||||
|
||||
Most importantly, the board framebuffer is bit-for-bit identical to the full
|
||||
RTL simulation. Both MEM files have SHA-256
|
||||
`6aa98a68ee59b5df8457b651baf12decbbb7b71c70c4029ff2cb144a3defa1de`,
|
||||
and both PNG files have SHA-256
|
||||
`709d6a1438355531b38723654f27b0b07e49524af10d33388fdbb744739cf7b3`.
|
||||
Board versus the bilinearly resized PCSX2 frame measures MAE 20.4941 / RMSE
|
||||
30.0163 with 199,104 lit RGB pixels. Ch416 therefore realizes its simulated
|
||||
fidelity gain on hardware and is accepted.
|
||||
@@ -0,0 +1,153 @@
|
||||
# Ch417 — native 12.4 attribute gradients
|
||||
|
||||
## Objective
|
||||
|
||||
Close the main fidelity debt left by Ch416: coverage already samples native
|
||||
12.4 GS screen coordinates at pixel centers, but color, Z, UV, and STQ planes
|
||||
were still solved from integer vertex coordinates. This chapter makes the
|
||||
attribute setup and evaluation use the same native geometry as coverage while
|
||||
leaving draw population, texture state, blending, fog, and ordering unchanged.
|
||||
|
||||
## RTL cut
|
||||
|
||||
- Triangle orientation and the post-swap gradient determinant now use the full
|
||||
12.4 vertex coordinates. Coordinate deltas are signed 17-bit values and the
|
||||
determinant is signed 35-bit.
|
||||
- The shared gradient numerators are signed 64-bit. Because the determinant is
|
||||
in sixteenths-of-a-pixel squared, the numerator is shifted by 20 rather than
|
||||
16 to produce the existing Q16.16 per-pixel gradient.
|
||||
- The gradient FIFO sideband retains the full 35-bit determinant through the
|
||||
time-shared setup engine and its single sequential divider.
|
||||
- Color, Z, affine UV, and perspective STQ evaluation now use the native
|
||||
pixel-center offset `((pixel << 4) + 8) - vertex12.4`. Products are shifted
|
||||
by 20 to return to the existing attribute domains.
|
||||
- Affine UV filtering consumes the resulting Q16.16 fractional texel bits.
|
||||
This keeps bilinear sampling aligned with the corrected attribute plane.
|
||||
|
||||
Two correctness defects exposed by the new directed tests were repaired in
|
||||
the same path:
|
||||
|
||||
- The packed attribute-prefetch word was missing the LPDDR ABE bit in its
|
||||
unpack destination. Every following field was consequently displaced by
|
||||
one bit, including the vertex-coordinate context. The unpack now includes
|
||||
`gw_d_lpddr_abe` and exactly matches the stored word width.
|
||||
- The opaque affine fragment-Z output retained the reset value instead of the
|
||||
interpolated triangle Z. The emit sideband now selects `s2_interp_z` for an
|
||||
active affine triangle and retains the flat sprite value otherwise.
|
||||
|
||||
## Directed evidence
|
||||
|
||||
- Legacy raster regression: 16/16 pixels PASS.
|
||||
- New native-gradient triangle at `(0.75,0.75)`, `(3.75,0.75)`, and
|
||||
`(0.75,3.75)`: exact R values 72/104/136 and exact Z values
|
||||
1225/1325/1425 at the three covered pixel centers.
|
||||
- Triangle interpolation regression: 31 interior color samples within the
|
||||
established tolerance and 62 exact Z checks, PASS.
|
||||
- Shared gradient divider regression: PASS.
|
||||
- Affine textured triangle: 31/31 UV texels exact, PASS.
|
||||
- Perspective PSMCT32 demo: 96/96 samples exact, PASS.
|
||||
- Combined texture/alpha/Z demo: PASS.
|
||||
- PSMT8 runtime-CLUT triangle: affine, perspective, ABE, and MODULATE paths
|
||||
PASS.
|
||||
- Authentic three-epoch integration: 5,909 fragments fed, 5,909 Z-passing,
|
||||
zero drops, 0/307,200 final Z mismatches, and 0/5,858 color mismatches. The
|
||||
corrected affine Z sideband admits two fragments that Ch416 rejected.
|
||||
|
||||
## Full-scene simulation gate
|
||||
|
||||
The 263-epoch scene uses the same bit-exact divide arithmetic as production.
|
||||
`SH3_FAST_GRAD` selects a one-cycle setup path for quick framebuffer iteration;
|
||||
the final pre-fit gate uses `SH3_BOARD_GRAD`, the production combinational
|
||||
divider and its five-cycle registered settle window. The widened 64/35-bit
|
||||
divide therefore has a 200 ns functional and STA contract at 25 MHz. The
|
||||
sequential-divider implementation also passes its focused regression.
|
||||
|
||||
The full chronological gate passes:
|
||||
|
||||
- 1,145,412 fragments fed and 971,347 Z-passing;
|
||||
- zero fragment drops, request-FIFO high-water mark 1, no color overflow, and
|
||||
no AXI response errors;
|
||||
- 263 markers and 263 ordered read drains (the first drain begins from the
|
||||
reset frame, hence 262 frame-count advances);
|
||||
- 0/307,200 final Z mismatches and 0/235,951 written-color mismatches.
|
||||
|
||||
The dedicated production-control rerun also passes all 263 epochs with
|
||||
`GRAD_SEQ_DIVIDER=0` and `GRAD_DIV_CYCLES=5`: the same 1,145,412 fed /
|
||||
971,347 passing fragments, zero drops, request-FIFO high-water 1, all 263
|
||||
ordered drains, and exact final Z/color. Its framebuffer is byte-identical to
|
||||
the fast arithmetic run (`3d22b442...`), proving that the five-cycle settle FSM
|
||||
changes latency only.
|
||||
|
||||
The focused production board-path regression was corrected in Ch417: its old
|
||||
`GRAD_BOARDPATH` branch accidentally selected the sequential divider. It now
|
||||
selects the actual board combinational divider at five cycles and passes all
|
||||
252/252 interior perspective samples with zero errors. The directed subpixel
|
||||
gradient test also runs at five cycles and passes exact R/Z checks; its timeout
|
||||
is derived from the 14-step gradient setup latency rather than a fixed delay.
|
||||
|
||||
The first owner Analysis & Synthesis attempt exposed a Quartus-specific width
|
||||
limit before fitting: signed `64/64` inference prepended a sign-magnitude bit
|
||||
and requested unsupported `LPM_WIDTHN=65` (Error 272006). Ch417b now divides
|
||||
an explicitly unsigned 64-bit numerator magnitude by the native unsigned
|
||||
35-bit determinant magnitude and restores the quotient sign afterward. This
|
||||
retains signed truncation-toward-zero exactly while fixing the inferred LPM at
|
||||
64/35. All focused gates and the complete 263-epoch production-control gate
|
||||
were rerun after this change; the framebuffer remains byte-identical at
|
||||
`3d22b442...`.
|
||||
|
||||
The compiled Verilator run completed the full gate. The original Icarus run
|
||||
independently matched every count through epoch 59 before it was retired after
|
||||
the faster run passed, including the first Z-rejecting epochs. The two engines
|
||||
therefore agree across both the all-pass prefix and mixed pass/reject behavior.
|
||||
|
||||
The Ch417 framebuffer improves against the bilinearly resized PCSX2 reference
|
||||
from Ch416 MAE 20.4941 / RMSE 30.0163 to MAE 20.1177 / RMSE 29.4268. Lit RGB
|
||||
pixels rise from 199,104 to 199,827. Ch417 versus Ch416 measures MAE 2.9100 /
|
||||
RMSE 9.4742, with 135,574 pixels unchanged exactly.
|
||||
|
||||
Artifact SHA-256 identities:
|
||||
|
||||
- Ch417 RTL framebuffer MEM:
|
||||
`3d22b4421194d444677f3bc9f938e43fd856c6615b92585a10209093d982a625`;
|
||||
- Ch417 RTL framebuffer PNG:
|
||||
`b55b411cc5f6679e6a1ed708ef21ad5eaf5750abb233c6e433ab03594ec9c01e`.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI flow completed successfully at
|
||||
2026-07-18 07:21 EDT. Synthesis confirms that the repaired divider is exactly
|
||||
the intended unsigned `LPM_WIDTHN=64`, `LPM_WIDTHD=35`, with no pipeline
|
||||
inserted. Final STA attached the Ch417 setup=5/hold=4 destination constraint
|
||||
to 49 routed `grad_result_q` registers (including retimed internal divider
|
||||
launches), giving the widened cone its 200 ns functional contract.
|
||||
|
||||
Final signoff is clean:
|
||||
|
||||
- setup +0.140 ns;
|
||||
- hold 0.000 ns;
|
||||
- recovery +0.998 ns;
|
||||
- removal +0.143 ns;
|
||||
- minimum pulse width +0.200 ns.
|
||||
|
||||
The fit uses 38,461 / 46,800 ALMs (82%), 5,261,744 / 7,331,840 memory bits
|
||||
(72%), 336 / 358 RAM blocks (94%), and 160 / 376 DSP blocks (43%). The split
|
||||
RBF SHA-256 is
|
||||
`ef0ecc585b6e0506f30f56bbea44ba56023a305e9d22052877b0e51b1b65e643`.
|
||||
|
||||
## Board acceptance
|
||||
|
||||
The timing-clean RBF was installed and loaded on the Terasic board; the FPGA
|
||||
manager reported `operating` before and after the run. The previous installed
|
||||
image was preserved remotely as `retroDE_ps2.pre_ch417b.core.rbf`.
|
||||
|
||||
The live 263-epoch scheduler completed with `rc=0`. Every texture CRC,
|
||||
runtime-palette sum, staging-record count, ordered drain, AXI response, and
|
||||
fragment-drop gate passed. The final capture contains 307,200 words, sum32
|
||||
`0xc552c256`, xor32 `0x90a0ec16`, 235,280 nonzero words, and bounds
|
||||
`(0,0)..(511,479)`.
|
||||
|
||||
Most importantly, the board framebuffer, fast RTL framebuffer, and complete
|
||||
five-cycle production-control framebuffer are byte-for-byte identical. All
|
||||
three have SHA-256
|
||||
`3d22b4421194d444677f3bc9f938e43fd856c6615b92585a10209093d982a625`.
|
||||
Ch417 is therefore accepted in hardware.
|
||||
@@ -0,0 +1,85 @@
|
||||
# Ch418 — authentic SH3 display presentation mapping (prefit)
|
||||
|
||||
## Objective
|
||||
|
||||
Fix the large presentation mismatch between the accepted Ch417 framebuffer and
|
||||
the PCSX2 224139 frame without changing any rasterized framebuffer byte. Ch418
|
||||
is scanout-only: it maps the captured GS display source onto the board's
|
||||
640x480 HDMI/VGA active raster.
|
||||
|
||||
## Captured register evidence
|
||||
|
||||
The vendored PCSX2 `GSPrivRegSet` layout was used to decode the initial and all
|
||||
eight per-vsync register snapshots in dump 224139. The active context is
|
||||
DISPLAY2 (`PMODE.EN2=1`), stable in every snapshot:
|
||||
|
||||
- `DISPFB2 = 0x0001000000009000` (FBP rotates later), `FBW=8`, `PSM=1`,
|
||||
`DBX=0`, `DBY=32`;
|
||||
- `DISPLAY2 = 0x0037f9ff0203228c`, `DX=652`, `DY=50`, `MAGH=4`,
|
||||
`MAGV=0`, `DW=2559`, `DH=895`.
|
||||
|
||||
Therefore the display source is 512 pixels wide (`FBW*64`) and 448 interlaced
|
||||
source lines beginning at framebuffer line 32. DISPLAY2 expands each source
|
||||
pixel to five VCKs (`MAGH+1`) across 2560 display clocks. Reducing that
|
||||
captured display to the board raster gives the exact integer maps:
|
||||
|
||||
```
|
||||
source_x = floor(output_x * 4 / 5) // 0..639 -> 0..511
|
||||
source_y = 32 + floor(output_y * 14 / 15) // 0..479 -> 32..479
|
||||
```
|
||||
|
||||
## RTL change
|
||||
|
||||
`gs_lpddr_scanout_lb` now has opt-in divider-free presentation mapping:
|
||||
|
||||
- a five-state horizontal phase accumulator implements 512 -> 640;
|
||||
- a fifteen-state vertical phase accumulator implements 448 -> 480;
|
||||
- vertical prefetch starts at captured `DBY=32`;
|
||||
- buffer parity, prefetch throttling, and underflow checks use mapped source y;
|
||||
- all default parameters retain the legacy 1:1 behavior.
|
||||
|
||||
Only `GS_SH3_LPDDR_FB_640` enables the mapping in the DE25 top. The OSD remains
|
||||
in the 640x480 output domain and the LPDDR framebuffer/dump remains byte-exact
|
||||
to Ch417.
|
||||
|
||||
The mapper contains no `/` or variable multiply in synthesizable RTL. Its
|
||||
datapath is one small phase decrement and one coordinate increment per output
|
||||
pixel/line, both in the 25 MHz video domain.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
- New two-axis scanout oracle: 600/600 RGB pixels exact, including horizontal
|
||||
repeats, vertical repeats, DBY offset, alternating line buffers, zero
|
||||
underflow, and zero AXI read errors.
|
||||
- Legacy PSMCT16 line-buffer regression: PASS, underflow=0, read errors=0.
|
||||
- Legacy PSMCT32 line-buffer/concurrency regression: 49,152 pixels exact,
|
||||
underflow=0, read errors=0, 325/325 probes good.
|
||||
- The actual QSF profile macros plus `USE_QSYS_TOP` elaborate cleanly under
|
||||
Icarus (unavailable vendor IP treated as black boxes); no RTL binding or
|
||||
syntax errors.
|
||||
- `git diff --check` and the preview utility's Python compile pass.
|
||||
|
||||
Expected HDMI preview:
|
||||
|
||||
`sim/data/top_psmct32_raster_demo/sh3_zsrt139f17_ch418_scanout.png`
|
||||
|
||||
Preview SHA-256:
|
||||
|
||||
`b710aa7a09db6992faacdaa5a6257d490f1d4fa0112f6c6d20fc388f4b580a63`
|
||||
|
||||
The preview moves the already-rendered lamppost and character onto the PCSX2
|
||||
landmark positions. Full-frame RGB MAE rises from 20.12 to 21.02 because the
|
||||
board is still missing large bright/background draws that the transform now
|
||||
spreads over more output pixels; that global statistic is a coverage metric at
|
||||
this stage, not an alignment metric. The mapping is justified by the captured
|
||||
registers and visible landmark alignment, not by claiming a false MAE win.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for the owner-controlled Quartus 26.1 GUI compile. Required acceptance:
|
||||
|
||||
- Analysis & Synthesis succeeds with no inferred display divider;
|
||||
- setup, hold, recovery, removal, and minimum pulse all close;
|
||||
- after deployment, the unchanged 263-epoch board run still passes and the
|
||||
framebuffer dump remains byte-identical to Ch417;
|
||||
- HDMI shows the 512x448 captured source presented across 640x480.
|
||||
@@ -0,0 +1,158 @@
|
||||
# Ch419 — request-path timing root cut plus rabbit/bench completion (prefit)
|
||||
|
||||
## Objective
|
||||
|
||||
Make one owner compile carry two concrete advances:
|
||||
|
||||
1. remove the actual Ch418 310 MHz setup topology instead of rerolling placement;
|
||||
2. append a bounded set of authentic missing rabbit/bench draws to the accepted
|
||||
Ch417 framebuffer, without regenerating or perturbing its 263 accepted epochs.
|
||||
|
||||
Ch418's captured 512x448-to-640x480 presentation mapping is retained unchanged.
|
||||
|
||||
## Ch418 fit diagnosis
|
||||
|
||||
The 2026-07-18 owner fit completed placement and routing but failed only the
|
||||
EMIF setup domain:
|
||||
|
||||
- setup WNS `-0.388 ns`, TNS `-7.218 ns` at 310 MHz;
|
||||
- hold `0.000 ns` and every other reported timing check clean;
|
||||
- 38,328 / 46,800 ALMs (82%), 336 / 358 RAM blocks (94%).
|
||||
|
||||
The first nine setup endpoints are the same structural family:
|
||||
|
||||
```
|
||||
u_zc_emit|req_rd
|
||||
-> u_zc_emit|u_req|mem...ram_block...~reg1 (RAM enable)
|
||||
```
|
||||
|
||||
`req_rd` has netlist fan-out 747. The worst paths contain no logic levels:
|
||||
`3.370 ns` data delay is almost entirely the `3.035 ns` interconnect route to
|
||||
the wide request FIFO's physical RAM enables. This is not a scanout-mapping
|
||||
path and is not a seed-quality diagnosis.
|
||||
|
||||
The next distinct setup family is `-0.331 ns` inside `u_lpddr_rd_arb`, from a
|
||||
duplicated encoded `grant` bit back into `grant` through response-completion
|
||||
selection.
|
||||
|
||||
## Structural timing cuts
|
||||
|
||||
### Request FIFO RAM enable
|
||||
|
||||
In `gs_async_fifo` registered-read mode, the inferred synchronous RAM head is
|
||||
now sampled every read clock instead of qualifying every physical RAM bank with
|
||||
`rd`. The read pointer still advances only on an accepted pop and `rdata`
|
||||
retains its one-cycle registered-read contract.
|
||||
|
||||
This removes `req_rd` from the 747-load RAM-enable net entirely; it is a
|
||||
topology change, not a fitter hint or another seed roll.
|
||||
|
||||
### Read-arbiter grant release
|
||||
|
||||
`gs_lpddr_rd_arb` now registers the terminal accepted `RLAST` handshake and
|
||||
releases ownership on the following cycle. `ARVALID/ARREADY` are masked after
|
||||
the address handshake and throughout the deliberate release bubble, so a
|
||||
selected requester cannot accidentally issue a second address.
|
||||
|
||||
This breaks the requester-`RREADY` selection cone out of the encoded grant
|
||||
register's direct D path while preserving AXI ownership through response
|
||||
acceptance.
|
||||
|
||||
## Fidelity batch
|
||||
|
||||
The accepted `zsrt139f17` fixture remains byte-for-byte intact. Ch419 appends
|
||||
21 authentic opaque PSMT8 draw runs missing between the accepted group heads in
|
||||
the PCSX2 rabbit/bench region:
|
||||
|
||||
```
|
||||
71361, 71574, 72000, 72213, 72639, 72852, 73278,
|
||||
73491, 73917, 74130, 74556, 74769, 75195, 75408,
|
||||
75834, 76047, 76473, 76686, 77112, 77325, 77538
|
||||
```
|
||||
|
||||
Capacity-safe grouping produces 20 appended epochs and 7,496 independently
|
||||
covered reference pixels. The merged `zsrt139f18` scene has 283 epochs total.
|
||||
Persistent authentic Z decides visibility against the accepted base.
|
||||
|
||||
This is deliberately bounded. An exhaustive supported-draw plan expanded to
|
||||
6,977 epochs and was rejected as operationally useless before deployment.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
The full production-control replay uses the exact board gradient-divider
|
||||
selection and settle FSM, the modified request FIFO, the modified read arbiter,
|
||||
one persistent color/Z memory, and all 283 chronological epochs:
|
||||
|
||||
- 1,177,489 fragments fed;
|
||||
- 984,845 fragments passed authentic Z;
|
||||
- 283 ordered markers and 283 fresh drains;
|
||||
- zero fragment drops, color overflow, or AXI response errors;
|
||||
- final Z mismatch `0 / 307,200`;
|
||||
- final color mismatch `0 / 235,963` written pixels;
|
||||
- testbench `PASS` with `errors=0`.
|
||||
|
||||
Final framebuffer SHA-256:
|
||||
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`
|
||||
|
||||
Relative to the accepted Ch417 production replay, the tail changes 4,446
|
||||
framebuffer pixels at `x=342..416, y=214..363`, the intended right-center
|
||||
rabbit/bench region. Twelve pixels add previously empty coverage; the rest
|
||||
replace Z-visible surface color/detail. Ch417's prior hash was:
|
||||
|
||||
`3d22b4421194d444677f3bc9f938e43fd856c6615b92585a10209093d982a625`
|
||||
|
||||
Supporting regressions also pass:
|
||||
|
||||
- async FIFO: 3,284 exact writes/reads, no duplicate/drop;
|
||||
- read arbiter contention/priority: PASS;
|
||||
- Z/color emit: 1,500 fragments across three epochs, exact;
|
||||
- horizontal-stretch scanout: 600 pixels exact, no underflow/read errors;
|
||||
- PSMCT32 linebuffer: 49,152 pixels exact, no underflow/read errors;
|
||||
- full-frame scanout: 105,968 pixels checked, exact beat count, no errors;
|
||||
- concurrent scanout/reload/probe: 16,384 pixels exact;
|
||||
- host scheduler build and complete 283-epoch asset dry-run: PASS;
|
||||
- board staging set: 323 unique assets, 21,733,472 bytes (duplicates removed);
|
||||
- relevant `git diff --check`: PASS.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
This is ready for one owner-controlled Quartus 26.1 GUI compile. It is not
|
||||
claimed timing-clean until that report exists.
|
||||
|
||||
Acceptance for the fit:
|
||||
|
||||
- the `req_rd -> request RAM enable` family is absent (not merely moved down);
|
||||
- the encoded read-arbiter `grant -> grant` response family is absent or clean;
|
||||
- setup, hold, recovery, removal, and minimum pulse all close;
|
||||
- synthesis still infers the request FIFO RAM and remains inside device limits.
|
||||
|
||||
After a clean fit, deploy the RBF, stage `zsrt139f18`, run the 283-epoch board
|
||||
scene, and require board framebuffer equality with the production replay hash
|
||||
above before accepting the chapter.
|
||||
|
||||
## Owner fit result — 2026-07-18 11:07
|
||||
|
||||
The fit was successful, but setup remained narrowly red:
|
||||
|
||||
- setup improved from `-0.388 ns / -7.218 ns` to
|
||||
`-0.115 ns / -1.150 ns`;
|
||||
- hold improved to `+0.001 ns`; all other timing checks remained clean;
|
||||
- ALMs decreased from 38,328 to 38,234; RAM use remained 336 / 358.
|
||||
|
||||
Both Ch419 targets disappeared completely from the violated top ten:
|
||||
|
||||
- no `req_rd -> request RAM enable` path;
|
||||
- no encoded read-arbiter `grant -> grant` path.
|
||||
|
||||
All ten remaining violations are one newly exposed zero-logic family:
|
||||
|
||||
```
|
||||
u_zc_emit|u_req|rbin[6]
|
||||
-> u_zc_emit|u_req|mem...ram_block...portbaddr[6]
|
||||
```
|
||||
|
||||
The launch bit has fan-out 713. Of the `3.192 ns` data delay, `2.892 ns`
|
||||
(91%) is routing. Ch419 therefore succeeded as a structural peel, but is not
|
||||
accepted for deployment. Ch420 applies the corresponding dedicated read-RAM
|
||||
address stage before the next owner fit.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Ch420 — request FIFO dedicated read-address stage (prefit)
|
||||
|
||||
## Trigger
|
||||
|
||||
Ch419 removed both intended timing families and reduced setup from
|
||||
`-0.388 ns / -7.218 ns` to `-0.115 ns / -1.150 ns`. Its completed fit exposed
|
||||
one uniform remaining family: request FIFO `rbin[6]` directly driving the wide
|
||||
banked RAM's `portbaddr[6]` network.
|
||||
|
||||
This is not a new functional cone and not a reason to reroll placement. The
|
||||
paths have zero logic levels, fan-out 713, and spend `2.892 ns` of `3.192 ns`
|
||||
in one interconnect route.
|
||||
|
||||
## Structural cut
|
||||
|
||||
Registered-read mode in `gs_async_fifo` now has a dedicated RAM-facing
|
||||
`raddr_q` stage, marked `dont_merge, preserve` so it cannot collapse back into
|
||||
the binary CDC pointer.
|
||||
|
||||
`raddr_q` captures `rbin_nxt` while the synchronous RAM reads the prior
|
||||
`raddr_q`. Before each edge, `raddr_q` equals the current head address, so the
|
||||
returned entry and accepted-pop latency are unchanged for isolated and
|
||||
back-to-back reads. The added boundary only separates pointer/empty logic from
|
||||
the physical address fan-out and gives the fitter a placeable/duplicable RAM-
|
||||
local launch register.
|
||||
|
||||
The stage intentionally has no reset or clock enable. The FIFO remains empty
|
||||
for multiple read clocks while the write pointer crosses its two synchronizer
|
||||
flops, so the address has settled to zero before any legal pop. Avoiding reset
|
||||
and enable prevents recreating the prior high-fanout RAM-control failures.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
- async FIFO randomized CDC test: 3,284 writes and reads exact, no duplicate or
|
||||
drop;
|
||||
- Z/color emit: 1,500 fragments across three epochs exact, including directed
|
||||
`ZTST=ALWAYS`;
|
||||
- concurrent scanout/reload/probe: 16,384 pixels exact;
|
||||
- full 283-epoch production-control replay: PASS;
|
||||
- 1,177,489 fragments fed, 984,845 passed Z, zero drops/errors;
|
||||
- final Z mismatch `0 / 307,200` and color mismatch `0 / 235,963`;
|
||||
- framebuffer SHA-256 remains exactly
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`;
|
||||
- relevant `git diff --check`: PASS.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for one owner-controlled Quartus 26.1 GUI compile. Acceptance requires:
|
||||
|
||||
- the direct `rbin -> request RAM portbaddr` family is absent, not merely
|
||||
exchanged for an equally long `rbin -> raddr_q` or `raddr_q -> portbaddr`
|
||||
family;
|
||||
- setup, hold, recovery, removal, and minimum pulse all close;
|
||||
- request FIFO RAM inference and the 336 / 358 RAM-block budget remain intact.
|
||||
|
||||
Do not deploy the RBF until this report is clean. After timing acceptance, run
|
||||
the already-staged Ch419 283-epoch board scene and require exact equality with
|
||||
the production framebuffer hash above.
|
||||
|
||||
## Owner fit result — 2026-07-18 11:59
|
||||
|
||||
The fitter preserved `raddr_q`, and the direct `rbin -> portbaddr` family is
|
||||
absent from the violated paths. Setup did not close:
|
||||
|
||||
- WNS `-0.273 ns`, TNS `-1.613 ns`;
|
||||
- hold `0.000 ns`; all other timing checks clean;
|
||||
- 38,227 ALMs and 336 / 358 RAM blocks.
|
||||
|
||||
The ten reported violations are the next request boundary, not either half of
|
||||
the new address stage. They launch at the request RAM output and terminate at
|
||||
the two packet-type validity registers:
|
||||
|
||||
```
|
||||
u_zc_emit|u_req|mem...portbdataout
|
||||
-> req_stage_frag_valid / req_stage_marker_valid
|
||||
```
|
||||
|
||||
The worst path is `3.443 ns`, with the RAM output `uTco` accounting for
|
||||
`1.396 ns` and three downstream decode/routing levels accounting for the rest.
|
||||
Ch421 removes packet contents from stage-occupancy control and captures the
|
||||
complete packet across one explicit boundary.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Ch421 — complete request-packet boundary (prefit)
|
||||
|
||||
## Trigger
|
||||
|
||||
Ch420 successfully removed the direct request-pointer-to-RAM-address family.
|
||||
Its fit exposed ten paths from the wide request RAM's registered data output,
|
||||
through scene-bit decode, into separate fragment/marker valid registers. The
|
||||
worst was `-0.273 ns`; no address-stage path appeared in the violated top ten.
|
||||
|
||||
## Structural cut
|
||||
|
||||
`gs_lpddr_zc_emit` now captures all `PW` request bits, including the scene bit,
|
||||
into one `req_stage_packet` register. A single `req_stage_valid` occupancy bit
|
||||
is driven only by the already-registered `req_read_pending` control.
|
||||
|
||||
Fragment versus marker selection is decoded after that complete packet
|
||||
boundary:
|
||||
|
||||
```
|
||||
req_stage_frag_valid = req_stage_valid && !req_stage_packet.scene
|
||||
req_stage_marker_valid = req_stage_valid && req_stage_packet.scene
|
||||
```
|
||||
|
||||
Therefore no request RAM output bit feeds stage occupancy or two competing
|
||||
valid-register D cones. The packet register intentionally has no reset;
|
||||
`req_stage_valid=0` makes it unobservable until a complete read is captured.
|
||||
Pop, pending, consume, marker ordering, and external latency are unchanged.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
- async FIFO randomized CDC test: 3,284 writes/reads exact;
|
||||
- Z/color emit: 1,500 fragments exact across three epochs;
|
||||
- concurrent scanout/reload/probe: 16,384 pixels exact;
|
||||
- full 283-epoch production-control replay: PASS;
|
||||
- 1,177,489 fragments fed, 984,845 passed Z, zero drops/errors;
|
||||
- final Z mismatch `0 / 307,200`, color mismatch `0 / 235,963`;
|
||||
- framebuffer SHA-256 remains exactly
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`;
|
||||
- relevant `git diff --check`: PASS.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for one owner-controlled Quartus 26.1 GUI compile. Acceptance requires:
|
||||
|
||||
- no request RAM output path to stage occupancy/fragment/marker valid state;
|
||||
- any RAM-output-to-`req_stage_packet` data path is timing-clean;
|
||||
- setup, hold, recovery, removal, and minimum pulse all close;
|
||||
- request FIFO RAM inference remains intact at the existing device budget.
|
||||
|
||||
Do not deploy the Ch420 RBF. If Ch421 closes, deploy that RBF and execute the
|
||||
already-verified 283-epoch board scene before accepting the chapter.
|
||||
|
||||
## Owner fit result — request path closed, design path exposed
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI fit completed successfully. Ch421 did
|
||||
close the intended 310 MHz EMIF/request family:
|
||||
|
||||
- EMIF setup WNS `+0.155 ns`, TNS `0`;
|
||||
- EMIF hold slack `0.000 ns` and all other timing classes clean;
|
||||
- no request FIFO path appeared in the violated setup paths;
|
||||
- 38,332 ALMs (82%), 55,712 registers, 336/358 RAM blocks (94%), 160 DSPs.
|
||||
|
||||
The fit is nevertheless **not deployable** because placement exposed a separate
|
||||
25 MHz design-clock failure: setup WNS `-1.993 ns`, TNS `-14.856 ns`. All ten
|
||||
reported paths launch at `u_tex|g_bilinear.tap[0][8/9]` and terminate at
|
||||
`raster_pixel_color_q[16/18]`. The worst path contains 30 logic levels and
|
||||
41.955 ns of data delay: both bilinear interpolation stages plus TEX0 vertex
|
||||
modulation were being evaluated in one cycle. That is an independent, real
|
||||
combinational boundary defect, not a reason to undo the now-clean request
|
||||
packet cut. Ch422 addresses it structurally.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Ch422 — registered bilinear output boundary (prefit)
|
||||
|
||||
## Trigger
|
||||
|
||||
Ch421 closed the 310 MHz EMIF/request family at `+0.155 ns`, but its owner GUI
|
||||
fit exposed a design-clock path from a captured bilinear tap through both lerp
|
||||
levels, the texture output mux, TEX0 vertex modulation, and finally
|
||||
`raster_pixel_color_q`. The worst of ten identical-family paths had 30 logic
|
||||
levels, 41.955 ns data delay, and `-1.993 ns` slack against the 40 ns clock.
|
||||
|
||||
## Root cause
|
||||
|
||||
`gs_texture_unit` already captured `tex_color_blend` into `tex_color_hold` while
|
||||
leaving `BS_DONE`. However, during that same `BS_DONE` cycle its external
|
||||
`tex_color` selected the live combinational blend and `out_valid` asserted.
|
||||
Consequently, the perspective palette-bilinear emit path could consume the
|
||||
unregistered value and append four channel-modulation multipliers before the
|
||||
`raster_pixel_color_q` register. The intended hold register was present but
|
||||
was bypassed at the only cycle that mattered for this caller.
|
||||
|
||||
## Structural cut
|
||||
|
||||
The bilinear FSM now has a distinct `BS_OUT` state after `BS_DONE`:
|
||||
|
||||
1. `BS_DONE` evaluates the unchanged two-stage bilinear math and captures it in
|
||||
`tex_color_hold`;
|
||||
2. `BS_OUT` asserts `out_valid` and exposes only `tex_color_hold`;
|
||||
3. the FSM then returns to `BS_IDLE`.
|
||||
|
||||
This adds one internal sampler cycle but changes no pixel arithmetic and no
|
||||
external handshake. Existing consumers already wait on `out_valid` or the
|
||||
`busy` level, so their natural stalls absorb the cycle. The former 30-level
|
||||
tap-to-emit path is split at `tex_color_hold`: bilinear arithmetic ends there,
|
||||
while TEX0 modulation starts from a register on the following cycle.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
- standalone PSMCT32/PSMT8/PSMT4 bilinear suite: all 12 cases PASS;
|
||||
- tile PSMCT32 bilinear integration: PASS;
|
||||
- tile palette-bilinear integration: PASS;
|
||||
- full 283-epoch production-control replay: PASS;
|
||||
- 1,177,489 fragments fed, 984,845 passed Z, zero drops/errors;
|
||||
- final Z mismatch `0 / 307,200`, color mismatch `0 / 235,963`;
|
||||
- framebuffer SHA-256 remains exactly
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for one owner-controlled Quartus 26.1 GUI compile. Acceptance requires:
|
||||
|
||||
- no `g_bilinear.tap[*] -> raster_pixel_color_q[*]` setup family;
|
||||
- bilinear tap paths terminate at `tex_color_hold` and close at 25 MHz;
|
||||
- the already-clean 310 MHz EMIF/request family remains non-negative;
|
||||
- setup, hold, recovery, removal, and minimum pulse all close;
|
||||
- RAM inference and device fit remain within the existing budget.
|
||||
|
||||
Do not deploy the timing-unclean Ch421 RBF. Deploy and board-test Ch422 only if
|
||||
the complete timing report is clean.
|
||||
|
||||
## Owner fit result
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI fit confirmed that the Ch422 structural
|
||||
cut worked. The design clock closed at `+8.604 ns`, the reference clock closed
|
||||
at `+7.564 ns`, and hold, recovery, removal, and minimum-pulse checks were
|
||||
clean. The former bilinear tap-to-`raster_pixel_color_q` family was absent.
|
||||
|
||||
The only remaining failure was the 310 MHz EMIF clock at WNS `-0.012 ns`, TNS
|
||||
`-0.047 ns`, across six endpoints. Five endpoints were color-align tuple data
|
||||
register enables (`ca_wdata_q[21/24/25/28/30]|ena`) reached through
|
||||
`ca_tail -> ca_full -> feed_ok`. The sixth was
|
||||
`req_stage_packet[79]|ena`, whose enable cone included the synchronized EMIF
|
||||
calibration reset. These are independent control-to-data-enable artifacts;
|
||||
Ch423 removes both in one combined structural closeout.
|
||||
|
||||
Ch422 is therefore functionally verified and its intended timing family is
|
||||
closed, but its RBF remains non-deployable because the complete fit was not
|
||||
timing-clean.
|
||||
@@ -0,0 +1,111 @@
|
||||
# Ch423 — control-free data stages (prefit)
|
||||
|
||||
## Trigger
|
||||
|
||||
Ch422 eliminated the design-clock bilinear critical path and left only six
|
||||
310 MHz EMIF setup endpoints: WNS `-0.012 ns`, TNS `-0.047 ns`. The actual
|
||||
post-fit netlist showed that all six ended at data-register clock enables, not
|
||||
at the RAMs or payload datapaths themselves:
|
||||
|
||||
- five `ca_wdata_q[*]|ena` endpoints were driven by the
|
||||
`ca_tail -> ca_full -> feed_ok` control cone;
|
||||
- `req_stage_packet[79]|ena` was driven through the async-reset request-stage
|
||||
process, pulling the high-fanout synchronized EMIF calibration reset into
|
||||
the payload register's enable implementation.
|
||||
|
||||
This chapter handles both members of that same root class in one fit cycle.
|
||||
|
||||
## Structural cuts
|
||||
|
||||
### Request packet stage
|
||||
|
||||
`req_stage_packet` now has its own non-reset `always_ff` block and captures
|
||||
only when the local registered `req_read_pending` pulse is high. Occupancy
|
||||
and observability remain controlled by the separately reset
|
||||
`req_stage_valid`. This preserves the request FIFO protocol while preventing
|
||||
the asynchronous reset cone from being folded into the wide payload register
|
||||
enable.
|
||||
|
||||
### Color-align RAM write tuple
|
||||
|
||||
`ca_waddr_q` and `ca_wdata_q` now capture the prospective write tuple every
|
||||
cycle without reset or `feed_ok` enables. The separately reset `ca_wr_q`
|
||||
continues to be asserted only for an accepted fragment. On the next edge the
|
||||
RAM consumes the prior captured tuple exactly when the prior `feed_ok` raised
|
||||
`ca_wr_q`, preserving address, payload, and commit ordering while removing the
|
||||
FIFO-full comparison from 82 data-register enables.
|
||||
|
||||
No clock constraint, multicycle exception, frequency reduction, or functional
|
||||
pixel change was introduced.
|
||||
|
||||
## Prefit verification
|
||||
|
||||
- asynchronous request FIFO regression: 3,284 exact transfers, PASS;
|
||||
- Z/color emitter regression: 1,500 fragments, zero errors, PASS;
|
||||
- LPDDR scanout-concurrency regression: 16,384 exact pixels, PASS;
|
||||
- full 283-marker / 282-epoch production-control replay: PASS;
|
||||
- 1,177,489 fragments fed, 984,845 passed Z, zero drops/errors;
|
||||
- final Z mismatch `0 / 307,200`, color mismatch `0 / 235,963`;
|
||||
- framebuffer SHA-256 remains exactly
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for one owner-controlled Quartus 26.1 GUI compile. Inspect the actual
|
||||
post-fit timing and synthesis reports. Acceptance requires:
|
||||
|
||||
- no `ca_tail -> ca_wdata_q[*]|ena` or
|
||||
`ca_tail -> ca_waddr_q[*]|ena` setup family;
|
||||
- no synchronized EMIF calibration-reset / `lock_sync` path to
|
||||
`req_stage_packet[*]|ena`;
|
||||
- the Ch422 bilinear family remains absent and the design clock stays clean;
|
||||
- setup, hold, recovery, removal, and minimum pulse are all non-negative;
|
||||
- color-align RAM inference and overall resource use remain intact.
|
||||
|
||||
Do not deploy the Ch422 RBF. If the complete Ch423 report is clean, its RBF is
|
||||
the next board-deployment candidate.
|
||||
|
||||
## Owner fit result — 2026-07-18 17:24
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI fit is signoff-clean:
|
||||
|
||||
- EMIF setup WNS `+0.025 ns`, TNS `0.000 ns`;
|
||||
- 25 MHz design setup WNS `+4.124 ns`, TNS `0.000 ns`;
|
||||
- reference-clock setup WNS `+8.056 ns`, TNS `0.000 ns`;
|
||||
- hold has zero violations (reported minima `0.000 ns`);
|
||||
- recovery minimum `+1.071 ns`, removal minimum `+0.167 ns`;
|
||||
- minimum-pulse-width minimum `+0.200 ns`;
|
||||
- Timing Analyzer completed successfully with zero errors.
|
||||
|
||||
The retired `ca_tail -> ca_wdata_q[*]|ena`, synchronized calibration-reset to
|
||||
`req_stage_packet[*]|ena`, and Ch422 bilinear families are absent from the
|
||||
setup top paths. The color-align memory remains an inferred simple dual-port
|
||||
M20K (`8,832` bits). Final resources are 38,241 / 46,800 ALMs (82%),
|
||||
5,261,744 block-memory bits (72%), and 336 / 358 RAM blocks (94%).
|
||||
|
||||
The accepted deploy artifact is `output_files/retroDE_ps2.core.rbf`, 4,120,576
|
||||
bytes, SHA-256:
|
||||
|
||||
`17d1c1b49aac4d893ed56285cf0703bf375db2ee9f472ea36862cca376ae63fe`
|
||||
|
||||
## Board acceptance
|
||||
|
||||
The RBF was checksum-verified on the DE25-Nano and loaded successfully through
|
||||
`core_loader.sh`; `fpga0` reported `operating`. Live bridge preflight passed:
|
||||
|
||||
- `CORE_ID = 0x50533200`, ABI `0x00000100`, status `0x0000001f`;
|
||||
- frame counter advanced by 145 over two seconds;
|
||||
- raster-overflow count and delta were both zero.
|
||||
|
||||
The exact 283-epoch `sh3_zsrt139f18` production fixture then completed with
|
||||
all texture CRC, CLUT sum, staged-list, fresh-drain, and record-count gates
|
||||
passing. Every epoch reported zero fragment drops and the scheduler ended
|
||||
with `DONE rc=0`.
|
||||
|
||||
The board dumped all 307,200 framebuffer words. Its SHA-256 is
|
||||
|
||||
`a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44`,
|
||||
|
||||
identical to the full production simulation. `cmp` confirms byte-for-byte
|
||||
equality. Ch423 is therefore timing-, simulation-, and hardware-accepted and
|
||||
is the new deployment baseline.
|
||||
@@ -0,0 +1,67 @@
|
||||
# Ch424 — restore the full scene population under native 12.4 coverage
|
||||
|
||||
## Root cause
|
||||
|
||||
Ch416 was described as a one-variable native-subpixel conversion of Ch415,
|
||||
but its fixture was regenerated from only 113 draw IDs. Ch415 actually fed
|
||||
766 captured draws grouped into 254 compatible state runs. The 113 IDs were
|
||||
only the surviving groups' representative indices, so treating them as the
|
||||
source draw list silently discarded most of the scene. The resulting
|
||||
software reference already contained the long spike/band geometry later seen
|
||||
bit-exactly in simulation and on the board; this was not an FPGA timing fault.
|
||||
|
||||
The `--legacy-strip-kicks` compatibility switch also ignored captured ADC
|
||||
kick suppression. Ch424 uses the parsed kick semantics and does not enable
|
||||
that switch.
|
||||
|
||||
## Fixture repair
|
||||
|
||||
`sh3_zsrt139f19` starts from the audited 766-draw / 254-group plan in
|
||||
`/tmp/sh3_opaque_qclip_plan.json`, retains authentic chronological grouping,
|
||||
and enables the already-proven production feature set:
|
||||
|
||||
- authentic Z, color modulation, zero-color fog fold, and bilinear reference;
|
||||
- native GS XYZ 12.4 coordinates and pixel-center coverage;
|
||||
- authentic scissor clipping and normalized full-region clamp;
|
||||
- runtime CLUT staging and 14,500-fragment capacity epochs;
|
||||
- parsed ADC/kick behavior, with no legacy strip override.
|
||||
|
||||
The repaired fixture schedules 125 epochs. Its software reference restores
|
||||
the coherent booth, floor, lamp, character, fence, and bench geometry. With
|
||||
the accepted Ch418 scanout mapping, comparison against the PCSX2 224139 frame
|
||||
is MAE 18.5560 / RMSE 26.2740. The raw 640x480 buffer is MAE 21.0802 / RMSE
|
||||
32.3348.
|
||||
|
||||
## Acceptance gates
|
||||
|
||||
- Production-gradient full RTL replay must finish all 125 epochs with zero
|
||||
drops and exact final Z/color comparisons.
|
||||
- The unchanged, timing-clean Ch423 RBF must pass the same fixture on hardware.
|
||||
- The board framebuffer must match the production-gradient RTL framebuffer
|
||||
bit for bit before Ch424 becomes the visible baseline.
|
||||
|
||||
## Production RTL acceptance
|
||||
|
||||
The production registered-gradient Verilator replay completed all 125 epochs:
|
||||
157,208 fragments were fed, 138,825 passed Z, fragment drops remained zero,
|
||||
and the final comparisons reported 0/307,200 Z mismatches and 0/114,550 color
|
||||
mismatches. Marker/drain counts were complete, `col_ovf=0`,
|
||||
`bresp_err=0`, and the testbench finished PASS.
|
||||
|
||||
The raw RTL frame measures MAE 22.9740 / RMSE 33.6203 against PCSX2. Through
|
||||
the accepted Ch418 scanout mapping it measures MAE 20.9469 / RMSE 29.7626.
|
||||
Unlike the lower scalar score previously claimed for Ch416, this frame also
|
||||
passes the essential visual gate: its scene topology is coherent rather than
|
||||
dominated by false long triangles.
|
||||
|
||||
## Board acceptance
|
||||
|
||||
No new fit was required. The timing-clean Ch423 RBF ran the new assets and
|
||||
passed every one of the 125 texture CRC, runtime-palette, staging-record,
|
||||
drain, and zero-drop gates. The board dumped 307,200 words with 114,504
|
||||
nonzero pixels, bounds `(0,10)..(511,479)`, sum32 `0x42ee1faa`, and xor32
|
||||
`0x0dc19c66`; HDMI was switched to the resulting line-buffer scanout.
|
||||
|
||||
The board and production RTL framebuffer dumps are byte-identical. Both have
|
||||
SHA-256 `2bd7a81d3650c00b1397d5196713634bbd4c87a5e607b75bcf0df346cb7b3126`.
|
||||
Ch424 is accepted as the new visible baseline.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Ch425 — post-process bisection closeout
|
||||
|
||||
## Objective
|
||||
|
||||
Append the captured post-process families to the accepted Ch424 scene and
|
||||
admit them only if the production replay stays exact and the PCSX2 fidelity
|
||||
score improves.
|
||||
|
||||
## Candidates and isolation
|
||||
|
||||
`zsrt139f20` concatenated the 125-epoch Ch424 scene, the 20-epoch PSMCT32
|
||||
darken pass, the 212-epoch Ch405 PSMT8 alpha-fan fixture, and the 18-epoch
|
||||
PSMT4 pass. The 375-epoch production replay was functionally clean but its
|
||||
frame was catastrophically white (mapped MAE 165.23 / RMSE 189.17), so it was
|
||||
not deployed.
|
||||
|
||||
Epoch-boundary replays isolated each family:
|
||||
|
||||
- Ch424 + CT32 darken: mapped MAE 21.3646 / RMSE 30.1358, worse than the
|
||||
Ch424 baseline 20.9469 / 29.7626.
|
||||
- Ch424 + CT32 + old alpha fans: mapped MAE 161.9749 / RMSE 185.4484; this is
|
||||
the white-frame source.
|
||||
- Ch424 + PSMT4 only (`zsrt139f21`): mapped MAE 23.4472 / RMSE 32.3453 and
|
||||
most scene detail was erased.
|
||||
|
||||
Every isolation replay had zero fragment drops and exact RTL Z/color
|
||||
scoreboards. The problem was therefore captured-state interpretation, not
|
||||
timing, loss, or board nondeterminism. Ch425 rejected all three fixtures as
|
||||
generated and left the live board on Ch424 while the alpha source was audited.
|
||||
|
||||
## Status
|
||||
|
||||
Closed as a diagnostic chapter. Ch426 supersedes the alpha result after
|
||||
repairing the fixture's RGBAQ alpha packing.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Ch426 — authentic vertex-alpha repair and atmospheric composite
|
||||
|
||||
## Root cause
|
||||
|
||||
The scheduler generator's `--auth-color-tfx` path preserved captured RGB but
|
||||
called `bake.rgbaq_with_q()`, a legacy helper that always writes alpha
|
||||
`0xff`. The first captured alpha fan actually uses vertex alpha `0x03` at
|
||||
the anchor and `0x00` at the remaining vertices. Under MODULATE+TCC, forcing
|
||||
that alpha to `0xff` made the authentic additive blend roughly two orders of
|
||||
magnitude stronger and produced Ch425's white rectangles.
|
||||
|
||||
`gs_make_sh3_scheduler_fixture.py` now packs the complete captured 32-bit
|
||||
RGBA word when authentic color is enabled. It also fails closed if emitted
|
||||
RGBAQ alpha differs from the canonicalized source vertex. Legacy fixtures
|
||||
without authentic color retain their old opaque-alpha behavior.
|
||||
|
||||
## Repaired fixture
|
||||
|
||||
`zsrt139f22` regenerates the same 53 visible PSMT8 fan draws used by Ch405,
|
||||
in three exact-state groups, with:
|
||||
|
||||
- captured RGBAQ alpha;
|
||||
- native GS 12.4 screen coordinates;
|
||||
- parsed kick semantics, authentic scissor, and framebuffer clipping;
|
||||
- authentic Z/TEST/ZMSK and ALPHA state;
|
||||
- runtime CLUT, MODULATE color, and production bilinear sampling.
|
||||
|
||||
The repaired geometry expands to 218 one-triangle bounded epochs. The final
|
||||
chronological candidate `zsrt139f23` is Ch424's 125 epochs followed by the 20
|
||||
authentic CT32 darken epochs and the 218 repaired alpha epochs: 363 total.
|
||||
The rejected PSMT4 pass is not included.
|
||||
|
||||
## Production RTL acceptance
|
||||
|
||||
The complete replay passed:
|
||||
|
||||
- 1,009,406 fragments fed; 990,062 passed;
|
||||
- 363 markers, zero fragment drops, zero color overflows, zero AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,314;
|
||||
- framebuffer SHA-256
|
||||
`ccf574d7e7ab06a519488c187da08b8c56dce5b923b6909dafba11cad6b4ce4a`.
|
||||
|
||||
Against the PCSX2 frame, the accepted display mapping measures MAE 20.0713 /
|
||||
RMSE 28.9639, improving on Ch424's 20.9469 / 29.7626. The new image adds a
|
||||
soft captured atmospheric veil without the false white rectangles.
|
||||
|
||||
A controlled no-darken replay (`zsrt139f24`, Ch424 + repaired alpha) also
|
||||
passed exactly but measured 20.0890 / 29.0439. The chronological CT32 pass
|
||||
therefore provides a small measured improvement as well as preserving the
|
||||
captured order; `zsrt139f23` remains the accepted candidate.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
No new Quartus compile was needed. The timing-clean Ch423 RBF
|
||||
(`17d1c1b49aac4d893ed56285cf0703bf375db2ee9f472ea36862cca376ae63fe`)
|
||||
ran all 363 epochs on the DE25. Every texture CRC, palette checksum, staged
|
||||
record count, ordered drain, and zero-drop gate passed; the host returned
|
||||
`rc=0` and enabled the HDMI line-buffer source.
|
||||
|
||||
The board dumped all 307,200 words with 196,889 nonzero pixels, bounds
|
||||
`(0,0)..(511,479)`, sum32 `0xb59376d4`, and xor32 `0x28c61f44`. Board and RTL
|
||||
framebuffer dumps are byte-identical and share the SHA-256 above. Ch426 is
|
||||
accepted on silicon and is the current live HDMI baseline.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Ch427 — complete authentic alpha family
|
||||
|
||||
## Objective
|
||||
|
||||
Replace Ch426's hand-selected 53-draw alpha subset with every captured PSMT8
|
||||
alpha-fan draw in the chronological post-process range, while retaining strict
|
||||
RTL and silicon equality and admitting the result only on measured PCSX2
|
||||
fidelity improvement.
|
||||
|
||||
## Precision control
|
||||
|
||||
Before expanding the family, a controlled replay increased the shared
|
||||
reciprocal table from 11 to 13 bits. It changed 32,173 output pixels, but the
|
||||
mapped PCSX2 score was effectively flat: MAE 20.0716 / RMSE 28.9629 versus
|
||||
20.0713 / 28.9639 at 11 bits. The extra table cost therefore had no useful
|
||||
fidelity return and was rejected.
|
||||
|
||||
## Complete family and epoch packing
|
||||
|
||||
The captured interval contains 93 authentic PSMT8 alpha-fan draws, not the 53
|
||||
draws selected by the older Ch405 fixture. The omitted 40 include captured
|
||||
anchor alpha as high as `0x11`; they are real atmospheric contributions, not
|
||||
transparent no-ops.
|
||||
|
||||
An initial one-triangle expansion produced 408 alpha epochs. It also exposed
|
||||
a valid marker corner: a fully Z-rejected epoch emits no color write, leaving
|
||||
the host's stale `frame_drained` observation high and preventing a new drain
|
||||
edge. The acceptance gate was not weakened. Instead, the same ordered draws
|
||||
were safely capacity-packed into 129 productive alpha epochs, with maximum
|
||||
coverage 14,497 fragments. `zsrt139f28` is Ch424's 125 scene epochs, the 20
|
||||
captured CT32 darken epochs, and those 129 alpha epochs: 274 total.
|
||||
|
||||
## Production RTL acceptance
|
||||
|
||||
The complete replay passed:
|
||||
|
||||
- 1,325,665 fragments fed; 1,306,030 passed;
|
||||
- 274 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,423;
|
||||
- framebuffer SHA-256
|
||||
`2aaaabfbe4054b6445458eb43dffb5bcb9d7989c3121875c64fcf0839478d976`.
|
||||
|
||||
Against the PCSX2 reference using the accepted display mapping, the result is
|
||||
MAE 18.9384 / RMSE 27.6464. That is a material improvement over Ch426's
|
||||
20.0713 / 28.9639. The complete family changes 142,182 pixels relative to the
|
||||
53-draw subset and restores broad captured atmosphere without the former
|
||||
white-frame failure.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
No new Quartus compile was required. The timing-clean Ch423 RBF
|
||||
(`17d1c1b49aac4d893ed56285cf0703bf375db2ee9f472ea36862cca376ae63fe`)
|
||||
ran all 274 epochs on the DE25. Every texture CRC, palette checksum, staged
|
||||
record count, ordered drain, and zero-drop gate passed; the host returned
|
||||
`rc=0` and enabled the HDMI line-buffer source.
|
||||
|
||||
The board dumped all 307,200 words with 212,213 nonzero pixels, bounds
|
||||
`(0,0)..(511,479)`, sum32 `0x9c2fcd95`, and xor32 `0x6e7390f3`. Board and RTL
|
||||
framebuffer dumps are byte-identical and share the SHA-256 above. The accepted
|
||||
board image is preserved as
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f28_ch427_board.png`.
|
||||
|
||||
Ch427 is accepted on silicon and is the current live HDMI baseline.
|
||||
@@ -0,0 +1,83 @@
|
||||
# Ch428 — missing blended population and logical 256x256 PSMT8
|
||||
|
||||
## Objective
|
||||
|
||||
Recover captured blended geometry omitted from the Ch427 baseline without
|
||||
returning to draw-count churn: census the missing PSMT8 population, preserve
|
||||
dump chronology, reject families that do not improve the PCSX2 comparison,
|
||||
and require production RTL/silicon identity for any accepted addition.
|
||||
|
||||
## Population census
|
||||
|
||||
The frame contains two previously omitted PSMT8 ABE families before the final
|
||||
opaque scene draws:
|
||||
|
||||
- 70 triangle-strip draws interleaved with the 766 accepted opaque strips;
|
||||
- 240 triangle-list draws using a logical 256x256 PSMT8 texture, concentrated
|
||||
on the foreground character at draw indices 172601 through 175947.
|
||||
|
||||
The coverage planner now supports explicit ABE inclusion, primitive subsets,
|
||||
and maximum draw-index boundaries while retaining its historical opaque-strip
|
||||
default.
|
||||
|
||||
## Rejected interleaved-strip experiment
|
||||
|
||||
`zsrt139f30` inserted all 70 missing ABE strips in authentic dump order and
|
||||
then retained the accepted CT32 and 93-draw alpha families. Its 307-epoch
|
||||
production RTL replay passed every structural gate and produced framebuffer
|
||||
SHA-256
|
||||
`5ec8549ab3b88d429403e5abe1a5074bd329eac576ed87421174b92c1dfe28ae`.
|
||||
|
||||
The addition changed only 836 pixels and slightly worsened the mapped PCSX2
|
||||
score to MAE 18.9599 / RMSE 27.6639 from Ch427's 18.9384 / 27.6464. It was
|
||||
therefore rejected and never deployed to the board.
|
||||
|
||||
## Logical 256x256 texture support
|
||||
|
||||
The 240 triangle-list draws all share the same captured state and texture.
|
||||
The fixture generator now preserves TEX0 logical TW/TH=8 while padding the
|
||||
256x256 PSMT8 source row-by-row into the existing physical 512-texel LPDDR
|
||||
cache stride. No RTL or RBF change is required. Fail-closed generation
|
||||
checks require every logical row to match the reconstructed GS local memory
|
||||
byte-for-byte and require the entire unused right/lower cache padding to be
|
||||
zero. The emitted descriptor was independently decoded as TBP=1024, TBW=8,
|
||||
PSMT8, TW=8, TH=8; its texture CRC is `0x68e8cb9d`.
|
||||
|
||||
The independent software-reference path was also corrected to use logical
|
||||
dimensions for UV wrap/clamp and sampling while retaining the physical
|
||||
512-texel cache stride.
|
||||
|
||||
## Accepted f33 result
|
||||
|
||||
`zsrt139f33` preserves chronology by inserting the three capacity-packed
|
||||
triangle-list epochs between Ch424 scene rows 122 and 123, before the final
|
||||
two opaque scene epochs, CT32 darken, and complete alpha family. The result
|
||||
has 277 epochs.
|
||||
|
||||
Production RTL replay passed with:
|
||||
|
||||
- 1,326,469 fragments fed and 1,306,834 passed;
|
||||
- 277 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,423;
|
||||
- framebuffer SHA-256
|
||||
`c4e26d4f93d9b30f98b0abe0d99ccb4be8d362401b49f07ef76ca85c316b84de`.
|
||||
|
||||
Relative to Ch427, the recovered character family changes 249 pixels within
|
||||
`(323,240)..(360,280)`. The mapped PCSX2 score improves narrowly but in both
|
||||
metrics, to MAE 18.9378 / RMSE 27.6458. This is accepted as authentic local
|
||||
detail, not claimed as a broad visual milestone.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
The timing-clean Ch423 RBF remained loaded. The DE25 completed all 277
|
||||
epochs with every texture CRC, palette checksum, staged-record count, ordered
|
||||
drain, and zero-drop gate passing; the host returned `rc=0` and selected the
|
||||
HDMI line-buffer source. The board dump reports 212,225 nonzero pixels,
|
||||
bounds `(0,0)..(511,479)`, sum32 `0x9c95eca0`, and xor32 `0x6e5a9090`.
|
||||
|
||||
Board and production RTL framebuffer files are byte-identical at the SHA-256
|
||||
above. The accepted board image is preserved as
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f33_ch428_board.png`.
|
||||
|
||||
Ch428 is accepted on silicon and f33 is the current live HDMI baseline.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Ch429 — native PSMT4 character recovery
|
||||
|
||||
## Objective
|
||||
|
||||
Recover visible captured geometry that was still absent from the accepted
|
||||
Ch428 frame, while preserving authentic draw order and refusing additions
|
||||
that merely increase epoch count or worsen the presentation.
|
||||
|
||||
## Deferred PSMT4 postprocess
|
||||
|
||||
`zsrt139f34` appended the existing 18-epoch tiled PSMT4 overlay after the
|
||||
Ch428 frame, in its authentic late-frame position. Its 295-epoch production
|
||||
RTL replay passed every structural gate and produced framebuffer SHA-256
|
||||
`7b167db3927c6e765c464d0e8ddbfb37f23d5b980d87ebdfc9af97b20128e044`.
|
||||
|
||||
The replay also established that the captured overlay is a real contrast
|
||||
operation, not an opaque texture: its alpha equation is
|
||||
`(Cd-Cs)*0xdc/128 + Cs` with COLCLAMP enabled and source RGB values of 0 or
|
||||
24. Applied to the still-underlit reconstructed base, it crushes most of the
|
||||
scene to black and worsens the mapped PCSX2 score to MAE 24.0034 / RMSE
|
||||
32.9396. The overlay is therefore deferred until the missing illumination
|
||||
and base-color population is present; f34 was not deployed.
|
||||
|
||||
## Native 512x1024 PSMT4 support
|
||||
|
||||
A separate captured family of 19 opaque PSMT4 triangle strips covers the
|
||||
foreground character body at draw indices 165536 through 172233. The draws
|
||||
share TBP 9216, TBW 8, a logical 512x1024 texture, and several authentic CLUT
|
||||
banks.
|
||||
|
||||
The coverage planner now accepts explicit PSMT4 selection. The fixture
|
||||
generator reconstructs the canonical GS-swizzled 512x1024 PSMT4 local-memory
|
||||
image, packs its nibbles into the fixed 262,144-byte texture cache, preserves
|
||||
PSM/TBW/TW/TH in TEX0, and samples packed nibbles in the independent software
|
||||
reference. Fast-fit scaling now uses the logical texture dimensions.
|
||||
|
||||
Generation is fail-closed. An independent host check confirmed that all
|
||||
262,144 emitted texture bytes exactly match the local-memory reconstruction;
|
||||
the emitted TEX0 decodes to TBP 1024, TBW 8, PSM `0x14`, TW 9, TH 10. The
|
||||
texture CRC is `0x9ecc08f5`.
|
||||
|
||||
## Accepted f36 result
|
||||
|
||||
`zsrt139f35` groups the 19 strips into 13 exact-state/asset epochs.
|
||||
`zsrt139f36` inserts those epochs at their authentic position before the
|
||||
final opaque draws, CT32 darken, and complete alpha family. The resulting
|
||||
frame has 290 epochs.
|
||||
|
||||
Production RTL replay passed with:
|
||||
|
||||
- 1,331,626 fragments fed and 1,311,991 passed;
|
||||
- 290 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,437;
|
||||
- framebuffer SHA-256
|
||||
`102bf7925b859bcacc91172ecdcd1755b4f01210f327ac918a1c8d7954905d2b`.
|
||||
|
||||
Relative to Ch428, the recovered family changes 3,099 source pixels within
|
||||
`(319,242)..(361,479)` and restores the visible foreground character-body
|
||||
silhouette. On the mapped changed-pixel support its RMSE improves from 15.10
|
||||
to 12.82. Whole-frame mapped RMSE improves from 27.6458 to 27.6303, while
|
||||
MAE moves narrowly from 18.9378 to 18.9407. This is accepted as authentic
|
||||
structural fidelity with a mixed scalar-score result, not described as a
|
||||
broad color-fidelity win.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
No new compile or RBF was required; the timing-clean Ch423 image remained
|
||||
loaded. The DE25 completed all 290 epochs with every texture CRC, palette
|
||||
checksum, staged-record count, ordered drain, and zero-drop gate passing.
|
||||
The scheduler returned `rc=0`, selected the HDMI line-buffer source, and
|
||||
reported 212,673 nonzero pixels, bounds `(0,0)..(511,479)`, sum32
|
||||
`0x00e0b761`, and xor32 `0x9622a8a3`.
|
||||
|
||||
The board and production RTL framebuffer files are byte-identical at the
|
||||
SHA-256 above. The mapped board score is MAE 18.9407 / RMSE 27.6303, and the
|
||||
accepted board image is preserved as
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f36_ch429_board.png`.
|
||||
|
||||
Ch429 is accepted on silicon and f36 is the current live HDMI baseline.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Ch431 — direct-color character highlights
|
||||
|
||||
## Objective
|
||||
|
||||
Restore two captured direct-color highlight strips omitted from the foreground
|
||||
character, preserve their exact interleaving with the accepted PSMT4 body
|
||||
draws, and extend the scheduler fixture path to PSMCT32 without changing RTL
|
||||
or the timing-clean RBF.
|
||||
|
||||
## Preceding sprite rejection
|
||||
|
||||
The three late PSMT8 sprites at indices 198700, 198710, and 198720 were first
|
||||
recovered as an authentic two-epoch candidate. A 14,500-sample bound exceeded
|
||||
the production fresh-drain deadline, so the identical geometry was repacked
|
||||
into four epochs under a 6,000-sample estimate. The 294-epoch production
|
||||
replay then passed with zero drops and exact scoreboards, but the resulting
|
||||
framebuffer was byte-identical to Ch429: persistent authentic Z rejected the
|
||||
entire late family. It was rejected and never deployed.
|
||||
|
||||
## PSMCT32 fixture support
|
||||
|
||||
The draw census identified two ABE PSMCT32 triangle strips at indices 165358
|
||||
and 170407. Both sample a resident 64x64 direct-color texture at TBP 13760,
|
||||
TBW 1 and write the visible framebuffer around the character torso.
|
||||
|
||||
The coverage planner and scheduler generator now accept this direct-color
|
||||
shape. Each source texel is reconstructed through the GS PSMCT32 local-memory
|
||||
reader and placed in the upper-left 64x64 region of the fixed 512-wide,
|
||||
256-KiB LPDDR cache. TEX0 keeps the logical 64x64 dimensions and selects
|
||||
PSMCT32; CLUT staging is deterministic zero data and is ignored by the direct
|
||||
sampler. The cache checksum is `0xb0a82094`.
|
||||
|
||||
The two draws remain separate singleton epochs. `zsrt139f42` inserts the
|
||||
first before the PSMT4 character family and the second between captured draws
|
||||
170177 and 170637. The runtime scheduler merge was also hardened so a sliced
|
||||
input carrying `reuse=1` is forced fresh whenever the immediately preceding
|
||||
output texture checksum differs. This prevents false cache residency across
|
||||
fixture seams.
|
||||
|
||||
## Production and fidelity result
|
||||
|
||||
The complete 292-epoch production replay passed with:
|
||||
|
||||
- 1,331,684 fragments fed and 1,312,049 passed;
|
||||
- 292 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,437;
|
||||
- framebuffer SHA-256
|
||||
`8bf59d48638c16dc9cd4a96d6ddb1104b919dfcefb514a35c6a3298d192e6eb6`.
|
||||
|
||||
The authentic addition changes 14 pixels at `(319,306)..(323,317)`. Mapped
|
||||
PCSX2 comparison improves narrowly in both metrics, from MAE 18.9407 / RMSE
|
||||
27.6303 to MAE 18.9405 / RMSE 27.6301. This is accepted as exact missing
|
||||
character detail, not claimed as a broad visual milestone.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
The timing-clean Ch423 RBF remained loaded. The DE25 completed all 292
|
||||
epochs with every texture checksum, palette checksum, staged-record count,
|
||||
ordered drain, and zero-drop gate passing. The host returned `rc=0`, selected
|
||||
the HDMI line-buffer source, and reported 212,680 nonzero pixels, bounds
|
||||
`(0,0)..(511,479)`, sum32 `0x0108df89`, and xor32 `0x962ca2af`.
|
||||
|
||||
Board and production RTL framebuffer files are byte-identical at the SHA-256
|
||||
above. The accepted board image is preserved as
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f42_ch431_board.png`.
|
||||
|
||||
Ch431 is accepted on silicon and f42 is the current live HDMI baseline.
|
||||
@@ -0,0 +1,69 @@
|
||||
# Ch432 — perspective palette-bilinear handshake repair
|
||||
|
||||
## Result
|
||||
|
||||
Ch432 removes the alternate-sample loss in the serialized perspective
|
||||
palette-bilinear raster path. It restores a broad missing surface population
|
||||
in the unchanged 292-epoch f42 composition and is accepted on silicon.
|
||||
|
||||
The mapped PCSX2 score improves from Ch431's MAE 18.9405 / RMSE 27.6301 to
|
||||
MAE 15.0765 / RMSE 21.9717. This is a fidelity improvement from corrected
|
||||
RTL coverage, not an increase in draw count or a fixture substitution.
|
||||
|
||||
## Root and repair
|
||||
|
||||
Dense perspective epochs emitted almost exactly half of the independently
|
||||
rasterized coverage. Isolated f19 epoch 74 produced 7,301 fragments against
|
||||
14,371 reference pixels. The sampler advanced once when launching the held
|
||||
S1 pixel and again on `PB_RELEASE`, skipping the next S1 sample.
|
||||
|
||||
Launch is now the single normal advance, `PB_WAIT` holds while the four-tap
|
||||
sample returns, and `PB_RELEASE` contributes a final hold cycle. Perspective
|
||||
valid is qualified by the existing Z and texture-alpha advance enables so a
|
||||
frozen beat cannot resubmit the same pixel. The expensive triangle-inside
|
||||
result remains off the global pipeline-enable path.
|
||||
|
||||
An ALWAYS-Z diagnostic had previously added only 571 lit pixels and worsened
|
||||
the reference score, independently ruling out Z as the large coverage root.
|
||||
|
||||
## Simulation acceptance
|
||||
|
||||
The focused perspective PSMT8 regression emits all 31/31 independently
|
||||
covered samples, with no missing pixels, valid colors, correct alpha metadata,
|
||||
and correct MODULATE behavior. The isolated production epoch-74 regression
|
||||
passes its explicit 14,341-fragment count, up from 7,301, with zero drops and
|
||||
exact scoreboards. The affine palette-bilinear regression remains clean.
|
||||
|
||||
The complete unchanged f42 replay passes:
|
||||
|
||||
- 2,339,405 fragments fed and 2,285,783 passed;
|
||||
- 292 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,760;
|
||||
- framebuffer SHA-256
|
||||
`31d21fb5c38816ef99ace1d7b55186dc749720e874ecb055a68b21584ec27037`.
|
||||
|
||||
The repaired f19 scene improves against its independent software reference
|
||||
from MAE 11.7491 / RMSE 24.6649 to MAE 8.7494 / RMSE 18.7008. Its mapped
|
||||
PCSX2 score improves from 20.9469 / 29.7626 to 18.3393 / 25.8374.
|
||||
|
||||
## Fit and silicon acceptance
|
||||
|
||||
The owner GUI fit is timing-clean. Runtime-fabric audit reports 38,367 ALMs,
|
||||
336 RAM blocks, required feeder/texture/Z hierarchy present, and 310 MHz setup
|
||||
met at +0.069 ns. Hold is nonnegative. The deployed RBF SHA-256 is
|
||||
`69b1f91b26d0d78ba654b3d0ccc48f747fa3249f08e2a23535007ff3df40d63e`.
|
||||
|
||||
After explicit loader confirmation, the DE25 completed all 292 epochs with
|
||||
every texture checksum, palette checksum, staged-record count, ordered drain,
|
||||
and zero-drop gate passing. The host returned `rc=0`, selected the HDMI
|
||||
line-buffer source, and dumped 307,200 words with sum32 `0x8304eb9b`, xor32
|
||||
`0x89a68e4f`, 240,414 nonzero 32-bit words, and bounds `(0,0)..(511,479)`.
|
||||
|
||||
The board dump is byte-identical to the production-gradient simulation at the
|
||||
framebuffer SHA above. The accepted board image is
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f42_ch432_board.png`; its PNG
|
||||
SHA-256 is
|
||||
`45d7f3eed485ab4650bcf61e849598423c46302c42465dbd2a2579ae4518fab3`.
|
||||
|
||||
Ch432 is accepted and is the current live HDMI baseline.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Ch432 — perspective palette-bilinear handshake repair (prefit)
|
||||
|
||||
## Objective
|
||||
|
||||
Remove the regular missing-sample pattern from the authentic SH3 perspective
|
||||
scene without changing its fixture, chronology, Z state, textures, palettes,
|
||||
or accepted display mapping. The live f42 composition remains the input; this
|
||||
chapter is an RTL fidelity repair and therefore requires a new owner GUI fit.
|
||||
|
||||
## Root cause
|
||||
|
||||
Dense perspective palette-bilinear epochs emitted almost exactly half of their
|
||||
independent software coverage. Representative f19 epoch 74 emitted 7,301
|
||||
fragments against 14,371 independently rasterized covered pixels. Other dense
|
||||
epochs showed the same approximately 2:1 deficit. A GEQUAL-to-ALWAYS Z-only
|
||||
diagnostic added just 571 lit pixels and worsened PCSX2 score, ruling out Z as
|
||||
the broad missing-surface cause.
|
||||
|
||||
The serialized four-tap sampler launched an S1 pixel in `PB_IDLE`, held the
|
||||
pipeline in `PB_WAIT`, emitted the completed pixel, and then advanced again in
|
||||
`PB_RELEASE`. Because the launch cycle had already advanced the raster walker,
|
||||
the release advance skipped the next waiting S1 sample. This produced the
|
||||
regular screen-door population loss while all existing scoreboards still
|
||||
passed for the subset that was actually emitted.
|
||||
|
||||
## RTL repair
|
||||
|
||||
The sampler now treats launch as the single normal pipeline advance, holds
|
||||
through `PB_WAIT`, and uses `PB_RELEASE` as a final hold cycle. The next S1
|
||||
sample is therefore launched rather than overwritten. Perspective input valid
|
||||
is also qualified by the existing Z and texture-alpha advance enables, so a
|
||||
frozen beat cannot submit the held sample twice.
|
||||
|
||||
This sequencing deliberately keeps the 35-bit triangle-inside result off the
|
||||
high-fanout pipeline-enable path. The only added global gating term is the
|
||||
already-registered two-bit sampler state, minimizing timing risk after the
|
||||
timing-clean Ch431 baseline.
|
||||
|
||||
## Regression gates
|
||||
|
||||
The PSMT8 perspective triangle test now enables the serialized
|
||||
palette-bilinear path and checks independent coverage. It passes 31/31 covered
|
||||
samples with no missing pixels, valid colors, correct alpha metadata, and
|
||||
correct MODULATE behavior. The affine palette-bilinear tile regression also
|
||||
passes unchanged.
|
||||
|
||||
The production isolated epoch-74 gate is now explicit through
|
||||
`+EXPECT_FED=14341`. It passes at 14,341 fragments (up from 7,301), with zero
|
||||
drops, exact Z/color comparisons, and complete marker/drain accounting. The
|
||||
30-pixel difference from the independent 14,371 coverage map is the existing
|
||||
edge-rule/model boundary, not alternate-sample loss.
|
||||
|
||||
The complete unchanged f42 composition passes all 292 epochs:
|
||||
|
||||
- 2,339,405 fragments fed and 2,285,783 passed;
|
||||
- 292 markers and drains;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- Z mismatch 0/307,200 and color mismatch 0/245,760;
|
||||
- framebuffer SHA-256
|
||||
`31d21fb5c38816ef99ace1d7b55186dc749720e874ecb055a68b21584ec27037`.
|
||||
|
||||
## Fidelity result
|
||||
|
||||
The repaired f19 opaque scene lights 173,354 pixels instead of 111,705. Its
|
||||
error against the independent f19 software reference improves from MAE 11.7491
|
||||
/ RMSE 24.6649 to MAE 8.7494 / RMSE 18.7008. Against the PCSX2 frame through
|
||||
the accepted display map it improves from MAE 20.9469 / RMSE 29.7626 to MAE
|
||||
18.3393 / RMSE 25.8374.
|
||||
|
||||
On the complete f42 composition, 240,224 pixels are nonzero. The mapped PCSX2
|
||||
score improves materially from Ch431's MAE 18.9405 / RMSE 27.6301 to MAE
|
||||
15.0765 / RMSE 21.9717. The remaining visual noise is real follow-on work, but
|
||||
this chapter restores a large missing surface population rather than merely
|
||||
adding more draw capacity.
|
||||
|
||||
## Fit boundary
|
||||
|
||||
The preceding owner GUI fit is clean and the runtime-fabric audit passes at
|
||||
38,241 ALMs and 336 RAM blocks, with 310 MHz setup met. Those reports predate
|
||||
this RTL repair. Ch432 is simulation-complete and ready for the owner to run a
|
||||
new Quartus GUI compile; no command-line Quartus flow was used.
|
||||
@@ -0,0 +1,69 @@
|
||||
# Ch433 — UV-optimized STQ packing
|
||||
|
||||
## Root cause
|
||||
|
||||
The repaired Ch432 sampler restored the missing perspective-bilinear samples,
|
||||
but the f19 base scene still showed granular spatial misregistration against
|
||||
its independent floating-point reference. Post-repair isolation rejected a
|
||||
13-bit reciprocal table and rejected nearest filtering: both worsened the
|
||||
software-reference and PCSX2 scores.
|
||||
|
||||
The remaining fixture path used `--fast-fit-scale`. That shortcut selected
|
||||
the largest representable common S/T/Q scale, normally 6144, even though the
|
||||
scheduler generator already had a per-triangle search that scores packed RTL
|
||||
UVs against authentic floating-point UVs. A common scale cancels only at
|
||||
infinite precision; vertex quantization, integer gradients, and reciprocal
|
||||
quantization make the choice observable.
|
||||
|
||||
## One-variable repair
|
||||
|
||||
`zsrt139f43` retains f19's exact 766-draw population, 254 chronological state
|
||||
groups, 125 capacity epochs, native 12.4 geometry, textures, palettes, fog,
|
||||
bilinear reference, Z state, and alpha state. Only `--fast-fit-scale` was
|
||||
removed. The optimizer selected scales from 0.375 through 6144 rather than
|
||||
forcing almost every triangle to 6144.
|
||||
|
||||
The coverage planner no longer emits the shortcut by default. It remains
|
||||
available through an explicit planner `--fast-fit-scale` option for quick
|
||||
diagnostic fixture generation.
|
||||
|
||||
## Production result
|
||||
|
||||
The full registered-gradient f43 replay passed all 125 epochs:
|
||||
|
||||
- 282,363 fragments fed and 232,326 passed Z;
|
||||
- zero drops, color overflows, and AXI errors;
|
||||
- 125 complete markers and drains;
|
||||
- final Z mismatch 0/307,200 and color mismatch 0/176,888.
|
||||
|
||||
Against its independent software reference, f43 improves from f19's
|
||||
MAE/RMSE 8.7494/18.7008 to 4.1633/11.9970. Its mapped PCSX2 score improves
|
||||
from 18.3393/25.8374 to 17.7172/24.8787.
|
||||
|
||||
`zsrt139f44` substitutes the optimized f43 base slices into the complete f42
|
||||
composition while preserving the chronology-correct PSMT4 character,
|
||||
direct-color highlights, and alpha/postprocess population. The production
|
||||
replay passed all 292 epochs with 2,339,405 fragments fed, 2,285,783 passed,
|
||||
zero drops/errors, and exact final Z and color scoreboards. Relative to f42,
|
||||
87,282 pixels change. The mapped PCSX2 score improves from
|
||||
15.0765/21.9717 to 14.8127/21.5567.
|
||||
|
||||
## Silicon acceptance
|
||||
|
||||
No compile was required. The timing-clean Ch432 RBF ran both asset-only
|
||||
fixtures. f43 passed all 125 runtime gates and matched simulation byte for
|
||||
byte at SHA-256
|
||||
`f4ae82153791a66ae8ed7c4b3dd01f609b9706e826e971311c602181f8a08bc7`.
|
||||
|
||||
The complete f44 board run passed all 292 texture, palette, staging, drain,
|
||||
and zero-drop gates. It reported 240,492 nonzero words, bounds
|
||||
`(0,0)..(511,479)`, sum32 `0x96f07662`, xor32 `0x0a031310`, and selected the
|
||||
HDMI line-buffer source. Its 307,200-word framebuffer is byte-identical to
|
||||
production simulation at SHA-256
|
||||
`3f492ab65c12415f4d0cd1aeafc64072870fd43bed237be4a923efbce30d2081`.
|
||||
|
||||
The accepted board image is
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f44_ch433_board.png`; the mapped
|
||||
comparison is
|
||||
`captures/gs/silenthill3/extracted/recon/sh3_zsrt139f44_ch433_board_mapped.png`.
|
||||
Ch433 is accepted, and f44 is the current live HDMI baseline.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Ch434 — current-frame light-buffer reconstruction
|
||||
|
||||
## Fidelity gap
|
||||
|
||||
Ch433's accepted `zsrt139f44` frame used the captured contents of TBP 11264
|
||||
for the two late full-screen darkening sprites. That texture was stale GS
|
||||
local memory rather than the intermediate produced by the current frame.
|
||||
The result retained recognizable scene structure, but its lighting was not
|
||||
chronologically connected to the scene being rendered.
|
||||
|
||||
The omitted current-frame chain is:
|
||||
|
||||
1. a PSMCT16S light target at FBP 256/TBP 8192, built by a clear, 2,053
|
||||
untextured Z-tested additive/subtractive volume draws, and a final bias
|
||||
sprite;
|
||||
2. conversion to the CT32 target at FBP 320/TBP 10240;
|
||||
3. three CT32 ping-pong sprites through FBP 352/TBP 11264 and FBP 320;
|
||||
4. the authentic draws 196167 and 196177, which sample the final TBP 11264
|
||||
image and blend it across the display.
|
||||
|
||||
Ch434 reconstructs this chain as ordered static fixtures. The PSMCT16S
|
||||
target is rendered with the accepted scene Z, decoded to linear CT32, and
|
||||
then passed through the captured CT32 sprite states before the two display
|
||||
composites. This is a static fidelity bridge; animated render-to-texture
|
||||
still requires native target residency and ping-pong ownership in RTL.
|
||||
|
||||
## Triangle-record topology repair
|
||||
|
||||
The first integrated attempt exposed a fixture-contract bug. The scheduler
|
||||
generator expanded captured TRI_STRIP, TRI_FAN, and SPRITE topology into
|
||||
independent three-vertex records, while preserving the captured PRIM type in
|
||||
the feeder header. Because the feeder reissues PRIM for every record, a
|
||||
SPRITE record was assembled as a two-vertex sprite plus a dangling vertex,
|
||||
and strip/fan records restarted with the wrong topology.
|
||||
|
||||
`tools/gs_make_sh3_scheduler_fixture.py` now advertises TRIANGLE for every
|
||||
expanded three-vertex record while preserving authentic TME, ABE, FST, and
|
||||
CTXT state. This changed the broken all-white ping-pong result into a stable
|
||||
binary light mask that retains the booth and character geometry through all
|
||||
three copies.
|
||||
|
||||
## Rejected diagnostics
|
||||
|
||||
- `zsrt139f46` painted the untextured volume family directly into the display.
|
||||
It was useful for isolation but architecturally wrong because the family
|
||||
targets PSMCT16S off-screen storage. It was never deployed.
|
||||
- `zsrt139f48` used the reconstructed chain before the triangle-record repair.
|
||||
It passed the internal RTL scoreboard but collapsed the intermediate to
|
||||
white and over-darkened the display. Its mapped PCSX2 score was
|
||||
MAE/RMSE 19.4763/29.3660, so it was rejected and never deployed.
|
||||
|
||||
## Accepted result
|
||||
|
||||
`zsrt139f49` combines the accepted Ch433 scene, the topology-correct
|
||||
current-frame light composite, and the existing textured-alpha tail. The
|
||||
production registered-gradient simulation passed all 311 epochs:
|
||||
|
||||
- 2,339,914 fragments fed and 2,286,292 passed;
|
||||
- zero fragment drops, color overflows, and AXI errors;
|
||||
- 311 complete markers and drains;
|
||||
- zero final Z and color scoreboard mismatches.
|
||||
|
||||
Against the PCSX2 frame through the accepted display map, f49 scores
|
||||
MAE/RMSE 14.1067/21.3468. This improves both metrics from f44's
|
||||
14.8127/21.5567, with a 0.7060 MAE reduction.
|
||||
|
||||
No compile was required. The timing-clean Ch432 RBF ran the new assets on
|
||||
the Terasic board. All 311 runtime texture, palette, staging, drain, and
|
||||
zero-drop gates passed. The host reported 244,981 nonzero words, bounds
|
||||
`(0,0)..(511,479)`, sum32 `0x385dc4f6`, xor32 `0x6330653c`, and selected HDMI
|
||||
line-buffer source 1.
|
||||
|
||||
The 307,200-word board framebuffer is byte-identical to production
|
||||
simulation at SHA-256
|
||||
`adb21828465758b0601956abef39b649f1f441a0a51831f90826ae76936f6606`.
|
||||
The accepted board image is
|
||||
`captures/gs/silenthill3/extracted/sh3_zsrt139f49_ch434_board.png`; its mapped
|
||||
comparison is
|
||||
`captures/gs/silenthill3/extracted/recon/sh3_zsrt139f49_ch434_board_mapped.png`.
|
||||
Ch434 is accepted, and f49 is the current live HDMI baseline.
|
||||
@@ -0,0 +1,94 @@
|
||||
# Ch435 — FRAME.FBMSK light-buffer alpha
|
||||
|
||||
## Root cause
|
||||
|
||||
The Ch434 current-frame light chain was structurally correct but the second
|
||||
draw of the CT32 conversion stage, draw 195973, has
|
||||
`FRAME.FBMSK=0xff000000`. The scheduler previously discarded that field when
|
||||
relocating the framebuffer, and the external LPDDR color path had no byte-mask
|
||||
transport. Draw 195973 therefore replaced alpha across the full 256x256
|
||||
target instead of preserving the alpha produced by draw 195957. Feeding that
|
||||
incorrect all-128 alpha target through the remaining ping-pong passes made the
|
||||
integrated frame much too dark.
|
||||
|
||||
## Static fidelity result
|
||||
|
||||
The first correction was an asset-boundary reconstruction. It retained alpha
|
||||
128 on the 20,861 lit texels and alpha zero on the 44,675 black texels, then
|
||||
propagated that target through draws 196087, 196108, 196129, 196167, and
|
||||
196177. The resulting 311-epoch `zsrt139f52` replay passed production
|
||||
simulation and the DE25-Nano runtime gates with zero drops, overflows, AXI
|
||||
errors, Z mismatches, or color mismatches.
|
||||
|
||||
The board framebuffer is byte-identical to simulation at SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
Its mapped mean RGB `(26.38, 23.32, 21.19)` is close to the PCSX2 frame mean
|
||||
`(28.47, 23.54, 21.33)`, and the booth, lamp, rabbit, bench, and character are
|
||||
all readable. This supersedes the over-dark f49 result and is the live HDMI
|
||||
asset baseline. The remaining dominant visual defect is spatial speckle and
|
||||
edge noise, not global brightness.
|
||||
|
||||
## Native RTL repair
|
||||
|
||||
The production path now carries a four-bit byte enable derived from
|
||||
`FRAME.FBMSK` with each fragment:
|
||||
|
||||
- the fixture generator preserves the captured upper 32 FRAME bits and
|
||||
rejects masks that are not byte-granular;
|
||||
- the raster wrapper converts each `00` mask byte to an enabled write byte and
|
||||
each `ff` byte to a preserved destination byte;
|
||||
- the request FIFO and color-align RAM carry the byte enable across the GS to
|
||||
EMIF path;
|
||||
- partial opaque writes use the same ordered destination-read/modify/write
|
||||
path as alpha blends;
|
||||
- the color stage merges disabled bytes from the destination after either the
|
||||
GS ALPHA equation or opaque source selection.
|
||||
|
||||
The directed color-blend regression preserves destination alpha with
|
||||
`BE=0111`, producing `0x8024180c`. The 1,500-fragment Z/color regression also
|
||||
passes with zero errors.
|
||||
|
||||
The regenerated authentic two-draw fixture `zsrt139l3f` contains
|
||||
`ff000000000a0000` in draw 195973's FRAME header. Its registered-gradient
|
||||
simulation passes 22 epochs and 131,072 fragments with zero drops, overflows,
|
||||
AXI errors, Z mismatches, or color mismatches. Most importantly, the native
|
||||
256x256 output is byte-identical in all 65,536 words to the static corrected
|
||||
target: 44,675 black/alpha-zero texels and 20,861 lit/alpha-128 texels.
|
||||
|
||||
## Accepted fit
|
||||
|
||||
The owner-controlled Quartus 26.1 GUI compile completed successfully on
|
||||
2026-07-19. The accepted RBF is 4,112,384 bytes with SHA-256
|
||||
`55b23b94f51f1aab271d91aa4fa766561c044b9633146f25f4242b431f6ce902`.
|
||||
All signoff classes are nonnegative:
|
||||
|
||||
- EMIF setup WNS `+0.083 ns`, TNS `0.000 ns`;
|
||||
- 25 MHz design setup WNS `+6.324 ns`, TNS `0.000 ns`;
|
||||
- hold minimum `0.000 ns`, with zero TNS;
|
||||
- recovery minimum `+1.074 ns`;
|
||||
- removal minimum `+0.017 ns`;
|
||||
- minimum-pulse-width minimum `+0.200 ns`.
|
||||
|
||||
Final resources are 38,387 / 46,800 ALMs (82%), 5,327,792 / 7,331,840
|
||||
block-memory bits (73%), 344 / 358 RAM blocks (96%), and 160 / 376 DSP
|
||||
blocks (43%).
|
||||
|
||||
## Hardware acceptance
|
||||
|
||||
The RBF checksum was verified on the DE25-Nano and `core_loader.sh` loaded it
|
||||
successfully; `fpga0` reported `operating`. The authentic 22-epoch
|
||||
`zsrt139l3f` fixture then passed every texture CRC, staging, fresh-drain, and
|
||||
zero-drop gate. Its 307,200-word framebuffer has SHA-256
|
||||
`e2b9f847fb64f5dbc70f112df91c6fccc54bf439138f772927150ff99aa026ce`,
|
||||
byte-identical to production simulation. The native target contains exactly
|
||||
20,861 lit/alpha-128 pixels and 44,675 black/alpha-zero pixels in its 256x256
|
||||
region, proving that draw 195973 preserves the destination alpha byte on
|
||||
silicon.
|
||||
|
||||
The complete 311-epoch f52 scene was then replayed on the same RBF. All
|
||||
epochs completed with zero fragment drops and its framebuffer remained
|
||||
byte-identical to simulation at SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
HDMI therefore ends on the readable f52 scene. The accepted artifact is now
|
||||
the board's standard `/home/terasic/cores/retroDE_ps2.core.rbf`; the previous
|
||||
artifact is retained as `retroDE_ps2.pre_ch435.core.rbf`.
|
||||
@@ -0,0 +1,168 @@
|
||||
# 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.
|
||||
@@ -0,0 +1,151 @@
|
||||
# Ch437 — zero-line-RAM horizontal-linear presentation prefit
|
||||
|
||||
## Purpose
|
||||
|
||||
Ch436 made the captured 15:14 vertical presentation linear while retaining the
|
||||
Ch418 nearest-neighbour 5:4 horizontal map. The accepted framebuffer and board
|
||||
replay are exact, so this chapter changes presentation only: it reconstructs
|
||||
the fractional horizontal samples that nearest presentation repeats.
|
||||
|
||||
For output column `x`, the exact source coordinate is:
|
||||
|
||||
- `x0 = floor(x*4/5)`;
|
||||
- `xf = (x*4) mod 5`;
|
||||
- `x1 = min(x0+1, 511)`.
|
||||
|
||||
The existing five-state mapper already produces both `x0` and `xf`; no divider
|
||||
or new wide coordinate cone is introduced.
|
||||
|
||||
## Architecture
|
||||
|
||||
The rejected Ch436 horizontal prototype mirrored both complete line buffers to
|
||||
obtain an `x+1` read port. Quartus implemented the mirrors as 30,720 registers
|
||||
and rejected the design at 6,270 required LABs. Ch437 does not restore those
|
||||
arrays.
|
||||
|
||||
Instead, each physical line buffer retains one video read address. Two
|
||||
256-bit register slots hold the current and next beat for each of the two
|
||||
resident source rows. Horizontal blanking alternately primes beats 0 and 1.
|
||||
When active scanout enters beat K, the retired parity slot is refilled with
|
||||
beat K+1. The 5:4 cadence provides ten output clocks for each eight-source-pixel
|
||||
beat, so the next beat is resident well before the single lane-7 boundary
|
||||
sample needs it.
|
||||
|
||||
The interpolation order is separable and matches the software oracle:
|
||||
|
||||
1. blend row L and L+1 at x0 with denominator 15;
|
||||
2. blend row L and L+1 at x1 with denominator 15;
|
||||
3. blend those two results with denominator 5.
|
||||
|
||||
The source-right edge clamps at pixel 511. Other profiles retain their existing
|
||||
nearest/1:1 path through default-off parameters.
|
||||
|
||||
## Evidence before owner fit
|
||||
|
||||
Directed and legacy regressions:
|
||||
|
||||
- `tb_gs_lpddr_scanout_lb_hstretch`: 2,400 checked, zero errors, zero underflow,
|
||||
across eight 256-bit beats and the clamped right edge;
|
||||
- `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;
|
||||
- `tb_gs_lpddr_scanout_fb`: 105,968 checked, zero errors/underflow;
|
||||
- Verilator lint: no errors;
|
||||
- relevant `git diff --check`: pass.
|
||||
|
||||
The exact software presentation model improves the accepted f52 framebuffer's
|
||||
PCSX2 comparison again:
|
||||
|
||||
- Ch436 vertical-linear: MAE/RMSE `14.2678 / 21.3085`;
|
||||
- Ch437 separable-linear: MAE/RMSE `13.9525 / 20.6568`.
|
||||
|
||||
This is a visible smoothing of the horizontal staircase/noise without changing
|
||||
framebuffer bytes, render ordering, LPDDR traffic, or draw count.
|
||||
|
||||
## Owner GUI compile acceptance
|
||||
|
||||
### Rejected first fit
|
||||
|
||||
The first owner fit rejected the initial cache implementation at placement:
|
||||
6,337 LABs were required on the 4,680-LAB device. The synthesis/netlist report,
|
||||
not the summary alone, showed the exact cause:
|
||||
|
||||
- `u_lpddr_scan_lb` contained 32,312 registers;
|
||||
- the SDC line-buffer reset collection found 30,720 destinations;
|
||||
- `lb0[0..79]` and `lb1[0..79]` appeared as individual flip-flop nodes;
|
||||
- no line-buffer M20K payload remained in the scanout hierarchy.
|
||||
|
||||
The conditional reads used to prime/refill the cache prevented Quartus from
|
||||
recognizing the dual-clock RAM template. This was the same physical failure
|
||||
mode as the rejected Ch436 mirrors, despite the source-level arrays not being
|
||||
duplicated.
|
||||
|
||||
### Corrected inference-safe candidate
|
||||
|
||||
Each physical array now has exactly one unconditional video-clock read:
|
||||
|
||||
```systemverilog
|
||||
lb0_video_rd_q <= lb0[video_rd_addr_q];
|
||||
lb1_video_rd_q <= lb1[video_rd_addr_q];
|
||||
```
|
||||
|
||||
Address, valid, and beat tag are registered beside those outputs. A separate
|
||||
control process fills the two-beat register cache only from the registered
|
||||
RAM outputs. It never indexes `lb0` or `lb1` directly. This is the canonical
|
||||
simple-dual-port, dual-clock inference form already proven by the accepted
|
||||
line-buffer implementation.
|
||||
|
||||
The corrected candidate retains identical horizontal results: the expanded
|
||||
2,400-pixel test, all PSMCT32 legacy regressions, Verilator lint, and relevant
|
||||
`git diff --check` pass again.
|
||||
|
||||
The corrected RTL was accepted by an owner-controlled Quartus 26.1 GUI compile.
|
||||
The generated core is:
|
||||
|
||||
- `retroDE_ps2.core.rbf`, 4,132,864 bytes;
|
||||
- SHA-256
|
||||
`3dd624cd34e56cf553fc92c47c3a0d47dc6a9c0513f37cbf72f2c4f6f9c71559`.
|
||||
|
||||
All report gates pass:
|
||||
|
||||
- fitter successful at 39,077 / 46,800 ALMs (83%), 56,526 registers,
|
||||
5,327,792 block-memory bits, 344 / 358 RAM blocks, and 163 / 376 DSPs;
|
||||
- both line buffers are inferred as simple-dual-port, dual-clock
|
||||
`altera_syncram` instances, five M20Ks and 15,360 bits apiece;
|
||||
- the scanout hierarchy contains 1,602 registers rather than the rejected
|
||||
implementation's 32,312;
|
||||
- EMIF setup slack is +0.069 ns with zero TNS;
|
||||
- the 25 MHz design-clock setup slack is +5.473 ns with zero TNS;
|
||||
- all hold classes have zero TNS and minimum slack 0.000 ns;
|
||||
- minimum recovery, removal, and pulse-width slack are respectively
|
||||
+1.056 ns, +0.164 ns, and +0.200 ns.
|
||||
|
||||
## Hardware acceptance
|
||||
|
||||
The accepted core was installed on the DE25-Nano and loaded successfully.
|
||||
The live fabric reported the expected core ID/ABI, healthy status, active HDMI
|
||||
scanout, an advancing frame counter, and zero raster overflow.
|
||||
|
||||
The complete f52 scheduler replay then passed on hardware:
|
||||
|
||||
- all 311 epochs completed;
|
||||
- all fresh texture CRCs matched and resident reuse checks passed;
|
||||
- every epoch reported zero fragment drops;
|
||||
- `DONE rc=0 (all gates passed)`;
|
||||
- the dump contained 307,200 words, `sum32=0xaad0b94d`,
|
||||
`xor32=0x33138181`, 245,155 nonzero pixels, and bounds `(0,0)..(511,479)`.
|
||||
|
||||
The retrieved Ch437 board framebuffer has SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`
|
||||
and is byte-identical to the accepted Ch436 framebuffer. This is the intended
|
||||
result: Ch437 changes only the HDMI presentation filter, after framebuffer
|
||||
storage, while preserving the proven renderer and replay output.
|
||||
|
||||
Ch437 is accepted. Its closure criteria were:
|
||||
|
||||
- fitter completes within the device's 4,680-LAB capacity;
|
||||
- line buffers remain inferred M20Ks and total RAM stays at 344 / 358 blocks;
|
||||
- all setup, hold, recovery, removal, and pulse-width classes are nonnegative;
|
||||
- the narrow EMIF request-address family remains clean;
|
||||
- the 25 MHz presentation domain remains clean.
|
||||
|
||||
All five criteria passed before deployment.
|
||||
@@ -0,0 +1,136 @@
|
||||
# Ch438 — source-space 3x3 binomial scanout (pre-fit)
|
||||
|
||||
## Why this chapter
|
||||
|
||||
Ch437 proved exact horizontal and vertical linear presentation, but the complete
|
||||
f52 framebuffer still contains high-frequency speckle that the PCSX2 reference
|
||||
does not. Adding more draws does not address that deficit. An offline filter
|
||||
sweep identified a source-space separable `[1 2 1]/4` low-pass followed by the
|
||||
authentic nearest presentation map as the best small, bounded scanout change.
|
||||
|
||||
The renderer and LPDDR framebuffer are unchanged. Ch438 only changes pixels at
|
||||
the final HDMI scanout boundary, so the accepted f52 framebuffer SHA remains the
|
||||
rollback and equivalence anchor.
|
||||
|
||||
## RTL architecture
|
||||
|
||||
- `gs_lpddr_scanout_lb.sv` adds opt-in `BINOMIAL_3X3_FILTER`.
|
||||
- SH3 full-frame scanout disables the Ch436/437 linear filters and enables the
|
||||
binomial filter.
|
||||
- A third rotating line buffer retains source rows `y-1`, `y`, and `y+1`.
|
||||
- Each physical line RAM still has one unconditional registered video read, the
|
||||
Quartus-safe inference form established in Ch437.
|
||||
- Six 256-bit register-cache slots retain the even/odd beats for all three rows.
|
||||
- Horizontal and vertical passes each compute `(a + 2*b + c + 2) >> 2`.
|
||||
- Horizontal edges clamp at source columns 0 and 511. Vertical edges clamp at
|
||||
source rows 32 and 479.
|
||||
- The filtered source pixel is presented with the captured nearest maps:
|
||||
`sx=floor(x*4/5)` and `sy=32+floor(y*14/15)`.
|
||||
- The AXI prefetcher still stays one source row ahead; its physical write target
|
||||
now rotates 0/1/2 rather than alternating 0/1.
|
||||
|
||||
Expected fit delta from the accepted Ch437 build is one 640-pixel physical RAM
|
||||
bank (approximately five M20Ks in the established 256-bit implementation), two
|
||||
additional 256-bit beat-cache registers, and small shift/add logic. Ch437 used
|
||||
344/358 RAM blocks, so the expected result is about 349/358.
|
||||
|
||||
## Exact preview result
|
||||
|
||||
Input framebuffer:
|
||||
|
||||
- `captures/gs/silenthill3/extracted/sh3_zsrt139f52_ch435_board.png`
|
||||
- Its underlying f52 board dump is byte-identical to the accepted Ch436/437
|
||||
framebuffer (`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`).
|
||||
|
||||
Reference: `captures/gs/silenthill3/pcsx2_ref_224139.png`.
|
||||
|
||||
| Scanout | MAE | RMSE |
|
||||
|---|---:|---:|
|
||||
| Ch437 separable linear | 13.9525 | 20.6568 |
|
||||
| Ch438 3x3 binomial + nearest | 13.1111 | 19.1051 |
|
||||
|
||||
Preview:
|
||||
`captures/gs/silenthill3/extracted/recon/sh3_zsrt139f52_ch438_binomial_preview.png`
|
||||
|
||||
Preview SHA-256:
|
||||
`5a0402c523b64e252746067488177b08f0d23ab8a4a7dc09857e914c07f269f1`
|
||||
|
||||
The preview is generated by `tools/preview_scanout_ch438.py`, which reproduces
|
||||
the RTL's rounding after each separable pass.
|
||||
|
||||
## Pre-fit verification
|
||||
|
||||
- `make -C sim tb_gs_lpddr_scanout_lb_binomial`
|
||||
- 2,400/2,400 output pixels exact
|
||||
- zero underflow
|
||||
- zero read errors
|
||||
- `make -C sim tb_gs_lpddr_scanout_lb_hstretch`
|
||||
- Ch437 compatibility: 2,400/2,400 exact
|
||||
- zero underflow/read errors
|
||||
- `make -C sim tb_gs_lpddr_scanout_lb`
|
||||
- legacy scanout PASS under its established one-pixel-per-line simulation
|
||||
alignment allowance
|
||||
- zero underflow/read errors
|
||||
- Targeted Verilator lint of the binomial parameterization: no errors, latches,
|
||||
multidriven signals, combinational loops, or range errors.
|
||||
- Repository `git diff --check`: clean.
|
||||
|
||||
The repository-wide `make lint` still stops at the pre-existing unsupported
|
||||
default-valued `rewind_i` input in `sif_dma_ee_ram_bridge_stub.sv`; the targeted
|
||||
scanout lint is clean and this unrelated baseline issue was not changed.
|
||||
|
||||
## Owner fit gate
|
||||
|
||||
Ready for a fresh Quartus 26.1 GUI compile. Accept only if:
|
||||
|
||||
1. fit succeeds;
|
||||
2. all setup/hold/recovery/removal/pulse-width checks are clean;
|
||||
3. RAM use remains at or below 358 blocks;
|
||||
4. all three scanline arrays infer as RAM rather than register banks.
|
||||
|
||||
## First fit and timing-root correction
|
||||
|
||||
The first Ch438 GUI fit completed successfully and confirmed the scanout
|
||||
resource projection:
|
||||
|
||||
- 38,904 ALMs
|
||||
- 57,173 registers
|
||||
- 349/358 RAM blocks
|
||||
- 160 DSP blocks
|
||||
|
||||
All non-setup checks were clean, but EMIF setup failed at `-0.120 ns`, TNS
|
||||
`-3.122`, across 64 endpoints. The actual top-ten family was unrelated to the
|
||||
new filter datapath:
|
||||
|
||||
- launch: `u_zc_emit|u_req|raddr_q[6]`
|
||||
- capture: the deep request FIFO's packed `mem_rtl_0` port-B address banks
|
||||
- launch-register fanout: 744
|
||||
- data path: one 2.886 ns route, zero logic levels
|
||||
|
||||
This is the established 93-bit x 16K request-FIFO physical-address family. The
|
||||
additional scanout RAM changed placement enough to expose it again.
|
||||
|
||||
The correction keeps the full 16K request depth and banks only the payload into
|
||||
two independently inferred RAM arrays. Each half has a separate preserved
|
||||
registered read address, reducing the single 744-load launch net to two roughly
|
||||
half-sized physical trees. FIFO order, pointer CDC, and registered-read latency
|
||||
are unchanged. The banked form is enabled only on `u_zc_emit.u_req`; all other
|
||||
`gs_async_fifo` users retain the monolithic default.
|
||||
|
||||
Post-cut verification:
|
||||
|
||||
- default async FIFO stress: 3,285 writes/reads, zero errors;
|
||||
- monolithic registered-read stress: 3,285 writes/reads, zero errors;
|
||||
- banked registered-read stress: 3,285 writes/reads, zero errors;
|
||||
- full f52 production Verilator replay:
|
||||
- 311 epochs;
|
||||
- 2,339,914 fragments fed;
|
||||
- 2,286,292 passed;
|
||||
- zero drops, color overflow, BRESP errors, Z mismatches, or color mismatches;
|
||||
- PASS;
|
||||
- post-cut framebuffer SHA-256:
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`,
|
||||
byte-identical to the accepted Ch437 board framebuffer.
|
||||
|
||||
The first timing-red RBF (`7fa4724f...`) was not deployed. A fresh GUI compile
|
||||
is required for the banked-address correction.
|
||||
@@ -0,0 +1,279 @@
|
||||
# Ch439 — measured FIFO right-sizing and scanout write-port timing convergence
|
||||
|
||||
## Why this chapter exists
|
||||
|
||||
The second Ch438 GUI fit completed successfully but was not timing-clean and
|
||||
was not deployed. Its RBF SHA-256 was
|
||||
`b5865b599101d429b86c67c25ae9688c0f6dda334aa7ebbcbd664f31226aa602`.
|
||||
The fit used 39,442 ALMs, 56,446 registers, 349/358 M20Ks, and 160 DSPs.
|
||||
|
||||
The actual post-fit STA report showed three concrete families:
|
||||
|
||||
- setup WNS -0.924 ns / TNS -12.931 ns in the 310 MHz EMIF domain;
|
||||
- six of the top ten setup paths were
|
||||
`u_zc_emit|u_req|raddr_lo_q[1]` to physical `mem_lo` RAM address ports;
|
||||
- one setup path at -0.403 ns was `u_lpddr_scan_lb|r_data_q[240]` to the
|
||||
`lb1` RAM write port;
|
||||
- the only negative design-clock hold path was -4.221 ns from the bridge's
|
||||
quasi-static `lpddr_video_src_q` to `vsrc_cap_d` across unrelated clocks.
|
||||
|
||||
The preceding two-way width bank did not reduce the request RAM count and made
|
||||
placement worse than the original packed 16K FIFO. This chapter therefore
|
||||
removes that banked form from the production instance instead of chasing it
|
||||
with another seed.
|
||||
|
||||
## Structural correction
|
||||
|
||||
### Request FIFO: 16K to 8K from measured occupancy
|
||||
|
||||
The complete 311-epoch f52 production replay was rerun at depth 16,384 while
|
||||
recording the per-epoch request occupancy. The maximum was 6,115 entries at
|
||||
epoch 148. The next power-of-two depth, 8,192, therefore leaves 2,077 entries
|
||||
or 34 percent measured headroom. It also halves the packed 93-bit request
|
||||
FIFO's depth, expected M20K footprint, and physical read-address tree.
|
||||
|
||||
The production `u_zc_emit` instance now uses `REQ_DEPTH=8192` and the ordinary
|
||||
monolithic registered-read FIFO. `zc_g_drops` remains the fail-closed runtime
|
||||
guard if a future fixture exceeds the measured envelope.
|
||||
|
||||
### Scanout line buffers: RAM-local physical write stage
|
||||
|
||||
The response stage no longer drives all three line-buffer RAM write ports.
|
||||
`L_R` copies each returned beat directly into data/address/enable registers
|
||||
dedicated to the selected physical RAM. Those registers commit independently
|
||||
while the FSM issues or waits for the next single-beat read; `L_C` is used only
|
||||
once to flush the final beat of a row. The fitter can place each 256-bit launch
|
||||
bank beside its RAM without adding a state to every beat.
|
||||
|
||||
### LPDDR video-source bundled CDC
|
||||
|
||||
`lpddr_video_src_q` is written before `lpddr_ctrl_commit_w` toggles.
|
||||
`vsrc_cap_d` samples the stable data only after that toggle traverses the
|
||||
three-flop `commit_d_sync`. The raw zero-cycle hold analysis between unrelated
|
||||
clocks is therefore non-functional. The SDC now cuts only HOLD for this exact
|
||||
source/destination pair and retains a 2 ns maximum net-delay bound. Setup is
|
||||
not false-pathed.
|
||||
|
||||
## Verification before the next GUI compile
|
||||
|
||||
- binomial scanout: 2,400/2,400 exact pixels, zero underflow/read errors, PASS;
|
||||
- horizontal-stretch scanout: 2,400/2,400 exact pixels, zero underflow/read
|
||||
errors, PASS;
|
||||
- registered asynchronous FIFO stress: 3,285 writes/reads, zero errors, PASS;
|
||||
- directed Z/color integration: 1,500 fragments, zero color overflow/BRESP
|
||||
errors, PASS;
|
||||
- complete f52 replay at the shipping 8K request depth:
|
||||
- 311 epochs;
|
||||
- 2,339,914 fragments fed and 2,286,292 passed;
|
||||
- zero drops, Z mismatches, color mismatches, color overflow, or BRESP errors;
|
||||
- PASS;
|
||||
- Ch439 framebuffer SHA-256:
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`;
|
||||
- byte-identical to the accepted Ch437 framebuffer and the prior Ch438
|
||||
production simulation.
|
||||
|
||||
No Ch438 timing-red RBF has been deployed. A fresh Quartus 26.1 GUI compile is
|
||||
required for this consolidated Ch439 correction.
|
||||
|
||||
## First Ch439 fit and hardware feedback
|
||||
|
||||
The first owner GUI fit of the resource-relieved design was fully signoff-clean:
|
||||
EMIF setup +0.098 ns, all hold classes nonnegative, 39,514 ALMs, 57,331
|
||||
registers, 309/358 M20Ks, and 160 DSPs. It also proved that the 8K cut removed
|
||||
exactly 40 RAM blocks as predicted. The generated RBF SHA-256 was
|
||||
`7167deb651c08057828a360b6083ec27eb140d59eb08b7b06315cbc1d235ec13`.
|
||||
It loaded successfully and the complete 311-epoch hardware replay passed every
|
||||
renderer gate; its framebuffer was byte-identical to simulation at SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
|
||||
However, the HDMI line-buffer status was not acceptable. `LPDDR_STATUS` held
|
||||
`0xF1`, with bit 5 set. Disabling LPDDR scanout cleared it to `0xD1`, and
|
||||
re-enabling scanout restored `0xF1`, proving sustained line-buffer underflow
|
||||
rather than a sticky AXI read error or startup-only event.
|
||||
|
||||
Root cause was the first Ch439 `L_R -> L_C -> L_W` write pipeline, which added
|
||||
one EMIF cycle to every 32-byte beat and crossed the real just-in-time refill
|
||||
margin. Ch439b removed `L_W`, but board testing proved that retaining `L_C`
|
||||
after every beat was still too slow. Its clean fit used 39,616 ALMs, 57,109
|
||||
registers, 309/358 M20Ks, and 160 DSPs; EMIF setup was +0.050 ns and every
|
||||
other timing class was also clean. RBF SHA-256 was
|
||||
`56e45346338907eb6c307320757774ac65efa56dabb644906a5600f5ea73a982`.
|
||||
The full 311-epoch board replay again passed every renderer gate and produced
|
||||
the exact expected framebuffer, but four live samples across advancing frames
|
||||
all read `LPDDR_STATUS=0xF1`. Source-off cleared status to `0xD1`; source-on
|
||||
restored `0xF1` immediately. Ch439b is therefore rejected as well.
|
||||
Its board evidence is retained as
|
||||
`sim/data/top_psmct32_raster_demo/sh3_zsrt139f52_ch439b_board_run.log` and
|
||||
`sh3_zsrt139f52_ch439b_board_fb.mem`; the framebuffer is byte-identical to the
|
||||
8K production simulation at SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
|
||||
Ch439c turns the RAM-local write stage into an actual pipeline. A captured
|
||||
beat commits from its local register while the AXI FSM advances to the next
|
||||
read. Only the final beat takes `L_C`, as a one-cycle row-end flush before
|
||||
`next_fetch` is published. This restores the accepted pre-Ch439 per-beat
|
||||
cadence while retaining the physical timing cut. Directed binomial and
|
||||
horizontal-stretch tests are exact at 2,400/2,400 pixels with zero underflow or
|
||||
read errors; the 640x192 and 256x768 PSMCT32 tests are exact at 49,152/49,152
|
||||
and 196,608/196,608 pixels with zero underflow or read errors. A fresh owner
|
||||
GUI compile is required for Ch439c.
|
||||
|
||||
## Ch439c fit feedback and Ch439d address-tree cut
|
||||
|
||||
The owner Ch439c GUI compile completed successfully but was not deployed. It
|
||||
used 39,472 ALMs, 56,640 registers, 309/358 M20Ks, and 160 DSPs. Hold,
|
||||
recovery, removal, and minimum-pulse-width checks were clean, but EMIF setup
|
||||
failed at -1.009 ns / -60.117 ns TNS across 166 endpoints. All ten reported
|
||||
worst paths were the same zero-logic-level route:
|
||||
|
||||
- launch: `u_zc_emit|u_req|raddr_q[7]`;
|
||||
- capture: the monolithic request FIFO's physical `mem_rtl_0` port-B address
|
||||
registers;
|
||||
- data delay: 4.077 ns, of which 3.759 ns was interconnect.
|
||||
|
||||
This is not a scanout-pipeline path. The Ch439c placement exposed the remaining
|
||||
8K request-RAM address tree. Ch439d enables the already-regressed two-way
|
||||
payload bank only on `u_zc_emit.u_req`. At the present 8K depth, each preserved
|
||||
read-address copy drives half the width at half the original Ch438 depth: about
|
||||
one quarter of the physical RAM load that defeated the earlier 16K banked fit.
|
||||
Depth, ordering, registered-read latency, and the measured 2,077-entry capacity
|
||||
margin are unchanged.
|
||||
|
||||
Post-cut verification is complete:
|
||||
|
||||
- banked asynchronous FIFO stress: 3,285 writes and reads, zero errors, PASS;
|
||||
- directed Z/color integration: 1,500 fragments, zero overflow/BRESP errors,
|
||||
PASS;
|
||||
- complete 311-epoch f52 replay at 8K: 2,339,914 fragments fed, 2,286,292
|
||||
passed, zero drops/mismatches/errors, PASS;
|
||||
- framebuffer remains byte-identical at SHA-256
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
|
||||
The Ch439c timing-red RBF SHA-256 is
|
||||
`d006cc1ede2db1eeb5b8ae961eafc047eff3e6ef3ce58a173ae4f8e3bf7c3cac` and
|
||||
was not deployed. A fresh owner GUI compile is required for Ch439d.
|
||||
|
||||
Board evidence is retained as
|
||||
`sim/data/top_psmct32_raster_demo/sh3_zsrt139f52_ch439_board_run.log` and
|
||||
`sh3_zsrt139f52_ch439_board_fb.mem`. The HDMI-equivalent filtered preview is
|
||||
`captures/gs/silenthill3/extracted/recon/sh3_zsrt139f52_ch439_hdmi.png` and
|
||||
remains MAE 13.1111 / RMSE 19.1051 against the PCSX2 reference.
|
||||
|
||||
## Ch439d fit feedback and Ch439e quadrant cut
|
||||
|
||||
The owner Ch439d GUI compile completed successfully and the two width banks
|
||||
were inferred as intended, but the RBF was not deployed because EMIF setup
|
||||
still failed. Its RBF SHA-256 is
|
||||
`fe6eb909b8d875b617587f8afafdc510f77e4b5369c66c225ba9cea404ef6ba9`.
|
||||
The actual post-fit results were:
|
||||
|
||||
- 39,410 required ALMs and 42,843 final-placement ALMs (91 percent);
|
||||
- 56,822 dedicated logic registers, 309/358 M20Ks, and 160 DSPs;
|
||||
- setup WNS -0.515 ns / TNS -36.152 ns, with 120 failing endpoints;
|
||||
- hold, recovery, removal, and minimum-pulse-width checks all clean.
|
||||
|
||||
Every reported worst setup path remained one zero-logic-level physical-route
|
||||
family from `u_req|raddr_{lo,hi}_q[*]` to the corresponding `mem_{lo,hi}` M20K
|
||||
address input register. The worst path was `raddr_lo_q[10]` to a `mem_lo`
|
||||
address register, with 3.615 ns data delay into the 3.225 ns EMIF period.
|
||||
Width banking improved WNS by about 0.5 ns versus Ch439c but left each address
|
||||
copy spanning the full 8K depth, so Ch439d is rejected rather than reseeded.
|
||||
|
||||
Reducing the FIFO below 8K is not valid for the current producer. The existing
|
||||
instrumented complete f52 replay measured a peak request occupancy of 6,115 at
|
||||
epoch 148, and the producer drops fragments when `zc_g_ready` deasserts. The
|
||||
8,192-entry depth and its measured 2,077-entry margin therefore remain fixed.
|
||||
Similarly, directly feeding the next binary pointer into the RAM address port
|
||||
was already exercised before Ch420 and exposed pointer logic plus the same
|
||||
high-fanout physical address family.
|
||||
|
||||
Ch439e instead crosses two depth banks with the existing two payload-width
|
||||
banks. The request FIFO is physically four 4K-deep RAM quadrants:
|
||||
`mem_lo0`, `mem_lo1`, `mem_hi0`, and `mem_hi1`. Each has its own preserved
|
||||
11-bit RAM-facing read-address register, reducing one launch tree to roughly
|
||||
one quarter of the original physical RAM load. A one-bit selector delayed with
|
||||
the synchronous RAM data performs only a 2:1 lower/upper-depth selection at
|
||||
the registered output. Capacity, ordering, CDC publication, accepted-read
|
||||
latency, and atomic tuple writes are unchanged.
|
||||
|
||||
Ch439e prefit verification is complete:
|
||||
|
||||
- quadrant asynchronous FIFO stress: 3,285 writes and reads, zero errors,
|
||||
PASS;
|
||||
- directed Z/color integration: 1,500 fragments, zero overflow/BRESP errors,
|
||||
PASS;
|
||||
- complete 311-epoch f52 production replay at 8K: 2,339,914 fragments fed,
|
||||
2,286,292 passed, zero drops/mismatches/errors, PASS;
|
||||
- binomial and horizontal-stretch scanout: 2,400/2,400 exact pixels apiece,
|
||||
zero underflow/read errors, PASS;
|
||||
- framebuffer SHA-256 remains byte-identical at
|
||||
`d0047677371a0f6e4e319458926f604a8599c92baaf34d09b8e1fd452e31662b`.
|
||||
|
||||
The next owner GUI compile must confirm that all four quadrant memories and
|
||||
four independent read-address trees survive synthesis, that setup closes, and
|
||||
that the new RAM-output depth selector does not become a replacement setup
|
||||
family. Only a fully signoff-clean Ch439e artifact is eligible for deployment.
|
||||
|
||||
## Ch439e fit feedback and Ch439f arithmetic-boundary correction
|
||||
|
||||
The owner Ch439e GUI compile completed successfully and confirmed the intended
|
||||
request-FIFO result. All four quadrant memories were inferred, request-memory
|
||||
usage stayed at 309/358 M20Ks, and the 310 MHz EMIF setup domain closed at
|
||||
+0.019 ns. Hold, recovery, removal, and minimum-pulse-width checks were also
|
||||
clean. The design used 38,849 required ALMs, 42,880 final-placement ALMs
|
||||
(92 percent), 57,233 dedicated registers, and 160/376 DSP blocks.
|
||||
|
||||
The artifact is nevertheless rejected because the 25 MHz design clock failed
|
||||
at WNS -1.294 ns / TNS -89.732 ns across 208 endpoints. Its rejected RBF
|
||||
SHA-256 is
|
||||
`4deb590b83036e250e042158896a3a69c731bbccc09eef04c06f523cc382c6e5`.
|
||||
Every reported worst path was the same 27-logic-level, 41.141 ns arithmetic
|
||||
family:
|
||||
|
||||
- launch: `u_demo|u_gs|u_tex|g_bilinear.tap[0][11]`;
|
||||
- capture: `u_texcache|tex_mem...portbaddr[10]`;
|
||||
- middle: both bilinear lerps, GS modulation/blend arithmetic, and the next
|
||||
texture-coordinate/address arithmetic.
|
||||
|
||||
The initial hypothesis was that the project-wide `AUTO_RESOURCE_SHARING ON`
|
||||
setting caused this apparently cross-transaction path. The fit report records
|
||||
GS arithmetic operators packed with `u_tex` bilinear operators, including
|
||||
`u_demo|u_gs|mult_66` merged into `u_demo|u_gs|u_tex|mult_9`; Intel's Quartus
|
||||
26.1 setting reference also warns that sharing mux/control logic can reduce
|
||||
Fmax. Ch439f tests that hypothesis directly below rather than assuming it.
|
||||
|
||||
Ch439f disabled automatic resource sharing globally while retaining
|
||||
`AGGRESSIVE AREA`. This was a controlled synthesis experiment, not a seed or
|
||||
RTL-latency change.
|
||||
|
||||
The fresh owner Ch439f compile conclusively rejected that hypothesis.
|
||||
Synthesis reported `Auto Resource Sharing: Off`, but the complete result was
|
||||
bit-for-bit structurally unchanged at report precision: 38,849 required ALMs,
|
||||
42,880 final-placement ALMs, 57,233 registers, 309 M20Ks, 160 DSPs, EMIF setup
|
||||
+0.019 ns, and the identical design-clock -1.294 ns / -89.732 ns / 208-endpoint
|
||||
tap-to-texture-cache family with the same 41.141 ns path. The project setting
|
||||
is therefore restored to its area-oriented value.
|
||||
|
||||
## Ch439g functional exception for the impossible packed-DSP arc
|
||||
|
||||
The RTL cone proves that a captured bilinear tap cannot reach the texture read
|
||||
address combinationally. `tap[*]` feeds the two lerp levels only in `BS_DONE`,
|
||||
where the result is captured into `tex_color_hold`; the external filtered
|
||||
result is exposed from that register only in the distinct `BS_OUT` cycle.
|
||||
Texture-memory address capture occurs under `tex_rd_en` in `BS_ISSUE` or a
|
||||
nearest-read issue cycle. Those state conditions are mutually exclusive.
|
||||
|
||||
The remaining path is therefore a conservative physical arc introduced by
|
||||
packing mutually exclusive arithmetic into Agilex DSP structures, not a
|
||||
single-cycle functional requirement. Ch439g adds a fail-closed SDC exception
|
||||
from exactly the architectural 128 `g_bilinear.tap[0:3][31:0]` registers to
|
||||
the existing `u_texcache.tex_mem` endpoint collection. The exception does not
|
||||
cut any walker, affine-UV, perspective-UV, descriptor, or address register;
|
||||
all real texture-address launches remain timed normally. The SDC halts the
|
||||
compile if the tap population is not exactly 128 or the cache collection is
|
||||
empty.
|
||||
|
||||
No functional RTL changed after the already-exact Ch439e simulations. The next
|
||||
owner GUI compile must show the Ch439g collection-count message, retain the
|
||||
four request quadrants and EMIF closure, and expose the true next design-clock
|
||||
family. Deployment remains forbidden unless every timing class is clean.
|
||||
Reference in New Issue
Block a user