简介:围绕Sentaurus器件仿真整理的语句示例文档,面向微电子、纳米电子与光电子方向的学习者和科研人员,聚焦I-V、C-V曲线计算、辐照损伤与重粒子入射、瞬态过程等常见场景,帮助读者理解SDevice语句的组织方式与参数配置逻辑。压缩包共1个docx文件,约16KB,以代码片段与模型说明为主:既有电流电压File与电极、物理模型、Math求解控制的完整定义,也包含混合模式AC耦合提取二极管电容、HeavyIon重离子撞击以及激光光照瞬态等典型写法,涉及迁移率、复合、雪崩、能带模型与时间步长设置。文档将零散命令按仿真目标归类,便于在项目中查找并替换材料、几何与偏置条件。已有2036人学习下载,适合具备一定TCAD基础、希望快速定位语法结构、对照修改网格与求解参数并复用仿真流程的读者参考。
1. 一份语句合集能省多少事:从 .docx 里那几百行 sdevice 命令说起
刚接触 Sentaurus 的人,十有八九会被卡在同一个位置:物理模型知道该开哪个,网格文件也生成了,真到写 sdevice 命令文件的时候,File段里四个路径、Math段里的求解器、Solve段里那串Coupled的顺序,全靠翻别人的文件拼凑。这份「各种语句 sentaurus.docx」就是在这类场景里攒出来的:它把五类常用仿真场景的完整命令段集中在一起,包括直流 I-V 扫描、Mixed-Mode 下的小信号 C-V、重离子入射瞬态、激光辐照瞬态,以及带陷阱能级的辐照损伤模型。适合已经能跑通最简单的二极管例子、需要照着修改参数的人:知道Physics里每一行的作用,知道Solve里为什么先单独解 Poisson,也清楚哪些参数必须根据器件实际情况修改,而不能直接照抄。下面按“这个参数在哪里出现、改了会怎样”的顺序拆开。
2. I-V 扫描的五段骨架:File、Electrode、Physics、Math、Solve 按什么顺序填
直流扫描是整个合集里出现频率最高的一块,也是新手踩坑最集中的地方。它看起来只是把电压从 0 加到某个值,实际上前面四段全是铺垫,真正决定结果对不对的,是你有没有把模型开关和输出变量对上。一条完整的 I-V 命令文件长这样,后面逐段拆。
File { Grid = "Diode_msh.tdr" Current = "Diode_IV.plt" Plot = "Diode_IV.tdr" Output = "Diode_IV.log" Parameter = "sentaurus.par" } Electrode { { Name="ElectrodeN" Voltage=0.0 } { Name="ElectrodeP" Voltage=0.0 } } Physics { AreaFactor = 1 Temperature = 300 Mobility ( DopingDependence eHighFieldSaturation hHighFieldSaturation Enormal CarrierCarrierScattering ) Recombination ( SRH (DopingDependence) Auger (withGeneration) Avalanche (UniBo Eparallel) Band2Band (Hurkx) ) EffectiveIntrinsicDensity (OldSlotboom) } Math { Method = Pardiso Number_of_threads = 4 StackSize = 1e8 ExtrapolateDerivatives AvalDerivatives RelErrControl Iterations = 15 Notdamped = 60 BreakCriteria { Current (Contact="ElectrodeN" maxval=1e-8) } } 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 } ) { Coupled { Hole Electron Poisson } Plot (FilePrefix="IV_" Time=(0.01;0.05;0.1;0.5) NoOverwrite) } }2.1 File 段先定三个输出,别让结果在跑完之后找不到
File段里四个关键字对应四种完全不同的文件,混淆一次就能浪费半天。Grid指向网格文件,通常由 sde 或 sprocess 生成,后缀是.tdr;Current存的是电极上的电流电压随时间或偏压的曲线数据,后缀习惯写.plt,这是你画 I-V 曲线时真正要用的那个;Plot存的是空间分布场,每一步的载流子浓度、电场、复合率都往里写,文件体积比Current大一两个数量级;Output是文本日志,收敛失败、奇异矩阵、模型不支持的报错全在这里,出问题时第一个打开的应该是它。Parameter是可选的材料参数覆盖文件,想临时改某个材料的迁移率或寿命,写在这里比改命令文件干净。
| 关键字 | 典型后缀 | 存什么 | 什么时候看 |
|---|---|---|---|
| Grid | .tdr | 网格与掺杂、材料区 | 每次跑之前确认几何对不对 |
| Current | .plt | 电极电流、电压、电荷 | 画曲线、算导通压降 |
| Plot | .tdr | 各物理量的空间分布 | 定位击穿点、看电场集中 |
| Output | .log | 迭代次数、错误、警告 | 报错时的第一现场 |
有个细节值得单独说:如果只需要曲线,Solve里的Plot语句可以整段删掉,仿真速度能明显变快。很多人习惯性把Plot段写满十几个物理量,结果一次扫描下来磁盘直接爆掉,最后真正用到的只有那几个。我的做法是先只输出Current,确认曲线形状合理之后再补一次带Plot的重跑,专门用来看空间分布。
2.2 Physics 段:迁移率、复合、雪崩、带间隧穿四个开关怎么配
Physics段是整个文件里最需要根据物理理解来选择的部分,多开一个模型可能让仿真不收敛,少开一个模型可能让结果完全失真。AreaFactor = 1是电流的面积因子,做二维切片仿真时它等于器件宽度,做三维时保持 1。Temperature = 300定义晶格温度,注意它是器件温度而不是环境温度,自热仿真要另外开热力学模型。
迁移率那几行里,DopingDependence让低场迁移率随掺杂浓度下降,这是重掺杂区串联电阻的主要来源;eHighFieldSaturation和hHighFieldSaturation是速度饱和,不加这两个,高压下的电流会被严重高估;Enormal是表面散射,只有 MOSFET 这类沟道贴栅氧的器件才需要,纯二极管加它意义不大;CarrierCarrierScattering用于大注入条件下,少子浓度接近多子时散射增强、迁移率下降,功率二极管的正向大电流段离不开它。
复合项的选择更讲究。SRH (DopingDependence)是肖克利-里德-霍尔复合,加DopingDependence表示寿命也随掺杂变化,重掺杂区寿命更短;Auger (withGeneration)是高注入下的俄歇复合,括号里的withGeneration意味着它也参与产生,反向漏电算得准不准和它有关;Avalanche (UniBo Eparallel)是雪崩倍增,括号里指定的是模型和场方向假设,Eparallel表示只考虑平行于电流方向的电场驱动,反向击穿必须开;Band2Band (Hurkx)是带间隧穿,用 Hurkx 的局部模型,适合高掺杂结的反向漏电分析。EffectiveIntrinsicDensity (OldSlotboom)是重掺杂带隙收缩,掺杂超过 1e18 之后不开这个本征载流子浓度会算错一个量级。
| 开关 | 影响的物理量 | 不加会怎样 |
|---|---|---|
| DopingDependence | 低场迁移率 | 串联电阻偏小,正向电流偏大 |
| HighFieldSaturation | 漂移速度 | 高压段电流虚高 |
| SRH + Auger | 复合电流 | 反向漏电与正向开压都不对 |
| Avalanche | 碰撞电离 | 击穿根本不会出现 |
| Band2Band | 隧穿漏电 | 高掺杂结反偏漏电低估 |
常见做法是:正向 I-V 只开 SRH 和迁移率;反向击穿扫描再把 Avalanche 打开;如果反偏漏电与实测差很远,再补 Band2Band。一次性全开,收敛难度会大很多,因为 Avalanche 和 Band2Band 的导数都不平滑。
2.3 Math 段:Pardiso 线程数、Notdamped 与 BreakCriteria 的收敛作用
Math段决定求解器怎么解那个巨大的非线性方程组,参数改一个数字往往就是“跑得动”和“跑不动”的差别。Method = Pardiso是直接法稀疏求解器,内存占用大但稳定性好,小规模二维器件优先用它;规模上去之后可以考虑迭代法求解器,代价是要调更多预处理参数。Number_of_threads = 4是并行线程数,实际能开多少取决于机器核数和内存带宽,不是越大越快。StackSize是栈空间,网格加密后如果报栈溢出,先把这个值往上调。
ExtrapolateDerivatives用上一步的解外推当前步的导数,能显著减少迭代次数;AvalDerivatives专门给雪崩模型加解析导数项,因为碰撞电离率对电场的依赖非常陡,没有它 Newton 迭代几乎必然发散。RelErrControl把收敛判据从绝对误差换成相对误差,对于电流跨度好几个数量级的扫描来说更合理。Iterations = 15是每个非线性步允许的最大迭代次数,Notdamped = 60表示前 60 次迭代不做阻尼,阻尼是防止步子迈太大的保护机制。
提示:
Notdamped设得太大,前期收敛快但容易在击穿附近直接发散;设得小又会把收敛速度拖慢。我的经验是先留默认值跑,出现反复振荡再往下调。
BreakCriteria { Current (Contact="ElectrodeN" maxval=1e-8) }这一行是全局的停止判据,电流超过 10 nA 就认为器件已经击穿、终止扫描。它的作用是节省时间,但也很容易被误用:如果器件正常工作电流本来就大于这个值,扫描会在刚导通时就被掐断;如果器件面积很大,10 nA 对应的电流密度小得离谱,击穿点会被判早。用之前一定按AreaFactor和实际电流密度换算一遍。
2.4 Solve 段:三段 Coupled 预热加 QuasiStationary,步长序列怎么给
Solve段是执行顺序,写法直接反映求解策略。前三条Coupled是逐步增加求解难度:先只解 Poisson 方程(此时假设没有载流子,纯静电),收敛后再加入空穴方程,最后把电子也加进去。这么写不是形式主义,而是因为初始猜测离真实解很远时,一次性解三个方程几乎不可能收敛。把难度分级,相当于给 Newton 迭代一个更好的起点。
QuasiStationary是准静态扫描,电压一点点往上加,每一步都当作稳态求解。InitialStep = 1e-6是初始电压步长,MaxStep = 0.01是步长上限,MinStep = 1e-9是下限——步长缩到这个值还不收敛,仿真就判定失败。步长不是固定值,求解器会根据收敛情况自动增减:连续几步顺利就放大步长,遇到困难就缩小。所以三个数的比例关系很重要,MaxStep太大,击穿附近会一步跨过去;MinStep太小,出问题时会长时间卡在无效迭代上。
Goal { Name="ElectrodeN" Voltage=1000 }指定扫描终点和扫描电极。这里的 1000 是个需要特别留意的数值——它和Electrode段里初始的 0.0 形成一个跨度极大的目标,绝大多数二极管根本撑不到这个电压,仿真要么被BreakCriteria提前掐断,要么在某个电压点反复缩步长然后失败。合理做法是把Goal改成你真正关心的电压,比如击穿点附近,或者干脆拆成几段QuasiStationary,每段换一个目标电压。
Plot (FilePrefix="IV_" Time=(0.01;0.05;0.1;0.5) NoOverwrite)里的Time在准静态扫描下表示扫描进度,而不是真实的秒数,NoOverwrite防止重复运行时覆盖已有文件。这一步的实际意义是:不必每一步都存空间分布,只在几个关键位置留快照,用于后续查看载流子分布和电场分布就够了。
3. C-V 曲线:Mixed-Mode 里接一个 1 kHz 小信号,AC 抽取要写全三段
直流扫描解决 I-V,电容电压特性就得换一套写法。单器件模式下的ACCoupled也能算,但更容易理解、也更常用的写法是把器件塞进 Mixed-Mode 的System段里,外面挂一个电压源,然后在这个电路节点上加小信号。这样做的额外好处是:后面如果要接电阻、电感做交流分析,结构不用重写。
Device Diode { Electrode { { Name="ElectrodeN" Voltage=0.0 } { Name="ElectrodeP" Voltage=0.0 } } File { Grid = "Diode_msh.tdr" Current = "Diode_CV_1kHz.plt" Plot = "Diode_CV_1kHz.tdr" } Physics { ... } Plot { ... } } System { Diode diodesystem ("ElectrodeN"=front "ElectrodeP"=0) Vsource_pset vn (front 0) { dc=0 } } 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 } } }3.1 为什么 C-V 要挪到 Mixed-Mode:System 段把器件变成一个两端网络
Device Diode { ... }这一整块和普通单器件命令文件几乎一样,区别是它被包在一个命名块里,名字叫Diode,这个块本身不会独立求解。真正让它动起来的是System段:Diode diodesystem ("ElectrodeN"=front "ElectrodeP"=0)把器件实例化成diodesystem,并把两个电极分别接到电路节点front和地节点0上。注意front是电路网络里的节点名,不是电极名,这个区分在后面Node(front)里会再次出现,写错了 AC 信号就加错地方。
Vsource_pset vn (front 0) { dc=0 }是一个直流电压源,初始值 0,接在front和地之间。pset这个后缀表示它同时参与直流和后续的小信号分析。整个结构的效果是:器件被一个电压源偏置,你在front节点上加频率为 1 kHz 的小信号,求解器在直流工作点上做一次线性化,得到该节点的导纳,再换算成电容。
这种写法的价值在于扩展性。想在半导体内串一个电阻看寄生效应,加一行Resistor就行;想做交流阻抗谱,把频率从 1 Hz 扫到 1 MHz 也只是改三个参数。单器件模式的ACCoupled就做不到这些。
3.2 小信号抽取:ACExtract、StartFrequency/EndFrequency/NumberOfPoints
File段里的ACExtract是专门给小信号结果用的,和Current分开。这个文件里存的是每个偏置点上的电容、电导(或者导纳的实部虚部),画 C-V 曲线就是读它。这里有个常见的翻车点:把ACExtract的文件名写成和Current一样,后写的会把先写的覆盖掉,跑完发现 C-V 曲线文件里打开只有直流数据。
ACCoupled括号里的频率三参数决定扫哪些频点。StartFrequency=1e3和EndFrequency=1e3相等,表示只算 1 kHz 这一个点;NumberOfPoints = 1和后面的Decade配合,表示在给定范围内按十倍频程均分多少个点。如果只看 1 kHz 的 C-V,直接把首尾频率设成一样最省时间;如果要看电容随频率的变化(比如做界面态分析),就把EndFrequency设到 1e6,NumberOfPoints给个 5 到 10,频率点会自动按对数分布。
ACMethod = Blocked指定用分块方式求解交流系统,ACSubMethod("diodesystem")=ParDiSo指定对这个器件块用并行直接求解器。这两行在器件规模不大时可以保持默认设置,但如果求解时出现“AC 系统奇异”的报错,先检查这两个求解器设置和网格质量,通常能定位到问题。
3.3 偏置爬坡与 AC 求解的耦合顺序
最容易被忽略的是求解顺序。QuasiStationary的括号里嵌套了ACCoupled,意思是每加一步直流偏压,就在这个新工作点上做一次交流小信号求解,把结果写进ACExtract。所以 C-V 曲线上的点数等于直流扫描的步数,而不是 AC 的频率点数——这个理解如果反了,就会以为NumberOfPoints越大曲线越密。
Increment=2 Decrement=4控制步长自适应:连续收敛顺利时,下一步步长乘以 2;迭代失败时,步长除以 4。Goal { Parameter=vn.dc Voltage=100 }表示以电压源vn的直流值为扫描变量,扫到 100 V。注意这里用的是Parameter而不是Name,因为扫描对象是电路元件而不是器件电极,两种写法的区别就在这里。
Coupled (Iterations=15) { Electron Hole Poisson Contact }这一行在准静态扫描之前多解了一次带Contact的耦合,目的是把接触处的边界条件收敛得更彻底。别小看这一句,接触处的载流子浓度梯度很大,如果直接进入带 AC 的扫描,很容易在第一个偏压点就报收敛失败。
4. 瞬态两类硬骨头:重离子入射与激光辐照,物理段差在哪
瞬态仿真和直流扫描的最大区别是时间变成了自变量,Transient的步长控制直接决定你能不能抓到峰值。合集里给了两个典型场景:重离子入射(电荷在皮秒量级沉积)和激光辐照(光生载流子按高斯时间包络产生)。两者在Physics段里的写法完全不同,一个是粒子径迹,一个是光学求解。
Physics { HeavyIon ( Direction = (0,1) Location = (200, 0) Time = 1e-9 Length = 20 Wt_hi = 0.1 LET_f = [0 8.7e-6 8.7e-6 0] Gaussian PicoCoulomb ) } Solve { NewCurrentPrefix = "trans_" Transient ( InitialTime=0 FinalTime=35e-9 MinStep=1e-17 MaxStep=1e-10 ) { Coupled { Poisson Electron Hole Circuit } Plot (FilePrefix="TransHI_" Time=(0.5e-9;1e-9;2e-9;5e-9;10e-9) NoOverwrite) } }4.1 HeavyIon:位置、时间、线性能量转移三件事先对齐单位
HeavyIon括号里每个参数都对应一个物理量,错一个结果就完全不可信。Direction = (0,1)是入射方向向量,二维器件里 (0,1) 表示从表面垂直往下打;Location = (200, 0)是入射点坐标,单位跟网格一致,通常是 μm——如果你的网格是用 nm 建的,这个 200 会落在器件外面,仿真跑完什么也没发生。跑之前用可视化工具打开网格,把坐标点对一遍,这一步花不了两分钟,省下的是几个小时的无效计算。
Time = 1e-9是粒子击中时刻,必须落在Transient的InitialTime和FinalTime之间,否则电荷永远不会注入。Length是径迹长度,Wt_hi是径迹的横向特征宽度,这两个参数一起决定了沉积电荷的空间分布形状;合集原稿里这两个位置是空的方括号,说明它们必须按粒子种类和能量自行填写,不能照抄。
LET_f = [0 8.7e-6 8.7e-6 0]是线性能量转移随时间的变化曲线,四个点构成一个梯形脉冲,前后两个 0 表示上升沿和下降沿。Gaussian表示径迹横向按高斯分布,PicoCoulomb表示LET_f的单位是 pC/μm 而不是默认的 MeV·cm²/mg。这两个开关选错,注入电荷量会差好几个数量级,而且日志里不会报错——结果看起来“跑通了”,但物理上是错的。
| 参数 | 含义 | 常见错误 |
|---|---|---|
| Location | 入射点坐标(μm) | 与 nm 网格混用,粒子打到器件外 |
| Time | 入射时刻(s) | 落在仿真时间窗之外 |
| Length | 径迹长度(μm) | 小于结构厚度,电荷沉积累积在表面 |
| Wt_hi | 径迹横向宽度(μm) | 设成 0 会导致网格上出现奇异点 |
| LET_f | LET 时程(pC/μm) | 单位与 PicoCoulomb 开关不匹配 |
NewCurrentPrefix = "trans_"给所有输出文件加前缀,避免和之前的直流结果混在一起。这个习惯值得保留,同一个项目里往往要跑十几次瞬态,文件名不加区分,回头根本认不出哪个是哪个。
4.2 Optics:光学窗口、光束方向和复折射率栈
激光辐照这一块走的是完全不同的路径,靠Optics段里的光学求解器算吸收分布,再把光生率喂给电学方程。
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)) ) ) ) ) )ComputeFromMonochromaticSource声明光源是单色的,后面Excitation里的Wavelength = 0.8*um和Intensity = 0.06*W/cm2才有意义。波长决定了吸收深度,0.8 μm 在硅里穿透大概十几微米,如果你的器件厚度只有 2 μm,光基本是均匀吸收的;反过来如果器件很厚,就得考虑背面反射和厚度方向上的衰减。
TimeDependence (WaveTime=(1e-9 1e-9) WaveTSigma=50e-12)定义时间包络:起始时刻 1 ns、持续 1 ns,高斯上升沿宽度 50 ps。这个 50 ps 是关键数字,它决定了你需要多小的瞬态步长才能把光脉冲的前沿采样出来。
Window("L1")定义一条一维光路,Origin = (200,0)是起点,XDirection = (1,0,0)是传播方向,Line (Dx=10)表示沿这条线按 10 μm 的间距取点。OptBeam加LayerStackExtraction表示用一维分层膜系的方法算各层吸收,再用Mode = ElementWise把结果映射回二维网格。ComplexRefractiveIndex (WavelengthDep(real imag))让折射率的实部和虚部都随波长变化,虚部对应吸收系数。
这里的坑在于光学窗口和器件几何不重合。窗口起点如果落在电极上而不是半导体表面,算出来的光生率分布会整体偏移,最后收集到的电流波形看着“有响应”但形状不对。验证方法是把OpticalGeneration的分布单独画出来看一眼。
4.3 Transient:MinStep 与 MaxStep 差七个数量级时会发生什么
Transient (InitialTime=0 FinalTime=35e-9 MinStep=1e-17 MaxStep=1e-10)这行的信息量比看上去大。MinStep到 1e-17 秒、MaxStep到 1e-10 秒,中间跨了七个数量级,说明求解器在电荷沉积的那一瞬间会被迫缩到极小步长,之后随着电流衰减再逐步放大。这是正常的:重离子入射的电荷沉积发生在皮秒以内,步长必须足够细才能捕捉到峰值电流。
问题出在MaxStep和物理时间尺度的匹配上。光学生成那个例子里,高斯前沿宽 50 ps,而MaxStep = 1e-10(100 ps)比前沿还宽,意味着上升沿可能只被采到一两个点,峰值直接失真。合理的关系是让MaxStep不超过特征时间的二十分之一,也就是 50 ps / 20 ≈ 2.5 ps,写法上是MaxStep = 2.5e-12。
FinalTime也不是随便给的。它要长到让瞬态电流衰减回稳态,否则你算出来的收集电荷会偏小。判断办法是把FinalTime加长 50% 再跑一次,如果总收集电荷变化小于百分之几,说明时间窗够用了;如果还在明显增长,说明拖尾还没走完。
Plot (FilePrefix="TransHI_" Time=(...))里的Time在瞬态下才是真实时间,和准静态扫描里的含义不同。列出的这五个时刻是电荷收集过程中最关心的位置:入射前、峰值附近、衰减中段。全部网格的场量在每个时刻都写一份,文件很大,所以只挑这几个点。
5. 避坑与排查:五条让仿真中途翻车的写法
下面这五条基本覆盖了从“跑不动”到“跑完了但结果不对”的绝大多数情况。每条按现象、原因、解决三步写,遇到问题可以先按这个顺序对照检查。
5.1 收敛类问题:目标电压、停止判据与阻尼设置互相打架
现象一:QuasiStationary卡在MinStep不动,日志里步长被反复除以 4,最后报收敛失败。原因通常是Goal里的目标电压远超器件实际能承受的范围——命令文件里的Voltage=1000就是典型例子,一个普通二极管在几伏到几十伏就击穿了,让它扫到 1000 V,等于逼着求解器在物理上不存在的解附近反复挣扎。另一种可能是BreakCriteria的电流阈值和扫描目标冲突:电流判据早就触发了,但电压目标还没到,两个条件互相拉扯。解决办法是把Goal改成实际关心的电压,用BreakCriteria里的电流阈值判断击穿点,或者把一次长扫描拆成几段QuasiStationary,每段一个目标。
现象二:加了陷阱或雪崩模型之后,迭代次数从个位数涨到几十次,最后报No convergence。原因是这些模型的导数不平滑,在网格上引入了局部尖锐变化。合集里那段辐照损伤的Traps定义开了Randomize,会让陷阱浓度在空间上随机涨落,等于人为给方程组加噪声。解决办法是先关掉Randomize做一轮干净校准,确认能级位置、浓度、俘获截面这些参数的量级对得上,再把随机化打开做统计意义上的分析。同理,Avalanche打开时必须同时开AvalDerivatives,否则几乎必然发散。
现象三:正向扫描刚开始就停在很低的电压,曲线只有一小段。大概率是BreakCriteria { Current (Contact="ElectrodeN" maxval=1e-8) }里的 1e-8 安培对于你的器件太小。这个绝对电流值要结合AreaFactor和电流密度来设:一个面积为 1e-4 cm² 的器件,1e-8 A 对应 1e-4 A/cm²,很多器件在零点几伏就到了。把阈值按实际电流密度乘面积换算一遍,或者干脆先注释掉这一行,让扫描靠Goal自然结束。
5.2 语法、文件与单位类问题:跑通了但结果是错的
现象四:日志里没有报错,但 C-V 曲线文件是空的,或者里面只有几行。原因有两类。一是ACCoupled里漏了Circuit求解量,只写了Poisson Electron Hole Contact,交流系统没有把外部电路算进去,自然抽不出电容。二是Node(front)里的节点名和System段的对不上——front是电路节点标识,不是电极名,两者名字相近但完全不是一回事。排查办法是先把System段抄一遍,确认每个节点名的拼写,再回去对Node()括号里的内容。
现象五:重离子打进去之后电流完全没有响应,或者响应出现在一个奇怪的位置。最常见的是单位错位:Location按 μm 解释,而网格坐标是按 nm 建的,(200, 0)实际落在器件外几百微米处,电荷注入到了真空里。其次是Time = 1e-9落在了Transient的InitialTime之后没问题,但如果FinalTime比它小,粒子就永远不会到达。还有一种情况是Length和Wt_hi留空或设成 0,径迹退化成一个点,网格上出现奇异源项,求解器要么发散要么给出一个尖刺状的假峰值。解决方式很朴素:跑之前打开网格看一眼坐标范围,把Location换算成和网格一致的单位,Length和Wt_hi按粒子能量给一个物理上合理的值。
除了这五条,还有一个不属于“错误”但很浪费时间的习惯:把Plot段写得特别满。瞬态仿真每个输出时刻都写全部网格场量,一个二维几万节点的网格、十几个物理量、五六个时刻,轻松上 GB。正确的做法是Current文件负责曲线,Plot只在真正需要看空间分布的那几个时刻输出,或者干脆重跑一次专门的短瞬态。
6. 辐照损伤陷阱模型:把 Traps 段写对,再用三步自检确认结果不是幻觉
陷阱模型是这份合集里最容易被“抄错也不知道”的一块。它没有明显的语法错误提示,参数写错照样跑完,输出的 I-V 曲线看起来也平滑,只是物理含义全变了。命令段长这样:
Physics (Material="Silicon") { Traps ( ( Acceptor Level EnergyMid=0.42 fromCondBand Conc=2.3226E15 Randomize=0.29 eXsection=9.5E-15 hXsection=9.5E-14 ) ( 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) }6.1 Traps 段六个参数:能级位置、浓度、俘获截面、随机化
先说清楚这一组陷阱在模拟什么:辐照在硅里引入的深能级缺陷,它们既俘获电子也俘获空穴,改变载流子寿命和耗尽区电荷,最终体现在漏电流和阈值漂移上。三个陷阱条目分别对应不同的能级位置和俘获截面,这种多能级组合是辐照缺陷建模的常见做法。
Acceptor和Donor决定陷阱带电的符号。Acceptor 陷阱俘获电子后带负电、释放电子后中性;Donor 陷阱释放电子后带正电。这个区别直接影响耗尽区的空间电荷分布,写反了电容曲线会整体平移。Level EnergyMid=0.42 fromCondBand表示能级在导带下方 0.42 eV 处,fromCondBand和fromValBand二选一,决定参考的是导带底还是价带顶——同一个 0.42,从导带算是深能级,从价带算就接近禁带中央,物理效果差很多。
Conc是陷阱浓度,单位 cm⁻³。原稿的注释里写着#Conc=Fluence*1.1613,这是个很关键的提示:陷阱浓度不是独立参数,而是由辐照注量乘以一个引入率换算出来的。改注量的时候如果只改了注释没改数值,两轮仿真之间就没有可比性。eXsection和hXsection分别是电子和空穴的俘获截面,单位 cm²,数量级通常在 1e-15 到 1e-13 之间;电子截面远大于空穴截面时,陷阱表现为电子陷阱,反之亦然。
Randomize是相对涨落幅度,让陷阱浓度在空间上按给定比例随机分布,用来模拟离散缺陷而不是均匀连续分布。这个开关会显著增加收敛难度,因为它在网格上引入了高频扰动。校准阶段建议关掉,把平均浓度和能级定准之后再打开,做多次随机实现看结果分散度。
| 参数 | 单位 | 作用 | 写错的后果 |
|---|---|---|---|
| EnergyMid | eV | 陷阱能级位置 | 复合率量级错,漏电偏差一个数量级 |
| fromCondBand/fromValBand | — | 能级参考边 | 深能级变浅能级 |
| Conc | cm⁻³ | 陷阱浓度 | 与注量不对应,无法跨实验对比 |
| eXsection/hXsection | cm² | 俘获截面 | 寿命与实测不符 |
| Randomize | 相对值 | 空间随机涨落 | 收敛困难,结果不可复现 |
Physics (MaterialInterface="Oxide/Silicon") { Charge (Conc=1.5e11) }这一行是界面固定电荷,单位 cm⁻²,和体陷阱完全不同的物理量。它影响的是表面势和沟道开启,用在 MOS 结构上;如果器件没有氧化层界面,这一行写了也不起作用,但会让人误以为模型已经设好了。
6.2 三步自检:零辐照对账、步长收敛、网格加密
参数抄完只是第一步,确认结果可信才是重点。我一般会按下面三步走一遍,任何一步出问题都说明前面的设置里有隐藏错误。
第一步是零辐照对账。把Traps整段注释掉,用完全相同的网格、温度、AreaFactor和Solve设置跑一条 I-V,结果应该和你在加入陷阱之前的基线曲线一致,相对误差在千分之一量级。如果不一致,说明你在改陷阱的时候顺手动了别的——最常见的是Temperature被改了,或者Mobility里少写了一个开关。这一步花的时间不多,但能拦住绝大多数“改了 A 结果变了 B”的糊涂账。
第二步是步长收敛。把Transient的MaxStep缩小十倍重跑一次,比较收集电荷的峰值和总电荷。如果两者差异小于百分之五,说明当前步长已经足够;如果差异很大,说明之前的峰值是数值伪影,不是真实的电荷收集。这一步对重离子入射尤其重要,因为电荷沉积的时间尺度本来就在皮秒量级,步长给粗了,峰值会被抹平
本文还有配套的精品资源,点击获取