Fix spelling errors. Allow multiple rectangle pin shapes in router.

This commit is contained in:
Matt Guthaus 2016-11-18 08:55:34 -08:00
parent 1c9b5c7372
commit ed5700d698
4 changed files with 114 additions and 73 deletions

View File

@ -601,7 +601,7 @@ class VlsiLayout:
self.populateCoordinateMap() self.populateCoordinateMap()
cellBoundary = [None, None, None, None] cellBoundary = [None, None, None, None]
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
cellBoundary=self.measureSizeInStruture(TreeUnit,cellBoundary) cellBoundary=self.measureSizeInStructure(TreeUnit,cellBoundary)
cellSize=[cellBoundary[2]-cellBoundary[0],cellBoundary[3]-cellBoundary[1]] cellSize=[cellBoundary[2]-cellBoundary[0],cellBoundary[3]-cellBoundary[1]]
cellSizeMicron=[cellSize[0]*self.units[0],cellSize[1]*self.units[0]] cellSizeMicron=[cellSize[0]*self.units[0],cellSize[1]*self.units[0]]
return cellSizeMicron return cellSizeMicron
@ -611,27 +611,27 @@ class VlsiLayout:
self.populateCoordinateMap() self.populateCoordinateMap()
cellBoundary = [None, None, None, None] cellBoundary = [None, None, None, None]
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
cellBoundary=self.measureSizeInStruture(TreeUnit,cellBoundary) cellBoundary=self.measureSizeInStructure(TreeUnit,cellBoundary)
return [[self.units[0]*cellBoundary[0],self.units[0]*cellBoundary[1]], return [[self.units[0]*cellBoundary[0],self.units[0]*cellBoundary[1]],
[self.units[0]*cellBoundary[2],self.units[0]*cellBoundary[3]]] [self.units[0]*cellBoundary[2],self.units[0]*cellBoundary[3]]]
def measureSizeInStruture(self,Struture,cellBoundary): def measureSizeInStructure(self,Structure,cellBoundary):
StrutureName=Struture[0] StructureName=Structure[0]
StrutureOrgin=[Struture[1][0],Struture[1][1]] StructureOrigin=[Structure[1][0],Structure[1][1]]
StrutureuVector=[Struture[2][0],Struture[2][1],Struture[2][2]] StructureuVector=[Structure[2][0],Structure[2][1],Structure[2][2]]
StruturevVector=[Struture[3][0],Struture[3][1],Struture[3][2]] StructurevVector=[Structure[3][0],Structure[3][1],Structure[3][2]]
#debug.info(debug_level,"Checking Structure: "+str(StrutureName)) #debug.info(debug_level,"Checking Structure: "+str(StructureName))
#debug.info(debug_level,"-Structure Struture Orgin:"+str(StrutureOrgin)) #debug.info(debug_level,"-Structure Structure Origin:"+str(StructureOrigin))
#debug.info(debug_level,"-Structure direction: uVector["+str(StrutureuVector)+"]") #debug.info(debug_level,"-Structure direction: uVector["+str(StructureuVector)+"]")
#debug.info(debug_level,"-Structure direction: vVector["+str(StruturevVector)+"]") #debug.info(debug_level,"-Structure direction: vVector["+str(StructurevVector)+"]")
for boundary in self.structures[str(StrutureName)].boundaries: for boundary in self.structures[str(StructureName)].boundaries:
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,StrutureuVector,StruturevVector) thisBoundary=self.tranformRectangle(thisBoundary,StructureuVector,StructurevVector)
thisBoundary=[thisBoundary[0]+StrutureOrgin[0],thisBoundary[1]+StrutureOrgin[1], thisBoundary=[thisBoundary[0]+StructureOrigin[0],thisBoundary[1]+StructureOrigin[1],
thisBoundary[2]+StrutureOrgin[0],thisBoundary[3]+StrutureOrgin[1]] thisBoundary[2]+StructureOrigin[0],thisBoundary[3]+StructureOrigin[1]]
cellBoundary=self.update_boundary(thisBoundary,cellBoundary) cellBoundary=self.update_boundary(thisBoundary,cellBoundary)
return cellBoundary return cellBoundary
@ -650,9 +650,10 @@ class VlsiLayout:
cellBoundary[3]=right_top_Y cellBoundary[3]=right_top_Y
return cellBoundary return cellBoundary
def readPin(self,label_name,mod="offset"): def readPin(self,label_name):
""" """
Search for a pin label and return all the largest enclosing rectangle. Search for a pin label and return the largest enclosing rectangle
on the same layer as the pin label.
""" """
label_layer = None label_layer = None
label_coordinate = [None, None] label_coordinate = [None, None]
@ -662,50 +663,80 @@ class VlsiLayout:
label_layer = Text.drawingLayer label_layer = Text.drawingLayer
label_coordinate = Text.coordinates label_coordinate = Text.coordinates
pin_boundary=self.readPinInStructureList(label_coordinate, label_layer) pin_boundaries=self.readAllPinInStructureList(label_coordinate, label_layer)
# sort the boundaries, return the max area pin boundary
pin_boundaries.sort(cmpBoundaryAreas,reverse=True)
pin_boundary=pin_boundaries[0]
# Convert to user units # Convert to user units
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 [label_name, label_layer, pin_boundary]
def readPinInStructureList(self,label_coordinates,layer): def readAllPin(self,label_name):
"""
Search for a pin label and return ALL the enclosing rectangles on the same layer
as the pin label.
"""
label_layer = None
label_coordinate = [None, None]
for Text in self.structures[self.rootStructureName].texts:
if Text.textString == label_name or Text.textString == label_name+"\x00":
label_layer = Text.drawingLayer
label_coordinate = Text.coordinates
pin_boundaries=self.readAllPinInStructureList(label_coordinate, label_layer)
# Convert to user units
new_boundaries = []
for pin_boundary in pin_boundaries:
new_boundaries.append([pin_boundary[0]*self.units[0],pin_boundary[1]*self.units[0],
pin_boundary[2]*self.units[0],pin_boundary[3]*self.units[0]])
return [label_name, label_layer, new_boundaries]
def readAllPinInStructureList(self,label_coordinates,layer):
""" """
Given the label coordinate, search for enclosing structures on the given layer. Given the label coordinate, search for enclosing structures on the given layer.
Return the single biggest area rectangle. Return the single biggest area rectangle.
""" """
label_boundary = [None,None,None,None] label_boundaries = []
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
label_boundary=self.readPinInStruture(label_coordinates,layer,TreeUnit,label_boundary) boundaries = self.readPinInStructure(label_coordinates,layer,TreeUnit)
return label_boundary label_boundaries += boundaries
return label_boundaries
def readPinInStruture(self,label_coordinates,layer,Struture,label_boundary): def readPinInStructure(self,label_coordinates,layer,Structure):
""" """
Go through all the shapes in a strutcure and return the list of shapes
that the label coordinates are inside.
""" """
StrutureName=Struture[0] StructureName=Structure[0]
StrutureOrgin=[Struture[1][0],Struture[1][1]] StructureOrigin=[Structure[1][0],Structure[1][1]]
StrutureuVector=[Struture[2][0],Struture[2][1],Struture[2][2]] StructureuVector=[Structure[2][0],Structure[2][1],Structure[2][2]]
StruturevVector=[Struture[3][0],Struture[3][1],Struture[3][2]] StructurevVector=[Structure[3][0],Structure[3][1],Structure[3][2]]
#debug.info(debug_level,"Checking Structure: "+str(StrutureName))
#debug.info(debug_level,"-Structure Struture Orgin:"+str(StrutureOrgin))
#debug.info(debug_level,"-Structure direction: uVector["+str(StrutureuVector)+"]")
#debug.info(debug_level,"-Structure direction: vVector["+str(StruturevVector)+"]")
for boundary in self.structures[str(StrutureName)].boundaries: boundaries = []
for boundary in self.structures[str(StructureName)].boundaries:
if layer==boundary.drawingLayer: if layer==boundary.drawingLayer:
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,StrutureuVector,StruturevVector) MetalBoundary=self.tranformRectangle(MetalBoundary,StructureuVector,StructurevVector)
MetalBoundary=[MetalBoundary[0]+StrutureOrgin[0],MetalBoundary[1]+StrutureOrgin[1], MetalBoundary=[MetalBoundary[0]+StructureOrigin[0],MetalBoundary[1]+StructureOrigin[1],
MetalBoundary[2]+StrutureOrgin[0],MetalBoundary[3]+StrutureOrgin[1]] MetalBoundary[2]+StructureOrigin[0],MetalBoundary[3]+StructureOrigin[1]]
result = self.labelInRectangle(label_coordinates[0],MetalBoundary) if self.labelInRectangle(label_coordinates[0],MetalBoundary):
if (result): boundaries.append(MetalBoundary)
#debug.info(debug_level,"Rectangle(layer"+str(layer)+") at "+str(MetalBoundary))
#debug.info(debug_level,"covers label (offset"+str(label_coordinates)+")") return boundaries
label_boundary=self.returnBiggerBoundary(MetalBoundary,label_boundary)
return label_boundary
def tranformRectangle(self,orignalRectangle,uVector,vVector): def tranformRectangle(self,orignalRectangle,uVector,vVector):
""" """
@ -746,18 +777,18 @@ class VlsiLayout:
else: else:
return False return False
def returnBiggerBoundary(self,comparedRectangle,label_boundary): def cmpBoundaryAreas(A,B):
""" """
Compares two rectangles and returns the bigger in terms of area. Compares two rectangles and returns the bigger in terms of area.
""" """
if label_boundary[0]== None: area_A=(A[2]-A[0])*(A[3]-A[1])
label_boundary=comparedRectangle area_B=(B[2]-B[0])*(B[3]-B[1])
#debug.info(debug_level,"The label_boundary is initialized to "+str(label_boundary)) if area_A>area_B:
else: return 1
area_label_boundary=(label_boundary[2]-label_boundary[0])*(label_boundary[3]-label_boundary[1]) elif area_A==area_B:
area_comparedRectangle=(comparedRectangle[2]-comparedRectangle[0])*(comparedRectangle[3]-comparedRectangle[1]) return 0
if area_label_boundary<=area_comparedRectangle: else:
label_boundary = comparedRectangle return -1
#debug.info(debug_level,"The label_boundary is updated to "+str(label_boundary))
return label_boundary

View File

@ -27,6 +27,8 @@ class router:
self.pin_names = [] self.pin_names = []
self.pin_shapes = {} self.pin_shapes = {}
# Used to track which shapes should not become blockages
self.all_pin_shapes = []
self.pin_layers = {} self.pin_layers = {}
self.boundary = self.layout.measureBoundary(self.top_name) self.boundary = self.layout.measureBoundary(self.top_name)
@ -86,16 +88,22 @@ class router:
def find_pin(self,pin): def find_pin(self,pin):
""" Finds the offsets to the gds pins """ """ Finds the pin shapes and converts to tracks """
(pin_name,pin_layer,pin_shape) = self.layout.readPin(str(pin)) (pin_name,pin_layer,pin_shapes) = self.layout.readAllPin(str(pin))
debug.info(3,"Find pin {0} layer {1} shape {2}".format(pin_name,str(pin_layer),str(pin_shape)))
# repack the shape as a pair of vectors rather than four values self.pin_shapes[str(pin)]=[]
shape=[vector(pin_shape[0],pin_shape[1]),vector(pin_shape[2],pin_shape[3])]
new_shape = self.convert_shape_to_tracks(shape,round_bigger=False)
self.pin_names.append(pin_name) self.pin_names.append(pin_name)
self.pin_shapes[str(pin)] = new_shape
self.pin_layers[str(pin)] = pin_layer for pin_shape in pin_shapes:
return new_shape debug.info(3,"Find pin {0} layer {1} shape {2}".format(pin_name,str(pin_layer),str(pin_shape)))
# repack the shape as a pair of vectors rather than four values
shape=[vector(pin_shape[0],pin_shape[1]),vector(pin_shape[2],pin_shape[3])]
new_shape = self.convert_shape_to_tracks(shape,round_bigger=False)
self.pin_shapes[str(pin)].append(new_shape)
self.all_pin_shapes.append(new_shape)
self.pin_layers[str(pin)] = pin_layer
return self.pin_shapes[str(pin)]
def find_blockages(self): def find_blockages(self):
if len(self.pin_names)!=2: if len(self.pin_names)!=2:
@ -205,17 +213,19 @@ class router:
self.rg.set_path(path) self.rg.set_path(path)
def set_source(self,name): def set_source(self,name):
shape = self.find_pin(name) shapes = self.find_pin(name)
zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1 zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1
debug.info(1,"Set source: " + str(name) + " " + str(shape) + " z=" + str(zindex)) for shape in shapes:
self.rg.set_source(shape[0],shape[1],zindex) debug.info(1,"Set source: " + str(name) + " " + str(shape) + " z=" + str(zindex))
self.rg.set_source(shape[0],shape[1],zindex)
def set_target(self,name): def set_target(self,name):
shape = self.find_pin(name) shapes = self.find_pin(name)
zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1 zindex = 0 if self.pin_layers[name]==self.horiz_layer_number else 1
debug.info(1,"Set target: " + str(name) + " " + str(shape) + " z=" + str(zindex)) for shape in shapes:
self.rg.set_target(shape[0],shape[1],zindex) debug.info(1,"Set target: " + str(name) + " " + str(shape) + " z=" + str(zindex))
self.rg.set_target(shape[0],shape[1],zindex)
def write_obstacle(self, sref, mirr = 1, angle = math.radians(float(0)), xyShift = (0, 0)): def write_obstacle(self, sref, mirr = 1, angle = math.radians(float(0)), xyShift = (0, 0)):
"""Recursive write boundaries on each Structure in GDS file to LEF""" """Recursive write boundaries on each Structure in GDS file to LEF"""
@ -230,7 +240,7 @@ class router:
pin_shape_tracks=self.convert_shape_to_tracks(shape,round_bigger=False) pin_shape_tracks=self.convert_shape_to_tracks(shape,round_bigger=False)
# don't add a blockage if this shape was a pin shape # don't add a blockage if this shape was a pin shape
if pin_shape_tracks not in self.pin_shapes.values(): if pin_shape_tracks not in self.all_pin_shapes:
# inflate the ll and ur by 1 track in each direction # inflate the ll and ur by 1 track in each direction
[ll,ur]=self.convert_shape_to_tracks(shape) [ll,ur]=self.convert_shape_to_tracks(shape)
zlayer = 0 if boundary.drawingLayer==self.horiz_layer_number else 1 zlayer = 0 if boundary.drawingLayer==self.horiz_layer_number else 1

View File

@ -49,7 +49,7 @@ class no_blockages_test(unittest.TestCase):
r=router.router(gdsname+".gds") r=router.router(gdsname+".gds")
layer_stack =("metal1","via1","metal2") layer_stack =("metal1","via1","metal2")
path=r.route(layer_stack,src="A",dest="B") path=r.route(layer_stack,src="A",dest="B")
#r.rg.view() r.rg.view()
self.add_wire(layer_stack,path) self.add_wire(layer_stack,path)