Browse Source

Reduce vdmos to a native 3 terminal version.

pre-master-46
dwarning 7 years ago
committed by Holger Vogt
parent
commit
1363b7a6b2
  1. 17
      src/spicelib/devices/vdmos/vdmos.c
  2. 42
      src/spicelib/devices/vdmos/vdmosacld.c
  3. 54
      src/spicelib/devices/vdmos/vdmosask.c
  4. 33
      src/spicelib/devices/vdmos/vdmosconv.c
  5. 124
      src/spicelib/devices/vdmos/vdmosdefs.h
  6. 922
      src/spicelib/devices/vdmos/vdmosdist.c
  7. 405
      src/spicelib/devices/vdmos/vdmosdset.c
  8. 5
      src/spicelib/devices/vdmos/vdmosic.c
  9. 162
      src/spicelib/devices/vdmos/vdmosload.c
  10. 7
      src/spicelib/devices/vdmos/vdmospar.c
  11. 55
      src/spicelib/devices/vdmos/vdmospzld.c
  12. 44
      src/spicelib/devices/vdmos/vdmosset.c
  13. 2
      src/spicelib/devices/vdmos/vdmostemp.c
  14. 1
      src/spicelib/devices/vdmos/vdmostrun.c
  15. 7
      src/spicelib/parser/inp2m.c

17
src/spicelib/devices/vdmos/vdmos.c

@ -18,10 +18,9 @@ IFparm VDMOSpTable[] = { /* parameters */
IP("off", VDMOS_OFF, IF_FLAG, "Device initially off"),
IOPU("icvds", VDMOS_IC_VDS, IF_REAL, "Initial D-S voltage"),
IOPU("icvgs", VDMOS_IC_VGS, IF_REAL, "Initial G-S voltage"),
IOPU("icvbs", VDMOS_IC_VBS, IF_REAL, "Initial B-S voltage"),
IOPU("temp", VDMOS_TEMP, IF_REAL, "Instance temperature"),
IOPU("dtemp", VDMOS_DTEMP, IF_REAL, "Instance temperature difference"),
IP( "ic", VDMOS_IC, IF_REALVEC, "Vector of D-S, G-S, B-S voltages"),
IP( "ic", VDMOS_IC, IF_REALVEC, "Vector of D-S, G-S voltages"),
OP( "id", VDMOS_CD, IF_REAL, "Drain current"),
OP( "is", VDMOS_CS, IF_REAL, "Source current"),
@ -35,7 +34,6 @@ IFparm VDMOSpTable[] = { /* parameters */
OPU( "dnode", VDMOS_DNODE, IF_INTEGER, "Number of the drain node "),
OPU( "gnode", VDMOS_GNODE, IF_INTEGER, "Number of the gate node "),
OPU( "snode", VDMOS_SNODE, IF_INTEGER, "Number of the source node "),
OPU( "bnode", VDMOS_BNODE, IF_INTEGER, "Number of the node "),
OPU( "dnodeprime", VDMOS_DNODEPRIME, IF_INTEGER, "Number of int. drain node"),
OPU( "snodeprime", VDMOS_SNODEPRIME, IF_INTEGER, "Number of int. source node "),
@ -50,22 +48,12 @@ IFparm VDMOSpTable[] = { /* parameters */
OP( "gm", VDMOS_GM, IF_REAL, "Transconductance"),
OP( "gds", VDMOS_GDS, IF_REAL, "Drain-Source conductance"),
OP( "gmb", VDMOS_GMBS, IF_REAL, "Bulk-Source transconductance"),
OPR( "gmbs", VDMOS_GMBS, IF_REAL, ""),
OPU( "gbd", VDMOS_GBD, IF_REAL, "Bulk-Drain conductance"),
OPU( "gbs", VDMOS_GBS, IF_REAL, "Bulk-Source conductance"),
OPU( "cqgs", VDMOS_CQGS, IF_REAL, "Capacitance due to gate-source charge storage"),
OPU( "cqgd", VDMOS_CQGD, IF_REAL, "Capacitance due to gate-drain charge storage"),
OPU( "cqgb", VDMOS_CQGB, IF_REAL, "Capacitance due to gate-bulk charge storage"),
OPU( "cqbd", VDMOS_CQBD, IF_REAL, "Capacitance due to bulk-drain charge storage"),
OPU( "cqbs", VDMOS_CQBS, IF_REAL, "Capacitance due to bulk-source charge storage"),
OPU( "qgs", VDMOS_QGS, IF_REAL, "Gate-Source charge storage"),
OPU( "qgd", VDMOS_QGD, IF_REAL, "Gate-Drain charge storage"),
OPU( "qgb", VDMOS_QGB, IF_REAL, "Gate-Bulk charge storage"),
OPU( "qbd", VDMOS_QBD, IF_REAL, "Bulk-Drain charge storage"),
OPU( "qbs", VDMOS_QBS, IF_REAL, "Bulk-Source charge storage"),
OPU( "p", VDMOS_POWER, IF_REAL, "Instaneous power"),
};
@ -124,8 +112,7 @@ IFparm VDMOSmPTable[] = { /* model parameters */
char *VDMOSnames[] = {
"Drain",
"Gate",
"Source",
"Bulk"
"Source"
};
int VDMOSnSize = NUMELEMS(VDMOSnames);

42
src/spicelib/devices/vdmos/vdmosacld.c

@ -22,12 +22,8 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
int xrev;
double xgs;
double xgd;
double xgb;
double xbd;
double xbs;
double capgs;
double capgd;
double capgb;
for( ; model != NULL; model = VDMOSnextModel(model)) {
for(here = VDMOSinstances(model); here!= NULL;
@ -47,13 +43,8 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate0+here->VDMOScapgs));
capgd = ( *(ckt->CKTstate0+here->VDMOScapgd)+
*(ckt->CKTstate0+here->VDMOScapgd));
capgb = ( *(ckt->CKTstate0+here->VDMOScapgb)+
*(ckt->CKTstate0+here->VDMOScapgb));
xgs = capgs * ckt->CKTomega;
xgd = capgd * ckt->CKTomega;
xgb = capgb * ckt->CKTomega;
xbd = here->VDMOScapbd * ckt->CKTomega;
xbs = here->VDMOScapbs * ckt->CKTomega;
/* bulk diode */
double gspr, geq, xceq;
@ -64,47 +55,30 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt)
/*
* load matrix
*/
*(here->VDMOSGPgpPtr +1) += xgd+xgs+xgb;
*(here->VDMOSBbPtr +1) += xgb+xbd+xbs;
*(here->VDMOSDPdpPtr +1) += xgd+xbd;
*(here->VDMOSSPspPtr +1) += xgs+xbs;
*(here->VDMOSGPbPtr +1) -= xgb;
*(here->VDMOSGPgpPtr +1) += xgd+xgs;
*(here->VDMOSDPdpPtr +1) += xgd;
*(here->VDMOSSPspPtr +1) += xgs;
*(here->VDMOSGPdpPtr +1) -= xgd;
*(here->VDMOSGPspPtr +1) -= xgs;
*(here->VDMOSBgpPtr +1) -= xgb;
*(here->VDMOSBdpPtr +1) -= xbd;
*(here->VDMOSBspPtr +1) -= xbs;
*(here->VDMOSDPgpPtr +1) -= xgd;
*(here->VDMOSDPbPtr +1) -= xbd;
*(here->VDMOSSPgpPtr +1) -= xgs;
*(here->VDMOSSPbPtr +1) -= xbs;
*(here->VDMOSDdPtr) += here->VDMOSdrainConductance;
*(here->VDMOSSsPtr) += here->VDMOSsourceConductance;
*(here->VDMOSBbPtr) += here->VDMOSgbd+here->VDMOSgbs;
*(here->VDMOSDPdpPtr) += here->VDMOSdrainConductance+
here->VDMOSgds+here->VDMOSgbd+
xrev*(here->VDMOSgm+here->VDMOSgmbs);
here->VDMOSgds+xrev*(here->VDMOSgm);
*(here->VDMOSSPspPtr) += here->VDMOSsourceConductance+
here->VDMOSgds+here->VDMOSgbs+
xnrm*(here->VDMOSgm+here->VDMOSgmbs);
here->VDMOSgds+xnrm*(here->VDMOSgm);
*(here->VDMOSDdpPtr) -= here->VDMOSdrainConductance;
*(here->VDMOSSspPtr) -= here->VDMOSsourceConductance;
*(here->VDMOSBdpPtr) -= here->VDMOSgbd;
*(here->VDMOSBspPtr) -= here->VDMOSgbs;
*(here->VDMOSDPdPtr) -= here->VDMOSdrainConductance;
*(here->VDMOSDPgpPtr) += (xnrm-xrev)*here->VDMOSgm;
*(here->VDMOSDPbPtr) += -here->VDMOSgbd+(xnrm-xrev)*here->VDMOSgmbs;
*(here->VDMOSDPspPtr) -= here->VDMOSgds+
xnrm*(here->VDMOSgm+here->VDMOSgmbs);
*(here->VDMOSDPspPtr) -= here->VDMOSgds+xnrm*(here->VDMOSgm);
*(here->VDMOSSPgpPtr) -= (xnrm-xrev)*here->VDMOSgm;
*(here->VDMOSSPsPtr) -= here->VDMOSsourceConductance;
*(here->VDMOSSPbPtr) -= here->VDMOSgbs+(xnrm-xrev)*here->VDMOSgmbs;
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+
xrev*(here->VDMOSgm+here->VDMOSgmbs);
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+xrev*(here->VDMOSgm);
/* gate resistor */
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance);
*(here->VDMOSGPgpPtr) +=
(here->VDMOSgateConductance)/* + ?? FIXME */;
*(here->VDMOSGPgpPtr) += (here->VDMOSgateConductance)/* + ?? FIXME */;
*(here->VDMOSGgpPtr) -= here->VDMOSgateConductance;
*(here->VDMOSGPgPtr) -= here->VDMOSgateConductance;
/* bulk diode */

54
src/spicelib/devices/vdmos/vdmosask.c

@ -50,9 +50,6 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case VDMOS_OFF:
value->rValue = here->VDMOSoff;
return(OK);
case VDMOS_IC_VBS:
value->rValue = here->VDMOSicVBS;
return(OK);
case VDMOS_IC_VDS:
value->rValue = here->VDMOSicVDS;
return(OK);
@ -68,12 +65,6 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case VDMOS_SNODE:
value->iValue = here->VDMOSsNode;
return(OK);
case VDMOS_BNODE:
value->iValue = here->VDMOSbNode;
return(OK);
case VDMOS_DNODEPRIME:
value->iValue = here->VDMOSdNodePrime;
return(OK);
case VDMOS_SNODEPRIME:
value->iValue = here->VDMOSsNodePrime;
return(OK);
@ -110,21 +101,12 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case VDMOS_CD:
value->rValue = here->VDMOScd;
return(OK);
case VDMOS_GMBS:
value->rValue = here->VDMOSgmbs;
return(OK);
case VDMOS_GM:
value->rValue = here->VDMOSgm;
return(OK);
case VDMOS_GDS:
value->rValue = here->VDMOSgds;
return(OK);
case VDMOS_GBD:
value->rValue = here->VDMOSgbd;
return(OK);
case VDMOS_GBS:
value->rValue = here->VDMOSgbs;
return(OK);
case VDMOS_VGS:
value->rValue = *(ckt->CKTstate0 + here->VDMOSvgs);
return(OK);
@ -143,24 +125,6 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case VDMOS_CQGD:
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgd);
return(OK);
case VDMOS_QGB:
value->rValue = *(ckt->CKTstate0 + here->VDMOSqgb);
return(OK);
case VDMOS_CQGB:
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgb);
return(OK);
case VDMOS_QBD:
value->rValue = *(ckt->CKTstate0 + here->VDMOSqbd);
return(OK);
case VDMOS_CQBD:
value->rValue = *(ckt->CKTstate0 + here->VDMOScqbd);
return(OK);
case VDMOS_QBS:
value->rValue = *(ckt->CKTstate0 + here->VDMOSqbs);
return(OK);
case VDMOS_CQBS:
value->rValue = *(ckt->CKTstate0 + here->VDMOScqbs);
return(OK);
case VDMOS_CG :
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = TMALLOC(char, strlen(msg) + 1);
@ -173,8 +137,7 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
(ckt->CKTmode & MODETRANOP)) {
value->rValue = 0;
} else {
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgb) +
*(ckt->CKTstate0 + here->VDMOScqgd) + *(ckt->CKTstate0 +
value->rValue = *(ckt->CKTstate0 + here->VDMOScqgd) + *(ckt->CKTstate0 +
here->VDMOScqgs);
}
return(OK);
@ -186,12 +149,9 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
return(E_ASKCURRENT);
} else {
value->rValue = -here->VDMOScd;
value->rValue -= here->VDMOScbd + here->VDMOScbs -
*(ckt->CKTstate0 + here->VDMOScqgb);
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
!(ckt->CKTmode & MODETRANOP)) {
value->rValue -= *(ckt->CKTstate0 + here->VDMOScqgb) +
*(ckt->CKTstate0 + here->VDMOScqgd) +
value->rValue -= *(ckt->CKTstate0 + here->VDMOScqgd) +
*(ckt->CKTstate0 + here->VDMOScqgs);
}
}
@ -207,22 +167,16 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
value->rValue = here->VDMOScd *
*(ckt->CKTrhsOld + here->VDMOSdNode);
value->rValue += (here->VDMOScbd + here->VDMOScbs -
*(ckt->CKTstate0 + here->VDMOScqgb)) *
*(ckt->CKTrhsOld + here->VDMOSbNode);
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
!(ckt->CKTmode & MODETRANOP)) {
value->rValue += (*(ckt->CKTstate0 + here->VDMOScqgb) +
*(ckt->CKTstate0 + here->VDMOScqgd) +
value->rValue += (*(ckt->CKTstate0 + here->VDMOScqgd) +
*(ckt->CKTstate0 + here->VDMOScqgs)) *
*(ckt->CKTrhsOld + here->VDMOSgNode);
}
temp = -here->VDMOScd;
temp -= here->VDMOScbd + here->VDMOScbs ;
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) &&
!(ckt->CKTmode & MODETRANOP)) {
temp -= *(ckt->CKTstate0 + here->VDMOScqgb) +
*(ckt->CKTstate0 + here->VDMOScqgd) +
temp -= *(ckt->CKTstate0 + here->VDMOScqgd) +
*(ckt->CKTstate0 + here->VDMOScqgs);
}
value->rValue += temp * *(ckt->CKTrhsOld + here->VDMOSsNode);

33
src/spicelib/devices/vdmos/vdmosconv.c

@ -14,15 +14,10 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
{
VDMOSmodel *model = (VDMOSmodel*)inModel;
VDMOSinstance *here;
double delvbs;
double delvbd;
double delvgs;
double delvds;
double delvgd;
double cbhat;
double cdhat;
double vbs;
double vbd;
double vgs;
double vds;
double vgd;
@ -33,21 +28,15 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
for(here = VDMOSinstances(model); here!= NULL;
here = VDMOSnextInstance(here)) {
vbs = model->VDMOStype * (
*(ckt->CKTrhs+here->VDMOSbNode) -
*(ckt->CKTrhs+here->VDMOSsNodePrime));
vgs = model->VDMOStype * (
*(ckt->CKTrhs+here->VDMOSgNode) -
*(ckt->CKTrhs+here->VDMOSsNodePrime));
vds = model->VDMOStype * (
*(ckt->CKTrhs+here->VDMOSdNodePrime) -
*(ckt->CKTrhs+here->VDMOSsNodePrime));
vbd=vbs-vds;
vgd=vgs-vds;
vgdo = *(ckt->CKTstate0 + here->VDMOSvgs) -
*(ckt->CKTstate0 + here->VDMOSvds);
delvbs = vbs - *(ckt->CKTstate0 + here->VDMOSvbs);
delvbd = vbd - *(ckt->CKTstate0 + here->VDMOSvbd);
delvgs = vgs - *(ckt->CKTstate0 + here->VDMOSvgs);
delvds = vds - *(ckt->CKTstate0 + here->VDMOSvds);
delvgd = vgd-vgdo;
@ -56,24 +45,15 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
if (here->VDMOSmode >= 0) {
cdhat=
here->VDMOScd-
here->VDMOSgbd * delvbd +
here->VDMOSgmbs * delvbs +
here->VDMOScd -
here->VDMOSgm * delvgs +
here->VDMOSgds * delvds ;
} else {
cdhat=
here->VDMOScd -
( here->VDMOSgbd -
here->VDMOSgmbs) * delvbd -
here->VDMOSgm * delvgd +
here->VDMOSgds * delvds ;
}
cbhat=
here->VDMOScbs +
here->VDMOScbd +
here->VDMOSgbd * delvbd +
here->VDMOSgbs * delvbs ;
/*
* check convergence
*/
@ -81,17 +61,8 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
ckt->CKTabstol;
if (fabs(cdhat-here->VDMOScd) >= tol) {
ckt->CKTnoncon++;
ckt->CKTtroubleElt = (GENinstance *) here;
ckt->CKTtroubleElt = (GENinstance *) here;
return(OK); /* no reason to continue, we haven't converged */
} else {
tol=ckt->CKTreltol*
MAX(fabs(cbhat),fabs(here->VDMOScbs+here->VDMOScbd))+
ckt->CKTabstol;
if (fabs(cbhat-(here->VDMOScbs+here->VDMOScbd)) > tol) {
ckt->CKTnoncon++;
ckt->CKTtroubleElt = (GENinstance *) here;
return(OK); /* no reason to continue, we haven't converged*/
}
}
}
}

124
src/spicelib/devices/vdmos/vdmosdefs.h

