Beispiel #1
0
def coupler_netlist(
    wg_width=0.5,
    gap=0.236,
    length=20.007,
    coupler_symmetric_factory=coupler_symmetric,
    coupler_straight=coupler_straight,
):
    """
     SBEND_L-CS-SBEND_R
    """

    assert_on_1nm_grid(length)
    assert_on_2nm_grid(gap)

    _sbend = coupler_symmetric_factory(gap=gap, wg_width=wg_width)
    _cpl_straight = coupler_straight(length=length, gap=gap, width=wg_width)

    components = {
        "SBEND_L": (_sbend, "mirror_y"),
        "SBEND_R": (_sbend, "None"),
        "CS": (_cpl_straight, "None"),
    }

    connections = [("SBEND_L", "W0", "CS", "W0"), ("CS", "E0", "SBEND_R", "W0")]

    ports_map = {
        "W0": ("SBEND_L", "E0"),
        "W1": ("SBEND_L", "E1"),
        "E0": ("SBEND_R", "E0"),
        "E1": ("SBEND_R", "E1"),
    }

    return components, connections, ports_map
def ring_double_bus_netlist(
    bend_radius=5,
    length_x=1,
    length_y=1,
    gap=0.2,
    coupler90_factory=coupler90,
    straight_factory=waveguide,
    cpl_straight_factory=coupler_straight,
    wg_width=0.5,
):
    """
    .. code::

         -CTL==CTS==CTR-
         |          |
         VL         VR
         |          |
        -CBL==CBS==CBR-
    """
    assert_on_2nm_grid(gap)

    _cpl_bend = coupler90_factory(bend_radius=bend_radius,
                                  width=wg_width,
                                  gap=gap)

    _cpl_straight = cpl_straight_factory(length=length_x,
                                         gap=gap,
                                         width=wg_width)
    _v = straight_factory(length=length_y)

    components = {
        "CBL": (_cpl_bend, "mirror_y"),
        "CBR": (_cpl_bend, "None"),
        "CTR": (_cpl_bend, "mirror_x"),
        "CTL": (_cpl_bend, "R180"),
        "CTS": (_cpl_straight, "None"),
        "CBS": (_cpl_straight, "None"),
        "VL": (_v, "R90"),
        "VR": (_v, "R90"),
    }

    connections = [
        ("CBL", "W0", "CBS", "W0"),
        ("CBS", "E0", "CBR", "W0"),
        ("CBL", "N0", "VL", "W0"),
        ("VL", "E0", "CTL", "N0"),
        ("CTL", "W0", "CTS", "W0"),
        ("CTS", "E0", "CTR", "W0"),
        ("CBR", "N0", "VR", "W0"),
        ("VR", "E0", "CTR", "N0"),
    ]

    ports_map = {
        "W0": ("CBL", "E0"),
        "E0": ("CBR", "E0"),
        "W1": ("CTL", "E0"),
        "E1": ("CTR", "E0"),
    }

    return components, connections, ports_map
def ring_single_bus_netlist(
    bend_radius=5,
    length_x=1,
    length_y=1,
    gap=0.2,
    bend90_factory=bend_circular,
    coupler90_factory=coupler90,
    straight_factory=waveguide,
    cpl_straight_factory=coupler_straight,
    wg_width=0.5,
):
    """
    .. code::

         BL--H1--BR
         |       |
         VL      VR
         |       |
        -CL==CS==CR-
    """
    assert_on_2nm_grid(gap)

    bend = bend90_factory(width=wg_width, radius=bend_radius)
    cpl_bend = coupler90_factory(bend_radius=bend_radius,
                                 width=wg_width,
                                 gap=gap)
    cpl_straight = cpl_straight_factory(length=length_x,
                                        gap=gap,
                                        width=wg_width)
    h1 = straight_factory(length=length_x, width=wg_width)
    v = straight_factory(length=length_y, width=wg_width)

    components = {
        "CL": (cpl_bend, "mirror_y"),
        "CR": (cpl_bend, "None"),
        "BR": (bend, "mirror_x"),
        "BL": (bend, "R180"),
        "CS": (cpl_straight, "None"),
        "H1": (h1, "None"),
        "VL": (v, "R90"),
        "VR": (v, "R90"),
    }

    connections = [
        ("CL", "W0", "CS", "W0"),
        ("CS", "E0", "CR", "W0"),
        ("CR", "N0", "VR", "W0"),
        ("VR", "E0", "BR", "N0"),
        ("BR", "W0", "H1", "E0"),
        ("H1", "W0", "BL", "W0"),
        ("BL", "N0", "VL", "E0"),
        ("VL", "W0", "CL", "N0"),
    ]

    ports_map = {"W0": ("CL", "E0"), "E0": ("CR", "E0")}

    return components, connections, ports_map
