VDMOS consider body diode thermal contribution for self-heatine effect
This commit is contained in:
parent
c86cd740d6
commit
d3da0d5ebf
|
|
@ -3,8 +3,8 @@
|
|||
vdd 1 0 5.0
|
||||
|
||||
.subckt inv out in vdd vss
|
||||
mp1 out in vdd p1 l=2u w=20u
|
||||
mn1 out in vss n1 l=2u w=10u
|
||||
mp1 out in vdd p1 m=2
|
||||
mn1 out in vss n1
|
||||
c1 out vss 0.2p
|
||||
.ends
|
||||
|
||||
|
|
@ -18,10 +18,10 @@ xinv7 9 8 1 0 inv
|
|||
xinv8 10 9 1 0 inv
|
||||
xinv9 2 10 1 0 inv
|
||||
|
||||
.model N1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n ksubthres=0.2
|
||||
.model P1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=2e-5 rb=1e7 cjo=1n pchan ksubthres=0.2
|
||||
.model N1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=1e-5 rb=1e7 cjo=1n ksubthres=0.2
|
||||
.model P1 vdmos cgdmin=0.05p cgdmax=0.2p a=1.2 cgs=0.15p rg=10 kp=1e-5 rb=1e7 cjo=1n pchan ksubthres=0.2
|
||||
|
||||
.tran 0.1n 1u
|
||||
.tran 0.1n 5u
|
||||
|
||||
.control
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
|||
|
||||
IFparm VDMOSpTable[] = { /* parameters */
|
||||
IOPU("m", VDMOS_M, IF_REAL, "Multiplier"),
|
||||
IOPU("l", VDMOS_L, IF_REAL, "Length"),
|
||||
IOPU("w", VDMOS_W, IF_REAL, "Width"),
|
||||
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"),
|
||||
|
|
|
|||
|
|
@ -41,12 +41,6 @@ VDMOSask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double vgd;
|
||||
double vgdo;
|
||||
double tol;
|
||||
double delvd,vd,cd;
|
||||
int selfheat;
|
||||
double delTemp, deldelTemp;
|
||||
|
||||
|
|
@ -77,6 +78,34 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt)
|
|||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
return(OK); /* no reason to continue, we haven't converged */
|
||||
}
|
||||
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
|
||||
vd = *(ckt->CKTrhsOld+here->VDIOposPrimeNode)-
|
||||
*(ckt->CKTrhsOld + here->VDMOSdNode);
|
||||
|
||||
delvd=vd- *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
|
||||
cdhat= *(ckt->CKTstate0 + here->VDIOcurrent) +
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) * delvd +
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) * deldelTemp;
|
||||
|
||||
cd= *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||
|
||||
/*
|
||||
* check convergence
|
||||
*/
|
||||
tol=ckt->CKTreltol*
|
||||
MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol;
|
||||
if (fabs(cdhat-cd) > tol) {
|
||||
ckt->CKTnoncon++;
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
return(OK); /* don't need to check any more device */
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ typedef struct sVDMOSinstance {
|
|||
|
||||
double VDMOSm; /* parallel device multiplier */
|
||||
|
||||
double VDMOSl; /* the length of the channel region */
|
||||
double VDMOSw; /* the width of the channel region */
|
||||
double VDMOSsourceConductance; /*conductance of source(or 0):set in setup*/
|
||||
double VDMOSdrainConductance; /*conductance of drain(or 0):set in setup*/
|
||||
double VDMOSdrainResistance; /*resistance of drain(or 0): set in temp*/
|
||||
|
|
@ -107,6 +105,7 @@ typedef struct sVDMOSinstance {
|
|||
double VDMOScdT;
|
||||
double VDMOScth; /* current alias power */
|
||||
|
||||
// double VDIOdIth_dVdio;
|
||||
/*
|
||||
* naming convention:
|
||||
* x = vgs
|
||||
|
|
@ -151,8 +150,6 @@ typedef struct sVDMOSinstance {
|
|||
unsigned VDMOStempGiven :1; /* instance temperature specified */
|
||||
unsigned VDMOSdtempGiven :1; /* instance delta temperature specified */
|
||||
unsigned VDMOSmGiven :1;
|
||||
unsigned VDMOSlGiven :1;
|
||||
unsigned VDMOSwGiven :1;
|
||||
unsigned VDMOSdNodePrimeSet :1;
|
||||
unsigned VDMOSsNodePrimeSet :1;
|
||||
unsigned VDMOSicVDSGiven :1;
|
||||
|
|
@ -163,68 +160,68 @@ typedef struct sVDMOSinstance {
|
|||
unsigned VDMOSmodeGiven :1;
|
||||
|
||||
double *VDMOSDdPtr; /* pointer to sparse matrix element at
|
||||
* (Drain node,drain node) */
|
||||
(Drain node,drain node) */
|
||||
double *VDMOSGgPtr; /* pointer to sparse matrix element at
|
||||
* (gate node,gate node) */
|
||||
(gate node,gate node) */
|
||||
double *VDMOSSsPtr; /* pointer to sparse matrix element at
|
||||
* (source node,source node) */
|
||||
(source node,source node) */
|
||||
double *VDMOSDPdpPtr; /* pointer to sparse matrix element at
|
||||
* (drain prime node,drain prime node) */
|
||||
(drain prime node,drain prime node) */
|
||||
double *VDMOSSPspPtr; /* pointer to sparse matrix element at
|
||||
* (source prime node,source prime node) */
|
||||
(source prime node,source prime node) */
|
||||
double *VDMOSDdpPtr; /* pointer to sparse matrix element at
|
||||
* (drain node,drain prime node) */
|
||||
(drain node,drain prime node) */
|
||||
double *VDMOSGdpPtr; /* pointer to sparse matrix element at
|
||||
* (gate node,drain prime node) */
|
||||
(gate node,drain prime node) */
|
||||
double *VDMOSGspPtr; /* pointer to sparse matrix element at
|
||||
* (gate node,source prime node) */
|
||||
(gate node,source prime node) */
|
||||
double *VDMOSSspPtr; /* pointer to sparse matrix element at
|
||||
* (source node,source prime node) */
|
||||
(source node,source prime node) */
|
||||
double *VDMOSDPspPtr; /* pointer to sparse matrix element at
|
||||
* (drain prime node,source prime node) */
|
||||
(drain prime node,source prime node) */
|
||||
double *VDMOSDPdPtr; /* pointer to sparse matrix element at
|
||||
* (drain prime node,drain node) */
|
||||
(drain prime node,drain node) */
|
||||
double *VDMOSDPgPtr; /* pointer to sparse matrix element at
|
||||
* (drain prime node,gate node) */
|
||||
(drain prime node,gate node) */
|
||||
|
||||
double *VDMOSSPgPtr; /* pointer to sparse matrix element at
|
||||
* (source prime node,gate node) */
|
||||
(source prime node,gate node) */
|
||||
double *VDMOSSPsPtr; /* pointer to sparse matrix element at
|
||||
* (source prime node,source node) */
|
||||
(source prime node,source node) */
|
||||
double *VDMOSSPdpPtr; /* pointer to sparse matrix element at
|
||||
* (source prime node,drain prime node) */
|
||||
(source prime node,drain prime node) */
|
||||
/* added for VDMOS */
|
||||
double *VDMOSGPgpPtr; /* pointer to sparse matrix element at
|
||||
* (gate prime node, gate prime node) */
|
||||
(gate prime node, gate prime node) */
|
||||
double *VDMOSGPdpPtr; /* pointer to sparse matrix element at
|
||||
* (gate prime node, drain prime node) */
|
||||
(gate prime node, drain prime node) */
|
||||
double *VDMOSGPspPtr; /* pointer to sparse matrix element at
|
||||
* (gate prime node, source prime node) */
|
||||
(gate prime node, source prime node) */
|
||||
double *VDMOSDPgpPtr; /* pointer to sparse matrix element at
|
||||
* (drain prime node, gate prime node) */
|
||||
(drain prime node, gate prime node) */
|
||||
double *VDMOSSPgpPtr; /* pointer to sparse matrix element at
|
||||
* (source prime node, gate prime node) */
|
||||
(source prime node, gate prime node) */
|
||||
double *VDMOSGgpPtr; /* pointer to sparse matrix element at
|
||||
* (gate node, gate prime node) */
|
||||
(gate node, gate prime node) */
|
||||
double *VDMOSGPgPtr; /* pointer to sparse matrix element at
|
||||
* (gate prime node, gate node) */
|
||||
(gate prime node, gate node) */
|
||||
double *VDMOSDsPtr; /* pointer to sparse matrix element at
|
||||
* (source node, drain node) */
|
||||
(source node, drain node) */
|
||||
double *VDMOSSdPtr; /* pointer to sparse matrix element at
|
||||
* (drain node, source node) */
|
||||
(drain node, source node) */
|
||||
/* body diode */
|
||||
double *VDIORPdPtr; /* pointer to sparse matrix element at
|
||||
* (diode prime node, drain node) */
|
||||
(diode prime node, drain node) */
|
||||
double *VDIODrpPtr; /* pointer to sparse matrix element at
|
||||
* (drain node, diode prime node) */
|
||||
(drain node, diode prime node) */
|
||||
double *VDIORPrpPtr; /* pointer to sparse matrix element at
|
||||
* (diode prime node, diode prime node) */
|
||||
(diode prime node, diode prime node) */
|
||||
double *VDIOSrpPtr; /* pointer to sparse matrix element at
|
||||
* (source node, diode prime node) */
|
||||
(source node, diode prime node) */
|
||||
double *VDIORPsPtr; /* pointer to sparse matrix element at
|
||||
* (diode prime node, source node) */
|
||||
(diode prime node, source node) */
|
||||
/* self heating */
|
||||
double *VDMOSTemptempPtr;
|
||||
double *VDMOSTemptempPtr; /* Transistor thermal contribution */
|
||||
double *VDMOSTempdpPtr;
|
||||
double *VDMOSTempspPtr;
|
||||
double *VDMOSTempgpPtr;
|
||||
|
|
@ -232,14 +229,17 @@ typedef struct sVDMOSinstance {
|
|||
double *VDMOSDPtempPtr;
|
||||
double *VDMOSSPtempPtr;
|
||||
|
||||
double *VDIOTempposPrimePtr; /* Diode thermal contribution */
|
||||
double *VDIOTempnegPtr;
|
||||
double *VDIOPosPrimetempPtr;
|
||||
double *VDIONegtempPtr;
|
||||
|
||||
double *VDMOSTcasetcasePtr; /* for Rthjc */
|
||||
double *VDMOSTcasetempPtr;
|
||||
double *VDMOSTemptcasePtr;
|
||||
|
||||
double *VDMOSTptpPtr; /* for Rthca */
|
||||
double *VDMOSTptcasePtr;
|
||||
double *VDMOSTcasetpPtr;
|
||||
|
||||
double *VDMOSCktTcktTPtr; /* for VcktTemp */
|
||||
double *VDMOSCktTtpPtr;
|
||||
double *VDMOSTpcktTPtr;
|
||||
|
|
@ -248,7 +248,7 @@ typedef struct sVDMOSinstance {
|
|||
|
||||
#define VDMOSvgs VDMOSstates+ 0 /* gate-source voltage */
|
||||
#define VDMOSvds VDMOSstates+ 1 /* drain-source voltage */
|
||||
#define VDMOSdelTemp VDMOSstates+ 2
|
||||
#define VDMOSdelTemp VDMOSstates+ 2 /* thermal voltage over rth0 */
|
||||
|
||||
#define VDMOScapgs VDMOSstates+3 /* gate-source capacitor value */
|
||||
#define VDMOSqgs VDMOSstates+ 4 /* gate-source capacitor charge */
|
||||
|
|
@ -261,14 +261,17 @@ typedef struct sVDMOSinstance {
|
|||
#define VDIOvoltage VDMOSstates+ 9
|
||||
#define VDIOcurrent VDMOSstates+ 10
|
||||
#define VDIOconduct VDMOSstates+ 11
|
||||
|
||||
#define VDIOcapCharge VDMOSstates+ 12
|
||||
#define VDIOcapCurrent VDMOSstates+ 13
|
||||
|
||||
#define VDMOScapth VDMOSstates+ 14 /* thermal capacitor value */
|
||||
#define VDMOSqth VDMOSstates+ 15 /* thermal capacitor charge */
|
||||
#define VDMOScqth VDMOSstates+ 16 /* thermal capacitor current */
|
||||
#define VDMOScapth VDMOSstates+ 14 /* thermal capacitor value */
|
||||
#define VDMOSqth VDMOSstates+ 15 /* thermal capacitor charge */
|
||||
#define VDMOScqth VDMOSstates+ 16 /* thermal capacitor current */
|
||||
|
||||
#define VDMOSnumStates 17
|
||||
#define VDIOdIdio_dT VDMOSstates+ 17
|
||||
|
||||
#define VDMOSnumStates 18
|
||||
|
||||
|
||||
/* per model data */
|
||||
|
|
@ -428,9 +431,7 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
|
||||
/* device parameters */
|
||||
enum {
|
||||
VDMOS_W = 1,
|
||||
VDMOS_L,
|
||||
VDMOS_OFF,
|
||||
VDMOS_OFF = 1,
|
||||
VDMOS_IC,
|
||||
VDMOS_IC_VDS,
|
||||
VDMOS_IC_VGS,
|
||||
|
|
|
|||
|
|
@ -53,8 +53,7 @@ VDMOSdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
Beta = here->VDMOStTransconductance;
|
||||
|
||||
OxideCap = model->VDMOSoxideCapFactor * here->VDMOSl *
|
||||
here->VDMOSm * here->VDMOSw;
|
||||
OxideCap = model->VDMOSoxideCapFactor * here->VDMOSm;
|
||||
|
||||
vgs = model->VDMOStype * (
|
||||
*(ckt->CKTrhsOld+here->VDMOSgNode) -
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
register int selfheat;
|
||||
double rd0T, rd1T, dBeta_dT, dIds_dT;
|
||||
double deldelTemp, delTemp, delTemp1, Temp, Vds, Vgs;
|
||||
double deldelTemp=0.0, delTemp, delTemp1, Temp, Vds, Vgs;
|
||||
double ceqqth=0.0;
|
||||
double GmT, gTtg, gTtdp, gTtt, gTtsp, gcTt=0.0;
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
*(ckt->CKTstate0 + here->VDMOSdelTemp) =
|
||||
*(ckt->CKTstate1 + here->VDMOSdelTemp);
|
||||
delTemp = (1 + xfact)* (*(ckt->CKTstate1 + here->VDMOSdelTemp))
|
||||
- (xfact * (*(ckt->CKTstate2 + here->VDMOSdelTemp)));
|
||||
- (xfact * (*(ckt->CKTstate2 + here->VDMOSdelTemp)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -557,10 +557,10 @@ bypass:
|
|||
*(ckt->CKTstate0 + here->VDMOSqgd);
|
||||
if (selfheat)
|
||||
{
|
||||
error = NIintegrate(ckt, &gcTt, &ceqqth, 0.0, here->VDMOSqth);
|
||||
error = NIintegrate(ckt, &gcTt, &ceqqth, capth, here->VDMOSqth);
|
||||
if (error) return(error);
|
||||
gcTt = model->VDMOScthj * ckt->CKTag[0];
|
||||
ceqqth = *(ckt->CKTstate0 + here->VDMOScqth) - gcTt * delTemp;
|
||||
ceqqth = ceqqth - gcTt*delTemp + ckt->CKTag[0] *
|
||||
*(ckt->CKTstate0 + here->VDMOSqth);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -608,8 +608,11 @@ bypass:
|
|||
if (selfheat) {
|
||||
*(ckt->CKTrhs + here->VDMOSdNodePrime) += GmT * delTemp;
|
||||
*(ckt->CKTrhs + here->VDMOSsNodePrime) += -GmT * delTemp;
|
||||
*(ckt->CKTrhs + here->VDMOStempNode) -= here->VDMOScth + ceqqth; /* MOS dissipated power + Cthj current */
|
||||
*(ckt->CKTrhs + here->VDMOSvcktTbranch) = ckt->CKTtemp-CONSTCtoK; /* ckt temperature */
|
||||
*(ckt->CKTrhs + here->VDMOStempNode) -= here->VDMOScth + ceqqth; /* MOS dissipated power + Cthj current */
|
||||
double vCktTemp = (ckt->CKTtemp-CONSTCtoK); /* ckt temperature */
|
||||
if (ckt->CKTmode & MODETRANOP)
|
||||
vCktTemp *= ckt->CKTsrcFact;
|
||||
*(ckt->CKTrhs + here->VDMOSvcktTbranch)+= vCktTemp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -646,7 +649,7 @@ bypass:
|
|||
|
||||
if (selfheat)
|
||||
{
|
||||
(*(here->VDMOSDPtempPtr) += GmT);
|
||||
(*(here->VDMOSDPtempPtr) += GmT);
|
||||
(*(here->VDMOSSPtempPtr) += -GmT);
|
||||
(*(here->VDMOSGPtempPtr) += 0.0);
|
||||
(*(here->VDMOSTemptempPtr) += gTtt + 1/model->VDMOSrthjc + gcTt);
|
||||
|
|
@ -667,15 +670,17 @@ bypass:
|
|||
* Delivers reverse conduction and forward breakdown
|
||||
* of VDMOS transistor
|
||||
*/
|
||||
|
||||
double vd; /* current diode voltage */
|
||||
double vd, cd;
|
||||
double vte;
|
||||
double vtebrk, vbrknp;
|
||||
double cd, cdb, csat, cdeq;
|
||||
double cdb, csat, cdeq;
|
||||
double capd;
|
||||
double gd, gdb, gspr;
|
||||
double delvd; /* change in diode voltage temporary */
|
||||
double evrev;
|
||||
double Ith=0.0, dIth_dT=0.0;
|
||||
double dIdio_dT=0.0, dIth_dVdio=0.0;
|
||||
double arg1, darg1_dT, arg2, darg2_dT, csat_dT;
|
||||
#ifndef NOBYPASS
|
||||
double tol; /* temporary for tolerance calculations */
|
||||
#endif
|
||||
|
|
@ -684,8 +689,8 @@ bypass:
|
|||
cdb = 0.0;
|
||||
gd = 0.0;
|
||||
gdb = 0.0;
|
||||
csat = here->VDIOtSatCur;
|
||||
gspr = here->VDIOtConductance;
|
||||
|
||||
vt = CONSTKoverQ * Temp;
|
||||
vte = model->VDMOSn * vt;
|
||||
vtebrk = model->VDIObrkdEmissionCoeff * vt;
|
||||
|
|
@ -711,6 +716,8 @@ bypass:
|
|||
*(ckt->CKTstate1 + here->VDIOcurrent);
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) =
|
||||
*(ckt->CKTstate1 + here->VDIOconduct);
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) =
|
||||
*(ckt->CKTstate1 + here->VDIOdIdio_dT);
|
||||
} else {
|
||||
#endif /* PREDICTOR */
|
||||
vd = model->VDMOStype * (*(ckt->CKTrhsOld + here->VDIOposPrimeNode) -
|
||||
|
|
@ -720,7 +727,8 @@ bypass:
|
|||
#endif /* PREDICTOR */
|
||||
delvd = vd - *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
cdhat = *(ckt->CKTstate0 + here->VDIOcurrent) +
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) * delvd;
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) * delvd +
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) * deldelTemp;
|
||||
/*
|
||||
* bypass if solution has not changed
|
||||
*/
|
||||
|
|
@ -734,10 +742,16 @@ bypass:
|
|||
ckt->CKTabstol;
|
||||
if (fabs(cdhat - *(ckt->CKTstate0 + here->VDIOcurrent))
|
||||
< tol) {
|
||||
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
cd = *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||
gd = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||
goto load;
|
||||
if ((here->VDMOStempNode == 0) ||
|
||||
(fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp),
|
||||
fabs(*(ckt->CKTstate0+here->VDMOSdelTemp)))+
|
||||
ckt->CKTvoltTol*1e4))) {
|
||||
vd = *(ckt->CKTstate0 + here->VDIOvoltage);
|
||||
cd = *(ckt->CKTstate0 + here->VDIOcurrent);
|
||||
gd = *(ckt->CKTstate0 + here->VDIOconduct);
|
||||
dIdio_dT= *(ckt->CKTstate0 + here->VDIOdIdio_dT);
|
||||
goto load;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -759,38 +773,53 @@ bypass:
|
|||
vte, here->VDIOtVcrit, &Check_dio);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* temperature dependent diode saturation current and derivative
|
||||
*/
|
||||
arg1 = ((Temp / model->VDMOStnom) - 1) * model->VDMOSeg / (model->VDMOSn*vt);
|
||||
darg1_dT = model->VDMOSeg / (vte*model->VDMOStnom)
|
||||
- model->VDMOSeg*(Temp/model->VDMOStnom -1)/(vte*Temp);
|
||||
|
||||
arg2 = model->VDMOSxti / model->VDMOSn * log(Temp / model->VDMOStnom);
|
||||
darg2_dT = model->VDMOSxti / model->VDMOSn / Temp;
|
||||
|
||||
csat = here->VDMOSm * model->VDIOjctSatCur * exp(arg1 + arg2);
|
||||
csat_dT = here->VDMOSm * model->VDIOjctSatCur * exp(arg1 + arg2) * (darg1_dT + darg2_dT);
|
||||
|
||||
/*
|
||||
* compute dc current and derivatives
|
||||
*/
|
||||
if (vd >= -3 * vte) { /* bottom current forward */
|
||||
if (vd >= -3 * vte) { /* forward current */
|
||||
double evd;
|
||||
|
||||
evd = exp(vd / vte);
|
||||
cdb = csat*(evd - 1);
|
||||
dIdio_dT = csat_dT * (evd - 1) - csat * vd * evd / (vte * Temp);
|
||||
gdb = csat*evd / vte;
|
||||
|
||||
} else if ((!(model->VDMOSbvGiven)) ||
|
||||
vd >= -vbrknp) { /* reverse */
|
||||
vd >= -vbrknp) { /* reverse */
|
||||
double arg3, darg3_dT;
|
||||
|
||||
arg = 3 * vte / (vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cdb = -csat*(1 + arg);
|
||||
arg3 = arg * arg * arg;
|
||||
darg3_dT = 3 * arg3 / Temp;
|
||||
cdb = -csat*(1 + arg3);
|
||||
dIdio_dT = -csat_dT * (arg3 + 1) - csat * darg3_dT;
|
||||
gdb = csat * 3 * arg / vd;
|
||||
|
||||
} else { /* breakdown */
|
||||
} else { /* breakdown */
|
||||
|
||||
evrev = exp(-(vbrknp + vd) / vtebrk);
|
||||
cdb = -csat*evrev;
|
||||
dIdio_dT = csat * (-vbrknp-vd) * evrev / vtebrk / Temp - csat_dT * evrev;
|
||||
gdb = csat*evrev / vtebrk;
|
||||
|
||||
}
|
||||
|
||||
|
||||
cd = cdb;
|
||||
gd = gdb;
|
||||
|
||||
gd = gd + ckt->CKTgmin;
|
||||
cd = cd + ckt->CKTgmin*vd;
|
||||
cd = cdb + ckt->CKTgmin*vd;
|
||||
gd = gdb + ckt->CKTgmin;
|
||||
|
||||
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) ||
|
||||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
|
||||
|
|
@ -812,7 +841,7 @@ bypass:
|
|||
}
|
||||
diffcharge = here->VDIOtTransitTime*cdb;
|
||||
*(ckt->CKTstate0 + here->VDIOcapCharge) =
|
||||
diffcharge + deplcharge;
|
||||
diffcharge + deplcharge;
|
||||
|
||||
diffcap = here->VDIOtTransitTime*gdb;
|
||||
capd = diffcap + deplcap;
|
||||
|
|
@ -855,16 +884,22 @@ bypass:
|
|||
|
||||
if ((Check_th == 1) || (Check_dio == 1)) {
|
||||
ckt->CKTnoncon++;
|
||||
ckt->CKTtroubleElt = (GENinstance *)here;
|
||||
ckt->CKTtroubleElt = (GENinstance *) here;
|
||||
}
|
||||
|
||||
*(ckt->CKTstate0 + here->VDIOvoltage) = vd;
|
||||
*(ckt->CKTstate0 + here->VDIOcurrent) = cd;
|
||||
*(ckt->CKTstate0 + here->VDIOconduct) = gd;
|
||||
*(ckt->CKTstate0 + here->VDIOdIdio_dT) = dIdio_dT;
|
||||
|
||||
#ifndef NOBYPASS
|
||||
load:
|
||||
#endif
|
||||
if (selfheat) {
|
||||
Ith = vd*cd;
|
||||
dIth_dVdio = cd + vd*gd;
|
||||
dIth_dT = dIdio_dT*vd;
|
||||
}
|
||||
/*
|
||||
* load current vector
|
||||
*/
|
||||
|
|
@ -876,7 +911,11 @@ load:
|
|||
*(ckt->CKTrhs + here->VDMOSdNode) -= cdeq;
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) += cdeq;
|
||||
}
|
||||
|
||||
if (selfheat) {
|
||||
*(ckt->CKTrhs + here->VDMOSdNode) += dIdio_dT*delTemp;
|
||||
*(ckt->CKTrhs + here->VDIOposPrimeNode) -= dIdio_dT*delTemp;
|
||||
*(ckt->CKTrhs + here->VDMOStempNode) += Ith - dIth_dVdio*vd - dIth_dT*delTemp; /* Diode dissipated power */
|
||||
}
|
||||
/*
|
||||
* load matrix
|
||||
*/
|
||||
|
|
@ -887,6 +926,13 @@ load:
|
|||
*(here->VDIODrpPtr) -= gd;
|
||||
*(here->VDIORPsPtr) -= gspr;
|
||||
*(here->VDIORPdPtr) -= gd;
|
||||
if (selfheat) {
|
||||
(*(here->VDMOSTemptempPtr) += dIth_dT);
|
||||
(*(here->VDIOTempposPrimePtr) += -dIth_dVdio);
|
||||
(*(here->VDIOTempnegPtr) += dIth_dVdio);
|
||||
(*(here->VDIOPosPrimetempPtr) += -dIdio_dT);
|
||||
(*(here->VDIONegtempPtr) += dIdio_dT);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -113,9 +113,8 @@ VDMOSnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
|
|||
noizDens[VDMOSFLNOIZ] *= model->VDMOSfNcoef *
|
||||
exp(model->VDMOSfNexp *
|
||||
log(MAX(fabs(inst->VDMOScd),N_MINLOG))) /
|
||||
(data->freq * inst->VDMOSw *
|
||||
inst->VDMOSm *
|
||||
inst->VDMOSl * coxSquared);
|
||||
(data->freq *
|
||||
inst->VDMOSm * coxSquared);
|
||||
lnNdens[VDMOSFLNOIZ] =
|
||||
log(MAX(noizDens[VDMOSFLNOIZ],N_MINLOG));
|
||||
|
||||
|
|
|
|||
|
|
@ -42,14 +42,6 @@ VDMOSparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
here->VDMOSm = value->rValue;
|
||||
here->VDMOSmGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_W:
|
||||
here->VDMOSw = value->rValue * scale;
|
||||
here->VDMOSwGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_L:
|
||||
here->VDMOSl = value->rValue * scale;
|
||||
here->VDMOSlGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_OFF:
|
||||
here->VDMOSoff = (value->iValue != 0);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -212,12 +212,6 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if(!here->VDMOSmGiven) {
|
||||
here->VDMOSm = 1;
|
||||
}
|
||||
if(!here->VDMOSlGiven) {
|
||||
here->VDMOSl = 1;
|
||||
}
|
||||
if(!here->VDMOSwGiven) {
|
||||
here->VDMOSw = 1;
|
||||
}
|
||||
if (model->VDMOSdrainResistance != 0) {
|
||||
here->VDMOSdrainConductance = here->VDMOSm / model->VDMOSdrainResistance;
|
||||
} else {
|
||||
|
|
@ -242,7 +236,7 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
} else {
|
||||
here->VDMOSdsConductance = 1e-15;
|
||||
}
|
||||
if (model->VDIOresistance > 10e-03) {
|
||||
if (model->VDIOresistance > 10e-3) {
|
||||
here->VDIOconductance = here->VDMOSm / model->VDIOresistance;
|
||||
} else {
|
||||
here->VDIOconductance = here->VDMOSm / 10e-03;
|
||||
|
|
@ -375,7 +369,7 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
} } while(0)
|
||||
|
||||
if ((here->VDMOSthermalGiven) && (model->VDMOSrthjcGiven)) {
|
||||
TSTALLOC(VDMOSTemptempPtr, VDMOStempNode, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTemptempPtr, VDMOStempNode, VDMOStempNode); /* Transistor thermal contribution */
|
||||
TSTALLOC(VDMOSTempdpPtr, VDMOStempNode, VDMOSdNodePrime);
|
||||
TSTALLOC(VDMOSTempspPtr, VDMOStempNode, VDMOSsNodePrime);
|
||||
TSTALLOC(VDMOSTempgpPtr, VDMOStempNode, VDMOSgNodePrime);
|
||||
|
|
@ -383,10 +377,15 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
|
|||
TSTALLOC(VDMOSDPtempPtr, VDMOSdNodePrime, VDMOStempNode);
|
||||
TSTALLOC(VDMOSSPtempPtr, VDMOSsNodePrime, VDMOStempNode);
|
||||
|
||||
TSTALLOC(VDMOSTcasetcasePtr, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/
|
||||
TSTALLOC(VDIOTempposPrimePtr, VDMOStempNode, VDIOposPrimeNode);/* Diode thermal contribution */
|
||||
TSTALLOC(VDIOTempnegPtr, VDMOStempNode, VDMOSdNode);
|
||||
TSTALLOC(VDIOPosPrimetempPtr, VDIOposPrimeNode, VDMOStempNode);
|
||||
TSTALLOC(VDIONegtempPtr, VDMOSdNode, VDMOStempNode);
|
||||
|
||||
TSTALLOC(VDMOSTcasetcasePtr, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/
|
||||
TSTALLOC(VDMOSTcasetempPtr, VDMOStcaseNode, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTemptcasePtr, VDMOStempNode, VDMOStcaseNode);
|
||||
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
||||
TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */
|
||||
TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStempNode);
|
||||
TSTALLOC(VDMOSTcasetpPtr, VDMOStempNode, VDMOStNodePrime);
|
||||
TSTALLOC(VDMOSCktTcktTPtr, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */
|
||||
|
|
|
|||
|
|
@ -93,8 +93,7 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* vdmos temperature model */
|
||||
ratio = here->VDMOStemp/model->VDMOStnom;
|
||||
here->VDMOStTransconductance = model->VDMOStransconductance
|
||||
* here->VDMOSm * here->VDMOSw / here->VDMOSl
|
||||
* pow(ratio, model->VDMOSmu);
|
||||
* here->VDMOSm * pow(ratio, model->VDMOSmu);
|
||||
|
||||
here->VDMOStVth = model->VDMOSvth0 - model->VDMOStype * model->VDMOStcvth * dt;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue