Xilinx
HLS
Block Preview

Introduction

The Multi-stage FIR Decimator turns a high-rate baseband stream into a low-rate one while rejecting everything that would alias into the new band. Doing a large decimation in one FIR is prohibitively expensive; the efficient answer is a cascade of small decimators, each dropping the rate by a modest factor with a relaxed anti-alias filter, so the total tap count (and DSP count) is a fraction of the single-stage design.

You do not enter taps or ratios directly. Instead you give the design intent in physical units:

      Input Sample Rate  (Hz)      e.g. 1 000 000
    Output Sample Rate (Hz)      e.g.    20 000     ->  R = 50
    Passband Edge      (Hz)      e.g.     8 000
    Stopband Atten.    (dB)      e.g.        80
  

and the plugin does the rest: it factorises R = Fin / Fout into up to four factors (preferring 5, 3, 2, largest first), designs a Kaiser-window low-pass FIR per stage (passband = your passband edge, stopband edge = the new Nyquist after that stage), quantises each to signed CoefSize integers with unity DC gain, and generates the cascade.

Multi-FIR Decimator Designer

The block uses a custom WebView2 graphical designer instead of the standard property grid. Double-clicking the block opens the designer (shown above), where you set the rates, passband, attenuation and bit widths, pick the input/output format, and read a live resource estimate — the per-stage factorisation, tap counts and multiplier usage — before committing. Properties are set there, not in a plain grid.

      IN_I / IN ─┐  [ stage0: /r0 ]→[ stage1: /r1 ]→ ... → OUT_I / OUT
    IN_Q      ─┘   (Kaiser LP)     (Kaiser LP)         └─ OUT_Q
                                                VALID_OUT ── (decimated tick)
  

Pin Description

IN_I Input InputSize bit BIT VECTOR
In-phase (I) input sample (present only when Input Type = I/Q). Signed, Input Bit Width bits. One sample per system clock.
Default: Must be connected
IN_Q Input InputSize bit BIT VECTOR
Quadrature (Q) input sample (present only when Input Type = I/Q). Signed, Input Bit Width bits.
Default: Must be connected
CLK Input 1 bit BIT
System clock input. Default: Acquisition clock. The block consumes one input sample per rising edge.
Default: Default Board Clock
RESET Input 1 bit BIT
HLS synchronous reset (ap_rst). Default: Global reset. Clears all stage delay lines, counters and registers.
Default: Default Board Reset
OUT_I Output OutputSize bit BIT VECTOR
In-phase (I) decimated output (present only when Output Type = I/Q). Signed, Output Bit Width bits.
OUT_Q Output OutputSize bit BIT VECTOR
Quadrature (Q) decimated output (present only when Output Type = I/Q). Signed, Output Bit Width bits. Reads ~0 if the input is Real.
VALID_OUT Output 1 bit BIT
Output-valid strobe. Pulses high for one system-clock cycle on each decimated output sample (rate OutputFreqHz). Latch the output pins only when it is high.
IN InputSize bit
Real-mode input sample (present only when Input Type = Real). Signed, Input Bit Width bits. One sample per system clock.
Default: Must be connected
OUT OutputSize bit
Real-mode decimated output (present only when Output Type = Real). Signed, Output Bit Width bits. Valid when VALID_OUT is high.

Properties

Property window

Input Bit Width InputSize

Bit width of each I/Q input sample (signed).

Bit width of each signed I/Q input sample. Range 4 to 32, default 16.

Default: 16

Options: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

Output Bit Width OutputSize

Bit width of each I/Q output sample (signed).

Bit width of each signed I/Q output sample. Range 8 to 40, default 24.

Default: 24

Options: 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

Intermediate Bit Width IntermSize

Bit width of the signal between stages (signed).

Bit width of the signal carried between stages (signed). One of 20, 24, 28, 32, 36, 40, 48. Wider preserves more dynamic range through the cascade. Default 32.

Default: 32

Options: 20 24 28 32 36 40 48

Coefficient Bit Width CoefSize

Bit width of each coefficient (signed). 24 gives ~140 dB dynamic range.

Bit width of each signed coefficient. One of 12, 14, 16, 18, 20, 24. 24 gives ~140 dB coefficient dynamic range. Default 24.

Default: 24

Options: 12 14 16 18 20 24

Input Sample Rate (Hz) InputFreqHz

Input sample rate in Hz.

Input sample rate in Hz (text). Default 1000000.

Default: 1000000

Output Sample Rate (Hz) OutputFreqHz

Output sample rate in Hz. Must divide the input rate.

Output sample rate in Hz (text). Should divide the input rate; a non-integer ratio is rounded (with a warning). Default 20000 (giving R = 50 = 552 for the defaults).

Default: 20000

Passband Edge (Hz) PassbandHz

Upper edge of the passband in Hz. Signals within [0, PassbandHz] must be preserved with < 0.5 dB ripple.

Upper edge of the passband in Hz. Signals in [0, PassbandHz] are preserved with low ripple; the same passband is used for every stage. Must stay below the final Nyquist OutputFreqHz / 2. Default 8000.

Default: 8000

Stopband Attenuation (dB) StopbandAttenDB

Minimum stopband attenuation of each stage. Higher = more taps.

Minimum stopband attenuation of each stage (dB). One of 40, 60, 80, 90, 100, 120. Higher = more taps per stage. Default 80.

Default: 80

Options: 40 60 80 90 100 120

Input Type InputType

Real: single input channel (IN). I/Q: two input channels (IN_I/IN_Q).

Real (single input channel IN) or I/Q (two input channels IN_I/IN_Q). Default I/Q.

Default: I/Q

Options: Real I/Q

Output Type OutputType

Real: one output channel (OUT), half the multipliers. I/Q: two channels (OUT_I/OUT_Q).

Real (single output channel OUT, Q pipeline removed -> half the multipliers) or I/Q (two output channels OUT_I/OUT_Q). Chosen independently of InputType. Default I/Q.

Default: I/Q

Options: Real I/Q

Config (JSON, use editor) DecimProject

Config produced by the Multi-FIR Decimator Designer.

Hidden text property holding the Multi-FIR Decimator Designer output as JSON (the hw block: rates, passband, attenuation, widths and formats). Never shown in a grid — the block is edited through the designer. The per-stage Kaiser filters are regenerated from these values at HDL-generation time.

Usage

Multistage factorisation

Let R = round(Fin / Fout) be the total decimation ratio. Splitting it into a cascade

      R = r0 * r1 * ... * r_{M-1}          (M <= 4 stages)
  

is much cheaper than one big filter, because only the last stage has to build the final sharp transition; the earlier stages run at higher rates but only need to reject the (wide) band that will fold into the next stage’s Nyquist. The plugin factorises R greedily into primes 5, 3, 2 (falling back to any remaining factor), then orders the factors largest first so the biggest rate drop — with the most relaxed filter — happens first and the tightest filters run last at the lowest rate where they cost the fewest multiplies. Up to 4 stages are supported; the unused stages compile away.

For each stage k the sample rate steps Fk -> Fk / r_k and the plugin designs a low-pass with:

      f_pass = PassbandHz                    (same for every stage)
    f_stop = (Fk / r_k) / 2                (the new Nyquist)
  

If any stage’s new Nyquist would fall at or below the passband edge the compile fails, asking you to lower PassbandHz or raise OutputFreqHz.

Per-stage FIR design (Kaiser window)

Each stage is a windowed-sinc low-pass with a Kaiser window whose beta and tap count follow the standard Kaiser formulas from the requested stopband attenuation A (dB) and the transition width Δω (rad):

      beta  = 0.1102*(A - 8.7)                         for A > 50
          = 0.5842*(A-21)^0.4 + 0.07886*(A-21)       for 21 <= A <= 50
          = 0                                          for A < 21

    N     = ceil( (A - 7.95) / (2.285 * Δω) )        (forced odd, linear phase)

    fc    = 0.5 * (f_pass + f_stop) / Fk             (normalised cutoff)
    h[n]  = sinc(2*fc*(n - (N-1)/2)) * kaiser(n, beta)
  

