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
da718ddf3b
commit
cb0baad184
|
|
@ -9,24 +9,25 @@ Author: 1987 Thomas L. Quarles
|
||||||
#include "cswdefs.h"
|
#include "cswdefs.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
IFparm CSWpTable[] = { /* parameters */
|
|
||||||
IOP( "control",CSW_CONTROL, IF_INSTANCE, "Name of controlling source"),
|
IFparm CSWpTable[] = { /* parameters */
|
||||||
IP( "on", CSW_IC_ON, IF_FLAG , "Initially closed"),
|
IOP("control", CSW_CONTROL, IF_INSTANCE, "Name of controlling source"),
|
||||||
IP( "off", CSW_IC_OFF, IF_FLAG , "Initially open"),
|
IP("on", CSW_IC_ON, IF_FLAG, "Initially closed"),
|
||||||
OPU( "pos_node",CSW_POS_NODE,IF_INTEGER, "Positive node of switch"),
|
IP("off", CSW_IC_OFF, IF_FLAG, "Initially open"),
|
||||||
OPU( "neg_node",CSW_NEG_NODE,IF_INTEGER, "Negative node of switch"),
|
OPU("pos_node", CSW_POS_NODE, IF_INTEGER, "Positive node of switch"),
|
||||||
OP( "i" ,CSW_CURRENT, IF_REAL, "Switch current"),
|
OPU("neg_node", CSW_NEG_NODE, IF_INTEGER, "Negative node of switch"),
|
||||||
OP( "p" ,CSW_POWER, IF_REAL, "Instantaneous power")
|
OP("i", CSW_CURRENT, IF_REAL, "Switch current"),
|
||||||
|
OP("p", CSW_POWER, IF_REAL, "Instantaneous power")
|
||||||
};
|
};
|
||||||
|
|
||||||
IFparm CSWmPTable[] = { /* model parameters */
|
IFparm CSWmPTable[] = { /* model parameters */
|
||||||
IOPU( "csw", CSW_CSW, IF_FLAG, "Current controlled switch model"),
|
IOPU("csw", CSW_CSW, IF_FLAG, "Current controlled switch model"),
|
||||||
IOPU( "it", CSW_ITH, IF_REAL, "Threshold current"),
|
IOPU("it", CSW_ITH, IF_REAL, "Threshold current"),
|
||||||
IOPU( "ih", CSW_IHYS, IF_REAL, "Hysterisis current"),
|
IOPU("ih", CSW_IHYS, IF_REAL, "Hysterisis current"),
|
||||||
IOPU( "ron", CSW_RON, IF_REAL, "Closed resistance"),
|
IOPU("ron", CSW_RON, IF_REAL, "Closed resistance"),
|
||||||
IOPU( "roff", CSW_ROFF, IF_REAL, "Open resistance"),
|
IOPU("roff", CSW_ROFF, IF_REAL, "Open resistance"),
|
||||||
OPU( "gon", CSW_GON, IF_REAL, "Closed conductance"),
|
OPU("gon", CSW_GON, IF_REAL, "Closed conductance"),
|
||||||
OPU( "goff", CSW_GOFF, IF_REAL, "Open conductance")
|
OPU("goff", CSW_GOFF, IF_REAL, "Open conductance")
|
||||||
};
|
};
|
||||||
|
|
||||||
char *CSWnames[] = {
|
char *CSWnames[] = {
|
||||||
|
|
@ -34,8 +35,8 @@ char *CSWnames[] = {
|
||||||
"W-"
|
"W-"
|
||||||
};
|
};
|
||||||
|
|
||||||
int CSWnSize = NUMELEMS(CSWnames);
|
int CSWnSize = NUMELEMS(CSWnames);
|
||||||
int CSWpTSize = NUMELEMS(CSWpTable);
|
int CSWpTSize = NUMELEMS(CSWpTable);
|
||||||
int CSWmPTSize = NUMELEMS(CSWmPTable);
|
int CSWmPTSize = NUMELEMS(CSWmPTable);
|
||||||
int CSWiSize = sizeof(CSWinstance);
|
int CSWiSize = sizeof(CSWinstance);
|
||||||
int CSWmSize = sizeof(CSWmodel);
|
int CSWmSize = sizeof(CSWmodel);
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -14,33 +12,24 @@ Author: 1985 Gordon Jacobs
|
||||||
|
|
||||||
int
|
int
|
||||||
CSWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
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;
|
CSWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
int current_state;
|
int current_state;
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = CSWnextModel(model))
|
||||||
for( ; model != NULL; model = CSWnextModel(model)) {
|
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||||
for (here = CSWinstances(model); here != NULL ;
|
|
||||||
here=CSWnextInstance(here)) {
|
|
||||||
|
|
||||||
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->CSWposPosPtr) += g_now;
|
||||||
*(here->CSWposNegPtr) -= g_now;
|
*(here->CSWposNegPtr) -= g_now;
|
||||||
*(here->CSWnegPosPtr) -= g_now;
|
*(here->CSWnegPosPtr) -= g_now;
|
||||||
*(here->CSWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Thomas L. Quarles
|
Author: 1987 Thomas L. Quarles
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine gives access to the internal device parameters
|
* This routine gives access to the internal device parameters
|
||||||
|
|
@ -19,53 +17,53 @@ Author: 1987 Thomas L. Quarles
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
CSWask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select)
|
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";
|
static char *msg = "Current and power not available in ac analysis";
|
||||||
|
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(which) {
|
switch (which) {
|
||||||
case CSW_CONTROL:
|
case CSW_CONTROL:
|
||||||
value->uValue = here->CSWcontName;
|
value->uValue = here->CSWcontName;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_POS_NODE:
|
case CSW_POS_NODE:
|
||||||
value->iValue = here->CSWposNode;
|
value->iValue = here->CSWposNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_NEG_NODE:
|
case CSW_NEG_NODE:
|
||||||
value->iValue = here->CSWnegNode;
|
value->iValue = here->CSWnegNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_CURRENT:
|
case CSW_CURRENT:
|
||||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||||
errRtn = "CSWask";
|
errRtn = "CSWask";
|
||||||
strcpy(errMsg,msg);
|
strcpy(errMsg, msg);
|
||||||
return(E_ASKCURRENT);
|
return E_ASKCURRENT;
|
||||||
} else {
|
} else {
|
||||||
value->rValue = (*(ckt->CKTrhsOld+here->CSWposNode)
|
value->rValue =
|
||||||
- *(ckt->CKTrhsOld + here->CSWnegNode)) *
|
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||||
here->CSWcond;
|
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||||
}
|
here->CSWcond;
|
||||||
return(OK);
|
}
|
||||||
case CSW_POWER:
|
return OK;
|
||||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
case CSW_POWER:
|
||||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||||
errRtn = "CSWask";
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||||
strcpy(errMsg,msg);
|
errRtn = "CSWask";
|
||||||
return(E_ASKPOWER);
|
strcpy(errMsg, msg);
|
||||||
} else {
|
return E_ASKPOWER;
|
||||||
value->rValue = (*(ckt->CKTrhsOld+here->CSWposNode)
|
} else {
|
||||||
- *(ckt->CKTrhsOld + here->CSWnegNode)) *
|
value->rValue =
|
||||||
(*(ckt->CKTrhsOld + here->CSWposNode)
|
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||||
- *(ckt->CKTrhsOld + here->CSWnegNode)) *
|
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||||
here->CSWcond;
|
(ckt->CKTrhsOld[here->CSWposNode] -
|
||||||
}
|
ckt->CKTrhsOld[here->CSWnegNode]) *
|
||||||
return(OK);
|
here->CSWcond;
|
||||||
default:
|
}
|
||||||
return (E_BADPARM);
|
return OK;
|
||||||
|
default:
|
||||||
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ Modified: 2000 AlansFixes
|
||||||
#include "ngspice/noisedef.h"
|
#include "ngspice/noisedef.h"
|
||||||
#include "ngspice/complex.h"
|
#include "ngspice/complex.h"
|
||||||
|
|
||||||
/* structures used to describe current controlled switches */
|
/* structures used to describe current controlled switches */
|
||||||
|
|
||||||
|
|
||||||
/* information to describe each instance */
|
/* information to describe each instance */
|
||||||
|
|
@ -27,44 +27,44 @@ typedef struct sCSWinstance {
|
||||||
#define CSWname gen.GENname
|
#define CSWname gen.GENname
|
||||||
#define CSWstate gen.GENstate
|
#define CSWstate gen.GENstate
|
||||||
|
|
||||||
const int CSWposNode; /* number of positive node of switch */
|
const int CSWposNode; /* number of positive node of switch */
|
||||||
const int CSWnegNode; /* number of negative node of switch */
|
const int CSWnegNode; /* number of negative node of switch */
|
||||||
int CSWcontBranch; /* number of branch of controlling current */
|
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
|
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
|
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
|
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
|
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 */
|
unsigned CSWzero_stateGiven : 1; /* flag to indicate initial state */
|
||||||
#ifndef NONOISE
|
#ifndef NONOISE
|
||||||
double CSWnVar[NSTATVARS];
|
double CSWnVar[NSTATVARS];
|
||||||
#else /* NONOISE */
|
#else
|
||||||
double *CSWnVar;
|
double *CSWnVar;
|
||||||
#endif /* NONOISE */
|
|
||||||
|
|
||||||
#ifdef KLU
|
|
||||||
BindElement *CSWposPosBinding ;
|
|
||||||
BindElement *CSWposNegBinding ;
|
|
||||||
BindElement *CSWnegPosBinding ;
|
|
||||||
BindElement *CSWnegNegBinding ;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} CSWinstance ;
|
#ifdef KLU
|
||||||
|
BindElement *CSWposPosBinding;
|
||||||
|
BindElement *CSWposNegBinding;
|
||||||
|
BindElement *CSWnegPosBinding;
|
||||||
|
BindElement *CSWnegNegBinding;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} CSWinstance;
|
||||||
|
|
||||||
/* data per model */
|
/* data per model */
|
||||||
|
|
||||||
#define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
#define CSW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
||||||
#define CSW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */
|
#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 */
|
typedef struct sCSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
#define CSWmodType gen.GENmodType
|
#define CSWmodType gen.GENmodType
|
||||||
#define CSWnextModel(inst) ((struct sCSWmodel *)((inst)->gen.GENnextModel))
|
#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
|
#define CSWmodName gen.GENmodName
|
||||||
|
|
||||||
double CSWonResistance; /* switch "on" resistance */
|
double CSWonResistance; /* switch "on" resistance */
|
||||||
|
|
@ -82,10 +82,10 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
||||||
double CSWonConduct; /* switch "on" conductance */
|
double CSWonConduct; /* switch "on" conductance */
|
||||||
double CSWoffConduct; /* switch "off" conductance */
|
double CSWoffConduct; /* switch "off" conductance */
|
||||||
|
|
||||||
unsigned CSWonGiven : 1; /* flag to indicate on-resistance was specified */
|
unsigned CSWonGiven : 1; /* flag to indicate on-resistance was specified */
|
||||||
unsigned CSWoffGiven : 1;/* flag to indicate off-resistance was " */
|
unsigned CSWoffGiven : 1; /* flag to indicate off-resistance was " */
|
||||||
unsigned CSWthreshGiven : 1;/* flag to indicate threshold volt was given */
|
unsigned CSWthreshGiven : 1; /* flag to indicate threshold volt was given */
|
||||||
unsigned CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
unsigned CSWhystGiven : 1; /* flag to indicate hysteresis volt was given */
|
||||||
} CSWmodel;
|
} CSWmodel;
|
||||||
|
|
||||||
/* device parameters */
|
/* device parameters */
|
||||||
|
|
@ -112,4 +112,4 @@ typedef struct sCSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
#include "cswext.h"
|
#include "cswext.h"
|
||||||
|
|
||||||
#endif /*CSW*/
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,22 @@ Author: 1985 Gordon M. Jacobs
|
||||||
Modified: 2000 AlansFixes
|
Modified: 2000 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
extern int CSWask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
extern int CSWask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||||
extern int CSWacLoad(GENmodel*,CKTcircuit*);
|
extern int CSWacLoad(GENmodel *, CKTcircuit *);
|
||||||
extern int CSWdelete(GENinstance*);
|
extern int CSWdelete(GENinstance *);
|
||||||
extern void CSWdestroy(void);
|
extern void CSWdestroy(void);
|
||||||
extern int CSWload(GENmodel*,CKTcircuit*);
|
extern int CSWload(GENmodel *, CKTcircuit *);
|
||||||
extern int CSWmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
extern int CSWmAsk(CKTcircuit *, GENmodel *, int, IFvalue *);
|
||||||
extern int CSWmDelete(GENmodel*);
|
extern int CSWmDelete(GENmodel *);
|
||||||
extern int CSWmParam(int,IFvalue*,GENmodel*);
|
extern int CSWmParam(int, IFvalue *, GENmodel *);
|
||||||
extern int CSWparam(int,IFvalue*,GENinstance*,IFvalue*);
|
extern int CSWparam(int, IFvalue *, GENinstance *, IFvalue *);
|
||||||
extern int CSWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
extern int CSWpzLoad(GENmodel *, CKTcircuit *, SPcomplex *);
|
||||||
extern int CSWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
extern int CSWsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *);
|
||||||
extern int CSWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int CSWnoise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *);
|
||||||
extern int CSWtrunc(GENmodel*,CKTcircuit*,double*);
|
extern int CSWtrunc(GENmodel *, CKTcircuit *, double *);
|
||||||
|
|
||||||
#ifdef KLU
|
#ifdef KLU
|
||||||
extern int CSWbindCSC (GENmodel*, CKTcircuit*) ;
|
extern int CSWbindCSC(GENmodel *, CKTcircuit *);
|
||||||
extern int CSWbindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int CSWbindCSCComplex(GENmodel *, CKTcircuit *);
|
||||||
extern int CSWbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int CSWbindCSCComplexToReal(GENmodel *, CKTcircuit *);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef _CSWINIT_H
|
#ifndef _CSWINIT_H
|
||||||
#define _CSWINIT_H
|
#define _CSWINIT_H
|
||||||
|
|
||||||
extern IFparm CSWpTable[ ];
|
extern IFparm CSWpTable[];
|
||||||
extern IFparm CSWmPTable[ ];
|
extern IFparm CSWmPTable[];
|
||||||
extern char *CSWnames[ ];
|
extern char *CSWnames[];
|
||||||
extern int CSWpTSize;
|
extern int CSWpTSize;
|
||||||
extern int CSWmPTSize;
|
extern int CSWmPTSize;
|
||||||
extern int CSWnSize;
|
extern int CSWnSize;
|
||||||
|
|
|
||||||
|
|
@ -12,55 +12,47 @@ Modified: 2001 Jon Engelbert
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
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;
|
CSWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
double i_ctrl;
|
double i_ctrl;
|
||||||
double previous_state = -1;
|
double previous_state = -1;
|
||||||
double current_state = -1, old_current_state = -1;
|
double current_state = -1, old_current_state = -1;
|
||||||
double REALLY_OFF = 0, REALLY_ON = 1;
|
double REALLY_OFF = 0, REALLY_ON = 1;
|
||||||
/* switch is on or off, not in hysteresis region. */
|
/* switch is on or off, not in hysteresis region. */
|
||||||
double HYST_OFF = 2, HYST_ON = 3;
|
double HYST_OFF = 2, HYST_ON = 3;
|
||||||
/* switch is on or off while control value is in hysteresis region. */
|
/* 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 != NULL; model = CSWnextModel(model)) {
|
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
old_current_state = ckt->CKTstates[0][here->CSWstate + 0];
|
||||||
for (here = CSWinstances(model); here != NULL ;
|
previous_state = ckt->CKTstates[1][here->CSWstate + 0];
|
||||||
here=CSWnextInstance(here)) {
|
i_ctrl = ckt->CKTrhsOld[here->CSWcontBranch];
|
||||||
|
|
||||||
old_current_state = *(ckt->CKTstates[0] + here->CSWstate);
|
|
||||||
previous_state = *(ckt->CKTstates[1] + here->CSWstate);
|
|
||||||
i_ctrl = *(ckt->CKTrhsOld +
|
|
||||||
here->CSWcontBranch);
|
|
||||||
|
|
||||||
/* decide the state of the switch */
|
/* decide the state of the switch */
|
||||||
|
|
||||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
if (ckt->CKTmode & (MODEINITFIX | MODEINITJCT)) {
|
||||||
|
|
||||||
if(here->CSWzero_stateGiven) {
|
if (here->CSWzero_stateGiven) {
|
||||||
/* switch specified "on" */
|
/* switch specified "on" */
|
||||||
if ((model->CSWiHysteresis >= 0) && (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis)))
|
if (model->CSWiHysteresis >= 0 && i_ctrl > model->CSWiThreshold + model->CSWiHysteresis)
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
else if ((model->CSWiHysteresis < 0) && (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis)))
|
else if (model->CSWiHysteresis < 0 && i_ctrl > model->CSWiThreshold - model->CSWiHysteresis)
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
else
|
else
|
||||||
current_state = HYST_ON;
|
current_state = HYST_ON;
|
||||||
} else {
|
} else {
|
||||||
if ((model->CSWiHysteresis >= 0) && (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis)))
|
if (model->CSWiHysteresis >= 0 && i_ctrl < model->CSWiThreshold - model->CSWiHysteresis)
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else if ((model->CSWiHysteresis < 0) && (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis)))
|
else if (model->CSWiHysteresis < 0 && i_ctrl < model->CSWiThreshold + model->CSWiHysteresis)
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else
|
else
|
||||||
current_state = HYST_OFF;
|
current_state = HYST_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||||
|
|
@ -70,78 +62,78 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
||||||
/* use state0 since INITTRAN or INITPRED already called */
|
/* use state0 since INITTRAN or INITPRED already called */
|
||||||
|
|
||||||
if (model->CSWiHysteresis > 0) {
|
if (model->CSWiHysteresis > 0) {
|
||||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis)) {
|
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
} else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis)) {
|
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
} else {
|
else
|
||||||
current_state = previous_state;
|
current_state = previous_state;
|
||||||
}
|
} else {
|
||||||
} else {
|
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis)) {
|
current_state = REALLY_ON;
|
||||||
current_state = REALLY_ON;
|
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||||
} else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis)) {
|
current_state = REALLY_OFF;
|
||||||
current_state = REALLY_OFF;
|
else {
|
||||||
} else {
|
/* in hysteresis... change value if going from low to hysteresis,
|
||||||
/* in hysteresis... change value if going from low to hysteresis,
|
* or from hi 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(current_state != old_current_state) {
|
/* if previous state was in hysteresis, then don't change the state.. */
|
||||||
ckt->CKTnoncon++; /* ensure one more iteration */
|
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
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) {
|
} else if (ckt->CKTmode & (MODEINITTRAN | MODEINITPRED)) {
|
||||||
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis)) {
|
|
||||||
current_state = REALLY_ON;
|
if (model->CSWiHysteresis > 0) {
|
||||||
} else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis)) {
|
if (i_ctrl > (model->CSWiThreshold + model->CSWiHysteresis))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_ON;
|
||||||
} else {
|
else if (i_ctrl < (model->CSWiThreshold - model->CSWiHysteresis))
|
||||||
current_state = previous_state;
|
current_state = REALLY_OFF;
|
||||||
}
|
else
|
||||||
} else {
|
current_state = previous_state;
|
||||||
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis)) {
|
} else {
|
||||||
current_state = REALLY_ON;
|
if (i_ctrl > (model->CSWiThreshold - model->CSWiHysteresis))
|
||||||
} else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis)) {
|
current_state = REALLY_ON;
|
||||||
current_state = REALLY_OFF;
|
else if (i_ctrl < (model->CSWiThreshold + model->CSWiHysteresis))
|
||||||
} else {
|
current_state = REALLY_OFF;
|
||||||
/* in hysteresis... change value if going from low to hysteresis,
|
else {
|
||||||
* or from hi to hysteresis. */
|
/* 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)) {
|
/* if previous state was in hysteresis, then don't change the state.. */
|
||||||
current_state = previous_state;
|
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||||
} else if (previous_state == REALLY_ON) {
|
current_state = previous_state;
|
||||||
current_state = HYST_OFF;
|
else if (previous_state == REALLY_ON)
|
||||||
} else if (previous_state == REALLY_OFF) {
|
current_state = HYST_OFF;
|
||||||
current_state = HYST_ON;
|
else if (previous_state == REALLY_OFF)
|
||||||
} else
|
current_state = HYST_ON;
|
||||||
internalerror("bad value for previous region in cswload");
|
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->CSWcond = g_now;
|
||||||
|
|
||||||
*(here->CSWposPosPtr) += g_now;
|
*(here->CSWposPosPtr) += g_now;
|
||||||
|
|
@ -149,6 +141,6 @@ CSWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
*(here->CSWnegPosPtr) -= g_now;
|
*(here->CSWnegPosPtr) -= g_now;
|
||||||
*(here->CSWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Thomas L. Quarles
|
Author: 1987 Thomas L. Quarles
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine gives access to the internal model parameters
|
* This routine gives access to the internal model parameters
|
||||||
|
|
@ -19,35 +17,33 @@ Author: 1987 Thomas L. Quarles
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
CSWmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
CSWmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
||||||
{
|
{
|
||||||
CSWmodel *here = (CSWmodel*)inst;
|
CSWmodel *here = (CSWmodel *) inst;
|
||||||
|
|
||||||
NG_IGNORE(ckt);
|
NG_IGNORE(ckt);
|
||||||
|
|
||||||
switch(which) {
|
switch (which) {
|
||||||
case CSW_RON:
|
case CSW_RON:
|
||||||
value->rValue = here->CSWonResistance;
|
value->rValue = here->CSWonResistance;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_ROFF:
|
case CSW_ROFF:
|
||||||
value->rValue = here->CSWoffResistance;
|
value->rValue = here->CSWoffResistance;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_ITH:
|
case CSW_ITH:
|
||||||
value->rValue = here->CSWiThreshold;
|
value->rValue = here->CSWiThreshold;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_IHYS:
|
case CSW_IHYS:
|
||||||
value->rValue = here->CSWiHysteresis;
|
value->rValue = here->CSWiHysteresis;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_GON:
|
case CSW_GON:
|
||||||
value->rValue = here->CSWonConduct;
|
value->rValue = here->CSWonConduct;
|
||||||
return (OK);
|
return OK;
|
||||||
case CSW_GOFF:
|
case CSW_GOFF:
|
||||||
value->rValue = here->CSWoffConduct;
|
value->rValue = here->CSWoffConduct;
|
||||||
return (OK);
|
return OK;
|
||||||
default:
|
default:
|
||||||
return (E_BADPARM);
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
Modified: 2001 Jon Englebert
|
Modified: 2001 Jon Englebert
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/ifsim.h"
|
#include "ngspice/ifsim.h"
|
||||||
|
|
@ -16,33 +14,35 @@ Modified: 2001 Jon Englebert
|
||||||
int
|
int
|
||||||
CSWmParam(int param, IFvalue *value, GENmodel *inModel)
|
CSWmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||||
{
|
{
|
||||||
CSWmodel *model = (CSWmodel*)inModel;
|
CSWmodel *model = (CSWmodel *) inModel;
|
||||||
switch(param) {
|
|
||||||
case CSW_CSW:
|
switch (param) {
|
||||||
/* just says that this is a switch */
|
case CSW_CSW:
|
||||||
break;
|
/* just says that this is a switch */
|
||||||
case CSW_RON:
|
break;
|
||||||
model->CSWonResistance = value->rValue;
|
case CSW_RON:
|
||||||
model->CSWonConduct = 1.0/(value->rValue);
|
model->CSWonResistance = value->rValue;
|
||||||
model->CSWonGiven = TRUE;
|
model->CSWonConduct = 1.0 / value->rValue;
|
||||||
break;
|
model->CSWonGiven = TRUE;
|
||||||
case CSW_ROFF:
|
break;
|
||||||
model->CSWoffResistance = value->rValue;
|
case CSW_ROFF:
|
||||||
model->CSWoffConduct = 1.0/(value->rValue);
|
model->CSWoffResistance = value->rValue;
|
||||||
model->CSWoffGiven = TRUE;
|
model->CSWoffConduct = 1.0 / value->rValue;
|
||||||
break;
|
model->CSWoffGiven = TRUE;
|
||||||
case CSW_ITH:
|
break;
|
||||||
model->CSWiThreshold = value->rValue;
|
case CSW_ITH:
|
||||||
model->CSWthreshGiven = TRUE;
|
model->CSWiThreshold = value->rValue;
|
||||||
break;
|
model->CSWthreshGiven = TRUE;
|
||||||
case CSW_IHYS:
|
break;
|
||||||
/* take absolute value of hysteresis voltage */
|
case CSW_IHYS:
|
||||||
/* model->CSWiHysteresis = fabs(value->rValue); */
|
/* take absolute value of hysteresis voltage */
|
||||||
model->CSWiHysteresis = value->rValue;
|
/* model->CSWiHysteresis = fabs(value->rValue); */
|
||||||
model->CSWhystGiven = TRUE;
|
model->CSWiHysteresis = value->rValue;
|
||||||
break;
|
model->CSWhystGiven = TRUE;
|
||||||
default:
|
break;
|
||||||
return(E_BADPARM);
|
default:
|
||||||
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
return(OK);
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ Author: 1987 Gary W. Ng
|
||||||
|
|
||||||
|
|
||||||
int
|
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;
|
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
|
||||||
|
|
||||||
|
|
@ -35,90 +35,81 @@ CSWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *d
|
||||||
double lnNdens;
|
double lnNdens;
|
||||||
int current_state;
|
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)) {
|
switch (operation) {
|
||||||
for (inst=CSWinstances(model); inst != NULL; inst=CSWnextInstance(inst)) {
|
|
||||||
|
|
||||||
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 (job->NStpsSm != 0)
|
||||||
/* if so, name the noise generator */
|
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) {
|
case N_CALC:
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
||||||
case N_DENS:
|
case N_DENS:
|
||||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->CSWname, "");
|
current_state = (int) ckt->CKTstates[0][inst->CSWstate + 0];
|
||||||
break;
|
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
|
||||||
|
inst->CSWposNode, inst->CSWnegNode,
|
||||||
|
current_state ? model->CSWonConduct : model->CSWoffConduct);
|
||||||
|
|
||||||
case INT_NOIZ:
|
*OnDens += noizDens;
|
||||||
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:
|
if (data->delFreq == 0.0) {
|
||||||
switch (mode) {
|
|
||||||
|
|
||||||
case N_DENS:
|
/* if we haven't done any previous integration, we need to */
|
||||||
current_state = (int)*(ckt->CKTstate0 + inst->CSWstate);
|
/* initialize our "history" variables */
|
||||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
|
||||||
inst->CSWposNode,inst->CSWnegNode,
|
|
||||||
current_state?(model->CSWonConduct):(model->CSWoffConduct));
|
|
||||||
|
|
||||||
*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 */
|
if (data->freq == job->NstartFreq)
|
||||||
/* initialize our "history" variables */
|
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) {
|
return OK;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "cswdefs.h"
|
#include "cswdefs.h"
|
||||||
|
|
@ -12,30 +10,28 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
CSWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
CSWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
||||||
{
|
{
|
||||||
CSWinstance *here = (CSWinstance*)inst;
|
CSWinstance *here = (CSWinstance *) inst;
|
||||||
|
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(param) {
|
switch (param) {
|
||||||
case CSW_CONTROL:
|
case CSW_CONTROL:
|
||||||
here->CSWcontName = value->uValue;
|
here->CSWcontName = value->uValue;
|
||||||
break;
|
break;
|
||||||
case CSW_IC_ON:
|
case CSW_IC_ON:
|
||||||
if(value->iValue) {
|
if (value->iValue)
|
||||||
here->CSWzero_stateGiven = TRUE;
|
here->CSWzero_stateGiven = TRUE;
|
||||||
}
|
break;
|
||||||
break;
|
case CSW_IC_OFF:
|
||||||
case CSW_IC_OFF:
|
if (value->iValue)
|
||||||
if(value->iValue) {
|
here->CSWzero_stateGiven = FALSE;
|
||||||
here->CSWzero_stateGiven = FALSE;
|
break;
|
||||||
}
|
default:
|
||||||
break;
|
return E_BADPARM;
|
||||||
default:
|
|
||||||
return(E_BADPARM);
|
|
||||||
}
|
}
|
||||||
return(OK);
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -13,38 +11,28 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
CSWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
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;
|
CSWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
int current_state;
|
int current_state;
|
||||||
|
|
||||||
NG_IGNORE(s);
|
NG_IGNORE(s);
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = CSWnextModel(model))
|
||||||
for( ; model != NULL; model = CSWnextModel(model)) {
|
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
current_state = (int) ckt->CKTstates[0][here->CSWstate + 0];
|
||||||
for (here = CSWinstances(model); here != NULL ;
|
|
||||||
here=CSWnextInstance(here)) {
|
|
||||||
|
|
||||||
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->CSWposPosPtr) += g_now;
|
||||||
*(here->CSWposNegPtr) -= g_now;
|
*(here->CSWposNegPtr) -= g_now;
|
||||||
*(here->CSWnegPosPtr) -= g_now;
|
*(here->CSWnegPosPtr) -= g_now;
|
||||||
*(here->CSWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -11,67 +9,59 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.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
|
int
|
||||||
CSWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
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;
|
CSWinstance *here;
|
||||||
|
|
||||||
/* loop through all the current source models */
|
for (; model; model = CSWnextModel(model)) {
|
||||||
for( ; model != NULL; model = CSWnextModel(model)) {
|
|
||||||
|
|
||||||
#ifdef USE_CUSPICE
|
#ifdef USE_CUSPICE
|
||||||
/* This model doesn't support CUDA */
|
/* This model doesn't support CUDA */
|
||||||
model->gen.has_cuda = 0 ;
|
model->gen.has_cuda = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default Value Processing for Switch Model */
|
/* Default Value Processing for Switch Model */
|
||||||
if (!model->CSWthreshGiven) {
|
if (!model->CSWthreshGiven)
|
||||||
model->CSWiThreshold = 0;
|
model->CSWiThreshold = 0;
|
||||||
}
|
if (!model->CSWhystGiven)
|
||||||
if (!model->CSWhystGiven) {
|
|
||||||
model->CSWiHysteresis = 0;
|
model->CSWiHysteresis = 0;
|
||||||
}
|
|
||||||
if (!model->CSWonGiven) {
|
if (!model->CSWonGiven) {
|
||||||
model->CSWonConduct = CSW_ON_CONDUCTANCE;
|
model->CSWonConduct = CSW_ON_CONDUCTANCE;
|
||||||
model->CSWonResistance = 1.0/model->CSWonConduct;
|
model->CSWonResistance = 1.0 / model->CSWonConduct;
|
||||||
}
|
}
|
||||||
if (!model->CSWoffGiven) {
|
if (!model->CSWoffGiven) {
|
||||||
model->CSWoffConduct = CSW_OFF_CONDUCTANCE;
|
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 != NULL ;
|
|
||||||
here=CSWnextInstance(here)) {
|
|
||||||
|
|
||||||
/* Default Value Processing for Switch Instance */
|
/* Default Value Processing for Switch Instance */
|
||||||
here->CSWstate = *states;
|
here->CSWstate = *states;
|
||||||
*states += CSW_NUM_STATES;
|
*states += CSW_NUM_STATES;
|
||||||
|
|
||||||
here->CSWcontBranch = CKTfndBranch(ckt,here->CSWcontName);
|
here->CSWcontBranch = CKTfndBranch(ckt, here->CSWcontName);
|
||||||
if(here->CSWcontBranch == 0) {
|
if (here->CSWcontBranch == 0) {
|
||||||
SPfrontEnd->IFerrorf (ERR_FATAL,
|
SPfrontEnd->IFerrorf(ERR_FATAL,
|
||||||
"%s: unknown controlling source %s", here->CSWname, here->CSWcontName);
|
"%s: unknown controlling source %s", here->CSWname, here->CSWcontName);
|
||||||
return(E_BADPARM);
|
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(CSWposPosPtr, CSWposNode, CSWposNode);
|
||||||
TSTALLOC(CSWposNegPtr, CSWposNode, CSWnegNode);
|
TSTALLOC(CSWposNegPtr, CSWposNode, CSWnegNode);
|
||||||
TSTALLOC(CSWnegPosPtr, CSWnegNode, CSWposNode);
|
TSTALLOC(CSWnegPosPtr, CSWnegNode, CSWposNode);
|
||||||
TSTALLOC(CSWnegNegPtr, CSWnegNode, CSWnegNode);
|
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
|
Author: 1985 Thomas L. Quarles
|
||||||
Modified: 2000 AlansFixes
|
Modified: 2000 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -13,37 +11,42 @@ Modified: 2000 AlansFixes
|
||||||
|
|
||||||
#include "cswdefs.h"
|
#include "cswdefs.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||||
{
|
{
|
||||||
CSWmodel *model = (CSWmodel*)inModel;
|
CSWmodel *model = (CSWmodel *) inModel;
|
||||||
CSWinstance *here;
|
CSWinstance *here;
|
||||||
|
|
||||||
double lastChange, maxChange, maxStep, ref;
|
double lastChange, maxChange, maxStep, ref;
|
||||||
|
|
||||||
for( ; model!= NULL; model = CSWnextModel(model)) {
|
for (; model; model = CSWnextModel(model))
|
||||||
for(here = CSWinstances(model); here != NULL ;
|
for (here = CSWinstances(model); here; here = CSWnextInstance(here)) {
|
||||||
here = CSWnextInstance(here)) {
|
lastChange =
|
||||||
lastChange = *(ckt->CKTstate0+(here->CSWstate+1)) -
|
ckt->CKTstates[0][here->CSWstate + 1] -
|
||||||
*(ckt->CKTstate1+(here->CSWstate+1));
|
ckt->CKTstates[1][here->CSWstate + 1];
|
||||||
if (*(ckt->CKTstate0+(here->CSWstate))==0) {
|
if (ckt->CKTstates[0][here->CSWstate + 0] == 0) {
|
||||||
ref = (model->CSWiThreshold + model->CSWiHysteresis);
|
ref = model->CSWiThreshold + model->CSWiHysteresis;
|
||||||
if ((*(ckt->CKTstate0+(here->CSWstate+1))<ref) && (lastChange>0)) {
|
if (ckt->CKTstates[0][here->CSWstate + 1] < ref && lastChange > 0) {
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->CSWstate+1))) *
|
maxChange =
|
||||||
0.75 + 0.00005;
|
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
+ 0.00005;
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||||
}
|
if (*timeStep > maxStep)
|
||||||
|
*timeStep = maxStep;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ref = (model->CSWiThreshold - model->CSWiHysteresis);
|
ref = model->CSWiThreshold - model->CSWiHysteresis;
|
||||||
if ((*(ckt->CKTstate0+(here->CSWstate+1))>ref) && (lastChange<0)) {
|
if (ckt->CKTstates[0][here->CSWstate + 1] > ref && lastChange < 0) {
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->CSWstate+1))) *
|
maxChange =
|
||||||
0.75 - 0.00005;
|
(ref - ckt->CKTstates[0][here->CSWstate + 1]) * 0.75
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
- 0.00005;
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
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 "swdefs.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
IFparm SWpTable[] = { /* parameters */
|
IFparm SWpTable[] = { /* parameters */
|
||||||
IP("on", SW_IC_ON, IF_FLAG,"Switch initially closed"),
|
IP("on", SW_IC_ON, IF_FLAG, "Switch initially closed"),
|
||||||
IP("off", SW_IC_OFF, IF_FLAG,"Switch initially open"),
|
IP("off", SW_IC_OFF, IF_FLAG, "Switch initially open"),
|
||||||
IOPU("pos_node", SW_POS_NODE,IF_INTEGER,"Positive node of switch"),
|
IOPU("pos_node", SW_POS_NODE, IF_INTEGER, "Positive node of switch"),
|
||||||
IOPU("neg_node", SW_NEG_NODE,IF_INTEGER,"Negative 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,
|
OPU("cont_p_node", SW_POS_CONT_NODE, IF_INTEGER, "Positive contr. node of switch"),
|
||||||
"Positive contr. node of switch"),
|
OPU("cont_n_node", SW_NEG_CONT_NODE, IF_INTEGER, "Positive contr. node of switch"),
|
||||||
OPU("cont_n_node",SW_NEG_CONT_NODE,IF_INTEGER,
|
OP("i", SW_CURRENT, IF_REAL, "Switch current"),
|
||||||
"Positive contr. node of switch"),
|
OP("p", SW_POWER, IF_REAL, "Switch power")
|
||||||
OP("i", SW_CURRENT, IF_REAL, "Switch current"),
|
|
||||||
OP("p", SW_POWER, IF_REAL, "Switch power")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IFparm SWmPTable[] = { /* model parameters */
|
IFparm SWmPTable[] = { /* model parameters */
|
||||||
IOPU( "sw", SW_MOD_SW, IF_FLAG,"Switch model"),
|
IOPU("sw", SW_MOD_SW, IF_FLAG, "Switch model"),
|
||||||
IOPU( "vt", SW_MOD_VTH, IF_REAL,"Threshold voltage"),
|
IOPU("vt", SW_MOD_VTH, IF_REAL, "Threshold voltage"),
|
||||||
IOPU( "vh", SW_MOD_VHYS, IF_REAL,"Hysteresis voltage"),
|
IOPU("vh", SW_MOD_VHYS, IF_REAL, "Hysteresis voltage"),
|
||||||
IOPU( "ron", SW_MOD_RON, IF_REAL,"Resistance when closed"),
|
IOPU("ron", SW_MOD_RON, IF_REAL, "Resistance when closed"),
|
||||||
OPU( "gon", SW_MOD_GON, IF_REAL,"Conductance when closed"),
|
OPU("gon", SW_MOD_GON, IF_REAL, "Conductance when closed"),
|
||||||
IOPU( "roff", SW_MOD_ROFF, IF_REAL,"Resistance when open"),
|
IOPU("roff", SW_MOD_ROFF, IF_REAL, "Resistance when open"),
|
||||||
OPU( "goff", SW_MOD_GOFF, IF_REAL,"Conductance when open")
|
OPU("goff", SW_MOD_GOFF, IF_REAL, "Conductance when open")
|
||||||
};
|
};
|
||||||
|
|
||||||
char *SWnames[] = {
|
char *SWnames[] = {
|
||||||
|
|
@ -39,8 +37,8 @@ char *SWnames[] = {
|
||||||
"SC-"
|
"SC-"
|
||||||
};
|
};
|
||||||
|
|
||||||
int SWnSize = NUMELEMS(SWnames);
|
int SWnSize = NUMELEMS(SWnames);
|
||||||
int SWpTSize = NUMELEMS(SWpTable);
|
int SWpTSize = NUMELEMS(SWpTable);
|
||||||
int SWmPTSize = NUMELEMS(SWmPTable);
|
int SWmPTSize = NUMELEMS(SWmPTable);
|
||||||
int SWiSize = sizeof(SWinstance);
|
int SWiSize = sizeof(SWinstance);
|
||||||
int SWmSize = sizeof(SWmodel);
|
int SWmSize = sizeof(SWmodel);
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -14,34 +12,26 @@ Author: 1985 Gordon Jacobs
|
||||||
|
|
||||||
int
|
int
|
||||||
SWacLoad(GENmodel *inModel, CKTcircuit *ckt)
|
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;
|
SWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
int current_state;
|
int current_state;
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = SWnextModel(model))
|
||||||
for( ; model != NULL; 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)) {
|
|
||||||
|
|
||||||
/* In AC analysis, just propogate the state... */
|
/* 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->SWposPosPtr) += g_now;
|
||||||
*(here->SWposNegPtr) -= g_now;
|
*(here->SWposNegPtr) -= g_now;
|
||||||
*(here->SWnegPosPtr) -= g_now;
|
*(here->SWnegPosPtr) -= g_now;
|
||||||
*(here->SWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Thomas L. Quarles
|
Author: 1987 Thomas L. Quarles
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine gives access to the internal device parameters
|
* This routine gives access to the internal device parameters
|
||||||
|
|
@ -19,56 +17,56 @@ Author: 1987 Thomas L. Quarles
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
SWask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *select)
|
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";
|
static char *msg = "Current and power not available in ac analysis";
|
||||||
|
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(which) {
|
switch (which) {
|
||||||
case SW_POS_NODE:
|
case SW_POS_NODE:
|
||||||
value->iValue = here->SWposNode;
|
value->iValue = here->SWposNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_NEG_NODE:
|
case SW_NEG_NODE:
|
||||||
value->iValue = here->SWnegNode;
|
value->iValue = here->SWnegNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_POS_CONT_NODE:
|
case SW_POS_CONT_NODE:
|
||||||
value->iValue = here->SWposCntrlNode;
|
value->iValue = here->SWposCntrlNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_NEG_CONT_NODE:
|
case SW_NEG_CONT_NODE:
|
||||||
value->iValue = here->SWnegCntrlNode;
|
value->iValue = here->SWnegCntrlNode;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_CURRENT:
|
case SW_CURRENT:
|
||||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||||
errRtn = "SWask";
|
errRtn = "SWask";
|
||||||
strcpy(errMsg,msg);
|
strcpy(errMsg, msg);
|
||||||
return(E_ASKCURRENT);
|
return E_ASKCURRENT;
|
||||||
} else {
|
} else {
|
||||||
value->rValue = (*(ckt->CKTrhsOld + here->SWposNode)
|
value->rValue =
|
||||||
- *(ckt->CKTrhsOld + here->SWnegNode)) *
|
(ckt->CKTrhsOld[here->SWposNode] -
|
||||||
here->SWcond;
|
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||||
}
|
here->SWcond;
|
||||||
return(OK);
|
}
|
||||||
case SW_POWER:
|
return OK;
|
||||||
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
case SW_POWER:
|
||||||
errMsg = TMALLOC(char, strlen(msg) + 1);
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
||||||
errRtn = "SWask";
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
||||||
strcpy(errMsg,msg);
|
errRtn = "SWask";
|
||||||
return(E_ASKPOWER);
|
strcpy(errMsg, msg);
|
||||||
} else {
|
return E_ASKPOWER;
|
||||||
value->rValue = (*(ckt->CKTrhsOld + here->SWposNode)
|
} else {
|
||||||
- *(ckt->CKTrhsOld + here->SWnegNode)) *
|
value->rValue =
|
||||||
(*(ckt->CKTrhsOld + here->SWposNode)
|
(ckt->CKTrhsOld[here->SWposNode] -
|
||||||
- *(ckt->CKTrhsOld + here->SWnegNode)) *
|
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||||
here->SWcond;
|
(ckt->CKTrhsOld[here->SWposNode] -
|
||||||
}
|
ckt->CKTrhsOld[here->SWnegNode]) *
|
||||||
return(OK);
|
here->SWcond;
|
||||||
default:
|
}
|
||||||
return (E_BADPARM);
|
return OK;
|
||||||
|
default:
|
||||||
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ Modified: 2000 AlansFixes
|
||||||
#include "ngspice/complex.h"
|
#include "ngspice/complex.h"
|
||||||
#include "ngspice/noisedef.h"
|
#include "ngspice/noisedef.h"
|
||||||
|
|
||||||
/* structures used to describe voltage controlled switches */
|
/* structures used to describe voltage controlled switches */
|
||||||
|
|
||||||
|
|
||||||
/* information to describe each instance */
|
/* information to describe each instance */
|
||||||
|
|
@ -27,43 +27,43 @@ typedef struct sSWinstance {
|
||||||
#define SWname gen.GENname
|
#define SWname gen.GENname
|
||||||
#define SWstate gen.GENstate
|
#define SWstate gen.GENstate
|
||||||
|
|
||||||
const int SWposNode; /* number of positive node of switch */
|
const int SWposNode; /* number of positive node of switch */
|
||||||
const int SWnegNode; /* number of negative node of switch */
|
const int SWnegNode; /* number of negative node of switch */
|
||||||
const int SWposCntrlNode; /* number of positive controlling node of switch */
|
const int SWposCntrlNode; /* number of positive controlling node of switch */
|
||||||
const int SWnegCntrlNode; /* number of negative controlling node of switch */
|
const int SWnegCntrlNode; /* number of negative controlling node of switch */
|
||||||
|
|
||||||
double *SWposPosPtr; /* pointer to sparse matrix diagonal at
|
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
|
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
|
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
|
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 */
|
unsigned SWzero_stateGiven : 1; /* flag to indicate initial state */
|
||||||
#ifndef NONOISE
|
#ifndef NONOISE
|
||||||
double SWnVar[NSTATVARS];
|
double SWnVar[NSTATVARS];
|
||||||
#else /* NONOISE */
|
#else
|
||||||
double *SWnVar;
|
double *SWnVar;
|
||||||
#endif /* NONOISE */
|
|
||||||
|
|
||||||
#ifdef KLU
|
|
||||||
BindElement *SWposPosBinding ;
|
|
||||||
BindElement *SWposNegBinding ;
|
|
||||||
BindElement *SWnegPosBinding ;
|
|
||||||
BindElement *SWnegNegBinding ;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} SWinstance ;
|
#ifdef KLU
|
||||||
|
BindElement *SWposPosBinding;
|
||||||
|
BindElement *SWposNegBinding;
|
||||||
|
BindElement *SWnegPosBinding;
|
||||||
|
BindElement *SWnegNegBinding;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} SWinstance;
|
||||||
|
|
||||||
/* data per model */
|
/* data per model */
|
||||||
|
|
||||||
#define SW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
#define SW_ON_CONDUCTANCE 1.0 /* default on conductance = 1 mho */
|
||||||
#define SW_OFF_CONDUCTANCE ckt->CKTgmin /* default off conductance */
|
#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 */
|
typedef struct sSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ typedef struct sSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
#define SWmodType gen.GENmodType
|
#define SWmodType gen.GENmodType
|
||||||
#define SWnextModel(inst) ((struct sSWmodel *)((inst)->gen.GENnextModel))
|
#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
|
#define SWmodName gen.GENmodName
|
||||||
|
|
||||||
double SWonResistance; /* switch "on" resistance */
|
double SWonResistance; /* switch "on" resistance */
|
||||||
|
|
@ -81,10 +81,10 @@ typedef struct sSWmodel { /* model structure for a switch */
|
||||||
double SWonConduct; /* switch "on" conductance */
|
double SWonConduct; /* switch "on" conductance */
|
||||||
double SWoffConduct; /* switch "off" conductance */
|
double SWoffConduct; /* switch "off" conductance */
|
||||||
|
|
||||||
unsigned SWonGiven : 1; /* flag to indicate on-resistance was specified */
|
unsigned SWonGiven : 1; /* flag to indicate on-resistance was specified */
|
||||||
unsigned SWoffGiven : 1; /* flag to indicate off-resistance was " */
|
unsigned SWoffGiven : 1; /* flag to indicate off-resistance was " */
|
||||||
unsigned SWthreshGiven : 1; /* flag to indicate threshold volt was given */
|
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;
|
} SWmodel;
|
||||||
|
|
||||||
/* device parameters */
|
/* device parameters */
|
||||||
|
|
@ -112,4 +112,4 @@ typedef struct sSWmodel { /* model structure for a switch */
|
||||||
|
|
||||||
#include "swext.h"
|
#include "swext.h"
|
||||||
|
|
||||||
#endif /*SW*/
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,22 @@ Author: 1985 Gordon M. Jacobs
|
||||||
Modified: 2000 AlansFixes
|
Modified: 2000 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
|
|
||||||
extern int SWacLoad(GENmodel*,CKTcircuit*);
|
extern int SWacLoad(GENmodel *, CKTcircuit *);
|
||||||
extern int SWask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
extern int SWask(CKTcircuit *, GENinstance *, int, IFvalue *, IFvalue *);
|
||||||
extern int SWdelete(GENinstance*);
|
extern int SWdelete(GENinstance *);
|
||||||
extern void SWdestroy(void);
|
extern void SWdestroy(void);
|
||||||
extern int SWload(GENmodel*,CKTcircuit*);
|
extern int SWload(GENmodel *, CKTcircuit *);
|
||||||
extern int SWmAsk(CKTcircuit*,GENmodel*,int,IFvalue*);
|
extern int SWmAsk(CKTcircuit *, GENmodel *, int, IFvalue *);
|
||||||
extern int SWmDelete(GENmodel*);
|
extern int SWmDelete(GENmodel *);
|
||||||
extern int SWmParam(int,IFvalue*,GENmodel*);
|
extern int SWmParam(int, IFvalue *, GENmodel *);
|
||||||
extern int SWparam(int,IFvalue*,GENinstance*,IFvalue*);
|
extern int SWparam(int, IFvalue *, GENinstance *, IFvalue *);
|
||||||
extern int SWpzLoad(GENmodel*,CKTcircuit*,SPcomplex*);
|
extern int SWpzLoad(GENmodel *, CKTcircuit *, SPcomplex *);
|
||||||
extern int SWsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
extern int SWsetup(SMPmatrix *, GENmodel *, CKTcircuit *, int *);
|
||||||
extern int SWnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
extern int SWnoise(int, int, GENmodel *, CKTcircuit *, Ndata *, double *);
|
||||||
extern int SWtrunc(GENmodel*,CKTcircuit*,double*);
|
extern int SWtrunc(GENmodel *, CKTcircuit *, double *);
|
||||||
|
|
||||||
#ifdef KLU
|
#ifdef KLU
|
||||||
extern int SWbindCSC (GENmodel*, CKTcircuit*) ;
|
extern int SWbindCSC(GENmodel *, CKTcircuit *);
|
||||||
extern int SWbindCSCComplex (GENmodel*, CKTcircuit*) ;
|
extern int SWbindCSCComplex(GENmodel *, CKTcircuit *);
|
||||||
extern int SWbindCSCComplexToReal (GENmodel*, CKTcircuit*) ;
|
extern int SWbindCSCComplexToReal(GENmodel *, CKTcircuit *);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#ifndef _SWINIT_H
|
#ifndef _SWINIT_H
|
||||||
#define _SWINIT_H
|
#define _SWINIT_H
|
||||||
|
|
||||||
extern IFparm SWpTable[ ];
|
extern IFparm SWpTable[];
|
||||||
extern IFparm SWmPTable[ ];
|
extern IFparm SWmPTable[];
|
||||||
extern char *SWnames[ ];
|
extern char *SWnames[];
|
||||||
extern int SWpTSize;
|
extern int SWpTSize;
|
||||||
extern int SWmPTSize;
|
extern int SWmPTSize;
|
||||||
extern int SWnSize;
|
extern int SWnSize;
|
||||||
|
|
|
||||||
|
|
@ -12,56 +12,51 @@ Modified: 2001 Jon Engelbert
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
/* actually load the current values into the
|
|
||||||
* sparse matrix previously provided
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel *) inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
SWinstance *here;
|
SWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
double v_ctrl;
|
double v_ctrl;
|
||||||
double previous_state = -1;
|
double previous_state = -1;
|
||||||
double current_state = -1;
|
double current_state = -1;
|
||||||
double old_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 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 HYST_OFF = 2, HYST_ON = 3; // switch is on or off while control value is in hysteresis region.
|
||||||
// double previous_region = -1;
|
// double previous_region = -1;
|
||||||
// double current_region = -1;
|
// double current_region = -1;
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = SWnextModel(model))
|
||||||
for( ; model != NULL; model = SWnextModel(model)) {
|
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||||
|
|
||||||
/* loop through all the instances of the model */
|
old_current_state = ckt->CKTstates[0][here->SWstate + 0];
|
||||||
for (here = SWinstances(model); here != NULL ;
|
previous_state = ckt->CKTstates[1][here->SWstate + 0];
|
||||||
here=SWnextInstance(here)) {
|
|
||||||
|
|
||||||
old_current_state = *(ckt->CKTstates[0] + here->SWstate);
|
|
||||||
previous_state = *(ckt->CKTstates[1] + here->SWstate);
|
|
||||||
|
|
||||||
v_ctrl = *(ckt->CKTrhsOld + here->SWposCntrlNode)
|
v_ctrl =
|
||||||
- *(ckt->CKTrhsOld + here->SWnegCntrlNode);
|
ckt->CKTrhsOld[here->SWposCntrlNode] -
|
||||||
|
ckt->CKTrhsOld[here->SWnegCntrlNode];
|
||||||
/* decide the state of the switch */
|
|
||||||
|
|
||||||
if(ckt->CKTmode & (MODEINITFIX|MODEINITJCT)) {
|
|
||||||
|
|
||||||
if(here->SWzero_stateGiven) {
|
/* decide the state of the switch */
|
||||||
/* switch specified "on" */
|
|
||||||
if ((model->SWvHysteresis >= 0) && (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)))
|
if (ckt->CKTmode & (MODEINITFIX | MODEINITJCT)) {
|
||||||
current_state = REALLY_ON;
|
|
||||||
else if ((model->SWvHysteresis < 0) && (v_ctrl > (model->SWvThreshold - model->SWvHysteresis)))
|
if (here->SWzero_stateGiven) {
|
||||||
current_state = REALLY_ON;
|
/* switch specified "on" */
|
||||||
else
|
if (model->SWvHysteresis >= 0 && v_ctrl > model->SWvThreshold + model->SWvHysteresis)
|
||||||
current_state = HYST_ON;
|
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 {
|
} else {
|
||||||
if ((model->SWvHysteresis >= 0) && (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)))
|
if (model->SWvHysteresis >= 0 && v_ctrl < model->SWvThreshold - model->SWvHysteresis)
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else if ((model->SWvHysteresis < 0) && (v_ctrl < (model->SWvThreshold + model->SWvHysteresis)))
|
else if (model->SWvHysteresis < 0 && v_ctrl < model->SWvThreshold + model->SWvHysteresis)
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else
|
else
|
||||||
current_state = HYST_OFF;
|
current_state = HYST_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
} else if (ckt->CKTmode & (MODEINITSMSIG)) {
|
||||||
|
|
@ -71,79 +66,77 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
} else if (ckt->CKTmode & (MODEINITFLOAT)) {
|
||||||
|
|
||||||
/* use state0 since INITTRAN or INITPRED already called */
|
/* use state0 since INITTRAN or INITPRED already called */
|
||||||
if (model->SWvHysteresis > 0) {
|
if (model->SWvHysteresis > 0) {
|
||||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis)) {
|
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
} else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis)) {
|
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
} else {
|
else
|
||||||
current_state = old_current_state;
|
current_state = old_current_state;
|
||||||
}
|
} else { // negative hysteresis case.
|
||||||
} else { // negative hysteresis case.
|
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
current_state = REALLY_ON;
|
||||||
{
|
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_OFF;
|
||||||
} else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
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..
|
||||||
current_state = REALLY_OFF;
|
if (previous_state == HYST_OFF || previous_state == HYST_ON)
|
||||||
} else { // in hysteresis... change value if going from low to hysteresis, or from hi to hysteresis.
|
current_state = previous_state;
|
||||||
// if previous state was in hysteresis, then don't change the state..
|
else if (previous_state == REALLY_ON)
|
||||||
if ((previous_state == HYST_OFF) || (previous_state == HYST_ON)) {
|
current_state = HYST_OFF;
|
||||||
current_state = previous_state;
|
else if (previous_state == REALLY_OFF)
|
||||||
} else if (previous_state == REALLY_ON) {
|
current_state = HYST_ON;
|
||||||
current_state = HYST_OFF;
|
else
|
||||||
} else if (previous_state == REALLY_OFF) {
|
internalerror("bad value for previous state in swload");
|
||||||
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 (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 (model->SWvHysteresis > 0) {
|
||||||
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
if (v_ctrl > (model->SWvThreshold + model->SWvHysteresis))
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
else if (v_ctrl < (model->SWvThreshold - model->SWvHysteresis))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else
|
else
|
||||||
current_state = previous_state;
|
current_state = previous_state;
|
||||||
} else { // negative hysteresis case.
|
} else { // negative hysteresis case.
|
||||||
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
if (v_ctrl > (model->SWvThreshold - model->SWvHysteresis))
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
else if (v_ctrl < (model->SWvThreshold + model->SWvHysteresis))
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
else {
|
else {
|
||||||
current_state = 0.0;
|
current_state = 0.0;
|
||||||
if ((previous_state == HYST_ON) || (previous_state == HYST_OFF)) {
|
if (previous_state == HYST_ON || previous_state == HYST_OFF)
|
||||||
current_state = previous_state;
|
current_state = previous_state;
|
||||||
} else if (previous_state == REALLY_ON) {
|
else if (previous_state == REALLY_ON)
|
||||||
current_state = REALLY_OFF;
|
current_state = REALLY_OFF;
|
||||||
} else if (previous_state == REALLY_OFF) {
|
else if (previous_state == REALLY_OFF)
|
||||||
current_state = REALLY_ON;
|
current_state = REALLY_ON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// code added to force the state to be updated.
|
// code added to force the state to be updated.
|
||||||
// there is a possible problem. What if, during the transient analysis, the time is stepped
|
// 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
|
// 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.
|
// 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
|
// After analyzing the transient code, it seems that this is not a problem because state updating
|
||||||
// occurs before the convergence loop in transient processing.
|
// occurs before the convergence loop in transient processing.
|
||||||
*(ckt->CKTstates[0] + here->SWstate) = current_state;
|
|
||||||
*(ckt->CKTstates[0] + here->SWstate + 1) = v_ctrl;
|
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->SWcond = g_now;
|
||||||
|
|
||||||
*(here->SWposPosPtr) += g_now;
|
*(here->SWposPosPtr) += g_now;
|
||||||
|
|
@ -151,6 +144,6 @@ SWload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
*(here->SWnegPosPtr) -= g_now;
|
*(here->SWnegPosPtr) -= g_now;
|
||||||
*(here->SWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1987 Thomas L. Quarles
|
Author: 1987 Thomas L. Quarles
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine gives access to the internal model parameter
|
* This routine gives access to the internal model parameter
|
||||||
|
|
@ -19,35 +17,33 @@ Author: 1987 Thomas L. Quarles
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
SWmAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
SWmAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel *)inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
|
|
||||||
NG_IGNORE(ckt);
|
NG_IGNORE(ckt);
|
||||||
|
|
||||||
switch(which) {
|
switch (which) {
|
||||||
case SW_MOD_RON:
|
case SW_MOD_RON:
|
||||||
value->rValue = model->SWonResistance;
|
value->rValue = model->SWonResistance;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_MOD_ROFF:
|
case SW_MOD_ROFF:
|
||||||
value->rValue = model->SWoffResistance;
|
value->rValue = model->SWoffResistance;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_MOD_VTH:
|
case SW_MOD_VTH:
|
||||||
value->rValue = model->SWvThreshold;
|
value->rValue = model->SWvThreshold;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_MOD_VHYS:
|
case SW_MOD_VHYS:
|
||||||
value->rValue = model->SWvHysteresis;
|
value->rValue = model->SWvHysteresis;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_MOD_GON:
|
case SW_MOD_GON:
|
||||||
value->rValue = model->SWonConduct;
|
value->rValue = model->SWonConduct;
|
||||||
return (OK);
|
return OK;
|
||||||
case SW_MOD_GOFF:
|
case SW_MOD_GOFF:
|
||||||
value->rValue = model->SWoffConduct;
|
value->rValue = model->SWoffConduct;
|
||||||
return (OK);
|
return OK;
|
||||||
default:
|
default:
|
||||||
return (E_BADPARM);
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
Modified: 2001 Jon Engelbert
|
Modified: 2001 Jon Engelbert
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "swdefs.h"
|
#include "swdefs.h"
|
||||||
|
|
@ -16,36 +14,37 @@ Modified: 2001 Jon Engelbert
|
||||||
int
|
int
|
||||||
SWmParam(int param, IFvalue *value, GENmodel *inModel)
|
SWmParam(int param, IFvalue *value, GENmodel *inModel)
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel *)inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
switch(param) {
|
|
||||||
case SW_MOD_SW:
|
switch (param) {
|
||||||
/* just says that this is a switch */
|
case SW_MOD_SW:
|
||||||
break;
|
/* just says that this is a switch */
|
||||||
case SW_MOD_RON:
|
break;
|
||||||
model->SWonResistance = value->rValue;
|
case SW_MOD_RON:
|
||||||
model->SWonConduct = 1.0/(value->rValue);
|
model->SWonResistance = value->rValue;
|
||||||
model->SWonGiven = TRUE;
|
model->SWonConduct = 1.0 / value->rValue;
|
||||||
break;
|
model->SWonGiven = TRUE;
|
||||||
case SW_MOD_ROFF:
|
break;
|
||||||
model->SWoffResistance = value->rValue;
|
case SW_MOD_ROFF:
|
||||||
model->SWoffConduct = 1.0/(value->rValue);
|
model->SWoffResistance = value->rValue;
|
||||||
model->SWoffGiven = TRUE;
|
model->SWoffConduct = 1.0 / value->rValue;
|
||||||
break;
|
model->SWoffGiven = TRUE;
|
||||||
case SW_MOD_VTH:
|
break;
|
||||||
/* take absolute value of hysteresis voltage */
|
case SW_MOD_VTH:
|
||||||
model->SWvThreshold = value->rValue;
|
/* take absolute value of hysteresis voltage */
|
||||||
model->SWthreshGiven = TRUE;
|
model->SWvThreshold = value->rValue;
|
||||||
break;
|
model->SWthreshGiven = TRUE;
|
||||||
case SW_MOD_VHYS:
|
break;
|
||||||
/* take absolute value of hysteresis voltage */
|
case SW_MOD_VHYS:
|
||||||
// model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) :
|
/* take absolute value of hysteresis voltage */
|
||||||
// value->rValue;
|
// model->SWvHysteresis = (value->rValue < 0) ? -(value->rValue) :
|
||||||
model->SWvHysteresis = value->rValue;
|
// value->rValue;
|
||||||
model->SWhystGiven = TRUE;
|
model->SWvHysteresis = value->rValue;
|
||||||
break;
|
model->SWhystGiven = TRUE;
|
||||||
default:
|
break;
|
||||||
return(E_BADPARM);
|
default:
|
||||||
|
return E_BADPARM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(OK);
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ Author: 1987 Gary W. Ng
|
||||||
|
|
||||||
|
|
||||||
int
|
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;
|
NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
|
||||||
|
|
||||||
|
|
@ -35,88 +35,81 @@ SWnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *da
|
||||||
double lnNdens;
|
double lnNdens;
|
||||||
int current_state;
|
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)) {
|
switch (operation) {
|
||||||
for (inst=SWinstances(model); inst != NULL; inst=SWnextInstance(inst)) {
|
|
||||||
|
|
||||||
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 (job->NStpsSm != 0)
|
||||||
/* if so, name the noise generator */
|
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) {
|
case N_CALC:
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
|
||||||
case N_DENS:
|
case N_DENS:
|
||||||
NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->SWname, "");
|
current_state = (int) ckt->CKTstates[0][inst->SWstate + 0];
|
||||||
break;
|
NevalSrc(&noizDens, &lnNdens, ckt, THERMNOISE,
|
||||||
|
inst->SWposNode, inst->SWnegNode,
|
||||||
|
current_state ? model->SWonConduct : model->SWoffConduct);
|
||||||
|
|
||||||
case INT_NOIZ:
|
*OnDens += noizDens;
|
||||||
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:
|
if (data->delFreq == 0.0) {
|
||||||
switch (mode) {
|
|
||||||
|
|
||||||
case N_DENS:
|
/* if we haven't done any previous integration, we need to */
|
||||||
current_state = (int)*(ckt->CKTstate0 + inst->SWstate);
|
/* initialize our "history" variables */
|
||||||
NevalSrc(&noizDens,&lnNdens,ckt,THERMNOISE,
|
|
||||||
inst->SWposNode,inst->SWnegNode,
|
|
||||||
current_state?(model->SWonConduct):(model->SWoffConduct));
|
|
||||||
|
|
||||||
*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 */
|
if (data->freq == job->NstartFreq)
|
||||||
/* initialize our "history" variables */
|
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) {
|
return OK;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "swdefs.h"
|
#include "swdefs.h"
|
||||||
|
|
@ -12,28 +10,25 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/*ARGSUSED*/
|
|
||||||
int
|
int
|
||||||
SWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
SWparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
||||||
{
|
{
|
||||||
SWinstance *here = (SWinstance *)inst;
|
SWinstance *here = (SWinstance *) inst;
|
||||||
|
|
||||||
NG_IGNORE(select);
|
NG_IGNORE(select);
|
||||||
|
|
||||||
switch(param) {
|
switch (param) {
|
||||||
case SW_IC_ON:
|
case SW_IC_ON:
|
||||||
if(value->iValue) {
|
if (value->iValue)
|
||||||
here->SWzero_stateGiven = TRUE;
|
here->SWzero_stateGiven = TRUE;
|
||||||
}
|
break;
|
||||||
break;
|
case SW_IC_OFF:
|
||||||
case SW_IC_OFF:
|
if (value->iValue)
|
||||||
if(value->iValue) {
|
here->SWzero_stateGiven = FALSE;
|
||||||
here->SWzero_stateGiven = FALSE;
|
break;
|
||||||
}
|
default:
|
||||||
break;
|
return E_BADPARM;
|
||||||
default:
|
|
||||||
return(E_BADPARM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(OK);
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -13,39 +11,30 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
int
|
int
|
||||||
SWpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
|
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;
|
SWinstance *here;
|
||||||
double g_now;
|
double g_now;
|
||||||
int current_state;
|
int current_state;
|
||||||
|
|
||||||
NG_IGNORE(s);
|
NG_IGNORE(s);
|
||||||
|
|
||||||
/* loop through all the switch models */
|
for (; model; model = SWnextModel(model))
|
||||||
for( ; model != NULL; 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)) {
|
|
||||||
|
|
||||||
/* In AC analysis, just propogate the state... */
|
/* 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->SWposPosPtr) += g_now;
|
||||||
*(here->SWposNegPtr) -= g_now;
|
*(here->SWposNegPtr) -= g_now;
|
||||||
*(here->SWnegPosPtr) -= g_now;
|
*(here->SWnegPosPtr) -= g_now;
|
||||||
*(here->SWnegNegPtr) += 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.
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||||
Author: 1985 Gordon Jacobs
|
Author: 1985 Gordon Jacobs
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/smpdefs.h"
|
#include "ngspice/smpdefs.h"
|
||||||
|
|
@ -12,55 +10,47 @@ Author: 1985 Gordon Jacobs
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.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
|
int
|
||||||
SWsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
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;
|
SWinstance *here;
|
||||||
|
|
||||||
/* loop through all the current source models */
|
for (; model; model = SWnextModel(model)) {
|
||||||
for( ; model != NULL; model = SWnextModel(model)) {
|
|
||||||
|
|
||||||
#ifdef USE_CUSPICE
|
#ifdef USE_CUSPICE
|
||||||
/* This model doesn't support CUDA */
|
/* This model doesn't support CUDA */
|
||||||
model->gen.has_cuda = 0 ;
|
model->gen.has_cuda = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Default Value Processing for Switch Model */
|
/* Default Value Processing for Switch Model */
|
||||||
if (!model->SWthreshGiven) {
|
if (!model->SWthreshGiven)
|
||||||
model->SWvThreshold = 0;
|
model->SWvThreshold = 0;
|
||||||
}
|
if (!model->SWhystGiven)
|
||||||
if (!model->SWhystGiven) {
|
|
||||||
model->SWvHysteresis = 0;
|
model->SWvHysteresis = 0;
|
||||||
}
|
|
||||||
if (!model->SWonGiven) {
|
if (!model->SWonGiven) {
|
||||||
model->SWonConduct = SW_ON_CONDUCTANCE;
|
model->SWonConduct = SW_ON_CONDUCTANCE;
|
||||||
model->SWonResistance = 1.0/model->SWonConduct;
|
model->SWonResistance = 1.0 / model->SWonConduct;
|
||||||
}
|
}
|
||||||
if (!model->SWoffGiven) {
|
if (!model->SWoffGiven) {
|
||||||
model->SWoffConduct = SW_OFF_CONDUCTANCE;
|
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 != NULL ;
|
|
||||||
here=SWnextInstance(here)) {
|
|
||||||
|
|
||||||
here->SWstate = *states;
|
here->SWstate = *states;
|
||||||
*states += SW_NUM_STATES;
|
*states += SW_NUM_STATES;
|
||||||
|
|
||||||
/* Default Value Processing for Switch Instance */
|
/* Default Value Processing for Switch Instance */
|
||||||
/* none */
|
/* 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)
|
|
||||||
|
|
||||||
TSTALLOC(SWposPosPtr, SWposNode, SWposNode);
|
TSTALLOC(SWposPosPtr, SWposNode, SWposNode);
|
||||||
TSTALLOC(SWposNegPtr, SWposNode, SWnegNode);
|
TSTALLOC(SWposNegPtr, SWposNode, SWnegNode);
|
||||||
|
|
@ -68,5 +58,6 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
||||||
TSTALLOC(SWnegNegPtr, SWnegNode, SWnegNode);
|
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
|
Author: 1985 Thomas L. Quarles
|
||||||
Modified: 2000 AlansFixes
|
Modified: 2000 AlansFixes
|
||||||
**********/
|
**********/
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ngspice/ngspice.h"
|
#include "ngspice/ngspice.h"
|
||||||
#include "ngspice/cktdefs.h"
|
#include "ngspice/cktdefs.h"
|
||||||
|
|
@ -12,36 +10,41 @@ Modified: 2000 AlansFixes
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
#include "swdefs.h"
|
#include "swdefs.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
|
||||||
{
|
{
|
||||||
SWmodel *model = (SWmodel*)inModel;
|
SWmodel *model = (SWmodel *) inModel;
|
||||||
SWinstance *here;
|
SWinstance *here;
|
||||||
double lastChange, maxChange, maxStep, ref;
|
double lastChange, maxChange, maxStep, ref;
|
||||||
|
|
||||||
for( ; model!= NULL; model = SWnextModel(model)) {
|
for (; model; model = SWnextModel(model))
|
||||||
for(here = SWinstances(model); here != NULL ;
|
for (here = SWinstances(model); here; here = SWnextInstance(here)) {
|
||||||
here = SWnextInstance(here)) {
|
lastChange =
|
||||||
lastChange = *(ckt->CKTstate0+(here->SWstate+1)) -
|
ckt->CKTstates[0][here->SWstate + 1] -
|
||||||
*(ckt->CKTstate1+(here->SWstate+1));
|
ckt->CKTstates[1][here->SWstate + 1];
|
||||||
if (*(ckt->CKTstate0+(here->SWstate))==0) {
|
if (ckt->CKTstates[0][here->SWstate + 0] == 0) {
|
||||||
ref = (model->SWvThreshold + model->SWvHysteresis);
|
ref = model->SWvThreshold + model->SWvHysteresis;
|
||||||
if ((*(ckt->CKTstate0+(here->SWstate+1))<ref) && (lastChange>0)) {
|
if (ckt->CKTstates[0][here->SWstate + 1] < ref && lastChange > 0) {
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) *
|
maxChange =
|
||||||
0.75 + 0.05;
|
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
+ 0.05;
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||||
}
|
if (*timeStep > maxStep)
|
||||||
|
*timeStep = maxStep;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ref = (model->SWvThreshold - model->SWvHysteresis);
|
ref = model->SWvThreshold - model->SWvHysteresis;
|
||||||
if ((*(ckt->CKTstate0+(here->SWstate+1))>ref) && (lastChange<0)) {
|
if (ckt->CKTstates[0][here->SWstate + 1] > ref && lastChange < 0) {
|
||||||
maxChange = (ref - *(ckt->CKTstate0+(here->SWstate+1))) *
|
maxChange =
|
||||||
0.75 - 0.05;
|
(ref - ckt->CKTstates[0][here->SWstate + 1]) * 0.75
|
||||||
maxStep = maxChange/lastChange * ckt->CKTdeltaOld[0];
|
- 0.05;
|
||||||
if (*timeStep > maxStep) { *timeStep = maxStep; }
|
maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0];
|
||||||
}
|
if (*timeStep > maxStep)
|
||||||
|
*timeStep = maxStep;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return(OK);
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue