Skip to content

Electrical Short (Through Hierarchy)

File: pics/two_elec.pic.yml + pics/elec.pic.yml

Error caught: short + net.missing_in_schematic — the routing wires inside each elec instance cross on the same metal layer, and the two instances are placed so their wires also overlap. Three geometric shorts transitively tie six pad ports onto a single electrical net that the schematic doesn't declare.

Error type: LVS.short

Expected: ok=False, error_count=4 (3 shorts + 1 missing_in_schematic net group)

import tempfile
from copy import deepcopy
from pathlib import Path

import elvis
import gdsfactory as gf
from gdsfactory.gpdk import PDK
from IPython.display import Markdown
from kwasm import Tool, show

PDK.activate()

PICS = Path("../pics")
BUILD_GDS = Path("../build/gds")
BUILD_GDS.mkdir(parents=True, exist_ok=True)
PIC_UP = PICS / "two_elec.pic.yml"
PIC_DOWN = PICS / "elec.pic.yml"

Schematic

two_elec.pic.yml places two elec instances. instance1 is rotated 90° — observe how its ports rotate accordingly. elec.pic.yml routes four pads in two pairs on the same metal layer.

schematic = elvis.load_schematics(PIC_UP, PIC_DOWN)
schematic
{'two_elec': {'instances': {'instance1': {'component': 'elec', 'settings': {}},
   'instance2': {'component': 'elec', 'settings': {}}},
  'ports': {},
  'placements': {'instance1': {'x': 0,
    'y': 0,
    'dx': 491.989,
    'dy': -104.859,
    'rotation': 90,
    'mirror': False},
   'instance2': {'x': 100,
    'y': 0,
    'dx': 267.46,
    'dy': 53.93,
    'rotation': 0,
    'mirror': False}}},
 'elec': {'instances': {'pad1': {'component': 'pad', 'settings': {}},
   'pad2': {'component': 'pad', 'settings': {}},
   'pad3': {'component': 'pad', 'settings': {}},
   'pad4': {'component': 'pad', 'settings': {}}},
  'routes': {'electrical': {'links': {'pad1,e3': 'pad2,e1'},
    'routing_strategy': 'route_bundle_electrical',
    'settings': {'allow_layer_mismatch': False,
     'allow_type_mismatch': False,
     'allow_width_mismatch': False}},
   'electrical2': {'links': {'pad3,e3': 'pad4,e3'},
    'routing_strategy': 'route_bundle_electrical',
    'settings': {'allow_layer_mismatch': False,
     'allow_type_mismatch': False,
     'allow_width_mismatch': False,
     'radius': 10}}},
  'ports': {},
  'placements': {'pad1': {'x': 0, 'y': 0, 'dx': -98.125, 'dy': -19.273},
   'pad2': {'x': 0,
    'y': 0,
    'dx': 349.71,
    'dy': -394.94,
    'rotation': 0,
    'mirror': False},
   'pad3': {'x': -98.125,
    'y': -19.273,
    'dx': -97.005,
    'dy': -423.277,
    'rotation': 0,
    'mirror': False},
   'pad4': {'x': 0,
    'y': 0,
    'dx': 137.75,
    'dy': -124.39,
    'rotation': 0,
    'mirror': False}}}}

Build from schematic

# for the top-level to work the lower levels needs to be registered.
# tools like gdsfactoryplus do this automatically for you.
if "elec" not in PDK.cells:
    elec = gf.read.from_yaml(schematic["elec"], name="elec")
    PDK.cells["elec"] = lambda: elec

