Netlist Model
The Netlist is the central data structure in kfnetlist. It represents the
connectivity of a circuit cell: which sub-cell instances are placed, which of
their ports are connected, and which ports are exposed at the cell boundary.
Data model overview
| Attribute | Type | Description |
|---|---|---|
instances |
dict[str, NetlistInstance] |
Sub-cell instances keyed by name |
nets |
list[Net] |
Each net groups connected port members |
ports |
list[NetlistPort] |
Top-level ports exposed by this cell |
A Net is an ordered collection of net members — each member is one of:
| Type | Meaning |
|---|---|
NetlistPort |
A cell-level port (top-level pin) |
PortRef |
A port on a named instance |
PortArrayRef |
A port on a specific element of an array instance |
from kfnetlist import (
Net,
Netlist,
NetlistPort,
PortRef,
)
Creating a Netlist
Start with an empty Netlist and populate it with instances, ports, and nets.
nl = Netlist()
Instances
create_inst returns the created NetlistInstance. Each instance records the
PDK name (kcl), component name, and a settings dict.
inst1 = nl.create_inst(
"mmi1",
kcl="MY_PDK",
component="mmi1x2",
settings={"width": 500, "gap": 250},
)
inst2 = nl.create_inst(
"wg1",
kcl="MY_PDK",
component="straight",
settings={"width": 500, "length": 10_000},
)
print(f"Instances: {nl.instance_names()}")
print(f"has 'mmi1': {nl.has_instance('mmi1')}")
print(f"mmi1 component: {nl.get_instance('mmi1').component}")
print(f"mmi1 settings: {nl.get_instance('mmi1').settings}")
Instances: ['mmi1', 'wg1']
has 'mmi1': True
mmi1 component: mmi1x2
mmi1 settings: {'gap': 250, 'width': 500}
Array instances
Pass na and nb to create_inst to create an array instance. Use
PortArrayRef to reference ports on specific array elements.
nl2 = Netlist()
arr = nl2.create_inst(
"pad_array",
kcl="MY_PDK",
component="pad",
settings={"size": 100},
na=4,
nb=2,
)
print(f"Array: na={arr.array.na}, nb={arr.array.nb}")
Array: na=4, nb=2
Top-level ports
p_in = nl.create_port("in")
p_out1 = nl.create_port("out1")
p_out2 = nl.create_port("out2")
print("Ports:", [p.name for p in nl.ports])
Ports: ['in', 'out1', 'out2']
Nets
create_net takes two or more net members and records that they share
electrical connectivity.
nl.create_net(p_in, PortRef(instance="mmi1", port="o1"))
nl.create_net(PortRef(instance="mmi1", port="o2"), PortRef(instance="wg1", port="o1"))
nl.create_net(PortRef(instance="wg1", port="o2"), p_out1)
nl.create_net(PortRef(instance="mmi1", port="o3"), p_out2)
print(f"\nNets ({len(nl.nets)}):")
for i, net in enumerate(nl.nets):
members = []
for m in net:
if isinstance(m, PortRef):
members.append(f"{m.instance}.{m.port}")
elif isinstance(m, NetlistPort):
members.append(f"<{m.name}>")
print(f" net[{i}]: {' — '.join(members)}")
Nets (4):
net[0]: <in> — mmi1.o1
net[1]: mmi1.o2 — wg1.o1
net[2]: <out1> — wg1.o2
net[3]: <out2> — mmi1.o3
Adding pre-built nets
You can also build a Net object manually and add it with add_net.
nl3 = Netlist()
nl3.create_inst("a", kcl="X", component="comp_a")
nl3.create_inst("b", kcl="X", component="comp_b")
net = Net([PortRef(instance="a", port="out"), PortRef(instance="b", port="in")])
nl3.add_net(net)
print("Net members:", [f"{m.instance}.{m.port}" for m in nl3.nets[0]])
Net members: ['a.out', 'b.in']
Sorting
sort() normalises instance order, port order, and intra-net member order.
This makes equality checks between two netlists deterministic.
nl.sort()
print("Sorted instances:", nl.instance_names())
print("Sorted ports:", [p.name for p in nl.ports])
Sorted instances: ['mmi1', 'wg1']
Sorted ports: ['in', 'out1', 'out2']
Properties return snapshots
The instances, nets, and ports properties return fresh copies each
time they are accessed. This prevents accidental mutation of the internal
state — any changes must go through the mutation API (create_inst,
create_net, etc.).
instances_a = nl.instances
instances_b = nl.instances
assert instances_a is not instances_b
print("Properties return fresh snapshots ✓")
Properties return fresh snapshots ✓
Summary
| Operation | API |
|---|---|
| Create empty netlist | Netlist() |
| Add instance | nl.create_inst(name, kcl, component, settings, na, nb) |
| Check instance | nl.has_instance(name) / nl.get_instance(name) |
| List instance names | nl.instance_names() |
| Add top-level port | nl.create_port(name) |
| Create a net | nl.create_net(member1, member2, ...) |
| Add pre-built net | nl.add_net(net) |
| Normalise ordering | nl.sort() |
See Also
| Topic | Where |
|---|---|
| Port reference types | Ports & Refs |
| Serialization | Serialization |
| Equivalent ports | Guides: Equivalent Ports |