예제 #1
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
예제 #2
0
    def cell(length=length, angle=angle):
        anglerad = radians(angle)
        """Create a trapezoidal IO cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True, instantiate=False) as C:
            """When instantiate is True, cell put in (0, 0, 0)"""
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\
                put(0.5*length*(1.0+1.0/cos(anglerad)))

            pdk.put_stub(['a0', 'b0'])
            pdk.cellname(length=0.5 * length).put(C.pin['a0'].rot(180))

            temp_a = tan(anglerad) + 0.5 * width * tan(anglerad)
            temp_b = length / cos(anglerad) + length
            for lay, grow, acc in nd.layeriter(xs['a0']):
                outline = [(0, 0.5 * width + grow),
                           (0.5 * temp_b - (width + grow) * temp_a,
                            0.5 * width + grow),
                           (0.5 * temp_b + grow * temp_a, -0.5 * width - grow),
                           (0, -0.5 * width - grow)]
                nd.Polygon(layer=lay, points=outline).put(0)
            cfg.cp = C.pin['b0']
        C.groupname = groupname
        return C
def mzi(length=1000, sep=50):
    with nd.Cell(hashme=True) as mziBB:
        eopm = eopm_dc(length=length, pads=True, sep=40)
        mmi_left  = mmi2x2_dp().put('lc')
        deep.sbend(offset=sep).put(mmi_left.pin['b0'])
        eopm_top = eopm.put()
        deep.sbend(offset=-sep).put()
        mmi_right = mmi2x2_dp().put()

        deep.sbend(offset=-sep).put(mmi_left.pin['b1'])
        eopm_bot = eopm.put(flip=True)
        deep.sbend(offset=sep).put()

        nd.Pin('a0', pin=mmi_left.pin['a0']).put()
        nd.Pin('a1', pin=mmi_left.pin['a1']).put()
        nd.Pin('b0', pin=mmi_right.pin['b0']).put()
        nd.Pin('b1', pin=mmi_right.pin['b1']).put()
        nd.Pin('c0', pin=eopm_top.pin['c0']).put()
        nd.Pin('c1', pin=eopm_top.pin['c1']).put()
        nd.Pin('d0', pin=eopm_bot.pin['c0']).put()
        nd.Pin('d1', pin=eopm_bot.pin['c1']).put()
        pdk.put_stub()

        bb_length, y, a = nd.diff(mziBB.pin['a0'], mziBB.pin['b0'])
        pdk.put_boundingbox('org', length=abs(bb_length), width=2*sep+428)
    return mziBB
def dbr_laser(Ldbr1=50, Ldbr2=500, Lsoa=750, Lpm=70):
    """Create a parametrized dbr laser building block."""
    Liso = 20
    with nd.Cell(hashme=True) as laser:
        #create an isolation cell for reuse
        iso = isolation_act(length=Liso)

        #draw the laser
        s2a1 = s2a().put(0)
        iso.put()
        dbr1 = dbr(length=Ldbr1).put()
        iso.put()
        soa1 = soa(length=Lsoa).put()
        iso.put()
        phase1 = phase_shifter(length=Lpm).put()
        iso.put()
        dbr2 = dbr(length=Ldbr2).put()
        iso.put()
        a2s1 = a2s().put()

        # add pins to the laser building block
        nd.Pin('a0', pin=s2a1.pin['a0']).put()
        nd.Pin('b0', pin=a2s1.pin['b0']).put()
        nd.Pin('c0', pin=dbr1.pin['c0']).put()
        nd.Pin('c1', pin=soa1.pin['c0']).put()
        nd.Pin('c2', pin=phase1.pin['c0']).put()
        nd.Pin('c3', pin=dbr2.pin['c0']).put()
        pdk.put_stub()

        length, y, a = nd.diff(laser.pin['a0'], laser.pin['b0'])
        pdk.put_boundingbox('org', length=abs(length), width=200, align='lb',
            move=(0, -30, 0))
    return laser
def abb_eopm_dc(length=750, contacts=2):
    """Create an electro-optic phase modulator cell.

    Args:
        length (float): length of the modulator section in um

    Returns:
        Cell: eopm element
    """
    width = 60
    with nd.Cell(hashme=True) as C:
        nd.Pin(name='a0', xs='Deep', width=wdeep).put(0, 0, 180)
        nd.Pin(name='b0', xs='Deep', width=wdeep).put(length, 0, 0)

        # x-positions of pads:
        L = 0.5*(length - wmetdc)
        xpos = []
        if contacts > 1:
            for n in range(contacts):
                xpos.append(0.5*wmetdc + L*2*n/(contacts-1))
        elif contacts == 1:
            xpos = [0.5*length]
        elif contacts == 0:
            pass
        for n, x in enumerate(xpos):
            pinname = 'c'+str(n)
            p1 = nd.Pin(name=pinname, xs='MetalDC', width=wmetdc).put(x, 0, 90)
            nd.put_stub(pinname)

        #nd.Pin(name='c0', xs='MetalDC', width=wmetdc).put(0.5*length, 5.0, 90)
        pdk.put_stub(['a0', 'b0', 'c0'])
        pdk.put_boundingbox('org', length, width, align='lc')
        icons.icon_strt(length, width, bufx=0, bufy=10, layer='MetalDCIcon').put('cc', 0, 'cc')
        icons.icon_strt(length, width, bufx=10, bufy=-8, layer='DeepIcon').put('cc', 0, 'cc')
    return C
예제 #6
0
    def cell(length=length, angle=angle):
        anglerad = radians(angle)
        """Create a trapezoidal IO cell.

        Returns:
            Cell
        """
        with nd.Cell(hashme=True, instantiate=False) as C:
            #When instantiate is True, cell put in (0,0,0)
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).\
                put(length/cos(anglerad)-0.5*width*tan(abs(anglerad)))

            pdk.put_stub(['b0'])
            pdk.cellname(length=0.5 * length).put(-0.1 * length, 0, 180, 'a0')

            for lay, grow, acc in nd.layeriter(xs['a0']):
                outline = nd.geom.trapezoid(length=length / cos(anglerad) +
                                            grow * tan(abs(anglerad)),
                                            height=width + 2 * grow,
                                            angle1=90 + angle,
                                            angle2=90,
                                            position=2)
                nd.Polygon(layer=lay, points=outline).put(0)
            cfg.cp = C.pin['b0']
            C.groupname = groupname
        return C
예제 #7
0
    def icon_ssc(length=100, width=20, bufx=None, bufy=None):
        """Create an icon for a grating.

        Args:
            length (float): length of the grating icon
            width (float): width of the grating icon

        Returns:
            Cell: grating icon
        """
        length, width, bufx, bufy = calc_buf(length, width, bufx, bufy)

        N = 20
        dx = length / N
        wout = width
        win = 0.1 * wout
        wi = 0.5 * win
        wo = 0.5 * (wout - win)
        x, y1, y2 = [], [], []
        for i in range(N):
            x.append(i * dx)
            dy = wi + (wo / (N - 1)) * i * i / (N - 1)
            y1.append(dy)
            y2.append(-dy)
        X = x + x[::-1]
        Y = y1 + y2[::-1]
        outline = list(zip(X, Y))

        with nd.Cell('icon', instantiate=False) as icon:
            nd.Polygon(points=outline, layer=layer).put(0)
            nd.Pin('cc').put(0.5 * length)
            nd.Pin('a0').put(0, 0, 180)
            nd.Pin('b0').put(length, 0, 0)
        return icon
    def cell(length=length, pitch=pitch, duty_cycle=duty_cycle):
        """Create a DBR cell.

        Args:
            length (float): length of DBR section in um
            pitch (float): pitch (full period) of dbr in um
            duty_cycle (float): duty cycle of grating (default = 0.5)

        Returns:
            Cell: dbr element
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            C.foundry_spt = []
            pdk.addBBmap(name, params=(length, pitch, duty_cycle))
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).put(length)
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0']).put(length/2, 5.0, 90)

            pdk.put_stub(['a0', 'b0', 'c0'])
            pdk.put_boundingbox('org', length, width)

            if icon:
                icon(length, width).put(0)

        return C
    def cell(length=length):
        """Create and return a DCpad cell.

        Args:
            length (float): pad length in um
            width (float): pad width in um

        Returns:
            Cell: pad element
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            C.foundry_spt = []
            bb_length = length + 2*buf_length

            pdk.addBBmap(name, params=(length, tab_width, "RoundedRectangle"),
                trans=(0.5*(length-100), 0, 0))
            C.default_pins('c0','c0')
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\
                put(0.5*bb_length, 0, 180)

            pdk.put_stub('c0', length=pinwidth['c0'], shape='circle')
            pdk.put_boundingbox('org', bb_length, bb_length)

            if icon:
                icon(bb_length, bb_length).put(0, 'cc')
        return C
예제 #10
0
    def getcell(self):
        with nd.Cell(name=self.name) as dha_cell:
            inpin = nd.Pin(name='a0').put(self.start[0], self.start[1],
                                          self.start[2])
            nd.Pin(name='b0').put(self.end[0], self.end[1], self.end[2])
            a, b = self.outline()

            if self.return_path == True:
                nd.Polygon(nd.util.polyline2polygon(xy=self.points,
                                                    width=self.ww),
                           layer=self.layer).put()
                nd.Polyline(width=self.owidth, points=a,
                            layer=self.olayer).put(inpin.rotate(180))
                nd.Polyline(width=self.owidth, points=b,
                            layer=self.olayer).put(inpin.rotate(180))
            else:
                nd.Polygon(nd.util.polyline2polygon(xy=self.points,
                                                    width=self.ww),
                           layer=self.layer).put()
                nd.Polygon(nd.util.polyline2polygon(xy=a, width=self.owidth),
                           layer=self.olayer).put(inpin.rotate(180))
                nd.Polygon(nd.util.polyline2polygon(xy=b, width=self.owidth),
                           layer=self.olayer).put(inpin.rotate(180))

        return dha_cell
예제 #11
0
def eulbendtest(L=10000,
                r1=200,
                r2=200,
                l1=500,
                layer=1,
                w1=1,
                w2=0.5,
                p=0.2,
                n=4,
                olayer=2):
    with nd.Cell('Bend_test') as ebt:
        path = dha(layer=1, width=w1, olayer=olayer, owidth=w_trench)

        path.strt(length=l1 / 4)
        path.taper(length=l1, width1=w1, width2=w2)
        L = L - 4 * l1
        l = L / (2 * n) - (r1 + r2)
        for i in range(n):
            path.strt(length=l)
            path.eulerbend(angle=90, radius=r1, p=p)
            path.eulerbend(angle=-180, radius=r2, p=p)
            path.eulerbend(angle=90, radius=r1, p=p)
            path.strt(length=l)
        path.taper(length=l1, width1=w2, width2=w1)
        path.strt(length=l1 * (7 / 4))
        path.getcell().put()
    return ebt
예제 #12
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
예제 #13
0
    def cell(length=length, width_sig=width_sig, width_gnd=width_gnd, gap=gap):
        """Create a GSG RF line cell.

        Returns:
           Cell
        """
        with nd.Cell(name=pdk._hash_name, instantiate=False) as C:
            C.groupname = groupname
            pdk.addBBmap(name)

            #bb_width = width_sig + 2*width_gnd + 2*gap
            width = width_sig
            sig = nd.strt(length=length, width=width, xs=xs['a0']).put(0)
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0'], remark='electrical').put(sig.pin['a0'])
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0'], remark='electrical').put(sig.pin['b0'])

            pdk.put_stub(['a0', 'b0'])
            #pdk.put_boundingbox('org', length, bb_width)
            #pdk.parameters(pdk._hash_params).put(0)
            #pdk.cellname(C.cell_name, length, align='rc').put(-0.25*length, 'b0')

            width = width_gnd
            #nd.strt(length=length, width=width+2*width_gnd+2*gap+2*wext_bg, layer='bbox').put(0)
            nd.strt(length=length, width=width, xs=xs['a0']).put(0, -gap-0.5*(width_sig+width_gnd))
            nd.strt(length=length, width=width, xs=xs['a0']).put(0, +gap+0.5*(width_sig+width_gnd))

            if xs_bg is not None:
                nd.strt(length=length, width=xs_bg_width, xs=xs_bg).put(0)

            cfg.cp = C.pin['b0']
        return C
예제 #14
0
    def cell(diameter=diameter):
        """Create a DCpad cell.

        Args:
            diameter (float): diameter of circular debt

        Returns:
            Cell
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            pdk.addBBmap(name)
            bb_width = diameter + 2*buf_width
            bb_length = diameter + 2*buf_length

            C.default_pins('c0', 'c0')
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\
                put(0.5*bb_length, 0, 180)

            pdk.put_stub('c0', length=pinwidth['c0'], shape='circle')
            pdk.put_boundingbox('org', bb_length, bb_width)

            for lay, grow, acc in nd.layeriter(xs['c0']):
                pad = nd.geom.circle(radius=0.5*diameter, N=100)
                nd.Polygon(layer=lay, points=pad).\
                    put('cc')

        return C
