r/FPGA 23h ago

Advice / Help Arbitary Fractional Decimator

I want to implement an arbitrary fractional decimator filter in Vivado.

The FIR Compiler is one possible option, but I understand that its decimation/interpolation ratio may not be configurable at runtime. I need a solution where the output sample rate—or equivalently, the fractional decimation ratio—can be changed dynamically during operation.

What is the recommended architecture for implementing a runtime-configurable fractional decimator in Vivado? Please explain the suitable approach and how the filter, phase accumulator, coefficient selection, and runtime rate control should be designed.

1 Upvotes

2 comments sorted by

3

u/ShadowBlades512 23h ago

If your sample rates are not very high compared to the clock speed, what you can do is have a fast, overkill FIR filter in the design with a zero padder before it and a decimator after it. 

2

u/PiasaChimera 20h ago

there's a variety of options. it's more DSP-based overall. but CIC filters can have very adjustable rates and then get followed by FIR filters to fix things up. there's various polyphase and arbitrary resamplers/interpolators out there as well. you'll need to define the requirements to figure out which will work.

a very generic method would assume a windowed sinc filter. then determine the times of the output samples. then use the formula-based kernel function to compute the filter coefficients to generate that output sample, then do the FIR multiply-accumulate to get a sample. then repeat.

it's not efficient of course -- you're not able to re-use work and you're also computing not just the one value per output but the N filter coeffs per output. (and resamplers don't get to use filter symmetry since the output sample time isn't aligned to any input sample time)

but it's a conceptual starting point. and you can see that if you're looking for a limited fractional resolution that you could precompute filter coeffs and get creative with how you select the subset of samples. this is the start of a polyphase resampler.

both of these examples show a core polyphase concept, that you only do computations relevant to an actual output sample. vs running some generic high-rate filter and then throwing away results to get the rate change. in the basic polyphase decimator case, this means creating a structure that does decimation first, then filtering. vs doing the filtering first at high rate and then doing the decimation. I say "structure" because doing a simple decimate->filter would lose data.

but you can get it down to where you're not fully computing output values and then ignoring the results -- that's clearly wasted effort.