工作任务
1.逻辑使用200MHz时钟做参考,做一个DDS数字频率合成器产生1MHz、10MHz和50MHz的正弦波,然后相加得到一个三音正弦波形。\
2.然后用MATLAB设计一个带通FIR滤波器,16bit量化,导出抽头文件,在FPGA上实现,对前面的三音信号进行带通滤波,滤掉1MHz和50MHz频率,得到一个10MHz的正弦波。\
3.编写TestBench对工程进行仿真,并在米联客7035开发板上综合运行,使用内置逻辑分析仪观察信号波形。
设计方案
1.倍频–clking winzard ip核(100Mhz–>200Mhz)\
2.dds adder3模块(调用dds ip核产生1MHz、10MHz和50MHz的正弦波,并合成)\
3.fir ip模块(带通FIR滤波)\
4.tb仿真\
5.ILA板级验证
实验流程
MATLAB——滤波器设计
Simulation–testbench 仿真结果
Simulation–ILA 板级仿真
具体过程
1.米联客7035开发板的晶振为100Mhz,而实验要求为200Mhz,所以需要调用时钟ip核进行倍频
clk_wiz_double u_clk_wiz_double
(
// Clock out ports
.clk_out1(clk), // output clk_out1
// Clock in ports
.clk_in1(sys_clk)); // input clk_in1
2.调用dds ip核进行频率合成,分别产生1MHz、10MHz和50MHz的正弦波
dds_1mhz u_dds_1mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_1mhz) // output wire [7 : 0] m_axis_data_tdata
);
dds_10mhz u_dds_10mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_10mhz) // output wire [7 : 0] m_axis_data_tdata
);
dds_50mhz u_dds_50mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_50mhz) // output wire [7 : 0] m_axis_data_tdata
);
3.构建加法器进行三音合成,有符号数相加为防止溢出需进行符号位扩展
always@(posedge clk )begin
sin_add = {{2{sin_1mhz[7]}},sin_1mhz} + {{2{sin_10mhz[7]}},sin_10mhz} + {{2{sin_50mhz[7]}},sin_50mhz};
end
4.利用matlab进行fir滤波器参数设计,导出coe文件。利用vivado fir ip核进行滤波器设计,fir滤波器输入为16位,所以需要对三音合成后的10位输出进行符号位扩展。
always @(posedge clk) begin
fir_in = {{6{fir_in_10[9]}},fir_in_10};
end
assign s_axis_data_tvalid = 1'b1;
fir_dds_adder3 u_fir_dds_adder3 (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(s_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(fir_in), // 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(fir_out) // output wire [31 : 0] m_axis_data_tdata
);
5.后续进行testbench仿真,调用ila ip核进行板级验证。
ila_0 u_ila_0 (
.clk(clk), // input wire clk
.probe0(sys_clk), // input wire [0:0] probe0
.probe1(sin_1mhz), // input wire [7:0] probe1
.probe2(sin_10mhz), // input wire [7:0] probe2
.probe3(sin_50mhz), // input wire [7:0] probe3
.probe4(sin_add), // input wire [9:0] probe4
.probe5(fir_out) // input wire [31:0] probe5
);
程序代码
代码详情分为三个模块:
1.top模块
`timescale 1ns / 1ps
module top_dds_fir(
input sys_clk
//output wire clk,
//output wire [7:0] sin_1mhz,sin_10mhz,sin_50mhz,
//output wire [9:0] sin_add,
//output wire [31:0] fir_out,
//output wire [9:0] fir_in_10
);
wire clk;
wire [7:0] sin_1mhz,sin_10mhz,sin_50mhz;
wire [9:0] sin_add;
wire [31:0] fir_out;
//wire [9:0] fir_in_10;
dds_adder3 u_dds_adder3(
.clk (clk) ,
.sin_1mhz (sin_1mhz) ,
.sin_10mhz (sin_10mhz) ,
.sin_50mhz (sin_50mhz) ,
.sin_add (sin_add)
);
fir_ip u_fir_ip(
.clk (clk ),
.fir_in_10 (sin_add ),
.fir_out (fir_out )
);
//assign fir_in_10 = sin_add;
clk_wiz_double u_clk_wiz_double
(
// Clock out ports
.clk_out1(clk), // output clk_out1
// Clock in ports
.clk_in1(sys_clk)); // input clk_in1
ila_0 u_ila_0 (
.clk(clk), // input wire clk
.probe0(sys_clk), // input wire [0:0] probe0
.probe1(sin_1mhz), // input wire [7:0] probe1
.probe2(sin_10mhz), // input wire [7:0] probe2
.probe3(sin_50mhz), // input wire [7:0] probe3
.probe4(sin_add), // input wire [9:0] probe4
.probe5(fir_out) // input wire [31:0] probe5
);
endmodule
2.dds模块
`timescale 1ns / 1ps
module dds_adder3(
input clk,
output [7:0] sin_1mhz,
output [7:0] sin_10mhz,
output [7:0] sin_50mhz,
output reg[9:0] sin_add
);
//wire data_tvalid;
//wire[7:0] sin_1mhz;
//wire[7:0] sin_10mhz;
//wire[7:0] sin_50mhz;
dds_1mhz u_dds_1mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_1mhz) // output wire [7 : 0] m_axis_data_tdata
);
dds_10mhz u_dds_10mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_10mhz) // output wire [7 : 0] m_axis_data_tdata
);
dds_50mhz u_dds_50mhz (
.aclk(clk), // input wire aclk
//.m_axis_data_tvalid(data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(sin_50mhz) // output wire [7 : 0] m_axis_data_tdata
);
always@(posedge clk )begin
sin_add = {{2{sin_1mhz[7]}},sin_1mhz} + {{2{sin_10mhz[7]}},sin_10mhz} + {{2{sin_50mhz[7]}},sin_50mhz};
end
endmodule
3.fir模块
`timescale 1ns / 1ps
module fir_ip(
input clk,
input [9:0] fir_in_10,
output [31:0] fir_out
);
reg [15:0] fir_in;
wire s_axis_data_tvalid;
always @(posedge clk) begin
fir_in = {{6{fir_in_10[9]}},fir_in_10};
end
assign s_axis_data_tvalid = 1'b1;
fir_dds_adder3 u_fir_dds_adder3 (
.aclk(clk), // input wire aclk
.s_axis_data_tvalid(s_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(fir_in), // 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(fir_out) // output wire [31 : 0] m_axis_data_tdata
);
endmodule
代码链接:
工程下载