☰
Sigma-Delta ADC的MATLAB行为级建模与SNR分析
2026/10/20 8:49:44 网站建设 项目流程

做混合信号系统设计的人,对Sigma-Delta ADC基本都是又爱又恨。爱的是它可以用过采样和噪声整形换分辨率,恨的是架构选型、系数调整、稳定性判断,每一步都藏着不少坑。我在实际项目里养成了一个习惯:方案一出来,先在MATLAB里把Sigma-Delta ADC的模型建起来,把可行性和系统指标快速过一遍,再安排电路实现。这次想把自己整理的一套Sigma-Delta ADC Matlab建模资料摊开讲讲,内容包括一阶/二阶调制器的完整可运行代码、频谱与SNR分析脚本、非理想效应建模、常见排查技巧,以及建模时需要想清楚的几个关键点。这套内容尤其适合正在做ADC架构选型、研究生课题需要建模验证、或者从电路设计转向系统级验证的工程师参考。

1. 为什么要把Sigma-Delta ADC搬进MATLAB建模

1.1 行为级建模到底省在哪

很多人一听到ADC建模,第一反应是上SPICE跑晶体管级仿真。但Sigma-Delta ADC这种系统,用晶体管级仿真验证架构是一件性价比很低的事。一个最简单的二阶调制器,SPICE仿真跑几万个周期可能就要好几天,而行为级模型用MATLAB几分钟就能跑完几百万个采样点。行为级建模的精髓在于:把调制器里的积分器、量化器、DAC反馈都抽象成数学表达式,不关心单个晶体管是怎么实现这些功能的,只关心它们在离散时域里的输入输出关系。

这种抽象能保留系统级最关键的信息:噪声整形效果、环路稳定性、带内量化噪声功率、信号幅度的过载边界。这些信息对架构选型来说已经足够。我自己常用的流程是,先用行为级模型做参数扫描,比如对比一阶、二阶、三阶在同一个过采样率下的SNR表现,再根据趋势锁定候选架构。这一步用SPICE做会让人崩溃,用MATLAB模型则轻松得多。

1.2 模型要建到什么程度:理想、非理想还是混合

建模不是越精细越好,而是要和当前阶段的目标匹配。我一般把Sigma-Delta ADC的MATLAB模型分成三个层级。

第一层是理想模型。忽略KT/C噪声、运放非理想、DAC失配等所有实际效应,只保留调制器的核心环路结构。这个层级用来验证架构是否成立、NTF是否合理、需要多少阶和多少bit量化器才能达到目标SNR。它的代码最简单,跑得最快,所有结论都干净利落。

第二层是非理想模型。在理想模型基础上逐个加入实际非理想因素,比如热噪声、运放有限增益、有限摆率、时钟抖动、DAC单元失配。这一层是用来做系统级性能预算的,也是行为级建模最核心的价值所在。有了它,你才能在电路设计之前就大概知道,运放增益需要做到多少dB、电容取多大、DAC失配要控制在什么范围。

第三层是混合模型。调制器部分继续用行为级模型,但后端数字抽取滤波器换成RTL行为模型或者C代码,用来验证调制器与数字滤波器之间的接口、带外噪声抑制是否够、增益和直流偏移处理是否正确。这种混合模型在系统级流片前后特别有用。

我的建议很明确:第一步用理想模型把架构定下来,第二步在非理想模型里滚参数,第三步再让模拟工程师介入做电路实现。每次从理想往非理想演进,都要保持同一套输入信号、同一个频谱分析脚本,这样模型之间的差异才真正来自新增的非理想因素,而不是分析方法不一致。

2. 建模前必须吃透的四个关键点

2.1 过采样和噪声整形到底在做什么

Sigma-Delta ADC有两大核心支柱:过采样和噪声整形。过采样的意思是,用比信号带宽高很多的采样频率去量化输入信号。量化噪声的总功率通常是固定的,等于Δ²/12,其中Δ是量化步长。当采样率提高时,这个总功率被摊到更宽的频带里,落到信号带宽内的那部分噪声自然就变少了,这就是过采样增益。仅靠过采样,每把OSR提高一倍,带内SNR大约改善3dB。

