• Synopsys Sentaurus TCAD系列教程之-Tcl《3》


    Tool command language(Tcl)

    3. 其它有用的Tcl命令

    TCAD Sentaurus工具引入更高级的Tcl命令

    3.1文件输入和输出

    • 使用open函数打开文件:

      set FIDw [open Writing.tmp "w"]

      这里以写的方式打开文件Writing.tmp。FIDw是一个常规的Tcl变量,它包含文件标识符。

    • 使用put 命令写入打开的文件:

       puts $FIDw "This is the first line of this file"
       puts $FIDw $ABCList
    
    • 1
    • 2
    • 使用close命令关闭文件:
        close $FIDw
    
    • 1
    • 以读的方式打开文件
        set FIDr [open Writing.tmp "r"]
    
    • 1
    • gets命令逐行读取文件
    	while { [gets $FIDr NewLine] > 0 } {                       #NewLine是固定必须的关键词?
    	  	puts $NewLine
    	  }
    	  close $FIDr
    	  #-> This is the first line of this file
    	  #-> a b c d e f
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这里,while循环检测文件的结尾。gets命令返回读取的字节数。如果gets到达文件末尾,它将返回-1.while循环将测试此条件。

    • 使用read命令将文件作为单个数据块读取
    	 set FIDr [open Writing.tmp "r"]
    	 set DATA [read $FIDr]
    	 puts $DATA
    	 close $FIDr
    	 #-> This is the first line of this file
    	 #-> a b c d e f
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    包含特殊Tcl字符的文件通常无法逐行读取。read命令没有这些问题。

    3.2 格式化输出

    使用格式函数控制打印期间变量的格式:

    set pi [ expr 2.0*asin(1.0) ]
    puts "pi unformated :$pi"
    #-> pi unformated: 3.141592
    
    puts "pi with 2 digits :[format %.2f $pi]"
    #-> pi with 2 digits : 3.14
    
    puts "pi in exponential format: [format %.4e $pi]"
    #-> pi in exponential format: 3.1416e+00
    
    set i 24
    puts "Integer with leading zeros: >[format %05d $i]<"
    #-> Integer with leading zeros: >00024<
    
    puts "Integer with leading blanks: >[format %5d $i]<"
    #-> Integer with leading zeros: >   24<
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.3 程序

    自定义一个计算Arrthenius law的程序。A=A0exp(-E/KT),其中 A0是指前因子(频率因子),E是活化能。温度由全局变量T给出。

    proc Arrhenius {A0 E} {
    	global T
    	set k 8.62e-5; # eV/K
    	set A [expr $A0*exp(-$E/($k*$T))]
    	return $A
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    可以在Tcl脚本的任何位置定义过程。但是,只有在定义过程之后才能调用该过程。

    set T 300
    set A [Arrhenius 1e5 1.0]
    puts "The Arrhenius expression given: [format %.4e $A]"
    #-> The Arrhenius expression given: 1.6067e-12
    
    • 1
    • 2
    • 3
    • 4

    3.4 屏蔽特殊字符、替换

    美元符号$、括号[]和大括号{}是Tcl中的特殊字符。例如,如果在字符串中使用这些字符,则必须对它们进行掩码,也就是说,它们前面必须有反斜杠()

    set T 400.0
    set CMD_Static "[Arrhenius 1e5 1.0]"
    puts [format "\[Arrhenius 1e5 1.0\] gives %.4e" $CMD_Static]
    #-> [Arrhenius 1e5 1.0] gives 2.5378e-08
    
    set T 1100.0
    puts [format "\[Arrhenius 1e5 1.0\] gives %.4e" $CMD_Static]
    #-> [Arrhenius 1e5 1.0] gives 2.5378e-08
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意,变量CMD_Static包含Arrhenius表达式的值,在定义变量时计算。后面的温度变化对此没有影响。

    CME_Static和CMD_Dynamic是关键字??

    还有,使用\屏蔽函数调用仅在使用expr命令调用时计算函数Arrhenius

    set T 400.0
    set CMD_Dynamic "\[Arrhenius 1e5 1.0\]"
    puts $CMD_Dynamic
    #-> [Arrhenius 1e5 1.0]
    puts [format  %.4e  [expr $CMD_Dynamic]]
    #-> 2.5378e-08
    
    set T 1100.0
    puts [format  %.4e  [expr $CMD_Dynamic]]
    #-> 2.6291e-08
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.5 文件和目录

    • 使用glob函数获取与特定模式匹配的所有文件名的列表:

      set FIDw [open Tmp_1.tmp "w"] 
      puts $FIDw "test"
      close $FIDw
      
      set FIDw [open TMP_2.tmp "w"] 
      puts $FIDw "test" 
      close $FIDw
      
      set FIELS [glob "TMP"] 
      puts "$FILES"
      #-> TMP_1.tmp TMP_2.tmp 
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      这里创建了两个文件TMP_1.TMP和TMP_2.TMP. 然后,创建当前工作目录中以TMP开头的所有文件的列表。

    • 使用file函数分隔文件名和扩展名

          set FILE [lindex $FILES 0]
          set STEM [file rootname $FILE]
          puts "The rootname is : $STEM"
          #-> The rootname is :TMP_1
          set EXT [file extension $FILE]
          puts "The extension is :$EXT"
          #-> The extension is : .tmp
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 使用pwd命令访问当前工作目录的名称:

      set CWD [pwd]
      puts $CWD
      
      • 1
      • 2
    • 使用file函数分隔路径和目录:

      set PATH [file dirname $CWD]
      puts "Path is : $PATH"
      set DIR [file tail $CWD]
      puts "Directory is $DIR"
      
      • 1
      • 2
      • 3
      • 4

    3.6 系统调用

    • 使用exec命令发出系统调用

        exec rm -f Writing.tmp
      
      • 1

      这里从Tcl内调用UNIX命令rm -f

    • 使用eval命令进行包含Tcl变量的系统调用

      set FILE source.tcl
        eval exec rm -f $FILE
      
      • 1
      • 2

      eval 命令强制展开所有Tcl变量和表达式

    • 返回数据的系统调用

      set ls_output [exec ls]
      puts "The output of the ls command is:"
      puts $ls_output
      
      • 1
      • 2
      • 3

    3.7 处理错误

    如果发生错误,Tcl将终止脚本的执行。使用catch命令抑制终止:

    set Nom 0.0
    set Denom 10.0
    if {  [catch { set result [expr  $Denom/$Nom] } Errcode] != 0} 
    {
    	puts "An Error occured.The Error code is >$Errcode< "
    	
    } else {
    	puts "$Denom/$Nom = $result"
    }
    #-> An error occured.The Error code is >divide by zero<
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    有意的操作是set result [expr $Denom/$Nom],如果此操作失败,catch将抑制脚本的终止,将错误代码分配给变量ErrCode,并返回一个非零值。

    3.8 字符操作

    举例,假如要处理一个字符串,该字符串包含有关简单结构描述的信息,包括材料名称、区域名称和几何对象(注意,双引号、大括号和方括号必须用反斜杠屏蔽,因为它们在Tcl中具有特定的含义)

    set STRING "Silicon \"substrate\" \{ rectangle \[(0.0, -0.5) (1.0, 0.5)\] \}"
    
    • 1
    • 使用字符串函数隔离材质和区域名称

      set itmp  [expr [string first " " $STRING]}
      set MATERIAL [string range $STRING 0 [expr $itmp -1]]
      set istart [ expr [string first "\"“ $STRING]]
      set iend [ expr [string last "\"” $STRING]]
      set REGION  [string range $STRING [expr $istart +1 ] [expr $iend -1]]
      
      puts "The material is : $MATERIAL"
      #-> The material is : Silicon
      puts "The region name is :$Region"
      #-> The region name is:substrate
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      函数string first和string last 分别返回给定模式的第一次或最后一次出现的索引,这里是空白或双引号。函数字符串范围返回一个子字符串,它在给定的索引处开始和结束。
      坐标X0、Y0、X1和Y1可以以类似的方式提取:

      set istart    [expr  [string first "(" $STRING]]
      set iend     [expr  [string first "," $STRING]]
      set X0        [string range $STRING [expr $istart+1]  [expr $iend -1]]
      
      set istart    [expr  [string first "," $STRING]]
      set iend     [expr  [string first ")" $STRING]]
      set Y0        [string range $STRING [expr $istart+1]  [expr $iend -1]]
      
      set istart    [expr  [string last "(" $STRING]]
      set iend     [expr  [string last "," $STRING]]
      set X1        [string range $STRING [expr $istart+1]  [expr $iend -1]]
      
      set istart    [expr  [string last "," $STRING]]
      set iend     [expr  [string last ")" $STRING]]
      set Y1        [string range $STRING [expr $istart+1]  [expr $iend -1]]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    • 连接两个字符串:

      set NewString  ${MATERIAL}_${REGION}
      puts $NewString
      #-> Silicon_substrate
      
      • 1
      • 2
      • 3
    • 使用append函数将文本附加到字符串:

      set  Text "$NewString extends from"
      append Text "X=$X0 to $X1 "
      append Text "and from"
      append Text "Y= $Y0 to $Y1."
      puts $Text
      #->Silicon_substrate extends from X=0.0 to 1.0 and from Y = -0.5 to 0.5
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 比较字符串(词典编纂)与字符串比较

      set NAME1 "Eva"
      set NAME2 "Adam"
      if { [string compare $NAME1 $NAME2] == 0} {
      	puts "Both names are the same"
      } elseif { [string compare $NAME1 $NAME2] <0 } {
      	puts "$NAME1 comes before $NAME2"
      } elseif { [string compare $NAME1 $NAME2] >0} {
      	puts "$NAME2 comes before $NAME1"
      }
      #-> Adam comes before Eva
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 提取字符串匹配的子模式

      set DEV "HV NMOStransistor"
      if { [string match "*NMOS*" $DEV]} {
      	puts "This device is an NMOS"
      } else {
      	puts "This device is NOT an NMOS"
      }
      #-> This device is an NMOS
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    • 用regsub替换字符串中的模式

      set OLDString "HV NMOStransistor"
      set OLDPattern "NMOS"
      set NEWPattern "PFET"
      set NEWString [regsub $OLDPattern $OLDString $NEWPattern]
      puts "NEWString:$NEWString"
      #-> NEW String: HV PFETransistor
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 将字符串转换为列表:
      Tcl允许将字符串重新解释为列表,只要条目用空格分隔即可

      set string "1 2 3 4"
      set SUM 0
      foreach Number $String {
      	set SUM [expr $SUM+$Number ]
      }
      puts $SUM
      #->10
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      如果条目由不同的符号(如逗号分隔值(CSV)分隔,请使用split命令:

      set String "1,2,3,4"
      set List [split $String ","]
      set SUM 0
      foreach Number $List{
      	set SUM [expr $SUM+$Number]
      }
      puts $SUM
      #->10
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
  • 相关阅读:
    VTK-vtkImplicitFunction及其子类介绍
    STM32存储左右互搏 QSPI总线FATS文件读写FLASH W25QXX
    思辨:移动开发的未来在哪?
    使用jQuery获取不同元素的ID
    刷了一个月leetcode算法,成功收下阿里巴巴、网易等大厂的offer
    mojo初体验
    数据结构与算法课后题-第六章(图的存储及基本操作)
    配置https接口
    Java项目——博客系统(前后端交互)
    SpringCloud Alibaba核心组件Nacos【服务多级存储模型&配置集群】第2章
  • 原文地址:https://blog.csdn.net/weixin_42104289/article/details/128013775