Exemplo n.º 1
0
def align_TE_on_via():

    cell = dl.Device("Align TE on VIA")

    circle = pg.circle(radius=50, layer=pt.LayoutDefault.layerVias)

    cross = pg.cross(width=30, length=250, layer=pt.LayoutDefault.layerVias)

    g = Group([circle, cross])

    g.align(alignment='x')
    g.align(alignment='y')
    circle.add(cross)

    viapattern = pg.union(circle, 'A+B', layer=pt.LayoutDefault.layerVias)

    TEpattern = pg.union(circle, 'A+B',
                         layer=pt.LayoutDefault.layerTop).copy('tmp',
                                                               scale=0.8)

    cell.add(viapattern)
    cell.add(TEpattern)

    cell.align(alignment='x')
    cell.align(alignment='y')

    cell.flatten()

    return cell
Exemplo n.º 2
0
def mask_names(
        names=("Bottom Electrode", "Top Electrode", "Via Layer", "Etch Layer",
               "PartialEtch Layer", "Pad Layer"),
        layers=(pt.LayoutDefault.layerBottom, pt.LayoutDefault.layerTop,
                pt.LayoutDefault.layerVias, pt.LayoutDefault.layerEtch,
                pt.LayoutDefault.layerPartialEtch, pt.LayoutDefault.layerPad),
        size=250):
    """ Prints array of strings on different layers.

        Mostly useful for Layer Sorting on masks.

        Parameters
        ----------
            names : iterable of str

            layers : iterable of int

            size : float

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

    text = pc.Text()

    text['Size'] = size

    if not len(names) == len(layers):

        raise ValueError("Unbalanced mask names/layers combo")

    else:

        text_cells = []

        for label, layer in zip(names, layers):

            text['Label'] = label

            text['Layer'] = (layer, )

            text_cells.append(text.draw())

        g = Group(text_cells)

        g.distribute(direction='x', spacing=size)

        cell_name = Device(name='Mask Names')

        for x in text_cells:

            cell_name.absorb(cell_name << x)

        return cell_name
Exemplo n.º 3
0
def load_gds(cells):

    if isinstance(cells, str):

        cells = pathlib.Path(cells)

    elif isinstance(cells, list) or isinstance(cells, tuple):

        cells_logo = []

        for p in cells:

            if isinstance(p, str):

                # import pdb ; pdb.set_trace()

                cells_logo.append(pg.import_gds(p))

            elif isinstance(p, pathlib.Path):

                cells_logo.append(pg.import_gds(str(p.absolute())))

    g = Group(cells_logo)

    g.distribute(direction='x', spacing=150)

    g.align(alignment='y')

    logo_cell = dl.Device(name="cells")

    for c in cells_logo:

        logo_cell.add(c)

    logo_cell.flatten()

    logo_cell.name = 'Logos'

    return logo_cell
Exemplo n.º 4
0
def add_utility_cell(cell,
                     align_scale=[0.25, 0.5, 1],
                     position=['top', 'left']):

    align_mark = alignment_marks_4layers(scale=align_scale)

    test_cell = resistivity_test_cell()

    align_via = Device('Align_Via')

    maskname_cell = mask_names()

    align_via.add_array(align_TE_on_via(), rows=3, columns=1, spacing=(0, 350))

    align_via.flatten()

    g = Group([align_via, align_mark, test_cell])

    g.distribute(direction='x', spacing=100)

    g.align(alignment='y')

    g.move(origin=(g.center[0], g.ymax),
           destination=(cell.center[0], cell.ymax - 300))

    maskname_cell.move(origin=(maskname_cell.x, maskname_cell.ymin),
                       destination=(g.x, test_cell.ymax + 150))

    utility_cell = Device(name="UtilityCell")

    if isinstance(position, str):

        position = [position]

    if 'top' in position:

        utility_cell << align_mark
        utility_cell << align_via
        utility_cell << test_cell
        utility_cell << maskname_cell

    if 'left' in position:

        t2 = utility_cell << align_mark
        t3 = utility_cell << align_via
        g = Group(t2, t3)

        g.rotate(angle=90, center=(t2.xmin, t2.ymin))

        g.move(origin=(t2.xmin,t2.center[1]),\
            destination=(cell.xmin,cell.center[1]))

    cell << utility_cell
Exemplo n.º 5
0
def alignment_marks_4layers(scale=[0.2, 0.5, 1]):
    def dr(cell):

        return DeviceReference(cell)

    BElayer = pt.LayoutDefault.layerBottom
    TElayer = pt.LayoutDefault.layerTop
    VIAlayer = pt.LayoutDefault.layerVias
    ETCHlayer = pt.LayoutDefault.layerEtch
    PETCHlayer = pt.LayoutDefault.layerPartialEtch
    Zerolayer = pt.LayoutDefault.layerPad

    align1 = verniers(scale,
                      layers=[BElayer, VIAlayer],
                      label='VIA',
                      reversed=True)
    align_ph = pg.bbox(align1.bbox)  #only for space
    align2 = verniers(scale, layers=[BElayer, TElayer], label='TE')
    align3 = verniers(scale, layers=[BElayer, ETCHlayer], label='ETCH')
    align4 = verniers(scale, layers=[BElayer, PETCHlayer], label='PETCH')

    text = pc.Text()
    text.size = 300
    text.layer = (BElayer, TElayer, ETCHlayer, PETCHlayer, VIAlayer)
    text.label = "Align to BE"

    t1 = text.draw()

    g = Group([align1, dr(align_ph), align2, align3, align4, t1])
    g.distribute(direction='x', spacing=150)
    g.align(alignment='y')

    align5 = verniers(scale,
                      layers=[TElayer, VIAlayer],
                      label='VIA',
                      reversed=True)
    align6 = verniers(scale, layers=[TElayer, ETCHlayer], label='ETCH')
    align7 = verniers(scale, layers=[TElayer, PETCHlayer], label='PETCH')

    text.layer = (TElayer, ETCHlayer, PETCHlayer, VIAlayer)
    text.label = 'Align to TE'
    t2 = text.draw()

    g2 = Group([align5, dr(align_ph), dr(align_ph), align6, align7, t2])
    g2.distribute(direction='x', spacing=150)
    g2.align(alignment='y')

    align8 = verniers(scale,
                      layers=[Zerolayer, VIAlayer],
                      label='VIA',
                      reversed=True)
    align9 = verniers(scale, layers=[Zerolayer, BElayer], label='BE')
    align10 = verniers(scale, layers=[Zerolayer, TElayer], label='TE')
    align11 = verniers(scale, layers=[Zerolayer, ETCHlayer], label='ETCH')
    align12 = verniers(scale, layers=[Zerolayer, PETCHlayer], label='PETCH')

    text.layer = (Zerolayer, BElayer, TElayer, ETCHlayer, PETCHlayer, VIAlayer)
    text.label = "Align to Pad"

    t3 = text.draw()

    g3 = Group([align8, align9, align10, align11, align12, t3])
    g3.distribute(direction='x', spacing=150)
    g3.align(alignment='y')

    g_tot = Group([g, g2, g3])
    g_tot.distribute(direction='y', spacing=150)
    g_tot.align(alignment='xmin')

    cell = Device("Alignments")

    for c in [align1, align2, align3, align4, t1]:

        cell.add(c)

    for c in [align5, align6, align7, t2]:
        cell.add(c)

    for c in [align8, align9, align10, align11, align12, t3]:
        cell.add(c)

    return cell
Exemplo n.º 6
0
    def draw(self):

        device = self.device

        df_original = device.get_params()

        master_name = self.name

        master_cell = Device(master_name)

        cells = list()

        top_label_matrix = self.labels_top

        bottom_label_matrix = self.labels_bottom

        y_param = self.y_param

        x_param = self.x_param

        df = {}

        dlist = []

        for index in range(len(y_param)):

            for name, value in zip(y_param.names, y_param.values):

                df[name] = value[index]

            device._set_params(df)

            # print("drawing array {} of {}".format(index+1,len(y_param)),end='\r')

            if top_label_matrix is not None:

                if isinstance(top_label_matrix[index], list):

                    if len(top_label_matrix[index]) == len(self.x_param):

                        self.labels_top = top_label_matrix[index]

                    else:

                        self.labels_top = None

                else:

                    self.labels_top = None

            if bottom_label_matrix is not None:

                if isinstance(bottom_label_matrix[index], list):

                    if len(bottom_label_matrix[index]) == len(self.x_param):

                        self.labels_bottom = bottom_label_matrix[index]

                    else:

                        self.labels_bottom = None

                else:

                    self.labels_bottom = None

            self.name = master_name + "Arr" + str(index + 1)

            new_cell = PArray.draw(self)

            dlist.extend(new_cell.references)

            print("\033[K", end='')

            master_cell << new_cell

            cells.append(new_cell)

        device._set_params(df_original)

        self.labels_top = top_label_matrix

        self.labels_bottom = bottom_label_matrix

        self.name = master_name

        if not self._pack:

            g = Group(cells)

            g.distribute(direction='y', spacing=self.y_spacing)

            g.align(alignment='x')

            return master_cell

        else:

            dlist_new = []

            for d in dlist:

                dlist_new.append(pg.deepcopy(d.parent))

            return pg.packer(dlist_new,
                             aspect_ratio=(2, 1),
                             spacing=max(self.x_spacing, self.y_spacing))
Exemplo n.º 7
0
    def draw(self):

        device = self.device

        df_original = device.get_params()

        master_cell = Device(name=self.name)

        cells = []

        param = self.x_param

        df = {}

        for index in range(len(param)):

            for name, value in zip(param.names, param.values):

                df[name] = value[index]

            device.set_params(df)

            if self.base_params:

                device.set_params(self.base_params)

            new_cell = st.join(device.draw())

            new_cell.name = self.name + "_" + str(index + 1)

            if self.labels_top is not None:

                self.text.label = self.labels_top[index]

                self.text.add_to_cell(new_cell,
                                      anchor_source='s',
                                      anchor_dest='n',
                                      offset=(0, 0.02))

            if self.labels_bottom is not None:

                self.text.label = self.labels_bottom[index]

                self.text.add_to_cell(new_cell,
                                      anchor_source='n',
                                      anchor_dest='s',
                                      offset=(0, -0.02))

            master_cell << new_cell

            cells.append(new_cell)

        g = Group(cells)

        g.distribute(spacing=self.x_spacing)

        g.align(alignment='ymin')

        device.set_params(df_original)

        del device, cells, g

        return master_cell
Exemplo n.º 8
0
def grid(
    components: Tuple[ComponentOrFactory, ...],
    spacing: Tuple[float, float] = (5.0, 5.0),
    separation: bool = True,
    shape: Tuple[int, int] = None,
    align_x: str = "x",
    align_y: str = "y",
    edge_x: str = "x",
    edge_y: str = "ymax",
) -> Component:
    """Returns a component with a 1D or 2D grid of components

    Adapted from phid.geometry

    Args:
        components: Iterable to be placed onto a grid. (can be 1D or 2D)
        spacing: between adjacent elements on the grid, can be a tuple for
          different distances in height and width.
        separation: If True, guarantees elements are speparated with fixed spacing
          if False, elements are spaced evenly along a grid.
        shape: x, y shape of the grid (see np.reshape).
          If no shape and the list is 1D, if np.reshape were run with (1, -1).
        align_x: {'x', 'xmin', 'xmax'}
          edge to perform the x (column) alignment along
        align_y: {'y', 'ymin', 'ymax'}
          edge to perform the y (row) alignment along
        edge_x: {'x', 'xmin', 'xmax'}
          Which edge to perform the x (column) distribution (ignored if separation = True)
        edge_y: {'y', 'ymin', 'ymax'}
          edge to perform the y (row) distribution along (ignored if separation = True)

    Returns:
        Component containing all the components in a grid.
    """

    device_array = np.asarray(components)
    # Check arguments
    if device_array.ndim not in (1, 2):
        raise ValueError("[PHIDL] grid() The components needs to be 1D or 2D.")
    if shape is not None and len(shape) != 2:
        raise ValueError("[PHIDL] grid() shape argument must be None or" +
                         " have a length of 2, for example shape=(4,6)")

    # Check that shape is valid and reshape array if needed
    if (shape is None) and (device_array.ndim
                            == 2):  # Already in desired shape
        shape = device_array.shape
    elif (shape is None) and (device_array.ndim == 1):
        shape = (device_array.size, -1)
    elif 0 < shape[0] * shape[1] < device_array.size:
        raise ValueError(
            "[PHIDL] grid() The shape is too small for all the items in components"
        )
    else:
        if np.min(shape) == -1:
            remainder = np.max(shape) - device_array.size % np.max(shape)
        else:
            remainder = shape[0] * shape[1] - device_array.size
        if remainder != 0:
            device_array = np.append(
                device_array,
                [
                    None,
                ] * remainder,
            )
    device_array = np.reshape(device_array, shape)

    D = Component("grid")
    ref_array = np.empty(device_array.shape, dtype=object)
    dummy = Component()
    for idx, d in np.ndenumerate(device_array):
        if d is not None:
            d = d() if callable(d) else d
            ref_array[idx] = D << d
        else:
            ref_array[idx] = D << dummy  # Create dummy devices
        D.aliases[idx] = ref_array[idx]

    rows = [Group(ref_array[n, :]) for n in range(ref_array.shape[0])]
    cols = [Group(ref_array[:, n]) for n in range(ref_array.shape[1])]

    # Align rows and columns independently
    for r in rows:
        r.align(alignment=align_y)
    for c in cols:
        c.align(alignment=align_x)

    # Distribute rows and columns
    Group(cols).distribute(direction="x",
                           spacing=spacing[0],
                           separation=separation,
                           edge=edge_x)
    Group(rows[::-1]).distribute(direction="y",
                                 spacing=spacing[1],
                                 separation=separation,
                                 edge=edge_y)

    return D
Exemplo n.º 9
0
    def draw(self):

        device=self.device

        df_original=device.export_params()

        master_name=self.name

        master_cell=Device(master_name)

        cells=list()

        top_label_matrix=self.labels_top

        bottom_label_matrix=self.labels_bottom

        y_param=self.y_param

        x_param=self.x_param

        df={}

        for key in df_original.keys():

            if callable(df_original[key]):

                df.update({key:df_original[key]})

        for index in range(len(y_param)):

            for name,value in zip(y_param.names,y_param.values):

                df[name]=value[index]

            device.import_params(df)

            print("drawing array {} of {}".format(index+1,len(y_param)),end='\r')

            if top_label_matrix is not None:

                if isinstance(top_label_matrix[index],list):

                    if len(top_label_matrix[index])==len(self.x_param):

                        self.labels_top=top_label_matrix[index]

                    else:

                        self.labels_top=None

                else:

                    self.labels_top=None

            if bottom_label_matrix is not None:

                if isinstance(bottom_label_matrix[index],list):

                    if len(bottom_label_matrix[index])==len(self.x_param):

                        self.labels_bottom=bottom_label_matrix[index]

                    else:

                        self.labels_bottom=None

                else:

                    self.labels_bottom=None

            self.name=master_name+"Arr"+str(index+1)

            new_cell=PArray.draw(self)

            print("\033[K",end='')

            master_cell<<new_cell

            cells.append(new_cell)

        g=Group(cells)

        g.distribute(direction='y',spacing=self.y_spacing)

        g.align(alignment='x')

        device.import_params(df_original)

        del device, cells ,g

        self.labels_top=top_label_matrix

        self.labels_bottom=bottom_label_matrix

        self.name=master_name

        return master_cell
Exemplo n.º 10
0
    def draw(self):

        device=self.device

        df_original=device.export_params()

        master_cell=Device(name=self.name)

        cells=list()

        param=self.x_param

        df={}

        for key,val in df_original.items():

            if callable(val):

                df[key]=val

        for index in range(len(param)):

            for name,value in zip(param.names,param.values):

                df[name]=value[index]

            device.import_params(df)

            # print("drawing device {} of {}".format(index+1,len(param)),end="\r")

            new_cell=Device()
            new_cell.absorb(new_cell<<device.draw())
            new_cell=join(new_cell)

            master_cell<<new_cell

            new_cell.name=self.name+"_"+str(index+1)

            if self.labels_top is not None:

                self.text_params.set('location','top')

                self.text_params.add_text(new_cell,self.labels_top[index])

            if self.labels_bottom is not None:

                self.text_params.set('location','bottom')

                self.text_params.add_text(new_cell,self.labels_bottom[index])

            cells.append(new_cell)

        g=Group(cells)

        g.distribute(spacing=self.x_spacing)

        g.align(alignment='ymin')

        device.import_params(df_original)

        del device, cells ,g

        return master_cell