|
楼主 |
发表于 2018-3-1 22:35:21
|
显示全部楼层
- /*
- 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")
复制代码 |
|