def place_rects(rect_name, rect_length, rect_width, rect_angles, rect_x_coords,
                rect_y_coords):
    try:
        rect_width[0]
    except TypeError:
        rect_width = num.array([rect_width])
    with nd.Cell(rect_name) as rect_array:
        for u in num.arange(rect_y_coords.size):
            for v in num.arange(rect_angles.size):
                # (c, s) = (num.cos(rect_angles[v]*num.pi/180),
                #           num.sin(rect_angles[v]*num.pi/180))
                # rotation = num.array(((c, -s), (s, c)))
                rect_pts = num.array([[0, 0, rect_width[u], rect_width[u]],
                                      [0, rect_length, rect_length, 0]])
                rect_pts = num.transpose(
                    num.dot(rotation_mat(rect_angles[v]), rect_pts))
                rect_pts = geom.transform(points=rect_pts,
                                          move=(rect_x_coords[v],
                                                rect_y_coords[u], 0))
                nd.Polygon(points=rect_pts, layer='layer3').put(0)
            message = 'Angle = ' + num.array2string(rect_angles[0]) + \
                      ' to ' + num.array2string(rect_angles[-1]) + ', width = '
            if rect_width.size == 1:
                message += rect_width
            else:
                message += num.array2string(rect_width[u])
            nd.text(text=message, height=20, layer='layer3', align='rb') \
                .put(int(rect_x_coords[-2]  + 250 ),
                     int(rect_y_coords[u]) + 100)
    rect_array.put(0)
    return rect_array
Exemple #2
0
    def RF_pad(self, pin):
        """Standard RF pad for pixapp layout.

        The current pin will be set at rc of the pad.

        Args:
            pin (Node): pin to connect standard RF pad to.

        Returns:
            Cell: cell with RF pad and name of the pad
        """
        cfg.cp = pin
        pnpos = pin.name.find('_rf')
        padname = pin.name[pnpos + 1:pnpos + 6]
        with nd.Cell('RF-pad-' + padname) as C:
            pad = sp.gsg_pad(length_pad=90,
                             width_pad_sig=70,
                             width_pad_gnd=70,
                             gap2=80 + 30).put('rc')
            pad.raise_pins()
            C.default_pins('rc', 'c1')
            txt = '{}\n{}'.format(padname[0:2], padname[2:])
            nd.text(txt, height=30, align='ct', layer=self.textlayer).\
                    put(pad.pin['c1'].move(-7,0,-90))
        return C
Exemple #3
0
def bezier(a=0,
           b=0,
           c=0,
           p0_x=0,
           p0_y=0,
           length=2000,
           width=5000,
           orientation=-1):
    """Create a Bezier waveguide based on parameters a, b and c."""
    with nd.Cell(name='Bezier') as bez:
        t = np.arange(0, 1, 0.001)
        width = width * orientation
        p1_x = p0_x + length
        p1_y = p0_y
        p2_x = p1_x
        p2_y = p1_y - width
        p3_x = p0_x
        p3_y = p0_y - width

        x = p0_x * (1 - t)**3 + 3 * p1_x * t * (
            1 - t)**2 + 3 * p2_x * t * t * (1 - t) + p3_x * t**3
        y = p0_y * (1 - t)**3 + 3 * p1_y * t * (
            1 - t)**2 + 3 * p2_y * t * t * (1 - t) + p3_y * t**3

        #l = list(product(x, y))
        #mylist = [[0,1],  [0,2],  [0,2],  [0,5]];
        x1 = np.array([x])
        y1 = np.array([y])
        x2 = x1.T
        y2 = y1.T
        bezier_curve = np.hstack((x2, y2))
        #bezier_curve = [(0, 0), (3, 3), (500, 500),(500, 900)] # Bezier waveguide outline
        #nd.Polygon(layer=1,points=bezier_curve ).put(0)
        nd.Polyline(layer=0, points=bezier_curve, width=50).put(0)
        #add pins to the input and output, pointing outwards of the bezier guide
        nd.Pin('a0').put(0, 0, 180)  #if bezier starts in (0, 0, 0)
        #        nd.Pin('b0').put(xout, yout, aout)
        nd.strt(length=100, width=100).put(p0_x, p0_y)
        nd.strt(length=100, width=100).put(p1_x, p1_y)
        nd.strt(length=100, width=100).put(p2_x, p2_y)
        nd.strt(length=100, width=100).put(p3_x, p3_y)

        width_x = (p1_x + p2_x) / 2
        width_y = (p1_y + p2_y) / 2
        nd.text('width', height=250, align='cc', layer=2).put(width_x, width_y)

        length_x = (p0_x + p1_x) / 2
        length_y = (p0_y + p1_y) / 2
        nd.text('length', height=250, align='cc',
                layer=2).put(length_x, length_y)

    return bez
