3阶连续时间Delta-Sigma ADC的Matlab行为级仿真与调优
2026/9/7 5:02:48 网站建设 项目流程

简介:面向模拟IC设计、混合信号处理及电子工程相关学生与工程师,一套3阶连续时间Delta-Sigma(ΔΣ)ADC的Matlab/Simulink仿真代码,既能用于理解过采样、噪声整形与高阶积分器原理,也可作为课程设计或工程验证的起点。资源包共10个文件,约3.14MB,包含可运行的m脚本、Simulink模型,以及三篇参考论文、Excel计算表、操作说明等辅助材料,覆盖时序仿真、FFT频域分析、功率谱密度计算等完整流程。目前已有954人学习或浏览,适合ADC入门到进阶的实践学习。通过运行该模型,读者可复现三阶3位量化、400倍过采样率的连续时间ΔΣ调制器,结合论文中的设计实例与计算表格,分析信噪比、SNDR、稳定性等核心指标,从而深入掌握连续时间Delta-Sigma ADC的建模与仿真方法。高过采样率与高阶噪声整形的组合,也能帮助读者更直观地理解性能折衷。 搞过几天Delta-Sigma ADC的人应该都有同感:看架构、看论文、看理想模型,觉得一切尽在掌握,一旦自己动手在Matlab里把3阶连续时间Delta-Sigma ADC搭起来跑通,才发现坑全藏在系数映射和环路稳定性上。这篇东西就是把我的仿真代码和整个思考过程拆开来讲——从为什么选连续时间结构、怎么算3阶环路滤波器系数,到Matlab里怎么搭模型、怎么从频谱图里抠出准确的SNDR,最后还会聊几个我在仿真中踩得最疼的坑。适合正在做CTDSM课程设计、流片前验证或者纯粹想搞懂SDM仿真原理的读者。

1. 架构选型:为什么连续时间比离散时间更适合3阶设计

1.1 离散时间与连续时间的本质差异

传统教科书里讲Delta-Sigma ADC,多半从离散时间(DT)结构开始——开关电容积分器、z域传递函数、离散时间噪声传递函数(NTF),这套体系非常成熟,Matlab里建模也简单,一个filter函数就能搞定。但工程实际中,尤其是带宽要求做到几十MHz以上的场景,离散时间结构会遇到两个硬伤:一是开关电容积分器的建立时间受运放带宽限制,采样率越高越难满足;二是采样电容在输入端会引入开关噪声,等效热噪声和采样时钟抖动的影响很难压下去。

连续时间(CT)结构绕开了这两个问题——环路滤波器是RC积分器或跨导-电容(gm-C)积分器,信号在整个环路里是连续时间处理的,只在量化器前才采样。这样一来,运放的增益带宽积要求比离散时间结构低很多,而且输入端的RC网络本身就有抗混叠滤波效果,省掉了一个独立的抗混叠滤波器。代价是什么?环路滤波器对时钟抖动更敏感,而且环路滤波器的系数不再直接等于离散域的系数,需要做一次映射。

1.2 3阶环路滤波器的稳定性边界

DT结构里,NTF的零点全部落在z=1(直流处),零点的分布可以靠系数直接控制。CT结构里,环路滤波器由多个积分器级联构成,每个积分器贡献一个在s=0处的极点(对应z=1),这一点和DT结构是一致的。但CT结构的额外难点在于:量化器前面的环路滤波器输出是连续时间信号,环路延时的变化会直接改变噪声整形效果,而且反馈DAC的脉冲波形(NRZ还是RZ)会改变环路滤波器的有效增益。

3阶环路之所以是“甜点位”,是因为2阶的量化噪声整形斜率ilove足够低、带内噪底压不下去,而4阶以上的环路系数对元件失配和集成运放有限增益的敏感度会明显上升,稳定裕度更难控制。3阶结构在功耗、稳定性和性能之间取得了较好的平衡,很多商用高速CTDSM芯片都选这个阶数。

