Vivado中的TCL脚本语言

Source
原文链接: https://blog.csdn.net/hzdxw/article/details/51965916

本文介绍了Tcl在Vivado中的基础应用,希望起到抛砖引玉的作用,指引使用者在短时间内快速掌握相关技巧,更好地发挥Vivado在FPGA设计中的优势。

Vivado TCL脚本语言


使用Tcl作为它的命令语言的好处:


1  Tcl提供了标准语法,一旦用户掌握了Tcl就可以很容易的发布命令给基于Tcl的程序


2  Tcl可作为程序间通信的接口


3  通过Tcl, Vivado具备了强大的设计分析能力
• 快速定位设计中的问题
• 减少设计迭代周期


 


基本语法和基础命令


在Vivado中的Tcl命令行里,学习这些基本语法 

(Windows下 –> 开始 –> 所有程序 –> Xilinx Design Tools –> Vivado xxx –> Vivado xxx Tcl Shell)

 

 01

命令格式

一条Tcl的命令串包含了多条命令时,用换行符或分号来隔开,而每一条命令包含了一个域的集合,域使用空白分开的,第一个域是一个命令的名字,其它的是作为参数来传给它。

02

数据类型

Tcl只支持一种数据结构:字符串。所有的命令、命令里的所有的参数、命令的结果、变量全部都是都是字符串。

简单实例:

set i 123 
       将123这个字符串赋值给i变量

unset i 
       清除变量

set i hi 
       将hi这个字符串赋值给i变量

set i "hi hello" 
       hi hello中有空格,所以加引号

set i 123;#开始注释 
       注意: 注释前,要先用分号,把命令结束掉,或者换行注释 

03

设置变量

  %set myVar"Hello World!" //设置一个名为myVar的变量,其值为Hello World!

设置一个名为myVar的变量,其值为Hello World!

04

使用$符号引用变量

   Vivado  set i 123 ; puts $i 123

其中puts是打印命令

05

使用[]将命令返回值,作为新命令的参数

  Vivado set i [set j 232] ; puts $i 232

set j 232命令会返回值232 
新命令就成了 set i 232

这里稍微复杂一点点的例子: 
set i a[set j b][set k c] 
最后的结果就是:j=b ; k=c ; i=abc

06

数组

数组不需要声明,直接赋值即可,也不必按照顺序来: 
set i(1)   123 ; set i(16) hi

当然也支持任意维数的数组: 
set i(1,2,3) hi 
引用的时候直接$i(1,2,3)即可

parray命令 
可以打印出一个数组的全部信息: 

  Vivado set d<1,1,1> hi ; set d<2,1,6> hello ; set d<0,0,3> 5 ; parray d

  d<0,0,3> = 5

  d<1,1,1> = hi

  d<2,1,6> = hello

 array命令 
命令格式:array option arrayName

option 是 操作选项,有如下可选: 
  name : 返回数组的所有元素的名称 
  size : 返回数组的长度 
  startsearch  : 初始化一次遍历,返回一个遍历标识符(searchId),这个searchId在下面用到,(是可以多个遍历同时进行的) 
  下面的命令格式为:array option arrayName searchId 
  ->nextelement : 返回数组中下一个元素,如果没有返回空 
  ->anymore : 如果接下来还有元素,返回1,否则返回0 
  ->donesearch : 结束遍历 

Vivado set k<0> 11 ; set k<2> 22 ; set k<0> xx ; array name k

x 0 2

Vivado array startsearch k

s-1-k

Vivado array nextelement k s-1-k

x

Vivado array nextelement k s-1-k

0

Vivado array nextelement k s-1-k

2

Vivado array anymore k s-1-k

0

Vivado array donesearch k s-1-k


 

07

字符串命令

string命令:

命令格式:string option string1 string2

option 是 操作选项,有如下可选: 
compare : 按照字母的排序方式比较,string1 <,=,>string2,分别返回-1,0,1 
match : 判断string1和string2是否匹配 
first : 检索string2中第一次出现string1的位置,如果没有出现string1则返回-1 
last : 和first相反 
trim : 从string1中删除开头和结尾的,string2的字符 

 Vivado string trim ----abc-def------

 abc-def

