spicelib/devices/{sw,csw}, #5/, bug fix, semantics of "state"

> 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

This commit changed "state" from ranging over {0,1} to ranging over {0,1,2,3}
but did not fix queries to "state" accordingly.
This commit is contained in:
rlar 2018-03-10 11:03:16 +01:00
parent 56d1d3901d
commit d0599517de
12 changed files with 24 additions and 16 deletions

View File

@ -23,7 +23,7 @@ CSWacLoad(GENmodel *inModel, CKTcircuit *ckt)
current_state = (int) ckt->CKTstate0[here->CSWswitchstate];
g_now = current_state ? model->CSWonConduct : model->CSWoffConduct;
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : model->CSWoffConduct;
*(here->CSWposPosPtr) += g_now;
*(here->CSWposNegPtr) -= g_now;

View File

@ -84,6 +84,13 @@ typedef struct sCSWmodel { /* model structure for a switch */
unsigned CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
} 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
};
/* device parameters */
#define CSW_CONTROL 1
#define CSW_IC_ON 2

View File

@ -22,10 +22,6 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
double i_ctrl;
double previous_state = -1;
double current_state = -1, 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. */
for (; model; model = CSWnextModel(model))
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
@ -81,7 +77,7 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
internalerror("bad value for previous region in swload");
}
if (current_state != old_current_state) {
if ((current_state == REALLY_ON || current_state == HYST_ON) != (old_current_state == REALLY_ON || old_current_state == HYST_ON)) {
ckt->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here;
}

View File

@ -64,7 +64,7 @@ CSWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
current_state = (int) ckt->CKTstate0[inst->CSWswitchstate];
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
inst->CSWposNode, inst->CSWnegNode,
current_state ? model->CSWonConduct : model->CSWoffConduct);
(current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : model->CSWoffConduct);
*OnDens += noizDens;

View File

@ -26,7 +26,7 @@ CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
current_state = (int) ckt->CKTstate0[here->CSWswitchstate];
g_now = current_state ? model->CSWonConduct : model->CSWoffConduct;
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->CSWonConduct : 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] == 0) {
if (ckt->CKTstate0[here->CSWswitchstate] == REALLY_OFF || ckt->CKTstate0[here->CSWswitchstate] == HYST_OFF) {
ref = model->CSWiThreshold + fabs(model->CSWiHysteresis);
if (ckt->CKTstate0[here->CSWctrlvalue] < ref && lastChange > 0) {
maxChange =

View File

@ -25,7 +25,7 @@ SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
current_state = (int) ckt->CKTstate0[here->SWswitchstate];
g_now = current_state ? model->SWonConduct : model->SWoffConduct;
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : model->SWoffConduct;
*(here->SWposPosPtr) += 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 */
} 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
};
/* device parameters */
#define SW_IC_ON 1
#define SW_IC_OFF 2

View File

@ -23,8 +23,6 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
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;
@ -83,7 +81,7 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
internalerror("bad value for previous state in swload");
}
if (current_state != old_current_state) {
if ((current_state == REALLY_ON || current_state == HYST_ON) != (old_current_state == REALLY_ON || old_current_state == HYST_ON)) {
ckt->CKTnoncon++; /* ensure one more iteration */
ckt->CKTtroubleElt = (GENinstance *) here;
}

View File

@ -64,7 +64,7 @@ SWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *dat
current_state = (int) ckt->CKTstate0[inst->SWswitchstate];
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
inst->SWposNode, inst->SWnegNode,
current_state ? model->SWonConduct : model->SWoffConduct);
(current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : model->SWoffConduct);
*OnDens += noizDens;

View File

@ -28,7 +28,7 @@ SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
current_state = (int) ckt->CKTstate0[here->SWswitchstate];
g_now = current_state ? model->SWonConduct : model->SWoffConduct;
g_now = (current_state == REALLY_ON || current_state == HYST_ON) ? model->SWonConduct : 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] == 0) {
if (ckt->CKTstate0[here->SWswitchstate] == REALLY_OFF || ckt->CKTstate0[here->SWswitchstate] == HYST_OFF) {
ref = model->SWvThreshold + fabs(model->SWvHysteresis);
if (ckt->CKTstate0[here->SWctrlvalue] < ref && lastChange > 0) {
maxChange =