Moving Average (TM)
Time-multiplexed moving average filter with programmable window size. Computes sliding-window average of TM data streams using circular buffer stored in BRAM. Supports signed/unsigned arithmetic up to 32 bits per sample, configurable buffer depth (32-8192 samples per TM lane). Pipeline latency: 2 cycles.
Introduction
This block computes the moving average of a time-multiplexed (TM) input stream over a programmable window of past samples. Each TM lane maintains its own independent circular buffer.
On every rising edge of CLK, the component updates:
$$ \mathrm{OUT}(n) = \frac{1}{W} \sum_{k=0}^{W-1} \mathrm{IN}(n-k), $$
where $W = 2^{\text{WINDOW_EXP}}$ is the window size determined by the exponent
input WINDOW_EXP, and the division is implemented as a right-shift operation.
Pin Description
Input bits × TM Factor
Each TM lane has an independent circular buffer.
Input bits × TM Factor (same as input)
Valid data appear after 2 clock cycles + W/2 sample group delay.
Properties
Set the number of bits of the input per sample
Number of bits per input sample ($N_\text{in}$). Range: 4 – 32. Output bit width matches input bit width.Default: 16
Range: 4 – 32
Select the sign/unsign of the input
Arithmetic type of input and output:
UNSIGNED→ Non-negative integersSIGNED→ Two’s complement
Averaging preserves sign (signed average of signed inputs).
Default: UNSIGNED
Options: UNSIGNED SIGNED
Select the Time Multiplexing factor (samples per word)
Number of time-multiplexed phases (samples per clock). Allowed values: 2, 4, 8, 16, 32. Each TM lane has an independent circular buffer of depth = Max Memory Length.Default: 4
Options: 2 4 8 16 32
Maximum buffer size (samples per TM lane). Stored in BRAM. Window input is 16 bits but limited to this value.
Maximum window size (buffer depth per TM lane), stored in BRAM. Allowed values: 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192.
Larger buffers consume more BRAM:
- BRAM usage ≈ (Input bits) × (Max Memory Length) × (TM Factor) / 18k bits
The WINDOW_EXP input can dynamically select any exponent from 5 to 13
(window sizes 32 to 8192) at runtime without reconfiguration, provided
the resulting window size ≤ Max Memory Length.
Default: 1024
Options: 32 64 128 256 512 1024 2048 4096 8192
Functional description
The component is implemented using Xilinx HLS (High-Level Synthesis) and uses BRAM-based circular buffers for sample storage, replicated N times (where N = TM Factor) to support independent averaging per TM lane.
Window configuration
- WINDOW_EXP: 16-bit input specifying the exponent of the window size
- Window size is computed as $W = 2^{\text{WINDOW_EXP}}$
- Max Memory Length: BRAM buffer size per TM lane (design-time parameter)
- Valid exponent range: 5 to 13 (window sizes: 32 to 8192 samples)
| WINDOW_EXP | Window Size (samples) |
|---|---|
| 5 | 32 |
| 6 | 64 |
| 7 | 128 |
| 8 | 256 |
| 9 | 512 |
| 10 | 1024 |
| 11 | 2048 |
| 12 | 4096 |
| 13 | 8192 |
Buffer operation
Each TM lane maintains:
- Circular buffer of depth = Max Memory Length
- Running sum accumulator
- Write pointer (auto-increments each cycle)
The moving average is computed as:
$$ \text{avg}[n] = \frac{\text{sum}[n]}{W} = \frac{\text{sum}[n-1] - x[n-W] + x[n]}{W} $$
where $x[n-W]$ is fetched from the circular buffer.
Fixed-point precision
- Input/Output bits: Same width (user-configurable, 4-32 bits)
- Sign: Configurable (SIGNED/UNSIGNED)
- Division: Implemented as right-shift by
WINDOW_EXPbits (efficient for power-of-2)
Since the window size is always $W = 2^{\text{WINDOW_EXP}}$, the division is exact and computed as: $\text{avg} = \text{sum} \gg \text{WINDOW_EXP}$.
Mathematical background
For a moving average filter with window $W$:
$$ H(z) = \frac{1}{W} \cdot \frac{1 - z^{-W}}{1 - z^{-1}} $$
This is a lowpass FIR filter with:
- First null at $f = f_s / W$ (where $f_s$ is sampling rate)
- Passband droop: ~4 dB at DC for W ≥ 4
- Linear phase (symmetric impulse response)
The filter attenuates high-frequency noise while preserving low-frequency signal components.
Timing
The HLS-generated IP has a fixed pipeline latency of 2 clock cycles:
| Property | Latency (clock cycles) |
|---|---|
| Moving Average (TM) | 2 |
Total system delay: T_delay = 2 × T_CLK.
Note: This latency is in addition to the group delay of $W/2$ samples introduced by the averaging window itself.
Typical use cases
- Noise reduction in ADC data streams
- Baseline estimation for pulse detection
- Trend analysis in time-series data
- Smoothing of multi-channel detector signals
Waveform example
Example with TM Factor = 4, WINDOW_EXP = 1 (window size = 2), Input = [10, 20, 30, 40, 50, …].
Note: WINDOW_EXP = 1 → W = 2^1 = 2 samples, OUT = (IN[n] + IN[n-1]) / 2, with 2 cycle latency.