示例#1
0
def add_electrical_pads_top(component: Component, **kwargs) -> Component:
    """connects component electrical ports with pad array at the top

    Args:
        component:
        pad: pad element
        spacing: pad array (x, y) spacing
        width: pad width
        height: pad height
        layer: pad layer
    """
    c = Component(f"{component.name}_e")
    ports = component.get_ports_list(port_type="dc")
    c << component
    pads = c << pad_array(n=len(ports), port_list=["S"], **kwargs)
    pads.x = component.x
    pads.y = component.ymax + 100
    ports_pads = list(pads.ports.values())
    for p1, p2 in zip(ports_pads, ports):
        c.add(connect_electrical_shortest_path(p1, p2))

    c.ports = component.ports
    for port in ports:
        c.ports.pop(port.name)
    return c
示例#2
0
def pad(
    width: int = 100, height: int = 100, layer: Tuple[int, int] = LAYER.M3
) -> Component:
    """rectangular pad with 4 ports (N, S, E, W)

    Args:
        width: pad width
        height: pad height
        layer: pad layer


    .. plot::
      :include-source:

      import pp

      c = pp.c.pad(width=100, height=100, layer=pp.LAYER.M3)
      pp.plotgds(c)

    """
    c = Component()
    _c = compass(size=(width, height), layer=layer).ref()
    c.add(_c)
    c.absorb(_c)
    c.ports = _c.ports
    return c
示例#3
0
def rotate(component: Component, angle: int = 90) -> Component:
    """ returns rotated component
    """
    c = Component(f"{component.name}_r")
    cr = c.add_ref(component)
    cr.rotate(angle)
    c.ports = cr.ports
    return c
示例#4
0
def rotate(component, angle=90):
    """ returns rotated component
    """
    c = Component(
        settings=component.get_settings(),
        test_protocol=component.test_protocol,
        data_analysis_protocol=component.data_analysis_protocol,
    )
    cr = c.add_ref(component)
    cr.rotate(angle)
    c.ports = cr.ports
    c.name = component.name + "_r"
    return c
示例#5
0
def add_electrical_pads_shortest(component,
                                 pad=pad,
                                 pad_port_spacing=50,
                                 **kwargs):
    """add a pad to each closest electrical port
    Args:
        component:
        pad: pad element or function
        pad_port_spacing: between pad and port
        width: pad width
        height: pad height
        layer: pad layer

    """
    c = Component(f"{component.name}_e")
    ports = component.get_ports_list(port_type="dc")
    c << component

    pad = pad(**kwargs) if callable(pad) else pad
    pad_port_spacing += pad.settings["width"] / 2

    for port in ports:
        p = c << pad
        if port.orientation == 0:
            p.x = port.x + pad_port_spacing
            p.y = port.y
            c.add(connect_electrical_shortest_path(port, p.ports["W"]))
        elif port.orientation == 180:
            p.x = port.x - pad_port_spacing
            p.y = port.y
            c.add(connect_electrical_shortest_path(port, p.ports["E"]))
        elif port.orientation == 90:
            p.y = port.y + pad_port_spacing
            p.x = port.x
            c.add(connect_electrical_shortest_path(port, p.ports["S"]))
        elif port.orientation == 270:
            p.y = port.y - pad_port_spacing
            p.x = port.x
            c.add(connect_electrical_shortest_path(port, p.ports["N"]))

    c.ports = component.ports
    for port in ports:
        c.ports.pop(port.name)
    return c
def add_electrical_pads_top(
    component: Component,
    component_top_to_pad_bottom_distance: float = 100.0,
    route_filter=connect_elec_waypoints,
    **kwargs,
) -> Component:
    """connects component electrical ports with pad array at the top

    Args:
        component:
        pad: pad element
        spacing: pad array (x, y) spacing
        width: pad width
        height: pad height
        layer: pad layer
    """
    c = Component(f"{component.name}_e")
    ports = component.get_ports_list(port_type="dc")
    # for port in ports:
    #     print(port.name)
    # print(len(ports))
    c << component
    pads = c << pad_array(n=len(ports), port_list=["S"], **kwargs)
    pads.x = component.x
    pads.ymin = component.ymax + component_top_to_pad_bottom_distance

    ports_pads = list(pads.ports.values())

    ports_pads.sort(key=lambda p: p.x)
    ports.sort(key=lambda p: p.x)

    for p1, p2 in zip(ports_pads, ports):
        c.add(connect_electrical_shortest_path(p1, p2))

    c.ports = component.ports.copy()
    for port in ports:
        c.ports.pop(port.name)
    return c