真正让Sigma-Delta与众不同的是噪声整形。调制器环路通过反馈把量化噪声推到了高频段,信号带内的噪声进一步被压低。一阶调制器的噪声传递函数近似为1-z⁻¹,低频处幅度很小、高频处幅度放大。带内噪声功率大约降低了10log₁₀(π²/3)≈5dB,同时配合过采样,一阶调制器每把OSR翻一倍能带来约9dB的SNR提升。二阶调制器的NTF近似为(1-z⁻¹)²,每倍OSR能提升约15dB。

我整理了不同阶数在1bit量化器、OSR=64时的理想SNR粗略值,方便感受差距:

调制器阶数NTF近似理想SNR近似(1bit, OSR=64)每倍OSR理论提升
一阶1-z⁻¹约57dB约9dB
二阶(1-z⁻¹)²约85dB约15dB
三阶(1-z⁻¹)³约110dB约21dB

这里要强调:表格里的数值是理想近似,没考虑稳定性和具体NTF系数的影响,实际模型跑出来会有几dB偏差,但趋势是准确的。三阶以上虽然理论SNR高,但环路稳定性约束很强,输入幅度要控制得更保守。

2.2 调制器结构怎么选:CIFB还是CIFF

离散时间Sigma-Delta调制器的结构五花八门,最常见的两类是CIFB和CIFF。

CIFB(积分器级联反馈式,Cascade of Integrators with Feedback)的特点是每个积分器前面都有本地反馈路径,系数直观,对参数敏感度低,设计起来比较稳妥。对于新手或者追求快速验证的场景,CIFB是优先选项。CIFF(积分器级联前馈式,Cascade of Integrators with Feedforward)的核心思路是把信号前馈到量化器输入处,积分器内部处理的信号摆幅较小,对内部运放摆幅要求低,适合低功耗设计,但需要在量化器前端额外做一个求和电路,且系数设计时要更仔细。

我建议在建模阶段至少把CIFB和CIFF各搭一遍。它们在相同的NTF指标下,积分器内部电压摆幅差别很大,这会直接影响后续运放的设计目标。很多人在建模阶段只看SNR,忽略了内部节点摆幅,到了电路设计时才发现某一级积分器的输出动态范围不够,被迫重新选架构,返工成本很高。

2.3 量化器位数:1bit和多bit的取舍

量化器位数是架构选型里另一个关键岔路。1bit量化器的最大好处是DAC天然线性,因为只有一个比较器,反馈DAC永远输出两个电平,不存在单元失配问题。代价是量化噪声大,需要高阶数或高过采样率来压制,同时高阶1bit环路的最大稳定输入幅度有限。

多bit量化器能显著降低量化噪声、改善环路稳定性,但引入了一个新麻烦:反馈DAC的多个单元之间增益不完全一致,失配会把非线性谐波引入信号带内。所以多bit调制器必须搭配DWA(动态加权平均)或者DEM等动态匹配算法。建模的时候别只把量化器改成3bit或者5bit就收工,一定要把DAC失配模型和DWA算法一起建进去,否则等到电路实现阶段才发现失配问题,会很被动。

2.4 后端抽取滤波器要提前留接口

完整的Sigma-Delta ADC还包括数字抽取滤波器。很多人在建模时只盯着调制器的SNR,把数字滤波器忘得一干二净。这不对。抽取滤波器的通带纹波、阻带抑制、带外衰减速率都会直接影响最终ADC的有效位数。我建议在建模初期就设计一个滤波器的接口,先用简单的CIC加补偿滤波器占位,留有后期替换成正式RTL模型的余地。尤其是验证带外噪声抑制时,没有数字滤波器的模型会高估系统性能,这一点要特别注意。

3. 实操:从零搭一个一阶Sigma-Delta调制器模型

3.1 最小可运行模型代码

先从最简单的开始。下面是一个完整的一阶Sigma-Delta调制器理想模型,用离散时间循环实现。

function [ybit, v] = mod1_ideal(x, nlevel) % 一阶Sigma-Delta调制器理想行为级模型 % x: 输入信号,幅度归一化到[-1,1] % nlevel: 量化器电平数,2表示1bit % ybit: 量化器输出码流 % v: 积分器状态,便于调试 N = length(x); v = 0; yprev = 0; % 上一个周期的反馈DAC输出 ybit = zeros(1, N); for n = 1:N % 积分器输入是当前输入减去上个周期的反馈输出 v = v + x(n) - yprev; % 量化器 if nlevel == 2 if v >= 0 y = 1; else y = -1; end else delta = 2 / (nlevel - 1); idx = floor((v + 1) / delta) + 1; idx = max(1, min(nlevel, idx)); y = -1 + (idx - 1) * delta; end ybit(n) = y; yprev = y; % 反馈DAC输出,保持一个周期延迟 end end

