示例#1
0
        def _make_internal_ground_connections(self, cell):

            lx_ports = pt._find_ports(cell, 'GroundLX', depth=0)

            rx_ports = pt._find_ports(cell, 'GroundRX', depth=0)

            if len(lx_ports) <= 1 or len(rx_ports) <= 1:

                return

            else:

                lx_ports.remove(lx_ports[0])

                rx_ports.remove(rx_ports[-1])

            polyconn = pc.PolyRouting()

            polyconn.layer = (self.plate_layer, )

            for l, r in zip(lx_ports, rx_ports):

                polyconn.source = l
                polyconn.destination = r

                cell.add(polyconn.draw())
                cell.remove(cell.ports[l.name])
                cell.remove(cell.ports[r.name])
示例#2
0
        def _move_probe_ref(self, cell):

            device_ref = cell["Device"]

            probe_ref = cell["Probe"]

            bottom_ports = pt._find_ports(cell, 'bottom', depth=0, exact=True)

            try:

                probe_port = probe_ref.ports['SigN']

            except:

                probe_port = probe_ref.ports['SigN_1']

            top_ports = pt._find_ports(device_ref, 'top')

            if len(top_ports) > 1:

                probe_ref.connect(port=probe_port,
                                  destination=bottom_ports[0],
                                  overlap=-self.probe_conn_distance.y)

            else:

                probe_ref.connect(port=probe_port,
                                  destination=bottom_ports[0],
                                  overlap=-self.probe_dut_distance.y)
示例#3
0
def add_pads(cell, pad, tag='top', exact=False):
    ''' add pad designs to a cell, connecting it to selected ports.

    Parameters:
    -----------
        cell : Device

        pad : pt.LayoutPart

        tags : str (or iterable of str)
            used to find ports
    '''
    if not isinstance(tag, str):

        ports = []

        for t in tag:

            ports.extend(pt._find_ports(cell, t, depth=0, exact=exact))

    else:

        ports = pt._find_ports(cell, tag, depth=0, exact=exact)

    pad_cell = Device()

    for port in ports:

        pad.port = port

        pad_ref = pad_cell.add_ref(pad.draw())

        pad_ref.connect('conn', destination=port)

    cell.add_ref(pad_cell, alias="Pad")
示例#4
0
        def _setup_probe(self, device_cell):

            top_ports = [
                pt.Point(p.midpoint)
                for p in pt._find_ports(device_cell, 'top', depth=0)
            ]

            bottom_ports = [
                pt.Point(p.midpoint)
                for p in pt._find_ports(device_cell, 'bottom', depth=0)
            ]

            top_port_midpoint = pt._get_centroid(*top_ports)

            bottom_port_midpoint = pt._get_centroid(*bottom_ports)

            self.probe.offset = pt.Point(
                (top_port_midpoint.x - bottom_port_midpoint.x),
                (top_port_midpoint.y - bottom_port_midpoint.y) +
                2 * self.probe_dut_distance.y)
示例#5
0
        def _add_signal_connection(self, cell, tag):

            device_cell = cell["Device"]

            ports = pt._find_ports(device_cell, tag, depth=0)

            if len(ports) > 1:

                distance = self.probe_dut_distance.y - self.probe_conn_distance.y

                port_mid = pt._get_centroid_ports(ports)

                if distance - port_mid.width > 0:

                    sigtrace = connect_ports(device_cell,
                                             tag=tag,
                                             layers=self.probe.sig_layer,
                                             distance=distance -
                                             port_mid.width,
                                             metal_width=port_mid.width)

                else:

                    sigtrace = connect_ports(device_cell,
                                             tag=tag,
                                             layers=self.probe.sig_layer,
                                             distance=0,
                                             metal_width=distance)

                _add_default_ground_vias(self, sigtrace)

                cell.absorb(cell << sigtrace)

                sigtrace.ports[tag].width = self.probe.size.x

                pt._copy_ports(sigtrace, cell)

            else:

                cell.add_port(port=device_cell.ports[tag])
示例#6
0
        def _setup_ground_routing(self, cell, label):

            device_ref = cell["Device"]

            probe_ref = cell["Probe"]

            bbox = super()._bbox_mod(device_ref.bbox)

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

                for index, groundroute in enumerate(
                    [self.gndlefttrace, self.gndrighttrace]):

                    groundroute.layer = self.probe.ground_layer

                    groundroute.clearance = bbox

                    groundroute.set_auto_overhang(True)

                    groundroute.trace_width = self.gnd_routing_width

                    if index == 0:

                        groundroute.side = 'left'

                        if label == 'straight':

                            groundroute.source = (
                                probe_ref.ports['GroundLXN'], )

                        elif label == 'side':

                            groundroute.source = (
                                probe_ref.ports['GroundLXW'], )

                    elif index == 1:

                        groundroute.side = 'right'

                        if label == 'straight':

                            groundroute.source = (
                                probe_ref.ports['GroundRXN'], )

                        elif label == 'side':

                            groundroute.source = (
                                probe_ref.ports['GroundRXE'], )

                    dest_ports = pt._find_ports(device_ref, 'top')

                    groundroute.destination = tuple(dest_ports)

            elif isinstance(self.probe, pc.GSProbe):

                raise ValueError(
                    "OnePortProbed with GSprobe to be implemented ")

            else:

                raise ValueError(
                    "OnePortProbed without GSG/GSprobe to be implemented ")
示例#7
0
def connect_ports(cell: Device,
                  tag: str = 'top',
                  layers: tuple = (LayoutDefault.layerTop, ),
                  distance: float = 10.0,
                  metal_width: float = None):
    ''' connects all the ports in the cell with name matching a tag.

    Parameters:
    -----------
        cell : Device

        tag: str

        conn_dist: pt.Point
            offset from port location

        layer : tuple.


    Returns:
    ----------

        cell : Device
            contains routings and connection port

    '''

    import pirel.pcells as pc

    ports = pt._find_ports(cell, tag, depth=0)

    ports.sort(key=lambda x: x.midpoint[0])

    ports_centroid = pt._get_centroid_ports(ports)

    if len(ports) == 1:

        raise ValueError("pm.connect_ports() : len(ports) must be >1 ")

    if metal_width is None:

        metal_width = ports_centroid.width

    port_mid_norm = pt.Point(ports_centroid.normal[1]) - pt.Point(
        ports_centroid.normal[0])

    midpoint_projected = Point(
        ports_centroid.midpoint) + port_mid_norm * (distance + metal_width)

    pad_side = ports_centroid.width

    new_port = Port(name=tag,
                    orientation=ports_centroid.orientation,
                    width=ports_centroid.width,
                    midpoint=midpoint_projected.coord)

    output_cell = Device()

    for p in ports:

        straight_conn = output_cell << pt._draw_multilayer(
            'compass',
            layers,
            size=(p.width, abs(midpoint_projected.y - p.midpoint[1])))

        straight_conn.connect("S", p)

    cross_conn = output_cell << pt._draw_multilayer(
        'compass', layers, size=(output_cell.xsize, metal_width))

    cross_conn.connect('S', new_port, overlap=metal_width)

    output = pt.join(output_cell)

    output.add_port(new_port)

    return output
示例#8
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