Nodes, branches and the netlist

Read and write a SPICE netlist: parts, nodes, ground and units, and the voltages and currents SPICE prints, signs included.

Lesson
E1.1
Time
20 min
Runs on
ngspice
Check
5 questions

A micropower bias divider was meant to make 0.9 V from 1.8 V with two 10 MΩ resistors, drawing 90 nA. The netlist said 10M for both, and SPICE reads M as milli. The output still read 0.9 V, so the run looked right, while the supply delivered 90 A.

DC sweepThe divider as typed and as meantThe supply is swept from 0 to 1.8 V. Both dividers give the same output voltage; the currents differ by a factor of a billion.
  • v(outa)
  • v(outb)
  • i(va)
  • i(vb)
00.2 V0.4 V0.6 V0.8 V1.0 VOutput voltage020 A40 A60 A80 A100 ADivider current00.2 V0.4 V0.6 V0.8 V1.0 V1.2 V1.4 V1.6 V1.8 VSupply voltage00.5 V1.0 VOutput voltage050 A100 ADivider current00.5 V1.0 V1.5 VSupply voltage
  1. Supply voltage 900 mVv(outa) = 450 mV · v(outb) = 450 mV · i(va) = 45 A · i(vb) = 45 nA

    Half the supply: both outputs read 0.45 V. The 10M divider (a) already draws 45 A.

  2. Supply voltage 1.8 Vv(outa) = 900 mV · v(outb) = 900 mV · i(va) = 90 A · i(vb) = 90 nA

    Full supply: both outputs read 0.9 V. Divider a draws 90 A through 20 mΩ. Divider b draws 90 nA through 20 MΩ, too small to leave the axis.

Read the plot as a table
Supply voltagev(outa)v(outb)i(va)i(vb)
0 V0 V0 V0 A0 A
200 mV100 mV100 mV10 A10 nA
400 mV200 mV200 mV20 A20 nA
600 mV300 mV300 mV30 A30 nA
800 mV400 mV400 mV40 A40 nA
900 mV450 mV450 mV45 A45 nA
1 V500 mV500 mV50 A50 nA
1.2 V600 mV600 mV60 A60 nA
1.4 V700 mV700 mV70 A70 nA
1.6 V800 mV800 mV80 A80 nA
1.8 V900 mV900 mV90 A90 nA

Divider a is written 10M, divider b 10meg. Measured on ngspice 42; VA and VB are 0 V sources that measure each current.

A netlist is the only thing the simulator reads, so learn to read it the way SPICE does.

A netlist is a list of parts

A divider with a loadVDD = 1.8 V drives R1 = 10 kΩ into node out. R2 = 10 kΩ and the load RL = 100 kΩ go from out to ground.
A divider with a load+VDD1.8 VR110 kΩR210 kΩRL100 kΩvdd1.8 Vout0.8571 V
  1. Node out

    Every terminal written out is one point. The 94.29 µA arriving through R1 splits: 85.71 µA down R2 and 8.571 µA into the load. What flows in flows out.

    94.29 µA · 85.71 µA · 8.571 µA

  2. The supply

    The 94.29 µA leaves the + terminal of VDD. SPICE counts current into the + terminal as positive, so it prints i(VDD) as −94.29 µA.

    94.29 µA

  3. Ground

    Node 0 is ground. Every current returns to it, and every voltage is measured from it.

Read the circuit as text
  • VDD voltage source (1.8 V): + → vdd, − → 0
  • R1 resistor (10 kΩ): pin 1 → vdd, pin 2 → out
  • R2 resistor (10 kΩ): pin 1 → out, pin 2 → 0
  • RL resistor (100 kΩ): pin 1 → out, pin 2 → 0
  • vdd = 1.8 V
  • out = 0.8571 V

Node voltages from the operating point of the lab netlist below, measured on ngspice 42.

Here is the netlist of that circuit. A netlist has no wires and no positions: each line after the first is one part, and the shared node names are the wires.

Line 1 is the title. Then name, two nodes, value.
* resistor divider with a 100 k load
VDD vdd 0 1.8
R1 vdd out 10k
R2 out 0 10k
RL out 0 100k

A part line starts with a name. Its first letter says what the part is: R resistor, C capacitor, L inductor, V voltage source, I current source, D diode, X subcircuit. Then come the nodes it connects to, then its value.

A node is a name for one electrical point. Every terminal written with the same node name is wired together, so R1, R2 and RL all meet at out. Node 0 is ground, the reference that every printed voltage is measured from. A branch is one part between two nodes, and the current in it is the same at both ends.

Names are free text, so out, vdd and n7 are equally good node names. A typing slip is the danger. Write R2 ouy 0 10k and R2 hangs from a new node of its own: vout rises to 1.636 V, and nothing warns you.

What SPICE solves for

SPICE writes one equation per node from Kirchhoff's current law: the currents into a node sum to zero. The unknowns are the node voltages, one per node except ground. Each voltage source adds one more unknown, its own current, because a source fixes a voltage and lets the current be whatever the circuit needs. This method is called modified nodal analysis.

