Xilinx
HLS
Block Preview

Introduction

The Goertzel Sliding (per-sample) block tracks a single DFT bin X(k) continuously: it emits an updated power |X(k)|^2 on every input sample over a sliding window of the last N samples, rather than one value per non-overlapping block. It is the sliding-DFT (SDFT) counterpart of Component_Goertzel.

Instead of the block Goertzel recurrence, it uses the sliding-DFT update (W = e^{j*2*pi*k/N} = cos(w) + j*sin(w)):

      X[n] = r * W * ( X[n-1] + x[n] - x[n-N] )
  

A length-N delay line holds the sample x[n-N] leaving the window, so each new sample slides the window forward by one and updates the bin with a single complex twiddle multiply. The power is |X[n]|^2 = Xr^2 + Xi^2.

Goertzel Designer

The optional damping factor r = 1 - 2^-DampShift bleeds off the marginal-stability error that a pure SDFT (r = 1) accumulates over long runs; DampShift = 0 is exact but can drift, 12..16 is a safe default.

Selectivity and resolution are identical to the block Goertzel: the bin is snapped to k = round(N*f/Fs), giving a ~Fs/N-wide main lobe and a resolution of Fs/N. The difference is purely the per-sample output and the N-deep delay line it costs.

For a once-per-block output use Component_Goertzel; to monitor several tones with one shared multiplier use Component_GoertzelMulti.

Pin Description

IN Input InputSize bit BIT VECTOR
Real input sample. Present only when SignalType = Real. Signed, InputSize bits.
SAMPLE_IN Input 1 bit BIT
New-sample strobe. Pulse high for one clock per input sample; the sliding DFT slides the window and updates the bin only on these pulses.
CLK Input 1 bit BIT
System clock input. Default: Acquisition clock.
Default: Default Board Clock
RESET Input 1 bit BIT
HLS synchronous reset (ap_rst). Clears the N-deep history line(s), the running bin state and the write index. Default: Global reset.
Default: Default Board Reset
POWER Output 2*(InputSize + ceil(log2 N) + 2) + 4 bit BIT VECTOR
Sliding-window bin power |X(k)|^2, updated on every SAMPLE_IN. The first N-1 values after reset are the fill-up transient. Signed bus, 2(InputSize + ceil(log2 N) + 2) + 4* bits; the value is non-negative.
VALID_OUT Output 1 bit BIT
Mirrors SAMPLE_IN: high for every processed sample, since a fresh POWER is produced per sample.
IN_I InputSize bit
In-phase (I) input sample. Present only when SignalType = Complex. Signed, InputSize bits.
IN_Q InputSize bit
Quadrature (Q) input sample. Present only when SignalType = Complex. Signed, InputSize bits.

Properties

Property window

Signal Type SignalType

Real: one input channel. Complex: I/Q input.

Real: single input channel IN (one history line). Complex: I/Q input IN_I / IN_Q (two history lines, true one-sided bin). Default Real.

Default: Real

Options: Real Complex

Input Bit Width InputSize

Bit width of the input sample(s).

Bit width of each signed input sample. Range 4..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

Coefficient Bit Width CoefSize

Bit width of the cos/sin coefficients.

Bit width of the signed cos/sin twiddle coefficients (scale 2^(CoefSize-2)). One of 12, 14, 16, 18, 20, 24. Default 18.

Default: 18

Options: 12 14 16 18 20 24

Window Length N BlockN

Sliding window / DFT size: resolution Fs/N.

Sliding window / DFT size N. Resolution Fs/N; also the depth of the history delay line (BRAM cost scales with N). One of 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192. Default 256.

Default: 256

Options: 16 32 64 128 256 512 1024 2048 4096 8192

Data Rate Fs (Hz) Fs

Sample rate of the data feeding this block.

Sample rate (Hz) of the data feeding this block. Used to map the target frequency to a DFT bin k = round(N*f/Fs). Default 1000000.

Default: 1000000

Target Frequency (Hz) Freq

Tone to monitor (nearest DFT bin).

Target tone to monitor (Hz). Snapped to the nearest DFT bin k = round(N*f/Fs); the actual monitored frequency is k*Fs/N. Default 50000. Normally set from the Goertzel Designer.

Default: 50000

Damping shift (0=off) Damping

SDFT stability: r = 1 - 2^-shift. 0 = exact but drifts over long runs; 12-16 = safe.

SDFT stability control: r = 1 - 2^-shift. 0 = exact SDFT but the marginally-stable resonator can drift over long runs; 10..18 pull the pole slightly inside the unit circle so rounding error decays. One of 0, 10, 12, 14, 16, 18. Default 14.

Default: 14

Options: 0 10 12 14 16 18

Config (JSON, use editor) GoertzelProject

Config produced by the Goertzel Designer.

Hidden JSON blob produced by the Goertzel Designer (tone + hardware config). Managed by the visual designer, not edited by hand.

Usage

Sliding DFT (SDFT)

