Variable IIR-Filter Coefficient calculation in frequency domain

Started by Nordmann 5 months ago6 replieslatest reply 2 months ago305 views


Currently im evaluating the usefulness of frequency domain filtering in FPGA for one of our projects. Im stuck with a problem that my limited knowledge of dsp does not suffice for. Hopefully you can help me out a bit here.

We receive a bunch of data from a sensor. In our old products this has been filtered in the time domain by a IIR filter of order 14. Now, i would like to do this in the frequency domain (for a variety of reasons). First the data is FFTd blockwise with n=1024 points (n cant be changed here for other reasons). Then it is filtered by said IIR highpass (multiplication with the filter frequency response). So far, so standard.

The problem now is that the aforementioned highpass is a variable filter, with its cutoff-requency being tunable between 1kHz to 127kHz in 0.5Hz steps. When the filtering was done in the time domain we simply stored a file containing all the filter-coefficients. Depending on cutoff-frequency requirements, the corresponding coefficients were loaded into the fpga. If I were to implement the same concept for my frequency domain filtering I would have to store 255 steps*n=1024 frequency bins *2 Bytes = 512kB of frequency coefficients/bins for just one filter. This is way to much. Hence i am looking for a way to greatly reduce the number of frequency coefficients/bins i have to save. A processor is included and can be used to help with coefficient calculation. Therefore my questions are the following:

1) Is there a way to save a reference frequency response with a cutoff-frequency of, lets say, 60kHz, and to shift that frequency response for other cutoff frequencies? For example, if i need a cutoff frequency of 80kHz i just shift my reference magnitude response by 20kHz or something like that. I have tried that by convolving in the frequency domain with the frequency response of a sine (so basically mixing, just in the frequency domain). That works for some frequencies, but also tends to pull in (for lack of a better word) negative frequencies at some point, which messes up the frequency response again.

2) Is there a simple way to calculate a filter on the fly by supplying cutoff frequency, stop band width and such? Simple, because i would like to keep computations short to save processor time.

3) Would it be possible to just save a fraction of the frequency coefficients/bins and then interpolate to n? For Example, to save only n=128 bins for each frequency step that are then interpolated to 1024 when needed. I know that frequency bins can be interpolated, but is it possible for that many?

4) Is there maybe a way to implement a tunable filter in fpga without having to input any coefficients to begin with?

5) Aside from my ideas, are there other ways to approach the problem?

Thanks and regards,


[ - ]
Reply by emebFebruary 15, 2024

Option 1) is attractive as it would imply simply shifting a single fixed response up or down. You'd want to evaluate your filter response across its whole range though as its shape may change as Fc varies, in which case merely shifting a fixed curve is not the answer.

Alternatively, perhaps you could store the filter bin weights as a simple polynomial-per-bin that could easily be computed on-the-fly. Basically you pre-compute the filter responses for each bin at all Fc steps and generate an Nth-order curve fit that can be easily computed in the FPGA (or processor) from a few coefficients per bin. I'm guessing that a fair number of your bins don't change much (always weighted 0.0 or 1.0) so you might be able to significantly pare down the complexity.

Finally, it sounds as though you're trying to match the original 14th order IIR response pretty faithfully which may be making the task more difficult than it needs to be if that's not actually a requirement. If matching that response is not a hard spec then you might be able to save a lot of trouble by doing a much more simple bin truncation operation in the frequency domain.

[ - ]
Reply by NordmannFebruary 26, 2024

Thanks a lot for the reply,

Regarding your first suggestion: I do not quite understand your idea. Could you explain it in a bit more detail please, especially your points about the usage of polynomials and the n-th order curve fit?

The order 14 is not set. I would actually like to increase it to improve the filters slope. However, once again I do not quite understand your suggestion. What do you mean by bin truncation in the frequency domain?

[ - ]
Reply by emebFebruary 26, 2024

For the curve fitting approach: You need to generate a family of responses, basically a 2D surface with FFT bin weights in one axis and cutoff frequency setting along the other axis. Then you do a polynomial curve fit for each bin along the cutoff frequency axis yielding a set of Nth-order coefficients that describe how that bin's weighting changes as the cutoff frequency varies. If the number of coefficients needed to describe your response with desired accuracy is small (say, less than four) then you've basically compressed your entire response curve down to the number of bins times the number of coefficients and you can reproduce those weights in realtime with fairly simple computations in the FPGA.

For the other suggestion: If you don't care to accurately reproduce the current 14th-order IIR response curve then you could try a simple step-function in the frequency domain as your HPF response. Just set all bins below Fc to zero and all bins above Fc to 1.0 - this will give you a transition band that has the shape of whatever windowing function you use for the OLA processing. If you need finer frequency resolution than one band then you can interpolate at the band edge.

[ - ]
Reply by Robert WolfeFebruary 15, 2024

I've done 2) above, but it was for a DSP processor.  Found an online C version of the filter design, and just ran it each time a new set of filter configuration parameters were sent, and updated the coefficients.  Not sure how equivalent an effort it would be in FPGA-land.  And you'd have the extra step of running the FFT on the resulting updated coefficients.  The filter design could be implemented, if there is no version available, but again, not sure if that is realistic in FPGA (and calculations would likely not be short)

[ - ]
Reply by asserFebruary 16, 2024

I`ve resolved such a problem in the following project:


It contains a detailed description.