Repository navigation
Conversation
LVS-034 lacked KLayout's value filters and LVS-032 had no counterpart
to KLayout's same_nets between nets of different names.
`lvs max_res r` and `lvs min_caps c` leave out, on both sides and before
reduction, each resistor stating an r above r and each capacitor
stating a c below c, as KLayout's max_res and min_caps ("the netlist
compare will ignore resistor devices with a resistance value above the
given threshold"): opens. The layout's own value is read before
measures the reference does not declare are dropped, and the deck
interns r and c so the layout computes them. A device stating no value
stays. `lvs same_nets "layout" "reference"` seeds the labelled layout
net and the named reference net as a class of their own, as KLayout's
same_nets! holds them together; a pair whose wiring disagrees is left
unpaired. The deck parses, lowers, decompiles and prints all three.
Tests: compare_with on hand-built graphs (KLayout's definitions by
hand: thresholds either side of the values, each alone, and an
unvalued resistor kept; a symmetric pair held with and against the
reference's wiring); the X5 harness's oracle reads the same controls
from deck.md and the drawn fixtures match it end to end (a drawn
200 ohm resistor and 0.56 fF capacitor either side of each threshold,
a written 1 Mohm, and the same_nets cases); the deck parser's errors
and the printer round trip. Each breaks if a threshold is read the
wrong way round or unit, or if a same_nets row does not seed its pair.
LVS-043, LVS-044 and LVS-049 combined passives in parallel only, while
Netgen's relaxed topology and KLayout's combiners also chain them in
series, so a drawn resistor chain never matched one card of the sum.
Under `lvs topology relaxed` a resistor or capacitor stating its value
now merges in series with another of its model through a net only the
two touch and that is no port, their far ends on two other nets: r and
a resistor's l add, c combines harmonically, area and perim add, as
KLayout's ResistorDeviceCombiner::serial and CapacitorDeviceCombiner::
serial combine them; a resistor's w must agree, as Netgen's sky130
setup states `series {w critical}`. Ordered capacitor plates chain only
plate to plate (plates `lvs permute` joins either way); a ring, or a
chain closing on one net, stays as drawn. Diodes and bipolars never
merge in series, nor anything passive under the strict policy.
Tests: reduce_with on hand-built chains against the closed forms (three
100 ohm resistors are 300 ohm, l and area tripled; two 2 fF capacitors
are 1 fF with their plates kept) and each refusal (strict, a port, w
differing, a ring, tail to tail, no value); the X5 oracle gains the
same law from deck.md and the drawn fixtures agree with it (a drawn
chain against the sum, through a port, a written chain against one
drawn, capacitors in series and tail to tail, diodes); and relaxed
cases join the Netgen differential under `parallel {value par|add}`
and `series {value add|par}`. A merge by the wrong law, or one made
through a port or tail to tail, breaks them.
LVS-075 was missing: a digital block's schematic arrives as gate-level Verilog placing standard cells whose transistors are in a SPICE library, and the reference reader took one SPICE or Spectre file. `--reference` now repeats (Inputs::reference is a list): at most one SPICE or Spectre file, the cell library, and any number of `.v` files, read by the new netlist::verilog::read_into into the library's netlist as one subcircuit per module, as Netgen's `readnet verilog` reads a top into the cells' netlist. The top is the one module no other module places (Netlist::top_in), whatever library cells go unused. The subset is IEEE 1364-2005's structural one: ports in either style, input/ output/inout/wire/supply0/supply1 with constant ranges, assign between nets as one net, instances by name or in order, bits, part selects, concatenations, escaped identifiers, attributes; an unconnected port is its own net, and a blackbox stub of a library cell declares it. Bus bits are named `d[3]`, and a cell's `D[0]` port takes bit 0 of `.D()`. Directives, constants, parameters, instance arrays and behavioural code are refused; two SPICE or Spectre files are NetlistError::Several. Tests: each construct against the SPICE hierarchy stating the same connections (flattened devices and ports equal), and every refusal by construction; X5 fixtures of a drawn inverter chain against a Verilog top placing a SPICE inverter by name, in order, through a bus and an assign, and two faults, the verdict the flattening oracle's (so a hierarchical reference equals its flattening); the same tops join the Netgen differential, which reads the Verilog over the library with readnet as OpenLane does. A named port landing by position, a bus bit on the wrong pin or an assign that does not join breaks them.
…ail caps apart (X3)
Run locally under the oracle shell, the sample differential broke on
four of the new cases. Netgen's Verilog reader drops an instance
connected by position ("Ignoring subcircuit with no pin names",
base/verilog.c), so its copy of each Verilog top now names every
connection; GPurify still reads both forms (IEEE 1364-2005 12.3.6),
proved against the SPICE twin. Netgen combines two capacitors in
series whichever plates meet, where GPurify keeps a capacitor's plates
ordered (F15) and chains them only plate to plate, the conservative
side: a documented difference, TAIL_TO_TAIL, that the full run must
exercise. The open-output fault moves to the first inverter, so the
fault is structural rather than a dangling top port, whose report is
Netgen's pin matching, which the differential does not read.
LVS-017 reported a missing block only as its devices unpaired, with nothing naming the instance, and LVS-010 had no design for comparing cell by cell. Flattening now records each placement it expands (Netlist::placements: its path, cell and the run of flat device rows it holds, inner placements included), compare_traced returns, beside compare_with's verdict and merges, the rows of the given reference each reduced device stands for, and unpaired_instances names each reference instance none of whose kept devices paired, the outermost such, as KLayout reports a subcircuit with no partner. The run records each as an lvs.unpaired_instance error row and lists it with its path and cell in the text report. The flat comparison still decides the verdict; this only names what its mismatch left unpaired. limitations.md gains the design for cell-by-cell matching that keeps the flat comparison as its oracle, and why it is not written: the layout is flattened on reading. Tests: unpaired_instances on hand-built placements (outermost only, partly paired not named, a merged device's rows all read, left-out rows never named, layout-side ignored); an X5 test drawing a three-level reference whole and with each block left out, which names exactly the missing outermost instance. Breaks if an inner placement is named again or a paired one is named.
Rebased onto H13: Inputs::reference became a list of files for the Verilog reference (LVS-075), so the system subcommand now takes exactly one --reference and refuses two, and reads it from the list. Its parser test reads the path back from the list.
H13 found that SETUP reads `$asymmetric`, which only netgen_setup defines, so a caller writing SETUP itself would have Netgen's Tcl error out of the setup loop and compare with Netgen's defaults: no permute, no tolerance, a differential weakened without a word. netgen_setup now takes only the controls and fills SETUP's tolerance itself, so no caller touches SETUP (the per-case batches and H13's system stacks both go through it), and a merge-tier test holds every setup the curated cases write, and the default, to define `$asymmetric` first, leave no TOL unfilled, and carry the permute and tolerance lines. Oracle: construct-from-answer: SETUP's own lines and 2t/(2 - t) of the documented 2 %. Breaks if a setup omits the variable or a line.
Regenerated by tests/catalog.rs from the catalog after the rebase onto H13: LVS-032, 034, 043, 044, 049 and 075 implemented, 017 partial.
The message the system subcommand gives without exactly one --reference changed with the list; the refusal test now states it, for none and for two.
LVS-068 checked a device's parameters against ranges but not how many devices of a model a layout holds, which foundries limit per chip (IHP SG13G2's recommended rules: at most 4000 npn13G2 emitters, 800 each of npn13G2L and npn13G2V). `lvs count "model" >= min <= max` (either bound or both, whole numbers) holds the count of the model's layout devices to its bounds, reported as lvs.device_count: on the first device past the maximum, measured the count against it, or on the model's first device (nowhere when there is none) under the minimum. The values are the deck's; a device is one marker, so a multi-emitter bipolar counts once. The deck parses, lowers, decompiles and prints it. Tests: X5 fixtures of three drawn nmos and a pmos, within, over and under the bounds, a model the layout lacks, and another model left alone, the counts by construction; the parser's refusals (bounds admitting nothing, none, a fraction, a second row) and the printer round trip. A count read off by one, or held to the wrong model, breaks them.
LVS-065 was missing: there was no inductor, so neither a drawn one nor an `L` card could be compared. `device inductor <marker> model "m" terminals [a, b] inductance 2nH` recognises a two-pin device whose ends are interchangeable, as KLayout's DeviceClassInductor declares them, its inductance the value the deck states for every device of the recogniser (a foundry's fixed inductor cell; the value is the deck's). The SPICE reader takes `L` cards, the value positional or `l=`, and Spectre's `inductor` primitive, reading the inductance as `ind` so it never passes for a length; a card with no model is the deck's one inductor. Strict, parallel inductors count m; relaxed, they combine harmonically in parallel and add in series (KLayout's InductorDeviceCombiner). The deck parses, prints and decompiles the kind and its `inductance` (pH, nH, uH); the extracted netlist writes it as an `L` card. Tests: the reader's L and Spectre forms, by construction; the deck's unit and kind checks and the printer round trip; X5 fixtures (one inductor either way round, 4.8 % off, two in series and in parallel, strict and relaxed, and every_model's Spectre and unmeasured-parameter relations), against the oracle extended with the inductor's law; and five cases in the Netgen differential, which agrees on all (run locally under the oracle shell). An inductor read as polar, or its law misapplied, breaks them.
LVS-047 was missing, recorded as defined only by Calibre. Silvaco's public Guardian LVS material defines it: its MOS series and parallel reductions merge same-type transistors "connected in series [or parallel] with different gate terminals" into one element whose gates are swappable, and its logic gate recognition (application note, 2020) builds INV, NAND_N and NOR_N on them, "all N input terminals ... swappable". `lvs recognize_gates` (off by default; an analog stack's order is part of the circuit) turns that reduction on: once neither ordinary law merges anything, plain transistors of one model and bit-identical parameters, each on a gate of its own, in parallel on one source/drain pair or chained through nodes only the two touch and that are no port, become one device with all their gates as interchangeable Gate terminals (lvs::gates), and the ordinary laws run again. A merged device is not merged again, so an AOI's or OAI's groups in another order still mismatch; transistors of different sizes never merge. compare_traced's row trace and the merge log cover the new merges. Tests: X5 fixtures of a NAND2 and a NOR2 wired in the other input order, a stack of different widths and one through a labelled node, each with and without the control, against an oracle that tries every reassignment of each group's gates (the definition, by brute force); hand-derived verdicts for the fixtures; a metamorphic relation that every reassignment of a group's inputs keeps a match, over the sample of the enumeration and the NAND2; the deck parser and printer. A merge of different sizes, or a swap the tool reads as another circuit, breaks them.
LVS-074: `lvs lde "model" od <layer> max <length> [well <layer> scref <length>]` measures BSIM4's sa/sb (gate ends to active-area edges, BSIM4's effective average over a non-straight edge, compared as a pair smaller first) and, with a well, sca/scb/scc in Silvaco's public closed forms from the median gate-to-well-edge distances (lvs::lde), added to the layout graph in run_lvs. Deck parse, lower, print and decompile; reduce and gate merges refuse transistors stating sa/sb in series. Tests written and passing locally: the Silvaco worked example (lvs::lde unit test, SE), seven X5 fixtures by construction (L-shaped OD, enclosing well, well beside, sa/sb either way, each value 5 % off), the deck parser and printer round trip; catalog, doc_counts, oracles, golden and the merge-depth exhaustive fixtures pass. Unfinished: one local clippy pedantic warning (items_after_statements on the `type Case` alias inside lde_fixtures in tests/exhaustive/lvs.rs: move it above the first statement); the docs/check-sources.md and docs/limitations.md generated blocks were rewritten by the catalog test for LVS-047/065/074 and are in this commit; CI has not run on it.
Contributor
Author
|
Landed on verification-hardening (rebased over X2/X4/X5, WIP lint fixed; workspace tests run locally). |
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.
Brings the LVS rows that are partial or missing (outside H13's multi-die rows) as far as public sources define them: deck controls (max_res, min_caps, same_nets), relaxed series passives, a structural Verilog reference, hierarchy reporting, new device kinds, and the rows only Calibre defines recorded with what was checked. Per-row status in the final report.