Add separate layer and purpose pairs to tech layers.

This commit is contained in:
Matt Guthaus 2019-10-25 10:03:25 -07:00
parent 31825d9d77
commit 38213d998f
10 changed files with 160 additions and 155 deletions

View File

@ -266,11 +266,12 @@ class instance(geometry):
class path(geometry): class path(geometry):
"""Represents a Path""" """Represents a Path"""
def __init__(self, layerNumber, coordinates, path_width): def __init__(self, lpp, coordinates, path_width):
"""Initializes a path for the specified layer""" """Initializes a path for the specified layer"""
geometry.__init__(self) geometry.__init__(self)
self.name = "path" self.name = "path"
self.layerNumber = layerNumber self.layerNumber = lpp[0]
self.layerPurpose = lpp[1]
self.coordinates = map(lambda x: [x[0], x[1]], coordinates) self.coordinates = map(lambda x: [x[0], x[1]], coordinates)
self.coordinates = vector(self.coordinates).snap_to_grid() self.coordinates = vector(self.coordinates).snap_to_grid()
self.path_width = path_width self.path_width = path_width
@ -283,7 +284,7 @@ class path(geometry):
"""Writes the path to GDS""" """Writes the path to GDS"""
debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates) debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates)
new_layout.addPath(layerNumber=self.layerNumber, new_layout.addPath(layerNumber=self.layerNumber,
purposeNumber=0, purposeNumber=self.layerPurpose,
coordinates=self.coordinates, coordinates=self.coordinates,
width=self.path_width) width=self.path_width)
@ -303,12 +304,13 @@ class path(geometry):
class label(geometry): class label(geometry):
"""Represents a text label""" """Represents a text label"""
def __init__(self, text, layerNumber, offset, zoom=-1): def __init__(self, text, lpp, offset, zoom=-1):
"""Initializes a text label for specified layer""" """Initializes a text label for specified layer"""
geometry.__init__(self) geometry.__init__(self)
self.name = "label" self.name = "label"
self.text = text self.text = text
self.layerNumber = layerNumber self.layerNumber = lpp[0]
self.layerPurpose = lpp[1]
self.offset = vector(offset).snap_to_grid() self.offset = vector(offset).snap_to_grid()
if zoom<0: if zoom<0:
@ -325,7 +327,7 @@ class label(geometry):
debug.info(4, "writing label (" + str(self.layerNumber) + "): " + self.text) debug.info(4, "writing label (" + str(self.layerNumber) + "): " + self.text)
new_layout.addText(text=self.text, new_layout.addText(text=self.text,
layerNumber=self.layerNumber, layerNumber=self.layerNumber,
purposeNumber=0, purposeNumber=self.layerPurpose,
offsetInMicrons=self.offset, offsetInMicrons=self.offset,
magnification=self.zoom, magnification=self.zoom,
rotate=None) rotate=None)
@ -346,11 +348,12 @@ class label(geometry):
class rectangle(geometry): class rectangle(geometry):
"""Represents a rectangular shape""" """Represents a rectangular shape"""
def __init__(self, layerNumber, offset, width, height): def __init__(self, lpp, offset, width, height):
"""Initializes a rectangular shape for specified layer""" """Initializes a rectangular shape for specified layer"""
geometry.__init__(self) geometry.__init__(self)
self.name = "rect" self.name = "rect"
self.layerNumber = layerNumber self.layerNumber = lpp[0]
self.layerPurpose = lpp[1]
self.offset = vector(offset).snap_to_grid() self.offset = vector(offset).snap_to_grid()
self.size = vector(width, height).snap_to_grid() self.size = vector(width, height).snap_to_grid()
self.width = round_to_grid(self.size.x) self.width = round_to_grid(self.size.x)
@ -374,7 +377,7 @@ class rectangle(geometry):
debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):" debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):"
+ str(self.width) + "x" + str(self.height) + " @ " + str(self.offset)) + str(self.width) + "x" + str(self.height) + " @ " + str(self.offset))
new_layout.addBox(layerNumber=self.layerNumber, new_layout.addBox(layerNumber=self.layerNumber,
purposeNumber=0, purposeNumber=self.layerPurpose,
offsetInMicrons=self.offset, offsetInMicrons=self.offset,
width=self.width, width=self.width,
height=self.height, height=self.height,

View File

@ -150,9 +150,9 @@ class layout():
if not height: if not height:
height=drc["minwidth_{}".format(layer)] height=drc["minwidth_{}".format(layer)]
# negative layers indicate "unused" layers in a given technology # negative layers indicate "unused" layers in a given technology
layer_num = techlayer[layer] lpp = techlayer[layer]
if layer_num >= 0: if lpp[0] >= 0:
self.objs.append(geometry.rectangle(layer_num, offset, width, height)) self.objs.append(geometry.rectangle(lpp, offset, width, height))
return self.objs[-1] return self.objs[-1]
return None return None
@ -165,10 +165,10 @@ class layout():
if not height: if not height:
height=drc["minwidth_{}".format(layer)] height=drc["minwidth_{}".format(layer)]
# negative layers indicate "unused" layers in a given technology # negative layers indicate "unused" layers in a given technology
layer_num = techlayer[layer] lpp = techlayer[layer]
corrected_offset = offset - vector(0.5*width,0.5*height) corrected_offset = offset - vector(0.5*width,0.5*height)
if layer_num >= 0: if lpp[0] >= 0:
self.objs.append(geometry.rectangle(layer_num, corrected_offset, width, height)) self.objs.append(geometry.rectangle(lpp, corrected_offset, width, height))
return self.objs[-1] return self.objs[-1]
return None return None
@ -334,9 +334,9 @@ class layout():
"""Adds a text label on the given layer,offset, and zoom level""" """Adds a text label on the given layer,offset, and zoom level"""
# negative layers indicate "unused" layers in a given technology # negative layers indicate "unused" layers in a given technology
debug.info(5,"add label " + str(text) + " " + layer + " " + str(offset)) debug.info(5,"add label " + str(text) + " " + layer + " " + str(offset))
layer_num = techlayer[layer] lpp = techlayer[layer]
if layer_num >= 0: if lpp[0] >= 0:
self.objs.append(geometry.label(text, layer_num, offset, zoom)) self.objs.append(geometry.label(text, lpp, offset, zoom))
return self.objs[-1] return self.objs[-1]
return None return None
@ -347,9 +347,9 @@ class layout():
import wire_path import wire_path
# NOTE: (UNTESTED) add_path(...) is currently not used # NOTE: (UNTESTED) add_path(...) is currently not used
# negative layers indicate "unused" layers in a given technology # negative layers indicate "unused" layers in a given technology
#layer_num = techlayer[layer] #lpp = techlayer[layer]
#if layer_num >= 0: #if lpp[0] >= 0:
# self.objs.append(geometry.path(layer_num, coordinates, width)) # self.objs.append(geometry.path(lpp, coordinates, width))
wire_path.wire_path(obj=self, wire_path.wire_path(obj=self,
layer=layer, layer=layer,
@ -539,7 +539,7 @@ class layout():
Do not write the pins since they aren't obstructions. Do not write the pins since they aren't obstructions.
""" """
if type(layer)==str: if type(layer)==str:
layer_num = techlayer[layer] layer_num = techlayer[layer][0]
else: else:
layer_num = layer layer_num = layer

View File

@ -17,7 +17,7 @@ class pin_layout:
single shape. single shape.
""" """
def __init__(self, name, rect, layer_name_num): def __init__(self, name, rect, layer_name_pp):
self.name = name self.name = name
# repack the rect as a vector, just in case # repack the rect as a vector, just in case
if type(rect[0])==vector: if type(rect[0])==vector:
@ -30,12 +30,19 @@ class pin_layout:
debug.check(self.width()>0,"Zero width pin.") debug.check(self.width()>0,"Zero width pin.")
debug.check(self.height()>0,"Zero height pin.") debug.check(self.height()>0,"Zero height pin.")
# if it's a layer number look up the layer name. this assumes a unique layer number. # if it's a string, use the name
if type(layer_name_num)==int: if type(layer_name_pp)==str:
self.layer = list(layer.keys())[list(layer.values()).index(layer_name_num)] self.layer=layer_name_pp
# else it is required to be a lpp
else: else:
self.layer=layer_name_num for (layer_name, lpp) in layer.items():
self.layer_num = layer[self.layer] if layer_name_pp[0]==lpp[0] and (layer_name_pp[1]==None or layer_name_pp[1]==lpp[1]):
self.layer=layer_name
break
else:
debug.error("Couldn't find layer {}".format(layer_name_pp),-1)
self.lpp = layer[self.layer]
def __str__(self): def __str__(self):
""" override print function output """ """ override print function output """
@ -310,8 +317,9 @@ class pin_layout:
"""Writes the pin shape and label to GDS""" """Writes the pin shape and label to GDS"""
debug.info(4, "writing pin (" + str(self.layer) + "):" debug.info(4, "writing pin (" + str(self.layer) + "):"
+ str(self.width()) + "x" + str(self.height()) + " @ " + str(self.ll())) + str(self.width()) + "x" + str(self.height()) + " @ " + str(self.ll()))
newLayout.addBox(layerNumber=layer[self.layer], (layer_num,purpose) = layer[self.layer]
purposeNumber=0, newLayout.addBox(layerNumber=layer_num,
purposeNumber=purpose,
offsetInMicrons=self.ll(), offsetInMicrons=self.ll(),
width=self.width(), width=self.width(),
height=self.height(), height=self.height(),
@ -319,8 +327,8 @@ class pin_layout:
# Add the tet in the middle of the pin. # Add the tet in the middle of the pin.
# This fixes some pin label offsetting when GDS gets imported into Magic. # This fixes some pin label offsetting when GDS gets imported into Magic.
newLayout.addText(text=self.name, newLayout.addText(text=self.name,
layerNumber=layer[self.layer], layerNumber=layer_num,
purposeNumber=0, purposeNumber=purpose,
offsetInMicrons=self.center(), offsetInMicrons=self.center(),
magnification=GDS["zoom"], magnification=GDS["zoom"],
rotate=None) rotate=None)

View File

@ -45,7 +45,7 @@ def pin_center(boundary):
""" """
return [0.5 * (boundary[0] + boundary[2]), 0.5 * (boundary[1] + boundary[3])] return [0.5 * (boundary[0] + boundary[2]), 0.5 * (boundary[1] + boundary[3])]
def auto_measure_libcell(pin_list, name, units, layer): def auto_measure_libcell(pin_list, name, units, lpp):
""" """
Open a GDS file and find the pins in pin_list as text on a given layer. Open a GDS file and find the pins in pin_list as text on a given layer.
Return these as a set of properties including the cell width/height too. Return these as a set of properties including the cell width/height too.
@ -56,19 +56,19 @@ def auto_measure_libcell(pin_list, name, units, layer):
reader.loadFromFile(cell_gds) reader.loadFromFile(cell_gds)
cell = {} cell = {}
measure_result = cell_vlsi.getLayoutBorder(layer) measure_result = cell_vlsi.getLayoutBorder(lpp[0])
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:
(name,layer,boundary)=cell_vlsi.getPinShapeByLabel(str(pin)) (name,lpp,boundary)=cell_vlsi.getPinShapeByLabel(str(pin))
cell[str(pin)] = pin_center(boundary) cell[str(pin)] = pin_center(boundary)
return cell return cell
def get_gds_size(name, gds_filename, units, layer): def get_gds_size(name, gds_filename, units, lpp):
""" """
Open a GDS file and return the size from either the Open a GDS file and return the size from either the
bounding box or a border layer. bounding box or a border layer.
@ -79,20 +79,20 @@ def get_gds_size(name, gds_filename, units, layer):
reader.loadFromFile(gds_filename) reader.loadFromFile(gds_filename)
cell = {} cell = {}
measure_result = cell_vlsi.getLayoutBorder(layer) measure_result = cell_vlsi.getLayoutBorder(lpp)
if measure_result == None: if measure_result == None:
debug.info(2,"Layout border failed. Trying to measure size for {}".format(name)) debug.info(2,"Layout border failed. Trying to measure size for {}".format(name))
measure_result = cell_vlsi.measureSize(name) measure_result = cell_vlsi.measureSize(name)
# returns width,height # returns width,height
return measure_result return measure_result
def get_libcell_size(name, units, layer): def get_libcell_size(name, units, lpp):
""" """
Open a GDS file and return the library cell size from either the Open a GDS file and return the library cell size from either the
bounding box or a border layer. bounding box or a border layer.
""" """
cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds" cell_gds = OPTS.openram_tech + "gds_lib/" + str(name) + ".gds"
return(get_gds_size(name, cell_gds, units, layer)) return(get_gds_size(name, cell_gds, units, lpp))
def get_gds_pins(pin_names, name, gds_filename, units): def get_gds_pins(pin_names, name, gds_filename, units):
@ -109,10 +109,10 @@ def get_gds_pins(pin_names, name, gds_filename, units):
cell[str(pin_name)]=[] cell[str(pin_name)]=[]
pin_list=cell_vlsi.getPinShape(str(pin_name)) pin_list=cell_vlsi.getPinShape(str(pin_name))
for pin_shape in pin_list: for pin_shape in pin_list:
(layer,boundary)=pin_shape (lpp,boundary)=pin_shape
rect=[vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])] rect=[vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
# this is a list because other cells/designs may have must-connect pins # this is a list because other cells/designs may have must-connect pins
cell[str(pin_name)].append(pin_layout(pin_name, rect, layer)) cell[str(pin_name)].append(pin_layout(pin_name, rect, lpp))
return cell return cell
def get_libcell_pins(pin_list, name, units): def get_libcell_pins(pin_list, name, units):

View File

@ -686,10 +686,6 @@ class Gds2reader:
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.stripNonASCII(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])
# stripped = (c for c in structName if 0 < ord(c) < 127)
# structName = "".join(stripped)
# 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
@ -767,10 +763,6 @@ class Gds2reader:
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.stripNonASCII(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])
# stripped = (c for c in structName if 0 < ord(c) < 127)
# structName = "".join(stripped)
# 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

@ -19,7 +19,8 @@ class VlsiLayout:
self.layerNumbersInUse = [] self.layerNumbersInUse = []
self.debug = False self.debug = False
if name: if name:
self.rootStructureName=name #take the root structure and copy it to a new structure with the new name
self.rootStructureName=self.padText(name)
#create the ROOT structure #create the ROOT structure
self.structures[self.rootStructureName] = GdsStructure() self.structures[self.rootStructureName] = GdsStructure()
self.structures[self.rootStructureName].name = name self.structures[self.rootStructureName].name = name
@ -82,13 +83,9 @@ class VlsiLayout:
return coordinatesRotate return coordinatesRotate
def rename(self,newName): def rename(self,newName):
#make sure the newName is a multiple of 2 characters
if(len(newName)%2 == 1):
#pad with a zero
newName = newName + '\x00'
#take the root structure and copy it to a new structure with the new name #take the root structure and copy it to a new structure with the new name
self.structures[newName] = self.structures[self.rootStructureName] self.structures[newName] = self.structures[self.rootStructureName]
self.structures[newName].name = newName self.structures[newName].name = self.padText(newName)
#and delete the old root #and delete the old root
del self.structures[self.rootStructureName] del self.structures[self.rootStructureName]
self.rootStructureName = newName self.rootStructureName = newName
@ -159,6 +156,7 @@ class VlsiLayout:
debug.check(len(structureNames)==1,"Multiple possible root structures in the layout: {}".format(str(structureNames))) debug.check(len(structureNames)==1,"Multiple possible root structures in the layout: {}".format(str(structureNames)))
self.rootStructureName = structureNames[0] self.rootStructureName = structureNames[0]
def traverseTheHierarchy(self, startingStructureName=None, delegateFunction = None, def traverseTheHierarchy(self, startingStructureName=None, delegateFunction = None,
transformPath = [], rotateAngle = 0, transFlags = [0,0,0], coordinates = (0,0)): transformPath = [], rotateAngle = 0, transFlags = [0,0,0], coordinates = (0,0)):
#since this is a recursive function, must deal with the default #since this is a recursive function, must deal with the default
@ -219,7 +217,7 @@ class VlsiLayout:
self.populateCoordinateMap() self.populateCoordinateMap()
for layerNumber in self.layerNumbersInUse: for layerNumber in self.layerNumbersInUse:
self.processLabelPins(layerNumber) self.processLabelPins((layerNumber,None))
def populateCoordinateMap(self): def populateCoordinateMap(self):
@ -400,10 +398,10 @@ class VlsiLayout:
cY = self.userUnits(coordinate[1]) cY = self.userUnits(coordinate[1])
layoutUnitCoordinates.append((cX,cY)) layoutUnitCoordinates.append((cX,cY))
pathToAdd = GdsPath() pathToAdd = GdsPath()
pathToAdd.drawingLayer=layerNumber pathToAdd.drawingLayer = layerNumber
pathToAdd.purposeLayer = purposeNumber pathToAdd.purposeLayer = purposeNumber
pathToAdd.pathWidth=widthInLayoutUnits pathToAdd.pathWidth = widthInLayoutUnits
pathToAdd.coordinates=layoutUnitCoordinates pathToAdd.coordinates = layoutUnitCoordinates
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].paths.append(pathToAdd) self.structures[self.rootStructureName].paths.append(pathToAdd)
@ -415,9 +413,7 @@ class VlsiLayout:
textToAdd.dataType = 0 textToAdd.dataType = 0
textToAdd.coordinates = [offsetInLayoutUnits] textToAdd.coordinates = [offsetInLayoutUnits]
textToAdd.transFlags = [0,0,0] textToAdd.transFlags = [0,0,0]
if(len(text)%2 == 1): textToAdd.textString = self.padText(text)
text = text + '\x00'
textToAdd.textString = text
#textToAdd.transFlags[1] = 1 #textToAdd.transFlags[1] = 1
textToAdd.magFactor = magnification textToAdd.magFactor = magnification
if rotate: if rotate:
@ -426,6 +422,12 @@ class VlsiLayout:
#add the sref to the root structure #add the sref to the root structure
self.structures[self.rootStructureName].texts.append(textToAdd) self.structures[self.rootStructureName].texts.append(textToAdd)
def padText(self, text):
if(len(text)%2 == 1):
return text + '\x00'
else:
return text
def isBounded(self,testPoint,startPoint,endPoint): def isBounded(self,testPoint,startPoint,endPoint):
#these arguments are touples of (x,y) coordinates #these arguments are touples of (x,y) coordinates
if testPoint == None: if testPoint == None:
@ -591,22 +593,23 @@ class VlsiLayout:
passFailIndex += 1 passFailIndex += 1
print("Done\n\n") print("Done\n\n")
def getLayoutBorder(self,borderlayer): def getLayoutBorder(self,lpp):
cellSizeMicron=None cellSizeMicron=None
for boundary in self.structures[self.rootStructureName].boundaries: for boundary in self.structures[self.rootStructureName].boundaries:
if boundary.drawingLayer==borderlayer: if boundary.drawingLayer==lpp[0] and \
(lpp[1]==None or boundary.purposeLayer==None or boundary.purposeLayer==lpp[1]):
if self.debug: if self.debug:
debug.info(1,"Find border "+str(boundary.coordinates)) debug.info(1,"Find border "+str(boundary.coordinates))
left_bottom=boundary.coordinates[0] left_bottom=boundary.coordinates[0]
right_top=boundary.coordinates[2] right_top=boundary.coordinates[2]
cellSize=[right_top[0]-left_bottom[0],right_top[1]-left_bottom[1]] cellSize=[right_top[0]-left_bottom[0],right_top[1]-left_bottom[1]]
cellSizeMicron=[cellSize[0]*self.units[0],cellSize[1]*self.units[0]] cellSizeMicron=[cellSize[0]*self.units[0],cellSize[1]*self.units[0]]
if not(cellSizeMicron): debug.check(cellSizeMicron,
print("Error: "+str(self.rootStructureName)+".cell_size information not found yet") "Error: "+str(self.rootStructureName)+".cell_size information not found yet")
return cellSizeMicron return cellSizeMicron
def measureSize(self,startStructure): def measureSize(self,startStructure):
self.rootStructureName=startStructure self.rootStructureName=self.padText(startStructure)
self.populateCoordinateMap() self.populateCoordinateMap()
cellBoundary = [None, None, None, None] cellBoundary = [None, None, None, None]
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
@ -616,7 +619,7 @@ class VlsiLayout:
return cellSizeMicron return cellSizeMicron
def measureBoundary(self,startStructure): def measureBoundary(self,startStructure):
self.rootStructureName=startStructure self.rootStructureName=self.padText(startStructure)
self.populateCoordinateMap() self.populateCoordinateMap()
cellBoundary = [None, None, None, None] cellBoundary = [None, None, None, None]
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
@ -653,13 +656,13 @@ class VlsiLayout:
return cellBoundary return cellBoundary
def getTexts(self, layer): def getTexts(self, lpp):
""" """
Get all of the labels on a given layer only at the root level. Get all of the labels on a given layer only at the root level.
""" """
text_list = [] text_list = []
for Text in self.structures[self.rootStructureName].texts: for Text in self.structures[self.rootStructureName].texts:
if Text.drawingLayer == layer: if Text.drawingLayer==lpp[0] and (lpp[1]==None or Text.purposeLayer==lpp[1]):
text_list.append(Text) text_list.append(Text)
return text_list return text_list
@ -700,16 +703,16 @@ class VlsiLayout:
return shape_list return shape_list
def processLabelPins(self, layer): def processLabelPins(self, lpp):
""" """
Find all text labels and create a map to a list of shapes that Find all text labels and create a map to a list of shapes that
they enclose on the given layer. they enclose on the given layer.
""" """
# Get the labels on a layer in the root level # Get the labels on a layer in the root level
labels = self.getTexts(layer) labels = self.getTexts(lpp)
# Get all of the shapes on the layer at all levels # Get all of the shapes on the layer at all levels
# and transform them to the current level # and transform them to the current level
shapes = self.getAllShapes(layer) shapes = self.getAllShapes(lpp)
for label in labels: for label in labels:
label_coordinate = label.coordinates[0] label_coordinate = label.coordinates[0]
@ -717,7 +720,7 @@ class VlsiLayout:
pin_shapes = [] pin_shapes = []
for boundary in shapes: for boundary in shapes:
if self.labelInRectangle(user_coordinate,boundary): if self.labelInRectangle(user_coordinate,boundary):
pin_shapes.append((layer, boundary)) pin_shapes.append((lpp, boundary))
label_text = label.textString label_text = label.textString
# Remove the padding if it exists # Remove the padding if it exists
@ -731,14 +734,14 @@ class VlsiLayout:
self.pins[label_text].append(pin_shapes) self.pins[label_text].append(pin_shapes)
def getBlockages(self,layer): def getBlockages(self, lpp):
""" """
Return all blockages on a given layer in [coordinate 1, coordinate 2,...] format and Return all blockages on a given layer in [coordinate 1, coordinate 2,...] format and
user units. user units.
""" """
blockages = [] blockages = []
shapes = self.getAllShapes(layer) shapes = self.getAllShapes(lpp)
for boundary in shapes: for boundary in shapes:
vectors = [] vectors = []
for i in range(0,len(boundary),2): for i in range(0,len(boundary),2):
@ -746,7 +749,7 @@ class VlsiLayout:
blockages.append(vectors) blockages.append(vectors)
return blockages return blockages
def getAllShapes(self,layer): def getAllShapes(self, lpp):
""" """
Return all shapes on a given layer in [llx, lly, urx, ury] format and user units for rectangles Return all shapes on a given layer in [llx, lly, urx, ury] format and user units for rectangles
and [coordinate 1, coordinate 2,...] format and user units for polygons. and [coordinate 1, coordinate 2,...] format and user units for polygons.
@ -754,7 +757,7 @@ class VlsiLayout:
boundaries = set() boundaries = set()
for TreeUnit in self.xyTree: for TreeUnit in self.xyTree:
#print(TreeUnit[0]) #print(TreeUnit[0])
boundaries.update(self.getShapesInStructure(layer,TreeUnit)) boundaries.update(self.getShapesInStructure(lpp,TreeUnit))
# Convert to user units # Convert to user units
user_boundaries = [] user_boundaries = []
@ -766,7 +769,7 @@ class VlsiLayout:
return user_boundaries return user_boundaries
def getShapesInStructure(self,layer,structure): def getShapesInStructure(self, lpp, structure):
""" """
Go through all the shapes in a structure and return the list of shapes in Go through all the shapes in a structure and return the list of shapes in
the form [llx, lly, urx, ury] for rectangles and [coordinate 1, coordinate 2,...] for polygons. the form [llx, lly, urx, ury] for rectangles and [coordinate 1, coordinate 2,...] for polygons.
@ -775,7 +778,7 @@ class VlsiLayout:
#print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose()) #print(structureName,"u",structureuVector.transpose(),"v",structurevVector.transpose(),"o",structureOrigin.transpose())
boundaries = [] boundaries = []
for boundary in self.structures[str(structureName)].boundaries: for boundary in self.structures[str(structureName)].boundaries:
if layer==boundary.drawingLayer: if boundary.drawingLayer==lpp[0] and (lpp[1]==None or boundary.purposeLayer==lpp[1]):
if len(boundary.coordinates)!=5: if len(boundary.coordinates)!=5:
# if shape is a polygon (used in DFF) # if shape is a polygon (used in DFF)
boundaryPolygon = [] boundaryPolygon = []

View File

@ -438,7 +438,6 @@ def import_tech():
OPTS.openram_tech = os.path.dirname(tech_mod.__file__) + "/" OPTS.openram_tech = os.path.dirname(tech_mod.__file__) + "/"
# Add the tech directory # Add the tech directory
tech_path = OPTS.openram_tech tech_path = OPTS.openram_tech
sys.path.append(tech_path) sys.path.append(tech_path)

View File

@ -35,39 +35,39 @@ GDS["zoom"] = 0.05
# create the GDS layer map # create the GDS layer map
# FIXME: parse the gds layer map from the cadence map? # FIXME: parse the gds layer map from the cadence map?
layer = {} layer = {}
layer["active"] = 1 layer["active"] = (1, 0)
layer["pwell"] = 2 layer["pwell"] = (2, 0)
layer["nwell"] = 3 layer["nwell"] = (3, 0)
layer["nimplant"]= 4 layer["nimplant"]= (4, 0)
layer["pimplant"]= 5 layer["pimplant"]= (5, 0)
layer["vtg"] = 6 layer["vtg"] = (6, 0)
layer["vth"] = 7 layer["vth"] = (7, 0)
layer["thkox"] = 8 layer["thkox"] = (8, 0)
layer["poly"] = 9 layer["poly"] = (9, 0)
layer["contact"] = 10 layer["contact"] = (10, 0)
layer["active_contact"] = 10 layer["active_contact"] = (10, 0)
layer["metal1"] = 11 layer["metal1"] = (11, 0)
layer["via1"] = 12 layer["via1"] = (12, 0)
layer["metal2"] = 13 layer["metal2"] = (13, 0)
layer["via2"] = 14 layer["via2"] = (14, 0)
layer["metal3"] = 15 layer["metal3"] = (15, 0)
layer["via3"] = 16 layer["via3"] = (16, 0)
layer["metal4"] = 17 layer["metal4"] = (17, 0)
layer["via4"] = 18 layer["via4"] = (18, 0)
layer["metal5"] = 19 layer["metal5"] = (19, 0)
layer["via5"] = 20 layer["via5"] = (20, 0)
layer["metal6"] = 21 layer["metal6"] = (21, 0)
layer["via6"] = 22 layer["via6"] = (22, 0)
layer["metal7"] = 23 layer["metal7"] = (23, 0)
layer["via7"] = 24 layer["via7"] = (24, 0)
layer["metal8"] = 25 layer["metal8"] = (25, 0)
layer["via8"] = 26 layer["via8"] = (26, 0)
layer["metal9"] = 27 layer["metal9"] = (27, 0)
layer["via9"] = 28 layer["via9"] = (28, 0)
layer["metal10"] = 29 layer["metal10"] = (29, 0)
layer["text"] = 239 layer["text"] = (239, 0)
layer["boundary"]= 239 layer["boundary"]= (239, 0)
layer["blockage"]= 239 layer["blockage"]= (239, 0)
################################################### ###################################################
##END GDS Layer Map ##END GDS Layer Map

View File

@ -29,24 +29,24 @@ GDS["zoom"] = 0.5
# create the GDS layer map # create the GDS layer map
layer={} layer={}
layer["vtg"] = -1 layer["vtg"] = (-1, 0)
layer["vth"] = -1 layer["vth"] = (-1, 0)
layer["contact"] = 47 layer["contact"] = (47, 0)
layer["pwell"] = 41 layer["pwell"] = (41, 0)
layer["nwell"] = 42 layer["nwell"] = (42, 0)
layer["active"] = 43 layer["active"] = (43, 0)
layer["pimplant"] = 44 layer["pimplant"] = (44, 0)
layer["nimplant"] = 45 layer["nimplant"] = (45, 0)
layer["poly"] = 46 layer["poly"] = (46, 0)
layer["active_contact"] = 48 layer["active_contact"] = (48, 0)
layer["metal1"] = 49 layer["metal1"] = (49, 0)
layer["via1"] = 50 layer["via1"] = (50, 0)
layer["metal2"] = 51 layer["metal2"] = (51, 0)
layer["via2"] = 61 layer["via2"] = (61, 0)
layer["metal3"] = 62 layer["metal3"] = (62, 0)
layer["text"] = 63 layer["text"] = (63, 0)
layer["boundary"] = 63 layer["boundary"] = (63, 0)
layer["blockage"] = 83 layer["blockage"] = (83, 0)
################################################### ###################################################
##END GDS Layer Map ##END GDS Layer Map

View File

@ -35,26 +35,26 @@ GDS["zoom"] = 0.5
# create the GDS layer map # create the GDS layer map
layer={} layer={}
layer["vtg"] = -1 layer["vtg"] = (-1, 0)
layer["vth"] = -1 layer["vth"] = (-1, 0)
layer["contact"] = 47 layer["contact"] = (47, 0)
layer["pwell"] = 41 layer["pwell"] = (41, 0)
layer["nwell"] = 42 layer["nwell"] = (42, 0)
layer["active"] = 43 layer["active"] = (43, 0)
layer["pimplant"] = 44 layer["pimplant"] = (44, 0)
layer["nimplant"] = 45 layer["nimplant"] = (45, 0)
layer["poly"] = 46 layer["poly"] = (46, 0)
layer["active_contact"] = 48 layer["active_contact"] = (48, 0)
layer["metal1"] = 49 layer["metal1"] = (49, 0)
layer["via1"] = 50 layer["via1"] = (50, 0)
layer["metal2"] = 51 layer["metal2"] = (51, 0)
layer["via2"] = 61 layer["via2"] = (61, 0)
layer["metal3"] = 62 layer["metal3"] = (62, 0)
layer["via3"] = 30 layer["via3"] = (30, 0)
layer["metal4"] = 31 layer["metal4"] = (31, 0)
layer["text"] = 63 layer["text"] = (63, 0)
layer["boundary"] = 63 layer["boundary"] = (63, 0)
layer["blockage"] = 83 layer["blockage"] = (83, 0)
################################################### ###################################################
##END GDS Layer Map ##END GDS Layer Map