pythonpyspice

How do you use a behavioral resistor in pySpice?


I am trying to simulate a very simple circuit with behavioral resistors that change state based on a global parameter. Really I'm just new to *spice and playing with "resistors as switches"

The working circuit in ngspice is:

.param pos = 1

vin 1 0 dc 10
r1 1 2 r='{pos} == 1 ? 1u : 1G'
r2 2 0 1
r3 1 3 r='{pos} == 2 ? 1u : 1G'
r4 3 0 1

Which when run (and 'pos' is altered) does exactly what I expect:

Circuit: resistor switch circuit

Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

No. of Data Rows : 1
v(2) = 9.999990e+00
v(3) = 1.000000e-08
Reset re-loads circuit resistor switch circuit

Circuit: resistor switch circuit

Doing analysis at TEMP = 27.000000 and TNOM = 27.000000

No. of Data Rows : 1
v(2) = 1.000000e-08
v(3) = 9.999990e+00

I'd like to recreate this circuit in pyspice which looks like this:

circuit = Circuit('resistor switch circuit')
circuit._parameters['pos'] = 1
circuit.V('input', 'in', circuit.gnd, 10@u_V)
circuit.R(1, 'in', 'pos1', raw_spice='r=\'{pos} == 1 ? 1u : 1G\'')
circuit.R(2, 'pos1', circuit.gnd, 1@u_Ohm)
circuit.R(3, 'in', 'pos2', raw_spice='r=\'{pos} == 2 ? 1u : 1G\'')
circuit.R(4, 'pos2', circuit.gnd, 1@u_Ohm)

print(circuit)

And generates a netlist that as far as I can tell is (effectively) the same as the ngspice netlist above:

.title resistor switch circuit
.param pos=1

Vinput in 0 10V
R1 in pos1 r='{pos} == 1 ? 1u : 1G'
R2 pos1 0 1
R3 in pos2 r='{pos} == 2 ? 1u : 1G'
R4 pos2 0 1

However running it results in the following:

2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 4, new internal line no.: 5:
2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Syntax error: letter [{]
2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 4, new internal line no.: 5:
2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Expression err: {pos}==1?1u:1g}
2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 4, new internal line no.: 5:
2023-01-10 17:01:07,739 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Cannot compute substitute
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 6, new internal line no.: 7:
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Syntax error: letter [{]
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 6, new internal line no.: 7:
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Expression err: {pos}==2?1u:1g}
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Original line no.: 6, new internal line no.: 7:
2023-01-10 17:01:07,740 - PySpice.Spice.NgSpice.Shared.NgSpiceShared - Shared.ERROR - Cannot compute substitute

I believe pyspice supports behavioral resistors: https://pyspice.fabrice-salvaire.fr/releases/v1.3/api/PySpice/Spice/BasicElement.html#PySpice.Spice.BasicElement.BehavioralResistor

But regardless of how I try to provide the expression:

circuit.R(1, 'in', 'pos1', '{pos} == 1 ? 1u : 1G')
circuit.R(1, 'in', 'pos1', R='{pos} == 1 ? 1u : 1G')

and so on I always get some kind of error when trying to run the simulation. Only "raw_spice=" seems to truly give a compatible netlist - but then fails at the simulation.

How do you actually use a behavioral resistor in pyspice?


Solution

  • Per Joshua's comment - including {} around a variable/parameter name (as with {pos} in my examples) seems to not be required for proper parsing.

    Oddly, ngspice directly readily accepts that format. Being new to using netlists I saw that format used quite frequently in sample code, and since it worked, presumed it was required to denote vars/params - it is not.

    Removing the extraneous '{}' from the component creation (though I am still passing the equation in via raw_spice) resolves the issue and lets the simulation run. Answering here for future reference.