FIR Filter with a C program example

FIR滤波器,是一种数字信号处理领域较为常见的滤波器,其本质上是一种卷积运算,也就是用系数(也称为阶数),与输入的信号进行卷积操作。其脉冲响应如下图所示:

FIR Impulse Response

另外一种更为常见的形式是下图所示的滤波器结构图,更易于理解数据流的计算过程:

Direct Form FIR Structure

简单的说,完成一个FIR滤波器的示例,需要三个部分,滤波器系数,待滤波的输入信号,以及滤波函数本身。在本例中,我们采用的滤波器阶数为72,待滤波的输入信号长度为200。为了便于验证程序的正确性,同时也为了方便本示例的实现,这里的滤波器系数,参考输入和参考输出,借用了ADI公司提供的库函数,bkfir_flp32,在此对ADI公司表示感谢。

浮点版本的滤波器系数和参考输入输出分别为:

coeff_float[72] = {-7.093663742380000e-04,-7.463516563680000e-04,-7.390480262020000e-04,-6.664798080820000e-04,-4.984659328720000e-04,-2.031871611250000e-04,2.422437673130000e-04,
8.400802821220000e-04,1.561480226335000e-03,2.339779283806000e-03,3.069686418967000e-03,3.613860888962000e-03,3.817265443125000e-03,3.528429181475000e-03,2.625479445696000e-03,
1.043714336973000e-03,-1.199228199290000e-03,-3.984748953470000e-03,-7.084965801936000e-03,-1.016746465379000e-02,-1.281442058762500e-02,-1.455558454434300e-02,-1.491272846799500e-02,
-1.345139439519800e-02,-9.834450014237999e-03,-3.871222777731000e-03,4.443997134321000e-03,1.490948569454300e-02,2.711350813782600e-02,4.045339193788000e-02,5.417557224990200e-02,
6.743346686731100e-02,7.935784759851600e-02,8.913274201048700e-02,9.606904167963699e-02,9.966803476930500e-02,9.966803476930500e-02,9.606904167963699e-02,8.913274201048700e-02,
7.935784759851600e-02,6.743346686731100e-02,5.417557224990200e-02,4.045339193788000e-02,2.711350813782600e-02,1.490948569454300e-02,4.443997134321000e-03,-3.871222777731000e-03,
-9.834450014237999e-03,-1.345139439519800e-02,-1.491272846799500e-02,-1.455558454434300e-02,-1.281442058762500e-02,-1.016746465379000e-02,-7.084965801936000e-03,-3.984748953470000e-03,
-1.199228199290000e-03,1.043714336973000e-03,2.625479445696000e-03,3.528429181475000e-03,3.817265443125000e-03,3.613860888962000e-03,3.069686418967000e-03,2.339779283806000e-03,
1.561480226335000e-03,8.400802821220000e-04,2.422437673130000e-04,-2.031871611250000e-04,-4.984659328720000e-04,-6.664798080820000e-04,-7.390480262020000e-04,-7.463516563680000e-04,
-7.093663742380000e-04,};
input_float[200] = {4.994242052975361e-01,8.814603189945307e-01,1.057458993083499e+00,9.892121207948544e-01,6.983055607507846e-01,2.608322153487866e-01,-2.112401130453833e-01,-5.974842886936822e-01,
-7.985005442392729e-01,-7.602549438680772e-01,-4.873107024895226e-01,-4.171287177179128e-02,4.722005399799706e-01,9.333422472829028e-01,1.233520183436078e+00,1.303924807239500e+00,
1.131974204764305e+00,7.643927185168465e-01,2.957693489511733e-01,-1.546027685807193e-01,-4.719353069121000e-01,-5.740507414847038e-01,-4.315040677229087e-01,-7.479374245895209e-02,
4.131036412530023e-01,9.170471746703777e-01,1.317920418204734e+00,1.521793553615754e+00,1.482918992316557e+00,1.214930313552152e+00,7.875026424751017e-01,3.092921246973268e-01,
-9.866849039568926e-02,-3.326044678610882e-01,-3.314083182304666e-01,-9.160257480020306e-02,3.318072931585325e-01,8.387986547735036e-01,1.308819288920011e+00,1.630301341627150e+00,
1.727975624005695e+00,1.581298758506915e+00,1.229481565989473e+00,7.618875696085654e-01,2.961523971669739e-01,-5.061878413880461e-02,-1.905239275742820e-01,-8.638679370562552e-02,
2.391398406268461e-01,7.091192347101235e-01,1.211166375971531e+00,1.624962677722941e+00,1.851713125448903e+00,1.838333735289451e+00,1.590447391716533e+00,1.171006230484374e+00,
6.848778559290868e-01,2.531692245587993e-01,-1.642539593493331e-02,-5.599253812563554e-02,1.459721168617825e-01,5.417463541264740e-01,1.036064797282263e+00,1.509442541530916e+00,
1.847428608963023e+00,1.968626960225532e+00,1.844624541864496e+00,1.506947288555340e+00,1.039341008477284e+00,5.572670604923091e-01,1.796329966398132e-01,-3.205052514293483e-04,
6.215147555693934e-02,3.523427111806405e-01,7.996961869675921e-01,1.295078722684968e+00,1.717500423377123e+00,1.963737106514054e+00,1.973603102193718e+00,1.744686763520854e+00,
1.332940920318944e+00,8.389837125144647e-01,3.834638369410669e-01,7.752165428244218e-02,-4.421692667125443e-03,1.571150233761032e-01,5.219036628517262e-01,9.998562422430320e-01,
1.473081924360673e+00,1.824751155412314e+00,1.967700001292227e+00,1.865771343801257e+00,1.542667867492200e+00,1.076149317016819e+00,5.789947385532231e-01,1.713908123616581e-01,
-4.849342458089656e-02,-2.854113197130359e-02,2.245530010481142e-01,6.469225731217529e-01,1.133166953178112e+00,1.562157826796754e+00,1.826696463541093e+00,1.859760571548002e+00,
1.650914593632992e+00,1.248865631734710e+00,7.495392198793370e-01,2.725944119270668e-01,-6.787189071628930e-02,-1.912587695390298e-01,-7.019410202467269e-02,2.627649229975080e-01,
7.231041071450387e-01,1.195045463428747e+00,1.559894933685155e+00,1.725104092114789e+00,1.646930515834505e+00,1.341148772909314e+00,8.791896039078280e-01,3.706525594489344e-01,
-6.352639058824883e-02,-3.206827716740221e-01,-3.415579935202170e-01,-1.248064388435111e-01,2.726765886893947e-01,7.496863498268888e-01,1.185488674300654e+00,1.469381474623917e+00,
1.527800078916849e+00,1.342330051311567e+00,9.542173326333285e-01,4.542714609646815e-01,-3.936608483014209e-02,-4.101453344334511e-01,-5.716415998008052e-01,-4.887135110172740e-01,
-1.861050898900904e-01,2.576142256418685e-01,7.292879121977681e-01,1.108878831713794e+00,1.298860331209747e+00,1.248096004561207e+00,9.643615170253623e-01,5.124427124231471e-01,
-1.724348074118670e-03,-4.569883446621907e-01,-7.466428734715770e-01,-8.045499925740145e-01,-6.213311850360866e-01,-2.466616273495632e-01,2.228939529208793e-01,6.675256232147821e-01,
9.735138344596396e-01,1.061073876010644e+00,9.038919025906195e-01,5.355694317136311e-01,4.139847308315649e-02,-4.625189756405622e-01,-8.576947918165162e-01,-1.052262797350955e+00,
-1.003468848447284e+00,-7.281365880195625e-01,-2.985464803541262e-01,1.752629151618583e-01,5.724381650099186e-01,7.909020362593252e-01,7.723474971439450e-01,5.165152396859126e-01,
8.125908811077237e-02,-4.316167219754183e-01,-9.012808664126266e-01,-1.217456759419627e+00,-1.307420222455723e+00,-1.153803024851557e+00,-7.988433692922290e-01,-3.340426558108164e-01,
1.222390900600328e-01,4.537637036680364e-01,5.748758476275011e-01,4.514762203057054e-01,1.093720327879648e-01,-3.720397343841860e-01,-8.792097363518755e-01,-1.292235376971528e+00,
-1.514215438033578e+00,-1.494973188339234e+00,-1.243339728836423e+00,-8.249901831963971e-01,-3.463625105025201e-01,7.140382379340204e-02,3.221285957349309e-01,3.405890033804361e-01,
1.184900180453670e-01,-2.935031933160400e-01,-7.981683830758766e-01,-1.275528160721228e+00,-1.612223209557774e+00,-1.729265195025653e+00,-1.601374485317729e+00,0.000000000000000e+00,
};
output_float[200] = {-0.000354,-0.000998,-0.001777,-0.002475,-0.002852,-0.002683,-0.001805,-0.000152,0.002222,0.005119,0.008201,0.011007,0.012993,0.013586,0.012266,0.008655,0.002609,-0.005693,
-0.015700,-0.026468,-0.036700,-0.044838,-0.049221,-0.048268,-0.040697,-0.025720,-0.003208,0.026221,0.061195,0.099686,0.139194,0.177005,0.210482,0.237366,
0.256029,0.265659,0.266342,0.259043,0.245481,0.227920,0.208912,0.191018,0.176550,0.167357,0.164682,0.169099,0.180521,0.198284,0.221270,0.248072,
0.277155,0.307020,0.336334,0.364037,0.389402,0.412064,0.432003,0.449505,0.465084,0.479391,0.493121,0.506908,0.521249,0.536441,0.552560,0.569468,
0.586854,0.604310,0.621415,0.637819,0.653309,0.667856,0.681928,0.695691,0.709319,0.722952,0.736658,0.750418,0.764126,0.777617,0.790702,0.803217,
0.815061,0.826218,0.836760,0.846829,0.856603,0.866248,0.875876,0.885522,0.895128,0.904561,0.913641,0.922186,0.930058,0.937192,0.943612,0.949428,
0.954803,0.959917,0.964919,0.969893,0.974835,0.979653,0.984190,0.988264,0.991707,0.994411,0.996352,0.997596,0.998280,0.998585,0.998682,0.998699,
0.998685,0.998598,0.998316,0.997669,0.996476,0.994593,0.991950,0.988563,0.984534,0.980027,0.975225,0.970289,0.965316,0.960317,0.955217,0.949870,
0.944095,0.937728,0.930654,0.922839,0.914343,0.905299,0.895888,0.886290,0.876644,0.867014,0.857374,.847616,0.837577,0.827078,0.815975,0.804186,
0.791721,0.778676,0.765211,0.751513,0.737753,0.724040,0.710403,0.696779,0.683033,0.668992,0.654488,0.639401,0.623690,0.607405,0.590675,0.573678,
0.556602,0.539595,0.522736,0.506014,0.489333,0.472538,0.455454,0.437930,0.419878,0.401298,0.382277,0.362972,0.343571,0.324251,0.305135,0.286264,
0.267590,0.248988,0.230288,0.211322,0.191963,0.172160,0.151953,0.131462,0.110865,0.090350,0.070076,0.050134,0.030524,0.011165,-0.008095,-0.027428,
-0.046989,-0.066877,-0.087102,-0.107588,-0.128184,-0.149600,};

