FPGA实现级联型IIR滤波器

FPGA实现级联型IIR滤波器

MATLAB仿真级联型IIR滤波器系数及运算字长的量化性能_小小低头哥的博客-CSDN博客上回使用MATLAB仿真了级联型IIR滤波器系数及运算字长,这次就叙述如何使用FPGA实现级联型IIR滤波器

  由于IIR滤波器具有反馈结构,必须通过仿真确定IIR滤波器输出的范围,以进一步确定输出数据位数。

1.级联型IIR滤波器实现方法

  上回使用MATLAB将8级IIR滤波器等效为3个3级IIR滤波器和一个2级IIR滤波器的级联,并最终进行了量化,根据级联型结构可以直接写出IIR滤波器的差分方程。如下
2048 y 1 ( n ) = 30 [ x ( n ) + x ( n − 2 ) ] + 40 x ( n − 1 ) − [ − 707 y 1 ( n − 1 ) + 212 y 1 ( n − 2 ) ] . . . . . . ( 1 ) 2048y_1(n)=30[x(n)+x(n-2)]+40x(n-1)-[-707y_1(n-1)+212y_1(n-2)]......(1) 2048y1(n)=30[x(n)+x(n2)]+40x(n1)[707y1(n1)+212y1(n2)]......(1)

2048 y 2 ( n ) = 2048 [ y 1 ( n ) + y 1 ( n − 2 ) ] + 988 y 1 ( n − 1 ) − [ − 1099 y 2 ( n − 1 ) + 699 y 2 ( n − 2 ) ] . . . . . . ( 2 ) 2048y_2(n)=2048[y_1(n)+y_1(n-2)]+988y_1(n-1)-[-1099y_2(n-1)+699y_2(n-2)]......(2) 2048y2(n)=2048[y1(n)+y1(n2)]+988y1(n1)[1099y2(n1)+699y2(n2)]......(2)

1024 y 3 ( n ) = 1024 [ y 2 ( n ) + x ( n − 2 ) ] + 52 y 2 ( n − 1 ) − [ − 805 y 3 ( n − 1 ) + 743 y 3 ( n − 2 ) ] . . . . . . ( 3 ) 1024y_3(n)=1024[y_2(n)+x(n-2)]+52y_2(n-1)-[-805y_3(n-1)+743y_3(n-2)]......(3) 1024y3(n)=1024[y2(n)+x(n2)]+52y2(n1)[805y3(n1)+743y3(n2)]......(3)

2048 y ( n ) = 2048 [ y 3 ( n ) + y 3 ( n − 1 ) ] − [ − 276 y ( n − 1 ) ] . . . . . . ( 4 ) 2048y(n)=2048[y_3(n)+y_3(n-1)]-[-276y(n-1)]......(4) 2048y(n)=2048[y3(n)+y3(n1)][276y(n1)]......(4)

也就是前一个滤波器的输出是后一个滤波器的输入

2.分析各级滤波器的输出数据范围并确定输出数据位数

  由于整个IIR滤波器由4个IIR滤波器级联而成,因此需要分别仿真出各级滤波器的输出数据范围并确定各级滤波器的输出数据范围。仍然由MATLAB实现。代码如下

