sycan.circuit

Netlist container.

Node "0" is always ground. Components are added either in bulk via Circuit.add() or through typed convenience methods that mirror SPICE letters (add_resistor, add_vsource, add_vcvs …).

Circuit.add reads a component’s circuit nodes through the unified ports interface — it does not know about specific component types. The catalog of available component classes is populated at import time via sycan.components and exposed by Circuit.available_components().

Functions

print_hierarchy(circuit[, file])

Print circuit's hierarchy tree to file (or stdout).

Classes

Circuit([name])

Symbolic netlist.

sycan.circuit.print_hierarchy(circuit, file=None)[source]

Print circuit’s hierarchy tree to file (or stdout).

Convenience wrapper for Circuit.print_hierarchy() so callers can write sycan.print_hierarchy(c) symmetrically with the rest of the top-level analysis API.

Parameters:

circuit (Circuit)

Return type:

None

class sycan.circuit.Circuit(name='circuit')[source]

Bases: object

Symbolic netlist.

Parameters:

name (str)

add(component)[source]

Append a pre-built component, registering its referenced nodes.

Nodes are read through the component’s ports declaration, so any new Component subclass works without changes here.

Parameters:

component (Component)

Return type:

Component

static available_components()[source]

Return a name → class map of every registered component type.

Return type:

dict[str, type[Component]]

flat_components(collapse_paths=None)[source]

All leaf components, recursively expanding any SubCircuit.

SubCircuit instances are flattened into renamed, node-rerouted clones of their bodies (see SubCircuit.expand_leaves()). Non-subcircuit components are passed through unchanged. Used by the MNA build / solve path so that hierarchical designs are stamped as if hand-inlined.

collapse_paths is an optional set of fully-qualified SubCircuit instance paths (tuples) that should be replaced by a single _CollapsedGroup placeholder instead of being expanded. Intended for use by visualisation code that wants to hide implementation detail; the placeholders are not valid MNA components, so callers passing collapse_paths must not feed the result back into the solver.

Parameters:

collapse_paths (frozenset[tuple[str, ...]] | None)

Return type:

list

subcircuits()[source]

Top-level SubCircuit instances in this circuit.

Return type:

list[SubCircuit]

print_hierarchy(file=None)[source]

Print the design’s component tree, expanding subcircuits.

Output has three sections:

  1. A header naming the top-level circuit.

  2. A summary listing each SubCircuit instance found at any depth, grouped by class, with its dotted instance path.

  3. A box-drawn tree of every component, with subcircuit bodies shown as nested branches under their instance node.

Return type:

None

add_subcircuit(name, body, port_map, params=None)[source]

Add a generic subcircuit instance wrapping body.

params (optional) maps parameter names to values that substitute matching cas.Symbol(name) placeholders inside the body when it is flattened. Outer params propagate into nested SubCircuit instances unless those instances override the same key.

Parameters:
  • name (str)

  • body (Circuit)

  • port_map (dict[str, str])

  • params (dict[str, Expr | int | float | str] | None)

Return type:

SubCircuit

add_opamp(name, in_p, in_n, out, A=None)[source]

Add an ideal differential op-amp (OPAMP subcircuit).

Parameters:
  • name (str)

  • in_p (str)

  • in_n (str)

  • out (str)

  • A (Expr | int | float | str | None)

Return type:

OPAMP

add_opamp1(name, in_p, in_n, out, A=None, GBW=None, Z_out=None)[source]

Add a first-order op-amp with finite GBW and output impedance.

See OPAMP1.

Parameters:
  • name (str)

  • in_p (str)

  • in_n (str)

  • out (str)

  • A (Expr | int | float | str | None)

  • GBW (Expr | int | float | str | None)

  • Z_out (Expr | int | float | str | None)

Return type:

OPAMP1

add_resistor(name, n_plus, n_minus, value)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • value (Expr | int | float | str)

Return type:

Resistor

add_inductor(name, n_plus, n_minus, value)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • value (Expr | int | float | str)

