Fix a very old bug in the implementation of the
gummel-poon model formulas for the junction capacities.
(already in spice3f4)
For unknown reasons, the same formulas in the
diode mos1 mos2 mos6 jfet models
have been implemented correctly right from the beginning,
the typo was bjt specific.
Many Thanks for the concise and precise Bug Report
provided by Schabo Rumanus on the ngspice-users mailing list
> To: ngspice-users@lists.sourceforge.net
> Subject: [Ngspice-users] Temperatursimulation von Sperrschichtkapazitäten
Many Thanks to Dietmar Warning for his thorough verification
of this commit.
which moved processing of several parameters into a new function
ACM_SourceDrainResistances()
but did so incompletely.
As a consequence the matrix footprint was not correctly modified
when source or drainresistance is zero
Thanks for the bug report by "Sto" in message
> bug: mosfet models with deliberate NRD=0 (ngspice-27)
https://sourceforge.net/p/ngspice/discussion/133842/thread/fa39228d
This function is invoked several times during initialisation,
possibly with yet incomplete model and instance parameter settings.
And it might be invoked many times during dc sweep.
When "alter" is invoked after a break-point stopped a transient simulation,
then it might be necessary to update RESconductance
before continuing the transient simulation.
Thanks for the bug report to An Zou
in message "alter resistor value" on the ngspice-users forum
https://sourceforge.net/p/ngspice/discussion/133842/thread/33ce6855/
Note:
RESresist and RESacResist are device parameters
they do not reflect effective resistance when "ask"'ed
(don't reflect tc1, tc2, tce, m, scale, temp ...)
RESconduct and RESacConduct are "query-only" parameters
these report the effective conductance when "ask"'ed
(including tc1, tc2, tce, m, scale, temp ...)
and use a more robust test for local node numbers.
That is, transform this pattern :
if (here->Node && ...) {
CKTdltNNum(ckt, here->Node);
here->Node = 0;
}
into this :
if (here->Node > 0 && ...)
CKTdltNNum(ckt, here->Node);
here->Node = 0;
The change of "!= 0" ==> "> 0" accounts for rare cases where "Node"
might have been set to -1, (meaning "unconnected")
The unconditional execution of the zero assignment is for those cases
where "Node" might have been assigned to some external or other local Node.
If so, the variable would not be set to zero, confusing the "guarding" if's
in the corresponding XXXsetup() routine.
The Pattern to follow is:
1) unset and delete *all* local Nodes in XXXunsetup()
2) allocate all of them again in a re-invocation of XXXsetup(),
exactly the same way as in the very first invocation.
for almost all other external nodes (notable exception "txl")
src/spicelib/devices/*/*def*.h, declare external node variables const
1) The compiler shall emit an error message if we still mess around
with external node numbers.
2) To mark which elements of the instance struct are meant to be set
externally when parsing the netlist
These "external" node variables are exclusively set via the
overlay struct GENinstance, member GENnode[]
We shall not mess around with these "external" node variables
because it would get rather difficult to avoid bugs considering
re-invocation of the XXXsetup() routine.
This gets interesting for devices with optional ports,
which get copied around depending on the amount of connected ports.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes the complex cases,
which are external node variables (ports of the instance),
which might be moved over to other external node variables
to cope with optional port connections.
This is fixed by copying the node numbers to local shadow variables
to avoid messing with the external nodes.
Otherwise a following CKTsetup() might again meddle with the external
node variables, at least causing considerable confusion, probably causing
hard to find bugs.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes a little bit more complex cases,
which are local node variables which will start with value 0
and eventually be set with the result of a CKTmk..() invocations,
but might as well receive a node number from another node variable.
Here CKTdltNNum() must not be invoked if the node number is merely
a copy from another node variable.
All locally created nodes (CKTmk..() invocations in XXXsetup())
must be deleted in XXXunsetup()
Otherwise CKTmk..() invocations during a following CKTsetup()
will re-emit still used node numbers,
thus accidentally shorting nodes.
This patch fixes the simple cases,
which are local node variables which will start with value 0
and eventually be set with the result of a CKTmk..() invocation.
More complex cases evolve, if such a local variable might receive
a node number which origins from another node, or the netlist itself.
Invoke CKTdltNNum() in reverse order of local node creation in XXXsetup()
This fixes a bug at least in mesa and hfet1,
where already destroyed node variables have still been accessed
in the guarding 'if' of a later CKTdltNNum() stanza.
Invoking them in revers order easily prevents such bugs,
and improves readability.
Consider the following silent contracts:
1)
CKTsetup() invocations must be separated by a CKTunsetup() invocation
But CKTsetup() has an internal flag,
which will prevent re-invocation of DEVsetup()
But DEVsetup() will be called during sensitivity analysis,
bypassing this precaution. It is fatal if this will
cause another node allocation (CKTmk..()).
This commit tries to detect such cases.
(Note: many DEVsetup routines (all ?) have their CKTmk..() invocations
guarded to avoid reallocation of local nodes,
see commit f7f454c0a1
bug fix, fix the guard for device generated internal nodes (via CKTmkVolt())
)
FIXME:
DEVsetup() is seriously obfuscated by these guards.
If would be far better, if the sensitivity analysis
wouldn't sidestep into DEVsetup()
consider a device local variant of the CKTisSetup flag
2)
DEVunsetup() must delete all, each and every,
local allocated node in DEVsetup()
Otherwise CKTmk..() invocations in a following CKTsetup() will
return duplicate node numbers, effectively shorting device nodes.
This commit tries to detect incomplete CKTdltNNum() invocations.
3)
DEVunsetup() must not delete a netlist node.
This can easily happen in those devices which have optional ports,
which have code in DEVsetup() which copies node numbers to
local node variables.
This commit tries to detect such errors.