Ejemplo n.º 1
0
        def _draw_padded_via(self):

            viaref=DeviceReference(self.via.draw())

            size=float(self.via.size*self.over_via)

            port=viaref.ports['conn']

            trace=pg.rectangle(size=(size,size),layer=self.pad_layers[0])

            trace.move(origin=trace.center,\
                destination=viaref.center)

            trace2=pg.copy_layer(trace,layer=self.pad_layers[0],new_layer=self.pad_layers[1])

            cell=Device(self.name)

            cell.absorb(cell<<trace)

            cell.absorb(cell<<trace2)

            cell.add(viaref)

            port.midpoint=(port.midpoint[0],cell.ymax)

            port.width=size

            cell.add_port(port)

            if bottom_conn==False:

                cell.remove_layers(layers=[self.pad_layers[1]])

            return cell
Ejemplo n.º 2
0
    def draw(self):
        ''' Generates layout cell based on current parameters.

        'conn' port is included in the cell.

        Returns
        -------
        cell : phidl.Device.
        '''
        o = self.origin

        pad=pg.rectangle(size=self.size.coord,\
        layer=self.layer).move(origin=(0,0),\
        destination=o.coord)

        cell = Device(self.name)

        r1 = cell << pad
        cell.absorb(r1)
        r2 = cell << pad

        r2.move(origin=o.coord,\
        destination=(o+self.distance).coord)

        cell.absorb(r2)

        cell.add_port(name='conn',\
        midpoint=(o+Point(self.size.x/2,self.size.y)).coord,\
        width=self.size.x,\
        orientation=90)

        del pad

        return cell
Ejemplo n.º 3
0
def check(device: Device, joined=False, blocking=True):
    ''' Shows the device layout.

        If run by terminal, blocks script until window is closed.

        Parameters
        ----------
            device : phidl.Device

            joined : boolean (optional, default False)

                if true, returns a flattened/joined version of device

    '''
    set_quickplot_options(blocking=blocking)

    if joined:

        cell = Device()
        cell.absorb(cell << device)
        cell.flatten()
        qp(join(cell))

    else:

        qp(device)
Ejemplo n.º 4
0
def add_vias(cell: Device,
             bbox,
             via: pt.LayoutPart,
             spacing: float = 0,
             tolerance: float = 0):
    ''' adds via pattern to cell with constraints.

    Parameters:
    -----------

    cell : Device
        where the vias will be located

    bbox : iterable
        x,y coordinates of box ll and ur to define vias patterns size

    via : pt.LayoutPart

    spacing : float

    tolerance : float (default 0)
        if not 0, used to determine via distance from target object border

    Returns:
    --------
    cell_out : Device
    '''

    bbox_cell = pg.bbox(bbox)

    nvias_x = int(np.floor(bbox_cell.xsize / (via.size + spacing)))

    nvias_y = int(np.floor(bbox_cell.ysize / (via.size + spacing)))

    if nvias_x == 0 or nvias_y == 0:

        return

    via_cell = pt.draw_array(via.draw(),
                             nvias_x,
                             nvias_y,
                             row_spacing=spacing,
                             column_spacing=spacing)

    via_cell.move(origin=(via_cell.x, via_cell.y),
                  destination=(bbox_cell.x, bbox_cell.y))

    tbr = []

    for elem in via_cell.references:

        if not pt.is_cell_inside(elem, cell, tolerance):

            tbr.append(elem)

    via_cell.remove(tbr)

    cell.absorb(cell.add_ref(via_cell, alias="Vias"))
Ejemplo n.º 5
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
Ejemplo n.º 6
0
        def draw(self):

            self._set_relations()

            device_cell=cls.draw(self)

            probe_cell=self.probe.draw()

            cell=Device(name=self.name)

            cell.add_ref(device_cell, alias="Device")

            self._add_signal_connection(cell,'bottom')

            probe_ref=cell.add_ref(probe_cell, alias="Probe")

            self._move_probe_ref(cell)

            self._setup_signal_routing(cell)

            cell.absorb(cell<<self._draw_signal_routing())

            try:

                self._setup_ground_routing(
                    cell,
                    'straight')

                routing_cell=self._draw_ground_routing()

            except:

                self._setup_ground_routing(
                    cell,
                    'side')

                try:

                    routing_cell=self._draw_ground_routing()

                except:

                    import pdb; pdb.set_trace()

                    self._draw_ground_routing()

            _add_default_ground_vias(self,routing_cell)

            cell.add_ref(routing_cell,alias=self.name+"GroundTrace")

            return cell
