AutoCutBus.il
已有 126 次阅读|
2025-6-24 14:13
|系统分类:芯片设计
procedure(AutoCutBus()
let((cv objs objs1 objs2 refPoint win techFile cGroudId myViaOptions objPaths points pointsNum startPoint endPoint xStart xEnd yStart yEnd temp1 temp2 Vlist pair_V pair_Vlist Hlist pair_H pair_Hlist length_H length_V length_Min tempH j tempV)
cv = geGetEditCellView()
objs = setof(x geGetSelSet() x~>objType == "path")
objs1 = setof(x geGetSelSet() x~>objType == "pathSeg")
objs2 = setof(x geGetSelSet() x~>objType == "rect")
objs3 = setof(x geGetSelSet() x~>objType == "polygon")
when(objs || objs1 || objs2
if(!boundp('autoCutBusForm) || autoCutBusForm==nil then
autoCutBusForm=hiCreateOptionsForm(
'autoCutBusForm
"AutoCutBusForm"
list(
list(
hiCreateRadioField(
?name 'connection
?prompt "Connection?"
?choices '("direct" "reverse")
)
5:0 100:35 80
)
list(
hiCreateSeparatorField(
?name 'separator
)
5:37 300:0
)
list(
hiCreateRadioField(
?name 'createVia
?prompt "Create via?"
?choices '("yes" "no")
)
5:40 100:35 80
)
list(
hiCreateSpinBox(
?name 'minNuMCUts
?prompt "Min Number of Cuts"
?defValue 1
?value 2
?range list(1 10000)
)
5:80 300:35 150
)
list(
hiCreateCyclicField(
?name 'cutBBoxOrientation
?prompt "Cut BBox Orientation"
?choices '("auto" "horizontal" "vertical")
)
5:120 300:35 150
)
list(
hiCreateCyclicField(
?name 'enclosureDirection
?prompt "Enclosure Direction"
?choices '("XY" "wire" "minArea" "horizontal" "vertical")
)
5:160 300:35 150
)
)
)
);end if
refPoint=enterPoint(
?prompts list("enter a reference point between the two threads.")
?form autoCutBusForm
?alwaysMap t
)
when(refPoint
win=hiGetCurrentWindow()
when(deGetEIP(win) refPoint=geWindowToEditPoint(win refPoint));end when
;****************************************************************
;create via setup
techFile = techGetTechFile(cv)
cGroupId = cstFindConstraintGroupIn(techFile "virtuosoDefaultSetup")
myViaOptions = viaGetViaOptions(cGroupId)
myViaOptions->automatic->minNumCuts=autoCutBusForm->minNumCuts->value
myViaOptions->automatic->cutBBoxOrientation=autoCutBusForm->cutBBoxOrientation->value
myViaOptions->automatic->enclosureDirection=autoCutBusForm->enclosureDirection->value
when(objs1
objPaths=mapcar('leConvertPolygonToPath leMergeShapes(mapcar('leConvertShapeToPolygon objs1)))
mapcar(lambda((x) objs=append1(objs x)) objPaths)
);end when
when(objs2
objPaths=mapcar('leConvertPolygonToPath leMergeShapes(mapcar('leConvertShapeToPolygon objs2)))
;mapcar('dbDeleteObject objs2)
mapcar(lambda((x) objs=append1(objs x)) objPaths)
);end when
foreach(obj objs
;****************************************************************
;split objs for Horizontal or Vertical
points = obj ~> points
pointsNum = obj ~> nPoints
startPoint = nth(0 points)
endPoint = nth(pointsNum-1 points)
xStart = xCoord(startPoint)
yStart = yCoord(startPoint)
xEnd = xCoord(endPoint)
yEnd = yCoord(endPoint)
temp1 = expt(xStart-xCoord(refPoint) 2) + expt(yStart-yCoord(refPoint) 2)
temp2 = expt(xEnd-xCoord(refPoint) 2) + expt(yEnd-yCoord(refPoint) 2)
if(temp1 < temp2 then
if(xStart == xCoord(nth(1 points)) then
Vlist=append1(Vlist obj)
pair_V = list(obj startPoint 0)
pair_Vlist = append1(pair_Vlist pair_V)
else
if(yStart == yCoord(nth(1 points)) then
Hlist=append1(Hlist obj)
pair_H = list(obj startPoint 0)
pair_Hlist = append1(pair_Hlist pair_H)
);end if
);end if
else
if(xEnd == xCoord(nth(pointsNum-2 points)) then
Vlist=append1(Vlist obj)
pair_V = list(obj endPoint pointsNum)
pair_Vlist = append1(pair_Vlist pair_V)
else
if(yEnd == yCoord(nth(pointsNum-2 points)) then
Hlist=append1(Hlist obj)
pair_H = list(obj endPoint pointsNum)
pair_Hlist = append1(pair_Hlist pair_H)
);end if
);end if
);end if
);foreach
;****************************************************************
;sorting
length_H = length(pair_Hlist)
length_V = length(pair_Vlist)
length_Min = min(length_H length_V)
declare(ppa[length_H])
declare(ppb[length_V])
for(i 0 length_H-1
ppa[i] = nth(i pair_Hlist)
);for
for(i 0 length_V-1
ppb[i] = nth(i pair_Vlist)
);for
;***************InsertSort******************
for(i 0 length_H-1
tempH=ppa[i]
j=i
while((j>0 && yCoord(cadr(ppa[j-1])) > yCoord(cadr(tempH)))
ppa[j]=ppa[--j]
);while
ppa[j]=tempH
);for
for(i 0 length_V-1
tempV=ppb[i]
j=i
while((j>0 && xCoord(cadr(ppb[j-1])) > xCoord(cadr(tempV)))
ppb[j]=ppb[--j]
);while
ppb[j]=tempV
);for
;****************************************************************
;cut metal
for(i 0 length_Min-1
if(autoCutBusForm->connection->value == "direct" then
CutMetal(ppa[i] ppb[i])
else
CutMetal(ppa[i] ppb[length_Min-1-i])
);if
);for
;****************************************************************
;convert path to pathSeg which convert to path in before
when(objs1 || objs2
mapcar('leConvertShapeToPathSeg objPaths)
);end when
);end when refPoint
);end when objs || objs1
);let
);proc
procedure(CutMetal(pairA pairB)
let((widthA widthB pointsA pointsB numA numB refPoint x y new_pointA new_pointB viaArea newVias)
widthA = car(pairA) ~> width
widthB = car(pairB) ~> width
pointsA = car(pairA) ~> points
pointsB = car(pairB) ~> points
numA = car(pairA) ~>nPoints
numB = car(pairB) ~>nPoints
refPoint=list(xCoord(cadr(pairB)) yCoord(cadr(pairA)))
x=xCoord(refPoint)
y=yCoord(refPoint)
if(car(last(pairA)) == 0 then
if(xCoord(cadr(pairA)) < xCoord(nth(1 pointsA)) then
new_pointA = list(x-widthB/2 y)
else
new_pointA = list(x+widthB/2 y)
);if
car(pairA) ~> points = cons(new_pointA cdr(pointsA))
else
if(xCoord(cadr(pairA)) < xCoord(nth(numA-2 pointsA)) then
new_pointA = list(x-widthB/2 y)
else
new_pointA = list(x+widthB/2 y)
);if
car(pairA) ~> points = cons(new_pointA cdr(reverse(pointsA)))
);if
if(car(last(pairB)) == 0 then
if(yCoord(cadr(pairB)) < yCoord(nth(1 pointsB)) then
new_pointB = list(x y-widthA/2)
else
new_pointB = list(x y+widthA/2)
);if
car(pairB) ~> points = cons(new_pointB cdr(pointsB))
else
if(yCoord(cadr(pairB)) < yCoord(nth(numB-2 pointsB)) then
new_pointB = list(x y-widthA/2)
else
new_pointB = list(x y+widthA/2)
);if
car(pairB) ~> points = cons(new_pointB cdr(reverse(pointsB)))
);if
;****************************************************************
;create via
unless(autoCutBusForm->createVia->value == "no" || car(pairA)~>layerName == car(pairB)~>layerName
viaArea=list(x-widthB/2:y-widthA/2 x-widthB/2:y+widthA/2 x+widthB/2:y+widthA/2 x+widthB/2:y-widthA/2)
newVias = viaGenerateViasInArea(cv viaArea myViaOptions)
);end unless
);let
);proc
;AutoCutBus()
;hiSetBindKey("layout" "<Key>0" "AutoCutBus()")