LMS自适应滤波器的FPGA实现

简介

数字滤波器简介

​ 滤波器一直以来都是信号处理的重要工具,在通信、医学和图像处理等领域也有着至关重要的作用。随着电子计算机、大规模集成电路及芯片工业的发展,又促使数字滤波器能通过软件计算机模拟实现,再通过大规模集成电路及芯片设计达到硬件实现。数字滤波器通常指的是通过对数字信号进行数学运算和逻辑处理,合理改变滤波参数,完成滤波功能的装置。随着芯片工业及数字信号处理技术的发展,数字滤波器的优势愈发明显。
​ 数字滤波器相较于模拟滤波器,在应对系统外部环境时(如温度、外部信号干扰等),滤波器会因为器件本身的特性差异而产生不同的滤波效果,而数字滤波器具有统一性,只要程序实现的功能相同,产生的滤波效果基本不会有差异;并且数字滤波器还具有高度的灵活性和扩展性,只要改变程序代码,即可获得需要的滤波性能,方便快捷;随着近些年来数字集成电路的高速发展,芯片的性能和价格优势越来越明显,数字滤波器有着优秀的发展潜力。

​ 数字滤波器的主流结构设计方法有两种,按照冲击响应的方式可分为无限冲击响应(IIR)滤波器和有限冲击响应(FIR)滤波器。两种滤波方式都有其各自优势,但在面对线性相位结构系统上,FIR 滤波器结构有着得天独厚的优势。

自适应滤波器简介

​ 在很多信号处理系统中,并没有信号的先验统计特性,不能使用某一固定参数的滤波器来处理,比如信道均衡、回声消除以及其他因素之间的系统模型等,均采用了调整系数的滤波器,称为自适应滤波器。这样的滤波器结合了允许滤波器系数适应于信号统计特性的算法。

  • 自适应滤波器的特点
  1. 没有关于待提取信息的先验统计知识
  2. 直接利用观测数据依据某种判据在观测过程中不断递归更新
  3. 最优化
  • 自适应滤波器分类
  1. 按结构分:横向结构、格型结构
  2. 按算法分:随机梯度、最小二乘
  3. 按处理方式分:成批处理、递归处理
  • 自适应滤波器应用
  1. 噪声抵消
  2. 回音消除
  3. 谱线增强
  4. 通道均衡
  5. 系统辨识

LMS算法简介

​ 最小均方误差算法是B.Widrow和Hoff于 1960 年提出的。由于实现简单且对信号的统计特性变化具有稳健性,LMS算法获得了极为广泛的应用。LMS算法是基于最小均方误差准则(MMSE)的维纳滤波器和最陡下降法提出的。LMS算法使用随机梯度下降的方法实现代价函数最小化,具体地说,每次迭代时权矢量沿着误差性能曲面的梯度估值的负方向按一定比例更新。误差输出
ϵk\epsilon_k ϵk​
可写为:
ϵk=dk−XkT∗Wk\epsilon_k = d_k-X_k^T*W_k ϵk​=dk​−XkT​∗Wk​

理论基础

FIR滤波器

