Netlist Parser¶
Layer 0 — netlist parsing.
Parses circuitgenome.synthesizer.netlist.to_flat_spice() output — and,
now, sized SPICE netlists produced by real design flows or CircuitGenome’s
own sizer — into a ParsedNetlist.
The unsized form is the structural inverse of to_flat_spice’s
_device_line:
{ref} {d} {g} {s} {b} {nmos|pmos} # MOSFET (6 tokens)
{ref} {t1} {t2} [1k] # resistor (3-4 tokens)
{ref} {p} {m} [1p] # capacitor (3-4 tokens)
wrapped in a .subckt <name> <port...> / .ends block (or .suckt
for netlists with that common typo). Net and ref names are treated as
arbitrary strings – the parser makes no assumptions about to_flat_spice’s
own naming conventions (e.g. net_bias{N} or {ref}_{slot}).
Sized dialect. The parser also accepts the sized dialect that real flows and the sizer emit:
MOSFET lines may carry trailing
key=valueparameters —W=0.5u L=0.15u nf=1 m=2— with values kept as SI-suffixed SPICE strings. Any otherkey=valuetoken is tolerated and preserved. They land inparamskeyed as written.The type token may be a real process model name (e.g.
sky130_fd_pr__nfet_01v8) mapped tonmos/pmosthrough a configurable model-name table (seeDEFAULT_MODEL_MAP); the barenmos/pmostokens keep working. Because real flows instantiate those models as subcircuits, a MOSFET line may bex-prefixed instead ofm-prefixed — both are accepted when the model token resolves to a MOSFET.Resistor/capacitor value tokens (
1k/1p) are preserved onparamsundervaluerather than ignored.
Sizes ride along on the parsed devices; recognition still matches on topology
(device type + terminal connectivity), so recognize() behaves identically
on sized and unsized netlists.
Device lines are dispatched by the first character of the ref (SPICE
convention): m → MOSFET, c → capacitor, r → resistor, x →
subcircuit instance (accepted only when its model token names a MOSFET in the
model map — the real-flow SKY130 device shape).
- circuitgenome.recognizer.netlist_parser.DEFAULT_MODEL_MAP: dict[str, str] = {'nmos': 'nmos', 'nmos_3p3': 'nmos', 'pmos': 'pmos', 'pmos_3p3': 'pmos', 'sky130_fd_pr__nfet_01v8': 'nmos', 'sky130_fd_pr__nfet_01v8_lvt': 'nmos', 'sky130_fd_pr__pfet_01v8': 'pmos', 'sky130_fd_pr__pfet_01v8_hvt': 'pmos', 'sky130_fd_pr__pfet_01v8_lvt': 'pmos'}¶
Default model-name → device-type table. Maps the bare synthesizer tokens, the CircuitGenome
device_maptargets (gf180mcu core), and the common SKY130 process primitives onto"nmos"/"pmos". Lookups are case-insensitive. Callers pass amodel_maptoparse()to extend or override this table (their entries win).
- circuitgenome.recognizer.netlist_parser.parse(spice, model_map=None)[source]¶
Parse a flat SPICE
.subcktblock into aParsedNetlist.Accepts both the unsized dialect emitted by
to_flat_spice()and the sized dialect produced by real design flows / CircuitGenome’s own sizer (see the module docstring): MOSFET lines with trailingW=/L=/nf=/m=(and any otherkey=value) params, real process model names, and preserved resistor/capacitor value tokens.- Parameters:
spice (str) – A SPICE netlist string. The header keyword may be
.subcktor.suckt(common typo).model_map (dict[str, str] | None) – Optional model-name →
"nmos"/"pmos"table, merged overDEFAULT_MODEL_MAP(caller entries win) and matched case-insensitively. Use it to teach the parser process-specific model names beyond the built-in SKY130/gf180 set.
- Returns:
A
ParsedNetlistwithdevicesin the same order as the input, andinternal_nets= every net referenced by a device terminal that is not inexternal_ports. Sizing parameters ride along on eachparams.- Raises:
ValueError – If a MOSFET line’s model token is unknown, a device line has an unexpected token count/shape, or a bare token follows a
key=valueparameter.- Return type:
Example:
from circuitgenome.recognizer import parse, recognize parsed = parse(''' .subckt ota in1 in2 out vdd! gnd! m1 net1 in1 tail vdd! sky130_fd_pr__pfet_01v8 W=4u L=0.5u nf=2 m=1 m2 net2 in2 tail vdd! sky130_fd_pr__pfet_01v8 W=4u L=0.5u nf=2 m=1 .ends''') print(parsed.devices[0].type) # "pmos" print(parsed.devices[0].params["W"]) # "4u" result = recognize(parsed) # topology match, sizes ride along