Beispiel #4
0
def ring_double(
    wg_width: float = 0.5,
    gap: float = 0.2,
    length_x: float = 3.0,
    bend_radius: float = 5.0,
    length_y: float = 2.0,
    coupler: Callable = coupler_ring,
    waveguide: Callable = waveguide_function,
    pins: bool = False,
) -> Component:
    """ double bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical waveguides (wyl: left, wyr: right)

    .. code::

         --==ct==--
          |      |
          wl     wr length_y
          |      |
         --==cb==-- gap

          length_x

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_double(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5)
      pp.plotgds(c)
    """
    assert_on_2nm_grid(gap)

    coupler = call_if_func(coupler,
                           gap=gap,
                           wg_width=wg_width,
                           bend_radius=bend_radius,
                           length_x=length_x)
    waveguide = call_if_func(waveguide, width=wg_width, length=length_y)

    c = Component()
    cb = c << coupler
    ct = c << coupler
    wl = c << waveguide
    wr = c << waveguide

    wl.connect(port="E0", destination=cb.ports["N0"])
    ct.connect(port="N1", destination=wl.ports["W0"])
    wr.connect(port="W0", destination=ct.ports["N0"])
    cb.connect(port="N1", destination=wr.ports["E0"])
    c.add_port("E0", port=cb.ports["E0"])
    c.add_port("W0", port=cb.ports["W0"])
    c.add_port("E1", port=ct.ports["W0"])
    c.add_port("W1", port=ct.ports["E0"])
    if pins:
        pp.add_pins_to_references(c)
    return c
Beispiel #5
0
def coupler_ring(
    coupler90: Callable = coupler90,
    coupler: Callable = coupler_straight,
    length_x: float = 4.0,
    gap: float = 0.2,
    wg_width: float = 0.5,
    bend_radius: float = 5.0,
) -> Component:
    """ coupler for half a ring

    .. code::

           N0            N1
           |             |
            \           /
             \         /
           ---=========---
        W0    length_x    E0

    .. plot::
      :include-source:

      import pp

      c = pp.c.coupler_ring(length_x=20, bend_radius=5.0, gap=0.3, wg_width=0.45)
      pp.plotgds(c)

    """
    c = pp.Component()
    assert_on_2nm_grid(gap)

    # define subcells
    coupler90 = pp.call_if_func(coupler90,
                                gap=gap,
                                width=wg_width,
                                bend_radius=bend_radius)
    coupler_straight = pp.call_if_func(coupler,
                                       gap=gap,
                                       length=length_x,
                                       width=wg_width)

    # add references to subcells
    cbl = c << coupler90
    cbr = c << coupler90
    cs = c << coupler_straight

    # connect references
    cs.connect(port="E0", destination=cbr.ports["W0"])
    cbl.reflect(p1=(0, coupler90.y), p2=(1, coupler90.y))
    cbl.connect(port="W0", destination=cs.ports["W0"])

    c.add_port("W0", port=cbl.ports["E0"])
    c.add_port("N0", port=cbl.ports["N0"])
    c.add_port("E0", port=cbr.ports["E0"])
    c.add_port("N1", port=cbr.ports["N0"])
    return c
Beispiel #6
0
def coupler_netlist(
    wg_width: float = 0.5,
    gap: float = 0.236,
    length: float = 20.007,
    coupler_symmetric_factory: Callable = coupler_symmetric,
    coupler_straight: Callable = coupler_straight,
    layer: Tuple[int, int] = LAYER.WG,
    layers_cladding: List[Tuple[int, int]] = [LAYER.WGCLAD],
    cladding_offset: int = 3,
) -> Tuple[Dict[str, Tuple[Component, str]], List[Tuple[str, str, str, str]],
           Dict[str, Tuple[str, str]], ]:
    """
    SBEND_L-CS-SBEND_R
    """

    assert_on_1nm_grid(length)
    assert_on_2nm_grid(gap)

    _sbend = coupler_symmetric_factory(
        gap=gap,
        wg_width=wg_width,
        layer=layer,
        layers_cladding=layers_cladding,
        cladding_offset=cladding_offset,
    )
    _cpl_straight = coupler_straight(
        length=length,
        gap=gap,
        width=wg_width,
        layer=layer,
        layers_cladding=layers_cladding,
        cladding_offset=cladding_offset,
    )

    components = {
        "SBEND_L": (_sbend, "mirror_y"),
        "SBEND_R": (_sbend, "None"),
        "CS": (_cpl_straight, "None"),
    }

    connections = [("SBEND_L", "W0", "CS", "W0"),
                   ("CS", "E0", "SBEND_R", "W0")]

    ports_map = {
        "W0": ("SBEND_L", "E0"),
        "W1": ("SBEND_L", "E1"),
        "E0": ("SBEND_R", "E0"),
        "E1": ("SBEND_R", "E1"),
    }

    return components, connections, ports_map
