DSPRelated.com
Forums

CIC pruning theory

Started by david447 May 25, 2011
Hello.

I have a problem with the implementation (VHDL) of the pruning technique
for the CIC.

I designed a CIC with this characteristics : 
Bin = 16;
Decimation : 40;
Delay : 1;
Stages : 6.

I calculated Bmax = 48 bits.

So my first CIC written in VHDL used Bmax for all the integrators and
combs, and I found the results I expected.
The result of the simulation in ModelSim gives some values at the output @
Fs/40, and then, the output is equal to “0” (with an impulse at the
input). 
(Bin = 16 bits, Bout = 48 bit)

But there is an other FIR low-pass compensating filter after this CIC, and
I can’t use 48 bits at the input, I want to have 16 bits at the output of
the CIC.

Bin = Bout = 16 bits

So I read the original Hogenauer paper’s and Uwe Meyer-Baese (DSP with
FPGAs) book’s, and I use the program cic.exe which gives the bits to
discard at each stages. The result is : 

-- --------------------------------------------------------
-- Program for the design of a CIC decimator.
-- --------------------------------------------------------
--      Input bit width      Bin  =    16
--      Output bit width     Bout =    16
--      Number of stages     S    =     6
--      Decimation factor    R    =    40
--      COMB delay           D    =     1
--      Frequency resolution DR   =    40
--      Passband freq. ratio P    =   160
-- --------------------------------------------------------
-- ----------------- Results of the Design ----------------
-- --------------------------------------------------------
-- -------- Computed bit width:
-- -------- Maximum bit growth over all stages      =    32 
-- -------- Maximum bit width including sign Bmax+1 =    48 
-- Stage   1 INTEGRATOR. Bit width :  46 
-- Stage   2 INTEGRATOR. Bit width :  41 
-- Stage   3 INTEGRATOR. Bit width :  36 
-- Stage   4 INTEGRATOR. Bit width :  32 
-- Stage   5 INTEGRATOR. Bit width :  28 
-- Stage   6 INTEGRATOR. Bit width :  24 
-- Stage   1 COMB.       Bit width :  22 
-- Stage   2 COMB.       Bit width :  21 
-- Stage   3 COMB.       Bit width :  21 
-- Stage   4 COMB.       Bit width :  20 
-- Stage   5 COMB.       Bit width :  19 
-- Stage   6 COMB.       Bit width :  18 
-- ------- Maximum aliasing component : 0.000000 = 264.12 dB
-- ------- Amplitude distortion       : 0.999615 =  0.00 dB

With this previous results, I modified my VHDL program by discarding some
LSBs at each stages.
But now I have a problem : my impulse response is not good anymore. Indeed,
in the results of ModelSim, I have some good values at the output of the
CIC, but then, the values alternate between –1 and 0 in signed mode (in
fact, “0000000..000” and “1111111..11111”).

I also read the threads about CICs but I didn’t find this problem.

Maybe it is a problem with my signals in my program (mismanagement of
signed and std_logic_vector).

If anyone can help me, I can show you  apart of my vhdl program.

Thank you very much for your help.

David.



