spicelib/devices/{sw,csw}, #8/, cleanup, enums

reorder enum values for "state" to simplify boolean expressions,
 and to make the miss-use of a "double" as "enum" less disturbing.
This commit will cause ngspice to exit()
  in certain not thought of cases.

See
> commit 0dae4607a0
> Date:   Wed Apr 25 18:28:20 2001 +0000
>
>     Added a patch to csw and sw from Jon Engelbert dealing with negative histeresys

which changed "state" to range over {0,1,2,3}
spicelib/devices/{sw,csw}, #8/, cleanup, enums
This commit is contained in:
rlar 2018-03-10 13:42:27 +01:00
parent 91d4f74b2e
commit 1d998d0c42
12 changed files with 60 additions and 53 deletions

View File

@ -16,14 +16,14 @@ CSWacLoad(GENmodel *inModel, CKTcircuit *ckt)
CSWmodel *model = (CSWmodel *) inModel;
CSWinstance *here;
double g_now;
int current_state;
for (; model; model = CSWnextModel(model))
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
current_state = (int) ckt->CKTstate0[here->CSWswitchstate];
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : model->CSWoffConduct;
if (ckt->CKTstate0[here->CSWswitchstate] > 0)
g_now = model->CSWonConduct;
else
g_now = model->CSWoffConduct;
*(here->CSWposPosPtr) += g_now;
*(here->CSWposNegPtr) -= g_now;

View File

@ -85,10 +85,10 @@ typedef struct sCSWmodel { /* model structure for a switch */
} CSWmodel;
enum {
REALLY_OFF = 0, // switch definitely off
REALLY_ON = 1, // switch definitely on
HYST_OFF = 2, // switch is off and in the hysteresis region
HYST_ON = 3, // switch is on and in the hysteresis region
REALLY_OFF = -2, // switch definitely off
HYST_OFF = -1, // switch is off and in the hysteresis region
HYST_ON = 1, // switch is on and in the hysteresis region
REALLY_ON = 2, // switch definitely on
};
/* device parameters */

View File

@ -32,17 +32,16 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
{
CSWmodel *model = (CSWmodel *) inModel;
CSWinstance *here;
double g_now;
double i_ctrl;
double previous_state = -1;
double current_state = -1, old_current_state = -1;
for (; model; model = CSWnextModel(model))
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
old_current_state = ckt->CKTstate0[here->CSWswitchstate];
previous_state = ckt->CKTstate1[here->CSWswitchstate];
i_ctrl = ckt->CKTrhsOld[here->CSWcontBranch];
int old_current_state = (int) ckt->CKTstate0[here->CSWswitchstate];
int previous_state = (int) ckt->CKTstate1[here->CSWswitchstate];
int current_state;
double g_now;
double i_ctrl = ckt->CKTrhsOld[here->CSWcontBranch];
/* decide the state of the switch */
@ -91,7 +90,7 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
current_state = previous_state;
}
if ((current_state == REALLY_ON || current_state == HYST_ON) != (old_current_state == REALLY_ON || old_current_state == HYST_ON)) {
if ((current_state > 0) != (old_current_state > 0)) {
ckt->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here;
}
@ -119,12 +118,15 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
else
current_state = previous_state;
}
} else {
internalerror("bad things in swload");
controlled_exit(1);
}
ckt->CKTstate0[here->CSWswitchstate] = current_state;
ckt->CKTstate1[here->CSWswitchstate] = previous_state;
if (current_state == REALLY_ON || current_state == HYST_ON)
if (current_state > 0)
g_now = model->CSWonConduct;
else
g_now = model->CSWoffConduct;

View File

