Hello

I'm implementing one IIR Elliptical filter for Blackfin (BF-518), but the output of the filter does not agree with what I expected.

My input is a waveform of 60 Hz (Amplitude = 0.8) 600Hz 720Hz 840Hz 960Hz (Amplitude = 0.08)

The filter coefficients were generated by MATLAB. The cutoff frequency is 500Hz and the sampling frquency is 61440Hz:

"[B, A] = ELLIP (4,3,40,500 / 30,720).

Running the filter library "iirdf1_fr16" I get the following waveform at the filter output:

I would like a help because I do not understand why this occurs.

The project files are attached.

Thank you.

Rafael.

Hi Rafael,

It looks like your filter coefficients are causing the function iirdf1_fr16 to saturate - I tried scaling the B coefficients, but I still couldn't get a sensible response. The problem is that after scaling (by the function coeff_iirdf1_fr16), the value of one of the coefficients is 0x0003 which is very small (for a fract16 value). If you look at the description of the coeff_iirdf1_fr16 function you will see that there is a warning about this; the text says:

Warning: Be aware of the consequence of specifying a set of filter

coefficients whose order of magnitude are significantly

different. Significantly refers to an order of magnitude

greater than or equal to 15 when expressed as a power of 2.

In this situation, one or more filter coefficients may be

transformed to zero due to the restricted precision of the

fract16 type, and this may affect the performance of the

user-designed filter.

What I did next was to take your example, and convert it to using some of the new fract32 library functions that are going to be part of the next Update of VisualDSP++ 5.0 (which will be Update 9). Having done that, your example will filter the input signal as expected.

I am going to attach a ZIP file that contains my version of your example, together with the fract32 library functions that it uses. Your example that I modified is called test.c and is in the folder TEST.dir. There are two things that I need to point out to you with regard to this example.

The first thing is that the coefficients that are passed into the coeff_iirdf1_fr32 function are double precision constants and the function itself using 64-bit, double precision, floating-point arithmetic internally - this will increase the memory footprint of your application (and remember that if you want the ability to print double precision floating-point values then you should compile your application with the switch -double-size-64 which will also increase your memory occupancy).

The second issue that you must be aware of is that the fract32 library functions that have been included in the ZIP file are pre-release versions and so come with no warranty. If you do make use of these sources then you must read the file LICENSE.txt, which is included in the ZIP file, and agree to the terms that it sets out.

You can also verify this behaviour using Matlab:

twopow = 2^15; % 2^15 (=32768) for fract16 or 2^31 (=2147483648) for fract32

Aa=double(int64(A*twopow))/twopow; % convert from type double to fractional x.15|x.31 and back

Bb=double(int64(B*twopow))/twopow; % convert from type double to fractional x.15|x.31 and back

num2hex(Aa),num2hex(A) % bit-pattern of converted and original coefficients

num2hex(Bb),num2hex(B)

plot([1:1024],signal,'blue',[1:1024],filter(Bb,Aa,signal),'red')

When converting to fract16, you loose too many significant digits (in your B-coefficients in particular if you look at the bit-pattern) and thus your filter will no longer work as expected (note that Matlab will fail differently since it uses floating point arithmetic). When using fract32 arithmetic, a sufficient number of significant digits are retained and thus the filter will work as expected.

I hope that this will be useful to you.

Andreas