ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Sentaurus语句解析:SDE/SProcess/SDevice模块与仿真流程

Sentaurus语句解析:SDE/SProcess/SDevice模块与仿真流程

简介:围绕Sentaurus仿真软件在半导体器件电学特性与辐照效应模拟中的典型应用,该文档整理自实际工程案例,适合从事微电子、纳米电子及光电子器件设计的研究生、工程师与科研人员参考。包内仅1个docx文件,压缩包约16KB,内容虽精简但覆盖完整设置流程,便于直接查看与复用。已有2027人学习浏览。文档重点介绍了I-V曲线与C-V曲线的仿真计算方法,包括电流电压文件配置、网格与输出参数设定、Diode混合模式仿真等;同时讲解辐照损伤、重粒子入射与瞬态仿真的物理模型和求解设置,并给出重离子撞击、激光照射等瞬态仿真的关键词示例,对理解软件操作与物理建模均有实际帮助。

1. 各种语句sentaurus.docx:先分清这是哪一层的语句再动手

如果你手里也有一份叫“各种语句sentaurus.docx”的文档,大概率是从各个教程、案例文件里摘出来的命令片段:有SDE的括号嵌套,有SProcess的工艺步骤,还有SDevice里一大段物理模型声明。问题在于,Sentaurus不是一条命令走到底的工具,它分成结构编辑器、工艺仿真器、器件仿真器三个独立模块,每层的语句语法、执行方式和调试手段都不一样。拿SDE的Scheme语法去套SDevice的命令文件,第一行就会翻车。这篇笔记就按“语句属于哪个模块→每条语句干什么→怎么拼成能跑的流程→报错怎么看”的顺序,把这类docx里最常见的语句拆开讲清楚。适合刚接触TCAD仿真、手头有一堆语句片段但拼不出完整仿真的开发者。

2. 从文档里的各种语句到能跑的仿真:先分清三个模块的语句边界

拿到任何一份Sentaurus相关文档,我第一件事不是读内容,而是先看它摘的是哪个模块的语句。Sentaurus的仿真链路很长,一条完整的仿真通常要经历结构定义、工艺模拟、器件特性模拟三个阶段。这三个阶段对应三个不同的可执行文件:SDE(结构编辑器)、SProcess(工艺仿真器)、SDevice(器件仿真器)。每个模块读取的输入文件格式完全不同,语句风格也差着十万八千里。

2.1 SDE语句:用Scheme语法写几何、掺杂与网格

SDE是三层里最特殊的一个,它不使用类似“命令+参数”的简单格式,而是直接吃一段Scheme脚本。这意味着你在docx里看到的SDE语句,往往长这样:括号开头、括号结尾、函数名在前面、参数一个接一个排后面。如果你之前只写过命令行式的脚本,第一次看SDE语句会觉得极其别扭,但它的好处是逻辑表达力强,可以用循环、变量、条件判断来生成复杂结构。

SDE的核心语句集中在几个方面。几何结构用sdegeo:create-rectangle、sdegeo:create-polygon这类函数创建;掺杂分布用sdedr:add-constant-profile、sdedr:add-gaussian-profile来定义;网格密度控制用sdedr:define-refinement-size和sdedr:add-refinement完成。这些语句有一个共同特点:必须先定义区域,再往区域里填充材料或掺杂,最后才谈网格。顺序反了,比如先定义掺杂窗口再创建几何体,SDE会直接报“region not found”。

我建议你在整理docx里的SDE语句时,按“几何创建→材料分配→掺杂定义→网格定义→网格生成”这个顺序重新排列,而不是按文档原顺序抄。很多docx之所以跑不通,不是因为语句本身错了,而是语句之间的依赖顺序被摘乱了。SDE是按照脚本从上到下顺序执行的,前面语句生成的实体,后面语句才能引用,这一点和SProcess、SDevice的声明式风格有本质区别。

2.2 SProcess语句:把工艺步骤翻译成命令序列

SProcess模块处理的是工艺仿真,也就是氧化、扩散、注入、刻蚀、沉积这些步骤。它的语句风格比SDE友好得多,基本是depo、etch、diffuse、implant这样的动词开头,后面跟工艺参数。但这里有一个容易踩坑的地方:SProcess的语句不是随意排列的,它严格模拟工艺顺序,先沉积还是先刻蚀、先注入还是先退火,都会影响最终结构。

举个例子,一条典型的扩散语句长这样:

diffuse temperature=950 time=30min

