I have designed a 2nd order Butterworth filter with MATLAB fdatool for VHDL implementation. the cuttoff frequency is less than Fs/10, which should be okay since fdatool uses prewarping. Indeed, the floating point implementation works fine. However, after quantization to fixed point, even with very large word lengths (64 bit), the filter does not work as expected. Is there a way of fixing this? or is there another way of approximating a butterwoth response which will work with fixed point ?
-
What do you mean with "not working as expected"? Limit cycles? Diverging? Shifted cutoff frequency? – JHBonarius Jun 23 '17 at 18:31
-
In cases where there was extreme overflow, I could not tell from the plot, because the output looked like noise. I have since solved the problem, see my answer, but thank you for your help. – Mordechai Salomon Jul 05 '17 at 14:34
2 Answers
The question is how did you do the shift to fixed point. The main key here is that you're trying to preserve all the dynamic range.
If all your filter constants are between 0 and 5, let's say, if you use 64bit you will have very little dynamic range because it is impossible to do 1.3, you can just do integers.
What is typically done, for example, is to use 16 bit as Q1.15. This means that you have a range from -1 to 0.999969482421875. Here each bit corresponde to 2^(-15).
A consequence of this is that you need to scale your input so that your maximum is constrained to -1/1. If you're reading values from an ADC, for example, that's quite straightforward to do because you know the maximum value that can be read.
For a second order filter 16bit should be more than enough dynamic range, unless you're frequency range is also huge.

- 473
- 2
- 7
-
The shift to fixed point is done through matlab's fdatool quantizer, using 15 bit fractional 16 bit wordlength. I emphasize, that when designing a filter where the cuttoff frequency is more than 1/10 of the sampling frequency, the design works fine. It is only when this "limit" is passed, and prewarping is required, that the design does not work. also, to clarify, I am using a "butterworth" IIR. (MATLAB designs a lowpass filter,transformed to Highpass. the frequency scale has to be "warped" in order for high frequencies work- the infinite Imaginary axis is being mapped to the unit circle.) – Mordechai Salomon Jun 11 '17 at 19:25
-
I use an explicit definition of the filter in MATLAB, and rounding the Coefficients was NOT the problem as I had thought. The problem seems to be with the fixed point type, as the same filter works fine with a floating point sample signal, and gives unreasonable results with a 'fi' type signal. I do not know if this is a real problem or a Matlab quirk. – Mordechai Salomon Jun 13 '17 at 15:27
-
Can you post come matlab code, or upload your matlab script? Then I can look at it at night. – Andrés Jun 13 '17 at 16:49
I tried using int16 an in32 types for the Signal sample, and I found that when the wordlength has enough overhead (sign bits between the Sign bit and the MSB) the filter works fine, so apparently it is an overflow problem. What I did was scale the signal up: the float signal is between +-1, so for int16 I multiplied it by 2^5, and for int32 by 2^21, and tested the filter- it worked fine. in some cases less overhead was necessary,for the 1500 Hz filter, I needed 4 extra bits, and for the 250 Hz I needed 10 extra bits.

- 59
- 4