自适应滤波算法的FPGA实现思路
1、原理简介
参考相关论文,自适应滤波器主要由FIR滤波器本体、参数自适应计算两部分组成。参数自适应计算部分是用来迭代计算滤波器系数的,它的输入是期望估计误差f、原始数据采样保存的向量U,输出是可变的FIR滤波器系数。FIR滤波器就是传统的有限冲击响应滤波器,可以是低通、高通等类型。所谓滤波器系数可变,指的是自适应算法根据动态变化的期望估计误差f和输入向量U,不停地进行迭代和更新FIR滤波器系数。有了自适应算法,FIR滤波器对动态误差的响应会更快,理论上噪声抑制效果也更好。
图1 自适应滤波器架构
自适应算法有很多种,其中LMS最小均方差自适应滤波算法计算量比较小,所以我选择它用在自己的项目里。
LMS自适应算法公式:
![]()
公式里的
就是需要不断迭代的滤波器系数,M维向量;c和r都是常数;UT表示U的转置也是M维的向量;其他符号在图里面已经比较清楚。这是一种可变更新步长的算法,因为UTU是变化的。
如果用固定步长算法,那么公式就是:
![]()
这里面的h就是步长,相当于是一个固定的系数。
可变步长算法的好处是收敛快,滤波器延时更小。
2、实现流程
明白了原理,下面再设计滤波器的verilog实现方案。
分析前面第1个公式,有加法、乘法、除法,还有M维的向量。做过FPGA算法的开发者应该有体会,向量和矩阵计算在verilog里面不太好实现,一般会把它转化成单个元素的计算,不然会占用太多资源,换种说法就是要把并行计算架构转成流水线形式的计算架构。这里面还需要关注的是参数向量B(n)和输入向量U(n):如何表示这两个动态变化的向量,还有就是如何计算
。
我选择用FIFO表示前面提到的几个M维向量,需要计算时就读FIFO中的数据,计算完成之后更新FIFO。至于
,手动推导后可以看出它其实就是向量各元素的平方和,因此也可以用FIFO通过不断缓存
以及动态累加的方式实现。
基于FIFO的自适应算法架构如下图所示。

图片画的不太简洁,用文字描述一下在FPGA中实现的过程。
第一步:系统复位后先对FIFOA1和FIFOB1初始化,也就是先缓存得到一组向量B和向量U。
第二步:初始化结束后,等待输入数据(滤波前)u和滤波后数据u1更新,然后FIFOCtrlB模块读FIFOA1的数据并参与计算流水线,动态累加模块读FIFOC以及新输入数据完成累加值更新并参与计算流水线,FIFOCTRLU模块读FIFOB1数据参与计算流水线。
第三步:计算流水线完成乘法、加法全部计算过程,得到一个新的参数B(n+1),FIFOCtrlB把这个新参数写入FIFOA2,以供下一轮计算使用,同时FIFOCTRLU模块把上一步参与计算流水线的数据写入FIFOB2,也是为了下一轮次计算使用。直到FIFOA1中的参数读完了也就是计算完了,与此同时FIFOB1也被读空了,相应的FIFOA2、FIFOB2也都写完成了,这一轮计算结束。
下一轮计算时,FIFOA1和FIFOA2互换读写次序,FIFOB1、FIFOB2互换读写次序。循环往复。
由于和都是常数,因此代入常数后就省掉了除法器,用乘法代替。
自适应算法是滤波器最核心最难的部分,把这部分的输出直接接入FIR滤波器,就可以实现了自适应FIR滤波。至于FIR滤波器,用IP核就可以,不需要自行设计。当然也可以自己用逻辑和加法器、乘法器搭建FIR滤波器,这样可控性更好,不然还要去理解FIR的IP核的接口和参数的含义,也挺费事的。
目前已经按照这个流程写好了verilog逻辑,后面会仿真测试,与MATLAB计算的结果比较一下,验证设计是否正确。
本文来自博客园,作者:不高工程师,转载请注明原文链接:https://www.cnblogs.com/y0011/p/19394755/bugao123
浙公网安备 33010602011771号