静态时序分析简明教程-浅议tcl语言
- 一、写在前面
- 1.1 快速导航链接·
- 二、Tcl基础知识
- 三、Tcl的语言结构
- 3.1 Tcl变量
- 3.2 Tcl表达式与运算符
- 3.3 Tcl的控制流语句
- 3.3.1 列表遍历
- 3.3.2 决策
- 3.3.3 Tcl循环
- 3.3.4 Tcl过程
- 3.4 其他Tcl命令
- 3.4.1 open/close
- 3.4.2 gets/puts
- 3.4.3 catch
- 3.4.4 info
- 3.4.5 source
- 3.4.6 incr
- 3.4.7 exit
- 四、总结
一、写在前面
一个数字芯片工程师的核心竞争力是什么?不同的工程师可能给出不同的答复,有些人可能提到硬件描述语言,有些人可能会提到对于特定算法和协议的理解,有些人或许会提到对于软硬件的结合划分,作者想说,这些说法,其实对也不对,硬件描述语言,翻来覆去无非是always和assign这几个语句的反复使用,而一些基础的协议算法,深究起来其实也并不复杂,于作者而言,在常规的技能以外,有两项额外的技能颇为重要,其中之一便为sdc/STA的分析能力,它的重要之处在于作为桥梁建立了前端和后端的连接,虽然对于DE工程师而言,初版交付的sdc往往不甚准确,也没有办法通过这份sdc生成一份无误的timing report,但sdc的内容体现却是完完整整的将时序约束从行为级的描述映射到了gate level这样一个真实的电路层次上面。
写此专栏,一为学习记录,二为交流分享,以犒粉丝读者。
1.1 快速导航链接·
静态时序分析简明教程(一)绪论
静态时序分析简明教程(二)基础知识:建立保持时间,违例修复,时序分析路径
静态时序分析简明教程(三)备战秋招,如何看懂一个陌生的timing report
静态时序分析简明教程(四)时钟常约束
静态时序分析简明教程(五)生成时钟
静态时序分析简明教程(六)时钟组与其他时钟特性
静态时序分析简明教程(七)端口延迟
静态时序分析简明教程(八)虚假路径
静态时序分析简明教程(九)多周期路径
静态时序分析简明教程(十)组合电路路径
静态时序分析简明教程(十一)模式分析与约束管理
静态时序分析简明教程(十二)浅议tcl语言
二、Tcl基础知识
SDC的约束基于Tcl语言。通过使SDC扩展到Tcl,基于工具的命令可以和原生Tcl的结构,如变量,表达式,语句和子程序相混合,实现更为强大的功能,因此,作为SDC约束的提供方,对Tcl命令的理解,本身也是IC技能中颇为重要的一个方面。
Tcl是由加州大学伯克利分校开发的常用脚本语言,它是一种解释语言,每条语句被以此解析并立即执行, 在Tcl脚本遇到第一个错误的时候就会立刻停止。
Tcl脚本遵循一些基本的语义,总结起来是以下四点
- 每条Tcl以换行符或分号结束;
- 如果一条语句跨越多行,然后再下一行继续执行,需要在行尾加反斜杠
- 双引号和大括号括住的包括多个单词的字符串被认定为单元
- #开头的语句是注释
给出两个简单的例子,帮助读者们快速get以上四条的含义
puts “Hello World!”; # 这是一条注释
puts {Hello, World!}
三、Tcl的语言结构
Tcl的语言结构可以区分为以下几种
- 变量
- 列表
- 表达式与运算符
- 控制流语句
- 过程
接下来我们将逐一讲解其含义
3.1 Tcl变量
Tcl变量是ASCII字符串,变量使用set命令来分配(Example1),如果要对变量求值,需要使用“$“符号(Example2),因为”$“的特殊含义,因此假如想要打印这个变量,需要”\$",多一个“\”符号(Example3)
Example1:
set abc “1234” #set是命令,abc是变量,1234是分配给变量的值
Example2:
puts $abc #将打印1234
Example3:
puts “I have a \$bill”
3.2 Tcl表达式与运算符
Tcl中使用expr命令来对表达式求值
set x 10
# 两条语句的返回值都为30
expr $x + 20
expr [$x + 20]
两条expr命令将返回相同的值,但是Tcl建议表达式使用大括号,这有助于程序更快地执行。
下面的表格将列出Tcl所支持的运算符
运算符 | 描述 |
---|---|
- + ~ ! | 一元减,一元加,按位取反,逻辑非 |
+ - * / | 加 减 乘 除 |
** | 指数 |
<> <= >= == != | 关系运算符:小于、大于、小于或等于、大于或等于、等于、不等于 |
eq,ne | 比较两个字符串相等(eq)或不相等(ne) |
in,ni | 检查列表中包括(in)不包括字符串的运算符。返回1为真,0为假 |
&|^ | 按位与、或、异或 |
&&,|| | 逻辑与、或 |
<< >> | 左移右移 |
3.3 Tcl的控制流语句
Tcl的控制流语句由以下种类的结构组成
1.列表遍历
2.决策
3.循环
4.子程序
3.3.1 列表遍历
Tcl提供了foreach结构来遍历列表,案例如下
# 创建一个包含元素的列表
set my_list {apple banana orange}# 使用 foreach 命令遍历列表
foreach item $my_list {# 输出当前列表元素puts "Item: $item"
}
它会有如下的输出结果
Item: apple
Item: banana
Item: orange
3.3.2 决策
Tcl提供if-else if-else的结构来提供决策能力,举例如下:
# 假设有一个变量 age 表示年龄
set age 25# 使用 if-else if-else 结构进行决策
if {$age < 18} {puts "未成年人"
} elseif {$age >= 18 && $age < 60} {puts "成年人"
} else {puts "老年人"
}
其输出的结果如下:
成年人
3.3.3 Tcl循环
当程序想在一个条件下循环和终止时,可以使用Tcl提供的for和while语句,它还提供了两个额外的结构,break和continue,其中break用提提前结束循环,而continue用于停止执行当前代码的循环,并重新评估当前循环的代码。
for语句的循环举例如下:
# 使用 for 循环输出数字从1到5
for {set i 1} {$i <= 5} {incr i} {puts $i
}
运行上面的代码会产生如下的输出
1
2
3
4
5
while语句的循环举例如下:
# 使用 while 循环计算数字的阶乘
set num 5
set factorial 1
while {$num > 0} {set factorial [expr $factorial * $num]incr num -1
}
puts "5的阶乘是: $factorial"
它会产生如下的输出结果
5的阶乘是: 120
break语句的举例如下
# 使用 while 循环打印数字,直到遇到数字 4 时终止循环
set i 1
while {$i <= 10} {puts $iif {$i == 4} {break ;# 当 i 等于 4 时终止循环}incr i
}
在这个示例中,我们使用 while 循环打印数字从 1 到 10。然而,当 i 的值等于 4 时,我们使用 break 语句提前终止了循环的执行,因此循环只会打印数字 1 到 3。以上的代码将会输出如下的结果
1
2
3
4
3.3.4 Tcl过程
在Tcl中,过程可以通过 proc 命令定义,用于封装一系列命令,形成一个可重复使用的代码块,以下是一个例子
# 定义一个计算两个数之和的过程
proc add_numbers {num1 num2} {set sum [expr $num1 + $num2]return $sum
}# 调用定义的过程来计算和
set result [add_numbers 10 20]
puts "计算结果是: $result"
在这个示例中,我们首先使用 proc 命令定义了一个名为 add_numbers 的过程,该过程接受两个参数 num1 和 num2,并计算它们的和。然后,我们在代码的后续部分调用了这个过程,传递了参数 10 和 20,并将计算结果存储在变量 result 中。
其结果输出如下:
计算结果是: 30
3.4 其他Tcl命令
以下是一些常用的Tcl命令
3.4.1 open/close
文件句柄,用来打开和关闭文件
#以写模式打开文件"file.txt"
set fhandle [open "file.txt" w]
#关闭文件句柄
close $fhandle
3.4.2 gets/puts
获取字符串或打印字符串,举例如下:
# 提示用户输入姓名
puts "请输入您的姓名:"
# 使用 gets 命令读取用户输入的一行数据
gets stdin name# 提示用户输入年龄
puts "请输入您的年龄:"
# 使用 gets 命令读取用户输入的一行数据
gets stdin age# 使用 puts 命令输出用户输入的信息
puts "您的姓名是:$name"
puts "您的年龄是:$age"
在这个示例中,我们首先使用 puts 命令提示用户输入姓名,并使用 gets 命令从标准输入读取用户输入的姓名。然后,我们再次使用 puts 命令提示用户输入年龄,并使用 gets 命令从标准输入读取用户输入的年龄。最后,我们使用 puts 命令将用户输入的姓名和年龄输出到标准输出。
运行上述代码将会产生类似于以下的交互过程:
请输入您的姓名:
John Smith
请输入您的年龄:
28
您的姓名是:John Smith
您的年龄是:28
3.4.3 catch
在Tcl中,catch 命令用于捕获可能引发异常的代码块,并在发生异常时进行处理。以下是一个使用 catch 命令的示例
# 尝试将一个非数字字符串转换为整数
set input "abc"
catch {set number [expr $input]
} result# 检查是否捕获到异常
if {[catch "set number [expr $input]" result]} {puts "捕获到异常:$result"
} else {puts "转换结果为:$number"
}
在这个示例中,我们首先尝试将字符串 “abc” 转换为整数,这是不合法的操作,会引发异常。我们使用 catch 命令来捕获可能发生的异常,并将异常信息存储在变量 result 中。然后,我们检查是否捕获到异常,如果捕获到异常,则输出异常信息;否则,输出转换结果。
运行上述代码将会输出:
捕获到异常:expected integer but got "abc"
3.4.4 info
从Tcl解释器获取信息所使用的命令
info commands <pattern>: 返回名称与pattern格式匹配的命令列表
info exists <name>:如果name作为变量存在,则返回1,否则返回0
info procs <pattern>:返回与pattern格式匹配的Tcl过程列表
3.4.5 source
在 Tcl 编程语言中,source 命令用于在当前脚本中执行另一个 Tcl 脚本文件。通过使用 source 命令,可以将另一个脚本文件中的代码嵌入到当前脚本中执行,从而实现模块化和代码重用。
3.4.6 incr
在 Tcl 编程语言中,incr 是一个内置命令,用于增加变量的值。它可以用于增加整数变量或双精度浮点数变量的值。
# 增加整数变量的值
set count 5
incr count ;# 将 count 增加 1
puts "增加后的值是: $count"# 增加整数变量的值,并指定增量
set value 10
incr value 2 ;# 将 value 增加 2
puts "增加后的值是: $value"# 增加双精度浮点数变量的值
set total 3.5
incr total 1.2 ;# 将 total 增加 1.2
puts "增加后的值是: $total"
上面的代码会输出如下的结果
增加后的值是: 6
增加后的值是: 12
增加后的值是: 4.7
3.4.7 exit
exit 是一个内置命令,用于终止当前脚本的执行,并退出 Tcl 解释器。您可以使用 exit 命令来在特定条件下终止脚本的执行,或在脚本执行完毕后退出解释器。
四、总结
本文中,我们总结了Tcl语句的相关使用方法,提供了大量的案例来讲解:Tcl的变量、表达式、运算符列表遍历、决策、循环、Tcl过程,其中还会涉及到额外的语句如open/close、gets/puts、catch、info、source、incr、exit。