mirror of https://github.com/VLSIDA/OpenRAM.git
Add separate layer and purpose pairs to tech layers.
This commit is contained in:
parent
31825d9d77
commit
38213d998f
|
|
@ -266,11 +266,12 @@ class instance(geometry):
|
|||
class path(geometry):
|
||||
"""Represents a Path"""
|
||||
|
||||
def __init__(self, layerNumber, coordinates, path_width):
|
||||
def __init__(self, lpp, coordinates, path_width):
|
||||
"""Initializes a path for the specified layer"""
|
||||
geometry.__init__(self)
|
||||
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 = vector(self.coordinates).snap_to_grid()
|
||||
self.path_width = path_width
|
||||
|
|
@ -283,7 +284,7 @@ class path(geometry):
|
|||
"""Writes the path to GDS"""
|
||||
debug.info(4, "writing path (" + str(self.layerNumber) + "): " + self.coordinates)
|
||||
new_layout.addPath(layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
coordinates=self.coordinates,
|
||||
width=self.path_width)
|
||||
|
||||
|
|
@ -303,12 +304,13 @@ class path(geometry):
|
|||
class label(geometry):
|
||||
"""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"""
|
||||
geometry.__init__(self)
|
||||
self.name = "label"
|
||||
self.text = text
|
||||
self.layerNumber = layerNumber
|
||||
self.layerNumber = lpp[0]
|
||||
self.layerPurpose = lpp[1]
|
||||
self.offset = vector(offset).snap_to_grid()
|
||||
|
||||
if zoom<0:
|
||||
|
|
@ -325,7 +327,7 @@ class label(geometry):
|
|||
debug.info(4, "writing label (" + str(self.layerNumber) + "): " + self.text)
|
||||
new_layout.addText(text=self.text,
|
||||
layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
offsetInMicrons=self.offset,
|
||||
magnification=self.zoom,
|
||||
rotate=None)
|
||||
|
|
@ -346,11 +348,12 @@ class label(geometry):
|
|||
class rectangle(geometry):
|
||||
"""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"""
|
||||
geometry.__init__(self)
|
||||
self.name = "rect"
|
||||
self.layerNumber = layerNumber
|
||||
self.layerNumber = lpp[0]
|
||||
self.layerPurpose = lpp[1]
|
||||
self.offset = vector(offset).snap_to_grid()
|
||||
self.size = vector(width, height).snap_to_grid()
|
||||
self.width = round_to_grid(self.size.x)
|
||||
|
|
@ -374,7 +377,7 @@ class rectangle(geometry):
|
|||
debug.info(4, "writing rectangle (" + str(self.layerNumber) + "):"
|
||||
+ str(self.width) + "x" + str(self.height) + " @ " + str(self.offset))
|
||||
new_layout.addBox(layerNumber=self.layerNumber,
|
||||
purposeNumber=0,
|
||||
purposeNumber=self.layerPurpose,
|
||||
offsetInMicrons=self.offset,
|
||||
width=self.width,
|
||||
height=self.height,
|
||||
|
|
|
|||
|
|
@ -150,9 +150,9 @@ class layout():
|
|||
if not height:
|
||||
height=drc["minwidth_{}".format(layer)]
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
layer_num = techlayer[layer]
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.rectangle(layer_num, offset, width, height))
|
||||
lpp = techlayer[layer]
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.rectangle(lpp, offset, width, height))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
|
|
@ -165,10 +165,10 @@ class layout():
|
|||
if not height:
|
||||
height=drc["minwidth_{}".format(layer)]
|
||||
# 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)
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.rectangle(layer_num, corrected_offset, width, height))
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.rectangle(lpp, corrected_offset, width, height))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
|
|
@ -334,9 +334,9 @@ class layout():
|
|||
"""Adds a text label on the given layer,offset, and zoom level"""
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
debug.info(5,"add label " + str(text) + " " + layer + " " + str(offset))
|
||||
layer_num = techlayer[layer]
|
||||
if layer_num >= 0:
|
||||
self.objs.append(geometry.label(text, layer_num, offset, zoom))
|
||||
lpp = techlayer[layer]
|
||||
if lpp[0] >= 0:
|
||||
self.objs.append(geometry.label(text, lpp, offset, zoom))
|
||||
return self.objs[-1]
|
||||
return None
|
||||
|
||||
|
|
@ -347,9 +347,9 @@ class layout():
|
|||
import wire_path
|
||||
# NOTE: (UNTESTED) add_path(...) is currently not used
|
||||
# negative layers indicate "unused" layers in a given technology
|
||||
#layer_num = techlayer[layer]
|
||||
#if layer_num >= 0:
|
||||
# self.objs.append(geometry.path(layer_num, coordinates, width))
|
||||
#lpp = techlayer[layer]
|
||||
#if lpp[0] >= 0:
|
||||
# self.objs.append(geometry.path(lpp, coordinates, width))
|
||||
|
||||
wire_path.wire_path(obj=self,
|
||||
layer=layer,
|
||||
|
|
@ -539,7 +539,7 @@ class layout():
|
|||
Do not write the pins since they aren't obstructions.
|
||||
"""
|
||||
if type(layer)==str:
|
||||
layer_num = techlayer[layer]
|
||||
layer_num = techlayer[layer][0]
|
||||
else:
|
||||
layer_num = layer
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class pin_layout:
|
|||
single shape.
|
||||
"""
|
||||
|
||||
def __init__(self, name, rect, layer_name_num):
|
||||
def __init__(self, name, rect, layer_name_pp):
|
||||
self.name = name
|
||||
# repack the rect as a vector, just in case
|
||||
if type(rect[0])==vector:
|
||||
|
|
@ -30,12 +30,19 @@ class pin_layout:
|
|||
debug.check(self.width()>0,"Zero width 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 type(layer_name_num)==int:
|
||||
self.layer = list(layer.keys())[list(layer.values()).index(layer_name_num)]
|
||||
# if it's a string, use the name
|
||||
if type(layer_name_pp)==str:
|
||||
self.layer=layer_name_pp
|
||||
# else it is required to be a lpp
|
||||
else:
|
||||
self.layer=layer_name_num
|
||||
self.layer_num = layer[self.layer]
|
||||
for (layer_name, lpp) in layer.items():
|
||||
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):
|
||||
""" override print function output """
|
||||
|
|
@ -310,8 +317,9 @@ class pin_layout:
|
|||
"""Writes the pin shape and label to GDS"""
|
||||
debug.info(4, "writing pin (" + str(self.layer) + "):"
|
||||
+ str(self.width()) + "x" + str(self.height()) + " @ " + str(self.ll()))
|
||||
newLayout.addBox(layerNumber=layer[self.layer],
|
||||
purposeNumber=0,
|
||||
(layer_num,purpose) = layer[self.layer]
|
||||
newLayout.addBox(layerNumber=layer_num,
|
||||
purposeNumber=purpose,
|
||||
offsetInMicrons=self.ll(),
|
||||
width=self.width(),
|
||||
height=self.height(),
|
||||
|
|
@ -319,8 +327,8 @@ class pin_layout:
|
|||
# Add the tet in the middle of the pin.
|
||||
# This fixes some pin label offsetting when GDS gets imported into Magic.
|
||||
newLayout.addText(text=self.name,
|
||||
layerNumber=layer[self.layer],
|
||||
purposeNumber=0,
|
||||
layerNumber=layer_num,
|
||||
purposeNumber=purpose,
|
||||
offsetInMicrons=self.center(),
|
||||
magnification=GDS["zoom"],
|
||||
rotate=None)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ def pin_center(boundary):
|
|||
"""
|
||||
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.
|
||||
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)
|
||||
|
||||
cell = {}
|
||||
measure_result = cell_vlsi.getLayoutBorder(layer)
|
||||
measure_result = cell_vlsi.getLayoutBorder(lpp[0])
|
||||
if measure_result == None:
|
||||
measure_result = cell_vlsi.measureSize(name)
|
||||
[cell["width"], cell["height"]] = measure_result
|
||||
|
||||
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)
|
||||
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
|
||||
bounding box or a border layer.
|
||||
|
|
@ -79,20 +79,20 @@ def get_gds_size(name, gds_filename, units, layer):
|
|||
reader.loadFromFile(gds_filename)
|
||||
|
||||
cell = {}
|
||||
measure_result = cell_vlsi.getLayoutBorder(layer)
|
||||
measure_result = cell_vlsi.getLayoutBorder(lpp)
|
||||
if measure_result == None:
|
||||
debug.info(2,"Layout border failed. Trying to measure size for {}".format(name))
|
||||
measure_result = cell_vlsi.measureSize(name)
|
||||
# returns width,height
|
||||
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
|
||||
bounding box or a border layer.
|
||||
"""
|
||||
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):
|
||||
|
|
@ -109,10 +109,10 @@ def get_gds_pins(pin_names, name, gds_filename, units):
|
|||
cell[str(pin_name)]=[]
|
||||
pin_list=cell_vlsi.getPinShape(str(pin_name))
|
||||
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])]
|
||||
# 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
|
||||
|
||||
def get_libcell_pins(pin_list, name, units):
|
||||
|
|
|
|||
|
|
@ -686,10 +686,6 @@ class Gds2reader:
|
|||
if idBits==('\x07','\x00'): break; #we've reached the end of the structure
|
||||
elif(idBits==('\x06','\x06')):
|
||||
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
|
||||
if(findStructName==thisStructure.name):
|
||||
wantedStruct=1
|
||||
|
|
@ -767,10 +763,6 @@ class Gds2reader:
|
|||
if idBits==('\x07','\x00'): break; #we've reached the end of the structure
|
||||
elif(idBits==('\x06','\x06')):
|
||||
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
|
||||
if(self.debugToTerminal==1):
|
||||
print("\tStructure Name: "+structName)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ class VlsiLayout:
|
|||
self.layerNumbersInUse = []
|
||||
self.debug = False
|
||||
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
|
||||
self.structures[self.rootStructureName] = GdsStructure()
|
||||
self.structures[self.rootStructureName].name = name
|
||||
|
|
@ -82,13 +83,9 @@ class VlsiLayout:
|
|||
return coordinatesRotate
|
||||
|
||||
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
|
||||
self.structures[newName] = self.structures[self.rootStructureName]
|
||||
self.structures[newName].name = newName
|
||||
self.structures[newName].name = self.padText(newName)
|
||||
#and delete the old root
|
||||
del self.structures[self.rootStructureName]
|
||||
self.rootStructureName = newName
|
||||
|
|
@ -159,13 +156,14 @@ class VlsiLayout:
|
|||
debug.check(len(structureNames)==1,"Multiple possible root structures in the layout: {}".format(str(structureNames)))
|
||||
self.rootStructureName = structureNames[0]
|
||||
|
||||
|
||||
def traverseTheHierarchy(self, startingStructureName=None, delegateFunction = None,
|
||||
transformPath = [], rotateAngle = 0, transFlags = [0,0,0], coordinates = (0,0)):
|
||||
#since this is a recursive function, must deal with the default
|
||||
#parameters explicitly
|
||||
if startingStructureName == None:
|
||||
startingStructureName = self.rootStructureName
|
||||
|
||||
|
||||
#set up the rotation matrix
|
||||
if(rotateAngle == None or rotateAngle == ""):
|
||||
angle = 0
|
||||
|
|
@ -219,7 +217,7 @@ class VlsiLayout:
|
|||
self.populateCoordinateMap()
|
||||
|
||||
for layerNumber in self.layerNumbersInUse:
|
||||
self.processLabelPins(layerNumber)
|
||||
self.processLabelPins((layerNumber,None))
|
||||
|
||||
|
||||
def populateCoordinateMap(self):
|
||||
|
|
@ -400,10 +398,10 @@ class VlsiLayout:
|
|||
cY = self.userUnits(coordinate[1])
|
||||
layoutUnitCoordinates.append((cX,cY))
|
||||
pathToAdd = GdsPath()
|
||||
pathToAdd.drawingLayer=layerNumber
|
||||
pathToAdd.drawingLayer = layerNumber
|
||||
pathToAdd.purposeLayer = purposeNumber
|
||||
pathToAdd.pathWidth=widthInLayoutUnits
|
||||
pathToAdd.coordinates=layoutUnitCoordinates
|
||||
pathToAdd.pathWidth = widthInLayoutUnits
|
||||
pathToAdd.coordinates = layoutUnitCoordinates
|
||||
#add the sref to the root structure
|
||||
self.structures[self.rootStructureName].paths.append(pathToAdd)
|
||||
|
||||
|
|
@ -414,10 +412,8 @@ class VlsiLayout:
|
|||
textToAdd.purposeLayer = purposeNumber
|
||||
textToAdd.dataType = 0
|
||||
textToAdd.coordinates = [offsetInLayoutUnits]
|
||||
textToAdd.transFlags = [0,0,0]
|
||||
if(len(text)%2 == 1):
|
||||
text = text + '\x00'
|
||||
textToAdd.textString = text
|
||||
textToAdd.transFlags = [0,0,0]
|
||||
textToAdd.textString = self.padText(text)
|
||||
#textToAdd.transFlags[1] = 1
|
||||
textToAdd.magFactor = magnification
|
||||
if rotate:
|
||||
|
|
@ -425,7 +421,13 @@ class VlsiLayout:
|
|||
textToAdd.rotateAngle = rotate
|
||||
#add the sref to the root structure
|
||||
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):
|
||||
#these arguments are touples of (x,y) coordinates
|
||||
if testPoint == None:
|
||||
|
|
@ -591,22 +593,23 @@ class VlsiLayout:
|
|||
passFailIndex += 1
|
||||
print("Done\n\n")
|
||||
|
||||
def getLayoutBorder(self,borderlayer):
|
||||
def getLayoutBorder(self,lpp):
|
||||
cellSizeMicron=None
|
||||
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:
|
||||
debug.info(1,"Find border "+str(boundary.coordinates))
|
||||
left_bottom=boundary.coordinates[0]
|
||||
right_top=boundary.coordinates[2]
|
||||
cellSize=[right_top[0]-left_bottom[0],right_top[1]-left_bottom[1]]
|
||||
cellSizeMicron=[cellSize[0]*self.units[0],cellSize[1]*self.units[0]]
|
||||
if not(cellSizeMicron):
|
||||
print("Error: "+str(self.rootStructureName)+".cell_size information not found yet")
|
||||
debug.check(cellSizeMicron,
|
||||
"Error: "+str(self.rootStructureName)+".cell_size information not found yet")
|
||||
return cellSizeMicron
|
||||
|
||||
def measureSize(self,startStructure):
|
||||
self.rootStructureName=startStructure
|
||||
self.rootStructureName=self.padText(startStructure)
|
||||
self.populateCoordinateMap()
|
||||
cellBoundary = [None, None, None, None]
|
||||
for TreeUnit in self.xyTree:
|
||||
|
|
@ -616,7 +619,7 @@ class VlsiLayout:
|
|||
return cellSizeMicron
|
||||
|
||||
def measureBoundary(self,startStructure):
|
||||
self.rootStructureName=startStructure
|
||||
self.rootStructureName=self.padText(startStructure)
|
||||
self.populateCoordinateMap()
|
||||
cellBoundary = [None, None, None, None]
|
||||
for TreeUnit in self.xyTree:
|
||||
|
|
@ -653,13 +656,13 @@ class VlsiLayout:
|
|||
return cellBoundary
|
||||
|
||||
|
||||
def getTexts(self, layer):
|
||||
def getTexts(self, lpp):
|
||||
"""
|
||||
Get all of the labels on a given layer only at the root level.
|
||||
"""
|
||||
text_list = []
|
||||
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)
|
||||
return text_list
|
||||
|
||||
|
|
@ -700,16 +703,16 @@ class VlsiLayout:
|
|||
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
|
||||
they enclose on the given layer.
|
||||
"""
|
||||
# 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
|
||||
# and transform them to the current level
|
||||
shapes = self.getAllShapes(layer)
|
||||
shapes = self.getAllShapes(lpp)
|
||||
|
||||
for label in labels:
|
||||
label_coordinate = label.coordinates[0]
|
||||
|
|
@ -717,7 +720,7 @@ class VlsiLayout:
|
|||
pin_shapes = []
|
||||
for boundary in shapes:
|
||||
if self.labelInRectangle(user_coordinate,boundary):
|
||||
pin_shapes.append((layer, boundary))
|
||||
pin_shapes.append((lpp, boundary))
|
||||
|
||||
label_text = label.textString
|
||||
# Remove the padding if it exists
|
||||
|
|
@ -731,14 +734,14 @@ class VlsiLayout:
|
|||
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
|
||||
user units.
|
||||
"""
|
||||
blockages = []
|
||||
|
||||
shapes = self.getAllShapes(layer)
|
||||
shapes = self.getAllShapes(lpp)
|
||||
for boundary in shapes:
|
||||
vectors = []
|
||||
for i in range(0,len(boundary),2):
|
||||
|
|
@ -746,7 +749,7 @@ class VlsiLayout:
|
|||
blockages.append(vectors)
|
||||
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
|
||||
and [coordinate 1, coordinate 2,...] format and user units for polygons.
|
||||
|
|
@ -754,7 +757,7 @@ class VlsiLayout:
|
|||
boundaries = set()
|
||||
for TreeUnit in self.xyTree:
|
||||
#print(TreeUnit[0])
|
||||
boundaries.update(self.getShapesInStructure(layer,TreeUnit))
|
||||
boundaries.update(self.getShapesInStructure(lpp,TreeUnit))
|
||||
|
||||
# Convert to user units
|
||||
user_boundaries = []
|
||||
|
|
@ -766,7 +769,7 @@ class VlsiLayout:
|
|||
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
|
||||
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())
|
||||
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 shape is a polygon (used in DFF)
|
||||
boundaryPolygon = []
|
||||
|
|
|
|||
|
|
@ -438,7 +438,6 @@ def import_tech():
|
|||
|
||||
OPTS.openram_tech = os.path.dirname(tech_mod.__file__) + "/"
|
||||
|
||||
|
||||
# Add the tech directory
|
||||
tech_path = OPTS.openram_tech
|
||||
sys.path.append(tech_path)
|
||||
|
|
|
|||
|
|
@ -35,39 +35,39 @@ GDS["zoom"] = 0.05
|
|||
# create the GDS layer map
|
||||
# FIXME: parse the gds layer map from the cadence map?
|
||||
layer = {}
|
||||
layer["active"] = 1
|
||||
layer["pwell"] = 2
|
||||
layer["nwell"] = 3
|
||||
layer["nimplant"]= 4
|
||||
layer["pimplant"]= 5
|
||||
layer["vtg"] = 6
|
||||
layer["vth"] = 7
|
||||
layer["thkox"] = 8
|
||||
layer["poly"] = 9
|
||||
layer["contact"] = 10
|
||||
layer["active_contact"] = 10
|
||||
layer["metal1"] = 11
|
||||
layer["via1"] = 12
|
||||
layer["metal2"] = 13
|
||||
layer["via2"] = 14
|
||||
layer["metal3"] = 15
|
||||
layer["via3"] = 16
|
||||
layer["metal4"] = 17
|
||||
layer["via4"] = 18
|
||||
layer["metal5"] = 19
|
||||
layer["via5"] = 20
|
||||
layer["metal6"] = 21
|
||||
layer["via6"] = 22
|
||||
layer["metal7"] = 23
|
||||
layer["via7"] = 24
|
||||
layer["metal8"] = 25
|
||||
layer["via8"] = 26
|
||||
layer["metal9"] = 27
|
||||
layer["via9"] = 28
|
||||
layer["metal10"] = 29
|
||||
layer["text"] = 239
|
||||
layer["boundary"]= 239
|
||||
layer["blockage"]= 239
|
||||
layer["active"] = (1, 0)
|
||||
layer["pwell"] = (2, 0)
|
||||
layer["nwell"] = (3, 0)
|
||||
layer["nimplant"]= (4, 0)
|
||||
layer["pimplant"]= (5, 0)
|
||||
layer["vtg"] = (6, 0)
|
||||
layer["vth"] = (7, 0)
|
||||
layer["thkox"] = (8, 0)
|
||||
layer["poly"] = (9, 0)
|
||||
layer["contact"] = (10, 0)
|
||||
layer["active_contact"] = (10, 0)
|
||||
layer["metal1"] = (11, 0)
|
||||
layer["via1"] = (12, 0)
|
||||
layer["metal2"] = (13, 0)
|
||||
layer["via2"] = (14, 0)
|
||||
layer["metal3"] = (15, 0)
|
||||
layer["via3"] = (16, 0)
|
||||
layer["metal4"] = (17, 0)
|
||||
layer["via4"] = (18, 0)
|
||||
layer["metal5"] = (19, 0)
|
||||
layer["via5"] = (20, 0)
|
||||
layer["metal6"] = (21, 0)
|
||||
layer["via6"] = (22, 0)
|
||||
layer["metal7"] = (23, 0)
|
||||
layer["via7"] = (24, 0)
|
||||
layer["metal8"] = (25, 0)
|
||||
layer["via8"] = (26, 0)
|
||||
layer["metal9"] = (27, 0)
|
||||
layer["via9"] = (28, 0)
|
||||
layer["metal10"] = (29, 0)
|
||||
layer["text"] = (239, 0)
|
||||
layer["boundary"]= (239, 0)
|
||||
layer["blockage"]= (239, 0)
|
||||
|
||||
###################################################
|
||||
##END GDS Layer Map
|
||||
|
|
|
|||
|
|
@ -29,24 +29,24 @@ GDS["zoom"] = 0.5
|
|||
|
||||
# create the GDS layer map
|
||||
layer={}
|
||||
layer["vtg"] = -1
|
||||
layer["vth"] = -1
|
||||
layer["contact"] = 47
|
||||
layer["pwell"] = 41
|
||||
layer["nwell"] = 42
|
||||
layer["active"] = 43
|
||||
layer["pimplant"] = 44
|
||||
layer["nimplant"] = 45
|
||||
layer["poly"] = 46
|
||||
layer["active_contact"] = 48
|
||||
layer["metal1"] = 49
|
||||
layer["via1"] = 50
|
||||
layer["metal2"] = 51
|
||||
layer["via2"] = 61
|
||||
layer["metal3"] = 62
|
||||
layer["text"] = 63
|
||||
layer["boundary"] = 63
|
||||
layer["blockage"] = 83
|
||||
layer["vtg"] = (-1, 0)
|
||||
layer["vth"] = (-1, 0)
|
||||
layer["contact"] = (47, 0)
|
||||
layer["pwell"] = (41, 0)
|
||||
layer["nwell"] = (42, 0)
|
||||
layer["active"] = (43, 0)
|
||||
layer["pimplant"] = (44, 0)
|
||||
layer["nimplant"] = (45, 0)
|
||||
layer["poly"] = (46, 0)
|
||||
layer["active_contact"] = (48, 0)
|
||||
layer["metal1"] = (49, 0)
|
||||
layer["via1"] = (50, 0)
|
||||
layer["metal2"] = (51, 0)
|
||||
layer["via2"] = (61, 0)
|
||||
layer["metal3"] = (62, 0)
|
||||
layer["text"] = (63, 0)
|
||||
layer["boundary"] = (63, 0)
|
||||
layer["blockage"] = (83, 0)
|
||||
|
||||
###################################################
|
||||
##END GDS Layer Map
|
||||
|
|
|
|||
|
|
@ -35,26 +35,26 @@ GDS["zoom"] = 0.5
|
|||
|
||||
# create the GDS layer map
|
||||
layer={}
|
||||
layer["vtg"] = -1
|
||||
layer["vth"] = -1
|
||||
layer["contact"] = 47
|
||||
layer["pwell"] = 41
|
||||
layer["nwell"] = 42
|
||||
layer["active"] = 43
|
||||
layer["pimplant"] = 44
|
||||
layer["nimplant"] = 45
|
||||
layer["poly"] = 46
|
||||
layer["active_contact"] = 48
|
||||
layer["metal1"] = 49
|
||||
layer["via1"] = 50
|
||||
layer["metal2"] = 51
|
||||
layer["via2"] = 61
|
||||
layer["metal3"] = 62
|
||||
layer["via3"] = 30
|
||||
layer["metal4"] = 31
|
||||
layer["text"] = 63
|
||||
layer["boundary"] = 63
|
||||
layer["blockage"] = 83
|
||||
layer["vtg"] = (-1, 0)
|
||||
layer["vth"] = (-1, 0)
|
||||
layer["contact"] = (47, 0)
|
||||
layer["pwell"] = (41, 0)
|
||||
layer["nwell"] = (42, 0)
|
||||
layer["active"] = (43, 0)
|
||||
layer["pimplant"] = (44, 0)
|
||||
layer["nimplant"] = (45, 0)
|
||||
layer["poly"] = (46, 0)
|
||||
layer["active_contact"] = (48, 0)
|
||||
layer["metal1"] = (49, 0)
|
||||
layer["via1"] = (50, 0)
|
||||
layer["metal2"] = (51, 0)
|
||||
layer["via2"] = (61, 0)
|
||||
layer["metal3"] = (62, 0)
|
||||
layer["via3"] = (30, 0)
|
||||
layer["metal4"] = (31, 0)
|
||||
layer["text"] = (63, 0)
|
||||
layer["boundary"] = (63, 0)
|
||||
layer["blockage"] = (83, 0)
|
||||
|
||||
###################################################
|
||||
##END GDS Layer Map
|
||||
|
|
|
|||
Loading…
Reference in New Issue