Xilinx-IP核 DDS
一、功能介绍
DDS IP核通过数字方式生成高精度、可编程频率信号,具备频率合成、相位控制、多波形输出、调制功能、实时控制、低功耗、高集成度和高稳定性等特点
二、 设置界面
(栅格化后模数选择:最大输出频率/预期输出频率)
- 仿真(找了B站一个博主FPGA干货分享的tb代码操作下):
`timescale 1ns/100ps module tb_dds_fix_normal; reg aclk ='d0; reg aresetn ='d0; wire m_axis_data_tvalid ; wire [ 31: 0] m_axis_data_tdata ; wire m_axis_phase_tvalid ; wire [ 31: 0] m_axis_phase_tdata ; always #1 aclk = ~aclk; initial begin #100; aresetn = 1'b1; end dds_compiler_0 dds_compiler_0 ( .aclk (aclk ),// input wire aclk .aresetn (aresetn ),// input wire aresetn .m_axis_data_tvalid (m_axis_data_tvalid ),// output wire m_axis_data_tvalid .m_axis_data_tdata (m_axis_data_tdata ),// output wire [31 : 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 ); reg S_ch0_valid ; reg [ 15: 0] S_ch0_cos ; reg [ 15: 0] S_ch0_sin ; reg [ 31: 0] S_ch0_pha ; reg [ 15: 0] S_ch1_cos ; reg [ 15: 0] S_ch1_sin ; reg [ 31: 0] S_ch1_pha ; always @(posedge aclk ) if (!aresetn) begin S_ch0_valid <= 1'b1; end else begin S_ch0_valid <= ~S_ch0_valid; end always @(posedge aclk ) if (S_ch0_valid) begin S_ch0_cos <= m_axis_data_tdata[15:0]; S_ch0_sin <= m_axis_data_tdata[31:16]; S_ch0_pha <= m_axis_phase_tdata; S_ch1_cos <= S_ch1_cos; S_ch1_sin <= S_ch1_sin; S_ch1_pha <= S_ch1_pha; end else begin S_ch0_cos <= S_ch0_cos; S_ch0_sin <= S_ch0_sin; S_ch0_pha <= S_ch0_pha; S_ch1_cos <= m_axis_data_tdata[15:0]; S_ch1_sin <= m_axis_data_tdata[31:16]; S_ch1_pha <= m_axis_phase_tdata; end endmodule
`timescale 1ns / 1ps module dds_cfg_tb(); reg aclk ='d0 ; reg aresetn ='d0 ; reg s_axis_config_tvalid ='d0 ; reg [ 31: 0] s_axis_config_tdata ={{16'd1310},{16'd1310}} ; //16'd1310 对应频率:1310*aclk频率/2^16;本例大概10MHz //对应相位:1310*2π/2^16 * 180/π ,大概2.29 reg s_axis_config_tlast ='d0 ; wire m_axis_data_tvalid ; wire [ 31: 0] m_axis_data_tdata ; wire m_axis_phase_tvalid ; wire [ 31: 0] m_axis_phase_tdata ; always #1 aclk = ~aclk; initial begin #100; aresetn = 1'b1; end reg [10:0] S_clk_cnt; always @(posedge aclk) if (~aresetn) S_clk_cnt <= 'd2; //初始值设置大于1的数,等待tdata等信号配置完成,设置0输出波形会为直线 / 设为1,s_axis_config_tdata会在初始状态就开始自加 else S_clk_cnt <= S_clk_cnt+'d1; always @(posedge aclk) s_axis_config_tvalid <= ((S_clk_cnt == 0)||(S_clk_cnt == 1)); always @(posedge aclk) s_axis_config_tlast <= (S_clk_cnt == 1); always @(posedge aclk) if(s_axis_config_tvalid && S_clk_cnt == 1) s_axis_config_tdata <= s_axis_config_tdata + s_axis_config_tdata; //前期自加相位偏移,后期自加频率增加 dds_compiler_0 dds_compiler_0 ( .aclk(aclk), // input wire aclk .aresetn(aresetn), // input wire aresetn .s_axis_config_tvalid(s_axis_config_tvalid), // 数据有效信号,该信号拉高时,会同步一次tdata的数据,从而改变波形 .s_axis_config_tdata(s_axis_config_tdata), // 配置数据总线,位 [31:16]:频率控制字,位 [15:0]:相位偏移 .s_axis_config_tlast(s_axis_config_tlast), // 该信号拉高代表当前数据包传输完成 .m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid .m_axis_data_tdata(m_axis_data_tdata), // output wire [31 : 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 [15 : 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 ); reg S_ch0_valid ; //将通道1和通道2采样时间分开 reg [ 15: 0] S_ch0_cos ; reg [ 15: 0] S_ch0_sin ; reg [ 15: 0] S_ch0_pha ; reg [ 15: 0] S_ch1_cos ; reg [ 15: 0] S_ch1_sin ; reg [ 15: 0] S_ch1_pha ; always @(posedge aclk ) if (!aresetn) begin S_ch0_valid <= 1'b1; end else begin S_ch0_valid <= ~S_ch0_valid; end always @(posedge aclk ) if (S_ch0_valid) begin S_ch0_cos <= m_axis_data_tdata[15:0]; S_ch0_sin <= m_axis_data_tdata[31:16]; S_ch0_pha <= m_axis_phase_tdata; S_ch1_cos <= S_ch1_cos; S_ch1_sin <= S_ch1_sin; S_ch1_pha <= S_ch1_pha; end else begin S_ch0_cos <= S_ch0_cos; S_ch0_sin <= S_ch0_sin; S_ch0_pha <= S_ch0_pha; S_ch1_cos <= m_axis_data_tdata[15:0]; S_ch1_sin <= m_axis_data_tdata[31:16]; S_ch1_pha <= m_axis_phase_tdata; end endmodule