@ -41,7 +41,6 @@ typedef struct sVDMOSinstance {
const int VDMOSdNode; /* number of the gate node of the mosfet */
const int VDMOSgNode; /* number of the gate node of the mosfet */
const int VDMOSsNode; /* number of the source node of the mosfet */
const int VDMOSbNode; /* number of the bulk node of the mosfet */
int VDMOSdNodePrime; /* number of the internal drain node of the mosfet */
int VDMOSsNodePrime; /* number of the internal source node of the mosfet */
int VDMOSgNodePrime; /* number of the internal gate node of the mosfet */
@ -63,7 +62,6 @@ typedef struct sVDMOSinstance {
double VDMOStVto; /* temperature corrected Vto */
double VDMOStSatCur; /* temperature corrected saturation Cur. */
double VDMOSicVBS; /* initial condition B-S voltage */
double VDMOSicVDS; /* initial condition D-S voltage */
double VDMOSicVGS; /* initial condition G-S voltage */
double VDMOSvon;
@ -71,17 +69,8 @@ typedef struct sVDMOSinstance {
double VDMOSsourceVcrit; /* Vcrit for pos. vds */
double VDMOSdrainVcrit; /* Vcrit for pos. vds */
double VDMOScd;
double VDMOScbs;
double VDMOScbd;
double VDMOSgmbs;
double VDMOSgm;
double VDMOSgds;
double VDMOSgbd;
double VDMOSgbs;
double VDMOScapbd;
double VDMOScapbs;
double VDMOSCbd;
double VDMOSCbs;
double VDMOSf2d;
double VDMOSf3d;
double VDMOSf4d;
@ -114,7 +103,7 @@ typedef struct sVDMOSinstance {
* cdr = cdrain
*/
#define VDMOSNDCOEFFS 30
#define VDMOSNDCOEFFS 11
#ifndef NODISTO
double VDMOSdCoeffs[VDMOSNDCOEFFS];
@ -124,36 +113,17 @@ typedef struct sVDMOSinstance {
#ifndef CONFIG
#define capbs2 VDMOSdCoeffs[0]
#define capbs3 VDMOSdCoeffs[1]
#define capbd2 VDMOSdCoeffs[2]
#define capbd3 VDMOSdCoeffs[3]
#define gbs2 VDMOSdCoeffs[4]
#define gbs3 VDMOSdCoeffs[5]
#define gbd2 VDMOSdCoeffs[6]
#define gbd3 VDMOSdCoeffs[7]
#define capgb2 VDMOSdCoeffs[8]
#define capgb3 VDMOSdCoeffs[9]
#define cdr_x2 VDMOSdCoeffs[10]
#define cdr_y2 VDMOSdCoeffs[11]
#define cdr_z2 VDMOSdCoeffs[12]
#define cdr_xy VDMOSdCoeffs[13]
#define cdr_yz VDMOSdCoeffs[14]
#define cdr_xz VDMOSdCoeffs[15]
#define cdr_x3 VDMOSdCoeffs[16]
#define cdr_y3 VDMOSdCoeffs[17]
#define cdr_z3 VDMOSdCoeffs[18]
#define cdr_x2z VDMOSdCoeffs[19]
#define cdr_x2y VDMOSdCoeffs[20]
#define cdr_y2z VDMOSdCoeffs[21]
#define cdr_xy2 VDMOSdCoeffs[22]
#define cdr_xz2 VDMOSdCoeffs[23]
#define cdr_yz2 VDMOSdCoeffs[24]
#define cdr_xyz VDMOSdCoeffs[25]
#define capgs2 VDMOSdCoeffs[26]
#define capgs3 VDMOSdCoeffs[27]
#define capgd2 VDMOSdCoeffs[28]
#define capgd3 VDMOSdCoeffs[29]
#define cdr_x2 VDMOSdCoeffs[0]
#define cdr_y2 VDMOSdCoeffs[1]
#define cdr_xy VDMOSdCoeffs[2]
#define cdr_x3 VDMOSdCoeffs[3]
#define cdr_y3 VDMOSdCoeffs[4]
#define cdr_x2y VDMOSdCoeffs[5]
#define cdr_xy2 VDMOSdCoeffs[6]
#define capgs2 VDMOSdCoeffs[7]
#define capgs3 VDMOSdCoeffs[8]
#define capgd2 VDMOSdCoeffs[9]
#define capgd3 VDMOSdCoeffs[10]
#endif
@ -174,7 +144,6 @@ typedef struct sVDMOSinstance {
unsigned VDMOSwGiven :1;
unsigned VDMOSdNodePrimeSet :1;
unsigned VDMOSsNodePrimeSet :1;
unsigned VDMOSicVBSGiven :1;
unsigned VDMOSicVDSGiven :1;
unsigned VDMOSicVGSGiven :1;
unsigned VDMOSvonGiven :1;
@ -188,32 +157,22 @@ typedef struct sVDMOSinstance {
* (gate node,gate node) */
double *VDMOSSsPtr; /* pointer to sparse matrix element at
* (source node,source node) */
double *VDMOSBbPtr; /* pointer to sparse matrix element at
* (bulk node,bulk node) */
double *VDMOSDPdpPtr; /* pointer to sparse matrix element at
* (drain prime node,drain prime node) */
double *VDMOSSPspPtr; /* pointer to sparse matrix element at
* (source prime node,source prime node) */
double *VDMOSDdpPtr; /* pointer to sparse matrix element at
* (drain node,drain prime node) */
double *VDMOSGbPtr; /* pointer to sparse matrix element at
* (gate node,bulk node) */
double *VDMOSGdpPtr; /* pointer to sparse matrix element at
* (gate node,drain prime node) */
double *VDMOSGspPtr; /* pointer to sparse matrix element at
* (gate node,source prime node) */
double *VDMOSSspPtr; /* pointer to sparse matrix element at
* (source node,source prime node) */
double *VDMOSBdpPtr; /* pointer to sparse matrix element at
* (bulk node,drain prime node) */
double *VDMOSBspPtr; /* pointer to sparse matrix element at
* (bulk node,source prime node) */
double *VDMOSDPspPtr; /* pointer to sparse matrix element at
* (drain prime node,source prime node) */
double *VDMOSDPdPtr; /* pointer to sparse matrix element at
* (drain prime node,drain node) */
double *VDMOSBgPtr; /* pointer to sparse matrix element at
* (bulk node,gate node) */
double *VDMOSDPgPtr; /* pointer to sparse matrix element at
* (drain prime node,gate node) */
@ -221,23 +180,15 @@ typedef struct sVDMOSinstance {
* (source prime node,gate node) */
double *VDMOSSPsPtr; /* pointer to sparse matrix element at
* (source prime node,source node) */
double *VDMOSDPbPtr; /* pointer to sparse matrix element at
* (drain prime node,bulk node) */
double *VDMOSSPbPtr; /* pointer to sparse matrix element at
* (source prime node,bulk node) */
double *VDMOSSPdpPtr; /* pointer to sparse matrix element at
* (source prime node,drain prime node) */
/* added for VDMOS */
double *VDMOSGPgpPtr; /* pointer to sparse matrix element at
* (gate prime node, gate prime node) */
double *VDMOSGPbPtr; /* pointer to sparse matrix element at
* (gate prime node, bulk node) */
double *VDMOSGPdpPtr; /* pointer to sparse matrix element at
* (gate prime node, drain prime node) */
double *VDMOSGPspPtr; /* pointer to sparse matrix element at
* (gate prime node, source prime node) */
double *VDMOSBgpPtr; /* pointer to sparse matrix element at
* (bulk node, gate prime node) */
double *VDMOSDPgpPtr; /* pointer to sparse matrix element at
* (drain prime node, gate prime node) */
double *VDMOSSPgpPtr; /* pointer to sparse matrix element at
@ -264,36 +215,24 @@ typedef struct sVDMOSinstance {
} VDMOSinstance ;
#define VDMOSvbd VDMOSstates+ 0 /* bulk-drain voltage */
#define VDMOSvbs VDMOSstates+ 1 /* bulk-source voltage */
#define VDMOSvgs VDMOSstates+ 2 /* gate-source voltage */
#define VDMOSvds VDMOSstates+ 3 /* drain-source voltage */
#define VDMOSvgs VDMOSstates+ 0 /* gate-source voltage */
#define VDMOSvds VDMOSstates+ 1 /* drain-source voltage */
#define VDMOScapgs VDMOSstates+4 /* gate-source capacitor value */
#define VDMOSqgs VDMOSstates+ 5 /* gate-source capacitor charge */
#define VDMOScqgs VDMOSstates+ 6 /* gate-source capacitor current */
#define VDMOScapgs VDMOSstates+2 /* gate-source capacitor value */
#define VDMOSqgs VDMOSstates+ 3 /* gate-source capacitor charge */
#define VDMOScqgs VDMOSstates+ 4 /* gate-source capacitor current */
#define VDMOScapgd VDMOSstates+ 7 /* gate-drain capacitor value */
#define VDMOSqgd VDMOSstates+ 8 /* gate-drain capacitor charge */
#define VDMOScqgd VDMOSstates+ 9 /* gate-drain capacitor current */
#define VDMOScapgd VDMOSstates+ 5 /* gate-drain capacitor value */
#define VDMOSqgd VDMOSstates+ 6 /* gate-drain capacitor charge */
#define VDMOScqgd VDMOSstates+ 7 /* gate-drain capacitor current */
#define VDMOScapgb VDMOSstates+10 /* gate-bulk capacitor value */
#define VDMOSqgb VDMOSstates+ 11 /* gate-bulk capacitor charge */
#define VDMOScqgb VDMOSstates+ 12 /* gate-bulk capacitor current */
#define VDIOvoltage VDMOSstates+ 8
#define VDIOcurrent VDMOSstates+ 9
#define VDIOconduct VDMOSstates+ 10
#define VDIOcapCharge VDMOSstates+ 11
#define VDIOcapCurrent VDMOSstates+ 12
#define VDMOSqbd VDMOSstates+ 13 /* bulk-drain capacitor charge */
#define VDMOScqbd VDMOSstates+ 14 /* bulk-drain capacitor current */
#define VDMOSqbs VDMOSstates+ 15 /* bulk-source capacitor charge */
#define VDMOScqbs VDMOSstates+ 16 /* bulk-source capacitor current */
#define VDIOvoltage VDMOSstates+ 17
#define VDIOcurrent VDMOSstates+ 18
#define VDIOconduct VDMOSstates+ 19
#define VDIOcapCharge VDMOSstates+ 20
#define VDIOcapCurrent VDMOSstates+ 21
#define VDMOSnumStates 22
#define VDMOSnumStates 13
/* per model data */
@ -412,7 +351,6 @@ enum {
VDMOS_L,
VDMOS_OFF,
VDMOS_IC,
VDMOS_IC_VBS,
VDMOS_IC_VDS,
VDMOS_IC_VGS,
VDMOS_CG,
@ -473,7 +411,6 @@ enum {
VDMOS_DNODE,
VDMOS_GNODE,
VDMOS_SNODE,
VDMOS_BNODE,
VDMOS_DNODEPRIME,
VDMOS_SNODEPRIME,
VDMOS_SOURCECONDUCT,
@ -483,23 +420,14 @@ enum {
VDMOS_SOURCEVCRIT,
VDMOS_DRAINVCRIT,
VDMOS_CD,
VDMOS_GMBS,
VDMOS_GM,
VDMOS_GDS,
VDMOS_GBD,
VDMOS_GBS,
VDMOS_VGS,
VDMOS_VDS,
VDMOS_QGS,
VDMOS_CQGS,
VDMOS_QGD,
VDMOS_CQGD,
VDMOS_QGB,
VDMOS_CQGB,
VDMOS_QBD,
VDMOS_CQBD,
VDMOS_QBS,
VDMOS_CQBS,
VDMOS_SOURCERESIST,
VDMOS_DRAINRESIST,
};

922
src/spicelib/devices/vdmos/vdmosdist.c
File diff suppressed because it is too large
View File

405
src/spicelib/devices/vdmos/vdmosdset.c

@ -25,49 +25,23 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
double SourceSatCur;
double gm;
double gds;
double gb;
double ebd;
double vgst;
double evbs;
double vbd;
double vbs;
double vds;
double vdsat;
double vgd;
double vgs;
double vt;
double lgbs;
double lgbs2;
double lgbs3;
double lgbd;
double lgbd2;
double lgbd3;
double gm2;
double gds2;
double gb2;
double gmds;
double gmb;
double gbds;
double gm3;
double gds3;
double gb3;
double gm2ds;
double gmds2;
double gm2b;
double gmb2;
double gb2ds;
double gbds2;
double lcapgb2;
double lcapgb3;
double lcapgs2;
double lcapgs3;
double lcapgd2;
double lcapgd3;
double lcapbs2 = 0;
double lcapbs3 = 0;
double lcapbd2 = 0;
double lcapbd3 = 0;
double gmbds = 0.0;
/* loop through all the VDMOS device models */
@ -84,47 +58,17 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
Beta = here->VDMOStTransconductance * here->VDMOSm *
here->VDMOSw/here->VDMOSl;
vbs = model->VDMOStype * (
*(ckt->CKTrhsOld+here->VDMOSbNode) -
*(ckt->CKTrhsOld+here->VDMOSsNodePrime));
vgs = model->VDMOStype * (
*(ckt->CKTrhsOld+here->VDMOSgNode) -
*(ckt->CKTrhsOld+here->VDMOSsNodePrime));
vds = model->VDMOStype * (
*(ckt->CKTrhsOld+here->VDMOSdNodePrime) -
*(ckt->CKTrhsOld+here->VDMOSsNodePrime));
vgs = model->VDMOStype * (
*(ckt->CKTrhsOld+here->VDMOSgNode) -
*(ckt->CKTrhsOld+here->VDMOSsNodePrime));
vds = model->VDMOStype * (
*(ckt->CKTrhsOld+here->VDMOSdNodePrime) -
*(ckt->CKTrhsOld+here->VDMOSsNodePrime));
/* now some common crunching for some more useful quantities */
/* now some common crunching for some more useful quantities */
vbd=vbs-vds;
vgd=vgs-vds;
vgd=vgs-vds;
/*
* bulk-source and bulk-drain diodes
* here we just evaluate the ideal diode current and the
* corresponding derivative (conductance).
*/
if(vbs <= 0) {
lgbs = SourceSatCur/vt;
lgbs += ckt->CKTgmin;
lgbs2 = lgbs3 = 0;
} else {
evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
lgbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
lgbs2 = model->VDMOStype *0.5 * (lgbs - ckt->CKTgmin)/vt;
lgbs3 = model->VDMOStype *lgbs2/(vt*3);
}
if(vbd <= 0) {
lgbd = DrainSatCur/vt;
lgbd += ckt->CKTgmin;
lgbd2 = lgbd3 = 0;
} else {
ebd = exp(MIN(MAX_EXP_ARG,vbd/vt));
lgbd = DrainSatCur*ebd/vt +ckt->CKTgmin;
lgbd2 = model->VDMOStype *0.5 * (lgbd - ckt->CKTgmin)/vt;
lgbd3 = model->VDMOStype *lgbd2/(vt*3);
}
/* now to determine whether the user was able to correctly
* identify the source and drain of his device
@ -148,13 +92,8 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
/* the following variables are local to this code block until
* it is obvious that they can be made global
*/
{
double betap;
double dvondvbs;
double d2vondvbs2;
double d3vondvbs3;
dvondvbs = d2vondvbs2 = d3vondvbs3 = 0.0;
{
double betap;
vgst=(here->VDMOSmode==1?vgs:vgd);
vdsat=MAX(vgst,0);
@ -163,73 +102,49 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
/*
* cutoff region
*/
/* cdrain = 0 */
/* cdrain = 0 */
gm=0;
gds=0;
gb=0;
gm2=gb2=gds2=0;
gmds=gbds=gmb=0;
gm3=gb3=gds3=0;
gm2ds=gmds2=gm2b=gmb2=gb2ds=gbds2=0;
} else{
gm2=gds2=0;
gmds=0;
gm3=gds3=0;
gm2ds=gmds2=0;
} else {
/*
* saturation region
*/
betap=Beta*(1+model->VDMOSlambda*(vds*here->VDMOSmode));
/* cdrain = betap * vgst * vgst * 0.5; */
/* cdrain = betap * vgst * vgst * 0.5; */
if (vgst <= (vds*here->VDMOSmode)){
gm=betap*vgst;
gds=model->VDMOSlambda*Beta*vgst*vgst*.5;
/* gb=here->VDMOSgm*arg; */
gb= -gm*dvondvbs;
gm2 = betap;
gds2 = 0;
gb2 = -(gm*d2vondvbs2 - betap*dvondvbs*dvondvbs);
gmds = vgst*model->VDMOSlambda*Beta;
gbds = - gmds*dvondvbs;
gmb = -betap*dvondvbs;
gm3 = 0;
gb3 = -(gmb*d2vondvbs2 + gm*d3vondvbs3 -
betap*2*dvondvbs*d2vondvbs2);
gds3 = 0;
gm2ds = Beta * model->VDMOSlambda;
gm2b = 0;
gmb2 = -betap*d2vondvbs2;
gb2ds = -(gmds*d2vondvbs2 - dvondvbs*dvondvbs*
Beta * model->VDMOSlambda);
gmds2 = 0;
gbds2 = 0;
gmbds = -Beta * model->VDMOSlambda*dvondvbs;
gm2 = betap;
gds2 = 0;
gmds = vgst*model->VDMOSlambda*Beta;
gm3 = 0;
gds3 = 0;
gm2ds = Beta * model->VDMOSlambda;
gmds2 = 0;
} else {
/*
* linear region
*/
/* cdrain = betap * vds * (vgst - vds/2); */
/*
* linear region
*/
/* cdrain = betap * vds * (vgst - vds/2); */
gm=betap*(vds*here->VDMOSmode);
gds= Beta * model->VDMOSlambda*(vgst*
vds*here->VDMOSmode - vds*vds*0.5) +
betap*(vgst - vds*here->VDMOSmode);
/* gb=gm*arg; */
gb = - gm*dvondvbs;
gm2 = 0;
gb2 = -(gm*d2vondvbs2);
gds2 = 2*Beta * model->VDMOSlambda*(vgst -
vds*here->VDMOSmode) - betap;
gmds = Beta * model->VDMOSlambda* vds *
here->VDMOSmode + betap;
gbds = - gmds*dvondvbs;
gmb=0;
gm3=0;
gb3 = -gm*d3vondvbs3;
gds3 = -Beta*model->VDMOSlambda*3.;
gm2ds=gm2b=gmb2=0;
gmds2 = 2*model->VDMOSlambda*Beta;
gb2ds = -(gmds*d2vondvbs2);
gbds2 = -gmds2*dvondvbs;
gmbds = 0;
vds*here->VDMOSmode - vds*vds*0.5) +
betap*(vgst - vds*here->VDMOSmode);
gm2 = 0;
gds2 = 2*Beta * model->VDMOSlambda*(vgst -
vds*here->VDMOSmode) - betap;
gmds = Beta * model->VDMOSlambda* vds *
here->VDMOSmode + betap;
gm3=0;
gds3 = -Beta*model->VDMOSlambda*3.;
gm2ds=0;
gmds2 = 2*model->VDMOSlambda*Beta;
}
}
/*
@ -250,163 +165,111 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
* is somewhat long in an attempt to avoid log/exponential
* evaluations
*/
/*
* charge storage elements
*
*.. bulk-drain and bulk-source depletion capacitances
*/
/*
* meyer's capacitor model
*/
/*
* the meyer capacitance equations are in DEVqmeyer
* these expressions are derived from those equations.
* these expressions are incorrect; they assume just one
* controlling variable for each charge storage element
* while actually there are several; the VDMOS small
* signal ac linear model is also wrong because it
* ignores controlled capacitive elements. these can be
* corrected (as can the linear ss ac model) if the
* expressions for the charge are available
*/
{
/*
* the meyer capacitance equations are in DEVqmeyer
* these expressions are derived from those equations.
* these expressions are incorrect; they assume just one
* controlling variable for each charge storage element
* while actually there are several; the VDMOS small
* signal ac linear model is also wrong because it
* ignores controlled capacitive elements. these can be
* corrected (as can the linear ss ac model) if the
* expressions for the charge are available
*/
{
double phi;
double cox;
double vddif;
double vddif1;
double vddif2;
/* von, vgst and vdsat have already been adjusted for
possible source-drain interchange */
phi = here->VDMOStPhi;
cox = 0;/*FIXME: can we do disto without knowing the oxide thickness?*/
lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
if (vgst <= 0) {
lcapgs2 = cox/(3*phi);
} else { /* the VDMOSmodes are around because
vds has not been adjusted */
if (vdsat <= here->VDMOSmode*vds) {
lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
} else {
vddif = 2.0*vdsat-here->VDMOSmode*vds;
vddif1 = vdsat-here->VDMOSmode*vds/*-1.0e-12*/;
vddif2 = vddif*vddif;
lcapgd2 = -vdsat*here->VDMOSmode*vds*cox/(3*vddif*vddif2);
lcapgd3 = - here->VDMOSmode*vds*cox*(vddif - 6*vdsat)/(9*vddif2*vddif2);
lcapgs2 = -vddif1*here->VDMOSmode*vds*cox/(3*vddif*vddif2);
lcapgs3 = - here->VDMOSmode*vds*cox*(vddif - 6*vddif1)/(9*vddif2*vddif2);
}
}
}
double phi;
double cox;
double vddif;
double vddif1;
double vddif2;
/* von, vgst and vdsat have already been adjusted for
possible source-drain interchange */
phi = here->VDMOStPhi;
cox = 0;/*FIXME: can we do disto without knowing the oxide thickness?*/
if (vgst <= -phi) {
lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
} else if (vgst <= -phi/2) {
lcapgb2= -cox/(4*phi);
lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
} else if (vgst <= 0) {
lcapgb2= -cox/(4*phi);
lcapgb3=lcapgs3=lcapgd2=lcapgd3=0;
lcapgs2 = cox/(3*phi);
} else { /* the VDMOSmodes are around because
vds has not been adjusted */
if (vdsat <= here->VDMOSmode*vds) {
lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
} else {
vddif = 2.0*vdsat-here->VDMOSmode*vds;
vddif1 = vdsat-here->VDMOSmode*vds/*-1.0e-12*/;
vddif2 = vddif*vddif;
lcapgd2 = -vdsat*here->VDMOSmode*vds*cox/(3*vddif*vddif2);
lcapgd3 = - here->VDMOSmode*vds*cox*(vddif - 6*vdsat)/(9*vddif2*vddif2);
lcapgs2 = -vddif1*here->VDMOSmode*vds*cox/(3*vddif*vddif2);
lcapgs3 = - here->VDMOSmode*vds*cox*(vddif - 6*vddif1)/(9*vddif2*vddif2);
lcapgb2=lcapgb3=0;
}
}
}
/*
* process to get Taylor coefficients, taking into
* account type and mode.
*/
/* the b-s and b-d diodes need no processing ... */
here->capbs2 = lcapbs2;
here->capbs3 = lcapbs3;
here->capbd2 = lcapbd2;
here->capbd3 = lcapbd3;
here->gbs2 = lgbs2;
here->gbs3 = lgbs3;
here->gbd2 = lgbd2;
here->gbd3 = lgbd3;
here->capgb2 = model->VDMOStype*lcapgb2;
here->capgb3 = lcapgb3;
if (here->VDMOSmode == 1)
{
/* normal mode - no source-drain interchange */
here->cdr_x2 = gm2;
here->cdr_y2 = gds2;;
here->cdr_xy = gmds;
here->cdr_x3 = gm3;
here->cdr_y3 = gds3;
here->cdr_x2y = gm2ds;
here->cdr_xy2 = gmds2;
/* the gate caps have been divided and made into
Taylor coeffs., but not adjusted for type */
here->capgs2 = model->VDMOStype*lcapgs2;
here->capgs3 = lcapgs3;
here->capgd2 = model->VDMOStype*lcapgd2;
here->capgd3 = lcapgd3;
} else {
/*
* process to get Taylor coefficients, taking into
* account type and mode.
* inverse mode - source and drain interchanged
*/
if (here->VDMOSmode == 1)
{
/* normal mode - no source-drain interchange */
here->cdr_x2 = gm2;
here->cdr_y2 = gb2;;
here->cdr_z2 = gds2;;
here->cdr_xy = gmb;
here->cdr_yz = gbds;
here->cdr_xz = gmds;
here->cdr_x3 = gm3;
here->cdr_y3 = gb3;
here->cdr_z3 = gds3;
here->cdr_x2z = gm2ds;
here->cdr_x2y = gm2b;
here->cdr_y2z = gb2ds;
here->cdr_xy2 = gmb2;
here->cdr_xz2 = gmds2;
here->cdr_yz2 = gbds2;
here->cdr_xyz = gmbds;
/* the gate caps have been divided and made into
Taylor coeffs., but not adjusted for type */
here->capgs2 = model->VDMOStype*lcapgs2;
here->capgs3 = lcapgs3;
here->capgd2 = model->VDMOStype*lcapgd2;
here->capgd3 = lcapgd3;
} else {
/*
* inverse mode - source and drain interchanged
*/
here->cdr_x2 = -gm2;
here->cdr_y2 = -gb2;
here->cdr_z2 = -(gm2 + gb2 + gds2 + 2*(gmb + gmds + gbds));
here->cdr_xy = -gmb;
here->cdr_yz = gmb + gb2 + gbds;
here->cdr_xz = gm2 + gmb + gmds;
here->cdr_x3 = -gm3;
here->cdr_y3 = -gb3;
here->cdr_z3 = gm3 + gb3 + gds3 +
3*(gm2b + gm2ds + gmb2 + gb2ds + gmds2 + gbds2) + 6*gmbds ;
here->cdr_x2z = gm3 + gm2b + gm2ds;
here->cdr_x2y = -gm2b;
here->cdr_y2z = gmb2 + gb3 + gb2ds;
here->cdr_xy2 = -gmb2;
here->cdr_xz2 = -(gm3 + 2*(gm2b + gm2ds + gmbds) +
gmb2 + gmds2);
here->cdr_yz2 = -(gb3 + 2*(gmb2 + gb2ds + gmbds) +
gm2b + gbds2);
here->cdr_xyz = gm2b + gmb2 + gmbds;
here->capgs2 = model->VDMOStype*lcapgd2;
here->capgs3 = lcapgd3;
here->capgd2 = model->VDMOStype*lcapgs2;
here->capgd3 = lcapgs3;
here->cdr_x2 = -gm2;
here->cdr_y2 = -(gm2 + gds2 + 2*(gmds));
here->cdr_xy = gm2 + gmds;
here->cdr_x3 = -gm3;
here->cdr_y3 = gm3 + gds3 +
3*(gm2ds + gmds2) ;
here->cdr_x2y = gm3 + gm2ds;
here->cdr_xy2 = -(gm3 + 2*(gm2ds) +
gmds2);
here->capgs2 = model->VDMOStype*lcapgd2;
here->capgs3 = lcapgd3;
here->capgd2 = model->VDMOStype*lcapgs2;
here->capgd3 = lcapgs3;
}
/* now to adjust for type and multiply by factors to convert to Taylor coeffs. */
here->cdr_x2 = 0.5*model->VDMOStype*here->cdr_x2;
here->cdr_y2 = 0.5*model->VDMOStype*here->cdr_y2;
here->cdr_xy = model->VDMOStype*here->cdr_xy;
here->cdr_x3 = here->cdr_x3/6.;
here->cdr_y3 = here->cdr_y3/6.;
here->cdr_x2y = 0.5*here->cdr_x2y;
here->cdr_xy2 = 0.5*here->cdr_xy2;
}
/* now to adjust for type and multiply by factors to convert to Taylor coeffs. */
here->cdr_x2 = 0.5*model->VDMOStype*here->cdr_x2;
here->cdr_y2 = 0.5*model->VDMOStype*here->cdr_y2;
here->cdr_z2 = 0.5*model->VDMOStype*here->cdr_z2;
here->cdr_xy = model->VDMOStype*here->cdr_xy;
here->cdr_yz = model->VDMOStype*here->cdr_yz;
here->cdr_xz = model->VDMOStype*here->cdr_xz;
here->cdr_x3 = here->cdr_x3/6.;
here->cdr_y3 = here->cdr_y3/6.;
here->cdr_z3 = here->cdr_z3/6.;
here->cdr_x2z = 0.5*here->cdr_x2z;
here->cdr_x2y = 0.5*here->cdr_x2y;
here->cdr_y2z = 0.5*here->cdr_y2z;
here->cdr_xy2 = 0.5*here->cdr_xy2;
here->cdr_xz2 = 0.5*here->cdr_xz2;
here->cdr_yz2 = 0.5*here->cdr_yz2;
}
}
return(OK);
}
return(OK);
}

5
src/spicelib/devices/vdmos/vdmosic.c

@ -25,11 +25,6 @@ VDMOSgetic(GENmodel *inModel, CKTcircuit *ckt)
for( ; model ; model = VDMOSnextModel(model)) {
for(here = VDMOSinstances(model); here ; here = VDMOSnextInstance(here)) {
if(!here->VDMOSicVBSGiven) {
here->VDMOSicVBS =
*(ckt->CKTrhs + here->VDMOSbNode) -
*(ckt->CKTrhs + here->VDMOSsNode);
}
if(!here->VDMOSicVDSGiven) {
here->VDMOSicVDS =
*(ckt->CKTrhs + here->VDMOSdNode) -

162
src/spicelib/devices/vdmos/vdmosload.c

@ -32,32 +32,21 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
double DrainSatCur;
double SourceSatCur;
double arg;
double cbhat;
double cdhat;
double cdrain;
double cdreq;
double ceq;
double ceqbd;
double ceqbs;
double ceqgb;
double ceqgd;
double ceqgs;
double delvbd;
double delvbs;
double delvds;
double delvgd;
double delvgs;
double gcgb;
double gcgd;
double gcgs;
double geq;
double sarg;
double vbd;
double vbs;
double vds;
double vdsat;
double vgb1;
double vgb;
double vgd1;
double vgd;
double vgdo;
@ -72,13 +61,11 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
int xrev;
double capgs = 0.0; /* total gate-source capacitance */
double capgd = 0.0; /* total gate-drain capacitance */
double capgb = 0.0; /* total gate-bulk capacitance */
int Check;
#ifndef NOBYPASS
double tempv;
#endif /*NOBYPASS*/
int error;
double CGBdummy;
/* loop through all the VDMOS device models */
for (; model != NULL; model = VDMOSnextModel(model)) {
/* VDMOS capacitance parameters */
@ -123,10 +110,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
/* predictor step */
xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1];
*(ckt->CKTstate0 + here->VDMOSvbs) =
*(ckt->CKTstate1 + here->VDMOSvbs);
vbs = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSvbs))
- (xfact * (*(ckt->CKTstate2 + here->VDMOSvbs)));
*(ckt->CKTstate0 + here->VDMOSvgs) =
*(ckt->CKTstate1 + here->VDMOSvgs);
vgs = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSvgs))
@ -135,17 +118,11 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate1 + here->VDMOSvds);
vds = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSvds))
- (xfact * (*(ckt->CKTstate2 + here->VDMOSvds)));
*(ckt->CKTstate0 + here->VDMOSvbd) =
*(ckt->CKTstate0 + here->VDMOSvbs) -
*(ckt->CKTstate0 + here->VDMOSvds);
} else {
#endif /* PREDICTOR */
/* general iteration */
vbs = model->VDMOStype * (
*(ckt->CKTrhsOld + here->VDMOSbNode) -
*(ckt->CKTrhsOld + here->VDMOSsNodePrime));
vgs = model->VDMOStype * (
*(ckt->CKTrhsOld + here->VDMOSgNodePrime) -
*(ckt->CKTrhsOld + here->VDMOSsNodePrime));
@ -158,13 +135,9 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
/* now some common crunching for some more useful quantities */
vbs = 0;
vbd = vbs - vds;
vgd = vgs - vds;
vgdo = *(ckt->CKTstate0 + here->VDMOSvgs) -
*(ckt->CKTstate0 + here->VDMOSvds);
delvbs = vbs - *(ckt->CKTstate0 + here->VDMOSvbs);
delvbd = vbd - *(ckt->CKTstate0 + here->VDMOSvbd);
delvgs = vgs - *(ckt->CKTstate0 + here->VDMOSvgs);
delvds = vds - *(ckt->CKTstate0 + here->VDMOSvds);
delvgd = vgd - vgdo;
@ -174,45 +147,20 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
if (here->VDMOSmode >= 0) {
cdhat =
here->VDMOScd -
here->VDMOSgbd * delvbd +
here->VDMOSgmbs * delvbs +
here->VDMOSgm * delvgs +
here->VDMOSgds * delvds;
} else {
cdhat =
here->VDMOScd -
(here->VDMOSgbd -
here->VDMOSgmbs) * delvbd -
here->VDMOSgm * delvgd +
here->VDMOSgds * delvds;
}
cbhat =
here->VDMOScbs +
here->VDMOScbd +
here->VDMOSgbd * delvbd +
here->VDMOSgbs * delvbs;
#ifndef NOBYPASS
/* now lets see if we can bypass (ugh) */
tempv = (MAX(fabs(cbhat),
fabs(here->VDMOScbs + here->VDMOScbd)) +
ckt->CKTabstol);
if ((!(ckt->CKTmode &
(MODEINITPRED | MODEINITTRAN | MODEINITSMSIG))) &&
(ckt->CKTbypass) &&
(fabs(cbhat - (here->VDMOScbs +
here->VDMOScbd)) < ckt->CKTreltol * tempv) &&
(fabs(delvbs) < (ckt->CKTreltol *
MAX(fabs(vbs),
fabs(*(ckt->CKTstate0 +
here->VDMOSvbs))) +
ckt->CKTvoltTol)) &&
(fabs(delvbd) < (ckt->CKTreltol *
MAX(fabs(vbd),
fabs(*(ckt->CKTstate0 +
here->VDMOSvbd))) +
ckt->CKTvoltTol)) &&
(fabs(delvgs) < (ckt->CKTreltol *
MAX(fabs(vgs),
fabs(*(ckt->CKTstate0 +
@ -233,20 +181,15 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
* copy all the values computed last iteration out
* and keep going
*/
vbs = *(ckt->CKTstate0 + here->VDMOSvbs);
vbd = *(ckt->CKTstate0 + here->VDMOSvbd);
vgs = *(ckt->CKTstate0 + here->VDMOSvgs);
vds = *(ckt->CKTstate0 + here->VDMOSvds);
vgd = vgs - vds;
vgb = vgs - vbs;
cdrain = here->VDMOSmode * (here->VDMOScd + here->VDMOScbd);
cdrain = here->VDMOSmode * (here->VDMOScd);
if (ckt->CKTmode & (MODETRAN | MODETRANOP)) {
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
*(ckt->CKTstate1 + here->VDMOScapgs));
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
*(ckt->CKTstate1 + here->VDMOScapgd));
capgb = (*(ckt->CKTstate0 + here->VDMOScapgb) +
*(ckt->CKTstate1 + here->VDMOScapgb));
}
goto bypass;
@ -281,15 +224,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
}
vgs = vgd + vds;
}
if (vds >= 0) {
vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->VDMOSvbs),
vt, here->VDMOSsourceVcrit, &Check);
vbd = vbs - vds;
} else {
vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->VDMOSvbd),
vt, here->VDMOSdrainVcrit, &Check);
vbs = vbd + vds;
}
#endif /*NODELIMITING*/
@ -303,17 +237,15 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
if ((ckt->CKTmode & MODEINITJCT) && !here->VDMOSoff) {
vds = model->VDMOStype * here->VDMOSicVDS;
vgs = model->VDMOStype * here->VDMOSicVGS;
vbs = model->VDMOStype * here->VDMOSicVBS;
if ((vds == 0) && (vgs == 0) && (vbs == 0) &&
if ((vds == 0) && (vgs == 0) &&
((ckt->CKTmode &
(MODETRAN | MODEDCOP | MODEDCTRANCURVE)) ||
(!(ckt->CKTmode & MODEUIC)))) {
vbs = 0;
vgs = model->VDMOStype * here->VDMOStVto;
vds = 0;
}
} else {
vbs = vgs = vds = 0;
vgs = vds = 0;
}
}
@ -322,20 +254,9 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
* now all the preliminaries are over - we can start doing the
* real work
*/
vbd = vbs - vds;
vgd = vgs - vds;
vgb = vgs - vbs;
/*
* bulk-source and bulk-drain diodes are not available in vdmos
*/
here->VDMOSgbs = 0;
here->VDMOScbs = 0;
here->VDMOSgbd = 0;
here->VDMOScbd = 0;
/* now to determine whether the user was able to correctly
* identify the source and drain of his device
*/
@ -387,7 +308,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
cdrm = cweakinv(model->VDMOSksubthres, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
here->VDMOSgmbs = 0.;
}
else if (model->VDMOSsubslGiven && (here->VDMOSmode == 1)) {
double delta = 0.001;
@ -409,7 +329,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
cdrm = cweakinv2(model->VDMOSsubsl, model->VDMOSsubshift, vgst1, vds, model->VDMOSlambda,
Beta, vt, model->VDMOSmtr);
here->VDMOSgm = (cdrp - cdrm) / (2. * delta);
here->VDMOSgmbs = 0.;
} else {
if (vgst <= 0) {
/*
@ -418,7 +337,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
cdrain = 0;
here->VDMOSgm = 0;
here->VDMOSgds = 0;
here->VDMOSgmbs = 0;
} else {
/*
* saturation region
@ -430,7 +348,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
cdrain = betap*vgst*vgst*.5;
here->VDMOSgm = betap*vgst;
here->VDMOSgds = model->VDMOSlambda*Beta*vgst*vgst*.5;
here->VDMOSgmbs = 0.;
} else {
/*
* linear region
@ -442,7 +359,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
model->VDMOSlambda * Beta *
(vds * here->VDMOSmode) * mtr *
(vgst - .5 * (vds * here->VDMOSmode) * mtr);
here->VDMOSgmbs = 0.;
}
}
}
@ -457,24 +373,10 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
/*
* COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
*/
here->VDMOScd = here->VDMOSmode * cdrain - here->VDMOScbd;
if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) {
/*
* capacitance evaluation for drain-source is done with the bulk diode
*/
*(ckt->CKTstate0 + here->VDMOSqbs) = 0;
here->VDMOScapbs = 0;
*(ckt->CKTstate0 + here->VDMOSqbd) = 0;
here->VDMOScapbd = 0;
}
here->VDMOScd = here->VDMOSmode * cdrain;
/* save things away for next time */
*(ckt->CKTstate0 + here->VDMOSvbs) = vbs;
*(ckt->CKTstate0 + here->VDMOSvbd) = vbd;
*(ckt->CKTstate0 + here->VDMOSvgs) = vgs;
*(ckt->CKTstate0 + here->VDMOSvds) = vds;
@ -497,22 +399,18 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs,
(ckt->CKTstate0 + here->VDMOScapgs),
(ckt->CKTstate0 + here->VDMOScapgd),
(ckt->CKTstate0 + here->VDMOScapgb));
&CGBdummy);
vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs);
vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds);
vgb1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvbs);
if (ckt->CKTmode & (MODETRANOP | MODEINITSMSIG)) {
capgs = 2 * *(ckt->CKTstate0 + here->VDMOScapgs);
capgd = 2 * *(ckt->CKTstate0 + here->VDMOScapgd);
capgb = 2 * *(ckt->CKTstate0 + here->VDMOScapgb);
} else {
capgs = (*(ckt->CKTstate0 + here->VDMOScapgs) +
*(ckt->CKTstate1 + here->VDMOScapgs));
capgd = (*(ckt->CKTstate0 + here->VDMOScapgd) +
*(ckt->CKTstate1 + here->VDMOScapgd));
capgb = (*(ckt->CKTstate0 + here->VDMOScapgb) +
*(ckt->CKTstate1 + here->VDMOScapgb));
}
/*
@ -526,9 +424,6 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate0 + here->VDMOSqgd) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgd)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) =
(1 + xfact) * *(ckt->CKTstate1 + here->VDMOSqgb)
- xfact * *(ckt->CKTstate2 + here->VDMOSqgb);
} else {
#endif /*PREDICTOR*/
if (ckt->CKTmode & MODETRAN) {
@ -536,13 +431,10 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate1 + here->VDMOSqgs);
*(ckt->CKTstate0 + here->VDMOSqgd) = (vgd - vgd1)*capgd +
*(ckt->CKTstate1 + here->VDMOSqgd);
*(ckt->CKTstate0 + here->VDMOSqgb) = (vgb - vgb1)*capgb +
*(ckt->CKTstate1 + here->VDMOSqgb);
} else {
/* TRANOP only */
*(ckt->CKTstate0 + here->VDMOSqgs) = vgs*capgs;
*(ckt->CKTstate0 + here->VDMOSqgd) = vgd*capgd;
*(ckt->CKTstate0 + here->VDMOSqgb) = vgb*capgb;
}
#ifndef PREDICTOR
}
@ -562,12 +454,9 @@ bypass :
ceqgs = 0;
gcgd = 0;
ceqgd = 0;
gcgb = 0;
ceqgb = 0;
} else {
if (capgs == 0) *(ckt->CKTstate0 + here->VDMOScqgs) = 0;
if (capgd == 0) *(ckt->CKTstate0 + here->VDMOScqgd) = 0;
if (capgb == 0) *(ckt->CKTstate0 + here->VDMOScqgb) = 0;
/*
* calculate equivalent conductances and currents for
* meyer"s capacitors
@ -576,42 +465,32 @@ bypass :
if (error) return(error);
error = NIintegrate(ckt, &gcgd, &ceqgd, capgd, here->VDMOSqgd);
if (error) return(error);
error = NIintegrate(ckt, &gcgb, &ceqgb, capgb, here->VDMOSqgb);
if (error) return(error);
ceqgs = ceqgs - gcgs*vgs + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgs);
ceqgd = ceqgd - gcgd*vgd + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgd);
ceqgb = ceqgb - gcgb*vgb + ckt->CKTag[0] *
*(ckt->CKTstate0 + here->VDMOSqgb);
}
/*
* load current vector
*/
ceqbs = model->VDMOStype *
(here->VDMOScbs - (here->VDMOSgbs)*vbs);
ceqbd = model->VDMOStype *
(here->VDMOScbd - (here->VDMOSgbd)*vbd);
if (here->VDMOSmode >= 0) {
xnrm = 1;
xrev = 0;
cdreq = model->VDMOStype*(cdrain - here->VDMOSgds*vds -
here->VDMOSgm*vgs - here->VDMOSgmbs*vbs);
here->VDMOSgm*vgs);
} else {
xnrm = 0;
xrev = 1;
cdreq = -(model->VDMOStype)*(cdrain - here->VDMOSgds*(-vds) -
here->VDMOSgm*vgd - here->VDMOSgmbs*vbd);
here->VDMOSgm*vgd);
}
*(ckt->CKTrhs + here->VDMOSgNodePrime) -=
(model->VDMOStype * (ceqgs + ceqgb + ceqgd));
*(ckt->CKTrhs + here->VDMOSbNode) -=
(ceqbs + ceqbd - model->VDMOStype * ceqgb);
(model->VDMOStype * (ceqgs + ceqgd));
*(ckt->CKTrhs + here->VDMOSdNodePrime) +=
(ceqbd - cdreq + model->VDMOStype * ceqgd);
(- cdreq + model->VDMOStype * ceqgd);
*(ckt->CKTrhs + here->VDMOSsNodePrime) +=
cdreq + ceqbs + model->VDMOStype * ceqgs;
cdreq + model->VDMOStype * ceqgs;
/* quasi saturation
@ -636,35 +515,28 @@ bypass :
*(here->VDMOSDdPtr) += (here->VDMOSdrainConductance + here->VDMOSdsConductance);
*(here->VDMOSGgPtr) += (here->VDMOSgateConductance); //((gcgd + gcgs + gcgb));
*(here->VDMOSSsPtr) += (here->VDMOSsourceConductance + here->VDMOSdsConductance);
*(here->VDMOSBbPtr) += (here->VDMOSgbd + here->VDMOSgbs + gcgb);
*(here->VDMOSDPdpPtr) +=
(here->VDMOSdrainConductance + here->VDMOSgds +
here->VDMOSgbd + xrev*(here->VDMOSgm + here->VDMOSgmbs) + gcgd);
xrev*(here->VDMOSgm) + gcgd);
*(here->VDMOSSPspPtr) +=
(here->VDMOSsourceConductance + here->VDMOSgds +
here->VDMOSgbs + xnrm*(here->VDMOSgm + here->VDMOSgmbs) + gcgs);
xnrm*(here->VDMOSgm) + gcgs);
*(here->VDMOSGPgpPtr) +=
(here->VDMOSgateConductance) + (gcgd + gcgs + gcgb);
(here->VDMOSgateConductance) + (gcgd + gcgs);
*(here->VDMOSGgpPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSDdpPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSGPgPtr) += (-here->VDMOSgateConductance);
*(here->VDMOSGPbPtr) -= gcgb;
*(here->VDMOSGPdpPtr) -= gcgd;
*(here->VDMOSGPspPtr) -= gcgs;
*(here->VDMOSSspPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSBgpPtr) -= gcgb;
*(here->VDMOSBdpPtr) -= here->VDMOSgbd;
*(here->VDMOSBspPtr) -= here->VDMOSgbs;
*(here->VDMOSDPdPtr) += (-here->VDMOSdrainConductance);
*(here->VDMOSDPgpPtr) += ((xnrm - xrev)*here->VDMOSgm - gcgd);
*(here->VDMOSDPbPtr) += (-here->VDMOSgbd + (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSDPspPtr) += (-here->VDMOSgds - xnrm*
(here->VDMOSgm + here->VDMOSgmbs));
(here->VDMOSgm));
*(here->VDMOSSPgpPtr) += (-(xnrm - xrev)*here->VDMOSgm - gcgs);
*(here->VDMOSSPsPtr) += (-here->VDMOSsourceConductance);
*(here->VDMOSSPbPtr) += (-here->VDMOSgbs - (xnrm - xrev)*here->VDMOSgmbs);
*(here->VDMOSSPdpPtr) += (-here->VDMOSgds - xrev*
(here->VDMOSgm + here->VDMOSgmbs));
(here->VDMOSgm));
*(here->VDMOSDsPtr) += (-here->VDMOSdsConductance);
*(here->VDMOSSdPtr) += (-here->VDMOSdsConductance);

7
src/spicelib/devices/vdmos/vdmospar.c

@ -52,10 +52,6 @@ VDMOSparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
case VDMOS_OFF:
here->VDMOSoff = (value->iValue != 0);
break;
case VDMOS_IC_VBS:
here->VDMOSicVBS = value->rValue;
here->VDMOSicVBSGiven = TRUE;
break;
case VDMOS_IC_VDS:
here->VDMOSicVDS = value->rValue;
here->VDMOSicVDSGiven = TRUE;
@ -66,9 +62,6 @@ VDMOSparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
break;
case VDMOS_IC:
switch(value->v.numValue){
case 3:
here->VDMOSicVBS = *(value->v.vec.rVec+2);
here->VDMOSicVBSGiven = TRUE;
case 2:
here->VDMOSicVGS = *(value->v.vec.rVec+1);
here->VDMOSicVGSGiven = TRUE;

55
src/spicelib/devices/vdmos/vdmospzld.c

@ -23,12 +23,8 @@ VDMOSpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
int xrev;
double xgs;
double xgd;
double xgb;
double xbd;
double xbs;
double capgs;
double capgd;
double capgb;
for( ; model != NULL; model = VDMOSnextModel(model)) {
for(here = VDMOSinstances(model); here!= NULL;
@ -46,69 +42,46 @@ VDMOSpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s)
*/
capgs = ( 2* *(ckt->CKTstate0+here->VDMOScapgs));
capgd = ( 2* *(ckt->CKTstate0+here->VDMOScapgd));
capgb = ( 2* *(ckt->CKTstate0+here->VDMOScapgb));
xgs = capgs;
xgd = capgd;
xgb = capgb;
xbd = here->VDMOScapbd;
xbs = here->VDMOScapbs;
/*printf("vdmos: xgs=%g, xgd=%g, xgb=%g, xbd=%g, xbs=%g\n",
xgs,xgd,xgb,xbd,xbs);*/
/*printf("vdmos: xgs=%g, xgd=%g\n",
xgs,xgd);*/
/*
* load matrix
*/
*(here->VDMOSGgPtr ) += (xgd+xgs+xgb)*s->real;
*(here->VDMOSGgPtr +1) += (xgd+xgs+xgb)*s->imag;
*(here->VDMOSBbPtr ) += (xgb+xbd+xbs)*s->real;
*(here->VDMOSBbPtr +1) += (xgb+xbd+xbs)*s->imag;
*(here->VDMOSDPdpPtr ) += (xgd+xbd)*s->real;
*(here->VDMOSDPdpPtr +1) += (xgd+xbd)*s->imag;
*(here->VDMOSSPspPtr ) += (xgs+xbs)*s->real;
*(here->VDMOSSPspPtr +1) += (xgs+xbs)*s->imag;
*(here->VDMOSGbPtr ) -= xgb*s->real;
*(here->VDMOSGbPtr +1) -= xgb*s->imag;
*(here->VDMOSGgPtr ) += (xgd+xgs)*s->real;
*(here->VDMOSGgPtr +1) += (xgd+xgs)*s->imag;
*(here->VDMOSDPdpPtr ) += (xgd)*s->real;
*(here->VDMOSDPdpPtr +1) += (xgd)*s->imag;
*(here->VDMOSSPspPtr ) += (xgs)*s->real;
*(here->VDMOSSPspPtr +1) += (xgs)*s->imag;
*(here->VDMOSGdpPtr ) -= xgd*s->real;
*(here->VDMOSGdpPtr +1) -= xgd*s->imag;
*(here->VDMOSGspPtr ) -= xgs*s->real;
*(here->VDMOSGspPtr +1) -= xgs*s->imag;
*(here->VDMOSBgPtr ) -= xgb*s->real;
*(here->VDMOSBgPtr +1) -= xgb*s->imag;
*(here->VDMOSBdpPtr ) -= xbd*s->real;
*(here->VDMOSBdpPtr +1) -= xbd*s->imag;
*(here->VDMOSBspPtr ) -= xbs*s->real;
*(here->VDMOSBspPtr +1) -= xbs*s->imag;
*(here->VDMOSDPgPtr ) -= xgd*s->real;
*(here->VDMOSDPgPtr +1) -= xgd*s->imag;
*(here->VDMOSDPbPtr ) -= xbd*s->real;
*(here->VDMOSDPbPtr +1) -= xbd*s->imag;
*(here->VDMOSSPgPtr ) -= xgs*s->real;
*(here->VDMOSSPgPtr +1) -= xgs*s->imag;
*(here->VDMOSSPbPtr ) -= xbs*s->real;
*(here->VDMOSSPbPtr +1) -= xbs*s->imag;
*(here->VDMOSDdPtr) += here->VDMOSdrainConductance;
*(here->VDMOSSsPtr) += here->VDMOSsourceConductance;
*(here->VDMOSBbPtr) += here->VDMOSgbd+here->VDMOSgbs;
*(here->VDMOSDPdpPtr) += here->VDMOSdrainConductance+
here->VDMOSgds+here->VDMOSgbd+
xrev*(here->VDMOSgm+here->VDMOSgmbs);
here->VDMOSgds+
xrev*(here->VDMOSgm);
*(here->VDMOSSPspPtr) += here->VDMOSsourceConductance+
here->VDMOSgds+here->VDMOSgbs+
xnrm*(here->VDMOSgm+here->VDMOSgmbs);
here->VDMOSgds+
xnrm*(here->VDMOSgm);
*(here->VDMOSDdpPtr) -= here->VDMOSdrainConductance;
*(here->VDMOSSspPtr) -= here->VDMOSsourceConductance;
*(here->VDMOSBdpPtr) -= here->VDMOSgbd;
*(here->VDMOSBspPtr) -= here->VDMOSgbs;
*(here->VDMOSDPdPtr) -= here->VDMOSdrainConductance;
*(here->VDMOSDPgPtr) += (xnrm-xrev)*here->VDMOSgm;
*(here->VDMOSDPbPtr) += -here->VDMOSgbd+(xnrm-xrev)*here->VDMOSgmbs;
*(here->VDMOSDPspPtr) -= here->VDMOSgds+
xnrm*(here->VDMOSgm+here->VDMOSgmbs);
xnrm*(here->VDMOSgm);
*(here->VDMOSSPgPtr) -= (xnrm-xrev)*here->VDMOSgm;
*(here->VDMOSSPsPtr) -= here->VDMOSsourceConductance;
*(here->VDMOSSPbPtr) -= here->VDMOSgbs+(xnrm-xrev)*here->VDMOSgmbs;
*(here->VDMOSSPdpPtr) -= here->VDMOSgds+
xrev*(here->VDMOSgm+here->VDMOSgmbs);
xrev*(here->VDMOSgm);
}
}

