ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Cadence噪声仿真:如何使能指定噪声类型并优化仿真精度

Cadence噪声仿真:如何使能指定噪声类型并优化仿真精度 1. 噪声仿真在Cadence里的定位与核心思路1.1 为什么噪声类型不能“一把抓”做模拟电路仿真的人迟早会碰到噪声分析。Cadence Virtuoso里的噪声仿真noise analysis跟瞬态、AC、DC这些分析不太一样它不是一个“跑完看波形”的活儿而是要在频域里把每个器件贡献的噪声功率谱密度算出来再积分到输出端或者等效到输入端。问题在于噪声源不是只有一种。电阻有热噪声MOS管有沟道热噪声还有闪烁噪声flicker noise也就是1/f噪声有些工艺模型里还会带散粒噪声或者感应栅噪声。这些噪声的物理机制不同频率特性不同对最终结果的贡献也完全不同。如果你在仿真设置里不指定噪声类型Cadence默认会按照模型里定义的噪声源全部算进去。听起来好像很省事但实际上会带来两个麻烦。第一你没法单独看某一类噪声的贡献比如想知道1/f噪声在低频段到底占了多少默认设置下你只能看到一个总噪声没法拆开。第二有些噪声模型在特定工艺节点下可能没有正确启用或者你用的模型卡里某些噪声参数是关掉的这时候如果不显式使能仿真结果会偏乐观你以为噪声达标了流片回来一测发现低频噪声比仿真高了一大截。所以“使能指定噪声类型”这件事本质上是在仿真精度和调试效率之间找一个可控的平衡点。你得知道哪些噪声该开哪些可以暂时忽略以及怎么在Cadence里把这些开关拨到正确的位置。1.2 噪声类型在仿真器里的映射关系Cadence的噪声仿真底层依赖的是Spectre或APS仿真器噪声类型的使能最终会映射到模型卡里的噪声参数和仿真选项上。对于MOS管BSIM3/BSIM4/BSIM6这些模型里跟噪声相关的参数主要有几个NOIA、NOIB、NOIC控制闪烁噪声的幅度TNOIMOD选择热噪声模型FNOMOD选择闪烁噪声模型。对于电阻RNOIMOD决定热噪声的计算方式。这些参数在工艺库的模型文件里通常有默认值但默认值不一定适合你的仿真场景。举个例子很多工艺库默认把TNOIMOD设成0也就是最简单的热噪声模型只考虑沟道热噪声不考虑感应栅噪声。如果你做的是低噪声放大器LNA输入级的感应栅噪声在射频段是有贡献的这时候就得把TNOIMOD改成1或者2让仿真器把感应栅噪声也算进去。再比如FNOMOD默认可能是0只算一个简单的1/f噪声但实际器件在靠近栅氧化层界面的陷阱密度分布可能更复杂有些工艺库会提供更精细的模型选项。在Virtuoso ADE里你不需要直接去改模型卡而是通过仿真设置里的选项来覆盖这些参数。具体路径是在ADE L或ADE XL的Simulation菜单下找到Options然后进Noise选项卡。这里有几个关键设置Noise Type可以选择thermal、flicker、shot或者allOutput Noise和Input Noise分别对应输出端和输入端的噪声积分方式。但要注意这个界面里的选项是全局的它会影响整个电路的噪声计算不能针对单个器件单独设置。1.3 指定噪声类型的两种典型场景实际工作中使能指定噪声类型通常出现在两种场景下。第一种是噪声预算分配。比如你设计一个传感器前端总输入等效噪声不能超过10μVrms你得知道热噪声贡献了多少1/f噪声贡献了多少然后决定是把输入对管的面积加大来压1/f噪声还是把偏置电流加大来压热噪声。这时候你就需要分别跑两次仿真一次只开热噪声一次只开1/f噪声对比结果。第二种是模型验证和调试。有时候你从代工厂拿到的模型卡里噪声参数可能没配好或者你怀疑某个器件的噪声模型没生效这时候单独使能某一类噪声看仿真结果是否符合预期就能快速定位问题。比如你跑一个简单的共源放大器只开热噪声理论上输出噪声应该跟gm和负载电阻有关如果仿真结果跟手算差很远那可能是模型卡里的TNOIMOD设置有问题。这两种场景对“使能指定噪声类型”的操作要求不太一样。前者需要灵活切换后者需要精确控制。下面我会分别讲怎么在ADE里操作以及怎么通过网表或者表达式来实现更细粒度的控制。2. 在ADE中配置噪声类型的关键步骤2.1 从仿真设置入口找到噪声选项打开Virtuoso ADE L或者ADE XL加载你的电路和测试平台。在ADE L里菜单栏找到Simulation点开Options然后选Noise。如果你用的是ADE XL路径稍微不同是在Data View里选中你的仿真右键Edit然后在Options里找Noise。这个界面里最上面是Noise Type下拉菜单里有几个选项All、Thermal、Flicker、Shot。默认是All也就是所有模型里定义的噪声源都算。这里有个细节要注意Noise Type这个选项并不是所有版本的Cadence都有。我用的IC617和IC618里都有但有些老版本IC5141里可能叫法不一样或者藏在Analysis的Noise设置里。如果你找不到可以先确认一下你的仿真器是Spectre还是APSAPS的噪声选项跟Spectre基本一致但界面可能略有差异。选好噪声类型之后下面还有几个参数需要关注。Output Noise里可以指定输出节点和参考节点通常输出节点选你的电路输出参考节点选地。Input Noise里可以指定输入源这样仿真器会把输出噪声等效到输入端方便你算噪声系数。Sweep Range设置频率扫描范围噪声分析一般从1Hz扫到几十GHz具体看你的应用。Points Per Decade控制频率点的密度默认是10对于1/f噪声这种低频斜率变化快的建议加到20以上不然积分结果会偏小。2.2 用表达式覆盖模型参数ADE界面里的Noise Type只能做全局切换如果你想更精细地控制比如只让某个特定器件开闪烁噪声其他器件只开热噪声那就得用表达式或者网表参数来覆盖。在ADE里你可以通过Model Libraries设置里的Section来切换模型卡的不同段有些工艺库会把不同噪声模型放在不同的section里比如tt_noise_on和tt_noise_off。但这种方法比较笨而且需要工艺库支持。更灵活的方式是在仿真网表里直接加参数。在ADE L里你可以用Simulation菜单下的Netlist and Run生成网表然后在网表里找到对应的器件实例手动加上噪声参数。比如对于一个MOS管M1你可以在网表里加一行M1 (d g s b) nmos w10u l1u nf2 tnoimod1 fnomod1 noia1e20 noib5e4 noic-1e-3这里的tnoimod1就是让这个器件用更精细的热噪声模型fnomod1是让闪烁噪声用更复杂的模型noia、noib、noic是闪烁噪声的幅度参数。这些参数会覆盖模型卡里的默认值。但要注意手动改网表之后如果你在ADE里重新生成网表这些修改会被覆盖掉。所以更好的做法是在ADE的Setup里用Parameter或者Expression来定义这些值然后在网表里引用。在ADE XL里你可以用Corners或者Parameters来批量设置这些噪声参数。比如定义一个参数noise_mode然后在模型卡里用条件语句parameters noise_mode0 ... M1 (d g s b) nmos w10u l1u nf2 tnoimodnoise_mode这样你只需要在ADE XL的Parameters里改noise_mode的值就能切换噪声模型不用手动改网表。2.3 噪声类型与仿真精度的权衡使能指定噪声类型之后仿真时间会发生变化。只开热噪声的时候仿真器只需要计算电阻和沟道热噪声计算量相对小。一旦开了闪烁噪声尤其是用精细模型的时候仿真器需要计算每个器件的1/f噪声贡献频率点越多计算量越大。我实测过一个两级运放只开热噪声跑100个频率点大概3秒开了闪烁噪声之后变成12秒如果频率点加到1000个时间会到一分半左右。所以这里有个权衡如果你只是做初步的噪声预算可以先用All跑一遍看看总噪声水平。如果总噪声超标再分别跑Thermal和Flicker定位主要贡献源。如果总噪声达标但你想确认1/f噪声的拐点频率那就得单独跑Flicker并且把低频段的频率点加密。拐点频率是指热噪声和1/f噪声贡献相等的频率点低于这个频率1/f噪声主导高于这个频率热噪声主导。对于大多数CMOS工艺拐点频率在几十kHz到几百kHz之间具体取决于器件面积和偏置。还有一个容易忽略的点噪声积分的方式。ADE里的Output Noise默认是积分到整个仿真频段但有时候你只关心某个频段内的噪声比如音频应用只关心20Hz到20kHz。这时候你可以在Output Noise设置里指定积分上下限或者在表达式里用integ()函数手动积分。比如integ(getData(out ?result noise) 20 20k)这个表达式会把输出噪声功率谱密度从20Hz积分到20kHz得到这个频段内的总噪声功率。注意getData返回的是功率谱密度单位是V^2/Hz积分之后是V^2开根号才是Vrms。3. 通过网表与脚本实现精细控制3.1 直接编辑网表使能特定噪声源有时候ADE界面里的选项不够用比如你想让某个电阻只贡献热噪声但不贡献1/f噪声电阻的1/f噪声在有些模型里是有的虽然通常很小或者你想让某个MOS管的闪烁噪声用特定的noia值。这时候直接编辑网表是最直接的方法。在ADE L里先跑一次仿真生成网表网表文件通常在simulation目录下的netlist文件夹里文件名类似netlist或者input.scs。用文本编辑器打开找到你要修改的器件。对于MOS管噪声参数通常跟在器件实例后面用续行。比如M1 (net1 net2 net3 net4) nmos w1u l0.1u nf4 ad2e-12 as2e-12 pd4u ps4u tnoimod2 fnomod1 noia1e20 noib5e4 noic-1e-3这里的tnoimod2表示用BSIM4的感应栅噪声模型fnomod1表示用更精细的闪烁噪声模型。如果你只想开热噪声可以把fnomod设成0或者把noia、noib、noic设成0。但要注意有些模型卡里noia的默认值可能是0这时候你设成0反而没变化得先确认模型卡里的默认值是多少。对于电阻噪声参数通常是rnoimod。比如R1 (net1 net2) resistor r1k rnoimod1rnoimod1表示用更精细的电阻噪声模型可能会包含1/f噪声贡献。如果设成0就只算热噪声。编辑完网表之后在ADE里选择Simulation菜单下的Run但不要选Netlist and Run因为那会重新生成网表覆盖你的修改。选Run会直接用当前网表跑仿真。但这种方法有个缺点每次改电路或者改仿真设置网表都会被重新生成你的手动修改就丢了。所以这只适合临时调试不适合长期使用。3.2 用Ocean脚本批量切换噪声类型如果你需要频繁切换噪声类型比如跑一个噪声预算的扫描手动改网表太慢了。这时候可以用Ocean脚本。Ocean是Cadence的脚本语言可以控制ADE的仿真流程。下面是一个简单的Ocean脚本示例它先跑一次只开热噪声的仿真再跑一次只开闪烁噪声的仿真然后把结果保存下来simulator(spectre) design(my_lib my_cell schematic) analysis(noise ?start 1 ?stop 1e9 ?dec 20 ?oprobe /out ?iprobe /in ?noiseType thermal) temp(27) run() saveResults(thermal_noise) analysis(noise ?start 1 ?stop 1e9 ?dec 20 ?oprobe /out ?iprobe /in ?noiseType flicker) run() saveResults(flicker_noise)这里的?noiseType参数就是指定噪声类型的关键。thermal只算热噪声flicker只算闪烁噪声。跑完之后你可以用getData把结果读出来画在一起对比。比如thermal getData(thermal_noise ?result noise) flicker getData(flicker_noise ?result noise) plot(thermal flicker)这个脚本可以在ADE的Script编辑器里运行也可以在命令行用ocean命令跑。如果你用的是ADE XL可以把Ocean脚本嵌到Corners或者Parametric里实现批量扫描。3.3 噪声类型与工艺角的联合仿真实际项目中噪声仿真往往要跟工艺角一起跑。比如你需要在tt、ss、ff三个工艺角下分别看热噪声和闪烁噪声的贡献。这时候如果手动切换工作量很大。用ADE XL的Corners功能可以自动化这个过程。在ADE XL里先建一个Corners设置把工艺角加进去。然后在Parameters里定义一个noise_type参数取值可以是thermal、flicker、all。然后在仿真设置里把Noise Type绑定到这个参数上。具体做法是在Options的Noise选项卡里把Noise Type设成%noise_type%或者用表达式引用。这样跑Corners的时候每个工艺角都会分别跑三种噪声类型结果会自动整理成表格。我试过用这种方法跑一个LDO的噪声仿真三个工艺角乘以三种噪声类型一共九次仿真ADE XL大概跑了五分钟。如果手动跑至少得半小时。而且ADE XL的结果浏览器可以直接把不同工艺角、不同噪声类型的结果画在一起对比起来很方便。但要注意ADE XL的Corners设置里Noise Type这个选项有时候不直接支持参数化得用Expression或者Ocean脚本来实现。具体做法是在Corners的Setup里把Noise Type设成eval(%noise_type%)然后在Parameters里定义noise_type。如果不行就退回到用Ocean脚本在脚本里循环工艺角和噪声类型。4. 常见问题与排查技巧实录4.1 噪声类型设置了但结果没变化这是最常见的问题。你在ADE里把Noise Type从All改成Thermal跑完发现输出噪声曲线跟之前一模一样。可能的原因有几个。第一你的模型卡里根本没有定义闪烁噪声参数或者noia、noib、noic都是0这时候开不开Flicker都没区别。第二你改的是ADE L的Options但实际跑的是APS仿真器APS的噪声选项可能不在同一个地方。第三你的电路里噪声源主要来自电阻而电阻的1/f噪声在模型里默认是关的所以切到Flicker之后总噪声几乎不变。排查方法先跑一个简单的测试电路比如一个理想电阻分压只开热噪声看输出噪声是不是sqrt(4kTR)。如果对得上说明热噪声使能正常。然后加一个MOS管只开闪烁噪声看低频段是不是有1/f斜率。如果都没有那可能是模型卡的问题。你可以用spectre -h命令查看仿真器支持的噪声选项或者在网表里加noise_type参数强制指定。4.2 闪烁噪声参数的单位与量级noia、noib、noic这三个参数的单位经常让人困惑。在BSIM3/BSIM4模型里noia的单位是V^2·m^2或者V^2·μm^2具体看模型卡的定义。noib的单位是V^2·mnoic是无量纲的。这些参数跟工艺相关通常代工厂会在模型卡里给好你不需要自己算。但如果你要手动覆盖得注意单位换算。比如模型卡里noia1e-20单位是V^2·μm^2你手动设成1e-20那没问题。但如果你从文献里看到一个值1e-24 V^2·m^2换算成V^2·μm^2就是1e-12差了八个数量级。我见过有人直接把文献值填进去结果闪烁噪声大了好几个量级仿真结果完全不对。所以手动改这些参数之前一定要确认单位。4.3 噪声积分结果与手算对不上有时候你跑完噪声仿真发现输出噪声积分结果跟手算差很多。除了模型参数的问题还有可能是积分频段设置不对。ADE默认的噪声积分是从仿真起始频率到终止频率如果你只关心某个频段得手动设置积分上下限。另外Output Noise和Input Noise的积分方式不一样Output Noise是直接对输出噪声功率谱密度积分Input Noise是先把输出噪声等效到输入端再积分。如果你要看噪声系数应该用Input Noise然后跟源电阻的热噪声比。还有一个坑噪声仿真里的oprobe和iprobe设置。oprobe是输出探针指定你要看哪个节点的噪声。iprobe是输入探针指定输入源。如果你把oprobe设成输出节点但iprobe没设那Input Noise的结果可能是错的。我一般会显式设置这两个探针确保结果可追溯。4.4 常见问题速查表问题现象可能原因排查方法解决措施切换噪声类型后结果不变模型卡未定义对应噪声参数检查模型卡里noia、noib、noic是否非零换用带噪声参数的模型卡或手动在网表里加参数闪烁噪声量级异常大参数单位搞错对比模型卡默认值和手动值确认单位是V^2·μm^2还是V^2·m^2噪声积分结果偏小频率点太少看Points Per Decade设置加到20以上低频段加密输入噪声结果不对iprobe未设置检查Input Noise设置显式指定输入源和参考节点仿真时间过长频率点太多或噪声模型太复杂看仿真日志里的频率点数和模型评估次数先用All粗跑再针对性细跑APS仿真器噪声选项找不到APS界面与Spectre不同查APS文档或切回Spectre在APS的Options里找Noise或改用Spectre跑噪声4.5 几个实操心得第一个心得跑噪声仿真之前先跑一遍DC工作点确认所有器件都在饱和区。如果某个管子在线性区它的噪声贡献会跟饱和区完全不一样仿真结果没有参考价值。我习惯在ADE里先跑dc看region参数确认所有MOS管都是2饱和区。第二个心得噪声仿真对温度敏感。热噪声跟温度成正比闪烁噪声跟温度的关系更复杂。如果你做的是宽温应用比如-40到125度最好在tt、ss、ff之外再加温度扫描。ADE XL里可以把温度加到Corners里跑完看噪声随温度的变化趋势。第三个心得如果仿真结果跟预期差很多先别急着改模型参数先检查电路本身。比如偏置电流对不对负载电阻是不是设成了理想值电源电压是不是正常。我踩过一次坑噪声仿真结果比手算大了十倍查了半天发现是偏置电流设错了管子实际工作在亚阈值区噪声自然大。第四个心得噪声仿真结果最好跟实测对比。如果条件允许流片回来测一下输出噪声谱密度跟仿真曲线叠在一起看。你会发现仿真在低频段往往偏乐观因为模型卡里的1/f噪声参数通常是典型值实际工艺波动可能让1/f噪声高出一倍。所以设计时最好留20%到30%的噪声余量。5. 噪声类型使能的进阶用法5.1 用子电路封装实现器件级噪声控制如果你不想改模型卡也不想手动改网表还有一个办法把需要特殊噪声设置的器件封装成子电路。在子电路里你可以用spectre的parameters语句定义噪声参数然后在子电路内部引用。比如subckt my_nmos (d g s b) parameters w1u l0.1u nf1 M1 (d g s b) nmos ww ll nfnf tnoimod1 fnomod1 noia1e20 noib5e4 noic-1e-3 ends my_nmos然后在主电路里实例化这个子电路而不是直接用nmos。这样你只需要在子电路定义里改一次所有实例都会生效。而且子电路可以放在单独的库文件里方便复用。缺点是子电路会增加网表层级仿真器需要多一层解析仿真时间可能略微增加但通常可以忽略。5.2 噪声类型与蒙卡分析的结合蒙卡分析Monte Carlo是评估工艺波动对电路性能影响的标准方法。噪声仿真也可以跟蒙卡结合看工艺波动对噪声的影响。在ADE XL里你可以先设置蒙卡仿真然后在Options里指定噪声类型。跑完之后你会得到一组噪声曲线可以统计均值和标准差。但要注意蒙卡分析本身就很耗时如果再加上噪声仿真时间会成倍增加。我一般会先用少量样本比如30次跑一下看看噪声的波动范围。如果波动不大就没必要跑几百次。如果波动很大再增加样本数。另外蒙卡的process和mismatch设置会影响噪声结果process主要影响模型参数mismatch主要影响器件尺寸和阈值电压两者对噪声的贡献不一样最好分开跑。5.3 噪声类型在射频电路中的特殊处理射频电路的噪声仿真跟低频电路不太一样。在射频段除了热噪声和闪烁噪声还有感应栅噪声和散粒噪声。感应栅噪声在TNOIMOD2的时候才会被算进去散粒噪声通常只在二极管或者双极晶体管里考虑。如果你做的是LNA或者混频器噪声系数是关键指标这时候噪声类型的设置直接影响噪声系数的仿真结果。我一般会先用All跑一遍看噪声系数的大致水平。如果噪声系数超标再分别跑Thermal和Flicker看哪个贡献大。在射频段热噪声通常是主导闪烁噪声在低频段影响大但经过混频之后会搬到射频段所以也不能完全忽略。具体怎么设置得看你的电路架构和工艺节点。5.4 噪声类型设置的版本差异不同版本的Cadence噪声类型的设置方式可能不一样。IC617里Noise Type在Options的Noise选项卡里IC618里基本一样但APS仿真器的选项可能藏在APS Options里。IC5141里没有Noise Type这个选项得通过模型卡的section来切换。如果你用的是较新的IC23.1界面又变了Noise Type可能在Analysis的Noise设置里而不是Options里。所以如果你照着教程操作但找不到选项先确认你的Cadence版本。可以在CIW窗口里输入getVersion()查看版本号。另外不同版本的仿真器对噪声参数的支持也不一样比如tnoimod2在有些老版本里不支持得用tnoimod1。这些细节最好查一下对应版本的Spectre用户手册或者直接在命令行用spectre -h noise看帮助。6. 从仿真到实测的噪声验证思路6.1 仿真结果的后处理与可视化跑完噪声仿真之后ADE里默认会画出输出噪声功率谱密度曲线。但这条曲线只是原始数据你还需要做一些后处理。比如算总噪声功率可以用integ()函数对曲线积分。算噪声系数可以用Input Noise除以源电阻的热噪声。算拐点频率可以找热噪声和闪烁噪声曲线相交的点。在ADE的Calculator里你可以用integ()、sqrt()、db20()这些函数做后处理。比如total_noise sqrt(integ(getData(out ?result noise) 1 1e9)) noise_figure db20(getData(in ?result noise) / (4*k*T*50))这里的k是玻尔兹曼常数T是温度50是源电阻。注意getData返回的是功率谱密度单位是V^2/Hz积分之后是V^2开根号才是Vrms。噪声系数是输入噪声除以源电阻热噪声再取dB。6.2 实测噪声与仿真对比的注意事项如果你有条件做实测比如用频谱分析仪测输出噪声对比仿真结果时要注意几点。第一实测的噪声带宽通常受限于测量设备比如频谱分析仪的RBW分辨率带宽你得把仿真结果也做相应的带宽限制。第二实测的噪声包括电路噪声和测量设备的底噪如果电路噪声接近设备底噪测量结果会偏大。第三实测的噪声跟PCB布局、电源去耦、屏蔽措施都有关系仿真里通常假设理想电源和地实测可能差很多。我一般会先测一个已知噪声水平的基准电路比如一个简单的电阻分压确认测量系统正常。然后再测实际电路对比仿真和实测的曲线形状。如果低频段实测比仿真高可能是1/f噪声模型偏乐观或者PCB上有额外的低频噪声源。如果高频段实测比仿真高可能是寄生电容或者电感的影响仿真里没考虑进去。6.3 噪声优化的几个方向如果仿真发现噪声超标可以从几个方向优化。第一加大输入对管的面积1/f噪声跟器件面积成反比面积加倍1/f噪声降一半。但面积加大会增加寄生电容影响带宽。第二加大偏置电流热噪声跟gm成反比gm跟偏置电流的平方根成正比所以偏置电流加倍热噪声降约30%。但偏置电流加大会增加功耗。第三换用噪声更低的工艺比如从0.18μm换到0.13μm1/f噪声通常会改善但成本会增加。这些优化方向在仿真里都可以快速验证。比如你可以在ADE XL里定义一个参数w_input扫描它的值看噪声怎么变。或者定义一个参数ibias扫描偏置电流看噪声和功耗的权衡。跑完扫描之后你可以画一条噪声-功耗曲线找最优的工作点。6.4 噪声类型使能的自动化脚本模板最后分享一个我常用的Ocean脚本模板它可以自动跑三种噪声类型并把结果保存成CSV文件方便后续用Excel或者Python分析simulator(spectre) design(my_lib my_cell schematic) temp(27) noise_types list(thermal flicker all) foreach(nt noise_types analysis(noise ?start 1 ?stop 1e9 ?dec 20 ?oprobe /out ?iprobe /in ?noiseType nt) run() results getData(noise ?result noise) ocnPrint(results ?fileName sprintf(nil noise_%s.csv nt) ?type csv) )这个脚本会依次跑thermal、flicker、all三种噪声类型每次跑完把结果输出到CSV文件。你可以把这个脚本保存成.ocn文件在ADE的Script编辑器里加载运行或者在命令行用ocean -restore noise_script.ocn跑。跑完之后用Python的pandas读CSV画对比图或者算积分都很方便。这个模板的好处是你不需要手动切换噪声类型也不需要记住每种类型的设置路径。脚本跑完所有结果都在CSV里想怎么分析就怎么分析。我一般会在项目初期用这个脚本跑一遍看看噪声的大致分布然后再针对性地优化。
返回列表