TCL裏的過程,等效於C語言裏的函數(function)
一個標準的proc一般具有如下的特點
proc proc_name {argument} {
......
return return_value
}
1
2
3
4
在使用的時候,直接輸入過程名即可執行。
先來看一個下面的例子,
這是一個標準的過程,get_area就是這個過程名,直接執行它就可以了,這個過程名的作用就是得到整個設計裏邊的cell 的面積,源碼示例如下
proc get_area {} {
set area 0
foreach_in_collection c [get_flat_cell *] {
set area [expr [get_attribute $c area] + $area]
}
puts "cell area is: $area"
return $area
}
define_proc_attributes get_area \
-info "get_area"
1
2
3
4
5
6
7
8
9
10
可以看到,除過計算面積意外,這裏還有一個return和define_proc_attributes ,通過下面的操作來感受一下它們的意義
這個操作,就是使用 [] 來獲取命令的返回值,這個是和shell裏邊的 `` 功能是一樣的。
再來看看以下define_proc_attributes,這個命令可以定義你的proc的釋義等。使用help proc_name來喚出來proc的解釋
這個get_area僅僅就是計算所有cell面積的一個過程,如果只想計算某種特殊名稱的cell 面積呢?沒問題,使用argument輕鬆完成。
先看一下命令使用上的變化
可以看到,這裏使用了pattern 這個參數,但是帶來的便利性是巨大的,用戶可以自行篩選結果,而不用去修改下邊的proc本身。代碼示例如下:
proc get_area {args} {
parse_proc_arguments -args $args opt
set pattern ""
if {[info exists opt(-pattern) ]} {
set pattern $opt(-pattern)
}
set area 0
foreach_in_collection c [get_flat_cell *${pattern}*] {
set area [expr [get_attribute $c area] + $area]
}
puts "Pattarn \"${pattern}\" cell area is: $area"
return $area
}
define_proc_attributes get_area \
-info "get_area for specified pattern" \
-define_args {
{-pattern "instance name pattern" AString string required } \
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
可以看到,在proc get_area 裏邊,加入瞭如下的擴充
parse_proc_arguments -args $args opt
1
這個即使參數解析的命令,通過這個命令,可以很方便的將外界的參數,轉化爲proc內部的數組(array)opt 用戶通過調用這個數組,來實現參數的傳遞
此外,在定義過程屬性的命令裏邊,也多了一些信息
-define_args {
{-pattern "instance name pattern" AString string required } \
}
1
2
3
這個命令就是在定義argument的具體需求,具體格式釋義如下面表格
arg_name option_help value_help data_type attributes
縮略語 描述 示例
arg_name 選項的名稱 -pattern
option_help 選項的描述 “instance name pattern”
value_help 選項值的描述 AString
string 選項值的類別 string
attribute 選項的屬性 required
這裏的選項值的類別和選項的屬性 都是需要符合工具的定義,必須要按照工具定義的來,類別一般分爲:string/int/ boolean等,屬性一般有:required/required等等。如果用戶的輸入和定義的不匹配,工具會報錯。
更進一步,再來一個使用ref_name進行二次過濾,運行結果如下
proc的代碼如下
proc get_area {args} {
parse_proc_arguments -args $args opt
set pattern ""
if {[info exists opt(-pattern) ]} {
set pattern $opt(-pattern)
}
set area 0
if {[info exists opt(-ref) ]} {
foreach_in_collection c [get_flat_cell *${pattern}* -f "ref_name=~*$opt(-ref)*"] {
set area [expr [get_attribute $c area] + $area]
}
puts "Pattarn \"${pattern}\" with ref \"$opt(-ref)\" cell area is: $area"
} else {
foreach_in_collection c [get_flat_cell *${pattern}*] {
set area [expr [get_attribute $c area] + $area]
}
puts "Pattarn \"${pattern}\" cell area is: $area"
}
return $area
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
細心的同學們可能已經注意到了,這裏使用了-ref這個新的argument,但是依然支持不帶-ref的命令行操作
這是因爲下面的代碼的操作:
define_proc_attributes get_area \
-info "get_area for specified pattern" \
-define_args {
{-pattern "instance name pattern" AString string required } \
{-ref "ref name pattern" AString string optional } \
}
1
2
3
4
5
6
這裏的**-ref …optional**就是這個作用,可以使用,也可以不使用,非必須的argument。
在文章的最開始提到proc還有一個不留“殘渣”的作用,說的是proc裏邊的變量都是局部變量,每次執行的時候纔會用到,但是不會影響當前的會話,利用這個特點可以放心的執行,又不用擔心環境被破壞。用戶只需要使用當前proc的返回值就可以了。
foreach t { place CTS route_opt } {
puts "area for $t is [get_area -pattern $t]"
}
1
2
3
執行結果如下,可以看到,每次的返回值都回基於輸入而產生不同,相互之間不影響
從上邊的例子中,同學們已經能感知到proc的強大威力了吧!在真正的工作中,可以使用這些特點,構建自己的強大proc,從而可以更爲方便的運行命令。