clear all
%My_E5_54_MatlabSim.M
%求直接型IIR滤波器的系数
[b,a] = cheby2(7,60,0.5);
%求分解出来的每个二阶IIR滤波器的分子分母系数
[b0,B,A]=My_E5_51_dir2cas(b,a);
%量化每个二阶IIR滤波器的分子分母系数
[Qb1,Qa1]=E5_52_Qcoe(b0*B(1,:),A(1,:),12);
[Qb2,Qa2]=E5_52_Qcoe(B(2,:),A(2,:),12);
[Qb3,Qa3]=E5_52_Qcoe(B(3,:),A(3,:),12);
[Qb4,Qa4]=E5_52_Qcoe(B(4,:),A(4,:),12);
%获取测试输入数据
[Q_s,Q_noise]=E5_53_NoiseAndCarrier;
%对级联型滤波器进行滤波
%对白噪声进行滤波
N1 = filter(Qb1,Qa1,Q_noise);
N2 = filter(Qb2,Qa2,N1);%级联型:上一级的输出是这一级的输入
N3 = filter(Qb3,Qa3,N2);
Nout = filter(Qb4,Qa4,N3);%得到最终滤波结果
%对合成单频信号进行滤波
S1 = filter(Qb1,Qa1,Q_s);
S2 = filter(Qb2,Qa2,S1);%级联型:上一级的输出是这一级的输入
S3 = filter(Qb3,Qa3,S2);
Sout = filter(Qb4,Qa4,S3);%得到最终滤波结果
%求取每级滤波器输出数据位宽
QN1 = ceil(log2(max(abs(N1)))+1);%计算N1所需的位数,+1是因为是有符号数
if 2^(QN1-1) == max(abs(N1)) %如果除去符号位的最大值刚好等于2的整数冥
    QN1 = QN1 + 1;%那么此时要加一了,比如N1=[-612,1024],则需要12位表示
end       %第11位的值表示1024(10位的表示范围是1024-1),第12位为符号位
QN2 = ceil(log2(max(abs(N2)))+1);
if 2^(QN2-1) == max(abs(N2)) 
    QN2 = QN2 + 1;
end
QN3 = ceil(log2(max(abs(N3)))+1);
if 2^(QN3-1) == max(abs(N3)) 
    QN3 = QN3 + 1;
end   
QNout = ceil(log2(max(abs(Nout)))+1);
if 2^(QNout-1) == max(abs(Nout)) 
    QNout = QNout + 1;
end   
QS1 = ceil(log2(max(abs(S1)))+1);
if 2^(QS1-1) == max(abs(S1)) 
    QS1 = QS1 + 1;
end   
QS2 = ceil(log2(max(abs(S2)))+1);
if 2^(QS2-1) == max(abs(S2)) 
    QS2 = QS2 + 1;
end   
QS3 = ceil(log2(max(abs(S3)))+1);
if 2^(QS3-1) == max(abs(S3)) 
    QS3 = QS3 + 1;
end   
QSout = ceil(log2(max(abs(Sout)))+1);
if 2^(QSout-1) == max(abs(Sout)) 
    QSout = QSout + 1;
end   
if QN1>QS1  %保证同一级滤波器的输出位宽相同 取最大的位宽
    QS1 = QN1;
else 
    QN1 = QS1;
end
if QN2>QS2 
    QS2 = QN2;
else 
    QN2 = QS2;
end
if QN3>QS3  
    QS3 = QN3;
else 
    QN3 = QS3;
end
if QNout>QSout  
    QSout = QNout;
else 
    QNout = QSout;
end
%求幅频响应
FNin = 20*log10(abs(fft(Q_noise))); %输入噪声的幅频响应
FNin = FNin - max(FNin);
FNout = 20*log10(abs(fft(Nout)));   %滤波后噪声的幅频响应
FNout = FNout - max(FNout);
FSin = 20*log10(abs(fft(Q_s)));     %输入单频合成信号的幅频响应
FSin = FSin - max(FSin);
FSout = 20*log10(abs(fft(Sout)));  %滤波后单品合成信号的幅频响应
FSout = FSout - max(FSout);
%设置幅频响应的横坐标单位为Hz
fs = 2000;  %采样频率为2000HZ
x_f = [0:fs/length(FSout):fs/2];
FNin = FNin(1:length(x_f));
FNout = FNout(1:length(x_f));
FSin = FSin(1:length(x_f));
FSout = FSout(1:length(x_f));

