diff --git a/examples/vdmos/ro_11_vdmos.sp b/examples/vdmos/ro_11_vdmos.sp index 84300d4ae..f277dc49a 100644 --- a/examples/vdmos/ro_11_vdmos.sp +++ b/examples/vdmos/ro_11_vdmos.sp @@ -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 diff --git a/src/spicelib/devices/vdmos/vdmos.c b/src/spicelib/devices/vdmos/vdmos.c index b78f01c79..e76c0940b 100644 --- a/src/spicelib/devices/vdmos/vdmos.c +++ b/src/spicelib/devices/vdmos/vdmos.c @@ -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"), diff --git a/src/spicelib/devices/vdmos/vdmosask.c b/src/spicelib/devices/vdmos/vdmosask.c index 87a67ef77..69accba89 100644 --- a/src/spicelib/devices/vdmos/vdmosask.c +++ b/src/spicelib/devices/vdmos/vdmosask.c @@ -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); diff --git a/src/spicelib/devices/vdmos/vdmosconv.c b/src/spicelib/devices/vdmos/vdmosconv.c index d620a817f..aa810b8ce 100644 --- a/src/spicelib/devices/vdmos/vdmosconv.c +++ b/src/spicelib/devices/vdmos/vdmosconv.c @@ -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); diff --git a/src/spicelib/devices/vdmos/vdmosdefs.h b/src/spicelib/devices/vdmos/vdmosdefs.h index 13e225eaf..5b33e7918 100644 --- a/src/spicelib/devices/vdmos/vdmosdefs.h +++ b/src/spicelib/devices/vdmos/vdmosdefs.h @@ -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, diff --git a/src/spicelib/devices/vdmos/vdmosdset.c b/src/spicelib/devices/vdmos/vdmosdset.c index 6ffa1b902..2c1a7506e 100644 --- a/src/spicelib/devices/vdmos/vdmosdset.c +++ b/src/spicelib/devices/vdmos/vdmosdset.c @@ -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) - diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index 6b543eb67..baeec97ef 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -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); diff --git a/src/spicelib/devices/vdmos/vdmosnoi.c b/src/spicelib/devices/vdmos/vdmosnoi.c index 3d96af5bb..a31a34485 100644 --- a/src/spicelib/devices/vdmos/vdmosnoi.c +++ b/src/spicelib/devices/vdmos/vdmosnoi.c @@ -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)); diff --git a/src/spicelib/devices/vdmos/vdmospar.c b/src/spicelib/devices/vdmos/vdmospar.c index 5b6fb1554..9e97a147e 100644 --- a/src/spicelib/devices/vdmos/vdmospar.c +++ b/src/spicelib/devices/vdmos/vdmospar.c @@ -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; diff --git a/src/spicelib/devices/vdmos/vdmosset.c b/src/spicelib/devices/vdmos/vdmosset.c index 13ab6faa1..085b43910 100644 --- a/src/spicelib/devices/vdmos/vdmosset.c +++ b/src/spicelib/devices/vdmos/vdmosset.c @@ -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 */ diff --git a/src/spicelib/devices/vdmos/vdmostemp.c b/src/spicelib/devices/vdmos/vdmostemp.c index dbd81fe84..46d891392 100644 --- a/src/spicelib/devices/vdmos/vdmostemp.c +++ b/src/spicelib/devices/vdmos/vdmostemp.c @@ -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;