diff --git a/src/spicelib/devices/dio/dio.c b/src/spicelib/devices/dio/dio.c index f58fc5a3f..663af176c 100644 --- a/src/spicelib/devices/dio/dio.c +++ b/src/spicelib/devices/dio/dio.c @@ -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"), diff --git a/src/spicelib/devices/dio/diodefs.h b/src/spicelib/devices/dio/diodefs.h index 1fb122c31..648767bb5 100644 --- a/src/spicelib/devices/dio/diodefs.h +++ b/src/spicelib/devices/dio/diodefs.h @@ -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, diff --git a/src/spicelib/devices/dio/diomask.c b/src/spicelib/devices/dio/diomask.c index c05476c71..cb9da53f8 100644 --- a/src/spicelib/devices/dio/diomask.c +++ b/src/spicelib/devices/dio/diomask.c @@ -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); diff --git a/src/spicelib/devices/dio/diompar.c b/src/spicelib/devices/dio/diompar.c index 66b351d66..b24aa10d3 100644 --- a/src/spicelib/devices/dio/diompar.c +++ b/src/spicelib/devices/dio/diompar.c @@ -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; diff --git a/src/spicelib/devices/dio/diosetup.c b/src/spicelib/devices/dio/diosetup.c index 83dca48f7..a657a1f15 100644 --- a/src/spicelib/devices/dio/diosetup.c +++ b/src/spicelib/devices/dio/diosetup.c @@ -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; } diff --git a/src/spicelib/devices/dio/diosoachk.c b/src/spicelib/devices/dio/diosoachk.c index 410c00996..6c2bda16d 100644 --- a/src/spicelib/devices/dio/diosoachk.c +++ b/src/spicelib/devices/dio/diosoachk.c @@ -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++; + } + } }