I have a sensor signal which is unsigned 12 bits and i need to filter the signal using a FIR filter. The filtered output feeds into an algorithm which expects 12bit unsigned input.I have used FIR compiler to design fir filter, but the output length is 28 bits. How can is scale the coefficients so as to have minimum quantization error if i discard the LSBs from the filter output. Can someone provide guidance, with an example.
Your filter input range is 0 ~ 4095.scale your coeffs so that their sum = 4096 coeff = round(4096*coeff/sum(coeff)); Then discard 12 LSBs (bit 11:0) giving you unity gain (output 0 ~ 4095); Discard remaing 4 MSBs(bit 27:24). you may insert flag/saturate if bit 24 gets that occasional hit at extremes.
Hi Kaz,Thanks for your reply. The Fir compiler has floating point, fixed point and Integer coefficients. For the calculation in your previous post: coeff = round(4096*coeff/sum(coeff)); should I be using the integer coefficients that are output to the text file by fir compiler when i generate the filter? or the fixed point coefficients? I have tried to use coeff = (4096*coeff/sum(coeff)); without rounding with the integer coefficients. The sum of resultant coeffs is 4096. And then I copied these scaled coefficients into a text file and used Import coefficient of fir compiler. The new Integer coefficients that the compiler generates are less than 12 bits but their sum is greater than 12 bits. I am not sure how the hardware implementation works, but i assume it uses the integer coefficients, So for DC signal value the output will be equal to sum of integer coefficients which is greater than 12bits. Is that true? Once again thanks for replying to my question.
I regret I don't know about specifics of Altera FIR compiler. I referred to general concepts of filtering.I always think of signed representation for a filter's input/output and don't really understand what unsigned means or is it converted to signed invisibley. The rule for fixed point (incidentally it is sort of integer) is that what you mentioned: DC output = 4095*h0 + 4095*h1 + ...etc = 4095(ho+h1+...etc). hence if sum of coeffs = 4096 then your output = 4095*4096 then divide back by 4096(truncate 12 bits) and your output becomes 4095. The only exceptions are those input patterns that = DC level but with pattern that negates the sign of some coeffs resulting in a sum larger than actual sum of signed coeffs ! I think the best thing is to try and see how FIR implements the output scaling through simulation.
The FIR compiler scales the coefficients in a way, that the largest coefficient gets the maximum value in the choosen numeric format. To achieve a DC gain of 1 (respectively a power of 2), you have to use manual scaling. The rightmost "fixed point" column in the coefficient table shows the final coefficients used by the filter. Their sum should be a power of 2.
The sum of coeff is 51519. Do you think some thing is not set right in the fir compiler setting. I am using the following settings:Input Number System : unsigned binary Input Bit Width: 12 Coeffecients scaling: Auto Bit width 12 Structure: fully Parallel filter.
--- Quote Start --- The sum of coeff is 51519. Do you think some thing is not set right in the fir compiler setting. --- Quote End --- I guess it's normal operation of the FIR compiler, but it ends up in a DC gain that's not a power of two, so you can't get a gain of 1 by just adjusting the number of bits. Provided, that the coefficients are now using the full range, you can use manual scaling to the next smaller power of two, 32768.
IMHO you should replace sum(coefs) with sum(abs(coefs)) everywhere, and the algorithm will work a lot better.Read a book on convolution and you will find out why.