subplot(211);
plot(x_f,FNout,'-',x_f,FNin,'--');
xlabel('频率(Hz)');ylabel('幅度(dB)');title('Matlab仿真白噪声信号滤波前后的频谱');
legend('输出信号频谱','输入信号频谱');
grid;
subplot(212);
plot(x_f,FSout,'-',x_f,FSin,'--');
xlabel('频率(Hz)');ylabel('幅度(dB)');title('Matlab仿真合成单频信号滤波前后的频谱');
legend('输出信号频谱','输入信号频谱');
grid;

最后仿真结果,得到第1级IIR滤波器输出数据的位数为8比特,第2级为9比特,第3级为11比特,第4级为12比特。

3.编写Verilog HDL程序,实现级联型IIR滤波器

  每个IIR滤波器的实现方法与直接型IIR滤波器的实现方法完全相同,需要注意的是根据仿真结果对IIR滤波器输出数据进行截尾即可。

由于级联型IIR滤波器阶数小。故其零极点系数的实现代码编写在同一个文件中。

顶层文件:

module Cascade_Filter_IIR(
    input   rst,    //复位信号
    input   clk,    //时钟信号  
    input   signed[11:0] din,   //输入数据
    
    output  signed[11:0] dout   //滤波后的输出数据 仿真结果位12比特
);

//实例化第一级IIR滤波器运算模块
wire signed [7:0] Y1;
FirstTap U1(
    .rst    (rst),    
    .clk    (clk),        
    .Xin    (din),   
    .Yout   (Y1)
);
//实例化第2级IIR滤波器运算模块
wire signed [8:0] Y2;
SecondTap U2(
    .rst    (rst),    
    .clk    (clk),        
    .Xin    (Y1),   
    .Yout   (Y2)
);
//实例化第3级IIR滤波器运算模块
wire signed [10:0] Y3;
ThirdTap U3(
    .rst    (rst),    
    .clk    (clk),        
    .Xin    (Y2),   
    .Yout   (Y3)
);
//实例化第4级IIR滤波器运算模块
FourthTap U4(
    .rst    (rst),    
    .clk    (clk),        
    .Xin    (Y3),   
    .Yout   (dout)
);
endmodule

各级滤波器实现代码类似,仅仅系数不同,因此只给出第一级代码