定点版本的滤波器系数和参考输入输出分别为(这里为Q30格式的定点数据):

coeff_fix[72] = {};
input_fix[200] = {};
output_fix[200] = {};

浮点版本的C程序,这里只给出核心的FIR程序段,只需要按照需要准备数据,就可以运行仿真:

    for ( i = 0; i < SIGNAL_LENGTH; i++ ) {
        // calculate output n
        acc_float = 0;
        for ( j = 0; j <= FIR_ORDER; j++ ) {
            acc_float += (coeff_float[j]) * (buffer_float[i+j]);
        }
        output_float[i] = acc_float;
    }

定点版本的C程序,与浮点版本类似,这里也只给出核心的FIR程序段,这里需要注意的是,输入的滤波器系数和待滤波的信号,其数据类型为int32_t,在计算过程中需要保留到64位的结果,防止溢出:

    for ( i = 0; i < SIGNAL_LENGTH; i++ ) {
        // calculate output n
        acc_fix = 0;
        for ( j = 0; j <= FIR_ORDER; j++ ) {
            acc_fix += (int64_t)(coeff_fix[j]) * (int64_t)(buffer_fix[i+j]);
        }
        output_fix[i] = acc_fix;
    }

为了验证程序的正确性,最直接的方法就是比较结果,也可以采用图示的方式,如下图:

FIR Fixpoint Simulation Result

FIR滤波器的实现方式多种多样,不同DSP厂商的实现也与特定的硬件有关,因为FIR的卷积操作不存在数据相关性,如果增加硬件并行度,很容易提高滤波器的执行效率;同时,由于FIR滤波的内循环体是信号和系数的乘累加,TI C2000在实现的时候就增加取数逻辑,可以同时从存储器中获取数据并且完成乘累加操作;而ADI的TS201则通过循环展开+SIMD的形式,将内循环体的执行效率进一步提升,同时TS201支持多发射,也能够极大地提升FIR滤波器的执行效率。

Junning Wu wechat
Welcome To Contact Me with My Personal WeChat ID(Weixin)