The taps are DC-normalised (sum h = 1), symmetrised to clean up FP rounding, then quantised to signed CoefSize bits with a scale of 2^(CoefSize-1) - 1. Higher StopbandAttenDB and narrower transitions produce more taps, so the resource estimate in the designer scales with both.

Independent input / output type selection

The input and output formats are chosen independently (a “disjoint” choice), which directly trades multipliers:

  • InputType — Real (single pin IN) or I/Q (two pins IN_I/IN_Q).
  • OutputType — Real (single pin OUT) or I/Q (two pins OUT_I/OUT_Q).

OutputType drives how many channels are actually filtered: with OutputType = Real the entire Q pipeline is compiled away, so a Real -> Real cascade uses half the multipliers of I/Q -> I/Q. The meaningful combinations:

      InputType   OutputType   behaviour
    ---------   ----------   ---------------------------------------------
    I/Q         I/Q          full complex decimation (2x multipliers)
    Real        Real         real-only decimation   (1x multipliers)
    I/Q         Real         filter I only; Q is dropped
    Real        I/Q          Q input tied to 0 -> OUT_Q ~ 0 (warns)
  

The last row emits a compile warning because the Q output is meaningless (there is no Q input to process).

Bit widths

Data is signed two’s complement.

  • IN / IN_I / IN_Q: signed InputSize bits.
  • Between stages the signal is carried at IntermSize bits (each stage right-shifts its accumulator by CoefSize - 1 to hold unity DC gain).
  • OUT / OUT_I / OUT_Q: signed OutputSize bits.

Internal accumulators grow to InputSize + CoefSize + 8 (first stage) and IntermSize + CoefSize + 8 (later stages) to avoid overflow before the shift.

Visual designer

This block has no plain property grid. Double-clicking it opens the Multi-FIR Decimator Designer (see the screenshot in the introduction), where you enter the input/output rates, passband edge, stopband attenuation and the input/intermediate/output/coefficient bit widths, and select the input and output formats. The designer shows a live resource estimate: how R factorises into stages, the tap count per stage, the total taps and the resulting multiplier count — so you can trade attenuation, passband and widths against DSP usage before pressing Save & Close. The chosen values are mirrored back into the hidden DecimProject property plus the visible hardware properties documented below, and the actual Kaiser filters are (re)designed at HDL-generation time from those values.

Streaming model, latency and throughput

  • #pragma HLS PIPELINE II=1: the cascade accepts one input sample per system clock (ap_none, no input strobe needed — feed it a continuous stream at the input rate).
  • Each stage keeps a modulo-r_k counter and only pushes a new sample into the next stage on its tick, so the effective rate divides down the chain.
  • VALID_OUT pulses for one clock on each valid decimated output sample (rate Fout); read the output pins only when it is high.

Reset

RESET (ap_rst) clears every stage’s delay line, counter and output register.

Typical applications

  • Digital down-conversion back-end: decimate a mixed-down baseband from ADC rate to a manageable processing rate.
  • Narrowband channelisation with a steep, high-attenuation final filter.
  • Real-only rate reduction (Real -> Real) at half the DSP cost.

Resources & Timing

  • Latency: One cascade fill (sum of the stage delay lines); VALID_OUT marks each valid output

  • Throughput: One input sample per system clock in; one output sample per R clocks out (rate OutputFreqHz)

Implemented with Vitis HLS as up to 4 cascaded parallel FIR decimators (each fully unrolled, II=1). Total taps and multiplier count depend on the factorisation of R, the stopband attenuation and the passband — the designer’s live estimate reflects this. Coefficients are compile-time constants (Vivado can prune trivial taps). Choosing Output Type = Real removes the Q pipeline entirely, halving the multipliers versus I/Q -> I/Q. Modelled on the PolarFire 1 MSps -> 20 kSps decimator (R = 50 = 552, ~73 / 105 / 131 taps per stage) but fully generic.