def place_cross(cross_name, x, y, cross_w, cross_l):
    try:
        cross_w[0]
    except TypeError:
        cross_w = num.array([cross_w])
    with nd.Cell(name=cross_name) as xs:
        for u in num.arange(num.size(cross_w)):
            box_pts = num.array([[0, 0, cross_l, cross_l],
                                 [cross_w[u], 0, 0, cross_w[u]]])
            xs_box_h = geom.transform(
                points=num.transpose(box_pts),
                move=(+x, y + (cross_l - cross_w[u]) / 2 + u * (cross_l + 50),
                      0))
            xs_box_v = geom.transform(points=num.transpose(
                num.dot(rotation_mat(90), box_pts)),
                                      move=(+x + (cross_l + cross_w[u]) / 2,
                                            +y + u * (cross_l + 50), 0))
            xs_box_30 = geom.transform(
                points=num.transpose(num.dot(rotation_mat(30), box_pts)),
                move=(+x + (cross_l - cross_l * num.cos(num.pi / 6) +
                            cross_w[u] * num.sin(num.pi / 6)) / 2,
                      +y + (cross_l - cross_l * num.sin(num.pi / 6) -
                            cross_w[u] * num.cos(num.pi / 6)) / 2 + u *
                      (cross_l + 50), 0))
            xs_box_60 = geom.transform(
                points=num.transpose(num.dot(rotation_mat(60), box_pts)),
                move=(+x + (cross_l - cross_l * num.cos(num.pi / 3) +
                            cross_w[u] * num.sin(num.pi / 3)) / 2,
                      +y + (cross_l - cross_l * num.sin(num.pi / 3) -
                            cross_w[u] * num.cos(num.pi / 3)) / 2 + u *
                      (cross_l + 50), 0))
            xs_box_120 = geom.transform(xs_box_60,
                                        flipy=True,
                                        move=(0, +2 * y + cross_l + 2 * u *
                                              (cross_l + 50), 0))
            xs_box_150 = geom.transform(xs_box_30,
                                        flipx=True,
                                        move=(+2 * x + cross_l, 0, 0))
            nd.Polygon(points=xs_box_h, layer='layer3').put(0)
            nd.Polygon(points=xs_box_v, layer='layer3').put(0)
            nd.Polygon(points=xs_box_30, layer='layer3').put(0)
            nd.Polygon(points=xs_box_60, layer='layer3').put(0)
            nd.Polygon(points=xs_box_120, layer='layer3').put(0)
            nd.Polygon(points=xs_box_150, layer='layer3').put(0)
            message_txt = 'Height = ' + str(cross_l) + ', Width = ' + str(
                cross_w[u])
            nd.text(text=message_txt, height=20, layer='layer3') \
                .put(int(x - cross_l / 2 - 150), int(y + u * (cross_l + 50)))
    xs.put(0)
    return
