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):
|
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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,13 +156,14 @@ 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
|
||||||
#parameters explicitly
|
#parameters explicitly
|
||||||
if startingStructureName == None:
|
if startingStructureName == None:
|
||||||
startingStructureName = self.rootStructureName
|
startingStructureName = self.rootStructureName
|
||||||
|
|
||||||
#set up the rotation matrix
|
#set up the rotation matrix
|
||||||
if(rotateAngle == None or rotateAngle == ""):
|
if(rotateAngle == None or rotateAngle == ""):
|
||||||
angle = 0
|
angle = 0
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
@ -414,10 +412,8 @@ class VlsiLayout:
|
||||||
textToAdd.purposeLayer = purposeNumber
|
textToAdd.purposeLayer = purposeNumber
|
||||||
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:
|
||||||
|
|
@ -425,7 +421,13 @@ class VlsiLayout:
|
||||||
textToAdd.rotateAngle = rotate
|
textToAdd.rotateAngle = rotate
|
||||||
#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 = []
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue