Updated gdsMill with new getter routines for router to get by location. Cleaned up vlsiLayout.

This commit is contained in:
Matt Guthaus 2017-05-17 14:27:14 -07:00
parent a09ff8c358
commit a1496e70a8
4 changed files with 112 additions and 78 deletions

View File

@ -20,7 +20,7 @@ class Gds2reader:
print (number>>(63-index))&0x1, print (number>>(63-index))&0x1,
print "\n" print "\n"
def strip_non_ascii(self,string): def stripNonASCII(self,string):
#''' Returns the string without non ASCII characters''' #''' Returns the string without non ASCII characters'''
stripped = (c for c in string if 0 < ord(c) < 127) stripped = (c for c in string if 0 < ord(c) < 127)
return "".join(stripped) return "".join(stripped)
@ -290,7 +290,7 @@ class Gds2reader:
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print "\t\tPLEX: "+str(plex) print "\t\tPLEX: "+str(plex)
elif(idBits==('\x12','\x06')): #Reference Name elif(idBits==('\x12','\x06')): #Reference Name
sName = self.strip_non_ascii(record[2::]) sName = self.stripNonASCII(record[2::])
thisSref.sName=sName.rstrip() thisSref.sName=sName.rstrip()
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print "\t\tReference Name:"+sName print "\t\tReference Name:"+sName
@ -595,11 +595,11 @@ class Gds2reader:
idBits = (record[0],record[1]) idBits = (record[0],record[1])
if idBits==('\x07','\x00'): break; #we've reached the end of the structure if idBits==('\x07','\x00'): break; #we've reached the end of the structure
elif(idBits==('\x06','\x06')): elif(idBits==('\x06','\x06')):
structName = self.strip_non_ascii(record[2::]) #(record[2:1] + record[1::]).rstrip() structName = self.stripNonASCII(record[2::]) #(record[2:1] + record[1::]).rstrip()
# print ''.[x for x in structName if ord(x) < 128] # print ''.[x for x in structName if ord(x) < 128]
# stripped = (c for c in structName if 0 < ord(c) < 127) # stripped = (c for c in structName if 0 < ord(c) < 127)
# structName = "".join(stripped) # structName = "".join(stripped)
# print self.strip_non_ascii(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming! # print self.stripNonASCII(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming!
thisStructure.name = structName thisStructure.name = structName
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print "\tStructure Name: "+structName print "\tStructure Name: "+structName
@ -694,11 +694,11 @@ class Gds2reader:
idBits = (record[0],record[1]) idBits = (record[0],record[1])
if idBits==('\x07','\x00'): break; #we've reached the end of the structure if idBits==('\x07','\x00'): break; #we've reached the end of the structure
elif(idBits==('\x06','\x06')): elif(idBits==('\x06','\x06')):
structName = self.strip_non_ascii(record[2::]) #(record[2:1] + record[1::]).rstrip() structName = self.stripNonASCII(record[2::]) #(record[2:1] + record[1::]).rstrip()
# print ''.[x for x in structName if ord(x) < 128] # print ''.[x for x in structName if ord(x) < 128]
# stripped = (c for c in structName if 0 < ord(c) < 127) # stripped = (c for c in structName if 0 < ord(c) < 127)
# structName = "".join(stripped) # structName = "".join(stripped)
# print self.strip_non_ascii(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming! # print self.stripNonASCII(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming!
thisStructure.name = structName thisStructure.name = structName
if(findStructName==thisStructure.name): if(findStructName==thisStructure.name):
wantedStruct=1 wantedStruct=1
@ -775,11 +775,11 @@ class Gds2reader:
idBits = (record[0],record[1]) idBits = (record[0],record[1])
if idBits==('\x07','\x00'): break; #we've reached the end of the structure if idBits==('\x07','\x00'): break; #we've reached the end of the structure
elif(idBits==('\x06','\x06')): elif(idBits==('\x06','\x06')):
structName = self.strip_non_ascii(record[2::]) #(record[2:1] + record[1::]).rstrip() structName = self.stripNonASCII(record[2::]) #(record[2:1] + record[1::]).rstrip()
# print ''.[x for x in structName if ord(x) < 128] # print ''.[x for x in structName if ord(x) < 128]
# stripped = (c for c in structName if 0 < ord(c) < 127) # stripped = (c for c in structName if 0 < ord(c) < 127)
# structName = "".join(stripped) # structName = "".join(stripped)
# print self.strip_non_ascii(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming! # print self.stripNonASCIIx(structName) ##FIXME: trimming by Tom g. ##could be an issue here with string trimming!
thisStructure.name = structName thisStructure.name = structName
if(self.debugToTerminal==1): if(self.debugToTerminal==1):
print "\tStructure Name: "+structName print "\tStructure Name: "+structName

View File

@ -58,12 +58,6 @@ class VlsiLayout:
self.tempCoordinates=None self.tempCoordinates=None
self.tempPassFail = True self.tempPassFail = True
def strip_non_ascii(string):
''' Returns the string without non ASCII characters'''
stripped = (c for c in string if 0 < ord(c) < 127)
return ''.join(stripped)
def rotatedCoordinates(self,coordinatesToRotate,rotateAngle): def rotatedCoordinates(self,coordinatesToRotate,rotateAngle):
#helper method to rotate a list of coordinates #helper method to rotate a list of coordinates
angle=math.radians(float(0)) angle=math.radians(float(0))
@ -584,7 +578,7 @@ class VlsiLayout:
passFailIndex+=1 passFailIndex+=1
print "Done\n\n" print "Done\n\n"
def readLayoutBorder(self,borderlayer): def getLayoutBorder(self,borderlayer):
for boundary in self.structures[self.rootStructureName].boundaries: for boundary in self.structures[self.rootStructureName].boundaries:
if boundary.drawingLayer==borderlayer: if boundary.drawingLayer==borderlayer:
if self.debug: print "Find border "+str(boundary.coordinates) if self.debug: print "Find border "+str(boundary.coordinates)
@ -629,41 +623,66 @@ class VlsiLayout:
left_bottom=boundary.coordinates[0] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
thisBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]] thisBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
thisBoundary=self.tranformRectangle(thisBoundary,StructureuVector,StructurevVector) thisBoundary=self.transformRectangle(thisBoundary,StructureuVector,StructurevVector)
thisBoundary=[thisBoundary[0]+StructureOrigin[0],thisBoundary[1]+StructureOrigin[1], thisBoundary=[thisBoundary[0]+StructureOrigin[0],thisBoundary[1]+StructureOrigin[1],
thisBoundary[2]+StructureOrigin[0],thisBoundary[3]+StructureOrigin[1]] thisBoundary[2]+StructureOrigin[0],thisBoundary[3]+StructureOrigin[1]]
cellBoundary=self.update_boundary(thisBoundary,cellBoundary) cellBoundary=self.updateBoundary(thisBoundary,cellBoundary)
return cellBoundary return cellBoundary
def update_boundary(self,thisBoundary,cellBoundary): def updateBoundary(self,thisBoundary,cellBoundary):
[left_butt_X,left_butt_Y,right_top_X,right_top_Y]=thisBoundary [left_bott_X,left_bott_Y,right_top_X,right_top_Y]=thisBoundary
if cellBoundary==[None,None,None,None]: if cellBoundary==[None,None,None,None]:
cellBoundary=thisBoundary cellBoundary=thisBoundary
else: else:
if cellBoundary[0]>left_butt_X: if cellBoundary[0]>left_bott_X:
cellBoundary[0]=left_butt_X cellBoundary[0]=left_bott_X
if cellBoundary[1]>left_butt_Y: if cellBoundary[1]>left_bott_Y:
cellBoundary[1]=left_butt_Y cellBoundary[1]=left_bott_Y
if cellBoundary[2]<right_top_X: if cellBoundary[2]<right_top_X:
cellBoundary[2]=right_top_X cellBoundary[2]=right_top_X
if cellBoundary[3]<right_top_Y: if cellBoundary[3]<right_top_Y:
cellBoundary[3]=right_top_Y cellBoundary[3]=right_top_Y
return cellBoundary return cellBoundary
def readPinShape(self,label_name):
def getLabelDBInfo(self,label_name):
""" """
Search for a pin label and return the largest enclosing rectangle Return the coordinates in DB units and layer of a label
on the same layer as the pin label.
""" """
label_layer = None label_layer = None
label_coordinate = [None, None] label_coordinate = [None, None]
# Why must this be the last one found? It breaks if we return the first.
for Text in self.structures[self.rootStructureName].texts: for Text in self.structures[self.rootStructureName].texts:
if Text.textString == label_name or Text.textString == label_name+"\x00": if Text.textString == label_name or Text.textString == label_name+"\x00":
label_layer = Text.drawingLayer label_layer = Text.drawingLayer
label_coordinate = Text.coordinates label_coordinate = Text.coordinates
pin_boundaries=self.readAllPinShapesInStructureList(label_coordinate, label_layer) return (label_coordinate, label_layer)
def getLabelInfo(self,label_name):
"""
Return the coordinates in USER units and layer of a label
"""
(label_coordinate,label_layer)=getLabelDBInfo(label_name)
user_coordinates = [x*self.units[0] for x in label_coordinates]
return (user_coordinates,layer)
def getPinShapeByLocLayer(self, coordinate, layer):
"""
Return the largest enclosing rectangle on a layer and at a location.
Coordinates should be in user units.
"""
db_coordinates = [x/self.units[0] for x in coordinate]
return self.getPinShapeByDBLocLayer(db_coordinate, layer)
def getPinShapeByDBLocLayer(self, coordinate, layer):
"""
Return the largest enclosing rectangle on a layer and at a location.
Coordinates should be in db units.
"""
pin_boundaries=self.getAllPinShapesInStructureList(coordinate, layer)
# sort the boundaries, return the max area pin boundary # sort the boundaries, return the max area pin boundary
pin_boundaries.sort(cmpBoundaryAreas,reverse=True) pin_boundaries.sort(cmpBoundaryAreas,reverse=True)
@ -673,22 +692,22 @@ class VlsiLayout:
pin_boundary=[pin_boundary[0]*self.units[0],pin_boundary[1]*self.units[0], pin_boundary=[pin_boundary[0]*self.units[0],pin_boundary[1]*self.units[0],
pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]] pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]]
return [label_name, label_layer, pin_boundary] return [None, layer, pin_boundary]
def readAllPinShapes(self,label_name): def getAllPinShapesByLocLayer(self, coordinate, layer):
""" """
Search for a pin label and return ALL the enclosing rectangles on the same layer Return ALL the enclosing rectangles on the same layer
as the pin label. at the given coordinate. Coordinates should be in user units.
""" """
label_layer = None db_coordinates = [x/self.units[0] for x in coordinate]
label_coordinate = [None, None] return self.getAllPinShapesByDBLocLayer(db_coordinate, layer)
for Text in self.structures[self.rootStructureName].texts: def getAllPinShapesByDBLocLayer(self, coordinate, layer):
if Text.textString == label_name or Text.textString == label_name+"\x00": """
label_layer = Text.drawingLayer Return ALL the enclosing rectangles on the same layer
label_coordinate = Text.coordinates at the given coordinate. Coordinates should be in db units.
"""
pin_boundaries=self.readAllPinShapesInStructureList(label_coordinate, label_layer) pin_boundaries=self.getAllPinShapesInStructureList(coordinate, layer)
# Convert to user units # Convert to user units
new_boundaries = [] new_boundaries = []
@ -697,24 +716,38 @@ class VlsiLayout:
pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]]) pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]])
return [label_name, label_layer, new_boundaries] def getPinShapeByLabel(self,label_name):
"""
Search for a pin label and return the largest enclosing rectangle
on the same layer as the pin label.
"""
(label_coordinate,label_layer)=self.getLabelDBInfo(label_name)
return self.getPinShapeByDBLocLayer(label_coordinate, label_layer)
def readAllPinShapesInStructureList(self,label_coordinates,layer): def getAllPinShapesByLabel(self,label_name):
""" """
Given the label coordinate, search for enclosing structures on the given layer. Search for a pin label and return ALL the enclosing rectangles on the same layer
Return the single biggest area rectangle. as the pin label.
""" """
label_boundaries = [] (label_coordinate,label_layer)=self.getLabelDBInfo(label_name)
return self.getAllPinShapesByDBLocLayer(label_coordinate, label_layer)
def getAllPinShapesInStructureList(self,coordinates,layer):
"""
Given a coordinate, search for enclosing structures on the given layer.
Return all pin shapes.
"""
boundaries = []
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
boundaries = self.readPinInStructure(label_coordinates,layer,TreeUnit) boundaries += self.getPinInStructure(coordinates,layer,TreeUnit)
label_boundaries += boundaries
return label_boundaries return boundaries
def readPinInStructure(self,label_coordinates,layer,Structure): def getPinInStructure(self,coordinates,layer,Structure):
""" """
Go through all the shapes in a strutcure and return the list of shapes Go through all the shapes in a structure and return the list of shapes
that the label coordinates are inside. that the label coordinates are inside.
""" """
StructureName=Structure[0] StructureName=Structure[0]
@ -729,49 +762,50 @@ class VlsiLayout:
left_bottom=boundary.coordinates[0] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
MetalBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]] MetalBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
MetalBoundary=self.tranformRectangle(MetalBoundary,StructureuVector,StructurevVector) MetalBoundary=self.transformRectangle(MetalBoundary,StructureuVector,StructurevVector)
MetalBoundary=[MetalBoundary[0]+StructureOrigin[0],MetalBoundary[1]+StructureOrigin[1], MetalBoundary=[MetalBoundary[0]+StructureOrigin[0],MetalBoundary[1]+StructureOrigin[1],
MetalBoundary[2]+StructureOrigin[0],MetalBoundary[3]+StructureOrigin[1]] MetalBoundary[2]+StructureOrigin[0],MetalBoundary[3]+StructureOrigin[1]]
if self.labelInRectangle(label_coordinates[0],MetalBoundary): if self.labelInRectangle(coordinates[0],MetalBoundary):
boundaries.append(MetalBoundary) boundaries.append(MetalBoundary)
return boundaries return boundaries
def tranformRectangle(self,orignalRectangle,uVector,vVector): def transformRectangle(self,orignalRectangle,uVector,vVector):
""" """
Transforms the four coordinates of a rectangle in space Transforms the four coordinates of a rectangle in space
and recomputes the left, bottom, right, up values. and recomputes the left, bottom, right, top values.
""" """
LeftBottom=mpmath.matrix([orignalRectangle[0],orignalRectangle[1]]) leftBottom=mpmath.matrix([orignalRectangle[0],orignalRectangle[1]])
LeftBottom=self.tranformCoordinate(LeftBottom,uVector,vVector) leftBottom=self.transformCoordinate(leftBottom,uVector,vVector)
RightUp=mpmath.matrix([orignalRectangle[2],orignalRectangle[3]]) rightTop=mpmath.matrix([orignalRectangle[2],orignalRectangle[3]])
RightUp=self.tranformCoordinate(RightUp,uVector,vVector) rightTop=self.transformCoordinate(rightTop,uVector,vVector)
Left=min(LeftBottom[0],RightUp[0]) left=min(leftBottom[0],rightTop[0])
Bottom=min(LeftBottom[1],RightUp[1]) bottom=min(leftBottom[1],rightTop[1])
Right=max(LeftBottom[0],RightUp[0]) right=max(leftBottom[0],rightTop[0])
Up=max(LeftBottom[1],RightUp[1]) top=max(leftBottom[1],rightTop[1])
return [Left,Bottom,Right,Up] return [left,bottom,right,top]
def tranformCoordinate(self,Coordinate,uVector,vVector): def transformCoordinate(self,coordinate,uVector,vVector):
""" """
Rotate a coordinate in space. Rotate a coordinate in space.
""" """
x=Coordinate[0]*uVector[0]+Coordinate[1]*uVector[1] x=coordinate[0]*uVector[0]+coordinate[1]*uVector[1]
y=Coordinate[1]*vVector[1]+Coordinate[0]*vVector[0] y=coordinate[1]*vVector[1]+coordinate[0]*vVector[0]
tranformCoordinate=[x,y] transformCoordinate=[x,y]
return tranformCoordinate
return transformCoordinate
def labelInRectangle(self,label_coordinate,Rectangle): def labelInRectangle(self,coordinate,rectangle):
""" """
Checks if a coordinate is within a given rectangle. Checks if a coordinate is within a given rectangle.
""" """
coordinate_In_Rectangle_x_range=(label_coordinate[0]>=int(Rectangle[0]))&(label_coordinate[0]<=int(Rectangle[2])) coordinate_In_Rectangle_x_range=(coordinate[0]>=int(rectangle[0]))&(coordinate[0]<=int(rectangle[2]))
coordinate_In_Rectangle_y_range=(label_coordinate[1]>=int(Rectangle[1]))&(label_coordinate[1]<=int(Rectangle[3])) coordinate_In_Rectangle_y_range=(coordinate[1]>=int(rectangle[1]))&(coordinate[1]<=int(rectangle[3]))
if coordinate_In_Rectangle_x_range & coordinate_In_Rectangle_y_range: if coordinate_In_Rectangle_x_range & coordinate_In_Rectangle_y_range:
return True return True
else: else:
@ -779,7 +813,7 @@ class VlsiLayout:
def cmpBoundaryAreas(A,B): def cmpBoundaryAreas(A,B):
""" """
Compares two rectangles and returns the bigger in terms of area. Compares two rectangles and return true if Area(A)>Area(B).
""" """
area_A=(A[2]-A[0])*(A[3]-A[1]) area_A=(A[2]-A[0])*(A[3]-A[1])
area_B=(B[2]-B[0])*(B[3]-B[1]) area_B=(B[2]-B[0])*(B[3]-B[1])

