I am designing a CIC Decimator followed by a FIR compensation decimator filter in Matlab. I am trying to figure out how to tell Matlab to make sure that my output (which I truncate to a 16 bit value) has the full range of values based on the input which is either 1 or -1. Basically, if I give the filter constant 1s, I would expect something close to 16'b0111_1111_1111_1111 and if I give the filter constant -1s, I would expect 16'b1000_0000_0000_0000 (both values in 2's complement).
Any help would be very appreciated.
Are you using 2's complement overflow in your matlab simulation... I'm guessing from your question that you are concerned with your accumulators overflowing... If the width of the binary word is sufficient to represent the dynamic range of the box car integrator output (the gain per stage is M) and if you have K stages the bit growth is K log_2(M) on top of the word width you bring into the cascade boxcars.... The CIC will form the correct output if the number of bits in te accumulators matches the bit growth plus input bit width.
I've written, and use, a 2-complement adder to demonstrate that internal overflow of the accumulators still give the correct width if the accumulator width matches the constraint I described. If you are not using the overflow option... you need to do it... can change bit width in simulation to demonstrate overflow effects... two few bits wont't work.. more than enough works but uses very wide width accumulators,,, wider than they have to be
the most telling input is straight DC... the integrators have to overflow as they integrate the DC for a long enough interval.
Then the thought struck me... if you are applying +/-1 to your CIC you are feeding it the output of a sigma delta converter. The reason the CIC is attractive, it can perform filtering without multiplies.... if the input sample are restricted to +/-1 every FIR filter can process those samples without multiplies. You can do much better with a polyphase filter which can process the +/-1 samples without multiplies and without the CIC tilt correction.... see attached paper
best of luck
Thank you Fred,
The input is in fact a Sigma Delta converter and I do have a very large width on the accumulators. The reason for using the CIC is I am decimating over 8000 and I follow it up with the FIR (which decimates by 2) to clean up the signal and meet the filter's specs. I am able to see the output from the CIC and I have truncated it to 16 bits by verifying which bits actually change when I supply either an all 1s or -1s into the filter. Thus, i.e. when supplying all 1s I get a very large number (54 bits) 010000000000000000..., which I change to 0111_1111_1111_1111 before supplying this to the FIR. the issue I'm having is to still keep the full dynamic range from -32k to 32k of hte 16bit number, the FIR coefficients aren't the correct scale or the products aren't truncating at the correct locations. I hope I am making sense b/c I am not a dsp guy, but this filter meets our specs and I need to make sure I am getting the full range from the 16 bit output despite the gains and filtering.
You have 13 bits of growth per stage in your filter... how may stages do you have? if you have 4 stages you have 52 bits of growth... how many bits wide is the input data: if it is a ten bit input word, you accumulators have to be 62 bits wide... your 54 bit accumulator won't give you correct answers due to your truncation.. I give a lecture on things we did in the past which in hindsight were not sensible... high on that list is the CIC filter. Each 64 bit wide accumulator in the (grey chip set) running at full input sample rate use unexpectedly large amounts of energy and have very long delays due to ripple carry. The polyphase filter with the same number of adds as the CIC and no multiplies (as in the CIC) does a much less expensive job of filtering with embedded resampling. i have some matlab demos i use to show how truncation rather than overflow (with floating point numbers that increment exponent) starts raising the noise floor at each step of the exponent because the difference in the derivatives can't cancel the missing bits that were discarded upon xpenent increment. The factor of 8000 may be done less expensively in a two stage decimator with gain changes between stages.
read my paper for some fresh perspective
Thanks Fred, I'm actually only inputting a 2 bit word and there are four stages which is why my 54 bit width accommodates my data. I am not against the polyphase filter, but does Matlab have a tool to generate one? I need to be able to decimate the signal from 500kHz to less than 100 Hz while maintaining the other filter specs required. They are pretty strict which is why I use the CIC to decimate the signal and then the rather large FIR to clean up the signal and meet the specs. I can't go into specifics, but the CIC followed by the FIR meets the specs from Matlab, but like I said, if I input all 1s or -1s, the output from the FIR is not close to the max/min dynamic range for any 16 consecutive bits out of the 32 bit number that Matlab creates if I don't truncate the CIC. If I do truncate the CIC before going into the FIR, I still have the same issue with the 16 bit number out of the FIR not getting close to the max/min dynamic range. It is actually close to 1/8 of the max value when all 1s or -1s are the exclusive inputs. Is there a way to force Matlab to scale/change the coefficients of the FIR to make sure that the max/min value is close to the max/min binary numbers?
For the CIC I am using a number that is a power of 2 because the max gain is then correlated to 0100000000... (which I change to 0011111111....), but I'm not sure how to fix the FIR to give me the max gain be a "full" binary number. Hope that makes sense.
CIC has its own inherent scaling though you can double your input or so but at expense of filling bits without information. FIR can be scaled as you wish by scaling coeffs to any value you want. Polyphase idea is ok in your case as it does not need mults but requires large memory to hold coeffs.
Thanks for the reply kaz. I totally get that, I suppose what I'm asking is does Matlab have a "toggle" that I can turn on to make sure that the output from the truncated 16 bit number actually reaches the full dynamic range of values on the output? Right now, when giving the filter all 1s or 0s, I get 1/8 of the total dynamic range.
No as far as I know. You need to look after that, sounds like AGC if variable. DC gain serves as good indicator for fir dynamic range and power transfer.
If your need is a reduction in BW and sample rate by 8000-to-1 you should be doing this with an 2000-to-1 CIC filter followed by 2- half band filters that correct the CIC Mainlobe droop while performing a 2-to-1 BW and sample rate reduction. This will widen the main lobe and give you less amplitude reduction due to frequency displacement from DC (I'm assuming you are testing the filter with a single real sinewave.
If you have access to a copy of my multirate book there is an example of that cascade in my section of CIC filters. If you send me your filtering specifications and a description of your test signal I may be able to give you more specific directions.