这条语句的意思是让器件在950摄氏度下退火30分钟。看起来简单,但它会触发掺杂再分布,且激活率和扩散系数由物理模型决定。如果你的docx里只摘了扩散语句,却没摘在此之前注入产生的掺杂分布,那这条扩散语句实际处理的是一个没有掺杂源的片子,结果自然不对。

SProcess里的工艺语句还有几个特别需要注意的修饰语句,比如gas用来设定环境气氛,strain用来打开应力计算。实际项目中我一般会先跑一条不带物理模型的快速验证脚本,确认工艺顺序没有逻辑错误,再开启完整模型跑精确结果。这样做的好处是,语法错误能在几秒内暴露,而不是等一小时工艺仿真跑完才发现语句顺序有问题。

2.3 SDevice语句:物理模型与数值求解的声明式配置

SDevice是三层里语句量最大、也最容易让人看懵的部分。它的输入文件是分段式的,每段以Section开头,以}结束,段内是一系列参数赋值语句。常见的段有:File(文件输入输出)、Electrode(电极定义)、Physics(物理模型)、Plot(输出量)、Math(数值算法控制)、Solve(求解序列)、Output(结果保存)。

这套结构和SDE完全不同:SDEVICE不关心几何是怎么画出来的,它只读取SDE生成的网格文件,然后按照你在各个 Section 里声明的物理模型去算电学特性。所以你在docx里看到的SDevice语句,几乎都是“在某段里设置某个参数”的形式,脱离了Section来谈语句是没有任何意义的。

举个例子,打开碰撞电离模型的写法是在Physics段里声明:

Physics { Temperature = 300 Hydrodynamic Avalanche (vanOverstraeten) }

这里第一行设置晶格温度,第二行开启流体动力学输运模型,第三行开启碰撞电离模型并指定使用 vanOverstraeten 公式。如果docx里单独摘出Avalanche (vanOverstraeten)而不说明它必须在Physics段内,你把它放在Math段,SDevice会报“unknown parameter”。这种段归属错误,我在各类语句文档里见得太多了。

3. 照着文档复现一个仿真:最小可运行脚本与参数含义

上面说过,语句必须放回各自的模块才有意义。这一章我直接给一个最常见的入门结构——PN结二极管,从SDE建结构到SDevice算出IV特性,把三层的语句串成一条完整链路。你看完可以直接照抄,改改尺寸和掺杂浓度就能当自己的第一个跑通案例。

3.1 最小SDE脚本:从衬底到掺杂区

先写SDE脚本。这个脚本创建一个一维PN结结构,左边是P型区,右边是N型区,然后定义掺杂和网格。

; 创建一个矩形区域,定义PN结的物理边界 (sdegeo:create-rectangle (position 0 0 0) (position 1 0.5 0) "Silicon") ; 给区域分配材料属性,Silicon为衬底材料 (sdegeo:set-region-material (find-body-id (position 0.1 0.25 0)) "Silicon") ; 定义P型掺杂:浓度1e18,注入到左侧区域 (sdedr:define-constant-profile "P_Profile" "BoronActiveConcentration" 1e18) (sdedr:define-refeval-window "P_Window" "Rectangle" (position 0 0 0) (position 0.5 0.5 0)) (sdedr:add-constant-profile-placement "P_Placement" "P_Profile" "P_Window") ; 定义N型掺杂:浓度1e16,注入到右侧区域 (sdedr:define-constant-profile "N_Profile" "ArsenicActiveConcentration" 1e16) (sdedr:define-refeval-window "N_Window" "Rectangle" (position 0.5 0 0) (position 1 0.5 0)) (sdedr:add-constant-profile-placement "N_Placement" "N_Profile" "N_Window") ; 定义网格密度:结区附近加密 (sdedr:define-refinement-size "Ref_Size" 0.02 0.05 0.005 0.01) (sdedr:define-refinement-window "Ref_Window" "Rectangle" (position 0.4 0 0) (position 0.6 0.5 0)) (sdedr:add-refinement-placement "Ref_Placement" "Ref_Size" "Ref_Window") ; 生成网格并保存 (sde:save-model "pn_diode")

这段脚本里有几个关键点。position接受三维坐标,单位是微米,Z方向没用到所以统一写0。find-body-id用来定位已经创建的区域,后面跟坐标,SDE会自动找到包含该坐标的实体。掺杂浓度单位是cm^-3,1e18 表示每立方厘米1e18个杂质原子。define-refinement-size四个参数分别是水平方向最大网格尺寸、垂直方向最大网格尺寸、结区附近的最小水平尺寸、最小垂直尺寸,网格越细计算越准但耗时越长,PN结附近必须加密,因为耗尽区内的电场变化剧烈,网格太粗算出来的击穿电压会严重偏大。

3.2 最小SDevice脚本:漂移扩散方程与接触设置

SDE跑完后会生成pn_diode.msh网格文件,接下来用SDevice读取它,设置电极和物理模型,求解电压扫描。

# SDevice输入文件:pn_diode_des.cmd Device "pn_diode" { File { Grid = "pn_diode.msh" } Electrode { { Name = "anode" Voltage = 0 } { Name = "cathode" Voltage = 0 } } Physics { Temperature = 300 Mobility (DopingDependence) } Plot { eDensity hDensity eMobility hMobility } Math { Extrapolate Iterations = 30 RelErrControl } Solve { Coupled { Poisson Electron Hole } Quasistationary ( DoStep 0.01 10 Goal { Name = "anode" Voltage = 1.0 } ) } }

注意这个文件里的语句不是可执行命令,而是声明式配置。Device "pn_diode"指定要仿真的器件名称;File里的Grid指向SDE生成的网格文件;Electrode段需要在SDE里定义过对应的电极边界,否则这里会报找不到接触。Solve段里的Coupled表示对泊松方程、电子连续性方程、空穴连续性方程联立求解;Quasistationary是准静态扫描,DoStep 0.01 10表示初始步长0.01V,最多走10步,Goal指定阳极电压扫描到1V。

这里最容易翻车的是电极定义。SDE里建结构时如果没在边界上定义电极名字,SDevice这边写了Name = "anode",会直接报electrode not found。所以回到SDE脚本,在创建矩形区域后,必须用sdegeo:define-contact-set和sdegeo:set-contact-boundary把左右两个边界分别命名为 anode 和 cathode。有的docx只摘了SDevice语句,没摘SDE里对应的电极定义语句,这就是仿真相当于盖了楼没装门。

3.3 参数说明:单位、温度、网格密度怎么改

写Sentaurus语句,单位是最容易出隐性错误的地方。SDE坐标默认微米,掺杂浓度默认cm^-3;SDevice里电压单位是伏特,温度单位是开尔文。零散语句看多了,很容易把SDE里的浓度1e18直接搬到SDevice的物理模型参数里去,但后者根本不认这个参数。

我建了一个常用参数速查表,每次写脚本都会对照一眼:

参数所属模块单位常见取值备注
position坐标SDE微米结构尺寸Z方向默认0
掺杂浓度SDEcm^-31e15~1e19区分Active与Total
温度SDeviceK300低温仿真可设77
电压SDeviceV击穿测试可到上百配合步长控制
网格最大尺寸SDE微米结构尺寸的1/10结区需加密
Math迭代次数SDevice次30~50不收敛时先加大

网格密度这个参数特别值得多写几句。网格不是越密越好,我在模拟一个功率器件的击穿特性时,把结区最小网格从0.005微米改到0.001微米,仿真时间直接膨胀了8倍,但击穿电压只变化了1.2%。如果你用docx里的语句做参数扫描,建议先跑一个粗网格版本确认趋势,再对关键结构局部加密。不要全局加密,那是拿计算资源换微小的精度提升,很不划算。

4. 语句报错排查:格式、语法与运行环境的三类高频问题

语句文档看多了,你会发现绝大多数报错不是物理模型选错,而是最基础的格式和语法问题。SDE的Schema语法、SProcess的命令风格、SDevice的Section结构,每层都有各自的“脾气”。下面是我在帮人调脚本时遇到最多的三类问题,每一类都附了定位方法。

4.1 语法错误:括号不匹配与Scheme大小写

SDE脚本用Scheme语法,括号嵌套深度经常超过五层,少写一个右括号,错误信息往往会指向文件末尾而不是真正出错的那一行。我排查这类问题有一个习惯:先看函数名大小写。SDE内置函数全是小写开头的驼峰式,比如sdegeo:create-rectangle,如果你在docx里摘到的版本是Create-Rectangle或SDEGEO:create_rectangle,不管括号多完美都过不了解析。

括号匹配的检查工具,我一般直接用文本编辑器的括号高亮功能。把光标放在左括号上,编辑器会标出对应的右括号,沿着嵌套结构一层层检查。另一个更高效的办法是把脚本缩进做好,Scheme的缩进习惯是两个空格一层,缩进对齐了,括号缺失的位置一眼就能看出来。

SDevice和SProcess的语法错误则不同,它们更常见的是少写了分号。SDevice的每个参数赋值语句结尾都要有分号,Section段的结尾不用分号而用右花括号。如果某条语句漏了分号,解析器可能会把下一行语句的第一段当成上一行参数的延续,报错位置和真实错误位置相隔好几行,要看上下文才能定位。

