I am writing a SKILL script to extract the overlap position (and the connected pins on the overlap path) and the longest path between input to output based on the number of transistors between them.
Q1: Starting from the overlap position script, I designed a small latch layout and I have only resistor and n-type transistor in my layout. For routing, I have a text file in which coordinates of all devices terminals are given. I read that file line by line and do point to point routing. Since I have only 2 metal layers (ITO and PEDOT_PSS), the router will form overlap at some points. I want to extract the where is the overlap and pins that are connected to the overlapping layers. Based on this information I can extract the connected pin coordinates and with the position of those coordinates in my route list I can find out which path was created first and which path was created after wards and caused an overlap. Based on the connected pin name, I assign some penalty for example. if overlap layer is connected to gate terminal "g" then it will get the highest cost, then lower cost if it is connected to drain or source and lowest of it is connected to resistance. In this way I can extract the total cost of the layout design , the higher the cost the worse the layout design is. I wrote a SKILL script that can do this for me but I am stuck at a point where I cannot restrict it to not to add cost 2 time for the same pin. For example: let say I have path1 and path2 overlapping in the layout I can first extract the paths in the layout using shapeList = setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && (shape~>layerName=="ITO" || shape~>layerName=="PEDOT_PSS")) and then for each shape I find the overlapping layers which are from the same net using overlapList = setof(overlap dbGetOverlaps(cv shape~>bBox) member(overlap~>objType '("path" "pathSeg"))). Since I do this for each shape, the path 1 and 2 both will be repeated . Path 1 will have overlap with path 2 and path 2 will have overlap with path 1 and then their cost will be added twice. My complete code is given below:
procedure(pinCost(pinName, gatePinCost, DSPinCost, RPinCost)
case( pinName
;; GATE Pin
( "g"
cost = gatePinCost
)
;; DRAIN or Source Pin
( "d" || "s"
cost = DSPinCost
)
;; GATE Pin
( "PLUS" || "MINUS"
cost = RPinCost
)
)
cost
)
procedure(getOverlapCost(cv, routeList)
gatePinCost = 10000 ;;Gate pin cost
DSPinCost = 5000 ;;Drain-source pin cost
RPinCost = 2000 ;;Resistor pin cost
overlapCost = 0 ;;overlap cost initilization
checkedBefore = list(nil) ;;if the paths was already checked before
;;Find paths on the ITO and PEDOT_PSS layer in the given cv
shapeList = setof(shape cv~>shapes member(shape~>objType '("path" "pathSeg")) && (shape~>layerName=="ITO" || shape~>layerName=="PEDOT_PSS"))
;shapeList = dbGetOverlaps(cv cv~>bBox "PEDOT_PSS")
foreach( shape shapeList
;printf("%L, %L, %L\n" shape~>lpp shape~>objType shape~>net~>name)
;printf("%L\n" routeList)
;;Find which paths are overlapping this shape
overlapList = setof(overlap dbGetOverlaps(cv shape~>bBox) member(overlap~>objType '("path" "pathSeg")))
;printf("Shape: %L, overlapList: %L\n" shape~>net~>name overlapList~>net~>name)
;;If net names of the shape and overlaing shapes are different then continue otherwise skip
if(remd(shape~>net~>name overlapList~>net~>name)
then
origNetSCoord=origNetECoord=diffNetSCoord=diffNetECoord=0 ;;initilaizing original net (shape~>net) and different net (start and end pin coordinates)
;; Which net name is different in the overlaplist
diffNetName = setof(netName overlapList~>net~>name netName!=shape~>net~>name)
diffNetidx = lindex(overlapList~>net~>name car(diffNetName))-1
diffNet = nth(diffNetidx overlapList)
;printf("Overlapping: %L, this shape net: %L, overlapping net %L\n" overlapList~>net~>name shape~>net~>name overlapNet~>net~>name)
;; Find the start and end pin names (for the original and differnet net) and their coordinates
origNet = shape
origNetidx = lindex(overlapList~>net~>name origNet~>net~>name)-1
origNetSIns = nth(origNetidx overlapList~>route~>startConn~>inst~>name)
origNetSPin = nth(origNetidx overlapList~>route~>startConn~>term~>name)
origNetEIns = nth(origNetidx overlapList~>route~>endConn~>inst~>name)
origNetEPin = nth(origNetidx overlapList~>route~>endConn~>term~>name)
diffNetSIns = nth(diffNetidx overlapList~>route~>startConn~>inst~>name)
diffNetSPin = nth(diffNetidx overlapList~>route~>startConn~>term~>name)
diffNetEIns = nth(diffNetidx overlapList~>route~>endConn~>inst~>name)
diffNetEPin = nth(diffNetidx overlapList~>route~>endConn~>term~>name)
;printf("OSP:%L, OEP:%L, DSP:%L, DEP:%L\n" origNetSPin origNetEPin diffNetSPin diffNetEPin)
;; Find coordinates of the pins
if(origNetSIns && origNetSPin
then
origNetSCoord = dbTransformPoint(centerBox(car(nth(origNetidx overlapList~>route~>startConn~>term~>pins)~>fig~>bBox)) nth(origNetidx overlapList~>route~>startConn~>inst~>transform))
origRouteidx = lindex(routeList car(setof(thisList routeList abs(xCoord(origNetSCoord)-xCoord(car(thisList)))<1 && abs(yCoord(origNetSCoord)-yCoord(car(thisList)))<1)))-1
)
if(origNetEIns && origNetEPin
then
origNetECoord = dbTransformPoint(centerBox(car(nth(origNetidx overlapList~>route~>endConn~>term~>pins)~>fig~>bBox)) nth(origNetidx overlapList~>route~>endConn~>inst~>transform))
origRouteidx = lindex(routeList car(setof(thisList routeList abs(xCoord(origNetECoord)-xCoord(cadr(thisList)))<1 && abs(yCoord(origNetECoord)-yCoord(cadr(thisList)))<1)))-1
)
if(diffNetSIns && diffNetSPin
then
diffNetSCoord = dbTransformPoint(centerBox(car(nth(diffNetidx overlapList~>route~>startConn~>term~>pins)~>fig~>bBox)) nth(diffNetidx overlapList~>route~>startConn~>inst~>transform))
diffRouteidx = lindex(routeList car(setof(thisList routeList abs(xCoord(diffNetSCoord)-xCoord(car(thisList)))<1 && abs(yCoord(diffNetSCoord)-yCoord(car(thisList)))<1)))-1
)
if(diffNetEIns && diffNetEPin
then
diffNetECoord = dbTransformPoint(centerBox(car(nth(diffNetidx overlapList~>route~>endConn~>term~>pins)~>fig~>bBox)) nth(diffNetidx overlapList~>route~>endConn~>inst~>transform))
diffRouteidx = lindex(routeList car(setof(thisList routeList abs(xCoord(diffNetECoord)-xCoord(cadr(thisList)))<1 && abs(yCoord(diffNetECoord)-yCoord(cadr(thisList)))<1)))-1
)
;printf("OSP:%L, OEP:%L, DSP:%L, DEP:%L\n" origNetSCoord origNetECoord diffNetSCoord diffNetECoord)
;; Find which one is overlapping by comparing sequence in the route list
;printf("origIdx:%L, diffIdx:%L\n" origRouteidx diffRouteidx)
if(origRouteidx < diffRouteidx ;;orig net was routed first and diff is overlapping it
then
checkedBefore = append(checkedBefore list(diffNet))
if(diffNetSCoord != 0
then
overlapCost = overlapCost + pinCost(diffNetSPin, gatePinCost, DSPinCost, RPinCost)
else if(diffNetECoord != 0
then
overlapCost = overlapCost + pinCost(diffNetEPin, gatePinCost, DSPinCost, RPinCost)
)
)
else if(origRouteidx > diffRouteidx ;;diff net was routed first and orig is overlapping it
then
checkedBefore = append(checkedBefore list(origNet))
if(origNetSCoord != 0
then
overlapCost = overlapCost + pinCost(origNetSPin, gatePinCost, DSPinCost, RPinCost)
else if(origNetECoord != 0
then
overlapCost = overlapCost + pinCost(origNetEPin, gatePinCost, DSPinCost, RPinCost)
)
)
)
)
)
)
overlapCost
)
Is there any solution that I can avoid assignment of the cost 2 times for the same pin ? The overlap can be seen in the attached figure (Blue= PEDOT_PSS, grey = ITO ).
Q2: My second question is is there any command to extract the critical path or the longest path from input to output ? This longest path length is based in the number of devices in between the input and the output port
For example: IN-M1 -M2-M3-M4-OUT and IN-M3-M4-OUT, The critical path is IN-M1 -M2-M3-M4-OUT becuase there are 4 transistors between IN and OUT pin.
Thanks
PS: I couldn't find the option to put my script in the CODE block.