Browse Source

SOA for bipolar

Replace pow_max by pd_max
pre-master-46
Holger Vogt 5 years ago
parent
commit
7c84e3f993
  1. 2
      examples/soa/bjt-soa.cir
  2. 2
      src/spicelib/devices/bjt/bjt.c
  3. 6
      src/spicelib/devices/bjt/bjtdefs.h
  4. 4
      src/spicelib/devices/bjt/bjtmask.c
  5. 6
      src/spicelib/devices/bjt/bjtmpar.c
  6. 4
      src/spicelib/devices/bjt/bjtsetup.c
  7. 44
      src/spicelib/devices/bjt/bjtsoachk.c

2
examples/soa/bjt-soa.cir

@ -6,7 +6,7 @@ Ve e 0 0
Q1 c b e MPSA92
.MODEL MPSA92 PNP(IS=9.53E-14 ISE=8.37E-13 ISC=9.99E-11 XTI=3.00 BF=9.80E1 BR=4.78 IKF=3.49E-2 IKR=1.00 XTB=1.5 VAF=2.60E2 VAR=1.40E2 VJE=3.00E-1 VJC=3.00E-1 RE=1.00E-2 RC=1.00E-2 RB=2.76E1 RBM=6.66E-2 IRB=7.02E-4 CJE=9.54E-11 CJC=4.66E-11 .00 FC=5.00E-1 NF=1.00 NR=1.55 NE=1.49 NC=1.50 MJE=4.26E-1 MJC=7.00E-1 TF=9.52E-10 TR=516.9p ITF=4.12E-1 VTF=9.99E5 XTF=1.03 EG=1.11 VCEO=300 ICRATING=500m MFG=SIEMENS pow_max=0.625 rth0=200 tnom=25)
.MODEL MPSA92 PNP(IS=9.53E-14 ISE=8.37E-13 ISC=9.99E-11 XTI=3.00 BF=9.80E1 BR=4.78 IKF=3.49E-2 IKR=1.00 XTB=1.5 VAF=2.60E2 VAR=1.40E2 VJE=3.00E-1 VJC=3.00E-1 RE=1.00E-2 RC=1.00E-2 RB=2.76E1 RBM=6.66E-2 IRB=7.02E-4 CJE=9.54E-11 CJC=4.66E-11 .00 FC=5.00E-1 NF=1.00 NR=1.55 NE=1.49 NC=1.50 MJE=4.26E-1 MJC=7.00E-1 TF=9.52E-10 TR=516.9p ITF=4.12E-1 VTF=9.99E5 XTF=1.03 EG=1.11 VCEO=300 ICRATING=500m MFG=SIEMENS pd_max=0.625 rth0=200 tnom=25)
.option warn=1 maxwarns=2
.temp 50

2
src/spicelib/devices/bjt/bjt.c

