Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

CIC decimation filter: does bit pruning affect the gain?

Status
Not open for further replies.

H.Hachem

Junior Member level 3
Joined
May 29, 2012
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,520
Hello,
I'm trying to calculate the gain of a CIC decimation filter after bit pruning. I believe bit pruning affects the gain because it is not possible to represent the factor (RM)^N with the limited output precision.
Any help will be appreciated
 

A CIC decimator with power-of-two ratio R will keep the most significant bits and add less significant bits according to the useable dynamic range. If we imagine a fractional number representation, this corresponds to a gain of 1. Bit pruning is just the method to derive the required bit number of each stage after deciding about the output word width.

I've only used gain calculations for non 2^n R numbers up to now.
 
Hello neighbor (Aachen here ;)),

well that's good to know. So far I've used 64 and 32 as decimation factors, so what you are saying applies. However, I relied on the code of MAYER-BAESE (DSP with FPGA), and simply modified the decimation factor , the differential delay from 2 to 1 and adjusted the bit pruning, but the filter isn't behaving as it should. Here's the code and testbench just in case:

Code:
// cic decimation filter : R=64, M=1, N=3
module cicdecim64 (x_in,y_out,clk,reset);
input			clk; 
input 			reset;
input signed	[11:0]	x_in;
output signed 	[11:0]	y_out;
reg signed 		[11:0] y;

parameter hold=0, sample=1;
reg			clk2,state; 	//sample or hold states
reg		[5:0]	count;			//count till 63 starting from 0
reg signed	[11:0]	x;					//input
wire signed	[27:0]	sx;				//sign extended input
reg signed	[27:0] 	i0;				//Integrator output section 0
reg signed	[22:0]	i1;				//output section 1 under the consideration of Haugenauer's pruning
reg signed	[17:0]	i2;
reg signed	[15:0] 	z0, c1, c0; 	// Integrator+COMB 0
reg signed	[14:0] 	z1, c2;
reg signed	[13:0] 	z2, c3;



always @(negedge clk)
begin : FSM 							// finite state machine
case (state)
hold : begin
if (count<63) 							// setting states for downsampling
state <= hold;
else
state <=sample;
end
default:
state <= hold;
endcase
end

assign sx={{16{x[11]}},x_in};

// Integrator
always @(posedge clk or reset)begin
if(reset) begin
count = 0;
x = 0;
i0 = 0;
i1 = 0;
i2 = 0;
c0 = 0;
c1 = 0;
c2 = 0;
c3 = 0;
z0 = 0;
z1 = 0;
z2 = 0;
y=0;
end

begin: I
x <= x_in;
i0 <= i0 + sx; 						
i1 <= i1+i0[27:5];
i2 <= i2+i1[22:5];
case (state) 								//downsample
sample : begin
c0 <= i2[17:2];
count <= 0; 								//reset counter once a sample has been fetched
end
default :
count <= count+1;
endcase
if((count>16)&&(count<32))
clk2 <=1;
else
clk2 <=0;
end
end


// COMB
always @(posedge clk2)
begin: COMB
z0 <= c0;
c1 <= c0-z0;
z1 <= c1[15:1];
c2 <= c1[15:1]-z1;
z2 <= c2[14:1];
c3 <= c2[14:1]-z2;
y	<=c3[13:2];
end
assign y_out=y; 
endmodule

MODELSIM: sampling frequency = 2MHz input signal: square signal @ 500Hz (should pass through)
wave.png
 
Last edited:

I must confess, that I can't easily check the code for correct operation, but it looks basically correct, near to Baese's VHDL code.

I can't see exact signal values in the simulation, but it doesn't look particularly as a gain problem.

Not directly related to discussed point, but you shouldn't operate the CIC design with a "ripple" clock. You better use sample as a clock enable, like it's done in the book.
 

Hey FvM,

thanks for the reply. I just checked the original code of Meyer-Baese and tested it. However the response to a constant 1 ist between 4 and 3. I expected it to be 1 also.
On a different note, the cic.exe program provided by the author is supposed to calculate the amount of bits which can be discarded. However I don't get what the importance of the passband to sampling frequency ratio (last parameter) is. I need the CIC filter to simply pass the DC component of a signal, so I'm flexible when it comes to the passband. In his book, Meyer chose 8 for this parameter, however he did not mention why.
 
Last edited:

A simple point first. Passband to frequency ratio is only used for the aliasing and "amplitude distortion" (passband attenuation) calculations. You can enter any value, if you are only interested in the bit width data.

