ZLANG HDL / GUIDES/FIXED-POINT-ARITHMETIC

Fixed-point arithmetic, explicitly

Choose a representation, keep intermediate precision, then specify rounding and overflow at the conversion boundary.

ZLang HDL documentationPublished Source c768da0bce8b ↗

Choose the stored representation

fixed<16,8> is a signed fixed-point value with 16 total bits and eight fractional bits. A stored integer represents that integer multiplied by 2-8. Its range is -128 through 127.99609375, in increments of 1/256.

fixed_sat<16,8> has the same representation with a saturating target-narrowing policy. Integer, raw-bit and fixed-point families are distinct; ZLang does not silently convert between them.

Keep the intermediate product

Multiplying two fixed<16,8> inputs produces a widened result with 32 total bits and 16 fractional bits. Converting it to the 16-bit output loses fractional precision and may exceed the target range. The conversion therefore states how to round and how to handle overflow.

FixedGain.zhl
module FixedGain {
    in sample : fixed<16,8>
    in gain   : fixed<16,8>
    out y     : fixed_sat<16,8>

    product = sample * gain
    y = quantize<fixed_sat<16,8>>(product) {
        round nearest_even
        overflow saturate
    }
}

Round, then handle overflow

nearest_even chooses the nearest representable result; an exact tie chooses the even stored integer. saturate clamps an out-of-range result to the target minimum or maximum. The conversion order is rescale, round, then apply the overflow policy.

The explicit block above supplies both policies. The language also supports other documented quantization forms. Consult the pinned numerical reference before choosing a different conversion or rounding mode.

Check the module

Save the complete module as FixedGain.zhl in your pinned compiler checkout, then run:

Semantic check
zlang FixedGain.zhl --top FixedGain --check

This example was checked against the website's compiler revision. It demonstrates typing and conversion policy, not a measured DSP count, target frequency or error bound for a larger algorithm.

Choose policies for the algorithm

Wrapping arithmetic and saturation produce different boundary behavior. Check values near half-step rounding ties and the representable limits. For an accumulating design, inspect intermediate widths and choose where to quantize rather than assuming every operation narrows automatically.

Read the complex multiplication and FFT examples for larger arithmetic designs and their documented configurations.

Keep exploring

Canonical manuals and PDFs →