用于Vivado工程管理的Tcl语法学习

  学习一样东西,很重要一点就是要知道学这个是为了什么。Tcl作为一种脚本语言,类似于Python,甚至可以用Tcl来简单地处理一些文件,只是不像Python有那么多库的支持。我也是昨天刚开始学习Tcl的语法,目的是为了用Tcl脚本重建Vivado工程,然后便于做版本管理。Tcl确实和很多人说的一样比较容易学,而且我觉得所有做FPGA开发的人应该都先学Tcl。

学习方式

  学习一种语法我觉得最好的方法就是边看边自己敲代码练习,就像RUNOOB上的教程一样,每一条知识点都有一个例子,而且可以在线编辑。学习Tcl也可以采用类似的方法。我比较推崇使用VS Code,下面是我的学习方式。

下载安装

  Active Tcl类似于Tcl的一个发行版,在Tcl的官网上能够找到Tcl解释器的源码,Active Tcl在这个基础上又加了一些常用的Package。从官网下载之后再安装一下就可以了。安装的时候,

  1. 把Tcl的路径添加到PATH环境是必要的!
  2. 不建议把后缀为“.tcl”的文件和它绑定。就是下面图片里的第二个勾最好不要打,因为它会默认让Tcl脚本用Wish Application执行,这不是我期望的,因为我的Tcl脚本只是用在Vivado工程里的。
    在这里插入图片描述

VS Code配置

  VS Code的安装就不多说了,如果想用VS Code便捷地执行Tcl脚本,可以安装“Code Runner”这个插件,除了这个插件,还有Tcl语法高亮的插件也可以装一个,这个就不细说了。
在这里插入图片描述
  Code Runner安装完成后,对插件进行设置,这个插件本身不能识别Tcl脚本语言,所以要从文件的后缀来映射对应的Tcl解释器。在插件的设置中,点击下面红框里的“Edit in settings.json”。
在这里插入图片描述
  然后就会打开相应的文件,在"code-runner.executorMapByFileExtension"里加上下面这个设置就好了。这个设置表示,当文件后缀为".tcl"时,运行代码会首先将目录切换到当前文件所在目录,然后调用tclsh执行脚本。tclsh的路径已经在安装的时候添加到PATH环境变量中,所以在这里可以直接运行。

".tcl": "cd $dir && tclsh $fileName"

在这里插入图片描述
  运行代码的快捷方式是“Ctrl+Alt+N”,也可以按右上角的小三角形来运行,下面是实际使用的效果。
在这里插入图片描述

主要知识点

  Tcl的官网教程非常精炼,基本上一天就能把这些内容看完。可以一边对着官网的这个教程,一边在VS Code中自己写,这样的学习是最有效的。Tcler’s Wiki可以搜到几乎与Tcl相关的任何问题。我在这里记录一些Vivado工程中主要用到的语法规则,其他的比如数值计算、循环结构、变量作用域等就不写了,需要用到的时候可以再去查阅。

puts - 输出

  在控制台输出字符串。带空格的字符串可以用花括号({})或者双引号("")组合起来。

puts hello;                 # hello
puts {hello world};         # hello world
puts "hello world";         # hello world

set - 设置变量

  set可以设置变量,变量调用需要在前面加“$”,双引号内的“$”开头的变量会被替换,而花括号内的不会。

set var "hello world"
puts "$var";                # hello world
puts {$var};                # $var

  再看下面这个例子会发现,变量在双引号里面,但是也被正确替换了。而且结果输出的是correct。查看if相关的说明,我的理解是if指令有两个阶段,一个是变量替换阶段,一个是命令执行阶段。双引号内的变量在变量替换阶段被替换,而花括号内的变量则是在命令执行阶段被替换。对于if结构的判断条件,文档中建议用花括号。
  其他说明:一条命令需要跨行可以用反斜杠"\",花括号内的内容被当做是连续的,不用反斜杠;“eq”用来比较字符串是否相等的。

if {$var eq "hello world"} {
    puts correct
} \
else {
    puts error
}