예제 #15
0
def soa(length=100):
    """Parametrized SOA whitebox generation."""
    angle = 70.0
    width_active = 30.0
    width = 2.0
    name = 'wb_shallow.soa_{}'.format(length)

    with nd.Cell(name=name, instantiate=False) as C:
        bb = bbbb.soa(length=length).put(0, 0, 0)
        bb.raise_pins(namesin=['a0'])

        #active
        paral = geom.parallelogram2(
            length=length,
            height=width_active,
            angle=angle,
            position=2,
            shift=(0 + 0.5 * width_active / tan(radians(angle)), 0))
        active = nd.Polygon(layer=50, points=paral).put(0, 0, 0)

        #pad
        rect = geom.rectangle(length=length,
                              height=200,
                              position=2,
                              shift=(0, 30))
        metal = nd.Polygon(layer=10, points=rect).put(0, 0, 0)

        #waveguide
        nd.strt(width=3, length=length, xs='wb_soa').put(0, 0, 0)

    return C
예제 #16
0
    def cell(length=length, width=width):
        """Create a DCpad_lw cell.

        Args:
            length (float): length of the pad in um
            width (float): width of the pad in um

        Returns:
            Cell: dcpad element
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            C.default_pins('c0','c0')
            buf = 10
            bb_width = width + buf
            bb_length = length + buf
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='electrical').\
                put(0.5*bb_length, 0, 180)
            pdk.put_stub('c0', length=pinwidth['c0'], shape='circle')
            pdk.put_boundingbox('org', bb_length, bb_width)

            for lay, grow, acc in nd.layeriter(xs['c0']):
                pad = nd.geom.rounded_rect(
                    length=length+grow, height=width, position=5)
                nd.Polygon(layer=lay, points=pad).\
                    put(C.pin['c0'])
        return C
예제 #17
0
    def cell(length=length, pitch=pitch, metal=metal):
        """Create a DBR cell.

        Args:
            length (float):
            pitch (float):

        Returns:
            Cell
        """
        duty_cycle = 0.5
        if metal:
            contact = 1
        else:
            contact = 0
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            pdk.addBBmap(name, params=(length, pitch, duty_cycle, contact))
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0']).put(0, 0, 180)
            nd.Pin(name='b0', xs=xs['b0'], width=pinwidth['b0']).put(length)
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0']).put(0.5*length, 0, 90)

            pdk.put_stub(['a0', 'b0', 'c0'])
            pdk.put_boundingbox('org', length, width)

            if icon:
                icon(length, width).put(0)
        return C
예제 #18
0
    def icon_grating(length=100, width=20, bufx=None, bufy=None):
        """Create an icon for a grating.

        Args:
            length (float): length of the grating icon
            width (float): width of the grating icon

        Returns:
            Cell: grating icon
        """
        length, width, bufx, bufy = calc_buf(length, width, bufx, bufy)
        Nmin = 3
        h = width
        w = 0.4 * width

        if length < 2 * Nmin * w:
            w = length / 6
            N = 3
        else:
            N = int(length / (2 * w))

        with nd.Cell('icon', instantiate=False) as icon:
            t, u, v = w / 4, w / 2, h / 2
            cross = [(u, t), (u, v), (-u, v), (-u, t), (-w, t), (-w, -t),
                     (-u, -t), (-u, -v), (u, -v), (u, -t), (w, -t), (w, t)]
            for i in range(N):
                nd.Polygon(points=cross, layer=layer).put(0 + i * w * 2)

            nd.Pin('cc').put((N - 1) * w)
        return icon
예제 #19
0
 def icon_pad(length, width, bufx=bufx, bufy=bufy):
     length, width, bufx, bufy = calc_buf(length, width, bufx, bufy)
     with nd.Cell('icon', instantiate=False) as icon:
         pad = geom.rounded_rect(length=length, height=width, position=5)
         nd.Polygon(layer=layer, points=pad).put(0)
         nd.Pin('cc').put(0)
     return icon
예제 #20
0
def xsection_transition(length, width, layer1, layer2):
    with nd.Cell('icon', instantiate=False) as icon:
        rect = geom.box(0.25 * length, 0.50 * width)
        nd.Polygon(points=rect, layer=layer1).put(0.25 * length)
        nd.Polygon(points=rect, layer=layer2).put(0.50 * length)
        nd.Pin('cc').put(0.5 * length)
    return icon
예제 #21
0
def icon_strt(length, width, layer, bufx=None, bufy=None):
    length, width, bufx, bufy = calc_buf(length, width, bufx, bufy)
    with nd.Cell('icon', instantiate=False) as icon:
        rect = geom.box(length, width)
        nd.Polygon(points=rect, layer=layer).put(0)
        nd.Pin('cc').put(0.5 * length)
    return icon
예제 #22
0
    def cell(length=length):
        """Create a photodetector RF cell.

        Returns:
            Cell
        """
        cshift = 0
        with nd.Cell(hashme=True) as C:
            C.default_pins('a0', 'a0')
            C.groupname = groupname
            C.foundry_spt = []
            pdk.addBBmap(name)
            nd.Pin(name='a0', xs=xs['a0'], width=pinwidth['a0'], remark='optical').\
                put(0, 0, 180)
            nd.Pin(name='c0', xs=xs['c0'], width=pinwidth['c0'], remark='gnd').\
                put(length, cshift-spaceGS-pinwidth['c0'])
            nd.Pin(name='c1', xs=xs['c1'], width=pinwidth['c1'], remark='signal').\
                put(length, cshift)
            nd.Pin(name='c2', xs=xs['c2'], width=pinwidth['c2'], remark='gnd').\
                put(length, cshift+spaceGS+pinwidth['c2'])

            pdk.put_stub(['a0'])
            pdk.put_boundingbox('org', length, width)
            if icon:
                icon(length, width).put(0)
            pdk.put_stub(['c0', 'c1', 'c2'])
        return C
예제 #23
0
    def icon_mmi(length=None, width=None, bufx=None, bufy=None):
        length, width, bufx, bufy = calc_buf(length, width, bufx, bufy)

        Nin0 = 0.5 * (Nin - 1)
        Nout0 = 0.5 * (Nout - 1)
        w_mmi = scale_width * width
        w_in = w_mmi / (2.0 * max(Nin + 0.5, Nout + 0.5))
        w_pitch = 2 * w_in
        l_in = w_in

        p = []  # list of points (x, y)
        p.append((bufx + l_in, -0.5 * w_mmi))  #bottom left
        for i in range(Nin):
            p.append((bufx + l_in, (-Nin0 + i) * w_pitch - 0.5 * w_in))
            p.append((bufx, (-Nin0 + i) * w_pitch - 0.5 * w_in))
            p.append((bufx, (-Nin0 + i) * w_pitch + 0.5 * w_in))
            p.append((bufx + l_in, (-Nin0 + i) * w_pitch + 0.5 * w_in))
        p.append((bufx + l_in, +0.5 * w_mmi))
        p.append((bufx + length - l_in, +0.5 * w_mmi))
        for i in range(Nout - 1, -1, -1):
            p.append(
                (bufx + length - l_in, (-Nout0 + i) * w_pitch + 0.5 * w_in))
            p.append((bufx + length, (-Nout0 + i) * w_pitch + 0.5 * w_in))
            p.append((bufx + length, (-Nout0 + i) * w_pitch - 0.5 * w_in))
            p.append(
                (bufx + length - l_in, (-Nout0 + i) * w_pitch - 0.5 * w_in))
        p.append((bufx + length - l_in, -0.5 * w_mmi))

        with nd.Cell('icon', instantiate=False) as icon:
            nd.Polygon(points=p, layer=layer).put(0)
            nd.Pin('cc').put(0.5 * length)
        return icon
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
예제 #25
0
    def cell(length=length, pads=pads):
        """Create a SOA cell.

        Args:
            length (float): SOA length in um

        Returns:
            Cell; SOA element
        """
        nonlocal width
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            pdk.addBBmap(name, params=(length))
            nd.Pin(name='a0', xs=xs['a0'],
                   width=pinwidth['a0']).put(0, dy_io, 180)
            nd.Pin(name='b0', xs=xs['b0'],
                   width=pinwidth['b0']).put(length, dy_io, 0)
            nd.Pin(name='c0', xs=xs['c0'],
                   width=pinwidth['c0']).put(length / 2, dy_io, 90)

            if pads:
                bb_width = padwidth
            else:
                bb_width = width

            pdk.put_stub(['a0', 'b0', 'c0'])
            pdk.put_boundingbox('org', length, bb_width, align='lb')
            if icon:
                icon(length, bb_width).put(0, 0, 180, 'lc')
            cfg.cp = C.pin['b0']
        return C
예제 #26
0
def yjunction(radius=20, angle=45):
    with nd.Cell('y_junction') as yj:
        b1 = ic1.bend(angle=angle, radius=radius, xs='xs1').put(0, 0, 0)
        b2 = ic1.bend(angle=-angle, radius=radius, xs='xs1').put(0, 0, 0)
        nd.Pin(name='a0').put(b1.pin['a0'])
        nd.Pin(name='b0').put(b1.pin['b0'])
        nd.Pin(name='b1').put(b2.pin['b0'])
    return yj
예제 #27
0
def marker2(layera=1, layerb=None, layerc=None):

    """TU/e-Smart alignment marker 2.

    This is the second (marker2) of two matching markers.

    Args:
        layera (int | str | tuple): layer (or list of layers) in which
            marker pattern is written. Default 1.
        layerb (int | str | tuple): layer (or list of layers) in which the
            background is defined. Default None.
        layerc (int | str | tuple): layer (or list of layers) in which an
            extra box around the marker is drawn for visibility in dark
            field masks. Default None.

    Returns:
        function: function generating a cell with this specific marker.

    Example:
        Place marker centered at (0,0) in layer 5 with darkfield box::

            import nazca as nd

            m2 = nd.marker2(layera=5, layerc=5)
            m2.put()

            nd.export_plt()
    """
    with nd.Cell(name='marker2_'+nd.md5((layera,layerb,layerc))) as C:
        poly = (((-55,-75), (-55,-55), (-75,-55), (-75,55),
            (-55,55), (-55,75), (-5,75), (-5,55), (-40,55),
            (-40,40), (-55,40), (-55,30), (-40,30), (-40,15),
            (-30,15), (-30,30), (-15,30), (-15,40), (-30,40),
            (-30,55), (-5,55), (-5,-16), (-39,-16), (-39,-31),
            (-54,-31), (-54,-39), (-39,-39), (-39,-54), (-31,-54),
            (-31,-39), (-16,-39), (-16,-31), (-31,-31), (-31,-16),
            (-5,-16), (-5,-75),), ((30,15), (30,30), (15,30),
            (15,40), (30,40), (30,55), (40,55), (40,40), (55,40),
            (55,30), (40,30), (40,15),), ((31,-54), (31,-39),
            (16,-39), (16,-31), (31,-31), (31,-16), (39,-16),
            (39,-31), (54,-31), (54,-39), (39,-39), (39,-54),),
            ((55,-75), (55,-55), (75,-55), (75,-75),), ((55,55),
            (55,75), (75,75), (75,55),))
        nd.Pin(name='a0', xs=None).put(0,0,180)
        nd.Pin(name='b0', xs=None).put(0,0,0)
        for p in poly:
            for lay in nd.make_iter(layera):
                nd.Polygon(layer=lay, points=p).put()
        for lay in nd.make_iter(layerb):
            nd.Polygon(layer=lay,
                points=geom.rectangle(180, 180, position=5)).put()
        for lay in nd.make_iter(layerc):
            nd.Polygon(layer=lay,
                points=geom.frame(60, 240,240)).put(-90,-90)
    return C
예제 #28
0
    def icon_gsg(pitch=100, height=None):
        """Create an icon with a gsg diode symbol.

        The icon scales with the pitch and the height.

        Args:
            pitch (float): pitch beteween ground and signal
            height (float): height of the icon

        Returns:
            Cell: diode gsg icon
        """
        if height is None:
            height = 2 * pitch

        ratio = 0.3
        w_line = 0.1 * ratio * height
        radius = 0.15 * ratio * height
        height = height - 2 * radius - 2 * w_line

        with nd.Cell('icon_gsg', instantiate=False) as icon:
            # define shapes
            outline = [(-0.5 * ratio * height, 0.5 * ratio * height),
                       (0.5 * ratio * height, 0.5 * ratio * height),
                       (0, -0.5 * ratio * height)]
            diode_triangle = nd.Polygon(points=outline, layer=layer)

            outline = geom.rectangle(ratio * height, w_line, position=5)
            diode_base = nd.Polygon(points=outline, layer=layer)

            outline = geom.ring(radius=radius, width=w_line, N=20)
            ring = nd.Polygon(points=outline, layer=layer)

            outline = geom.rectangle(w_line, height, position=5)
            pole = nd.Polygon(points=outline, layer=layer)

            outline = geom.rectangle(2 * pitch, w_line, position=5)
            gnd = nd.Polygon(points=outline, layer=layer)

            # put shapes
            gnd.put(0, -0.5 * (height - w_line))
            diode_triangle.put(0)
            diode_base.put(0, -0.5 * ratio * (height - w_line))
            pole.put(0)
            pole.put(pitch - 0.5 * w_line)
            pole.put(-pitch + 0.5 * w_line)
            ringpos = 0.5 * (height + radius + w_line)
            ring.put(0, ringpos)
            ring.put(pitch - 0.5 * w_line, ringpos)
            ring.put(-pitch + 0.5 * w_line, ringpos)

            # add pins
            nd.Pin('cc').put(0)
            nd.Pin('top').put(0, ringpos + radius + w_line, -90)
        return icon
    def cell(length=length, contacts=contacts):
        """Create an electro-optical phase modulator (EOPM) cell.

        Their can be from 0 up to <contacts> contac points.
        They will be equidistantly spaced along the modulator.

        Args:
            length (float): length of the EOPM.
            contacts (int): number of contact
            pads (bool): draw pads

        Returns:
            Cell: eopm
        """
        with nd.Cell(hashme=True) as C:
            C.groupname = groupname
            pdk.addBBmap(name, params=(length))

            # modulator section:
            nd.Pin(name='a0',
                   xs=xs['a0'],
                   width=pinwidth['a0'],
                   remark='optical').put(0, 0, 180)
            nd.Pin(name='b0',
                   xs=xs['b0'],
                   width=pinwidth['b0'],
                   remark='optical').put(length)

            # x-positions of pads:
            L = 0.5 * (length - pinwidth['c0'])
            xpos = []
            if contacts > 1:
                for n in range(contacts):
                    xpos.append(0.5 * pinwidth['c0'] + L * 2 * n /
                                (contacts - 1))
            elif contacts == 1:
                xpos = [0.5 * length]
            elif contacts == 0:
                pass

            for n, x in enumerate(xpos):
                pinname = 'c' + str(n)
                p1 = nd.Pin(name=pinname, xs=xs['c0'], width=pinwidth['c0']).\
                    put(x, 0, 90)
                nd.put_stub(pinname)

            pdk.put_stub(['a0', 'b0'])
            pdk.put_boundingbox('org', length, width)

            if icon:
                icon(length, width).put(0)

            cfg.cp = C.pin['b0']
        return C
예제 #30
0
def marker1(layera=1, layerb=None):
    """TU/e-Smart alignment marker 1.

    This is the first (marker1) of two matching markers.

    Args:
        layera (int | str | tuple): layer (or list of layers) in which
            marker pattern is written.
        layerb (int | str | tuple): layer (or list of layers) in which the
            background is defined.

    Returns:
        function: marker cell.

    Example:
        Place marker centered at (0,0) in layer 1 with background layer 12::

            import nazca as nd

            m1 = nd.marker1(layera=1, layerb=12)
            m1.put()

            nd.export_plt()
    """
    with nd.Cell(name='marker1_'+nd.md5((layera,layerb))) as C:
        poly = (((-75,55), (-75,75), (75,75), (75,55), (65,55),
            (65,65), (-65,65), (-65,55),), ((-37.5,17.5),
                (-37.5,32.5), (-52.5,32.5), (-52.5,37.5),
                (-37.5,37.5), (-37.5,52.5), (-32.5,52.5),
                (-32.5,37.5), (-17.5,37.5), (-17.5,32.5),
                (-32.5,32.5), (-32.5,17.5),), ((32.5,17.5),
                (32.5,32.5), (17.5,32.5), (17.5,37.5), (32.5,37.5),
                (32.5,52.5), (37.5,52.5), (37.5,37.5), (52.5,37.5),
                (52.5,32.5), (37.5,32.5), (37.5,17.5),),
                ((-38.5,-53.5), (-38.5,-38.5), (-53.5,-38.5),
                (-53.5,-31.5), (-38.5,-31.5), (-38.5,-16.5),
                (-31.5,-16.5), (-31.5,-31.5), (-16.5,-31.5),
                (-16.5,-38.5), (-31.5,-38.5), (-31.5,-53.5),),
                ((31.5,-53.5), (31.5,-38.5), (16.5,-38.5),
                (16.5,-31.5), (31.5,-31.5), (31.5,-16.5),
                (38.5,-16.5), (38.5,-31.5), (53.5,-31.5),
                (53.5,-38.5), (38.5,-38.5), (38.5,-53.5),),
                ((-75,-75), (-75,-55), (-65,-55), (-65,-65),
                (65,-65), (65,-55), (75,-55), (75,-75),))
        nd.Pin(name='a0', xs=None).put(0,0,180)
        nd.Pin(name='b0', xs=None).put(0,0,0)
        for p in poly:
            for lay in nd.make_iter(layera):
                nd.Polygon(layer=lay, points=p).put()
        for lay in nd.make_iter(layerb):
            nd.Polygon(layer=lay,
                points=geom.rectangle(180, 180, position=5)).put()
    return C