use an enum, fixing commit

commit 0dae4607a0
Author: pnenzi <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.
This commit is contained in:
rlar 2018-02-25 10:47:42 +01:00
parent 454f2bfb64
commit d870c02ff6
7 changed files with 40 additions and 25 deletions

View File

@ -22,7 +22,6 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
SWmodel *model = (SWmodel *)inModel; SWmodel *model = (SWmodel *)inModel;
SWinstance *here; SWinstance *here;
double g_now; double g_now;
int current_state;
/* loop through all the switch models */ /* loop through all the switch models */
for( ; model != NULL; model = SWnextModel(model)) { for( ; model != NULL; model = SWnextModel(model)) {
@ -33,9 +32,10 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
/* In AC analysis, just propogate the state... */ /* In AC analysis, just propogate the state... */
current_state = (int) ckt->CKTstate0[here->SWswitchstate]; if (ckt->CKTstate0[here->SWswitchstate] > 0)
g_now = model->SWonConduct;
g_now = current_state?(model->SWonConduct):(model->SWoffConduct); else
g_now = model->SWoffConduct;
*(here->SWposPosPtr) += g_now; *(here->SWposPosPtr) += g_now;
*(here->SWposNegPtr) -= g_now; *(here->SWposNegPtr) -= g_now;

View File

@ -83,6 +83,13 @@ typedef struct sSWmodel { /* model structure for a switch */
unsigned SWhystGiven : 1; /* flag to indicate hysteresis volt was given */ unsigned SWhystGiven : 1; /* flag to indicate hysteresis volt was given */
} SWmodel; } 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 */ /* device parameters */
#define SW_IC_ON 1 #define SW_IC_ON 1
#define SW_IC_OFF 2 #define SW_IC_OFF 2

View File

@ -20,19 +20,15 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
SWinstance *here; SWinstance *here;
double g_now; double g_now;
double v_ctrl; double v_ctrl;
double previous_state = -1; int previous_state;
double current_state = -1; int current_state;
double old_current_state = -1; int old_current_state;
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;
for (; model; model = SWnextModel(model)) { for (; model; model = SWnextModel(model)) {
for (here = SWinstances(model); here; here=SWnextInstance(here)) { for (here = SWinstances(model); here; here=SWnextInstance(here)) {
old_current_state = ckt->CKTstate0[here->SWswitchstate]; old_current_state = (int) ckt->CKTstate0[here->SWswitchstate];
previous_state = ckt->CKTstate1[here->SWswitchstate]; previous_state = (int) ckt->CKTstate1[here->SWswitchstate];
v_ctrl = v_ctrl =
ckt->CKTrhsOld [here->SWposCntrlNode] - ckt->CKTrhsOld [here->SWposCntrlNode] -
@ -89,11 +85,12 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
current_state = HYST_ON; current_state = HYST_ON;
} else { } else {
internalerror("bad value for previous state in swload"); 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->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here; ckt->CKTtroubleElt = (GENinstance *) here;
} }
@ -119,10 +116,16 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
current_state = REALLY_OFF; current_state = REALLY_OFF;
else if (previous_state == REALLY_OFF) else if (previous_state == REALLY_OFF)
current_state = REALLY_ON; current_state = REALLY_ON;
else else {
current_state = 0.0; 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. // 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->SWswitchstate] = current_state;
ckt->CKTstate0[here->SWctrlvalue] = v_ctrl; ckt->CKTstate0[here->SWctrlvalue] = v_ctrl;
if ((current_state == REALLY_ON) || (current_state == HYST_ON)) if (current_state > 0)
g_now = model->SWonConduct; g_now = model->SWonConduct;
else else
g_now = model->SWoffConduct; g_now = model->SWoffConduct;

View File

@ -33,7 +33,7 @@ SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
double tempInNoise; double tempInNoise;
double noizDens; double noizDens;
double lnNdens; double lnNdens;
int current_state; double conductance;
for (model=firstModel; model != NULL; model=SWnextModel(model)) { 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) { switch (mode) {
case N_DENS: 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, NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
inst->SWposNode,inst->SWnegNode, inst->SWposNode,inst->SWnegNode,
current_state?(model->SWonConduct):(model->SWoffConduct)); conductance);
*OnDens += noizDens; *OnDens += noizDens;

View File

@ -24,11 +24,13 @@ SWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
case SW_IC_ON: case SW_IC_ON:
if(value->iValue) { if(value->iValue) {
here->SWzero_stateGiven = TRUE; here->SWzero_stateGiven = TRUE;
// FIXME, need to set the state somewhere too !
} }
break; break;
case SW_IC_OFF: case SW_IC_OFF:
if(value->iValue) { if(value->iValue) {
here->SWzero_stateGiven = FALSE; here->SWzero_stateGiven = FALSE;
// FIXME, need to set the state somewhere too !
} }
break; break;
default: default:

View File

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

View File

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