Repository navigation
Conversation
KLayout's SPICE reader folds a subcircuit's default parameters into its NAME: `l=0.28u w=3u m=1` turns the circuit into `TWO_TRANSISTOR_INTERDIGITIZED(L=0.28U,M=1,W=3U)`, after which the gf180 klayout deck cannot match it to the layout's top cell and aborts with "Can't find a schematic counterpart for the top cell". The device lines carry l/w/m explicitly, so the defaults on the .subckt line were never used. sky130 goes through magic+netgen and is unaffected, which is why this only ever showed up on gf180. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Gate the cached venv on a `.installed` marker written after a successful install, rather than on the python binary existing: a half-built venv used to look like a cache hit forever. Also stop discarding `uv pip install` output so failures are visible.
Same defect as the previous commit, second instance. KLayout's SPICE reader
folds a subcircuit's default parameters into its *name*, so
.subckt DIFF_TO_SINGLE VIN VOUT VSS VSS2 l=1.0 w=6.0 mt=8 mb=10
is read back as the circuit `DIFF_TO_SINGLE(L=1.0,MB=10,MT=8,W=6.0)`. The gf180
klayout deck then cannot match it to the layout's top cell and aborts with
"Can't find a schematic counterpart for the top cell", which the runner reports
as the catch-all "LVS inconclusive (0 mismatches)" -- zero comparisons, not zero
errors.
Unlike two_transistor_interdigitized the device lines here referenced the subckt
parameters as l={l} w={w} m={mt}, so the values are inlined instead. The emitted
netlist is electrically identical; only the parameterisation moves from the
subckt header onto the device lines.
gf180 now produces a real comparison:
before LVS inconclusive (0 mismatches)
after Netlists do not match (11 mismatches)
- extra top-level pin(s) in layout: SUB
That remaining mismatch is a genuine discrepancy this change makes visible for
the first time; it is not fixed here. sky130 is unchanged at 5 mismatches
(Magic's PMOS-bulk mis-extraction, the reason this cell is on the default
--skip-cells list). CI is unaffected for the same reason.
…uilds
gf180 has two mutually exclusive MIM stacks. glayout builds option B --
`mimcap` and `mimcap_array` both default to option="B" (primitives/mimcap.py:56,
:333), which is the met4/FuseTop/met5 stack -- but the LVS runner defaulted to
option A (met2/FuseTop/met3).
Extracting A against a B layout yields no capacitor at all, so every MIM in the
cell showed up as missing:
[FAIL] opamp: Netlists do not match (3 mismatches)
1 schematic device(s) missing from layout, first 1.2.0.1 [CAP_MIM_2F0FF]
The capacitors were always there: opamp.gds carries FuseTop (75/0) x6 and
MIM_L_MK (117/10) x6 alongside Metal4 and Metal5, six of each matching the six
MIMCap instances in the netlist.
With the default corrected, gf180 LVS is green across every cell, opamp
included. $GF180_MIM_OPTION still overrides for a layout genuinely built on the
met2/met3 stack.
Note the --mim-option flag already existed and was documented, but
.github/workflows/lvs.yml never passed it, so CI has been extracting the wrong
stack for every gf180 cell with a MIM. Fixing the default means the workflow
needs no change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Branch:
lvs-harness-fixes→main· 4 commits · no layout changesThree independent bugs in the LVS harness, each of which made gf180 report
something other than the truth. None of them touch a cell's geometry.
1 & 2 —
.subcktdefault params break the gf180 deckKLayout's SPICE reader folds a subcircuit's default parameters into its name.
So a netlist emitting
is read back as the circuit
TWO_TRANSISTOR_INTERDIGITIZED(L=0.28U,M=1,W=3U).The gf180 deck then cannot match it to the layout's top cell and aborts:
_parsehas no branch for that string, so it falls through to the catch-all"LVS inconclusive"withunmatched_nets: 0— which reads as "0 mismatches".There genuinely were zero comparisons, not zero errors. Extraction itself was
fine; the
.cirhad every device.Two cells were affected.
two_transistor_interdigitized's device lines alreadycarried
l/w/mexplicitly so the defaults were dead weight; the converter'sbody referenced them (
l={l} w={w} m={mt}), so the values are inlined instead.Both netlists are electrically identical afterwards.
transmission_gatewas never affected — its top-level.subcktcarries onlynode names. Its inner
NMOS/PMOSsubckts do have params and get the sameparenthesised names, but they are not the top cell and match structurally.
3 — gf180 was extracting the wrong MIM stack
gf180 has two mutually exclusive MIM stacks. glayout builds option B
(
mimcapandmimcap_arrayboth default tooption="B", met4/FuseTop/met5),but the runner extracted option A (met2/FuseTop/met3). Extracting A against a
B layout yields no capacitor at all:
The capacitors were always present —
opamp.gdscarries FuseTop (75/0) ×6 andMIM_L_MK (117/10) ×6 alongside Metal4/Metal5, six of each matching the six
MIMCapinstances.$GF180_MIM_OPTIONstill overrides.The
--mim-optionflag already existed and was documented, but.github/workflows/lvs.ymlnever passed it, so CI has been extracting the wrongstack for every gf180 cell with a MIM. Fixing the default means the workflow
needs no change.
Result
Full DRC + LVS, both PDKs, measured on this branch off
main:opampFAIL,two_transistor_interdigitizedinconclusiveopamp1 mismatchopamp1 mismatchThe remaining sky130
opampfailure is pre-existing and unrelated — Magicmis-extracts the PMOS bulk of
differential_to_single_ended_converter(thedocumented reason that cell is on the default
--skip-cellslist), which strandstwo pfet source/drains off the inter-stage net. gf180 extracts the same source
layout as connected. Not addressed here.
Also included:
tests: rebuild stale venvs in the local CI bootstrap, adev-tooling fix to
run_ci_locally.py.Follow-up worth doing separately
_parseshould get an explicit branch for "Can't find a schematic counterpart"so a name mismatch stops reporting as the catch-all. It cost two diagnoses.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RExJUxLyBEHcQRb6GprVSL