本文使用FPGA来实现FIR滤波器设计,设计中使用的DDS、乘法器与FIR滤波器均采用IP core进行实现,实现效果是将3MHz和4MHz的正弦信号混频后使用FIR低通滤波器滤除7MHz信号得到1MHz的信号。
DDS产生正弦信号
首先用两个DDS核生成3MHz以及4MHz的正弦波信号。
注意:此处的dds的命名要和代码中对应,系统时钟为50MHz。需要两个核,此处只例举dds1的实现,dds2的实现类似。
选择正弦信号,取消相位选项。
输出频率选择3MHz,另外一个核选择4MHz。
乘法器混频
由于DDS输出的正弦是8bit信号,此处选择8。
FIR滤波器
抽头系数的获取
其中的抽头系数使用filter solutions进行滤波器设计获取抽头系数。
在软件中根据自己的需求设置,最后点击箭头处的理想频率响应和综合滤波器生成频响图和抽头系数:
幅频响应:
抽头系数:
抽头系数:
NUM = [-0.001304, -0.001178, -0.001023, -0.000514, 0.000759, 0.003221, 0.00724, 0.01305, 0.02067, 0.02991, 0.04031, 0.05121, 0.06181, 0.07124, 0.07866, 0.08342, 0.08506, 0.08342, 0.07866, 0.07124, 0.06181, 0.05121, 0.04031, 0.02991, 0.02067, 0.01305, 0.00724, 0.003221, 0.000759, -0.000514, -0.001023, -0.001178, -0.001304]
粘贴上抽头系数:
FIR滤波器Verilog代码
例化前面生成的IP核。
module dds_fir(
input wire clk, //系统时钟(此处为50MHz)
output wire [7:0] sin1, //DDS正弦信号1(此处为3MHz)
output wire [7:0] sin2, //DDS正弦信号2(此处为4MHz)
output wire [15:0] P, //sin1*sin2得到的混频信号(此处为1MHz和7MHz)
output wire [39:0] P_OUT //FIR滤波后得到的信号
);
dds1 dds1_inst (
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin1) // output wire [7 : 0] m_axis_data_tdata
);
dds2 dds2_inst (
.aclk(clk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin2) // output wire [7 : 0] m_axis_data_tdata
);
mult mult_inst (
.CLK(clk), // input wire CLK
.A(sin1), // input wire [7 : 0] A
.B(sin2), // input wire [7 : 0] B
.P(P) // output wire [15 : 0] P
);
fir fir_inst (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(m_axis_data_tvalid), // input wire s_axis_data_tvalid
.s_axis_data_tready(s_axis_data_tready), // output wire s_axis_data_tready
.s_axis_data_tdata(P), // input wire [15 : 0] s_axis_data_tdata
.m_axis_data_tvalid(m_axis_data_tvalid1), // output wire m_axis_data_tvalid
.m_axis_data_tdata(P_OUT) // output wire [39 : 0] m_axis_data_tdata
);
endmodule
其中将两正弦信号相乘,实际上是利用积化和差公式得到两频率的相加。
testbench代码
主要产生50MHz时钟即可。
module tb_dds_fir ();
reg clk = 0;
wire [7:0] sin1;
wire [7:0] sin2;
wire [15:0] P;
wire [39:0] P_OUT;
always #10 clk <= ~ clk ; //产生50MHz时钟
dds_fir dds_fir_inst(
.clk(clk),
.sin1(sin1),
.sin2(sin2),
.P(P), //混频信号
.P_OUT(P_OUT) //滤波信号
);
endmodule
仿真效果
可以看出,P信号中的7MHz成分信号被滤除,得到1MHz的P_OUT信号,实现了滤波功能。