目录

  1. 引言
  2. DDS 基本概念
  3. DDS 硬件实现
  4. Verilog DDS 代码实现
  5. 优化方案
  6. 参考资料

引言

直接数字频率合成(Direct Digital Synthesis, DDS) 是一种基于 查找表(LUT) 方式生成 正弦波、方波 等波形的技术。DDS 具有以下特点:

  • 高频率分辨率:通过相位累加器调整频率
  • 快速频率转换:可实现频率、相位调制(如 FSK、PSK)
  • 适用于 FPGA/ASIC:可使用 BRAM、ROM 存储波形数据

应用领域:

  • 通信系统(无线电、雷达)
  • 数字音频合成
  • FPGA 频率发生器

本文介绍 Verilog 实现 DDS 的方法,并提供 完整代码示例


DDS 基本概念

3.1 相位累加器

相位累加器用于 控制输出波形的相位变化,核心公式如下:θ[n]=θ[n−1]+Δf

  • θ[n] 为当前相位
  • Δf 为 相位增量,决定输出频率

频率计算公式:fout=Δf⋅fclk2N

  • fclk:系统时钟
  • 2N:相位累加器位宽(如 N=16, 24, 32)

3.2 正弦查找表(LUT)

DDS 通过 LUT 存储预计算的正弦波数据,根据 相位值查询正弦值

示例:8 级相位 LUT

相位: 000 001 010 011 100 101 110 111
正弦值:  0  707 1000 707  0  -707 -1000 -707

存储格式:

reg signed [15:0] sine_table [0:255];  // 256 级 LUT


3.3 频率控制

改变 相位步进值,即可 调整输出频率

  • 增大 Δf → 提高输出频率
  • 减小 Δf → 降低输出频率
reg [23:0] phase_step = 24'h200000; // 设定频率


Verilog DDS 代码实现

module dds #(
    parameter PHASE_WIDTH = 24,  // 相位累加器位宽
    parameter LUT_SIZE = 256,  // 正弦查找表大小
    parameter DATA_WIDTH = 16  // 波形输出位宽
)(
    input clk,  // 时钟
    input rst,  // 复位
    input [PHASE_WIDTH-1:0] freq_step,  // 频率控制字
    output reg signed [DATA_WIDTH-1:0] sine_out  // 正弦波输出
);

    // 相位累加器
    reg [PHASE_WIDTH-1:0] phase_acc = 0;

    // 正弦查找表(预存 256 点正弦值)
    reg signed [DATA_WIDTH-1:0] sine_lut [0:LUT_SIZE-1];

    // 初始化正弦波表
    integer i;
    initial begin
        for (i = 0; i < LUT_SIZE; i = i + 1) begin
            sine_lut[i] = $sin(2 * 3.14159265358979 * i / LUT_SIZE) * (1 << (DATA_WIDTH-1));
        end
    end

    always @(posedge clk or posedge rst) begin
        if (rst) begin
            phase_acc <= 0;
            sine_out <= 0;
        end else begin
            // 相位累加
            phase_acc <= phase_acc + freq_step;

            // 查找表取值(使用高位地址)
            sine_out <= sine_lut[phase_acc[PHASE_WIDTH-1 -: 8]];
        end
    end

endmodule


优化方案

1. 优化 LUT 存储

  • 减少存储空间:只存 0~90° 数据,利用 对称性 计算:case (quadrant) 2'b00: sine_value = sine_table[index]; // 0-90° 2'b01: sine_value = sine_table[255-index]; // 90-180° 2'b10: sine_value = -sine_table[index]; // 180-270° 2'b11: sine_value = -sine_table[255-index]; // 270-360° endcase
  • 用 ROM 存 LUT,减少 FPGA 逻辑资源消耗。

2. 动态调整频率

  • 通过 输入控制 freq_step,实现 可变频 DDS
always @(posedge clk) begin
    if (freq_up) freq_step <= freq_step + 24'h1000; // 频率增加
    if (freq_down) freq_step <= freq_step - 24'h1000; // 频率减少
end


3. CORDIC 计算替代查找表

  • 使用 CORDIC 算法计算正弦值,不需要 LUT,减少存储需求:sine_out <= cordic_sin(phase_acc); 适用于 FPGA DSP 资源优化设计

4. 支持不同波形输出

  • 生成 方波、三角波、锯齿波square_wave = (phase_acc[PHASE_WIDTH-1]) ? 16'h7FFF : 16'h8000; sawtooth_wave = phase_acc[PHASE_WIDTH-1 -: DATA_WIDTH]; triangle_wave = (phase_acc[PHASE_WIDTH-1]) ? ~phase_acc[PHASE_WIDTH-2 -: DATA_WIDTH] : phase_acc[PHASE_WIDTH-2 -: DATA_WIDTH];

参考资料

  1. Xilinx DDS Compiler IP
  2. Intel FPGA DDS
  3. ASIC-World: Verilog DDS
  4. CORDIC Algorithm Overview