Ejemplo n.º 7
0
        def _draw_ground_routing(self):

            if isinstance(self.probe, pc.GSGProbe):

                routing_cell = Device()

                routing_cell.absorb(routing_cell << self.gndlefttrace.draw())

                routing_cell.absorb(routing_cell << self.gndrighttrace.draw())

                return pt.join(routing_cell)

            else:

                raise ValueError("To be implemented")
Ejemplo n.º 8
0
def attach_taper(cell : Device , port : Port , length : float , \
    width2 : float, layer=LayoutDefault.layerTop) :

    t = pg.taper(length=length, width1=port.width, width2=width2, layer=layer)

    t_ref = cell.add_ref(t)

    t_ref.connect(1, destination=port)

    new_port = t_ref.ports[2]

    new_port.name = port.name

    cell.absorb(t_ref)

    cell.remove(port)

    cell.add_port(new_port)
Ejemplo n.º 9
0
    def draw(self):
        ''' Generates layout cell based on current parameters.

        'top' and 'bottom' ports is included in the cell.

        Returns
        -------
        cell : phidl.Device.
        '''
        o = self.origin

        b_main = Bus()

        b_main.origin = o

        b_main.layer = self.layer

        b_main.size = Point(self.x, self.active_area.y)

        b_main.distance = Point(self.active_area.x + self.x, 0)

        main_etch = b_main.draw()

        etch = Device(self.name)

        etch.absorb(etch << main_etch)

        port_up=Port('top',\
        midpoint=(o+Point(self.x+self.active_area.x/2,self.active_area.y)).coord,\
        width=self.active_area.x,\
        orientation=-90)

        port_down=Port('bottom',\
        midpoint=(o+Point(self.x+self.active_area.x/2,0)).coord,\
        width=self.active_area.x,\
        orientation=90)

        etch.add_port(port_up)
        etch.add_port(port_down)

        del main_etch

        return etch
Ejemplo n.º 10
0
    def _draw_unit_cell(self):

        o = self.origin

        rect=pg.rectangle(size=(self.coverage*self.pitch,self.length),\
            layer=self.layer)

        rect.move(origin=(0, 0), destination=o.coord)

        unitcell = Device()

        r1 = unitcell << rect

        unitcell.absorb(r1)

        r2 = unitcell << rect

        r2.move(origin=o.coord,\
        destination=(o+Point(self.pitch,self.y_offset)).coord)

        r3 = unitcell << rect

        r3.move(origin=o.coord,\
            destination=(o+Point(2*self.pitch,0)).coord)

        unitcell.absorb(r2)

        unitcell.absorb(r3)

        unitcell.name = "UnitCell"

        del rect

        return unitcell
Ejemplo n.º 11
0
        def draw(self):

            cell=Device()

            cell.name=self.name

            d_ref=cell.add_ref(cls.draw(self))

            for name,port in d_ref.ports.items():

                self.pad.port=port

                pad_ref=cell.add_ref(self.pad.draw())

                pad_ref.connect(pad_ref.ports['conn'],
                    destination=port)

                cell.absorb(pad_ref)

                cell.add_port(port,name)

            return cell
