1. 项目背景与核心价值
在电子工程和通信系统开发中,高质量的信号源是不可或缺的基础工具。传统模拟信号发生器虽然稳定可靠,但在频率切换速度、相位连续性和波形灵活性方面存在明显局限。而基于直接数字频率合成(DDS)技术的信号发生器,凭借其频率分辨率高、切换速度快、相位可编程等优势,正逐步成为现代测试测量领域的主流选择。
这次的设计之旅,我选择了Xilinx Artix-7系列FPGA作为硬件平台,主要考虑到其内置的DSP Slice资源丰富,时钟管理单元完善,能够很好地满足DDS设计的性能需求。整个项目从DDS数学原理推导开始,到Verilog代码实现,最后通过PmodDA4数模转换模块输出实际波形,完整呈现了一个可实际工作的信号发生器开发全流程。
2. DDS核心原理剖析
2.1 相位累加器:DDS的心脏
DDS技术的核心在于相位累加器的工作机制。这个32位宽的寄存器每个时钟周期都会累加一个频率控制字(FTW),其数学表达为:
code复制相位累加值 = (当前相位值 + FTW) mod 2^32
这里的关键在于理解FTW与输出频率的关系。假设系统时钟为100MHz,要生成1MHz的正弦波,FTW的计算公式为:
code复制FTW = (期望频率 × 2^32) / 系统时钟频率
= (1MHz × 4294967296) / 100MHz
= 42949672.96 ≈ 42949673
2.2 波形查找表设计技巧
相位累加器输出的高N位作为查找表地址,常见的N取值在10-14位之间。我在设计中采用了12位地址线,对应4096点的波形数据存储深度。这里有几个关键考量:
- 存储深度与资源消耗的平衡:12位地址在Artix-7 FPGA中正好可以充分利用Block RAM的存储结构
- 量化噪声控制:12位地址配合14位DAC输出,能保证足够低的谐波失真
- 预计算波形数据:通过MATLAB生成最优化的定点数波形数据,减少实时计算负担
查找表内容采用16位有符号数表示,其中1位符号位,15位数据位。这种配置在动态范围和分辨率之间取得了良好平衡。
3. FPGA实现细节
3.1 时钟域处理方案
系统采用100MHz主时钟,但需要注意三个关键时钟域:
- 相位累加器时钟:100MHz,严格同步
- DAC接口时钟:通过MMCM生成25MHz,与主时钟异步
- 控制接口时钟:UART的115200波特率,完全异步
针对这种情况,我采用了以下同步策略:
- 对FTW等控制参数使用两级触发器同步
- DAC数据接口采用异步FIFO进行时钟域隔离
- UART接收端使用过采样技术保证稳定性
3.2 关键Verilog模块解析
verilog复制module dds_core (
input wire clk,
input wire reset,
input wire [31:0] ftw,
output reg [15:0] dac_data
);
reg [31:0] phase_accum;
wire [11:0] lut_addr;
reg [15:0] sine_lut [0:4095];
// 相位累加器
always @(posedge clk or posedge reset) begin
if (reset)
phase_accum <= 32'd0;
else
phase_accum <= phase_accum + ftw;
end
assign lut_addr = phase_accum[31:20]; // 取高12位作为查找表地址
// 波形输出
always @(posedge clk) begin
dac_data <= sine_lut[lut_addr];
end
// 初始化查找表
initial begin
$readmemh("sine_table.hex", sine_lut);
end
endmodule
这个核心模块体现了几个重要设计选择:
- 采用同步复位确保确定性
- 相位累加器位宽为32位,保证足够频率分辨率
- 查找表通过$readmemh初始化,便于预计算波形
4. 数模转换与输出调理
4.1 PmodDA4接口实现
Digilent PmodDA4是一款性价比较高的12位DAC模块,通过SPI接口与FPGA通信。在实际使用中需要注意:
- 时序要求:SCLK最大50MHz,建立保持时间需严格遵守
- 电压基准:使用外部2.5V精密基准源替代板载基准
- 输出缓冲:必须配置轨到轨运放缓冲器,避免直接驱动负载
我的SPI接口实现采用了状态机设计,确保即使在FPGA主时钟较高的情况下,也能可靠地满足DAC的时序要求。
4.2 输出滤波器设计
DDS输出的阶梯状波形包含大量高频噪声,必须通过低通滤波器进行平滑。根据奈奎斯特准则,100MHz时钟下,输出信号最高频率应限制在40MHz以下。我选择了7阶椭圆滤波器,关键参数:
- 截止频率:0.4 × 系统时钟 = 40MHz
- 阻带衰减:>60dB @ 60MHz
- 通带纹波:<0.1dB
实际测试显示,该滤波器能将带外噪声降低约55dB,完全满足一般测试需求。
5. 性能优化技巧
5.1 杂散抑制方法
DDS输出中常见的杂散来源及对策:
-
相位截断误差:
- 增加相位累加器位宽(本设计采用32位)
- 采用相位抖动技术
-
幅度量化误差:
- 增加DAC分辨率(本设计实际使用14位有效输出)
- 优化查找表数据分布
-
DAC非线性:
- 精心设计PCB布局,减少数字噪声耦合
- 使用差分输出降低偶次谐波
5.2 动态性能提升
通过实测发现,当频率控制字变化时,输出信号会出现瞬时毛刺。解决方法:
- 双缓冲FTW寄存器:先写入影子寄存器,在相位累加器回零时同步切换
- 相位连续切换算法:计算新旧相位差,保持相位累加器连续性
- 增加输出静默期:在频率切换时短暂关闭DAC输出
6. 实测结果与分析
使用Rigol DS1104Z示波器对输出信号进行测试,主要指标如下:
| 测试项目 | 指标值 | 测试条件 |
|---|---|---|
| 频率范围 | 1Hz - 40MHz | 正弦波输出 |
| 频率分辨率 | 0.023Hz | 32位相位累加器 |
| 谐波失真 | < -65dBc | 1MHz输出 |
| 相位噪声 | -125dBc/Hz @ 10kHz | 10MHz载波 |
| 频率切换时间 | < 50ns | 任意频率切换 |
特别值得注意的是,通过优化查找表内容和采用14位有效DAC输出,在1MHz输出时实现了-65dBc的谐波失真性能,这已经接近中端商用信号发生器的水平。
7. 扩展功能实现
7.1 多波形支持
在基础正弦波基础上,通过修改查找表内容,可以轻松实现其他波形:
- 方波:查找表仅输出最大值和最小值
- 三角波:线性递增/递减的查找表
- 任意波形:通过PC软件生成自定义波形数据
为节省存储资源,我设计了一个波形选择模块,可以根据控制信号动态切换查找表内容。
7.2 调幅与调频功能
通过修改核心算法,可以实现基本的调制功能:
verilog复制// AM调制实现
wire [15:0] am_output = (carrier * (16'sh7FFF + modulation)) >>> 15;
// FM调制实现
wire [31:0] modulated_ftw = ftw + (fm_deviation * modulation);
实际测试显示,该系统能实现深度达90%的AM调制,以及最大±10%的FM调制。
8. 常见问题与解决方案
8.1 输出信号幅度不稳定
可能原因及对策:
- 电源噪声:增加LC滤波网络,使用低噪声LDO
- 基准电压漂移:采用带温度补偿的基准源
- PCB布局问题:确保模拟和数字地适当分离
8.2 高频输出失真严重
典型解决方案:
- 检查滤波器截止频率是否合适
- 确认DAC输出建立时间是否足够
- 降低输出频率或提高系统时钟
8.3 SPI通信失败
排查步骤:
- 用逻辑分析仪捕获SPI信号
- 检查片选信号极性设置
- 验证时钟相位和极性配置
- 测量DAC供电电压是否正常
9. 项目优化方向
经过完整的设计和测试周期,我认为这个DDS信号发生器还有以下改进空间:
- 增加直接数字合成模式,支持更复杂的调制方式
- 实现多通道同步输出,满足MIMO系统测试需求
- 添加自动校准功能,补偿温度和老化带来的参数漂移
- 开发上位机控制软件,提供更友好的用户界面
这个项目最让我满意的部分是相位累加器的优化设计,通过合理的位宽选择和同步机制,在有限的FPGA资源下实现了极高的频率分辨率。在实际调试过程中,花费最多时间的是DAC接口的时序收敛问题,最终通过插入适当的寄存器级数解决了这一难题。