- 216.03 KB
- 2022-08-11 发布
- 1、本文档由用户上传,淘文库整理发布,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,请立即联系网站客服。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细阅读内容确认后进行付费下载。
- 网站客服QQ:403074932
TCL脚本语言学习前言Tcl和Java一样,是平台无关的语言,windows、linux下面都可运行;Tcl和Perl一样,是脚本语言,无须编译,解释执行;QuartusII支持Tcl;Modelsim支持Tcl,.do文件就是按照Tcl语法写的;学会了Tcl,QuartusII的项目设置可以随身带走,项目维护简便至极;学会了Tcl,可以把QuartusII的STA工具用起来,时序分析从此不难;学会了Tcl,自己就能EDA。语法基本操作命令1、输出:语法为:puts?-nonewline??channelled?String例如:putshello,如果是写成puts-nonewlinehello,就是表示不输出回车换行。如果是puts{"hello,world!"},此时输出的结果是“hello,world!”注意:putsstdout{"hello,world!"},与上面的输出是一样的,这里stdout是表示标准输出I/O流,它同stderr(用于标识标准出错输出),stdin(标准输入)一样,是和其他文件的I/O命令的约定。2、变量赋值与取消定义:语法为:setvanName[value]unsetvarNameset:变量定义和赋值命令,为变量赋值时,会为变量开辟一段内存空间来存储变量值。set命令也可以只跟变量而无变量值,若变量已经定义,则返回变量值,效果和puts类似,如果该变量不存在,则返回错误信息。当设置了一个变量时,要读取它可以通过“$”符号来引用。setahello;#定义变量a并赋值puts$a;#此时输出的就是hello,有点类似指针的概念setb$a;#把hello这个值赋给bUnset:取消变量定义,并释放变量所占的内存空间。\n3、替换:(1)、用“$”可以引用替换功能,但是注意TCL对替换只进行一遍解释,对嵌套的“$”不予理睬例如:setahellosetbasetx$$b,此时输出为$a(2)、[]也可以完成替换的命令例如:setb[seta5]或setb[expr5*10]4、“\”的作用:用于引用特殊字符或特殊功能。例如:setx"\$a";#把X定义为$aputs"\a";#输出震铃(在tclsh下运行)puts"\nhello";#\n表示换行显示hello所谓的替代,其实包含3层意思,一、变量的替代。二、命令的替代。三、反斜杠替代。变量的替代:setvar5;setb$var;在这里,使用$符号就是一个替代的例子,它相当于替代Var变量的数值给$var。命令的替代:setlen[stringlengthfoobar],它的意思是把foobar的字符长度给len。嵌套命令由[]分隔,这是一种命令替代。如果在一个命令中有多重命令替代,那么是按照从左到右的顺序处理,每遇到右中括号就开始处理其分隔的命令。反斜杠替代:它用来引用对于解释器有特殊意义的字符。比如seta\$b;此时a的值为$b。反斜杠还有一个作用就是在多行之间延续长命令,因为换行符会结束一个命令。数学表达式expr命令1、数学运算要用数学运算时,就用expr命令就可以了,比如exprlog(10);exprsin(30);#此处的30是弧度,不是角度。2、incr命令:用于根据指定的步长来增加或减少参数的值,当步长为负时,减少参数值;当步长为正时,增加参数值。语法:incrvarName?step?例如:seta10;incra4;#此时会显示的是14,表示a的值为14。\n字符串基本指令1、append:将值追加到字符串尾,将一段字符串连接到另一字符串尾部从而组成新的字符串。语法:appendvarName?value?例如:setvar1hello;setvar2world;appendvar1$var2;#此时输出的就是helloworld,也就是var1的值现在变成helloworld。2、format:根据一组格式说明来格式化字符串,此命令不会改变被操作字符串的内容。语法:formatspecvalue1value2...其中,spec包含了格式说明关键词和附加文字,使用%来引入一个关键词,后跟0个或多个修饰符,然后使用一个转换格式符结尾。关键词的基本格式是:“%aaaB",aaa表示修饰符,B表示一种格式转换符。valueX是变元,其关键词可以多达6部分:位置说明符、标志、字段宽度、精度、长度、转换符。例如:format”%8x“20;#将20转换为十六进制数,8位数据宽度,右对齐。如果是-8x表示左对齐。3、scan:根据格式描述符来解析一个字符串并将对应值赋给后面的变量。返回值是成功转换的个数。语法:scanstringformatvar?var?.....%c的作用与format的正好相反,是将一个ASCII字符转换为对应的整数值。与format的区别:format是将多个目标变量转换成一个字符串,scan是将一个字符串分解为多个变量。例如:setnum[scan"abcABC""%c%c"var1var2];puts"$var1$var2";输出:=>9798注意:这里其实只是对a、b进行了转换,后面的cABC没有转换,要想转换,只要多写几个%c,后面多定义几个变量就可以了。并且%c的个数与变量的个数要一一对应。4、binary类命令:binaryformat将数值根据规定模式对TCL的普通数据进行二进制压缩,而binaryscan的作用正好相反。(用它的目的是用二进制保存数据比用ASCII表示省空间)。例:seta[binaryformat"s"23]#23为十六进制数,需要转换成二进制的数。5、string命令:(1)、stringcompare、stringequal字符串比较\n例4-8stringcompare和stringequal进行字符串比较的例子%sets1abc=>abc%sets2abd=>abd%if{[stringcompare$s1$s2]==0}{puts"s1issameass2"}else{puts"s1isn’tsameass2"}=>s1isn’tsameass2%if{[stringequal$s1$s2]}{puts"s1issameass2"}else{puts"s1isn’tsameass2"}=>s1isn’tsameass2(2)stringmatch:匹配stringmatchalphaalpha;=>1;#匹配时输出1stringmatch{[alpha]*}bfadsalpha;=>0;#表示要匹配以alpha任何一个开头的字符串(3)stringreplace:字符串替换(4)字符串映射:stringmapstringmap命令根据字符映射对字符串进行转换。映射以输入、输出表的形式表示。凡是字符串中包含有输入序列的地方都使用相应的输出序列替换(列表中输入后的字符)。输入、输出要成对使用,如:stringmap{fpdl}"food"=>poolstringmap{fppdllooa}"food"=>ppall列表操作命令1、list命令:用来创建列表,一个列表可以包含子列表,即列表可以嵌套。setl1[listSunMonTues];=>SunMonTues#列表l1中含有3个元素setl2[list$l1Wed]=>{SunMonTues}Wed;#列表l2中含有两个元素。第一个元素用花括号括起来。2、concat命令:以空格为分隔符将多个列表拼装在一起成为新的列表。%setx{12};sety[concat$x3];=>123\n它的作用等同于双引号:sety"$x3"3、lappend命令:用来将新元素追加到列表末尾。注意显示的时候会有空格setahel;lappendalo;=>hello(由此可以看出,lappend可以用于创建一个列表)4、llength命令:用于获得一个列表的元素个数。setl"a3k";llength$l;=>35、lindex命令:返回列表中指定位置的特定元素,它是从0开始计数。setx{1457809};lindex$x6;=>9(1表示第0个数,所以第6个数为9)。6、lrange命令:返回一个指定区段的列表元素,可以以end或者end-n作为索引(n为正整数)。lrange{123{45}6}2end;=>3{45}6\n7、linsert和lreplace命令:linsert命令用来将元素插入到一个列表由索引指定的位置。如果索引为0或者更小,则元素就会被添加到最前面。如果索引值大于或者等于列表长度,则元素被追加到列表尾部。其他情况元素被添加到指定位置之前。lreplace命令将一个指定区段的列所谓的替代,其实包含3层意思,一、变量的替代。二、命令的替代。三、反斜杠替代。变量的替代:setvar5;setb$var;在这里,使用$符号就是一个替代的例子,它相当于替代Var变量的数值给$var。命令的替代:setlen[stringlengthfoobar],它的意思是把foobar的字符长度给len。嵌套命令由【】分隔,这是一种命令替代。如果在一个命令中有多重命令替代,那么是按照从左到右的顺序处理,每遇到右中括号就开始处理其分隔的命令。反斜杠替代:它用来引用对于解释器有特殊意义的字符。比如seta\$b;此时a的值为$b。反斜杠还有一个作用就是在多行之间延续长命令,因为换行符会结束一个命令。表元素替换为新元素。如果没有指定新元素,则这个区域的元素就会被从列表中删除。setx{12};setnew[linsert$x1heshe];=>1heshe2;#此处的1表示在第一个元素处插入。8、lsearch命令:在给定列表中搜索与匹配字符串匹配的元素,成功就返回正确的元素索引,否则返回-1。setl1[listThisisonelist];setindex[lsearch$l1l*];=>39、lsort命令:lsort命令实现对列表的排序。排序操作不影响原表,而是返回排序之后的新表。排序的方式有多种选择,可以通过-ascii、-dictionary、–integer、-real来指定基本排序类型,然后使用-increasing、decreasing指定排列方式,默认为-ascii、-increasing。要注意ASCII排序时使用字符编码;而dictionary排序方式整合大小写,并将包含的数字以数值大小来处理。setlist"aZzn100n200MpHlhLm120";lsort-ascii$list;=>120HlMZahLmn100n200pz\n10、join与split命令:join命令接收一个列表,并用指定的分隔符将列表元素整合成一个字符串。join{1{23}{456}}:;=>1:23:456(注意此处的“:”表示指定的分隔符)split命令的作用与join的作用相反,它接收一个字符串,并根据给定的字符将其分割转换成一个列表。用于分割的字符应该在字符串中存在,否则split因为没有搜索到对应字符而将整个字符串作为唯一列表元素而返回,即返回原字符串。数组操作1、数组的定义与格式:语法:setarrName(index)value或者是arraysetarrName{index1value1index2value2...}或者setval$arrName(index)例如:setarray01(5)"HelloWorld";=>HelloWorld#此处的array01表示数组名,5表示这个数组的第五个元素,并且其值为“helloworld"arraynamesarray01;=>5;#显示数组名字parrayarray01;#显示数组所有内容(数组一定要定义了才有)2、多维数组:tcl其实并没有什么多维数组这个说法,但是用户可以定义一个所谓的多维数组。setarr(0,0)100;setarr(0,1)200数组操作命令:(1)、arrayget命令:提取数组索引、元素值对并将这些值组织成一个列表。setarray2(5)"HelloWorld";arraygetarray2;=>5{HelloWorld}(2)、arraynames命令:返回所有元素索引名与模式pattern匹配的元素索引名列表。注意:arraynames返回的元素索引的时候,最后一个元素的索引被放置到了列表的第一个位置上。Tcl提供了if、if/else、if/elseif、foreach、for、while和switch命令来管理控制结构。这些命令和其他语言如C语言的条件语句的作用相同。需要区别的是在Tcl中所有控制结构都是由相应的命令来实现,而C语言中则是一条控制语句。\n控制结构命令1、if/else命令:if{testexpr测试表达式}{body1}elseif{testexpr}{body2}else{testexpr}{body3}注意:1、语法中用以界定过程体的花括号一定要和if命令在同一行上!因为对Tcl来讲,换行符就是命令结束符。2、如果if后面还有else/elseif命令,则要留意else/elseif的位置。else/elseif要跟在if执行命令体的后面一个花括号后,不能分行,要有空格间隔花括号和else/elseif。2、for命令:语法:for{start}{testexpr}{next}{body}3、while命令:语法:while{test}{body}4、switch命令:语法:switch[option]string{pattern-1{body1}pattern-2{body2}...pattern-n{bodyn}}注意:1、option主要有:-exact用精确匹配(默认);-glob用glob格式行模式匹配;-regexp用正则表达式模式匹配;\n--标记选项结束或者说明不用选项。2、如果项邻的两个或者多个pattern-x的执行命令体是一样的,则可以只写出最后的一个执行命令体,而前面的执行命令体可以省略,并用“-”号来替代。3、最后一个option一定是“--",这个选项不可缺少!4、可以使用default匹配命令体来处理无法匹配模式。当其他模式都不匹配时,default命令体就会被执行。需要注意,default命令体要设置在最后,否则它就会被当作纯粹的字符串default而进行匹配。5、对于switch执行命令体内的注释一定要小心。Tcl语法器处理的注释应该和命令处于同一层次,即一个注释要占用一个命令的位置。这样就限制了在switch体内注释的位置。比如你不能将一条注释放在和pattern-n同一级别的位置,那样switch命令就会将此条注释也当成一个匹配模式来解释,这有可能引起意想不到的错误。所以,如果打算在switch体内写注释的话,最好将注释放在相应的某个匹配模式的命令体body-n内。5、catch命令:在实际应用中,如果一条命令或函数在调用时使用了错误输入参数或者自身出现错误,它就会报错,而且终止当前脚本的执行。严重的错误也可能导致Tclshell退出。catch命令就可以用来捕获这种调用错误。语法:catch{com_proc}?res?catch命令有两个变元,com_proc是命令体。res用来保存命令返回结果,或是出错时的错误信息,此变元为可选项。如果有错,catch会返回1,无错就返回0。命令体需要用花括号括起来。6、error命令:报告错误信息并终止脚本执行。最多接收3个变元。errormessage?Info?Code?过程与作用域1、过程定义命令:proc[语法]:procprocName{var1var2...}{body}注意:1、proc命令有三个参数:procName是定义的过程名字;{var1var2...}是输入、输出参数列表;body是过程执行命令体。2、可以使用return命令在需要的时候返回调用程序。3、使用过程的时候,不一定输入所有的参数值。过程的输入参数可以有默认值。procTest{a{b7}{str"Helloworld"}}{puts"$str"\nreturn[expr$a*$b]}4、注意:可以不用定义输入输出参数列表,但是一定要用空格。如果参数列表中最后一个参数是args的话,则过程可以接收可变数目的输入参数。当调用过程时,除了指定参数以外的参数值都被args接收。如果参数列表中只有args一项,则args接收所有输入参数值。2、过程的作用域:默认情况下,过程名具有单一的作用域即全局作用域。过程的定义可以嵌套,低层定义的过程只有在上层过程被执行后才能生效。在一个过程内部,即可以使用自身的局部变量,又可以使用全局变量,但是全局变量在过程内部不会自动可见,需要通过global命令来事先声明。3、upvar命令:upvar命令的作用与global的作用相似,upvar通过“引用”来使用上层过程中的变量,它传递的是参数名而非值。[语法]:upvar?level?otherVar1myVar1?otherVar2myVar2...?4、rename命令:可以用来更改命令名[语法]:renameoldFuncNamenewFuncName正则表达式1、regexp命令:语法:regexp?switches?expstring?matchvar??subMatchVar...subMatchVar?说明:1.regexp命令比较字符串string是否与正则表达式exp部分或者全部匹配,并可以将字符串中的子字符串提取出来。如果字符串的某个子字符串和正则表达式匹配,则返回1,否则返回0。2.如果在string变量后面,还有其它的变量(称之为匹配变量,matchvariables),则这些变量就保存了那些与正则表达式匹配的子字符串信息(如可能是子字符串的实际内容,或者是界定子字符串的起始、结束的索引数字)。matchVar保存了匹配exp的字符串,而subMatchVar依次存放了和exp各个中单个括号语法(子模式)匹配的子字符串。2、regsub命令:regsub命令基于正则表达式完成字符串匹配和替换。[语法]:regsub?switches?expstringsubSpecvarName\n说明:1.switches是命令开关选项,主要有:-开关选项-nocase、-expanded、-line、-linestop、-lineanchor、-startindex和--与regexp命令开关选项作用相同--all对所有满足匹配条件的字符串范围进行替换,返回匹配和替换的次数。没有此选项时,只匹配第一个满足匹配条件的匹配范围并用subSpec替换之。2.替换模式subSpec可以是普通字符,也可以含有&和\x(x是一个数字)。当是这两个特殊字符时,&和\x就会被替换成与exp中的对应模式匹配的string中的匹配范围内的字符。有关变量的细节1、如果只传递一个参数,set命令返回变量的数值。例如:setvar123;setnamevar;此时name的数值就是123setname;此时返回变量的数值=>varset$name;此时返回的是变量的数值=>1232、查看变量是否存在:infoexists命令:比如setname123;infoexistsname;=>1表示存在这个变量双引号“”与花括号的区别{}双引号和花括号都可以用于单词的组合,形成一个参数,但是他们是有区别的:双引号允许组内替代,花括号不允许。setahello;putsstdout"thelengthof$ais[stringlength$s]."输出为:thelengthofhellois5.putsstdout{thelengthof$ais[stringlength$s].}输出为:thelengthof$ais[stringlength$s]\n操作文件和程序1、复制文件:filecopy语法:filecopy?-force?file1file2(将file1文件复制到file2)2、创建目录:filemkdir,它可以创建一个或多个目录(目录在C:\DocumentsandSettings\name)输入pwd可以看到当前的目录filemkdirdirdir....3、删除文件:filedeletefiledeletename(注意,文件必须是空的时候才能被删除)4、重命名文件和目录:filerename操作从old到new改一个文件名(也是只能在文件为空的时候才能更改)5、输入/输出命令总结:openwhat?access??permissions?给文件或管道返回通道IDputs?nonewline??channel?string写入字符串getschannel?varname?读出一行readchannel?numBytes?读出numBytes字节,或全部数据tellchannel返回搜索偏移量eofchannel查询是否在文件末尾flushchannel写入一个通道的缓冲区closechannel关闭一个I/O通道6、打开一个文件并写入数据:setfileid[open"rick/haha"w+];以读写形式打开puts$fileid"hello";在文件中写入helloclose$fileid