//这是FirstTap.v文件的程序清单
module FirstTap (
	rst,clk,Xin,
	Yout);
	
	input		rst;   //复位信号,高电平有效
	input		clk;   //FPGA系统时钟,频率为2kHz
	input	 signed [11:0]	Xin;  //数据输入频率为2kHZ
	output signed [7:0]	Yout; //滤波后的输出数据
	
	//零点系数的实现代码/
	//将输入数据存入移位寄存器中
	reg signed[11:0] Xin1,Xin2;
	always @(posedge clk or posedge rst)
		if (rst)
			//初始化寄存器值为0
			begin
				Xin1 <= 12'd0;
				Xin2 <= 12'd0;
		   end	
		else
		   begin
				Xin1 <= Xin;
				Xin2 <= Xin1;
			end
			
   //采用移位运算及加法运算实现乘法运算
	wire signed [23:0] XMult0,XMult1,XMult2;
	assign XMult0 = {{7{Xin[11]}},Xin,5'd0}-{{11{Xin[11]}},Xin,1'd0};      //*30
	assign XMult1 = {{7{Xin1[11]}},Xin1,5'd0}+{{9{Xin1[11]}},Xin1,3'd0};   //*40
	assign XMult2 = {{7{Xin2[11]}},Xin2,5'd0}-{{11{Xin2[11]}},Xin2,1'd0};  //*30
 
	//对滤波器系数与输入数据乘法结果进行累加
	wire signed [23:0] Xout;
	assign Xout = XMult0 + XMult1 + XMult2;
	
	
	//极点系数的实现代码///
	wire signed[7:0] Yin;
	reg signed[7:0] Yin1,Yin2;
	always @(posedge clk or posedge rst)
		if (rst)
			//初始化寄存器值为0
			begin
				Yin1 <= 9'd0;
				Yin2 <= 9'd0;
			end
		else
		   begin
				Yin1 <= Yin;
				Yin2 <= Yin1;
			end
			
	//采用移位运算及加法运算实现乘法运算
	wire signed [23:0] YMult1,YMult2;
	wire signed [23:0] Ysum,Ydiv;
	assign YMult1 = {{7{Yin1[7]}},Yin1,9'd0}+{{9{Yin1[7]}},Yin1,7'd0}+{{10{Yin1[7]}},Yin1,6'd0}+
	                {{15{Yin1[7]}},Yin1,1'd0}+{{16{Yin1[7]}},Yin1};  //*707
	assign YMult2 = {{9{Yin2[7]}},Yin2,7'd0}+{{10{Yin2[7]}},Yin2,6'd0}+{{12{Yin2[7]}},Yin2,4'd0}-
	                {{14{Yin2[7]}},Yin2,2'd0};  //*212


	//第一级IIR滤波器实现代码///
	assign Ysum = Xout+YMult1-YMult2;	
	assign Ydiv = {{11{Ysum[23]}},Ysum[23:11]};//2048
	//根据仿真结果可知,第一级滤波器的输出范围可用9位表示
   assign Yin = (rst ? 8'd0 : Ydiv[7:0]);
	//增加一级寄存器,提高运行速度
	reg signed [7:0] Yout_reg ;
	always @(posedge clk)
		Yout_reg <= Yin;
	assign Yout = Yout_reg;
	
endmodule

整个文件的RTL如下图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4znGvmUy-1688129590034)(C:/Users/lenovo/AppData/Roaming/Typora/typora-user-images/image-20230630202407094.png)]

图1 RTL视图 

4.级联型IIR滤波器FPGA实现后的测试仿真

  级联型IIR滤波器FPGA实现后仿真步骤及方法与直接型结构相同,仍然可分为三个步骤进行;编写M文件,生成二进制输入数据;编写Test Bench文件,采用Modelsim进行仿真;编写M文件,用MATLAB分析FPGA分析FPGA实现后的数据。这些代码和前几回相同,不再赘述,可查看往期。最后结果如图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdjknTBK-1688129590036)(C:/Users/lenovo/AppData/Roaming/Typora/typora-user-images/image-20230630205108001.png)]

图2 级联型IIR滤波器信号频谱图及信号时域图
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
iir数字滤波器可以通过FPGA进行实现。下面是一些实现步骤: 1. 设计数字滤波器的传递函数,选择合适的IIR滤波器,例如Butterworth、Chebyshev I、Chebyshev II或Elliptic等。根据信号处理要求和设计参数,确定滤波器的阶数、截止频率、通带和阻带衰减等参数。 2. 将数字滤波器的传递函数转换为差分方程,即将传递函数的分子和分母多项式进行离散化,得到滤波器的差分方程。这个过程可以使用MATLAB或Octave等数学软件进行计算。 3. 将差分方程转换为直接IIR滤波器或级IIR滤波器的结构,即将差分方程化简为可实现IIR滤波器结构。直接IIR滤波器结构的实现简单,但需要更高的运算精度;级IIR滤波器结构的实现复杂,但运算精度低,可以通过级多个直接IIR滤波器来提高精度。 4. 在FPGA实现IIR滤波器结构,可以使用硬件描述语言如Verilog或VHDL来实现。在实现过程中需要考虑时钟频率、滤波器的输入和输出数据格式、运算精度、滤波器系数的存储和更新等问题。 5. 将FPGA实现IIR数字滤波器进行仿真和调试,可以使用FPGA开发板或仿真软件进行验证。通过对比仿真结果和设计要求,调整滤波器参数和结构,直到达到设计要求。 总的来说,FPGA实现数字滤波器可以提供更高的计算性能和更低的延迟,适用于实时信号处理和高速通信等应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值