diff --git a/src/spicelib/devices/vdmos/vdmosacld.c b/src/spicelib/devices/vdmos/vdmosacld.c index 920cbd611..fd90caa66 100644 --- a/src/spicelib/devices/vdmos/vdmosacld.c +++ b/src/spicelib/devices/vdmos/vdmosacld.c @@ -138,7 +138,6 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt) double gthca = here->VDMOSm / model->VDMOSrthca; *(here->VDMOSDPtempPtr) += GmT; *(here->VDMOSSPtempPtr) += -GmT; - *(here->VDMOSTemptempPtr) += gTtt + gthjc; *(here->VDMOSTempgpPtr) += gTtg; *(here->VDMOSTempdpPtr) += gTtdp; @@ -149,8 +148,8 @@ VDMOSacLoad(GENmodel *inModel, CKTcircuit *ckt) *(here->VDMOSTptpPtr) += gthca; *(here->VDMOSTptcasePtr) += -gthca; *(here->VDMOSTcasetpPtr) += -gthca; - *(here->VDMOSCktTtpPtr) += 1.0; - *(here->VDMOSTpcktTPtr) += 1.0; + *(here->VDMOSDevTtpPtr) += 1.0; + *(here->VDMOSTpdevTPtr) += 1.0; *(here->VDMOSTemptempPtr + 1) += xcTt; *(here->VDMOSDPtempPtr + 1) += xcdT; diff --git a/src/spicelib/devices/vdmos/vdmosbindCSC.c b/src/spicelib/devices/vdmos/vdmosbindCSC.c index 860dee0c6..bd24b856d 100644 --- a/src/spicelib/devices/vdmos/vdmosbindCSC.c +++ b/src/spicelib/devices/vdmos/vdmosbindCSC.c @@ -67,8 +67,8 @@ VDMOSbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VDMOSTempdPtr, VDMOSTempdBinding, VDMOStempNode, VDMOSdNode); CREATE_KLU_BINDING_TABLE(VDIOPosPrimetempPtr, VDIOPosPrimetempBinding, VDIOposPrimeNode, VDMOStempNode); CREATE_KLU_BINDING_TABLE(VDMOSDtempPtr, VDMOSDtempBinding, VDMOSdNode, VDMOStempNode); - CREATE_KLU_BINDING_TABLE(VDMOStempSPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); - CREATE_KLU_BINDING_TABLE(VDMOSSTempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); + CREATE_KLU_BINDING_TABLE(VDMOSTempsPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); + CREATE_KLU_BINDING_TABLE(VDMOSStempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); CREATE_KLU_BINDING_TABLE(VDMOSTcasetcasePtr, VDMOSTcasetcaseBinding, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/ CREATE_KLU_BINDING_TABLE(VDMOSTcasetempPtr, VDMOSTcasetempBinding, VDMOStcaseNode, VDMOStempNode); @@ -76,9 +76,9 @@ VDMOSbindCSC (GENmodel *inModel, CKTcircuit *ckt) CREATE_KLU_BINDING_TABLE(VDMOSTptpPtr, VDMOSTptpBinding, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */ CREATE_KLU_BINDING_TABLE(VDMOSTptcasePtr, VDMOSTptcaseBinding, VDMOStNodePrime, VDMOStcaseNode); CREATE_KLU_BINDING_TABLE(VDMOSTcasetpPtr, VDMOSTcasetpBinding, VDMOStcaseNode, VDMOStNodePrime); - CREATE_KLU_BINDING_TABLE(VDMOSCktTcktTPtr, VDMOSCktTcktTBinding, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */ - CREATE_KLU_BINDING_TABLE(VDMOSCktTtpPtr, VDMOSCktTtpBinding, VDMOSvcktTbranch, VDMOStNodePrime); - CREATE_KLU_BINDING_TABLE(VDMOSTpcktTPtr, VDMOSTpcktTBinding, VDMOStNodePrime, VDMOSvcktTbranch); + CREATE_KLU_BINDING_TABLE(VDMOSDevTdevTPtr, VDMOSDevTdevTBinding, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=devTemp to gnd */ + CREATE_KLU_BINDING_TABLE(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime); + CREATE_KLU_BINDING_TABLE(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch); } } } @@ -142,8 +142,8 @@ VDMOSbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTempdPtr, VDMOSTempdBinding, VDMOStempNode, VDMOSdNode); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDIOPosPrimetempPtr, VDIOPosPrimetempBinding, VDIOposPrimeNode, VDMOStempNode); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSDtempPtr, VDMOSDtempBinding, VDMOSdNode, VDMOStempNode); - CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOStempSPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); - CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSSTempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTempsPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSStempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTcasetcasePtr, VDMOSTcasetcaseBinding, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/ CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTcasetempPtr, VDMOSTcasetempBinding, VDMOStcaseNode, VDMOStempNode); @@ -151,9 +151,9 @@ VDMOSbindCSCComplex (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTptpPtr, VDMOSTptpBinding, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */ CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTptcasePtr, VDMOSTptcaseBinding, VDMOStNodePrime, VDMOStcaseNode); CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTcasetpPtr, VDMOSTcasetpBinding, VDMOStcaseNode, VDMOStNodePrime); - CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSCktTcktTPtr, VDMOSCktTcktTBinding, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */ - CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSCktTtpPtr, VDMOSCktTtpBinding, VDMOSvcktTbranch, VDMOStNodePrime); - CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTpcktTPtr, VDMOSTpcktTBinding, VDMOStNodePrime, VDMOSvcktTbranch); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSDevTdevTPtr, VDMOSDevTdevTBinding, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=devTemp to gnd */ + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime); + CONVERT_KLU_BINDING_TABLE_TO_COMPLEX(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch); } } } @@ -217,8 +217,8 @@ VDMOSbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTempdPtr, VDMOSTempdBinding, VDMOStempNode, VDMOSdNode); CONVERT_KLU_BINDING_TABLE_TO_REAL(VDIOPosPrimetempPtr, VDIOPosPrimetempBinding, VDIOposPrimeNode, VDMOStempNode); CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSDtempPtr, VDMOSDtempBinding, VDMOSdNode, VDMOStempNode); - CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOStempSPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); - CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSSTempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTempsPtr, VDMOStempSBinding, VDMOStempNode, VDMOSsNode); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSStempPtr, VDMOSSTempBinding, VDMOSsNode, VDMOStempNode); CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTcasetcasePtr, VDMOSTcasetcaseBinding, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/ CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTcasetempPtr, VDMOSTcasetempBinding, VDMOStcaseNode, VDMOStempNode); @@ -226,9 +226,9 @@ VDMOSbindCSCComplexToReal (GENmodel *inModel, CKTcircuit *ckt) CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTptpPtr, VDMOSTptpBinding, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */ CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTptcasePtr, VDMOSTptcaseBinding, VDMOStNodePrime, VDMOStcaseNode); CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTcasetpPtr, VDMOSTcasetpBinding, VDMOStcaseNode, VDMOStNodePrime); - CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSCktTcktTPtr, VDMOSCktTcktTBinding, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */ - CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSCktTtpPtr, VDMOSCktTtpBinding, VDMOSvcktTbranch, VDMOStNodePrime); - CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTpcktTPtr, VDMOSTpcktTBinding, VDMOStNodePrime, VDMOSvcktTbranch); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSDevTdevTPtr, VDMOSDevTdevTBinding, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=devTemp to gnd */ + CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSDevTtpPtr, VDMOSDevTtpBinding, VDMOSvdevTbranch, VDMOStNodePrime); + CONVERT_KLU_BINDING_TABLE_TO_REAL(VDMOSTpdevTPtr, VDMOSTpdevTBinding, VDMOStNodePrime, VDMOSvdevTbranch); } } } diff --git a/src/spicelib/devices/vdmos/vdmosconv.c b/src/spicelib/devices/vdmos/vdmosconv.c index 6b6dfca42..49e0ccde8 100644 --- a/src/spicelib/devices/vdmos/vdmosconv.c +++ b/src/spicelib/devices/vdmos/vdmosconv.c @@ -83,8 +83,8 @@ VDMOSconvTest(GENmodel *inModel, CKTcircuit *ckt) */ vd = model->VDMOStype * ( - *(ckt->CKTrhsOld+here->VDIOposPrimeNode)- - *(ckt->CKTrhsOld + here->VDMOSdNode)); + *(ckt->CKTrhsOld+here->VDIOposPrimeNode)- + *(ckt->CKTrhsOld + here->VDMOSdNode)); delvd=vd- *(ckt->CKTstate0 + here->VDIOvoltage); diff --git a/src/spicelib/devices/vdmos/vdmosdefs.h b/src/spicelib/devices/vdmos/vdmosdefs.h index 28e42b74b..5409a520f 100644 --- a/src/spicelib/devices/vdmos/vdmosdefs.h +++ b/src/spicelib/devices/vdmos/vdmosdefs.h @@ -50,7 +50,7 @@ typedef struct sVDMOSinstance { int VDMOStNodePrime; /* number of the internal temp node between voltage source and Rthca */ int VDIOposPrimeNode; /* number of the internal node of the body diode */ - int VDMOSvcktTbranch; /* equation number of branch equation added for cktTemp source */ + int VDMOSvdevTbranch; /* equation number of branch equation added for cktTemp source */ double VDMOSm; /* parallel device multiplier */ @@ -229,8 +229,8 @@ typedef struct sVDMOSinstance { double *VDMOSTempdPtr; double *VDIOPosPrimetempPtr; double *VDMOSDtempPtr; - double *VDMOStempSPtr; - double *VDMOSSTempPtr; + double *VDMOSTempsPtr; + double *VDMOSStempPtr; double *VDMOSTcasetcasePtr; /* for Rthjc */ double *VDMOSTcasetempPtr; @@ -238,9 +238,9 @@ typedef struct sVDMOSinstance { double *VDMOSTptpPtr; /* for Rthca */ double *VDMOSTptcasePtr; double *VDMOSTcasetpPtr; - double *VDMOSCktTcktTPtr; /* for VcktTemp */ - double *VDMOSCktTtpPtr; - double *VDMOSTpcktTPtr; + double *VDMOSDevTdevTPtr; /* for VdevTemp */ + double *VDMOSDevTtpPtr; + double *VDMOSTpdevTPtr; #ifdef KLU BindElement *VDMOSDdBinding ; @@ -287,9 +287,9 @@ typedef struct sVDMOSinstance { BindElement *VDMOSTptpBinding ; BindElement *VDMOSTptcaseBinding ; BindElement *VDMOSTcasetpBinding ; - BindElement *VDMOSCktTcktTBinding ; - BindElement *VDMOSCktTtpBinding ; - BindElement *VDMOSTpcktTBinding ; + BindElement *VDMOSDevTdevTBinding ; + BindElement *VDMOSDevTtpBinding ; + BindElement *VDMOSTpdevTBinding ; #endif } VDMOSinstance ; diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index 5e93d9174..f5c0d4e8d 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -57,10 +57,10 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) int error; int selfheat; - double rd0T, rd1T, dBeta_dT, dIds_dT; + double rd0T, rd1T, dBeta_dT, dIds_dT=0.0; double Vrd=0.0, dIth_dVrd=0.0, dIrd_dT=0.0; - double drd0T_dT, drd1T_dT, drd_dT, dgdrain_dT=0.0; - double dIrd_dgdrain; + double drd0T_dT, drd1T_dT, dgdrain_dT=0.0; + double rsT, Vrs=0.0, dIth_dVrs=0.0, dIrs_dT=0.0, dgsource_dT=0.0; double deldelTemp=0.0, delTemp, delTemp1, Temp, Vds, Vgs; double ceqqth=0.0; double GmT, gTtg, gTtdp, gTtt, gTtsp, gcTt=0.0; @@ -270,7 +270,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) } if (selfheat) delTemp = DEVlimitlog(delTemp, - *(ckt->CKTstate0 + here->VDMOSdelTemp),30,&Check_th); + *(ckt->CKTstate0 + here->VDMOSdelTemp),10,&Check_th); else delTemp = 0.0; #endif /*NODELIMITING*/ @@ -278,7 +278,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) } if (selfheat) { - Temp = here->VDMOStemp + delTemp; + Temp = delTemp + CONSTCtoK; VDMOStempUpdate(model, here, Temp, ckt); } else { Temp = here->VDMOStemp; @@ -287,17 +287,24 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) /* Calculate temperature dependent values for self-heating effect */ if (selfheat) { - double TempRatio = Temp / here->VDMOStemp; - Beta = here->VDMOStTransconductance * pow(TempRatio,model->VDMOSmu); + Beta = here->VDMOStTransconductance; dBeta_dT = Beta * model->VDMOSmu / Temp; - rd0T = here->VDMOSdrainResistance * pow(TempRatio, model->VDMOStexp0); - drd0T_dT = rd0T * model->VDMOStexp0 / Temp; + rd0T = here->VDMOSdrainResistance; + if (model->VDMOStexp0Given) + drd0T_dT = rd0T * model->VDMOStexp0 / Temp; + else + drd0T_dT = model->VDMOSdrainResistance / here->VDMOSm + * (model->VDMOStrd1 + 2 * model->VDMOStrd2 * (Temp - model->VDMOStnom)); rd1T = 0.0; drd1T_dT = 0.0; if (model->VDMOSqsGiven) { - rd1T = here->VDMOSqsResistance * pow(TempRatio, model->VDMOStexp1); + rd1T = here->VDMOSqsResistance; drd1T_dT = rd1T * model->VDMOStexp1 / Temp; } + rsT = 1 / here->VDMOSsourceConductance; + double drsT_dT = model->VDMOSsourceResistance / here->VDMOSm + * (model->VDMOStrs1 + 2 * model->VDMOStrs2 * (Temp - model->VDMOStnom)); + dgsource_dT = -drsT_dT / (rsT*rsT); } else { Beta = here->VDMOStTransconductance; dBeta_dT = 0.0; @@ -307,6 +314,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) drd1T_dT = 0.0; if (model->VDMOSqsGiven) rd1T = here->VDMOSqsResistance; + dgsource_dT = 0.0; } /* @@ -359,25 +367,37 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) double betap = Beta*t0/t1; double dbetapdvgs = -Beta*theta*t0/(t1*t1); double dbetapdvds = Beta*lambda/t1; - double dbetapdT = dBeta_dT*t0/t1; double t2 = exp((vgst-shift)/slope); vgst = slope * log(1 + t2); double dvgstdvgs = t2/(t2+1); - + if (vgst <= vdss) { /* saturation region */ cdrain = betap * vgst*vgst * .5; here->VDMOSgm = betap*vgst*dvgstdvgs + 0.5*dbetapdvgs*vgst*vgst; here->VDMOSgds = .5*dbetapdvds*vgst*vgst; - dIds_dT = dbetapdT * vgst*vgst * .5; } else { /* linear region */ cdrain = betap * vdss * (vgst - .5 * vdss); here->VDMOSgm = betap*vdss*dvgstdvgs + vdss*dbetapdvgs*(vgst-.5*vdss); here->VDMOSgds = vdss*dbetapdvds*(vgst-.5*vdss) + betap*mtr*(vgst-.5*vdss) - .5*vdss*betap*mtr; - dIds_dT = dbetapdT * vdss * (vgst - .5 * vdss); + } + if (selfheat) { + double dvgst_dT = model->VDMOStype * model->VDMOStcvth; + double dvdsat_dT = 0.0; + if (vgst > 0) { + dvdsat_dT = dvgst_dT; + } + double dt1_dT = theta * dvdsat_dT; + double dbetap_dT = t0 * (t1 * dBeta_dT - Beta * dt1_dT) / (t1 * t1); + if (vgst <= vdss) { + dIds_dT = .5 * dbetap_dT * vgst*vgst + betap * vgst * dvgst_dT; + } + else { + dIds_dT = vdss * (dbetap_dT * vgst + betap * dvgst_dT) - dbetap_dT * vdss * .5 * vdss; + } } } @@ -409,7 +429,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTrhsOld + here->VDMOSdNode) - *(ckt->CKTrhsOld + here->VDMOSsNode)); double rd = rd0T + rd1T * (vdsn / (vdsn + fabs(model->VDMOSqsVoltage))); - drd_dT = drd0T_dT + drd1T_dT * (vdsn / (vdsn + fabs(model->VDMOSqsVoltage))); + double drd_dT = drd0T_dT + drd1T_dT * (vdsn / (vdsn + fabs(model->VDMOSqsVoltage))); if (rd > 0) { here->VDMOSdrainConductance = 1 / rd + ckt->CKTgmin; dgdrain_dT = -drd_dT / (rd*rd); @@ -442,10 +462,16 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) - here->VDMOSgtempT * delTemp; Vrd = *(ckt->CKTrhsOld + here->VDMOSdNode) - *(ckt->CKTrhsOld + here->VDMOSdNodePrime); - dIth_dVrd = here->VDMOSdrainConductance * Vrd; - dIrd_dgdrain = Vrd; + dIth_dVrd = here->VDMOSdrainConductance * 2 * Vrd; + double dIrd_dgdrain = Vrd; dIrd_dT = dIrd_dgdrain * dgdrain_dT; here->VDMOScth += here->VDMOSdrainConductance * Vrd*Vrd - dIth_dVrd*Vrd - dIrd_dT*Vrd*delTemp; + + Vrs = *(ckt->CKTrhsOld + here->VDMOSsNode) - *(ckt->CKTrhsOld + here->VDMOSsNodePrime); + dIth_dVrs = here->VDMOSsourceConductance * 2 * Vrs; + double dIrs_dgsource = Vrs; + dIrs_dT = dIrs_dgsource * dgsource_dT; + here->VDMOScth += here->VDMOSsourceConductance * Vrs*Vrs - dIth_dVrs*Vrs - dIrs_dT*Vrs*delTemp; } /* @@ -466,8 +492,11 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) DevCapVDMOS(vgd, cgdmin, cgdmax, a, cgs, (ckt->CKTstate0 + here->VDMOScapgs), (ckt->CKTstate0 + here->VDMOScapgd)); - // Everything is computed for m parallel instances... so scale cthj accordingly - *(ckt->CKTstate0 + here->VDMOScapth) = here->VDMOSm * model->VDMOScthj; /* always constant */ + /* Everything is computed for m parallel instances... so scale cthj accordingly + * Also, take into account Meyer numerical integration style and + * halve the value of cthj that gets stored in the state. + */ + *(ckt->CKTstate0 + here->VDMOScapth) = here->VDMOSm * model->VDMOScthj / 2; /* always constant */ vgs1 = *(ckt->CKTstate1 + here->VDMOSvgs); vgd1 = vgs1 - *(ckt->CKTstate1 + here->VDMOSvds); @@ -550,8 +579,6 @@ bypass: { error = NIintegrate(ckt, &gcTt, &ceqqth, capth, here->VDMOSqth); if (error) return(error); - ceqqth = ceqqth - gcTt*delTemp + ckt->CKTag[0] * - *(ckt->CKTstate0 + here->VDMOSqth); } } @@ -598,15 +625,18 @@ bypass: *(ckt->CKTrhs + here->VDMOSsNodePrime) += cdreq + model->VDMOStype * ceqgs; if (selfheat) { *(ckt->CKTrhs + here->VDMOSdNode) += dIrd_dT * delTemp; + *(ckt->CKTrhs + here->VDMOSsNode) += dIrs_dT * delTemp; *(ckt->CKTrhs + here->VDMOSdNodePrime) += GmT * delTemp - dIrd_dT * delTemp; - *(ckt->CKTrhs + here->VDMOSsNodePrime) += -GmT * delTemp; + *(ckt->CKTrhs + here->VDMOSsNodePrime) += -GmT * delTemp - dIrs_dT * delTemp; *(ckt->CKTrhs + here->VDMOStempNode) += here->VDMOScth - ceqqth; - double vCktTemp = (ckt->CKTtemp-CONSTCtoK); /* ckt temperature */ + double vDevTemp = (ckt->CKTtemp-CONSTCtoK); /* ckt temperature */ + if (here->VDMOStempGiven) + vDevTemp = (here->VDMOStemp-CONSTCtoK); /* device temperature */ if (ckt->CKTmode & MODETRANOP) - vCktTemp *= ckt->CKTsrcFact; - *(ckt->CKTrhs + here->VDMOSvcktTbranch)+= vCktTemp; + vDevTemp *= ckt->CKTsrcFact; + *(ckt->CKTrhs + here->VDMOSvdevTbranch)+= vDevTemp; } - + /* * load y matrix */ @@ -641,26 +671,28 @@ bypass: if (selfheat) { - // Everything is computed for m parallel instances... so scale gthjc and gthja accordingly + /* Everything is computed for m parallel instances... so scale gthjc and gthja accordingly + */ double gthjc = here->VDMOSm / model->VDMOSrthjc; double gthca = here->VDMOSm / model->VDMOSrthca; (*(here->VDMOSDtempPtr) += dIrd_dT); (*(here->VDMOSDPtempPtr) += GmT - dIrd_dT); - (*(here->VDMOSSPtempPtr) += -GmT); - (*(here->VDMOSGPtempPtr) += 0.0); - (*(here->VDMOSTemptempPtr) += -gTtt - dIrd_dT*Vrd + gthjc + gcTt); + (*(here->VDMOSStempPtr) += dIrs_dT); + (*(here->VDMOSSPtempPtr) += -GmT - dIrs_dT); + (*(here->VDMOSTemptempPtr) += -gTtt - dIrd_dT*Vrd - dIrs_dT*Vrs + gthjc + gcTt); (*(here->VDMOSTempgpPtr) += -gTtg); (*(here->VDMOSTempdPtr) += -dIth_dVrd); + (*(here->VDMOSTempsPtr) += -dIth_dVrs); (*(here->VDMOSTempdpPtr) += -gTtdp + dIth_dVrd); - (*(here->VDMOSTempspPtr) += -gTtsp); + (*(here->VDMOSTempspPtr) += -gTtsp + dIth_dVrs); (*(here->VDMOSTemptcasePtr) += -gthjc); (*(here->VDMOSTcasetempPtr) += -gthjc); (*(here->VDMOSTcasetcasePtr) += gthjc + gthca); (*(here->VDMOSTptpPtr) += gthca); (*(here->VDMOSTptcasePtr) += -gthca); (*(here->VDMOSTcasetpPtr) += -gthca); - (*(here->VDMOSCktTtpPtr) += 1.0); - (*(here->VDMOSTpcktTPtr) += 1.0); + (*(here->VDMOSDevTtpPtr) += 1.0); + (*(here->VDMOSTpdevTPtr) += 1.0); } /* body diode model @@ -672,18 +704,18 @@ bypass: double vtebrk, vbrknp; double cdb, cdeq; double capd; - double gd, gdb, gspr; + double gd, gdb, gbpr; 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 vrs=0.0, dIrs_dT=0.0, dIth_dVrs=0.0; + double vrb=0.0, dIrb_dT=0.0, dIth_dVrb=0.0; #ifndef NOBYPASS double tol; /* temporary for tolerance calculations */ #endif - gspr = here->VDIOtConductance; + gbpr = here->VDIOtConductance; vt = CONSTKoverQ * Temp; vte = model->VDIOn * vt; @@ -878,18 +910,18 @@ bypass: load: #endif if (selfheat) { - double dIrs_dgspr, dIth_dIrs; - vrs = *(ckt->CKTrhsOld + here->VDMOSsNode) - *(ckt->CKTrhsOld + here->VDIOposPrimeNode); + double dIrb_dgbpr, dIth_dIrb; + vrb = *(ckt->CKTrhsOld + here->VDMOSsNode) - *(ckt->CKTrhsOld + here->VDIOposPrimeNode); - Ith = vd*cd + vrs*vrs*gspr; + Ith = vd*cd + vrb*vrb*gbpr; dIth_dVdio = cd + vd*gd; - dIth_dVrs = vrs*gspr; + dIth_dVrb = vrb*gbpr; - dIrs_dgspr = vrs; - dIrs_dT = dIrs_dgspr * here->VDIOtConductance_dT; - dIth_dIrs = vrs; - dIth_dT = dIth_dIrs*dIrs_dT + dIdio_dT*vd; + dIrb_dgbpr = vrb; + dIrb_dT = dIrb_dgbpr * here->VDIOtConductance_dT; + dIth_dIrb = vrb; + dIth_dT = dIth_dIrb*dIrb_dT + dIdio_dT*vd; } /* * load current vector @@ -903,28 +935,28 @@ load: *(ckt->CKTrhs + here->VDIOposPrimeNode) += cdeq; } if (selfheat) { - *(ckt->CKTrhs + here->VDIOposPrimeNode) += dIdio_dT*delTemp - dIrs_dT*delTemp; + *(ckt->CKTrhs + here->VDIOposPrimeNode) += dIdio_dT*delTemp - dIrb_dT*delTemp; *(ckt->CKTrhs + here->VDMOSdNode) += -dIdio_dT*delTemp; - *(ckt->CKTrhs + here->VDMOSsNode) += dIrs_dT*delTemp; - *(ckt->CKTrhs + here->VDMOStempNode) += Ith - model->VDMOStype*dIth_dVdio*vd - dIth_dVrs*vrs - dIth_dT*delTemp; + *(ckt->CKTrhs + here->VDMOSsNode) += dIrb_dT*delTemp; + *(ckt->CKTrhs + here->VDMOStempNode) += Ith - model->VDMOStype*dIth_dVdio*vd - dIth_dVrb*vrb - dIth_dT*delTemp; } /* * load matrix */ - *(here->VDMOSSsPtr) += gspr; + *(here->VDMOSSsPtr) += gbpr; *(here->VDMOSDdPtr) += gd; - *(here->VDIORPrpPtr) += (gd + gspr); - *(here->VDIOSrpPtr) -= gspr; + *(here->VDIORPrpPtr) += (gd + gbpr); + *(here->VDIOSrpPtr) -= gbpr; *(here->VDIODrpPtr) -= gd; - *(here->VDIORPsPtr) -= gspr; + *(here->VDIORPsPtr) -= gbpr; *(here->VDIORPdPtr) -= gd; if (selfheat) { - (*(here->VDMOStempSPtr) += -dIth_dVrs); - (*(here->VDIOTempposPrimePtr) += -dIth_dVdio + dIth_dVrs); + (*(here->VDMOSTempsPtr) += -dIth_dVrb); + (*(here->VDIOTempposPrimePtr) += -dIth_dVdio + dIth_dVrb); (*(here->VDMOSTempdPtr) += dIth_dVdio); (*(here->VDMOSTemptempPtr) += -dIth_dT); - (*(here->VDIOPosPrimetempPtr) += dIdio_dT - dIrs_dT); - (*(here->VDMOSSTempPtr) += dIrs_dT); + (*(here->VDIOPosPrimetempPtr) += dIdio_dT - dIrb_dT); + (*(here->VDMOSStempPtr) += dIrb_dT); (*(here->VDMOSDtempPtr) += -dIdio_dT); } } diff --git a/src/spicelib/devices/vdmos/vdmosset.c b/src/spicelib/devices/vdmos/vdmosset.c index 58e6cd300..dfc6a2da3 100644 --- a/src/spicelib/devices/vdmos/vdmosset.c +++ b/src/spicelib/devices/vdmos/vdmosset.c @@ -416,10 +416,10 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, if (error) return(error); here->VDMOStcaseNode = tmp->number; } - if(here->VDMOSvcktTbranch == 0) { - error = CKTmkCur(ckt,&tmp,here->VDMOSname,"VcktTemp"); + if(here->VDMOSvdevTbranch == 0) { + error = CKTmkCur(ckt,&tmp,here->VDMOSname,"VdevTemp"); if(error) return(error); - here->VDMOSvcktTbranch = tmp->number; + here->VDMOSvdevTbranch = tmp->number; } if (here->VDMOStNodePrime == 0) { error = CKTmkVolt(ckt, &tmp, here->VDMOSname, "cktTemp"); @@ -479,8 +479,8 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(VDMOSTempdPtr, VDMOStempNode, VDMOSdNode); TSTALLOC(VDIOPosPrimetempPtr, VDIOposPrimeNode, VDMOStempNode); TSTALLOC(VDMOSDtempPtr, VDMOSdNode, VDMOStempNode); - TSTALLOC(VDMOStempSPtr, VDMOStempNode, VDMOSsNode); - TSTALLOC(VDMOSSTempPtr, VDMOSsNode, VDMOStempNode); + TSTALLOC(VDMOSTempsPtr, VDMOStempNode, VDMOSsNode); + TSTALLOC(VDMOSStempPtr, VDMOSsNode, VDMOStempNode); TSTALLOC(VDMOSTcasetcasePtr, VDMOStcaseNode, VDMOStcaseNode); /* Rthjc between tj and tcase*/ TSTALLOC(VDMOSTcasetempPtr, VDMOStcaseNode, VDMOStempNode); @@ -488,9 +488,9 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(VDMOSTptpPtr, VDMOStNodePrime, VDMOStNodePrime); /* Rthca between tcase and Vsrc */ TSTALLOC(VDMOSTptcasePtr, VDMOStNodePrime, VDMOStcaseNode); TSTALLOC(VDMOSTcasetpPtr, VDMOStcaseNode, VDMOStNodePrime); - TSTALLOC(VDMOSCktTcktTPtr, VDMOSvcktTbranch, VDMOSvcktTbranch); /* Vsrc=cktTemp to gnd */ - TSTALLOC(VDMOSCktTtpPtr, VDMOSvcktTbranch, VDMOStNodePrime); - TSTALLOC(VDMOSTpcktTPtr, VDMOStNodePrime, VDMOSvcktTbranch); + TSTALLOC(VDMOSDevTdevTPtr, VDMOSvdevTbranch, VDMOSvdevTbranch); /* Vsrc=cktTemp to gnd */ + TSTALLOC(VDMOSDevTtpPtr, VDMOSvdevTbranch, VDMOStNodePrime); + TSTALLOC(VDMOSTpdevTPtr, VDMOStNodePrime, VDMOSvdevTbranch); } } } @@ -533,9 +533,9 @@ VDMOSunsetup(GENmodel *inModel, CKTcircuit *ckt) if (here->VDMOStNodePrime > 0) CKTdltNNum(ckt, here->VDMOStNodePrime); here->VDMOStNodePrime = 0; - if (here->VDMOSvcktTbranch > 0) - CKTdltNNum(ckt, here->VDMOSvcktTbranch); - here->VDMOSvcktTbranch = 0; + if (here->VDMOSvdevTbranch > 0) + CKTdltNNum(ckt, here->VDMOSvdevTbranch); + here->VDMOSvdevTbranch = 0; } }