热度 5| |
名字: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
随便选一层layer画个框框,框处要抓取坐标的区域,然后在LSW选中PAD laye
执行快捷键 ctrl+g, 所有的label 会调整到PAD中心点
执行脚本后弹出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