脚本练手-提取pcell中的金属1信息

bigtd 2020-04-11 10:15
158

本脚本编写目标

1. 提取PCELL中的金属1信息,在顶层生成一致的金属1图层,暂时只考虑金属层图形为矩形;

2. 同时处理多个选中的instance

3. 能处理各种旋转角度

 

编写过程:

1. 先考虑一个instance的情况,本步骤只考虑“R0”情况

鼠标选中一个instance,skill获取这个instance的id,相关语句如下:

tdid=car(geGetSelSet())

;geGetSelSet(),该函数用于获取当前选中的列表

; car,用于获取目标列表中的第一个元素

定义金属1的变量值:

td_mt=“M1”

下一步要获取PCELL实例中所有金属1的形状,实现办法是先获取所有形状

tdshapelist=tdid~>master~>shapes

;master是pcell在数据库中虚拟化的一个视图,与一般instance的区别是,该视图的相关信息与原视图并不一致,而是与相关的参数有关,比如宽长不同器件的各个图层都会有所不同。而一般器件还有一个办法是可以打开对应的layout视图来获取shapes信息,而pcell必须用master。

现在遍历所有shape,如果shape的layerName与金属1名称一致,那么就生成相应的图层。

采用以下结构进行处理

foreach(tdshapeid tdshapelist

  when(tdshapeid~>layerName==td_mt

    执行生成矩形图层的语句

 )

)

对于一个矩形图层,其坐标信息与bBox一致,因此我采用bBox作为该矩形图形的坐标信息,利用bBox的左下角和右上角的信息左右矩形参数

相关语句如下

tdbB=tdshapeid~>bBox

;获取bBox坐标信息

tdx1=car(car(tdbB))
 tdx2=car(car(cdr(tdbB)))
 tdy1=car(cdr(car(tdbB)))
tdy2=car(cdr(car(cdr(tdbB))))

;获取矩形左下角和右上角的xy坐标。

;cdr,用户获取目标List中的最后一个元素,与car不同的是,它获取的还是一个List,因此对于不能使用list的情况,还需要用一个car真正获取最后一个元素。

需要注意的是,上述获取的坐标信息只是底层master中的坐标信息,而不是当前视图下的坐标信息,需要根据当前instance的坐标信息来做更新

tdx=car(tdid~>xy)
tdy=car(cdr(tdid~>xy))

tdx1=car(car(tdbB))+tdx
tdx2=car(car(cdr(tdbB)))+tdx
tdy1=car(cdr(car(tdbB)))+tdy
tdy2=car(cdr(car(cdr(tdbB))))+tdy

;tdx和tdy是当前instance的xy坐标值

最后一个就是生成矩形图形

tdmout=dbCreateRect(tdid~>cellView td_mt list(tdx1:tdy1 tdx2:tdy2))

;dbCreateRect(),该函数用于生成一个矩形图形,函数格式dbCreateRect(cellView_id LayerName 坐标列表)

2. 下面分析以下旋转角度的问题

旋转角度总共有八种,最简单的思路是可以分别对待处理,比如用when语句来分别处理坐标信息

when(tdid~>orient=="R0"

 执行获取坐标语句

)

…………

when(tdid~>orient=="MXR90"

 执行获取坐标语句

)

上述办法虽然可行,但有些繁琐。这里我们采用新建一个单元来生成图形,然后调入这个单元并打散来规避繁琐的旋转角度问题。

首先定义个临时cell的名字,我这里是采用一个固定名称“zcell_tempcellformt”

td_tgn="zcell_tempcellformt"

td_tgcv=dbOpenCellViewByType(tdid~>cellView~>libName td_tgn "layout" "maskLayout" "w")

;在当前lib下打开一个zell_tempcellformt单元的layout视图,以覆盖方式打开。

需要注意的是,上一个步骤中生成坐标时考虑了所选instance的坐标信息,但是这里我们只需要提取shape中的坐标信息就可以了,所选器件的坐标可以在调入新生成单元的过程中定义。

tdbB=tdshapeid~>bBox
tdx1=car(car(tdbB))
tdx2=car(car(cdr(tdbB)))
tdy1=car(cdr(car(tdbB)))
tdy2=car(cdr(car(cdr(tdbB))))

tdmout=dbCreateRect(td_tgcv td_mt list(tdx1:tdy1 tdx2:tdy2))

;上述语句是定义坐标参数和生成图形的语句,需要注意的除了坐标运算有所改变外,还需要注意的是dbCreateRect中对应的单元视图id跟之前不同。

完成shape遍历后,保存新建的单元

dbSave(td_tgcv)

在操作单元中调入上述新建的单元,旋转方向与所选单元一致,坐标也一致。

td_inst_add=dbCreateInst(tdid~>cellView td_tgcv td_tgn tdid~>xy tdid~>orient)

关闭新建单元的id

dbClose(td_tgcv)

打散新调入的Instance

td_slt=dbFlattenInst(td_inst_add 1)

3. 上面解决了旋转角度的问题,下面解决多个器件的问题,在此假定所有的pcell都是instance类型,并且存在同一个工艺库中,并且当前视图中不存在group。希望实现的功能是ctrl+a全选后,脚本运行后在所有Pcell上提取金属1的图形。

思路如下,遍历所有选中的内容,如果是instance并且是目标工艺库中的单元的话,则执行金属1的提取

tdidlist=geGetSelSet()

;获取所有的已选对象列表

foreach(tdid tdidlist

 when(tdid~>objType=="inst" && tdid~>libName=="process_library"

  金属1提取语句

 )

;遍历所有已选对象

;when语句中判断对象是不是inst类型并且在工艺库中。

完整脚本总共24行,load执行之前需要更改第二行td_mt后面的金属1名称,默认是“M1”,第三行libName后面的工艺库名称,默认是“process_library”。

本脚本在IC6.1.8-64b.500.4环境下编写,估计IC6系列应该都可以运行。

 

每一个脚本都有更好的方案,欢迎大神们指导。

完整源码:

tdidlist=geGetSelSet()
td_mt="M1"
foreach(tdid tdidlist
    when(tdid~>objType=="inst" && tdid~>libName=="process_library"
        tdshapelist=tdid~>master~>shapes
        td_tgn="zcell_tempcellformt"
        td_tgcv=dbOpenCellViewByType(tdid~>cellView~>libName td_tgn "layout" "maskLayout" "w")
        foreach(tdshapeid tdshapelist
            when(tdshapeid~>layerName==td_mt
                printf("%s",tdshapeid~>layerName)
                tdbB=tdshapeid~>bBox
                tdx1=car(car(tdbB))
                tdx2=car(car(cdr(tdbB)))
                tdy1=car(cdr(car(tdbB)))
                tdy2=car(cdr(car(cdr(tdbB))))
                tdmout=dbCreateRect(td_tgcv td_mt list(tdx1:tdy1 tdx2:tdy2))
            )
        )
        dbSave(td_tgcv)
        td_inst_add=dbCreateInst(tdid~>cellView td_tgcv td_tgn tdid~>xy tdid~>orient)
        dbClose(td_tgcv)
        td_slt=dbFlattenInst(td_inst_add 1)
    )
)

评论
暂无任何评论
已成功加入购物车!