Quanta ControlQuantaControl
Back to Blog
·Quanta Control

Understanding CIC Decimation Filters for Feedback Control

technicalDSPCIC filterFPGA

What is a CIC Filter?

A Cascaded Integrator-Comb (CIC) filter is a highly efficient class of FIR filter that performs decimation (sample rate reduction) and interpolation without requiring any multipliers. This makes them exceptionally efficient on FPGAs, where multiplier resources (DSP slices) are often the bottleneck.

The transfer function of a CIC decimation filter in the z-domain is:

H(z)=Hint(z)Hcomb(z)=(1zRM1z1)NH(z) = H_{int}(z) \cdot H_{comb}(z) = \left( \frac{1 - z^{-RM}}{1 - z^{-1}} \right)^N

Where:

  • RR: Decimation factor.
  • MM: Differential delay (usually 1 or 2).
  • NN: Number of stages.

Our Implementation: 125 MSPS to 1 MSPS

In our feedback controller architecture, the CIC filter serves a critical role: reducing the 125 MSPS ADC sample rate to a 1 MSPS rate suitable for the PID controller. This decimation process provides significant processing gain and reduces the high-frequency noise bandwidth before the feedback logic.

Parameters

ParameterValue
Number of stages (NN)6
Decimation factor (RR)125
Input sample rate125 MSPS
Output sample rate1 MSPS
Input bit width14 bits
Internal bit width64 bits

The Physics of Bit Growth

One of the most important considerations in CIC design is register growth. To prevent overflow, the internal registers must have sufficient width to handle the accumulated DC gain. The maximum bit growth is given by:

Bmax=Nlog2(RM)+BinB_{max} = \lceil N \cdot \log_2(R \cdot M) \rceil + B_{in}

For our N=6,R=125,M=1N=6, R=125, M=1 configuration:

Bmax=6log2(125)+14=42+14=56 bitsB_{max} = \lceil 6 \cdot \log_2(125) \rceil + 14 = 42 + 14 = 56 \text{ bits}

We use 64-bit internal accumulators to provide extra headroom and simplify the RTL implementation on a 64-bit AXI bus.

The Scaler: Normalizing RNR^N Gain

A 6-stage CIC filter with R=125R=125 has a massive DC gain of 12563.814×1012125^6 \approx 3.814 \times 10^{12}. To normalize this back to unity gain (so the 14-bit input maps correctly to a 14-bit output), we must divide by RNR^N.

On the FPGA, we avoid actual division by using a fixed-point multiplier and a right-shift:

// CIC Scaler: Normalizing gain of 125^6
// Constant = round(2^60 / 125^6)
assign dout_raw = (din * 302231) >>> 60;

The constant 302231 provides a precision normalization with minimal logic overhead.

Frequency Response: The Sinc Effect

The frequency response of a CIC filter follows a sincN\text{sinc}^N shape:

H(f)=sin(πMfR/fs)sin(πf/fs)N|H(f)| = \left| \frac{\sin(\pi M f R / f_s)}{\sin(\pi f / f_s)} \right|^N

This results in:

  1. Excellent stopband rejection near multiples of the output sample rate (11 MHz, 22 MHz, etc.), which effectively aliases high-frequency noise into the DC nulls.
  2. Passband droop: The signal is slightly attenuated as it approaches the Nyquist frequency of the decimated rate.

For our laser locking applications, the passband droop is negligible because the PID bandwidth is typically <500< 500 kHz, well within the flat region of the 1 MSPS decimated stream.

Summary

The CIC filter is the "silent workhorse" of FPGA-based signal processing. By leveraging its multiplier-less architecture, we can process 125 million samples per second using only basic additions and subtractions, providing a clean, decimated error signal for our high-precision feedback loops.