​ 单位脉冲响应长度是有限的滤波器就是 FIR 滤波器。单位取样 h(n)是一个 N 点长的有限长序列,0≤n≤N-1。滤波器的输出 y(n)可表示为输入序列 x(n)与单位取样响应 h(n)的线性卷积。所以该关系表达式为:
y(n)=∑k=0N−1x(n−k)h(k)=x(n)∗h(n)y(n) = \sum_{k=0}^{N-1}x(n-k)h(k) = x(n)*h(n) y(n)=k=0∑N−1​x(n−k)h(k)=x(n)∗h(n)
系统函数为
H(z)=∑n=0N−1h(n)z−n=h(0)+h(1)z−1+h(2)z−2+...+h(N−1)z−(N−1)H(z) = \sum_{n=0}^{N-1}h(n)z^{-n}\\=h(0)+h(1)z^{-1}+h(2)z^{-2}+...+h(N-1)z^{-(N-1)} H(z)=n=0∑N−1​h(n)z−n=h(0)+h(1)z−1+h(2)z−2+...+h(N−1)z−(N−1)
根据系统函数,该函数只有原点上存在极点,系统不存在极点,所以可知道 FIR 滤波系统有着绝对的全局稳定性。FIR 滤波器是由一个抽头延迟线加法器和乘法器集合构成的,每一个乘法器的操作系数就是一个 FIR 滤波器。FIR 滤波器具有严格的线性相位特性,但是当 FIR 滤波器单位取样响应为偶对称的相位特性,和单位取样函数为奇对称的相位特性是不完全相同的。设单位响应不为零的点有 M+1 个,不管是奇对称还是偶对称,系统都具有 M/2 个延迟,但是奇对称会多产生 90°的移相,下图2.1是 FIR 滤波器的线性相位特性:

接下来,介绍 FIR 滤波器的幅度特性,根据奇偶数和奇偶对称再将 FIR 滤波器分为四种情况。在图 2.2 中,a 为偶数的偶对称,b 为奇数的偶对称,c 为偶数的奇对称,d为偶数的奇对称:

如果要想进行 FPGA 实现,必须要结合 FPGA 本身的特点来使用合适的 FIR 滤波器结构,所以得到四种合适的 FPGA 设计结构:

第一种,直接行 FIR 滤波器结构,根据图 2.3 可知道整个运算需要 M+1 个乘法,M个延时和 1 个加法器,对于 FPGA 器件来说,乘法是很消耗资源的。所以一般要对该结构进行对称改进得到对称直接型结构。

第二种是级联型结构,因为 FIR 滤波器系统结构并没有极点,只有零点。由此得到如下公式:
H(z)=∑n=0N−1h(n)z−n=∏k=1Nc(b0k+b1kz−1+b2kz−2)H(z) = \sum_{n=0}^{N-1}h(n)z^{-n}=\prod_{k=1}^{N_c}(b_{0k}+b_{1k}z^{-1}+b_{2k}z^{-2}) H(z)=n=0∑N−1​h(n)z−n=k=1∏Nc​​(b0k​+b1k​z−1+b2k​z−2)
得到结构:

可以知道需要大约 3[Nc]的乘法结构,需要乘法实在过多不易于 FPGA 实现,并且结构不易于改进,所以包括文中在内大量学者都不采用这种结构。

第三种是频率取样型结构,该结构是 FIR 的系统函数在单位元上做 N 等分处理,然后取样,相当于单位取样响应 h(n)的离散傅里叶变换 H(K)。H(K)和系统函数 H(z):
H(z)=(1N)(1−rNz−N)∑k=0N−1H(k)1−rWN−Kz−1H(z) = (\frac{1}{N})(1-r^Nz^{-N})\sum_{k=0}^{N-1}\frac{H(k)}{1-rW_N^{-K}z^{-1}} H(z)=(N1​)(1−rNz−N)k=0∑N−1​1−rWN−K​z−1H(k)​
由此结构为:

该结构有很多不适于文中实现的缺点。首先该结构所乘系数为复数,运算量急剧增加;然后是所有谐振器都在单位圆上,当系数变化时,极点会随之而变化,引发系统振荡;最后是对于文中后续实现的滤波器模块,该结构灵活性很差,不易于改进和实现。

第四种是快速卷积型结构,由于 FIR 滤波器单位取样响应是一个 N 点长的有限长序列,0≤n≤N-1,输入序列 x(n)和单位取样响应 h(n)线性卷积即为输出 y(n),所以得到系统输出函数:
y(n)=∑k=0N−1x(k)h(n−k)=x(n)∗h(n)y(n) = \sum_{k=0}^{N-1}x(k)h(n-k) = x(n)*h(n) y(n)=k=0∑N−1​x(k)h(n−k)=x(n)∗h(n)
取适当卷积 L 点数(L≥N+M-1,M-1≥n,M 点为输入序列 x(n)的长,L 点循环可以表示线性卷积),根据卷积的性质的到结构:

