How can I plot transistor currents after a simulation?

I’ve been playing with the ngspice simulator a bit, and for very basic simulations it seems to work fine, but I cannot figure out how to plot the currents of my transistors.

In LTSpice you can do this by just probing the pins.

I tried to add .save all, and then go to “Add Signals” but still don’t see any of the transistor currents.

The only currents I can see are those of voltage sources, so an ugly workaround is to insert 0V voltage sources everywhere you want to measure current, which is super awkward.

I can’t duplicate this on my end. Can you send screenshots of your schematic and what’s showing up in the simulator? Also, copy/paste your SPICE netlist here if you can.

Here is a screen shot that shows my schematic and all the signals shown in the simulator.
This includes the savecurrents option, but KiCad decides on its own what signals it saves, which does not include any transistor currents.

.title KiCad schematic
.include "/home/pepijn/code/skywater-pdk/libraries/sky130_fd_pr/latest/models/corners/tt.spice"
.include "/home/pepijn/code/skywater-pdk/libraries/sky130_fd_pr/latest/models/r+c/res_typical__cap_typical.spice"
.include "/home/pepijn/code/skywater-pdk/libraries/sky130_fd_pr/latest/models/r+c/res_typical__cap_typical__lin.spice"
V1 /vdd GND dc(10)
V2 /voff GND dc(5)
V3 /vin GND dc(5)
I1 /diff GND dc(1e-3)
XM1 /right /vgnd /diff /diff sky130_fd_pr__nfet_g5v0d10v5 L=0.5 W=10
XM2 /left /vin /diff /diff sky130_fd_pr__nfet_g5v0d10v5 L=0.5 W=10
XM5 /left /left /vdd /vdd sky130_fd_pr__pfet_g5v0d10v5 L=0.5 W=10
XM4 /right /right /vdd /vdd sky130_fd_pr__pfet_g5v0d10v5 L=0.5 W=10
R1 /vgnd /voff 50
XM3 /vgnd /left /vdd /vdd sky130_fd_pr__pfet_g5v0d10v5 L=0.5 W=10 M=100
I2 /vgnd GND dc(50e-3)
.save @v1[i]
.save @v2[i]
.save @v3[i]
.save @r1[i]
.save V(/diff)
.save V(/left)
.save V(/right)
.save V(/vdd)
.save V(/vgnd)
.save V(/vin)
.save V(/voff)
.param TEMP=27 
.option scale=1E-6 
.option savecurrents 
.dc V2 0 5 10m

Ah, you’re using MOSFET subcircuits. Unfortunately, I don’t know how to force the .save command onto subcircuit pin currents in ngspice. Perhaps @holger might know?

There are two issues here, one linked to Eeschema, the other to ngspice.

The command .savecurrent was developed for supporting the MOS1 model. With this model it will save Id, Ig, Is, and Ib. If one uses BSIM3 or BSIM4 models (required by the Skywater PDK), only Id will be saved. Ig, Ib, and Is vectors will remain empty. The native Berkeley models do not support reading Ig, Ib, and Is. Id is also saved, if the transistor resides in a subcircuit.

Obviously now Eeschema does not even read the single Id vector.

Adding .save something to ngspice (by a text box in the circuit window), ngspice will be forced to save the additional data, but Eeschema does not recognize them in its own memory.

The most useful solution would be to modify the BSIM3 and BSIM4 models in ngspice to offer the additional data. I will have a look. And Eeschema has to be modified as well (not my business).

Thanks for the information.

I’m very much interested in getting involved with writing EDA software.
I’m currently looking if eeschema is suitable for IC design, and running into some problems with the spice integration.

If either the ngspice or the eeschema problem is suitable for a first issue, I’d be more than happy to help.

Another thing that would be useful that I’m not sure if it’s an ngspice or eeschema problem: plotting more complex expressions of combinations of signals. Would that be a matter of adding the correct .save expression, and eeschema picking up on it? In that case fixing the currents maybe also takes care of other expressions.

