Beispiel #1
0
        num_lines = 20,
        line_width = 0.4,
        diameter = 20,
        layer = 0
        )
qp(D) # quickplot the geometry
create_image(D, 'litho_star')

# example-litho_calipers
import phidl.geometry as pg
from phidl import quickplot as qp

D = pg.litho_calipers(
        notch_size = [1,5],
        notch_spacing = 2,
        num_notches = 7,
        offset_per_notch = 0.1,
        row_spacing = 0,
        layer1 = 1,
        layer2 = 2)
qp(D) # quickplot the geometry
create_image(D, 'litho_calipers')

# example-extract
import phidl.geometry as pg
from phidl import quickplot as qp
from phidl import Device

E = Device()
E.add_ref(pg.ellipse(layer = {0,1}))
#X = pg.ellipse(layer = {0,1})
D = pg.extract(E, layers = [0,1])
# experimental and may change with time.

# Let's save this file so we can practice importing it in the next step
D.write_gds('MyNewGDS.gds')

#==============================================================================
# Premade geometry: Lithography shapes
#==============================================================================
# PHIDL comes with a set of handy functions for creating standard lithographic
# test structures, such as calipers (for detecting fabrication-layer-offsets),
# stars, and positive + negative-tone steps
D = Device()
d1 = D << pg.litho_calipers(notch_size=[3, 10],
                            notch_spacing=2,
                            num_notches=7,
                            offset_per_notch=0.2,
                            row_spacing=0,
                            layer1=1,
                            layer2=2).rotate(90)
d2 = D << pg.litho_steps(
    line_widths=[1, 2, 4, 8, 16
                 ], line_spacing=10, height=80, layer=0).movex(80)
d3 = D << pg.litho_star(num_lines=16, line_width=3, diameter=80,
                        layer=4).movex(240)
d1.y = d2.y = d3.y
qp(D)
D.write_gds('LithographyTestStructuresMetrics.gds')

#==============================================================================
# Importing GDS files
#==============================================================================
Beispiel #3
0
def verniers(scale=[1, 0.5, 0.1],
             layers=[1, 2],
             label='TE',
             text_size=20,
             reversed=False):
    """ Create a cell with vernier aligners.

    Parameters
    ----------
        scale : iterable of float (default [1,0.5,0.25])
            each float in list is the offset of a vernier.
            for each of them a vernier will be created in the X-Y axis

        layers : 2-len iterable of int (default [1,2])
            define the two layers for the verniers.

        label : str (default "TE")

            add a label to the set of verniers.

        text_size : float (default)

            label size

        reversed : boolean

            if true, creates a negative alignment mark for the second layer

    Returns
    -------
        cell : phidl.Device.
    """

    cell = dl.Device(name="verniers")

    import numpy

    if not isinstance(scale, numpy.ndarray):

        scale = np.array(scale)

    scale = np.sort(scale)

    xvern = []

    for dim in scale:

        notch_size = [dim * 5, dim * 25]
        notch_spacing = dim * 10
        num_notches = 5
        notch_offset = dim
        row_spacing = 0
        layer1 = layers[0]
        layer2 = layers[1]

        cal=pg.litho_calipers(\
            notch_size,\
            notch_spacing,\
            num_notches,\
            notch_offset,\
            row_spacing,\
            layer1,\
            layer2)

        cal.flatten()

        if reversed:

            tobedel = cal.get_polygons(by_spec=(layer2, 0))

            cal = cal.remove_polygons(
                lambda pts, layer, datatype: layer == layer2)

            replica = dl.Device()

            replica.add(gdspy.PolygonSet(tobedel, layer=layer2))

            frame = dl.Device()

            frame.add(pg.bbox(replica.bbox, layer=layer2))

            frame_ext = dl.Device()

            frame_ext.add(
                gdspy.PolygonSet(frame.copy('tmp', scale=1.5).get_polygons(),
                                 layer=layer2))

            frame_ext.flatten()

            frame_ext.move(origin=frame_ext.center, destination=replica.center)

            new_cal = pg.boolean(replica, frame_ext, 'xor', layer=layer2)

            new_cal.rotate(angle=180,
                           center=(cal.xmin + cal.xsize / 2, cal.ymin))

            new_cal.move(destination=(0, -notch_size[1]))

            cal << new_cal

            cal.flatten()

        xvern.append(cal)

    g = dl.Group(xvern)

    g.distribute(direction='y', spacing=scale[-1] * 20)
    g.align(alignment='x')
    xcell = dl.Device(name="x")

    for x in xvern:

        xcell << x

    xcell = pt.join(xcell)

    vern_x = cell << xcell
    vern_y = cell << xcell

    vern_y.rotate(angle=-90)
    vern_y.move(origin=(vern_y.xmin,vern_y.y),\
        destination=(vern_x.x+scale[-1]*10,vern_x.ymin-scale[-1]*10))

    cell.absorb(vern_x)
    cell.absorb(vern_y)

    label = pg.text(text=label, size=text_size, layer=layers[0])

    label.move(destination=(cell.xmax - label.xsize / 2,
                            cell.ymax - 2 * label.ysize))

    overlabel = pg.bbox(label.bbox, layer=layers[1])

    overlabel_scaled = dl.Device().add(
        gdspy.PolygonSet(overlabel.copy('tmp', scale=2).get_polygons(),
                         layer=layers[1]))

    overlabel_scaled.move(origin=overlabel_scaled.center,\
        destination=label.center)

    cutlab = pg.boolean(label, overlabel_scaled, 'xor', layer=layers[1])

    cell << label
    cell << cutlab

    cell = pt.join(cell)

    return cell