Schematic

Contents

Schematic#

A schematic is a graph representation of your circuit.

For complex circuits, a schematic allows you to create symbols and hierarchy levels to represent your circuit.

Having a schematic allows you to also ensure that your layout matches you schematic (design intent).

There are many schematic capture tools out there:

  • Qucs-s: for RF.

  • Xschem: for analog circuits.

  • Lumerical interconnect: for photonic circuits.

These tools allow you to both create schematics with your mouse or by code.

gdsfactory also allows you to create complex Schematics directly from python with a very simple interface.

import gdsfactory as gf
import gdsfactory.schematic as gt
import yaml
c = gf.c.mzi()
c.plot_netlist_graphviz(interactive=False)
../_images/76de6f09e81e70e42a78d02ba341889ad174759cffd38b6ae4454ec8338eedc0.png
c.plot_netlist()
<networkx.classes.graph.Graph at 0x7fb5889385d0>
../_images/cc4b8da979fbb06be2cda15d396e0a0ffece237cd52a587b5f315b7bc5f6820d.png

Lets create a MZI lattice of 3 elements.

s = gt.Schematic()
s.add_instance("mzi1", gt.Instance(component=gf.c.mzi(delta_length=10)))
s.add_instance("mzi2", gt.Instance(component=gf.c.mzi(delta_length=100)))
s.add_instance("mzi3", gt.Instance(component=gf.c.mzi(delta_length=200)))
s.add_placement("mzi1", gt.Placement(x=000, y=0))
s.add_placement("mzi2", gt.Placement(x=100, y=100))
s.add_placement("mzi3", gt.Placement(x=200, y=0))
s.add_net(gt.Net(p1="mzi1,o2", p2="mzi2,o1"))
s.add_net(gt.Net(p1="mzi2,o2", p2="mzi3,o1"))
g = s.plot_graphviz()
../_images/3e2a6eac7e60c0199a25565795cd0faa158e4a6b71d86deff035b0f0653ebc0b.png

You can also create a splitter tree.

s = gt.Schematic()
s.add_instance("s11", gt.Instance(component=gf.c.mmi1x2()))
s.add_instance("s21", gt.Instance(component=gf.c.mmi1x2()))
s.add_instance("s22", gt.Instance(component=gf.c.mmi1x2()))
s.add_placement("s11", gt.Placement(x=000, y=0))
s.add_placement("s21", gt.Placement(x=100, y=+50))
s.add_placement("s22", gt.Placement(x=100, y=-50))
s.add_net(gt.Net(p1="s11,o2", p2="s21,o1"))
s.add_net(gt.Net(p1="s11,o3", p2="s22,o1"))
g = s.plot_graphviz()
../_images/5f45a653c60368850d453dd2d84e21c51806a063aa7c45c4fb7453fdbb68a217.png

The nice thing is that you can abstract it to have as many levels as you need.

splitter = gf.components.mmi1x2()
n = 3
dx = 100
dy = 100
s = gt.Schematic()

for col in range(n):
    rows = 2**col
    for row in range(rows):
        s.add_instance(f"s{col}{row}", gt.Instance(component=splitter))
        s.add_placement(
            f"s{col}{row}", gt.Placement(x=col * dx, y=(row - rows / 2) * dy)
        )
        if col < n - 1:
            s.add_net(gt.Net(p1=f"s{col}{row},o2", p2=f"s{col+1}{2*row},o1"))
            s.add_net(gt.Net(p1=f"s{col}{row},o3", p2=f"s{col+1}{2*row+1},o1"))


g = s.plot_graphviz()
../_images/7d9f1a50f3b2e686ec86f57daca3bed6f837ae145a6551dd1095a6b27a7da56f.png
splitter = gf.components.mmi1x2()
n = 5
dx = 100
dy = 100
s = gt.Schematic()

