Spice is a powerful tool for circuit analysis. But it often surprises users with
. holes in its abilities and strange definitions
. lack of industry-wide standards
. the need for the user to model the physics of their circuit, not just draw the schematic

I hope this blog will educate users and promote discussion in these areas.

Spice3 convergence testing never works!

Keywords: Transient simulation, loss of accuracy, "timestep too small", "time step too small", bug fix

> This problem is in Berkeley Spice3 code and can only be fixed by your software vendor.
5Spice fixed this problem in early 2012. Documenting here so other Spice programs can be fixed.
Hope this helps make Spice more robust for all users!

History: Spice3 changed when it tested for convergence in the Transient simulation iteration control loop, compared to Spice2. This change occurs if Spice3 is compiled with "NEWCONV" defined, which is the default and runs faster.

"NEWCONV" introduces two major bugs that are still present in today's Berkeley Spice3 code. And quite possibly in many Spice programs, as these bugs are amazingly hard to find.

1) The flag set by active devices to indicate failure of convergence is ALWAYS overwritten.
Each active device model has a convTest() convergence function. This function sets a flag if the solution is too far from the solution of the previous iteration, based on Spice's solution tolerances.

The base level iteration control loop in code module niiter.c calls all these convergence test functions after every new solution. The concept: if none of these functions report a problem, then Spice has reached a solution within its error bounds. Otherwise do another iteration of the solution.

detail: niiter.c calls NIconvTest() (file niconv.c) which calls CKTconvTest() (file cktop.c)
               which calls the individual devices' convTest() functions.

The non-convergence flag ckt->CKTnoncon is set in the individual convTest() functions. The return value of the CKTcovTest() is the not the non-convergence flag, it is an error code but is set to zero if non-convergence. NIcovTest() returns the return value from CKTconvTest().

Problem: In niiter.c,  line
   ckt->CKTnoncon = NIconvTest(ckt);
overwrites a set non-convergence flag

Result: the iteration control loop never receives a set non-convergence flag, never does another iteration! Spice has other, less stringent ways of judging if it has found an accurate enough solution so this bug is not fatal (and not easily found).

Failing to do the requested iteration results in greater than expected solution error.
Also, in a few cases, this drifting away from the solution could end up with the dreaded "time step too small" failure. (with non-linear equations, a solution at the next time step is only guaranteed if we are mathematically "close" when we start solving).

2) After bug 1 is fixed, about half of the active device models never set the non-convergence flag even though their code runs properly.

The problem is with the pointers to the old and new solution data. The pointers were correct in Spice2 but end up pointing to the same data location in Spice3.

The problem models
ASRC, Diode, Diode2, BJT and all modern Berkeley MOSFET models  (all BSIM, B3SOI, etc).
These use pointer CKTrhsOld in their convergence test functions.
This usage means the function compares the same identical voltage as "old" and "new" - so will never detect non-convergence and set flag.

non-problem models
MOS1,MOS2,MOS3,MOS6,MOS9 and EKV models use pointer CKTrhs in their convergence functions. This is correct and they are able to detect non-convergence and set flag.
The JFET, JFET2 and MES models do their convergence testing in the Load function, they don't have convTest functions.

1 comment: