cj_181888888的个人空间 https://blog.eetop.cn/1760954 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

一些脚本

热度 5已有 1094 次阅读| 2022-10-11 10:59 |系统分类:芯片设计

名字:PutOnGrid.il
语言:SKILL
功能:消除版图中的off grid
内容:


procedure( OnGrid( Point )
if( listp( Point ) then
mapcar( lambda( (x) OnGrid(x) ) Point)
else
round((Point/Grid))*Grid
)
)

procedure( PutOnGrid( Grid )
let(( SelectObj )
SelectObj = geGetSelSet()
foreach( Object SelectObj
cond(
(Object~>objType == "path"
Polygon = leConvertShapeToPolygon(Object)
Polygon~>points = OnGrid(Polygon~>points)
)

(Object~>objType == "polygon"
Object~>points = OnGrid(Object~>points)
)

(Object~>objType == "rect"
Object~>bBox = OnGrid(Object~>bBox)
)

(Object~>objType == "inst" || Object~>objType == "mosaic"
Object~>xy = OnGrid(Object~>xy)
)
)
)
)
)


使用方法:在CIW中load这个il文件。使用时输OnGrid(0.005),如果你的最小格点是0.005的话。



名字:layout_cross_ruler.il
语言:skill
功能:显示以点击出为交点的十字交叉尺子
内容:
procedure(layout_cross_ruler()
        let((cv bbox xy xLL yLL xUR yUR)
        cv = geGetEditCellView()
        bbox = cv~>bBox
        xy = hiGetPoint(getCurrentWindow())
        xLL = caar(bbox)
        yLL = cadar(bbox)
        xUR = caadr(bbox)
        yUR = cadadr(bbox)
        leCreateRuler(cv list(xy xLL:cadr(xy)))
        leCreateRuler(cv list(xy xUR:cadr(xy)))
        leCreateRuler(cv list(xy car(xy):yLL))
        leCreateRuler(cv list(xy car(xy):yUR))
        ))

hiSetBindKey("layout" "<Key>v" "layout_cross_ruler()")

使用方法:
在CIW中加载
load "layout_cross_ruler.il"
在版图中按 v


load 脚本


示例显示1

示例显示2

随便选一层layer画个框框,框处要抓取坐标的区域,然后在LSW选中PAD laye

随便选一层layer画个框框,框处要抓取坐标的区域,然后在LSW选中PAD layer

执行快捷键 ctrl+g, 所有的label 会调整到PAD中心点

执行快捷键 ctrl+g, 所有的label 会调整到PAD中心点

执行脚本后弹出pad location文件,保存在当前目录下

执行脚本后弹出pad location文件,保存在当前目录下





/*

Dcript name: ok_GetPadLocation.il

Author: Okfunny

Date: 2018-03-01

Description: This script is used to get PAD coordinate, user can set PAD layer, Pin layer, extraction range and, 

    It contains a very useful function which can use to copy specific layer hierarchially.

    It is also quick start of learning skill, welcome to use and modify it ^_^

Usage:

Copy layer from sub block

1. select the layer you want to copy in LSW

2. draw a rectangle in a auxiliary layer to determine which region is copid from

3. select the rectangle

4. invoke the function ok_CopyFig(32)


Get pad location

1. select the PAD layer in LSW

2. draw a rectangle in a auxiliary layer to determine which region is copid from

3. select the rectangle

4. invoke the function ok_GetPadLocation(32)


the output looks like:

create time: Mar  1 22:32:59 2018

there are total 24 pads

Name                    centerX    centerY      width     length

PAD_4                   581.750     58.945     52.000     73.000

PAD_14                  581.750    168.945     52.000     73.000

PAD_24                  581.750    264.985     52.000     73.000


*/


; skill use semicolon to represent comments, use can delete these comments


; these are built-in fuctions used in this script, you can find usage in cadence help system: cdnshelp

; car  cadr cadar cadadr last list listp nconc append1 error geGetSelSet geGetEditCellView 

; dbGetOverlaps dbGetHierPathTransform dbCopyFig dbCreateLabel dbDeleteObject

; hiDisplayMenu hiCreateSimpleMenu hiSetBindKey centerBox

; leMergeShapes geDeselectAll setof  strcat outfile fprintf getCurrentTime

; length leIsPointInsideFig dbDeleteObject close view


; user defined functions start with prefix ok_


; this is our first user defined fuction, procedure is a keyword to define a function

; ok_FlatList is function name, testList is argument

; this function is used to flatten a nested list

