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,進而可以更為友善的運作指令。