add_route_astar finds a path from one port to another that avoids
the listed obstacle layers — useful when you don't want to dictate
the route shape but the wire has to navigate around existing
components (waveguides, bond pads, MMIs, fences, …).
This is optical routing, so we route on a waveguide cross-section
and use bend_euler for the bends — sharp corners would scatter the
mode and break the loss budget. The bend radius must be ≥ the PDK's
minimum; here we use 5 µm for cspdk.si220.cband.
The grid the A* algorithm searches over is set by grid_unit (in
dbu). A finer grid finds tighter paths but costs more solve time;
coarser is faster but can miss valid routes through narrow gaps.
Imports
Single Route on a Test Field
dr.pcells.field1() is a small example layout with in and out
named instances and a handful of waveguide stubs scattered between
them as obstacles — a stand-in for the kind of crowded floorplan you
might be routing through. A* finds a path on the WG (waveguide)
layer that doesn't cross any of those obstacles.
c = gf.Component()
ref = c << dr.pcells.field1()
dr.add_route_astar(
c=c,
start=ref.cell.insts["in"].ports["o2"],
stop=ref.cell.insts["out"].ports["o1"],
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
layers=["WG"], # obstacles to avoid
grid_unit=500, # A* grid pitch (dbu) — smaller = tighter paths, more solve time
)
dr.util.show_cell(c)
API key for organization 'DoPlayDo' found.
Next steps
- Need to route N parallel waveguides as a single bundle? See A* Bundle Routing.
- Want full control over the route shape instead of an algorithmic search? See Corners Routing and Steps Routing.
- Build whole circuits from a YAML description that calls into A*? See Circuit From Netlist.