Revise the SOA and add new parameters:
pd_max id_max idr_max te_max rth_ext derating rth_ext is currently not used
This commit is contained in:
parent
3f322e1954
commit
18478380ad
|
|
@ -140,8 +140,10 @@ IFparm VDMOSmPTable[] = { /* model parameters */
|
|||
IOP("vgdr_max", VDMOS_MOD_VGDR_MAX, IF_REAL, "maximum voltage G-D branch"),
|
||||
IOP("pd_max", VDMOS_MOD_PD_MAX, IF_REAL, "maximum device power dissipation"),
|
||||
IOP("id_max", VDMOS_MOD_ID_MAX, IF_REAL, "maximum drain/source current"),
|
||||
IOP("idr_max", VDMOS_MOD_IB_MAX, IF_REAL, "maximum drain/source reverse current"),
|
||||
IOP("idr_max", VDMOS_MOD_IDR_MAX, IF_REAL, "maximum drain/source reverse current"),
|
||||
IOP("te_max", VDMOS_MOD_TE_MAX, IF_REAL, "maximum temperature"),
|
||||
IOP("rth_ext", VDMOS_MOD_RTH_EXT, IF_REAL, "thermal resistance case to ambient, incl. heat sink"),
|
||||
IOP("derating", VDMOS_MOD_DERATING, IF_REAL, "thermal derating for power"),
|
||||
};
|
||||
|
||||
char *VDMOSnames[] = {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ typedef struct sVDMOSinstance {
|
|||
#define VDMOSname gen.GENname
|
||||
#define VDMOSstates gen.GENstate
|
||||
|
||||
const int VDMOSdNode; /* number of the gate node of the mosfet */
|
||||
const int VDMOSdNode; /* number of the drain 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 */
|
||||
int VDMOStempNode; /* number of the temperature node of the mosfet */
|
||||
|
|
@ -361,6 +361,12 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
double VDMOSvdsMax;
|
||||
double VDMOSvgsrMax;
|
||||
double VDMOSvgdrMax;
|
||||
double VDMOSid_max;
|
||||
double VDMOSidr_max;
|
||||
double VDMOSpd_max;
|
||||
double VDMOSrth_ext;
|
||||
double VDMOSte_max;
|
||||
double VDMOSderating;
|
||||
|
||||
unsigned VDMOStypeGiven :1;
|
||||
unsigned VDMOSdrainResistanceGiven :1;
|
||||
|
|
@ -424,6 +430,12 @@ typedef struct sVDMOSmodel { /* model structure for a resistor */
|
|||
unsigned VDMOSvdsMaxGiven :1;
|
||||
unsigned VDMOSvgsrMaxGiven :1;
|
||||
unsigned VDMOSvgdrMaxGiven :1;
|
||||
unsigned VDMOSrth_extGiven :1;
|
||||
unsigned VDMOSpd_maxGiven :1;
|
||||
unsigned VDMOSte_maxGiven :1;
|
||||
unsigned VDMOSid_maxGiven :1;
|
||||
unsigned VDMOSidr_maxGiven :1;
|
||||
unsigned VDMOSderatingGiven :1;
|
||||
} VDMOSmodel;
|
||||
|
||||
#ifndef NMOS
|
||||
|
|
@ -510,8 +522,10 @@ enum {
|
|||
VDMOS_MOD_VGDR_MAX,
|
||||
VDMOS_MOD_PD_MAX,
|
||||
VDMOS_MOD_ID_MAX,
|
||||
VDMOS_MOD_IB_MAX,
|
||||
VDMOS_MOD_IDR_MAX,
|
||||
VDMOS_MOD_TE_MAX,
|
||||
VDMOS_MOD_RTH_EXT,
|
||||
VDMOS_MOD_DERATING,
|
||||
};
|
||||
|
||||
/* device questions */
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_TKSUBTHRES2:
|
||||
value->rValue = model->VDMOStksubthres2;
|
||||
return(OK);
|
||||
/* SOA */
|
||||
case VDMOS_MOD_VGS_MAX:
|
||||
value->rValue = model->VDMOSvgsMax;
|
||||
return(OK);
|
||||
|
|
@ -197,6 +198,25 @@ VDMOSmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
|
|||
case VDMOS_MOD_VGDR_MAX:
|
||||
value->rValue = model->VDMOSvgdrMax;
|
||||
return(OK);
|
||||
case VDMOS_MOD_PD_MAX:
|
||||
value->rValue = model->VDMOSpd_max;
|
||||
return(OK);
|
||||
case VDMOS_MOD_ID_MAX:
|
||||
value->rValue = model->VDMOSid_max;
|
||||
return(OK);
|
||||
case VDMOS_MOD_IDR_MAX:
|
||||
value->rValue = model->VDMOSidr_max;
|
||||
return(OK);
|
||||
case VDMOS_MOD_TE_MAX:
|
||||
value->rValue = model->VDMOSte_max;
|
||||
return(OK);
|
||||
case VDMOS_MOD_RTH_EXT:
|
||||
value->rValue = model->VDMOSrth_ext;
|
||||
return(OK);
|
||||
case VDMOS_MOD_DERATING:
|
||||
value->rValue = model->VDMOSderating;
|
||||
return(OK);
|
||||
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -262,6 +262,30 @@ VDMOSmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->VDMOSvgdrMax = value->rValue;
|
||||
model->VDMOSvgdrMaxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_PD_MAX:
|
||||
model->VDMOSpd_max = value->rValue;
|
||||
model->VDMOSpd_maxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_ID_MAX:
|
||||
model->VDMOSid_max = value->rValue;
|
||||
model->VDMOSid_maxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_IDR_MAX:
|
||||
model->VDMOSidr_max = value->rValue;
|
||||
model->VDMOSidr_maxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_TE_MAX:
|
||||
model->VDMOSte_max = value->rValue;
|
||||
model->VDMOSte_maxGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_RTH_EXT:
|
||||
model->VDMOSrth_ext = value->rValue;
|
||||
model->VDMOSrth_extGiven = TRUE;
|
||||
break;
|
||||
case VDMOS_MOD_DERATING:
|
||||
model->VDMOSderating = value->rValue;
|
||||
model->VDMOSderatingGiven = TRUE;
|
||||
break;
|
||||
default:
|
||||
return(E_BADPARM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,6 +190,24 @@ VDMOSsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
|
|||
if (!model->VDMOSvgdrMaxGiven)
|
||||
model->VDMOSvgdrMax = 1e99;
|
||||
|
||||
if (!model->VDMOSpd_maxGiven)
|
||||
model->VDMOSpd_max = 1e99;
|
||||
|
||||
if (!model->VDMOSid_maxGiven)
|
||||
model->VDMOSpd_max = 1e99;
|
||||
|
||||
if (!model->VDMOSidr_maxGiven)
|
||||
model->VDMOSidr_max = 1e99;
|
||||
|
||||
if (!model->VDMOSte_maxGiven)
|
||||
model->VDMOSte_max = 1e99;
|
||||
|
||||
if (!model->VDMOSderatingGiven)
|
||||
model->VDMOSderating = 0;
|
||||
|
||||
if (!model->VDMOSrth_extGiven)
|
||||
model->VDMOSrth_ext = model->VDMOSrthca;
|
||||
|
||||
if (!model->VDMOSqsResistanceGiven)
|
||||
model->VDMOSqsResistance = 0.0;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,21 @@ VDMOSsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
VDMOSinstance *here;
|
||||
double vgs, vgd, vds; /* actual mos voltages */
|
||||
int maxwarns;
|
||||
static int warns_vgs = 0, warns_vgd = 0, warns_vds = 0;
|
||||
static int warns_vgs = 0, warns_vgd = 0, warns_vds = 0, warns_id = 0, warns_idr = 0, warns_pd = 0, warns_te = 0;
|
||||
double id; /* current VDMOS current */
|
||||
double idr; /* current reverse diode current */
|
||||
double pd; /* current VDMOS power dissipation */
|
||||
double pd_max; /* maximum VDMOS power */
|
||||
double te; /* current VDMOS temperature */
|
||||
|
||||
if (!ckt) {
|
||||
warns_vgs = 0;
|
||||
warns_vgd = 0;
|
||||
warns_vds = 0;
|
||||
warns_id = 0;
|
||||
warns_idr = 0;
|
||||
warns_pd = 0;
|
||||
warns_te = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -35,13 +44,13 @@ VDMOSsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
for (here = VDMOSinstances(model); here; here = VDMOSnextInstance(here)) {
|
||||
|
||||
vgs = ckt->CKTrhsOld [here->VDMOSgNode] -
|
||||
ckt->CKTrhsOld [here->VDMOSsNodePrime];
|
||||
ckt->CKTrhsOld [here->VDMOSsNode];
|
||||
|
||||
vgd = ckt->CKTrhsOld [here->VDMOSgNode] -
|
||||
ckt->CKTrhsOld [here->VDMOSdNodePrime];
|
||||
ckt->CKTrhsOld [here->VDMOSdNode];
|
||||
|
||||
vds = ckt->CKTrhsOld [here->VDMOSdNodePrime] -
|
||||
ckt->CKTrhsOld [here->VDMOSsNodePrime];
|
||||
vds = ckt->CKTrhsOld [here->VDMOSdNode] -
|
||||
ckt->CKTrhsOld [here->VDMOSsNode];
|
||||
|
||||
if (!model->VDMOSvgsrMaxGiven) {
|
||||
if (fabs(vgs) > model->VDMOSvgsMax)
|
||||
|
|
@ -135,6 +144,92 @@ VDMOSsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
warns_vds++;
|
||||
}
|
||||
|
||||
/* max. drain current */
|
||||
id = fabs(here->VDMOScd);
|
||||
if (model->VDMOSid_maxGiven && id > fabs(model->VDMOSid_max))
|
||||
if (warns_id < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Id=%.4g A at Vd=%.4g V has exceeded Id_max=%.4g A\n",
|
||||
id, vds, model->VDMOSid_max);
|
||||
warns_id++;
|
||||
}
|
||||
|
||||
/* max. reverse current */
|
||||
idr = fabs(*(ckt->CKTstate0 + here->VDIOcurrent) * -1. + here->VDMOScd);
|
||||
if (model->VDMOSidr_maxGiven && idr > fabs(model->VDMOSidr_max))
|
||||
if (warns_idr < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Idr=%.4g A at Vd=%.4g V has exceeded Idr_max=%.4g A\n",
|
||||
fabs(idr), vds, model->VDMOSidr_max);
|
||||
warns_idr++;
|
||||
}
|
||||
|
||||
pd = fabs((id + idr) * vds);
|
||||
pd += fabs(*(ckt->CKTstate0 + here->VDMOScqgd) *
|
||||
(*(ckt->CKTrhsOld + here->VDMOSgNode) -
|
||||
*(ckt->CKTrhsOld + here->VDMOSdNode)));
|
||||
pd += fabs(*(ckt->CKTstate0 + here->VDMOScqgs) *
|
||||
(*(ckt->CKTrhsOld + here->VDMOSgNode) -
|
||||
*(ckt->CKTrhsOld + here->VDMOSsNode)));
|
||||
|
||||
/* Calculate max power including derating:
|
||||
up to tnom the derating is zero,
|
||||
at maximum temp allowed the derating is 100%.
|
||||
Device temperature by self-heating or given externally. */
|
||||
if (here->VDMOSthermal && model->VDMOSderatingGiven && model->VDMOSpd_maxGiven
|
||||
&& model->VDMOSte_maxGiven && model->VDMOStnomGiven) {
|
||||
te = ckt->CKTrhsOld[here->VDMOStcaseNode];
|
||||
if (te < model->VDMOStnom - CONSTCtoK)
|
||||
pd_max = model->VDMOSpd_max;
|
||||
else {
|
||||
pd_max = model->VDMOSpd_max - (te - model->VDMOStnom + CONSTCtoK) * model->VDMOSderating;
|
||||
pd_max = (pd_max > 0) ? pd_max : 0.;
|
||||
}
|
||||
if (pd > pd_max)
|
||||
if (warns_pd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Pd=%.4g W at Vd=%.4g V and Te=%.4g C has exceeded Pd_max=%.4g W\n",
|
||||
pd, vds, te, pd_max);
|
||||
warns_pd++;
|
||||
}
|
||||
if (te > model->VDMOSte_max)
|
||||
if (warns_te < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Te=%.4g C at Vd=%.4g V has exceeded te_max=%.4g C\n",
|
||||
te, vds, model->VDMOSte_max);
|
||||
warns_te++;
|
||||
}
|
||||
|
||||
}
|
||||
/* Derating of max allowed power dissipation, without self-heating,
|
||||
external temp given by .temp (global) or instance parameter 'temp',
|
||||
therefore no temperature limits are calculated */
|
||||
else if (!here->VDMOSthermal && model->VDMOSderatingGiven && model->VDMOSpd_maxGiven && model->VDMOStnomGiven) {
|
||||
if (here->VDMOStemp < model->VDMOStnom)
|
||||
pd_max = model->VDMOSpd_max;
|
||||
else {
|
||||
pd_max = model->VDMOSpd_max - (here->VDMOStemp - model->VDMOStnom) * model->VDMOSderating;
|
||||
pd_max = (pd_max > 0) ? pd_max : 0.;
|
||||
}
|
||||
if (pd > pd_max)
|
||||
if (warns_pd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Pd=%.4g W at Vd=%.4g V and Te=%.4g C has exceeded Pd_max=%.4g W\n",
|
||||
pd, vds, here->VDMOStemp - CONSTCtoK, pd_max);
|
||||
warns_pd++;
|
||||
}
|
||||
}
|
||||
/* No derating, max power is fixed by model parameter pd_max */
|
||||
else {
|
||||
pd_max = model->VDMOSpd_max;
|
||||
if (pd > pd_max)
|
||||
if (warns_pd < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"Pd=%.4g W at Vd=%.4g V has exceeded Pd_max=%.4g W\n",
|
||||
pd, vds, pd_max);
|
||||
warns_pd++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue