sycan.spice

Minimal SPICE netlist parser (and writer) for DC / AC circuits.

Supported syntax:

  • first line is a title and is discarded

  • lines starting with * are comments; text after ; is trimmed

  • lines starting with + are continuations of the previous element

  • .end stops parsing; other dot-directives are ignored

  • .subckt name pin1 pin2 ... [PARAMS: k=v ...] / .ends [name] defines a reusable subcircuit. PARAMS: declares default parameter values that body components may reference via plain symbols (R1 in out R). Instances override defaults via Xinst pin1 ... name PARAMS: k=v .... The body may itself contain X references to other user subcircuits or to the built-in OPAMP / TRIODE blocks. Nested .subckt in source is rejected; nest semantically by having one subckt instantiate another via its X element.

  • elements:

    Rxxx  N+ N- value
    Lxxx  N+ N- value            ; inductor (DC short, AC 1/(sL))
    Cxxx  N+ N- value            ; capacitor (DC open, AC sC)
    Vxxx  N+ N- [DC dcval] [AC acval]
    Ixxx  N+ N- [DC dcval] [AC acval]
    Exxx  N+ N- NC+ NC- gain     ; VCVS
    Gxxx  N+ N- NC+ NC- gain     ; VCCS
    Fxxx  N+ N- VNAM gain        ; CCCS
    Hxxx  N+ N- VNAM gain        ; CCVS
    Wxxx  N1 N2                  ; ideal wire (stamped as a 0 V source)
    Mxxx  D G S TYPE mu_n Cox W L V_TH [m [V_T]]
                                                  ; TYPE=N/PMOS_subthreshold
    Mxxx  D G S TYPE mu_n Cox W L V_TH [lam [V_GS_op V_DS_op [C_gs [C_gd]]]]
                                                  ; TYPE=N/PMOS_L1
    Qxxx  C B E TYPE IS BF BR [V_T [VAF]]         ; TYPE=NPN or PNP (G-P)
    Dxxx  A K IS [N [V_T]]                        ; Shockley diode
    Pxxx  N+ N- [role]                            ; named port (role=input/output/generic)
    Txxx  N1+ N1- N2+ N2- Z0 td                   ; lossless transmission line
    Xxxx  P G K TRIODE K mu [V_g_op V_p_op [C_gk C_gp C_pk]]
                                                  ; vacuum-tube triode subcircuit
    Xxxx  IN+ IN- OUT OPAMP [A]                   ; ideal differential op-amp
    GND[n] NODE                  ; ties NODE to the absolute zero reference
    

Values may be plain numbers with an engineering suffix (T G MEG K M U N P F, case-insensitive) plus arbitrary trailing unit letters, or a bare identifier that becomes a sympy symbol.

Functions

parse(text)

Parse a SPICE netlist string into a Circuit.

parse_file(path)

Parse a SPICE netlist from a file path.

parse_value(token)

Convert a SPICE value token into a sympy expression.

to_spice(circuit, *[, title])

Serialize circuit to a SPICE netlist string.

write_file(circuit, path)

Write circuit to path as a SPICE netlist.

sycan.spice.parse_value(token)[source]

Convert a SPICE value token into a sympy expression.

Numeric tokens accept engineering suffixes and arbitrary trailing unit letters. Non-numeric tokens are returned as cas.Symbol.

Parameters:

token (str)

Return type:

Expr

sycan.spice.parse(text)[source]

Parse a SPICE netlist string into a Circuit.

Top-level lines populate the returned circuit directly. Lines inside .SUBCKT name pin1 pin2 ... .ENDS blocks are stored as reusable templates and instantiated whenever an X element references their name (case-insensitive). Subcircuit bodies may themselves reference other user subcircuits or the built-in OPAMP / TRIODE blocks.

Parameters:

text (str)

Return type:

Circuit

sycan.spice.parse_file(path)[source]

Parse a SPICE netlist from a file path.

Parameters:

path (str | Path)

Return type:

Circuit

sycan.spice.to_spice(circuit, *, title=None)[source]

Serialize circuit to a SPICE netlist string.

Hierarchical designs are emitted with one .SUBCKT block per distinct body identity, followed by the top-level component list. SubCircuit instances become X references that carry their params dict via PARAMS:. The first line is a SPICE title (defaults to circuit.name).

Components without a SPICE-letter representation (e.g. behavioural sources, switches, varactors, transfer-function and signal-flow blocks, OPAMP1) raise NotImplementedError.

Parameters:
  • circuit (Circuit)

  • title (str | None)

Return type:

str

sycan.spice.write_file(circuit, path)[source]

Write circuit to path as a SPICE netlist.

Parameters:
  • circuit (Circuit)

  • path (str | Path)

Return type:

Path