Fixed point

The engine is integer hardware. Every value has a fixed format, and the formats were chosen by a numerics study before any RTL was written. The golden model in sim/golden/fixed.py uses the same integers, so the RTL can be checked bit for bit.

Formats

ValueFormatNotes
Q, K, Vint8Symmetric per-tensor scale, set on the host (see below)
S = Q·Kᵀint17Signed dot product of int8 values
cfg_scaleUQ4.20, 24 bitsFolds s_Q · s_K · log₂e / √d into one multiplier
Z, mQ8.8, signedScaled scores in log₂ units, and their running maximum
Z − mQ9.8, signedAlways ≤ 0; the input of exp2
2^(Z − m), αUQ1.15exp2 output and the rescale factor
PUQ1.8, 9 bitsProbabilities, 0 to 256
P·V (one tile)int18, signedMatrix product in the second array
l (running sum)18 bits, unsignedReal value × 2¹²
O (accumulator)26 bits, signedReal value × 2⁴, in V units
ReciprocalUQ1.16 mantissa, 5-bit exponentUsed once per row, at the end
OutputQ8.8, signedDequantize with s_V: value = out / 256 · s_V

Quantization

The host picks one scale per tensor: s = max|x| / 127, then int8 = round(x / s) with ties to even, clipped to ±127. The scales of Q and K go into cfg_scale, so the datapath never multiplies by a scale. Try it:

The exp2 unit

2^(x/256) for x ≤ 0 is split into an integer shift and a fraction. The fraction indexes a 256-entry table of 16-bit values. The integer part is a right shift. Results that shift past 16 bits are exactly zero, and the output is truncated, not rounded. The table is generated by sim/golden/gen_luts.py, and CI checks that the committed table is up to date.

The unit is tested exhaustively over its input range, so there is no sampling gap.

Measured error

Errors are against float attention on the same inputs, in float units. The first table is for each preset, with the engine's output after dequantization. The second is from the recorded 1000-seed study at N = 32, in V units (one int8 step of V). The study separates the datapath error (dp, on the INT8 inputs) from the total error (tot, which includes input quantization).

PresetNCausalMax |engine − float|
toy_sentence12yes0.0049
previous_token16yes0.0105
attention_sink16yes0.0254
uniform16no0.0028
self16no0.0260
random16no0.0163
Study, N = 32, peaky inputsdp maxdp meantot maxtot mean
FLASH1.2600.069111.9040.4722
NAIVE1.7440.098911.8060.4798

For the default format at N = 32 (peaky inputs), the datapath error averages 0.07 of a V step for FLASH and 0.10 for NAIVE. The largest errors are 1.26 steps for FLASH and 1.74 for NAIVE. The total error is larger because it also includes the rounding of the inputs to INT8. The full study output is recorded in sim/golden/study_results_1000seeds.txt.