我用的反馈量是yprev,也就是上一个周期的输出,而不是当前周期的输出。这不是随手写的,Sigma-Delta环路的DAC反馈在实际电路中天然存在一个时钟周期的延迟。如果改用当前输出反馈,会让噪声传递函数在高频段变样,模型跑出来的SNR和频谱形状都会失真。你可以自己试着把yprev改成y跑一次,频谱图上的噪声整形斜率会有明显异常。

3.2 频谱与SNR分析测试平台

有调制器模型还不够,关键是学会如何从输出码流里提取SNR。下面是我的标准测试脚本,输入为一个带内正弦波,输出为该调制器模型在工作条件下的带内SNR。

% 一阶调制器测试平台 fs = 1e6; % 采样率1MHz osr = 64; fb = fs / (2 * osr); % 信号带宽 N = 2^14; % 仿真点数 t = (0:N-1) / fs; fin = 10e3; % 输入信号频率 A = 0.5; % -6dBFS x = A * sin(2 * pi * fin * t); [ybit, ~] = mod1_ideal(x, 2); % 频谱分析(加Hann窗) win = hann(N)'; y = ybit - mean(ybit); % 去掉直流分量 Y = fft(y .* win); Y = Y(1:floor(N/2)); PSD = abs(Y).^2 / (sum(win.^2) * fs / 2); % 单边PSD近似 PSD(1) = 0; f = (0:floor(N/2)-1) * fs / N; % 带内SNR计算 inband = f <= fb; rb = round(fin / (fs / N)) + 1; % 信号频率所在bin sigbins = max(1, rb-2):rb+2; % 信号周围5个bin noibins = find(inband); noibins = noibins(~ismember(noibins, sigbins)); snr = 10 * log10(sum(PSD(sigbins)) / sum(PSD(noibins))); fprintf('In-band SNR = %.2f dB\n', snr); % 画频谱 figure; semilogx(f(2:end), 10 * log10(PSD(2:end))); xlabel('Frequency (Hz)'); ylabel('PSD (dBFS/Hz)'); xlim([1, fb * 2]); grid on;

几个容易被忽略的细节:第一,输入信号频率尽量选成FFT bin的中心频率,也就是满足fin = k * fs / N,这样频谱泄漏最小;如果不满足相干采样,即使加窗也会有一些泄漏,但不影响大趋势。第二,SNR计算时要剔除信号本身占的少数几个bin,否则会把信号功率算成噪声功率。第三,PSD的单位和缩放在不同MATLAB版本里可能略有差异,不必纠结绝对值,关键是噪声整形曲线和SNR相对变化。

3.3 一阶模型能看到什么,看不到什么

一阶模型结构最简单,但能验证很多基本规律。跑完上面脚本,你会看到频谱图上噪声以大约20dB/dec的斜率上升,这是典型的一阶整形特征。改变OSR从32到64再到128,SNR大约每翻倍提升9dB,这和理论预期比较吻合。这个模型非常适合用来验证工具链是否正确、测试脚本是否自洽。

但一阶模型也暴露了它的天花板:OSR翻一倍只提升9dB,意味着想拿到60dB以上SNR需要很高OSR,采样率代价太大。所以实际工程里一阶调制器只用在传感器、低速低功耗等对分辨率要求不高的场合。做高精度ADC,基本从二阶起步,二阶建模能力会强很多。

4. 二阶调制器和非理想效应建模

4.1 二阶CIFB结构实现

二阶调制器的工程价值明显更高。下面是二阶CIFB结构的理想模型,量化器和前面类似,只是环路里多了一级积分器。

function [ybit, v1, v2] = mod2_cifb_ideal(x, c1, c2, nlevel) % 二阶CIFB Sigma-Delta调制器理想模型 % c1: 第一级反馈系数 % c2: 第二级反馈系数 % nlevel: 量化器电平数 N = length(x); v1 = 0; v2 = 0; yprev = 0; ybit = zeros(1, N); for n = 1:N % 第一级积分器:输入是当前输入减去反馈DAC输出 v1 = v1 + x(n) - c1 * yprev; % 第二级积分器:输入是第一级积分器输出减去反馈DAC输出 v2 = v2 + v1 - c2 * yprev; % 量化器 if nlevel == 2 if v2 >= 0 y = 1; else y = -1; end else delta = 2 / (nlevel - 1); idx = floor((v2 + 1) / delta) + 1; idx = max(1, min(nlevel, idx)); y = -1 + (idx - 1) * delta; end ybit(n) = y; yprev = y; end end

