开篇先说个结论:在Cadence ADE里跑VCO的相位噪声仿真,卡住90%新人的不是电路本身,而是对PSS和Pnoise这套分析机制的理解。很多人上来就点仿真,结果PSS不收敛、Pnoise报错、相位噪声曲线像心电图一样乱跳,最后只能去论坛翻老帖碰运气。
这篇东西我按实际项目的完整流程来写,从原理到操作、从参数设置到问题排查,目标是让你照着走一遍就能拿到一条能用的1GHz VCO相位噪声曲线。里面所有步骤都在IC617/IC618的ADE L和ADE XL里实测过,有些坑是我自己踩过、也帮别人排过的。
1. 为什么VCO相位噪声必须用PSS+Pnoise
1.1 直接跑AC分析为什么不行
很多从LNA、Mixer转过来的人,第一反应是拿AC分析去跑相位噪声。这个思路在VCO上行不通,原因很简单:AC分析的前提是电路工作在固定偏置点上的线性时不变系统。但VCO本质上是一个自激振荡器,它的工作点本身就随时间周期性变化,而且输出信号的大信号摆幅会剧烈改变器件的工作状态。
以LC振荡器为例,交叉耦合管在振荡周期内一会儿工作在饱和区、一会儿进入线性区甚至截止区,跨导gm和输出电容都在随相位不断变化。你用AC分析只能看到某个瞬间的小信号响应,根本抓不到这种时变特性对噪声的调制作用。
还有个更致命的问题:VCO没有外部输入信号,AC分析需要定义输入源才能算出传输函数。你总不能给振荡器强行加一个输入端口,那测出来的东西没有任何物理意义。
所以,要仿真VCO相位噪声,必须用PSS(Periodic Steady-State)先求出振荡器的周期稳态解,再用Pnoise(Periodic Noise)在这个稳态解基础上做周期时变噪声分析。这两步是绑定的,缺一不可。
1.2 相位噪声的本质是什么
相位噪声描述的是振荡器输出信号在频域上的纯度。理想振荡器输出是一个单根谱线,实际振荡器由于器件噪声的扰动,能量会扩散到载波附近的边带上。在频偏Δf处取1Hz带宽内的噪声功率与载波功率之比,就是L(Δf),单位是dBc/Hz。
用Leeson模型可以直观理解:
[ L(\Delta f) = 10 \log_{10} \left[ \frac{2FkT}{P_{sig}} \cdot \left( \frac{f_0}{2Q\Delta f} \right)^2 \right] ]
这里面F是噪声因子,Q是谐振腔品质因数,Psig是振荡信号功率。从公式能看出两个关键点:一是频偏越小相位噪声越大,呈现-20dBc/Hz每十倍频程的斜率(除了闪烁噪声主导的近载波区域斜率更陡);二是Q值越高,相位噪声越低。所以LC振荡器天然比环形振荡器相位噪声好,因为LC谐振腔的Q值动辄几十,环形振荡器等效Q值只有个位数。
我们最终要看的就是f0=1GHz情况下,不同频偏处的相位噪声值。通常关注1kHz、10kHz、100kHz、1MHz这几个点,对应不同应用场景的需求。
1.3 PSS和Pnoise的分工逻辑
PSS负责找到振荡器稳定的周期工作状态。对VCO来说,它的输出是一个周期信号(近似正弦波),频率f0由电路参数决定。PSS通过牛顿迭代法求解这个周期稳态解,而不是先做瞬态仿真等到稳定再取数据,这样能大幅缩短仿真时间。
Pnoise则是在PSS解出的周期工作点上,把器件噪声源(热噪声、闪烁噪声等)做周期时变的小信号分析。它把噪声分为两类处理:AM噪声和PM噪声。对振荡器来说,PM噪声(相位扰动)才是我们关心的相位噪声,AM噪声通常被振荡器的幅度限制机制压制,影响很小。
这里有个关键设置:Pnoise里要把noise type选成“jitter”或“phase noise”,并勾选**“Output: phase noise”**。如果选成普通noise,仿真器会自动把AM和PM噪声一起算,得到的曲线不是标准的相位噪声定义。
2. 仿真前的准备工作
2.1 电路搭建的基本要求
我默认你已经有一个能正常起振的VCO原理图。不管是LC交叉耦合、Colpitts还是环形结构,进PSS之前有几点必须确认:
第一,电源和地要干净。仿真器默认忽略理想电源上的噪声,但如果你在电源路径上放了电感或电阻用于噪声注入,要确保这些器件参数设置合理,否则会影响PSS收敛。
第二,输出节点要明确。Pnoise分析需要指定输出节点,一般选VCO的单端输出或差分输出的一端。差分输出的话,可以用“vout_p - vout_m”这样的表达式作为输出,但新手建议先用单端输出,把流程跑通再说。
第三,电路必须能起振。PSS的本质是求稳态解,如果电路本身没有振荡,PSS会一直不收敛。我见过有人把负阻管的偏置给错了,电路根本没起振,然后花了两天调PSS参数——方向就错了。进PSS之前,先跑一个2~3us的瞬态仿真,确认输出波形是稳定的正弦波再继续。
这里顺便提一句:PSS求解器对初始条件不敏感,它不管电路是怎么起振的,只要存在稳定的周期解就能找到。所以哪怕瞬态要跑1us才能稳定,PSS也可能只需要几十个周期就能收敛,这是PSS效率高的核心原因。
2.2 仿真器的版本和设置
我用的是IC617自带的ADE L,IC618的ADE XL操作逻辑类似,只是界面换成了新风格。仿真器用Spectre,这是Cadence自己的SPICE级仿真器,对PSS/Pnoise支持最完善。
在ADE窗口里,Setup → Simulator确认选的是Spectre。如果你用了APS(Advanced Parallel Simulator),某些老版本对Pnoise的支持有问题,建议先用标准Spectre跑通再考虑提速。
另外,模型库一定要包含噪声参数。有些foundry的模型默认把噪声开关关了,你可能要用**“noise”**语句或模型库里的选项打开。怎么确认?瞬态仿真时右键输出节点查看噪声——这个后面在注意事项里细说。
2.3 测试平台的搭建
为了测相位噪声,我们需要把VCO的输出引出来。这里建议加一个理想缓冲器或者直接用输出节点分析。如果VCO后级接了分频器或buffer,PSS分析的是整个环路的周期稳态,仿真时间会变长,但结果更接近实际。
我一般这样搭testbench:
电源用理想直流源vdc,VCO输出直接连一个理想电阻到地作为负载,电阻值取50欧姆或者VCO输出阻抗的匹配值。注意不要用太大的负载电容,否则会改变振荡频率。
如果方便,把输出节点命名成“vout”,后面Pnoise设置内部节点时直接填就行。
3. PSS仿真参数配置详解
3.1 打开PSS分析
在ADE窗口选择Analyses → Choose,在弹出的窗口中选择pss。这里有几个参数要填:Fundamental Frequency、Number of Harmonics、Accuracy Defaults、Errest、Oscillator等。
Fundamental Frequency填的是振荡频率,对1GHz VCO来说填1G。注意这里有个细节:如果VCO的实际振荡频率不是你填的这个值,PSS会迭代调整。但如果你填的范围离真实频率太远,收敛会变慢甚至失败。建议先用瞬态仿真测一下实际频率,再回来填。
Number of Harmonics表示你要计算多少个谐波次数。对1GHz的LC振荡器来说,填5到10就足够了。这个参数影响仿真精度和时间:填得越大,高频段的噪声计算越准,但仿真时间成倍增加。我这个项目里填了5,后面看结果够用。环形振荡器可能需要更多谐波,因为它的波形不是纯正弦,高次谐波能量较大。
Accuracy Defaults可以选moderate或conservative。第一次跑推荐用conservative,这个模式会自动收紧误差容限,避免因为精度不够导致PSS收敛到“伪稳态”。虽然仿真时间会多花一点,但能省去排查问题的大把时间。
3.2 振荡器设置的关键选项
在PSS窗口里有一个Oscillator选项,必须选中。这个选项告诉Spectre:你分析的是一个自激振荡器,没有外部周期激励源。
选中后会出现一个Reference Node字段,这里填振荡器输出节点,比如“vout”。Spectre会从这个节点提取振荡频率和相位信息,用于后续的Pnoise分析。
很多教程会忽略这个Reference Node的填写,结果就是PSS跑完了,Pnoise出来一堆NaN。我在实际项目中确实遇到过,原因是Spectre不知道以哪个节点的相位为基准来定义“相位噪声”。你可以在测试台里填“vout”,或者填差分输出的两个节点(用表达式),推荐单端节点,简单明确。
3.3 计算谐波次数和beat频率的配合
PSS里还有一个Beat Frequency的概念。对于普通周期驱动电路,beat频率等于激励频率;对于VCO,beat频率等于振荡频率f0。Specify框中选Automatic,让Spectre自行计算;选User specified时手动填频率。
注意,1GHz并不是跑1ns的仿真时间。PSS是频域方法,计算时间跟周期数无关,只跟谐波数和求解精度有关。有些新人以为PSS和瞬态一样要跑很多个周期,其实不用。Spectre会在频域建立谐波平衡方程,迭代求解傅里叶系数。
这里有个经验:PSS的收敛速度对初值敏感。如果第一次PSS跑挂了,你可以先在瞬态模式跑一小段(比如500ns),把PSS的初始猜测设为瞬态结果。在PSS窗口里勾选Initialize选项卡中的相应选项,通过加载瞬态结果文件来提供初始值,能显著提升收敛概率。
3.4 PSS仿真时间和误差控制
PSS的tstab参数表示“瞬态启动时间”,也就是在进入周期稳态分析之前,先跑一段瞬态让电路接近稳态。对VCO来说,这个值一般设为振荡周期的几百到几千倍。
1GHz的周期是1ns,tstab建议设为一个数,比如从0到50n或100n。50n意味着先跑50个周期让振荡器达到幅度稳定。这个值设小了,PSS从非稳态出发会导致迭代不收敛;设大了虽然稳但浪费时间。
ErrPreset参数控制误差。有low、medium、high三档,对应Spectre内部不同的误差容限组合。选medium即可,配合conservative的Accuracy Defaults,能兼顾精度和速度。如果你最终要的相位噪声曲线在1MHz频偏处出现非物理的凸起,可以考虑把ErrPreset调到high重跑一遍。
运行PSS后,Spectre会输出一个pss_fd结果,包含各个谐波的幅度和相位。你可以调用计算器里的**“pss Harmonic”**函数,查看1GHz处的输出幅度。如果这个值跟瞬态的幅度对不上,说明PSS计算有问题。
4. Pnoise仿真参数配置详解
4.1 基本设置项
PSS跑通之后,回到Analyses → Choose,这次选择pnoise。Pnoise窗口里的第一个参数是Noise Type,选jitter。如果你选的是“sources”,那做的是器件噪声贡献分析,而不是相位噪声——两个概念别搞混。
Sweep Type选relative,表示我们关注的是相对载波的频偏。Sweep Range是指频偏范围,比如从1kHz扫到10MHz或者100MHz。Type选Logarithmic,Points per decade填20或50。用于画图足够,用于提取单点值也够用。
关键字段是Output和Input Source。
Output指的是噪声输出的节点,填“vout”,或者选中输出节点后在电路原理图上点选。Output Type选voltage,表示以电压形式测噪声。如果输出是差分,可以用“vout_p - vout_m”表达式。
Input Source是参考源的设置。对VCO这类自激振荡器来说,Pnoise分析并不需要像LNA那样指定输入源,但它要一个参考节点来定义相位。所以这个项目里频率参考来自PSS Reference Node设置,我们在PSS里已经填了“vout”。Pnoise里Input Source可以留空或选择“none”,因为噪声源是振荡器内部器件,不是外部输入。
4.2 输出与参考节点的设置
Pnoise窗口中有个Output Harmonics选项,默认是1。这个参数决定在哪个谐波处计算相位噪声。对1GHz基波振荡器,1就够了。如果你关心的是二次谐波处的噪声,可以在这里改,但一般用不上。
底层还有一个Max Sideband参数,这个比较重要。Pnoise计算时会考虑噪声在各谐波附近的混叠效应。Max Sideband=7意味着每个噪声源会被混叠到±7次谐波上再叠加。LC振荡器这个值填7够用,环形振荡器建议填到15。数值越大计算越精确,但仿真时间暴涨,按需设置。
关于输出表达式,如果你用的ADE XL,可以在Outputs里添加表达式:
phaseNoise(vout ?result "pnoise" ?pnoiseType "phaseNoise" ?freq "1G" ?relHarmNum 1)这种表达式可以批量提取不同频偏处的值,比如1kHz、100kHz、1MHz,方便数据对比。
4.3 phase noise和jitter的关系
Pnoise跑完后,Spectre会同时给出phase noise和jitter两类结果。它们本质上是同一个物理量的不同表述:相位噪声是频域表征,jitter是时域表征。两者通过积分关联:
[ \sigma_{\Delta T} = \frac{1}{2\pi f_0} \sqrt{2 \int_{f_1}^{f_2} L(f) df} ]
如果你的应用是时钟恢复电路,那jitter值更有参考意义;如果是射频本振,相位噪声值是设计指标直接相关的。Pnoise窗口里有一个**“Compute jitter”**选项,勾上之后会额外计算积累抖动(accumulated jitter),包括随机抖动和确定性抖动分离。我在做SerDes时钟时经常用这个功能。
这里提醒一句:不要在PSS里把tstab设得特别大,然后指望Pnoise结果不受影响。Pnoise是在PSS稳态解上进行计算,PSS的精度直接影响Pnoise的每一个点。如果PSS没收敛好,Pnoise在低频偏(比如1kHz)处会出现明显毛刺,这种毛刺通过增加Pnoise点数解决不了,必须回到PSS调精度。
5. 完整仿真流程实操演示
5.1 分步执行一次完整的仿真
下面以我常用的某个0.18um工艺LC-VCO为例,把完整操作串一遍。
电路基本参数:电源1.8V,尾电流源设定2mA,电感3nH,可变电容在0.9V控制电压下约2.2pF,交叉耦合管宽长比40um/0.18um。理论谐振频率约1.95GHz(3nH对2.2pF)。实际振荡频率会低于谐振频率,我瞬态跑完看到频率约1.85GHz。为了对齐1GHz的标题,假设我们把电感改成10nH左右,或者直接把这个流程用在1GHz设计里,方法一致。
第一步,瞬态确认起振。
在ADE里新建瞬态分析,stop time设为1us,精度选moderate。跑完后用计算器看vout的频率和幅度。确认f0=1.000GHz,幅度在0.8V到1.4V之间(单端)。这一步能同时确认电路工作点是否合理,比如尾电流管是否在饱和区。
第二步,配置PSS。
在Analyses里选pss,设置如下:
- Fundamental Frequency: 1G(按瞬态结果填)
- Number of Harmonics: 5
- Accuracy Defaults: conservative
- Oscillator: 勾选,Reference Node填vout
- tstab: 50n
跑之前先保存一下状态,用ADE的Check and Save。然后直接跑PSS。
第一次跑通常会花几分钟。跑完后看结果,点击Direct Plot → Main Form,选择PSS,查看vout的基波幅度。如果幅度正常,说明PSS收敛到了正确的周期解。
第三步,配置Pnoise。
- Noise Type: jitter
- Sweep Type: relative
- Sweep Range: 1kHz 到 100MHz
- Points per decade: 30
- Output: vout
- Output Type: voltage
- Max Sideband: 7
- 勾选Compute jitter
跑完之后,Direct Plot → Main Form里选Pnoise,Phase Noise,就能看到相位噪声曲线。横轴是频偏Frequency Offset,纵轴是dBc/Hz。
5.2 结果查看与数据提取
典型的1GHz LC-VCO在1MHz频偏处的相位噪声应该在-110到-125dBc/Hz之间(取决于Q值和功耗)。如果跑出来的值在-80左右,说明有问题——最常见的是PSS没收敛,或者器件噪声没开。
在波形窗口里,可以直接用Marker查看具体频偏处的值。也可以用计算器函数提取数据点,方便写入报告。
phaseNoise(vout ?result "pnoise" ?pnoiseType "phaseNoise" ?freq "1G" ?relHarmNum 1 ?offsetFreq 1e6)这个表达式会返回1GHz载波、1MHz频偏处的相位噪声值,非常实用。
5.3 不同corner和温度的批量仿真
在ADE XL里可以方便地做PVT扫描。把PSS和Pnoise设好,然后扫描温度(-40、27、125)和工艺角(ss、tt、ff)。需要注意的是,PSS的Fundamental Frequency会随corner变化。直接用固定1G的话,在ss corner可能收敛缓慢。
解决办法有两种:一是用Parametric Analysis先扫PSS的频率;二是利用PSS的Oscillator PSS自动适应功能,勾选后Spectre会自己搜索振荡频率。后者在ADE XL里设置更简单,推荐优先尝试。
每个corner跑完后,把1MHz频偏处的相位噪声提取出来,填入表格。你会发现ss corner下相位噪声最差,这是因为MOS管跨导降低,环路增益变小,起振条件变弱,振荡摆幅下降,信噪比劣化。
6. 常见问题与避坑技巧
6.1 PSS不收敛怎么办
PSS不收敛是最常见的报错。Spectre通常会提示“PSS analysis failed to converge”之类的信息。遇到这个,按顺序排查:
先看电路是否起振。用瞬态跑1us,确认波形稳定。如果瞬态都起不来,PSS一定失败,问题在电路设计,不在仿真设置。
如果起振了还收敛不了,把Accuracy Defaults从moderate改conservative,或者把tstab加大。比如从50n改到200n,让瞬态启动阶段更充分。我遇到过LC振荡器在tstab=20n时PSS不收敛,改到100n后一次通过。
另一个有效技巧是用homotopy方法。在PSS窗口的Advanced选项卡里,把Solution Method从Newton改成Homotopy,Spectre会用更鲁棒的迭代策略。代价是仿真时间变长,但解决顽固不收敛问题非常有效。
6.2 Pnoise结果出现NaN或乱跳
Pnoise报NaN,八成是Max Sideband设得太小,或者PSS的谐波数不足。把Number of Harmonics从5调到10,Max Sideband从7调到15,重跑一次就能消除。
相位噪声曲线低频端乱跳,通常是PSS误差太大,导致在低频频偏处数值噪声淹没真实信号。这时把ErrPreset调高,同时增大Pnoise的Sweep Range点数,就可以平滑。注意,频偏范围不要低于1kHz,低于这个值Spectre会因近载波效应计算不稳定,数据也不具备参考意义。
6.3 器件噪声没开导致结果偏理想
VCO相位噪声曲线非常平滑、低得不真实,那要检查模型库的噪声开关是否开启。在model library设置中,有些工艺角库默认noise=no。确认每个器件模型都使用带噪声参数的版本。
检查方法:跑一个简易的AC噪声分析(比如在一个偏置电阻上加电流源),看输出噪声是否为0。如果为0,说明噪声模型没加载。
6.4 相位噪声和瞬态抖动对不上
理论上,Pnoise计算出的jitter应该和瞬态蒙特卡洛仿真的抖动接近。如果你发现两者差很多,通常是Pnoise的积分带宽没设对。在Pnoise的**“Oscillator Jitter”**选项卡里,设置积分的上下限频率。下限设为你关心的最低频偏(比如1kHz),上限设为系统带宽(比如100MHz)。如果直接用默认值,可能积分范围不对,导致抖动数值偏大或偏小。
6.5 差分输出如何处理
如果你用差分输出(比如vout_p和vout_m),PSS和Pnoise设置里:
- PSS Reference Node填“vout_p”或“vout_p vout_m”(两者选其一)
- Pnoise Output填“vout_p - vout_m”
这样测的是差分模式的相位噪声,单端共模噪声会得到抑制。部分工艺库对差分结构有特殊模型,建议跑之前先确认模型手册里关于oscillator仿真的说明。
7. 不同VCO拓扑的仿真差异
7.1 LC振荡器和环形振荡器
LC振荡器的波形接近正弦,谐波含量少,PSS的谐波数设5就够了。环形振荡器是反相器链,波形接近方波,谐波极其丰富,建议Number of Harmonics设15以上,否则Pnoise在远频偏处的精度很差。
还有一个细节:环形振荡器相位噪声曲线往往比LC振荡器“平”,因为没有谐振腔的滤波作用,宽带噪声直接折叠到输出边带。这导致环形VCO在1MHz频偏处通常比LC差20~30dB,但面积小、调谐范围大,在数字友好的工艺中仍然是主流选择。
7.2 电感Q值对相位噪声的影响
LC振荡器的总Q值由电感Q和电容Q并联决定。一般来说,电感的Q值(在1GHz下典型的片上电感Q在10~20之间)远低于电容Q,是限制因素。PSS/Pnoise仿真时,电感模型如果包含串联电阻,会自动把电阻热噪声算进相位噪声。所以仿真结果跟电感Q直接挂钩。
做设计回归时,可以固定电路尺寸,只扫描电感Q值从10到20,观察相位噪声变化。这在器件选型和工艺评估时非常有用。
7.3 尾电流源的噪声贡献
尾电流源对相位噪声的贡献不是直接的,而是通过AM-PM转换机制影响的。Pnoise会把每个器件噪声的贡献单独列出来,你可以查看**“pnoise noise contribution”**结果,分析交叉耦合管、尾电流管、谐振电容分别贡献了多少相位噪声。
实操中发现,尾电流源在低频段(<100kHz)的闪烁噪声贡献往往很大。改善方法是加大尾电流管面积,或者引入噪声滤波电容。这些结论通过Pnoise的噪声贡献分析可以很直观地得到,不用靠猜。
8. 仿真效率优化技巧
8.1 合理设置仿真停止条件
PSS的tstab是影响仿真时间的大头。如果振荡器启动时间很短,tstab可以设小一些;如果电路Q值非常高(起振慢),tstab必须足够大才能进入稳态。可以逐步增加tstab观察相位噪声结果,直到连续两次结果差异在0.5dB以内,这时候的tstab就是合适的。
不要盲目跟风网上的“50n”之类的固定值。不同电路起振时间差几十倍都有,用固定值很容易浪费时间或者得到错误结果。
8.2 利用谐波数判断精度
判断PSS谐波数是否足够,可以在PSS结果里查看各次谐波的幅度。如果5次谐波幅度比基波低了60dB以上,说明谐波数设置合理。如果5次谐波仍然很高(比如只低20dB),则需要增大谐波次数。
这个判断方法比看错误信息直观得多,我在做宽带VCO(振荡频率范围很宽)时常用这个方法来快速确定PSS参数。
8.3 合理使用APS加速
Spectre APS可以显著加速PSS仿真,但要注意APS的Pnoise支持情况。在老版本MMSIM中,APS对Pnoise的某些选项支持不完善。现在的IC618中的MMSIM15以上,APS已经能完整支持PSS/Pnoise。如果你的Pnoise结果在APS下出现异常,可以切换回Spectre标准模式对比一下。
我个人的习惯是:调试阶段用标准Spectre,批量跑corner时用APS,既能保证准确性又能提高效率。
最后说一个经验:相位噪声仿真这个事儿,参数设置比电路设计更容易让人头大。但只要你理解了PSS是在干什么、Pnoise又在干什么,所有报错和异常都是有迹可循的。建议第一次跑的时候,把每个参数都点开看看帮助文档里的解释,哪怕多花半小时,也比后面卡两小时调试强。跑通一次完整流程之后,你就会发现这套仿真方法其实非常机械,来来去去就那几个关键点。后面不管是做2.4G还是5G的VCO,流程都是一模一样的,只是换一下频率和工艺角而已。