On 05/25/2011 06:59 AM, david447 wrote:
> Hello. > > I have a problem with the implementation (VHDL) of the pruning technique > for the CIC. > > I designed a CIC with this characteristics : > Bin = 16; > Decimation : 40; > Delay : 1; > Stages : 6. > > I calculated Bmax = 48 bits. > > So my first CIC written in VHDL used Bmax for all the integrators and > combs, and I found the results I expected. > The result of the simulation in ModelSim gives some values at the output @ > Fs/40, and then, the output is equal to
>>>> &ldquo;0&rdquo; <<<< I don't know what character encoding you're using over there, but over here that renders as computer gibberish.
>(with an impulse at the > input). > (Bin = 16 bits, Bout = 48 bit) > > But there is an other FIR low-pass compensating filter after this CIC, and > I can&rsquo;t use 48 bits at the input, I want to have 16 bits at the output of > the CIC. > > Bin = Bout = 16 bits > > So I read the original Hogenauer paper&rsquo;s and Uwe Meyer-Baese (DSP with > FPGAs) book&rsquo;s, and I use the program cic.exe which gives the bits to > discard at each stages. The result is : > > -- -------------------------------------------------------- > -- Program for the design of a CIC decimator. > -- -------------------------------------------------------- > -- Input bit width Bin = 16 > -- Output bit width Bout = 16 > -- Number of stages S = 6 > -- Decimation factor R = 40 > -- COMB delay D = 1 > -- Frequency resolution DR = 40 > -- Passband freq. ratio P = 160 > -- -------------------------------------------------------- > -- ----------------- Results of the Design ---------------- > -- -------------------------------------------------------- > -- -------- Computed bit width: > -- -------- Maximum bit growth over all stages = 32 > -- -------- Maximum bit width including sign Bmax+1 = 48 > -- Stage 1 INTEGRATOR. Bit width : 46 > -- Stage 2 INTEGRATOR. Bit width : 41 > -- Stage 3 INTEGRATOR. Bit width : 36 > -- Stage 4 INTEGRATOR. Bit width : 32 > -- Stage 5 INTEGRATOR. Bit width : 28 > -- Stage 6 INTEGRATOR. Bit width : 24 > -- Stage 1 COMB. Bit width : 22 > -- Stage 2 COMB. Bit width : 21 > -- Stage 3 COMB. Bit width : 21 > -- Stage 4 COMB. Bit width : 20 > -- Stage 5 COMB. Bit width : 19 > -- Stage 6 COMB. Bit width : 18 > -- ------- Maximum aliasing component : 0.000000 = 264.12 dB > -- ------- Amplitude distortion : 0.999615 = 0.00 dB > > With this previous results, I modified my VHDL program by discarding some > LSBs at each stages. > But now I have a problem : my impulse response is not good anymore. Indeed, > in the results of ModelSim, I have some good values at the output of the > CIC, but then, the values alternate between &ndash;1 and 0 in signed mode (in > fact,
>>>> &ldquo;0000000..000&rdquo; and &ldquo;1111111..11111&rdquo;). <<<<
More gibberish.
> I also read the threads about CICs but I didn&rsquo;t find this problem. > > Maybe it is a problem with my signals in my program (mismanagement of > signed and std_logic_vector). > > If anyone can help me, I can show you apart of my vhdl program. > > Thank you very much for your help.
How are you reducing the number of bits? Are you throwing away your least significant bits by truncating (or rounding), or are you throwing away your most significant bits either by allowing wrap or by saturating? If you're throwing away most significant bits and you're saturating, then I could see what's happening. If you're truncating, then I'm kinda puzzled. Whatever else, you're probably throwing away immense amounts of useful data, and should revisit your decision to use a filter that can only take a 16 bit input on the output of a filter that may have many more than 16 bits of good data. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com Do you need to implement control loops in software? "Applied Control Theory for Embedded Systems" was written for you. See details at http://www.wescottdesign.com/actfes/actfes.html
On 5/25/2011 8:59 AM, david447 wrote:
> Hello. > > I have a problem with the implementation (VHDL) of the pruning technique > for the CIC. > > I designed a CIC with this characteristics : > Bin = 16; > Decimation : 40; > Delay : 1; > Stages : 6. > > I calculated Bmax = 48 bits. > > So my first CIC written in VHDL used Bmax for all the integrators and > combs, and I found the results I expected. > The result of the simulation in ModelSim gives some values at the output @ > Fs/40, and then, the output is equal to &ldquo;0&rdquo; (with an impulse at the > input). > (Bin = 16 bits, Bout = 48 bit) > > But there is an other FIR low-pass compensating filter after this CIC, and > I can&rsquo;t use 48 bits at the input, I want to have 16 bits at the output of > the CIC. > > Bin = Bout = 16 bits > > So I read the original Hogenauer paper&rsquo;s and Uwe Meyer-Baese (DSP with > FPGAs) book&rsquo;s, and I use the program cic.exe which gives the bits to > discard at each stages. The result is : > > -- -------------------------------------------------------- > -- Program for the design of a CIC decimator. > -- -------------------------------------------------------- > -- Input bit width Bin = 16 > -- Output bit width Bout = 16 > -- Number of stages S = 6 > -- Decimation factor R = 40 > -- COMB delay D = 1 > -- Frequency resolution DR = 40 > -- Passband freq. ratio P = 160 > -- -------------------------------------------------------- > -- ----------------- Results of the Design ---------------- > -- -------------------------------------------------------- > -- -------- Computed bit width: > -- -------- Maximum bit growth over all stages = 32 > -- -------- Maximum bit width including sign Bmax+1 = 48 > -- Stage 1 INTEGRATOR. Bit width : 46 > -- Stage 2 INTEGRATOR. Bit width : 41 > -- Stage 3 INTEGRATOR. Bit width : 36 > -- Stage 4 INTEGRATOR. Bit width : 32 > -- Stage 5 INTEGRATOR. Bit width : 28 > -- Stage 6 INTEGRATOR. Bit width : 24 > -- Stage 1 COMB. Bit width : 22 > -- Stage 2 COMB. Bit width : 21 > -- Stage 3 COMB. Bit width : 21 > -- Stage 4 COMB. Bit width : 20 > -- Stage 5 COMB. Bit width : 19 > -- Stage 6 COMB. Bit width : 18 > -- ------- Maximum aliasing component : 0.000000 = 264.12 dB > -- ------- Amplitude distortion : 0.999615 = 0.00 dB > > With this previous results, I modified my VHDL program by discarding some > LSBs at each stages. > But now I have a problem : my impulse response is not good anymore. Indeed, > in the results of ModelSim, I have some good values at the output of the > CIC, but then, the values alternate between &ndash;1 and 0 in signed mode (in > fact, &ldquo;0000000..000&rdquo; and &ldquo;1111111..11111&rdquo;). > > I also read the threads about CICs but I didn&rsquo;t find this problem. > > Maybe it is a problem with my signals in my program (mismanagement of > signed and std_logic_vector). > > If anyone can help me, I can show you apart of my vhdl program. > > Thank you very much for your help. > > David. > > >
Another test you can do to help shed some light, is simply remove the gain of the CIC before sending to the FIR. The gain of your CIC is (R*D)^S = 40^6 = 4.096e9 (unfortunate it is not a power of 2 :)). For test purpose, you should be able to remove the gain and get back to a 16bit number, if you right shift by 32 you will have a little less than unity gain but you will be in the 16bit range. .chris
<snip>
> > So I read the original Hogenauer paper&rsquo;s and Uwe Meyer-Baese (DSP with > FPGAs) book&rsquo;s, and I use the program cic.exe which gives the bits to > discard at each stages. The result is : > > -- -------------------------------------------------------- > -- Program for the design of a CIC decimator. > -- -------------------------------------------------------- > -- Input bit width Bin = 16 > -- Output bit width Bout = 16 > -- Number of stages S = 6 > -- Decimation factor R = 40 > -- COMB delay D = 1 > -- Frequency resolution DR = 40 > -- Passband freq. ratio P = 160 > -- -------------------------------------------------------- > -- ----------------- Results of the Design ---------------- > -- -------------------------------------------------------- > -- -------- Computed bit width: > -- -------- Maximum bit growth over all stages = 32 > -- -------- Maximum bit width including sign Bmax+1 = 48 > -- Stage 1 INTEGRATOR. Bit width : 46 > -- Stage 2 INTEGRATOR. Bit width : 41 > -- Stage 3 INTEGRATOR. Bit width : 36 > -- Stage 4 INTEGRATOR. Bit width : 32 > -- Stage 5 INTEGRATOR. Bit width : 28 > -- Stage 6 INTEGRATOR. Bit width : 24 > -- Stage 1 COMB. Bit width : 22 > -- Stage 2 COMB. Bit width : 21 > -- Stage 3 COMB. Bit width : 21 > -- Stage 4 COMB. Bit width : 20 > -- Stage 5 COMB. Bit width : 19 > -- Stage 6 COMB. Bit width : 18 > -- ------- Maximum aliasing component : 0.000000 = 264.12 dB > -- ------- Amplitude distortion : 0.999615 = 0.00 dB >
Why is your first comb section only 22bits? I believe it needs to match the size of the last integrator (to undo the wrapping). .chris
On 25.05.2011 17:59, david447 wrote:
 > I have a problem with the implementation (VHDL) of the pruning technique
 > for the CIC.
 >
 > I designed a CIC with this characteristics :
 > Bin = 16;
 > Decimation : 40;
 > Delay : 1;
 > Stages : 6.
 >
 > I calculated Bmax = 48 bits.
 >
 > So my first CIC written in VHDL used Bmax for all the integrators and
 > combs, and I found the results I expected.
 > The result of the simulation in ModelSim gives some values at the 
