From 1d998d0c42a867cb9c537916946f7395f735ae88 Mon Sep 17 00:00:00 2001 From: rlar Date: Sat, 10 Mar 2018 13:42:27 +0100 Subject: [PATCH] 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 0dae4607a01e2bbf93a925f5c37385ad9ce232f2 > 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 --- src/spicelib/devices/csw/cswacld.c | 8 ++++---- src/spicelib/devices/csw/cswdefs.h | 8 ++++---- src/spicelib/devices/csw/cswload.c | 20 +++++++++++--------- src/spicelib/devices/csw/cswnoise.c | 9 ++++++--- src/spicelib/devices/csw/cswpzld.c | 8 ++++---- src/spicelib/devices/csw/cswtrunc.c | 2 +- src/spicelib/devices/sw/swacload.c | 8 ++++---- src/spicelib/devices/sw/swdefs.h | 8 ++++---- src/spicelib/devices/sw/swload.c | 23 +++++++++++------------ src/spicelib/devices/sw/swnoise.c | 9 ++++++--- src/spicelib/devices/sw/swpzload.c | 8 ++++---- src/spicelib/devices/sw/swtrunc.c | 2 +- 12 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/spicelib/devices/csw/cswacld.c b/src/spicelib/devices/csw/cswacld.c index a1bf492e6..ca20e2c5e 100644 --- a/src/spicelib/devices/csw/cswacld.c +++ b/src/spicelib/devices/csw/cswacld.c @@ -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; diff --git a/src/spicelib/devices/csw/cswdefs.h b/src/spicelib/devices/csw/cswdefs.h index 5401232ef..d48bc622d 100644 --- a/src/spicelib/devices/csw/cswdefs.h +++ b/src/spicelib/devices/csw/cswdefs.h @@ -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 */ diff --git a/src/spicelib/devices/csw/cswload.c b/src/spicelib/devices/csw/cswload.c index cd6c0d021..83343d081 100644 --- a/src/spicelib/devices/csw/cswload.c +++ b/src/spicelib/devices/csw/cswload.c @@ -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; diff --git a/src/spicelib/devices/csw/cswnoise.c b/src/spicelib/devices/csw/cswnoise.c index 62e31b0d1..7fa0884dc 100644 --- a/src/spicelib/devices/csw/cswnoise.c +++ b/src/spicelib/devices/csw/cswnoise.c @@ -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; diff --git a/src/spicelib/devices/csw/cswpzld.c b/src/spicelib/devices/csw/cswpzld.c index 9beb03f27..cf6be2414 100644 --- a/src/spicelib/devices/csw/cswpzld.c +++ b/src/spicelib/devices/csw/cswpzld.c @@ -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; diff --git a/src/spicelib/devices/csw/cswtrunc.c b/src/spicelib/devices/csw/cswtrunc.c index 8dd199c5d..de8d0af0b 100644 --- a/src/spicelib/devices/csw/cswtrunc.c +++ b/src/spicelib/devices/csw/cswtrunc.c @@ -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 = diff --git a/src/spicelib/devices/sw/swacload.c b/src/spicelib/devices/sw/swacload.c index f0ecf519d..9e8fba627 100644 --- a/src/spicelib/devices/sw/swacload.c +++ b/src/spicelib/devices/sw/swacload.c @@ -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; diff --git a/src/spicelib/devices/sw/swdefs.h b/src/spicelib/devices/sw/swdefs.h index fdc9386ce..38d865431 100644 --- a/src/spicelib/devices/sw/swdefs.h +++ b/src/spicelib/devices/sw/swdefs.h @@ -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 */ diff --git a/src/spicelib/devices/sw/swload.c b/src/spicelib/devices/sw/swload.c index f1e267508..c4f9ec047 100644 --- a/src/spicelib/devices/sw/swload.c +++ b/src/spicelib/devices/sw/swload.c @@ -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; diff --git a/src/spicelib/devices/sw/swnoise.c b/src/spicelib/devices/sw/swnoise.c index 9fe7eade8..f602c5adc 100644 --- a/src/spicelib/devices/sw/swnoise.c +++ b/src/spicelib/devices/sw/swnoise.c @@ -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; diff --git a/src/spicelib/devices/sw/swpzload.c b/src/spicelib/devices/sw/swpzload.c index 202da5925..f01d0d72f 100644 --- a/src/spicelib/devices/sw/swpzload.c +++ b/src/spicelib/devices/sw/swpzload.c @@ -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; diff --git a/src/spicelib/devices/sw/swtrunc.c b/src/spicelib/devices/sw/swtrunc.c index cb61318ae..9be098f5c 100644 --- a/src/spicelib/devices/sw/swtrunc.c +++ b/src/spicelib/devices/sw/swtrunc.c @@ -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 =