当 N 和 M 很大时,IDFT 和 DFT 都是快速傅里叶计算,计算线性卷积的速度会很快。对于 FIR 滤波器设计方法上,文中直接采用 MATLAB 软件进行 FIR 滤波器单位取样响应的设计方法。

LMS算法

自适应滤波技术即是指能够根据具体环境和噪声特征随时修改滤波参数,使得滤波器可以随时改变以应对输入信号,得出有用信号,得到最好的滤波效果。评判一个自适应滤波系统的好坏主要由:收敛速度,计算复杂度,稳态性等几个方面来衡量。

自适应滤波器的基本结构,如图 2.9 所示。n 时刻,输入信号 x(n)通过 n-1 时刻调整后的滤波器得出输出信号 y(n),输出信号 y(n)和期望信号 d(n)比对得出误差信号 e(n),进而调整 n+1 时刻滤波器的滤波参数,整个过程让输出信号更加趋向于理想信号。

根据图 2.10 横向滤波器结构,可以得到:
X(n)=[x(n),x(n−1),...x(n−M+1)]TW(n)=[w(n),w(n−1),...w(n−M+1)]Te(n)=d(n)−y(n)=d(n)−WT(n)X(n)X(n) = [x(n),x(n-1),...x(n-M+1)]^T\\W(n) = [w(n),w(n-1),...w(n-M+1)]^T\\e(n) = d(n)-y(n)=d(n)-W^T(n)X(n) X(n)=[x(n),x(n−1),...x(n−M+1)]TW(n)=[w(n),w(n−1),...w(n−M+1)]Te(n)=d(n)−y(n)=d(n)−WT(n)X(n)
经典的 LMS 自适应滤波算法为:
y(n)=WH(n)X(n)e(n)=d(n)−y(n)W(n+1)=W(n)+2μX(n)e(n)y(n) = W^H(n)X(n)\\e(n) = d(n)-y(n)\\W(n+1) = W(n)+2\mu X(n)e(n) y(n)=WH(n)X(n)e(n)=d(n)−y(n)W(n+1)=W(n)+2μX(n)e(n)
其中,X(n)为 n 时刻输入信号向量,W(n)为 n 时刻自适应滤波器的抽头权向量,μ 这里定义为步长因子。由经典的 LMS 自适应滤波算法公式可知,权向量W(n)为更新的输入向量 X(n)数据,即为滤波器参数。由于相继输入数据 X(n)和权向量W(n)是相互独立的。所以可知 W(n)权向量的数学期望是:
E[W(n+1)]=E[W(n)]+2μ∗E[e(n)X(n)]=E[W(n)]−2μR{E[W(n)]−W0}E[W(n+1)]\\ = E[W(n)]+2\mu*E[e(n)X(n)]\\= E[W(n)]-2\mu R\lbrace E[W(n)]-W_0\rbrace E[W(n+1)]=E[W(n)]+2μ∗E[e(n)X(n)]=E[W(n)]−2μR{E[W(n)]−W0​}

W0为权相量W(n)的最佳维纳解,E[X(n)XT(n)]为输入向量X(n)的自相关矩阵。W_0为权相量 W(n)的最佳维纳解,E[X(n)X^T(n)]为输入向量 X(n)的自相关矩阵。 W0​为权相量W(n)的最佳维纳解,E[X(n)XT(n)]为输入向量X(n)的自相关矩阵。

当步长因子必须满足
0≤μ<1λmax0\leq\mu<\frac{1}{\lambda_{max}} 0≤μ<λmax​1​
时,自适应算法即可收敛。
λmax\lambda_{max} λmax​
为其自相关矩阵的最大特征值。随着迭代次数的进行,权向量 W(n)趋近于最佳的维纳解。

变步长LMS

