IIR数字滤波器设计.docx
《IIR数字滤波器设计.docx》由会员分享,可在线阅读,更多相关《IIR数字滤波器设计.docx(14页珍藏版)》请在冰豆网上搜索。
IIR数字滤波器设计
南昌大学实验报告
学生姓名:
辜道平学号:
4061074080850专业:
信号与信息处理
实验类型:
□验证■综合□设计□创新实验日期:
实验成绩:
实验三等精度频率/相位计设计
一.实验目地
1.了解基于EDA的Matlab/DSPBuilder数字信号处理设计流程;
2.巩固数字信号处理的理论知识;
3.熟悉数字信号处理的FPGA实现方法;
4.比较用FPGA实现的数字信号处理与常规方法的性能差异。
二.实验要求
在《数字信号处理》实验课程中要求进行“用双线性变换法设计IIR数字滤波器”实验,现要求用Matlab/DSPBuilder方法和硬件描述语言设计硬件的方法,用FPGA实现IIR滤波器的设计,设计的具体要求如下:
用双线性变换法设计一个巴特沃斯低通IIR数字滤波器。
设计指标参数为:
在通带内频率低于0.2π时,最大衰减小于1dB;在阻带内[0.3π,π]频率区间上,最小衰减大于15dB。
三.实验原理
设计IIR滤波器的任务就是寻求一个因果系统上可实现的系统函数H(z),使其频率响应H(ejw)满足所希望得到的频率指标,即符合给定的通带截止频率、阻带截止频率、通带最大衰减和阻带最小衰减等指标。
用双线性变换法设计巴特沃斯IIR数字滤波器步骤如下:
(1)根据任务,确定所设计的数字低通滤波器的技术指标:
通带截止频率
、通带衰减
、阻带截止频率
、阻带衰减
。
(2)将数字低通滤波器的技术指标转换成模拟低通滤波器的技术指标。
双线性变换法的转换关系为:
Ω=
tan(
),
为数字角频率,Ω为模拟角频率。
T为采样周期;
(3)用模拟低通滤波器设计方法得到巴特沃斯模拟低通滤波器的传输函数H(s)。
(4)利用双线性变换式s=
(
),将巴特沃斯模拟低通滤波器H(s),从s平面转换到z平面,得到巴特沃斯数字低通滤波器系统函数H(z)。
四.设计实现
1.利用Matlab软件计算出所要设计滤波器的相关系数,并绘出幅频响应的图形。
表1直接型系数b,a
b
0.00012985
0.0005194
0.0007791
0.0005194
0.00012985
a
1
-3.6079
4.9795
-3.1108
0.74152
由a,b得出系统函数:
图1巴特沃斯低通滤波器频率响应特征
2.将IIR数字滤波器直接型转换为级联型。
使用函数function[b0,B,A]=dir2cas(b,a)得出级联系数B,A,b0。
表2级联型系数B,A以及增益b0
B
1.0000
2.0047
1.0047
1.0000
1.9953
0.9953
A
1.0000
-1.7832
0.8084
1.0000
-1.8247
0.9173
b0
1.2985e-004
第一阶系统函数:
第二阶系统函数:
第一阶差分方程:
第二阶差分方程:
3.系数变换,把系数B,A转化为可以用VHDL实现的滤波器系数。
先增益b0取方根,然后在乘上系数B,接着将系数B,A乘上2^10,然后转化为二进制。
表3VHDL实现的滤波器扩大后的系数B,A
B
11.6736
23.3472
11.6736
11.6736
23.2448
11.5712
A
1.0000
-1826
828
1.0000
-1868
939
表4VHDL实现的滤波器二进制系数B,A
B
000000001011
000000010111
000000001011
000000001011
000000010111
000000001011
A
000000000001
011100100001
110011000101
000000000001
011101001100
101110101011
4.IIR数字低通滤波器的VHDL实现
IIR数字低通滤波器包括以下几个模块:
时序控制模块、延时模块、顶层模块、乘法累加模块。
时序控制模块主要产生两个信号,一个是时延信号加到延时模块,实现时延功能;另一个是计算处理信号,加到乘法累加模块,实现先加后乘的功能。
延时模块主要作用是对数据进行时延,使前一个数据赋给后一个数据,然后将数据输入到乘法累加模块。
乘法累加模块主要在时钟的作用下实现加法和乘法的功能,最后输出滤波器数据。
五.实验步骤:
1.点击菜单栏File下的NewProjectWizward打开新建工程窗口,点击Next后在接下来的对话框中为此工程选择一个工作目录,并给此工程命名,注意顶层文件名要和实体名一致,然后点击Next,在接下来的芯片选择窗口中,对于本实验,需选择ACEX1K下的EP1K100QC208-3系列,最后依次点击Next完成工程的创建。
2.打开QuartusⅡ,选择菜单栏下File->New->VHDLFile,点击OK后,在打开的空白窗口中键入源程序,点击SaveAs保存到工程文件夹中。
3.点击Processing下的startcompilation,编译成功后,再依次点击File->New->OtherFiles->VectorWaveformFile打开仿真窗口,再选择Edit下的Endtime设置仿真时间,然后依次选择View才当中UtilityWindows项的NodeFinder选项,在弹出的对话框Filter框选Pins:
all,再点击List按钮,用鼠标将各端口名拖到波形编辑器,结束后关闭NodesFound窗口。
再设置时钟周期,最后点击保存按钮保存波形文件到工程目录下。
4.启动仿真器,在Processing下选Startsimulation,直到出现Simulationwassuccessful,仿真结束,调整好波形到最佳观看状态后,再分析波形与真值表中的是否对应。
5.引脚锁定。
在QuartusⅡ选择Assignment菜单中AssignmentEditor,在打开的窗口中Category栏中选择Pin,双击“To”栏的《new》,在出现的下拉栏里分别选择本工程要锁定的端口信号名,再双击对应的Location栏的《new》,选择对应端口信号名单器件引脚号即可,最后点击保存按钮后再编译一次。
6.配置文件下载。
依次选择Tool->Programmer,在Mode栏中选择JTAG,,并选中打勾下载文件右侧的第一小方框,在单击HardwareSetup按钮选择HardwareSettings页,双击此页中选项ByeteBlasterMV,单击Close按钮,关闭对话框。
最后点击窗口左侧的Start按钮即可。
六.实验结果及分析
图2延时模块时序仿真图
图3第一级乘法累加模块时序仿真图
图4-10第二级乘法累加模块时序仿真图
图4-14顶层模块功能仿真图
IIR数字低通滤波器的系统仿真结果分析:
系统先开始处于初始状态,当RES信号为“1”时,对整个系统进行清零。
在RES为“0”的前提,时序控制模块在时钟clk上升沿的作用下产生两个信号CLK_REG及CLK_REGBT,其中CLK_REG信号用来作为延时模块、补码乘加模块和累加模块的输入时钟,CLK_REGBT每隔6个时钟产生一个高电平作为这三个模块的复位信号。
延时模块在接收到CLK_REG高电平信号时清零输出端,接收到低电平时,在CLK_REGBT上升沿的作用下对输入信号进行延时,以实现一次延时运算,而后将延时信号输出,送给乘法累加模块。
乘法累加模块在接收延时信号的同时也接收输入的系数信号,在CLK_REGBT上升沿的作用下实现系数和延时信号的乘法累加运算,而此步骤需要6个时钟来完成,正好与时序控制模块的输出信号CLK_REGBT相一致。
乘法累加模块的输出一部分送入延时模块以实现信号的反馈,另一部分则送入到累加模块,在累加模块中进行结果累加后输出,得到最终结果。
表5滤波后输出的数据
输入数据
X={225,226,227.228,229}b0=11,b1=23,b2=11,a1=1826,a2=-828
d0=11,d1=23,d2=11,c1=1868,c2=-939
仿真值
0
1
37
14
24
37
53
七.心得体会
为了做好本实验,我特地把本科阶段所学的《数字信号处理》中有关IIR数字滤波器的设计相关内容又看了一遍,加深了对IIR数字滤波器的印象,了解其设计步骤。
通过这次实验加强了我将EDA应用到所学专业当中去的能力,并锻炼了我将理论应用到实践的能力,为以后从事相关的研究工作打下了坚实的基础。
八.实验源程序代码
时序控制模块程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;
entitytime_controlis
port(clk,res:
instd_logic;
clk_reg,clk_regbt:
outstd_logic);
endtime_control;
architecturebhvoftime_controlis
signalcounter:
integer;
signalclk_en:
std_logic;
signalen:
std_logic;
begin
clk_regbt<=notclkandclk_enanden;
clk_reg<=notclkandnotclk_enanden;
process(clk,res)
begin
if(res='1')then
counter<=0;
clk_en<='0';
en<='0';
elsif(clk'eventandclk='1')then
if(counter<6)then
clk_en<='1';
en<='1';
counter<=counter+1;
elsecounter<=0;
clk_en<='0';
en<='1';
endif;
endif;
endprocess;
endbhv;
延时模块程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitytime_delayis
port(clk:
instd_logic;
res:
instd_logic;
xn:
instd_logic_vector(11downto0);
yout:
instd_logic_vector(11downto0);
x0,x1,x2:
outstd_logic_vector(11downto0);
y1,y2:
outstd_logic_vector(11downto0));
endtime_delay;
architecturebhvoftime_delayis
signalreg_x0,reg_x1,reg_x2:
std_logic_vector(11downto0);
signalreg_y1,reg_y2:
std_logic_vector(11downto0);
begin
x0<=reg_x0;
x1<=reg_x1;
x2<=reg_x2;
y1<=reg_y1;
y2<=reg_y2;
process(res,clk)
begin
if(res='1')then
reg_x0<="000000000000";
reg_x1<="000000000000";
reg_x2<="000000000000";
reg_y1<="000000000000";
reg_y2<="000000000000";
elsif(clk'eventandclk='1')then
reg_x2<=reg_x1;
reg_x1<=reg_x0;
reg_x0<=xn;
reg_y2<=reg_y1;
reg_y1<=yout;
--实现延时
endif;
endprocess;
endbhv;
一阶乘法累加模块程序
libraryieee
useieee.std_logic_1164.all
useieee.std_logic_arith.all
useieee.std_logic_unsigned.all
useieee.std_logic_signed.all
entitymult_add1is
port(clk_regbt,clk_reg,res:
instd_logic
x0,x1,x2,y1,y2:
instd_logic_vector(11downto0)
yout:
outstd_logic_vector(11downto0))
endmult_add1
architecturebehavofmult_add1is
signalcnt:
integerrange0to5
signaltmpa,tmpb:
std_logic_vector(11downto0)
signalytmp,p:
std_logic_vector(23downto0)
constantb0:
std_logic_vector(11downto0):
="000000001011"
constantb1:
std_logic_vector(11downto0):
="000000010111"
constantb2:
std_logic_vector(11downto0):
="000000001011"
constanta1:
std_logic_vector(11downto0):
="011100100001"
constanta2:
std_logic_vector(11downto0):
="110011000101"
begin
tmpa<=b0whencnt=0else
b1whencnt=1else
b2whencnt=2else
a1whencnt=3else
a2whencnt=4else(others=>'0')
tmpb<=x0whencnt=0else
x1whencnt=1else
x2whencnt=2else
y1whencnt=3else
y2whencnt=4else(others=>'0')
p<=tmpa*tmpb
process(clk_reg,clk_regbt,res)
begin
ifres='1'then
cnt<=0
ytmp<=(others=>'0')
yout<=(others=>'0')
elsifclk_reg='1'then
cnt<=0
ytmp<=(others=>'0')
elsif(clk_regbt'event
andclk_regbt='1')then
ifcnt<5then
ytmp<=ytmp+p
cnt<=cnt+1
elsif(cnt=5)then
yout(11downto0)<=ytmp(21downto10)
endif
endif
endprocess
endbehav
二阶乘法累加程序
libraryieee
useieee.std_logic_1164.all
useieee.std_logic_arith.all
--useieee.std_logic_unsigned.all
useieee.std_logic_signed.all
entitymult_add2is
port(clk_regbt,clk_reg,res:
instd_logic
x0,x1,x2,y1,y2:
instd_logic_vector(11downto0)
yout:
outstd_logic_vector(11downto0))
endmult_add2
architecturebehavofmult_add2is
signalcnt:
integerrange0to5
signaltmpa,tmpb:
std_logic_vector(11downto0)
signalytmp,p:
std_logic_vector(23downto0)
constantd0:
std_logic_vector(11downto0):
="000000001011"
constantd1:
std_logic_vector(11downto0):
="000000010111"
constantd2:
std_logic_vector(11downto0):
="000000001011"
constantc1:
std_logic_vector(11downto0):
="011101001100"
constantc2:
std_logic_vector(11downto0):
="110001010101"
begin
tmpa<=d0whencnt=0else
d1whencnt=1else
d2whencnt=2else
c1whencnt=3else
c2whencnt=4else
(others=>'0')
tmpb<=x0whencnt=0else
x1whencnt=1else
x2whencnt=2else
y1whencnt=3else
y2whencnt=4else
(others=>'0')
p<=tmpa*tmpb
process(clk_reg,clk_regbt,res)
begin
ifres='1'then
cnt<=0
ytmp<=(others=>'0')
yout<=(others=>'0')
elsifclk_reg='1'then
cnt<=0
ytmp<=(others=>'0')
elsif(clk_regbt'eventandclk_regbt='1')then
ifcnt<5thenytmp<=ytmp+p
cnt<=cnt+1
elsif(cnt=5)then
yout(11downto0)<=ytmp(21downto10)
endif
endif
endprocess
endbehav