1)实验目的:利用FPGA实现高精度数字滤波器的设计。
2)实验平台:
ALINIX黑金AX301开发板,芯片型号:ALTERA 公司的 Cyclone IV 系列 FPGA,型号为 EP4CE6F17C8, 芯片封装为FBGA,AN108ADDA模块
3) 实验步骤:
MATLAB fdatool(高版本改为filterdesignertool)设计滤波器直接生成Verilog代码---->testbench仿真----->实际仿真
3-1 MATLAB设计模块(FIR滤波器设计)
1.以设计为低通为例->选择为海明窗函数窗函数->设计采样频率50MHZ->设计截止频率为1MHZ
滤波器阶数此处设为30,与性能正相关,与资源消耗反相关
2.点击左下角的Set quantization parameter,设置Filter arithmetic为Fixed-point(定点)部分FPGA只支持定点运算。
Numerator word length设定数据的长度(影响滤波器)实测16位可达到较好的滤波效果。
3.先选择Filter precision为Specify all(这样才能设置output wordth length)设计配置输入输出的为宽(因为本实验使用的ADDA模块AN108 AD采样与DA输出数据都为8位),而又MATLAB生成的滤波器数据类型为signed即有符号位。因此实际的滤波器输入即输出数据应该为9位,最高位默认为0作为符号位。
4.生成verilog代码,生成路径选择工程文件夹下
3-2使用modisim仿真,新建工程,添加测试文件,compile验证成功后进行SIMULATE仿真,选中filter_tb文件。
图2为仿真效果,可以清楚看到高频波形被过滤。
具体的仿真过程可有参考https://blog.csdn.net/Reborn_Lee/article/details/82974294?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242
->
3-3代码编写
1.直接将生成的fir.v滤波器代码添加进工程,并编写顶层文件
`timescale 1ns/1ps module adda_test( //顶层模块 input clk,//main clock output daclk, output [7:0] dadata,//DAdata output adclk, input [7:0] addata //ADdata );
2.自设置网线型变量以及寄存器变量用于数据类型的转换(将上述的ADDA模块的8位无符号位数据转变为9位的有符号位数据,最高位为符号位)
reg signed [8:0] filterout; //用于滤波器的输出 wire signed [8:0] filterin; //用于滤波器模块的输入 assign filterin[7:0]=addata; //线网型变量的连接 assign dadata=filterout[7:0]; assign daclk=clk;//ADDA模块的时钟连接(直接连系统的50MHZ的时钟即可) assign adclk=clk;
3.例化滤波器模块
filter filter_inst( .clk(clk), //滤波器采样时钟,由于之前MALLAB中设置为50MHZ所以直接接系统时钟即可 .clk_enable(1'b1),//时钟使能信号,置为1即使能 .reset(1'b0),//reset置0为失能(最好设置单独的复位引脚) .filter_in(filterin),//滤波器输入数据 .filter_out(filterout)//滤波器输出数据 );
4.关于reset的设置缘由在filter.v中的288行可以找到,可以发现reset=1'b1时为复位功能启用,因为AX301的rst_n在按键未按下时高电平,所以若设置按键的话应当更改reser为1'b0。
1 always @( posedge clk or posedge reset) 2 begin: Delay_Pipeline_process 3 if (reset == 1'b1) begin
4)实验效果:
以低通为例实际操作发现,在设计过程中FS采样频率与截止频率的倍数相差不可过大,否则在MATLAB设计环节就无法达到所要的截止频率的效果。而采样频率又不可过小,否则容易导致波形的失真。
第一次我采用了FS采样频率 为50MHZ,恰好为开发板晶振的时钟频率,设定的截止频率为1MHZ,实验效果较好,实际在-3.01db时为1.02MHZ,波形无失真。
第二次测试较低频率的低通,选择滤波器时钟为1MHZ(将系统时钟用PLL锁相环50分频),截止频率设为30KHZ。效果图如下,图1为1KHZ的波形,较为清晰无失真。图2为30KHZ,失真较严重,虽然截止频率与设计预期基本相同。
之后又尝试了带通滤波器设计,MATLAB设计图如下,实际测试结果也与预期相仿,但是存在的问题便是失真严重,因为采样频率才100K,而截止达到30K。尝试提高采样频率,难以实际出想要的效果。
5)问题分析:个人认为主要难点还是在MATLAB的设计方面,想要设计达到预期的参数最基本需要了解各类型滤波器的参数以及设计的原理(本人准大二,模电还没学)。或许能避免采样频率过高或过低带来的效果问题。此外,还有直接调用IP核的设计方式,但是相比之下还是认为直接使用MATLAB生成代码方便,不过个人认为调用IP核设计的实际精度应该更高。不过貌似相同参数的滤波器调用IP核的话所占用的DSP(数字处理单元会更多),实验中就出现过DSP数目不够的情况,解决方式就是换性能更强的FPGA板子或者降低精度。因为实验并未取得较好的效果,所以IP核的方式在取得较好的实验效果之后再详细讨论。
如果有大佬碰巧看到本文并且有FPGA数字滤波器的好的设计方案也请多多指教。
6)设计过程中参考一些相关博客:
1.quartusII ip核的使用说明:https://www.cnblogs.com/cofin/p/10220648.html
2.FIR滤波器详解:https://blog.csdn.net/Reborn_Lee/article/details/82968488
3.MALLAB生成FIR滤波器的步骤及仿真过程:https://blog.csdn.net/Reborn_Lee/article/details/82974294?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242