diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index 74b02f5f..f8eb03ab 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -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, diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 2fea5c61..503bd1d5 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -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 diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index 2d389119..10d10774 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -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) diff --git a/compiler/base/utils.py b/compiler/base/utils.py index 61e12096..1816a508 100644 --- a/compiler/base/utils.py +++ b/compiler/base/utils.py @@ -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): diff --git a/compiler/gdsMill/gdsMill/gds2reader.py b/compiler/gdsMill/gdsMill/gds2reader.py index 85fc0c66..7e519c36 100644 --- a/compiler/gdsMill/gdsMill/gds2reader.py +++ b/compiler/gdsMill/gdsMill/gds2reader.py @@ -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) diff --git a/compiler/gdsMill/gdsMill/vlsiLayout.py b/compiler/gdsMill/gdsMill/vlsiLayout.py index 671802ae..8d071e9f 100644 --- a/compiler/gdsMill/gdsMill/vlsiLayout.py +++ b/compiler/gdsMill/gdsMill/vlsiLayout.py @@ -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 = [] diff --git a/compiler/globals.py b/compiler/globals.py index ab489242..0bdd486d 100644 --- a/compiler/globals.py +++ b/compiler/globals.py @@ -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) diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index caa3c748..07748390 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -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 diff --git a/technology/scn3me_subm/tech/tech.py b/technology/scn3me_subm/tech/tech.py index 074009f2..cc405c21 100755 --- a/technology/scn3me_subm/tech/tech.py +++ b/technology/scn3me_subm/tech/tech.py @@ -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 diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index 37e55e21..3964a088 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -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