44
src/spicelib/devices/vdmos/vdmosset.c

@ -110,23 +110,10 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
for (here = VDMOSinstances(model); here != NULL;
here = VDMOSnextInstance(here)) {
/* Check if source and bulk nodes are the same.
* The power MOS devices in fact are 3-terminal devices,
* but the actual device input still uses 4 terminals to be compatible.
*/
if (here->VDMOSbNode != here->VDMOSsNode) {
fprintf(stderr, "\nError: source and bulk nodes of device %s have to be the same!\n",
here->VDMOSname);
controlled_exit(1);
}
/* allocate a chunk of the state vector */
here->VDMOSstates = *states;
*states += VDMOSnumStates;
if (!here->VDMOSicVBSGiven) {
here->VDMOSicVBS = 0;
}
if (!here->VDMOSicVDSGiven) {
here->VDMOSicVDS = 0;
}
@ -239,53 +226,22 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
return(E_NOMEM);\
} } while(0)
/*
TSTALLOC(VDMOSDdPtr, VDMOSdNode, VDMOSdNode);
TSTALLOC(VDMOSGgPtr, VDMOSgNode, VDMOSgNode);
TSTALLOC(VDMOSSsPtr, VDMOSsNode, VDMOSsNode);
TSTALLOC(VDMOSBbPtr, VDMOSbNode, VDMOSbNode);
TSTALLOC(VDMOSDPdpPtr, VDMOSdNodePrime, VDMOSdNodePrime);
TSTALLOC(VDMOSSPspPtr, VDMOSsNodePrime, VDMOSsNodePrime);
TSTALLOC(VDMOSDdpPtr, VDMOSdNode, VDMOSdNodePrime);
TSTALLOC(VDMOSGbPtr, VDMOSgNode, VDMOSbNode);
TSTALLOC(VDMOSGdpPtr, VDMOSgNode, VDMOSdNodePrime);
TSTALLOC(VDMOSGspPtr, VDMOSgNode, VDMOSsNodePrime);
TSTALLOC(VDMOSSspPtr, VDMOSsNode, VDMOSsNodePrime);
TSTALLOC(VDMOSBdpPtr, VDMOSbNode, VDMOSdNodePrime);
TSTALLOC(VDMOSBspPtr, VDMOSbNode, VDMOSsNodePrime);
TSTALLOC(VDMOSDPspPtr, VDMOSdNodePrime, VDMOSsNodePrime);
TSTALLOC(VDMOSDPdPtr, VDMOSdNodePrime, VDMOSdNode);
TSTALLOC(VDMOSBgPtr, VDMOSbNode, VDMOSgNode);
TSTALLOC(VDMOSDPgPtr, VDMOSdNodePrime, VDMOSgNode);
TSTALLOC(VDMOSSPgPtr, VDMOSsNodePrime, VDMOSgNode);
TSTALLOC(VDMOSSPsPtr, VDMOSsNodePrime, VDMOSsNode);
TSTALLOC(VDMOSDPbPtr, VDMOSdNodePrime, VDMOSbNode);
TSTALLOC(VDMOSSPbPtr, VDMOSsNodePrime, VDMOSbNode);
TSTALLOC(VDMOSSPdpPtr, VDMOSsNodePrime, VDMOSdNodePrime);
*/
TSTALLOC(VDMOSDdPtr, VDMOSdNode, VDMOSdNode);
TSTALLOC(VDMOSGgPtr, VDMOSgNode, VDMOSgNode);
TSTALLOC(VDMOSSsPtr, VDMOSsNode, VDMOSsNode);
TSTALLOC(VDMOSBbPtr, VDMOSbNode, VDMOSbNode);
TSTALLOC(VDMOSDPdpPtr, VDMOSdNodePrime, VDMOSdNodePrime);
TSTALLOC(VDMOSSPspPtr, VDMOSsNodePrime, VDMOSsNodePrime);
TSTALLOC(VDMOSGPgpPtr, VDMOSgNodePrime, VDMOSgNodePrime);
TSTALLOC(VDMOSDdpPtr, VDMOSdNode, VDMOSdNodePrime);
TSTALLOC(VDMOSGPbPtr, VDMOSgNodePrime, VDMOSbNode);
TSTALLOC(VDMOSGPdpPtr, VDMOSgNodePrime, VDMOSdNodePrime);
TSTALLOC(VDMOSGPspPtr, VDMOSgNodePrime, VDMOSsNodePrime);
TSTALLOC(VDMOSSspPtr, VDMOSsNode, VDMOSsNodePrime);
TSTALLOC(VDMOSBdpPtr, VDMOSbNode, VDMOSdNodePrime);
TSTALLOC(VDMOSBspPtr, VDMOSbNode, VDMOSsNodePrime);
TSTALLOC(VDMOSDPspPtr, VDMOSdNodePrime, VDMOSsNodePrime);
TSTALLOC(VDMOSDPdPtr, VDMOSdNodePrime, VDMOSdNode);
TSTALLOC(VDMOSBgpPtr, VDMOSbNode, VDMOSgNodePrime);
TSTALLOC(VDMOSDPgpPtr, VDMOSdNodePrime, VDMOSgNodePrime);
TSTALLOC(VDMOSSPgpPtr, VDMOSsNodePrime, VDMOSgNodePrime);
TSTALLOC(VDMOSSPsPtr, VDMOSsNodePrime, VDMOSsNode);
TSTALLOC(VDMOSDPbPtr, VDMOSdNodePrime, VDMOSbNode);
TSTALLOC(VDMOSSPbPtr, VDMOSsNodePrime, VDMOSbNode);
TSTALLOC(VDMOSSPdpPtr, VDMOSsNodePrime, VDMOSdNodePrime);
TSTALLOC(VDMOSGgpPtr, VDMOSgNode, VDMOSgNodePrime);