Return type:

Inductor

add_capacitor(name, n_plus, n_minus, value)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • value (Expr | int | float | str)

Return type:

Capacitor

add_varactor(name, n_plus, n_minus, C0, V_J=0.7, M=0.5, V_op=None)[source]

Attach a junction-style voltage-controlled capacitor.

See Varactor.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • C0 (Expr | int | float | str)

  • V_J (Expr | int | float | str)

  • M (Expr | int | float | str)

  • V_op (Expr | int | float | str | None)

Return type:

Varactor

add_vswitch(name, n_plus, n_minus, nc_plus, nc_minus, R_on=1, R_off=1000000000.0, V_t=0, V_h=0.1, V_c_op=None)[source]

Attach a smooth voltage-controlled switch (SPICE S).

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • nc_plus (str)

  • nc_minus (str)

  • R_on (Expr | int | float | str)

  • R_off (Expr | int | float | str)

  • V_t (Expr | int | float | str)

  • V_h (Expr | int | float | str)

  • V_c_op (Expr | int | float | str | None)

Return type:

VSwitch

add_behavioral_current(name, n_plus, n_minus, expr, V_op_subs=None)[source]

Attach a behavioural current source I = expr.

expr may reference Symbol("V(<node>)") to access node voltages. V_op_subs is the operating-point map used for AC small-signal linearisation.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • expr (Expr | int | float | str)

  • V_op_subs (dict | None)

Return type:

BehavioralCurrent

add_behavioral_voltage(name, n_plus, n_minus, expr, V_op_subs=None)[source]

Attach a behavioural voltage source V(+)-V(-) = expr.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • expr (Expr | int | float | str)

  • V_op_subs (dict | None)

Return type:

BehavioralVoltage

add_vsource(name, n_plus, n_minus, value, ac_value=None, waveform=None, amplitude=None, frequency=None, phase=None, v1=None, v2=None, td=None, pw=None, td1=None, tau1=None, td2=None, tau2=None)[source]

Add an independent voltage source, optionally with a waveform mode.

Supported waveforms: "sine", "pulse", "exp". See VoltageSource.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • value (Expr | int | float | str)

  • ac_value (Expr | int | float | str | None)

  • waveform (str | None)

  • amplitude (Expr | int | float | str | None)

  • frequency (Expr | int | float | str | None)

  • phase (Expr | int | float | str | None)

  • v1 (Expr | int | float | str | None)

  • v2 (Expr | int | float | str | None)

  • td (Expr | int | float | str | None)

  • pw (Expr | int | float | str | None)

  • td1 (Expr | int | float | str | None)

  • tau1 (Expr | int | float | str | None)

  • td2 (Expr | int | float | str | None)

  • tau2 (Expr | int | float | str | None)

Return type:

VoltageSource

add_isource(name, n_plus, n_minus, value, ac_value=None, waveform=None, amplitude=None, frequency=None, phase=None, v1=None, v2=None, td=None, pw=None, td1=None, tau1=None, td2=None, tau2=None)[source]

Add an independent current source, optionally with a waveform mode.

Supported waveforms: "sine", "pulse", "exp". See CurrentSource.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • value (Expr | int | float | str)

  • ac_value (Expr | int | float | str | None)

  • waveform (str | None)

  • amplitude (Expr | int | float | str | None)

  • frequency (Expr | int | float | str | None)

  • phase (Expr | int | float | str | None)

  • v1 (Expr | int | float | str | None)

  • v2 (Expr | int | float | str | None)

  • td (Expr | int | float | str | None)

  • pw (Expr | int | float | str | None)

  • td1 (Expr | int | float | str | None)

  • tau1 (Expr | int | float | str | None)

  • td2 (Expr | int | float | str | None)

  • tau2 (Expr | int | float | str | None)

Return type:

CurrentSource

add_vcvs(name, n_plus, n_minus, nc_plus, nc_minus, gain)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • nc_plus (str)

  • nc_minus (str)

  • gain (Expr | int | float | str)

