学习目标:
理解掌握Tcl工具的基本用法,来控制一些EDA工具;
课程总览:
1.What is Tcl ?
Tcl : Tool command language; Widely used in many EDA tool command shells;
一些推荐的书和网站社区;
2.Tcl Syntax and Rules
①:Tcl的命令通常都是一个Command命令后面可能带有1-n个Argument 变量的形式;在有些EDA tool中,可能只要求能带一个变量,此时如果有多个变量,就需要用Grouping括起来;
②:当一个command的返回值作为另一个command的变量,就需要进行command substitution;
Backslash表示反斜杠,同vi正则表达式里面的转义模式,当我们需要用到某个字符本身,而该字符又是有特殊定义的时候,就在前面加上”\”;
③:command output输出值和返回值不是完全相同的,可以理解为输出值为输出到屏幕上的值,返回值为执行完命令后给到use来观察的数据;
在EDA工具中,都会集成Tcl的基本命令,但同时,他们还会有另外一些自己的命令;
Rule #1 :Command and Argument Parsing
"command arg1 arg2 arg3"基本形式:command 命令开头,后面加空格隔开,然后依次写上arg;执行逻辑:①执行时,会先将command命令拿到command library里面去找,找不到就会报错error no command;②找到了以后,就会依次将arg参数代入command;若arg的个数不对,多了或者少了,也会报错;(注:如果不清楚command的用法,可以用man command来查找相应的命令介绍手册,会给出基本用法,描述,参数使用及案例,这一点就和linux里面是一样的)
不同command之间需要隔开,有两种方法:①换行;②在一个command写完后加入分号”;”隔开;
当单个Arg里面有空格或者换行时,可以用””或者{}括起来,当成一个group;””与{}的区别就是,””内的变量可以替换,{}内的变量不可以替换,一般来说””用的多一些;
如上,Weak grouping using"";Rigid grouping using {};
那么,为什么要用grouping呢?
个人理解,在有些EDA tool中,可能只要求能带一个变量,此时如果有多个变量及判断语句,就需要用Grouping括起来;
Rule #2: Rigid Grouping Using {};
详细说明了{} grouping的用法,首先,不管是”“还是{},必须是成对出现的,程序在解析arg的时候,会先找到一对grouping标记,然后再解析,执行;在一对括号或者””中,无论出现空格,换行还是分号,都算作一个grouping;上述案例中,command 为while,后面跟了两个arg grouping,第一个是判断语句,第二个是执行语句;
Rule #3: Weak Grouping Using "";
quote:引号的意思;一对引号内,无论出现空格,换行还是分号,都算作一个grouping,直到另一个引号出现;
自己打开ICC_shell,设置一个set TNV b的值,再运行一下上面的代码;
Substitutions
一般来说,Variable替换用的最多,command替换其次,转义替换第三;
Rule #4: Backslash Substitution
"\+newline"=White space(空格) ,反斜杠在此处的作用就是,当一个command后面跟的arg太长时,一行写不下或者不好看,可以在某个arg后面加个\,再按回车换行,这样就可以换一行接着写,但还是属于这个command;(前面提过,普通换行就表示一个command的结束,但加个\就可以表示空格,下一行接着写)
详细列举了转义替换的一些常用组合,echo=print,即输出到屏幕上;
command执行完的标志:”newline” 或者 ”;”
Rule #5: Variable Substitution
set:设置变量名称及赋值;对要替换 变量前面加一个”$“符号;
echo:打印;
Rule #6: Command Substitution
当某个command1的返回值作为另一个command2的变量时,需要用到command替换,用{}将替换的command1括起来;有时经常会遇到一些嵌套command替换的结构,四层五层的都有;
3.Data Types
Tcl的数据类型概述:
①String:字符串;
②List:表格;
③Array:数组;
④Collection:注意,collection不是Tcl自带的数据类型,而是Synopsys公司为了工具使用的方便性,额外嵌套进来的一种数据类型;
⑤File IO:file的处理,保存,输入及输出操作时,可以给文件打个标签,后面的各种操作其实就是对标签在进行操作;
String
Tcl大神说过,任何命令,都是一个字符串,只不过该字符串里带了一些特殊字符,如空格,等;
”a sequence of characters”:从含以上来理解,其实就是一连串的字符的意思,这里的字符可以是字母/数字/各种运算符/空格/特殊字符等,按顺序排列,就是字符串;
简述:①对于在敲命令时,一般前面会有一个”dc_shell >”的显示,在此处我们用%进行了替换,故%可以忽略实际含义;
②append命令,在变量后面添加一些内容;
③split命令,指将字符串从某个位置相隔开,文中是以:相隔开,但该命令不会改变变量的值,变量的长度仍然是8位;
④match命令,将"abc*"与后面的变量进行匹配,能匹配到就输出1,不匹配就输出0;其中,abc后面跟的*表示匹配任意个任意字符,这一点和前面正则表达式中的含义稍有不同,在正则表达式中仅表示匹配任意个字符;
⑤join命令,用:将变量分隔开;
⑥regexp: 正则表达式,这里的”.*“即表示匹配任意个任意字符的意思;
⑦format:自己去man一下看看什么含义,怎么用;
List
List:简单理解就是列表的意思,内有若干个元素,每个元素直接用space分割,当需要使用List时,就用””或者{}括起来,当成一个变量grouping使用,如上述案例,mylist变量有三个值;echo mylist就会全部显示出来;
要点:①所有和list相关的command基本都是以”l”开头的;
②列表中允许嵌套grouping,仍作为一个元素;
③\加空格就表示空格的意思,用在两个list元素之间的含义就是把这两个元素连起来当作一个元素;此处,在one和word之间加入"\ "后,那么这两个就算一个元素了,打印出来的效果就是: one word;
④lindex命令含义是把list中的某个元素拿出来,参数有begin/end/0-n数字,也可以用end-1/end-2这种;注意,list相关的command中,计数都是从0开始的;
注意,list相关的command中,计数都是从0开始的;
lreplace:替换从第几到第几位的值,如果这个替换值为空白,就相当于remove了;
Array
Array:数组,用来便捷的定义成对的数据,如上述案例,在DC/ICC中,可能会有几十种clk,要是一个一个来定义,太麻烦而且代码可读性不好,为此,定义一个clk数组,把所有的clk变量都放在里面,用的时候调用clk数组后面带个具体的名称就可以了:$clk(pci_clk) 等;
(注:1 MH=1000 000 Hz,1s=1000ms=1000 000us=1000 000 000ns)
对数组进行操作的基本格式:array option arrayname
和list类似,array操作前面必须加一个array,告诉解析器是数组命令,然后arrayname是要操作的对象,即数组内的元素,option是操作逻辑;
Collection(对attribute用法不是很理解,先往后看看)
首先重申一下,collection不是tcl自带的,而是synopsys公司为了操作数据便捷性所嵌入的一种数据类型;
design objects中会含有多种数据,cells/pins/designs/ports等,而每种数据也含有多个元素,collection会通过一些attribute绑定告诉tcl解析器这些元素所属的种类;
例:上图中,ports和pins的元素名称是相同的,均为A B C D CLK五种,如果直接get inputport A B C D CLK,那么tcl工具不清楚是属于ports还是pins,这时候collection会给这些元素打上attribute标签,告知tcl解析器属于哪种;
列了一些ports和designs数据的标签属性种类,只有collection可以给数据贴标签,其他的变量类型都不可以;
get_attribute 案例;
不太理解,后面再看看;
先截下来,看看怎么解决hhh~
File I/O
File I/O可以对文件进行操作,”token”:句柄,≈ file,对句柄进行操作就是对file进行操作;
这里的"file4"就是生成的token句柄,可以理解为tcl不直接对文件进行操作,而是对生成的句柄文件进行操作,操作结束后再存到对应的文件中;这里的[]就是command替换的意思,最后的返回值就是token(file+数字);
”w”:可写(当然包含可读);”r”:只读;puts:写入文件命令;
在对文件操作完以后,一定要close $f,就相当于保存退出的意思;
①gets和puts都是以行为单位的,可以指定读某行的内容;
②read命令可以读到某个字节;
③seek可以查找到某个位置,就像指针指到某个位置,然后后面接read的话,就是从该位置往后读一定的字节;
简单案例,在对句柄操作完成后,一定记住要close $f,相当于在对句柄进行操作时,内容都是存在内存(buffer)里面的,只有close后,内容才真正写入并保存到文件里面了;close以后,该文件对应的token就会释放出来;
tell:告知当前的指针指的是哪一行;
seek:把指针设置到需要的那一行;