;; ============================================================
;; [Environment Settings]
;; ============================================================
;; 1. Target Cell Name Settings (The skill works only for cells specified here)
;; [Usage Examples]
;; To apply only to specific cells: defvar( MyTargetCells list("pmos2v" "nmos2v") )
;; To apply to all cells: defvar( MyTargetCells nil )
defvar( MyTargetCells list("pmos2v" "nmos2v") )
;; defvar( MyTargetCells nil )
;; 2. Layer and Via Settings
defvar( MyPdkPolyLayer list("POLY1" "drawing") )
defvar( MyPdkViaDefName "M1_POLY1" )
;; 3. Text Label Settings
defvar( MyPdkTextLayer list("TEXT" "drawing") )
defvar( MyTextHeight 0.2 )
defvar( MyTextFont "roman" )
defvar( MyEnableLabel t ) ;; Label creation setting (t: ON, nil: OFF)
;; 4. Poly Extension Length (Unit: um)
defvar( MyPolyExtLength 0.89 )
;; 5. Via Parameter Settings
defvar( MyPdkViaParams list(
list("cutRows" 2)
list("cutColumns" 1)
) )
;; ============================================================
procedure( MyAddGatePolyExt( direction )
let((cv selSet instMaster bBoxList mergedBoxes curBox newX1 newY1 newX2 newY2
box x1 y1 x2 y2 polyCenter viaCenterY extBoxMaster viaCenterMaster
extBoxTop viaCenterTop newRect newVia successCount orient extendMasterTop
tech viaDef instCenterX instCenterY instCenter newLabel)
cv = geGetEditCellView()
selSet = geGetSelSet()
successCount = 0
tech = techGetTechFile(cv)
viaDef = techFindViaDefByName(tech MyPdkViaDefName)
if( !viaDef then
printf(">>> [Error] Via Definition '%s' not found in Tech file.\n" MyPdkViaDefName)
return(nil)
)
if( !selSet then
printf(">>> [Error] No instances selected.\n")
return(nil)
)
foreach( inst selSet
if( inst~>objType == "inst" then
;; ★ Target Cell Name Filtering Condition ★
if( MyTargetCells && !member(inst~>cellName MyTargetCells) then
printf(">>> [Skip] Instance '%s' (Cell: %s) is not in the target list.\n" inst~>name inst~>cellName)
else
orient = inst~>orient
if( member(orient list("R0" "MY" "MX" "R180")) then
instMaster = inst~>master
bBoxList = nil
foreach( shape instMaster~>shapes
if( shape~>lpp == MyPdkPolyLayer && (shape~>objType == "rect" || shape~>objType == "polygon") then
bBoxList = cons(shape~>bBox bBoxList)
)
)
if( !bBoxList then
printf(">>> [Warning] Poly layer not found inside instance '%s'.\n" inst~>name)
else
bBoxList = sort( bBoxList lambda((a b) caar(a) < caar(b)) )
mergedBoxes = nil
curBox = car(bBoxList)
foreach( nextBox cdr(bBoxList)
if( caar(nextBox) <= caadr(curBox) + 0.001 then
newX1 = caar(curBox)
newY1 = min(cadar(curBox) cadar(nextBox))
newX2 = max(caadr(curBox) caadr(nextBox))
newY2 = max(cadadr(curBox) cadadr(nextBox))
curBox = list(list(newX1 newY1) list(newX2 newY2))
else
mergedBoxes = cons(curBox mergedBoxes)
curBox = nextBox
)
)
mergedBoxes = cons(curBox mergedBoxes)
foreach( box mergedBoxes
x1 = caar(box)
y1 = cadar(box)
x2 = caadr(box)
y2 = cadadr(box)
polyCenter = (x1 + x2) / 2.0
extendMasterTop = nil
if( (direction == "TOP" && (orient == "R0" || orient == "MY")) ||
(direction == "BOTTOM" && (orient == "MX" || orient == "R180")) then
extendMasterTop = t
)
if( extendMasterTop then
extBoxMaster = list( list(x1 y2) list(x2 y2 + MyPolyExtLength) )
viaCenterY = y2 + (MyPolyExtLength / 2.0)
else
extBoxMaster = list( list(x1 y1 - MyPolyExtLength) list(x2 y1) )
viaCenterY = y1 - (MyPolyExtLength / 2.0)
)
viaCenterMaster = list(polyCenter viaCenterY)
extBoxTop = dbTransformBBox( extBoxMaster inst~>transform )
viaCenterTop = dbTransformPoint( viaCenterMaster inst~>transform )
newRect = dbCreateRect( cv MyPdkPolyLayer extBoxTop )
newVia = dbCreateVia( cv viaDef viaCenterTop inst~>orient MyPdkViaParams )
if( newRect then leAttachFig( newRect inst ) )
if( newVia then leAttachFig( newVia inst ) )
)
;; ============================================================
;; ★ Explicit Text Label (Optional Processing) ★
;; ============================================================
if( MyEnableLabel then
instCenterX = (caar(inst~>bBox) + caadr(inst~>bBox)) / 2.0
instCenterY = (cadar(inst~>bBox) + cadadr(inst~>bBox)) / 2.0
instCenter = list(instCenterX instCenterY)
newLabel = dbCreateLabel(
cv
MyPdkTextLayer
instCenter
inst~>name
"centerCenter"
"R0"
MyTextFont
MyTextHeight
)
if( newLabel then
leAttachFig( newLabel inst )
)
)
successCount = successCount + 1
)
else
printf(">>> [Skip] Orientation '%s' is not supported. Skipping '%s'.\n" orient inst~>name)
)
)
else
printf(">>> [Skip] Selected object is not an instance. Skipping.\n")
)
)
printf(">>> [Done] %s Poly/Via/Label applied to %d instance(s).\n" direction successCount)
t
)
)
hiSetBindKey("Layout" "<Key>F8" "MyAddGatePolyExt(\"TOP\")")
hiSetBindKey("Layout" "<Key>F9" "MyAddGatePolyExt(\"BOTTOM\")")
printf(">>> [Loaded] Poly/Via/Label script loaded (F8: TOP, F9: BOTTOM)\n")
poly ext
2026. 11. 8. 22:55

