A Beginner's Guide To Cascaded Integrator-Comb (CIC) Filters
A Beginner's Guide To Cascaded Integrator-Comb (CIC) Filters
x(n) y(n)
R
–
z -1 z -N
After describing a few applications of CIC filters, this document introduces their
structure and behavior, presents the frequency-domain performance of CIC filters,
and discusses several important practical issues in implementing these filters.
Decimation
x(n) Decimation Compensation y(n)
(a)
CIC filter FIR filter
Interpolation
x(n) Interpolation y(n)
Zero Stuffing &
(b)
Compensation FIR filter CIC filter
Because their frequency magnitude responses are sin(x)/x-like, CIC filters are
typically followed, or preceded, by linear-phase lowpass tapped-delay line finite
impulse response (FIR) filters whose tasks are to compensate for the CIC filter's
non-flat passband.
z–1 z–1
Requires D-1 Previous
summations. average,
... ... y(n–1)
1
y(n) = [x(n) + x(n–1) + x(n–2) + x(n–3) + ... + x(n–D+1)] (1)
D
'
where n is our time-domain index. The z-domain expression for this moving
averager's output is
1 –1 –2 –D+1
Y(z) = [X(z) + X(z)z + X(z)z + ... + X(z)z ] (2)
D
D 1
Y(z) 1 1
HMA(z) =
X(z)
=
D
[1 + z
–1
+ z
–2
+ ... + z
–D+1
] =
D
n 0
z-n . (3)
We provide these equations not to make things complicated, but because they're
useful. Equation (1) tells us how to build a moving averager, and Equation (3) is
in the form used by commercial signal processing software to model the frequency-
domain behavior of the moving averager.
The next step in our journey toward understanding CIC filters is to consider an
equivalent form of the moving averager, the recursive running sum filter depicted
in Figure 2(b). Ignoring the 1/D scaling, there we see that the current input
sample x(n) is added to, and the oldest input sample x(n–D) is subtracted from, the
previous output average y(n–1). It's called "recursive" because it has feedback.
Each filter output sample is retained and used to compute the next output value.
The recursive running sum filter's difference equation is
1 1 - z-D
H RRS(z) . (5)
D 1 - z-1
We use the same H(z) variable for the transfer functions of the moving average
filter and the recursive running sum filter because their transfer functions are
equal to each other! It's true. Equation (3) is the nonrecursive expression, and
Equation (5) is the recursive expression, for a D-point averager. The mathematical
proof of this can be found in Appendix B of Reference [1], but shortly I'll
demonstrate that equivalency with in example.
Here is why we care about recursive running sum filters: the standard moving
averager in Figure 2(a) must perform D–1 additions per output sample. The recursive
running sum filter has the sweet advantage that only one addition and one
subtraction are required per output sample, regardless of the delay length D! This
computational efficiency makes the recursive running sum filter attractive in many
applications seeking noise reduction through averaging. Next we'll see how a CIC
filter is, itself, a recursive running sum filter.
CIC Filter
Comb Integrator
x(n) y(n)
–
z–D z–1
x(n–D)
The feedforward portion of the CIC filter is called the comb section, whose
differential delay is D, while the feedback section is typically called an
integrator. The comb stage subtracts a delayed input sample from the current input
sample, and the integrator is simply an accumulator. The CIC filter's time-domain
difference equation is
Y(z) 1 z-D
H CIC(z) . (7)
X(z) 1 z-1
To see why the CIC filter is of interest, first we examine its time-domain
behavior, for D = 5, shown in Figure 4. If a unit impulse sequence, a unity-valued
sample followed by many zero-valued samples, was applied to the comb stage, that
stage's output is as shown in Figure 4(a). Think, now, what would be the output of
1 1 1
0 0.5 0.5
–1 0 0
–2 –0.5 –0.5
0 5 9 0 5 9 0 5 9
Time Time Time
(a) (b) (c)
The key issue is that the combined unit impulse response of the CIC filter, being a
rectangular sequence, is identical to the unit impulse responses of a moving
average filter and the recursive running sum filter. (Moving averagers, recursive
running sum filters, and CIC filters are close kin. They have the same z-domain
pole/zero locations, their frequency magnitude responses have identical shapes,
their phase responses are identical, and their transfer functions differ only by a
constant scale factor.) If you understand the time-domain behavior of a moving
averager, then you now understand the time-domain behavior of the CIC filter in
Figure 3.
2
Radians
–10
dB
0 0
–20
–2
–1
–30 –4
–fs/2 –fs/4 0 fs/4 fs/2 –fs/2 –fs/4 0 fs/4 fs/2 –1 0 1
Frequency Frequency Real part
If we ignore the phase factor in Eq. (8), that ratio of sin() terms can be
approximated by a sin(x)/x function. This means the CIC filter's frequency
magnitude response is approximately equal to a sin(x)/x function centered at 0 Hz
as we see in Figure 5(a). (This is why CIC filters are sometimes called sinc
filters.)
The normally risky situation of having a filter pole directly on the z-plane's unit
circle need not trouble us here because there can be no coefficient quantization
error in our Hcic(z) transfer function. That's because CIC filter coefficients are
ones and can be represented with perfect precision with fixed-point number formats.
The filter pole will never be outside the unit circle. Although recursive, happily
CIC filters are guaranteed-stable, linear-phase, and have finite-length impulse
responses.
Again, CIC filters are primarily used for anti-aliasing filtering prior to
decimation, and for anti-imaging filtering for interpolated signals. With those
notions in mind we swap the order of Figure 2(C)'s comb and integrator—we're
permitted to do so because those operations are linear—and include decimation by
an integer sample rate change factor R in Figure 6(a). (The reader should prove to
themselves that the unit impulse response of the integrator/comb combination, prior
to the sample rate change, in Figure 6(a) is equal to that in Figure 4(C).) In most
CIC filter applications the rate change R is equal to the comb's differential delay
D, but I'll keep them as separate design parameters for now.
Decimation Interpolation
x(n) y(n) x(n) y(n)
R R
fs,in – fs,in –
fs,out = Rfs,in
z–1 z–D fs,out = fs,in/R z–D z–1
Figure 6: Single-stage CIC filters used in: (a) decimation; and (b)
interpolation. (Sample rates fs,in and fs,out are the sample
rates of the x(n) and y(n) sequences respectively.)
The decimation (also called "down-sampling") operation ↓R means discard all but
every Rth sample, resulting in an output sample rate of fs,out = fs,in/R. To
investigate a CIC filter's frequency-domain behavior in more detail, Figure 7(a)
shows the frequency magnitude response of a D = 8 CIC filter prior to decimation.
The spectral band, of width B Hz, centered at 0 Hz is the desired passband of the
filter. A key aspect of CIC filters is the spectral folding that takes place due to
decimation.
Those B-width shaded spectral bands centered about multiples of fs,in/R in Figure
7(a) will alias directly into our desired passband after decimation by R = 8 as
shown in Figure 7(b). Notice how the largest aliased spectral component, in this
1st-order CIC filter example, is 16 dB below the peak of the band of interest. Of
course the aliased power levels depend on the bandwidth B; the smaller B the lower
the aliased energy after decimation.
Figure 6(b) shows a CIC filter used for interpolation where the ↑R symbol means
insert R–1 zeros between each x(n) sample (up-sampling), yielding a y(n)output
sample rate of fs,out = Rfs,in. (In this CIC filter discussion, interpolation is
defined as zeros-insertion, called "zero stuffing", followed by CIC filter lowpass
filtering.)
After interpolation, Figure 8(b) shows the unwanted images of the B-width baseband
spectrum reside at the null centers, located at integer multiples of fs,out/R. If we
follow the CIC filter with a traditional lowpass tapped-delay line FIR filter,
whose stopband includes the first image band, fairly high image rejection can be
achieved.
Notice the increased attenuation at fs,in/R in Figure 9(b) compared to the 1st-order
CIC filter in Figure 7(a). Because the M = 3 CIC stages are in cascade, their
combined z-domain transfer function will be the product of their individual
transfer functions, or
M
W(z) 1 z-D
H CIC,Mth-order(z) -1 . (9a)
X(z) 1 z
–40 dB
–30
B
dB
–60
(b)
–90
–fs,in/8 0 fs,in/8 fs,in/4 3fs,in/8 fs,in/2
Frequency (before decimation)
It's important to notice the W(z) term in Eq. (9a). The transfer function in Eq.
(9a) does not include the down-sampling by R operation of the w(n) sequence in
Figure 9(a). (The entire system in Figure 9(a) is a multirate system, and multirate
systems do not have z-domain transfer functions. See Reference [2] for more
information on this subject.)
The frequency magnitude response of the Figure 9(b) filter, from the x(n) input to
the w(n) sequence, is:
M
sin(2πfD / 2)
H CIC,Mth-order(ej2 f ) . (9b)
sin(2πf / 2)
The price we pay for improved anti-alias attenuation is additional hardware adders
and increased CIC filter passband droop (downward mainlobe curvature). An
additional penalty of increased filter order comes from the gain of the filter,
which is exponential with the order M. Because CIC filters generally must work with
full precision to remain stable, the number of bits in the adders is Mlog2(D), so
there is a large data word-width penalty for higher order filters. Even so, because
CIC filters drastically simplify narrowband lowpass filtering operations,
multistage implementations (M > 1) are common in commercial integrated circuits
M
where an Mth-order CIC filter is often called a sinc filter.
In Figure 10 notice the decimation filter's comb section now has a reduced delay
length (differential delay) of N = D/R. That's because an N-sample comb delay after
down-sampling by R is equivalent to a D-sample comb delay before down-sampling by
R. Likewise for the interpolation filter; an N-sample comb delay before up-sampling
by R is equivalent to a D-sample comb delay after up-sampling by R.
Decimation Interpolation
x(n) y(n) x(n) y(n)
R R
fs,in – fs,out = fs,in/R fs,in – fs,out = Rfs,in
z–1 z–N z–N z–1
D
N=
R
(a) (b)
0 N=1 0
N=2
N=2
dB
–10
N=3
–10
dB
–20 R=2
R = 16
–30 –20
–fs,out/2 –fs,out/4 0 fs,out/4 fs,out/2 –fs,out/2 –fs,out/4 0 fs,out/4 fs,out/2
Frequency Frequency
(a) (b)
Figure 11: First-order CIC decimation filter responses: (a) for various
values of differential delay N, when R = 8; (b) for two
decimation factors when N = 2. (Sample rate fs,out is
the sample rate of the decimated output sequence.)
An interpolating CIC filter has zeros inserted between its input samples reducing
its gain by a factor of 1/R to account for the zero-valued samples, so the net gain
M
of an interpolating CIC filter is (NR) /R.
CIC filters suffer from accumulator (adder) arithmetic register overflow because of
the unity feedback at each integrator stage. This overflow is of no consequence as
long as the following two conditions are met:
When two's complement fixed-point arithmetic is used, the number of bits in an Mth-
order CIC decimation filter's integrator and comb registers must accommodate the
M
filter's input signal's maximum amplitude times the filter's total gain of (NR) . To
be specific, overflow errors are avoided if the number of integrator and comb
register bit widths is at least
where x(n) is the input to the CIC filter, and k means if k is not an integer,
round it up to the next larger integer.
Sign-extend
to 21 bits
x(n) 12 21 21 21 21 21 21 21 21 y(n)
SE 8
– – –
z–1 z–1 z–1 z–1 z–1 z–1
In some CIC filtering applications there is the opportunity to discard some of the
least significant bits (LSBs) within the accumulator (adder) stages of an Mth-order
CIC decimation filter, at the expense of added noise at the filter's output. The
specific effects of this LSB removal (called "register pruning") are, however, a
complicated issue so I refer the reader to References [3-5] for more details.
0 0
FIR filter –2
–1 Uncompensated response Uncompensated
–4
dB
dB
–2 –6 FIR filter
Compensated response
–8
–3
–10
Compensated
–4
0 fs,out/4 fs,out/2 0 fs,out/4 fs,out/2
Frequency Frequency
(a) (b)
If either the passband bandwidth or CIC filter order increases the correction
becomes more robust, requiring more compensation FIR filter taps. An example of
this situation is shown in Figure 13(b) where the dotted curve represents the
passband droop of a 3rd-order D = R = 8 CIC filter and the dashed curve, taking the
3
form of [x/sin(x)] , is the response of a 15-tap linear-phase compensation FIR
filter having the coefficients [-1, 4, -16, 32, -64, 136, -352, 1312, -352, 136,
-64, 32, -16, 4, -1].
For completeness I'll mention that Reference [6] also presents a low-order IIR
compensation filter for decimation applications where linear-phase filtering is not
necessary. That simple IIR filter's z-domain transfer function is:
9/8
HIIR(z) . (12)
1 (1/8)z-1
This compensation filter deserves consideration because it's linear-phase and was
designed to be implemented without multiplication. Figure 14(b) shows how to use
binary bit left-shifting and one addition to perform a multiplication by A = -10.
0
dB
–2
–4
–6
0 fs,in/4 fs,in/2
Frequency
Appendix A of this document presents MATLAB code for designing decimating FIR
compensation filters similar to that shown in Figure 15.
Conclusions
Here's the bottom line of our CIC filter presentation: a decimating CIC filter is
merely a very efficient recursive implementation of a moving average filter, with
NR taps, whose output is decimated by R. Likewise, an interpolating CIC filter is
insertion of R–1 zero samples between each input sample followed by an NR tap
moving average filter running at the output sample rate fs,out. The cascade
implementations in Figure 1 result in total computational workloads far less than
using a single FIR filter alone for high sample rate change decimation and
References
[1] Lyons, R., Understanding Digital Signal Processing, 2nd Ed., Prentice Hall,
Upper Saddle River, New Jersey, 2004, pp. 550–566.
[2] Lyons, R., "Do Multirate Systems Have Transfer Functions?". Available
online at: https://www.dsprelated.com/showarticle/143.php
[3] Hogenauer, E. "An Economical Class of Digital Filters For Decimation and
Interpolation," IEEE Trans. Acoust. Speech and Signal Proc., Vol. ASSP–29, pp.
155–162, April 1981. Available online at:
http://read.pudn.com/downloads163/ebook/744947/123.pdf
[5] Lyons, R., "Computing CIC Filter Register Pruning Using Matlab". Available
online at: https://www.dsprelated.com/showcode/269.php
[7] Jovanovic Dolecek, G., and harris, f., “Design of Wideband CIC
Compensation Filter for a Digital IF Receiver” Digital Signal Processing,
(Elsevier) Vol. 19, No. 5, pp. 827-837, Sept, 2009.
[8] Lyons, R., "The History of CIC Filters: The Untold Story". Available online
at: https://www.dsprelated.com/showarticle/160.php
Appendix A
Below is MATLAB code used to design decimating compensation filters
similar to that shown in Figure 15.
% Filename: CIC_compensation_filter.m
%
% Uses MATLAB's 'fir2()' command to
% design an FIR CIC-compensation filter by applying the
% inverse of a "final passband width" portion of a pre-defined
% CIC filter's mainlobe magnitude response as an input vector of
% magnitude values to Matlab's 'fir2()' command.
%
% Assumes the CIC filter is followed by a binary
clear, clc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define parameters of your desired CIC filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
M = 3; % Number of cascaded CIC stages.
R = 10; % Decimation sample rate-change factor.
N = 1; % Differential delay after sample rate change.
Fs = 1000; % CIC input sample rate before decimation (Hz).
Fp = 25; % Final cascaded-filters' passband cutoff freq
% (-6 dB mag. point) after decimation (Hz).
disp(' ')
disp(['CIC filter order = ', num2str(M), ' stages'])
disp(['CIC filter input sample rate = ', num2str(Fs), ' Hz'])
disp(['CIC decimation factor R = ', num2str(R)])
disp(['CIC filter output sample rate = ', num2str(Fs/R), ' Hz'])
disp(['Final cascaded-filter -6 dB passband width = ', num2str(Fp), '
Hz'])
disp(['FIR filter number of taps = ', num2str(FIR_Order+1), ' taps'])
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Plot target CIC filter positive-freq. mag. response
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Define frequency vector (Freq) in the range of 0 -to- 0.5
Freq = 0:1/(2*Num_Freq_Points):0.5 -1/(2*Num_Freq_Points);
figure(1), clf
Freq_Plot_Axis_1 = (0:Num_Freq_Points-1)*Fs/(2*Num_Freq_Points);
plot(Freq_Plot_Axis_1, Spec_Mag_dB_CIC, '-k')
axis([0, Fs/2, Threshold, 5])
xlabel('Hz'), ylabel('dB'),
title('CIC mag resp. before decimation'), grid on, zoom on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Design the FIR compensation filter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Num_FIR_Design_Freq_Points = 4*FIR_Order;
FIR_Freq_Vector = linspace(0, 1, Num_FIR_Design_Freq_Points);
Mag_Comp_Filter = abs(Spec_Comp_Filter);
Mag_dB_Comp_Filter = 20*log10(Mag_Comp_Filter);
%Freq_Plot_Axis_3 = (0:Num_Freq_Points-1)*(Fs/R)/(Num_Freq_Points);
Freq_Plot_Axis_3 = (0:Num_Freq_Points-1)*(Fs/(2*R))/(Num_Freq_Points);
figure(2)
hold on
plot(Freq_Plot_Axis_3, Mag_Comp_Filter, '-r', 'markersize', 2)
hold off
axis([0, Fs/(2*R), 0, 1.2*max(Inverse_CIC)])
figure(3), clf
plot(Freq_Plot_Axis_3, Mag_dB_Comp_Filter)
axis([0, Fs/(2*R), -80, max(Mag_dB_Comp_Filter)+5])
xlabel('Hz'), ylabel('dB')
title('FIR Comp. Filter mag. resp.'), grid on, zoom on
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% End of FIR compensation filter design
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Multiply the unity-gain FIR comp. filter complex freq response times
% the CIC filter's complex **mainlobe-only** freq response
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CIC_Mainlobe = ((1/(R*N))*(sin(pi*CIC_Mainlobe_Freq_vector*R*N/2)...
./sin(pi*CIC_Mainlobe_Freq_vector/2))).^M;
CIC_Mainlobe(1) = 1; % Zero Hz
subplot(2,1,2)
plot(Freq_Plot_Axis_3, Cascaded_Filter_Spec_Mag_dB, '-k')
hold on
plot(Freq_Plot_Axis_1(1:51), Spec_Mag_dB_CIC(1:51), '-r')
plot(Freq_Plot_Axis_3, Mag_dB_Comp_Filter, '-b')
hold off
title('Black = cascaded filter, Blue = comp. filter, Red = CIC')
axis([0, 1.2*Fp, -6-N, max(Mag_dB_Comp_Filter)+2])
xlabel('Hz'), ylabel('dB')
grid on, zoom on