使用matlab和ISE 的IP核联合设计FIR滤波器
使用MATLAB的fdatool工具箱生成抽头系数
FIR抽头系数可以直接调用matlab的filter design工具箱实现,在命令窗口直接输入fdatool即可调用,出来的界面如下所示:
我们假设滤波器的输入信号是100kHz的信号(8位)与2MHz(8位)的信号混合之后的信号(9位)。想把2MHz的信号给滤除
对于在生成滤波器参数设置的时候有以下几点要注意:
1.Fs为滤波器的采样频率,这个频率要符合采样定理,一定是要满足是最高杂波频率的两倍,像我的设计中就要大于2MHz的两倍,所以我在这里设计为8MHz
2.通带截止频率的设置:在我最初设置的时候我的通带截止频率都维持在100KHz后一点点大概就是110KHz左右,这样的话我们的采样频率稍大一点就会导致滤波器的阶数特别多,所以我在这里设计滤波器的通带截止频率就在1Mhz,个人认为只要我们需要通过的频率在这个截止频率希望滤掉的频率在这个截止频率之外内部就好了,当然下面的阻带截止频率就要在我们需要滤除波的内部就好,这样设置的话就会使得我们的滤波器的阶数比较少,生成IP核工程的话也会比较快。
3.系数的导出:看了一些博客,博客中说有些FPGA中的FIR滤波器的系数不识别浮点数,所以我们在导出系数的时候就要导出浮点数,点击上图中的左侧第三个按钮。将Filter arithmetic 设置为Fixd-point,量化数据位数选择16位,然后再target下导出.coe文件,这样就导出了16位数据类型为定点数的系数
ISE中FIR IP核的使用
添加FIR IP核选择5.0就行
select source:选择COE File文件类型,然后加入我们之前导入的文件
输入信号的采样频率:这个与我们matlab中设置参数时的Fs相同,时钟频率就是我们的系统时钟频率
切记系数的种类为16位的有符号数
根据我们的输入数据类型去填写这一栏的内容,后面保持默认就好了
关于使用DDS产生正弦信号之前的博客有讲述
然后就是IP核的例化
module top(
input wire sclk,
output wire [7:0] sin1,
output wire [7:0] sin2,
output wire [8:0] sin3,
output wire [7:0] sin4
);
wire [8:0] sin3_reg;
sin_100k sin_1000_inst (
.clk(sclk), // input clk
.sine(sin1) // output [7 : 0] sine
);
sin_2M sin_2M_inst (
.clk(sclk), // input clk
.sine(sin2) // output [7 : 0] sine
);
fir1 fir_1 (
.clk(sclk), // input clk
.rfd(), // output rfd
.rdy(), // output rdy
.din(sin3_reg), // input [8 : 0] din
.dout(sin4)); // output [7 : 0] dout
assign sin3_reg = $signed(sin1)+$signed(sin2);
assign sin3 = sin3_reg;
endmodule
module tb_top;
// Inputs
reg sclk;
// Outputs
wire [7:0] sin1;
wire [7:0] sin2;
wire [8:0] sin3;
wire [7:0] sin4;
// Instantiate the Unit Under Test (UUT)
top uut (
.sclk(sclk),
.sin1(sin1),
.sin2(sin2),
.sin3(sin3),
.sin4(sin4)
);
initial begin
// Initialize Inputs
sclk = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
always #10 sclk = ~sclk;
endmodule
仿真结果
结果分析
1.这个结果虽然把需要频率的波滤出来了但是幅度有问题。
2.再生成两个正弦波的时候两个波的频率最好相差的大一些,不然通过滤波器之后的效果很差。