简介:《各种语句sentaurus.docx》是一份面向微电子、纳米电子与光电子器件仿真学习者的 Sentaurus 语句参考文档,适合已具备 TCAD 基础、需要查阅或复用仿真命令的读者。内容围绕 I-V、C-V 曲线计算,辐照损伤与重粒子入射,以及瞬态仿真展开,涵盖电流电压文件、电极与物理模型、Math 数值方法、Solve 求解流程、AC 耦合电容提取、HeavyIon 重离子撞击和激光光照等典型语句片段。读者可据此快速定位关键参数设置、模型选择及输出控制方式,理解器件仿真输入文件的组织逻辑,并为搭建、调试和优化仿真 deck 提供可直接对照的模板,减少从零编写命令时的试错成本。压缩包共 1 个 docx 文件,约 16KB,体积轻便,便于检索与摘录。该文档已有 2038 人学习,适合作为 Sentaurus 常用语句的速查资料和课程实验、科研建模的辅助参考。
1. 一行 Physics 开关:为什么曲线形状和收敛性会绑在一起
在 Sentaurus 这类 TCAD 工具里,最反直觉的一件事是:物理模型和数值收敛并不是两件事。你在 Physics 段里多加一个Avalanche (UniBo Eparallel),曲线上会多出一条击穿分支;但同一个文件里 Math 段的Notdamped、BreakCriteria和 Solve 段的Coupled括号顺序,决定了这条分支是被算出来,还是让整个仿真在偏置扫到一半时崩掉。很多人第一次遇到发散,会本能地怀疑模型不对,真正的原因却常是求解路径没铺好。这套语句真正值得拆开看的地方,是它把“写哪个方程”“按什么顺序解”“结果往哪儿落”三件事拆成了独立层级,每层都能单独调试。搞懂分层,比背参数有用。
2. 声明与装配:Device/File/Electrode/Physics 为什么必须分层写
拿到一份能跑的 Sentaurus 语句,第一眼看到的是几个平级的块:File、Electrode、Physics、Math、Solve。看起来像一份配置清单,实际是一次自上而下的装配:先声明数据从哪来、往哪去,再声明边界条件,再声明方程里带哪些物理项,最后才声明怎么解。顺序不能乱,因为后面的块依赖前面的声明。
2.1 File 块:为什么输入输出要分成四条独立的流
一个二极管 I-V 求解的开头通常是这样:
File { Grid = "Diode_msh.tdr" # 输入:网格 + 材料区 + 掺杂分布,由结构编辑器生成 Current = "Diode_IV.plt" # 输出:电极上的标量电压/电流序列,一条曲线一个文件 Plot = "Diode_IV.tdr" # 输出:全场量快照(电势、载流子密度、电场矢量) Output = "Diode_IV.log" # 输出:求解日志,迭代次数、残差、步长回退记录 }这四条流分开写,不是为了好看。Current存的是电极上的一维时间序列,几百个点,几十 KB;Plot存的是全场量,每个节点十几个物理量,动辄几百 MB。把它们塞进一个文件,代价是每次只想看一条曲线都要读全场数据。更重要的是第四条:Output日志是唯一能解释“为什么没算完”的地方。求解器不会告诉你物理哪里错了,它只会告诉你第几步、残差多少、步长被砍到多少。把它当成黑匣子里的飞行记录仪,出问题第一件事就是翻它,而不是改模型。
工程实践中还有一个细节:Plot里的量由Plot段二次筛选,File只负责命名目的地。两者分离的设计,让你可以重跑后处理而不重算——前提是NoOverwrite这类开关用对,否则文件名被覆盖,后悔药就没了。
2.2 Physics 块:每个模型开关都是对方程组的一次修改
这是整套语句里信息密度最高的地方:
Physics { AreaFactor = 1 # 二维截面结果折算为等效三维时的宽度因子 Temperature = 300 # 晶格温度,单位 K,不是载流子温度 Mobility ( DopingDependence # 迁移率随掺杂浓度退化 eHighFieldSaturation # 电子高场速度饱和 hHighFieldSaturation # 空穴高场速度饱和 EnormalCarrier # 表面法向电场引起的额外退化 CarrierCarrierScattering # 载流子-载流子散射 ) Recombination ( SRH (DopingDependence) # 深能级复合,寿命随掺杂下降 Auger (withGeneration) # 三载流子过程,高注入下主导 Avalanche (UniBo Eparallel) # 碰撞电离,按平行电场驱动 Band2Band (Hurkx) # 带间隧穿,折算成等效产生率 EffectiveIntrinsicDensity (OldSlotboom) # 重掺杂下的禁带变窄 ) }关键在于:这些括号不是“精度档位”,每一个都往漂移-扩散方程组里加一项,加项就改雅可比矩阵的结构和条件数。SRH让复合率依赖寿命 τ,(DopingDependence)再把 τ 写成掺杂浓度的函数,于是高掺杂区的少子寿命被压到纳秒级,反向饱和电流随之变化;Auger (withGeneration)在 SRH 之外再加一个 ∝n²p 的复合通道,withGeneration让它允许把多余能量转给另一个载流子去激发,这在重掺杂发射区里不能省。
Avalanche (UniBo Eparallel)更典型。碰撞电离率对电场是指数敏感的,Eparallel指定驱动电场只取平行于电流方向的分量——如果取全电场模,在结边缘或异质结界面上电场方向不纯,会凭空触发大量电离,击穿电压直接跑偏。这类模型细节在曲线上表现为“击穿点提前了 20%”,不去拆开关根本定位不到。
Band2Band (Hurkx)和EffectiveIntrinsicDensity (OldSlotboom)属于另一类:前者把带间隧穿折算成局部产生率,避免对隧穿路径做能量积分;后者用经典模型描述禁带变窄,让本征载流子浓度在重掺杂区抬升,直接改变 PN 结的注入比。它们的共同点是——不加,结果可能看起来“还算像”,加上才和实测对得上,但加了以后收敛变难。这就是物理精度与数值鲁棒性的第一次正面冲突。
2.3 Electrode 与 AreaFactor:二维结果怎么变成“等效三维”
Electrode { Name="ElectrodeN" Voltage = 0.0 }只做两件事:给接触起名,给初值。名字非常重要——Plot段、BreakCriteria段、混合模式里的电路节点映射,全都靠这个名字索引。名字写错,语句照样能跑,只是断点判据失效,电流跑飞也没人拦。
AreaFactor = 1是另一个容易忽视的换算口。二维仿真的电流天然是“每单位深度”的电流,A/μm;真实器件的电流要乘以宽度。设成 1 意味着你在看“每微米宽度”的结果。忘了改这一项,得到的电流可能和实测差两个数量级,而曲线形状完全正确——这是最阴的一类错,因为形状对,人会先怀疑物理参数。
提示:二维结构里做校准之前,先把 AreaFactor 按实际器件宽度设好,再把实验结果换算到同一口径。顺序反了,后面所有拟合都是白做。
3. 求解序列:Coupled 的括号顺序比模型精度更决定成败
模型定了,接下来是解。漂移-扩散是一组强非线性耦合方程,泊松方程管静电势,两条连续性方程管电子和空穴,任何一条单独解都得不到有意义的电流。真正的难点不是“要不要耦合”,而是“从什么状态开始耦合”。
3.1 从 Poisson 到 Electron/Hole/Poisson 的渐进耦合
Solve { Coupled (Iterations=50) { Poisson } # 第一步只要静电势 Coupled (Iterations=15) { Hole Poisson } # 加空穴连续性 Coupled (Iterations=15) { Electron Hole Poisson } # 再加电子连续性 QuasiStationary ( InitialStep = 1e-6 MaxStep = 0.01 MinStep = 1e-9 Goal { Name="ElectrodeN" Voltage = 1000 } Plot { Range = (0 1) Intervals = 2 } ) { Coupled { Hole Electron Poisson } # 每个偏置点内部仍是全耦合牛顿 Plot (FilePrefix="IV_" Time=(0.01;0.05;0.1;0.5) NoOverwrite) } }前三条Coupled是渐进式装配:先解泊松拿到电势分布,把它当作空穴方程的初值,再拿两者当电子方程的初值。零初值下直接上三变量耦合,载流子密度在数量级上跨越十几个量级,牛顿迭代的线性系统条件数极差,几乎必然发散。分步走相当于给每一步一个“差不多合理”的起点,代价是多花几次迭代。
注意每步的Iterations不一样:泊松 50 次,后面 15 次。泊松方程相对好解但初值最差,给宽一点;连续性方程已有前一步的场做引导,15 次够用。这个数字不是固定的,网格加密后经常要调大。
QuasiStationary里的Goal是“扫到某个电压”,求解器自己决定中间踩哪些点。InitialStep、MaxStep、MinStep控制自适应步长:步长太大,越过击穿拐点,牛顿在无解区反复回退;步长太小,几百个偏置点白烧机时。MaxStep = 0.01意味着单步不超过 0.01 V,在 1000 V 的扫描范围里意味着至少 10 万个点——这显然不是常规用法,更像是先给一个保守上限确保能跑完。真实项目里通常会先粗后细:用大MaxStep跑通全程看形状,再在小范围内收紧步长抓拐点。
3.2 Math 块:收敛失败的病根常在导数
Math { # Cylindrical # 柱坐标对称,注释掉说明当前是笛卡尔坐标 Method = Pardiso # 稀疏直接法求解线性系统 Number_of_threads = 4 Stacksize = ... # 递归求解时防止栈溢出 ExtrapolateDerivatives # 导数用外推近似,省一次函数求值 AvalDerivatives # 碰撞电离项参与雅可比,必须给真导数 RelErrControl # 误差控制基于相对量 Iterations = 15 # 单个偏置点允许的最大牛顿迭代 Notdamped = 60 # 前 60 次迭代不做步长阻尼 BreakCriteria { Current (Contact="ElectrodeN" maxval = 1e-8) } }Pardiso是直接法:分解矩阵,一次解到底,鲁棒但内存随节点数非线性增长。强非线性问题(击穿、雪崩、辐照瞬态)一般不用迭代法,因为迭代法省下的内存会被“反复不收敛”加倍还回去。
ExtrapolateDerivatives和AvalDerivatives是一对反向操作。牛顿法需要雅可比矩阵里的 ∂F/∂x,有些项的解析导数代价很高,外推近似能省时间,但会破坏二次收敛;碰撞电离系数是电场的指数函数,导数错一点,迭代方向就差很远,所以必须用真实导数。这两个开关的取舍原则很朴素:线性或弱非线性项可以外推,指数型强非线性项不行。
Notdamped = 60和Iterations = 15之间其实有个矛盾:单点最多 15 次迭代,可阻尼要到 60 次才启用。等于说在这套设置下,阻尼形同虚设。这是血泪经验的产物——对某些结构,早开阻尼会让迭代在局部极小值附近磨蹭,反而不如放开步长让它冲过去。但这个值必须配合BreakCriteria使用,否则冲过头就是发散。
BreakCriteria是整套语句里最像后悔药的一行:接触电流超过 1e-8 就停。它不改变物理,只在数值失控时把进程从跑飞状态拉回来,并留下一个明确的终止位置,方便你回去看那一步的日志。
4. 外部激励:AC 小信号、重离子与激光为什么共用一套骨架
I-V 是直流稳态,C-V 是频率域的小扰动,重离子和激光是时域的大扰动,看起来是三套完全不同的东西。但它们在语句结构上高度同构:都要先有一个收敛的稳态解,再把外部激励作用上去,再沿着某个自变量(电压、频率、时间)推进。理解这个同构,就不会把它们当成三份互不相干的模板去背。
4.1 混合模式与 ACCoupled:C-V 为什么必须挂在直流解上
System { Diode diodesystem ("ElectrodeN"=front "ElectrodeP"=0) # 器件电极映射到电路节点 Vsource_pset vn (front 0) { dc = 0 } # 电压源,dc 是被扫描的量 } File { Output = "Diode_CV_1kHz.log" ACExtract = "Diode_CV_AC_1kHz.plt" } Solve { Coupled (Iterations=50) { Poisson } Coupled (Iterations=15) { Hole Poisson } Coupled (Iterations=15) { Electron Hole Poisson } Coupled (Iterations=15) { Electron Hole Poisson Contact } QuasiStationary (InitialStep=1e-6 MaxStep=1e-2 MinStep=1e-7 Increment=2 Decrement=4 Goal { Parameter = vn.dc Voltage = 100 }) { ACCoupled (StartFrequency=1e3 EndFrequency=1e3 NumberOfPoints=1 Decade Iterations=15 Node(front) ACMethod=Blocked ACSubMethod("diodesystem")=ParDiSo) { Poisson Electron Hole Contact Circuit } } }小信号分析的数学前提是线性化:把解写成 x = x₀ + Re(δx·e^{jωt}),代入原方程后丢掉二次以上的小量,得到一组复数线性方程。x₀ 就是直流工作点,没有它就没有扰动可加。所以ACCoupled必须嵌在QuasiStationary内部,每扫到一个偏置点,先解直流,再在这个点上加正弦扰动,最后从复导纳里取出电容。这也是为什么ACExtract输出的是“电容-电压”而不是“电容-频率”——频率在这里只是求导的算子,不是扫描变量。
StartFrequency = EndFrequency = 1e3加NumberOfPoints = 1,等于只算 1 kHz 单点。这是 C-V 的常见用法:固定频率扫偏置。若真想做频率扫描,这两个值要拉开并给点数,此时Decade才起作用。
ACMethod = Blocked把器件方程和电路方程分块求解,ACSubMethod("diodesystem") = ParDiSo指定该子系统的线性解法。分块的代价是丢掉器件-电路之间的一部分交叉项,在“一个器件加一个理想源”的拓扑下几乎无影响;一旦电路侧有多个强耦合元件,就要谨慎评估。Node(front)指明扰动从哪个电路节点注入,Contact出现在未知量列表里,意味着接触被当作额外变量处理,对接触电阻和边界通量的处理更稳。
低频 1 kHz 这个选择本身也有物理含义:频率足够低时,深能级陷阱跟得上信号,测到的是“含陷阱响应”的电容;频率高到陷阱来不及响应,电容会掉一截。用单频算 C-V,等于默认陷阱响应可以忽略或已经包含在直流模型里。
4.2 HeavyIon:LET 波形怎么变成体电荷
Physics { HeavyIon ( Direction = (0, 1) # 入射方向 Location = (200, 0) # 入射点 Time = 1e-9 # 入射时刻 Length = [ ] # 径迹长度区间 Wt_hi = [ ] # 径迹横向分布的权重 LET_f = [0 8.7e-6 8.7e-6 0] # 线性能量转移随时间的分段线性波形 Gaussian # 横向按高斯分布铺开 PicoCoulomb # 电荷量纲,避免与能量量纲混用 ) }机制链条很短但每一步都可能出错:LET(t) 给出单位长度上的能量沉积率,除以产生一对电子空穴所需的平均能量(硅约 3.6 eV),得到单位长度、单位时间的载流子对产生率;再按Gaussian的横向分布摊到径迹周围的网格节点上,转成体产生率塞进连续性方程。
LET_f那四个数就是波形的骨架:起、升、平台、落。平台段的斜率决定了瞬态电流尖峰有多陡,也直接决定后续Transient的MinStep要压到多小。Location和Direction决定径迹穿过哪些区域——打在结区还是衬底,产生的电荷收集效率完全不同,这是单粒子效应仿真里最敏感的几何参数。
Gaussian不能省。径迹在物理上有横向宽度,如果强行让所有电荷落在一列节点上,结果会强烈依赖网格:网格换一套,峰值电流就变一次。加上横向分布后,电荷铺到若干列节点上,网格依赖性显著下降。
注意:
PicoCoulomb是量纲声明,不是单位换算开关。LET 数据、器件尺寸、体电荷密度三者口径不一致时,得到的瞬态电流可能差好几个数量级,而且曲线形状还是对的。
4.3 激光与瞬态步长:为什么 MinStep 要压到 1e-17
Optics ( OpticalGeneration ( ComputeFromMonochromaticSource () TimeDependence (WaveTime = (1e-9 1e-9) WaveTSigma = 50e-12) # 脉冲起始与高斯展宽 Scaling = 0 Excitation ( Wavelength = 0.8 *um Intensity = 0.06 *W/cm2 Window("L1") (Origin=(200,0) XDirection=(1,0,0) Line(Dx=10) Theta=0) OpticalSolver (OptBeam (LayerStackExtraction ( WindowName = "L1" WindowPosition = Center Mode = ElementWise ComplexRefractiveIndex (WavelengthDep (real imag))))) ) ) )光生载流子的产生率不是均匀的一个常数,而是“吸收功率密度 ÷ 光子能量”。吸收功率密度由波长、入射强度和材料层堆叠的复折射率共同决定,LayerStackExtraction加OptBeam就是沿着光束方向做一层一层的吸收计算。所以Wavelength决定的是分布形状(短波长在表面就被吃掉,长波长穿得深),Intensity只决定总量。只调强度不改波长,空间分布永远不对。
时间维度上,WaveTSigma = 50e-12是一个 50 ps 量级的高斯脉冲。瞬态求解器的MaxStep = 1e-10(100 fs)远小于这个宽度,才能把脉冲的上升沿采样出来;MinStep = 1e-17是兜底,防止在载流子密度剧烈变化的瞬间步长被砍到零而卡死。重离子那段的FinalTime = 35e-9配MaxStep = 1e-10,同样是因为径迹沉积发生在皮秒量级,时间步必须比物理事件的时间尺度小一到两个数量级,否则瞬态电流尖峰会被直接抹平——曲线看起来平滑,其实什么都没捕到。
4.4 陷阱谱:辐照损伤为什么用“注量 × 引入率”标定
Physics (material = "Silicon") { Traps ( (Acceptor Level EnergyMid = 0.42 fromCondBand Conc = 2.3226E15 Randomize = 0.29 eXsection = 9.5E-15 hXsection = 9.5E-14) # 上面这行 Conc = Fluence * 1.1613 (Acceptor Level EnergyMid = 0.46 fromCondBand Conc = 1.8E15 Randomize = 0.23 eXsection = 5E-15 hXsection = 5E-14) (Donor Level EnergyMid = 0.36 fromValBand Conc = 1.8E15 Randomize = 0.31 eXsection = 3.23E-13 hXsection = 3.23E-14) ) } Physics (MaterialInterface = "Oxide/Silicon") { Charge (Conc = 1.5e11) }辐照在禁带里引入深能级,载流子的复合与产生改走这些能级,等效于把 SRH 的能级参数换成了“辐照后的谱”。EnergyMid指定能级位置(相对导带或价带),Conc是体浓度,注释里那行Fluence * 1.1613才是真正的机制说明:陷阱浓度由辐照注量乘一个引入率换算而来,引入率是材料与辐射类型的经验常数。这意味着整套模型的可迁移性完全取决于这个系数,换个工艺条件就得重新标定。
Randomize给能级一个随机展宽,让同一批陷阱的能级不是一根线而是一个分布。这个细节的价值在于:单一能级会让复合率在某个偏压区出现尖锐变化,展宽之后曲线更接近实测的“弥散”过渡。eXsection和hXsection差一个数量级,说明该陷阱对电子和空穴的俘获概率不对称,直接影响少子寿命的估算。
界面那行Charge (Conc = 1.5e11)是面电荷,单位是 cm⁻²,不是体浓度。混淆这两个单位,阈值电压会偏出好几伏。
5. 避坑:语句能跑通和结果可信之间差的那几步
能跑出曲线不算成功,能解释曲线才算。下面几条是这套语句最容易翻车的地方,几乎都表现为“形状对、数值不对”。
5.1 声明阶段的坑
现象:加了Avalanche之后击穿电压比预期高出一大截,而且曲线拐点很软。原因通常是两条:结区网格太粗,电场峰值被数值扩散抹平;同时没开AvalDerivatives,碰撞电离项在雅可比里只是一阶近似,迭代走不到真实的击穿点。解决办法是先把结区网格加密到德拜长度量级,再确认AvalDerivatives已开,最后把QuasiStationary的MaxStep降一个数量级重新逼近拐点。
现象:二维仿真的电流和实测差了两个数量级,但曲线形状几乎重合。原因几乎总是AreaFactor = 1,也就是在看“每微米宽度”的电流,而实测是整个器件的电流。解决办法是先把AreaFactor设成实际宽度与 1 μm 的比值,再重新校准。顺序不能反,否则前面所有拟合参数都是按错的口径定的。
现象:BreakCriteria写了但完全不生效,电流跑飞也没被拦。原因是Contact名字和Electrode里定义的名字不一致,判据挂在一个不存在的接触上。这种错不会报错,只会安静地失效。
5.2 求解阶段的坑
现象:QuasiStationary在某个偏置点反复回退,MinStep触底后报错终止。原因多半是该点发生了强非线性跃变(耗尽区穿通、击穿),而MaxStep太大加上Notdamped太大,牛顿一步跨过去落在无解区。解决办法是先把MaxStep降到原值的十分之一,观察是否还回退;仍然失败就把Notdamped调小,让阻尼早点介入。
现象:Transient第一步就发散,日志里残差暴涨。原因是初值不是稳态解,直接把零偏置的初始场丢进瞬态。正确做法是先QuasiStationary把偏置扫到目标工作点,再切换Transient,让时域推进从一个自洽的状态出发。
现象:瞬态能跑完,但峰值电流比预期低一大截,波形被削平。原因通常是MaxStep大于物理事件的时间尺度,脉冲上升沿被跨过去。检查方法很直接:把MaxStep减半重跑,看峰值是否变化;还在变,说明步长没收敛。
5.3 输出与单位的坑
现象:想扫 C-V,但输出文件里每个偏置点只有一组数,看不出频率依赖。原因是StartFrequency和EndFrequency设成了同一个值且NumberOfPoints = 1,只算了一个频点。做 C-V 时这是正确的,做频率扫描时才需要拉开区间并给点数。
现象:改了PicoCoulomb相关的量之后,瞬态电流整体差了六个数量级。原因是把 LET 的能量量纲和电荷量纲混用,而器件尺寸又是微米量级,量纲缺口正好落在 10⁶ 附近。核对方式是拿一个已知解析解的简单结构(均匀电场下的平板)先跑一遍,确认量级对得上再上真实结构。
现象:Plot段列了一堆物理量,输出文件里却没有。原因是Plot文件只在Solve里带Plot语句的偏置点或时刻写出,光在顶层Plot段声明不够。想固定输出,就在QuasiStationary或Transient的求解体里显式给Plot的范围和前缀。
6. 取舍:模型开得多和结果可信之间没有必然关系
把所有模型都打开,是最容易做也最没用的选择。每开一个模型,就引入至少一个未知参数:SRH 给了掺杂依赖,但寿命的掺杂曲线本身要标定;Auger 系数有文献值,但器件里实际的有效系数受工艺影响;陷阱模型的能级、浓度、俘获截面加起来接近十个自由度。而一份 I-V 曲线能提供的信息量,远不足以唯一确定这些参数。参数不可辨识的时候,拟合得再好也只是把误差摊到了别处。
可行的做法是分层校准,一次只放开一组参数:
| 阶段 | 固定住的部分 | 用来拟合的数据 | 主要标定对象 |
|---|---|---|---|
| 1 | 关掉雪崩、带间隧穿、陷阱 | 正向 I-V | 迁移率模型与 SRH 寿命 |
| 2 | 继承阶段 1 | 反向 I-V | 产生寿命、禁带变窄 |
| 3 | 继承阶段 2 | C-V | 掺杂剖面、界面电荷 |
| 4 | 继承阶段 3 | 瞬态波形 | 陷阱谱、LET 响应参数 |
顺序本身有物理依据:正向电流由串联电阻和注入决定,对迁移率和寿命最敏感;反向电流由产生过程决定;电容对掺杂和界面电荷最敏感;瞬态响应才对时间常数敏感。反过来做,用瞬态数据去定迁移率,参数之间会互相补偿,拟合出花来也对不上另一组实验。
数值参数同样要做收敛检查,它们也是“模型”。MaxStep减半、网格整体加密一倍,看关键结果(击穿电压、峰值电流、电容平台值)变化是否小于 1%;如果还在变,说明之前的结果是数值伪影而不是物理结论。这个检查花不了多少机时,但能挡掉大部分“仿真和实测对不上”的争论。
我自己的习惯是:任何一份新的语句文件,先关掉所有非必要模型跑一遍收敛性检查,确认网格和步长都收敛,再逐个把模型打开,每开一个就重跑同一组数据对比增量。有一次跳过这步,直接在一份继承来的文件上改LET_f,结果连续三天都在怀疑物理模型,最后发现是MinStep设得太大、峰值根本没被采到。从那以后我每次改瞬态参数,都强制先做一次步长减半的对照跑,再看曲线。希望这能帮你省掉那三天。
本文还有配套的精品资源,点击获取