Appearance
SWB 第 6 章:预处理项目
来源:
swb_ug.pdf第 6 章(W-2024.09) 说明:本页按 W-2024.09 的章节顺序归位,正文基于现有预处理章节稿件整理,并继续对照 2024 版细化。
本章目录
项目参数化简介
Sentaurus Workbench 的一个重要特性是支持项目参数化。参数化项目由一组实验组成,其中某些敏感的输入变量取不同的值。参数化项目表示为称为 gtree 的树结构。
在项目中,你需要为每个工具提供工具数据库中定义的输入文件模板集。可以使用 Sentaurus Workbench 的预处理器语言来表达模板中的变量。预处理器语言结构包括:
- 预处理器
#-commands(参见预处理器 #-Commands) @-引用(参见@-引用与树形导航)
为了区分 gtree 中的节点并考虑已计算的结果,Sentaurus Workbench 的预处理器(spp 工具)在运行时自动生成实际的输入文件。动态预处理允许仿真依赖于其他仿真的结果,即节点的行为可以随其他节点提取的变量值变化。
全局预处理与运行时预处理
注意:锁定节点不会被预处理。
预处理分为两个阶段执行:
全局项目级预处理阶段,在项目执行之前执行。此阶段不创建真实的输入文件(pp*),而是扫描工具的用户输入模板,提取作业相互依赖关系,生成项目执行图(gexec.cmd 文件),查找
#set和#seth命令,并将变量值插入项目变量文件(gvars.dat)。此外,全局预处理可以应用于表达式、节点和场景(参见节点表达式)。第二阶段是在启动作业之前生成作业输入文件。所有预处理器命令和
@-引用都在此时解析和替换。变量引用被替换为最近提取的值;如果没有提取值,则替换为最近#set命令指定的值。最后,提取所有预处理器 Tcl 块,进行求值,并用 Tcl 求值结果(标准输出)进行替换。
仅执行第一阶段的命令:
bash
spp PROJECT对整个项目执行两个阶段(创建执行图和变量文件,并生成所有 pp* 输入文件):
bash
spp -input PROJECT注意:在全局预处理阶段,变量引用被替换为 #set 或 #seth 的值,而不是提取值。
gsub 工具会在需要时自动执行第一阶段预处理(如果自上次全局预处理以来有任何输入文件被修改),然后再提交作业。
gjob 工具在作业执行前自动执行第二阶段预处理,除非项目处于 Editable 运行时编辑模式或明确指定了 -nopp 命令行选项。
预处理器 #-Commands
#-commands 向 Sentaurus Workbench 预处理器(spp 工具)发出指令。当简单的 @-引用 不足以修改工具行为时使用这些命令。例如,条件命令指示 spp 为不同节点(或节点组)创建输入文件的不同部分。条件通常引用参数,如下例所示(来自 Sentaurus Device 的输入文件片段):
tcl
#if @WithHydro@ == 1
coupled { Poisson Electron Hole eTemperature }
#else
coupled { Poisson Electron Hole }
#endif以下示例展示了一个模板,其中包含偶数节点索引和奇数节点索引的两个部分:
tcl
#if @node:index@ % 2 == 0
# section for even node indices
#else
# section for odd node indices
#endif以下示例展示如何测试下一个或上一个工具:
tcl
#if "@tool_label|+1@" == "shell2"
next tool is shell2
#else
next tool is something else
#endif有关 Sentaurus Workbench 所有可用 #-commands 的列表,请参见第 314 页的 #-Commands。
@-引用与树形导航
由于 Sentaurus Workbench 必须控制仿真树中所有工具的输入和输出文件,并确定作业相互依赖关系,文件名只能作为文件引用出现在输入文件中。
不要使用绝对的、硬编码的文件名。应使用节点引用代替硬编码的节点键。在运行时,Sentaurus Workbench 预处理器将文件引用和节点引用替换为相应的文件名或节点键。
使用的约定和表示法如下:
- 每个节点由其键(称为 nkey)唯一标识。
- 节点键可以显示在 Project Editor 中。
- 工具输出文件名以
n<nkey>_<acronym>为前缀,其中<acronym>是标识特定工具的三字符字符串。 - 某个树级别上的节点集代表该工具在该级别的所有出现。
这些节点从 1 到 n 索引,其中 1 表示最左边的节点,n 是该树级别最右边的节点。节点索引是节点在其树级别中的绝对位置。
@-引用 可以是参数、变量、表达式或包含在一对 @ 符号之间的命令。预处理器对包含的内容进行求值和替换。简单的 Sentaurus Workbench 引用通常指向当前节点(@node@)。
导航运算符可用于将引用从当前节点移动到仿真树中的另一个节点。相对导航可以沿当前节点的上、下、左、右各个方向进行,也可以使用绝对索引。
为说明文件引用的使用,典型的 Sentaurus Device 文件片段如下:
tcl
File {
Grid = "@tdr@"
Plot = "@tdrdat@"
Current = "@plot@"
Output = "@log@"
}注意:出于历史原因,关键字 Plot 在 Sentaurus Device 和 Sentaurus Workbench 中的含义不同。在 Sentaurus Device 中,Plot 指计算域上的基本量和派生量的图。在 Sentaurus Workbench 中,Plot 指 IV 曲线。
@-表达式
Sentaurus Workbench 支持两种在预处理期间求值的 @-表达式 类型:@[...]@ 和 @<...>@。这两种类型的 @-表达式 可以任意嵌套。例如:
@< ... @[...]@ ...>@
@[ ... @<... @[...]@ ...>@ ...]@以下表达式是等价的:
@< @HaloDose@ + 1e-14 >@
@[ expr {@HaloDose@ + 1e-14} ]@结合 #-commands,@-表达式 可以使命令文件更加灵活。
表达式 @[...]@
当预处理器找到 @[...]@ 类型的表达式时,它从括号中提取表达式并在 Tcl 解释器中求值,如下所示:
bash
% eval <expression>例如,表达式:
@[string compare @HaloDose@ 1e-14]@处理步骤如下:
@HaloDose@被替换为当前节点的相应 Sentaurus Workbench 值。- 以下命令在 Tcl 解释器中求值:
bash
% eval string compare <HaloDoseValue> 1e-14Sentaurus Workbench 将 @[...]@ 表达式视为任意 Tcl 命令。因此,在 @[...]@ 表达式内部引用 Sentaurus Workbench 参数和变量时,必须用 @-字符 将其括起来。这指示 Sentaurus Workbench 将此类引用替换为当前节点的相应值。否则,Sentaurus Workbench 会将此类引用视为 Tcl 字符串值,从而导致预处理结果不正确或出错。
例如,以下表达式始终替换为 0,因为字符串 "HaloDose" 和 "1e-14" 不等价:
@[string compare HaloDose 1e-14]@以下表达式会产生预处理错误,因为 Tcl 命令 expr 无法处理非数值参数:
@[expr HaloDose + 1e-14]@表达式 @<...>@
当预处理器找到 @<...>@ 类型的表达式时,它从尖括号中提取表达式并在 Tcl 解释器中求值,如下所示:
bash
% eval expr { <expression> }例如,表达式:
@< @HaloDose@ + 1e-14 >@处理步骤如下:
@HaloDose@被替换为当前节点的相应 Sentaurus Workbench 值。- 以下命令在 Tcl 解释器中求值:
bash
% eval expr {<HaloDoseValue> + 1e-14}与 @[...]@ 表达式不同,Sentaurus Workbench 允许你在 @<...>@ 表达式内部使用引用参数和变量,而不必用 @-字符 将它们括起来。以下表达式是等价的:
@< @HaloDose@ + 1e-14 >@
@< HaloDose + 1e-14 >@注意:如果变量或参数在父项目中定义,则应用 @-字符 将其括起来。如果变量名或参数名与使用 #define 命令指定的宏定义冲突,也应用 @-字符 将其括起来。
重定义分隔符
如 @-引用与树形导航 中所述,预处理器将 @ 符号识别为参数、变量、表达式或命令的分隔符。同时,某些集成到 Sentaurus Workbench 中的工具的输入语言语法允许在语言特定结构内部使用 @ 符号,例如 Taurus TSUPREM-4 的内部变量。
为避免预处理期间出现问题,输入文件中所有此类字符表达式必须用 #verbatim 关键字保护。但是,这会使输入文件充满预处理器命令和指令,难以阅读。当 @...@ 预处理引用与 @... 语言结构出现在同一行时,可能会出现其他预处理问题。
为避免此类问题,可以通过设置特定工具数据库指令来重定义工具的默认分隔符符号。例如:
tcl
set WB_tool(<tool_name>,substitution_delimiter) <delimiter>其中 <tool_name> 是工具名称。分隔符可以是单个字符或字符组合(不允许使用空格)。
@ 符号仍然是其他工具输入文件的合法分隔符。重定义的分隔符对所有涉及预处理的工具相关文件生效。同时,只能使用标准 @-分隔符 指定工具数据库中的工具特定设置、开场白和收场白脚本,以及变量提取命令。
预处理节点
在预处理项目时,可以使用节点过滤器和节点表达式。
节点过滤器
节点过滤器是 Tcl 表达式,对仿真树中任何现有节点求值为真(!=0)或假(0)。过滤器的语法为:
filter: "{" EXPR "}"EXPR 是求值为数字的 Tcl 表达式,可以使用 $NAME 表示法引用当前树中存在的参数或变量。例如,以下表达式在参数 P2 的值等于 3 且变量 V1 的值大于 2 的节点上求值为真:
tcl
{ $P2 == 3 && $V1 > 2 }引用未定义参数或变量的节点会被拒绝(求值为假)。换句话说,前面的表达式等价于:
tcl
{ ([info exists P2] && $P2 == 3) && ([info exists V1] && $V1 > 2) }此外,EXPR 识别预定义函数 min(NAME) 和 max(NAME)。以下示例在参数 P2 的值等于 P2 最小值的节点上求值为真:
tcl
{ $P2 == min(P2) }节点表达式
Sentaurus Workbench 提供表达式(缩写为 gexpr)来选择仿真树中的节点。节点表达式 gexpr 返回节点键列表,特别用于 Scheduler 中提交节点执行。节点表达式的语法请参见第 317 页的节点表达式。以下示例返回属于场景 sc1 和 sc2 且参数 P1 等于 1 的叶节点:
"sc1|last:{$P1 == 1} * sc2|last:{$P1 == 1}"示例
将节点表达式与节点过滤器结合使用是工具输入命令文件中脚本编写的强大工具。
以下预处理器表达式解析为 Sentaurus Structure Editor 工具(sde)中参数 Type 取值为 nMOS 的节点列表:
@node|sde:{$Type == "nMOS"}@在以下示例中,预处理器表达式解析为工具 sde 中参数 Type 取值为 nMOS 且参数 lgate 的值小于 0.050 的节点列表:
@node|sde:{$Type == "nMOS" && $lgate < 0.050}@要获取参数 SiC 取值为 0 的实验中参数 wmesa 的所有值:
@wmesa:{$SiC==0}@要获取参数 SiC 取当前节点定义值的实验中参数 wmesa 的所有值:
@wmesa:{$SiC==@<SiC>@}@分割点
参数在工具步骤的右侧引入仿真树的新级别。从树的角度看,参数将整体工具仿真阶段分为两个子阶段。但这仅仅是抽象视图,因为每个工具实例通常在一轮运行中从头到尾执行整个仿真阶段。
因此,相同的第一个子阶段(或多个子阶段)会被不必要地多次执行。这仅适用于其命令文件定义线性控制流(即从头到尾顺序执行命令的流)的工具。这些工具称为线性工具。典型的过程仿真工具是线性工具。
Sentaurus Workbench 提供分割功能,使线性工具能够保存和恢复状态;树中的每个中间分支只能执行一次。此功能可以节省大量计算时间,特别是对于具有多个阶段的长时间运行作业。
只有当 Save 和 Load 命令在工具数据库中定义时,工具才能被分割。例如,Sentaurus Process 在标准工具数据库中有以下两行:
tcl
set WB_tool(sprocess,split,save_cmd) "struct tdr=n@node@"
set WB_tool(sprocess,split,load_cmd) "init tdr=n@previous@"注意:为确保 Sentaurus Workbench 显示中间节点的真实状态,请确认是否选中了 View > Tree Options > Check Virtual Nodes(参见节点)。
预处理变量
与参数一样,变量保存一个值,可以在任何形式的 @-引用 中引用。主要区别在于变量不会在仿真流中创建分割,因此不会改变仿真树的形状。
#set 命令定义一个预处理变量并为其分配值:
#set <varname> <value>#seth 命令与 #set 命令相同,只是该变量在 Sentaurus Workbench 的 Variable Values 视图中被隐藏:
#seth <varname> <value>定义的变量可以通过其名称在任何 @-引用 表示法中引用。变量引用从执行引用的节点创建到设置该变量的第一个祖先节点的执行依赖关系。变量的作用域与参数类似,即从带有第一个 #set 或 #seth 指令的节点到其所有后代。
可以通过以下方式重新分配变量:
- 使用另一个
#set或#seth指令,即用另一个预处理值覆盖它。 - 执行提取,即用提取值覆盖它(参见提取变量)。
所有变量都显示在 Family Tree 中。
#set 和 #seth 命令的典型用法是定义绑定到参数的变量集,例如记录的字段:
tcl
#if @PARAM@ == 1
#set PARAM_V1 1.5
#seth PARAM_V2 2.5
#elif @PARAM@ == 2
#set PARAM_V1 11.5
#seth PARAM_V2 12.5
#endif此结构避免了两个虚拟参数的声明,减少了整体项目树的大小。
注意:为提高预处理性能,请勿在 #set 和 #seth 命令的变量值中使用 Tcl 注释和 Tcl 括号。将注释隔离在单独的行中,并使用 @<...>@ 或 @[...]@ 预处理指令代替。例如:
tcl
#set nez 1 # Number of vertices along z-length可以替换为:
tcl
# Number of vertices along z-length
#set nez 1以及:
tcl
#set NeVert [expr @nex@*@ney@*@nez@]可以替换为:
tcl
#set NeVert @< @nex@*@ney@*@nez@ >@提取变量
变量的另一个常见用途是从工具输出文件中提取值,并在下一个工具输入文件中引用它。
值从节点输出文件中提取。节点成功执行后,其输出文件被解析,查找与以下掩码匹配的字符串:
DOE: <varname> <value>然后,将找到的值写入 gvars.dat 文件。如果指定变量已存在,提取的值将覆盖现有值。如果指定变量不存在(即未全局定义或未使用 #set 或 #seth 命令定义),则会创建一个新变量。之后,可以使用标准预处理器 @-引用 在任何后续工具输入文件中引用提取的变量。
通知 Sentaurus Workbench 在仿真期间必须提取值并将其分配给某个变量的唯一方法是在节点输出文件中提供 DOE: <varname> <value> 字符串。通常,它应该打印在工具命令文件中。相应的命令严格依赖于工具及其命令语法。例如,对于 Sentaurus Process,它可能是一个简单的 Tcl 命令:
tcl
puts "DOE: ENERGY 120.56"在 Inspect 命令文件中,可以使用预定义的 ft_scalar 函数将值导出到 Family Tree:
tcl
ft_scalar <varname> <value>此函数将 DOE 提取掩码打印到节点输出文件,就像你使用 puts Tcl 命令手动执行一样。
提取值和预处理值是分开的。提取值在仿真运行阶段可用,预处理值在预处理阶段就已知道。
注意:使用提取变量时的一个常见错误原因是相应变量在预处理期间不存在。在这种情况下,如果其他工具的输入文件中存在对此变量的任何引用,项目的预处理可能会失败。为避免此错误,请全局声明变量或使用 #set 预处理命令。如果你想在 Sentaurus Workbench 的 Variable Values 视图中隐藏变量,可以使用 #seth 预处理命令。
以下示例演示如何从仿真步骤中提取值并在后续仿真步骤中访问它们:
- 在执行提取的工具中,必须为提取的变量分配任意默认值:
tcl
#set EXTRACTED_VAR 0此命令也可以在任何现有前置工具中指定。
- 在执行提取的工具中,打印命令必须在工具命令文件中指定。对于 Sentaurus Process 的情况,可能是以下之一:
tcl
puts "DOE: ENERGY 120.56"
puts "DOE: ENERGY @ENERGY_2@"其中 ENERGY_2 是另一个变量。
- 变量
EXTRACTED_VAR可以使用标准预处理器@-引用和#-commands在任何后续工具输入文件中引用。例如:
tcl
@EXTRACTED_VAR@
@< @EXTRACTED_VAR:+1@ / 2 >@
#if @EXTRACTED_VAR@ > 1.5e15
...
#endif注意:提取变量仅对在工具数据库中定义了提取算法的工具有效。例如,全局工具数据库为 Sentaurus Process 这样定义:
tcl
set WB_tool(sprocess,epilogue) { extract_vars "$nodedir" @stdout@ @node@; ... }其中 extract_vars 函数也在全局工具数据库中定义。此定义意味着每个执行节点的值将基于 DoE 中指定的模式从输出文件中提取。在全局工具数据库中,此提取算法已为所有支持的仿真工具和实用程序定义。要允许你自己的工具支持提取变量,必须在用户或项目工具数据库中指定相应的定义。也可以定义用户特定的提取算法来在 Family Tree 步骤之间提取值。
执行依赖关系
在预处理期间,以以下方式分析文件中的所有依赖关系。如果在任何命令文件或参数化输入文件中存在带可能方向后缀的文件引用 @file_type@(有关 @-引用 和树形导航的信息,请参见第 308 页的附录 A),则执行依赖于所指节点的成功完成。
注意:@node@ 引用不会创建任何依赖关系,也不存在隐式的子到父依赖关系。
可以使用 #setdep 命令强制创建依赖关系。例如,以下命令在当前级别之前创建一个屏障,即当前级别的任何节点在上一级别的所有节点成功完成之前都不能开始执行:
tcl
#setdep @node|-1:all@Sentaurus Workbench 预处理器(spp)检查循环引用并在发现时失败。可以通过扩展到先决节点来查看依赖关系(参见查看节点依赖关系)。可以使用 #remdep 命令显式移除依赖关系。例如:
tcl
#remdep @node|+1@注意:虽然引用 @previous@ 等效于 @node|-1@,但区别在于 @previous@ 创建依赖关系,而 @node|-1@ 不会。
设置与取消依赖关系
设置或取消依赖关系的顺序很重要。如果依赖关系稍后在同一输入文件中被隐式或显式重置,则取消依赖关系没有任何效果。因此,输入文件开头的 #remdep 命令没有任何效果。此命令通常出现在输入文件的末尾。
Tcl 命令块
Tcl 命令块的原始动机是将 Tcl 的强大功能引入某些集成到 Sentaurus Workbench 中的工具(如 Sentaurus Device)所使用的复杂语言中。但是,由于这些工具都支持 Tcl 和 Python,Tcl 命令块不再需要。
注意:Tcl 命令块对项目预处理和执行性能产生负面影响。请勿在新 Sentaurus Workbench 项目中使用 Tcl 命令块。
从现有 Sentaurus Workbench 项目中移除 Tcl 命令块可以获得显著的预处理器性能提升。一些 Tcl 块可以轻松地用常规预处理器指令(如 @[...]@)替换。其他 Tcl 块的逻辑可能在仿真工具的原生语言中有等效实现,例如 Sentaurus Structure Editor(Scheme)、Sentaurus Process(Tcl、Python)、Sentaurus Device Tcl 模式(Tcl)和 Sentaurus Device Python 模式(Python)。如需要帮助从 Tcl 命令块迁移,请联系当地的 TCAD 支持团队。
从仿真流程中移除 Tcl 命令块可以实现 5~10 倍的速度提升,预处理速度提升更为显著。要移除 Tcl 命令块,请使用 Sentaurus Workbench "原生" 预处理器语法或你有权访问的仿真工具的原生逻辑流控制。例如,可以使用 Sentaurus Structure Editor(Scheme)、Sentaurus Process(Tcl、Python)、Sentaurus Device Tcl 模式(Tcl)和 Sentaurus Device Python 模式(Python)。
如果你仍然需要使用 Tcl 命令块,请参阅第 359 页的附录 H。
Sentaurus™ Workbench User Guide W-2024.09 第 6 章