2
src/spicelib/devices/vdmos/vdmostemp.c

@ -118,12 +118,10 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
here->VDMOStPhi = fact2 * phio + pbfact;
here->VDMOStVto = model->VDMOSvt0;
here->VDMOSCbd = 0;
here->VDMOSf2d = 0;
here->VDMOSf3d = 0;
here->VDMOSf4d = 0;
here->VDMOSCbs = 0;
here->VDMOSf2s = 0;
here->VDMOSf3s = 0;
here->VDMOSf4s = 0;

1
src/spicelib/devices/vdmos/vdmostrun.c

@ -23,7 +23,6 @@ VDMOStrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
CKTterr(here->VDMOSqgs,ckt,timeStep);
CKTterr(here->VDMOSqgd,ckt,timeStep);
CKTterr(here->VDMOSqgb,ckt,timeStep);
}
}
return(OK);

7
src/spicelib/parser/inp2m.c

@ -31,6 +31,11 @@ model_numnodes(int type)
return 6;
}
if (type == INPtypelook("VDMOS")) /* 3 ; VDMOSnames */
{
return 3;
}
return 4;
}
@ -70,7 +75,7 @@ INP2M(CKTcircuit *ckt, INPtables *tab, struct card *current)
for (i = 0; ; i++) {
char *token;
INPgetNetTok(&line, &token, 1);
if (i >= 4) {
if (i >= 3) {
txfree(INPgetMod(ckt, token, &thismodel, tab));
/* check if using model binning -- pass in line since need 'l' and 'w' */

Loading…
Cancel
Save