当前位置:   article > 正文

TCL脚本语言学习

tcl脚本


前言

2022.11.21 开始学习TCL语言
2023.3.21 更新


TCLTool Command Language)命令的格式是命令+字符串,第一个是命令,后面都是字符串,tcl的解释器逐行执行)会根据命令去对后面的字符串进行相关操作。
注释符号:#

一、安装

启动tcl命令行,以%开头

sudo apt install tcl   //安装tcl
tclsh     //启动tcl
%  
  • 1
  • 2
  • 3

二、变量列表

1、置换subtitution

(1)变量置换$:把 $ 后面的变量置换成对应的值

set a 2
puts $a  //输出2

set b $a+100   //b=2+100,并不是102,2+100只是个字符串
  • 1
  • 2
  • 3
  • 4

(2)命令置换[]:[ ]内是独立的TCL指令
tcl解释器会把[ ]里面的内容看作是命令去执行,执行完之后的102,去给变量b,102仍然是个字符串

set b [expr $a+100]  //必须要加[]
set a [expr 3+3] //6
expr 5/2 //2
expr 5.0/2 //2.5
expr 5/2.0 //2.5
  • 1
  • 2
  • 3
  • 4
  • 5

(3)反斜杠置换\
\t:制表符
\n:换行

第一种写法会报错,解释器会识别到set给a的字符串有两个
第二种写法解释器会把中间的空格当作分隔符,hello world会被看成一个单词
第三种是可以的

set a hello world
set a hello\ world
set a {hello world}
  • 1
  • 2
  • 3

(4)双引号和花括号
" ":对$[]分别进行变量置换和命令置换,对各种分隔符不做处理,如空格等

set y "$a add"  //y=2 add
set a 2
set y 0.5
puts "[expr $x+$y]"   //2.5
puts "\[expr $x+$y\]"  //[expr 2+0.5]
puts "\[expr \$x+\$y\]"  //[expr $x+$y]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

{ }:所有字符都是普通字符

set a 2
set a.1 4
set b $a.1  //b=2.1
set b ${a.1}  //b=4
  • 1
  • 2
  • 3
  • 4

2、变量

设置:set 变量名 变量值
取值:puts $ 变量名

set a 2
puts $a
puts ${a}_1 //2_1
  • 1
  • 2
  • 3

3、数组

类似于SV中的关联数组,索引值可以是整型也可以是字符串
不可以单独声明一个数组,数组只能和数组元素一起声明
定义:set 数组名(元素名)值
取值:$数组名(元素名)

set day(monday) 1  
puts $day(monday)  //输出为1
  • 1
  • 2
array size cell_1  //3

array names cell_1
  • 1
  • 2
  • 3

4、列表

标量的有序集合 ,列表可以嵌套,里面元素可以是列表
定义:set 列表名 {元素1 元素2…}
取值:$列表名

list 1 2 {3 4}
set list1 {1 2 3}
puts $list1 //1 2 3
  • 1
  • 2
  • 3

只有lappend使用的时候不要加$符号

在这里插入图片描述

//TCL里面第一个总是命令
set list1 {1 2 3}
set list2 {4 5 6}

concat $list1 $list2

llength $list1  //3
llength [concat $list1 $list2]  //6

lindex $list1 1 //从0开始记数,输出为2
lindex $list1 [expr [llength $list1] - 1] //获取最后一个元素

lappend list1 4 //在末尾插入4
lappend list1 $list2  //1 2 3 {4 5 6}
lindex $list1 3 //4 5 6
lindex [lindex $list1 3] 0 //4

lsort $list1 //安装ASCII排序,由小到大
lsort -real $list1  //按照浮点数大小
lsort -unique $list1  //唯一化,删除重复元素
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

5、一些命令

unset:删除变量或数组元素
append:把文本添加到一个变量后面
incr:把一个变量加上整数,都必须是整数类型
expr:经常用,TCL支持常用的数学函数,凡是计算都要加上这个
eval:构造和执行tcl脚本的命令,可以接收多个参数,把这些参数用空格隔开然后创建一个脚本