for col in range(n):
    rows = 2**col
    for row in range(rows):
        s.add_instance(f"s{col}{row}", gt.Instance(component=splitter))
        s.add_placement(
            f"s{col}{row}", gt.Placement(x=col * dx, y=(row - rows / 2) * dy)
        )
        if col < n - 1:
            s.add_net(gt.Net(p1=f"s{col}{row},o2", p2=f"s{col+1}{2*row},o1"))
            s.add_net(gt.Net(p1=f"s{col}{row},o3", p2=f"s{col+1}{2*row+1},o1"))


g = s.plot_graphviz()
../_images/c129ada71bb7c55b761b9f1f31ff81ed1948224d6240e8ab8aa238f5ae83ae19.png
dict(s.netlist)
{'pdk': '',
 'instances': {'s00': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's10': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's11': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's20': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's21': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's22': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's23': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's30': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's31': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's32': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's33': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's34': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's35': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's36': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's37': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's40': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's41': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's42': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's43': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's44': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's45': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's46': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's47': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's48': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's49': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's410': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's411': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's412': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's413': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's414': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None),
  's415': Instance(component='mmi1x2', settings={'width_taper': 1.0, 'length_taper': 10.0, 'length_mmi': 5.5, 'width_mmi': 2.5, 'gap_mmi': 0.25, 'taper': 'taper', 'straight': 'straight', 'cross_section': 'strip'}, info={}, array=None)},
 'placements': {'s00': Placement(x=0.0, y=-50.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's10': Placement(x=100.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's11': Placement(x=100.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's20': Placement(x=200.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's21': Placement(x=200.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's22': Placement(x=200.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's23': Placement(x=200.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's30': Placement(x=300.0, y=-400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's31': Placement(x=300.0, y=-300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's32': Placement(x=300.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's33': Placement(x=300.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's34': Placement(x=300.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's35': Placement(x=300.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's36': Placement(x=300.0, y=200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's37': Placement(x=300.0, y=300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's40': Placement(x=400.0, y=-800.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's41': Placement(x=400.0, y=-700.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's42': Placement(x=400.0, y=-600.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's43': Placement(x=400.0, y=-500.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's44': Placement(x=400.0, y=-400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's45': Placement(x=400.0, y=-300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's46': Placement(x=400.0, y=-200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's47': Placement(x=400.0, y=-100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's48': Placement(x=400.0, y=0.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's49': Placement(x=400.0, y=100.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's410': Placement(x=400.0, y=200.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's411': Placement(x=400.0, y=300.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's412': Placement(x=400.0, y=400.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's413': Placement(x=400.0, y=500.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's414': Placement(x=400.0, y=600.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False),
  's415': Placement(x=400.0, y=700.0, xmin=None, ymin=None, xmax=None, ymax=None, dx=0, dy=0, port=None, rotation=0, mirror=False)},
 'connections': {},
 'routes': {'route_10': Bundle(links={'s00,o2': 's10,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_11': Bundle(links={'s00,o3': 's11,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_12': Bundle(links={'s10,o2': 's20,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_13': Bundle(links={'s10,o3': 's21,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_14': Bundle(links={'s11,o2': 's22,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_15': Bundle(links={'s11,o3': 's23,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_16': Bundle(links={'s20,o2': 's30,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_17': Bundle(links={'s20,o3': 's31,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_18': Bundle(links={'s21,o2': 's32,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_19': Bundle(links={'s21,o3': 's33,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_20': Bundle(links={'s22,o2': 's34,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_21': Bundle(links={'s22,o3': 's35,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_22': Bundle(links={'s23,o2': 's36,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_23': Bundle(links={'s23,o3': 's37,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_24': Bundle(links={'s30,o2': 's40,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_25': Bundle(links={'s30,o3': 's41,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_26': Bundle(links={'s31,o2': 's42,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_27': Bundle(links={'s31,o3': 's43,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_28': Bundle(links={'s32,o2': 's44,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_29': Bundle(links={'s32,o3': 's45,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_30': Bundle(links={'s33,o2': 's46,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_31': Bundle(links={'s33,o3': 's47,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_32': Bundle(links={'s34,o2': 's48,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_33': Bundle(links={'s34,o3': 's49,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_34': Bundle(links={'s35,o2': 's410,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_35': Bundle(links={'s35,o3': 's411,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_36': Bundle(links={'s36,o2': 's412,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_37': Bundle(links={'s36,o3': 's413,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_38': Bundle(links={'s37,o2': 's414,o1'}, settings={}, routing_strategy='route_bundle'),
  'route_39': Bundle(links={'s37,o3': 's415,o1'}, settings={}, routing_strategy='route_bundle')},
 'name': None,
 'info': {},
 'ports': {},
 'settings': {},
 'nets': [],
 'warnings': {}}
yaml_component = yaml.dump(s.netlist.model_dump(exclude_none=True))
print(yaml_component)
connections: {}
info: {}
instances:
  s00:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s10:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s11:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s20:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s21:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s22:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s23:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s30:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s31:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s32:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s33:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s34:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s35:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s36:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s37:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s40:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s41:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s410:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s411:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s412:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s413:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s414:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s415:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s42:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s43:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s44:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s45:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s46:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s47:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s48:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
  s49:
    component: mmi1x2
    settings:
      cross_section: strip
      gap_mmi: 0.25
      length_mmi: 5.5
      length_taper: 10.0
      straight: straight
      taper: taper
      width_mmi: 2.5
      width_taper: 1.0
nets: []
pdk: ''
placements:
  s00:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: -50.0
  s10:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 100.0
    y: -100.0
  s11:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 100.0
    y: 0.0
  s20:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: -200.0
  s21:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: -100.0
  s22:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: 0.0
  s23:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 200.0
    y: 100.0
  s30:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -400.0
  s31:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -300.0
  s32:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -200.0
  s33:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: -100.0
  s34:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s35:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 100.0
  s36:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 200.0
  s37:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 300.0
  s40:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -800.0
  s41:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -700.0
  s410:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 200.0
  s411:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 300.0
  s412:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 400.0
  s413:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 500.0
  s414:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 600.0
  s415:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 700.0
  s42:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -600.0
  s43:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -500.0
  s44:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -400.0
  s45:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -300.0
  s46:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -200.0
  s47:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: -100.0
  s48:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 0.0
  s49:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 400.0
    y: 100.0
ports: {}
routes:
  route_10:
    links:
      s00,o2: s10,o1
    routing_strategy: route_bundle
    settings: {}
  route_11:
    links:
      s00,o3: s11,o1
    routing_strategy: route_bundle
    settings: {}
  route_12:
    links:
      s10,o2: s20,o1
    routing_strategy: route_bundle
    settings: {}
  route_13:
    links:
      s10,o3: s21,o1
    routing_strategy: route_bundle
    settings: {}
  route_14:
    links:
      s11,o2: s22,o1
    routing_strategy: route_bundle
    settings: {}
  route_15:
    links:
      s11,o3: s23,o1
    routing_strategy: route_bundle
    settings: {}
  route_16:
    links:
      s20,o2: s30,o1
    routing_strategy: route_bundle
    settings: {}
  route_17:
    links:
      s20,o3: s31,o1
    routing_strategy: route_bundle
    settings: {}
  route_18:
    links:
      s21,o2: s32,o1
    routing_strategy: route_bundle
    settings: {}
  route_19:
    links:
      s21,o3: s33,o1
    routing_strategy: route_bundle
    settings: {}
  route_20:
    links:
      s22,o2: s34,o1
    routing_strategy: route_bundle
    settings: {}
  route_21:
    links:
      s22,o3: s35,o1
    routing_strategy: route_bundle
    settings: {}
  route_22:
    links:
      s23,o2: s36,o1
    routing_strategy: route_bundle
    settings: {}
  route_23:
    links:
      s23,o3: s37,o1
    routing_strategy: route_bundle
    settings: {}
  route_24:
    links:
      s30,o2: s40,o1
    routing_strategy: route_bundle
    settings: {}
  route_25:
    links:
      s30,o3: s41,o1
    routing_strategy: route_bundle
    settings: {}
  route_26:
    links:
      s31,o2: s42,o1
    routing_strategy: route_bundle
    settings: {}
  route_27:
    links:
      s31,o3: s43,o1
    routing_strategy: route_bundle
    settings: {}
  route_28:
    links:
      s32,o2: s44,o1
    routing_strategy: route_bundle
    settings: {}
  route_29:
    links:
      s32,o3: s45,o1
    routing_strategy: route_bundle
    settings: {}
  route_30:
    links:
      s33,o2: s46,o1
    routing_strategy: route_bundle
    settings: {}
  route_31:
    links:
      s33,o3: s47,o1
    routing_strategy: route_bundle
    settings: {}
  route_32:
    links:
      s34,o2: s48,o1
    routing_strategy: route_bundle
    settings: {}
  route_33:
    links:
      s34,o3: s49,o1
    routing_strategy: route_bundle
    settings: {}
  route_34:
    links:
      s35,o2: s410,o1
    routing_strategy: route_bundle
    settings: {}
  route_35:
    links:
      s35,o3: s411,o1
    routing_strategy: route_bundle
    settings: {}
  route_36:
    links:
      s36,o2: s412,o1
    routing_strategy: route_bundle
    settings: {}
  route_37:
    links:
      s36,o3: s413,o1
    routing_strategy: route_bundle
    settings: {}
  route_38:
    links:
      s37,o2: s414,o1
    routing_strategy: route_bundle
    settings: {}
  route_39:
    links:
      s37,o3: s415,o1
    routing_strategy: route_bundle
    settings: {}
warnings: {}
yaml.dump(s.netlist.model_dump(exclude_none=True), open("schematic.yaml", "w"))

Python routing#

n = 2**3
splitter = gf.components.splitter_tree(noutputs=n, spacing=(50, 50))
dbr_array = gf.components.array(
    component=gf.c.dbr, rows=n, columns=1, spacing=(0, 3), centered=True
)
s = gt.Schematic()
s.add_instance("s", gt.Instance(component=splitter))
s.add_instance("dbr", gt.Instance(component=dbr_array))
s.add_placement("s", gt.Placement(x=0, y=0))
s.add_placement("dbr", gt.Placement(x=300, y=0))

for i in range(n):
    s.add_net(
        gt.Net(
            p1=f"s,o2_2_{i+1}",
            p2=f"dbr,o1_{i+1}_1",
            name="splitter_to_dbr",
            settings=dict(radius=5, sort_ports=True, cross_section="strip"),
        )
    )

g = s.plot_graphviz()
Warning: node s, port o2_2_1 unrecognized
Warning: node dbr, port o1_1_1 unrecognized
Warning: node s, port o2_2_2 unrecognized
Warning: node dbr, port o1_2_1 unrecognized
Warning: node s, port o2_2_3 unrecognized
Warning: node dbr, port o1_3_1 unrecognized
Warning: node s, port o2_2_4 unrecognized
Warning: node dbr, port o1_4_1 unrecognized
Warning: node s, port o2_2_5 unrecognized
Warning: node dbr, port o1_5_1 unrecognized
Warning: node s, port o2_2_6 unrecognized
Warning: node dbr, port o1_6_1 unrecognized
Warning: node s, port o2_2_7 unrecognized
Warning: node dbr, port o1_7_1 unrecognized
Warning: node s, port o2_2_8 unrecognized
Warning: node dbr, port o1_8_1 unrecognized
../_images/dd4653c3efb3e6b4d206861fd118dca136e57ab27a07037095ff25d5546c02ad.png
dbr_array.pprint_ports()
┏━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ name    width  orientation  layer     center         port_type ┃
┡━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ o1_1_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, -10.5) │ optical   │
│ o1_2_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, -7.5)  │ optical   │
│ o1_3_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, -4.5)  │ optical   │
│ o1_4_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, -1.5)  │ optical   │
│ o1_5_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, 1.5)   │ optical   │
│ o1_6_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, 4.5)   │ optical   │
│ o1_7_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, 7.5)   │ optical   │
│ o1_8_1 │ 0.5   │ 180.0       │ WG (1/0) │ (-1.6, 10.5)  │ optical   │
└────────┴───────┴─────────────┴──────────┴───────────────┴───────────┘
splitter.pprint_ports()
┏━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ name    width  orientation  layer     center          port_type ┃
┡━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ o1_0_0 │ 0.5   │ 180.0       │ WG (1/0) │ (-10.0, 0.0)   │ optical   │
│ o2_2_1 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, -62.5) │ optical   │
│ o2_2_2 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, -87.5) │ optical   │
│ o2_2_3 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, -12.5) │ optical   │
│ o2_2_4 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, -37.5) │ optical   │
│ o2_2_5 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, 37.5)  │ optical   │
│ o2_2_6 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, 12.5)  │ optical   │
│ o2_2_7 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, 87.5)  │ optical   │
│ o2_2_8 │ 0.5   │ 0.0         │ WG (1/0) │ (165.5, 62.5)  │ optical   │
└────────┴───────┴─────────────┴──────────┴────────────────┴───────────┘
yaml.dump(s.netlist.model_dump(exclude_none=True), open("schematic.yaml", "w"))
yaml_component = yaml.dump(s.netlist.model_dump(exclude_none=True))
print(yaml_component)
connections: {}
info: {}
instances:
  dbr:
    component: array
    settings:
      add_ports: true
      auto_rename_ports: false
      centered: true
      column_pitch: 150
      columns: 1
      component: dbr
      row_pitch: 150
      rows: 8
      spacing: !!python/tuple
      - 0
      - 3
  s:
    component: splitter_tree
    settings:
      bend_s: bend_s
      coupler: mmi1x2
      cross_section: strip
      noutputs: 8
      spacing: !!python/tuple
      - 50
      - 50
nets: []
pdk: ''
placements:
  dbr:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: 0.0
ports: {}
routes:
  splitter_to_dbr:
    links:
      s,o2_2_1: dbr,o1_1_1
      s,o2_2_2: dbr,o1_2_1
      s,o2_2_3: dbr,o1_3_1
      s,o2_2_4: dbr,o1_4_1
      s,o2_2_5: dbr,o1_5_1
      s,o2_2_6: dbr,o1_6_1
      s,o2_2_7: dbr,o1_7_1
      s,o2_2_8: dbr,o1_8_1
    routing_strategy: route_bundle
    settings:
      cross_section: strip
      radius: 5
      sort_ports: true
warnings: {}
from gdsfactory.serialization import convert_tuples_to_lists

conf = s.netlist.model_dump(exclude_none=True)
conf = convert_tuples_to_lists(conf)
yaml_component = yaml.dump(conf)
print(yaml_component)
connections: {}
info: {}
instances:
  dbr:
    component: array
    settings:
      add_ports: true
      auto_rename_ports: false
      centered: true
      column_pitch: 150
      columns: 1
      component: dbr
      row_pitch: 150
      rows: 8
      spacing:
      - 0
      - 3
  s:
    component: splitter_tree
    settings:
      bend_s: bend_s
      coupler: mmi1x2
      cross_section: strip
      noutputs: 8
      spacing:
      - 50
      - 50
nets: []
pdk: ''
placements:
  dbr:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 300.0
    y: 0.0
  s:
    dx: 0
    dy: 0
    mirror: false
    rotation: 0
    x: 0.0
    y: 0.0
ports: {}
routes:
  splitter_to_dbr:
    links:
      s,o2_2_1: dbr,o1_1_1
      s,o2_2_2: dbr,o1_2_1
      s,o2_2_3: dbr,o1_3_1
      s,o2_2_4: dbr,o1_4_1
      s,o2_2_5: dbr,o1_5_1
      s,o2_2_6: dbr,o1_6_1
      s,o2_2_7: dbr,o1_7_1
      s,o2_2_8: dbr,o1_8_1
    routing_strategy: route_bundle
    settings:
      cross_section: strip
      radius: 5
      sort_ports: true
warnings: {}
c = gf.read.from_yaml(yaml_component)
c
../_images/5587aa5d945dd305dc3a083ebc501d5622723268938484b8a443d923bca87ae7.png