Exemple #5
0
def compass(size=200, layer=1):
    """Show compass image to identify the sample direction.

    Args:
        size (double): size (wxh) of the bounding box.
        layer (int | str | tuple): layer (or list of layers) to draw in.

    Returns:
        cell containing the compass.
    """
    s = size/182
    quart = [(0,0), (s,0), (s,s), (16*s,16*s), (s/2,70*s), (-s/2,70*s),
            (-16*s,16*s), (-15*s,15*s), (-s,65*s), (0,65*s)]
    p = 75 * s
    h = 20 * s

    with nd.Cell("compass_"+nd.md5(layer)) as C:
        for lay in nd.make_iter(layer):
            nd.Polygon(layer=lay, points=quart).put(0,0,0)
            nd.Polygon(layer=lay, points=quart).put(0,0,90)
            nd.Polygon(layer=lay, points=quart).put(0,0,180)
            nd.Polygon(layer=lay, points=quart).put(0,0,270)
            nd.text('E', layer=lay, height=h, align='lc').put(p, 0)
            nd.text('N', layer=lay, height=h, align='cb').put(0, 71*s)
            nd.text('W', layer=lay, height=h, align='rc').put(-p, 0)
            nd.text('S', layer=lay, height=h, align='ct').put(0, -p)
    return C
    def cell(length=length, height=height, cleave=cleave, pitch=pitch):
        """Create a cell boundary.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:
            pdk.parameters('hashme').put(0)

            #TODO: No foundry specific stuff here: remove.
            for lay, grow, acc in nd.layeriter(xs):
                frame = geom.frame(sizew=cleave,
                                   sizel=length,
                                   sizeh=height,
                                   grow=grow)
                nd.Polygon(layer=lay, points=frame).put(0)

            #Placing IOs
            amount_ios = round((height - cleave - pitch) / pitch)

            #IOs positions
            lay = 'AnnotationIO'
            for no in range(0, amount_ios):
                pinID = 'ioL{:03d}'.format(no)
                angle = 0

                p = nd.Pin(name=pinID).put(-cleave, pitch + no * pitch, angle)
                p = nd.Pin(name='ioL' + str(no)).put(-cleave,
                                                     pitch + no * pitch, angle)
                pdk.arrow.put(p)
                nd.text(pinID, layer=lay, height=0.15,
                        align='rc').put(p.move(-0.1))

            for no in range(0, amount_ios):
                mo = amount_ios + no
                pinID = 'ioR{:03d}'.format(no)
                angle = 0

                p = nd.Pin(name=pinID).put(length, pitch + no * pitch,
                                           180 + angle)
                p = nd.Pin(name='ioR' + str(no)).put(length,
                                                     pitch + no * pitch,
                                                     180 + angle)
                pdk.arrow.put(p)
                nd.text(pinID, layer=lay, height=0.15, align='lc').\
                    put(p.move(-0.1, 0, 180))

        C.groupname = groupname
        return C
Exemple #7
0
 def _put_arrow(self, loc, name, i):
     self.arrow.put(loc)
     t = nd.text(name.format(i),
                 layer=annotationlayer,
                 height=textheight,
                 align='rc')
     t.put(loc.move(textmove))
def cellname(cellname=None, length=0, width=None, align='lc'):
    """Create the cellname as a text cell.

    Args:
        cellname (str): name of the cell
        length (float): length available for the BB name in um
        width (float):
        align (str): text alignment (see nazca.text, default = 'lc')

    Returns:
        Cell: text with cellname
    """
    cell = cfg.cells[-1]
    if cellname is None:
        cellname = cell.cell_paramsname

    if width is not None:
        maxheight = min(width * 0.8, cfg.cellname_max_height)
    else:
        maxheight = cfg.cellname_max_height

    length = length * cfg.cellname_scaling
    texth = min(maxheight, abs(length) / nd.linelength(cellname, 1))
    txt = nd.text(cellname, texth, layer='bbox_name', align=align)
    return txt
def place_blks(block_name, block_height, block_width, block_angles,
               block_x_coords, block_y_coords):
    with nd.Cell(block_name) as blk_arr:
        for u in num.arange(block_width.size):
            for v in num.arange(block_angles.size):
                block_pts = geom.parallelogram(length=block_width[u],
                                               height=block_height,
                                               angle=block_angles[v],
                                               shift=(block_x_coords[v],
                                                      block_y_coords[u], 0))
                nd.Polygon(points=block_pts, layer='layer3').put(0)
            message = 'Angle = ' + num.array2string(block_angles[0]) + \
                      ' to ' + num.array2string(block_angles[-1]) + \
                      ', Width = ' + num.array2string(block_width[0]
                                                      * num.sin(num.pi/180
                                                                *block_angles[0]))
            nd.text(text=message, height=20, layer='layer3') \
                .put(int(block_x_coords[-1] + 0.5 * block_x_coords[0]),
                     int(block_y_coords[u]))
    blk_arr.put(0)
    return blk_arr
Exemple #10
0
    def DC_pad(self, pin):
        """Standard DC pad for pixapp layout.

        The current pin will be set at rc of the pad.

        Args:
            pin (Node): pin to connect standard DC pad to.

        Returns:
            Cell: cell with DC pad and name of the pad
        """
        cfg.cp = pin
        pnpos = pin.name.find('_dc')
        padname = pin.name[pnpos + 1:pnpos + 7]
        with nd.Cell('DC-pad-' + padname, instantiate=False) as C:
            pad = self.DCpadcell.put('rc')
            pad.raise_pins()
            C.default_pins('rc', 'c0')
            txt = '{}\n{}'.format(padname[0:3], padname[3:])
            nd.text(txt, height=30, align='cc', layer=self.textlayer).\
                    put(pad.pin['c0'].move(0,0,-90))
        return C
def whereami(text='here', size=100, pin=None):
    """Show current pointer position as arrow in the layout.

    Args:
        text (str): annotation text
        size (float): size of the annotation

    Returns:
        None
    """
    layer = 500
    nd.cp.push()
    if pin is None:
        pin = nd.cp.here()
    points = [(0, 0), (-0.5, 0.5), (-0.4, 0.25), (-1, 0.3), (-1, -0.3),
              (-0.4, -0.25), (-0.5, -0.5)]
    points = [(x * size, y * size) for x, y in points]
    with Cell('I am'.format(wherecnt)) as crisis:
        nd.Polygon(layer=layer, points=points).put(0)
        nd.text(text + ' ', height=size / 4, align='rc', layer=layer).put(0)

    crisis.put(pin)
    nd.cp.pop()
    def cell(self):
        """Create a Cell with DC, RF, Optical fiber postitions.

        Returns:
            Cell: package cell
        """
        with nd.Cell(name=self.name) as C:

            for arr in self.pads:

                count = arr['count']
                #Placing PAD IOs
                IOcountmax = round(\
                    (self.die_length - 2*arr['edge_sep_side']) / arr['pitch'])
                if count is not None and count < IOcountmax:
                    IOcount = count
                else:
                    IOcount = IOcountmax

                pin = arr['edge'] + arr['type']
                if arr['edge'] == 'left':
                    x0, y0, a0 = 0, 0, 90
                elif arr['edge'] == 'top':
                    x0, y0, a0 = 0, self.die_height, 0
                elif arr['edge'] == 'right':
                    x0, y0, a0 = self.die_length, self.die_height, -90
                elif arr['edge'] == 'bottom':
                    x0, y0, a0 = self.die_length, 0, 180
                else:
                    print("Edge not recognized in Package2: '{}'".format(
                        arr['edge']))

                #PAD positions
                for n in range(0, IOcount):
                    pinID = pin_naming[pin].format(n)
                    if arr['center']:
                        if arr['edge'] in ['top', 'bottom']:
                            dist_edge = self.die_length -\
                                (IOcount-1)*arr['pitch'] - 2*arr['edge_sep_side']
                        elif arr['edge'] in ['left', 'right']:
                            dist_edge = self.die_height -\
                                (IOcount-1)*arr['pitch'] - 2*arr['edge_sep_side']
                    else:
                        dist_edge = 0

                    #place metal io pins
                    start = nd.Pin().put(x0, y0, a0)
                    p = nd.Pin(pinID).put(
                        start.move(
                            n * arr['pitch'] + arr['edge_sep_side'] +
                            0.5 * dist_edge, -arr['edge_sep_front'], -90))
                    self.arrow.put(p)
                    text = nd.text(pinID,
                                   layer=annotationlayer,
                                   height=textheight,
                                   align='rc')
                    text.put(p.move(textmove))

            #Fiber positions
            dist_edgey = self.die_height - self.cleave - self.fiberarea
            faa_len = self.cleave + 50

            if self.show_fiberarea:
                farea = geom.box(width=self.fiberarea, length=faa_len)
                poly = nd.Polygon(layer=fiberIOlayer, points=farea)
                poly.put(-faa_len - 0.5 * self.cleave,
                         0.5 * dist_edgey + 0.5 * self.fiberarea, 0)
            else:
                print(
                    'Set show_fiberarea == True to see the fiber allowed area for this package.'
                )

        return C
    def cell(self):
        """Create a Cell with DC, RF, Optical fiber postitions.

        Returns:
            Cell: package cell
        """
        with nd.Cell(name=self.name) as C:

            #Placing PAD IOs
            IOcountmax = round(
                (self.die_length - 2 * self.DCside) / self.DCpitch)
            if self.DCcount is not None and self.DCcount < IOcountmax:
                IOcount = self.DCcount
            else:
                IOcount = IOcountmax

            #DC PAD positions
            for n in range(0, IOcount):
                pinIDT = DCtopname.format(n)
                pinIDB = DCbotname.format(n)

                if self.DCcenter:
                    dist_edgex = 0.5 * (self.die_length -
                                        (IOcount - 1) * self.DCpitch)
                else:
                    dist_edgex = self.DCside

                #Top DC ports
                p = nd.Pin(pinIDT).put(
                    dist_edgex + n * self.DCpitch - 0.5 * self.cleave,
                    self.die_height - self.DCedge - 0.5 * self.cleave, -90)
                self.arrow.put(p)
                text = nd.text(pinIDT,
                               layer=annotationlayer,
                               height=textheight,
                               align='rc')
                text.put(p.move(textmove))

                #Bottom DC ports
                p = nd.Pin(pinIDB).put(
                    dist_edgex + n * self.DCpitch - 0.5 * self.cleave,
                    self.DCedge - 0.5 * self.cleave, 90)
                self.arrow.put(p)
                text = nd.text(pinIDB,
                               layer=annotationlayer,
                               height=textheight,
                               align='rc')
                text.put(p.move(textmove))

            #DC PAD positions double row
            if self.double_row_DC:
                for ndr in range(0, IOcount - 1):
                    n = ndr + IOcountmax
                    pinIDT = DCtopname.format(n)
                    pinIDB = DCbotname.format(n)

                    if self.DCcenter == True:
                        dist_edgex = self.die_length - self.cleave -\
                            (IOcount-1)*self.DCpitch-2*self.DCside
                    else:
                        dist_edgex = 0

                    if self.DCx_doublerow == None:
                        self.DCx_doublerow = 0.5 * self.DCpitch

                    if self.DCy_doublerow == None:
                        self.DCy_doublerow = 1.0 * self.DCpitch

                    #Top DC ports
                    p = nd.Pin(pinIDT).put(
                        ndr * self.DCpitch + self.DCside + 0.5 * dist_edgex +
                        self.DCx_doublerow, self.die_height - self.cleave -
                        self.DCedge - self.DCy_doublerow, -90)
                    self.arrow.put(p)
                    text = nd.text(pinIDT,
                                   layer=annotationlayer,
                                   height=textheight,
                                   align='rc')
                    text.put(p.move(textmove))

                    #Bottom DC ports
                    p = nd.Pin(pinIDB).put(
                        ndr * self.DCpitch + self.DCside + 0.5 * dist_edgex +
                        self.DCx_doublerow, self.DCedge + self.DCy_doublerow,
                        90)
                    self.arrow.put(p)
                    text = nd.text(pinIDB,
                                   layer=annotationlayer,
                                   height=textheight,
                                   align='rc')
                    text.put(p.move(textmove))

            #RF PAD positions
            IOcountmax = round(
                (self.die_height - 2 * self.RFside) / self.RFpitch)
            if self.RFcount is not None and self.RFcount < IOcountmax:
                IOcount = self.RFcount
            else:
                IOcount = IOcountmax

            for n in range(0, IOcount):
                piRFn = RFname.format(n)

                if self.RFcenter:
                    dist_edgey = self.die_height-self.cleave -\
                        (IOcount-1)*self.RFpitch-2*self.RFside
                else:
                    dist_edgey = 0

                p = nd.Pin(piRFn).put(
                    self.die_length - self.cleave - self.RFedge,
                    n * self.RFpitch + self.RFside + 0.5 * dist_edgey, 180)
                self.arrow.put(p)
                text = nd.text(piRFn,
                               layer=annotationlayer,
                               height=textheight,
                               align='rc')
                text.put(p.move(textmove))

            #RF PAD positions double row
            if self.double_row_RF:
                for ndr in range(0, IOcount - 1):
                    n = ndr + IOcountmax
                    piRFn = RFname.format(n)

                    if self.RFcenter == True:
                        dist_edgey = self.die_height-self.cleave -\
                            (IOcount-1)*self.RFpitch-2*self.RFside
                    else:
                        dist_edgey = 0

                    if self.RFx_doublerow == None:
                        self.RFx_doublerow = 1.0 * self.RFpitch

                    if self.RFy_doublerow == None:
                        self.RFy_doublerow = 0.5 * self.RFpitch

                    p = nd.Pin(piRFn).put(\
                        self.die_length-self.cleave-self.RFedge-self.RFx_doublerow,
                        ndr*self.RFpitch+self.RFside+0.5*dist_edgey+self.RFy_doublerow,
                        180)
                    self.arrow.put(p)
                    text = nd.text(piRFn,
                                   layer=annotationlayer,
                                   height=textheight,
                                   align='rc')
                    text.put(p.move(textmove))

            #Fiber positions
            dist_edgey = self.die_height - self.cleave - self.fiberarea
            faa_len = self.cleave + 50

            if self.show_fiberarea:
                farea = geom.box(width=self.fiberarea, length=faa_len)
                poly = nd.Polygon(layer=fiberIOlayer, points=farea)
                poly.put(-faa_len - 0.5 * self.cleave,
                         0.5 * dist_edgey + 0.5 * self.fiberarea, 0)
            else:
                print(
                    'Set show_fiberarea == True to see the fiber allowed area for this package.'
                )

        return C
Exemple #14
0
    def cell(self):
        """Create a Project Cell with IO postition pins.

        Returns:
            Cell: cell containing design area and cleave boundaries
        """
        with nd.Cell(name=self.name) as C:
            # put the dice/cleave border
            frame = geom.frame(sizew=self.cleave,
                               sizel=self.length,
                               sizeh=self.height)
            nd.Polygon(layer='DiceArea', points=frame).put(0)

            nd.Pin('left',
                   show=False).put(-0.5 * (self.cleave),
                                   -0.5 * self.cleave + 0.5 * self.height, 0)
            tdk.put_boundingbox('left', self.length, self.height)

            # put the pins
            IOcountmax = round(
                (self.height - self.cleave - self.pitch) / self.pitch)
            pin_indent = 0
            ioy0 = 50

            for no in range(0, IOcountmax):
                pinIDL = 'ioL{:03d}'.format(no)
                pinIDR = 'ioR{:03d}'.format(no)
                if no % 2 is 0:
                    angle = 7
                else:
                    angle = 0

                #IOs left
                p = nd.Pin(name=pinIDL, xs='Shallow',
                           type=angle).put(-self.cleave + pin_indent,
                                           ioy0 + no * self.pitch, angle)
                self.arrow.put(p)
                nd.text(pinIDL,
                        layer=package_pin_text,
                        height=0.15,
                        align='rc').put(p.move(-0.1))

                #IOs right
                p = nd.Pin(name=pinIDR, xs='Shallow',
                           type=angle).put(-pin_indent + self.length,
                                           ioy0 + no * self.pitch, 180 + angle)
                self.arrow.put(p)
                nd.text(pinIDR,
                        layer=package_pin_text,
                        height=0.15,
                        align='rc').put(p.move(-0.575, 0, 180))

            # Adding coating
            options = {
                'AR': 'Coating_AR',
                'HR': 'Coating_HR',
                'NO': 'Coating_NO',
                'DC': 'Coating_DC'
            }
            coating_on_chip = 100

            box_coatno = [(0, 0), (self.cleave / 2, 0),
                          (self.cleave / 2, self.height), (0, self.height)]

            box_coatother = [(0, 0), (coating_on_chip + 0.5 * self.cleave, 0),
                             (coating_on_chip + 0.5 * self.cleave,
                              self.height), (0, self.height)]

            pinL = nd.Pin().put(-0.5 * self.cleave, -0.5 * self.cleave)
            pinR = nd.Pin().put(self.length - 0.5 * self.cleave,
                                self.height - 0.5 * self.cleave, 180)

            coatings = {'L': (self.coatingL, pinL), 'R': (self.coatingR, pinR)}

            for coat, pin in coatings.values():
                if coat in options.keys():
                    layer = options[coat]
                else:
                    print(
                        'Available coating options: AR | HR | NO | DC. Default is NO.'
                    )

                if coat is 'NO':
                    box = box_coatno
                else:
                    box = box_coatother
                nd.Polygon(layer=layer, points=box).put(pin)

            return C
        return cell
    def cell(cleave=cleave,
             length=length,
             height=height,
             coatingW=coatingW,
             coatingE=coatingE):
        """Create a Cell_Boundary cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:

            pdk.put_boundingbox('org', length, height, outline=False, \
                move=(-0.5*cleave, 0.5*height-0.5*cleave))
            pdk.parameters('hashme').put(0, 'cc')

            #TODO: No foundry specific stuff here: remove.
            outline = [(0, 0), (length - cleave, 0),
                       (length - cleave, height - cleave),
                       (0, height - cleave)]
            nd.Polygon(layer='Polyimide1Base', points=outline).put(0)

            for lay, grow, acc in nd.layeriter(xs):
                frame = geom.frame(sizew=cleave,
                                   sizel=length,
                                   sizeh=height,
                                   grow=grow)
                nd.Polygon(layer=lay, points=frame).put(0)

            ##adding coating to nd.Cell boundary: west and east
            options = {
                'AR': 'Coating_AR',
                'HR': 'Coating_HR',
                'NO': 'Coating_NO',
                'DC': 'Coating_DC'
            }
            coating_on_chip = nd.get_parameter('cell_coating_on_chip')
            box_coatno = [(0, 0), (cleave / 2, 0), (cleave / 2, height),
                          (0, height)]
            box_coatother = [(0, 0), (coating_on_chip + 0.5 * cleave, 0),
                             (coating_on_chip + 0.5 * cleave, height),
                             (0, height)]
            pinW = nd.Pin().put(-0.5 * cleave, -0.5 * cleave)
            pinE = nd.Pin().put(length - 0.5 * cleave, height - 0.5 * cleave,
                                180)

            coatings = {'E': (coatingE, pinE), 'W': (coatingW, pinW)}

            for coat, pin in coatings.values():
                if coat in options.keys():
                    layer = options[coat]
                else:
                    print(
                        'Available coating options: AR | HR | NO | DC. Default is NO.'
                    )

                if coat is 'NO':
                    box = box_coatno
                else:
                    box = box_coatother
                nd.Polygon(layer=layer, points=box).put(pin)

            #Placing IOs
            pitch = 12.5
            amount_ios = round((height - cleave - pitch) / pitch)

            #IOs positions
            lay = 'bb_pin'
            for no in range(0, amount_ios):
                pinID = 'io{:03d}'.format(no)
                if no % 2 is 0:
                    angle = 7
                else:
                    angle = 0

                p = nd.Pin(name=pinID).put(-cleave / 2, 12.5 + no * pitch,
                                           angle)
                p = nd.Pin(name='io' + str(no)).put(-cleave / 2,
                                                    12.5 + no * pitch, angle)
                pdk.make_pincell().put(p)
                nd.text(pinID, layer=lay, height=0.15,
                        align='rc').put(p.move(-0.1))

            for no in range(0, amount_ios):
                mo = amount_ios + no
                pinID = 'io{:03d}'.format(mo)
                if mo % 2 is 0:
                    angle = 7
                else:
                    angle = 0

                p = nd.Pin(name=pinID).put(length - cleave / 2,
                                           2 * 12.5 + no * pitch, 180 + angle)
                pdk.make_pincell().put(p)
                nd.text(pinID, layer=lay, height=0.15, align='lc').\
                    put(p.move(-0.1, 0, 180))

            C.groupname = groupname
        return C
Exemple #16
0
pitch = 50
wafer = 25.4 * 4 * 1000
w = 2.3
"wg width"
pos_y = 0

nd.bend(angle=360, radius=25.4 * 1000 * 2,
        width=w).put(25.4 * 1000 * 2, -25.4 * 1000 * 2)

# dose 600mj/cm2
n = 0
while n < 10:
    nd.strt(length=25.4 * 2 * 1000, width=w).put(25.4 * 1000,
                                                 25.4 * 1000 + n * 50)
    n = n + 1
nd.text('600', height=2000).put()

# dose 800mj/cm2

n = 0
while n < 10:
    nd.strt(length=25.4 * 2 * 1000, width=w).put(25.4 * 1000,
                                                 n * 50 - 10 * 1000)
    n = n + 1
nd.text('XL', height=5000).put(48000, 20000)

# dose 1000mj/cm2

n = 0
while n < 10:
    nd.strt(length=25.4 * 2 * 1000, width=w).put(25.4 * 1000,