From d870c02ff653633f464aacd4d3d581d138869f5d Mon Sep 17 00:00:00 2001 From: rlar Date: Sun, 25 Feb 2018 10:47:42 +0100 Subject: [PATCH] use an enum, fixing commit commit 0dae4607a01e2bbf93a925f5c37385ad9ce232f2 Author: pnenzi Date: Wed Apr 25 18:28:20 2001 +0000 Added a patch to csw and sw from Jon Engelbert dealing with negative histeresys this commit changed state from ranging over {0,1} to ranging over {0,1,2,3} but did not fix queries to "state" accordingly add some fixme, express some "no return" function calls (internal error) to make sure the compiler understand whether vars are initialized or not. --- src/spicelib/devices/sw/swacload.c | 8 ++++---- src/spicelib/devices/sw/swdefs.h | 7 +++++++ src/spicelib/devices/sw/swload.c | 29 ++++++++++++++++------------- src/spicelib/devices/sw/swnoise.c | 9 ++++++--- src/spicelib/devices/sw/swparam.c | 2 ++ src/spicelib/devices/sw/swpzload.c | 8 ++++---- src/spicelib/devices/sw/swtrunc.c | 2 +- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/spicelib/devices/sw/swacload.c b/src/spicelib/devices/sw/swacload.c index a1d2e7edd..23336acfe 100644 --- a/src/spicelib/devices/sw/swacload.c +++ b/src/spicelib/devices/sw/swacload.c @@ -22,7 +22,6 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt) SWmodel *model = (SWmodel *)inModel; SWinstance *here; double g_now; - int current_state; /* loop through all the switch models */ for( ; model != NULL; model = SWnextModel(model)) { @@ -33,9 +32,10 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt) /* In AC analysis, just propogate the state... */ - current_state = (int) ckt->CKTstate0[here->SWswitchstate]; - - g_now = current_state?(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 a98a8b530..7c96e4950 100644 --- a/src/spicelib/devices/sw/swdefs.h +++ b/src/spicelib/devices/sw/swdefs.h @@ -83,6 +83,13 @@ typedef struct sSWmodel { /* model structure for a switch */ unsigned SWhystGiven : 1; /* flag to indicate hysteresis volt was given */ } SWmodel; +enum { + 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 */ #define SW_IC_ON 1 #define SW_IC_OFF 2 diff --git a/src/spicelib/devices/sw/swload.c b/src/spicelib/devices/sw/swload.c index 06216a987..a91c66e71 100644 --- a/src/spicelib/devices/sw/swload.c +++ b/src/spicelib/devices/sw/swload.c @@ -20,19 +20,15 @@ SWload(GENmodel *inModel, CKTcircuit *ckt) SWinstance *here; double g_now; double v_ctrl; - double previous_state = -1; - double current_state = -1; - double old_current_state = -1; - double REALLY_OFF = 0, REALLY_ON = 1; // switch is on or off, not in hysteresis region. - double HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region. -// double previous_region = -1; -// double current_region = -1; + int previous_state; + int current_state; + int old_current_state; 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]; + old_current_state = (int) ckt->CKTstate0[here->SWswitchstate]; + previous_state = (int) ckt->CKTstate1[here->SWswitchstate]; v_ctrl = ckt->CKTrhsOld [here->SWposCntrlNode] - @@ -89,11 +85,12 @@ SWload(GENmodel *inModel, CKTcircuit *ckt) current_state = HYST_ON; } else { internalerror("bad value for previous state in swload"); + controlled_exit(1); } } } - if (current_state != old_current_state) { + if ((current_state > 0) != (old_current_state > 0)) { ckt->CKTnoncon++; /* ensure one more iteration */ ckt->CKTtroubleElt = (GENinstance *) here; } @@ -119,10 +116,16 @@ SWload(GENmodel *inModel, CKTcircuit *ckt) current_state = REALLY_OFF; else if (previous_state == REALLY_OFF) current_state = REALLY_ON; - else - current_state = 0.0; + else { + internalerror("bad value for state in swload"); + controlled_exit(1); + } } } + + } else { + internalerror("bad things in swload"); + controlled_exit(1); } // code added to force the state to be updated. @@ -135,7 +138,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 1b8332033..4059392a2 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 *da double tempInNoise; double noizDens; double lnNdens; - int current_state; + double conductance; for (model=firstModel; model != NULL; model=SWnextModel(model)) { @@ -65,10 +65,13 @@ SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da 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?(model->SWonConduct):(model->SWoffConduct)); + conductance); *OnDens += noizDens; diff --git a/src/spicelib/devices/sw/swparam.c b/src/spicelib/devices/sw/swparam.c index bda497b0e..3cfa326d4 100644 --- a/src/spicelib/devices/sw/swparam.c +++ b/src/spicelib/devices/sw/swparam.c @@ -24,11 +24,13 @@ SWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) case SW_IC_ON: if(value->iValue) { here->SWzero_stateGiven = TRUE; + // FIXME, need to set the state somewhere too ! } break; case SW_IC_OFF: if(value->iValue) { here->SWzero_stateGiven = FALSE; + // FIXME, need to set the state somewhere too ! } break; default: diff --git a/src/spicelib/devices/sw/swpzload.c b/src/spicelib/devices/sw/swpzload.c index 4640473f2..81974760f 100644 --- a/src/spicelib/devices/sw/swpzload.c +++ b/src/spicelib/devices/sw/swpzload.c @@ -24,7 +24,6 @@ SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) SWmodel *model = (SWmodel *)inModel; SWinstance *here; double g_now; - int current_state; NG_IGNORE(s); @@ -37,9 +36,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?(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 a873a64d4..c1f51461c 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] == 0) { + if (ckt->CKTstate0[here->SWswitchstate] < 0) { ref = (model->SWvThreshold + model->SWvHysteresis); if (ckt->CKTstate0[here->SWctrlvalue] < ref && lastChange > 1e-3) {