route_electrical

photonforge.parametric.route_electrical(*, terminal1=None, terminal2=None, strict_terminal_routing=None, width=None, spacing=None, layers=None, vias=None, obstacles=None, allow_diagonals=None, via_cost=None, via_cost_fraction=None, margin=None, max_depth=None, max_iterations=None, allow_partial=None, bundle=None, technology=None, name=None)[source]

Route between terminals, around obstacles and across layers.

Parameters:
  • terminal1 (Terminal | tuple[Reference, str] | tuple[Reference, str, int] | Sequence[Terminal | tuple[Reference, str] | tuple[Reference, str, int]] | None) – First terminal to be connected. The terminal can be specified as a photonforge.Terminal or as a tuple including a photonforge.Reference, the terminal name, and the repetition index (optional, only for array references).

  • terminal2 (Terminal | tuple[Reference, str] | tuple[Reference, str, int] | Sequence[Terminal | tuple[Reference, str] | tuple[Reference, str, int]] | None) – Second terminal to be connected. A sequence can be used for both arguments, of the same length, to route several pairs at once. Pairs whose terminals share metal (the same terminal, or the metal it sits on) are one net, so a net of more terminals is given as pairs that share them; nets routed together are kept apart from each other.

  • strict_terminal_routing (bool | None) – If True, routes run terminal to terminal. If False, a terminal given as a reference tuple is reached anywhere on its net (see notes), and a pair of a net of several pairs may end on a trace its net laid in the same call, so the net grows as a tree. If None, defaults to False, or to True for a bundle, which needs its exact endpoints.

  • width (Annotated[float, exclusiveMinimum=0, units='μm'] | dict[Annotated[str | tuple[int, int], _], Annotated[float, exclusiveMinimum=0, units='μm']] | None) – Trace width, either for all layers or per layer as a dictionary keyed by layer, by name or by number pair. A layer not given, or None, takes the min_width of its layer specification in the technology; a value below it raises a RuntimeWarning.

  • spacing (Annotated[float, exclusiveMinimum=0, units='μm'] | dict[Annotated[str | tuple[int, int], _], Annotated[float, exclusiveMinimum=0, units='μm']] | None) – Clearance the trace keeps from any obstacle, either for all layers or per layer as a dictionary keyed by layer, by name or by number pair. A layer not given, or None, takes the min_spacing of its layer specification in the technology; a value below it raises a RuntimeWarning. A layer only the vias reach that has neither takes the largest spacing of the routed layers.

  • layers (Sequence[Annotated[str | tuple[int, int], _]] | None) – Layers the route may run on. If None, the terminals’ routing layers and every layer the vias join are used.

  • vias (Sequence[Component] | None) – Components used to change layer, joining the layers of their terminals that are in layers. A via’s bounding box is kept clear of the obstacles on every conductive layer it has metal on, including the middle of a stack that no trace runs on.

  • obstacles (Sequence[Rectangle | Circle | Polygon | Path | Component | Reference] | Component | Reference | None) – Geometry the route must avoid. Use a sequence of 2D structures, or a Component or Reference. A terminal’s shape, and the metal it sits on in the element of the reference it names, are the route’s own: never in its way, and trace laid over them needs no clearance. For a route that will be added to a component, pass that component’s references, not the component: the argument is kept with the route, so the component would become one of its own dependencies.

  • allow_diagonals (bool | None) – Controls whether tracks at 45° are used alongside horizontal and vertical ones. A search through a congested region can take an order of magnitude longer with diagonals enabled. If None, defaults to False.

  • via_cost (Annotated[float, minimum=0, units='μm'] | None) – Extra length charged for each via. If None, defaults to 0.

  • via_cost_fraction (Annotated[float, minimum=0] | None) – Extra length charged for each via as a fraction of the Manhattan distance between the net’s own terminals, on top of via_cost. If None, defaults to 0.3.

  • margin (Annotated[float, exclusiveMinimum=0, units='μm'] | None) – Room added around the obstacles and terminals for the route to detour through, defining the bounding box for the route search. If None, defaults to 10 times the largest width.

  • max_depth (Annotated[int, minimum=0] | None) – Subdivision limit for the routing mesh away from terminals; a cell holding one is divided down to one track’s width. If None, defaults to 6.

  • max_iterations (Annotated[int, exclusiveMinimum=0] | None) – Passes the router may take to separate the nets. Pressure to keep off another net’s track starts gentle, so nets may share while they are still finding a shape, and rises over the first twelve passes until they must separate. The budget has to outlast that ramp and leave passes for the last few conflicts to come apart. When it runs out, the RuntimeError names every clashing pair of the best pass, by position in terminal1 and terminal2, with a point on their overlap. If None, defaults to 64.

  • allow_partial (bool | None) – If True, a net that cannot be routed, or kept apart from the others, is left out with a RuntimeWarning naming it by position, and the other nets are returned. If False, the call raises instead. A bundle routes or fails as a whole. If None, defaults to False.

  • bundle (bool | None) – If True, the nets travel together: one route is found and each net laid on its own track alongside it, keeping its place across the group the whole way. The members must be arranged alike at both ends, a whole number of tracks apart. If None, defaults to False.

  • technology (Technology | None) – Component technology. If None, the default technology is used.

  • name (str | None) – Component name.

Returns:

Component with the routes, including terminals and any vias. With several pairs, each net is a component of its own, referenced in the result and named with the position of its first pair in terminal1.

Return type:

Component

Notes

When connecting terminals strict_terminal_routing = False, only the nets present in the component referenced by the terminal can be searched. A route already added to a parent component, or geometry drawn there, is not part of the net because it cannot be reached from this function. To join an earlier route, name one of that route’s own terminals through its reference.

pads = pf.Component("PADS")
for i in range(3):
    pads.add_terminal(pf.Terminal("METAL", pf.Rectangle(center=(0, 30 * i), size=(20, 20))), f"T{i}")

block = pf.Component("BLOCK")
block.add("METAL", pf.Rectangle(center=(60, 30), size=(20, 50)))

ref1 = pf.Reference(pads)
ref2 = pf.Reference(pads, (120, 0))
ref3 = pf.Reference(block)

component = pf.parametric.route_electrical(
    terminal1=[(ref1, "T0"), (ref1, "T1"), (ref1, "T2")],
    terminal2=[(ref2, "T2"), (ref2, "T1"), (ref2, "T0")],
    width=4,
    spacing=3,
    obstacles=[ref3],
    allow_diagonals=True,
)
route_electrical