ngspice/justins_bsimbulk_pmos_fix.txt

20 lines
3.0 KiB
Plaintext

This branch (jfisher/bsimbulk-osdi-parsing) is built on top of jfisher/osdi-fixes and adds a small set of changes I needed for ngspice to correctly load an OSDI BSIM-BULK model and wire it up with the right number of terminals.
There are two commits on top of the osdi-fixes branch.
The first commit tells ngspice that a .model line with level=77 means "use the bsimbulk OSDI device". Before this change, level=77 ended up with INPmodType = -1 and the model card got registered with an invalid type. I also added bsimbulk to the model-type allowlist in INP2M() so the M-prefixed MOSFET instance lines using a BSIM-BULK model don't get rejected with "incorrect model type". (The original fix in my main work tree also touched inpgmod.c for multi-bin support - that piece is unrelated to the wiring demonstration here so I left it out.)
The second commit is a bug demonstration. The function model_numnodes() in src/spicelib/parser/inp2m.c returns the expected number of terminals for a given model type. Without an entry for bsimbulk and bsimcmg_va it falls through to the default "return 4", so the parser sets up only 4 GENnode slots on the instance. The OSDI runtime then reads its 5-port descriptor but port 5 doesn't exist, so it rewires the body (or temperature) terminal to whatever happens to be in that memory slot.
In simulation a PMOS body diode forward-biased through the supply rail. A simple CMOS inverter draws amps in steady state and fails to switch rail-to-rail. Build the binary at the first commit and you can see the bad behavior; build it at the second commit and the wiring is correct. Am I promising this is fool-proof? I am not! This, and everything I subsequently upload need to be THOROUGHLY tested by a 3rd party!!!
I also added bsimcmg_va to the model-type allowlist in INP2M() for consistency - same five-node BSIM-CMG OSDI device with the same reasoning.
A note on the 5th pin. As I understand it, it's a thermal node, not just a temperature input. The model injects its own power dissipation as a current out of the node, and reads the resulting voltage back as a temperature rise above ambient (1 V at the thermal node = +1 K). So whatever you wire to T affects the device's actual operating temperature. One would typically attach a thermal RC network (Rth to set steady-state degrees-per-watt, Cth to set thermal time-constant) or just short T to ground if you don't care about self-heating in this particular run. Leaving T floating gives a singular matrix during OP solve.
For the basic wiring demonstration on this branch, I think the thing to do is to short T to ground on each device - that pins V(T) = 0 (ambient) and takes the self-heating dynamics out of the picture, so what we're testing is purely whether the body terminal lands on the actual body node instead of whatever stale value was in the OSDI node_mapping slot 5. Verifying self-heating with a real Rth/Cth is a separate test for another day.
Bottom line - given my so far lack of interest in the thermal performance of the devices, I've not paid this much attention.
Justin.