尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

FPGA实现Sigma-Delta DAC:从噪声整形原理到高精度音频信号生成

FPGA实现Sigma-Delta DAC:从噪声整形原理到高精度音频信号生成 1. 项目概述从“噪声”中提炼高精度信号在数字信号处理的世界里我们常常面临一个核心矛盾如何用有限的数字资源去逼近无限连续的模拟世界。传统的数模转换器DAC比如R-2R电阻网络型其精度直接受限于电阻的匹配精度和位数。想要16位精度那对电阻匹配度的要求就高得吓人成本也直线上升。而Sigma-DeltaΣ-Δ转换器则提供了一种截然不同的思路——它不追求每一位的绝对精确而是玩起了“统计学”和“噪声整形”的游戏。简单来说Sigma-Delta DAC的核心思想是“过采样”和“噪声整形”。它用一个很低的精度常常是1位即只有0和1两种输出的量化器以远高于目标信号频率奈奎斯特频率的速率疯狂采样。然后通过巧妙的反馈环路结构将量化过程中产生的噪声量化误差“推”到高频区域。最后只需要一个简单的模拟低通滤波器就能把高频噪声滤掉留下我们想要的高精度、低频模拟信号。这就好比你要从一堆沙子里筛出金粉传统方法是努力提高每粒沙子的纯度高精度电阻而Sigma-Delta则是把整座沙山高速过筛过采样并通过特殊方法让金粉都沉在底层噪声整形到高频最后轻松扫掉表面的沙子低通滤波得到纯净的金粉。这个项目就是带你从理论到实践完整地走一遍Sigma-Delta DAC的设计与实现之路。我们会聚焦于用数字硬件描述语言如Verilog在FPGA上实现数字部分并探讨其与后端模拟滤波器的接口。无论你是正在学习数字信号处理的在校学生还是希望在产品中应用低成本、高精度音频或传感器信号生成的工程师亦或是FPGA开发爱好者这篇内容都将提供一套可直接复现的“蓝图”。你会发现用FPGA实现一个24位甚至更高有效位数的音频DAC其核心逻辑可能只需要几百行代码。2. Sigma-Delta调制器的核心原理拆解要理解Sigma-Delta DAC必须先吃透其心脏——Sigma-Delta调制器。它不是一个简单的ADC或DAC而是一个将高精度、低频的数字输入转换为低精度、高频的数字比特流Bitstream的装置。对于DAC应用这个比特流最终通过一个开关如MOSFET驱动模拟滤波器产生模拟电压。2.1 过采样提升信噪比的基础根据香农采样定理只要采样频率高于信号最高频率的两倍就能无失真地恢复信号。这个两倍的频率点称为奈奎斯特频率f_N。传统转换器工作在这个临界点附近。Sigma-Delta调制器首先进行过采样Oversampling。假设目标信号带宽为f_B我们选择一个过采样率OSR使得采样频率f_s OSR * 2 * f_B。例如对于20kHz的音频信号奈奎斯特频率是40kHz。如果OSR64那么f_s就是2.56MHz。过采样直接带来一个好处量化噪声的总功率是固定的取决于量化步长但过采样将这固定功率的噪声频谱分布到了更宽的频率范围0 到 f_s/2内。因此在我们关心的信号带宽0 到 f_B内噪声的功率密度就降低了。理论分析表明仅凭过采样每加倍OSR信噪比SNR就能提升3dB相当于有效位数ENOB增加约0.5位。注意这里的“信噪比提升”是相对于整个奈奎斯特带宽而言的。单纯过采样并不能改变总噪声功率只是把噪声“稀释”到了更宽的频带上。2.2 噪声整形将噪声“赶”到高频区单纯过采样带来的收益有限。Sigma-Delta的魔法在于“噪声整形”。它通过一个包含积分器Σ和反馈环路的结构来实现。以一个经典的一阶Sigma-Delta调制器为例它包含一个减法器、一个积分器、一个1位量化器实际上就是一个比较器和一个1位DAC实际上就是选择正或负参考电压构成的反馈环路。积分将输入信号与反馈信号的差值进行累加积分。量化对积分器的输出进行1位量化产生比特流例如正为1负为0。反馈将这个1位输出通过一个1位DAC选择Vref或-Vref反馈回输入端与下一个输入值相减。这个反馈环路的妙处在于它构成了一个针对量化误差的负反馈系统。量化器本身的非线性特性被“掩盖”了系统传递函数对输入信号是低通的而对量化噪声却是高通的。这意味着量化噪声的能量被“整形”到了高频区域在低频段信号带宽内的噪声被极大地抑制了。一阶噪声整形的理论效果是在信号带宽内噪声功率谱密度以20dB/十倍频程的斜率上升。结合过采样其信噪比提升为SNR ≈ 6.02N 1.76 - 5.17 30log10(OSR) [dB]其中N为量化器位数1位时N1。可以看到信噪比随OSR的对数增长每加倍OSRSNR提升9dB相当于1.5位比单纯过采样3dB强得多。高阶如二阶、三阶调制器使用多个积分器可以实现更陡峭的噪声整形斜率如40dB/dec 60dB/dec从而在相同的OSR下获得更高的信噪比和动态范围。但高阶系统面临稳定性问题需要精心设计系数。2.3 关键参数与设计权衡在设计Sigma-Delta调制器时我们需要在几个关键参数间做权衡阶数Order积分器的数量。阶数越高噪声整形效果越强但系统稳定性越差设计越复杂。过采样率OSR采样频率与两倍信号带宽的比值。OSR越高性能越好但对数字电路的工作频率要求也越高。量化器位数最常见的是1位两电平量化。1位量化器本质上是线性的只有两个输出点完美避免了多位数模转换中的非线性失配问题但需要更高的OSR来达到高精度。也可以使用多位量化器来降低对OSR的要求但会引入多位DAC的元件失配问题通常需要配合动态元件匹配DEM等技术。稳定性对于高于2阶的系统必须确保在任何输入下系统都不会饱和积分器溢出。这通常通过仿真、加入稳定化电路如钳位或使用特定的调制器结构如带前馈路径的CIFB结构来实现。对于大多数音频和中等精度传感器应用一个二阶或三阶的1位Sigma-Delta调制器已经足够在合理的OSR如64或128下实现超过16位96dB以上的动态范围。3. 数字部分设计与FPGA实现我们将以一个目标为16位精度、20kHz带宽的音频DAC为例设计一个二阶1位Sigma-Delta调制器并在FPGA上用Verilog实现。3.1 系统架构与指标确定首先明确目标信号带宽f_B: 20 kHz目标动态范围DR: 96 dB (约16位ENOB)过采样率OSR: 选择128。则采样频率 f_s OSR * 2 * f_B 128 * 40 kHz 5.12 MHz。调制器阶数: 选择二阶。其理想信噪比公式1位量化为SNR ≈ 6.021 1.76 - 12.9 50log10(OSR)。代入OSR128计算SNR ≈ 6.02 1.76 - 12.9 50log10(128) ≈ -5.12 502.107 100.23 dB。这远超我们的96dB目标留有充足裕量。输入数据格式: 假设输入是16位有符号整数范围-32768到32767。我们需要在调制器内部使用更高位宽的寄存器来处理积分累加防止溢出。3.2 二阶调制器的差分方程与系数设计我们采用最经典的二阶反馈SOFB结构。其信号流图包含两个离散时间积分器、两个反馈系数a1, a2和一个前向系数b0。经过简化和系数缩放一个稳定且常用的系数集是a10.5, a20.5, b01.0对于1位量化器b0通常归一化为1。由此我们可以写出系统的差分方程。设输入为x[n]两个积分器的状态为v1[n], v2[n]输出为y[n]取值为1或-1对应比特流的1和0。v1[n] v1[n-1] (x[n-1] - y[n-1])// 第一个积分器反馈系数隐含为1v2[n] v2[n-1] v1[n] - 0.5*y[n-1]// 第二个积分器包含来自第一个积分器的输入和部分反馈y[n] sign( v2[n] )// 1位量化sign为符号函数输出1或-1实操心得系数0.5在数字电路中可以通过右移一位来实现避免了乘法器节省资源。这是硬件实现中一个重要的优化点。3.3 Verilog代码实现详解下面是一个在FPGA中实现上述二阶调制器的Verilog模块。我们使用有符号数运算并预留足够的位宽防止溢出。module sigma_delta_dac_2nd_order #( parameter INPUT_WIDTH 16, // 输入数据位宽 parameter ACC_WIDTH 24 // 累加器位宽必须大于INPUT_WIDTHlog2(OSR)以应对累加溢出 )( input wire clk, // 主时钟频率5.12MHz input wire rst_n, // 异步低电平复位 input wire signed [INPUT_WIDTH-1:0] data_in, // 有符号输入数据 output reg dac_bit // 1位比特流输出驱动外部开关 ); // 内部寄存器声明 reg signed [ACC_WIDTH-1:0] v1_reg, v1_next; // 第一积分器状态 reg signed [ACC_WIDTH-1:0] v2_reg, v2_next; // 第二积分器状态 reg signed [ACC_WIDTH-1:0] feedback; // 反馈量根据输出y计算 wire signed [ACC_WIDTH-1:0] data_in_ext; // 符号扩展后的输入 // 将输入数据符号扩展到累加器位宽 assign data_in_ext {{(ACC_WIDTH-INPUT_WIDTH){data_in[INPUT_WIDTH-1]}}, data_in}; // 根据当前输出计算反馈值 (对应 1 或 -1) // 假设输出1对应 Full Scale, 输出0对应 -Full Scale。 // 在数字域我们用 M 和 -M 来表示M是一个合适的幅度系数。 // 为简化令M等于输入满量程的一半例如 2^(INPUT_WIDTH-1) 32768 (对于16位)。 localparam signed [ACC_WIDTH-1:0] FSCALE_POS 32768; // 对应输出为1 localparam signed [ACC_WIDTH-1:0] FSCALE_NEG -32768; // 对应输出为0 always (*) begin // 计算反馈值 feedback (dac_bit) ? FSCALE_POS : FSCALE_NEG; // 组合逻辑计算下一状态 (差分方程实现) v1_next v1_reg data_in_ext - feedback; // 第一个积分器v1[n] v1[n-1] x[n] - y[n-1] // 注意这里我们用了当前的data_in和上一拍的feedback是时序上的一个细节处理。 // 更严格的模型可能需要对齐时序。这里是一种常用简化。 v2_next v2_reg v1_next - (feedback 1); // 第二个积分器v2[n] v2[n-1] v1[n] - 0.5*y[n-1] // 右移一位实现乘以0.5 end // 时序逻辑寄存器更新 always (posedge clk or negedge rst_n) begin if (!rst_n) begin v1_reg 0; v2_reg 0; dac_bit 0; end else begin v1_reg v1_next; v2_reg v2_next; // 量化器判断v2_next的符号位 dac_bit ~v2_next[ACC_WIDTH-1]; // 最高位为符号位0正1负。我们取反使得正数输出1。 end end endmodule代码关键点解析位宽选择ACC_WIDTH累加器位宽至关重要。它必须足够大以容纳积分器在最大输入下的累加值而不溢出。一个保守的估计是INPUT_WIDTH ceil(log2(OSR * 调制器阶数))。这里选择24位对于16位输入和OSR128是安全的。符号扩展将输入的16位有符号数正确扩展到24位保持其数值和符号。反馈系数实现feedback 1是算术右移一位等价于除以2乘以0.5这是硬件友好的操作。时序对齐示例代码是一种简化。在实际中需要仔细安排数据流时序确保data_in在时钟边沿稳定并且与反馈计算对齐。通常我们会使用流水线寄存器来确保时序。量化器量化器只是简单地检查第二个积分器状态v2的符号位。输出dac_bit为1位直接连接到FPGA的IO引脚用于驱动外部的模拟开关如MOSFET。3.4 测试平台与仿真验证在烧录FPGA之前必须进行充分的仿真。我们需要编写一个Testbench输入一个正弦波或斜坡信号观察调制器的输出比特流和内部状态。timescale 1ns / 1ps module tb_sigma_delta_dac(); reg clk; reg rst_n; reg signed [15:0] data_in; wire dac_bit; // 实例化被测模块 sigma_delta_dac_2nd_order #(.INPUT_WIDTH(16), .ACC_WIDTH(24)) uut ( .clk(clk), .rst_n(rst_n), .data_in(data_in), .dac_bit(dac_bit) ); // 生成5.12MHz时钟 initial begin clk 0; forever #97.65625 clk ~clk; // 1/(5.12e6*2) ≈ 97.65625 ns end // 生成测试激励 integer i; real freq 1000.0; // 1kHz测试正弦波 real pi 3.1415926535; real fs 5120000.0; initial begin rst_n 0; data_in 0; #100 rst_n 1; // 释放复位 for (i0; i100000; ii1) begin // 生成一个1kHz的正弦波数字样本幅度为满量程的80% data_in $rtoi(0.8 * 32767.0 * $sin(2.0 * pi * freq * i / fs)); (posedge clk); // 每个时钟周期输入一个新样本 end $finish; end // 将输出波形和输入数据记录到文件便于用MATLAB等工具分析频谱 integer file_out; initial begin file_out $fopen(sd_output.txt, w); forever begin (posedge clk); $fwrite(file_out, %d %d\n, data_in, dac_bit); end end endmodule仿真后可以将sd_output.txt文件导入MATLAB或Python进行频谱分析验证在20kHz带宽内噪声基底是否被有效抑制信噪比是否达到预期目标。4. 模拟后端从比特流到平滑电压FPGA输出的高速1位比特流0和1本身是一个幅值在0V和3.3VFPGA IO电压之间跳变的数字信号。要得到平滑的模拟电压需要一个模拟后端电路通常包括一个开关驱动和一个低通滤波器。4.1 开关驱动与参考源最简单的驱动方式是将FPGA的IO引脚直接连接到一个MOSFET的栅极。MOSFET的漏极连接到一个正参考电压Vref如2.5V源极连接到负参考电压或地-Vref或0V。当比特流为1时MOSFET导通输出节点被拉到Vref为0时导通到-Vref。这就实现了一个1位DAC。参考电压源其精度和稳定性直接决定了整个DAC的绝对精度和温漂。对于音频应用可以使用专用的低噪声基准电压源芯片如ADR441、REF5025。开关选择需要选择导通电阻小、开关速度快的MOSFET或专用的模拟开关芯片。开关的非理想特性如导通电阻、电荷注入会引入失真。驱动强度FPGA的IO引脚驱动能力有限可能需要缓冲器如74HC04反相器并联来快速驱动MOSFET的栅极电容确保边沿陡峭减少开关损耗和时序误差。4.2 低通滤波器的设计与选型低通滤波器LPF的任务是滤除比特流中高频的噪声和采样频率成分保留带宽内的模拟信号。对于Sigma-Delta DAC这个滤波器通常被称为“重构滤波器”或“平滑滤波器”。关键指标截止频率f_c略高于信号带宽f_B例如22kHz或24kHz以保证通带平坦同时快速衰减。阻带频率从f_s/2开始对于OSR128, f_s/22.56MHz。滤波器需要在f_s/2处提供足够的衰减以抑制高频量化噪声。衰减要求在阻带处至少需要衰减掉被整形到高频的量化噪声使其不影响系统动态范围。通常要求阻带衰减大于系统动态范围目标如100dB。通带纹波应尽可能小0.1dB以免引起频率响应失真。群时延在音频应用中线性相位恒定群时延很重要以避免不同频率信号的相位失真。贝塞尔滤波器或线性相位FIR滤波器在数字域实现具有较好的相位特性但过渡带较缓。切比雪夫或椭圆滤波器衰减更快但相位非线性更严重。常用滤波器类型无源RC滤波器一阶或二阶简单便宜但衰减斜率慢-20dB/dec每阶要达到高衰减需要很高的阶数或极低的截止频率这会过度限制信号带宽。有源滤波器如Sallen-Key、多反馈MFB这是最常用的选择。使用运放和RC网络可以轻松实现二阶、四阶或更高阶的低通滤波。例如一个四阶巴特沃斯低通滤波器可以提供-80dB/dec的衰减在2.56MHz处可能有60-80dB的衰减对于许多应用已足够。LC滤波器适用于更高频率或需要极低噪声的应用但设计更复杂且电感可能引入非线性。设计示例二阶Sallen-Key低通滤波器 假设我们需要一个截止频率f_c24kHz的二阶巴特沃斯低通滤波器。巴特沃斯滤波器系数对于二阶是Q0.707。 选择电容C1C21nF标准值。 计算电阻 R1 R2 1 / (2 * π * f_c * C1) ≈ 1 / (2 * 3.1416 * 24000 * 1e-9) ≈ 6.63 kΩ。 选择最接近的标准值6.8kΩ。 运放选择低噪声、高带宽的音频运放如NE5532、OPA1612等。电源电压需覆盖预期的输出摆幅如±2.5V。注意事项模拟滤波器的元件电阻、电容精度和温漂会影响滤波器的截止频率和响应。对于高精度应用需选择1%甚至0.1%精度的薄膜电阻和C0G/NP0材质的电容。运放的输入失调电压、噪声和带宽也需要仔细考量。4.3 PCB布局与接地要点模拟电路的性能极度依赖于PCB布局地平面使用完整的接地平面为模拟部分提供低阻抗回流路径。电源去耦在每个运放和基准源的电源引脚附近放置一个0.1μF的陶瓷电容和一个10μF的钽电容或电解电容以滤除高频和低频噪声。信号分离将高速数字信号FPGA的比特流输出线远离敏感的模拟走线。如果必须交叉应垂直交叉。参考电压布线从基准源到开关和运放的参考电压走线应尽量短而粗减少寄生电阻和电感。滤波器元件布局将RC滤波网络的元件紧靠运放放置减少寄生电容的影响。5. 系统集成、测试与性能验证将FPGA数字模块、开关驱动和模拟滤波器连接起来就构成了完整的Sigma-Delta DAC系统。5.1 集成与调试步骤静态测试给FPGA输入一个固定的中值码如0用示波器观察DAC输出引脚。应该能看到一个占空比约为50%的方波因为输入为0输出平均值为0。测量其平均电压应接近0V。动态测试 - 时域输入一个满幅度的低频方波如1Hz。用示波器观察滤波器输出应该能看到一个平滑的、在正负满幅度之间切换的模拟波形上升/下降沿由滤波器的响应决定。动态测试 - 频域关键方法一使用音频分析仪如果做音频DAC这是最专业的方法。输入一个1kHz、-1dBFS的正弦波数字码用音频分析仪如APx555直接测量输出模拟信号的总谐波失真加噪声THDN、信噪比SNR和动态范围DR。方法二使用高质量声卡和软件对于业余或预研可以使用一个USB音频接口如Focusrite Scarlett 2i2其ADC性能较好来采集DAC的输出。在PC上使用如RMAA、ARTA或MATLAB/Octave配合脚本进行频谱分析。方法三使用示波器FFT功能现代高性能示波器如Keysight 3000T系列的FFT功能足够分析音频频段的频谱。输入单音信号观察基频幅度与噪声底之间的差距。5.2 常见问题与排查技巧即使设计看似正确实际搭建中也可能遇到各种问题。下面是一个常见问题速查表现象可能原因排查思路与解决方法输出有固定的直流偏移1. 参考电压不对称Vref ! |-Vref|。2. 模拟滤波器运放存在输入失调电压。3. FPGA输出高低电平的实际电压不对称。1. 用万用表测量两个参考电压的绝对值。2. 检查运放数据手册的Vos参数考虑使用调零电路或选择低Vos运放。3. 测量FPGA引脚在输出1和0时的实际电压检查IO标准设置如LVCMOS3.3。输出噪声大信噪比不达标1. 电源噪声。2. 参考电压源噪声大。3. 数字开关噪声耦合到模拟部分。4. 滤波器截止频率过高或衰减不足。5. 调制器本身性能未达理论值系数或时序问题。1. 用示波器检查电源纹波加强滤波。2. 更换为低噪声基准源如ADR4xx系列。3. 检查PCB布局确保数字地和模拟地单点连接数字信号远离模拟走线。4. 重新计算并测量滤波器频响确保在f_s/2处有足够衰减。5. 回到仿真检查调制器输出比特流的频谱与理论对比。高频输入信号时失真严重1. 模拟滤波器带宽不足造成带内幅度衰减和相位失真。2. 调制器在输入信号接近满幅度时可能不稳定过载。3. 运放压摆率Slew Rate不足无法响应快速变化的信号。1. 测量滤波器的频率响应确认通带平坦度。2. 在数字输入端对信号进行衰减如乘以0.9避免满幅度输入。仿真验证稳定性。3. 选择高压摆率的运放。输出有规律的“尖峰”或杂音1. 数字时钟抖动Jitter过大。2. 开关驱动瞬间引起电源/地弹。3. 调制器出现极限环振荡一种低频周期性模式。1. 使用FPGA内部的PLL产生低抖动的时钟源。2. 在开关MOSFET的漏极/源极附近增加小电容如100pF到地吸收尖峰。加强电源去耦。3. 这是高阶调制器的固有问题。可以尝试在积分器中加入很小的泄放通路leakage或使用带前馈的结构。动态范围低于仿真值1. 模拟部分的噪声和失真贡献。2. 调制器累加器位宽不足导致内部溢出或截断误差。3. 测试设备本身的噪声底限。1. 这是主要因素。单独测试模拟滤波器的噪声和失真。2. 增加ACC_WIDTH仿真验证是否改善。3. 了解所用声卡或分析仪的本底噪声确保其低于待测DAC的噪声。5.3 性能优化进阶方向当基本功能实现后可以考虑以下优化来提升性能或扩展功能高阶调制器实现三阶或更高阶的调制器以在相同OSR下获得更高的动态范围。但必须使用更复杂的稳定化技术如前馈-反馈混合结构或多位量化。多位量化与动态元件匹配DEM使用2-5位的内部量化器可以显著降低对OSR的要求。但多位DAC的单元失配会引入非线性失真。DEM技术通过随机轮换使用DAC单元将失配误差转化为白噪声从而大幅改善线性度。插值滤波器在调制器之前可以先对输入的低采样率数据进行插值上采样将其提升到调制器的工作频率。这可以在数字域用一个FIR插值滤波器完成它能滤除插值产生的镜像频率成分减轻后端模拟滤波器的压力。数字校正通过测量或校准在数字端对已知的DAC非线性如由参考电压误差或开关失配引起进行预失真补偿。在FPGA内集成数字滤波器将部分重构滤波的功能用数字FIR滤波器实现可以更精确地控制频率响应和线性相位最后只需要一个简单的模拟抗镜像滤波器即可。这通常需要更高的数字处理速度。从一块小小的FPGA芯片和一个简单的模拟电路开始到最终聆听到纯净的音频信号这个过程充满了挑战与乐趣。Sigma-Delta DAC的设计精髓在于理解并驾驭“噪声”。它教会我们有时候最高的精度并非来自对每一个细节的极致苛求而是来自对系统整体行为的巧妙规划和噪声的智慧管理。我个人的体会是调试这样一个系统时示波器和频谱分析仪是你的眼睛而耐心和系统的调试方法从数字仿真到静态测试再到简单的动态测试最后进行全面的频域分析则是你最重要的工具。当你第一次在频谱分析仪上看到那几乎被压到仪器底噪的本底噪声以及清晰独立的信号峰时那种成就感是对所有努力最好的回报。
返回列表