diff --git a/compiler/base/contact.py b/compiler/base/contact.py index 30f6870b..fb8ea0e8 100644 --- a/compiler/base/contact.py +++ b/compiler/base/contact.py @@ -48,7 +48,8 @@ class contact(hierarchy_design.hierarchy_design): # Module does not have pins, but has empty pin list. self.pins = [] self.create_layout() - + self.add_boundary() + def create_layout(self): self.setup_layers() @@ -71,14 +72,11 @@ class contact(hierarchy_design.hierarchy_design): (first_layer, via_layer, second_layer) = self.layer_stack self.first_layer_name = first_layer - self.via_layer_name = via_layer - # Some technologies have a separate active - # contact from the poly contact - # We will use contact for DRC, but active_contact for output - if first_layer == "active" or second_layer == "active": - self.via_layer_name_expanded = "active_" + via_layer + # Contacts will have unique per first layer + if via_layer == "contact": + self.via_layer_name = first_layer + "_" + via_layer else: - self.via_layer_name_expanded = via_layer + self.via_layer_name = via_layer self.second_layer_name = second_layer def setup_layout_constants(self): @@ -144,7 +142,7 @@ class contact(hierarchy_design.hierarchy_design): for i in range(self.dimensions[1]): offset = self.via_layer_position + vector(0, self.contact_pitch * i) for j in range(self.dimensions[0]): - self.add_rect(layer=self.via_layer_name_expanded, + self.add_rect(layer=self.via_layer_name, offset=offset, width=self.contact_width, height=self.contact_width) diff --git a/compiler/base/design.py b/compiler/base/design.py index 33914358..c6385243 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -48,12 +48,12 @@ class design(hierarchy_design): self.m4_space = drc("metal4_to_metal4") self.active_width = drc("minwidth_active") self.active_space = drc("active_to_body_active") - self.contact_width = drc("minwidth_contact") + self.contact_width = drc("minwidth_active_contact") self.poly_to_active = drc("poly_to_active") self.poly_extend_active = drc("poly_extend_active") - self.poly_to_polycontact = drc("poly_to_polycontact") - self.contact_to_gate = drc("contact_to_gate") + self.poly_to_poly_contact = drc("poly_to_poly_contact") + self.active_contact_to_gate = drc("active_contact_to_gate") self.well_enclose_active = drc("well_enclosure_active") self.implant_enclose_active = drc("implant_enclosure_active") self.implant_space = drc("implant_to_implant") diff --git a/compiler/base/geometry.py b/compiler/base/geometry.py index cbc1d268..e5c86546 100644 --- a/compiler/base/geometry.py +++ b/compiler/base/geometry.py @@ -193,7 +193,7 @@ class instance(geometry): blockages = [] blockages = self.mod.gds.getBlockages(lpp) for b in blockages: - new_blockages.append(self.transform_coords(b,self.offset, mirr, angle)) + new_blockages.append(self.transform_coords(vector(b),self.offset, mirr, angle)) else: blockages = self.mod.get_blockages(lpp) for b in blockages: @@ -327,7 +327,6 @@ class label(geometry): debug.info(4, "writing label (" + str(self.layerNumber) + "): " + self.text) new_layout.addText(text=self.text, layerNumber=self.layerNumber, - purposeNumber=self.layerPurpose, offsetInMicrons=self.offset, magnification=self.zoom, rotate=None) diff --git a/compiler/base/hierarchy_layout.py b/compiler/base/hierarchy_layout.py index 000e16ee..b6ca8f33 100644 --- a/compiler/base/hierarchy_layout.py +++ b/compiler/base/hierarchy_layout.py @@ -939,7 +939,11 @@ class layout(): def add_boundary(self, offset=vector(0,0)): """ Add boundary for debugging dimensions """ - self.add_rect(layer="boundary", + if "stdc" in techlayer.keys(): + boundary_layer = "stdc" + else: + boundary_layer = "boundary" + self.add_rect(layer=boundary_layer, offset=offset, height=self.height, width=self.width) diff --git a/compiler/base/pin_layout.py b/compiler/base/pin_layout.py index f7427a9c..ea114ac6 100644 --- a/compiler/base/pin_layout.py +++ b/compiler/base/pin_layout.py @@ -344,7 +344,6 @@ class pin_layout: # imported into Magic. newLayout.addText(text=self.name, layerNumber=layer_num, - purposeNumber=purpose, offsetInMicrons=self.center(), magnification=GDS["zoom"], rotate=None) diff --git a/compiler/bitcells/pbitcell.py b/compiler/bitcells/pbitcell.py index bbfdf942..0e0e1bf7 100644 --- a/compiler/bitcells/pbitcell.py +++ b/compiler/bitcells/pbitcell.py @@ -243,7 +243,7 @@ class pbitcell(bitcell_base.bitcell_base): (self.inverter_nmos.active_contact.height - self.inverter_nmos.active_height) self.inverter_gap = max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \ - + self.poly_to_polycontact + 2 * contact.poly.width \ + + self.poly_to_poly_contact + 2 * contact.poly.width \ + self.m1_space + inverter_pmos_contact_extension self.cross_couple_lower_ypos = self.inverter_nmos_ypos \ + self.inverter_nmos.active_height \ @@ -254,7 +254,7 @@ class pbitcell(bitcell_base.bitcell_base): + self.inverter_nmos.active_height \ + max(self.poly_to_active, self.m1_space + inverter_nmos_contact_extension) \ - + self.poly_to_polycontact \ + + self.poly_to_poly_contact \ + 1.5 * contact.poly.width # spacing between wordlines (and gnd) @@ -926,14 +926,14 @@ class pbitcell(bitcell_base.bitcell_base): """ # add poly to metal1 contacts for gates of the inverters left_storage_contact = vector(self.inverter_nmos_left.get_pin("G").lc().x \ - - self.poly_to_polycontact - 0.5*contact.poly.width, + - self.poly_to_poly_contact - 0.5*contact.poly.width, self.cross_couple_upper_ypos) self.add_via_center(layers=("poly", "contact", "metal1"), offset=left_storage_contact, directions=("H", "H")) right_storage_contact = vector(self.inverter_nmos_right.get_pin("G").rc().x \ - + self.poly_to_polycontact + 0.5*contact.poly.width, + + self.poly_to_poly_contact + 0.5*contact.poly.width, self.cross_couple_upper_ypos) self.add_via_center(layers=("poly", "contact", "metal1"), offset=right_storage_contact, diff --git a/compiler/gdsMill/gdsMill/gds2reader.py b/compiler/gdsMill/gdsMill/gds2reader.py index f660fe3c..351df6a4 100644 --- a/compiler/gdsMill/gdsMill/gds2reader.py +++ b/compiler/gdsMill/gdsMill/gds2reader.py @@ -175,6 +175,8 @@ class Gds2reader: def readBoundary(self): ##reads in a boundary type structure = a filled polygon + if(self.debugToTerminal==1): + print("\t\t\tBeginBoundary") thisBoundary=GdsBoundary() while 1: record = self.readNextRecord() @@ -201,11 +203,6 @@ class Gds2reader: thisBoundary.purposeLayer=purposeLayer if(self.debugToTerminal==1): print("\t\tPurpose Layer: "+str(purposeLayer)) - elif(idBits==b'\x0E\x02'): #DataType - dataType = struct.unpack(">h",record[2:4])[0] - thisBoundary.dataType=dataType - if(self.debugToTerminal==1): - print("\t\t\tData Type: "+str(dataType)) elif(idBits==b'\x10\x03'): #XY Data Points numDataPoints = len(record)-2 #packed as XY coordinates 4 bytes each thisBoundary.coordinates=[] @@ -216,10 +213,15 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tXY Point: "+str(x)+","+str(y)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndBoundary") break; return thisBoundary def readPath(self): #reads in a path structure + if(self.debugToTerminal==1): + print("\t\t\tBeginPath") + thisPath=GdsPath() while 1: record = self.readNextRecord() @@ -266,10 +268,15 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tXY Point: "+str(x)+","+str(y)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndPath") break; return thisPath def readSref(self): #reads in a reference to another structure + if(self.debugToTerminal==1): + print("\t\t\tBeginSref") + thisSref=GdsSref() while 1: record = self.readNextRecord() @@ -317,10 +324,15 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tXY Point: "+str(x)+","+str(y)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndSref") break; return thisSref def readAref(self): #an array of references + if(self.debugToTerminal==1): + print("\t\t\tBeginAref") + thisAref = GdsAref() while 1: record = self.readNextRecord() @@ -372,11 +384,15 @@ class Gds2reader: print("\t\t\t\tArray Width: "+str(rightMostX-topLeftX)) print("\t\t\t\tArray Height: "+str(topLeftY-bottomMostY)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndAref") break; return thisAref def readText(self): - ##reads in a text structure + if(self.debugToTerminal==1): + print("\t\t\tBeginText") + thisText=GdsText() while 1: record = self.readNextRecord() @@ -472,10 +488,15 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tText String: "+textString) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndText") break; return thisText def readNode(self): + if(self.debugToTerminal==1): + print("\t\t\tBeginNode") + ##reads in a node type structure = an electrical net thisNode = GdsNode() while 1: @@ -513,10 +534,15 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tXY Point: "+str(x)+","+str(y)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndNode") break; return thisNode def readBox(self): + if(self.debugToTerminal==1): + print("\t\t\tBeginBox") + ##reads in a gds BOX structure thisBox = GdsBox() while 1: @@ -559,6 +585,8 @@ class Gds2reader: if(self.debugToTerminal==1): print("\t\t\tXY Point: "+str(x)+","+str(y)) elif(idBits==b'\x11\x00'): #End Of Element + if(self.debugToTerminal==1): + print("\t\t\tEndBox") break; return thisBox @@ -566,6 +594,7 @@ class Gds2reader: thisStructure = GdsStructure() record = self.readNextRecord() idBits = record[0:2] + # Begin structure if(idBits==b'\x05\x02' and len(record)==26): createYear = struct.unpack(">h",record[2:4])[0] createMonth = struct.unpack(">h",record[4:6])[0] @@ -581,6 +610,10 @@ class Gds2reader: modSecond = struct.unpack(">h",record[24:26])[0] thisStructure.createDate=(createYear,createMonth,createDay,createHour,createMinute,createSecond) thisStructure.modDate=(modYear,modMonth,modDay,modHour,modMinute,modSecond) + if(self.debugToTerminal==1): + print("Date Created:"+str(createYear)+","+str(createMonth)+","+str(createDay)+\ + ","+str(createHour)+","+str(createMinute)+","+str(createSecond)) + print("Date Modified:"+str(modYear)+","+str(modMonth)+","+str(modDay)+","+str(modHour)+","+str(modMinute)+","+str(modSecond)) else: #means we have hit the last structure, so return the record #to whoever called us to do something with it diff --git a/compiler/gdsMill/gdsMill/gds2writer.py b/compiler/gdsMill/gdsMill/gds2writer.py index 402416cd..3a319324 100644 --- a/compiler/gdsMill/gdsMill/gds2writer.py +++ b/compiler/gdsMill/gdsMill/gds2writer.py @@ -187,27 +187,25 @@ class Gds2writer: idBits=b'\x08\x00' #record Type self.writeRecord(idBits) if(thisBoundary.elementFlags!=""): - idBits=b'\x26\x01' #ELFLAGS + idBits=b'\x26\x01' # ELFLAGS elementFlags = struct.pack(">h",thisBoundary.elementFlags) self.writeRecord(idBits+elementFlags) if(thisBoundary.plex!=""): - idBits=b'\x2F\x03' #PLEX + idBits=b'\x2F\x03' # PLEX plex = struct.pack(">i",thisBoundary.plex) self.writeRecord(idBits+plex) if(thisBoundary.drawingLayer!=""): - idBits=b'\x0D\x02' #drawig layer + idBits=b'\x0D\x02' # drawing layer drawingLayer = struct.pack(">h",thisBoundary.drawingLayer) self.writeRecord(idBits+drawingLayer) - if(thisBoundary.purposeLayer): - idBits=b'\x16\x02' #purpose layer - purposeLayer = struct.pack(">h",thisBoundary.purposeLayer) - self.writeRecord(idBits+purposeLayer) - if(thisBoundary.dataType!=""): - idBits=b'\x0E\x02'#DataType - dataType = struct.pack(">h",thisBoundary.dataType) + if(thisBoundary.purposeLayer!=""): + idBits=b'\x0E\x02' # DataType + if type(thisBoundary.purposeLayer)!=int: + import pdb; pdb.set_trace() + dataType = struct.pack(">h",thisBoundary.purposeLayer) self.writeRecord(idBits+dataType) if(thisBoundary.coordinates!=""): - idBits=b'\x10\x03' #XY Data Points + idBits=b'\x10\x03' # XY Data Points coordinateRecord = idBits for coordinate in thisBoundary.coordinates: x=struct.pack(">i",int(coordinate[0])) @@ -377,9 +375,9 @@ class Gds2writer: idBits=b'\x0D\x02' #drawing layer drawingLayer = struct.pack(">h",thisText.drawingLayer) self.writeRecord(idBits+drawingLayer) - #if(thisText.purposeLayer): + # TextType is always a 0 per GDS specification idBits=b'\x16\x02' #purpose layer - purposeLayer = struct.pack(">h",thisText.purposeLayer) + purposeLayer = struct.pack(">h",0) self.writeRecord(idBits+purposeLayer) if(thisText.transFlags != ""): idBits=b'\x1A\x01' diff --git a/compiler/gdsMill/gdsMill/gdsPrimitives.py b/compiler/gdsMill/gdsMill/gdsPrimitives.py index dc43fea6..09bd85b4 100644 --- a/compiler/gdsMill/gdsMill/gdsPrimitives.py +++ b/compiler/gdsMill/gdsMill/gdsPrimitives.py @@ -21,8 +21,7 @@ class GdsBoundary: self.elementFlags="" self.plex="" self.drawingLayer="" - self.purposeLayer = None - self.dataType="" + self.purposeLayer=0 self.coordinates="" class GdsPath: @@ -31,7 +30,7 @@ class GdsPath: self.elementFlags="" self.plex="" self.drawingLayer="" - self.purposeLayer = None + self.purposeLayer=0 self.pathType="" self.pathWidth="" self.coordinates="" @@ -140,7 +139,7 @@ class GdsText: self.elementFlags="" self.plex="" self.drawingLayer="" - self.purposeLayer = None + self.purposeLayer=0 self.transFlags=[0,0,0] self.magFactor="" self.rotateAngle="" @@ -165,6 +164,6 @@ class GdsBox: self.elementFlags="" self.plex="" self.drawingLayer="" - self.purposeLayer = None + self.purposeLayer=0 self.boxValue="" self.coordinates="" diff --git a/compiler/gdsMill/gdsMill/vlsiLayout.py b/compiler/gdsMill/gdsMill/vlsiLayout.py index eec1870c..412a430c 100644 --- a/compiler/gdsMill/gdsMill/vlsiLayout.py +++ b/compiler/gdsMill/gdsMill/vlsiLayout.py @@ -2,7 +2,6 @@ from .gdsPrimitives import * from datetime import * #from mpmath import matrix #from numpy import matrix -from vector import vector import numpy as np #import gdsPrimitives import debug @@ -358,7 +357,7 @@ class VlsiLayout: #add the sref to the root structure self.structures[self.rootStructureName].srefs.append(layoutToAddSref) - def addBox(self,layerNumber=0, purposeNumber=None, offsetInMicrons=(0,0), width=1.0, height=1.0,center=False): + def addBox(self,layerNumber=0, purposeNumber=0, offsetInMicrons=(0,0), width=1.0, height=1.0,center=False): """ Method to add a box to a layout """ @@ -383,13 +382,12 @@ class VlsiLayout: boundaryToAdd = GdsBoundary() boundaryToAdd.drawingLayer = layerNumber - boundaryToAdd.dataType = 0 boundaryToAdd.coordinates = coordinates boundaryToAdd.purposeLayer = purposeNumber #add the sref to the root structure self.structures[self.rootStructureName].boundaries.append(boundaryToAdd) - def addPath(self, layerNumber=0, purposeNumber=None, coordinates=[(0,0)], width=1.0): + def addPath(self, layerNumber=0, purposeNumber=0, coordinates=[(0,0)], width=1.0): """ Method to add a path to a layout """ @@ -408,12 +406,10 @@ class VlsiLayout: #add the sref to the root structure self.structures[self.rootStructureName].paths.append(pathToAdd) - def addText(self, text, layerNumber=0, purposeNumber=None, offsetInMicrons=(0,0), magnification=0.1, rotate = None): + def addText(self, text, layerNumber=0, offsetInMicrons=(0,0), magnification=0.1, rotate = None): offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1])) textToAdd = GdsText() textToAdd.drawingLayer = layerNumber - textToAdd.purposeLayer = purposeNumber - textToAdd.dataType = 0 textToAdd.coordinates = [offsetInLayoutUnits] textToAdd.transFlags = [0,0,0] textToAdd.textString = self.padText(text) @@ -757,7 +753,7 @@ class VlsiLayout: for boundary in shapes: vectors = [] for i in range(0, len(boundary), 2): - vectors.append(vector(boundary[i], boundary[i+1])) + vectors.append((boundary[i], boundary[i+1])) blockages.append(vectors) return blockages diff --git a/compiler/pgates/ptx.py b/compiler/pgates/ptx.py index f3180840..33098e7c 100644 --- a/compiler/pgates/ptx.py +++ b/compiler/pgates/ptx.py @@ -124,18 +124,18 @@ class ptx(design.design): # The contacted poly pitch (or uncontacted in an odd technology) - self.poly_pitch = max(2 * self.contact_to_gate + self.contact_width + self.poly_width, + self.poly_pitch = max(2 * self.active_contact_to_gate + self.contact_width + self.poly_width, self.poly_space) # The contacted poly pitch (or uncontacted in an odd technology) - self.contact_pitch = 2 * self.contact_to_gate + self.contact_width + self.poly_width + self.contact_pitch = 2 * self.active_contact_to_gate + self.contact_width + self.poly_width # The enclosure of an active contact. Not sure about second term. - active_enclose_contact = max(drc("active_enclosure_contact"), + active_enclose_contact = max(drc("active_enclosure_active_contact"), (self.active_width - self.contact_width) / 2) # This is the distance from the edge of poly to the contacted end of active - self.end_to_poly = active_enclose_contact + self.contact_width + self.contact_to_gate + self.end_to_poly = active_enclose_contact + self.contact_width + self.active_contact_to_gate # Active width is determined by enclosure on both ends and contacted pitch, diff --git a/technology/freepdk45/tech/tech.py b/technology/freepdk45/tech/tech.py index 13e7ccff..16c2b393 100644 --- a/technology/freepdk45/tech/tech.py +++ b/technology/freepdk45/tech/tech.py @@ -44,9 +44,8 @@ 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["poly_contact"] = None +layer["poly_contact"] = (10, 0) layer["metal1"] = (11, 0) layer["via1"] = (12, 0) layer["metal2"] = (13, 0) @@ -117,7 +116,7 @@ drc["poly_to_poly"] = 0.14 # POLY.3 Minimum poly extension beyond active drc["poly_extend_active"] = 0.055 # Not a rule -drc["poly_to_polycontact"] = 0.075 +drc["poly_to_poly_contact"] = 0.075 # POLY.4 Minimum enclosure of active around gate drc["active_enclosure_gate"] = 0.07 # POLY.5 Minimum spacing of field poly to active @@ -154,30 +153,51 @@ drc["implant_to_implant"] = 0.045 drc["minwidth_implant"] = 0.045 # CONTACT.1 Minimum width of contact -drc["minwidth_contact"] = 0.065 +drc["minwidth_active_contact"] = 0.065 # CONTACT.2 Minimum spacing of contact -drc["contact_to_contact"] = 0.075 +drc["active_contact_to_active_contact"] = 0.075 # CONTACT.4 Minimum enclosure of active around contact -drc["active_enclosure_contact"] = 0.005 +drc["active_enclosure_active_contact"] = 0.005 +# Reserved for asymmetric enclosures +drc["active_extend_active_contact"] = 0.005 +# CONTACT.5 Minimum enclosure of poly around contact +drc["poly_enclosure_active_contact"] = 0.005 +# Reserved for asymmetric enclosures +drc["poly_extend_active_contact"] = 0.005 +# CONTACT.6 Minimum spacing of contact and gate +drc["active_contact_to_gate"] = 0.0375 #changed from 0.035 +# CONTACT.7 Minimum spacing of contact and poly +drc["active_contact_to_poly"] = 0.090 + +# CONTACT.1 Minimum width of contact +drc["minwidth_poly_contact"] = 0.065 +# CONTACT.2 Minimum spacing of contact +drc["poly_contact_to_poly_contact"] = 0.075 +# CONTACT.4 Minimum enclosure of active around contact +drc["active_enclosure_poly_contact"] = 0.005 # Reserved for asymmetric enclosures drc["active_extend_contact"] = 0.005 # CONTACT.5 Minimum enclosure of poly around contact -drc["poly_enclosure_contact"] = 0.005 +drc["poly_enclosure_poly_contact"] = 0.005 # Reserved for asymmetric enclosures -drc["poly_extend_contact"] = 0.005 +drc["poly_extend_poly_contact"] = 0.005 # CONTACT.6 Minimum spacing of contact and gate -drc["contact_to_gate"] = 0.0375 #changed from 0.035 +drc["poly_contact_to_gate"] = 0.0375 #changed from 0.035 # CONTACT.7 Minimum spacing of contact and poly -drc["contact_to_poly"] = 0.090 +drc["poly_contact_to_poly"] = 0.090 # METAL1.1 Minimum width of metal1 drc["minwidth_metal1"] = 0.065 # METAL1.2 Minimum spacing of metal1 drc["metal1_to_metal1"] = 0.065 # METAL1.3 Minimum enclosure around contact on two opposite sides -drc["metal1_enclosure_contact"] = 0 +drc["metal1_enclosure_active_contact"] = 0 # Reserved for asymmetric enclosures -drc["metal1_extend_contact"] = 0.035 +drc["metal1_extend_active_contact"] = 0.035 +# METAL1.3 Minimum enclosure around contact on two opposite sides +drc["metal1_enclosure_poly_contact"] = 0 +# Reserved for asymmetric enclosures +drc["metal1_extend_poly_contact"] = 0.035 # METAL1.4 inimum enclosure around via1 on two opposite sides drc["metal1_extend_via1"] = 0.035 # Reserved for asymmetric enclosures diff --git a/technology/scn4m_subm/tech/tech.py b/technology/scn4m_subm/tech/tech.py index 2d1d5e15..deaab30c 100644 --- a/technology/scn4m_subm/tech/tech.py +++ b/technology/scn4m_subm/tech/tech.py @@ -43,9 +43,8 @@ layer["active"] = (43, 0) layer["pimplant"] = (44, 0) layer["nimplant"] = (45, 0) layer["poly"] = (46, 0) -layer["poly_contact"] = None -layer["contact"] = (47, 0) layer["active_contact"] = (48, 0) +layer["poly_contact"] = (47, 0) layer["metal1"] = (49, 0) layer["via1"] = (50, 0) layer["metal2"] = (51, 0) @@ -105,7 +104,7 @@ drc["poly_to_poly"] = 3*_lambda_ # 3.3 Minimum gate extension of active drc["poly_extend_active"] = 2*_lambda_ # 5.5.b Minimum spacing between poly contact and other poly (alternative rules) -drc["poly_to_polycontact"] = 4*_lambda_ +drc["poly_to_poly_contact"] = 4*_lambda_ # ?? drc["active_enclosure_gate"] = 0.0 # 3.5 Minimum field poly to active @@ -142,30 +141,51 @@ drc["implant_to_implant"] = 0 drc["minwidth_implant"] = 0 # 6.1 Exact contact size -drc["minwidth_contact"] = 2*_lambda_ +drc["minwidth_active_contact"] = 2*_lambda_ # 5.3 Minimum contact spacing -drc["contact_to_contact"] = 3*_lambda_ +drc["active_contact_to_active_contact"] = 3*_lambda_ # 6.2.b Minimum active overlap -drc["active_enclosure_contact"] = _lambda_ +drc["active_enclosure_active_contact"] = _lambda_ # Reserved for asymmetric enclosure -drc["active_extend_contact"] = _lambda_ +drc["active_extend_active_contact"] = _lambda_ # 5.2.b Minimum poly overlap -drc["poly_enclosure_contact"] = _lambda_ +drc["poly_enclosure_active_contact"] = _lambda_ # Reserved for asymmetric enclosures -drc["poly_extend_contact"] = _lambda_ +drc["poly_extend_active_contact"] = _lambda_ # Reserved for other technologies -drc["contact_to_gate"] = 2*_lambda_ +drc["active_contact_to_gate"] = 2*_lambda_ # 5.4 Minimum spacing to gate of transistor -drc["contact_to_poly"] = 2*_lambda_ - +drc["active_contact_to_poly"] = 2*_lambda_ + +# 6.1 Exact contact size +drc["minwidth_poly_contact"] = 2*_lambda_ +# 5.3 Minimum contact spacing +drc["poly_contact_to_poly_contact"] = 3*_lambda_ +# 6.2.b Minimum active overlap +drc["active_enclosure_poly_contact"] = _lambda_ +# Reserved for asymmetric enclosure +drc["active_extend_poly_contact"] = _lambda_ +# 5.2.b Minimum poly overlap +drc["poly_enclosure_poly_contact"] = _lambda_ +# Reserved for asymmetric enclosures +drc["poly_extend_poly_contact"] = _lambda_ +# Reserved for other technologies +drc["poly_contact_to_gate"] = 2*_lambda_ +# 5.4 Minimum spacing to gate of transistor +drc["poly_contact_to_poly"] = 2*_lambda_ + # 7.1 Minimum width drc["minwidth_metal1"] = 3*_lambda_ # 7.2 Minimum spacing drc["metal1_to_metal1"] = 3*_lambda_ # 7.3 Minimum overlap of any contact -drc["metal1_enclosure_contact"] = _lambda_ +drc["metal1_enclosure_active_contact"] = _lambda_ # Reserved for asymmetric enclosure -drc["metal1_extend_contact"] = _lambda_ +drc["metal1_extend_active_contact"] = _lambda_ +# 7.3 Minimum overlap of any contact +drc["metal1_enclosure_poly_contact"] = _lambda_ +# Reserved for asymmetric enclosure +drc["metal1_extend_poly_contact"] = _lambda_ # 8.3 Minimum overlap by metal1 drc["metal1_enclosure_via1"] = _lambda_ # Reserve for asymmetric enclosures