关于DDS IP核的使用说明和参数配置可参考这篇文章:Xilinx DDS IP核 配置及使用方法

1、创建好Vivado工程后,打开IP Catalog,搜索DDS,选择DDS Compiler IP核。双击打开进入配置界面:
在这里插入图片描述
2、进入Configuration配置界面

  • Configuration Options配置为phase generator and sin cos LUT
  • 系统时钟配置为100MHz
  • 操作模式配置为标准模式
  • 参数配置为使用系统参数
  • SFDR配置为48(6*N,N为正余弦波形数据输出位宽,如果只输出正弦波或余弦波,则输出数据位宽为8;如果同时输出正弦波和余弦波,则输出数据位宽为16,高8位为正弦波形数据,低8位为余弦波形数据)
  • 频率分辨率计算方法:Frequency resolution = f_clk / (2^N) ,其中N为相位位宽,相位位宽越大,频率分辨率越高,分辨率越精确,可调输出频率越精确,相位位宽越大,相位累加器和相位-幅度转换表(ROM)的资源消耗也会增加。尤其是ROM的大小会随着相位位宽(用于寻址的位数)的增加而指数增长。通常,DDS的相位位宽设置为24位到48位之间,这里相位位宽使用32进行计算。设置频率分辨率Frequency resolution = 100M / (2^32) = 0.023283064365386962890625。
  • 噪声整形配置为自动
    在这里插入图片描述
    3、Implementation 界面配置
  • 要实现输出任意频率的正余弦波,Phase increment programmability(相位增量可编程性)配置为可编程
  • Phase offset programmability(相位偏移可配置性)配置为None,无相位偏移
  • 输出选择正余弦同时输出
  • 其余保持默认即可
    在这里插入图片描述
    4、Detials Implementation 界面配置
    在AXI Channel options下可以选择 output tready(输出正余弦数据有效信号)输出引脚,其余设置保持默认即可。
    在这里插入图片描述
    5、Output Frequencies输出频率设置
    根据之前选择为单通道输出,为了输出任意频率之前选择相位增量可编程模式,输出频率由相位增量决定,这里不设置输出频率。
    在这里插入图片描述
    6、查看配置总结,确认无误后点击OK生成IP核
    在这里插入图片描述
    在这里插入图片描述
    7、在工程目录下找到例化模板进行例化
    在这里插入图片描述
    8、添加仿真文件查看IP核输出的正余弦波形
    相位增量计算方法:相位增量 = 输出波形频率 * 2^N / 系统时钟频率,N为相位位宽
    dds_wave.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/09/30 14:36:09
// Design Name: 
// Module Name: dds_wave
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module dds_wave(
    input           sysclk              ,
    input           sysrstn             ,
    input  [31:0]   phase_crement       ,    //  相位增量
    input           phase_crement_valid      //  相位增量有效
);

reg             s_axis_config_tvalid  ;
wire            s_axis_config_tready  ;
reg    [31:0]   s_axis_config_tdata   ;
wire            m_axis_data_tvalid    ;
wire    [15:0]  m_axis_data_tdata     ;
wire            m_axis_phase_tvalid   ;
wire    [31:0]  m_axis_phase_tdata    ;

wire  signed  [7:0]   sin                   ;
wire  signed  [7:0]   cos                   ;

dds_sin_cos u_dds_sin_cos (
  .aclk                 ( sysclk                ),                                  // 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

  .m_axis_data_tvalid   ( m_axis_data_tvalid    ),      // 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     ),        // output wire [15 : 0] m_axis_data_tdata

  .m_axis_phase_tvalid  ( m_axis_phase_tvalid   ),    // 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    )      // output wire [31 : 0] m_axis_phase_tdata
);

always @(posedge sysclk or posedge sysrstn ) begin
  if(!sysrstn)begin
    s_axis_config_tvalid <= 1'b0  ;
    s_axis_config_tdata <= 32'd0  ;
  end
  else if(s_axis_config_tready && phase_crement_valid)begin
    s_axis_config_tvalid <= phase_crement_valid ;
    s_axis_config_tdata <= phase_crement  ;
  end
end

assign sin =  m_axis_data_tvalid ? {~m_axis_data_tdata[7],m_axis_data_tdata[6:0]} : 8'd0;   //  DDS输出的数据是二进制补码形式,所以需要最高位取反
assign cos =  m_axis_data_tvalid ? {~m_axis_data_tdata[15],m_axis_data_tdata[14:8]} : 8'd0;

endmodule

仿真测试文件dds_tb.v

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2025/09/30 14:47:15
// Design Name: 
// Module Name: dds_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module dds_tb();

reg             sysclk              ;
reg             sysrstn             ;
reg   [31:0]    phase_crement       ;
reg             phase_crement_valid ;

dds_wave u_dds_wave(
    /*input           */.sysclk              ( sysclk               ),
    /*input           */.sysrstn             ( sysrstn              ),
    /*input           */.phase_crement       ( phase_crement        ),    //  相位增量
    /*input           */.phase_crement_valid ( phase_crement_valid  )     //  相位增量有效
);

parameter T_CLK = 10    ;

always # (T_CLK / 2) sysclk = ~sysclk ;

initial begin
    sysclk = 1'b1   ;
    sysrstn = 1'b1  ;
    #(T_CLK * 10);
    sysrstn = 1'b0  ;
    #(T_CLK * 15);
    sysrstn = 1'b1  ;
end

initial begin
    phase_crement = 32'd0    ;
    phase_crement_valid = 1'b0 ;
    #(T_CLK * 30);
    phase_crement = 32'h028F_5C29  ;        //  1M
    phase_crement_valid = 1'b1 ;   
    #(T_CLK * 2000);
    phase_crement = 32'h0CCC_CCCD ;   //  5M
    #(T_CLK * 2000);
    phase_crement = 32'h1999_999A ;   //  1M
    #(T_CLK * 2000);
    phase_crement_valid = 32'd0 ;
    $finish ;
end

endmodule

在这里插入图片描述
注意:由于DDS输出数据是二进制补码形式,所以需要在数据最高位取反,否则显示不是正常的正余弦波形。
在这里插入图片描述

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