具体做3阶CTDSM的Matlab仿真时,核心工作就三件:算出3阶NTF的离散域系数,把系数映射到连续时间积分器网络,然后把整个环路搬进Matlab里做行为级仿真。下面详细展开。

2. 系数计算与环路滤波器设计

2.1 从目标NTF到离散域系数

设计一个3阶CTDSM,先要确定目标噪声传递函数NTF(z)。常用的做法是从一个3阶巴特沃斯或切比雪夫II型高通滤波器反推。Matlab里的delsig工具箱里的synthesizeNTF函数可以直接给出离散域NTF:

% 3阶,OSR=32,目标带内增益约-80dB ntf = synthesizeNTF(3, 32, 0, 3, 1); % order=3, osr=32

这个函数返回的ntf是一个包含零点、极点和增益的struct。6个参数的意思分别是:阶数3、过采样率32、OPT=0(优化零点位置)、NTF峰值增益取3、H-infinity范数=1(归一化DC增益为1)。NTF峰值增益取3是一个常用折衷:取太低噪声整形不够,取太高容易导致量化器过载、环路不稳定。

拿到NTF后,可以把它展开成多项式形式,得到NTF(z)的零点、极点,再反推出环路滤波器的STF(信号传递函数)关系。但在CT结构中,我们不能直接用这个NTF塞进连续时间环路,因为NTF(z)描述的是离散时间采样点的行为,而CT环路滤波器的输入输出关系要从拉氏域层面推导。

2.2 从z域到s域的映射方法:impulse invariant transform

CT环路滤波器的系数要从离散域等效得到,最常用的是脉冲不变变换(Impulse Invariant Transform,IIT)。它的核心思想是:让CT环路滤波器在量化器采样点的响应,与参考DT环路滤波器的响应完全一致。

这句话翻译成人话就是:我在离散域设计了想要的噪声整形效果,那我找一个连续时间环路滤波器,让它在量化时钟边沿上的输出序列,和那个理想离散域环路滤波器的输出序列完全一样,这样整个环路的噪声整形行为就等效了。Matlab里,这体现在每个积分级联的反馈系数计算上:

% 3阶CIFB结构:三个积分器级联,本地反馈 % 系数向量(归一化到fs=1): % a = [a1, a2, a3] -- 前向路径系数 % c = [c1, c2] -- 本地反馈系数(形成零点) % 典型值(从synthesizeNTF结果换算) a = [0.4, 0.4, 0.4]; c = [0.05, 0.2];

CIFB(Cascade of Integrators with Feedback)结构是CTDSM最常见的拓扑:前向路径三个积分器级联,反馈DAC分别注入到三个求和点(对应三个前向系数),本地反馈从第二、第三级输出引回前级(对应两个反馈系数,用于把NTF零点从直流搬到带内高频处)。相比CIFF(前馈)结构,CIFB的优点是积分器输出摆幅比较小、对运放压摆率要求低一些,缺点是反馈DAC数量多、功耗略高。

这里必须强调一点:Matlab里delsig工具箱算出的系数默认是离散域的,不能直接拿去做连续时间电路。我最初做仿真时直接照搬DT系数跑CT模型,结果稳定性一塌糊涂——后来才意识到需要做一次DT到CT的等效变换。

2.3 连续时间积分器与RC取值

连续时间环路滤波器通常用RC有源积分器或者gm-C积分器实现。RC积分器的传递函数是:

H_integrator(s) = 1 / (s * R * C)

时间常数τ = R*C与采样周期Ts的比值决定了积分器的增益。我们在Matlab行为级模型里通常直接把积分器建模为s域的1/(s*τ)形式,系数直接以“每个采样周期内完成的积分量”来表示。换言之,前向系数a1实际上是反馈DAC电流经过第一个积分器后在单个Ts内产生的电压变化量,归一化到量化器满量程。

实际工程中,RC的绝对取值取决于电路指标——采样电容、热噪声预算、运放摆率等——但行为级仿真阶段根本不需要管这些物理量,只要保证每个积分器的传递函数在目标频率处的增益、以及各级系数比值是对的。这也是行为级仿真和晶体管级仿真的本质区别:前者验证架构和噪声整形是否达到理论性能,后者验证电路实际能不能跑出这个性能。

3. Matlab仿真模型搭建

3.1 行为级模型的核心结构

3阶CTDSM的行为级仿真模型,我习惯拆成三块:连续时间环路滤波器、量化器(比较器)和反馈DAC。整个环路要同时包含连续时间积分和离散时间量化——这种混合模型正是Matlab/Simulink最擅长处理的地方。

如果只用脚本做仿真(不搭Simulink模型),最常见的方式是把连续时间积分器用零阶保持等效离散化,再用循环逐个采样点跑。这种做法的好处是快、直观、可复现,坏处是没法真正体现连续时间行为(比如环路延时)。想验证连续时间行为的细节,更稳妥的是在Simulink里搭连续时间积分器,用小步长变步长求解器仿真。下面我给出的是脚本方式的离散等价模型实现,它足够精确地还原了环路在采样时刻的行为。

3.2 核心代码实现

整个仿真脚本的骨架长这样:

%% 3阶CIFB连续时间Delta-Sigma ADC行为级仿真 fs = 100e6; % 采样率 100 MHz Ts = 1/fs; OSR = 32; fb = fs/(2*OSR); % 信号带宽 1.5625 MHz N = 16384; % FFT点数 t = (0:N-1)*Ts; % 输入信号:满量程-3dBFS fin = 0.289e6; % 输入频率 289 kHz Amp = 0.7; uin = Amp*sin(2*pi*fin*t); % 环路滤波器状态变量 x1 = 0; x2 = 0; x3 = 0; % 前向系数(单位:1/s) a1 = 2*pi*8e6; % 第一个积分器的单位增益频率 a2 = 2*pi*5e6; a3 = 2*pi*3.2e6; % 本地反馈系数 c1 = 0.05*a1; c2 = 0.2*a2; % 量化器增益近似1(归一化) % 反馈DAC输出:NRZ脉冲,等效为零阶保持 vfb = 0; out = zeros(1, N); vfb_history = zeros(1, N); % 简化离散等价模型:每个Ts内积分器更新 for n = 1:N % 反馈信号(前一个时钟周期的量化结果) if n == 1 vfb = 0; else vfb = out(n-1); end % 第一个积分器输入:uin - vfb(假设DAC归一到±1) % 用“delta积分”近似连续时间积分 x1 = x1 + (uin(n) - vfb) * Ts * a1 - c1 * x2 * Ts; x2 = x2 + (x1 - vfb) * Ts * a2 - c2 * x3 * Ts; x3 = x3 + (x2 - vfb) * Ts * a3; % 量化器:1位比较器 out(n) = sign(x3); end

注意这个代码是简化版本,实际的工程设计里系数需要由前面提到的IIT变换精确求出,不能随手给a1=2*pi*8e6这种值。这里给出来是为了说明仿真循环的结构:每个采样周期内,积分器连续积分、采样点处量化器判决、反馈DAC维持上一个结果直到下一个时钟沿——这就是NRZ DAC的行为。

3.3 仿真时长与精度的权衡

这里有一个初学者很容易踩的坑:仿真点数N选多少合适?我的经验是:

  • N至少要覆盖足够多的输入信号周期,否则FFT频谱泄漏严重。经典做法是“相干采样”,让fin = k*fs/N(k为整数且与N互质),这样频谱上的能量就能完美落在一个FFT bin上。
  • N越大,噪底越低,SNDR的计算越准,但仿真时间线性增长。我在仿真100MHz采样率、OSR=32的3阶CTDSM时,N=65536基本足够把噪底压到量化噪声底之下,再大就是纯浪费计算时间了。

另一个容易被忽略的点是积分器的初值。仿真开始时若积分器从0起步,前几百个采样点会有一段“瞬态建立”过程,直接做FFT会引入严重的频谱假象。我通常的做法是丢掉前N/16个点,或者在输入信号上加一个软启动窗:

% 简单有效:去掉前N/16个点再计算频谱 start_idx = floor(N/16) + 1; y_seg = out(start_idx:end);

4. 仿真结果提取与性能评估

4.1 从时域输出到SNDR

跑完仿真后,输出序列out是一个±1的比特流。要评估性能,需要通过FFT计算频谱,然后从频谱里读取信号能量和带内噪声能量:

% 对输出比特流做FFT win = hann(N, 'periodic')'; % 汉宁窗,减少频谱泄漏 Y = fft(out .* win); Y_mag = abs(Y(1:N/2)) / (N/4); % 幅度归一化 % 计算信号bin:第一个非直流峰值 [~, signal_bin] = max(Y_mag(10:N/2)); % 跳过直流和极低频 signal_bin = signal_bin + 9; % 带内噪声求和 nbins = round(OSR/2); noise_bins = setdiff(1:nbins, signal_bin); inband_noise_power = sum(Y_mag(noise_bins).^2); signal_power = Y_mag(signal_bin)^2; % SNDR 和 ENOB SNDR = 10*log10(signal_power / inband_noise_power); ENOB = (SNDR - 1.76) / 6.02;

这里有个细节:计算SNDR时要不要把谐波算进去?严格意义上,SNDR=信号与噪声+失真之比,谐波也应该算在失真里。但很多行为级仿真里量化器是理想比较器,谐波主要来自量化器非线性,这个在理想模型里其实不存在——所以行为级仿真算出来的往往是理想性能上限。真正做电路设计时,更要关注的是带内噪底抬升了多少、有没有spur、稳定时间够不够这些指标。

对于1位量化器的理想CTDSM,理论SNDR上限可以近似用经验公式估算:

SNDR_max ≈ 6.02*N_bit + 3.01*order + 10*log10(OSR/π) - 2.3

这个公式来自理想NTF模型,实际仿真结果通常比理论值低几个dB,尤其是重载调制器(失稳边缘)时掉得更明显。如果你仿真出来的SNDR比理论估算高,那大概率是NTF零点全部落在直流处、或者输入幅度太大导致量化器过载——这些情况我都在调试中遇见过。

4.2 频谱泄漏与窗函数

关于FFT频谱计算,我更推荐“相干采样+短窗”的组合,而不是盲目加长的N。相干采样时,输入频率刚好是FFT分辨率的整数倍,信号能量不会泄漏,甚至不加窗都可以。真实电路测试中我们没法保证输入频率是时钟频率的整数分频,所以才要加窗。行为级仿真里我们完全可控,所以我会优先用相干采样,窗函数只做辅助,这样谱峰的幅值读取更准。

% 相干采样的输入频率选择 k = 47; % 与N互质的整数 fin = k * fs / N; % 例如 f=287.1 kHz when N=16384, fs=100MHz

用这个办法后,信号bin的谱线就是一个干净的峰值,SNDR计算也不会因为泄漏而虚高或虚低。

5. 调优实战:我在3阶CTDSM仿真中踩过的坑

5.1 系数缩放导致的稳定性问题

第一次仿真时,我直接用了离散域synthesizeNTF算出来的系数,没有做DT到CT的映射,结果积分器输出爆掉——不管输入幅度设多小,输出永远是全1。排查下来发现是极点位置完全变了。

后来我意识到,CT环路滤波器的极点其实是由积分器时间常数决定的,而NTF的极点是由反馈系数决定的——这两者要匹配才能得到预期的稳定性和噪声整形效果。换句话说,在CT结构中,系数的物理意义变了:离散域的反馈系数直接等价于连续时间积分器的增益和本地反馈路径的强度。没有做映射,相当于积分器增益和反馈系数错位,环路稳定性被打破。

正确做法是先确定积分器时间常数τ_i,再用映射算法算出对应的反馈系数。理想情况下,行为级仿真里可以把第一级积分器的单位增益频率设为fs/(2π*OSR)的若干倍,具体倍数由你的带宽目标和噪声整形目标决定。

5.2 环路延时补偿:没有它NTF会变形

这是CTDSM跟DTDSM最大的差异点。DT结构天然把量化器延迟也算进了环路里,而CT结构里量化器的传播延迟和DAC的开关延迟是“额外的、没有设计在NTF中的”延迟。这段额外的环路延迟哪怕只有0.2个时钟周期,也会让NTF的峰值增益明显抬升,甚至导致不稳定。

我在仿真中直观看到了这一点:加了0.25*Ts的额外环路延迟后,输出比特流的频谱里带内噪底抬高了大约7dB,噪底还出现了振荡纹波——这就是NTF峰值被延迟推到过高的典型特征。

补偿手段有两种:一是在量化器前加一个“额外DAC”(常见做法是给第一个反馈DAC并联一个小幅度DAC路径,抵消额外延迟的影响);二是在仿真里通过调整反馈系数来重新等效。行为级仿真阶段,我会先在理想模型里加一个可调的额外延迟,观察SNDR随延迟的变化曲线,就能知道这个设计对时钟裕度有多敏感。

5.3 仿真步长的坑

如果你用Simulink搭连续时间模型,要特别注意求解器步长。变步长求解器(比如ode15sode45)在某些条件下会把步长拉得很大,导致量化器输出沿的检测漏掉,仿真结果完全错误。我遇到过一次:Simulink里跑2万点,输出SNDR只有18dB,百思不得其解,后来发现是求解器最大步长设成了auto,在量化器翻转时没有精细采样。

我的建议是:Simulink行为级模型里,强制最大步长不超过Ts/10,这样每个时钟周期至少采10个点,量化器翻转的时刻能被捕捉到。脚本式仿真就没有这个问题,因为循环天然按Ts步进。

6. 扩展:从行为级到晶体管级的差距在哪里

写这篇文章时,我也想把行为级仿真和实际流片之间的差距做个说明。行为级仿真里,量化器是理想比较器,DAC是理想脉冲,积分器是理想积分器。真实电路里,运放的有限增益、有限带宽、压摆率,比较器的回踢噪声、失调,DAC的电流失配和毛刺,所有这些都是额外噪声源,行为级模型统统没有。

所以,如果你在做的是流片前的设计验证,千万别把行为级仿真的SNDR当成“期望值”,它只是“理论上限”。实际电路仿真(比如用Cadence或Hspice)跑出来的SNDR会比行为级低8~15dB都是正常的。反过来,如果你只是做课程设计或架构调研,行为级仿真已经完全够用——它能快速告诉你这个架构在不考虑电路非理想性的前提下能达到什么水平,以及系数设计是否合理。

从行为级往电路级过渡的时候,我最先会引入的非理想效应有三个:运放有限增益(等效为积分器漏电)、有限压摆率(等效为积分器输出削波)、DAC的失配噪声。这三个效应是决定CTDSM实际性能的天花板,早一点在行为级模型里加上,少走很多弯路。

% 引入运放有限增益的积分器模型示例 % 理想积分器: x = x + input*Ts % 有限增益A_vol: x = (1 - 1/(A_vol*2*pi*fu*Ts)) * x + input*Ts A_vol = 60e3; % 开环增益 fu = 250e6; % 单位增益带宽 leak = 1 - 1/(A_vol * 2*pi*fu * Ts); x1 = leak * x1 + (uin(n) - vfb) * Ts * a1 - c1 * x2 * Ts;

加了运放有限增益后,SNDR立刻掉了5dB,噪底明显抬高——这就是非理想效应的直观演示,也是行为级模型往精细化方向扩展的关键一步。


最后说点个人体会。3阶连续时间Delta-Sigma ADC的行为级仿真,最核心的能力其实就是两件事:一是理解DT和CT系数的映射关系,二是掌握从频谱里准确提取性能指标的方法。第一件事决定了你模型的稳定性,第二件事决定了你评估的正确性。我的经验是:在这两件事上多花一天时间,比多跑一百组参数都值。先把仿真脚本整理好,加上环路延迟补偿和运放非理想效应,当你能从仿真结果里一眼看出“这个设计还有多少裕量”的时候,这个模型就不再是玩具了。

本文还有配套的精品资源,点击获取

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

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

立即咨询