示例#7
0
def route_fiber_single(
    component: Component,
    optical_io_spacing: int = 50,
    grating_coupler: Component = grating_coupler_te,
    min_input2output_spacing: int = 230,
    optical_routing_type: int = 1,
    optical_port_labels: Optional[List[str]] = None,
    excluded_ports: Optional[List[str]] = None,
    **kwargs
) -> Tuple[List[Union[ComponentReference, Label]], List[ComponentReference]]:
    """Returns routes with grating couplers for single fiber input/output.

    Args:
        component: to add grating couplers
        optical_io_spacing: between grating couplers
        grating_coupler:
        min_input2output_spacing: so opposite fibers do not touch
        optical_routing_type: 0, 1, 2
        optical_port_labels: port labels that need connection
        excluded_ports: ports excluded from routing

    Returns:
        elements: list of routes ComponentReference
        grating_couplers: list of grating_couplers ComponentReferences

    """
    component = component.copy()
    component_copy = component.copy()

    if optical_port_labels is None:
        optical_ports = component.get_ports_list(port_type="optical")
    else:
        optical_ports = [component.ports[lbl] for lbl in optical_port_labels]

    excluded_ports = excluded_ports or []
    optical_ports = [p for p in optical_ports if p.name not in excluded_ports]
    N = len(optical_ports)

    if isinstance(grating_coupler, list):
        grating_couplers = [pp.call_if_func(g) for g in grating_coupler]
        grating_coupler = grating_couplers[0]
    else:
        grating_coupler = pp.call_if_func(grating_coupler)
        grating_couplers = [grating_coupler] * N

    gc_port2center = getattr(grating_coupler, "port2center",
                             grating_coupler.xsize / 2)
    if component.xsize + 2 * gc_port2center < min_input2output_spacing:
        fanout_length = (pp.drc.snap_to_grid(
            min_input2output_spacing - component.xsize - 2 * gc_port2center,
            10) / 2)
    else:
        fanout_length = None
    """
         _________
        |         |_E1
     W0_|         |
        |         |_E0
        |_________|

    rotate +90 deg and route West ports to South

          E1  E0
         _|___|_
        |       |
        |       |
        |       |
        |       |
        |       |
        |       |
        |_______|
            |
            W0

    """
    # route west ports to south
    component = component.rotate(90)
    west_ports = component.get_ports_dict(prefix="W")
    north_ports = {
        p.name: p
        for p in component.ports.values() if not p.name.startswith("W")
    }
    component.ports = west_ports

    elements_south, gratings_south, _ = route_fiber_array(
        component=component,
        with_align_ports=False,
        optical_io_spacing=optical_io_spacing,
        fanout_length=fanout_length,
        grating_coupler=grating_couplers[0],
        optical_routing_type=optical_routing_type,
        **kwargs)

    # route north ports
    component = component_copy.rotate(-90)
    north_ports = {
        p.name: p
        for p in component.ports.values() if not p.name.startswith("W")
    }
    component.ports = north_ports

    elements_north, gratings_north, _ = route_fiber_array(
        component=component,
        with_align_ports=False,
        optical_io_spacing=optical_io_spacing,
        fanout_length=fanout_length,
        grating_coupler=grating_couplers[1:],
        **kwargs)
    for e in elements_north:
        elements_south.append(e.rotate(180))

    if len(gratings_north) > 0:
        for io in gratings_north[0]:
            gratings_south.append(io.rotate(180))

    return elements_south, gratings_south