Beispiel #7
0
def ring_single(
    wg_width: float = 0.5,
    gap: float = 0.2,
    length_x: float = 4.0,
    bend_radius: float = 5.0,
    length_y: float = 2.0,
    coupler: Callable = coupler_ring,
    waveguide: Callable = waveguide,
    bend: Callable = bend_circular,
) -> Component:
    """ single bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical waveguides (wyl: left, wyr: right)

    .. code::

          bl-wt-br
          |      |
          wl     wr length_y
          |      |
         --==cb==-- gap

          length_x

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_single(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5)
      pp.plotgds(c)

    """
    bend_radius = float(bend_radius)
    assert_on_2nm_grid(gap)

    coupler = call_if_func(coupler,
                           gap=gap,
                           wg_width=wg_width,
                           bend_radius=bend_radius,
                           length_x=length_x)
    waveguide_side = call_if_func(waveguide, width=wg_width, length=length_y)
    waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x)
    bend = call_if_func(bend, width=wg_width, radius=bend_radius)

    c = Component()
    cb = c << coupler
    wl = c << waveguide_side
    wr = c << waveguide_side
    bl = c << bend
    br = c << bend
    wt = c << waveguide_top

    wl.connect(port="E0", destination=cb.ports["N0"])
    bl.connect(port="N0", destination=wl.ports["W0"])

    wt.connect(port="W0", destination=bl.ports["W0"])
    br.connect(port="N0", destination=wt.ports["E0"])
    wr.connect(port="W0", destination=br.ports["W0"])
    wr.connect(port="E0", destination=cb.ports["N1"])  # just for netlist

    c.add_port("E0", port=cb.ports["E0"])
    c.add_port("W0", port=cb.ports["W0"])
    return c
def ring_single_bus(
    coupler90_factory: Callable = coupler90,
    cpl_straight_factory: Callable = coupler_straight,
    straight_factory: Callable = waveguide,
    bend90_factory: Callable = bend_circular,
    length_y: float = 2.0,
    length_x: float = 4.0,
    gap: float = 0.2,
    wg_width: float = 0.5,
    bend_radius: int = 5,
) -> Component:
    """ single bus ring
    .. code::

         ctl--wx--ctr
          |       |
         wyl     wgr
          |       |
        -cbl==CS==cbr-
    """
    c = pp.Component()
    assert_on_2nm_grid(gap)

    # define subcells
    coupler90 = pp.call_if_func(coupler90_factory,
                                gap=gap,
                                width=wg_width,
                                bend_radius=bend_radius)
    waveguide_x = pp.call_if_func(straight_factory,
                                  length=length_x,
                                  width=wg_width,
                                  pins=False)
    waveguide_y = pp.call_if_func(straight_factory,
                                  length=length_y,
                                  width=wg_width,
                                  pins=False)
    bend = pp.call_if_func(bend90_factory,
                           width=wg_width,
                           radius=bend_radius,
                           pins=False)
    coupler_straight = pp.call_if_func(cpl_straight_factory,
                                       gap=gap,
                                       length=length_x,
                                       width=wg_width)

    # add references to subcells
    cbl = c << coupler90
    cbr = c << coupler90
    cs = c << coupler_straight
    wyl = c << waveguide_y
    wyr = c << waveguide_y
    wx = c << waveguide_x
    btl = c << bend
    btr = c << bend

    # connect references
    wyr.connect(port="E0", destination=cbr.ports["N0"])
    cs.connect(port="E0", destination=cbr.ports["W0"])

    cbl.reflect(p1=(0, coupler90.y), p2=(1, coupler90.y))
    cbl.connect(port="W0", destination=cs.ports["W0"])
    wyl.connect(port="E0", destination=cbl.ports["N0"])

    btl.connect(port="N0", destination=wyl.ports["W0"])
    btr.connect(port="W0", destination=wyr.ports["W0"])
    wx.connect(port="W0", destination=btl.ports["W0"])

    c.add_port("W0", port=cbl.ports["E0"])
    c.add_port("E0", port=cbr.ports["E0"])
    return c
