rewrite-rw, do.el applied
This commit is contained in:
parent
ae12f10fce
commit
510caa32c1
|
|
@ -10,24 +10,24 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
IFparm CSWpTable[] = { /* parameters */
|
||||
IOP( "control",CSW_CONTROL, IF_INSTANCE, "Name of controlling source"),
|
||||
IP( "on", CSW_IC_ON, IF_FLAG , "Initially closed"),
|
||||
IP( "off", CSW_IC_OFF, IF_FLAG , "Initially open"),
|
||||
OPU( "pos_node",CSW_POS_NODE,IF_INTEGER, "Positive node of switch"),
|
||||
OPU( "neg_node",CSW_NEG_NODE,IF_INTEGER, "Negative node of switch"),
|
||||
OP( "i" ,CSW_CURRENT, IF_REAL, "Switch current"),
|
||||
OP( "p" ,CSW_POWER, IF_REAL, "Instantaneous power")
|
||||
IFparm CSWpTable[] = { /* parameters */
|
||||
IOP( "control", CSW_CONTROL, IF_INSTANCE, "Name of controlling source"),
|
||||
IP( "on", CSW_IC_ON, IF_FLAG, "Initially closed"),
|
||||
IP( "off", CSW_IC_OFF, IF_FLAG, "Initially open"),
|
||||
OPU( "pos_node", CSW_POS_NODE, IF_INTEGER, "Positive node of switch"),
|
||||
OPU( "neg_node", CSW_NEG_NODE, IF_INTEGER, "Negative node of switch"),
|
||||
OP( "i", CSW_CURRENT, IF_REAL, "Switch current"),
|
||||
OP( "p", CSW_POWER, IF_REAL, "Instantaneous power")
|
||||
};
|
||||
|
||||
IFparm CSWmPTable[] = { /* model parameters */
|
||||
IOPU( "csw", CSW_CSW, IF_FLAG, "Current controlled switch model"),
|
||||
IOPU( "it", CSW_ITH, IF_REAL, "Threshold current"),
|
||||
IOPU( "ih", CSW_IHYS, IF_REAL, "Hysterisis current"),
|
||||
IOPU( "ron", CSW_RON, IF_REAL, "Closed resistance"),
|
||||
IOPU( "roff", CSW_ROFF, IF_REAL, "Open resistance"),
|
||||
OPU( "gon", CSW_GON, IF_REAL, "Closed conductance"),
|
||||
OPU( "goff", CSW_GOFF, IF_REAL, "Open conductance")
|
||||
IOPU( "csw", CSW_CSW, IF_FLAG, "Current controlled switch model"),
|
||||
IOPU( "it", CSW_ITH, IF_REAL, "Threshold current"),
|
||||
IOPU( "ih", CSW_IHYS, IF_REAL, "Hysterisis current"),
|
||||
IOPU( "ron", CSW_RON, IF_REAL, "Closed resistance"),
|
||||
IOPU( "roff", CSW_ROFF, IF_REAL, "Open resistance"),
|
||||
OPU( "gon", CSW_GON, IF_REAL, "Closed conductance"),
|
||||
OPU( "goff", CSW_GOFF, IF_REAL, "Open conductance")
|
||||
};
|
||||
|
||||
char *CSWnames[] = {
|
||||
|
|
@ -35,8 +35,8 @@ char *CSWnames[] = {
|
|||
"W-"
|
||||
};
|
||||
|
||||
int CSWnSize = NUMELEMS(CSWnames);
|
||||
int CSWpTSize = NUMELEMS(CSWpTable);
|
||||
int CSWmPTSize = NUMELEMS(CSWmPTable);
|
||||
int CSWiSize = sizeof(CSWinstance);
|
||||
int CSWmSize = sizeof(CSWmodel);
|
||||
int CSWnSize = NUMELEMS(CSWnames);
|
||||
int CSWpTSize = NUMELEMS(CSWpTable);
|
||||
int CSWmPTSize = NUMELEMS(CSWmPTable);
|
||||
int CSWiSize = sizeof(CSWinstance);
|
||||
int CSWmSize = sizeof(CSWmodel);
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@ Author: 1985 Gordon Jacobs
|
|||
|
||||
int
|
||||
CSWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis
|
||||
*/
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis
|
||||
*/
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
double g_now;
|
||||
int current_state;
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = CSWnextModel(model))
|
||||
for (; model; model = CSWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here; here=CSWnextInstance(here)) {
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||
|
||||
|
|
|
|||
|
|
@ -23,51 +23,51 @@ Author: 1987 Thomas L. Quarles
|
|||
int
|
||||
CSWask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select)
|
||||
{
|
||||
CSWinstance *here = (CSWinstance*)inst;
|
||||
CSWinstance *here = (CSWinstance *) inst;
|
||||
static char *msg = "Current and power not available in ac analysis";
|
||||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(which) {
|
||||
case CSW_CONTROL:
|
||||
value->uValue = here->CSWcontName;
|
||||
return OK;
|
||||
case CSW_POS_NODE:
|
||||
value->iValue = here->CSWposNode;
|
||||
return OK;
|
||||
case CSW_NEG_NODE:
|
||||
value->iValue = here->CSWnegNode;
|
||||
return OK;
|
||||
case CSW_CURRENT:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "CSWask";
|
||||
strcpy(errMsg,msg);
|
||||
return E_ASKCURRENT;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
here->CSWcond;
|
||||
}
|
||||
return OK;
|
||||
case CSW_POWER:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "CSWask";
|
||||
strcpy(errMsg,msg);
|
||||
return E_ASKPOWER;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
here->CSWcond;
|
||||
}
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (which) {
|
||||
case CSW_CONTROL:
|
||||
value->uValue = here->CSWcontName;
|
||||
return OK;
|
||||
case CSW_POS_NODE:
|
||||
value->iValue = here->CSWposNode;
|
||||
return OK;
|
||||
case CSW_NEG_NODE:
|
||||
value->iValue = here->CSWnegNode;
|
||||
return OK;
|
||||
case CSW_CURRENT:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "CSWask";
|
||||
strcpy(errMsg, msg);
|
||||
return E_ASKCURRENT;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
here->CSWcond;
|
||||
}
|
||||
return OK;
|
||||
case CSW_POWER:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "CSWask";
|
||||
strcpy(errMsg, msg);
|
||||
return E_ASKPOWER;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||
here->CSWcond;
|
||||
}
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/noisedef.h"
|
||||
#include "ngspice/complex.h"
|
||||
|
||||
/* structures used to describe current controlled switches */
|
||||
/* structures used to describe current controlled switches */
|
||||
|
||||
|
||||
/* information to describe each instance */
|
||||
|
|
@ -34,13 +34,13 @@ typedef struct sCSWinstance {
|
|||
IFuid CSWcontName; /* name of controlling source */
|
||||
|
||||
double *CSWposPosPtr; /* pointer to sparse matrix diagonal at
|
||||
(positive,positive) for switch conductance */
|
||||
(positive,positive) for switch conductance */
|
||||
double *CSWnegPosPtr; /* pointer to sparse matrix offdiagonal at
|
||||
(neagtive,positive) for switch conductance */
|
||||
(neagtive,positive) for switch conductance */
|
||||
double *CSWposNegPtr; /* pointer to sparse matrix offdiagonal at
|
||||
(positive,neagtive) for switch conductance */
|
||||
(positive,neagtive) for switch conductance */
|
||||
double *CSWnegNegPtr; /* pointer to sparse matrix diagonal at
|
||||
(neagtive,neagtive) for switch conductance */
|
||||
(neagtive,neagtive) for switch conductance */
|
||||
|
||||
double CSWcond; /* current conductance of switch */
|
||||
|
||||
|
|
@ -48,15 +48,15 @@ typedef struct sCSWinstance {
|
|||
#ifndef NONOISE
|
||||
double CSWnVar[NSTATVARS];
|
||||
#else /* NONOISE */
|
||||
double *CSWnVar;
|
||||
double *CSWnVar;
|
||||
#endif /* NONOISE */
|
||||
} CSWinstance ;
|
||||
} CSWinstance;
|
||||
|
||||
/* data per model */
|
||||
|
||||
#define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
||||
#define CSW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */
|
||||
#define CSW_NUM_STATES 2
|
||||
#define CSW_NUM_STATES 2
|
||||
|
||||
typedef struct sCSWmodel { /* model structure for a switch */
|
||||
|
||||
|
|
@ -64,7 +64,7 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
|||
|
||||
#define CSWmodType gen.GENmodType
|
||||
#define CSWnextModel(inst) ((struct sCSWmodel *)((inst)->gen.GENnextModel))
|
||||
#define CSWinstances(inst) ((CSWinstance *)((inst)->gen.GENinstances))
|
||||
#define CSWinstances(inst) ((CSWinstance *) ((inst)->gen.GENinstances))
|
||||
#define CSWmodName gen.GENmodName
|
||||
|
||||
double CSWonResistance; /* switch "on" resistance */
|
||||
|
|
@ -75,8 +75,8 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
|||
double CSWoffConduct; /* switch "off" conductance */
|
||||
|
||||
unsigned CSWonGiven : 1; /* flag to indicate on-resistance was specified */
|
||||
unsigned CSWoffGiven : 1;/* flag to indicate off-resistance was " */
|
||||
unsigned CSWthreshGiven : 1;/* flag to indicate threshold volt was given */
|
||||
unsigned CSWoffGiven : 1; /* flag to indicate off-resistance was " */
|
||||
unsigned CSWthreshGiven : 1; /* flag to indicate threshold volt was given */
|
||||
unsigned CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||
} CSWmodel;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ Author: 1985 Gordon M. Jacobs
|
|||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
extern int CSWask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int CSWacLoad(GENmodel*,CKTcircuit*);
|
||||
extern int CSWdelete(GENinstance*);
|
||||
extern int CSWask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||
extern int CSWacLoad(GENmodel *, CKTcircuit *);
|
||||
extern int CSWdelete(GENinstance *);
|
||||
extern void CSWdestroy(void);
|
||||
extern int CSWload(GENmodel*,CKTcircuit*);
|
||||
extern int CSWmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
||||
extern int CSWmDelete(GENmodel*);
|
||||
extern int CSWmParam(int,IFvalue*,GENmodel*);
|
||||
extern int CSWparam(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
||||
extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int CSWtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int CSWload(GENmodel *, CKTcircuit *);
|
||||
extern int CSWmAsk(CKTcircuit *, GENmodel *, int, IFvalue *);
|
||||
extern int CSWmDelete(GENmodel *);
|
||||
extern int CSWmParam(int, IFvalue *, GENmodel *);
|
||||
extern int CSWparam(int, IFvalue *, GENinstance *, IFvalue *);
|
||||
extern int CSWpzLoad(GENmodel *, CKTcircuit *, SPcomplex *);
|
||||
extern int CSWsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *);
|
||||
extern int CSWnoise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *);
|
||||
extern int CSWtrunc(GENmodel *, CKTcircuit *, double *);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef _CSWINIT_H
|
||||
#define _CSWINIT_H
|
||||
|
||||
extern IFparm CSWpTable[ ];
|
||||
extern IFparm CSWmPTable[ ];
|
||||
extern char *CSWnames[ ];
|
||||
extern IFparm CSWpTable[];
|
||||
extern IFparm CSWmPTable[];
|
||||
extern char *CSWnames[];
|
||||
extern int CSWpTSize;
|
||||
extern int CSWmPTSize;
|
||||
extern int CSWnSize;
|
||||
|
|
|
|||
|
|
@ -15,49 +15,49 @@ Modified: 2001 Jon Engelbert
|
|||
|
||||
int
|
||||
CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* actually load the current values into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
/* actually load the current values into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
double g_now;
|
||||
double i_ctrl;
|
||||
double previous_state = -1;
|
||||
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. */
|
||||
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. */
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = CSWnextModel(model))
|
||||
for (; model; model = CSWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here; here=CSWnextInstance(here)) {
|
||||
|
||||
old_current_state = ckt->CKTstates[0][here->CSWstate + 0];
|
||||
previous_state = ckt->CKTstates[1][here->CSWstate + 0];
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
old_current_state = ckt->CKTstates[0][here->CSWstate + 0];
|
||||
previous_state = ckt->CKTstates[1][here->CSWstate + 0];
|
||||
i_ctrl = ckt->CKTrhsOld[here->CSWcontBranch];
|
||||
|
||||
/* decide the state of the switch */
|
||||
|
||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
||||
if (ckt->CKTmode & (MODEINITFIX | MODEINITJCT)) {
|
||||
|
||||
if(here->CSWzero_stateGiven) {
|
||||
/* switch specified "on" */
|
||||
if (model->CSWiHysteresis >= 0 && i_ctrl > model->CSWiThreshold + model->CSWiHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else if (model->CSWiHysteresis < 0 && i_ctrl > model->CSWiThreshold - model->CSWiHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else
|
||||
current_state = HYST_ON;
|
||||
if (here->CSWzero_stateGiven) {
|
||||
/* switch specified "on" */
|
||||
if (model->CSWiHysteresis >= 0 && i_ctrl > model->CSWiThreshold + model->CSWiHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else if (model->CSWiHysteresis < 0 && i_ctrl > model->CSWiThreshold - model->CSWiHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else
|
||||
current_state = HYST_ON;
|
||||
} else {
|
||||
if (model->CSWiHysteresis >= 0 && i_ctrl < model->CSWiThreshold - model->CSWiHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else if (model->CSWiHysteresis < 0 && i_ctrl < model->CSWiThreshold + model->CSWiHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = HYST_OFF;
|
||||
if (model->CSWiHysteresis >= 0 && i_ctrl < model->CSWiThreshold - model->CSWiHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else if (model->CSWiHysteresis < 0 && i_ctrl < model->CSWiThreshold + model->CSWiHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = HYST_OFF;
|
||||
}
|
||||
|
||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||
|
|
@ -67,77 +67,77 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
||||
/* use state0 since INITTRAN or INITPRED already called */
|
||||
|
||||
if (model->CSWiHysteresis > 0) {
|
||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else {
|
||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
/* in hysteresis... change value if going from low to hysteresis,
|
||||
* or from hi to hysteresis. */
|
||||
|
||||
/* if previous state was in hysteresis, then don't change the state.. */
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous region in swload");
|
||||
}
|
||||
}
|
||||
if (model->CSWiHysteresis > 0) {
|
||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else {
|
||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
/* in hysteresis... change value if going from low to hysteresis,
|
||||
* or from hi to hysteresis. */
|
||||
|
||||
if(current_state != old_current_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
/* if previous state was in hysteresis, then don't change the state.. */
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous region in swload");
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ckt->CKTmode & (MODEINITTRAN|MODEINITPRED)) {
|
||||
if (current_state != old_current_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
}
|
||||
|
||||
if (model->CSWiHysteresis > 0) {
|
||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else {
|
||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
/* in hysteresis... change value if going from low to hysteresis,
|
||||
* or from hi to hysteresis. */
|
||||
|
||||
/* if previous state was in hysteresis, then don't change the state.. */
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous region in cswload");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ckt->CKTmode & (MODEINITTRAN | MODEINITPRED)) {
|
||||
|
||||
ckt->CKTstates[0][here->CSWstate + 0] = current_state;
|
||||
ckt->CKTstates[1][here->CSWstate + 0] = previous_state;
|
||||
if (model->CSWiHysteresis > 0) {
|
||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else {
|
||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
/* in hysteresis... change value if going from low to hysteresis,
|
||||
* or from hi to hysteresis. */
|
||||
|
||||
if (current_state == REALLY_ON || current_state == HYST_ON)
|
||||
g_now = model->CSWonConduct;
|
||||
else
|
||||
g_now = model->CSWoffConduct;
|
||||
/* if previous state was in hysteresis, then don't change the state.. */
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous region in cswload");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ckt->CKTstates[0][here->CSWstate + 0] = current_state;
|
||||
ckt->CKTstates[1][here->CSWstate + 0] = previous_state;
|
||||
|
||||
if (current_state == REALLY_ON || current_state == HYST_ON)
|
||||
g_now = model->CSWonConduct;
|
||||
else
|
||||
g_now = model->CSWoffConduct;
|
||||
|
||||
here->CSWcond = g_now;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,31 +23,31 @@ Author: 1987 Thomas L. Quarles
|
|||
int
|
||||
CSWmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
||||
{
|
||||
CSWmodel *here = (CSWmodel*)inst;
|
||||
CSWmodel *here = (CSWmodel *) inst;
|
||||
|
||||
NG_IGNORE(ckt);
|
||||
|
||||
switch(which) {
|
||||
case CSW_RON:
|
||||
value->rValue = here->CSWonResistance;
|
||||
return OK;
|
||||
case CSW_ROFF:
|
||||
value->rValue = here->CSWoffResistance;
|
||||
return OK;
|
||||
case CSW_ITH:
|
||||
value->rValue = here->CSWiThreshold;
|
||||
return OK;
|
||||
case CSW_IHYS:
|
||||
value->rValue = here->CSWiHysteresis;
|
||||
return OK;
|
||||
case CSW_GON:
|
||||
value->rValue = here->CSWonConduct;
|
||||
return OK;
|
||||
case CSW_GOFF:
|
||||
value->rValue = here->CSWoffConduct;
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (which) {
|
||||
case CSW_RON:
|
||||
value->rValue = here->CSWonResistance;
|
||||
return OK;
|
||||
case CSW_ROFF:
|
||||
value->rValue = here->CSWoffResistance;
|
||||
return OK;
|
||||
case CSW_ITH:
|
||||
value->rValue = here->CSWiThreshold;
|
||||
return OK;
|
||||
case CSW_IHYS:
|
||||
value->rValue = here->CSWiHysteresis;
|
||||
return OK;
|
||||
case CSW_GON:
|
||||
value->rValue = here->CSWonConduct;
|
||||
return OK;
|
||||
case CSW_GOFF:
|
||||
value->rValue = here->CSWoffConduct;
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,34 +16,34 @@ Modified: 2001 Jon Englebert
|
|||
int
|
||||
CSWmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
|
||||
switch(param) {
|
||||
case CSW_CSW:
|
||||
/* just says that this is a switch */
|
||||
break;
|
||||
case CSW_RON:
|
||||
model->CSWonResistance = value->rValue;
|
||||
model->CSWonConduct = 1.0/value->rValue;
|
||||
model->CSWonGiven = TRUE;
|
||||
break;
|
||||
case CSW_ROFF:
|
||||
model->CSWoffResistance = value->rValue;
|
||||
model->CSWoffConduct = 1.0/value->rValue;
|
||||
model->CSWoffGiven = TRUE;
|
||||
break;
|
||||
case CSW_ITH:
|
||||
model->CSWiThreshold = value->rValue;
|
||||
model->CSWthreshGiven = TRUE;
|
||||
break;
|
||||
case CSW_IHYS:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
/* model->CSWiHysteresis = fabs(value->rValue); */
|
||||
model->CSWiHysteresis = value->rValue;
|
||||
model->CSWhystGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (param) {
|
||||
case CSW_CSW:
|
||||
/* just says that this is a switch */
|
||||
break;
|
||||
case CSW_RON:
|
||||
model->CSWonResistance = value->rValue;
|
||||
model->CSWonConduct = 1.0 / value->rValue;
|
||||
model->CSWonGiven = TRUE;
|
||||
break;
|
||||
case CSW_ROFF:
|
||||
model->CSWoffResistance = value->rValue;
|
||||
model->CSWoffConduct = 1.0 / value->rValue;
|
||||
model->CSWoffGiven = TRUE;
|
||||
break;
|
||||
case CSW_ITH:
|
||||
model->CSWiThreshold = value->rValue;
|
||||
model->CSWthreshGiven = TRUE;
|
||||
break;
|
||||
case CSW_IHYS:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
/* model->CSWiHysteresis = fabs(value->rValue); */
|
||||
model->CSWiHysteresis = value->rValue;
|
||||
model->CSWhystGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Author: 1987 Gary W. Ng
|
|||
|
||||
|
||||
int
|
||||
CSWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
|
||||
CSWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
|
||||
{
|
||||
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
|
||||
|
||||
|
|
@ -35,83 +35,81 @@ CSWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *d
|
|||
double lnNdens;
|
||||
int current_state;
|
||||
|
||||
for (model=firstModel; model; model=CSWnextModel(model))
|
||||
for (inst=CSWinstances(model); inst; inst=CSWnextInstance(inst)) {
|
||||
for (model = firstModel; model; model = CSWnextModel(model))
|
||||
for (inst = CSWinstances(model); inst; inst = CSWnextInstance(inst)) {
|
||||
|
||||
switch (operation) {
|
||||
switch (operation) {
|
||||
|
||||
case N_OPEN:
|
||||
case N_OPEN:
|
||||
|
||||
/* see if we have to to produce a summary report */
|
||||
/* if so, name the noise generator */
|
||||
/* see if we have to to produce a summary report */
|
||||
/* if so, name the noise generator */
|
||||
|
||||
if (job->NStpsSm != 0)
|
||||
switch (mode) {
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->CSWname, "");
|
||||
break;
|
||||
case INT_NOIZ:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->CSWname, "");
|
||||
NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->CSWname, "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (job->NStpsSm != 0)
|
||||
switch (mode) {
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->CSWname, "");
|
||||
break;
|
||||
case INT_NOIZ:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->CSWname, "");
|
||||
NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->CSWname, "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
|
||||
case N_DENS:
|
||||
current_state = (int) ckt->CKTstates[0][inst->CSWstate + 0];
|
||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
||||
inst->CSWposNode,inst->CSWnegNode,
|
||||
current_state ? model->CSWonConduct : model->CSWoffConduct);
|
||||
case N_DENS:
|
||||
current_state = (int) ckt->CKTstates[0][inst->CSWstate + 0];
|
||||
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
|
||||
inst->CSWposNode, inst->CSWnegNode,
|
||||
current_state ? model->CSWonConduct : model->CSWoffConduct);
|
||||
|
||||
*OnDens += noizDens;
|
||||
*OnDens += noizDens;
|
||||
|
||||
if (data->delFreq == 0.0) {
|
||||
if (data->delFreq == 0.0) {
|
||||
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
|
||||
if (data->freq == job->NstartFreq)
|
||||
inst->CSWnVar[OUTNOIZ] = 0.0;
|
||||
} else { /* data->delFreq != 0.0 (we have to integrate) */
|
||||
tempOutNoise = Nintegrate(noizDens, lnNdens,
|
||||
inst->CSWnVar[LNLSTDENS], data);
|
||||
tempInNoise = Nintegrate(noizDens *
|
||||
data->GainSqInv ,lnNdens + data->lnGainInv,
|
||||
inst->CSWnVar[LNLSTDENS] + data->lnGainInv,
|
||||
data);
|
||||
inst->CSWnVar[OUTNOIZ] += tempOutNoise;
|
||||
inst->CSWnVar[INNOIZ] += tempInNoise;
|
||||
data->outNoiz += tempOutNoise;
|
||||
data->inNoise += tempInNoise;
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
}
|
||||
if (data->prtSummary)
|
||||
data->outpVector[data->outNumber++] = noizDens;
|
||||
break;
|
||||
if (data->freq == job->NstartFreq)
|
||||
inst->CSWnVar[OUTNOIZ] = 0.0;
|
||||
} else { /* data->delFreq != 0.0 (we have to integrate) */
|
||||
tempOutNoise = Nintegrate(noizDens, lnNdens,
|
||||
inst->CSWnVar[LNLSTDENS], data);
|
||||
tempInNoise = Nintegrate(noizDens *
|
||||
data->GainSqInv, lnNdens + data->lnGainInv,
|
||||
inst->CSWnVar[LNLSTDENS] + data->lnGainInv,
|
||||
data);
|
||||
inst->CSWnVar[OUTNOIZ] += tempOutNoise;
|
||||
inst->CSWnVar[INNOIZ] += tempInNoise;
|
||||
data->outNoiz += tempOutNoise;
|
||||
data->inNoise += tempInNoise;
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
}
|
||||
if (data->prtSummary)
|
||||
data->outpVector[data->outNumber++] = noizDens;
|
||||
break;
|
||||
|
||||
case INT_NOIZ: /* already calculated, just output */
|
||||
if (job->NStpsSm != 0) {
|
||||
data->outpVector[data->outNumber++] = inst->CSWnVar[OUTNOIZ];
|
||||
data->outpVector[data->outNumber++] = inst->CSWnVar[INNOIZ];
|
||||
} /* if */
|
||||
break;
|
||||
} /* switch (mode) */
|
||||
break;
|
||||
case INT_NOIZ: /* already calculated, just output */
|
||||
if (job->NStpsSm != 0) {
|
||||
data->outpVector[data->outNumber++] = inst->CSWnVar[OUTNOIZ];
|
||||
data->outpVector[data->outNumber++] = inst->CSWnVar[INNOIZ];
|
||||
} /* if */
|
||||
break;
|
||||
} /* switch (mode) */
|
||||
break;
|
||||
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,24 +16,24 @@ Author: 1985 Gordon Jacobs
|
|||
int
|
||||
CSWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
||||
{
|
||||
CSWinstance *here = (CSWinstance*)inst;
|
||||
CSWinstance *here = (CSWinstance *) inst;
|
||||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(param) {
|
||||
case CSW_CONTROL:
|
||||
here->CSWcontName = value->uValue;
|
||||
break;
|
||||
case CSW_IC_ON:
|
||||
if(value->iValue)
|
||||
here->CSWzero_stateGiven = TRUE;
|
||||
break;
|
||||
case CSW_IC_OFF:
|
||||
if(value->iValue)
|
||||
here->CSWzero_stateGiven = FALSE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (param) {
|
||||
case CSW_CONTROL:
|
||||
here->CSWcontName = value->uValue;
|
||||
break;
|
||||
case CSW_IC_ON:
|
||||
if (value->iValue)
|
||||
here->CSWzero_stateGiven = TRUE;
|
||||
break;
|
||||
case CSW_IC_OFF:
|
||||
if (value->iValue)
|
||||
here->CSWzero_stateGiven = FALSE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ Author: 1985 Gordon Jacobs
|
|||
/* ARGSUSED */
|
||||
int
|
||||
CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis
|
||||
*/
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis
|
||||
*/
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
double g_now;
|
||||
int current_state;
|
||||
|
|
@ -29,9 +29,9 @@ CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
NG_IGNORE(s);
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = CSWnextModel(model))
|
||||
for (; model; model = CSWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here; here=CSWnextInstance(here)) {
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||
|
||||
|
|
|
|||
|
|
@ -15,20 +15,20 @@ Author: 1985 Gordon Jacobs
|
|||
do { \
|
||||
if (!(here->ptr = SMPmakeElt(matrix, here->first, here->second))) \
|
||||
return E_NOMEM; \
|
||||
} while(0)
|
||||
} while (0)
|
||||
|
||||
|
||||
int
|
||||
CSWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||
/* load the switch conductance with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
/* load the switch conductance with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
|
||||
/* loop through all the current source models */
|
||||
for( ; model; model = CSWnextModel(model)) {
|
||||
for (; model; model = CSWnextModel(model)) {
|
||||
|
||||
/* Default Value Processing for Switch Model */
|
||||
if (!model->CSWthreshGiven)
|
||||
|
|
@ -37,24 +37,24 @@ CSWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
model->CSWiHysteresis = 0;
|
||||
if (!model->CSWonGiven) {
|
||||
model->CSWonConduct = CSW_ON_CONDUCTANCE;
|
||||
model->CSWonResistance = 1.0/model->CSWonConduct;
|
||||
model->CSWonResistance = 1.0 / model->CSWonConduct;
|
||||
}
|
||||
if (!model->CSWoffGiven) {
|
||||
model->CSWoffConduct = CSW_OFF_CONDUCTANCE;
|
||||
model->CSWoffResistance = 1.0/model->CSWoffConduct;
|
||||
model->CSWoffResistance = 1.0 / model->CSWoffConduct;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here; here=CSWnextInstance(here)) {
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
/* Default Value Processing for Switch Instance */
|
||||
here->CSWstate = *states;
|
||||
*states += CSW_NUM_STATES;
|
||||
|
||||
here->CSWcontBranch = CKTfndBranch(ckt,here->CSWcontName);
|
||||
if(here->CSWcontBranch == 0) {
|
||||
SPfrontEnd->IFerrorf (ERR_FATAL,
|
||||
"%s: unknown controlling source %s", here->CSWname, here->CSWcontName);
|
||||
here->CSWcontBranch = CKTfndBranch(ckt, here->CSWcontName);
|
||||
if (here->CSWcontBranch == 0) {
|
||||
SPfrontEnd->IFerrorf(ERR_FATAL,
|
||||
"%s: unknown controlling source %s", here->CSWname, here->CSWcontName);
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,36 +17,36 @@ Modified: 2000 AlansFixes
|
|||
int
|
||||
CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
|
||||
double lastChange, maxChange, maxStep, ref;
|
||||
|
||||
for( ; model; model = CSWnextModel(model))
|
||||
for(here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
for (; model; model = CSWnextModel(model))
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
lastChange =
|
||||
ckt->CKTstates[0][here->CSWstate + 1] -
|
||||
ckt->CKTstates[1][here->CSWstate + 1];
|
||||
if (ckt->CKTstates[0][here->CSWstate + 0]==0) {
|
||||
ref = model->CSWiThreshold + model->CSWiHysteresis;
|
||||
if (ckt->CKTstates[0][here->CSWstate + 1]<ref && lastChange>0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||
+ 0.00005;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
ckt->CKTstates[0][here->CSWstate + 1] -
|
||||
ckt->CKTstates[1][here->CSWstate + 1];
|
||||
if (ckt->CKTstates[0][here->CSWstate + 0] == 0) {
|
||||
ref = model->CSWiThreshold + model->CSWiHysteresis;
|
||||
if (ckt->CKTstates[0][here->CSWstate + 1] < ref && lastChange > 0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||
+ 0.00005;
|
||||
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
} else {
|
||||
ref = model->CSWiThreshold - model->CSWiHysteresis;
|
||||
if (ckt->CKTstates[0][here->CSWstate + 1]>ref && lastChange<0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||
- 0.00005;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
ref = model->CSWiThreshold - model->CSWiHysteresis;
|
||||
if (ckt->CKTstates[0][here->CSWstate + 1] > ref && lastChange < 0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||
- 0.00005;
|
||||
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,27 +9,27 @@ Author: 1987
|
|||
#include "swdefs.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
IFparm SWpTable[] = { /* parameters */
|
||||
IP("on", SW_IC_ON, IF_FLAG,"Switch initially closed"),
|
||||
IP("off", SW_IC_OFF, IF_FLAG,"Switch initially open"),
|
||||
IOPU("pos_node", SW_POS_NODE,IF_INTEGER,"Positive node of switch"),
|
||||
IOPU("neg_node", SW_NEG_NODE,IF_INTEGER,"Negative node of switch"),
|
||||
OPU("cont_p_node",SW_POS_CONT_NODE,IF_INTEGER,
|
||||
"Positive contr. node of switch"),
|
||||
OPU("cont_n_node",SW_NEG_CONT_NODE,IF_INTEGER,
|
||||
"Positive contr. node of switch"),
|
||||
OP("i", SW_CURRENT, IF_REAL, "Switch current"),
|
||||
OP("p", SW_POWER, IF_REAL, "Switch power")
|
||||
IFparm SWpTable[] = { /* parameters */
|
||||
IP("on", SW_IC_ON, IF_FLAG, "Switch initially closed"),
|
||||
IP("off", SW_IC_OFF, IF_FLAG, "Switch initially open"),
|
||||
IOPU("pos_node", SW_POS_NODE, IF_INTEGER, "Positive node of switch"),
|
||||
IOPU("neg_node", SW_NEG_NODE, IF_INTEGER, "Negative node of switch"),
|
||||
OPU("cont_p_node", SW_POS_CONT_NODE, IF_INTEGER,
|
||||
"Positive contr. node of switch"),
|
||||
OPU("cont_n_node", SW_NEG_CONT_NODE, IF_INTEGER,
|
||||
"Positive contr. node of switch"),
|
||||
OP("i", SW_CURRENT, IF_REAL, "Switch current"),
|
||||
OP("p", SW_POWER, IF_REAL, "Switch power")
|
||||
};
|
||||
|
||||
IFparm SWmPTable[] = { /* model parameters */
|
||||
IOPU( "sw", SW_MOD_SW, IF_FLAG,"Switch model"),
|
||||
IOPU( "vt", SW_MOD_VTH, IF_REAL,"Threshold voltage"),
|
||||
IOPU( "vh", SW_MOD_VHYS, IF_REAL,"Hysteresis voltage"),
|
||||
IOPU( "ron", SW_MOD_RON, IF_REAL,"Resistance when closed"),
|
||||
OPU( "gon", SW_MOD_GON, IF_REAL,"Conductance when closed"),
|
||||
IOPU( "roff", SW_MOD_ROFF, IF_REAL,"Resistance when open"),
|
||||
OPU( "goff", SW_MOD_GOFF, IF_REAL,"Conductance when open")
|
||||
IOPU( "sw", SW_MOD_SW, IF_FLAG, "Switch model"),
|
||||
IOPU( "vt", SW_MOD_VTH, IF_REAL, "Threshold voltage"),
|
||||
IOPU( "vh", SW_MOD_VHYS, IF_REAL, "Hysteresis voltage"),
|
||||
IOPU( "ron", SW_MOD_RON, IF_REAL, "Resistance when closed"),
|
||||
OPU( "gon", SW_MOD_GON, IF_REAL, "Conductance when closed"),
|
||||
IOPU( "roff", SW_MOD_ROFF, IF_REAL, "Resistance when open"),
|
||||
OPU( "goff", SW_MOD_GOFF, IF_REAL, "Conductance when open")
|
||||
};
|
||||
|
||||
char *SWnames[] = {
|
||||
|
|
@ -39,8 +39,8 @@ char *SWnames[] = {
|
|||
"SC-"
|
||||
};
|
||||
|
||||
int SWnSize = NUMELEMS(SWnames);
|
||||
int SWpTSize = NUMELEMS(SWpTable);
|
||||
int SWmPTSize = NUMELEMS(SWmPTable);
|
||||
int SWiSize = sizeof(SWinstance);
|
||||
int SWmSize = sizeof(SWmodel);
|
||||
int SWnSize = NUMELEMS(SWnames);
|
||||
int SWpTSize = NUMELEMS(SWpTable);
|
||||
int SWmPTSize = NUMELEMS(SWmPTable);
|
||||
int SWiSize = sizeof(SWinstance);
|
||||
int SWmSize = sizeof(SWmodel);
|
||||
|
|
|
|||
|
|
@ -14,20 +14,20 @@ Author: 1985 Gordon Jacobs
|
|||
|
||||
int
|
||||
SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis.
|
||||
*/
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis.
|
||||
*/
|
||||
{
|
||||
SWmodel *model = (SWmodel *)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
SWinstance *here;
|
||||
double g_now;
|
||||
int current_state;
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = SWnextModel(model))
|
||||
for (; model; model = SWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here; here=SWnextInstance(here)) {
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
|
||||
/* In AC analysis, just propogate the state... */
|
||||
|
||||
|
|
|
|||
|
|
@ -23,54 +23,54 @@ Author: 1987 Thomas L. Quarles
|
|||
int
|
||||
SWask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select)
|
||||
{
|
||||
SWinstance *here = (SWinstance *)inst;
|
||||
SWinstance *here = (SWinstance *) inst;
|
||||
static char *msg = "Current and power not available in ac analysis";
|
||||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(which) {
|
||||
case SW_POS_NODE:
|
||||
value->iValue = here->SWposNode;
|
||||
return OK;
|
||||
case SW_NEG_NODE:
|
||||
value->iValue = here->SWnegNode;
|
||||
return OK;
|
||||
case SW_POS_CONT_NODE:
|
||||
value->iValue = here->SWposCntrlNode;
|
||||
return OK;
|
||||
case SW_NEG_CONT_NODE:
|
||||
value->iValue = here->SWnegCntrlNode;
|
||||
return OK;
|
||||
case SW_CURRENT:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "SWask";
|
||||
strcpy(errMsg,msg);
|
||||
return E_ASKCURRENT;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
here->SWcond;
|
||||
}
|
||||
return OK;
|
||||
case SW_POWER:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "SWask";
|
||||
strcpy(errMsg,msg);
|
||||
return E_ASKPOWER;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
here->SWcond;
|
||||
}
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (which) {
|
||||
case SW_POS_NODE:
|
||||
value->iValue = here->SWposNode;
|
||||
return OK;
|
||||
case SW_NEG_NODE:
|
||||
value->iValue = here->SWnegNode;
|
||||
return OK;
|
||||
case SW_POS_CONT_NODE:
|
||||
value->iValue = here->SWposCntrlNode;
|
||||
return OK;
|
||||
case SW_NEG_CONT_NODE:
|
||||
value->iValue = here->SWnegCntrlNode;
|
||||
return OK;
|
||||
case SW_CURRENT:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "SWask";
|
||||
strcpy(errMsg, msg);
|
||||
return E_ASKCURRENT;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
here->SWcond;
|
||||
}
|
||||
return OK;
|
||||
case SW_POWER:
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||
errRtn = "SWask";
|
||||
strcpy(errMsg, msg);
|
||||
return E_ASKPOWER;
|
||||
} else {
|
||||
value->rValue =
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
(ckt->CKTrhsOld[here->SWposNode] -
|
||||
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||
here->SWcond;
|
||||
}
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/complex.h"
|
||||
#include "ngspice/noisedef.h"
|
||||
|
||||
/* structures used to describe voltage controlled switches */
|
||||
/* structures used to describe voltage controlled switches */
|
||||
|
||||
|
||||
/* information to describe each instance */
|
||||
|
|
@ -33,13 +33,13 @@ typedef struct sSWinstance {
|
|||
const int SWnegCntrlNode; /* number of negative controlling node of switch */
|
||||
|
||||
double *SWposPosPtr; /* pointer to sparse matrix diagonal at
|
||||
(positive,positive) for switch conductance */
|
||||
(positive,positive) for switch conductance */
|
||||
double *SWnegPosPtr; /* pointer to sparse matrix offdiagonal at
|
||||
(neagtive,positive) for switch conductance */
|
||||
(neagtive,positive) for switch conductance */
|
||||
double *SWposNegPtr; /* pointer to sparse matrix offdiagonal at
|
||||
(positive,neagtive) for switch conductance */
|
||||
(positive,neagtive) for switch conductance */
|
||||
double *SWnegNegPtr; /* pointer to sparse matrix diagonal at
|
||||
(neagtive,neagtive) for switch conductance */
|
||||
(neagtive,neagtive) for switch conductance */
|
||||
|
||||
double SWcond; /* conductance of the switch now */
|
||||
|
||||
|
|
@ -49,13 +49,13 @@ typedef struct sSWinstance {
|
|||
#else /* NONOISE */
|
||||
double *SWnVar;
|
||||
#endif /* NONOISE */
|
||||
} SWinstance ;
|
||||
} SWinstance;
|
||||
|
||||
/* data per model */
|
||||
|
||||
#define SW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
||||
#define SW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */
|
||||
#define SW_NUM_STATES 2
|
||||
#define SW_NUM_STATES 2
|
||||
|
||||
typedef struct sSWmodel { /* model structure for a switch */
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ typedef struct sSWmodel { /* model structure for a switch */
|
|||
|
||||
#define SWmodType gen.GENmodType
|
||||
#define SWnextModel(inst) ((struct sSWmodel *)((inst)->gen.GENnextModel))
|
||||
#define SWinstances(inst) ((SWinstance *)((inst)->gen.GENinstances))
|
||||
#define SWinstances(inst) ((SWinstance *) ((inst)->gen.GENinstances))
|
||||
#define SWmodName gen.GENmodName
|
||||
|
||||
double SWonResistance; /* switch "on" resistance */
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ Author: 1985 Gordon M. Jacobs
|
|||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
|
||||
extern int SWacLoad(GENmodel*,CKTcircuit*);
|
||||
extern int SWask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int SWdelete(GENinstance*);
|
||||
extern int SWacLoad(GENmodel *, CKTcircuit *);
|
||||
extern int SWask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||
extern int SWdelete(GENinstance *);
|
||||
extern void SWdestroy(void);
|
||||
extern int SWload(GENmodel*,CKTcircuit*);
|
||||
extern int SWmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
||||
extern int SWmDelete(GENmodel*);
|
||||
extern int SWmParam(int,IFvalue*,GENmodel*);
|
||||
extern int SWparam(int,IFvalue*,GENinstance*,IFvalue*);
|
||||
extern int SWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
||||
extern int SWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
||||
extern int SWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int SWtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int SWload(GENmodel *, CKTcircuit *);
|
||||
extern int SWmAsk(CKTcircuit *, GENmodel *, int, IFvalue *);
|
||||
extern int SWmDelete(GENmodel *);
|
||||
extern int SWmParam(int, IFvalue *, GENmodel *);
|
||||
extern int SWparam(int, IFvalue *, GENinstance *, IFvalue *);
|
||||
extern int SWpzLoad(GENmodel *, CKTcircuit *, SPcomplex *);
|
||||
extern int SWsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *);
|
||||
extern int SWnoise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *);
|
||||
extern int SWtrunc(GENmodel *, CKTcircuit *, double *);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef _SWINIT_H
|
||||
#define _SWINIT_H
|
||||
|
||||
extern IFparm SWpTable[ ];
|
||||
extern IFparm SWmPTable[ ];
|
||||
extern char *SWnames[ ];
|
||||
extern IFparm SWpTable[];
|
||||
extern IFparm SWmPTable[];
|
||||
extern char *SWnames[];
|
||||
extern int SWpTSize;
|
||||
extern int SWmPTSize;
|
||||
extern int SWnSize;
|
||||
|
|
|
|||
|
|
@ -15,53 +15,53 @@ Modified: 2001 Jon Engelbert
|
|||
|
||||
int
|
||||
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* actually load the current values into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
/* actually load the current values into the
|
||||
* sparse matrix previously provided
|
||||
*/
|
||||
{
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
SWinstance *here;
|
||||
double g_now;
|
||||
double v_ctrl;
|
||||
double previous_state = -1;
|
||||
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;
|
||||
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;
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = SWnextModel(model))
|
||||
for (; model; model = SWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here; here=SWnextInstance(here)) {
|
||||
|
||||
old_current_state = ckt->CKTstates[0][here->SWstate + 0];
|
||||
previous_state = ckt->CKTstates[1][here->SWstate + 0];
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
|
||||
v_ctrl =
|
||||
ckt->CKTrhsOld[here->SWposCntrlNode] -
|
||||
ckt->CKTrhsOld[here->SWnegCntrlNode];
|
||||
|
||||
/* decide the state of the switch */
|
||||
|
||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
||||
old_current_state = ckt->CKTstates[0][here->SWstate + 0];
|
||||
previous_state = ckt->CKTstates[1][here->SWstate + 0];
|
||||
|
||||
if(here->SWzero_stateGiven) {
|
||||
/* switch specified "on" */
|
||||
if (model->SWvHysteresis >= 0 && v_ctrl > model->SWvThreshold + model->SWvHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else if (model->SWvHysteresis < 0 && v_ctrl > model->SWvThreshold - model->SWvHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else
|
||||
current_state = HYST_ON;
|
||||
v_ctrl =
|
||||
ckt->CKTrhsOld[here->SWposCntrlNode] -
|
||||
ckt->CKTrhsOld[here->SWnegCntrlNode];
|
||||
|
||||
/* decide the state of the switch */
|
||||
|
||||
if (ckt->CKTmode & (MODEINITFIX | MODEINITJCT)) {
|
||||
|
||||
if (here->SWzero_stateGiven) {
|
||||
/* switch specified "on" */
|
||||
if (model->SWvHysteresis >= 0 && v_ctrl > model->SWvThreshold + model->SWvHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else if (model->SWvHysteresis < 0 && v_ctrl > model->SWvThreshold - model->SWvHysteresis)
|
||||
current_state = REALLY_ON;
|
||||
else
|
||||
current_state = HYST_ON;
|
||||
} else {
|
||||
if (model->SWvHysteresis >= 0 && v_ctrl < model->SWvThreshold - model->SWvHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else if (model->SWvHysteresis < 0 && v_ctrl < model->SWvThreshold + model->SWvHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = HYST_OFF;
|
||||
if (model->SWvHysteresis >= 0 && v_ctrl < model->SWvThreshold - model->SWvHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else if (model->SWvHysteresis < 0 && v_ctrl < model->SWvThreshold + model->SWvHysteresis)
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = HYST_OFF;
|
||||
}
|
||||
|
||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||
|
|
@ -71,76 +71,76 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
||||
|
||||
/* use state0 since INITTRAN or INITPRED already called */
|
||||
if (model->SWvHysteresis > 0) {
|
||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = old_current_state;
|
||||
} else { // negative hysteresis case.
|
||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.
|
||||
// if previous state was in hysteresis, then don't change the state..
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous state in swload");
|
||||
}
|
||||
}
|
||||
|
||||
if(current_state != old_current_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
if (model->SWvHysteresis > 0) {
|
||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = old_current_state;
|
||||
} else { // negative hysteresis case.
|
||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.
|
||||
// if previous state was in hysteresis, then don't change the state..
|
||||
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = HYST_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = HYST_ON;
|
||||
else
|
||||
internalerror("bad value for previous state in swload");
|
||||
}
|
||||
}
|
||||
|
||||
} else if(ckt->CKTmode & (MODEINITTRAN|MODEINITPRED) ) {
|
||||
if (current_state != old_current_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
}
|
||||
|
||||
if (model->SWvHysteresis > 0) {
|
||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else { // negative hysteresis case.
|
||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
current_state = 0.0;
|
||||
if (previous_state == HYST_ON || previous_state == HYST_OFF)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = REALLY_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = REALLY_ON;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ckt->CKTmode & (MODEINITTRAN | MODEINITPRED)) {
|
||||
|
||||
// code added to force the state to be updated.
|
||||
// there is a possible problem. What if, during the transient analysis, the time is stepped
|
||||
// forward enough to change the switch's state, but that time point is rejected as being too
|
||||
// distant and then the time is pushed back to a time before the switch changed states.
|
||||
// After analyzing the transient code, it seems that this is not a problem because state updating
|
||||
// occurs before the convergence loop in transient processing.
|
||||
if (model->SWvHysteresis > 0) {
|
||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else
|
||||
current_state = previous_state;
|
||||
} else { // negative hysteresis case.
|
||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||
current_state = REALLY_ON;
|
||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||
current_state = REALLY_OFF;
|
||||
else {
|
||||
current_state = 0.0;
|
||||
if (previous_state == HYST_ON || previous_state == HYST_OFF)
|
||||
current_state = previous_state;
|
||||
else if (previous_state == REALLY_ON)
|
||||
current_state = REALLY_OFF;
|
||||
else if (previous_state == REALLY_OFF)
|
||||
current_state = REALLY_ON;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ckt->CKTstates[0][here->SWstate + 0] = current_state;
|
||||
ckt->CKTstates[0][here->SWstate + 1] = v_ctrl;
|
||||
// code added to force the state to be updated.
|
||||
// there is a possible problem. What if, during the transient analysis, the time is stepped
|
||||
// forward enough to change the switch's state, but that time point is rejected as being too
|
||||
// distant and then the time is pushed back to a time before the switch changed states.
|
||||
// After analyzing the transient code, it seems that this is not a problem because state updating
|
||||
// occurs before the convergence loop in transient processing.
|
||||
|
||||
if (current_state == REALLY_ON || current_state == HYST_ON)
|
||||
g_now = model->SWonConduct;
|
||||
else
|
||||
g_now = model->SWoffConduct;
|
||||
ckt->CKTstates[0][here->SWstate + 0] = current_state;
|
||||
ckt->CKTstates[0][here->SWstate + 1] = v_ctrl;
|
||||
|
||||
if (current_state == REALLY_ON || current_state == HYST_ON)
|
||||
g_now = model->SWonConduct;
|
||||
else
|
||||
g_now = model->SWoffConduct;
|
||||
|
||||
here->SWcond = g_now;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,31 +23,31 @@ Author: 1987 Thomas L. Quarles
|
|||
int
|
||||
SWmAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
||||
{
|
||||
SWmodel *model = (SWmodel *)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
|
||||
NG_IGNORE(ckt);
|
||||
|
||||
switch(which) {
|
||||
case SW_MOD_RON:
|
||||
value->rValue = model->SWonResistance;
|
||||
return OK;
|
||||
case SW_MOD_ROFF:
|
||||
value->rValue = model->SWoffResistance;
|
||||
return OK;
|
||||
case SW_MOD_VTH:
|
||||
value->rValue = model->SWvThreshold;
|
||||
return OK;
|
||||
case SW_MOD_VHYS:
|
||||
value->rValue = model->SWvHysteresis;
|
||||
return OK;
|
||||
case SW_MOD_GON:
|
||||
value->rValue = model->SWonConduct;
|
||||
return OK;
|
||||
case SW_MOD_GOFF:
|
||||
value->rValue = model->SWoffConduct;
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (which) {
|
||||
case SW_MOD_RON:
|
||||
value->rValue = model->SWonResistance;
|
||||
return OK;
|
||||
case SW_MOD_ROFF:
|
||||
value->rValue = model->SWoffResistance;
|
||||
return OK;
|
||||
case SW_MOD_VTH:
|
||||
value->rValue = model->SWvThreshold;
|
||||
return OK;
|
||||
case SW_MOD_VHYS:
|
||||
value->rValue = model->SWvHysteresis;
|
||||
return OK;
|
||||
case SW_MOD_GON:
|
||||
value->rValue = model->SWonConduct;
|
||||
return OK;
|
||||
case SW_MOD_GOFF:
|
||||
value->rValue = model->SWoffConduct;
|
||||
return OK;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,36 +16,36 @@ Modified: 2001 Jon Engelbert
|
|||
int
|
||||
SWmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||
{
|
||||
SWmodel *model = (SWmodel *)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
|
||||
switch(param) {
|
||||
case SW_MOD_SW:
|
||||
/* just says that this is a switch */
|
||||
break;
|
||||
case SW_MOD_RON:
|
||||
model->SWonResistance = value->rValue;
|
||||
model->SWonConduct = 1.0/value->rValue;
|
||||
model->SWonGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_ROFF:
|
||||
model->SWoffResistance = value->rValue;
|
||||
model->SWoffConduct = 1.0/value->rValue;
|
||||
model->SWoffGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_VTH:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
model->SWvThreshold = value->rValue;
|
||||
model->SWthreshGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_VHYS:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
// model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) :
|
||||
// value->rValue;
|
||||
model->SWvHysteresis = value->rValue;
|
||||
model->SWhystGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (param) {
|
||||
case SW_MOD_SW:
|
||||
/* just says that this is a switch */
|
||||
break;
|
||||
case SW_MOD_RON:
|
||||
model->SWonResistance = value->rValue;
|
||||
model->SWonConduct = 1.0 / value->rValue;
|
||||
model->SWonGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_ROFF:
|
||||
model->SWoffResistance = value->rValue;
|
||||
model->SWoffConduct = 1.0 / value->rValue;
|
||||
model->SWoffGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_VTH:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
model->SWvThreshold = value->rValue;
|
||||
model->SWthreshGiven = TRUE;
|
||||
break;
|
||||
case SW_MOD_VHYS:
|
||||
/* take absolute value of hysteresis voltage */
|
||||
// model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) :
|
||||
// value->rValue;
|
||||
model->SWvHysteresis = value->rValue;
|
||||
model->SWhystGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ Author: 1987 Gary W. Ng
|
|||
|
||||
|
||||
int
|
||||
SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
|
||||
SWnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens)
|
||||
{
|
||||
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
|
||||
|
||||
|
|
@ -35,81 +35,81 @@ SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
|
|||
double lnNdens;
|
||||
int current_state;
|
||||
|
||||
for (model=firstModel; model; model=SWnextModel(model))
|
||||
for (inst=SWinstances(model); inst; inst=SWnextInstance(inst)) {
|
||||
for (model = firstModel; model; model = SWnextModel(model))
|
||||
for (inst = SWinstances(model); inst; inst = SWnextInstance(inst)) {
|
||||
|
||||
switch (operation) {
|
||||
switch (operation) {
|
||||
|
||||
case N_OPEN:
|
||||
case N_OPEN:
|
||||
|
||||
/* see if we have to to produce a summary report */
|
||||
/* if so, name the noise generator */
|
||||
/* see if we have to to produce a summary report */
|
||||
/* if so, name the noise generator */
|
||||
|
||||
if (job->NStpsSm != 0)
|
||||
switch (mode) {
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->SWname, "");
|
||||
break;
|
||||
case INT_NOIZ:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->SWname, "");
|
||||
NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->SWname, "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
if (job->NStpsSm != 0)
|
||||
switch (mode) {
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->SWname, "");
|
||||
break;
|
||||
case INT_NOIZ:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->SWname, "");
|
||||
NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->SWname, "");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
|
||||
case N_DENS:
|
||||
current_state = (int) ckt->CKTstates[0][inst->SWstate + 0];
|
||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
||||
inst->SWposNode,inst->SWnegNode,
|
||||
current_state ? model->SWonConduct : model->SWoffConduct);
|
||||
case N_DENS:
|
||||
current_state = (int) ckt->CKTstates[0][inst->SWstate + 0];
|
||||
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
|
||||
inst->SWposNode, inst->SWnegNode,
|
||||
current_state ? model->SWonConduct : model->SWoffConduct);
|
||||
|
||||
*OnDens += noizDens;
|
||||
*OnDens += noizDens;
|
||||
|
||||
if (data->delFreq == 0.0) {
|
||||
if (data->delFreq == 0.0) {
|
||||
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
|
||||
if (data->freq == job->NstartFreq)
|
||||
inst->SWnVar[OUTNOIZ] = 0.0;
|
||||
} else { /* data->delFreq != 0.0 (we have to integrate) */
|
||||
tempOutNoise = Nintegrate(noizDens, lnNdens,
|
||||
inst->SWnVar[LNLSTDENS], data);
|
||||
tempInNoise = Nintegrate(noizDens *
|
||||
data->GainSqInv ,lnNdens + data->lnGainInv,
|
||||
inst->SWnVar[LNLSTDENS] + data->lnGainInv,
|
||||
data);
|
||||
inst->SWnVar[OUTNOIZ] += tempOutNoise;
|
||||
inst->SWnVar[INNOIZ] += tempInNoise;
|
||||
data->outNoiz += tempOutNoise;
|
||||
data->inNoise += tempInNoise;
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
}
|
||||
if (data->prtSummary)
|
||||
data->outpVector[data->outNumber++] = noizDens;
|
||||
break;
|
||||
if (data->freq == job->NstartFreq)
|
||||
inst->SWnVar[OUTNOIZ] = 0.0;
|
||||
} else { /* data->delFreq != 0.0 (we have to integrate) */
|
||||
tempOutNoise = Nintegrate(noizDens, lnNdens,
|
||||
inst->SWnVar[LNLSTDENS], data);
|
||||
tempInNoise = Nintegrate(noizDens *
|
||||
data->GainSqInv, lnNdens + data->lnGainInv,
|
||||
inst->SWnVar[LNLSTDENS] + data->lnGainInv,
|
||||
data);
|
||||
inst->SWnVar[OUTNOIZ] += tempOutNoise;
|
||||
inst->SWnVar[INNOIZ] += tempInNoise;
|
||||
data->outNoiz += tempOutNoise;
|
||||
data->inNoise += tempInNoise;
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
}
|
||||
if (data->prtSummary)
|
||||
data->outpVector[data->outNumber++] = noizDens;
|
||||
break;
|
||||
|
||||
case INT_NOIZ: /* already calculated, just output */
|
||||
if (job->NStpsSm != 0) {
|
||||
data->outpVector[data->outNumber++] = inst->SWnVar[OUTNOIZ];
|
||||
data->outpVector[data->outNumber++] = inst->SWnVar[INNOIZ];
|
||||
} /* if */
|
||||
break;
|
||||
} /* switch (mode) */
|
||||
break;
|
||||
case INT_NOIZ: /* already calculated, just output */
|
||||
if (job->NStpsSm != 0) {
|
||||
data->outpVector[data->outNumber++] = inst->SWnVar[OUTNOIZ];
|
||||
data->outpVector[data->outNumber++] = inst->SWnVar[INNOIZ];
|
||||
} /* if */
|
||||
break;
|
||||
} /* switch (mode) */
|
||||
break;
|
||||
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
|
||||
return OK;
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,21 +16,21 @@ Author: 1985 Gordon Jacobs
|
|||
int
|
||||
SWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
||||
{
|
||||
SWinstance *here = (SWinstance *)inst;
|
||||
SWinstance *here = (SWinstance *) inst;
|
||||
|
||||
NG_IGNORE(select);
|
||||
|
||||
switch(param) {
|
||||
case SW_IC_ON:
|
||||
if(value->iValue)
|
||||
here->SWzero_stateGiven = TRUE;
|
||||
break;
|
||||
case SW_IC_OFF:
|
||||
if(value->iValue)
|
||||
here->SWzero_stateGiven = FALSE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
switch (param) {
|
||||
case SW_IC_ON:
|
||||
if (value->iValue)
|
||||
here->SWzero_stateGiven = TRUE;
|
||||
break;
|
||||
case SW_IC_OFF:
|
||||
if (value->iValue)
|
||||
here->SWzero_stateGiven = FALSE;
|
||||
break;
|
||||
default:
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ Author: 1985 Gordon Jacobs
|
|||
/* ARGSUSED */
|
||||
int
|
||||
SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis.
|
||||
*/
|
||||
/* load the current values into the
|
||||
* sparse matrix previously provided
|
||||
* during AC analysis.
|
||||
*/
|
||||
{
|
||||
SWmodel *model = (SWmodel *)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
SWinstance *here;
|
||||
double g_now;
|
||||
int current_state;
|
||||
|
|
@ -29,9 +29,9 @@ SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
|||
NG_IGNORE(s);
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model; model = SWnextModel(model))
|
||||
for (; model; model = SWnextModel(model))
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here; here=SWnextInstance(here)) {
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
|
||||
/* In AC analysis, just propogate the state... */
|
||||
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@ Author: 1985 Gordon Jacobs
|
|||
|
||||
int
|
||||
SWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||
/* load the switch conductance with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
/* load the switch conductance with those pointers needed later
|
||||
* for fast matrix loading
|
||||
*/
|
||||
{
|
||||
SWmodel *model = (SWmodel *)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
SWinstance *here;
|
||||
|
||||
/* loop through all the current source models */
|
||||
for( ; model; model = SWnextModel(model)) {
|
||||
for (; model; model = SWnextModel(model)) {
|
||||
|
||||
/* Default Value Processing for Switch Model */
|
||||
if (!model->SWthreshGiven)
|
||||
|
|
@ -38,21 +38,21 @@ SWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
model->SWvHysteresis = 0;
|
||||
if (!model->SWonGiven) {
|
||||
model->SWonConduct = SW_ON_CONDUCTANCE;
|
||||
model->SWonResistance = 1.0/model->SWonConduct;
|
||||
}
|
||||
model->SWonResistance = 1.0 / model->SWonConduct;
|
||||
}
|
||||
if (!model->SWoffGiven) {
|
||||
model->SWoffConduct = SW_OFF_CONDUCTANCE;
|
||||
model->SWoffResistance = 1.0/model->SWoffConduct;
|
||||
model->SWoffResistance = 1.0 / model->SWoffConduct;
|
||||
}
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here; here=SWnextInstance(here)) {
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
|
||||
here->SWstate = *states;
|
||||
*states += SW_NUM_STATES;
|
||||
|
||||
/* Default Value Processing for Switch Instance */
|
||||
/* none */
|
||||
/* none */
|
||||
|
||||
TSTALLOC(SWposPosPtr, SWposNode, SWposNode);
|
||||
TSTALLOC(SWposNegPtr, SWposNode, SWnegNode);
|
||||
|
|
|
|||
|
|
@ -16,35 +16,35 @@ Modified: 2000 AlansFixes
|
|||
int
|
||||
SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||
{
|
||||
SWmodel *model = (SWmodel*)inModel;
|
||||
SWmodel *model = (SWmodel *) inModel;
|
||||
SWinstance *here;
|
||||
double lastChange, maxChange, maxStep, ref;
|
||||
|
||||
for( ; model; model = SWnextModel(model))
|
||||
for(here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
for (; model; model = SWnextModel(model))
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
lastChange =
|
||||
ckt->CKTstates[0][here->SWstate + 1] -
|
||||
ckt->CKTstates[1][here->SWstate + 1];
|
||||
if (ckt->CKTstates[0][here->SWstate + 0]==0) {
|
||||
ref = model->SWvThreshold + model->SWvHysteresis;
|
||||
if (ckt->CKTstates[0][here->SWstate + 1]<ref && lastChange>0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||
+ 0.05;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
ckt->CKTstates[0][here->SWstate + 1] -
|
||||
ckt->CKTstates[1][here->SWstate + 1];
|
||||
if (ckt->CKTstates[0][here->SWstate + 0] == 0) {
|
||||
ref = model->SWvThreshold + model->SWvHysteresis;
|
||||
if (ckt->CKTstates[0][here->SWstate + 1] < ref && lastChange > 0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||
+ 0.05;
|
||||
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
} else {
|
||||
ref = model->SWvThreshold - model->SWvHysteresis;
|
||||
if (ckt->CKTstates[0][here->SWstate + 1]>ref && lastChange<0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||
- 0.05;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
ref = model->SWvThreshold - model->SWvHysteresis;
|
||||
if (ckt->CKTstates[0][here->SWstate + 1] > ref && lastChange < 0) {
|
||||
maxChange =
|
||||
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||
- 0.05;
|
||||
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep)
|
||||
*timeStep = maxStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue