1. 项目背景与核心价值
去年调试一个射频模块时,我发现自己需要一组特定频率和波形的测试信号。市面上的信号发生器要么功能单一,要么价格昂贵,于是萌生了用FPGA自制信号发生器的想法。这个项目最吸引人的地方在于,它完美结合了数字逻辑设计与模拟信号处理的边界——通过纯数字方式生成模拟世界需要的各种波形。
FPGA(现场可编程门阵列)在这个项目中展现出独特优势:它既具备ASIC的并行处理能力,又保留了软件的可编程特性。这意味着我们可以用硬件描述语言(如Verilog或VHDL)设计出能够实时生成复杂波形的数字电路,同时保持灵活的参数调整能力。与基于MCU的方案相比,FPGA方案在时序精度和输出带宽上有着数量级的提升。
2. 硬件架构设计
2.1 核心模块划分
整个系统采用典型的数字信号处理流水线结构:
- 相位累加器:32位精度,负责产生线性递增的相位值
- 波形查找表:预存一个完整周期的波形数据(正弦波常用1024点)
- DAC接口控制器:将数字样本转换为模拟信号的关键桥梁
- 配置寄存器组:接收外部控制参数(频率、波形类型等)
我选用的FPGA开发板是Xilinx Artix-7系列,配套的PmodDA3模块提供双通道12位DAC,足够产生0-5MHz的高质量信号。这个组合在成本和性能间取得了很好的平衡——整套硬件成本控制在千元以内,却能实现商用仪器级别的信号质量。
2.2 关键参数计算
输出频率的精度由相位累加器位数决定。采用32位累加器时,频率分辨率计算公式为:
code复制Δf = f_clk / 2^N (N=32)
当系统时钟f_clk=100MHz时,理论分辨率达到惊人的0.023Hz!实际应用中,我们还需要考虑DAC的建立时间和FPGA的布线延迟。经过实测,在输出1MHz正弦波时,相位噪声优于-80dBc/Hz,完全满足大多数射频测试需求。
3. Verilog实现详解
3.1 相位累加器设计
verilog复制module phase_accumulator (
input clk,
input rst,
input [31:0] freq_tuning_word,
output reg [31:0] phase_out
);
always @(posedge clk or posedge rst) begin
if (rst)
phase_out <= 32'd0;
else
phase_out <= phase_out + freq_tuning_word;
end
endmodule
这个看似简单的模块却是整个系统的核心。freq_tuning_word相当于数字"频率旋钮",其值由目标频率f_out计算得出:
code复制FTW = f_out * 2^32 / f_clk
3.2 波形查找表优化
正弦波查找表采用对称存储策略,只需存储0-π/2的1/4周期数据,其他象限通过相位映射实现。这使ROM资源消耗减少75%:
verilog复制// 256点正弦查找表(仅存储第一象限)
reg [11:0] sin_lut [0:255];
always @(*) begin
case (phase_out[31:24])
8'h00: data_out = sin_lut[addr];
8'h01: data_out = sin_lut[255-addr];
8'h02: data_out = -sin_lut[addr];
8'h03: data_out = -sin_lut[255-addr];
endcase
end
对于方波和三角波这类简单波形,我直接采用算法生成而非查找表,进一步节省存储资源。特别是方波生成,只需比较相位累加器最高位即可:
verilog复制assign square_wave = phase_out[31] ? 12'hFFF : 12'h000;
4. DAC接口与信号调理
4.1 时序同步设计
PmodDA3采用SPI接口,需要严格满足建立保持时间。我设计了一个状态机来协调数据转换:
verilog复制localparam IDLE = 2'b00;
localparam LOAD = 2'b01;
localparam XFER = 2'b10;
always @(posedge clk) begin
case(state)
IDLE: if (new_sample_ready) state <= LOAD;
LOAD: begin
dac_data <= waveform_out;
state <= XFER;
end
XFER: if (spi_done) state <= IDLE;
endcase
end
4.2 模拟滤波设计
DAC输出的阶梯状波形需要经过抗镜像滤波。我采用两级巴特沃斯滤波器:
- 第一级:截止频率=10MHz的RC低通
- 第二级:截止频率=5MHz的有源滤波器
这个组合有效抑制了采样带来的高频噪声,实测在5MHz带宽内谐波失真低于-60dB。特别提醒:滤波器的群延迟会影响脉冲信号的时序精度,在测试数字信号时需要绕过滤波器。
5. 实测性能与优化技巧
5.1 频率精度验证
使用频率计测量输出1MHz信号,连续采样1小时显示频率漂移小于0.1ppm。这个稳定性主要得益于:
- FPGA内部使用锁相环生成系统时钟
- 相位累加器的全数字实现
- 恒温晶振提供的参考时钟
5.2 常见问题排查
问题1:高频输出失真严重
- 检查DAC的建立时间是否满足
- 降低系统时钟频率测试
- 确认输出负载阻抗匹配(建议50Ω)
问题2:相位不连续
- 确保频率参数更新时同步复位相位累加器
- 检查时序约束是否满足(set_false_path跨时钟域)
问题3:底噪过大
- 加强电源滤波(建议使用π型滤波器)
- 检查地回路布局(星型接地最佳)
- 降低DAC输出幅度(满幅输出时失真较大)
6. 功能扩展方向
这个基础框架可以扩展出许多实用功能:
- 扫频模式:通过自动调整FTW实现线性/对数扫频
- 调制功能:添加AM/FM/PM调制模块
- 任意波形:用BRAM存储用户自定义波形
- 网络接口:通过Ethernet或WiFi远程控制
我最近添加的扫频功能特别实用,代码实现也很简洁:
verilog复制// 线性扫频控制器
always @(posedge sweep_clk) begin
if (sweep_en) begin
if (curr_ftw >= end_ftw)
curr_ftw <= start_ftw;
else
curr_ftw <= curr_ftw + sweep_step;
end
end
配合Python脚本控制,可以自动完成器件的频率响应测试,比手动调节效率提升十倍不止。这种软硬结合的方式,正是FPGA项目的魅力所在。