component_from_netlist

photonforge.component_from_netlist(netlist)

Create a component from a netlist description.

Parameters:

netlist (dict[str, Any]) – Dictionary with the component description. The only required key is 'instances', which describes the references to all sub-components. See other keys in the example below.

Return type:

Component

Examples

>>> coupler = parametric.dual_ring_coupler(
...     port_spec="Strip",
...     coupling_distance=0.6,
...     radius=4,
... )
... bus = parametric.ring_coupler(
...     port_spec="Strip",
...     coupling_distance=0.6,
...     radius=4,
...     bus_length=5,
... )
>>> netlist1 = {
...     "name": "RING",
...     "instances": {"COUPLER": coupler, "BUS_0": bus, "BUS_1": bus},
...     "instance_models": [
...         ("COUPLER", DirectionalCouplerModel(0.8, -0.5j)),
...     ],
...     "connections": [
...         (("COUPLER", "P0"), ("BUS_0", "P1")),
...         (("BUS_1", "P1"), ("COUPLER", "P3")),
...     ],
...     "ports": [
...         ("BUS_0", "P0"),
...         ("BUS_0", "P2"),
...         ("BUS_1", "P2"),
...         ("BUS_1", "P0"),
...     ],
...     "models": [CircuitModel()],
... }
>>> component1 = component_from_netlist(netlist1)
>>> netlist2 = {
...     "instances": [
...         coupler,
...         {"component": bus, "origin": (0, -12)},
...         {"component": bus, "origin": (3, 7), "rotation": 180},
...     ],
...     "virtual connections": [
...         ((0, "P0"), (1, "P1")),
...         ((0, "P2"), (1, "P3")),
...         ((2, "P3"), (0, "P1")),
...     ],
...     "routes": [
...         ((1, "P2"), (2, "P0"), {"radius": 6}),
...         ((2, "P1"), (0, "P3"), parametric.route_s_bend),
...     ],
...     "ports": [
...         (1, "P0", "In"),
...         (2, "P2", "Add"),
...     ],
...     "models": [(CircuitModel(), "Circuit")],
... }
>>> component2 = component_from_netlist(netlist2)
>>> spec = cpw_spec("METAL", 3, 1)
... tl = parametric.straight(port_spec=spec, length=20)
... terminal = Terminal(
...     "METAL", Rectangle(center=(-10, 20), size=(2, 2))
... )
... tl.add_terminal(terminal, "T0")
... netlist3 = {
...     "instances": [tl],
...     "terminal routes": [
...         ((0, "T0"), (0, ("E0", "gnd0"))),
...     ],
...     "terminals": [
...         (0, "T0", "GND0"),
...         (0, ("E1", "gnd0"), "GND1"),
...     ],
... }
>>> component3 = component_from_netlist(netlist3)

The value in "instances" can be a dictionary or a list, in which case, index numbers are used in place of the keys. Each value is can be a Component or another dictionary with keyword arguments to create a Reference.

Sub-components can receive extra models from "instance_models". The last added model for each sub-component will be active.

The "connections" list specifies connections between instances. Each item is of the form ((key1, port1), (key2, port2)), indicating that the reference key1 must be transformed to have its port1 connected to port2 from the reference key2.

Items in the "routes" list contain 2 reference ports, similarly to "connections", plus an optional routing function and a dictionary of keyword arguments to the function: ((key1, port1), (key2, port2), route_function, kwargs_dict). If route_function is not provided, photonforge.parametric.route() is used.

A list of "terminal routes" can be also be specified analogously to "routes", with the difference that only terminal routing functions can be used and photonforge.parametric.route_manhattan() is the default. Terminals within ports can also be used by replacing the terminal name string with a tuple (port_name, terminal_name).

The "ports" list specify the top-level component ports derived from instance ports from (key, port) or (key, port, new_name). The same goes for the "terminals" lists, except that terminal names can be replaced by a (port_name, terminal_name) tuple to indicate a terminals within a port.