That is why i(VDD) exists in the output and a resistor's current does not, by default. Check the hand value before you trust a run. R2 in parallel with RL is 9.091 kΩ, so vout = 1.8 V × 9.091 / 19.091 = 0.8571 V, and the run prints vout = 8.571429e-01.

  1. Read a source current

    i(VDD) is positive when current flows into the + node, through the source and out of the − node. A supply that delivers power therefore prints a negative current: isup = -9.428571e-05.

  2. Add an ammeter

    A 0 V voltage source in series with a branch changes nothing in the circuit, but it adds that branch current to the output. Move the load to a new node with RL out2 0 100k and add VAM out out2 0.

  3. Ask the device

    ngspice also reports a part's own current as @r1[i]. It reads the last point computed, so print it after op, or save it before a sweep.

Check the law on the measured lines: ir2 is 85.71 µA and irl is 8.571 µA, which add up to the 94.29 µA that the supply delivers. When a current in your own circuit looks wrong, this sum at one node is the fastest test.

Four syntax rules that catch everyone once

SuffixFactorTrap
f10−151F is 1 femtofarad, not one farad
p n u10−12, 10−9, 10−6u stands for µ
m10−3M is also milli: case does not matter
k10310kohm is 10 kΩ: letters after a suffix are ignored
meg106the only way to write mega
g t109, 1012

Scale factors as ngspice reads them.

Rule one: the first line is the title and is never read as a part. Delete the title, so that VDD vdd 0 1.8 moves up to line 1, and it becomes the title. The source vanishes without an error or a warning, and every node prints 0 V.

Rule two: a value takes a scale suffix from the table, and the case of the letter does not matter, so M and m are both milli. Rule three: * at the start of a line makes a comment, and + at the start continues the line above. Rule four: .end closes the netlist, and anything after it is ignored.

Written 10M

VDD vdd 0 1.8
R1 vdd out 10M
R2 out 0 10k
RL out 0 100k

vout = 1.799998e+00 and isup = -1.979998e-04: R1 is 10 mΩ, so out sits on the supply.

Written 10meg

VDD vdd 0 1.8
R1 vdd out 10meg
R2 out 0 10k
RL out 0 100k

vout = 1.634877e-03 and isup = -1.798365e-07: a 10 MΩ pull against 9.091 kΩ.

The lab netlist with R1 changed, both measured on ngspice 42.

One more letter matters from E2 on. The SKY130 transistors used in this track are defined as subcircuits, so every transistor line starts with X, as in XM1 d g s b sky130_fd_pr__nfet_01v8 W=2 L=0.15.

Asked in interviews
  1. What does SPICE solve for, and with what law?

    The node voltages, plus the current of every voltage source, from Kirchhoff's current law at every node (modified nodal analysis). Nonlinear parts are solved by iterating on that same system.

  2. How do you measure a branch current in SPICE?

    Put a 0 V voltage source in series with the branch and read its current, or ask for the device's own current such as @r1[i]. Mind the sign: a source current is positive into its + node, so a supply prints negative.

  3. What is 1M in SPICE?

    One milli: 0.001. M and m both mean milli; mega is meg. Letters after a scale factor are ignored, so 1Mohm is still one milliohm.

Try it

Predict vout before you run, then compare. Read the print line in the log too: it shows i(vdd) negative and every @r[i] positive, because a resistor's current is counted from its first node to its second.

Now try three changes in order. Change R1 to 10M and read isup. Move the load to out2 with an ammeter VAM out out2 0 and read i(VAM). Finally, delete the title line so that VDD is first, and watch what disappears.

SPICEngspice 42 · simulator service
Edit the netlist, then run it
Expected measurements: vout = 8.571429e-01 isup = -9.428571e-05 ir2 = 8.571429e-05 irl = 8.571429e-06

Check yourself

Predict the outputThis netlist puts 1.8 V across 18 kΩ. Type the line meas prints, in the format ngspice uses (for example isup = -9.428571e-05).
* 1.8 V across 18 k
VDD vdd 0 1.8
R1 vdd 0 18k
.control
dc VDD 0 1.8 1.8
meas dc isup FIND i(VDD) AT=1.8
.endc
.end
ConceptEach line is meant to be a 1 MΩ resistor. Which one is not?
ConceptThe supply in the lab delivers 94.29 µA to the circuit. Why does i(VDD) print −94.29 µA?
ConceptA copy of the lab netlist lost its title, so its first line is now R1 vdd out 10k. What does op print?
ConceptAfter the ammeter change, print all shows vdd#branch = -9.42857e-05 and vam#branch = 8.571429e-06. What current flows in R2?

Remember

  • A netlist line is a name whose first letter gives the part, the nodes it connects to, and a value; the first line is always the title.
  • Terminals with the same node name are one point; node 0 is ground, the reference for every voltage.
  • SPICE solves Kirchhoff's current law at every node for the node voltages and each voltage source's current.
  • A source current is positive into its + node, so a supply prints negative; a 0 V source in series is an ammeter.
  • M is milli and meg is mega; letters after a scale factor are ignored.