Ejemplo n.º 12
0
    def _draw_unit_cell(self):

        o = self.origin

        rect=pg.rectangle(size=(self.coverage*self.pitch,self.length),\
            layer=self.layer)

        rect.move(origin=(0, 0), destination=o.coord)

        unitcell = Device()

        r1 = unitcell << rect

        unitcell.absorb(r1)

        rect_partialetch=pg.rectangle(\
            size=(\
                (1-self.coverage)*self.pitch,self.length-self.y_offset),\
            layer=LayoutDefault.layerPartialEtch)

        rect_partialetch.move(origin=o.coord,\
            destination=(self.pitch*self.coverage,self.y_offset))

        rp1 = unitcell << rect_partialetch

        rp2 = unitcell << rect_partialetch

        rp2.move(destination=(self.pitch, 0))

        r2 = unitcell << rect

        r2.move(origin=o.coord,\
        destination=(o+Point(self.pitch,self.y_offset)).coord)

        r3 = unitcell << rect

        r3.move(origin=o.coord,\
            destination=(o+Point(2*self.pitch,0)).coord)

        unitcell.absorb(r2)

        unitcell.absorb(r3)

        unitcell.name = "UnitCell"

        del rect, rect_partialetch

        return unitcell
Ejemplo n.º 13
0
        def _draw_device_grounds(self, device_cell, probe_cell, label):

            output_cell = Device()

            lx_device_ports = []

            rx_device_ports = []

            gnd_ports = pt._find_ports(device_cell, 'Ground', depth=0)

            if not gnd_ports:

                return output_cell

            for p in gnd_ports:

                p_adj = Port(name=p.name,
                             midpoint=p.midpoint,
                             width=probe_cell['Port1'].size[1],
                             orientation=p.orientation)

                if "LX" in p.name:

                    lx_device_ports.append(p_adj)

                elif "RX" in p.name:

                    rx_device_ports.append(p_adj)

            r = pc.MultiRouting()

            r.layer = self.gndlefttrace.layer

            r.clearance = pt._bbox_to_tuple(self._bbox_mod(device_cell.bbox))

            r.trace_width = self.gnd_routing_width

            ## left connections

            if label == 'side':

                r.source = tuple(
                    pt._find_ports(probe_cell, 'GroundLXW', depth=0))

            elif label == 'straight':

                r.source = (probe_cell.ports['GroundLXN_1'], )

            r.destination = tuple(lx_device_ports)

            r.side = 'left'

            output_cell.absorb(output_cell << r.draw())

            ## right connections

            if label == 'side':

                r.source = tuple(
                    pt._find_ports(probe_cell, 'GroundRXE', depth=0))

            elif label == 'straight':

                r.source = (probe_cell.ports['GroundRXN_1'], )

            r.destination = tuple(rx_device_ports)

            r.side = 'right'

            output_cell.absorb(output_cell << r.draw())

            return output_cell
Ejemplo n.º 14
0
    def draw(self):
        ''' Generates layout cell based on current parameters.

        'conn' port is included in the cell.

        Returns
        -------
        cell : phidl.Device.
        '''

        self._check_anchor()

        o = self.origin

        anchor=pg.rectangle(\
            size=(self.size-Point(2*self.etch_margin.x,-2*self.etch_margin.y)).coord,\
            layer=self.layer)

        etch_size=Point(\
        (self.etch_x-self.size.x)/2,\
        self.size.y)

        offset = Point(self.x_offset, 0)

        cell = Device(self.name)

        etch_sx=pg.rectangle(\
            size=(etch_size-offset).coord,\
            layer=self.etch_layer)

        etch_dx=pg.rectangle(\
            size=(etch_size+offset).coord,\
            layer=self.etch_layer)

        etch_sx_ref=(cell<<etch_sx).move(origin=(0,0),\
        destination=(o-Point(0,self.etch_margin.y)).coord)

        anchor_transl = o + Point(etch_sx.size[0] + self.etch_margin.x,
                                  -2 * self.etch_margin.y)

        anchor_ref=(cell<<anchor).move(origin=(0,0),\
        destination=anchor_transl.coord)

        etchdx_transl = anchor_transl + Point(
            anchor.size[0] + self.etch_margin.x, +self.etch_margin.y)

        etch_dx_ref=(cell<<etch_dx).move(origin=(0,0),\
        destination=etchdx_transl.coord)

        cell.add_port(name='conn',\
        midpoint=(anchor_transl+Point(self.size.x/2-self.etch_margin.x,self.size.y+2*self.etch_margin.y)).coord,\
        width=self.metalized.x,\
        orientation=90)

        if self.etch_choice == True:

            cell.absorb(etch_sx_ref)
            cell.absorb(anchor_ref)
            cell.absorb(etch_dx_ref)

        else:

            cell.remove(etch_sx_ref)
            cell.remove(etch_dx_ref)

        del anchor, etch_sx, etch_dx

        return cell