list - 列表

  list和变量没有本质区别,都是字符串。list里的不同列表项是靠空格隔开的,没有空格的变量就是长度为1的list。list相关命令汇总,尖括号表示必须的参数,方括号表示可选的参数:

命令用法返回值功能
listlist [arg1] [arg2]…[argn]列表将多个变量组合成一个list
splitsplit <string> [splitChars]列表将string按照分隔符分割获得列表,默认分隔符是空格
lindexlindex <list> <index>列表项返回list对应index的列表项,index从0开始
llengthllength <list>整数返回list的长度
foreachforeach <varname> <list> <body>/遍历list中的每一个列表项目,并执行body中的内容

  用下面这个例子可以对list的一些基本操作有一个直观的认识。

set var "hello world"
set lst [list $var b c]
puts $lst;                  # {hello world} b c
puts [llength $lst];        # 3
puts [lindex $lst 0];       # hello world
foreach item $lst {
    puts $item;             # hello world\ b\ c
}

  方括号可以用来获取命令的返回值。例如上面第二行,list命令返回一个列表,传到外面后,用set命令来给这个列表命名为“lst”。如果想在每一行加注释,则需要在这一行命令的结尾加上分号,然后再用“#”加注释。
  list还有很多相关的命令,比如concat,lappend,linsert,lreplace,lset,lsearch,lsort,lrange,增删查改的功能都非常完备,具体的还是看官方教程。

string - 字符串

  string是Tcl最基础的数据结构,在Vivado工程里,经常需要用到字符串比较来检验某个设置是否已经存在。

命令用法返回值功能
string comparestring compare [-nocase] [-length int] <string1> <string2>-1/0/1根据字符的ASCII码,逐个比较字符,string1比string2小,返回-1;相等返回0;string1比string2大,返回1; -nocase可以忽略大小写;-length可以之比较前面的int个字符
string equalstring compare [-nocase] [-length int] <string1> <string2>0/1string1和string2相等,则返回1,不相等返回0; -nocase和-length的功能同上
string matchstring match [-nocase] pattern string0/1string和如果能匹配模版pattern,则返回1,不能则返回0; -nocase的功能同上

  下面的例子是为了区分string match和string equal。string match给的是模版,string equal是要求两个字符串匹配。

puts [string match "fred*" "freda"];    # 1 
puts [string equal "fred*" "freda"];    # 0

file - 文件

  Tcl脚本中偶尔也会需要用到文件操作,比如新建文件夹,删除文件,复制文件,这些都有对应的命令。

命令用法返回值功能
file normalizefile normalize name字符串把一个文件名规范化,并且返回这个文件的绝对路径;一般这个name也是包含文件绝对路径的一个字符串
file dirnamefile dirname name字符串返回一个文件的路径,不包含文件名

  file normalize在Vivado的Tcl脚本中也多次用到,这个命令是在Tcl8.4版本才开始支持的。

info - 检视信息

命令用法返回值功能
info existsinfo exists varName0/1如果存在变量varName,返回1;否则返回0
info scriptinfo script [filename]字符串返回当前执行的脚本文件的名称;如果给定filename,则返回filename,而且后续的info script也会返回filename

source - 执行外部Tcl脚本

  source跟脚本文件名可以执行另一个Tcl文件中的脚本。这么做可以让一个文件不至于太大,实现模块化设计,更好的模块化设计是用packages进行管理。在Vivado中可以将工程创建和Block Design 的创建分为两个Tcl脚本,工程创建之后source 创建Block Design的脚本就行。

namespace - 名称空间

  引入package之后,为了防止不同package之间产生冲突,就有了namespace的概念。::表示全局的名称空间。

后话

  如果你跟我一下只是之后准备用Tcl管理Vivao工程,了解了上面的内容基本就行了。Vivado可以导出Tcl脚本,导出的脚本也很容易看懂,如果有不懂的地方再去查就行。我之后准备用Git和Tcl脚本进行Vivado工程的版本管理。

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小裘HUST

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值