​ 收敛速度快慢,稳态性,计算复杂度低,易于硬件实现都是决定自适应滤波系统优劣的主要因素。但是对于经典的固定步长的 LMS 算法来说,其收敛速度和稳态性之间有着不可调和的矛盾,若其选用较大的步长因子 μ,收敛速度是会加快,但是收敛后的误差信号不稳定,也就是稳态性不好;同理若是选用较小步长因子 μ,收敛速度会变慢,但是收敛后的稳态性较好。所以针对这种矛盾性,很多学者引入函数模型,使得步长因子 μ 和误差 e 之间达成某种关系,从而调和这种矛盾。即:在算法运行的开始阶段,采用较大的步长因子 μ 用来加快收敛速度,而算法误差越来越小,使用较小的步长因子 μ来保证算法稳态性。

基于 Sigmoid 函数变步长最小均方算法,其步长因子 μ(n)是误差 e(n)的 Sigmoid 函数:
μ(n)=β11+e−α∣e(n)∣−0.5\mu(n) = \beta\frac{1}{1+e^{-\alpha|e(n)|}}-0.5 μ(n)=β1+e−α∣e(n)∣1​−0.5
​ α 控制 Sigmoid 函数的形状,β 决定曲线上升的快慢,控制该函数模型的取值范围。μ(n)随着 e(n)的减小而减小,当 e(n)逐渐接近零时,μ(n)也趋近为零。随着算法的不断收敛,步长的改变也迅速。误差越大,需要加快收敛速度,所以就需要采用越大的步长来加速收敛速度;同理,误差越小,需求系统的稳态性,所以就需要采用较小的误差来确保系统稳态性。

​ 这种改进方法表明变步长因子和误差的关系准则需要满足:当误差比较大时,采用较大的步长,用来加快收敛速度;当误差比较小时,采用较小的步长,用来保证系统的稳态性,从而提高整个算法性能。这样会使自适应滤波算法在开始阶段有较快的收敛速度,达到收敛后又不会有太差的稳定性。

LMS自适应滤波器的FPGA工程实现

FIR滤波器模块