Return type:

VCVS

add_vccs(name, n_plus, n_minus, nc_plus, nc_minus, gain)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • nc_plus (str)

  • nc_minus (str)

  • gain (Expr | int | float | str)

Return type:

VCCS

add_cccs(name, n_plus, n_minus, ctrl, gain)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • ctrl (str)

  • gain (Expr | int | float | str)

Return type:

CCCS

add_ccvs(name, n_plus, n_minus, ctrl, gain)[source]
Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • ctrl (str)

  • gain (Expr | int | float | str)

Return type:

CCVS

add_port(name, n_plus, n_minus='0', role='generic')[source]

Mark (n_plus, n_minus) as a named port for impedance analysis.

Parameters:
  • name (str)

  • n_plus (str)

  • n_minus (str)

  • role (str)

Return type:

Port

add_gnd(name, node)[source]

Tie node to the absolute zero reference.

Parameters:
  • name (str)

  • node (str)

Return type:

GND

add_mutual_coupling(name, inductors, k=1)[source]

Add mutual inductance coupling between inductors.

Parameters:
  • name (str) – Coupling designator (e.g. "K1").

  • inductors (list[str]) – List of inductor designators to couple.

  • k (Expr | int | float | str) – Coupling coefficient (default 1 = perfect coupling).

  • time (Inductor values are resolved lazily at MNA-build)

  • K (so)

  • references. (may precede the L elements it)

Return type:

MutualCoupling

add_triode(name, plate, grid, cathode, K, mu, **kwargs)[source]

Attach a Langmuir 3/2-power vacuum-tube triode.

Optional keywords: V_g_op / V_p_op (AC operating point), C_gk / C_gp / C_pk (intrinsic capacitances).