Beispiel #9
0
def ring_with_taper_netlist(
    bend_radius=5,
    length_x=1,
    length_y=0,
    gap=0.2,
    taper_width=1.0,
    taper_length=10,
    taper_factory=taper,
    bend90_factory=bend_circular,
    coupler90_factory=coupler90,
    straight_factory=waveguide,
    cpl_straight_factory=coupler_straight,
    wg_width=0.5,
):
    """
    .. code::

         BL--H1--BR
         |       |
         |       T2
         |       VR length_y
         VL      T1
         |       |
        -CL==CS==CR-
    """
    assert_on_2nm_grid(gap)

    taper = taper_factory(length=taper_length,
                          width1=wg_width,
                          width2=taper_width)
    bend = bend90_factory(radius=bend_radius, width=wg_width)
    cpl_bend = coupler90_factory(bend_radius=bend_radius,
                                 width=wg_width,
                                 gap=gap)
    cpl_straight = cpl_straight_factory(length=length_x,
                                        gap=gap,
                                        width=wg_width)
    h1 = straight_factory(length=length_x, width=wg_width)
    vl = straight_factory(length=length_y + 2 * taper_length, width=wg_width)
    vr = straight_factory(length=length_y, width=taper_width)

    components = {
        "CL": (cpl_bend, "mirror_y"),
        "CR": (cpl_bend, "None"),
        "BR": (bend, "mirror_x"),
        "BL": (bend, "R180"),
        "CS": (cpl_straight, "None"),
        "H1": (h1, "None"),
        "T1": (taper, "R90"),
        "T2": (taper, "R270"),
        "VL": (vl, "R90"),
        "VR": (vr, "R90"),
    }
    connections = [
        ("CL", "W0", "CS", "W0"),
        ("CS", "E0", "CR", "W0"),
        ("CR", "N0", "T1", "1"),
        ("T1", "2", "VR", "W0"),
        ("VR", "E0", "T2", "2"),
        ("T2", "1", "BR", "N0"),
        ("BR", "W0", "H1", "E0"),
        ("H1", "W0", "BL", "W0"),
        ("BL", "N0", "VL", "E0"),
        ("VL", "W0", "CL", "N0"),
    ]

    ports_map = {"W0": ("CL", "E0"), "E0": ("CR", "E0")}

    return components, connections, ports_map
Beispiel #10
0
def ring_single_dut(
    component,
    wg_width=0.5,
    gap=0.2,
    length_x=4,
    bend_radius=5,
    length_y=0,
    coupler=coupler_ring,
    waveguide=waveguide,
    bend=bend_circular,
    with_dut=True,
):
    """ single bus ring made of two couplers (ct: top, cb: bottom)
    connected with two vertical waveguides (wyl: left, wyr: right)
    DUT (Device Under Test) in the middle to extract loss from quality factor


    Args:
        with_dut: if False changes dut for just a waveguide

    .. code::

          bl-wt-br
          |      | length_y
          wl     dut
          |      |
         --==cb==-- gap

          length_x
    """
    dut = pp.call_if_func(component)
    dut = rename_ports_by_orientation(dut)

    assert_on_2nm_grid(gap)

    coupler = call_if_func(coupler,
                           gap=gap,
                           wg_width=wg_width,
                           bend_radius=bend_radius,
                           length_x=length_x)
    waveguide_side = call_if_func(waveguide,
                                  width=wg_width,
                                  length=length_y + dut.xsize)
    waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x)
    bend = call_if_func(bend, width=wg_width, radius=bend_radius)

    c = Component()
    cb = c << coupler
    wl = c << waveguide_side
    if with_dut:
        d = c << dut
    else:
        d = c << waveguide_side
    bl = c << bend
    br = c << bend
    wt = c << waveguide_top

    wl.connect(port="E0", destination=cb.ports["N0"])
    bl.connect(port="N0", destination=wl.ports["W0"])

    wt.connect(port="W0", destination=bl.ports["W0"])
    br.connect(port="N0", destination=wt.ports["E0"])
    d.connect(port="W0", destination=br.ports["W0"])
    c.add_port("E0", port=cb.ports["E0"])
    c.add_port("W0", port=cb.ports["W0"])
    return c
