赞
踩
2022.11.21 开始学习TCL语言
2023.3.21 更新
TCL(Tool Command Language
)命令的格式是命令+字符串
,第一个是命令,后面都是字符串,tcl的解释器(逐行执行
)会根据命令去对后面的字符串进行相关操作。
注释符号:#
启动tcl命令行,以%开头
sudo apt install tcl //安装tcl
tclsh //启动tcl
%
(1)变量置换$
:把 $ 后面的变量置换成对应的值
set a 2
puts $a //输出2
set b $a+100 //b=2+100,并不是102,2+100只是个字符串
(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
(3)反斜杠置换\
\t
:制表符
\n
:换行
第一种写法会报错,解释器会识别到set给a的字符串有两个
第二种写法解释器会把中间的空格当作分隔符,hello world会被看成一个单词
第三种是可以的
set a hello world
set a hello\ world
set a {hello world}
(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]
{ }
:所有字符都是普通字符
set a 2
set a.1 4
set b $a.1 //b=2.1
set b ${a.1} //b=4
设置:set
变量名 变量值
取值:puts
$ 变量名
set a 2
puts $a
puts ${a}_1 //2_1
类似于SV中的关联数组,索引值可以是整型也可以是字符串
不可以单独声明一个数组,数组只能和数组元素一起声明
定义:set 数组名(元素名)值
取值:$数组名(元素名)
set day(monday) 1
puts $day(monday) //输出为1
array size cell_1 //3
array names cell_1
标量的有序集合 ,列表可以嵌套,里面元素可以是列表
定义:set 列表名 {元素1 元素2…}
取值:$列表名
list 1 2 {3 4}
set list1 {1 2 3}
puts $list1 //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 //唯一化,删除重复元素
unset
:删除变量或数组元素
append
:把文本添加到一个变量后面
incr
:把一个变量加上整数,都必须是整数类型
expr
:经常用,TCL支持常用的数学函数,凡是计算都要加上这个
eval
:构造和执行tcl脚本的命令,可以接收多个参数,把这些参数用空格隔开然后创建一个脚本
unset a b
set txt hello
append txt "!how are you"
incr b 3
if {cond1}{
…
}elseif{cond2}{
…
} else {
…
}
上面是if的格式,花括号要放在上一行(固定格式)
foreach 变量 列表 循环主题
按照顺序取列表里面的每一个变量
set list1 {1 2 3}
foreach i $list1{
puts $i
}
set list1 {3 2 1}
foreach i $list1{
if{$i == 2}{
break
}
puts $i
} //最后只输出3
set list1 {3 2 1}
foreach i $list1{
if{$i == 2}{
continue
}
puts $i
} //最后输出3 1
while{cond1}{
…
}
只要条件满足就一直执行花括号里面的命令,不满足条件停止循环,while中断并返回一个空字符串
for 参数初始化 判断条件 重新初始化参数 循环主体
先判断语句符合,进入循环,重新初始化参数,再进行判断
for {set i 3}{$i>0}{incr i-1}{
puts i
} //输出3 2 1
switch option string{
…
}
option的选项默认是glob
-glob
:匹配字符串
-regexpr
:正则表达式的匹配方式
-exact
:精确匹配
switch $x{
b {incr t1}
c {incr t2}
}
proc 参数名 参数列表 函数主体
可以写return或者不写
proc add {a b} {
set sun [expr $a + $b]
return $sum
}
add 3 4 //输出为7
全局变量
:在所有过程之外定义的变量。
局部变量
:对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除。
指令global
:可以在过程内部引用全部变量
set a 4
proc sample {x}{
global a
incr a
return [expr $a + $x]
}
sample 3 //输出为8
正则表达式是一种特殊的字符串模式,用来去匹配符合规则的字符串。
\w
:匹配字母、数字、下划线
\d
:匹配数字
\s
:表示空格
.
:表示任意一个字符
先写代表的字符,再写个数匹配
regexp {^\d+.*\d+$} "1 dsg 1" //匹配以数字开头数字结尾的字符串
//输出为1 表示匹配成功
% 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
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 //关闭文件
% set INPUTFILE [open file.txt w] //以写的方式打开
file5 //这里输出的是获得的句柄值
% puts $INPUTFILE "123" //写入的值完全覆盖之前的1 2 3
% close $INPUTFILE //一定要记得关闭文件
glob
:查找当前目录下的文件,返回列表,进行模糊查找。再使用参数展开语法{*}
把列表元素作为独立参数给其他指令
file
:可以执行文件相关的一些操作
glob *.sv *.v
file delete {*}[glob *.sv *.v] //分别删除sv和v文件
eval file delete [glob *.sv *.v] //这种方式也可以,eval命令会把接收的参数用空格隔开
先把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
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 ....}
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.2 Pin object
属性 owner_net
: 用来保存与之相连的net的名称
get_attribute [get_pins U2/A] owner_net //输出 {BUS0}
1.3 Port object
属性 direction
: 用来保存port 的方向
get_attribute [get_ports A] direction //输出 {in}
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
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}
2.2 get_ -of
不同对象的连接关系:
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}
-filter:==相等 !=不相等 =~匹配 !~不匹配
-nocase:不区分大小写
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。