@ -33,7 +33,7 @@ CSWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
double tempInNoise;
double noizDens;
double lnNdens;
int current_state;
double conductance;
for (model = firstModel; model; model = CSWnextModel(model))
for (inst = CSWinstances(model); inst; inst = CSWnextInstance(inst)) {
@ -61,10 +61,13 @@ CSWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
switch (mode) {
case N_DENS:
current_state = (int) ckt->CKTstate0[inst->CSWswitchstate];
if (ckt->CKTstate0[inst->CSWswitchstate] > 0)
conductance = model->CSWonConduct;
else
conductance = model->CSWoffConduct;
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
inst->CSWposNode, inst->CSWnegNode,
(current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : model->CSWoffConduct);
conductance);
*OnDens += noizDens;

View File

@ -17,16 +17,16 @@ CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
CSWmodel *model = (CSWmodel *) inModel;
CSWinstance *here;
double g_now;
int current_state;
NG_IGNORE(s);
for (; model; model = CSWnextModel(model))
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
current_state = (int) ckt->CKTstate0[here->CSWswitchstate];
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : model->CSWoffConduct;
if (ckt->CKTstate0[here->CSWswitchstate] > 0)
g_now = model->CSWonConduct;
else
g_now = model->CSWoffConduct;
*(here->CSWposPosPtr) += g_now;
*(here->CSWposNegPtr) -= g_now;

View File

@ -25,7 +25,7 @@ CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
lastChange =
ckt->CKTstate0[here->CSWctrlvalue] -
ckt->CKTstate1[here->CSWctrlvalue];
if (ckt->CKTstate0[here->CSWswitchstate] == REALLY_OFF || ckt->CKTstate0[here->CSWswitchstate] == HYST_OFF) {
if (ckt->CKTstate0[here->CSWswitchstate] < 0) {
ref = model->CSWiThreshold + fabs(model->CSWiHysteresis);
if (ckt->CKTstate0[here->CSWctrlvalue] < ref && lastChange > 0) {
maxChange =

View File

@ -16,16 +16,16 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
SWmodel *model = (SWmodel *) inModel;
SWinstance *here;
double g_now;
int current_state;
for (; model; model = SWnextModel(model))
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
/* In AC analysis, just propogate the state... */
current_state = (int) ckt->CKTstate0[here->SWswitchstate];
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : model->SWoffConduct;
if (ckt->CKTstate0[here->SWswitchstate] > 0)
g_now = model->SWonConduct;
else
g_now = model->SWoffConduct;
*(here->SWposPosPtr) += g_now;
*(here->SWposNegPtr) -= g_now;

View File

@ -84,10 +84,10 @@ typedef struct sSWmodel { /* model structure for a switch */
} SWmodel;
enum {
REALLY_OFF = 0, // switch definitely off
REALLY_ON = 1, // switch definitely on
HYST_OFF = 2, // switch is off and in the hysteresis region
HYST_ON = 3, // switch is on and in the hysteresis region
REALLY_OFF = -2, // switch definitely off
HYST_OFF = -1, // switch is off and in the hysteresis region
HYST_ON = 1, // switch is on and in the hysteresis region
REALLY_ON = 2, // switch definitely on
};
/* device parameters */

View File

@ -32,21 +32,16 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
{
SWmodel *model = (SWmodel *) inModel;
SWinstance *here;
double g_now;
double v_ctrl;
double previous_state = -1;
double current_state = -1;
double old_current_state = -1;
// double previous_region = -1;
// double current_region = -1;
for (; model; model = SWnextModel(model))
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
old_current_state = ckt->CKTstate0[here->SWswitchstate];
previous_state = ckt->CKTstate1[here->SWswitchstate];
int old_current_state = (int) ckt->CKTstate0[here->SWswitchstate];
int previous_state = (int) ckt->CKTstate1[here->SWswitchstate];
int current_state;
v_ctrl =
double g_now;
double v_ctrl =
ckt->CKTrhsOld[here->SWposCntrlNode] -
ckt->CKTrhsOld[here->SWnegCntrlNode];
@ -96,7 +91,7 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
current_state = previous_state;
}
if ((current_state == REALLY_ON || current_state == HYST_ON) != (old_current_state == REALLY_ON || old_current_state == HYST_ON)) {
if ((current_state > 0) != (old_current_state > 0)) {
ckt->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here;
}
@ -121,6 +116,10 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
else
current_state = previous_state;
}
} else {
internalerror("bad things in swload");
controlled_exit(1);
}
// code added to force the state to be updated.
@ -133,7 +132,7 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
ckt->CKTstate0[here->SWswitchstate] = current_state;
ckt->CKTstate0[here->SWctrlvalue] = v_ctrl;
if (current_state == REALLY_ON || current_state == HYST_ON)
if (current_state > 0)
g_now = model->SWonConduct;
else
g_now = model->SWoffConduct;

View File

@ -33,7 +33,7 @@ SWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *dat
double tempInNoise;
double noizDens;
double lnNdens;
int current_state;
double conductance;
for (model = firstModel; model; model = SWnextModel(model))
for (inst = SWinstances(model); inst; inst = SWnextInstance(inst)) {
@ -61,10 +61,13 @@ SWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *dat
switch (mode) {
case N_DENS:
current_state = (int) ckt->CKTstate0[inst->SWswitchstate];
if (ckt->CKTstate0[inst->SWswitchstate] > 0)
conductance = model->SWonConduct;
else
conductance = model->SWoffConduct;
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
inst->SWposNode, inst->SWnegNode,
(current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : model->SWoffConduct);
conductance);
*OnDens += noizDens;

View File

@ -17,7 +17,6 @@ SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
SWmodel *model = (SWmodel *) inModel;
SWinstance *here;
double g_now;
int current_state;
NG_IGNORE(s);
@ -26,9 +25,10 @@ SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
/* In AC analysis, just propogate the state... */
current_state = (int) ckt->CKTstate0[here->SWswitchstate];
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : model->SWoffConduct;
if (ckt->CKTstate0[here->SWswitchstate] > 0)
g_now = model->SWonConduct;
else
g_now = model->SWoffConduct;
*(here->SWposPosPtr) += g_now;
*(here->SWposNegPtr) -= g_now;

View File

@ -23,7 +23,7 @@ SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
lastChange =
ckt->CKTstate0[here->SWctrlvalue] -
ckt->CKTstate1[here->SWctrlvalue];
if (ckt->CKTstate0[here->SWswitchstate] == REALLY_OFF || ckt->CKTstate0[here->SWswitchstate] == HYST_OFF) {
if (ckt->CKTstate0[here->SWswitchstate] < 0) {
ref = model->SWvThreshold + fabs(model->SWvHysteresis);
if (ckt->CKTstate0[here->SWctrlvalue] < ref && lastChange > 0) {
maxChange =