procedure(ok_FlatList(testList)

    ; let limits the variable range, and the last value is the return value of the fuction

    ; listNew is a local variable which means it cannot be read and modified outside the function

    ; It is a good habit to use local variable instead of global variable

    let((listNew)

        listNew=nil

        ;listp is used to determine if it is a list

        if(listp(testList)

            then

                foreach(cell testList

                    if(listp(cell)

                        then

                            ; nconc is used to concatenate two list

                            listNew=nconc(listNew ok_FlatList(cell))

                            ; append1 is used to append a item to a list

                        else

                            listNew=append1(listNew cell)

                    )

                )

            else

                ; error throw out a message if listNew is not a list

                error("ok_FlatList(): argument must be a list")

        )

        listNew

    )

)

;;Example

;;tlist=list("a" "b" list(1 2 list("c" 3) list("aa" "bb")))

;;ok_FlatList(tlist)



; this is out second user definde function, and the first functon can be involed as a built-in function 

; this function is use to get the last item in a nested list

procedure(ok_GetLast(testList)

    car(last(ok_FlatList(testList)))

)

;;Example

;;tlist=list(list(1,2), list(3,4,5,list(6,7)))

;;ok_GetLast(tlist)


procedure(ok_CopyFigSingal(object x_Depth l_LPP)

    ; prog is similar with let, but it can use the keyword return to return value in anywhere

    prog((cv objHier transList objList objTransList objTransLista newObj list1 listNew)


        ; geGetEditCellView is used to get current view ID, in this case, it means layer view window ID

        ; ~> is operational character which used to access a structure's attributes

        ; geGetEditCellView()~>?  can get all attributes name

        ; geGetEditCellView()~>?? can get all attributes name and value

        ; geGetEditCellView()~>bBox get current window size in a list (X_lowerleft:Y_lowerleft X_upperrignt:Y_upperright)

        cv=geGetEditCellView()


        ; get layers in l_LPP layer, in x_Depth level, in current window cv, in bBox region

        objHier=dbGetOverlaps(cv object~>bBox l_LPP x_Depth t)


        transList=nil


        ; for each obj in in selected objects, loop operating the item

        ; get the transform of the object, transform is a list such as (x:y rotation magnification)

        foreach(obj objHier transList=nconc(transList list(dbGetHierPathTransform(obj))))


        objList=nil

        foreach(obj objHier objList=nconc(objList list(ok_GetLast(list(obj)))))


        ; create a list with shape and it's transform

        objTransList=mapcar('list objList transList)

        objTransLista=setof(x objTransList ! member(car(x)~>objType list("inst" "mosaic")))


        ; copy shape

        newObj=foreach(mapcar xxx objTransLista dbCopyFig(car(xxx) cv cadr(xxx)))


        ; return the new copied layers as a list

        listNew=nconc(list(object) list(newObj))

        return(listNew)

    )

)



; this is our first usefull function which can copy layers hierarchially

procedure(ok_CopyFig(@optional 

    ; x_depth is the maximum level, default is 32

    ; l_lpp is the layer which you want to copy, default is current layer selected in LSW

    ; d_objects a auxiliary layer whose bBox is used to determine which range to copy from

    (x_depth 32) (l_lpp leGetEntryLayer()) (d_objects geGetSelSet()))


    prog((listNew)


        ; if the mode is readonly, it do nothing and pop-up a window

        if(geGetEditCellView()~>mode=="r"

            then

                ; pop-up a window

                hiDisplayMenu(hiCreateSimpleMenu(

                    'menu "" list("   read only   ") list(""))

                )

            else

                listNew=nil


                foreach(obj d_objects

                    listNew=nconc(listNew list(ok_CopyFigSingal(obj x_depth l_lpp)))

                    )

                return(listNew)

        )

    )

)



procedure(ok_GetPadLocation(@optional

    ;optional arguments, if invoke it without any arguments, it will use default value

    ;pinLPP is Pin label layer in top level, default is AP:pin

    ;depth is the maximum level, default is 32

    (pinLPP list("AP" "pin")) (depth 32)) 


    prog((cv pad_tmp pad labelInCV file outf bbox centerX centerY name)

    cv=geGetEditCellView()


    ; copy all PAD to current level to calculate

    pad_tmp=cadar(ok_CopyFig(depth))


    ; merge copied layers

    pad=leMergeShapes(pad_tmp)

    geDeselectAll()


    ; filter the labels

    labelInCV=setof(x cv~>shapes x~>objType=="label" && x~>lpp==pinLPP)



    ; create a file to store the pad location, the file name is cellname + _padLoacation

    file=strcat(cv~>cellName "_padLoacation")


    ; open the file to write to

    outf=outfile(file)


    ; fprintf is used to write to a file in specific format

    fprintf(outf "create time: %s\n" getCurrentTime())


    ; get the count of pads

    fprintf(outf "there are total %d pads\n" length(pad))


    fprintf(outf "%-20s %10s %10s %10s %10s\n" "Name" "centerX" "centerY" "width" "length")


    foreach(shape pad

        ; calculate the pad coordinate and size

        bbox=shape~>bBox

        centerX=car(centerBox(bbox))

        centerY=cadr(centerBox(bbox))

        width=caadr(bbox) - caar(bbox)

        length=cadadr(bbox) - cadar(bbox)


        ; use this flag to determine if the label is in the pad region

        p_count=1


        ; if the label is inside the pad, then get the pad name

        foreach(label labelInCV

            if(leIsPointInsideFig(shape label~>xy)

                then

                    label~>xy=centerX:centerY

                    p_count=p_count+1

                    name=label~>theLabel

            )

        )


        if(p_count==0

            then

                fprintf(outf "%-20s %10.3f %10.3f %10.3f %10.3f\n"

                            "NC" centerX centerY width length)

            else

                fprintf(outf "%-20s %10.3f %10.3f %10.3f %10.3f\n"

                            name centerX centerY width length)

        )

    )


    ; delete the copied pad layer

    foreach(x pad dbDeleteObject(x))


    ; close the file

    close(outf)



    ; view the location file

    view(file)


    printf("Please find result: %s\n" file)

    )

)


;set a bindkey with default setting: pin layer AP:pin, pad layer is current layer in LSW

hiSetBindKey("Layout" "Ctrl<Key>b" "ok_GetPadLocation()")


;set a bindkey with default setting, only copy layer from level 1, layer is current layer in LSW

hiSetBindKey("Layout" "Ctrl<Key>d" "ok_CopyFig(1)")


;set a bindkey with user defined layer setting: pin layer M11:pin, pad layer is current layer in LSW

hiSetBindKey("Layout" "Ctrl<Key>g" "ok_GetPadLocation(list("Metal11" "pin")")


println("load successfully")


名字:layout_save_sub_from_top.tcl
语言: tcl
功能:从gds中保存指定cell 为另一个gds
内容:

set L [layout create top.gds]
$L gdsout sub_cell.gds sub_cell

使用方法:
修改cellname.gds 为实际的gds
然后执行 calibredrv layout_save_sub_from_top.tcl


名字:layout_drc.sh
语言: c shell
功能:脚本的方式执行drc, 并且显示结果
内容:

#!/bin/csh -f
set cell_name = $1
set drc_rule = "your_drc.cal"
set gds_dir = "../gds"
sed -e 's#\(LAYOUT PRIMARY\).*#\1 \"'$cell_name'\"#g' \
        -e 's#\(LAYOUT PATH\).*#\1 \"'$gds_dir/$cell_name.gds'\"#g' \
        -e 's#\(DRC SUMMARY REPORT\).*#\1 \"'drc.rep'\"#g' \
        $drc_rule >! _drc.cal_

calibre -drc -64 -hier -hyper -turbo 2 _drc.cal_
grep "TOTAL Result Count = [1-9]" drc.rep

使用方法:
修改drc_rule 为实际drc rule file 的路径
修改 gds_dir 为gds存放的路径
然后执行 layout_drc.sh cell_name
类似的,你可以仿照这个写个执行 LVS 的脚本了


名字:layout_get_hlist.sh   
语言:shell
功能:从cdl网表当中抽取hcell list
内容:
#!/bin/csh -f
grep -i ".subckt” $1 | awk '{print $2, $2}' >! hlist
使用方法:
layout_get_hlist.sh your.cdl


名字:layout_get_hlist.sh   
语言:shell
功能:从cdl网表当中抽取hcell list
内容:
#!/bin/csh -f
grep -i ".subckt” $1 | awk '{print $2, $2}' >! hlist
使用方法:需要把cds.lib 拷贝到与脚本相同的目录
layout_get_hlist.sh your.cdl


名字:layout_ic61_strmout.sh
语言:shell
功能:用脚本导出GDS
内容:
#!/bin/csh -f
set cellname = $2
set library = $1

$CDSHOME/tools/dfII/bin/strmout \
-library $library \
-strmFile $cellname.gds \
-runDir . \
-topCell $cellname \
-view layout \
-logFile strmOut.log \
-converDot node \
-case Preserve


使用方法:
layout_ic61_strmout.sh library cell



3.
名字:layout_ic61_cdlout.sh
语言:shell
功能:用脚本导出CDL  网表
内容:
#!/bin/csh -f
set cellname = $2
set library = $1
set include_file = "`pwd`/source.added"

cat << EOF >! si.env
simLibName = "$library"
simCellName = "$cellname"
simViewName = "schematic"
netlistType = "Connection By Name"
hnlNtlistFIleName = "$cellname.cdl"
incFile = "$include_file"
...
EOF
# ... 省略的地方请打开一个工作目录下的 si.env 文件补充完整

cat /dev/null >! netlist
$CDSHOME/tools/dfII/bin/si -batch -command netlist

使用方法:需要把cds.lib 拷贝到与脚本相同的目录
layout_ic61_cdlout.sh library cell


名字:PutOnGrid.il
语言:SKILL
功能:消除版图中的off grid
内容:


procedure( OnGrid( Point )
if( listp( Point ) then
mapcar( lambda( (x) OnGrid(x) ) Point)
else
round((Point/Grid))*Grid
)
)

procedure( PutOnGrid( Grid )
let(( SelectObj )
SelectObj = geGetSelSet()
foreach( Object SelectObj
cond(
(Object~>objType == "path"
Polygon = leConvertShapeToPolygon(Object)
Polygon~>points = OnGrid(Polygon~>points)
)

(Object~>objType == "polygon"
Object~>points = OnGrid(Object~>points)
)

(Object~>objType == "rect"
Object~>bBox = OnGrid(Object~>bBox)
)

(Object~>objType == "inst" || Object~>objType == "mosaic"
Object~>xy = OnGrid(Object~>xy)
)
)
)
)
)


使用方法:在CIW中load这个il文件。使用时输OnGrid(0.005),如果你的最小格点是0.005的话。


名字:layout_get_gds_layer.tcl
语言: tcl
功能:获取gds 中的gds number 和 data type
内容:

set L [layout create cellname.gds -noReport -dtExpand]
puts "layer: [lsort -dictionary [$L layers]]"

使用方法:
修改cellname.gds 为实际的gds
然后执行 calibredrv layout_get_gds_layer.tcl


名字:layout_save_sub_from_top.tcl
语言: tcl
功能:从gds中保存指定cell 为另一个gds
内容:

set L [layout create top.gds]
$L gdsout sub_cell.gds sub_cell

使用方法:
修改cellname.gds 为实际的gds
然后执行 calibredrv layout_save_sub_from_top.tcl
这个是从以前的帖子里搬过来的

名字:layout_drc.sh
语言: c shell
功能:脚本的方式执行drc, 并且显示结果
内容:

#!/bin/csh -f
set cell_name = $1
set drc_rule = "your_drc.cal"
set gds_dir = "../gds"
sed -e 's#\(LAYOUT PRIMARY\).*#\1 \"'$cell_name'\"#g' \
        -e 's#\(LAYOUT PATH\).*#\1 \"'$gds_dir/$cell_name.gds'\"#g' \
        -e 's#\(DRC SUMMARY REPORT\).*#\1 \"'drc.rep'\"#g' \
        $drc_rule >! _drc.cal_

calibre -drc -64 -hier -hyper -turbo 2 _drc.cal_
grep "TOTAL Result Count = [1-9]" drc.rep

使用方法:
修改drc_rule 为实际drc rule file 的路径
修改 gds_dir 为gds存放的路径
然后执行 layout_drc.sh cell_name
类似的,你可以仿照这个写个执行 LVS 的脚本了

名字:layout_drc_auto.sh
语言: c shell
功能:脚本的方式执行导出gds ,然后执行drc 检查, 并且显示结果
内容:

#!/bin/csh -f
set cell_name = $1
cd gds_dir #改成你自己的gds保存路径
layout_ic61_strmout.sh $cell_name
cd drc_dir #改成你自己的执行drc 的路径
layout_drc.sh $cell_name

使用方法:
然后执行 layout_drc_auto.sh cell_name

类似的,你可以仿照这个写个自动导出cdl 和 gds, 然后执行lvs 的脚本了

名字 layout_get_subcell.csh   
语言:shell
功能:从cdl网表当中抽取top cell 调用到的cell list
内容:
#!/bin/csh -f

set cell = $1:t:r

#注意, |\ 后面没有空格,下面的代码是一条命令,之间不能有空行,
sed -n "/subckt $cell /,$ p" $1 |\
tr '\n' '@' |\
sed 's/@+/ /g' |\
sed 's/@/\n/g' |\
grep "/" |\
sed 's/.*\/ *//g' |\
sort |\
uniq

使用方法:
layout_get_subcell.csh your.cdl


名字:layout_ic51_strmout.sh
语言:shell
功能:用脚本导出GDS
内容:
#!/bin/csh -f
set cellname = $2
set library = $1

$CDSHOME/tools/dfII/bin/pipo strmout \
-library $library \
-strmFile $cellname.gds \
-runDir . \
-topCell $cellname \
-view layout \
-logFile strmOut.log \
-converDot node \
-case Preserve


使用方法:
layout_ic51_strmout.sh library cell



5

点赞

刚表态过的朋友 (5 人)

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 5

    总排名
  • 0

    关注
  • 28

    粉丝
  • 9

    好友
  • 127

    获赞
  • 12

    评论
  • 146

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-3-28 20:37 , Processed in 0.025436 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部