alternative temperature model for extrinsic resistances and subthreshold range

This commit is contained in:
dwarning 2020-02-03 20:40:36 +01:00
parent f09d1d451e
commit 9889f0f277
7 changed files with 162 additions and 12 deletions

View File

@ -89,10 +89,20 @@ IFparm VDMOSmPTable[] = { /* model parameters */
IOPR("bex", VDMOS_MOD_MU, IF_REAL, "Exponent of gain temperature dependency"),
IOP( "texp0", VDMOS_MOD_TEXP0, IF_REAL, "Drain resistance rd0 temperature exponent"),
IOP( "texp1", VDMOS_MOD_TEXP1, IF_REAL, "Drain resistance rd1 temperature exponent"),
IOP( "trd1", VDMOS_MOD_TRD1, IF_REAL, "Drain resistance linear temperature coefficient"),
IOP( "trd2", VDMOS_MOD_TRD2, IF_REAL, "Drain resistance quadratic temperature coefficient"),
IOP( "trg1", VDMOS_MOD_TRG1, IF_REAL, "Gate resistance linear temperature coefficient"),
IOP( "trg2", VDMOS_MOD_TRG2, IF_REAL, "Gate resistance quadratic temperature coefficient"),
IOP( "trs1", VDMOS_MOD_TRS1, IF_REAL, "Source resistance linear temperature coefficient"),
IOP( "trs2", VDMOS_MOD_TRS2, IF_REAL, "Source resistance quadratic temperature coefficient"),
IOP( "trb1", VDMOS_MOD_TRB1, IF_REAL, "Body resistance linear temperature coefficient"),
IOP( "trb2", VDMOS_MOD_TRB2, IF_REAL, "Body resistance quadratic temperature coefficient"),
/* weak inversion */
IOP("subshift", VDMOS_MOD_SUBSHIFT, IF_REAL, "Shift of weak inversion plot on the vgs axis"),
IOP("ksubthres", VDMOS_MOD_KSUBTHRES, IF_REAL, "Slope of weak inversion log current versus vgs"),
IOP("tksubthres1", VDMOS_MOD_TKSUBTHRES1, IF_REAL, "Linear temperature coefficient of ksubthres"),
IOP("tksubthres2", VDMOS_MOD_TKSUBTHRES2, IF_REAL, "Quadratic temperature coefficient of ksubthres"),
/* body diode */
IOP("bv", VDMOS_MOD_BV, IF_REAL, "Vds breakdown voltage"),

View File

@ -69,6 +69,7 @@ typedef struct sVDMOSinstance {
double VDMOStTransconductance; /* temperature corrected transconductance*/
double VDMOStPhi; /* temperature corrected Phi */
double VDMOStVth; /* temperature corrected Vth */
double VDMOStksubthres; /* temperature weak inversion slope */
double VDMOSicVDS; /* initial condition D-S voltage */
double VDMOSicVGS; /* initial condition G-S voltage */
@ -332,13 +333,23 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
double VDIOgradCoeffTemp1;
double VDIOgradCoeffTemp2;
double VDMOStcvth;
double VDMOSrthjc;
double VDMOSrthca;
double VDMOScthj;
double VDMOSmu;
double VDMOStexp0;
double VDMOStexp1;
double VDMOStcvth;
double VDMOStrd1;
double VDMOStrd2;
double VDMOStrg1;
double VDMOStrg2;
double VDMOStrs1;
double VDMOStrs2;
double VDMOStrb1;
double VDMOStrb2;
double VDMOStksubthres1;
double VDMOStksubthres2;
double VDMOSvgsMax;
double VDMOSvgdMax;
@ -385,13 +396,23 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
unsigned VDMOSegGiven :1;
unsigned VDMOSxtiGiven :1;
unsigned VDMOStcvthGiven :1;
unsigned VDMOSrthjcGiven :1;
unsigned VDMOSrthcaGiven :1;
unsigned VDMOScthjGiven :1;
unsigned VDMOSmuGiven :1;
unsigned VDMOStexp0Given :1;
unsigned VDMOStexp1Given :1;
unsigned VDMOStcvthGiven :1;
unsigned VDMOStrd1Given :1;
unsigned VDMOStrd2Given :1;
unsigned VDMOStrg1Given :1;
unsigned VDMOStrg2Given :1;
unsigned VDMOStrs1Given :1;
unsigned VDMOStrs2Given :1;
unsigned VDMOStrb1Given :1;
unsigned VDMOStrb2Given :1;
unsigned VDMOStksubthres1Given :1;
unsigned VDMOStksubthres2Given :1;
unsigned VDMOSvgsMaxGiven :1;
unsigned VDMOSvgdMaxGiven :1;
@ -462,13 +483,23 @@ enum {
VDMOS_MOD_TT,
VDMOS_MOD_EG,
VDMOS_MOD_XTI,
VDMOS_MOD_TCVTH,
VDMOS_MOD_RTHJC,
VDMOS_MOD_RTHCA,
VDMOS_MOD_CTHJ,
VDMOS_MOD_MU,
VDMOS_MOD_TEXP0,
VDMOS_MOD_TEXP1,
VDMOS_MOD_TCVTH,
VDMOS_MOD_TRD1,
VDMOS_MOD_TRD2,
VDMOS_MOD_TRG1,
VDMOS_MOD_TRG2,
VDMOS_MOD_TRS1,
VDMOS_MOD_TRS2,
VDMOS_MOD_TRB1,
VDMOS_MOD_TRB2,
VDMOS_MOD_TKSUBTHRES1,
VDMOS_MOD_TKSUBTHRES2,
VDMOS_MOD_VGS_MAX,
VDMOS_MOD_VGD_MAX,
VDMOS_MOD_VDS_MAX,

View File

@ -372,7 +372,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
* Scale the voltage overdrive vgst logarithmically in weak inversion.
* Best fits LTSPICE curves with shift=0
*/
double slope = model->VDMOSksubthres;
double slope = here->VDMOStksubthres;
double lambda = model->VDMOSlambda;
double theta = model->VDMOStheta;
double shift = model->VDMOSsubshift;

View File

@ -125,6 +125,9 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
case VDMOS_MOD_XTI:
value->rValue = model->VDMOSxti;
return(OK);
case VDMOS_MOD_TCVTH:
value->rValue = model->VDMOStcvth;
return(OK);
case VDMOS_MOD_RTHJC:
value->rValue = model->VDMOSrthjc;
return(OK);
@ -143,8 +146,35 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
case VDMOS_MOD_TEXP1:
value->rValue = model->VDMOStexp1;
return(OK);
case VDMOS_MOD_TCVTH:
value->rValue = model->VDMOStcvth;
case VDMOS_MOD_TRD1:
value->rValue = model->VDMOStrd1;
return(OK);
case VDMOS_MOD_TRD2:
value->rValue = model->VDMOStrd2;
return(OK);
case VDMOS_MOD_TRG1:
value->rValue = model->VDMOStrg1;
return(OK);
case VDMOS_MOD_TRG2:
value->rValue = model->VDMOStrg2;
return(OK);
case VDMOS_MOD_TRS1:
value->rValue = model->VDMOStrs1;
return(OK);
case VDMOS_MOD_TRS2:
value->rValue = model->VDMOStrs2;
return(OK);
case VDMOS_MOD_TRB1:
value->rValue = model->VDMOStrb1;
return(OK);
case VDMOS_MOD_TRB2:
value->rValue = model->VDMOStrb2;
return(OK);
case VDMOS_MOD_TKSUBTHRES1:
value->rValue = model->VDMOStksubthres1;
return(OK);
case VDMOS_MOD_TKSUBTHRES2:
value->rValue = model->VDMOStksubthres2;
return(OK);
case VDMOS_MOD_VGS_MAX:
value->rValue = model->VDMOSvgsMax;

View File

@ -174,6 +174,10 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
model->VDMOSxti = value->rValue;
model->VDMOSxtiGiven = TRUE;
break;
case VDMOS_MOD_TCVTH:
model->VDMOStcvth = value->rValue;
model->VDMOStcvthGiven = TRUE;
break;
case VDMOS_MOD_RTHJC:
model->VDMOSrthjc = value->rValue;
model->VDMOSrthjcGiven = TRUE;
@ -198,9 +202,45 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
model->VDMOStexp1 = value->rValue;
model->VDMOStexp1Given = TRUE;
break;
case VDMOS_MOD_TCVTH:
model->VDMOStcvth = value->rValue;
model->VDMOStcvthGiven = TRUE;
case VDMOS_MOD_TRD1:
model->VDMOStrd1 = value->rValue;
model->VDMOStrd1Given = TRUE;
break;
case VDMOS_MOD_TRD2:
model->VDMOStrd2 = value->rValue;
model->VDMOStrd2Given = TRUE;
break;
case VDMOS_MOD_TRG1:
model->VDMOStrg1 = value->rValue;
model->VDMOStrg1Given = TRUE;
break;
case VDMOS_MOD_TRG2:
model->VDMOStrg2 = value->rValue;
model->VDMOStrg2Given = TRUE;
break;
case VDMOS_MOD_TRS1:
model->VDMOStrs1 = value->rValue;
model->VDMOStrs1Given = TRUE;
break;
case VDMOS_MOD_TRS2:
model->VDMOStrs2 = value->rValue;
model->VDMOStrs2Given = TRUE;
break;
case VDMOS_MOD_TRB1:
model->VDMOStrb1 = value->rValue;
model->VDMOStrb1Given = TRUE;
break;
case VDMOS_MOD_TRB2:
model->VDMOStrb2 = value->rValue;
model->VDMOStrb2Given = TRUE;
break;
case VDMOS_MOD_TKSUBTHRES1:
model->VDMOStksubthres1 = value->rValue;
model->VDMOStksubthres1Given = TRUE;
break;
case VDMOS_MOD_TKSUBTHRES2:
model->VDMOStksubthres2 = value->rValue;
model->VDMOStksubthres2Given = TRUE;
break;
case VDMOS_MOD_VGS_MAX:
model->VDMOSvgsMax = value->rValue;

View File

@ -139,6 +139,36 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
if (!model->VDMOStexp1Given)
model->VDMOStexp1 = 0.3;
if (!model->VDMOStrd1Given)
model->VDMOStrd1 = 0.0;
if (!model->VDMOStrd2Given)
model->VDMOStrd2 = 0.0;
if (!model->VDMOStrg1Given)
model->VDMOStrg1 = 0.0;
if (!model->VDMOStrg2Given)
model->VDMOStrg2 = 0.0;
if (!model->VDMOStrs1Given)
model->VDMOStrs1 = 0.0;
if (!model->VDMOStrs2Given)
model->VDMOStrs2 = 0.0;
if (!model->VDMOStrb1Given)
model->VDMOStrb1 = 0.0;
if (!model->VDMOStrb2Given)
model->VDMOStrb2 = 0.0;
if (!model->VDMOStksubthres1Given)
model->VDMOStksubthres1 = 0.0;
if (!model->VDMOStksubthres2Given)
model->VDMOStksubthres2 = 0.0;
if (!model->VDMOSvgsMaxGiven)
model->VDMOSvgsMax = 1e99;

View File

@ -98,7 +98,16 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
here->VDMOStVth = model->VDMOSvth0 - model->VDMOStype * model->VDMOStcvth * dt;
here->VDMOSdrainResistance = model->VDMOSdrainResistance / here->VDMOSm * pow(ratio, model->VDMOStexp0);
here->VDMOStksubthres = model->VDMOSksubthres * (1.0 + (model->VDMOStksubthres1 * dt) + (model->VDMOStksubthres2 * dt * dt));
if (model->VDMOStexp0Given)
here->VDMOSdrainResistance = model->VDMOSdrainResistance / here->VDMOSm * pow(ratio, model->VDMOStexp0);
else
here->VDMOSdrainResistance = model->VDMOSdrainResistance / here->VDMOSm * (1.0 + (model->VDMOStrd1 * dt) + (model->VDMOStrd2 * dt * dt));
here->VDMOSgateConductance = here->VDMOSgateConductance / (1.0 + (model->VDMOStrg1 * dt) + (model->VDMOStrg2 * dt * dt));
here->VDMOSsourceConductance = here->VDMOSsourceConductance / (1.0 + (model->VDMOStrs1 * dt) + (model->VDMOStrs2 * dt * dt));
if (model->VDMOSqsGiven)
here->VDMOSqsResistance = model->VDMOSqsResistance / here->VDMOSm * pow(ratio, model->VDMOStexp1);
@ -206,8 +215,8 @@ VDMOStemp(GENmodel *inModel, CKTcircuit *ckt)
+ (model->VDIOtranTimeTemp2 * dt * dt);
here->VDIOtTransitTime = model->VDIOtransitTime * factor;
/* Series resistance temperature adjust (not implemented yet) */
here->VDIOtConductance = here->VDIOconductance;
/* Series resistance temperature adjust */
here->VDIOtConductance = here->VDIOconductance / (1.0 + (model->VDMOStrb1 * dt) + (model->VDMOStrb2 * dt * dt));
here->VDIOtF2 = exp((1 + here->VDIOtGradingCoeff)*xfc);
here->VDIOtF3 = 1 - model->VDIOdepletionCapCoeff*