0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

关于TCL的基础知识浅析

电子工程师 来源:CSDN技术社区 作者:空白MAX 2021-04-15 14:15 次阅读

什么是TCL?

TCL,Tool Command Language,是一种脚本语言,主流的EDA工具都支持TCL进行操作。TCL经常被用于 快速原型开发,脚本编程, GUI和测试等方面。

TCL学习

接下来以一个实际的tcl脚本为例,简单介绍TCL的使用。这个脚本是用于modelsim/qusetasim仿真的脚本,mentor将tcl进行拓展,称之为do文件,实际语法还是TCL。脚本来自链接:

# testbench name without .v , .vt , .vhd , .vht

set testbench_name conv

# simulation time ; ns/us/ms/min

set sim_time 1us

# auto add files when $auto_add_file==1; add file list when $auto_add_file==0

quietly set auto_add_file 1

# project path

set prj_path E:/conv_sim

# backup path

set bkp_path E:/conv_sim/backup

# monitor resolution ratio , for example : 1920 x 1080

quietly set m_width 1920

quietly set m_height 1080

if 0 {

my first program in Tcl program

Its very simple

}

首先,第一行,TCL采用#进行单行注释,多行注释使用判断句注释,就像末尾的if那样。TCL是一种弱语言类型,不需要声明类型,直接通过set声明变量并进行赋值。字符串变量直接输入即可,不需要额外的声明。这里直接set的变量是全局变量。

proc new_prj {new_prj_name} {

global prj_path

set new_prj_path E:/conv_sim/$new_prj_name/

quit -sim

project close

if { [file exists $new_prj_path]==0 } {

file mkdir $new_prj_path

}

project new $new_prj_path $new_prj_name work

if { [file exists $new_prj_path/src]==0 } {

file mkdir $new_prj_path/src

}

file copy -force -- $prj_path/sim.do $new_prj_path

puts “create new project successfully!”

puts “current project path : ”

pwd

}

这里定义了一个用于创建工程的命令new_prj。

proc为procedure的缩写,TCL使用proc声明过程,用proc声明后,过程就会成为脚本的一个命令,直接使用。对于在过程中定义的变量,因为它们只能在过程中被访问,并且当过程退出时会被自动删除,所以称为局部变量;在所有过程之外定义的变量我们称之为全局变量。TCL 中,局部变量和全局变量可以同名,两者的作用域的交集为空:局部变量的作用域是它所在的过程的内部;全局变量的作用域则不包括所有过程的内部。如果我们想在过程内部引用一个全局变量的值,可以使用 global 命令。这样在new_prj中就能访问到全局变量prj_path。

变量的引用通过$进行引用,会直接将表达式进行替换。

quit是qusetasim的命令,用于退出软件,加上选项-sim将只退出仿真而不会关闭软件。project close也是qusetasim的命令,用于关闭工程。

file exists path,判断是否存在指定文件夹。file mkdir path,创建文件夹。file copy -force — source targetDir 复制文件到指定目录,这个命令把 source 中指明的文件或目录递归的拷贝到目的地址 targetDir,只有当存在-force选项时,已经存在的文件才会被覆盖。试图覆盖一个非空的目录或以一个文件覆盖一个目录或以一个目录覆盖一个文件都会导致错误。

注意,-表示开关/选项,--表示这后面再没有开关(switchs)了,即后面以’-‘开头的参数将不作为 switch。

puts用于打印,和sv中的$display一个作用。

proc encrypt_src {} {

global prj_path

set encrypt_path $prj_path/encrypt_src/

file mkdir $encrypt_path

set paths {}

set paths [glob -nocomplain -directory $paths */]

lappend paths $prj_path

foreach one_path $paths {

set vfiles [glob -nocomplain -directory $one_path *.v *.vt *.sv]

foreach one_file $vfiles {

set one_file_path $prj_path

vencrypt [append one_file_path $one_file] -d $encrypt_path

}

}

puts “encrypt HDL design file(s) successfully!”

}

这里利用questasim的vencrypt将工程内的文件全部进行加密。

set paths {}创建一个列表,列表是TCL中的一个数据类型。

glob和file是TCL提供的两个进行文件名操作的命令,用来操作文件或获取文件信息。glob 命令采用一种或多种模式作参数,并返回匹配这个(些)模式的所有文件的列表,其语法为:glob switches pattern pattern 。-nocomplain是一个开关,使用这个开关允许glob返回空列表,不开启的话,如果结果是空,则会返回错误。-directory,用于指定目录,让glob在这个目录下进行匹配。pattern代表正则匹配的模式,匹配成功的文件名将添加进返回的列表。

lappend在一个列表后添加一个元素。

foreach遍历整个列表的元素,中间变量为one_path。

vencrypt是questasim的命令,用于将文件进行加密,加密后的文件可以被questasim识别编译,但是无法阅读。比如下面的代码的后半段就是前半段进行加密后的内容。-d用于指定加密后的文件生成加密文件的存放位置。

module relu_core (

input clk, //clk

input rst_n, //reset

input [255:0] pooling_in,

input relu_bypass,

output [255:0] relu_out //output of pooling

);

wire [255:0] relu_result;

genvar i;

generate

for(i=0; i《32; i=i+1) begin

assign relu_result[i*8+7:8*i] = pooling_in[i*8+7] ? 8‘h00 : pooling_in[i*8+:8];

end

endgenerate

assign relu_out = relu_bypass ? pooling_in : relu_result;

endmodule

`pragma protect begin_protected

`pragma protect version = 1

`pragma protect encrypt_agent = “QuestaSim” , encrypt_agent_info = “10.6c”

`pragma protect key_keyowner = “Mentor Graphics Corporation” , key_keyname = “MGC-VERIF-SIM-RSA-2”

`pragma protect key_method = “rsa”

`pragma protect encoding = ( enctype = “base64” , line_length = 64 , bytes = 256 )

`pragma protect key_block

NROTnsk8pETOxl4QiAgkLU/279V7O329exd+zzLCVEaVhofiC+ppJtC4dQapAZkK

4CZaxp/gcINr0jlEzm2pBtmqhJ5Kd71mtMNPuUCpphC+J/VJ0JNsOVsVnG6dGztB

+2p8OzoWDWF4F+yAF7L6O7Vksq5afDXEwJDlkIfxzxg3PfwWjDbssR5lq731UMSE

a9cfMZZxe8OO7itVsCz/zAK+WKSZvpAlArpT2mHg76CMXN5ybxCzwXtjeAZf0piM

61waCYBncD+dloA+5uhHJxOj10CAE7jsF8rgi3bfMG/XqmneMRzL8ODqaLtolytR

h2xcuR63Zyi3tgTOeUvXSg==

`pragma protect data_method = “aes128-cbc”

`pragma protect encoding = ( enctype = “base64” , line_length = 64 , bytes = 528 )

`pragma protect data_block

8v6OffgbV/rkWBfwQvGwkfKmdYvvLkohFDLb+Qy+qVnoZgIFOFAFomkEaZ5b32l7

Qmw1d80d+hxDgn4XFA3qbNpn80H3EDx8+HhZL8GeoZw1Wkp4dlFpUcQLEJ3tNh4d

j314qMHeKj8Uu/4928YoJVMzojlFbn+vWh0ZTyzs5jLJa+EspgVZCSIvlPY9WYOQ

1HmF3kaj/0rJ35hmJXvy+ZMshKS031slUm/7jSxVj0kzdrNLGNYdgKIOvKTTu9vT

lYCjfkZSbLEGAXKWFlWSGCfqgb4sGc6uB0j+oKpE2yVOrMJaQ4rqHg0ykJiwn1fM

MwByU4SVRJK024OPjQXEL4aSQHgi0gvw30Ihxvcr4Do15HVZCBn43R6SVNvQNa0s

Nj6PLcT3jYPk9HZs0ZiykRR+LMLLlfFD9NFaN1s1PNZugAywB9TmYh8Vq1CY5w0Y

GxucPCAqYDn+jet1wFh3Rk/ybjj8ageR/4W+U0eKXF+Uu7YWfUApRkGH75Ru3yE/

f9JiC/xdmH6As5aWGzvNZk2g2BLzamLp7d4tmCQbizQSby38hKW8VOJmOzEQPWHg

UxKcN/VZzW6yPVrJxPRHRIb/qarIrx75IdFRZjYrCI9FFchJ3TASPSviufKyAWOj

jWIkYe8Z9yQ5fTMZwe7NhT27PfRe46HR9YuMP9lCCGcYplKVbG5xFwX6bRdqAqwK

