You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
6.5 KiB
187 lines
6.5 KiB
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1987 Thomas L. Quarles
|
|
Modified: 2000 AlansFixes
|
|
**********/
|
|
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/const.h"
|
|
#include "ngspice/ifsim.h"
|
|
#include "ngspice/cktdefs.h"
|
|
#include "ngspice/devdefs.h"
|
|
#include "vdmosdefs.h"
|
|
#include "ngspice/sperror.h"
|
|
#include "ngspice/suffix.h"
|
|
|
|
/*ARGSUSED*/
|
|
int
|
|
VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|
IFvalue *select)
|
|
{
|
|
VDMOSinstance *here = (VDMOSinstance*)inst;
|
|
static char *msg = "Current and power not available for ac analysis";
|
|
NG_IGNORE(select);
|
|
|
|
switch(which) {
|
|
case VDMOS_TEMP:
|
|
value->rValue = here->VDMOStemp - CONSTCtoK;
|
|
return(OK);
|
|
case VDMOS_DTEMP:
|
|
value->rValue = here->VDMOSdtemp;
|
|
return(OK);
|
|
case VDMOS_CAPGS:
|
|
value->rValue = 2* *(ckt->CKTstate0 + here->VDMOScapgs);
|
|
return(OK);
|
|
case VDMOS_CAPGD:
|
|
value->rValue = 2* *(ckt->CKTstate0 + here->VDMOScapgd);
|
|
return(OK);
|
|
case VDMOS_CAPDS:
|
|
value->rValue = here->VDIOcap;
|
|
return(OK);
|
|
case VDMOS_M:
|
|
value->rValue = here->VDMOSm;
|
|
return(OK);
|
|
case VDMOS_L:
|
|
value->rValue = here->VDMOSl;
|
|
return(OK);
|
|
case VDMOS_W:
|
|
value->rValue = here->VDMOSw;
|
|
return(OK);
|
|
case VDMOS_OFF:
|
|
value->iValue = here->VDMOSoff;
|
|
return(OK);
|
|
case VDMOS_TNODEOUT:
|
|
value->iValue = here->VDMOStnodeout;
|
|
return(OK);
|
|
case VDMOS_IC_VDS:
|
|
value->rValue = here->VDMOSicVDS;
|
|
return(OK);
|
|
case VDMOS_IC_VGS:
|
|
value->rValue = here->VDMOSicVGS;
|
|
return(OK);
|
|
case VDMOS_DNODE:
|
|
value->iValue = here->VDMOSdNode;
|
|
return(OK);
|
|
case VDMOS_GNODE:
|
|
value->iValue = here->VDMOSgNode;
|
|
return(OK);
|
|
case VDMOS_SNODE:
|
|
value->iValue = here->VDMOSsNode;
|
|
return(OK);
|
|
case VDMOS_TNODE:
|
|
value->iValue = here->VDMOStempNode;
|
|
return(OK);
|
|
case VDMOS_SNODEPRIME:
|
|
value->iValue = here->VDMOSsNodePrime;
|
|
return(OK);
|
|
case VDMOS_SOURCECONDUCT:
|
|
value->rValue = here->VDMOSsourceConductance;
|
|
return(OK);
|
|
case VDMOS_SOURCERESIST:
|
|
if (here->VDMOSsNodePrime != here->VDMOSsNode)
|
|
value->rValue = 1.0 / here->VDMOSsourceConductance;
|
|
else
|
|
value->rValue = 0.0;
|
|
return(OK);
|
|
case VDMOS_DRAINCONDUCT:
|
|
value->rValue = here->VDMOSdrainConductance;
|
|
return(OK);
|
|
case VDMOS_DRAINRESIST:
|
|
if (here->VDMOSdNodePrime != here->VDMOSdNode)
|
|
value->rValue = 1.0 / here->VDMOSdrainConductance;
|
|
else
|
|
value->rValue = 0.0;
|
|
return(OK);
|
|
case VDMOS_VON:
|
|
value->rValue = here->VDMOSvon;
|
|
return(OK);
|
|
case VDMOS_CD:
|
|
value->rValue = here->VDMOScd;
|
|
return(OK);
|
|
case VDMOS_GM:
|
|
value->rValue = here->VDMOSgm;
|
|
return(OK);
|
|
case VDMOS_GDS:
|
|
value->rValue = here->VDMOSgds;
|
|
return(OK);
|
|
case VDMOS_VGS:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOSvgs);
|
|
return(OK);
|
|
case VDMOS_VDS:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOSvds);
|
|
return(OK);
|
|
case VDMOS_QGS:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOSqgs);
|
|
return(OK);
|
|
case VDMOS_CQGS:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgs);
|
|
return(OK);
|
|
case VDMOS_QGD:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOSqgd);
|
|
return(OK);
|
|
case VDMOS_CQGD:
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgd);
|
|
return(OK);
|
|
case VDMOS_CG :
|
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
|
errRtn = "VDMOSask.c";
|
|
strcpy(errMsg,msg);
|
|
return(E_ASKCURRENT);
|
|
} else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) {
|
|
value->rValue = 0;
|
|
} else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
|
|
(ckt->CKTmode & MODETRANOP)) {
|
|
value->rValue = 0;
|
|
} else {
|
|
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgd) + *(ckt->CKTstate0 +
|
|
here->VDMOScqgs);
|
|
}
|
|
return(OK);
|
|
case VDMOS_CS :
|
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
|
errRtn = "VDMOSask.c";
|
|
strcpy(errMsg,msg);
|
|
return(E_ASKCURRENT);
|
|
} else {
|
|
value->rValue = -here->VDMOScd;
|
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
|
|
!(ckt->CKTmode & MODETRANOP)) {
|
|
value->rValue -= *(ckt->CKTstate0 + here->VDMOScqgd) +
|
|
*(ckt->CKTstate0 + here->VDMOScqgs);
|
|
}
|
|
}
|
|
return(OK);
|
|
case VDMOS_POWER :
|
|
if (ckt->CKTcurrentAnalysis & DOING_AC) {
|
|
errMsg = TMALLOC(char, strlen(msg) + 1);
|
|
errRtn = "VDMOSask.c";
|
|
strcpy(errMsg,msg);
|
|
return(E_ASKPOWER);
|
|
} else {
|
|
double temp;
|
|
|
|
value->rValue = here->VDMOScd *
|
|
*(ckt->CKTrhsOld + here->VDMOSdNode);
|
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
|
|
!(ckt->CKTmode & MODETRANOP)) {
|
|
value->rValue += (*(ckt->CKTstate0 + here->VDMOScqgd) +
|
|
*(ckt->CKTstate0 + here->VDMOScqgs)) *
|
|
*(ckt->CKTrhsOld + here->VDMOSgNode);
|
|
}
|
|
temp = -here->VDMOScd;
|
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
|
|
!(ckt->CKTmode & MODETRANOP)) {
|
|
temp -= *(ckt->CKTstate0 + here->VDMOScqgd) +
|
|
*(ckt->CKTstate0 + here->VDMOScqgs);
|
|
}
|
|
value->rValue += temp * *(ckt->CKTrhsOld + here->VDMOSsNode);
|
|
}
|
|
return(OK);
|
|
default:
|
|
return(E_BADPARM);
|
|
}
|
|
/* NOTREACHED */
|
|
}
|
|
|