命令格式:string option string 
tolower : 返回string中的所有字符被转换为小写字符后的新字符串 
toupper : 返回string中的所有字符串转换为大写后的字符串 
trimleft : 去除string左空白,类似的还有trimright 
length : 返回string1的长度 

 Vivado string tolower abvASDA

 abvasda

 Vivado string toupper abvASDA

 ABVASDA

 Vivado string length abvASDA

 7

range  : 
string range abcdef 1 2,返回输出结果为bc

append命令:
字符串追加,可以无限拼接

set i a
append i b c d
puts $i123

i变量的值就成了 abcd,注意append i b c d命令,而不是append $i b c d

split命令 
命令格式:split 字符串 分割符,将字符串转换为列表 

  Vivado split sddsfsdf s

  <> dd f df

08

数字操作 

        tcl中只有string类型的变量,所以当进行数字运算的时候,需要用到incr和expr操作命令

incr命令:
a变量自加-3:incr a -3 
a变量自加1 : incr a

expr命令: 
        类似C语言中的算术操作符有(在Tcl 中的逻辑:真为1,假为0): 
!、* 、/、 %、+、-、<<、 >> 、< 、> 、<= 、>= 、== 、!=、& 、^ 、|、&&、 || 、x ? y : z 
除此之外,expr还能够识别一些函数及其返回值: abs(x) 、round(x) 、sin(x)、cos(x) 等 
使用方法:expr 表达式 
Vivado expr 222>111

1

Vivado expr 5/4.0

1.25

Vivado set a [expr 1 ? 123 : 321]

123

Vivado expr cos<0>

1.0
 

09

proc自定义函数 

proc:

proc hello {str} {
puts hello:$str}

需要注意的是,如果不能一行写完,那建议按照如下格式来定义(主要是要将“{”放到第一行的末尾): 
第一行: proc+(空格)+函数名+(空格)+{参数}+(空格)+{ 
中间行: 逻辑运算 
最后行: }

全局变量global: 
用于将过程中的局部变量变成外界可操作的全局变量

proc hello {} {    global x    set x hi    set i hello}1234

上述代码,执行结果: 
  Vivado hello ; puts $x ; puts $i 

  hi

  can't read "i": no such variable 


 

return命令:

proc hello {} {return world}
set i [hello]12

return命令没啥好说的,上述代码的结果是,将i变量赋值为world字符串

10

控制流和循环命令

        Tcl语言中用于控制流程和循环的命令与C语言及其它高级语言中相似,包括if、while、for和foreach等等。

具体使用可以参考如下示例:
  % if ($myVar !=1){puts "Sweet!"} //判断myVar变量的值,若不等于1就打印Sweet!

  Sweet!

  % if ($myVar ==1){puts "$myVar is =1"} else {puts "$myVar is !=1"} //多条件判断

  Hello World is !=1

  % foreach x $myVar {puts $x} //循环读取myVar变量的值并打印

  Hello 

  World!

  %set x 1 //设置变量x

  1

  %while {$x<5}{puts "x is $x"; set x [expr{$x+1}]} //判断变量的值,打印变量再赋值

  x is 1
 
if 流控制: 
这个同样建议按照格式来: 
第一行: if+(空格)+{表达式}+(空格)+{ 
中间行: 逻辑运算 
第N行: }+(空格)+else+(空格)+{ 
中间行: 逻辑运算 
最后行: } 

switch流控制 :
例子如下,一目了然:

switch 2 { 
1 {puts 111}              
2 {puts 222}     
3 {puts 333}     
default {puts xxx}     


case流控制:

case abcd in a {puts 111} *bc* {puts 333} default {puts xxx}      1

上述程序对字符串abcd进行判断: 
条件一 : 字符串为a 
条件二 : 不管字符串的前后字符是啥,只要中间有bc子字符串即可 
条件三 : default

foreach循环: 

循环读取myVar变量的值并打印,那就需要这个foreach了

for循环: 
TCL的for循环也是很类似C语言的:

for {set i 0} {$i < 10} {incr i} {
puts $i
}123

初始化i=0,范围 i<10 ,循环i=i+1

while循环:

判断变量的值,打印,变量再赋值就OK了

11

字符串转为命令 

eval命令: 
set a set ; set b i ; set c hello ; eval $a $b $c 
上述代码就等效于:set i hello 
eval将字符串的内容,作为命令,执行

12

打印输出 

        打印主要通过puts语句来执行,配合特殊符号,直接决定最终输出内容。