`pragma protect end_protected

proc create_file_list {} {

global prj_path

set prj_files [project filenames]

set paths {}

set paths [glob -nocomplain -directory $paths */]

lappend paths $prj_path

set fd [open $prj_path/hdl_design_file_list.tcl w+]

foreach one_path $paths {

set vfiles [glob -nocomplain -directory $one_path *.v *.vt *.vhd *.vht]

foreach one_file $vfiles {

set exists_num 0

set one_file_path {}

append one_file_path $prj_path

append one_file_path $one_file

foreach one_prj_file $prj_files {

if {$one_file_path == $one_prj_file} {

incr exists_num

}

}

if {$exists_num == 0} {

puts -nonewline $fd “# ”

}

puts $fd $one_file_path

}

}

close $fd

puts “create file list successfully!”

}

这里定义了一个创建文件列表的过程。

set fd [open $prj_path/hdl_design_file_list.tcl w+],open命令以特定模式打开文件,返回一个文件标识符。这与c语言类似,w+ 读写方式打开文件,如文件存在则清空文件内容,否则创建新的空文件。puts -nonewline $fd ”# “,向fd中写入内容,不开启-nonewline则会在末尾添加换行符。close关闭文件。

proc add_file {} {

global prj_path auto_add_file

set add_count 0

set del_count 0

set prj_files [project filenames]

if {$auto_add_file == 1} {

set paths [glob -nocomplain -directory $prj_path */]

lappend paths $prj_path

foreach one_path $paths {

set vfiles [glob -nocomplain -directory $one_path *.v *.vt *.vhd *.vht]

foreach one_file $vfiles {

set exists_num 0

foreach one_prj_file $prj_files {

if {$one_file == $one_prj_file} {

incr exists_num

}

}

if {$exists_num == 0} {

project addfile $one_file

incr add_count

}

}

}

} elseif {$auto_add_file == 0} {

if {[file exists $prj_path/hdl_design_file_list.tcl] == 0 ||

[file size $prj_path/hdl_design_file_list.tcl] 《= 1} {

create_file_list

}

set fd [open $prj_path/hdl_design_file_list.tcl r]

set old_content [read -nonewline $fd]

close $fd

regsub -all “ ” $old_content {} new_content

regsub -all + $new_content {} new_content

foreach one_file [split $new_content

] {

if {[regexp ^# $one_file] == 0 && $one_file != “

”} {

set exists_num 0

foreach one_prj_file $prj_files {

if {$one_file == $one_prj_file} {

incr exists_num

}

}

if {$exists_num == 0} {

project addfile $one_file

incr add_count

}

} elseif {[regexp ^# $one_file] == 1 && $one_file != “

”} {

set one_file [string trim $one_file “#”]

foreach one_prj_file $prj_files {

if { $one_file == $one_prj_file} {

project removefile $one_file

incr del_count

}

}

}

}

}

puts -nonewline “add ”

puts -nonewline $add_count

puts “ file(s) successfully!”

puts -nonewline “remove ”

puts -nonewline $del_count

puts “ file(s) successfully!”

}

创建了添加源文件的过程。

project filenames是questasim的命令,返回当前工程的文件列表。

regsub -all “ “ $old_content {} new_content,-all 没有这个开关时,regsub只替换第一个匹配,有了这个开关,regsub将把所有匹配的地方全部替换。第二项为正则匹配表达式,第三项为目标字符串,第四项为替换内容。regsub通过第二项进行匹配,将第三项中匹配的目标,替换为第四项,存到第五项中。

proc wave_style_set {} {

global testbench_name default_color

foreach sig [find signals $testbench_name/*] {

switch -regexp -nocase -- $sig {

/*/*rst+ {add wave -radix binary -color [lindex $default_color 0] $sig}

/*/*clk+ {add wave -radix binary -color [lindex $default_color 1] $sig}

/*/*en+ {add wave -radix binary -color [lindex $default_color 2] $sig}

/*/*cnt+ {add wave -radix decimal -color [lindex $default_color 3] $sig}

/*/*data+ {add wave -radix hex -color [lindex $default_color 4] $sig}

/*/*flag+ {add wave -radix binary -color [lindex $default_color 5] $sig}

default {add wave -radix hex -color [lindex $default_color 6] $sig}

}

}

}

创建了一个修改波形格式的过程。

switch -regexp -nocase — $sig ,和c语言的switch一样。TCL 支持三种匹配方式:-exact 方式, -glob方式, -regexp 方式,缺省情况表示-glob 方式。-exact 方式表示的是精确匹配, -glob 方式的匹配方式和 string match命令的匹配方式相同, -regexp 方式是正则表达式的匹配方式。-nocase是regexp的匹配选项,是大写字母也被当作小写来处理,相当于不区分大小写字符。最后一个变量就是被用来作测试的值 。每行的开头,比如/*/*rst+ ,用这个正则匹配进行选择。

lindex $default_color 0引用列表default_color 的第0项。

alias ne “new_prj”

alias es “encrypt_src”

alias af “add_file”

alias br “backup_prj”

alias cf “create_file_list”

alias cc “compile_changed”

alias cr “.main clear”

alias rr “run”

alias ra “run_all”

alias sw “save_wave”

alias aw “load_wave”

alias wr “write_report”

alias df “display_info”

alias dh “do_help”

为过程创建别名。通过别名也能够调用过程

8311e0a8-9dac-11eb-8b86-12bb97331649.gif

编辑:lyn

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • TCL
    TCL
    +关注

    关注

    10

    文章

    1712

    浏览量

    88403

原文标题:TCL简单教程

文章出处:【微信号:HXSLH1010101010,微信公众号:FPGA技术江湖】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    品质管理基础知识

    品质管理基础知识
    的头像 发表于 11-01 11:08 242次阅读
    品质管理<b class='flag-5'>基础知识</b>

    Verilog HDL的基础知识

    本文继续介绍Verilog HDL基础知识,重点介绍赋值语句、阻塞与非阻塞、循环语句、同步与异步、函数与任务语法知识
    的头像 发表于 10-24 15:00 130次阅读
    Verilog HDL的<b class='flag-5'>基础知识</b>

    负载开关基础知识

    电子发烧友网站提供《负载开关基础知识.pdf》资料免费下载
    发表于 10-08 09:56 1次下载
    负载开关<b class='flag-5'>基础知识</b>

    超声波传感基础知识

    电子发烧友网站提供《超声波传感基础知识.pdf》资料免费下载
    发表于 09-04 10:21 0次下载
    超声波传感<b class='flag-5'>基础知识</b>

    C++语言基础知识

    电子发烧友网站提供《C++语言基础知识.pdf》资料免费下载
    发表于 07-19 10:58 6次下载

    FPGA基础知识介绍

    电子发烧友网站提供《FPGA基础知识介绍.pdf》资料免费下载
    发表于 02-23 09:45 29次下载

    鸿蒙开发【设备开发基础知识

    鸿蒙开发基础知识讲解
    的头像 发表于 01-29 18:44 912次阅读
    鸿蒙开发【设备开发<b class='flag-5'>基础知识</b>】

    射频与微波基础知识

    射频与微波基础知识
    的头像 发表于 01-16 10:05 779次阅读
    射频与微波<b class='flag-5'>基础知识</b>

    电气技术基础知识

    电气技术基础知识
    的头像 发表于 12-14 09:11 1462次阅读
    电气技术<b class='flag-5'>基础知识</b>

    电子元器件的基础知识

    电子元器件的基础知识
    的头像 发表于 12-04 10:42 4869次阅读
    电子元器件的<b class='flag-5'>基础知识</b>

    端接电阻基础知识

    电子发烧友网站提供《端接电阻基础知识.doc》资料免费下载
    发表于 11-21 09:31 0次下载
    端接电阻<b class='flag-5'>基础知识</b>

    功放电路的基础知识

    电子发烧友网站提供《功放电路的基础知识.rar》资料免费下载
    发表于 11-20 10:41 10次下载
    功放电路的<b class='flag-5'>基础知识</b>

    电工培训的常用基础知识

    电子发烧友网站提供《电工培训的常用基础知识.pdf》资料免费下载
    发表于 11-18 09:27 20次下载
    电工培训的常用<b class='flag-5'>基础知识</b>

    SPI协议基础知识

    电子发烧友网站提供《SPI协议基础知识.pdf》资料免费下载
    发表于 11-16 10:32 1次下载
    SPI协议<b class='flag-5'>基础知识</b>

    电池的基础知识

    电子发烧友网站提供《电池的基础知识.doc》资料免费下载
    发表于 11-15 11:29 1次下载
    电池的<b class='flag-5'>基础知识</b>