output @
 > Fs/40, and then, the output is equal to &ldquo;0&rdquo; (with an impulse at the
 > input).
 > (Bin = 16 bits, Bout = 48 bit)
 >
 > But there is an other FIR low-pass compensating filter after this 
CIC, and
 > I can&rsquo;t use 48 bits at the input, I want to have 16 bits at the 
output of
 > the CIC.
 >
 > Bin = Bout = 16 bits

Why don't you just discard LSBs from the CIC output and scale the result 
as Chris Felton suggested? I always use this approach, since Hogenauer 
pruning can help increasing speed only when you are very limited in 
routing resources (because otherwise the throughput will be primarily 
determined by the width of the first integrator in a decimating CIC, 
which runs at high clock rate). And i don't bother with the area 
consumed by CIC because it's almost always negligibly small compared to 
the size of other logic in my projects.

  > So I read the original Hogenauer paper&rsquo;s and Uwe Meyer-Baese (DSP with
 > FPGAs) book&rsquo;s, and I use the program cic.exe which gives the bits to
 > discard at each stages. The result is :
 >
 > -- --------------------------------------------------------
 > -- Program for the design of a CIC decimator.
 > -- --------------------------------------------------------
 > --      Input bit width      Bin  =    16
 > --      Output bit width     Bout =    16
 > --      Number of stages     S    =     6
 > --      Decimation factor    R    =    40
 > --      COMB delay           D    =     1
 > --      Frequency resolution DR   =    40
 > --      Passband freq. ratio P    =   160
 > -- --------------------------------------------------------
 > -- ----------------- Results of the Design ----------------
 > -- --------------------------------------------------------
 > -- -------- Computed bit width:
 > -- -------- Maximum bit growth over all stages      =    32
 > -- -------- Maximum bit width including sign Bmax+1 =    48
 > -- Stage   1 INTEGRATOR. Bit width :  46
 > -- Stage   2 INTEGRATOR. Bit width :  41
 > -- Stage   3 INTEGRATOR. Bit width :  36
 > -- Stage   4 INTEGRATOR. Bit width :  32
 > -- Stage   5 INTEGRATOR. Bit width :  28
 > -- Stage   6 INTEGRATOR. Bit width :  24
 > -- Stage   1 COMB.       Bit width :  22
 > -- Stage   2 COMB.       Bit width :  21
 > -- Stage   3 COMB.       Bit width :  21
 > -- Stage   4 COMB.       Bit width :  20
 > -- Stage   5 COMB.       Bit width :  19
 > -- Stage   6 COMB.       Bit width :  18
 > -- ------- Maximum aliasing component : 0.000000 = 264.12 dB
 > -- ------- Amplitude distortion       : 0.999615 =  0.00 dB
 >
 > With this previous results, I modified my VHDL program by discarding some
 > LSBs at each stages.
 > But now I have a problem : my impulse response is not good anymore. 