Parameters:
  • name (str)

  • plate (str)

  • grid (str)

  • cathode (str)

  • K (Expr | int | float | str)

  • mu (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

Triode

add_tline(name, n_in_p, n_in_m, n_out_p, n_out_m, Z0, td, loss=0)[source]

Attach a transmission line (Z0, delay td, optional loss in nepers).

Parameters:
  • name (str)

  • n_in_p (str)

  • n_in_m (str)

  • n_out_p (str)

  • n_out_m (str)

  • Z0 (Expr | int | float | str)

  • td (Expr | int | float | str)

  • loss (Expr | int | float | str)

Return type:

TLINE

add_diode(name, anode, cathode, IS, N=None, V_T=None, C_j=None, V_D_op=None)[source]

Attach a Shockley diode: I_D = IS (exp(V_D/(N V_T)) - 1).

Optional C_j adds junction capacitance in AC analysis. Optional V_D_op pins the DC operating-point voltage for small-signal linearisation.

Parameters:
  • name (str)

  • anode (str)

  • cathode (str)

  • IS (Expr | int | float | str)

  • N (Expr | int | float | str | None)

  • V_T (Expr | int | float | str | None)

  • C_j (Expr | int | float | str | None)

  • V_D_op (Expr | int | float | str | None)

Return type:

Diode

add_njfet(name, drain, gate, source, BETA, VTO, **kwargs)[source]

Attach a Shichman-Hodges N-channel JFET (depletion-mode).

VTO is stored as a positive magnitude (pinch-off magnitude). Optional keyword parameters: LAMBDA (channel-length modulation), C_gs, C_gd (intrinsic capacitances), and V_GS_op / V_DS_op (AC linearisation point).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • BETA (Expr | int | float | str)

  • VTO (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

NJFET

add_pjfet(name, drain, gate, source, BETA, VTO, **kwargs)[source]

Attach a Shichman-Hodges P-channel JFET (depletion-mode).

VTO is stored as a positive magnitude (pinch-off magnitude). Optional keyword parameters: LAMBDA (channel-length modulation), C_gs, C_gd (intrinsic capacitances), and V_GS_op / V_DS_op (AC linearisation point).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • BETA (Expr | int | float | str)

  • VTO (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

PJFET

add_bjt(name, collector, base, emitter, polarity, IS, BF, BR, **kwargs)[source]

Attach a Gummel-Poon BJT (polarity='NPN' or 'PNP').

Optional G-P parameters: NF, NR, VAF, VAR, IKF, IKR, ISE, NE, ISC, NC, V_T, and AC model capacitances C_pi, C_mu.

Parameters:
  • name (str)

  • collector (str)

  • base (str)

  • emitter (str)

  • polarity (str)

  • IS (Expr | int | float | str)

  • BF (Expr | int | float | str)

  • BR (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

BJT

add_nmos_l1(name, drain, gate, source, mu_n, Cox, W, L, V_TH, **kwargs)[source]

Attach a Shichman-Hodges (Level 1) NMOS.

Optional keyword parameters: lam (channel-length modulation), C_gs, C_gd (intrinsic capacitances), and V_GS_op / V_DS_op (AC linearisation point).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

NMOS_L1

add_pmos_l1(name, drain, gate, source, mu_n, Cox, W, L, V_TH, **kwargs)[source]

Attach a Shichman-Hodges (Level 1) PMOS (V_TH is a magnitude).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

PMOS_L1

add_nmos_subthreshold(name, drain, gate, source, mu_n, Cox, W, L, V_TH, m=None, V_T=None)[source]

Attach a sub-threshold NMOS.

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • m (Expr | int | float | str | None)

  • V_T (Expr | int | float | str | None)

Return type:

NMOS_subthreshold

add_pmos_subthreshold(name, drain, gate, source, mu_n, Cox, W, L, V_TH, m=None, V_T=None)[source]

Attach a sub-threshold PMOS (V_TH is a magnitude).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • m (Expr | int | float | str | None)

  • V_T (Expr | int | float | str | None)

Return type:

PMOS_subthreshold

add_nmos_3t(name, drain, gate, source, mu_n, Cox, W, L, V_TH, **kwargs)[source]

Attach a segmented L1 + matched-weak-inversion NMOS.

Optional keyword parameters: lam (channel-length modulation), m (sub-threshold slope factor), V_T (thermal voltage), C_gs, C_gd (intrinsic capacitances), and V_GS_op / V_DS_op (AC linearisation point).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

NMOS_3T

add_pmos_3t(name, drain, gate, source, mu_n, Cox, W, L, V_TH, **kwargs)[source]

Attach a segmented L1 + matched-weak-inversion PMOS (V_TH is a positive magnitude).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

PMOS_3T

add_nmos_4t(name, drain, gate, source, bulk, mu_n, Cox, W, L, V_TH0, **kwargs)[source]

Attach a four-terminal segmented NMOS (body-effect aware).

Optional keyword parameters: lam (channel-length modulation), gamma (body-effect coefficient, V^0.5), phi (surface potential 2 φ_F), m (sub-threshold slope factor), V_T (thermal voltage), C_gs, C_gd, and the AC linearisation points V_GS_op / V_DS_op / V_BS_op.

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • bulk (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH0 (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

NMOS_4T

add_pmos_4t(name, drain, gate, source, bulk, mu_n, Cox, W, L, V_TH0, **kwargs)[source]

Attach a four-terminal segmented PMOS (body-effect aware, V_TH0 is a positive magnitude).

Parameters:
  • name (str)

  • drain (str)

  • gate (str)

  • source (str)

  • bulk (str)

  • mu_n (Expr | int | float | str)

  • Cox (Expr | int | float | str)

  • W (Expr | int | float | str)

  • L (Expr | int | float | str)

  • V_TH0 (Expr | int | float | str)

  • kwargs (Expr | int | float | str)

Return type:

PMOS_4T

add_transfer_function(name, in_p, in_m, out_p, out_m, H, var=None, dc_gain=None)[source]

Attach a generic LTI block V(out) = H(s) * V(in).

Parameters:
  • name (str)

  • in_p (str)

  • in_m (str)

  • out_p (str)

  • out_m (str)

  • H (Expr | int | float | str)

  • var (Expr | int | float | str | None)

  • dc_gain (Expr | int | float | str | None)

Return type:

TransferFunction

add_integrator(name, in_p, in_m, out_p, out_m, k=1, leak=0)[source]

Attach a continuous-time integrator H(s) = k / (s + leak).

Parameters:
  • name (str)

  • in_p (str)

  • in_m (str)

  • out_p (str)

  • out_m (str)

  • k (Expr | int | float | str)

  • leak (Expr | int | float | str)

Return type:

Integrator

add_gain(name, in_p, in_m, out_p, out_m, k)[source]

Attach a static gain V(out) = k * V(in).

Parameters:
  • name (str)

  • in_p (str)

  • in_m (str)

  • out_p (str)

  • out_m (str)

  • k (Expr | int | float | str)

Return type:

Gain

add_summer(name, out_p, out_m, inputs)[source]

Attach a weighted summing junction.

inputs is a list of (in_p, in_m, weight) tuples or (node, weight) 2-tuples for inputs referenced to ground.

Parameters:
  • name (str)

  • out_p (str)

  • out_m (str)

  • inputs (list)

Return type:

Summer

add_quantizer(name, in_p, in_m, out_p, out_m, k_q=1, qnoise=None)[source]

Attach a linear-model quantizer V(out) = k_q * V(in) + V_q.

qnoise overrides the additive-noise sympy symbol; pass 0 to model an ideal noiseless gain.

Parameters:
  • name (str)

  • in_p (str)

  • in_m (str)

  • out_p (str)

  • out_m (str)

  • k_q (Expr | int | float | str)

  • qnoise (Expr | int | float | str | None)

Return type:

Quantizer

property nodes: list[str]

Non-ground node names ordered by MNA index.

assume(*assumptions)[source]

Attach one or more Assumption objects to this circuit.

Attached assumptions are picked up automatically by the unified solve() entry point — they’re applied to the solution after the matrix solve, and (for region-style assumptions) verified by check_assumptions() against the resulting operating point.

Return type:

None

assume_limit(symbol, target)[source]

Sugar for self.assume(Limit(symbol, target)).

Parameters:
  • symbol (cas.Symbol)

  • target (cas.Expr)

Return type:

None

assume_much_greater(big, small)[source]

Sugar for self.assume(MuchGreater(big, small))big >> small.

Return type:

None

assume_much_less(small, big)[source]

Sugar for self.assume(MuchLess(small, big))small << big.

Return type:

None

assume_region(component_name, region_name)[source]

Sugar for self.assume(Region(component_name, region_name)).

Parameters:
  • component_name (str)

  • region_name (str)

Return type:

None

check_assumptions(solution, extra=None)[source]

Verify every attached Assumption against solution.

extra is an optional list of additional assumptions to verify in the same pass — useful for one-off checks that weren’t attached to the circuit. Returns a list of CheckResult.

Parameters:

extra (list | None)

group(components, name, body_name=None, params=None)[source]

Wrap an existing slice of this circuit’s components in a SubCircuit.

Replaces the listed components in place: they are removed from self.components and reattached inside a freshly created body Circuit, with a new SubCircuit instance inserted at the position of the first removed component.

Pin selection is automatic: any node that the listed components reference and that is also used by something outside the group (or is the SPICE ground node "0") becomes an external pin. Internal-only nodes stay namespaced inside the body.

Parameters:
  • components (list[Component]) – The components to absorb. Must all currently belong to self.components; order is preserved inside the body.

  • name (str) – Designator for the new SubCircuit instance (e.g. "X1").

  • body_name (str | None) – Optional name for the body Circuit; defaults to name.

  • params (dict[str, Expr | int | float | str] | None) – Optional {symbol: value} map propagated into the body via the standard parameter mechanism.

Return type:

SubCircuit