Ejemplo n.º 15
0
    def draw(self):

        cell = Device()

        cell.name = self.name

        supercell = LFERes.draw(self)

        super_ref = cell.add_ref(supercell)

        if self.plate_position == 'out, short':

            plate=pg.rectangle(size=(self.etchpit.active_area.x+8*self.idt.active_area_margin,self.idt.length-self.idt.y_offset/2),\
            layer=self.platelayer)

            plate_ref = cell.add_ref(plate, alias='Plate')

            transl_rel=Point(self.etchpit.x-4*self.idt.active_area_margin,self.anchor.size.y+2*self.anchor.etch_margin.y+self.bus.size.y\
                +self.idt.y_offset*3/4)

            lr_cell = get_corners(cell)[0]
            lr_plate = get_corners(plate_ref)[0]

            plate_ref.move(origin=lr_plate.coord,\
            destination=(lr_plate+lr_cell+transl_rel).coord)

            cell.absorb(plate_ref)

            del plate

        elif self.plate_position == 'in, short':

            plate=pg.rectangle(\
                size=(\
                    self.etchpit.active_area.x-\
                        2*self.idt.active_area_margin,\
                        self.idt.length-self.idt.y_offset/2),\
                layer=self.platelayer)

            plate_ref = cell.add_ref(plate, alias='Plate')

            transl_rel=Point(self.etchpit.x+\
                    self.idt.active_area_margin,\
                self.anchor.size.y+\
                2*self.anchor.etch_margin.y+\
                self.bus.size.y+\
                self.idt.y_offset*3/4)

            lr_cell = get_corners(cell)[0]
            lr_plate = get_corners(plate_ref)[0]

            plate_ref.move(origin=lr_plate.coord,\
            destination=(lr_plate+lr_cell+transl_rel).coord)

            cell.absorb(plate_ref)

            del plate

        elif self.plate_position == 'out, long':

            plate=pg.rectangle(\
                size=(self.etchpit.active_area.x+\
                        8*self.idt.active_area_margin,\
                    self.idt.length+\
                        2*self.bus.size.y+\
                        self.idt.y_offset),\
                layer=self.platelayer)

            plate_ref = cell.add_ref(plate, alias='Plate')

            transl_rel=Point(self.etchpit.x-\
                4*self.idt.active_area_margin,\
                    self.anchor.size.y+2*self.anchor.etch_margin.y)

            lr_cell = get_corners(cell)[0]
            lr_plate = get_corners(plate_ref)[0]

            plate_ref.move(origin=lr_plate.coord,\
            destination=(lr_plate+lr_cell+transl_rel).coord)

            cell.absorb(plate_ref)

            del plate

        elif self.plate_position == 'in, long':

            plate=pg.rectangle(\
                size=(\
                    self.etchpit.active_area.x-\
                        2*self.idt.active_area_margin,\
                        self.idt.length+\
                            2*self.bus.size.y+\
                            self.idt.y_offset),
                layer=self.platelayer)

            plate_ref = cell.add_ref(plate, alias='Plate')

            transl_rel=Point(self.etchpit.x+\
                    self.idt.active_area_margin,\
                        self.anchor.size.y+2*self.anchor.etch_margin.y)

            lr_cell = get_corners(cell)[0]
            lr_plate = get_corners(plate_ref)[0]

            plate_ref.move(origin=lr_plate.coord,\
            destination=(lr_plate+lr_cell+transl_rel).coord)

            cell.absorb(plate_ref)

            del plate

        for name, port in supercell.ports.items():

            cell.add_port(port, name)

        return cell