View File

@ -90,7 +90,7 @@ class router:
""" """
# Returns all the shapes that enclose a pin on a given layer # Returns all the shapes that enclose a pin on a given layer
(pin_name,pin_layer,pin_shapes) = self.layout.readAllPinShapes(str(pin)) (pin_name,pin_layer,pin_shapes) = self.layout.getAllPinShapes(str(pin))
self.pin_shapes[str(pin)]=[] self.pin_shapes[str(pin)]=[]
self.pin_names.append(pin_name) self.pin_names.append(pin_name)

View File

@ -39,13 +39,13 @@ def auto_measure_libcell(pin_list, name, units, layer):
reader.loadFromFile(cell_gds) reader.loadFromFile(cell_gds)
cell = {} cell = {}
measure_result = cell_vlsi.readLayoutBorder(layer) measure_result = cell_vlsi.getLayoutBorder(layer)
if measure_result == None: if measure_result == None:
measure_result = cell_vlsi.measureSize(name) measure_result = cell_vlsi.measureSize(name)
[cell["width"], cell["height"]] = measure_result [cell["width"], cell["height"]] = measure_result
for pin in pin_list: for pin in pin_list:
cell[str(pin)] = gds_pin_center(cell_vlsi.readPinShape(str(pin))) cell[str(pin)] = gds_pin_center(cell_vlsi.getPinShapeByLabel(str(pin)))
return cell return cell