参考博客:数字信号处理(一):Xilinx Vivado DDS IP核设计实例
DDS ip 0设置方法,其他默认设置。
DDS 1 设置情况,其他默认设置。
频率控制字:
主程序:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/01/13 08:40:13
// Design Name:
// Module Name: dds_test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dds_test(
input sclk, //100MHz
input rst_n,
//单通道DDS信号输出
output wire dds1_tvalid,
output wire [19:0] dds1_sine,
output wire [19:0] dds1_cosine,
output wire m_axis_phase_tvalid,
output wire [31:0] m_axis_phase_tdata,
//4通道DDS输出
output wire m_axis_data_tvalid_m,
output wire [47:0] m_axis_data_tdata_m,
output wire m_axis_phase_tvalid_m,
output wire [31:0] m_axis_phase_tdata_m,
output wire [1:0] m_axis_data_tuser_m,
output reg [19:0] m_dds_ch0_cosine,
output reg [19:0] m_dds_ch0_sine,
output reg [19:0] m_dds_ch1_cosine,
output reg [19:0] m_dds_ch1_sine,
output reg [19:0] m_dds_ch2_cosine,
output reg [19:0] m_dds_ch2_sine,
output reg [19:0] m_dds_ch3_cosine,
output reg [19:0] m_dds_ch3_sine,
output wire event_s_config_tlast_missing,
output wire event_s_config_tlast_unexpected
);
//----------------------单通道DDS输出sine cosine-------------------
//输出频率为1Mhz
wire [47:0] m_axis_data_tdata;
wire m_axis_data_tvalid;
assign dds1_sine =m_axis_data_tdata[43:24];
assign dds1_cosine=m_axis_data_tdata[19:0];
dds_compiler_0 dds_single_out(
.aclk(sclk), // input wire aclk
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [47 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata) // output wire [31 : 0] m_axis_phase_tdata
);
//------------------------4通道DDS输出sine cosine----------------------------
//1------------1Mhz--------32'h28F5C2
//2------------2Mhz--------51EB85
//3------------3Mhz--------7AE147
//4------------4MHz--------A3D70A
//通道PINC配置
reg s_axis_config_tvalid;
wire s_axis_config_tready;
reg s_axis_config_tlast;
reg [31:0] s_axis_config_tdata;
reg [3:0] cnt;
always @(posedge sclk)begin //频率控制字的分时段选择
if(rst_n==1'b0)begin
s_axis_config_tvalid<=1'b0;
s_axis_config_tlast<=1'b0;
s_axis_config_tdata<=32'h0;
cnt<=4'b0;
end
else begin
case (cnt)
4'd0:begin
s_axis_config_tvalid<=1'b0;
s_axis_config_tlast<=1'b0;
s_axis_config_tdata<=32'h0;
cnt<=cnt+1'b1;
end
4'd1:begin
s_axis_config_tvalid<=1'b1;
if(s_axis_config_tready==1'b1)begin
s_axis_config_tdata<=32'h28F5C2; //1Mhz的频率控制字
cnt<=cnt+1'b1;
end
else begin
cnt<=cnt;
end
end
4'd2:begin
if(s_axis_config_tready==1'b1)begin
s_axis_config_tdata<=32'h51EB85; //2Mhz的频率控制字
cnt<=cnt+1'b1;
end
else begin
cnt<=cnt;
end
end
4'd3:begin
if(s_axis_config_tready==1'b1)begin
s_axis_config_tdata<=32'h7AE147; //3Mhz的频率控制字
cnt<=cnt+1'b1;
end
else begin
cnt<=cnt;
end
end
4'd4:begin
if(s_axis_config_tready==1'b1)begin
s_axis_config_tdata<=32'hA3D70A; //4Mhz的频率控制字
s_axis_config_tlast <= 1'b1;
cnt<=cnt+1'b1;
end
else begin
cnt<=cnt;
end
end
4'd5: begin
if(s_axis_config_tready==1'b1) begin
s_axis_config_tdata <= 32'h0;
s_axis_config_tlast <= 1'b0;
s_axis_config_tvalid <= 1'b0;
cnt <= cnt + 1'b1;
end
else
cnt <= cnt;
end
4'd6: begin
cnt <= cnt;
end
endcase
end
end
always @(posedge sclk)begin
if(rst_n==1'b0)begin
m_dds_ch0_cosine <= 20'd0;
m_dds_ch0_sine <= 20'd0;
m_dds_ch1_cosine <= 20'd0;
m_dds_ch1_sine <= 20'd0;
m_dds_ch2_cosine <= 20'd0;
m_dds_ch2_sine <= 20'd0;
m_dds_ch3_cosine <= 20'd0;
m_dds_ch3_sine <= 20'd0;
end
else begin
case(m_axis_data_tuser_m)
2'b00:begin
m_dds_ch0_cosine <= m_axis_data_tdata_m[19:0];
m_dds_ch0_sine <= m_axis_data_tdata_m[43:24];
end
2'b01:begin
m_dds_ch1_cosine <= m_axis_data_tdata_m[19:0];
m_dds_ch1_sine <= m_axis_data_tdata_m[43:24];
end
2'b10:begin
m_dds_ch2_cosine <= m_axis_data_tdata_m[19:0];
m_dds_ch2_sine <= m_axis_data_tdata_m[43:24];
end
2'b11:begin
m_dds_ch3_cosine <= m_axis_data_tdata_m[19:0];
m_dds_ch3_sine <= m_axis_data_tdata_m[43:24];
end
endcase
end
end
dds_compiler_1 dds_four_out (
.aclk(sclk), // input wire aclk
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tready(s_axis_config_tready), // output wire s_axis_config_tready
.s_axis_config_tdata(s_axis_config_tdata), // input wire [31 : 0] s_axis_config_tdata
.s_axis_config_tlast(s_axis_config_tlast), // input wire s_axis_config_tlast
.m_axis_data_tvalid(m_axis_data_tvalid_m), // output wire m_axis_data_tvalid
.m_axis_data_tready(1'b1), // input wire m_axis_data_tready
.m_axis_data_tdata(m_axis_data_tdata_m), // output wire [47 : 0] m_axis_data_tdata
.m_axis_data_tuser(m_axis_data_tuser_m), // output wire [1 : 0] m_axis_data_tuser
.m_axis_phase_tvalid(m_axis_phase_tvalid_m), // output wire m_axis_phase_tvalid
.m_axis_phase_tready(1'b1), // input wire m_axis_phase_tready
.m_axis_phase_tdata(m_axis_phase_tdata_m), // output wire [31 : 0] m_axis_phase_tdata
.event_s_config_tlast_missing(event_s_config_tlast_missing), // output wire event_s_config_tlast_missing
.event_s_config_tlast_unexpected(event_s_config_tlast_unexpected) // output wire event_s_config_tlast_unexpected
);
endmodule
测试程序;
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/01/13 14:47:17
// Design Name:
// Module Name: dds_test_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dds_test_tb();
reg sclk;
reg rst_n;
wire dds1_tvalid;
wire [19:0] dds1_sine;
wire [19:0] dds1_cosine;
wire m_axis_phase_tvalid;
wire [31:0] m_axis_phase_tdata;
wire m_axis_data_tvalid_m;
wire [47:0] m_axis_data_tdata_m;
wire m_axis_phase_tvalid_m;
wire [31:0] m_axis_phase_tdata_m;
wire [1:0] m_axis_data_tuser_m;
wire [19:0] m_dds_ch0_cosine;
wire [19:0] m_dds_ch0_sine;
wire [19:0] m_dds_ch1_cosine;
wire [19:0] m_dds_ch1_sine;
wire [19:0] m_dds_ch2_cosine;
wire [19:0] m_dds_ch2_sine;
wire [19:0] m_dds_ch3_cosine;
wire [19:0] m_dds_ch3_sine;
wire event_s_config_tlast_missing;
wire event_s_config_tlast_unexpected;
dds_test dut(
.sclk(sclk),
.rst_n(rst_n),
.dds1_tvalid(dds1_tvalid),
.dds1_sine(dds1_sine),
.dds1_cosine(dds1_cosine),
.m_axis_phase_tvalid(m_axis_phase_tvalid),
.m_axis_phase_tdata(m_axis_phase_tdata),
.m_axis_data_tvalid_m(m_axis_data_tvalid_m),
.m_axis_data_tdata_m(m_axis_data_tdata_m),
.m_axis_phase_tvalid_m(m_axis_phase_tvalid_m),
.m_axis_phase_tdata_m(m_axis_phase_tdata_m),
.m_axis_data_tuser_m(m_axis_data_tuser_m),
.m_dds_ch0_cosine(m_dds_ch0_cosine),
.m_dds_ch0_sine(m_dds_ch0_sine),
.m_dds_ch1_cosine(m_dds_ch1_cosine),
.m_dds_ch1_sine(m_dds_ch1_sine),
.m_dds_ch2_cosine(m_dds_ch2_cosine),
.m_dds_ch2_sine(m_dds_ch2_sine),
.m_dds_ch3_cosine(m_dds_ch3_cosine),
.m_dds_ch3_sine(m_dds_ch3_sine),
.event_s_config_tlast_missing(event_s_config_tlast_missing),
.event_s_config_tlast_unexpected(event_s_config_tlast_unexpected)
);
initial begin
#0 sclk = 0;
rst_n = 1'b0;
#1000 rst_n = 1'b1;
end
always #5 sclk = ~sclk;
endmodule
仿真结果:
二.DDS 产生频率可控制变化的正弦余弦信号
dds设置,要求输出的sin 和cos的数据位宽为20.
其他默认。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2021/01/12 14:45:26
// Design Name:
// Module Name: dds_sin_cos
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dds_sin_cos_data(
input sclk,
input [23:0] fre_ctrl_word
);
wire fre_ctrl_word_en;
wire freq_out_en;
wire [47:0] m_axis_data_tdata;
wire [19:0] sin_data_out;
wire [19:0] cos_data_out;
wire [23:0]phase_data_out;
wire phase_data_en;
assign fre_ctrl_word_en=1'b1;
assign sin_data_out=m_axis_data_tdata[43:24];
assign cos_data_out=m_axis_data_tdata[19:0];
dds_sin_cos dds_sin_cos_inst (
.aclk(sclk), // input wire aclk
.s_axis_config_tvalid(fre_ctrl_word_en), // input wire s_axis_config_tvalid
.s_axis_config_tdata(fre_ctrl_word), // input wire [23 : 0] s_axis_config_tdata
.m_axis_data_tvalid(freq_out_en), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [47 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(phase_data_en), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(phase_data_out) // output wire [23 : 0] m_axis_phase_tdata
);
endmodule
测试程序:
module dds_sin_cos_data_tb();
reg sclk;
reg [23:0]fre_ctrl_word;
initial begin
sclk=0;
fre_ctrl_word='d0;
#100
fre_ctrl_word='h28f5; //1Mhz
#4000
fre_ctrl_word='h19999; //10Mhz
#4000
fre_ctrl_word='h51eb; //2Mhz
#4000
fre_ctrl_word='h68; //10khz
#40000
fre_ctrl_word='h28f5; //1Mhz
end
always #5 sclk=~sclk;
dds_sin_cos_data dds_sin_cos_inst(
.sclk(sclk),
.fre_ctrl_word(fre_ctrl_word)
);
测试结果;