You have in fact a "gain" of 4 in your implementation, because you ignore the Bmax parameter. Following the cic.exe calculation, two input bits would be cut before the first integrator. That's essentially a result of Hogenauer's pruning scheme rather than a cic.exe fault. In addition, there's a minor calculation fault in the cic.exe version shipped with the 2nd edition, I don't know if it's corrected in a recent version. I informed the author about this point in 2006, so it may be changed in the 3rd edition. But I don't know if the tools have been edited at all.

Cutting two input bits can be substantiated from a signal theory viewpoint, but isn't reasonable for all classes of signals. I have a CIC component, where the bit pruning is calculated in VHDL according to the instantiation parameters. I have modified Hogenauer's scheme in so far, that I don't cut more bits than (DINSIZE-DOUTSIZE) in the first stage, ususually zero because DOUTSIZE is greater or equal than DINSIZE. And I always apply rounding in the last stage. The respective register widths for your design parameters are 30, 23, 18, 15, 14, 13.

I also noticed that your code has several violations of synthesizable Verilog rules, e.g. multiple signal drivers, mixing blocking and non-blocking statements for the same signal.

I already mentioned the problem of ripple clock divider, which is likely to cause timing viiolations. All this points are easy to clean up.

Code:
-- --------------------------------------------------------
-- Program for the design of a CIC decimator.
-- --------------------------------------------------------
--      Input bit width      Bin  =    12
--      Output bit width     Bout =    12
--      Number of stages     S    =     3
--      Decimation factor    R    =    64
--      COMB delay           D    =     1
--      Frequency resolution DR   =    64
--      Passband freq. ratio P    =    10
-- --------------------------------------------------------
-- ----------------- Results of the Design ----------------
-- --------------------------------------------------------
-- -------- Computed bit width:
-- -------- Maximum bit growth over all stages      =    18 
-- -------- Maximum bit width including sign Bmax+1 =    30 
-- Stage   1 INTEGRATOR. Bit width :  28 
-- Stage   2 INTEGRATOR. Bit width :  23 
-- Stage   3 INTEGRATOR. Bit width :  18 
-- Stage   1 COMB.       Bit width :  16 
-- Stage   2 COMB.       Bit width :  15 
-- Stage   3 COMB.       Bit width :  14 
-- ------- Maximum aliasing component : 0.001307 = 57.68 dB
-- ------- Amplitude distortion       : 0.951694 =  0.43 dB
 
Thanks a lot for the help. I used your parameters, now the reponse to a constant input at 10 ist actually 10 but switches to 9 for a short period. I'm not sure how critical this is. I know the code is not synthesizable, so far I've only used the Modelsim compiler, and it worked normally. I modified it a bit and made it synthesizable. could you please explain how you calculated the bit widths?
Thanks in advance


UPDATE: hmmm it is not blocking frequencies above 2MHz/64.
 
Last edited:

now the reponse to a constant input at 10 ist actually 10 but switches to 9 for a short period.
yes, you need to implement rounding to get rid of this.
UPDATE: hmmm it is not blocking frequencies above 2MHz/64
It has a (sin(x)/x)^3 frequency characteristic. There's no particular problem with frequency components above the fs/64, they are not actually blocked but attenuated by at least 40 dB for a 3rd order CIC. The problem is rather with the components between fs/128 and fs/64 that are mirrrored down to the baseband.
 
I see. Well according to Hagenauer's paper, components between fs/128 and fs/64 do not contribute to aliasing so it should be ok if say 50kHz was to pass through right ? What's puzzling me is that the amplitude of the 50kHz signal is only being attenuated by a factor of 2. ( square input with amplitude 20 is leading to a square output with amplitude 10).

- - - Updated - - -

for rounding I used : y_out = (c3 + 1)>>1;
However, the output still oscillates...
 

If I understand right, you have an output data rate of 2 MHz/64 = 31.25 kHz. Then the attenuation of a 50 kHz input signal (aliasing to 12.5 kHz) should be > 40 dB.

What we can say about CIC decimators in general, they are not well suited for input signals with a spectral range near to the Nyquist frequency fs/2, because the passband attenuation is high and the alias suppressing insufficient. If CIC decimators are used in applications of this kind, e.g. audio ADC, they are supplemented by a regular FIR decimator for the last decimation step.

The multiplierless CIC topology has been published more than 30 years ago. At those days, digital signal processing was rather expensive. It's still interesting today, but can't compete for applications with critical frequency characteristic and aliasing risk.
 
Too bad. I'm writing this code as a part of a bachelors thesis, which I need to submit it in the next 2 days :/ . rewriting such a huge code would be simply crazy. So I will have to work around it somehow. By the way, is there any way to build an interpolator in verilog, which would multiply the input sampling frequency by a factor M and output it as a sampling clock for the next module?

- - - Updated - - -

Never mind, I found a work around for the interpolator's clock frequency.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top