Missing net in layout¶
File: pics/simple_splitter_with_error.pic.yml
Error caught: net — connection mmi,o3 ↔ wg_out2,o1 is declared in the schematic but the ports don't meet in the layout because wg_out2 is offset.
Error type: LVS.net.missing_in_layout
Expected: ok=False, error_count=3
import copy
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")
BUILD_GDS.mkdir(parents=True, exist_ok=True)
PIC = PICS / "simple_splitter_with_error.pic.yml"
Schematic¶
The schematic places wg_out2 with an extra dx=2.247, dy=-10.826 offset — shifting it ~11 µm south of its nominal position and breaking the connection to mmi,o3.
{'simple_splitter_with_error': {'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', 'wg_in,o2': 'mmi,o1'},
'nets': [{'p1': 'mmi,o3', 'p2': 'wg_out2,o1'}],
'ports': {'o1': 'wg_in,o1', '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,
'dx': 2.247,
'dy': -10.826,
'rotation': 0,
'mirror': False}}}}
Note
note the explicitly added net:
'nets': [{'p1': 'mmi,o3', 'p2': 'wg_out2,o1'}],
Which is the promise we won't be keeping in this netlist.
Build from schematic¶
gds_path = BUILD_GDS / "simple_splitter_with_error.gds"
c = gf.read.from_yaml(schematic["simple_splitter_with_error"])
c.write_gds(gds_path)
show(gds_path, netlist=PIC, tools=[Tool.FIT_ALL, Tool.INSTANCE_PORTS])
The Bug: Placement Offset Breaks the Connection¶
wg_out2 is declared in the schematic with an explicit dx/dy offset:
placements:
wg_out2:
x: 15.5
y: -0.625
dx: 2.247
dy: -10.826 # ← shifts wg_out2 ~11 µm off its nominal position
In GDSFactory placements, dx/dy adds to x/y, so wg_out2 ends up at (17.747, -11.451) instead of (15.5, -0.625). Its o1 port no longer aligns with mmi,o3 — Elvis cannot find the wire and reports the connection as missing in the layout.
LVS Results¶
rdb = elvis.lvs_rdb(gds_path, schematic)
lyrdb = Path(tempfile.gettempdir()) / "simple_splitter_with_error.lyrdb"
rdb.save(str(lyrdb))
show(gds_path, lyrdb=lyrdb, netlist=PIC, tools=[Tool.FIT_ALL])
Net errors in detail:
print(f"ok={rdb.num_items() == 0}, error_count={rdb.num_items()}")
Markdown(elvis.error_summary(rdb))
ok=False, error_count=3
| cell | error type | description |
|---|---|---|
| simple_splitter_with_error | LVS.net.missing_in_layout | Net mmi,o3 <-> wg_out2,o1 in schematic but not in layout |
| simple_splitter_with_error | LVS.open | Open port: mmi,o3 is not connected |
| simple_splitter_with_error | LVS.open | Open port: wg_out2,o1 is not connected |
Fix¶
Correct the placement in simple_splitter_with_error.pic.yml — remove or zero out the offset:
schematic_fixed = copy.deepcopy(schematic)
wg_out2_pl = schematic_fixed["simple_splitter_with_error"]["placements"]["wg_out2"]
# place port o1 of 'wg_out2' at the x and y position of port o3 of 'mmi'
wg_out2_pl["port"] = "o1"
wg_out2_pl["x"] = "mmi,o3"
wg_out2_pl["y"] = "mmi,o3"
wg_out2_pl["dx"] = 0.0
wg_out2_pl["dy"] = 0.0
# or alternatively connect wg_out2,o1 to mmi,o3
# note: the order when connecting is important:
# the first one gets moved (and possibly rotated) to the second one.
connections = schematic_fixed["simple_splitter_with_error"]["connections"]
connections["wg_out2,o1"] = "mmi,o3"
c_fixed = gf.read.from_yaml(schematic_fixed["simple_splitter_with_error"])
c_fixed.write_gds(gds_path)
rdb_fixed = elvis.lvs_rdb(gds_path, schematic_fixed)
rdb_fixed.save(str(lyrdb))
show(gds_path, lyrdb=lyrdb, netlist=PIC, tools=[Tool.FIT_ALL])
Why it matters¶
Unconnected instances can happen in many circumstances:
- You forgot to connect them
- You connected them but then moved them (the flexibility and dynamic nature of GDSFactory can be a blessing and a curse)
- There is a small nanometer sized gap between two components that are supposed to be connected (the most devious of all the occurences)
Elvis catches all of these circumstances.