unset a b
set txt hello
append txt "!how are you"  
incr b 3
  • 1
  • 2
  • 3
  • 4

三、控制流

1、if语句

if {cond1}{

}elseif{cond2}{

} else {

}

上面是if的格式,花括号要放在上一行(固定格式)

2、foreach

foreach 变量 列表 循环主题
按照顺序取列表里面的每一个变量

set list1 {1 2 3}
foreach i $list1{
	puts $i
}
  • 1
  • 2
  • 3
  • 4

3、break:直接结束循环

set list1 {3 2 1}
foreach i $list1{
	if{$i == 2}{
		break
		}
	puts $i
}  //最后只输出3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、continue:结束本次循环

set list1 {3 2 1}
foreach i $list1{
	if{$i == 2}{
		continue
		}
	puts $i
}  //最后输出3 1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5、while

while{cond1}{

}

只要条件满足就一直执行花括号里面的命令,不满足条件停止循环,while中断并返回一个空字符串

6、for循环

for 参数初始化 判断条件 重新初始化参数 循环主体
先判断语句符合,进入循环,重新初始化参数,再进行判断

for {set i 3}{$i>0}{incr i-1}{
	puts i
}  //输出3 2 1
  • 1
  • 2
  • 3

7、switch

switch option string{

}

option的选项默认是glob
-glob:匹配字符串
-regexpr:正则表达式的匹配方式
-exact:精确匹配

switch $x{
	b {incr t1}
	c {incr t2}
}
  • 1
  • 2
  • 3
  • 4

四、过程函数

1、proc自定义函数

proc 参数名 参数列表 函数主体
可以写return或者不写

proc add {a b} {
	set sun [expr $a + $b]
	return $sum
}
add 3 4 //输出为7
  • 1
  • 2
  • 3
  • 4
  • 5

2、全局变量和局部变量

全局变量:在所有过程之外定义的变量。
局部变量:对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除。
指令global:可以在过程内部引用全部变量

set a 4
proc sample {x}{
	global a
	incr a
	return [expr $a + $x]
}
sample 3 //输出为8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

五、正则表达式

正则表达式是一种特殊的字符串模式,用来去匹配符合规则的字符串
\w:匹配字母、数字、下划线
\d:匹配数字
\s:表示空格
. :表示任意一个字符
先写代表的字符,再写个数匹配

在这里插入图片描述

1、锚位^ $

在这里插入图片描述

2、正则匹配指令 regexp

在这里插入图片描述

regexp {^\d+.*\d+$} "1 dsg 1"  //匹配以数字开头数字结尾的字符串
//输出为1 表示匹配成功
  • 1
  • 2

3、( )捕获变量

% regexp {\s(\d+).*} "snow is 30 years old" total age
% puts $total
 30 years old
% puts $age
30

%  regexp {\d+} "snow is 30 years old" age  //直接匹配其中的数字
1
% puts $age
30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

六、文本处理

1、读写文件

open:open 文件 打开方式

  • r:读模式,默认方式
  • w:写模式
  • w+:读写,文件存在则清空内容,否则创建新文件
  • r+:读写,文件必须存在
  • a:只写,文件必须存在,指针指向文件尾
  • a+:读写,指针指向文件尾,文件不存在就创建

gets:gets fileId 变量名,gets读fileId标识的文件的下一行,并把该行赋给变量,并返回该行的字符数(文件尾返回-1)
close:close fileid

% set INPUTFILE [open file.txt r]   //以只读的方式打开文件
file3   //三个字符,里面每行分别是1 2 3 
% while {[gets $INPUTFILE line]>=0} {//读取文件,把每一行复制给line这个变量  
puts "$line"  //输出该变量,为什么要用引号?
}
1
2
3
% close $INPUTFILE  //关闭文件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
% set INPUTFILE [open file.txt w]  //以写的方式打开
file5   //这里输出的是获得的句柄值
% puts $INPUTFILE "123"  //写入的值完全覆盖之前的1 2 3
% close $INPUTFILE  //一定要记得关闭文件
  • 1
  • 2
  • 3
  • 4

2、glob和file

glob:查找当前目录下的文件,返回列表,进行模糊查找。再使用参数展开语法{*}把列表元素作为独立参数给其他指令
file:可以执行文件相关的一些操作

glob *.sv *.v
file delete {*}[glob *.sv *.v]  //分别删除sv和v文件
eval file delete [glob *.sv *.v]  //这种方式也可以,eval命令会把接收的参数用空格隔开
  • 1
  • 2
  • 3

例题

在这里插入图片描述
先把a = 1, b = 2,c = 3存到文件里面
把代码写到test.tcl文件里面,然后在source test.tcl
输出结果就是6!

set sum 0
set IN [open file.txt r]
while {[gets $IN line] >=0} {
        if { [regexp {^\w\s+=\s+(\d)} $line total num]} {
                set sum [expr $sum + $num]
        }
}
close $IN
puts $sum
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

七、Synopsys TCL语言

在这里插入图片描述

在这里插入图片描述

reference:ENCORDER、REGFILE、INV
instance:U1、U2、U3、U4

//这些是Synopsis TCL的指令
get_ports CLK  //找到CLK这个端口  输出为{CLK}
get_ports * //所有端口  {A B C D CLK OUT1[0] OUT1[1]}
get_ports C* //匹配C开头的端口

get_cell U4  //找到design
get_cell * 
get_cell U*
get_cells *3   //输出 {U3}

get_nets INV*
get_nets *

//查找design中有多少个net,两种方式
llength [get_object_name[get_nets *]]   //get_object_name把它转换为列表,再去获得列表的长度,这里用的TCL自身的语法
sizeof_collection [get_nets *]   //get_nets 得到的数据类型为集合collection,sizeof_collection为synopsis TCL指令,直接获得集合的大小

get_pins */Z //查看design当中有哪些pin的名字叫做Z {INV0/Z INV1/Z}
get_pins */Q* //查看design当中有哪些pin的名字以Q开头 {ENCODER/Q0 ....}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

1、对象:cell, net, port, pin

  • 任何一个属性都可以用get_attribute得到,
  • list_attribute –class * 可以得到所有object 的属性,
  • 部分属性可以用set_attribute来设置

1.1 Cell object
属性 ref_name : 用来保存其map到的reference cell名称

get_attribute [get_cells –h U3] ref_name  //输出 {INV}
  • 1

1.2 Pin object
属性 owner_net : 用来保存与之相连的net的名称

get_attribute [get_pins U2/A] owner_net  //输出 {BUS0}
  • 1

1.3 Port object
属性 direction : 用来保存port 的方向

get_attribute [get_ports A] direction  //输出 {in}
  • 1

1.4 Net object
属性 full_name : 用来保存net的名称

get_attribute [get_nets INV0] full_name  //输出为INV0
get_object_name [get_nets INV0] //输出为INV0

get_attribute INV0 full_name
Error: No attribute found
  • 1
  • 2
  • 3
  • 4
  • 5

2、有条件地查找对象

2.1 get_ * -f

get_ports * -f "direction == in"
{A B C D CLK}

get_pins * -f "direction == out"
{U1/Q0 U1/Q1 U2/Z U3/Z U4 REGFILE/Q[1] REGFILE/Q[0]}

get_cells * -f "ref_name == INV"
{U2 U3}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2.2 get_ -of

不同对象的连接关系:

  • port-net
  • net-port/pin
  • pin-net
  • cell-pin
get_nets -of [get_port A]   //A,单数和复数好像没有区别

get_net -of [get_pin U2/A]  //BUS0

get_pin -of [get_net INV1]  //U3/Z

get_pins -of [get_cell U4]  //{U4/D0 U4/D1 REGFILE/Q1 REGFILE/Q2}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3、总结

-filter:==相等 !=不相等 =~匹配 !~不匹配
-nocase:不区分大小写
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/187991
推荐阅读
相关标签
  

闽ICP备14008679号