Indeed,
 > in the results of ModelSim, I have some good values at the output of the
 > CIC, but then, the values alternate between &ndash;1 and 0 in signed mode (in
 > fact, &ldquo;0000000..000&rdquo; and &ldquo;1111111..11111&rdquo;).
 >

I haven't used pruning before, but as i know it introduces noise, which 
is less than one LSB in the required output. Since the noise is injected 
into the integrator stages, i suppose it is natural for the output of 
the last Comb to alternate between zero and the smallest negative 
number, which is all 1's in the signed two's complement format, even 
when the bitwidths are selected correctly (i may be wrong, and if so i 
hope someone with more experience in CIC design will correct me). If you 
simply truncate the output of the 6th stage comb to 16 bits the result 
will still keep alternating. Use rounding to nearest instead.

-- 

Alexander



-- 

Alexander
Hello,
Thank you very much for your help and for your rapid answers.
First of all, the weird characters are quotes (doubles) ;)


-- Tim Wescott

>How are you reducing the number of bits? Are you throwing away your >least significant bits by truncating (or rounding), or are you throwing >away your most significant bits either by allowing wrap or by >saturating? If you're throwing away most significant bits and you're >saturating, then I could see what's happening. If you're truncating, >then I'm kinda puzzled.
I just truncate the LSBs, as follows : (from the first to the second integrator) I2 <= I2 + I1(46-1 downto 46-41); And I resize the input data as follows : I0 <= resize(signed(data_in), 46);
>Whatever else, you're probably throwing away immense amounts of useful >data, and should revisit your decision to use a filter that can only >take a 16 bit input on the output of a filter that may have many more >than 16 bits of good data.
Yes I think that it will be more prudent to have 32 bits at the output, but the next FIR has 20 bits coefficients and maybe the problem will be the same when I will truncate the data at the output of the FIR (to have 32 bits at the output). -- Christopher Felton
>Another test you can do to help shed some light, is simply remove the >gain of the CIC before sending to the FIR. The gain of your CIC is >(R*D)^S = 40^6 = 4.096e9 (unfortunate it is not a power of 2 :)). For >test purpose, you should be able to remove the gain and get back to a >16bit number, if you right shift by 32 you will have a little less than >unity gain but you will be in the 16bit range.
So, if I understand well, I have to shift the output by 32 bits, without any truncation during the CIC process ?
>Why is your first comb section only 22bits? I believe it needs to match >the size of the last integrator (to undo the wrapping).
I tried to put 22bits to the last integrator and the first comb, but the problem is the same.
>Why don't you just discard LSBs from the CIC output and scale the result >as Chris Felton suggested? I always use this approach, since Hogenauer >pruning can help increasing speed only when you are very limited in >routing resources (because otherwise the throughput will be primarily >determined by the width of the first integrator in a decimating CIC, >which runs at high clock rate). And i don't bother with the area >consumed by CIC because it's almost always negligibly small compared to >the size of other logic in my projects.
Yes, that&rsquo;s what I will try, and I will give you the result of that test. Thank you very much for your help in this matter. I am going to try what you said.
I forgot to specify that, my impulse response is equal to 
0111111111111111, during on clock period.

