introduce IBE and IBC model parameter for more accurate current calculation
This commit is contained in:
parent
231e6218a5
commit
01fb0ac18b
|
|
@ -82,6 +82,8 @@ IFparm BJTmPTable[] = { /* model parameters */
|
|||
IOP("tnom", BJT_MOD_TNOM, IF_REAL, "Parameter measurement temperature"),
|
||||
IOPR("tref", BJT_MOD_TNOM, IF_REAL, "Parameter measurement temperature"),
|
||||
IOP("is", BJT_MOD_IS, IF_REAL, "Saturation Current"),
|
||||
IOP("ibe", BJT_MOD_IBE, IF_REAL, "Base-Emitter saturation Current"),
|
||||
IOP("ibc", BJT_MOD_IBC, IF_REAL, "Base-Collector saturation Current"),
|
||||
IOP("bf", BJT_MOD_BF, IF_REAL, "Ideal forward beta"),
|
||||
IOP("nf", BJT_MOD_NF, IF_REAL, "Forward emission coefficient"),
|
||||
IOP("vaf", BJT_MOD_VAF, IF_REAL, "Forward Early voltage"),
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ typedef struct sBJTinstance {
|
|||
double BJTtemp; /* instance temperature */
|
||||
double BJTdtemp; /* instance delta temperature from circuit */
|
||||
double BJTtSatCur; /* temperature adjusted saturation current */
|
||||
double BJTBEtSatCur; /* temperature adjusted saturation current */
|
||||
double BJTBCtSatCur; /* temperature adjusted saturation current */
|
||||
double BJTtBetaF; /* temperature adjusted forward beta */
|
||||
double BJTtBetaR; /* temperature adjusted reverse beta */
|
||||
double BJTtBEleakCur; /* temperature adjusted B-E leakage current */
|
||||
|
|
@ -371,6 +373,8 @@ typedef struct sBJTmodel { /* model structure for a bjt */
|
|||
|
||||
double BJTtnom; /* nominal temperature */
|
||||
double BJTsatCur; /* input - don't use */
|
||||
double BJTBEsatCur;
|
||||
double BJTBCsatCur;
|
||||
double BJTbetaF; /* input - don't use */
|
||||
double BJTemissionCoeffF;
|
||||
double BJTearlyVoltF;
|
||||
|
|
@ -505,6 +509,8 @@ typedef struct sBJTmodel { /* model structure for a bjt */
|
|||
unsigned BJTsubsGiven : 1;
|
||||
unsigned BJTtnomGiven : 1;
|
||||
unsigned BJTsatCurGiven : 1;
|
||||
unsigned BJTBEsatCurGiven : 1;
|
||||
unsigned BJTBCsatCurGiven : 1;
|
||||
unsigned BJTbetaFGiven : 1;
|
||||
unsigned BJTemissionCoeffFGiven : 1;
|
||||
unsigned BJTearlyVoltFGiven : 1;
|
||||
|
|
@ -659,6 +665,8 @@ enum {
|
|||
BJT_MOD_NPN = 101,
|
||||
BJT_MOD_PNP,
|
||||
BJT_MOD_IS,
|
||||
BJT_MOD_IBE,
|
||||
BJT_MOD_IBC,
|
||||
BJT_MOD_BF,
|
||||
BJT_MOD_NF,
|
||||
BJT_MOD_VAF,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double cbe;
|
||||
double cben;
|
||||
double cdis;
|
||||
double csat;
|
||||
double csatbe, csatbc;
|
||||
double ctot;
|
||||
double czbc;
|
||||
double czbcf2;
|
||||
|
|
@ -153,7 +153,8 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* dc model paramters
|
||||
*/
|
||||
csat=here->BJTtSatCur*here->BJTarea * here->BJTm;
|
||||
csatbe=here->BJTBEtSatCur*here->BJTarea * here->BJTm;
|
||||
csatbc=here->BJTBCtSatCur*here->BJTarea * here->BJTm;
|
||||
rbpr=here->BJTtminBaseResist/(here->BJTarea * here->BJTm);
|
||||
rbpi=here->BJTtbaseResist/(here->BJTarea * here->BJTm)-rbpr;
|
||||
oik=here->BJTtinvRollOffF/(here->BJTarea * here->BJTm);
|
||||
|
|
@ -228,9 +229,9 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
vtn=vt*here->BJTtemissionCoeffF;
|
||||
if(vbe > -5*vtn){
|
||||
evbe=exp(vbe/vtn);
|
||||
cbe=csat*(evbe-1)+ckt->CKTgmin*vbe;
|
||||
gbe=csat*evbe/vtn+ckt->CKTgmin;
|
||||
gbe2 = csat*evbe/vtn/vtn;
|
||||
cbe=csatbe*(evbe-1)+ckt->CKTgmin*vbe;
|
||||
gbe=csatbe*evbe/vtn+ckt->CKTgmin;
|
||||
gbe2 = csatbe*evbe/vtn/vtn;
|
||||
gbe3 = gbe2/vtn;
|
||||
|
||||
/* note - these are actually derivs, not Taylor
|
||||
|
|
@ -247,7 +248,7 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
gben3=gben2/vte;
|
||||
}
|
||||
} else {
|
||||
gbe = -csat/vbe+ckt->CKTgmin;
|
||||
gbe = -csatbe/vbe+ckt->CKTgmin;
|
||||
gbe2=gbe3=gben2=gben3=0;
|
||||
cbe=gbe*vbe;
|
||||
gben = -c2/vbe;
|
||||
|
|
@ -256,9 +257,9 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
vtn=vt*here->BJTtemissionCoeffR;
|
||||
if(vbc > -5*vtn) {
|
||||
evbc=exp(vbc/vtn);
|
||||
cbc=csat*(evbc-1)+ckt->CKTgmin*vbc;
|
||||
gbc=csat*evbc/vtn+ckt->CKTgmin;
|
||||
gbc2=csat*evbc/vtn/vtn;
|
||||
cbc=csatbc*(evbc-1)+ckt->CKTgmin*vbc;
|
||||
gbc=csatbc*evbc/vtn+ckt->CKTgmin;
|
||||
gbc2=csatbc*evbc/vtn/vtn;
|
||||
gbc3=gbc2/vtn;
|
||||
if (c4 == 0) {
|
||||
cbcn=0;
|
||||
|
|
@ -272,7 +273,7 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt)
|
|||
gbcn3=gbcn2/vtc;
|
||||
}
|
||||
} else {
|
||||
gbc = -csat/vbc+ckt->CKTgmin;
|
||||
gbc = -csatbc/vbc+ckt->CKTgmin;
|
||||
gbc2=gbc3=0;
|
||||
cbc = gbc*vbc;
|
||||
gbcn = -c4/vbc;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double geqsub;
|
||||
double ceqsub;
|
||||
double cex;
|
||||
double csat;
|
||||
double csatbe, csatbc;
|
||||
double csubsat;
|
||||
double ctot;
|
||||
double czbc;
|
||||
|
|
@ -172,7 +172,8 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* dc model paramters
|
||||
*/
|
||||
csat=here->BJTtSatCur*here->BJTarea;
|
||||
csatbe=here->BJTBEtSatCur*here->BJTarea;
|
||||
csatbc=here->BJTBCtSatCur*here->BJTarea;
|
||||
csubsat=here->BJTtSubSatCur*here->BJTarea;
|
||||
rbpr=here->BJTtminBaseResist/here->BJTarea;
|
||||
rbpi=here->BJTtbaseResist/here->BJTarea-rbpr;
|
||||
|
|
@ -451,13 +452,13 @@ next1: vtn=vt*here->BJTtemissionCoeffF;
|
|||
|
||||
if(vbe >= -3*vtn){
|
||||
evbe=exp(vbe/vtn);
|
||||
cbe=csat*(evbe-1);
|
||||
gbe=csat*evbe/vtn;
|
||||
cbe=csatbe*(evbe-1);
|
||||
gbe=csatbe*evbe/vtn;
|
||||
} else {
|
||||
arg=3*vtn/(vbe*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cbe = -csat*(1+arg);
|
||||
gbe = csat*3*arg/vbe;
|
||||
cbe = -csatbe*(1+arg);
|
||||
gbe = csatbe*3*arg/vbe;
|
||||
}
|
||||
if (c2 == 0) {
|
||||
cben=0;
|
||||
|
|
@ -481,13 +482,13 @@ next1: vtn=vt*here->BJTtemissionCoeffF;
|
|||
|
||||
if(vbc >= -3*vtn) {
|
||||
evbc=exp(vbc/vtn);
|
||||
cbc=csat*(evbc-1);
|
||||
gbc=csat*evbc/vtn;
|
||||
cbc=csatbc*(evbc-1);
|
||||
gbc=csatbc*evbc/vtn;
|
||||
} else {
|
||||
arg=3*vtn/(vbc*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cbc = -csat*(1+arg);
|
||||
gbc = csat*3*arg/vbc;
|
||||
cbc = -csatbc*(1+arg);
|
||||
gbc = csatbc*3*arg/vbc;
|
||||
}
|
||||
if (c4 == 0) {
|
||||
cbcn=0;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ BJTmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
|
|||
case BJT_MOD_IS:
|
||||
value->rValue = here->BJTsatCur;
|
||||
return(OK);
|
||||
case BJT_MOD_IBE:
|
||||
value->rValue = here->BJTBEsatCur;
|
||||
return(OK);
|
||||
case BJT_MOD_IBC:
|
||||
value->rValue = here->BJTBCsatCur;
|
||||
return(OK);
|
||||
case BJT_MOD_BF:
|
||||
value->rValue = here->BJTbetaF;
|
||||
return(OK);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@ BJTmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
mods->BJTsatCur = value->rValue;
|
||||
mods->BJTsatCurGiven = TRUE;
|
||||
break;
|
||||
case BJT_MOD_IBE:
|
||||
mods->BJTBEsatCur = value->rValue;
|
||||
mods->BJTBEsatCurGiven = TRUE;
|
||||
break;
|
||||
case BJT_MOD_IBC:
|
||||
mods->BJTBCsatCur = value->rValue;
|
||||
mods->BJTBCsatCurGiven = TRUE;
|
||||
break;
|
||||
case BJT_MOD_BF:
|
||||
mods->BJTbetaF = value->rValue;
|
||||
mods->BJTbetaFGiven = TRUE;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
if(!model->BJTsatCurGiven) {
|
||||
model->BJTsatCur = 1e-16;
|
||||
}
|
||||
if(!model->BJTBEsatCurGiven) {
|
||||
model->BJTBEsatCur = model->BJTsatCur;
|
||||
}
|
||||
if(!model->BJTBCsatCurGiven) {
|
||||
model->BJTBCsatCur = model->BJTsatCur;
|
||||
}
|
||||
if(!model->BJTbetaFGiven) {
|
||||
model->BJTbetaF = 100;
|
||||
}
|
||||
|
|
@ -396,19 +402,6 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
model->BJTteMax = 1e99;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* COMPATABILITY WARNING!
|
||||
* special note: for backward compatability to much older models, spice 2G
|
||||
* implemented a special case which checked if B-E leakage saturation
|
||||
* current was >1, then it was instead a the B-E leakage saturation current
|
||||
* divided by IS, and multiplied it by IS at this point. This was not
|
||||
* handled correctly in the 2G code, and there is some question on its
|
||||
* reasonability, since it is also undocumented, so it has been left out
|
||||
* here. It could easily be added with 1 line. (The same applies to the B-C
|
||||
* leakage saturation current). TQ 6/29/84
|
||||
*/
|
||||
|
||||
/* loop through all the instances of the model */
|
||||
for (here = BJTinstances(model); here != NULL ;
|
||||
here=BJTnextInstance(here)) {
|
||||
|
|
|
|||
|
|
@ -146,6 +146,14 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if ((model->BJTtlev == 0) || (model->BJTtlev == 1)) {
|
||||
factor = exp(factlog);
|
||||
here->BJTtSatCur = model->BJTsatCur * factor;
|
||||
if (model->BJTBEsatCurGiven) {
|
||||
factor = exp(factlog / model->BJTemissionCoeffF);
|
||||
here->BJTBEtSatCur = model->BJTBEsatCur * factor;
|
||||
}
|
||||
if (model->BJTBCsatCurGiven) {
|
||||
factor = exp(factlog / model->BJTemissionCoeffR);
|
||||
here->BJTBCtSatCur = model->BJTBCsatCur * factor;
|
||||
}
|
||||
if (model->BJTsubSatCurGiven)
|
||||
here->BJTtSubSatCur = model->BJTsubSatCur * factor;
|
||||
} else if (model->BJTtlev == 3) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue