之前看过一个华为tcl的手册,看过数字集成电路静态时序分析这门课,加上在时序分析中用过一些,趁着双十一买了高亚军老师新出的《vivado/Tcl零基础入门与案例实战》

        Tcl是一门脚本语言,同时也是跟python类似的解释性语言,所谓的解释性语言就是执行时候顺序解释执行,而不需要编译,当然它也比较慢。同时,tcl语言数据类型与其他语言不同,它默认数据类型为string类。

        安装好vivado后会默认带一个vivado tcl shell,可以直接用这个来跑代码。

         也可以按照下面的方式来跑Tcl脚本(引用来自于数字集成电路静态时序分析),下面的博客都是在wish.exe上面跑的。

 1.Tcl基础知识

 1.1 Tcl的换行以及注释

        Tcl的常用写法就是一行代码一个指令,但是也可以在一行写多个指令,中间用;分开,但是加上;的语句执行结果不会被打印(类似于Matlab)。

(System32) 1 % set x 1
1
(System32) 2 % set x 2
2
(System32) 3 % set x 1;set x 2
2

        Tcl在注释时候需要在命令的第一个字符位置,分号可以表示一条指令的结束,所以注释#可以出现在两个位置,一行的开始分号的后面。多行注释这可以使用\。

        我们也可以发现如果分号右边是注释,它还是会返回分号左边指令的结果,所以我认为加上;的一行语句会打印最后一个有效的指令,这里注释没有意义,所以会打印最后一个指令输出结果为1。

        如果注释大段,有三种方式:if命令、花括号、proc过程。

(System32) 1 % #一行的开始
(System32) 2 % set x 1;#分号的后面
1

(System32) 3 % #123 \
> 231


(System32) 4 % #if方法
(System32) 5 % if {0} {set x 10 ; set y 20;}


(System32) 6 % #花括号
(System32) 7 % set commment {set x 20; set y 20;}
set x 20; set y 20;


(System32) 8 % #proc过程,类似于函数,只有被调用才会出现。
(System32) 9 % proc set_commment{}{set x 20; set y 10;}

1.2 Tcl的变量和置换

        Tcl对于变量名没有严格要求,通过set来赋值,对于大小写敏感。

set <变量名> <变量值>

        incr指令也能用来赋值

incr  <变量名>  <变量值,若缺省变量名初始值为1,否则加上变量值>

其中变量名以及变量值的数值都必须为整数

        Tcl报错会将错误信息保存在全局变量errorInfo

puts  $errorInfo   

打印错误信息的位置

(System32) 1 % set x 1
1
(System32) 2 % incr y
1
(System32) 3 % incr y 1
2
(System32) 4 % incr y -1
1
(System32) 5 % incr y 0.1
expected integer but got "0.1"
(System32) 6 % puts $errorInfo
expected integer but got "0.1"
    (reading increment)
    invoked from within
"incr y 0.1"

unset <变量名>

取消定义的变量,如果未定义会报错 

info exists <变量名>

判断变量是否已经定义,若存在返回1,否则0

info tclversion

返回tcl版本

info hostname

返回主机名

(System32) 1 % set x 1
1
(System32) 2 % info exist x
1
(System32) 3 % unset x
(System32) 4 % unset y
can't unset "y": no such variable
(System32) 5 % info exist y
0


(System32) 6 % info tclversion
8.6

(System32) 7 % info hostname
laptop-5bsbjpik

        变量的置换,时刻记住tcl里面数据类型以string为主,set x y并不会把y的变量值赋值给x,而是把y赋值给了x,如要一个$来获得y的变量值,即 set x $y,就会把y的变量值赋值给x,这就类似于c++里面的指针,可以类比y是一个对于它数值的指针,通过增加一个$用来访问指针对应地址空间的数值大小

        此外,Tcl对于变量名,会认为-以及.当做字符串分隔符来用,这个时候可以把变量名用{}括起来来避免报错。

append <变量名> <变量值>

这就相当于string的加号,直接在数值后面增加新数值位数

(System32) 1 % set x 1
1
(System32) 2 % set y x
x
(System32) 3 % set y $x
1
(System32) 4 % set a-b 1
1
(System32) 5 % set z $a-b
can't read "a": no such variable
(System32) 6 % set z ${a-b}
1
(System32) 7 % set a.b 1
1
(System32) 8 % set z $a.b
can't read "a": no such variable
(System32) 9 % set z ${a.b}
1
(System32) 10 % append z 21
121

       $在同一层级下执行时,只会发生一次置换(最右边的$)。 对于$$var,有两种方式解决,一种是通过subst指令,一种是通过[]([]用于命令置换)。

(System32) 1 % set x  1
1
(System32) 2 % set y  x
x
(System32) 3 % puts $$y             ;#只执行最右边的$y
$x


(System32) 4 % subst $$y            ;#方法一,用subst
1
(System32) 5 % puts [set $y]        ;#方法二,用[]
1
(System32) 6 % puts [set [set y]]   ;# $y等价于[set y]
1

        [ ]用于命令置换,通常与expr一起配合使用,表示将执行结果以表达式形式返回。

(System32) 1 % set a 1
1
(System32) 2 % set b [$a*$a]
invalid command name "1*1"
(System32) 3 % set b [expr $a*$a]
1

        反斜线置换\主要用于被当成特殊字符的换行符、空格、"["、"$"等,相当于c++字符串里面的\。

(System32) 1 % set a \$a
$a

(System32) 2 % set b a[x]
invalid command name "x"
(System32) 3 % set b a\[a\]
a[a]


(System32) 4 % set a \\
\


(System32) 5 % set a \b

(System32) 6 % set a \\b
\b

Tcl的置换只有两条规则,一是解析指令从左到右扫描一次,二是置换只会发生一层(即$$a只会置换右边的$a,左边的$被保存下来了)。

1.3 Tcl的{}和" "

        { }里面的置换可能会被阻止(为什么是可能?如果是用来进行置换操作会阻碍里面的置换,但是如果用来做界限符比如if、循环语句、switch语句、数学表达式则不需要阻止);

        “ ”则不会被影响。

        同时使用时,最外层的符号决定一切!

(System32) 1 % set b "you are a {$a}"
you are a {1}
(System32) 2 % set b {you are $a "$a" }
you are $a "$a" 

1.4 总结

set  a   1赋值a=1
incr a  1a=a+1
incr  aa=1

puts  $errorInfo   

打印错误信息的位置

unset  a

取消定义的变量a,如果a未定义会报错 
info exists a判断变量是否已经定义,若存在返回1,否则0

info tclversion

返回tcl版本

info hostname

返回主机名

append a 1

若a=1,现在a=11
$$y若y=1,则返回$1
subst $$y

执行两次$

puts "Hello World"打印Hello World
set  a  [expr $c*$c]若c=2,将执行结果4,以表达式返回给a

参考

[1]vivado/Tcl零基础入门与案例实战

[2]数字集成电路静态时序分析

更多推荐

Tcl语言入门(一)基本知识