Enhance the SOA (safe operating area) operations

Parameters id_max, pd_max and te_max have been added
for current, power, and temperature to the already existing
fv_max and bv_max (max forward and backward volteges).
This commit is contained in:
Holger Vogt 2021-08-17 12:13:17 +02:00
parent e5fdb4c742
commit 9c8380a031
6 changed files with 85 additions and 4 deletions

View File

@ -108,11 +108,16 @@ IFparm DIOmPTable[] = { /* model parameters */
IOPR( "ib", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"),
IOP( "tcv", DIO_MOD_TCV, IF_REAL, "Reverse breakdown voltage temperature coefficient"),
OPU( "cond", DIO_MOD_COND,IF_REAL, "Ohmic conductance"),
IOP( "fv_max", DIO_MOD_FV_MAX, IF_REAL, "maximum voltage in forward direction"),
IOP( "bv_max", DIO_MOD_BV_MAX, IF_REAL, "maximum voltage in reverse direction"),
IOP( "isr", DIO_MOD_ISR, IF_REAL, "Recombination saturation current"),
IOP( "nr", DIO_MOD_NR, IF_REAL, "Recombination current emission coefficient"),
/* SOA parameters */
IOP( "fv_max", DIO_MOD_FV_MAX, IF_REAL, "maximum voltage in forward direction"),
IOP( "bv_max", DIO_MOD_BV_MAX, IF_REAL, "maximum voltage in reverse direction"),
IOP( "id_max", DIO_MOD_ID_MAX, IF_REAL, "maximum current"),
IOP( "te_max", DIO_MOD_TE_MAX, IF_REAL, "temperature"),
IOP( "pd_max", DIO_MOD_PD_MAX, IF_REAL, "maximum power dissipation"),
/* self heating */
IOP("rth0", DIO_MOD_RTH0, IF_REAL, "Self-heating thermal resistance"),
IOP("cth0", DIO_MOD_CTH0, IF_REAL, "Self-heating thermal capacitance"),

View File

@ -275,6 +275,9 @@ typedef struct sDIOmodel { /* model structure for a diode */
unsigned DIOtunEGcorrectionFactorGiven : 1;
unsigned DIOfv_maxGiven : 1;
unsigned DIObv_maxGiven : 1;
unsigned DIOid_maxGiven : 1;
unsigned DIOpd_maxGiven : 1;
unsigned DIOte_maxGiven : 1;
unsigned DIOrecSatCurGiven : 1;
unsigned DIOrecEmissionCoeffGiven : 1;
@ -342,6 +345,9 @@ typedef struct sDIOmodel { /* model structure for a diode */
double DIOtunEGcorrectionFactor; /* EG correction factor for tunneling (KEG) */
double DIOfv_max; /* maximum voltage in forward direction */
double DIObv_max; /* maximum voltage in reverse direction */
double DIOid_max; /* maximum current */
double DIOpd_max; /* maximum power dissipation */
double DIOte_max; /* maximum temperature */
double DIOrecSatCur; /* Recombination saturation current */
double DIOrecEmissionCoeff; /* Recombination emission coefficient */
@ -442,6 +448,9 @@ enum {
DIO_MOD_KEG,
DIO_MOD_FV_MAX,
DIO_MOD_BV_MAX,
DIO_MOD_ID_MAX,
DIO_MOD_TE_MAX,
DIO_MOD_PD_MAX,
DIO_MOD_ISR,
DIO_MOD_NR,
DIO_MOD_RTH0,

View File

@ -172,6 +172,15 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value)
case DIO_MOD_BV_MAX:
value->rValue = model->DIObv_max;
return(OK);
case DIO_MOD_ID_MAX:
value->rValue = model->DIOid_max;
return(OK);
case DIO_MOD_PD_MAX:
value->rValue = model->DIOpd_max;
return(OK);
case DIO_MOD_TE_MAX:
value->rValue = model->DIOte_max;
return(OK);
case DIO_MOD_ISR:
value->rValue = model->DIOrecSatCur;
return(OK);

View File

@ -209,6 +209,18 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel)
model->DIObv_max = value->rValue;
model->DIObv_maxGiven = TRUE;
break;
case DIO_MOD_ID_MAX:
model->DIOid_max = value->rValue;
model->DIOid_maxGiven = TRUE;
break;
case DIO_MOD_PD_MAX:
model->DIOpd_max = value->rValue;
model->DIOpd_maxGiven = TRUE;
break;
case DIO_MOD_TE_MAX:
model->DIOte_max = value->rValue;
model->DIOte_maxGiven = TRUE;
break;
case DIO_MOD_ISR:
model->DIOrecSatCur = value->rValue;
model->DIOrecSatCurGiven = TRUE;

View File

@ -164,6 +164,15 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if(!model->DIObv_maxGiven) {
model->DIObv_max = 1e99;
}
if(!model->DIOid_maxGiven) {
model->DIOid_max = 1e99;
}
if(!model->DIOpd_maxGiven) {
model->DIOpd_max = 1e99;
}
if(!model->DIOte_maxGiven) {
model->DIOte_max = 1e99;
}
if(!model->DIOrecEmissionCoeffGiven) {
model->DIOrecEmissionCoeff = 1;
}

View File

@ -18,12 +18,18 @@ DIOsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
DIOmodel *model = (DIOmodel *) inModel;
DIOinstance *here;
double vd; /* current diode voltage */
double id; /* current diode current */
double pd; /* current diode power */
double te; /* current diode temperature */
int maxwarns;
static int warns_fv = 0, warns_bv = 0;
static int warns_fv = 0, warns_bv = 0, warns_id = 0, warns_pd = 0, warns_te = 0;
if (!ckt) {
warns_fv = 0;
warns_bv = 0;
warns_id = 0;
warns_pd = 0;
warns_te = 0;
return OK;
}
@ -52,6 +58,37 @@ DIOsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
warns_bv++;
}
id = fabs(*(ckt->CKTstate0 + here->DIOcurrent));
if (id > fabs(model->DIOid_max))
if (warns_id < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Id=%g has exceeded Id_max=%g\n",
id, model->DIOid_max);
warns_id++;
}
pd = fabs(*(ckt->CKTstate0 + here->DIOcurrent) *
*(ckt->CKTstate0 + here->DIOvoltage) +
*(ckt->CKTstate0 + here->DIOcurrent) *
*(ckt->CKTstate0 + here->DIOcurrent) / here->DIOtConductance);
if (pd > fabs(model->DIOpd_max))
if (warns_pd < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Pd=%g has exceeded Pd_max=%g\n",
pd, model->DIOpd_max);
warns_pd++;
}
te = here->DIOtemp - CONSTCtoK;
if (te > model->DIOte_max)
if (warns_te < maxwarns) {
soa_printf(ckt, (GENinstance*) here,
"Te=%g has exceeded te_max=%g\n",
te, model->DIOte_max);
warns_te++;
}
}
}