[ Skill ] 遍历整个项目设计的两个思路
https://www.cnblogs.com/yeungchie/
RecursiveProject 递归项目
- code
;--------------------------------------
; Program : ycRecursiveProject.il
; Language : Cadence Skill
; Author : YEUNGCHIE
; Version : 2020.12.20
;--------------------------------------
procedure(ycRecursiveProject(\@optional cv(geGetEditCellView()) "d")
prog((insts viewNames viewName master)
unless(boundp('masters) masters = nil)
unless(boundp('ignoreLibNames) ignoreLibNames = nil)
; 优先处理顶层的操作放这里
printf("Opened \t libName : %s \t cellName : %s \n" cv~>libName cv~>cellName)
; dbCreateRect(cv "MET6" list(0:0 10:300))
;;;;;;;;;;;;;;;;;;;;;;;;;;
insts = cv~>instances
foreach(inst insts
case(cv~>cellViewType
("schematic"
; schematic 虽然调用的是 symbol ,但需要处理的是 schematic
viewNames = inst~>master~>cell~>views~>name
if(member("schematic" viewNames)
viewName = "schematic"
viewName = nil
)
)
("maskLayout"
viewName = inst~>viewName
)
)
if(viewName
master = dbOpenCellViewByType(
inst~>libName
inst~>cellName
viewName
nil
"r" ; 这里用的是只读模式,需要编辑内容的时候改为追加模式 "a" 即可。
)
master = nil
)
when(master && !member(master masters)
unless(member(inst~>libName ignoreLibNames)
ycRecursiveProject(master)
)
)
)
; 优先处理底层的操作放这里
;;;;;;;;;;;;;;;;;;;;;;;;;;
masters = append1(masters cv)
;-----------------
; 看情况保存。
; dbSave(cv)
; dbClose(cv)
)
); ycRecursiveProject
- run
; 不太喜欢全局变量,所以套一个 let
let((masters ignoreLibNames)
; ignoreLibNames 用来指定忽略不需要打开哪些库中的 cellView
ignoreLibNames = list("techLib" "basic" "analogLib")
ycRecursiveProject()
)
如果项目不大的可以用上面的 RecursiveProject 方式来处理,当项目比较大的时候递归的效率可能非常的低,此时推荐下面的 TraverseHierarchyTree ,Virtuoso 可以获取到 Tree 文件,通过它来依次打开每个 cellView 。
曾经递归一个芯片顶层,几天还没跑完,也可能是我 Memoization 没做好,后来决定换用下面的方式,结果只跑了不到半小时。
TraverseHierarchyTree 遍历层次树
版图 Tree 文件推荐使用 CIW --> Tools --> Print Hierarchy Tree 这个菜单的工具来导出,
Shift<Key>T
导出的方式实测存在 Bug 可能会丢失一些单元。
电路 Tree 导出没有上面这个问题。
- code
;-------------------------------------------
; Program : ycTraverseHierarchyTree.il
; Language : Cadence Skill
; Author : YEUNGCHIE
; Version : 2021.01.26
;-------------------------------------------
procedure(ycTraverseHierarchyTree(treeFile \@optional ignoreLibNames(nil) "tg")
prog((file str libCellView hierList libName cellName viewName cv )
; 首先读入 tree 文件,提取 cellView 调用信息。
isFile(treeFile) || error("%s is balabala !\n" treeFile)
file = infile(treeFile)
while(gets(str file)
if(rexMatchp("^\\*.+" str)
then
hierList = nil
else
libCellView = parseString(str)
hierList = append1(hierList
list(
nth(0 libCellView)
nth(1 libCellView)
nth(2 libCellView)
)
)
)
); while
close(file)
unless(listp(ignoreLibNames) ignoreLibNames = list(ignoreLibNames))
foreach(x artUnique(hierList)
libName = nth(0 x)
unless(member(libName ignoreLibNames)
cellName = nth(1 x)
viewName = if(nth(2 x) == "symbol" "schematic" nth(2 x))
when(cv = dbOpenCellViewByType(libName cellName viewName nil "r") ; 同理需要编辑操作改成 "a"
; 开始搞事情。
;-----------------
; 看情况保存。
; dbSave(cv)
; dbClose(cv)
)
)
); foreach hier
)
); ycTraverseHierarchyTree
- run
ycTraverseHierarchyTree("hier.tree" list("techLib" "basic" "analogLib"))