# 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.