The output of the CIC, when I use 48 bits, is equal to (clock divided by
40):

000000000000000010010000001010100101111110101001
000000000000100000010001000100101101110110111010
000000000000100111000011101001100111100010001100
000000000000000100100010111100101011101000010110
000000000000000000000000000000100111111111111011

Before it is equal to zero, and after too.

It seems there is a problem because the input 011...111 is the highest
value in 2's complement form, and there are many MSB bits equal to zero at
the output.
<snip>
>> Another test you can do to help shed some light, is simply remove the >> gain of the CIC before sending to the FIR. The gain of your CIC is >> (R*D)^S = 40^6 = 4.096e9 (unfortunate it is not a power of 2 :)). For >> test purpose, you should be able to remove the gain and get back to a >> 16bit number, if you right shift by 32 you will have a little less than >> unity gain but you will be in the 16bit range. > > So, if I understand well, I have to shift the output by 32 bits, without > any truncation during the CIC process ? >
Yes that is a valid approach. Note, because your gain is not a power of two you will be over compensating. You will have something less than 0dB at 0Hz.
>> Why is your first comb section only 22bits? I believe it needs to match >> the size of the last integrator (to undo the wrapping). > > I tried to put 22bits to the last integrator and the first comb, but the > problem is the same. >
I didn't crunch the numbers but I would think the comb should be 24. Promote the comb to the size of the integrator not the other way around. Chris
On 5/26/2011 6:24 AM, david447 wrote:
> I forgot to specify that, my impulse response is equal to > 0111111111111111, during on clock period. > > The output of the CIC, when I use 48 bits, is equal to (clock divided by > 40): > > 000000000000000010010000001010100101111110101001 > 000000000000100000010001000100101101110110111010 > 000000000000100111000011101001100111100010001100 > 000000000000000100100010111100101011101000010110 > 000000000000000000000000000000100111111111111011 > > Before it is equal to zero, and after too. > > It seems there is a problem because the input 011...111 is the highest > value in 2's complement form, and there are many MSB bits equal to zero at > the output.
If the gain of the filter is 40^6. If you take 32767*40^6 = 134213632000000L in binary, '0b_01111010_00010001_00001011_11011100_00000000_00000000'. I don't think the density of 0s is a good metric. Your third output is, 41937172620L, which is ~3200 times smaller than it should be? <Python snip for the above numbers> In [3]: x = int("0111111111111111",2) In [4]: y = x * 40**6 In [5]: y Out[5]: 134213632000000L In [6]: bin(y) Out[6]: '0b11110100001000100001011110111000000000000000000' In [7]: out = int("000000000000100111000011101001100111100010001100", 2) In [8]: out Out[8]: 41937172620L In [9]: float(y)/out Out[9]: 3200.3500382854377 Chris
>On 5/26/2011 6:24 AM, david447 wrote: >> I forgot to specify that, my impulse response is equal to >> 0111111111111111, during on clock period. >> >> The output of the CIC, when I use 48 bits, is equal to (clock divided
by
>> 40): >> >> 000000000000000010010000001010100101111110101001 >> 000000000000100000010001000100101101110110111010 >> 000000000000100111000011101001100111100010001100 >> 000000000000000100100010111100101011101000010110 >> 000000000000000000000000000000100111111111111011 >> >> Before it is equal to zero, and after too. >> >> It seems there is a problem because the input 011...111 is the highest >> value in 2's complement form, and there are many MSB bits equal to zero
at
>> the output. > >If the gain of the filter is 40^6. If you take 32767*40^6 = >134213632000000L in binary, >'0b_01111010_00010001_00001011_11011100_00000000_00000000'. > >I don't think the density of 0s is a good metric. > >Your third output is, 41937172620L, which is ~3200 times smaller than it >should be? > ><Python snip for the above numbers> >In [3]: x = int("0111111111111111",2) >In [4]: y = x * 40**6 >In [5]: y >Out[5]: 134213632000000L >In [6]: bin(y) >Out[6]: '0b11110100001000100001011110111000000000000000000' >In [7]: out = int("000000000000100111000011101001100111100010001100", 2) >In [8]: out >Out[8]: 41937172620L >In [9]: float(y)/out >Out[9]: 3200.3500382854377 > >Chris > > >
Hello, Thanks again for your help. So I tried to shift my output with 32 bits (with 48 bits in all stages). Obiouvsly, the results are : 0000000000001000 0000000000001001 0000000000000001 And zero before and after. According to what I said previously, with the highest value at the output, I have many zeros in the MSBs, so when I truncate like here, I have nothing...