correct the diode temperature model
This commit is contained in:
parent
c0e2d4abef
commit
fb23e1f024
|
|
@ -25,7 +25,7 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double arg;
|
||||
double argsw;
|
||||
double capd;
|
||||
double cd, cdsw=0.0;
|
||||
double cd;
|
||||
double cdeq;
|
||||
double cdhat;
|
||||
double ceq;
|
||||
|
|
@ -44,9 +44,8 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
|
||||
double delvd; /* change in diode voltage temporary */
|
||||
double evd;
|
||||
double evdsw;
|
||||
double evrev;
|
||||
double gd, gdsw=0.0;
|
||||
double gd;
|
||||
double geq;
|
||||
double gspr; /* area-scaled conductance */
|
||||
double sarg;
|
||||
|
|
@ -85,6 +84,8 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#endif /* SENSDEBUG */
|
||||
|
||||
}
|
||||
cd = 0.0;
|
||||
gd = 0.0;
|
||||
csat = here->DIOtSatCur;
|
||||
csatsw = here->DIOtSatSWCur;
|
||||
gspr = here->DIOtConductance * here->DIOarea;
|
||||
|
|
@ -188,60 +189,35 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/*
|
||||
* compute dc current and derivitives
|
||||
*/
|
||||
next1: if (model->DIOsatSWCurGiven) { /* consider sidewall currents */
|
||||
next1: if (model->DIOsatSWCurGiven) { /* sidewall current */
|
||||
|
||||
if (model->DIOswEmissionCoeffGiven) { /* sidewall currents with own characteristic */
|
||||
if (model->DIOswEmissionCoeffGiven) { /* current with own characteristic */
|
||||
|
||||
vtesw = model->DIOswEmissionCoeff * vt;
|
||||
|
||||
if (vd >= -3*vtesw) { /* sidewall forward */
|
||||
if (vd >= -3*vtesw) { /* forward */
|
||||
|
||||
evdsw = exp(vd/vtesw);
|
||||
cdsw = csatsw*(evdsw-1);
|
||||
gdsw = csatsw*evdsw/vtesw;
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evd - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evd / vtetun;
|
||||
}
|
||||
evd = exp(vd/vtesw);
|
||||
cd = csatsw*(evd-1);
|
||||
gd = csatsw*evd/vtesw;
|
||||
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) || /* sidewall reverse */
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) ||
|
||||
vd >= -here->DIOtBrkdwnV) { /* reverse */
|
||||
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
evdsw = exp(vd/vtesw);
|
||||
cdsw = csatsw*(evdsw-1);
|
||||
gdsw = csatsw*evdsw/vtesw;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evdsw = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evdsw - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evdsw / vtetun;
|
||||
} else {
|
||||
argsw = 3*vtesw/(vd*CONSTe);
|
||||
argsw = argsw * argsw * argsw;
|
||||
cdsw = -csatsw*(1+argsw);
|
||||
gdsw = csatsw*3*argsw/vd;
|
||||
}
|
||||
argsw = 3*vtesw/(vd*CONSTe);
|
||||
argsw = argsw * argsw * argsw;
|
||||
cd = -csatsw*(1+argsw);
|
||||
gd = csatsw*3*argsw/vd;
|
||||
|
||||
} else { /* sidewall breakdown */
|
||||
} else { /* breakdown */
|
||||
|
||||
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk);
|
||||
cdsw = -csatsw*evrev;
|
||||
gdsw = csatsw*evrev/vtebrk;
|
||||
if (model->DIOtunSatSWCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cdsw = cdsw - csatsw*(evd-1);
|
||||
gdsw = gdsw - csatsw*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cdsw = cdsw - here->DIOtTunSatSWCur * (evd - 1);
|
||||
gdsw = gdsw + here->DIOtTunSatSWCur * evd / vtetun;
|
||||
}
|
||||
cd = -csatsw*evrev;
|
||||
gd = csatsw*evrev/vtebrk;
|
||||
|
||||
}
|
||||
|
||||
} else { /* merge the current densities and use same characteristic as bottom diode */
|
||||
} else { /* merge saturation currents and use same characteristic as bottom diode */
|
||||
|
||||
csat = csat + csatsw;
|
||||
|
||||
|
|
@ -249,65 +225,50 @@ next1: if (model->DIOsatSWCurGiven) { /* consider sidewall currents */
|
|||
|
||||
}
|
||||
|
||||
if (vd >= -3*vte) { /* bottom forward */
|
||||
if (vd >= -3*vte) { /* bottom current forward */
|
||||
|
||||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1);
|
||||
gd = csat*evd/vte;
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
}
|
||||
cd = cd + csat*(evd-1);
|
||||
gd = gd + csat*evd/vte;
|
||||
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) || /* bottom reverse */
|
||||
vd >= -here->DIOtBrkdwnV) {
|
||||
} else if((!(model->DIObreakdownVoltageGiven)) ||
|
||||
vd >= -here->DIOtBrkdwnV) { /* reverse */
|
||||
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cd = csat*(evd-1);
|
||||
gd = csat*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
} else {
|
||||
arg = 3*vte/(vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cd = -csat*(1+arg);
|
||||
gd = csat*3*arg/vd;
|
||||
}
|
||||
arg = 3*vte/(vd*CONSTe);
|
||||
arg = arg * arg * arg;
|
||||
cd = cd - csat*(1+arg);
|
||||
gd = gd + csat*3*arg/vd;
|
||||
|
||||
} else { /* bottom breakdown */
|
||||
} else { /* breakdown */
|
||||
|
||||
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk);
|
||||
cd = -csat*evrev;
|
||||
gd = csat*evrev/vtebrk;
|
||||
if (model->DIOtunSatCurGiven) {
|
||||
evd = exp(vd/vte);
|
||||
cd = cd - csat*(evd-1);
|
||||
gd = gd - csat*evd/vte;
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
}
|
||||
cd = cd - csat*evrev;
|
||||
gd = gd + csat*evrev/vtebrk;
|
||||
|
||||
}
|
||||
|
||||
if (model->DIOsatSWCurGiven) {
|
||||
if (model->DIOtunSatSWCurGiven) { /* tunnel sidewall current */
|
||||
|
||||
if (model->DIOswEmissionCoeffGiven) {
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
|
||||
cd = cdsw + cd;
|
||||
gd = gdsw + gd;
|
||||
|
||||
}
|
||||
cd = cd - here->DIOtTunSatSWCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatSWCur * evd / vtetun;
|
||||
|
||||
}
|
||||
|
||||
if (vd >= -3*vte) { /* limit forward */
|
||||
if (model->DIOtunSatCurGiven) { /* tunnel bottom current */
|
||||
|
||||
vtetun = model->DIOtunEmissionCoeff * vt;
|
||||
evd = exp(-vd/vtetun);
|
||||
|
||||
cd = cd - here->DIOtTunSatCur * (evd - 1);
|
||||
gd = gd + here->DIOtTunSatCur * evd / vtetun;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (vd >= -3*vte) { /* limit forward */
|
||||
|
||||
if( (model->DIOforwardKneeCurrent > 0.0) && (cd > 1.0e-18) ) {
|
||||
ikf_area_m = here->DIOforwardKneeCurrent;
|
||||
|
|
@ -316,7 +277,7 @@ next1: if (model->DIOsatSWCurGiven) { /* consider sidewall currents */
|
|||
cd = cd/(1+sqrt_ikf) + ckt->CKTgmin;
|
||||
}
|
||||
|
||||
} else { /* limit reverse */
|
||||
} else { /* limit reverse */
|
||||
|
||||
if( (model->DIOreverseKneeCurrent > 0.0) && (cd < -1.0e-18) ) {
|
||||
ikr_area_m = here->DIOreverseKneeCurrent;
|
||||
|
|
|
|||
|
|
@ -178,9 +178,8 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
|||
}
|
||||
|
||||
here->DIOarea = here->DIOarea * here->DIOm;
|
||||
if (model->DIOlevel == 1) {
|
||||
here->DIOpj = here->DIOpj * here->DIOm;
|
||||
} else { /* level=3 */
|
||||
here->DIOpj = here->DIOpj * here->DIOm;
|
||||
if (model->DIOlevel == 3) {
|
||||
if((here->DIOwGiven) && (here->DIOlGiven)) {
|
||||
here->DIOarea = here->DIOw * here->DIOl * here->DIOm;
|
||||
here->DIOpj = (2 * here->DIOw + 2 * here->DIOl) * here->DIOm;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#endif
|
||||
double dt;
|
||||
double factor;
|
||||
double tBreakdownVoltage;
|
||||
|
||||
/* loop through all the diode models */
|
||||
for( ; model != NULL; model = model->DIOnextModel ) {
|
||||
|
|
@ -156,23 +157,23 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) +
|
||||
model->DIOsaturationCurrentExp/model->DIOemissionCoeff*
|
||||
model->DIOsaturationCurrentExp/model->DIOemissionCoeff *
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOactivationEnergy/(model->DIOswEmissionCoeff*vt) +
|
||||
model->DIOsaturationCurrentExp/model->DIOswEmissionCoeff*
|
||||
model->DIOsaturationCurrentExp/model->DIOswEmissionCoeff *
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
|
||||
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/(model->DIOtunEmissionCoeff*vt) +
|
||||
model->DIOtunSaturationCurrentExp/model->DIOtunEmissionCoeff*
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/vt +
|
||||
model->DIOtunSaturationCurrentExp *
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * exp(
|
||||
((here->DIOtemp/model->DIOnomTemp)-1) *
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/(model->DIOtunEmissionCoeff*vt) +
|
||||
model->DIOtunSaturationCurrentExp/model->DIOtunEmissionCoeff*
|
||||
model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy/vt +
|
||||
model->DIOtunSaturationCurrentExp *
|
||||
log(here->DIOtemp/model->DIOnomTemp) );
|
||||
|
||||
/* the defintion of f1, just recompute after temperature adjusting
|
||||
|
|
@ -191,9 +192,18 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
/* and now to compute the breakdown voltage, again, using
|
||||
* temperature adjusted basic parameters */
|
||||
if (model->DIObreakdownVoltageGiven){
|
||||
cbv=model->DIObreakdownCurrent * here->DIOarea;
|
||||
if (cbv < here->DIOtSatCur * model->DIObreakdownVoltage/vt) {
|
||||
cbv=here->DIOtSatCur * model->DIObreakdownVoltage/vt;
|
||||
if (model->DIOtlev == 0) {
|
||||
tBreakdownVoltage = model->DIObreakdownVoltage - model->DIOtcv * dt;
|
||||
} else {
|
||||
tBreakdownVoltage = model->DIObreakdownVoltage * (1 - model->DIOtcv * dt);
|
||||
}
|
||||
if (model->DIOlevel == 1) {
|
||||
cbv = model->DIObreakdownCurrent;
|
||||
} else { /* level=3 */
|
||||
cbv = model->DIObreakdownCurrent * here->DIOarea;
|
||||
}
|
||||
if (cbv < here->DIOtSatCur * tBreakdownVoltage/vt) {
|
||||
cbv=here->DIOtSatCur * tBreakdownVoltage/vt;
|
||||
#ifdef TRACE
|
||||
emsg = TMALLOC(char, 100);
|
||||
if(emsg == NULL) return(E_NOMEM);
|
||||
|
|
@ -205,17 +215,17 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
SPfrontEnd->IFerror (ERR_WARNING,
|
||||
"incompatibility with specified saturation current", NULL);
|
||||
#endif
|
||||
xbv=model->DIObreakdownVoltage;
|
||||
xbv=tBreakdownVoltage;
|
||||
} else {
|
||||
tol=ckt->CKTreltol*cbv;
|
||||
xbv=model->DIObreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(1+cbv/
|
||||
xbv=tBreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(1+cbv/
|
||||
(here->DIOtSatCur));
|
||||
iter=0;
|
||||
for(iter=0 ; iter < 25 ; iter++) {
|
||||
xbv=model->DIObreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(cbv/
|
||||
xbv=tBreakdownVoltage-model->DIObrkdEmissionCoeff*vt*log(cbv/
|
||||
(here->DIOtSatCur)+1-xbv/vt);
|
||||
xcbv=here->DIOtSatCur *
|
||||
(exp((model->DIObreakdownVoltage-xbv)/(model->DIObrkdEmissionCoeff*vt))-1+xbv/vt);
|
||||
(exp((tBreakdownVoltage-xbv)/(model->DIObrkdEmissionCoeff*vt))-1+xbv/vt);
|
||||
if (fabs(xcbv-cbv) <= tol) goto matched;
|
||||
}
|
||||
#ifdef TRACE
|
||||
|
|
@ -229,11 +239,7 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
#endif
|
||||
}
|
||||
matched:
|
||||
if (model->DIOtlev == 0) {
|
||||
here->DIOtBrkdwnV = xbv - model->DIOtcv * dt;
|
||||
} else if (model->DIOtlev == 1) {
|
||||
here->DIOtBrkdwnV = xbv * (1 - model->DIOtcv * dt);
|
||||
}
|
||||
here->DIOtBrkdwnV = xbv;
|
||||
}
|
||||
|
||||
/* transit time temperature adjust */
|
||||
|
|
|
|||
Loading…
Reference in New Issue