Skip to content

Net Missing in Layout

File: pics/metal_polys_scm.pic.yml

Error caught: net — the schematic declares pad1,e3 ↔ pad2,e1 but no metal trace exists in the GDS to physically connect them.

Error type: LVS.net.missing_in_layout

Expected: ok=False, error_count=3

import sys
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 / "metal_polys_scm.pic.yml"
BUILD_GDS.mkdir(parents=True, exist_ok=True)

sys.path.insert(0, str(PICS.parent))

Schematic

Two pads 1000 µm apart, connected by a single nets: entry. No routing geometry — the connection is declared without explicit route components.

schematic = elvis.load_schematics(PIC)
schematic
{'metal_polys_scm': {'instances': {'pad1': {'component': 'pad',
    'settings': {}},
   'pad2': {'component': 'pad', 'settings': {}}},
  'nets': [{'p1': 'pad1,e3', 'p2': 'pad2,e1'}],
  'ports': {},
  'placements': {'pad1': {'x': 0.0, 'y': 0.0, 'dx': 0, 'dy': 0},
   'pad2': {'x': 1000, 'y': 0.0, 'dx': 0, 'dy': 0}}}}

Build from schematic

gds_path = BUILD_GDS / "metal_polys_scm.gds"
c = gf.read.from_yaml(schematic["metal_polys_scm"])
c.write_gds(gds_path)
show(gds_path, netlist=PIC, tools=[Tool.RULER, Tool.CLEAR_ALL, Tool.TOP_PORTS])
GDS Layout Preview

Tip: Use the ruler to measure the ~1000µm separation between pads.

LVS Results

rdb = elvis.lvs_rdb(
    gds_path,
    schematic,
    short_layers=[(49, 0)],
    equivalent_ports={"pad": ["pad", "e1", "e2", "e3", "e4"]},
)
lyrdb = Path(tempfile.gettempdir()) / "metal_polys_scm.lyrdb"
rdb.save(str(lyrdb))
show(
    gds_path,
    lyrdb=lyrdb,
    netlist=PIC,
    tools=[Tool.SELECT, Tool.RULER, Tool.CLEAR_ALL],
)
GDS Layout Preview

flags used

The above LVS function is called with the following flags

  • short_layers=[(49, 0)]
  • equivalent_ports={'pad': ["pad", "e1", "e2", "e3", "e4"]}

this can also be pre-configured.

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
metal_polys_scm LVS.net.missing_in_layout Net pad1,{pad,e1,e2,e3,e4} <-> pad2,{pad,e1,e2,e3,e4} in schematic but not in layout
metal_polys_scm LVS.open Open port: pad2,{pad,e1,e2,e3,e4} is not connected
metal_polys_scm LVS.open Open port: pad1,{pad,e1,e2,e3,e4} is not connected

Fix

Add a route_bundle_electrical route between the pads in metal_polys_scm.pic.yml:

routes:
  metal_route:
    links:
      pad1,e3: pad2,e1
    routing_strategy: route_bundle_electrical

Another Fix

You can also just draw an electrical polygon directly. This is something electrical layout engineers like to do.

c2 = gf.read.from_yaml(schematic["metal_polys_scm"])
c2.add_polygon([(0, 0), (1000, 0), (1000, 10), (0, 10)], layer=(49, 0))
c2.write_gds(gds_path)
rdb = elvis.lvs_rdb(
    gds_path,
    schematic,
    short_layers=[(49, 0)],
    equivalent_ports={"pad": ["pad", "e1", "e2", "e3", "e4"]},
)
rdb.save(str(lyrdb))
show(
    gds_path,
    lyrdb=lyrdb,
    netlist=PIC,
    tools=[Tool.SELECT, Tool.RULER, Tool.CLEAR_ALL],
)
GDS Layout Preview

Why it matters

A nets: entry is a declaration of intent in the schematic — it says two ports belong to the same net — but it does not place any routing geometry. If the corresponding route is missing from the GDS, the two pads are physically disconnected even though the schematic says they should be connected. Elvis checks that every declared connection has a physical counterpart, turning silent omissions into explicit errors.