a first attempt to access branch current of rlc devices
This commit is contained in:
parent
000b23cc52
commit
9c8766f65b
|
|
@ -83,7 +83,7 @@ int fixme_inoise_type = SV_NOTYPE;
|
|||
|
||||
static clock_t lastclock, currclock;
|
||||
static double *rowbuf;
|
||||
static size_t column, rowbuflen;
|
||||
static size_t column, rowbuflen, doornroosje = 0;
|
||||
|
||||
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */
|
||||
|
||||
|
|
@ -175,6 +175,7 @@ beginPlot(JOB *analysisPtr, CKTcircuit *circuitPtr, char *cktName, char *analNam
|
|||
run->type = copy(analName);
|
||||
run->windowed = windowed;
|
||||
run->numData = 0;
|
||||
run->spindex = -1; // mhx
|
||||
|
||||
an_name = spice_analysis_get_name(analysisPtr->JOBtype);
|
||||
ft_curckt->ci_last_an = an_name;
|
||||
|
|
@ -508,13 +509,14 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
every quarter of a second, to give some feedback without using
|
||||
too much CPU time */
|
||||
#ifndef HAS_WINGUI
|
||||
if (!orflag) {
|
||||
if (!orflag && (doornroosje == 0)) {
|
||||
currclock = clock();
|
||||
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
|
||||
fprintf(stderr, " Reference value : % 12.5e\r",
|
||||
refValue->cValue.real);
|
||||
lastclock = currclock;
|
||||
}
|
||||
else doornroosje--;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
|
|
@ -523,7 +525,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
|
||||
fileAddRealValue(run->fp, run->binary, refValue->rValue);
|
||||
#ifndef HAS_WINGUI
|
||||
if (!orflag) {
|
||||
if (!orflag && (doornroosje == 0)) {
|
||||
currclock = clock();
|
||||
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
|
||||
fprintf(stderr, " Reference value : % 12.5e\r",
|
||||
|
|
@ -531,6 +533,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
lastclock = currclock;
|
||||
}
|
||||
}
|
||||
else doornroosje--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -606,7 +609,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
variable just the same */
|
||||
|
||||
#ifndef HAS_WINGUI
|
||||
if (!orflag) {
|
||||
if (!orflag && (doornroosje == 0)) {
|
||||
currclock = clock();
|
||||
if ((currclock-lastclock) > (0.25*CLOCKS_PER_SEC)) {
|
||||
if (run->isComplex) {
|
||||
|
|
@ -619,6 +622,7 @@ OUTpData(runDesc *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
|
|||
lastclock = currclock;
|
||||
}
|
||||
}
|
||||
else doornroosje--;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < run->numData; i++) {
|
||||
|
|
@ -942,7 +946,7 @@ fileStartPoint(FILE *fp, bool bin, int num)
|
|||
column = 0;
|
||||
}
|
||||
|
||||
|
||||
/* This code is used when one does RUN aap.raw but *not* when doing RUN. */
|
||||
static void
|
||||
fileAddRealValue(FILE *fp, bool bin, double value)
|
||||
{
|
||||
|
|
@ -1056,6 +1060,8 @@ plotInit(runDesc *run)
|
|||
}
|
||||
}
|
||||
|
||||
/* mhx: minimize the number of REALLOCs */
|
||||
#define OUTSIZE (256*4096)
|
||||
|
||||
static void
|
||||
plotAddRealValue(dataDesc *desc, double value)
|
||||
|
|
@ -1063,11 +1069,11 @@ plotAddRealValue(dataDesc *desc, double value)
|
|||
struct dvec *v = desc->vec;
|
||||
|
||||
if (isreal(v)) {
|
||||
v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + 1);
|
||||
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_realdata = TREALLOC(double, v->v_realdata, v->v_length + OUTSIZE);
|
||||
v->v_realdata[v->v_length] = value;
|
||||
} else {
|
||||
/* a real parading as a VF_COMPLEX */
|
||||
v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1);
|
||||
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE);
|
||||
v->v_compdata[v->v_length].cx_real = value;
|
||||
v->v_compdata[v->v_length].cx_imag = 0.0;
|
||||
}
|
||||
|
|
@ -1082,7 +1088,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
|
|||
{
|
||||
struct dvec *v = desc->vec;
|
||||
|
||||
v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + 1);
|
||||
if ((v->v_dims[0] & (OUTSIZE - 1)) == 0) v->v_compdata = TREALLOC(ngcomplex_t, v->v_compdata, v->v_length + OUTSIZE);
|
||||
v->v_compdata[v->v_length].cx_real = value.real;
|
||||
v->v_compdata[v->v_length].cx_imag = value.imag;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "ngspice/typedefs.h"
|
||||
|
||||
|
||||
typedef struct dataDesc {
|
||||
char *name; /* The name of the vector. */
|
||||
int type; /* The type. */
|
||||
|
|
@ -24,7 +23,6 @@ typedef struct dataDesc {
|
|||
struct dvec *vec;
|
||||
} dataDesc;
|
||||
|
||||
|
||||
struct runDesc {
|
||||
void *analysis;
|
||||
CKTcircuit *circuit;
|
||||
|
|
@ -38,13 +36,13 @@ struct runDesc {
|
|||
bool binary;
|
||||
struct plot *runPlot;
|
||||
FILE *fp;
|
||||
long pointPos; /* where to write pointCount */
|
||||
long pointPos; /* where to write pointCount */
|
||||
int pointCount;
|
||||
int isComplex;
|
||||
int windowCount;
|
||||
int spindex; /* mhx */
|
||||
};
|
||||
|
||||
|
||||
int OUTpBeginPlot(CKTcircuit *circuitPtr, JOB *analysisPtr,
|
||||
IFuid analName,
|
||||
IFuid refName, int refType,
|
||||
|
|
@ -64,11 +62,4 @@ int OUTattributes(runDesc *plotPtr, IFuid varName, int param, IFvalue *value);
|
|||
int OUTstopnow(void);
|
||||
void OUTerror(int flags, char *format, IFuid *names);
|
||||
|
||||
#ifdef __GNUC__
|
||||
void OUTerrorf(int, const char *fmt, ...) __attribute__ ((format (__printf__, 2, 3)));
|
||||
#else
|
||||
void OUTerrorf(int, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ int IFnewUid(CKTcircuit *, IFuid *, IFuid, char *, int, CKTnode **);
|
|||
int IFdelUid(CKTcircuit *, IFuid, int);
|
||||
int INPaName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *,
|
||||
IFvalue *);
|
||||
int INPaSpecName(char *, IFvalue *, CKTcircuit *, int *, char *, GENinstance **, IFsimulator *, int *, IFvalue *, int *);
|
||||
int INPapName(CKTcircuit *, int, JOB *, char *, IFvalue *);
|
||||
void INPcaseFix(char *);
|
||||
char *INPdevParse(char **, CKTcircuit *, int, GENinstance *, double *, int *, INPtables *);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ libcap_la_SOURCES = \
|
|||
capsset.c \
|
||||
capsupd.c \
|
||||
captemp.c \
|
||||
capfindbr.c \
|
||||
captrunc.c
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ typedef struct sCAPinstance {
|
|||
int CAPstate; /* pointer to start of capacitor state vector */
|
||||
int CAPposNode; /* number of positive node of capacitor */
|
||||
int CAPnegNode; /* number of negative node of capacitor */
|
||||
int CAPbrEq; /* mhx: store node number */
|
||||
|
||||
double CAPtemp; /* temperature at which this capacitor operates */
|
||||
double CAPdtemp; /* delta-temperature of this instance */
|
||||
|
|
@ -47,6 +48,7 @@ typedef struct sCAPinstance {
|
|||
* (positive,negative) */
|
||||
double *CAPnegPosptr; /* pointer to sparse matrix offdiagonal at
|
||||
* (negative,positive) */
|
||||
double *CAPbrptr; /* mhx: to get I(Cx), pointer to sparse matrix diagonal */
|
||||
unsigned CAPcapGiven : 1; /* flag to indicate capacitance was specified */
|
||||
unsigned CAPicGiven : 1; /* flag to indicate init. cond. was specified */
|
||||
unsigned CAPwidthGiven : 1; /* flag to indicate capacitor width given */
|
||||
|
|
|
|||
|
|
@ -23,4 +23,5 @@ extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
|||
extern int CAPtemp(GENmodel*,CKTcircuit*);
|
||||
extern int CAPtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
extern int CAPsoaCheck(CKTcircuit *, GENmodel *);
|
||||
extern int CAPfindBr(CKTcircuit*, GENmodel*, IFuid);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ SPICEdev CAPinfo = {
|
|||
/* DEVpzSetup */ CAPsetup,
|
||||
/* DEVtemperature*/ CAPtemp,
|
||||
/* DEVtrunc */ CAPtrunc,
|
||||
/* DEVfindBranch */ NULL,
|
||||
/* DEVfindBranch */ CAPfindBr,
|
||||
/* DEVacLoad */ CAPacLoad,
|
||||
/* DEVaccept */ NULL,
|
||||
/* DEVdestroy */ CAPdestroy,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,11 @@ CAPload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(here->CAPnegPosptr) -= m * geq;
|
||||
*(ckt->CKTrhs+here->CAPposNode) -= m * ceq;
|
||||
*(ckt->CKTrhs+here->CAPnegNode) += m * ceq;
|
||||
/* mhx: to access I(Cx) */
|
||||
if (here->CAPbrptr != NULL) {
|
||||
*(ckt->CKTrhs + here->CAPbrEq) = *(ckt->CKTstate0 + here->CAPccap);
|
||||
*(here->CAPbrptr) += 1.0;
|
||||
}
|
||||
} else
|
||||
*(ckt->CKTstate0+here->CAPqcap) = here->CAPcapac * vcap;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
TSTALLOC(CAPnegNegptr,CAPnegNode,CAPnegNode);
|
||||
TSTALLOC(CAPposNegptr,CAPposNode,CAPnegNode);
|
||||
TSTALLOC(CAPnegPosptr,CAPnegNode,CAPposNode);
|
||||
if (here->CAPbrEq & (here->CAPbrptr == NULL))
|
||||
TSTALLOC(CAPbrptr, CAPbrEq, CAPbrEq); /* mhx: to access I(Cx) */
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ libind_la_SOURCES = \
|
|||
indsacl.c \
|
||||
indsetup.c \
|
||||
indsload.c \
|
||||
indfindbr.c \
|
||||
indsprt.c \
|
||||
indsset.c \
|
||||
indsupd.c \
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ extern int INDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
|||
extern int INDunsetup(GENmodel*,CKTcircuit*);
|
||||
extern int INDtemp(GENmodel*, CKTcircuit*);
|
||||
extern int INDtrunc(GENmodel*,CKTcircuit*,double*);
|
||||
|
||||
extern int INDfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx: find inductor branch
|
||||
extern int MUTacLoad(GENmodel*,CKTcircuit*);
|
||||
extern int MUTask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*);
|
||||
extern int MUTdelete(GENmodel*,IFuid,GENinstance**);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ SPICEdev INDinfo = {
|
|||
/* DEVpzSetup */ INDsetup,
|
||||
/* DEVtemperature*/ INDtemp,
|
||||
/* DEVtrunc */ INDtrunc,
|
||||
/* DEVfindBranch */ NULL,
|
||||
/* DEVfindBranch */ INDfindBr, // mhx
|
||||
/* DEVacLoad */ INDacLoad,
|
||||
/* DEVaccept */ NULL,
|
||||
/* DEVdestroy */ INDdestroy,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ libres_la_SOURCES = \
|
|||
ressload.c \
|
||||
ressprt.c \
|
||||
ressset.c \
|
||||
resfindbr.c \
|
||||
restemp.c
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ typedef struct sRESinstance {
|
|||
int RESstate; /* not used but needed for sructure consistency */
|
||||
int RESposNode; /* number of positive node of resistor */
|
||||
int RESnegNode; /* number of negative node of resistor */
|
||||
int RESbrEq; /* mhx: number of the node that stores I(Rx) */
|
||||
|
||||
double REStemp; /* temperature at which this resistor operates */
|
||||
double RESdtemp; /* delta-temperature of a particular instance */
|
||||
|
|
@ -53,6 +54,7 @@ typedef struct sRESinstance {
|
|||
* (positive,negative) */
|
||||
double *RESnegPosptr; /* pointer to sparse matrix offdiagonal at
|
||||
* (negative,positive) */
|
||||
double *RESbrptr; /* mhx: to get I(Rx), pointer to sparse matrix diagonal */
|
||||
unsigned RESresGiven : 1; /* flag to indicate resistance was specified */
|
||||
unsigned RESwidthGiven : 1; /* flag to indicate width given */
|
||||
unsigned RESlengthGiven : 1; /* flag to indicate length given */
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@ extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
|
|||
extern int REStemp(GENmodel*,CKTcircuit*);
|
||||
extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
|
||||
extern int RESsoaCheck(CKTcircuit *, GENmodel *);
|
||||
extern int RESfindBr(CKTcircuit*, GENmodel*, IFuid); // mhx
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ SPICEdev RESinfo = {
|
|||
/* DEVpzSetup */ RESsetup,
|
||||
/* DEVtemperature*/ REStemp,
|
||||
/* DEVtrunc */ NULL,
|
||||
/* DEVfindBranch */ NULL,
|
||||
/* DEVfindBranch */ RESfindBr,
|
||||
/* DEVacLoad */ RESacload, /* ac load and normal load are identical */
|
||||
/* DEVaccept */ NULL,
|
||||
/* DEVdestroy */ RESdestroy,
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ Modified: Apr 2000 - Paolo Nenzi
|
|||
#include "ngspice/sperror.h"
|
||||
|
||||
|
||||
/* actually load the current resistance value into the sparse matrix
|
||||
/* actually load the current resistance value into the sparse matrix
|
||||
* previously provided */
|
||||
int
|
||||
int
|
||||
RESload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
{
|
||||
RESmodel *model = (RESmodel *)inModel;
|
||||
|
|
@ -23,14 +23,20 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
RESinstance *here;
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->RESinstances; here != NULL ;
|
||||
here = here->RESnextInstance) {
|
||||
for (here = model->RESinstances; here != NULL ;
|
||||
here = here->RESnextInstance) {
|
||||
|
||||
here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) -
|
||||
here->REScurrent = (*(ckt->CKTrhsOld+here->RESposNode) -
|
||||
*(ckt->CKTrhsOld+here->RESnegNode)) * here->RESconduct;
|
||||
|
||||
m = (here->RESm);
|
||||
|
||||
/* mhx: access current like I(Rx) */
|
||||
if (here->RESbrptr != NULL) {
|
||||
*(ckt->CKTrhs + here->RESbrEq) = m * here->REScurrent;
|
||||
*(here->RESbrptr) += 1.0;
|
||||
}
|
||||
|
||||
*(here->RESposPosptr) += m * here->RESconduct;
|
||||
*(here->RESnegNegptr) += m * here->RESconduct;
|
||||
*(here->RESposNegptr) -= m * here->RESconduct;
|
||||
|
|
@ -41,10 +47,10 @@ RESload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
}
|
||||
|
||||
|
||||
/* actually load the current resistance value into the sparse matrix
|
||||
/* actually load the current resistance value into the sparse matrix
|
||||
* previously provided */
|
||||
int
|
||||
RESacload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
int
|
||||
RESacload(GENmodel *inModel, CKTcircuit *ckt)
|
||||
{
|
||||
RESmodel *model = (RESmodel *)inModel;
|
||||
double m;
|
||||
|
|
@ -56,7 +62,7 @@ RESacload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
RESinstance *here;
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = model->RESinstances; here != NULL ;
|
||||
for (here = model->RESinstances; here != NULL ;
|
||||
here = here->RESnextInstance) {
|
||||
|
||||
m = (here->RESm);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
TSTALLOC(RESnegNegptr, RESnegNode, RESnegNode);
|
||||
TSTALLOC(RESposNegptr, RESposNode, RESnegNode);
|
||||
TSTALLOC(RESnegPosptr, RESnegNode, RESposNode);
|
||||
}
|
||||
if (here->RESbrEq & (here->RESbrptr == NULL))
|
||||
TSTALLOC(RESbrptr, RESbrEq, RESbrEq);
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,20 +19,18 @@ Author: 1985 Thomas L. Quarles
|
|||
#include "ngspice/iferrmsg.h"
|
||||
#include "inpxx.h"
|
||||
|
||||
int
|
||||
INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
|
||||
GENinstance **fast, IFsimulator * sim, int *dataType, IFvalue * selector)
|
||||
/* the name of the parameter to set */
|
||||
/* the parameter union containing the value to set */
|
||||
/* the circuit this device is a member of */
|
||||
/* the device type code to the device being parsed */
|
||||
/* the name of the device */
|
||||
/* direct pointer to device being parsed */
|
||||
/* the simulator data structure */
|
||||
/* the datatype of the returned value structure */
|
||||
/* data sub-selector for questions */
|
||||
int
|
||||
INPaName ( char *parm, // the name of the parameter to set,
|
||||
IFvalue *val, // the parameter union containing the value to set,
|
||||
CKTcircuit *ckt, // the circuit this device is a member of,
|
||||
int *dev, // the device type code to the device being parsed,
|
||||
char *devnam, // the name of the device,
|
||||
GENinstance **fast, // direct pointer to device being parsed,
|
||||
IFsimulator *sim, // the simulator data structure,
|
||||
int *dataType, // the datatype of the returned value structure,
|
||||
IFvalue *selector) // data sub-selector for questions.
|
||||
{
|
||||
int error; /* int to store evaluate error return codes in */
|
||||
int error; /* int to store evaluate error return codes in */
|
||||
int i;
|
||||
|
||||
/* find the instance - don't know about model, so use null there,
|
||||
|
|
@ -43,7 +41,7 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
|
|||
if (*fast == NULL)
|
||||
*fast = sim->findInstance (ckt, devnam);
|
||||
if (*fast == NULL)
|
||||
return (E_NODEV);
|
||||
return (E_NODEV);
|
||||
|
||||
*dev = (*fast)->GENmodPtr->GENmodType;
|
||||
|
||||
|
|
@ -52,20 +50,76 @@ INPaName(char *parm, IFvalue * val, CKTcircuit *ckt, int *dev, char *devnam,
|
|||
* parameter.
|
||||
*/
|
||||
for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) {
|
||||
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
|
||||
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
|
||||
/* found it, so we ask the question using the device info we got
|
||||
* above and put the results in the IFvalue structure our caller
|
||||
* gave us originally
|
||||
*/
|
||||
error = sim->askInstanceQuest (ckt, *fast,
|
||||
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
|
||||
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
|
||||
/* found it, so we ask the question using the device info we got
|
||||
* above and put the results in the IFvalue structure our caller
|
||||
* gave us originally
|
||||
*/
|
||||
error = sim->askInstanceQuest (ckt, *fast,
|
||||
sim->devices[*dev]->instanceParms[i].id, val,
|
||||
selector);
|
||||
if (dataType)
|
||||
*dataType =
|
||||
sim->devices[*dev]->instanceParms[i].dataType;
|
||||
return (error);
|
||||
}
|
||||
selector);
|
||||
if (dataType)
|
||||
*dataType =
|
||||
sim->devices[*dev]->instanceParms[i].dataType;
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
return (E_BADPARM);
|
||||
}
|
||||
|
||||
// mhx: specialized (faster) version that directly returns/uses the index of the parameter we seek
|
||||
int INPaSpecName (
|
||||
char *parm, // the name of the parameter to set,
|
||||
IFvalue *val, // the parameter union containing the value to set,
|
||||
CKTcircuit *ckt, // the circuit this device is a member of,
|
||||
int *dev, // the device type code to the device being parsed,
|
||||
char *devnam, // the name of the device,
|
||||
GENinstance **fast, // direct pointer to device being parsed,
|
||||
IFsimulator *sim, // the simulator data structure,
|
||||
int *dataType, // the datatype of the returned value structure,
|
||||
IFvalue *selector, // data sub-selector for questions.
|
||||
int *spindex) // special index
|
||||
{
|
||||
int error; // int to store evaluate error return codes in
|
||||
int i;
|
||||
|
||||
/*
|
||||
* find the instance - don't know about model, so use null there,
|
||||
* otherwise pass on as much info as we have about the device
|
||||
* (name, type, direct pointer) - the type and direct pointer
|
||||
* WILL be set on return unless error is not OK
|
||||
*/
|
||||
if (*fast == NULL)
|
||||
*fast = sim->findInstance(ckt, devnam);
|
||||
if (*fast == NULL)
|
||||
return (E_NODEV);
|
||||
|
||||
*dev = (*fast)->GENmodPtr->GENmodType;
|
||||
|
||||
/* now find the parameter - hunt through the parameter tables for
|
||||
* this device type and look for a name match of an 'ask'able
|
||||
* parameter.
|
||||
*/
|
||||
if (*spindex != -1) { // mhx: shortcut for repeated question
|
||||
error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[*spindex].id, val, selector);
|
||||
if (dataType) *dataType = sim->devices[*dev]->instanceParms[*spindex].dataType;
|
||||
return error;
|
||||
}
|
||||
|
||||
for (i = 0; i < *(sim->devices[*dev]->numInstanceParms); i++) {
|
||||
if (strcmp(parm, sim->devices[*dev]->instanceParms[i].keyword) == 0
|
||||
&& (sim->devices[*dev]->instanceParms[i].dataType & IF_ASK)) {
|
||||
/*
|
||||
* found it, so we ask the question using the device info we got
|
||||
* above and put the results in the IFvalue structure our caller gave us originally
|
||||
*/
|
||||
*spindex = i; /* mhx: shortcut for repeated questioning */
|
||||
error = sim->askInstanceQuest(ckt, *fast, sim->devices[*dev]->instanceParms[i].id, val, selector);
|
||||
if (dataType)
|
||||
*dataType = sim->devices[*dev]->instanceParms[i].dataType; // probably double
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return E_BADPARM;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue