def resize( self, width=0, height=0, via=None, metalLayer=None): """Modify the via instance to fit within a specific width or height. """ if width: (cols, tmp) = self.calculateViaCount( width=width, height=0, via=via, metalLayer=metalLayer) self.setParams( ParamArray( xCnt=cols)) if height: (tmp, rows) = self.calculateViaCount( width=0, height=height, via=via, metalLayer=metalLayer) self.setParams( ParamArray( yCnt=rows))
def bigtest( self): """Create layout instances for comprehensive testing, such as DRC or regression testing. """ i = 0 x = 0 y = 0 for master in [ "V0", "V1", "ndcont", "pdcont", "pcont"]: for xCnt in range( 10): for yCnt in range( 10): for origin in [ "centerCenter", "lowerCenter", "lowerLeft", "centerLeft"]: param = ParamArray( xCnt = xCnt, yCnt = yCnt, origin = origin, ) inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 20): x += 20 else: x = 0 y += 20 print("Total number of instances created: %d" % i) self.save()
def createGateCont(self, gateRect=False, coverage=1.0, stretch=False, terminal=False): """Create a gate contact by instantiating a poly contact PyCell. Arguments: gateRect - (PhysicalComponent) Gate rectangle for alignment. coverage - (float ) Percentage of poly width to be covered by contact stretch - (string ) Name of stretch handle property for gate contact """ gateCont = ViaInstance( "pcont", ParamArray(), None, "I%d" % self.instance, ) self.place(gateCont, Direction.SOUTH, gateRect, 0) width = self.l * coverage gateCont.resize( width=width, via=self.contact, metalLayer=self.poly, ) # Create overlapping poly rectangle for stretch handle polyRect = gateCont.promoteMetal(self.poly) bbox = polyRect.getBBox() width = max(width, bbox.getWidth()) / 2 center = bbox.getCenterX() bbox.setLeft(center - width) bbox.setRight(center + width) polyRect.setBBox(bbox) # Stretch handle for gate contact coverage stretchHandle( shape=polyRect, name=("stretch%d" % self.instance), parameter=stretch, location=Location.CENTER_RIGHT, direction=Direction.EAST_WEST, stretchType="relative", userScale="1.0", userSnap="0.0025", minVal=0.0, maxVal=1.0, ) # Create weakly-connected pins if terminal: Pin(("%sC%d" % (terminal, self.instance)), terminal, Rect(self.poly, bbox)) self.instance += 1 return (gateCont)
def unitTestMethod( self): """Define how to build the unit test. """ # Get default parameters from specs, then update # with explicitly supplied specs for unitTest. specs = ParamSpecArray() self.defineParamSpecs( specs) params = ParamArray( specs) params.update( paramsMaker()) print print( "Creating design: %s" % repr(self)) print( " using technology: %s" % self.tech.id()) print( " by %s.generate(%r)" % (self.__class__.__name__, params)) specs.verify( params) self.generate( params) self.save()
def bigtest( self): """Create layout instances for comprehensive testing, such as DRC or regression testing. """ i = 0 x = 0 y = 0 for w in [ 0.09, 2.0]: for l in [ 0.05, 1.0]: for fingers in [ 1, 2]: for diffContactLeftCov in [ 0.0, 0.33, 1.0]: for gateContactLeftCov in [ 0.0, 0.33, 1.0]: for diffContactCenterCov in [ 0.0, 0.33, 1.0]: for gateContactCenterCov in [ 0.0, 0.33, 1.0]: for diffContactRightCov in [ 0.0, 0.33, 1.0]: for gateContactRightCov in [ 0.0, 0.33, 1.0]: param = ParamArray( w = w, l = l, fingers = fingers, diffContactLeft = (not diffContactLeftCov), diffContactLeftCov = diffContactLeftCov, gateContactLeft = (not gateContactLeftCov), gateContactLeftCov = gateContactLeftCov, diffContactCenter = (not diffContactCenterCov), diffContactCenterCov = diffContactCenterCov, gateContactCenter = (not gateContactCenterCov), gateContactCenterCov = gateContactCenterCov, diffContactRight = (not diffContactRightCov), diffContactRightCov = diffContactRightCov, gateContactRight = (not gateContactRightCov), gateContactRightCov = gateContactRightCov, ) for master in [ "nmos_vtg", "pmos_vtg"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x,y)) i += 1 if (i % 100): x += 20 else: x = 0 y += 20 print("Total number of instances created: %d" % i) self.save()
def smalltest( self): """Create layout instances for quick development debugging. """ i = 0 x = 0 y = 0 param = ParamArray() for master in [ "V0", "V1", "ndcont", "pdcont", "dcont", "pcont"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 4): x += 5 else: x = 0 y += 5 self.save()
def bigtest( self): """Create layout instances for comprehensive testing, such as DRC or regression testing. """ i = 0 x = 0 y = 0 for width in [ 0.3, 0.45, 0.5, 1.553, 2.0]: for length in [ 0.1, 0.18, 0.194, 0.2, 0.55]: for sourceDiffOverlap in [0.0, 0.1, 0.12, 0.15, 0.55]: for drainDiffOverlap in [0.0, 0.1, 0.12, 0.15, 0.55]: for oxide in ["thin", "thick"]: for tranType in ["nmos_vtg", "pmos_vtg"]: for xtorFillLayer in ["metal1"]: param = ParamArray( width = width, length = length, sourceDiffOverlap = sourceDiffOverlap, drainDiffOverlap = drainDiffOverlap, oxide = oxide, tranType = tranType, xtorFillLayer = xtorFillLayer, ) inst = PyTransistorUnitInstance("PyTransistor", param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 20): x += 10 else: x = 0 y += 10 print("Total number of instances created: %d" % i) self.save()
def smalltest( self): """Create layout instances for quick development debugging. """ i = 0 x = 0 y = 0 for width in [ 0.6, 2.0]: for length in [ 0.18, 0.6]: for sourceDiffOverlap in [0.0, 0.1]: for drainDiffOverlap in [0.0, 0.1]: for oxide in ["thin", "thick"]: for tranType in ["nmos_vtg", "pmos_vtg"]: for xtorFillLayer in ["metal1"]: param = ParamArray( width = width, length = length, sourceDiffOverlap = sourceDiffOverlap, drainDiffOverlap = drainDiffOverlap, oxide = oxide, tranType = tranType, xtorFillLayer = xtorFillLayer, ) inst = Instance("PyTransistor", param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 20): x += 10 else: x = 0 y += 10 self.save()
) inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 20): x += 20 else: x = 0 y += 20 print("Total number of instances created: %d" % i) self.save() # TEST is defined externally from this file. # For building the test cases, invoke like this: # cnpy -c "TEST='SMALL';execfile('Via.py')" if "TEST" in vars(): if vars()["TEST"] == "SMALL": ViaTemplate.unitTest(lambda: ParamArray(), "MyPyCellLib", "UNITTEST_Via", "layout") DloGen.withNewDlo( smalltest, "MyPyCellLib", "SMALLTEST_Via", "layout") elif vars()["TEST"] == "BIG": DloGen.withNewDlo( bigtest, "MyPyCellLib", "BIGTEST_Via", "layout") else: DloGen.withNewDlo( smalltest, "MyPyCellLib", "SMALLTEST_Via", "layout") # end
def smalltest( self): """Create layout instances for quick development debugging. """ i = 0 x = 0 y = 0 param = ParamArray( w = 0.6, l = 0.18, fingers = 1, diffContactLeft = True, diffContactLeftCov = 0.7, gateContactLeft = False, gateContactLeftCov = 0.7, diffContactCenter = False, diffContactCenterCov = 0.5, gateContactCenter = False, gateContactCenterCov = 0.5, diffContactRight = False, diffContactRightCov = 1.0, gateContactRight = True, gateContactRightCov = 1.0, ) for master in [ "nmos_vtg", "pmos_vtg"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x,y)) i += 1 if (i % 4): x += 10 else: x = 0 y += 10 param = ParamArray( w = 2.0, l = 1.5, fingers = 1, diffContactLeft = True, diffContactLeftCov = 0.3, gateContactLeft = True, gateContactLeftCov = 0.3, diffContactCenter = True, diffContactCenterCov = 0.5, gateContactCenter = True, gateContactCenterCov = 0.5, diffContactRight = True, diffContactRightCov = 0.7, gateContactRight = True, gateContactRightCov = 0.7, ) for master in [ "nmos_vtg", "pmos_vtg"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x,y)) i += 1 if (i % 4): x += 10 else: x = 0 y += 10 param = ParamArray( w = 2.0, l = 1.5, fingers = 2, diffContactLeft = True, diffContactLeftCov = 0.3, gateContactLeft = True, gateContactLeftCov = 0.3, diffContactCenter = True, diffContactCenterCov = 0.5, gateContactCenter = True, gateContactCenterCov = 0.5, diffContactRight = True, diffContactRightCov = 1.0, gateContactRight = True, gateContactRightCov = 1.0, ) for master in [ "nmos_vtg", "pmos_vtg"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x,y)) i += 1 if (i % 4): x += 10 else: x = 0 y += 10 param = ParamArray( w = 2.0, l = 1.5, fingers = 2, diffContactLeft = False, diffContactLeftCov = 1.0, gateContactLeft = True, gateContactLeftCov = 1.0, diffContactCenter = False, diffContactCenterCov = 0.5, gateContactCenter = True, gateContactCenterCov = 0.6, diffContactRight = True, diffContactRightCov = 0.4, gateContactRight = False, gateContactRightCov = 0.4, ) for master in [ "nmos_vtg", "pmos_vtg"]: inst = Instance(("%s" % master), param, None, ("I%d" % i)) inst.setOrigin( Point( x,y)) i += 1 if (i % 4): x += 10 else: x = 0 y += 20 self.save()
def createSourceDrain( self, diffusionType="full", withContact=True, x=0, y=0, coverage=1.0, stretch=False, terminal=False): """Create a source or drain diffusion. Option to create diffusion contact instance. Option to create matching diffusion terminal. Option to create a stretch handle property. Override this method to create custom contacts. Arguments: diffusionType - (string) "full", "left", "right" withContact - (boolean) Create contact x - (float ) x coordinate for center of contact y - (float ) y coordinate for lower diffusion edge coverage - (float ) Percentage of source/drain diffusion to be covered by contact stretch - (string ) Name of stretch handle property """ # Create source/drain contact if withContact: diffCont = ViaInstance( "dcont", ParamArray( origin="lowerCenter"), None, "I%d" % self.instance, ) diffCont.setOrigin( Point(x, y-0.02)) height = self.w * coverage diffCont.resize( height = height, via = self.contact, metalLayer = self.diffusion, ) # Create overlapping diffusion rectangle for stretch handle diffRect = diffCont.promoteMetal( self.diffusion) bbox = diffRect.getBBox() height = max( height, bbox.getHeight()) bbox.setTop( bbox.getBottom() + height) diffRect.setBBox( bbox) # Stretch handle for diffusion contact coverage stretchHandle( shape = diffRect, name = ("stretch%d" % self.instance), parameter = stretch, location = Location.UPPER_CENTER, direction = Direction.NORTH_SOUTH, stretchType = "relative", userScale = "1.0", userSnap = "0.0025", minVal = 0.0, maxVal = 1.0, ) self.instance += 1 # Create source/drain diffusion if withContact: bbox = Box( bbox.getLeft(), y, bbox.getRight(), (y + self.w), ) else: if (diffusionType == "left"): bbox = Box( x, y, (x + self.GateSpaceDiv2), (y + self.w), ) elif (diffusionType == "right"): bbox = Box( (x - self.GateSpaceDiv2), y, x, (y + self.w), ) elif (diffusionType == "full"): bbox = Box( (x - self.GateSpaceDiv2), y, (x + self.GateSpaceDiv2), (y + self.w), ) else: raise ValueError, "Unknown: diffusionType=%s" % diffusionType if terminal: p0 = Pin( terminal, terminal, Rect( self.diffusion, bbox) ) pinRect = p0.getShapes()[0] autoAbutment( pinRect, self.w, [ Direction.WEST], "cniMOS", abut2PinEqual = [ { "spacing":0.0}, { "diffLeftStyle":"DiffHalf" }, { "diffLeftStyle":"DiffHalf" } ], abut2PinBigger = [ { "spacing":0.0}, { "diffLeftStyle":"DiffEdgeAbut" }, { "diffLeftStyle":"DiffEdgeAbut" } ], abut3PinBigger = [ { "spacing":0.0}, { "diffLeftStyle":"ContactEdgeAbut2"}, { "diffLeftStyle":"ContactEdgeAbut2"} ], abut3PinEqual = [ { "spacing":0.0}, { "diffLeftStyle":"DiffAbut" }, { "diffLeftStyle":"ContactEdgeAbut2"} ], abut2PinSmaller = [ { "spacing":0.0}, { "diffLeftStyle":"DiffEdgeAbut" }, { "diffLeftStyle":"DiffEdgeAbut" } ], abut3PinSmaller = [ { "spacing":0.0}, { "diffLeftStyle":"DiffEdgeAbut" }, { "diffLeftStyle":"DiffEdgeAbut" } ], noAbut = [ { "spacing":0.4}], function = "cniAbut", #shape = pinRect, #abutDirection = diffusionType, #abutClass = "cniMOS", #abutFunction = "cniAbut", #spacingRule = self.DiffSpace, ) else: pinRect = Rect( self.diffusion, bbox) return( pinRect)
inst.setOrigin(Point(x, y)) i += 1 if (i % 100): x += 20 else: x = 0 y += 20 print("Total number of instances created: %d" % i) self.save() # TEST is defined externally from this file. # For building the test cases, invoke like this: # cnpy -c "TEST='SMALL';execfile('Mosfet.py')" if "TEST" in vars(): if vars()["TEST"] == "SMALL": MosfetTemplate.unitTest(lambda: ParamArray(), "MyPyCellLib", "UNITTEST_Mosfet", "layout") DloGen.withNewDlo(smalltest, "MyPyCellLib", "SMALLTEST_Mosfet", "layout") elif vars()["TEST"] == "BIG": DloGen.withNewDlo(bigtest, "MyPyCellLib", "BIGTEST_Mosfet", "layout") else: DloGen.withNewDlo(smalltest, "MyPyCellLib", "SMALLTEST_Mosfet", "layout") # end
inst = PyTransistorUnitInstance("PyTransistor", param, None, ("I%d" % i)) inst.setOrigin( Point( x, y)) i += 1 if (i % 20): x += 10 else: x = 0 y += 10 print("Total number of instances created: %d" % i) self.save() # TEST is defined externally from this file. # For building the test cases, invoke like this: # cnpy -c "TEST='SMALL';execfile('transistorUnit.py')" if "TEST" in vars(): if vars()["TEST"] == "SMALL": PyTransistorUnit.unitTest(lambda: ParamArray(), "MyPyCellLib", "UNITTEST_transistorUnit", "layout") DloGen.withNewDlo( smalltest, "MyPyCellLib", "SMALLTEST_transistorUnit", "layout") elif vars()["TEST"] == "BIG": DloGen.withNewDlo( bigtest, "MyPyCellLib", "BIGTEST_transistorUnit", "layout") else: DloGen.withNewDlo( smalltest, "MyPyCellLib", "SMALLTEST_transistorUnit", "layout") # end