FPGA Intellectual Property
PCI Express*, Networking and Connectivity, Memory Interfaces, DSP IP, and Video IP
6350 Discussions

How to use correctly FIR filter as moving weighted average calculator?

Honored Contributor II

Hello to everyone, 


In my project (using Cyclone-III EP3C16F484 @ 50 MHz) I need to implement moving weighted average calculation of 16 samples coming from ADC @ 8.33 MSPS (12 bit DDR). For beginning I wanted to make it only for 1 channel. 

From my general knowledge (https://en.wikipedia.org/wiki/finite_impulse_response) I thought to use Altera megafunction FIR II. From the Figure 1.1 of the document ug_fir_compiler_ii.pdf (UG-01072 2015.10.01) I got impression that this should be rather straightforward task. However, numbers that I get out if serialization is activated (by setting sample rate 5 times smaller than the clock) commonly differ from those without serialization: 

1. In case of sample rate = clock, no multipliers are used, result is as expected for any filter length (5-16 elements tested). 

2. But just the same calculation required to be done in few cycles (sample rate = clock/N) the sum is becoming partial, except of few special cases-- see the next point. 

3. However, if the filter contains e.g., 6, 9, 18, or 36 elements (something x6 or x9, but except e.g. 12), serialization does not ruin the calculation result! 

I did not check really all the possible filter length between 5 and 36 (i.e. I do not know how the FIR II would do in case of 24 or 27 elements), but the trend seems to be quite clear. 


So, adding 2 "0" elements to my desired filter allows to produce expected result, but this behavior (x6, x9 effect) seems to be rather strange. In the documentation I've found only that the filter should have at least 5 non-zero elements, but no standard sizes were ever mentioned. 


I'm using Quartus II 13.1 on Ubuntu 12 (the latest for Cyclone III). 

My input: decimal number 10 coded on 13 bit reg (MSB=0, i.e. positive). 

FIR II setup: 

- Filter type: Single rate; 

- L-th Band Filter: All taps; 

- 4 bit coefficient (signed binary); 

- Coefficient scaling: None; 

- between 5 and 36 coefficients (values 1 - 6) loaded from the text file - correctly recognized by the builder; 

- 13 bit binary signed input data; 

- Output: signed binary 21-23 bit wide (auto-generated); 

- Clock frequency: 50 MHz; 

- Clock slack: 0; 

- Sample rate: 10 MSPS; 

- Speed grade: Medium; 

- Symmetry mode: Non symmetry. 


FIR II I/O are transmitted and received via wires. 


The output is obtained when ast_source_valid ==1 (checked at every posedge clock). 


Thanks for possible explanation for this x6,x9 effect.
0 Kudos
2 Replies
Honored Contributor II

I don't want to put you off your focus on FIR ip but for running average you can use very simple multiplier-less design: 


1) for n taps pass your input through n delay stages(registers). 

2) subtract output of delay line from current input 

3) add result to output (feedback), truncate as suitable. 


This is sometimes called IIR implementation of FIR 


you need to make sure that sample rate is taken care of.
0 Kudos
Honored Contributor II

Thank you for quick reply kaz. 

I need to have weighted average, and then it's becoming more complicated, even though if I consider currently used weight coefficients it should be still possible to converge to simple solution similar to what you have proposed. 

Also I was considering that use of Altera FIR in the current project would help me to get familiar with these tools for eventual more complicated tasks in future, but this feature when length of the filter affects the result is really frustrating.
0 Kudos