spicelib/devices/{sw,csw}, cleanup for readability
This change is functional invariant, and has been checked with gcc for object file in-variance. For the details see the "rewrite-sw" branch
This commit is contained in:
parent
3dd2115291
commit
bcecc19e8b
|
|
@ -9,24 +9,25 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "cswdefs.h"
|
||||
#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[] = {
|
||||
|
|
@ -34,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);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -14,33 +12,24 @@ Author: 1985 Gordon Jacobs
|
|||
|
||||
int
|
||||
CSWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
||||
|
||||
/* 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 != NULL; model = CSWnextModel(model)) {
|
||||
for (; model; model = CSWnextModel(model))
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here != NULL ;
|
||||
here=CSWnextInstance(here)) {
|
||||
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||
|
||||
current_state = (int)*(ckt->CKTstate0 + here->CSWstate);
|
||||
|
||||
g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct);
|
||||
g_now = current_state ? model->CSWonConduct : model->CSWoffConduct;
|
||||
|
||||
*(here->CSWposPosPtr) += g_now;
|
||||
*(here->CSWposNegPtr) -= g_now;
|
||||
*(here->CSWnegPosPtr) -= g_now;
|
||||
*(here->CSWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine gives access to the internal device parameters
|
||||
|
|
@ -19,53 +17,53 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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 */
|
||||
|
|
@ -27,36 +27,36 @@ typedef struct sCSWinstance {
|
|||
#define CSWname gen.GENname
|
||||
#define CSWstate gen.GENstate
|
||||
|
||||
const int CSWposNode; /* number of positive node of switch */
|
||||
const int CSWnegNode; /* number of negative node of switch */
|
||||
int CSWcontBranch; /* number of branch of controlling current */
|
||||
const int CSWposNode; /* number of positive node of switch */
|
||||
const int CSWnegNode; /* number of negative node of switch */
|
||||
int CSWcontBranch; /* number of branch of controlling current */
|
||||
|
||||
IFuid CSWcontName; /* name of controlling source */
|
||||
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 */
|
||||
double CSWcond; /* current conductance of switch */
|
||||
|
||||
unsigned CSWzero_stateGiven : 1; /* flag to indicate initial state */
|
||||
#ifndef NONOISE
|
||||
double CSWnVar[NSTATVARS];
|
||||
#else /* NONOISE */
|
||||
double *CSWnVar;
|
||||
#endif /* NONOISE */
|
||||
} CSWinstance ;
|
||||
#else
|
||||
double *CSWnVar;
|
||||
#endif
|
||||
} 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 */
|
||||
|
|
@ -74,10 +74,10 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
|||
double CSWonConduct; /* switch "on" conductance */
|
||||
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 CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||
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 CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||
} CSWmodel;
|
||||
|
||||
/* device parameters */
|
||||
|
|
@ -104,4 +104,4 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
|||
|
||||
#include "cswext.h"
|
||||
|
||||
#endif /*CSW*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -12,55 +12,47 @@ Modified: 2001 Jon Engelbert
|
|||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
int
|
||||
CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
|
||||
/* 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 != NULL; model = CSWnextModel(model)) {
|
||||
for (; model; model = CSWnextModel(model))
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here != NULL ;
|
||||
here=CSWnextInstance(here)) {
|
||||
|
||||
old_current_state = *(ckt->CKTstates[0] + here->CSWstate);
|
||||
previous_state = *(ckt->CKTstates[1] + here->CSWstate);
|
||||
i_ctrl = *(ckt->CKTrhsOld +
|
||||
here->CSWcontBranch);
|
||||
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)) {
|
||||
|
|
@ -70,78 +62,78 @@ 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)) {
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
*(ckt->CKTstates[0] + here->CSWstate) = current_state;
|
||||
*(ckt->CKTstates[1] + here->CSWstate) = previous_state;
|
||||
if ((current_state == REALLY_ON) || (current_state == HYST_ON))
|
||||
g_now = model->CSWonConduct;
|
||||
else
|
||||
g_now = model->CSWoffConduct;
|
||||
here->CSWcond = g_now;
|
||||
|
||||
*(here->CSWposPosPtr) += g_now;
|
||||
|
|
@ -149,6 +141,6 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->CSWnegPosPtr) -= g_now;
|
||||
*(here->CSWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine gives access to the internal model parameters
|
||||
|
|
@ -19,35 +17,33 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
Author: 1985 Gordon Jacobs
|
||||
Modified: 2001 Jon Englebert
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/ifsim.h"
|
||||
|
|
@ -16,33 +14,35 @@ Modified: 2001 Jon Englebert
|
|||
int
|
||||
CSWmParam(int param, IFvalue *value, GENmodel *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);
|
||||
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;
|
||||
}
|
||||
return(OK);
|
||||
|
||||
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,90 +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 != NULL; model=CSWnextModel(model)) {
|
||||
for (inst=CSWinstances(model); inst != NULL; 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_CALC:
|
||||
switch (mode) {
|
||||
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->CSWname, "");
|
||||
break;
|
||||
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 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;
|
||||
*OnDens += noizDens;
|
||||
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
if (data->delFreq == 0.0) {
|
||||
|
||||
case N_DENS:
|
||||
current_state = (int)*(ckt->CKTstate0 + inst->CSWstate);
|
||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
||||
inst->CSWposNode,inst->CSWnegNode,
|
||||
current_state?(model->CSWonConduct):(model->CSWoffConduct));
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
|
||||
*OnDens += noizDens;
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
|
||||
if (data->delFreq == 0.0) {
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
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;
|
||||
|
||||
inst->CSWnVar[LNLSTDENS] = lnNdens;
|
||||
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];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
}
|
||||
}
|
||||
|
||||
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 N_CLOSE:
|
||||
return (OK); /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
} /* for model */
|
||||
|
||||
return(OK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "cswdefs.h"
|
||||
|
|
@ -12,30 +10,28 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -13,38 +11,28 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
||||
|
||||
/* 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;
|
||||
|
||||
NG_IGNORE(s);
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model != NULL; model = CSWnextModel(model)) {
|
||||
for (; model; model = CSWnextModel(model))
|
||||
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = CSWinstances(model); here != NULL ;
|
||||
here=CSWnextInstance(here)) {
|
||||
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||
|
||||
current_state = (int)*(ckt->CKTstate0 + here->CSWstate);
|
||||
|
||||
g_now = current_state?(model->CSWonConduct):(model->CSWoffConduct);
|
||||
g_now = current_state ? model->CSWonConduct : model->CSWoffConduct;
|
||||
|
||||
*(here->CSWposPosPtr) += g_now;
|
||||
*(here->CSWposNegPtr) -= g_now;
|
||||
*(here->CSWnegPosPtr) -= g_now;
|
||||
*(here->CSWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -11,61 +9,54 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
#define TSTALLOC(ptr, first, second) \
|
||||
do { \
|
||||
if (!(here->ptr = SMPmakeElt(matrix, here->first, here->second))) \
|
||||
return E_NOMEM; \
|
||||
} 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
|
||||
*/
|
||||
|
||||
{
|
||||
CSWmodel *model = (CSWmodel*)inModel;
|
||||
CSWmodel *model = (CSWmodel *) inModel;
|
||||
CSWinstance *here;
|
||||
|
||||
/* loop through all the current source models */
|
||||
for( ; model != NULL; model = CSWnextModel(model)) {
|
||||
for (; model; model = CSWnextModel(model)) {
|
||||
|
||||
/* Default Value Processing for Switch Model */
|
||||
if (!model->CSWthreshGiven) {
|
||||
if (!model->CSWthreshGiven)
|
||||
model->CSWiThreshold = 0;
|
||||
}
|
||||
if (!model->CSWhystGiven) {
|
||||
if (!model->CSWhystGiven)
|
||||
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 != NULL ;
|
||||
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);
|
||||
return(E_BADPARM);
|
||||
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;
|
||||
}
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||
return(E_NOMEM);\
|
||||
} } while(0)
|
||||
|
||||
TSTALLOC(CSWposPosPtr, CSWposNode, CSWposNode);
|
||||
TSTALLOC(CSWposNegPtr, CSWposNode, CSWnegNode);
|
||||
TSTALLOC(CSWnegPosPtr, CSWnegNode, CSWposNode);
|
||||
TSTALLOC(CSWnegNegPtr, CSWnegNode, CSWnegNode);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -13,37 +11,42 @@ Modified: 2000 AlansFixes
|
|||
|
||||
#include "cswdefs.h"
|
||||
|
||||
|
||||
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!= NULL; model = CSWnextModel(model)) {
|
||||
for(here = CSWinstances(model); here != NULL ;
|
||||
here = CSWnextInstance(here)) {
|
||||
lastChange = *(ckt->CKTstate0+(here->CSWstate+1)) -
|
||||
*(ckt->CKTstate1+(here->CSWstate+1));
|
||||
if (*(ckt->CKTstate0+(here->CSWstate))==0) {
|
||||
ref = (model->CSWiThreshold + model->CSWiHysteresis);
|
||||
if ((*(ckt->CKTstate0+(here->CSWstate+1))<ref) && (lastChange>0)) {
|
||||
maxChange = (ref - *(ckt->CKTstate0+(here->CSWstate+1))) *
|
||||
0.75 + 0.00005;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
||||
}
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
ref = (model->CSWiThreshold - model->CSWiHysteresis);
|
||||
if ((*(ckt->CKTstate0+(here->CSWstate+1))>ref) && (lastChange<0)) {
|
||||
maxChange = (ref - *(ckt->CKTstate0+(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,27 +9,25 @@ 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 +37,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);
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -14,34 +12,26 @@ Author: 1985 Gordon Jacobs
|
|||
|
||||
int
|
||||
SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* 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 != NULL; model = SWnextModel(model)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here != NULL ;
|
||||
here=SWnextInstance(here)) {
|
||||
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->SWstate);
|
||||
current_state = (int) ckt->CKTstates[0][here->SWstate + 0];
|
||||
|
||||
g_now = current_state?(model->SWonConduct):(model->SWoffConduct);
|
||||
g_now = current_state ? model->SWonConduct : model->SWoffConduct;
|
||||
|
||||
*(here->SWposPosPtr) += g_now;
|
||||
*(here->SWposNegPtr) -= g_now;
|
||||
*(here->SWnegPosPtr) -= g_now;
|
||||
*(here->SWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine gives access to the internal device parameters
|
||||
|
|
@ -19,56 +17,56 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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 */
|
||||
|
|
@ -27,35 +27,35 @@ typedef struct sSWinstance {
|
|||
#define SWname gen.GENname
|
||||
#define SWstate gen.GENstate
|
||||
|
||||
const int SWposNode; /* number of positive node of switch */
|
||||
const int SWnegNode; /* number of negative node of switch */
|
||||
const int SWposNode; /* number of positive node of switch */
|
||||
const int SWnegNode; /* number of negative node of switch */
|
||||
const int SWposCntrlNode; /* number of positive controlling node of switch */
|
||||
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 */
|
||||
double SWcond; /* conductance of the switch now */
|
||||
|
||||
unsigned SWzero_stateGiven : 1; /* flag to indicate initial state */
|
||||
#ifndef NONOISE
|
||||
double SWnVar[NSTATVARS];
|
||||
#else /* NONOISE */
|
||||
#else
|
||||
double *SWnVar;
|
||||
#endif /* NONOISE */
|
||||
} SWinstance ;
|
||||
#endif
|
||||
} 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 */
|
||||
|
|
@ -73,10 +73,10 @@ typedef struct sSWmodel { /* model structure for a switch */
|
|||
double SWonConduct; /* switch "on" conductance */
|
||||
double SWoffConduct; /* switch "off" conductance */
|
||||
|
||||
unsigned SWonGiven : 1; /* flag to indicate on-resistance was specified */
|
||||
unsigned SWoffGiven : 1; /* flag to indicate off-resistance was " */
|
||||
unsigned SWonGiven : 1; /* flag to indicate on-resistance was specified */
|
||||
unsigned SWoffGiven : 1; /* flag to indicate off-resistance was " */
|
||||
unsigned SWthreshGiven : 1; /* flag to indicate threshold volt was given */
|
||||
unsigned SWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||
unsigned SWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||
} SWmodel;
|
||||
|
||||
/* device parameters */
|
||||
|
|
@ -104,4 +104,4 @@ typedef struct sSWmodel { /* model structure for a switch */
|
|||
|
||||
#include "swext.h"
|
||||
|
||||
#endif /*SW*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -12,56 +12,51 @@ Modified: 2001 Jon Engelbert
|
|||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
int
|
||||
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
/* 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 != NULL; model = SWnextModel(model)) {
|
||||
for (; model; model = SWnextModel(model))
|
||||
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here != NULL ;
|
||||
here=SWnextInstance(here)) {
|
||||
|
||||
old_current_state = *(ckt->CKTstates[0] + here->SWstate);
|
||||
previous_state = *(ckt->CKTstates[1] + here->SWstate);
|
||||
old_current_state = ckt->CKTstates[0][here->SWstate + 0];
|
||||
previous_state = ckt->CKTstates[1][here->SWstate + 0];
|
||||
|
||||
v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode)
|
||||
- *(ckt->CKTrhsOld + here->SWnegCntrlNode);
|
||||
|
||||
/* decide the state of the switch */
|
||||
|
||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
||||
v_ctrl =
|
||||
ckt->CKTrhsOld[here->SWposCntrlNode] -
|
||||
ckt->CKTrhsOld[here->SWnegCntrlNode];
|
||||
|
||||
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;
|
||||
/* 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,79 +66,77 @@ 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");
|
||||
}
|
||||
}
|
||||
|
||||
if (current_state != old_current_state) {
|
||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
}
|
||||
|
||||
} else if(ckt->CKTmode & (MODEINITTRAN|MODEINITPRED) ) {
|
||||
} else if (ckt->CKTmode & (MODEINITTRAN | MODEINITPRED)) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
*(ckt->CKTstates[0] + here->SWstate) = current_state;
|
||||
*(ckt->CKTstates[0] + here->SWstate + 1) = v_ctrl;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
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;
|
||||
|
||||
if ((current_state == REALLY_ON) || (current_state == HYST_ON))
|
||||
g_now = model->SWonConduct;
|
||||
else
|
||||
g_now = model->SWoffConduct;
|
||||
here->SWcond = g_now;
|
||||
|
||||
*(here->SWposPosPtr) += g_now;
|
||||
|
|
@ -151,6 +144,6 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->SWnegPosPtr) -= g_now;
|
||||
*(here->SWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1987 Thomas L. Quarles
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This routine gives access to the internal model parameter
|
||||
|
|
@ -19,35 +17,33 @@ Author: 1987 Thomas L. Quarles
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
Author: 1985 Gordon Jacobs
|
||||
Modified: 2001 Jon Engelbert
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "swdefs.h"
|
||||
|
|
@ -16,36 +14,37 @@ Modified: 2001 Jon Engelbert
|
|||
int
|
||||
SWmParam(int param, IFvalue *value, GENmodel *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);
|
||||
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;
|
||||
}
|
||||
|
||||
return(OK);
|
||||
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,88 +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 != NULL; model=SWnextModel(model)) {
|
||||
for (inst=SWinstances(model); inst != NULL; 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_CALC:
|
||||
switch (mode) {
|
||||
|
||||
case N_DENS:
|
||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->SWname, "");
|
||||
break;
|
||||
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 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;
|
||||
*OnDens += noizDens;
|
||||
|
||||
case N_CALC:
|
||||
switch (mode) {
|
||||
if (data->delFreq == 0.0) {
|
||||
|
||||
case N_DENS:
|
||||
current_state = (int)*(ckt->CKTstate0 + inst->SWstate);
|
||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
||||
inst->SWposNode,inst->SWnegNode,
|
||||
current_state?(model->SWonConduct):(model->SWoffConduct));
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
|
||||
*OnDens += noizDens;
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
|
||||
if (data->delFreq == 0.0) {
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
|
||||
/* if we haven't done any previous integration, we need to */
|
||||
/* initialize our "history" variables */
|
||||
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;
|
||||
|
||||
inst->SWnVar[LNLSTDENS] = lnNdens;
|
||||
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];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
/* clear out our integration variable if it's the first pass */
|
||||
case N_CLOSE:
|
||||
return OK; /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
}
|
||||
}
|
||||
|
||||
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 N_CLOSE:
|
||||
return (OK); /* do nothing, the main calling routine will close */
|
||||
break; /* the plots */
|
||||
} /* switch (operation) */
|
||||
} /* for inst */
|
||||
} /* for model */
|
||||
|
||||
return(OK);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "swdefs.h"
|
||||
|
|
@ -12,28 +10,25 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
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);
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -13,39 +11,30 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/suffix.h"
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
||||
/* 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;
|
||||
|
||||
NG_IGNORE(s);
|
||||
|
||||
/* loop through all the switch models */
|
||||
for( ; model != NULL; model = SWnextModel(model)) {
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = SWinstances(model); here != NULL ;
|
||||
here=SWnextInstance(here)) {
|
||||
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->SWstate);
|
||||
current_state = (int) ckt->CKTstates[0][here->SWstate + 0];
|
||||
|
||||
g_now = current_state?(model->SWonConduct):(model->SWoffConduct);
|
||||
g_now = current_state ? model->SWonConduct : model->SWoffConduct;
|
||||
|
||||
*(here->SWposPosPtr) += g_now;
|
||||
*(here->SWposNegPtr) -= g_now;
|
||||
*(here->SWnegPosPtr) -= g_now;
|
||||
*(here->SWnegNegPtr) += g_now;
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Gordon Jacobs
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/smpdefs.h"
|
||||
|
|
@ -12,49 +10,42 @@ Author: 1985 Gordon Jacobs
|
|||
#include "ngspice/sperror.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
#define TSTALLOC(ptr, first, second) \
|
||||
do { \
|
||||
if (!(here->ptr = SMPmakeElt(matrix, here->first, here->second))) \
|
||||
return E_NOMEM; \
|
||||
} while (0)
|
||||
|
||||
|
||||
int
|
||||
SWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||
/* 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 != NULL; model = SWnextModel(model)) {
|
||||
for (; model; model = SWnextModel(model)) {
|
||||
|
||||
/* Default Value Processing for Switch Model */
|
||||
if (!model->SWthreshGiven) {
|
||||
if (!model->SWthreshGiven)
|
||||
model->SWvThreshold = 0;
|
||||
}
|
||||
if (!model->SWhystGiven) {
|
||||
if (!model->SWhystGiven)
|
||||
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 != NULL ;
|
||||
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 */
|
||||
|
||||
/* macro to make elements with built in test for out of memory */
|
||||
#define TSTALLOC(ptr,first,second) \
|
||||
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||
return(E_NOMEM);\
|
||||
} } while(0)
|
||||
/* none */
|
||||
|
||||
TSTALLOC(SWposPosPtr, SWposNode, SWposNode);
|
||||
TSTALLOC(SWposNegPtr, SWposNode, SWnegNode);
|
||||
|
|
@ -62,5 +53,6 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
TSTALLOC(SWnegNegPtr, SWnegNode, SWnegNode);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
|||
Author: 1985 Thomas L. Quarles
|
||||
Modified: 2000 AlansFixes
|
||||
**********/
|
||||
/*
|
||||
*/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/cktdefs.h"
|
||||
|
|
@ -12,36 +10,41 @@ Modified: 2000 AlansFixes
|
|||
#include "ngspice/suffix.h"
|
||||
#include "swdefs.h"
|
||||
|
||||
|
||||
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!= NULL; model = SWnextModel(model)) {
|
||||
for(here = SWinstances(model); here != NULL ;
|
||||
here = SWnextInstance(here)) {
|
||||
lastChange = *(ckt->CKTstate0+(here->SWstate+1)) -
|
||||
*(ckt->CKTstate1+(here->SWstate+1));
|
||||
if (*(ckt->CKTstate0+(here->SWstate))==0) {
|
||||
ref = (model->SWvThreshold + model->SWvHysteresis);
|
||||
if ((*(ckt->CKTstate0+(here->SWstate+1))<ref) && (lastChange>0)) {
|
||||
maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) *
|
||||
0.75 + 0.05;
|
||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
||||
}
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
ref = (model->SWvThreshold - model->SWvHysteresis);
|
||||
if ((*(ckt->CKTstate0+(here->SWstate+1))>ref) && (lastChange<0)) {
|
||||
maxChange = (ref - *(ckt->CKTstate0+(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue