简介:这份资源是哈尔滨工业大学2014年工学硕士学位论文《18bits Sigma-Delta DAC的设计》,面向具备电子工程基础、对数模转换与Sigma-Delta技术有一定了解的研发人员和技术爱好者,帮助读者理解高精度、大带宽数模转换器的系统级设计原理与实现方法。论文围绕一位量化五阶全前馈结构Sigma-Delta调制器展开,确定128倍过采样率,采用三级数字FIR滤波器级联实现高倍插值,并选用六阶贝赛尔模拟低通滤波器,基于GF 0.35μm CMOS工艺完成综合、布局布线、电路设计与版图设计,仿真显示输入信号-6dB时信噪比达98.26dB。资源包为1个PDF文件,大小约3.03MB,内容涵盖MATLAB行为级建模仿真、各模块架构对比分析及整体仿真结果,适合音频处理、工业控制等高精度数模转换场景的学习与参考。目前已有105人学习下载。
1. 18bits Sigma-Delta DAC 的设计:为什么高精度音频链路绕不开它
做音频模拟前端的人迟早会撞上同一个问题:24bit 的 PCM 数据摆在面前,手头的 DAC 却只有 16bit 有效精度,直接截断吧,小信号细节全丢;加个数字衰减吧,又引入新的量化噪声。这时候 Sigma-Delta 架构就成了绕不过去的选项。它的核心思路不是把每一位都精确还原,而是用远高于信号带宽的采样率把量化噪声“推”到高频,再用数字滤波器把它切掉,最终在音频带内换来远超量化器位数的等效精度。18bits 这个指标放在 Sigma-Delta DAC 里,意味着带内信噪比要做到 108dB 以上,THD+N 要压到 -100dB 以下,这对调制器阶数、过采样率、时钟抖动和模拟后端都提出了硬约束。这篇笔记面向的是正在做音频 DAC 选型或自研模块的硬件工程师、IC 设计入门者和嵌入式音频开发者,我会把从架构选型到调制器参数、从数字滤波器到版图注意事项的完整链路拆开讲,重点放在“怎么算、怎么配、哪里会翻车”。
2. 架构选型:为什么是 Sigma-Delta 而不是 R-2R 或分段电流舵
2.1 三种主流 DAC 架构在 18bits 场景下的真实差距
先摆一个结论:在 18bits 及以上、信号带宽不超过几百 kHz 的场景里,Sigma-Delta 是综合成本最低的方案。R-2R 电阻网络 DAC 的精度直接取决于电阻匹配度,要跑到 18bits,电阻相对误差要控制在 2^-18 量级,也就是约 4ppm,这在标准 CMOS 工艺里几乎不可能靠版图匹配实现,必须加激光修调,成本直接起飞。分段电流舵 DAC 靠温度计码加二进制码混合,动态匹配可以做,但单元电流源的失配随面积指数下降,18bits 意味着要几千个单元,面积和功耗都不划算。
Sigma-Delta 的聪明之处在于:它不要求模拟元件精确,而是用时间和反馈来换精度。一个 1bit 量化器只有两个输出电平,理论上完全线性,所有精度压力转移到过采样率和噪声整形阶数上,而这两者都是数字域可以精确控制的。代价是采样率要高,输出码率大,后端滤波器要处理高频噪声。
| 架构 | 18bits 可达性 | 匹配要求 | 面积 | 功耗 | 适用场景 |
|---|---|---|---|---|---|
| R-2R | 需修调 | 极高 | 中 | 低 | 中低速精密 |
| 分段电流舵 | 可达到 | 高 | 大 | 高 | 高速视频 |
| Sigma-Delta | 容易达到 | 低 | 中 | 中 | 音频、精密测量 |
2.2 过采样率与阶数的联合选择
过采样率 OSR 和调制器阶数 L 决定了带内噪声抑制能力。对于 L 阶调制器,带内量化噪声功率近似正比于 1/(OSR^(2L+1))。每翻倍 OSR,带内噪声下降 3(2L+1) dB。18bits 要求带内 SNR 约 110dB,假设量化器为 1bit,理想 SNR 上限约 6.02N+1.76,但 Sigma-Delta 的等效位数由噪声整形决定。
实际选型时我一般这样估:目标带内噪声底 -110dBFS,音频带宽 20kHz。如果选 OSR=128,采样率 5.12MHz,二阶调制器理论带内 SNR 约 100dB,不够;三阶约 115dB,有余量。如果选 OSR=256,采样率 10.24MHz,二阶就能到 110dB 左右。所以常见组合是二阶 256 倍或三阶 128 倍。二阶稳定性好,三阶需要更仔细的系数缩放。
import numpy as np def sd_ideal_snr(order, osr, quant_bits=1): # 理想 Sigma-Delta 调制器带内 SNR 估算 # 量化噪声总功率,均匀分布假设 q = 1.0 / (2**quant_bits - 1) # 带内噪声功率近似:噪声传递函数 |NTF|^2 在带内积分 # NTF = (1 - z^-1)^order,带内近似 |NTF(f)|^2 ≈ (2*pi*f/fs)^(2*order) # 积分后带内噪声功率 ∝ q^2 * pi^(2*order) / ((2*order+1) * OSR^(2*order+1)) from math import pi p_inband = (q**2) * (pi**(2*order)) / ((2*order+1) * (osr**(2*order+1))) # 满幅正弦功率 p_signal = 0.5 snr = 10 * np.log10(p_signal / p_inband) return snr for order in [2, 3, 4]: for osr in [64, 128, 256]: snr = sd_ideal_snr(order, osr) print(f"order={order}, OSR={osr}, ideal SNR={snr:.1f} dB, ENOB≈{(snr-1.76)/6.02:.1f} bits")这段代码给的是理想上限,实际因为量化器非线性、时钟抖动、运放有限增益,会掉 10~20dB。参数说明:order 是调制器阶数,osr 是过采样率,quant_bits 是量化器位数,1bit 时 q=1。跑出来会看到三阶 128 倍理想约 120dB,实际做到 110dB 左右是合理目标。如果仿真出来差太远,先查积分器系数是否溢出。
2.3 连续时间还是离散时间:一个容易被低估的选型点
离散时间 Sigma-Delta 用开关电容实现,系数由电容比决定,匹配好,但采样保持电路对时钟抖动敏感,且运放建立时间要求高。连续时间 Sigma-Delta 把积分器放在环路滤波器里,对运放带宽要求低,功耗小,但系数由 RC 乘积决定,工艺偏差大,需要调谐。音频应用里离散时间更常见,因为采样率不算太高,开关电容的建立时间够用,且数字后端好接。如果做超低功耗始终开启的音频链路,连续时间方案值得考虑,但 RC 调谐电路会增加设计复杂度。
3. 调制器设计:从系数缩放到稳定性仿真
3.1 噪声传递函数与信号传递函数的配合
Sigma-Delta 调制器的核心是噪声传递函数 NTF 和信号传递函数 STF。理想情况下 STF 在带内平坦,NTF 在带内接近零,带外增益高。对于二阶调制器,NTF 通常取 (1-z^-1)^2,但纯微分器在高频增益无限,实际要加零点优化。常见做法是用 CRFB 结构,系数通过 Schreier 工具箱或自己推导。
我一般先用行为级模型跑通,再映射到电路。行为级用 Python 或 MATLAB 都行,关键是积分器要加饱和限幅,否则仿真会发散。下面是一个二阶 1bit 调制器的行为级代码。
import numpy as np def sdm2_order2(x, osr=256): # 二阶 1bit Sigma-Delta 调制器行为级模型 # x: 输入信号,已归一化到 [-1, 1] # 返回 1bit 输出序列 n = len(x) y = np.zeros(n) # 积分器状态 s1 = 0.0 s2 = 0.0 # 系数,CRFB 形式,a1=a2=0.5 为常见缩放 a1 = 0.5 a2 = 0.5 for i in range(n): # 积分器 1 输入:输入信号减去反馈 u1 = x[i] - y[i-1] if i > 0 else x[i] s1_new = s1 + a1 * u1 # 积分器 2 输入:积分器 1 输出 s2_new = s2 + a2 * s1_new # 1bit 量化器 y[i] = 1.0 if s2_new >= 0 else -1.0 # 状态更新,加限幅防止发散 s1 = np.clip(s1_new, -2.0, 2.0) s2 = np.clip(s2_new, -2.0, 2.0) return y # 测试:输入 1kHz 正弦,采样率 256*48k=12.288MHz fs = 12.288e6 osr = 256 fin = 1e3 n = 200000 t = np.arange(n) / fs x = 0.5 * np.sin(2 * np.pi * fin * t) y = sdm2_order2(x, osr) # 计算带内 SNR from numpy.fft import fft, fftfreq Y = fft(y * np.hanning(n)) freqs = fftfreq(n, 1/fs) # 带内 20kHz inband = np.abs(freqs) < 20e3 signal_bin = np.argmax(np.abs(Y[inband])) p_signal = np.abs(Y[inband][signal_bin])**2 p_noise = np.sum(np.abs(Y[inband])**2) - p_signal snr = 10 * np.log10(p_signal / p_noise) print(f"带内 SNR = {snr:.1f} dB")逻辑说明:每个时钟周期,输入减去上一周期反馈,进第一积分器,再进第二积分器,量化器输出 1bit。系数 a1、a2 控制积分器增益,太小噪声整形弱,太大容易过载。限幅是必须的,否则输入稍大就发散。参数说明:osr 只影响测试信号生成,调制器本身不感知 OSR,它只按采样率跑。跑完看 SNR,如果只有 80dB 左右,检查系数是否太小或输入幅度是否超过 0.6。实际电路里积分器用开关电容,系数由电容比实现,a1=C1/C2 之类。
3.2 系数缩放与积分器输出摆幅
行为级跑通后,下一步是确定积分器输出摆幅。二阶调制器第一积分器输出摆幅通常最大,如果超过运放输出范围就会削顶,噪声整形失效。经验值是第一积分器输出不超过满幅的 70%。可以通过调整系数或加前馈路径来降低摆幅。常见做法是在第二积分器前加一个本地反馈,或者用前馈把输入直接送到量化器,减轻积分器负担。
仿真时扫输入幅度,从 -20dBFS 到 0dBFS,看 SNR 曲线。如果某幅度后 SNR 骤降,说明过载。记录过载点,留 3~6dB 余量作为设计上限。这个余量就是“后悔药”,后期调音时不会因为信号峰值削顶。
3.3 时钟抖动对 18bits 的致命影响
18bits 意味着带内噪声底要压到 -110dB 以下。时钟抖动引入的采样误差会直接调制输入信号,产生边带。对于正弦输入,抖动引起的 SNR 上限约为 -20log10(2pifinsigma_t),其中 sigma_t 是时钟抖动 RMS。要保证 110dB,fin=20kHz 时,sigma_t 要小于约 1.8ps。这个数字很苛刻,普通晶振的抖动可能在 10~50ps 量级,必须用低抖动时钟源或加 PLL 净化。很多新手在这里翻车:调制器仿真完美,一上板子 SNR 只有 90dB,查半天发现是时钟源抖动太大。
4. 数字滤波器与后端:从 1bit 码流到 18bits PCM
4.1 抽取滤波器的两级结构
调制器输出是 1bit 高采样率码流,要变成 18bits 低采样率 PCM,需要抽取滤波器。单级实现不现实,因为过渡带太窄。常见两级:第一级 CIC 滤波器,只做降采样,通带下垂可接受;第二级 FIR 补偿下垂并锐化过渡带。CIC 的降采样比通常取 OSR/4 或 OSR/8,剩下的给 FIR。
CIC 滤波器参数:阶数 N,差分延迟 M,降采样比 R。通带下垂与 (pifMR/fs)^(2N) 有关。音频应用里 N=3~5,M=1,R=32~64。CIC 不需要乘法器,只用加减和积分,面积小。但 CIC 的位宽会增长,Nlog2(R*M) 位,要预留。
import numpy as np def cic_decimator(x, R=64, N=4, M=1): # CIC 抽取滤波器,输入 1bit 码流,输出降采样后序列 # 积分器级联 integrators = [0.0] * N # 梳状器延迟线 combs = [[0.0] * M for _ in range(N)] output = [] for sample in x: # 积分 v = sample for i in range(N): integrators[i] += v v = integrators[i] # 降采样计数 if len(output) * R < len(x): pass # 简化:每 R 个样本做一次梳状 # 实际实现要先积分再降采样再梳状,这里用直接形式示意 # 更清晰的实现:先积分所有样本,再降采样,再梳状 int_out = np.zeros(len(x)) for i in range(N): int_out = np.cumsum(int_out + x) if i == 0 else np.cumsum(int_out) # 降采样 dec = int_out[::R] # 梳状 comb_out = dec.copy() for i in range(N): delayed = np.roll(comb_out, M) delayed[:M] = 0 comb_out = comb_out - delayed return comb_out # 测试 np.random.seed(0) bits = np.random.choice([-1, 1], size=100000) out = cic_decimator(bits, R=64, N=4, M=1) print(f"输入长度 {len(bits)}, 输出长度 {len(out)}")这段代码是示意,实际 CIC 要先积分再降采样再梳状,顺序不能反。参数说明:R 是降采样比,N 是级数,M 是差分延迟。N 越大通带越平但功耗越高。输出位宽要足够,否则会溢出。CIC 之后接 FIR 补偿,FIR 系数可以用 scipy 设计,通带 20kHz,阻带 24kHz 开始,衰减 100dB 以上。
4.2 18bits 输出的位宽管理与舍入
抽取滤波器输出位宽通常比 18bits 宽,要截断或舍入到 18bits。直接截断会引入直流偏移和量化噪声,要用舍入加抖动。抖动噪声要整形到带外,否则会抬高带内噪声底。常见做法是加二阶整形抖动,把舍入误差推到高频。这一步做不好,前面调制器再好也白搭。
4.3 模拟后端:重建滤波器和输出缓冲
18bits DAC 的模拟后端包括重建滤波器和输出缓冲。重建滤波器把高频噪声滤掉,通常用二阶或三阶巴特沃斯,截止频率 20~24kHz。运放要选低噪声、低失真型号,输入噪声密度要小于 10nV/√Hz,否则会吃掉动态范围。输出缓冲要能驱动后级负载,同时保持线性。这里有个坑:运放的非线性在 18bits 下会显现,选型时看 THD+N 指标,要优于 -110dB。
5. 避坑与排查:18bits Sigma-Delta DAC 设计中最容易翻车的五个点
5.1 现象:仿真 SNR 达标,实测只有 90dB
原因:时钟抖动超标。调制器对时钟抖动敏感,仿真时用理想时钟,实测时钟源抖动可能几十 ps。解决:换低抖动晶振,或加时钟净化 PLL,实测抖动要小于 2ps RMS。用示波器测时钟相位噪声,积分到 20kHz~20MHz 看 RMS 抖动。
5.2 现象:小信号时噪声大,大信号时正常
原因:抖动或舍入处理不当。小信号时量化噪声调制更明显,如果数字截断没加抖动,小信号线性度差。解决:在抽取滤波器输出加二阶整形抖动,幅度约 1LSB,整形到高频。检查抖动是否被后续滤波器滤掉。
5.3 现象:调制器偶尔发散,输出满幅方波
原因:积分器过载。输入幅度太大或系数缩放不当。解决:降低输入幅度,或调整系数,加限幅。仿真时扫幅度找过载点,留余量。实际电路里运放输出摆幅有限,要确保积分器不削顶。
5.4 现象:带内噪声底有离散杂散
原因:时钟馈通或电源耦合。1bit 码流翻转频繁,会通过寄生电容耦合到模拟输出。解决:版图上加屏蔽,电源加去耦,时钟走线远离模拟信号。数字和模拟地分开,单点连接。
5.5 现象:THD+N 在低频段差
原因:运放闪烁噪声或电阻热噪声。18bits 下低频噪声贡献大。解决:选低闪烁噪声运放,电阻用大阻值但注意热噪声,或改用开关电容。版图上输入对管面积加大,减小 1/f 噪声。
6. 进阶技巧:用 FFT 和直方图快速定位调制器问题
6.1 用 FFT 看噪声整形斜率
跑完行为级仿真,先看输出码流的 FFT。理想二阶调制器噪声整形斜率是 40dB/decade,三阶是 60dB/decade。如果斜率不对,说明阶数没生效或系数错了。带内噪声底应该平坦,如果翘起,说明有低频噪声源。用 Welch 方法平均多次,看更平滑的谱。
from scipy.signal import welch import matplotlib.pyplot as plt # 假设 y 是调制器输出,fs 是采样率 f, pxx = welch(y, fs=fs, nperseg=8192, noverlap=4096) plt.semilogx(f, 10*np.log10(pxx)) plt.xlabel('Frequency (Hz)') plt.ylabel('PSD (dB/Hz)') plt.grid() plt.show()看 20kHz 以内是否平坦,20kHz 以上是否按预期斜率上升。如果带内有个凸起,查输入信号频率是否泄漏或系数有误。
6.2 用直方图看积分器状态分布
积分器状态直方图能反映摆幅和稳定性。正常工作时,第一积分器状态分布应该集中在零附近,尾部不超过限幅值。如果分布偏向一侧,说明有直流偏移或系数不对称。第二积分器分布更宽,但也不应频繁触碰限幅。用直方图快速判断,比看时域波形直观。
# 假设 s1_history 是记录的第一积分器状态序列 plt.hist(s1_history, bins=100, density=True) plt.xlabel('Integrator 1 state') plt.ylabel('Probability') plt.grid() plt.show()如果直方图在限幅值处有尖峰,说明过载,要降低输入幅度或调整系数。
6.3 一个我常犯的错误
早期做 18bits 设计时,我总把精力花在调制器阶数上,觉得阶数越高越好,结果三阶调制器系数没调好,稳定性余量不足,一上电就振荡。后来养成习惯:先用二阶跑通全链路,测出实际 SNR 和 THD+N,再决定是否升三阶。二阶 256 倍过采样在音频带内做到 108dB 是可行的,前提是时钟抖动和模拟后端都到位。升阶带来的收益往往被模拟非理想因素吃掉,不如先把二阶做扎实。每次流片前,我都会用行为级模型扫一遍工艺角,看系数偏差对 SNR 的影响,留够余量。希望帮到你。
本文还有配套的精品资源,点击获取