Open port¶
File: pics/simple_splitter.pic.yml
Error caught: open — port wg_in,o1 is connected in the layout but never promoted to a top-level schematic port.
Error type: LVS.open
Expected: ok=False, error_count=1
import tempfile
from pathlib import Path
import elvis
import gdsfactory as gf
from IPython.display import Markdown
from kwasm import Tool, show
gf.gpdk.PDK.activate()
PICS = Path("../pics")
BUILD_GDS = Path("../build/gds")
PIC = PICS / "simple_splitter.pic.yml"
BUILD_GDS.mkdir(parents=True, exist_ok=True)
Schematic¶
The schematic declares two top-level ports (o2, o3) but omits o1.
wg_in,o1 — the free end of the input waveguide — is left dangling.
{'simple_splitter': {'instances': {'mmi': {'component': 'mmi1x2',
'settings': {}},
'wg_in': {'component': 'straight', 'settings': {'length': 10}},
'wg_out1': {'component': 'straight', 'settings': {'length': 10}},
'wg_out2': {'component': 'straight', 'settings': {'length': 10}}},
'connections': {'mmi,o2': 'wg_out1,o1',
'mmi,o3': 'wg_out2,o1',
'wg_in,o2': 'mmi,o1'},
'ports': {'o2': 'wg_out1,o2', 'o3': 'wg_out2,o2'},
'placements': {'mmi': {'x': 0, 'y': 0},
'wg_in': {'x': -20, 'y': 0},
'wg_out1': {'x': 15.5, 'y': 0.625},
'wg_out2': {'x': 15.5, 'y': -0.625}}}}
Build from schematic¶
c = gf.read.from_yaml(schematic["simple_splitter"])
gds_path = BUILD_GDS / "simple_splitter.gds"
c.write_gds(gds_path)
show(gds_path, netlist=PIC, tools=[Tool.FIT_ALL, Tool.DANGLING_PORTS])
LVS Results¶
rdb = elvis.lvs_rdb(gds_path, schematic)
rdb_path = Path(tempfile.gettempdir()) / "simple_splitter.lyrdb"
rdb.save(str(rdb_path))
show(gds_path, lyrdb=rdb_path, netlist=PIC, tools=[Tool.FIT_ALL])
Open errors in detail:
print(f"ok={rdb.num_items() == 0}, error_count={rdb.num_items()}")
Markdown(elvis.error_summary(rdb))
ok=False, error_count=1
| cell | error type | description |
|---|---|---|
| simple_splitter | LVS.open | Open port: wg_in,o1 is not connected |
The Bug: Missing Port in ports:¶
The schematic ports: block only lists two of the three circuit I/O ports:
wg_in is a 2-port straight waveguide, so Elvis treats it as transparent routing.
Its free end (wg_in,o1) is reachable from the layout but has no corresponding top-level port in the schematic — Elvis flags it as an open (dangling) port.
Fix¶
Add the missing entry to ports: in simple_splitter.pic.yml:
schematic["simple_splitter"]["ports"]["o1"] = "wg_in,o1" # the fix
c2 = gf.read.from_yaml(schematic["simple_splitter"])
c2.write_gds(gds_path)
elvis.lvs_rdb(gds_path, schematic).save(str(rdb_path))
show(gds_path, lyrdb=rdb_path, netlist=PIC, tools=[Tool.FIT_ALL])
Why it matters¶
Open ports in optical waveguides can cause back-reflections and indicate an unfinished circuit. Promoting a port is a promise that it will be connected at a higher level of the hierarchy. If an open is intentional use a dedicated Terminator component (even a structurally empty one) with a single port to make the intent explicit.
Tip
Dangling / open / unused ports are such a common issue that we have a special tool in the gds viewer to find them. Use the 'dangling ports' tool in the first layout viewer to view the dangling ports without even having to run LVS.