主要是通过Vivado的Fir compiler IP核进行数字滤波器的设计,使用者只要提供相应的指标就可以进行高性能的数字滤波器设计。使用工具:Vivado 、MATLAB Fdatool 、MATLAB(Python)。
一、抽头系数的生成
第一步是使用MATLAB中Fdatool工具对滤波器进行设计,导出抽头系数
打开MATLAB中的工具箱找出FDATOOL,并打开,如上图。
下面就是根据我们的需求在fdatool中输入相应的指标,具体如下图
如上图,我们设置的是个高通滤波器,这是最近帮别人写的一个小程序因为是截止频率太小所以效果可能不是特别好。
图中1:是选择滤波器的类型,有低通、高通、带通、带阻四种;
图中2:是滤波器实现的函数,此处选择了窗函数,当然还有其他的类型,大家可以自行选择;
图中3:是选择窗函数中的Hamming(汉明窗:这个大家应该很熟悉);
图片4:是设置采样频率和截止频率。因为我们此次这个例子是高通滤波器,所有只有采样频率Fs和一个截止频率Fc;
图片5:是滤波器使用的阶数,当然阶数越高滤波器的性能越好、阻带内的衰减越大,但同时消耗的资源也就越多,这个需要大家自己在性能和资源之间自己权衡。
参数设置完成后我们可以点击图中Design Filter观察滤波器的衰减。
如上图所示,我们需要将参数设置定点数(第二步)才能导出参数的.coe文件。
这样我们就完成了数字滤波器的抽头系数的导出了,可以进行下一步Vivado中IP的参数设置了。
打开FIR compiler
如下图,1.select source先选择使用coe文件导入参数(建议把coe文件放在工程文件下);
2.是Filter type 我们选择single rate(这里是fir IP核的时钟频率要和采样频率一致,当然还有其他模式),也可以参考(http://xilinx.eetrend.com/d6-xilinx/blog/2018-02/12531.html)。
由于我们才使用的signal rate模式所以采样频率要和IP核时钟频率一致,所以特定的硬件过采样频率(Hardwa oversampling specification)选择select from ->Frequency specifiction,最后是采样频率和是时钟频率均设为在FDATOOL中采样频率FS,如下图
如下图所示,因为我们导出的coe文件参数一般都是有符号参数,所以coeffiient Type 选择signed ;又因为我们一般使用的FIR是对称性结构,所以coefficient structure 选择symmetric ;
如下图所示,我们的输入数据是有符号数的选择signed ,位宽根据实际的选择;另外在Fdatool中输出设置的全精度输出(Full precision),我们这里也一样,当然我们输入是16位的,所以我们的输出一般也是16位的,这样我就需要在例化FIR compiler后对其进行截断,截断我们使用assign语句进行截断。
其他出我们可以保持默认,当然还有一些使能,复位,我们根据自己的情况进行选择,最后我们可以看到如下图的fir的总的报告:
下面是对IP核进行例化核调用,在下图中的的.veo的文件中把例化文件拷贝到top层中调用。
module Top(
input sys_clk,
input rst_n ,
input [15:0] data_in
);
//wire define
wire clk6_5k ; //IP核时钟=采样时钟
wire m_axis_data_tvalid ; //为1时输出信号有效
wire [31:0] m_axis_data_tdata ; //输出的全精度信号
wire s_axis_data_tready ; //输入信号是否有效
wire locked ; //PLL稳定信号,为稳定前为0
wire [15:0] data_in_n ; //有符号输入信号的
wire [15:0] out_data ; //输出截位信号1
wire [15:0] out_data1 ; //输出截位信号2
wire [15:0] out_data2 ; //输出截位信号3
//无符号位转有符号位
assign data_in_n = data_in + 16'd32768 ;
//截位
assign out_data = m_axis_data_tdata[31:16]+16'd32768; //输出截位信号1
assign out_data1 = m_axis_data_tdata[30:15]+16'd32768; //输出截位信号2
assign out_data2 = m_axis_data_tdata[31:16]+16'd32768; //输出截位信号3
//Fir compiler 例化
fir_compiler_0 u_fir_compiler_0 (
.aclk(clk6_5k), // input wire aclk
.aclken(locked), // input wire aclken
.s_axis_data_tvalid(rst_n), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata(data_in_n), // input wire [15 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata) // output wire [15 : 0] m_axis_data_tdata
);
//产生6.536MHZ
clk_wiz_0 u_clk_wiz_0
(
.clk_out1 (clk6_5k), // output clk_out1
.resetn (rst_n), // input resetn
.locked (locked), // output locked
.clk_in1 (sys_clk)); // input clk_in1
四、仿真
使用python生成50HZ+100HZ的正弦波的点图,再保存的TXT文档中,不一定要采用python,MATLAB也可以的,由于最近在学习使用python,所以使用python。
先写这么多,有其他问题的话再补充,大家可以在下方留言,谢谢。