@ -230,7 +230,7 @@ IFparm BJTmPTable[] = { /* model parameters */
IOP("vbe_max", BJT_MOD_VBE_MAX, IF_REAL, "maximum voltage B-E junction"),
IOP("vbc_max", BJT_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"),
IOP("vce_max", BJT_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch"),
IOP("pow_max", BJT_MOD_POW_MAX, IF_REAL, "maximum device power dissipation"),
IOP("pd_max", BJT_MOD_PD_MAX, IF_REAL, "maximum device power dissipation"),
IOP("ic_max", BJT_MOD_IC_MAX, IF_REAL, "maximum collector current"),
IOP("ib_max", BJT_MOD_IB_MAX, IF_REAL, "maximum base current"),
IOP("te_max", BJT_MOD_TE_MAX, IF_REAL, "maximum temperature"),

6
src/spicelib/devices/bjt/bjtdefs.h

@ -500,7 +500,7 @@ typedef struct sBJTmodel { /* model structure for a bjt */
double BJTvceMax; /* maximum voltage over C-E branch */
double BJTicMax; /* maximum collector current */
double BJTibMax; /* maximum base current */
double BJTpowMax; /* maximum device power dissipation */
double BJTpdMax; /* maximum device power dissipation */
double BJTteMax; /* maximum device temperature */
double BJTrth0; /* thermal resistance juntion to ambient */
@ -622,7 +622,7 @@ typedef struct sBJTmodel { /* model structure for a bjt */
unsigned BJTvbeMaxGiven : 1;
unsigned BJTvbcMaxGiven : 1;
unsigned BJTvceMaxGiven : 1;
unsigned BJTpowMaxGiven : 1;
unsigned BJTpdMaxGiven : 1;
unsigned BJTicMaxGiven : 1;
unsigned BJTibMaxGiven : 1;
unsigned BJTteMaxGiven : 1;
@ -780,7 +780,7 @@ enum {
BJT_MOD_VBE_MAX,
BJT_MOD_VBC_MAX,
BJT_MOD_VCE_MAX,
BJT_MOD_POW_MAX,
BJT_MOD_PD_MAX,
BJT_MOD_IC_MAX,
BJT_MOD_IB_MAX,
BJT_MOD_TE_MAX,

4
src/spicelib/devices/bjt/bjtmask.c

@ -422,8 +422,8 @@ BJTmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case BJT_MOD_IB_MAX:
value->rValue = here->BJTibMax;
return(OK);
case BJT_MOD_POW_MAX:
value->rValue = here->BJTpowMax;
case BJT_MOD_PD_MAX:
value->rValue = here->BJTpdMax;
case BJT_MOD_RTH0:
value->rValue = here->BJTrth0;
return(OK);

6
src/spicelib/devices/bjt/bjtmpar.c

@ -514,9 +514,9 @@ BJTmParam(int param, IFvalue *value, GENmodel *inModel)
mods->BJTibMax = value->rValue;
mods->BJTibMaxGiven = TRUE;
break;
case BJT_MOD_POW_MAX:
mods->BJTpowMax = value->rValue;
mods->BJTpowMaxGiven = TRUE;
case BJT_MOD_PD_MAX:
mods->BJTpdMax = value->rValue;
mods->BJTpdMaxGiven = TRUE;
break;
case BJT_MOD_TE_MAX:
mods->BJTteMax = value->rValue;

4
src/spicelib/devices/bjt/bjtsetup.c

@ -375,8 +375,8 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if(!model->BJTibMaxGiven) {
model->BJTibMax = 1e99;
}
if(!model->BJTpowMaxGiven) {
model->BJTpowMax = 1e99;
if(!model->BJTpdMaxGiven) {
model->BJTpdMax = 1e99;
}
if(!model->BJTteMaxGiven) {
model->BJTteMax = 1e99;

44
src/spicelib/devices/bjt/bjtsoachk.c

@ -18,18 +18,18 @@ BJTsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
BJTmodel *model = (BJTmodel *) inModel;
BJTinstance *here;
double vbe, vbc, vce; /* actual bjt voltages */
double pow;
double pd;
double ic, ib; /* actual bjt currents */
int maxwarns;
static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0;
static int warns_pow = 0, warns_ic = 0, warns_ib = 0;
static int warns_pd = 0, warns_ic = 0, warns_ib = 0;
if (!ckt) {
warns_vbe = 0;
warns_vbc = 0;
warns_vce = 0;
warns_pow = 0;
warns_pd = 0;
warns_ic = 0;
warns_ib = 0;
return OK;
@ -90,49 +90,49 @@ BJTsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
warns_ib++;
}
if (warns_pow < maxwarns) {
pow = fabs(*(ckt->CKTstate0 + here->BJTcc) *
if (warns_pd < maxwarns) {
pd = fabs(*(ckt->CKTstate0 + here->BJTcc) *
(*(ckt->CKTrhsOld + here->BJTcolNode) -
*(ckt->CKTrhsOld + here->BJTemitNode))
);
pow += fabs(*(ckt->CKTstate0 + here->BJTcb) *
pd += fabs(*(ckt->CKTstate0 + here->BJTcb) *
(*(ckt->CKTrhsOld + here->BJTbaseNode) -
*(ckt->CKTrhsOld + here->BJTemitNode))
);
pow += fabs(*(ckt->CKTstate0 + here->BJTcdsub) *
pd += fabs(*(ckt->CKTstate0 + here->BJTcdsub) *
(*(ckt->CKTrhsOld + here->BJTsubstConNode) -
*(ckt->CKTrhsOld + here->BJTsubstNode))
);
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && !(ckt->CKTmode &
MODETRANOP)) {
pow += *(ckt->CKTstate0 + here->BJTcqsub) *
pd += *(ckt->CKTstate0 + here->BJTcqsub) *
fabs(*(ckt->CKTrhsOld + here->BJTsubstConNode) -
*(ckt->CKTrhsOld + here->BJTsubstNode));
}
pow *= here->BJTm;
pd *= here->BJTm;
/* derating without self-heating, external temp and model tnom given */
if (model->BJTrth0Given && model->BJTpowMaxGiven && model->BJTtnomGiven) {
double pow_max;
if (model->BJTrth0Given && model->BJTpdMaxGiven && model->BJTtnomGiven) {
double pd_max;
if (here->BJTtemp < model->BJTtnom)
pow_max = model->BJTpowMax;
pd_max = model->BJTpdMax;
else {
pow_max = model->BJTpowMax - (here->BJTtemp - model->BJTtnom) / model->BJTrth0;
pow_max = (pow_max > 0) ? pow_max : 0.;
pd_max = model->BJTpdMax - (here->BJTtemp - model->BJTtnom) / model->BJTrth0;
pd_max = (pd_max > 0) ? pd_max : 0.;
}
if (pow > pow_max) {
if (pd > pd_max) {
soa_printf(ckt, (GENinstance*)here,
"Pow=%.4g W has exceeded Pow_max=%.4g W\n at Vce=%.4g V, Ib=%.4g A, Ic=%.4g A, and Te=%.4g C\n",
pow, pow_max, vce, ib, ic, here->BJTtemp - CONSTCtoK);
warns_pow++;
"Pd=%.4g W has exceeded Pd_max=%.4g W\n at Vce=%.4g V, Ib=%.4g A, Ic=%.4g A, and Te=%.4g C\n",
pow, pd_max, vce, ib, ic, here->BJTtemp - CONSTCtoK);
warns_pd++;
}
}
/* no derating */
else {
if (pow > model->BJTpowMax) {
if (pd > model->BJTpdMax) {
soa_printf(ckt, (GENinstance*)here,
"Pow=%.4g W has exceeded Pow_max=%.4g W\n at Vce=%.4g V, Ib=%.4g A, and Ic=%.4g A\n",
pow, model->BJTpowMax, vce, ib, ic);
warns_pow++;
"Pd=%.4g W has exceeded Pd_max=%.4g W\n at Vce=%.4g V, Ib=%.4g A, and Ic=%.4g A\n",
pd, model->BJTpdMax, vce, ib, ic);
warns_pd++;
}
}
}

Loading…
Cancel
Save