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:
parent
91d4f74b2e
commit
1d998d0c42
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
Loading…
Reference in New Issue