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 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 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)