一直想找一个简单、清晰、明了的fir滤波器的设计,终于找到了一个可以应用的,和大家分享一下,有助于FPGA新手入门。
1.说道fir滤波器,滤波系数肯定是最重要的,因为后面程序中涉及到滤波系数问题,所以先来介绍,此处使用matlab来辅助求出。
①打开matlab中的start,toolbox,filter design,filter design & Analysis Tool,具体位置见下图。
②选择想要涉及的滤波器类型,本次以8阶fir滤波器为例。
设计参数:低通fir滤波器,采样精度是根据自己的输入数据来的,本例为25MHz,通过频率2MHz,截止频率8MHz,可以在specify order处选择几阶滤波器。
③把滤波器数据导出,选择export,在随后弹出的框中再次点击Export(本步骤可以改变数据的变量名),就可以看到命名为Num的滤波器系数出现在目录里。
可以看到如下结果,这个就是滤波器的系数了,新建一个txt文件,命名如图,把滤波器系数复制进去。
运行下面一段程序,生成的COF就是最后的量化数据,记录这组数据。
clc;
clear all ;
load COFFICIENT.dat;%加载系数
a1=COFFICIENT(1:1:length(COFFICIENT));
width = 16;%数据宽度8位
% 量化滤波器系数
COF = round(a1 .* (2^(width-1) - 1));%量化正弦波形数据并取整
2.在quartusII中建立一个工程,新建一个fir_filter模块,把我们计算出来的滤波器系数写在程序里面
`timescale 1 ns / 1 ns
module fir_filter
(
i_fpga_clk ,
i_rst_n ,
i_filter_in,
o_filter_out
);
input i_fpga_clk ; //25MHz
input i_rst_n ;
input signed [7:0] i_filter_in ; //数据速率25Mh
output signed [7:0] o_filter_out; //滤波输出
//==============================================================
//8阶滤波器系数,共9个系数,系数对称
//==============================================================
wire signed[15:0] coeff1 = 16'd239 ;
wire signed[15:0] coeff2 = 16'd1507;
wire signed[15:0] coeff3 = 16'd4397;
wire signed[15:0] coeff4 = 16'd7880;
wire signed[15:0] coeff5 = 16'd9493;
//===============================================================
// 延时链
//===============================================================
reg signed [7:0] delay_pipeline1 ;
reg signed [7:0] delay_pipeline2 ;
reg signed [7:0] delay_pipeline3 ;
reg signed [7:0] delay_pipeline4 ;
reg signed [7:0] delay_pipeline5 ;
reg signed [7:0] delay_pipeline6 ;
reg signed [7:0] delay_pipeline7 ;
reg signed [7:0] delay_pipeline8 ;
always@(posedge i_fpga_clk or negedge i_rst_n)
if(!i_rst_n)
begin
delay_pipeline1 <= 8'b0 ;
delay_pipeline2 <= 8'b0 ;
delay_pipeline3 <= 8'b0 ;
delay_pipeline4 <= 8'b0 ;
delay_pipeline5 <= 8'b0 ;
delay_pipeline6 <= 8'b0 ;
delay_pipeline7 <= 8'b0 ;
delay_pipeline8 <= 8'b0 ;
end
else
begin
delay_pipeline1 <= i_filter_in ;
delay_pipeline2 <= delay_pipeline1 ;
delay_pipeline3 <= delay_pipeline2 ;
delay_pipeline4 <= delay_pipeline3 ;
delay_pipeline5 <= delay_pipeline4 ;
delay_pipeline6 <= delay_pipeline5 ;
delay_pipeline7 <= delay_pipeline6 ;
delay_pipeline8 <= delay_pipeline7 ;
end
//================================================================
//加法,对称结构,减少乘法器的数目
//================================================================
reg signed [8:0] add_data1 ;
reg signed [8:0] add_data2 ;
reg signed [8:0] add_data3 ;
reg signed [8:0] add_data4 ;
reg signed [8:0] add_data5 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(0)+x(8)
if(!i_rst_n)
add_data1 <= 9'b0 ;
else
add_data1 <= i_filter_in + delay_pipeline8 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(1)+x(7)
if(!i_rst_n)
add_data2 <= 9'b0 ;
else
add_data2 <= delay_pipeline1 + delay_pipeline7 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(2)+x(6)
if(!i_rst_n)
add_data3 <= 9'b0 ;
else
add_data3 <= delay_pipeline2 + delay_pipeline6 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(3)+x(5)
if(!i_rst_n)
add_data4 <= 9'b0 ;
else
add_data4 <= delay_pipeline3 + delay_pipeline5 ;
always@(posedge i_fpga_clk or negedge i_rst_n) //x(4)
if(!i_rst_n)
add_data5 <= 9'b0 ;
else
add_data5 <= {delay_pipeline4[7],delay_pipel