Differences with ngspice42 and ngspice44

I have a subcircuit model that I’ve created to mimic the AimSpice level 16 model (poly-Si TFT) that I’ve been using for a while now. I recently updated from KiCAD 8.0 to KiCAD 9.0 which also moved me from ngspice 42 to ngspice 44. Once I updated, I quickly noticed that the subcircuit model I was using no longer works the same way that it did before - notably the devices turns on either earlier or later than anticipated (see images below). I tested the response separately using ngspice 43 and got the same response as ngspice 42. I tried to forced the matrix solver to be the same (setting SPARSE, reltol, abstol, vntol) - but this did not appear to have any effect. I also forced integration method to gear on both, and saw the same variation between the two versions.

My subcircuit model uses several conditional statements, and several comparisons of voltages where rounding could cause a change in the equation response. I can’t find any documentation, but did anything change in ngspice44 regarding the conditional (if) statements or how rounding is performed? I looked through the change list between ngspice43 and ngspice44 and didn’t see anything that would cause this effect, but is there another change that I missed or that might not be documented?

Ngspice42 simulation:
image
ngspice44 simulation:
image

Could you attach example projects that demonstrate this behavior? Otherwise it might be difficult to give you a good answer.

Are the netlists that kicad generates identical?

1 Like

I’m unable to upload the full project, but I’ve provided the netlist below and an image of the circuit - it is a discrete device test for a transistor. The netlists being generated are the same.

.include "A:/KiCAD/Amorphyx_Device_Libraries/amorphous_TFT_Model_RPI16_Von-adjusted.txt"
.save all
.probe alli
.probe p(XQ1)
.probe p(VPr1)
.probe p(V2)
.probe p(V1)
.probe p(Vdd1)
*.dc  V1 0 14 .1 V2 0 7 1 *output curve
*.dc  V1 -10 10 .1 V2 0 7 1 for symmetry
*.dc V2 -7 7 .1 *Transfer curve
*.tran 1e-06 90e-6 uic
*.options rshunt=1e12
.control
set wr_singlescale 
set wr_vecnames
option numdgt =7
*wrdata File_Location\File_Name.txt all
.endc

.dc V2 -15 15 100m
XQ1 0 Vg Net-_Q1-Drain_ a-IGZO_RPI16_TEST_to_match_15-9_9
VPr1 Vd Net-_Q1-Drain_ DC 0 
V2 Vg 0 DC .1 
V1 Vd 0 DC 0.1 
Vdd1 Vdd 0 DC 0 PULSE(0 1 1e-4 1e-6) 
.end

That looks like ngspice44 is more accurately including the sub threshold behaviour of mosfets. They don’t just snap on as the Vgs reaches the threshold voltage.

Unfortunately ngspice44 is inconsistent, see image below:
image

In either case, I’m more curious as to why ngspice44 is responding differently from ngspice42.

I haven’t used the built-in simulator in KICAD for a long time, but for testing you can try GitHub - ra3xdh/qucs_s: Qucs-S is a circuit simulation program with Qt-based GUI it will give an understanding on a simple example where the change occurs

1 Like

Could you maybe post your amorphous_TFT_Model_RPI16_Von-adjusted.txt model also (or is this confidential). So, the issue can be reproduced.

I have another wild guess, because you are saying that ngspice44 simulation results are not consistent. Have you been maybe playing with the “cshunt” option? Currently ngspice doesn’t consistently remove this option again. I was burned by this a little while ago (this is really just guess).

1 Like

Unfortunately I cannot share the entire model, I can provide examples of some statements in case they could cause issues:

Gdev DP SP value='Ids(V(G,SP),V(DP,S))'
.func Ids(Vgs,Vds) = '(Ileak(Vgs,Vds) + 1/( (1/Isub(Vgs,Vds)) + (1/Ia(Vgs,Vds)) ) ) * (M(Vgs,Vds)+1)' 
.func Ileak(Vgs,Vds) = 'coeff(Vds)*sum(Vgs,Vds)+Idiode(Vgs,Vds) + noise'
.func Isub(Vgs,Vds) = 'MUS*Cox*W/L*pow(Vsth,2)*exp(Vgt(Vgs,Vds)/Vsth)*(1-exp(-Vds/Vsth))'
.func Xtfe_lo(Vgs,Vds) = 'if((f(Vgs,Vds)>flo),(Xtfe_lo2(Vgs,Vds)),(Xtfe_lo1(Vgs,Vds)))'

I realize it may be difficult to find the root cause without the full model, which is why I was hoping someone might know if any changes were made to how ngspice44 solved the system.

I’m not using cshunt currently. By ngspice44 being not consistent, sometimes model parameters make the device start conducting before ngspice42 results, and other parameters make the device conduct after ngspice42 results (different parameters though, it doesn’t change when running the exact same parameters).