def createGate(self, x=0, y=0, terminal=False):
        """Create the poly rectangle which represents the MOS
        transistor gate.

        Override this method to create custom gates.

        Arguments:
        x           - (integer)  x coordinate of gate center
        y           - (integer)  y coordinate of lower diffusion edge
            """
        left = x - self.lDiv2
        right = x + self.lDiv2

        # Create transistor gate
        gateRect = Rect(self.poly, Box(left, (y - self.Endcap), right, (y + self.w + self.Endcap)))

        # Stretch handles for w & l
        stretchHandle(
            shape=gateRect,
            name=("stretch%d" % self.instance),
            parameter="w",
            location=Location.UPPER_CENTER,
            direction=Direction.NORTH_SOUTH,
            display=("w = %.2f" % self.w),
            stretchType="relative",
            userScale="1.0",
            userSnap="0.0025",
        )

        stretchHandle(
            shape=gateRect,
            name=("stretch%d" % self.instance),
            parameter="l",
            location=Location.CENTER_RIGHT,
            direction=Direction.EAST_WEST,
            display=("l = %.2f" % self.l),
            stretchType="relative",
            userScale="1.0",
            userSnap="0.0025",
        )

        # Create weakly-connected pins
        if terminal:
            # Bottom gate pin
            Pin("%sS%d" % (terminal, self.instance), terminal, Rect(self.poly, Box(left, (y - self.Endcap), right, y)))

            # Top gate pin
            Pin(
                "%sN%d" % (terminal, self.instance),
                terminal,
                Rect(self.poly, Box(left, (y + self.w), right, (y + self.w + self.Endcap))),
            )

        self.instance += 1
        return gateRect
    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
Exemple #3
0
    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)