module fir(input                clk_i,input                rst_n_i,input  signed [15:0] data_in,                       //fir_i,input signed [15:0] coef1,      //权值input signed [15:0] coef2,input signed [15:0] coef3,input signed [15:0] coef4,input signed [15:0] coef5,input signed [15:0] coef6,input signed [15:0] coef7,input signed [15:0] coef8,input signed [15:0] coef9,output signed [15:0] data_o                   //fir_o        //输出位宽待设置);//移位寄存器
reg signed [15:0] data_shift1;
reg signed [15:0] data_shift2;
reg signed [15:0] data_shift3;
reg signed [15:0] data_shift4;
reg signed [15:0] data_shift5;
reg signed [15:0] data_shift6;
reg signed [15:0] data_shift7;
reg signed [15:0] data_shift8;
reg signed [15:0] data_shift9;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)begindata_shift1 <= 16'd0;data_shift2 <= 16'd0;data_shift3 <= 16'd0;data_shift4 <= 16'd0;data_shift5 <= 16'd0;data_shift6 <= 16'd0;data_shift7 <= 16'd0;data_shift8 <= 16'd0;data_shift9 <= 16'd0;endelse begindata_shift9 <= data_shift8;data_shift8 <= data_shift7;data_shift7 <= data_shift6;data_shift6 <= data_shift5;data_shift5 <= data_shift4;data_shift4 <= data_shift3;data_shift3 <= data_shift2;data_shift2 <= data_shift1;data_shift1 <= data_in    ;end
end//乘法器//单独fir时固定的权值数据
//parameter signed COEF1 = 16'h2FB1;           //14'h304F;
//parameter signed COEF2 = 16'h2E51;           //14'h31AF;
//parameter signed COEF3 = 16'h19DC;           //14'h19DC;
//parameter signed COEF4 = 16'h4926;           //14'h4926;
//parameter signed COEF5 = 16'h6927;           //14'h6927;
//parameter signed COEF6 = 16'h4926;           //14'h4926;
//parameter signed COEF7 = 16'h19DC;           //14'h19DC;
//parameter signed COEF8 = 16'h2E51;           //14'h31AF;
//parameter signed COEF9 = 16'h2FB1;           //14'h304F;reg signed [31:0] multi_data1;
reg signed [31:0] multi_data2;
reg signed [31:0] multi_data3;
reg signed [31:0] multi_data4;
reg signed [31:0] multi_data5;
reg signed [31:0] multi_data6;
reg signed [31:0] multi_data7;
reg signed [31:0] multi_data8;
reg signed [31:0] multi_data9;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)beginmulti_data1 <= 32'd0;multi_data2 <= 32'd0;multi_data3 <= 32'd0;multi_data4 <= 32'd0;multi_data5 <= 32'd0;multi_data6 <= 32'd0;multi_data7 <= 32'd0;multi_data8 <= 32'd0;multi_data9 <= 32'd0;endelse beginmulti_data1 <= data_shift1 * coef1 ;multi_data2 <= data_shift2 * coef2 ;multi_data3 <= data_shift3 * coef3 ;multi_data4 <= data_shift4 * coef4 ;multi_data5 <= data_shift5 * coef5 ;multi_data6 <= data_shift6 * coef6 ;multi_data7 <= data_shift7 * coef7 ;multi_data8 <= data_shift8 * coef8 ;multi_data9 <= data_shift9 * coef9 ;end
end//加法树
reg signed [40:0] adder_data_one_1;
reg signed [40:0] adder_data_one_2;
reg signed [40:0] adder_data_one_3;
reg signed [40:0] adder_data_one_4;
reg signed [40:0] adder_data_one_5;reg signed [40:0] adder_data_two_1;
reg signed [40:0] adder_data_two_2;
reg signed [40:0] adder_data_two_3;reg signed [40:0] adder_data_three_1;
reg signed [40:0] adder_data_three_2;reg signed [40:0] adder_data_four;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)beginadder_data_one_1   <= 40'd0;adder_data_one_2   <= 40'd0;adder_data_one_3   <= 40'd0;adder_data_one_4   <= 40'd0;adder_data_one_5   <= 40'd0;adder_data_two_1   <= 40'd0;adder_data_two_2   <= 40'd0;adder_data_two_3   <= 40'd0;adder_data_three_1 <= 40'd0;adder_data_three_2 <= 40'd0;adder_data_four    <= 40'd0;endelse beginadder_data_one_1   <= multi_data1 + multi_data2;adder_data_one_2   <= multi_data3 + multi_data4;adder_data_one_3   <= multi_data5 + multi_data6;adder_data_one_4   <= multi_data7 + multi_data8;adder_data_one_5   <= multi_data9;adder_data_two_1   <= adder_data_one_1 + adder_data_one_2;adder_data_two_2   <= adder_data_one_3 + adder_data_one_4;adder_data_two_3   <= adder_data_one_5;adder_data_three_1 <= adder_data_two_1 + adder_data_two_2;adder_data_three_2 <= adder_data_two_3;adder_data_four    <= adder_data_three_1 + adder_data_three_2;end
endassign data_o = adder_data_four>>24;
//assign fir_o = adder_data_four>>n;endmodule

误差计算模块

module error_calcu(input                clk_i,input                rst_n_i,input  signed [15:0] data_in,           //滤波完成数据input  signed [15:0] data_ref,          //参考数据output signed [15:0] error_o            //误差输出);wire  signed [15:0] error;//reg signed [15:0] error_o;//延时寄存参考数据reg signed [15:0] data_shift1;reg signed [15:0] data_shift2;reg signed [15:0] data_shift3;reg signed [15:0] data_shift4;reg signed [15:0] data_shift5;reg signed [15:0] data_shift6;reg signed [15:0] data_shift7;reg signed [15:0] data_shift8;reg signed [15:0] data_shift9;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)begindata_shift1 <= 16'd0;data_shift2 <= 16'd0;data_shift3 <= 16'd0;data_shift4 <= 16'd0;data_shift5 <= 16'd0;data_shift6 <= 16'd0;data_shift7 <= 16'd0;data_shift8 <= 16'd0;data_shift9 <= 16'd0;endelse begindata_shift1 <= data_ref   ;data_shift2 <= data_shift1;data_shift3 <= data_shift2;data_shift4 <= data_shift3;data_shift5 <= data_shift4;data_shift6 <= data_shift5;data_shift7 <= data_shift6;data_shift8 <= data_shift7;data_shift9 <= data_shift8;endendassign error = data_shift9 - data_in;
assign error_o = error;
//ssign error_o = data_shift9 - data_in;endmodule

系数更新模块

module coef_update(                     //系数更新模块input               clk_i,input               rst_n_i,input signed [15:0] error_o,          //误差input signed [15:0] data_in,        //待滤波数据//权值更新output signed [15:0] coef1,output signed [15:0] coef2,output signed [15:0] coef3,output signed [15:0] coef4,output signed [15:0] coef5,output signed [15:0] coef6,output signed [15:0] coef7,output signed [15:0] coef8,output signed [15:0] coef9);reg signed [15:0] coef1;reg signed [15:0] coef2;reg signed [15:0] coef3;reg signed [15:0] coef4;reg signed [15:0] coef5;reg signed [15:0] coef6;reg signed [15:0] coef7;reg signed [15:0] coef8;reg signed [15:0] coef9;reg signed [15:0] mu;           //遗忘因子(步长)//延时寄存输入数据reg signed [15:0] data_shift1;reg signed [15:0] data_shift2;reg signed [15:0] data_shift3;reg signed [15:0] data_shift4;reg signed [15:0] data_shift5;reg signed [15:0] data_shift6;reg signed [15:0] data_shift7;reg signed [15:0] data_shift8;reg signed [15:0] data_shift9;always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)begindata_shift1 <= 16'd0;data_shift2 <= 16'd0;data_shift3 <= 16'd0;data_shift4 <= 16'd0;data_shift5 <= 16'd0;data_shift6 <= 16'd0;data_shift7 <= 16'd0;data_shift8 <= 16'd0;data_shift9 <= 16'd0;mu          <= 16'd383;             //步长不知道是多少,随便写了一个;endelse begindata_shift1 <= data_in   ;data_shift2 <= data_shift1;data_shift3 <= data_shift2;data_shift4 <= data_shift3;data_shift5 <= data_shift4;data_shift6 <= data_shift5;data_shift7 <= data_shift6;data_shift8 <= data_shift7;data_shift9 <= data_shift8;endend    //权值更新//mu*error*data_in*2reg signed [47:0] coef1_reg;reg signed [47:0] coef2_reg;reg signed [47:0] coef3_reg;reg signed [47:0] coef4_reg;reg signed [47:0] coef5_reg;reg signed [47:0] coef6_reg;reg signed [47:0] coef7_reg;reg signed [47:0] coef8_reg;reg signed [47:0] coef9_reg;
always @(posedge clk_i or negedge rst_n_i) beginif(!rst_n_i)begincoef1 <= 16'd0;coef2 <= 16'd0;coef3 <= 16'd0;coef4 <= 16'd0;coef5 <= 16'd0;coef6 <= 16'd0;coef7 <= 16'd0;coef8 <= 16'd0;coef9 <= 16'd0;coef1_reg <= 16'd0;coef2_reg <= 16'd0;coef3_reg <= 16'd0;coef4_reg <= 16'd0;coef5_reg <= 16'd0;coef6_reg <= 16'd0;coef7_reg <= 16'd0;coef8_reg <= 16'd0;coef9_reg <= 16'd0;endelse begincoef1_reg <= (mu * error_o * data_shift1)>>2;coef2_reg <= (mu * error_o * data_shift2)>>2;coef3_reg <= (mu * error_o * data_shift3)>>2;coef4_reg <= (mu * error_o * data_shift4)>>2;coef5_reg <= (mu * error_o * data_shift5)>>2;coef6_reg <= (mu * error_o * data_shift6)>>2;coef7_reg <= (mu * error_o * data_shift7)>>2;coef8_reg <= (mu * error_o * data_shift8)>>2;coef9_reg <= (mu * error_o * data_shift9)>>2;coef1 <= coef1 + coef1_reg;coef2 <= coef2 + coef2_reg;coef3 <= coef3 + coef3_reg;coef4 <= coef4 + coef4_reg;coef5 <= coef5 + coef5_reg;coef6 <= coef6 + coef6_reg;coef7 <= coef7 + coef7_reg;coef8 <= coef8 + coef8_reg;coef9 <= coef9 + coef9_reg;end
endendmodule

顶层模块

module lsm_top((* io_buffer_type = "none" *)input clk_i,(* io_buffer_type = "none" *)input rst_n_i,(* io_buffer_type = "none" *)input signed [15:0] data_in,        //输入待滤波数据(* io_buffer_type = "none" *)input signed [15:0] data_ref,       //参考数据(* io_buffer_type = "none" *)output signed [15:0] error_o,         //误差(* io_buffer_type = "none" *)output signed [15:0] data_o         //输出数据);wire signed [15:0] coef1;wire signed [15:0] coef2;wire signed [15:0] coef3;wire signed [15:0] coef4;wire signed [15:0] coef5;wire signed [15:0] coef6;wire signed [15:0] coef7;wire signed [15:0] coef8;wire signed [15:0] coef9;fir fir_dut (.clk_i (clk_i ),.rst_n_i (rst_n_i ),.data_in (data_in ),.coef1 (coef1 ),.coef2 (coef2 ),.coef3 (coef3 ),.coef4 (coef4 ),.coef5 (coef5 ),.coef6 (coef6 ),.coef7 (coef7 ),.coef8 (coef8 ),.coef9 (coef9 ),.data_o(data_o));error_calcu error_calcu_dut (.clk_i (clk_i ),.rst_n_i (rst_n_i ),.data_in (data_in ),.data_ref (data_ref ),.error_o  ( error_o));coef_update coef_update_dut (.clk_i (clk_i ),.rst_n_i (rst_n_i ),.error_o (error_o ),.data_in (data_in ),.coef1 (coef1 ),.coef2 (coef2 ),.coef3 (coef3 ),.coef4 (coef4 ),.coef5 (coef5 ),.coef6 (coef6 ),.coef7 (coef7 ),.coef8 (coef8 ),.coef9 (coef9 ));endmodule

LMS自适应滤波器的FPGA实现相关推荐

  1. 基于LMS自适应滤波器的QPSK信号均衡器matlab仿真

    目录 1.算法概述 2.仿真效果 3.MATLAB仿真源码 1.算法概述 在自适应滤波器设计中,最小均方(Least Mean Square,LMS)算法使用随机梯度下降的方法实现代价函数的最小化,具 ...

  2. lms自适应滤波器实现噪声干扰的语音恢复_ZLG深度解析语音识别技术

    语音识别已成为人与机器通过自然语言交互重要方式之一,本文将从语音识别的原理以及语音识别算法的角度出发为大家介绍语音识别的方案及详细设计过程. 语言作为人类的一种基本交流方式,在数千年历史中得到持续传承 ...

  3. LMS自适应滤波器算法及其改进

    -- 年初DSP课程期末设计时为了答辩做的PPT,内容背的滚瓜烂熟,给老师留下了深刻的印象,想必整个系也没有第二个人像我这么上心了,因此最后决定把PPT放到博客上:此外因为不希望PPT上有太多字,所以 ...

  4. 基于Simulink的RBF神经网络的LMS自适应滤波器设计仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 LMS(Least Mean Square), 由 Widrow 和 Hoff 于1960年提出,也 ...

  5. lms自适应滤波器matlab_自适应回声消除器简介

    本文介绍了一种基于最小均方(LMS)算法的基本声学回声消除器.声学回声消除器对于许多现代通信产品是必需的.我确定你曾经遇到过在电话讲话时听到声音的时候,对吗?嗯,这是声学回声的一个例子.声学回声是一个 ...

  6. lms自适应滤波器实现噪声干扰的语音恢复_使用VoiceFliter-Lite改进设备上的语音识别...

    作者 / Wang Quan 原文链接 / https://ai.googleblog.com/2020/11/improving-on-device-speech-recognition.html ...

  7. 自适应滤波器更新算法-EP2

    文章目录 1.变步长 SC-MPNLMS 频域分块算法 1.1 算法原理 1.2 算法代码 1.3 算法优缺点 2.集成多种自适应滤波算法的回声消除器 1.1 算法原理 1.2 算法代码 1.3算法优 ...

  8. 信号处理学习笔记6——自适应滤波器4-递归最小二乘(RLS)自适应滤波器

        前面学习的LMS自适应滤波器的核心思想是最速下降法,并根据当前输入信号和期望输出对代价函数的瞬时梯度进行估计.但LMS只使用了当前时刻的输入和期望信号,没有充分利用过去的信息.这就导致LMS自 ...

  9. 传统语音增强——最小均方(LMS)自适应滤波算法

    一.语音降噪的意义 语音降噪主要研究如何利用信号处理技术消除信号中的强噪声干扰,从而提高输出信噪比以提取出有用信号的技术.消除信号中噪声污染的通常方法是让受污染的信号通过一个能抑制噪声而让信号相对不变 ...

  10. lms c语言,LMS算法实现自适应滤波器(C语言版)

    上次只是发表了MATLAB版本的LMS算法,这次将C语言版的LMS算法一并发表,其中涉及到雅克比公式求矩阵最大特征值的部分我将后续发表到博客中,此C语言版本是本人自己研究MATLAB语言,然后独自翻译 ...

最新文章

  1. Android编程获取网络连接状态(3G/Wifi)及调用网络配置界面
  2. 如何在IDEA中使用git
  3. 计算机nit题百度云,计算机NIT应用基础试题
  4. Android彻底组件化方案实践
  5. VS2005 Extjs智能提示插件
  6. SC2012 Orchestrator - 文档及资源链接
  7. 报名啦!旷视研究院解读COCO 2017物体检测夺冠算法 | 吃瓜社
  8. Vue源码:mustache模板引擎学习
  9. a 算法 c语言实现,a最短路径算法地C语言实现.PDF
  10. Protel99SE
  11. 机器学习丨如何理解正定矩阵和半正定矩阵
  12. linux 使用rpm命令安装和卸载软件的使用方法
  13. ma2灯光控制台 linux,MA2灯光控制台简易教程.pdf
  14. TPP是也只是一种挑战
  15. 电脑键盘按键都代表着什么意思?
  16. 世嘉土星模拟器GIRI GIRI Loader的使用教程
  17. mybatis-plus自动填充(创建时间\修改时间)
  18. vscode上利用screen命令跑代码
  19. ubuntu16.04上搭建stm32f4开发环境
  20. 计算机防火墙打不开0x6d9,win7防火墙出现0x6d9该怎么办

热门文章

  1. 美观!!大气!!! LVGL『Color picker颜色选择器控件』介绍
  2. 中国地区城市php,中国城市列表
  3. 如何不打开excel文件搜索其中内容---在线绿色工具
  4. [转]sourceforge文件下载过慢
  5. 基于React的可编辑在线简历模板
  6. 程序员如何财务自由【原创】
  7. 采用qt技术,开发OFD电子文档阅读器
  8. 鼠标移入移出时定时器加速的原因_2020年值得购买的鼠标有哪些?
  9. 直接sql 添加字段赋值
  10. Idea终端中无法使用maven命令问题解决