如何用TCL PROC函数访问文件并实现LEF引脚属性对比
需求与问题
我原本用Python实现了以下功能:
- 编写
readPinFile函数读取LEF文件,提取引脚的LAYER和RECT信息并存储为字典 - 对比两个LEF文件中引脚的
LAYER与RECT属性,将匹配的引脚输出到file04.txt
现在尝试用TCL的proc实现相同功能,编写的fileinput proc存在问题,且引脚对比部分无法继续,请求完善TCL代码实现对应功能。
Python 实现代码
def readPinFile(filename): result = None with open(filename, "r") as file: result = {} lastPin = None for line in file: lines = line.strip() if lines[:3] == "PIN": lastPin = lines.split(" ")[1] result[lastPin] = {"LAYER": None, "RECT": None} if lines[:5] == "LAYER": result[lastPin]["LAYER"] = lines.split(" ")[1] if lines[:4] == "RECT": result[lastPin]["RECT"] = lines.split(" ") return result pin_of_file1 = readPinFile("osi_hbmp_top_briscm_1.lef") #lef file1 pin_of_file2 = readPinFile("osi_hbmp_top_briscm_2.lef")#lef file2
引脚对比代码
with open("file04.txt", "r+") as output_file4: #compare same pins with layer and location for pin, pin_data in pin_of_file1.items(): if pin in pin_of_file2: if pin_of_file2[pin]["LAYER"] == pin_data["LAYER"] and pin_of_file2[pin]["RECT"] == pin_data["RECT"]: output_file4.write(pin + "\n\n")
我编写的TCL代码(存在问题)
读取文件的proc
proc fileinput {filename} { set filedata [open filename r] set file1 [ read $filedata ] foreach line [split $file1 \n] { set pindata { PIN { LAYER {} RECT {} }} if {[string match *PIN* $line]} { dict lappend pindata PIN $line } if {[string match *LAYER* $line]} { dict lappend pindata PIN {LAYER{$line}} } if {[string match *RECT* $line]} { dict lappend pindata PIN {RECT{$line}} } } return $pindata } set fileinput1 [fileinput osi_hbmp_top_briscm_1.txt] set fileinput2 [fileinput osi_hbmp_top_briscm_2.txt]
未完成的引脚对比代码
foreach $pin, $pin_data [gets $fileinput1] if{[string match $pin $fileinput2]}
完善后的TCL代码实现
1. 读取LEF文件的proc
该proc逻辑与Python版本对齐,按引脚名分组存储LAYER和RECT信息:
proc readPinFile {filename} { set result [dict create] set lastPin "" set f [open $filename r] while {[gets $f line] >= 0} { set line [string trim $line] if {$line eq ""} { continue } # 匹配PIN行,提取引脚名并初始化属性 if {[string match "PIN *" $line]} { set parts [split $line] set lastPin [lindex $parts 1] dict set result $lastPin LAYER "" dict set result $lastPin RECT "" } # 匹配LAYER行,更新对应引脚的层信息 if {[string match "LAYER *" $line] && $lastPin ne ""} { set parts [split $line] dict set result $lastPin LAYER [lindex $parts 1] } # 匹配RECT行,更新对应引脚的坐标信息 if {[string match "RECT *" $line] && $lastPin ne ""} { set parts [split $line] dict set result $lastPin RECT $parts } } close $f return $result }
2. 读取文件并对比引脚属性
# 读取两个LEF文件的引脚数据 set pinData1 [readPinFile "osi_hbmp_top_briscm_1.lef"] set pinData2 [readPinFile "osi_hbmp_top_briscm_2.lef"] # 打开输出文件 set outFile [open "file04.txt" w] # 遍历第一个文件的引脚,对比属性并输出匹配项 dict for {pinName pinAttrs} $pinData1 { if {[dict exists $pinData2 $pinName]} { set layer1 [dict get $pinAttrs LAYER] set rect1 [dict get $pinAttrs RECT] set layer2 [dict get $pinData2 $pinName LAYER] set rect2 [dict get $pinData2 $pinName RECT] if {$layer1 eq $layer2 && $rect1 eq $rect2} { puts $outFile "$pinName\n\n" } } } close $outFile
关键修正点
- 原
fileinputproc每次循环重置pindata、字典操作逻辑错误,未按引脚名分组存储属性;修正后使用dict set实现嵌套属性存储,逻辑与Python完全对齐 - 采用逐行读取(
gets)替代一次性读取,适配大文件场景 - 对比部分使用
dict for遍历字典,dict exists检查引脚存在性,直接对比属性值实现匹配判断
内容的提问来源于stack exchange,提问作者user19842766
相关产品推荐
相关产品推荐

