Add operating point information to SOA check,
using vbefwd, vbcfwd, and vsubfwd Operating point heck is enabled by .options warn=2
This commit is contained in:
parent
443567dbaf
commit
c30af55491
|
|
@ -187,6 +187,9 @@ IFparm VBICmPTable[] = { /* model parameters */
|
|||
IOPR("bvce", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch"),
|
||||
IOP("vsub_max", VBIC_MOD_VSUB_MAX, IF_REAL, "maximum voltage C-substrate branch"),
|
||||
IOPR("bvsub", VBIC_MOD_VSUB_MAX, IF_REAL, "maximum voltage C-substrate branch"),
|
||||
IOP("vbefwd", VBIC_MOD_VBEFWD_MAX, IF_REAL, "maximum forward voltage B-E junction"),
|
||||
IOP("vbcfwd", VBIC_MOD_VBCFWD_MAX, IF_REAL, "maximum forward voltage B-C junction"),
|
||||
IOP("vsubfwd", VBIC_MOD_VSUBFWD_MAX, IF_REAL, "maximum forward voltage C-substrate junction"),
|
||||
IOP("selft", VBIC_MOD_SELFT, IF_INTEGER, "0: self-heating off, 1: self-heating on")
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -486,6 +486,9 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
double VBICvbcMax; /* maximum voltage over B-C junction */
|
||||
double VBICvceMax; /* maximum voltage over C-E branch */
|
||||
double VBICvsubMax; /* maximum voltage over C-substrate branch */
|
||||
double VBICvbcfwdMax; /* maximum forward voltage over B-C junction */
|
||||
double VBICvbefwdMax; /* maximum forward voltage over C-E branch */
|
||||
double VBICvsubfwdMax; /* maximum forward voltage over C-substrate branch */
|
||||
|
||||
unsigned VBICtnomGiven : 1;
|
||||
unsigned VBICextCollResistGiven : 1;
|
||||
|
|
@ -602,6 +605,9 @@ typedef struct sVBICmodel { /* model structure for a vbic */
|
|||
unsigned VBICvbcMaxGiven : 1;
|
||||
unsigned VBICvceMaxGiven : 1;
|
||||
unsigned VBICvsubMaxGiven : 1;
|
||||
unsigned VBICvbcfwdMaxGiven : 1;
|
||||
unsigned VBICvbefwdMaxGiven : 1;
|
||||
unsigned VBICvsubfwdMaxGiven : 1;
|
||||
} VBICmodel;
|
||||
|
||||
#ifndef NPN
|
||||
|
|
@ -739,6 +745,9 @@ enum {
|
|||
VBIC_MOD_VBC_MAX,
|
||||
VBIC_MOD_VCE_MAX,
|
||||
VBIC_MOD_VSUB_MAX,
|
||||
VBIC_MOD_VBEFWD_MAX,
|
||||
VBIC_MOD_VBCFWD_MAX,
|
||||
VBIC_MOD_VSUBFWD_MAX,
|
||||
VBIC_MOD_SELFT,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -366,6 +366,15 @@ VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
|
|||
case VBIC_MOD_VSUB_MAX:
|
||||
value->rValue = here->VBICvsubMax;
|
||||
return(OK);
|
||||
case VBIC_MOD_VBEFWD_MAX:
|
||||
value->rValue = here->VBICvbefwdMax;
|
||||
return(OK);
|
||||
case VBIC_MOD_VBCFWD_MAX:
|
||||
value->rValue = here->VBICvbcfwdMax;
|
||||
return(OK);
|
||||
case VBIC_MOD_VSUBFWD_MAX:
|
||||
value->rValue = here->VBICvsubfwdMax;
|
||||
return(OK);
|
||||
case VBIC_MOD_TYPE:
|
||||
if (here->VBICtype == NPN)
|
||||
value->sValue = "npn";
|
||||
|
|
|
|||
|
|
@ -513,6 +513,18 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
mods->VBICvsubMax = value->rValue;
|
||||
mods->VBICvsubMaxGiven = TRUE;
|
||||
break;
|
||||
case VBIC_MOD_VBEFWD_MAX:
|
||||
mods->VBICvbefwdMax = value->rValue;
|
||||
mods->VBICvbefwdMaxGiven = TRUE;
|
||||
break;
|
||||
case VBIC_MOD_VBCFWD_MAX:
|
||||
mods->VBICvbcfwdMax = value->rValue;
|
||||
mods->VBICvbcfwdMaxGiven = TRUE;
|
||||
break;
|
||||
case VBIC_MOD_VSUBFWD_MAX:
|
||||
mods->VBICvsubfwdMax = value->rValue;
|
||||
mods->VBICvsubfwdMaxGiven = TRUE;
|
||||
break;
|
||||
case VBIC_MOD_SELFT:
|
||||
mods->VBICselft = value->iValue;
|
||||
mods->VBICselftGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -391,6 +391,18 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->VBICvceMaxGiven) {
|
||||
model->VBICvceMax = 1e99;
|
||||
}
|
||||
if(!model->VBICvsubMaxGiven) {
|
||||
model->VBICvsubMax = 1e99;
|
||||
}
|
||||
if (!model->VBICvbefwdMaxGiven) {
|
||||
model->VBICvbefwdMax = 0.2;
|
||||
}
|
||||
if (!model->VBICvbcfwdMaxGiven) {
|
||||
model->VBICvbcfwdMax = 0.2;
|
||||
}
|
||||
if (!model->VBICvsubfwdMaxGiven) {
|
||||
model->VBICvsubfwdMax = 0.2;
|
||||
}
|
||||
if(!model->VBICselftGiven) {
|
||||
model->VBICselft = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,14 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
VBICinstance *here;
|
||||
double vbe, vbc, vce, vsub; /* actual bjt voltages */
|
||||
int maxwarns;
|
||||
static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0, warns_vsub = 0;
|
||||
static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0, warns_vsub = 0, warns_op = 0;
|
||||
|
||||
if (!ckt) {
|
||||
warns_vbe = 0;
|
||||
warns_vbc = 0;
|
||||
warns_vce = 0;
|
||||
warns_vsub = 0;
|
||||
warns_op = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
@ -33,48 +34,95 @@ VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
|
|||
|
||||
for (; model; model = VBICnextModel(model)) {
|
||||
|
||||
for (here = VBICinstances(model); here; here=VBICnextInstance(here)) {
|
||||
for (here = VBICinstances(model); here; here = VBICnextInstance(here)) {
|
||||
|
||||
vbe = fabs(ckt->CKTrhsOld [here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld [here->VBICemitNode]);
|
||||
vbc = fabs(ckt->CKTrhsOld [here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld [here->VBICcollNode]);
|
||||
vce = fabs(ckt->CKTrhsOld [here->VBICcollNode] -
|
||||
ckt->CKTrhsOld [here->VBICemitNode]);
|
||||
vsub = fabs(ckt->CKTrhsOld [here->VBICcollNode] -
|
||||
ckt->CKTrhsOld [here->VBICsubsNode]);
|
||||
vbe = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld[here->VBICemitNode]);
|
||||
vbc = fabs(ckt->CKTrhsOld[here->VBICbaseNode] -
|
||||
ckt->CKTrhsOld[here->VBICcollNode]);
|
||||
vce = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
|
||||
ckt->CKTrhsOld[here->VBICemitNode]);
|
||||
vsub = fabs(ckt->CKTrhsOld[here->VBICcollNode] -
|
||||
ckt->CKTrhsOld[here->VBICsubsNode]);
|
||||
|
||||
if (vbe > model->VBICvbeMax)
|
||||
if (warns_vbe < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vbe|=%g has exceeded Vbe_max=%g\n",
|
||||
vbe, model->VBICvbeMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vbe|=%g has exceeded Vbe_max=%g\n",
|
||||
vbe, model->VBICvbeMax);
|
||||
warns_vbe++;
|
||||
}
|
||||
|
||||
if (vbc > model->VBICvbcMax)
|
||||
if (warns_vbc < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vbc|=%g has exceeded Vbc_max=%g\n",
|
||||
vbc, model->VBICvbcMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vbc|=%g has exceeded Vbc_max=%g\n",
|
||||
vbc, model->VBICvbcMax);
|
||||
warns_vbc++;
|
||||
}
|
||||
|
||||
if (vce > model->VBICvceMax)
|
||||
if (warns_vce < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vce, model->VBICvceMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vce, model->VBICvceMax);
|
||||
warns_vce++;
|
||||
}
|
||||
|
||||
if (vsub > model->VBICvsubMax)
|
||||
if (warns_vsub < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*) here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vsub, model->VBICvsubMax);
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"|Vce|=%g has exceeded Vce_max=%g\n",
|
||||
vsub, model->VBICvsubMax);
|
||||
warns_vsub++;
|
||||
}
|
||||
|
||||
/* substrate diode is forward biased */
|
||||
if (model->VBICtype * (ckt->CKTrhsOld[here->VBICsubsNode] -
|
||||
ckt->CKTrhsOld[here->VBICcollNode]) > model->VBICvsubfwdMax) {
|
||||
/* substrate leakage */
|
||||
if (warns_vsub < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"substrate juntion is forward biased\n");
|
||||
warns_vsub++;
|
||||
}
|
||||
}
|
||||
|
||||
/* operating point information */
|
||||
if (ckt->CKTsoaCheck == 2) {
|
||||
if (vbe <= model->VBICvbefwdMax && vbc <= model->VBICvbefwdMax) {
|
||||
/*off*/
|
||||
if (warns_op < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"device is off\n");
|
||||
warns_op++;
|
||||
}
|
||||
}
|
||||
else if (vbe > model->VBICvbefwdMax && vbc > model->VBICvbefwdMax) {
|
||||
/*saturation*/
|
||||
if (warns_op < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"device is in sturation\n");
|
||||
warns_op++;
|
||||
}
|
||||
}
|
||||
else if (vbe > model->VBICvbefwdMax && vbc <= model->VBICvbefwdMax) {
|
||||
/*forward*/
|
||||
if (warns_op < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"device is forward biased\n");
|
||||
warns_op++;
|
||||
}
|
||||
}
|
||||
else if (vbe <= model->VBICvbefwdMax && vbc > model->VBICvbefwdMax) {
|
||||
/*reverse*/
|
||||
if (warns_op < maxwarns) {
|
||||
soa_printf(ckt, (GENinstance*)here,
|
||||
"device is reverse biased\n");
|
||||
warns_op++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue