很多人第一次在Cadence Virtuoso里跑两级运放的反馈环路稳定性仿真,都会图省事直接做一个AC分析,看到波特图上相位裕度有个六十几度就放心去流片了。我也踩过这个坑:仿真结果明明显示稳定,实际搭出来的电路一上电就疯狂振铃。后来才想明白,问题不在运放本身,而在环路增益的提取得不对——Virtuoso里看波特图并不是随手接个电压源就能拿到可信数据,探头放哪里、环路怎么断开、用AC还是STB分析,每一步都直接影响相位裕度的读数。这篇文章我就以两级运放为例,把从原理图搭建到STB仿真、再从波特图判断稳定性的完整流程一步步拆开讲,也会把仿真里常见的器件不定义、不收敛、相位曲线跳变这些坑一起列出来,给刚上手Virtuoso的朋友一条能直接照做的路径。
1. 仿真之前,先把反馈环路的稳定性问题想清楚
1.1 为什么两级运放特别容易不稳定
单极点系统永远不会振荡,因为最大相移只有90°。两级运放至少有两个主极点,第一级输出节点和最后一级输出节点各自贡献一个极点,闭环之后在单位增益频率附近很容易出现第二个极点的相移,让相位裕度掉到危险范围。更麻烦的是,两级运放还常常存在一个右半平面零点,尤其在加了Miller补偿之后,这个零点会进一步恶化相位,这也是为什么很多教科书里要专门加一个调零电阻。
在真正打开Virtuoso之前,建议先在脑子里过一遍这个链路:开环增益A(s)在高频以-20dB/dec滚降,反馈系数β如果小于1,环路增益T(s)=A(s)β的0dB频率就要比运放的单位增益频率低。两级运放不加补偿时,第二个极点往往就在GBW附近,这就导致0dB处的相位余量很小。你可以把稳定性的判定当成一个跷跷板:增益滚降越慢,越容易稳定;但为了带宽,我们又希望极点越远越好,两者天然矛盾。
1.2 相位裕度与增益裕度到底看什么
很多初学者盯着曲线上的0dB点看相位,这没错,但要注意Virtuoso里STB分析给出的相位曲线和相位裕度的换算关系。我们常用的判据是:在环路增益幅度降到1(0dB)的频率处,如果环路相位距离-180°(或0°,取决于定义)还有45°以上,系统就相对稳定。工程上我喜欢看60°左右的相位裕度,这个值既能保证没有明显振铃,又不会为了稳定把带宽压得太狠。增益裕度一般取10dB以上,也就是当相位到达-180°时,增益幅度要低于0dB至少10dB,防止温度和工艺角变化后出现临界振荡。
这里有个容易混淆的地方:Spectre的STB分析计算出来的环路增益T在低频时相位通常接近0°(因为它包含了负反馈的负号),所以相位裕度等于180°加上这个相位值。如果你用传统开环AC法测的是Aβ但不带负号,低频相位就可能是-180°。两种定义在Virtuoso里都能看到,关键是别搞混,看到相位曲线从-180°开始还是从0°开始,对应判据要反过来。我习惯在结果里直接找phaseMargin这个输出量,不自己从曲线上读数,减少出错。
1.3 需要的仿真环境和工具链
做这类仿真,Cadence Virtuoso IC6.1.8以后的版本配合spectre仿真器就够了,IC23.1也没问题。PDK倒不是重点,gpdk180、tsmc180或者更先进工艺的PDK都可以,关键是电路拓扑本身。如果你用的是老库,注意管子模型要带完整的寄生电容参数,否则仿真结果会偏乐观。ADE L适合单点仿真,要扫描参数就上ADE XL,两个界面在分析设置上差别不大,但xl批量跑工艺角方便。我通常在仿真前先确认原理图里的analogLib库可用,因为后面要用到vdc、gnd、iprobe这些基础符号,缺库的话原理图会直接飘红。
2. 搭建两级运放测试台:原理图、激励与模型设置
2.1 电路搭建要点
这里以最经典的Miller补偿两级运放为例:第一级是NMOS差分输入对,负载用PMOS电流镜,第二级是共源放大器,输出级采用Class A结构。仿真模型我建议先不要画太完整的偏置电路,用理想电流源做尾电流源反而更容易定位问题。管子尺寸可以先用这些初始值:输入对管W/L=20u/500n,电流镜负载W/L=10u/500n,第二级放大管W/L=50u/500n,尾电流20uA,电源1.8V。负载电容CL取5pF,这样第一级输出节点的极点大概在几百kHz量级,第二级输出节点因为负载电容比较大,极点也不会太高,足够看出补偿前后的差异。
反馈网络最简单的是接成单位增益缓冲器,把输出直接短接回反相输入端,这样反馈系数等于1,稳定性分析最严格。想做成增益为2的闭环,就用两个等值电阻R1=R2=10kΩ,构成同相放大器。电阻值别取太大,否则反馈节点寄生电容会引入额外极点;也别取太小,否则会明显加载第二级输出,改变开环增益。
2.2 差分激励与共模电压设置
测试台里我用两个理想电压源给差分输入端提供直流工作点,而不是直接接一个差分信号源,这样更好控制共模电压。让两个电压源DC值都等于0.9V,AC幅度一个设1V、另一个设-1V,这样等效输入差分AC信号为2V,算AC增益时记得除以2。但如果你用的是STB分析,其实不需要在输入加AC激励,STB会在环路内部自动注入小信号,所以输入端只保留DC工作点就行。很多新手在这里犯迷糊:明明采样点都在环路里,为什么还要外部AC源?答案是不需要,外部AC源只会干扰STB的结果。
设置完DC电压后,先跑一次DC工作点仿真,确认所有管子都工作在饱和区。检查方法很简单,在Virtuoso的Results里面把晶体管工作点打印出来,看Vds是否大于Vov。如果某个管子在线性区,后面AC和STB的结果都没有意义。这个步骤只要30秒,但能省掉后面几个小时查问题的时间。
2.3 仿真器与分析类型选择
在ADE L里选spectre作为仿真器,然后选择analysis。要做环路增益,我们有两种路径:传统的开环AC分析,或者STB分析。我建议直接学STB,因为它不需要手动破坏环路,负载效应也处理得干净。但开环AC法也不是没用,很多老工程师还在用,而且看到的结果更直观,所以下一章先演示开环法是怎么做的,再来对比为什么STB更好。具体到STB,你需要在analysis窗口选择stb,设置扫描频率范围从1Hz到1GHz,扫描点数取1000点logarithmic,这个密度够画一条平滑波特图,又不至于让仿真跑太久。
3. 波特图获取全流程:从开环AC到正确断开环路
3.1 为什么不能直接看闭环输出波特图
很多人图省事,在闭环结构下直接对输入跑AC,然后看输出Vout的波特图,以为这就是环路波特图。这是最大的误区。单位增益缓冲器的闭环输出幅度大约0dB,相位接近0°,这条曲线只能告诉你闭环响应,完全看不到环路增益T的0dB点在哪里,更算不出相位裕度。反馈环路的稳定性要看的是T(s)=A(s)β,而不是闭环传递函数H(s)=A/(1+T)。两者关系密切,但你没法直接从H的曲线上读出PM,除非H在0dB处的峰值形状非常明显,那也是一种间接法,但要靠经验。
所以必须“把环路断开”。断开的目的是让我们能够单独测环路增益,但又不破坏直流工作点。如果只是简单地把反馈线剪断,运放的工作点会漂移,管子可能退出饱和区,测出来的增益就是错的。解决办法是在断开点人为提供直流路径。
3.2 开环AC法:断开点位置和测试源设置
我用单位增益缓冲器做例子。反馈路径就是从输出直接接到反相输入的那根线。操作方法是:把这根线剪断,然后做两件事。第一,在运放输出端放一个直流电压源VDC,电压值设成前面DC仿真得到的静态输出电压,AC幅度设成0。这个电压源的作用是给运放输出提供直流负载和工作点,确保断开后运放仍然对地有正确的电压。第二,在原来接反相输入的那一端(也就是反馈网络侧),放一个交流电压源VAC,DC值设成0,AC幅度设为1V。这样AC信号从反相输入端注入,经过运放放大后在输出端得到一个响应。
这里要强调:你不能直接把Vout的AC幅度当作环路增益。因为测试信号会通过反馈网络前馈到输出端,你测到的是两部分叠加。标准做法是计算环路增益T = Vout/VAC - 1,减掉那部分前馈分量。在Virtuoso里可以用Calculator的表达式实现,或者在后处理时用波形相减。这一步很多人漏了,导致低频增益看起来比开环增益大很多,相位曲线也不对。
3.3 用大电感和大电容隔离直流,减少负载效应
开环AC法还有一个隐患:测试源和直流电压源会给环路增加额外的阻抗负载,影响运放输出节点的高频极点。简单点说,测量动作本身改变了电路。为了解决这个问题,工程上有一种经典做法是在断口处串一个大电感和并一个大电容。具体来说,在原输出端到反馈网络之间串联一个1GH的大电感,然后在反馈网络节点对地并联一个1GF的大电容。大电感让直流工作点能通过,但对AC信号相当于开路;大电容让AC信号对地短路,但直流被隔断。这样就把交流通路和直流通路分开了,测试源给出来的AC信号不会影响运放输出端的直流负载。
这种做法在Virtuoso里完全可行,但有点繁琐。每次要改原理图,还要小心电感电容的寄生方向。所以我个人更推荐用下一章的STB分析,它本质上就是自动实现了一种理想的中断测量,Virtuoso已经在spectre里替你处理好了负载效应,你只需要放一个iprobe符号。
4. 用STB分析直接测环路增益
4.1 STB的原理与iprobe放置
STB是Spectre自带的Loop Gain分析,全称是Stability Analysis。它的核心思想是在环路中的某个位置注入一个理想测试信号,通过比较注入点两侧的响应来计算环路增益。这样做的好处是既不影响直流工作点,也不引入额外的寄生负载。你要做的就是把一个名为iprobe的符号串联到环路里。
iprobe在analogLib库里,是一个带正负端子的紧凑符号。怎么放?以单位增益缓冲器为例,就是从输出到反相输入的反馈连线中间插入iprobe,让电流从输出流向反相输入。正负端子千万不要接反,否则时域仿真方向对、STB结果却可能差一个负号。对于电阻反馈闭环,iprobe应该放在反馈电阻进入运放反相输入端的那根线上,而不是放在输出端外头。很多新手把iprobe放在输出节点和负载之间,那就完全错了,因为那里不在反馈环路里,spectre根本找不到环。
4.2 设置stb analysis与仿真参数
在ADE L中打开Choose Analysis,选择stb类型。然后需要指定探测点,也就是选择你放置的iprobe实例。在analysis form里填上实例名,类似“I0.iprobe”,注意层次路径要写对。如果不填或者填错,spectre会直接报错找不到stb probe,这个报错信息非常常见。频率范围我一般填1Hz到1GHz,点数log10分布。输出选项里可以选择保存环路的幅度和相位,也可以让spectre自动计算phase margin和gain margin。
设置好后直接跑仿真。这个过程比AC要稍慢一点,因为spectre要在每个频点做矩阵扰动,但1000个频点通常几秒到十几秒就能结束,完全在可接受范围内。如果仿真报“未定义全局地”之类的错误,先回原理图检查有没有放analogLib的gnd符号,spectre对不接地这类问题很敏感。
4.3 波形查看:幅度、相位与相位裕度
仿真结束后,在Direct Plot -> Main Form里选择stb analysis,再选择Loop Gain,然后选中输出波形。Virtuoso会画出两条曲线:幅度曲线和相位曲线。幅度曲线以dB为单位,相位曲线会显示在0°附近下降,因为spectre定义的环路增益T已经包含了负反馈的负号。读取相位裕度的方法是:先找到幅度曲线穿越0dB的那个频率点,然后看同一频率下相位曲线是多少,PM = 180° + phase。比如相位是-120°,那PM就是60°。
更省事的办法是直接在Results Direct Plot里选“Phase Margin”,Virtuoso会把0dB处的相位裕度和频率自动打印出来。注意如果相位曲线在0dB附近有剧烈跳变,多半是扫描步长太粗或者环路没有完全断开,先用更密的点数确认一次。
5. 实测案例:补偿前后的对比仿真
5.1 未补偿时的波特图与稳定性隐患
我按前面的测试台搭了一个两级运放,不接Miller电容,直接跑STB。结果很典型:低频环路增益大约70dB,0dB频率落在大概8MHz,但在这个频率点相位已经掉到-140°,算下来PM只有40°,属于临界稳定。如果看在5pF负载下的瞬态响应,上升沿会有一串明显振铃,大概要经过几个周期才能稳定下来。这种电路做LDO或者buffer都会出问题,负载电流一变化就可能振荡。
这里想强调的是,幅度曲线看起来完全正常,一条平滑的-20dB/dec滚降,很容易给人“这个运放很稳定”的错觉。真正要命的是相位。两级运放的第二个极点在GBW附近,它把相位拖下去的速度比幅度还快,所以在不看相位的情况下你永远不知道系统有多危险。建议每次跑完STB,强制自己先看PM数值,再去看曲线形状。
5.2 Miller补偿电容如何改变波特图
现在我在第二级输入和输出之间加上一个2pF的Miller电容Cc,再跑STB。幅度曲线会看到两个明显变化:低频增益几乎不变,但第一极点的位置从几十kHz被压到了几kHz,而第二极点被推向了更高的频率,这就是极点分裂。GBW也会略微下降,从8MHz降到大概5MHz。最关键的是0dB处的相位变成了-115°,PM提升到了65°,瞬态振铃基本消失。Miller电容实际上是用低频增益换稳定性,所以我们看到第一极点低频移动并不是坏事。
Cc的取值有个经验尺度:对两级运放,Miller电容只要取负载电容的1/2到1/3左右,通常就能把PM拉到60°以上。太小了没效果,太大了带宽损失严重。你可以把Cc设成变量,在ADE XL里扫描0.5p、1p、2p、3p、5p,然后对比PM和GBW的变化曲线,很快就能找到一个适合自己指标的折中值。
5.3 调零电阻Rz的作用与仿真验证
Cc带来的副作用是右半平面零点,它会让相位曲线在某个频率后重新往上抬,听起来像好事,但右半平面零点实际上降低了相位裕度,在瞬态里表现为更长时间的拖尾。为了抵消这个零点,我会在Cc串联一个调零电阻Rz,阻值取第二级跨导的倒数附近。在Virtuoso里把Rz设成变量扫描,从1k到10k步进1k,然后观察PM曲线变化。仿真结果通常是Rz取2k到4k时PM最大,继续增大PM反而下降,因为电阻会引入另外的零点/极点对。
这一步非常建议用批量扫描做,不要一个个手改电阻值。ADE XL里设置好变量后,可以一次性把所有工艺角跑完。我见过很多工程师在补偿电容上反复试值,其实用扫描的方式半小时就能得到全部趋势。记住,仿真不是用来碰运气的,是用来找规律的。
6. 仿真中容易踩的坑与排查方法
6.1 器件未定义、不收敛和参考地问题
新手在Virtuoso里遇到的最多的问题就是“Device is undefined”或者“模型库没加载”。这个通常不是电路问题,而是没有在Model Library Setup里添加PDK的模型文件。如果你用的是PDK的管子,记得添加对应的spectre模型库,并确认工艺角选的是tt还是ss/ff。加了Miller电容后不收敛也是常见问题,尤其是在瞬态仿真时,建议先在DC分析里加大gmin(比如gmin=1e-12),或者给电容加初始条件ic=0,很多时候能直接跳过收敛死循环。
STB仿真报错找不到iprobe是另一种高频问题。检查一下你到底在哪个层级放的iprobe,如果放在子模块内部,就直接引用子模块内部的实例路径,路径写错肯定报错。我习惯把iprobe放在顶层测试台里,尽量不埋在子电路里,这样好找也好查。
6.2 相位曲线异常跳变或往上翘的原因
相位曲线出现很多毛刺和跳变,最常见的原因是仿真扫描点数太少。比如只有100个点,在相位快速滚降的区域会看到锯齿。解决办法是改用logarithmic扫描,并增加到500或1000点。另外,如果断点没有完全断开,比如反馈线上还有一个寄生电阻或者残留连接点,STB依然能跑,但相位会在某些频率出现奇怪的“上翘”,这是因为有一条额外的信号通路绕过了iprobe。检查原理图,确认反馈路径是唯一通路。
还有一点:如果你直接plot的相位曲线在±180°之间来回翻转,那只是反正切函数的结果回卷,不代表电路真的在这个频点跳变。在Calculator里用phaseUnwrap函数展开一下,或者直接看spectre输出的phaseMargin函数值。很多人在这个细节上被带偏过,以为是电路有额外的极点,其实是显示问题。
6.3 仿真结果与理论计算对不上时的检查清单
如果STB出来的GBW、PM和你按小信号模型手算的结果差很多,我从上到下检查三件事:第一,工作点对不对,具体看输入对管和电流镜是否都在饱和区,第二级放大管是否在线性区;第二,负载是否多加了寄生电容,比如你给输出节点接了一根很长的走线或者探针,探针本身就有电容;第三,环路是否真的只经过你放iprobe的那一条路径,有没有其他反馈路径,比如电源到地的寄生反馈。
还有一个小技巧:把反馈系数算出来,和仿真对比低频环路增益。如果β=1,低频T应该等于运放开环增益;如果β=0.5,低频T应该比开环增益低6dB。这个数字对不上,问题基本都出在反馈网络本身,要么是电阻接错,要么是地节点没接对。
说实话,这些坑我几乎每一个都踩过一遍。最开始跑STB的时候,为了省事直接复制了一个别人的测试台,结果iprobe方向反了,PM读出来一个负值,当时还以为是电路真的不稳定,查了好几天。后来把每一个环节都重新拆开验证,才真正理解了断开环路和探针位置这两件事的重要性。Cadence Virtuoso是个好工具,但它只负责“算”,不负责“对”,你得自己知道在算什么、为什么这么算。想通这一点,波特图就不再是一堆曲线,而是你跟电路之间对话的语言。