4.2 模型语句失效:方程组合与参数范围

物理模型语句的报错往往不是“语法错误”,而是“参数无效”或“模型不可用”。最常见的情况是开启了某个模型但没满足它的前置条件。比如SDevice里用Avalanche模型,需要在Math段设置RecBoxIntegr或相应的数值积分方法,否则仿真会中途崩溃。

另一个典型是温度参数。Physics段里声明Temperature = 77,但载流子迁移率模型还是默认的300K参数集,这时候仿真能跑,但结果毫无物理意义,而且非常难排查——因为没有报错,只有输出曲线明显不合理。我的排查经验是,改了温度就必须同步检查所有和温度相关的模型参数,Mobility、Recombination、BandGap这些模型如果有温度依赖,都得确认对应的参数文件覆盖了目标温度范围。

还有一种“静默失效”是语句没报错但也没生效。比如SDE里定义了多个掺杂窗口,后面的窗口覆盖了前面的窗口。这时仿真能正常跑完,但掺杂分布和你预期的完全不同。检查方法是在SVisual里打开掺杂浓度的等值线图,看实际结构里的掺杂分布是否符合语句定义。这比反复看日志文件高效得多。

4.3 文件路径与版本差异:docx里摘语句的连带问题

这一条专门说从docx整理语句会遇到的坑。Word文档里的引号、分号、括号经常会被编辑器自动替换成中文全角符号,尤其是引号。SDE和SDevice的解析器只认ASCII字符,一个全角引号就能让整条语句失效。我从docx复制语句到脚本文件后,第一件事就是把所有全角符号批量替换成半角。

版本差异也很隐蔽。Sentaurus不同版本对语句的支持有差异,比如早期版本用Mobility (DopingDependence),新版本里部分模型改成了Mobility (DopingDependenceHighFieldSaturation)。docx里如果没标注语句对应的软件版本,你在新版本上跑老语句,轻则警告重则报错。我建议在整理语句文档时,每段语句都备注来源版本,至少标注“实测可跑”或“从某案例摘录未验证”,这样后人用的时候心里有数。

文件路径问题多出现在SDevice的File段。通常我们写相对路径,比如Grid = "pn_diode.msh",这个路径是相对于运行SDevice时的当前目录。有人习惯用绝对路径,但换台机器路径就失效。我一般固定用相对路径,并且把网格文件、命令文件、输出文件放在同一个目录下,减少路径出错的可能。

5. 语句文档的避坑清单:五条来自一线的踩坑记录

这一章是血泪经验。下面五条坑,每条都是我在实际项目中遇到并花过不少时间解决的问题,按“现象→原因→解决”写出来,你对照着检查自己的语句文档能省很多时间。

5.1 掺杂语句不生效,结构里全是本底掺杂

现象:仿真跑完了,但IV特性像是本征半导体,漏电流在1e-12量级,怎么调偏压都上不去。检查SDE生成的掺杂分布图,发现整个区域浓度均匀且极低。

原因:sdedr:add-constant-profile-placement引用的窗口和区域不匹配。常见写法是从docx里复制了一个窗口定义,但窗口坐标是旧结构的,当前结构的尺寸改了,窗口落在结构之外,掺杂语句没有作用到任何实体上。SDE不会报错,因为这个窗口在几何上是合法的,只是没有覆盖到结构内部。

解决:给每条掺杂placement加一个覆盖性检查。我在每个SDE脚本末尾加一段验证,让SDE输出掺杂浓度在指定点的值:

(define (check-doping x y) (let ((val (sde:get-material-info (position x y 0) "DopingConcentration"))) (if (number? val) (printf "Doping at (~f,~f) = ~e cm^-3\n" x y val) (printf "No doping found at (~f,~f)\n" x y)))) (check-doping 0.25 0.25) (check-doping 0.75 0.25)

如果输出显示两个点的浓度一致,说明掺杂窗口位置不对,回SDE改坐标。

5.2 SDevice报“Matrix is singular”或“No convergence”

现象:Solve段跑了两三步就中断,日志里出现Matrix is singular或No convergence。

原因:通常是网格太粗,导致雅可比矩阵奇异;或者是电极接触边界上网格太疏,载流子无法数值求解。还有一种情况是Math段的Iterations设置太小,默认值在某些复杂模型下不够用。

解决:先检查网格,把电极附近的最小网格尺寸缩小一个数量级,重新跑SDE生成网格。然后检查Math段,把Iterations至少加到50,同时打开Extrapolate让前一步的解作为下一步的初始猜测。如果还是不收敛,把DoStep的初始步长从0.01改到0.001,用更小的电压步进跨过不收敛点。

5.3 SDE脚本运行报“unbound identifier”

现象:SDE启动加载脚本后,立刻报unbound identifier: xxx。

原因:这个报错几乎都是因为变量名或函数名拼写错误,或者使用了未定义变量。docx里的语句经过多次复制粘贴,函数名的某个字母大小写被改了就出现这种问题。我在一次排查中发现sdedr:define-refinement-window被写成了sdedr:define-refinement-windos,这种错位在视觉上很难发现。

解决:永远不要手动重敲SDE内置函数名,直接从官方示例或已验证脚本里复制。如果非要从docx里手抄,抄完做一次全文件搜索,核对每个sdedr:和sdegeo:开头的函数名拼写。效率更高的办法是启用SDE的语法检查模式,让它在执行前用scheme_parser做一次完整解析,能提前发现未绑定标识符。

5.4 docx全角符号替换导致的“看不到”的报错

现象:语句完全是从docx复制的,语法检查也过了,但运行时总在某一行的某个位置报非法字符,报错行有时还不固定。

原因:Word的自动更正功能会把直引号换成弯引号,把分号换成全角分号。这些字符在文本编辑器里看起来和半角很像,但解析器不认,报错会指向下一行甚至文件末尾。

解决:写了一个批处理替换的表达式,每次从docx复制完语句,先跑一遍全角转半角。具体替换项包括:弯引号转直引号、全角分号转半角、全角括号转半角、全角空格转半角。做完之后再检查一遍运算符两侧有没有混入不可见字符。这个习惯帮我避免了几十次无效排查。

5.5 SProcess工艺语句与实际工艺参数不一致

现象:工艺仿真跑完,PN结深度和实测结果差了30%以上。怎么调扩散时间都不对。

原因:SProcess的扩散模型是完整的物理模型,扩散系数受温度、时间、气氛影响,但docx里的语句往往只摘了主体命令,漏掉了gas这种环境设置语句。950度干氧和湿氧的氧化速率差很多,没有gas语句,SProcess默认按初始环境算,结果自然对不上。

解决:在SProcess脚本里显式写清每一步的环境。比如扩散前加一条:

gas flow rate=5.0 species="O2"

并且确认氧化模型选择了正确的类型。另外,工艺仿真一定要做校准:用一条已知的实测结果反推模型参数,再拿去预测新结构。我一般会用模拟项目X的实测数据先校准一套参数,再跑批量工艺条件,而不是直接拿官方默认参数硬算到底。

6. 把各种语句整理成可复用模板:一个验证与归档习惯

前面几章都在怎么跑通别人的语句,最后一章说说怎么把你手里的docx变成自己的东西。我最早接触Sentaurus时,也是攒了一堆从各处摘来的语句片段,用到哪条查哪条,结果就是同一个参数在不同脚本里写法不统一,光是调试格式就耗掉不少时间。后来我换了一种整理思路,把“各种语句”按模块和用途拆成模板段,每个模板段都带着验证记录,效果很好。

具体做法分三步。第一步,按SDE、SProcess、SDevice三个模块建立三个主文件,文件里不堆完整脚本,只放可复用的语句片段。SDE的模板按“几何创建”“材料定义”“掺杂定义”“网格控制”分节,SDevice的模板按“File段”“Electrode段”“Physics段”“Math段”“Solve段”分节。每个片段方都留了参数占位符,比如P_Profile浓度写成1e18但标注“按器件耐压调整”,这样下次做新器件时直接替换占位符。

第二步处理的是“能不能跑”的问题。每段模板背后都要有一个最小验证用例,可以是一维PN结,也可以是简单MOS结构,跑通之后把SDE的网格文件和SDevice的输出曲线打包存档。以后想用某条新语句,编译器提示语法错误时,我直接打开这组存档对照差异,很容易看出新语句缺了什么前置条件。

第三步是定期整理报错记录。我在模板文件的末尾建了一张表,列出遇到过的报错信息、对应原因和当时怎么改的。这相当于给自己建了一个小型知识库,下次报错时先搜索这张表,而不是从头翻手册。

用这套方法之后,我基本告别了对着一堆docx里零散语句发呆的状态。语句本身不神秘,它只是工具的语法接口,真正的功夫在于把每条语句放进合适的上下文里,并且用一套可重复的流程验证它的效果。我现在接手一个新结构仿真,从模板库拖出对应的语句块,改完尺寸和掺杂就跑验证,顺利的话整个链路半小时就能通。这个习惯建议你也试试,第一次整理会花点时间,但之后每次写脚本都在省时间。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进