Beispiel #11
0
def ring_single(
    wg_width: float = 0.5,
    gap: float = 0.2,
    bend_radius: float = 10.0,
    length_x: float = 4.0,
    length_y: float = 0.001,
    coupler: Callable = coupler_ring,
    waveguide: Callable = waveguide_function,
    bend: Callable = bend_circular,
    pins: bool = False,
) -> Component:
    """Single bus ring made of a ring coupler (cb: bottom)
    connected with two vertical waveguides (wl: left, wr: right)
    two bends (bl, br) and horizontal waveguide (wg: top)

    Args:
        wg_width: waveguide width
        gap: gap between for coupler
        bend_radius: for the bend and coupler
        length_x: ring coupler length
        length_y: vertical waveguide length
        coupler: ring coupler function
        waveguide: waveguide function
        bend: bend function
        pins: add pins


    .. code::

          bl-wt-br
          |      |
          wl     wr length_y
          |      |
         --==cb==-- gap

          length_x

    .. plot::
      :include-source:

      import pp

      c = pp.c.ring_single(wg_width=0.5, gap=0.2, length_x=4, length_y=0.1, bend_radius=5)
      pp.plotgds(c)

    """
    bend_radius = float(bend_radius)
    assert_on_2nm_grid(gap)

    coupler = call_if_func(coupler,
                           gap=gap,
                           wg_width=wg_width,
                           bend_radius=bend_radius,
                           length_x=length_x)
    waveguide_side = call_if_func(waveguide, width=wg_width, length=length_y)
    waveguide_top = call_if_func(waveguide, width=wg_width, length=length_x)
    bend_ref = bend(width=wg_width,
                    radius=bend_radius) if callable(bend) else bend

    c = Component()
    cb = c << coupler
    wl = c << waveguide_side
    wr = c << waveguide_side
    bl = c << bend_ref
    br = c << bend_ref
    wt = c << waveguide_top

    wl.connect(port="E0", destination=cb.ports["N0"])
    bl.connect(port="N0", destination=wl.ports["W0"])

    wt.connect(port="W0", destination=bl.ports["W0"])
    br.connect(port="N0", destination=wt.ports["E0"])
    wr.connect(port="W0", destination=br.ports["W0"])
    wr.connect(port="E0", destination=cb.ports["N1"])  # just for netlist

    c.add_port("E0", port=cb.ports["E0"])
    c.add_port("W0", port=cb.ports["W0"])
    if pins:
        pp.add_pins_to_references(c)
    return c
def ring_double_bus_netlist(
    bend_radius: float = 5.0,
    length_x: float = 1.0,
    length_y: float = 1.0,
    gap: float = 0.2,
    coupler90_factory: Callable = coupler90,
    straight_factory: Callable = waveguide,
    cpl_straight_factory: Callable = coupler_straight,
    wg_width: float = 0.5,
) -> Tuple[Dict[str, Tuple[Component, str]], List[Tuple[str, str, str, str]],
           Dict[str, Tuple[str, str]], ]:
    """
    .. code::

         -CTL==CTS==CTR-
         |          |
         VL         VR
         |          |
        -CBL==CBS==CBR-
    """
    assert_on_2nm_grid(gap)

    _cpl_bend = coupler90_factory(bend_radius=bend_radius,
                                  width=wg_width,
                                  gap=gap)

    _cpl_straight = cpl_straight_factory(length=length_x,
                                         gap=gap,
                                         width=wg_width)
    _v = straight_factory(length=length_y)

    components = {
        "CBL": (_cpl_bend, "mirror_y"),
        "CBR": (_cpl_bend, "None"),
        "CTR": (_cpl_bend, "mirror_x"),
        "CTL": (_cpl_bend, "R180"),
        "CTS": (_cpl_straight, "None"),
        "CBS": (_cpl_straight, "None"),
        "VL": (_v, "R90"),
        "VR": (_v, "R90"),
    }

    connections = [
        ("CBL", "W0", "CBS", "W0"),
        ("CBS", "E0", "CBR", "W0"),
        ("CBL", "N0", "VL", "W0"),
        ("VL", "E0", "CTL", "N0"),
        ("CTL", "W0", "CTS", "W0"),
        ("CTS", "E0", "CTR", "W0"),
        ("CBR", "N0", "VR", "W0"),
        ("VR", "E0", "CTR", "N0"),
    ]

    ports_map = {
        "W0": ("CBL", "E0"),
        "E0": ("CBR", "E0"),
        "W1": ("CTL", "E0"),
        "E1": ("CTR", "E0"),
    }

    return components, connections, ports_map