A block Goertzel gives one bin value per N samples. The sliding DFT keeps the same bin X(k) up to date on every sample by recognising that sliding the length-N window forward by one sample changes the bin by removing the oldest sample and adding the newest, then rotating by the bin twiddle:

      X[n] = r * W * ( X[n-1] + x[n] - x[n-N] )
    W    = cos(w) + j*sin(w),   w = 2*pi*k/N
    power = Xr^2 + Xi^2
  

Implementation per sample:

  • push x[n] into an N-deep history and read out x[n-N];
  • form s = damp(X[n-1]) + (x[n] - x[n-N]);
  • rotate: Xr = cos(w)*sr - sin(w)*si, Xi = sin(w)*sr + cos(w)*si (one complex twiddle multiply);
  • output Xr^2 + Xi^2.

The first N-1 outputs after reset are the window filling up (a transient); the bin is only fully valid once the delay line holds a full window.

Damping and SDFT stability

A pure SDFT resonator sits exactly on the unit circle (marginally stable), so fixed-point rounding error can accumulate without bound over long runs. Multiplying the recursion by r = 1 - 2^-DampShift pulls the pole slightly inside the unit circle so old error decays:

      DampShift = 0        -> r = 1        exact, but drifts over long runs
    DampShift = 12..16   -> r ~ 1        tiny bias, bounded error (safe)
  

Larger DampShift means r closer to 1 (less bias, weaker leakage control); smaller means stronger damping. Default 14.

Real vs complex input

  • Real (SignalType = Real): one input IN, one real history line; si is driven only by the fed-back imaginary state.
  • Complex (SignalType = Complex): IN_I / IN_Q with two history lines (hist_i, hist_q); both sr and si take an input difference, giving a true one-sided complex bin.

In both cases the twiddle multiply and |X|^2 are the same.

DFT-bin snapping and resolution

      k   = round(N * f / Fs)          (0 <= k < N)
    f_k = k * Fs / N                 (actual monitored frequency)
    df  = Fs / N                     (resolution / bin spacing, ~main-lobe width)
  

Identical selectivity to the block Goertzel; only the update cadence differs.

Coefficients

COS0 = cos(w), SIN0 = sin(w) are quantised by the plugin to signed CoefSize bits (scale 2^(CoefSize-2)) and applied in the twiddle multiply (result shifted right by COEF_SHIFT = CoefSize-2).

Bit widths

Data is signed two’s complement.

  • IN / IN_I / IN_Q : signed InputSize bits.
  • STATE_SIZE = InputSize + ceil(log2 N) + 2.
  • POWER : POW_SIZE = 2*STATE_SIZE + 4 bits (non-negative value).

Timing and handshake

  • #pragma HLS PIPELINE II=1, ap_ctrl_none : free-running, one call per system clock.
  • SAMPLE_IN pulses once per new input sample; the SDFT updates only on those pulses.
  • VALID_OUT mirrors SAMPLE_IN (high whenever a sample is processed): a fresh POWER is produced every sample. Note the first N-1 results after reset are the fill-up transient.
  • Latency reported to the diagram is 1 clock.

Reset

RESET (ap_rst) clears the delay line(s), the running bin state Xr/Xi, the write index and the last power. After reset the window must refill (N-1 samples) before the output is fully meaningful.

Visual designer

This block is configured through the Goertzel Designer (a WebView2 graphical tool), not the property grid. Double-click the block to open it. In sliding mode you set the hardware target (signal type, input/ coefficient bits, window length N, Fs and the Damping shift) and enter the target frequency to monitor; the tool snaps it to the nearest DFT bin k = round(N*f/Fs), draws the frequency-selectivity plot (the Goertzel/SDFT main lobe, ~Fs/N wide, showing what the bin integrates) and shows a live resource / result estimate: resolution Fs/N, -3 dB width, integration time, output bits and multiplier count. Save & Close writes the configuration and quantised coefficients back into the block.

Typical applications

  • Continuous narrowband power / envelope tracking of one tone with no block latency (a new reading every sample).
  • Fast tone presence / onset detection where waiting N samples for a block result is too slow.
  • Low-latency line tracking feeding a threshold or AGC.

Resources & Timing

  • Latency: 1 clock per sample; a fresh POWER every sample (window fill-up transient = N-1 samples)

  • Throughput: 1 input sample per SAMPLE_IN pulse (II=1, free-running ap_ctrl_none)

Implemented with Vitis HLS. Per sample: one N-deep history line (two in complex mode) plus one complex twiddle multiply (~4 real multiplies) and the |X|^2 squaring. The N-deep history is the main extra cost over the block Goertzel and is typically mapped to BRAM, growing with N. Optional damping (r = 1 - 2^-DampShift) is a cheap subtract-shift that keeps the fixed-point SDFT bounded. Choose this variant when you need a power reading on every sample (low latency); use the block Goertzel when a once-per-N result is enough and you want to save the delay-line BRAM.