系数c1和c2怎么取是个值得认真对待的问题。我常用的初始值组合是c1=0.5、c2=0.5,配合3bit或4bit量化器,输入幅度控制在-6dBFS左右,OSR=64时SNR大概能到80到90dB量级。但要说明,这只是为了让模型先跑起来的一组可用参数,不是最优参数。不同架构、不同NTF目标需要综合工具重新计算系数,一通乱改系数很容易让环路失稳,表现为时域输出幅值越来越大,SNR断崖式下跌。

4.2 非理想效应建模要逐个加

从理想模型转向非理想模型,我强烈建议一次只加一个非理想效应,每次只观察一个因素对SNR的影响。否则所有误差叠加在一起,你很难定位到底是什么限制了性能。下面是最常加的几类效应。

第一是KT/C热噪声。在输入节点叠加高斯白噪声,噪声功率为kT/C。举个例子,C=2pF时,k=1.38×10⁻²³,T=300K,kT/C≈2.07×10⁻⁹V²,折合RMS电压约45µV。如果满量程是1V,这个热噪声对应的信噪比大约80dB出头。在MATLAB里实现非常直接,在积分器输入端加randn乘以标准差即可。

第二是运放有限增益。运放增益有限会让积分器出现泄漏,理想的积分器传递函数变成带一个小于1的漏损系数。我一般把积分器状态乘以一个leak系数,比如leak=0.999,对应有效增益在60dB以上的情况,然后观察SNR下降幅度。如果不合适就继续压小泄漏系数,很快能算出运放增益的需求边界。

第三是运放有限摆率。这个可以用限幅实现,在每步循环里给积分器输出加一个最大值约束。它的影响主要体现在大信号输入时谐波明显增加,和小信号时的SNR下降模式完全不同。

第四是时钟抖动。抖动本质上是采样时刻的随机偏差,等效误差大小正比于输入信号变化率。对低频信号影响小,高频信号影响大。建模时可以在输入导数上叠加随机抖动。

非理想模型的代码核心结构大致长这样:

leak = 0.999; sigma_ktc = 4.5e-5; % 前面算出来的热噪声标准差 for n = 1:N noise = sigma_ktc * randn(); v1 = leak * v1 + (x(n) - c1 * yprev) + noise; v2 = leak * v2 + (v1 - c2 * yprev); % 摆率限制示例 % v2 = max(min(v2, 1.2), -1.2); end

注意,非理想效应加进去之后,输入幅度和OSR不变的前提下,SNR会下降,这个下降幅度就是你这个架构在该非理想因素下的性能预算。

4.3 多bit量化与DWA建模

多bit量化器的DAC失配会导致带内谐波,解决思路是让每个DAC单元的使用频率尽量均衡,把失配误差从低频调制到高频段。经典算法DWA(Data Weighted Averaging)属于旋转指针法的一种,核心逻辑是:每次需要使用的单位元素不是固定从第一个开始,而是从上次结束的位置接着选,保证所有单元的使用次数长期均匀。

下面是一个简化版指针型DWA代码,配合多bit量化器使用:

function y_dac = dwa_rotate(yq, M, egain) % yq: 量化器输出序列,范围[-1,1] % M: DAC单位元素个数 % egain: 各DAC单元的实际增益,失配时从1附近随机偏离 ptr = 1; N = length(yq); y_dac = zeros(1, N); for n = 1:N level = round((yq(n) + 1) / 2 * M); level = min(max(level, 0), M); if level > 0 idx = mod((ptr - 1) + (0:level - 1), M) + 1; y_dac(n) = sum(egain(idx)); ptr = mod(ptr + level - 1, M) + 1; else y_dac(n) = 0; end end end

这里有个容易忽略的细节:当level=0时DAC输出为0,但量化器输出是-1,反馈节点会引入一个直流偏置。实际使用时要对这个映射做归一化再参与反馈,否则环路里会多出一个直流项,影响输出谱。DWA的建模价值在于:你可以观察在加入单元失配后,带内谐波被有效抬到高频,带内SNR恢复正常的整个过程,这也是后续数字电路设计团队判断DWA算法是否够用的依据。

5. 常见问题与排查技巧实录

5.1 SNR上不去?先检查这四件事

SNR严重低于理论预期,是建模时最容易遇到的问题。我总结了四个最高频的坑。

第一,输入幅度是否过大。Sigma-Delta调制器存在最大稳定输入幅度,一旦超过,环路过载,SNR会突然掉下去。检查方式很简单,慢慢降低输入信号幅度,看SNR是否显著回升。通常把幅度控制在-6dBFS到-3dBFS之间比较稳妥。

第二,反馈延迟是否写对。这是代码层面最隐蔽的坑。如果模型里用的是当前时隙输出直接反馈,NTF会失真,噪声整形效果大打折扣。正确做法是反馈上一个周期的输出,这是对实际DAC反馈延迟的合理抽象。

第三,频谱泄漏是否处理干净。输入频率不满足相干采样时,信号能量会泄漏到邻近bin,计算带内噪声时这些泄漏会被当成噪声,SNR被压低。对一阶这种SNR不高的场景影响不算致命,但二阶以上动辄80dB量级,泄漏影响会非常明显。解决方案是选相干频率,同时加Hann窗做频谱分析。

第四,仿真点数是否足够。点数太少时频域分辨率太粗,带内噪声功率估计不稳定,SNR每次跑出来都不一样。建议至少2^14个点起步,做参数扫掠时也尽量保持点数不变。

5.2 稳定性问题怎么快速判断

高阶调制器经常在输入幅度偏大时突然失稳,表现是时域输出不再跟随输入周期,出现大幅度低频振荡,SNR暴跌。判断稳定性不能只靠理论推导,最好在模型里做一个输入幅度扫掠:从-20dBFS逐步加到0dBFS,记录每个幅度下的SNR。如果某个幅度之后SNR突然掉得很厉害,说明已经越过最大稳定输入幅度。这个幅度值就是该架构的有效输入范围。

理论上有Lee准则可以参考,也就是NTF的最大增益不要超过2,但这个准则更多是经验性的,最终还是要靠时域仿真来定。遇到稳定性问题时,常规动作有三个:降低输入幅度、增加量化器位数、重新设计NTF系数。不要指望在系数不变的前提下靠牺牲SNR来硬撑稳定性,那样上限太低。

5.3 模型仿真太慢怎么办

MATLAB里用for循环做离散时域仿真,点数一多或者加上DWA后确实会慢。优化思路从低到高有几级。

第一级是代码优化。量化器判断不要用大段if-else,可以预先计算阈值表,循环内部直接查表。积分器状态更新尽量用最简单的加减乘除。第二级是减少重复计算,比如噪声序列、窗函数、FFT这些都能提前准备好。第三级是并行化,做蒙特卡洛仿真时用parfor替代for,每个worker独立跑一条随机失配曲线,速度提升非常直接。第四级是把核心调制器函数做成MEX或者C代码,跑百亿次循环也不怕。我的做法是先用循环版本把功能验证准确,再封装成MEX用于后续大批量扫参数,效率和可读性兼顾。

5.4 常见问题速查表

现象可能原因排查方法
SNR低于理论值10dB以上输入幅度过大、反馈未加延迟、频谱泄漏降低幅度,检查yprev,确认相干采样
频谱图出现大量谐波毛刺输入幅度接近过载或DAC失配降幅测试,检查是否已加DWA
大信号时SNR突然暴跌超过最大稳定输入幅度降低输入,增加量化器位数
输出码流出现明显低频振荡环路失稳或极限环修改NTF系数,检查量化器阈值
模型运行速度太慢循环重、点数多查表优化、MEX、parfor
同一参数每次SNR有波动输入频率不满足相干采样或点数不足改相干频率,增大N

最后分享一点个人体会。我最早建模时总想一次把模型写得很完整,结果调代码的时间远超预期。后来改成先跑通一阶模型,再扩到二阶,再逐个加非理想因素,整个流程顺畅很多。这套方法最大的价值不是立刻得到一个完美的ADC模型,而是让你在短时间内把所有潜在瓶颈都暴露出来,逼着你去理解每一个参数背后的物理含义。你真正要做的,就是把这个模型拆成独立的函数库:信号生成、调制器、频谱分析、抽取滤波器各管各的。等N个架构都跑过一遍之后,你会发现自己对整个Sigma-Delta ADC的认识,已经远比看文档和公式要扎实得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询