You should write to the developers mailing list. There has been some talk about possible support for IC design but it’s not realistic yet. However, if someone can take that responsibility and help the team, it may become possible.

I have been adding this

set color0=white
set xbrushwidth=3
plot V(/diff) V(/vgnd)
plot @m.xm1.msky130_fd_pr__nfet_g5v0d10v5[id] @m.xm2.msky130_fd_pr__nfet_g5v0d10v5[id]
+ @m.xm3.msky130_fd_pr__pfet_g5v0d10v5[id] @m.xm4.msky130_fd_pr__pfet_g5v0d10v5[id] @m.xm5.msky130_fd_pr__pfet_g5v0d10v5[id]

to your spice netlist and simulated with standard ngspice.

This may be automated by a procedure as described in, which is using Eeschema for schematic entry and external ngspice for simulation and plotting.

The internal eeschema/ngspice interface is currently very limited. If you would go for Eeschema improvements (C++ coding), I would support this from the ngspice side.


EDIT: This has been achieved with ngspice from current master branch (soon to become ngspice-33) and adding

set ngbehavior = hski

to .spiceinit.

This is the main problem here, as Eeschema cannot read currents for any kind of subcircuit pins. The MOSFET level shouldn’t be relevant since those are internal to the subcircuit and he’s not trying to probe internal subcircuit nodes/branches. I even made a small project with a fake FET subcircuit which just has resistors inside. Eeschema simulator doesn’t populate these pins in the signal list. Sounds like the only workaround until Eeschema gets updated is to add small series resistors or 0V voltage sources (like @Pepijn_de_Vos mentioned in the first post). (3.4 KB)

You are right, I have been a little on the wrong track.

We want to measure the current at the ‘pins’ of a subcircuit. Inside ngspice, after reading and parsing the netlist, subcircuits are flattened. So there is no subcircuit any more when the simulation starts.

The only way for a SPICE simulator to measure the current in an arbitrary net is to insert a voltage source with 0V. This now has to be done manually, but of course can be automated.This netlist modification could be handled by Eeschema, but also by ngspice itself. For example a .probe command might be added to ngspice. The simulation time would increase (a bit) because of increased matrix size, but this is often neglgible.

OK, cool. Auto-adding voltage sources makes sense, and is probably what LTspice does too. I know they also have an option in the settings to save all voltages/current post-subcircuit-flattening. I just checked the options and they also have the ability to disable subcircuit pin current. One nice thing about doing it manually, is that you can easily keep track of which pin you are probing the current for. When doing it with an auto-generated list, the software has to use the pin naming used on the .subckt line, and model developers often use names like 20 and 99 instead of something a little more clear…like I dunno: INPUT and GROUND?

In my case the subcircuit is a thin wrapper around the actual mosfet, so I don’t see an immediate need for adding voltage sources to measure subcircuit interface currents in my case.

For now I think I’ll experiment a bit with the external interface, using ngspice directly, or maybe gaw as xschem seems to be doing.

I’ve also signed up for the developers list, so I’ll introduce myself there once I get accepted, to see if I can extend the built-in spice interface a bit.

To be clear, I don’t think KiCad as a whole is realistic for IC design. Making pcbnew do IC layout would probably not be worth it. I think the combination of eeschema+klayout is potentially more promising. But it all remains to be seen…

Most FOSS IC people seem to have settled on xschem for now, which at the moment appears to be more suitable. In particular, it apparently handles big hierarchical designs better.

1 Like

Here’s the mail:

No answers yet. I hope the developers will respond.

Hey, @Pepijn_de_Vos. Here are a couple threads that discuss possible improvements to the KiCad / ngspice experience. Might be worth skimming through to see if there’s something you want to help implement once you get access to do so.

How to improve the KiCad - ngspice interface

Including Default SPICE Models in KiCad

The 2nd link is a thread made by me trying to discuss the best way to deal with undefined semiconductor models. Since no one responded with any feedback, I decided to move forward on a side-project to create a default set of public domain device models which can be included as part of KiCad in a future release. I don’t know when that will be done, though.