c = gf.read.from_yaml(schematic["two_elec"], name="two_elec")
gds_path = BUILD_GDS / "two_elec.gds"
c.write_gds(gds_path)
show(gds_path, tools=[Tool.FIT_ALL])
GDS Layout Preview

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()) / "two_elec.lyrdb"
rdb.save(str(lyrdb))
show(gds_path, lyrdb=lyrdb, tools=[Tool.FIT_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.

The three LVS.short errors transitively tie six pad ports (across both elec instances) onto a single electrical net that the schematic doesn't declare. Elvis reports that as one LVS.net.missing_in_schematic group error — rendered with set notation {instance1~pad2,{pad,e1,e2,e3,e4}; instance1~pad4,{pad,e1,e2,e3,e4}; instance2~pad1,{pad,e1,e2,e3,e4}; …}. The underlying cross-pairs (25 × 6 = many) are listed in the rdb item's comment field. (See notebook 09 for the equivalent-port and net-group merge steps explained in isolation.)

print(f"ok={rdb.num_items() == 0}, error_count={rdb.num_items()}")
Markdown(elvis.error_summary(rdb))
ok=False, error_count=4
cell error type description
two_elec LVS.net.missing_in_schematic Net {instance2~pad2,{pad,e1,e2,e3,e4}; instance2~pad4,{pad,e1,e2,e3,e4}; instance2~pad1,{pad,e1,e2,e3,e4}; instance1~pad2,{pad,e1,e2,e3,e4}; instance1~pad4,{pad,e1,e2,e3,e4}; instance2~pad3,{pad,e1,e2,e3,e4}; instance1~pad1,{pad,e1,e2,e3,e4}; instance1~pad3,{pad,e1,e2,e3,e4}} in layout but not in schematic
two_elec LVS.short Geometric short between 'instance2~pad4,e3 -> instance2~pad3,e3' and 'instance1~pad2,e1 -> instance1~pad1,e3' (1 location)
two_elec LVS.short Geometric short between 'instance2~pad4,e3 -> instance2~pad3,e3' and 'instance2~pad1,e3 -> instance2~pad2,e1' (1 location)
two_elec LVS.short Geometric short between 'instance1~pad2,e1 -> instance1~pad1,e3' and 'instance1~pad3,e3 -> instance1~pad4,e3' (1 location)

Fix

There are obviously two sets of errors here:

  1. The LVS errors on the lower hierarchy are reported, we can't fix those in this hierarchy (see the "Electrical Short" example for that)
  2. On this hierarchy, the two instances are overlapping. We can fix that by moving instance2.
schematic2 = deepcopy(schematic)
schematic2["two_elec"]["placements"]["instance1"]["dx"] += 500
c = gf.read.from_yaml(schematic2["two_elec"], name="two_elec2")
c.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, tools=[Tool.FIT_ALL])
GDS Layout Preview
print(f"ok={rdb.num_items() == 0}, error_count={rdb.num_items()}")
Markdown(elvis.error_summary(rdb))
ok=False, error_count=4
cell error type description
two_elec LVS.net.missing_in_schematic Net {instance1~pad1,{pad,e1,e2,e3,e4}; instance1~pad3,{pad,e1,e2,e3,e4}; instance1~pad4,{pad,e1,e2,e3,e4}; instance1~pad2,{pad,e1,e2,e3,e4}} in layout but not in schematic
two_elec LVS.net.missing_in_schematic Net {instance2~pad1,{pad,e1,e2,e3,e4}; instance2~pad4,{pad,e1,e2,e3,e4}; instance2~pad2,{pad,e1,e2,e3,e4}; instance2~pad3,{pad,e1,e2,e3,e4}} in layout but not in schematic
two_elec LVS.short Geometric short between 'instance1~pad2,e1 -> instance1~pad1,e3' and 'instance1~pad4,e3 -> instance1~pad3,e3' (1 location)
two_elec LVS.short Geometric short between 'instance2~pad2,e1 -> instance2~pad1,e3' and 'instance2~pad3,e3 -> instance2~pad4,e3' (1 location)

Note

Even though the error count did not go down we did remove the short on this hierarchy level, which is what we care about. Our fix also separates the nets of the underlying instances. Those instances have problems of their own, which we show how to fix in the first "Electrical Short" discussion