Fixed-Point: FixedField

FixedField is a Vitis-bit-exact fixed-point scalar type. It maps to Vitis HLS ap_fixed<W, I, Q, O> (or ap_ufixed<...>) and its Python value model reproduces the hardware bit-for-bit — for quantization and arithmetic. It is defined in waveflow/hw/fixpoint.py; vector operations (the compute) are covered on the Fixed-point vectorization page in the Vectorization section.

The ap_fixed model

An ap_fixed<W, I> value is a W-bit integer with an implied binary point I bits from the MSB. With F = W − I fractional bits, the real value is

value = stored · 2^(−F)

where stored is the W-bit two’s-complement integer (ap_fixed, signed) or unsigned integer (ap_ufixed). I counts the integer bits (sign-inclusive when signed); F the fractional bits. For example ap_fixed<8, 4> has F = 4, so its LSB is 2^−4 = 0.0625 and its range is [−8, 7.9375].

Declaring a format

FixedField.specialize returns a cached element class — one class per distinct format:

from waveflow.hw.fixpoint import FixedField
from waveflow.utils.fixputils import QMode, OMode

Q8_4 = FixedField.specialize(8, 4)                       # ap_fixed<8, 4, AP_TRN, AP_WRAP>
U8_4 = FixedField.specialize(8, 4, signed=False)         # ap_ufixed<8, 4, AP_TRN, AP_WRAP>
Q16_8 = FixedField.specialize(16, 8,
                              q_mode=QMode.AP_RND,
                              o_mode=OMode.AP_SAT)        # ap_fixed<16, 8, AP_RND, AP_SAT>

The parameters are W (total bits), I (integer bits), signed (ap_fixed vs ap_ufixed), and the quantization / overflow modes. The emitted C++ type is on the class:

>>> Q16_8.cpp_type
'ap_fixed<16, 8, AP_RND, AP_SAT>'

Defaults match Vitis. A default-constructed format uses signed = True, AP_TRN, and AP_WRAP — exactly Vitis’s ap_fixed defaults — so FixedField.specialize(W, I) already matches the default hardware type.

A single FixedField is a scalar; arrays use DataArray[FixedField] (see Fixed-point vectorization).

Quantization (QMode) and overflow (OMode) modes

The modes are enum.Enums whose value is the Vitis template token (so codegen emits q.value / o.value directly). The v1 subset:

QMode meaning
AP_TRN (default) truncate — round toward −∞ (floor), for positives and negatives
AP_RND round half up — round to nearest, ties toward +∞
OMode meaning
AP_WRAP (default) two’s-complement wrap-around (mask)
AP_SAT saturate — clip to the format’s [min, max] (asymmetric for signed)

Round-half-up vs round-half-even

AP_RND is round-half-up (ties go toward +∞), matching Vitis AP_RND. It is not the unbiased banker’s rounding (round-half-to-even) — that is Vitis AP_RND_CONV, which is not in v1 (planned, see Phase 6). If your model needs unbiased rounding, do not assume AP_RND provides it.

Integer-backed storage and the real view

Storage is the stored integer (decision: integer-backed). A scalar FixedField’s .val is the stored W-bit integer; .real derives the real value:

f = Q8_4(24)        # assign the *stored* integer
f.val               # 24  (np.int64)
f.real              # 1.5  (= 24 · 2^-4)

To quantize a real value into a format, use from_real (which returns a DataArray[FixedField] — see the vector page); assigning a non-integer real directly to a scalar FixedField raises, to keep “stored integer” and “real value” unambiguous.

FixedField subclasses IntField and reuses its W-bit word serialization unchanged — the stored integer is the payload; only the C++ typed view (ap_fixed instead of ap_int, via a .range() bit-reinterpret) differs.

Bit-exactness — the conformance harness

The contract is proven empirically. The harness under examples/schemas/fixedpoint/ quantizes a sweep of edge values (exact-representable, rounding midpoints, min/max overflow, negatives, unsigned-negative inputs) in Vitis C-sim and asserts the emitted bits equal the Python fixputils bits exactly, across the curated configs × every mode. If Python and Vitis ever disagree, the Python model is wrong — it is fixed, the comparison is never loosened. Run it with pytest -m vitis -k fixedpoint.

See also


This site uses Just the Docs, a documentation theme for Jekyll.