|
|
@ -24,10 +24,10 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
DIOinstance *here; |
|
|
DIOinstance *here; |
|
|
double arg; |
|
|
double arg; |
|
|
double argsw; |
|
|
double argsw; |
|
|
double capd; |
|
|
|
|
|
|
|
|
double capd, capdsw=0.0; |
|
|
double cd, cdb, cdsw, cdb_dT, cdsw_dT; |
|
|
double cd, cdb, cdsw, cdb_dT, cdsw_dT; |
|
|
double cdeq; |
|
|
double cdeq; |
|
|
double cdhat; |
|
|
|
|
|
|
|
|
double cdhat, cdhatsw=0.0; |
|
|
double ceq; |
|
|
double ceq; |
|
|
double csat; /* area-scaled saturation current */ |
|
|
double csat; /* area-scaled saturation current */ |
|
|
double csatsw; /* perimeter-scaled saturation current */ |
|
|
double csatsw; /* perimeter-scaled saturation current */ |
|
|
@ -37,34 +37,33 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
double czeroSW; |
|
|
double czeroSW; |
|
|
double czof2SW; |
|
|
double czof2SW; |
|
|
double sargSW; |
|
|
double sargSW; |
|
|
double sqrt_ikr; |
|
|
|
|
|
double sqrt_ikf; |
|
|
|
|
|
double ikf_area_m; |
|
|
|
|
|
double ikr_area_m; |
|
|
|
|
|
|
|
|
double sqrt_ikx; |
|
|
|
|
|
|
|
|
double delvd; /* change in diode voltage temporary */ |
|
|
|
|
|
|
|
|
double delvd, delvdsw=0.0; /* change in diode voltage temporary */ |
|
|
double evd; |
|
|
double evd; |
|
|
double evrev; |
|
|
double evrev; |
|
|
double gd, gdb, gdsw, gen_fac, gen_fac_vd; |
|
|
double gd, gdb, gdsw, gen_fac, gen_fac_vd; |
|
|
double t1, evd_rec, cdb_rec, gdb_rec, cdb_rec_dT; |
|
|
double t1, evd_rec, cdb_rec, gdb_rec, cdb_rec_dT; |
|
|
double geq; |
|
|
double geq; |
|
|
double gspr; /* area-scaled conductance */ |
|
|
double gspr; /* area-scaled conductance */ |
|
|
|
|
|
double gsprsw; /* perim-scaled conductance */ |
|
|
double sarg; |
|
|
double sarg; |
|
|
#ifndef NOBYPASS |
|
|
#ifndef NOBYPASS |
|
|
double tol; /* temporary for tolerence calculations */ |
|
|
double tol; /* temporary for tolerence calculations */ |
|
|
#endif |
|
|
#endif |
|
|
double vd; /* current diode voltage */ |
|
|
|
|
|
|
|
|
double vd, vdsw=0.0; /* current diode voltage */ |
|
|
double vdtemp; |
|
|
double vdtemp; |
|
|
double vt; /* K t / Q */ |
|
|
double vt; /* K t / Q */ |
|
|
double vte, vtesw, vtetun, vtebrk; |
|
|
double vte, vtesw, vtetun, vtebrk; |
|
|
int Check_dio=0, Check_th; |
|
|
|
|
|
|
|
|
int Check_dio=0, Check_dio_sw=0, Check_th; |
|
|
int error; |
|
|
int error; |
|
|
int SenCond=0; /* sensitivity condition */ |
|
|
int SenCond=0; /* sensitivity condition */ |
|
|
double diffcharge, deplcharge, deplchargeSW, diffcap, deplcap, deplcapSW; |
|
|
double diffcharge, deplcharge, deplchargeSW, diffcap, deplcap, deplcapSW; |
|
|
|
|
|
|
|
|
double deldelTemp, delTemp, Temp; |
|
|
double deldelTemp, delTemp, Temp; |
|
|
double ceqqth=0.0, Ith=0.0, gcTt=0.0, vrs=0.0; |
|
|
|
|
|
|
|
|
double ceqqth=0.0, Ith=0.0, gcTt=0.0, vrs=0.0, vrssw=0.0; |
|
|
double dIdio_dT, dIth_dVdio=0.0, dIrs_dT=0.0, dIth_dVrs=0.0, dIth_dT=0.0; |
|
|
double dIdio_dT, dIth_dVdio=0.0, dIrs_dT=0.0, dIth_dVrs=0.0, dIth_dT=0.0; |
|
|
|
|
|
double dIdioSw_dT=0.0, dIth_dVdioSw=0.0, dIth_dVrssw=0.0, dIrssw_dT=0.0; |
|
|
double argsw_dT, csat_dT, csatsw_dT; |
|
|
double argsw_dT, csat_dT, csatsw_dT; |
|
|
|
|
|
|
|
|
/* loop through all the diode models */ |
|
|
/* loop through all the diode models */ |
|
|
@ -101,8 +100,10 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
delTemp = 0.0; |
|
|
delTemp = 0.0; |
|
|
vt = CONSTKoverQ * here->DIOtemp; |
|
|
vt = CONSTKoverQ * here->DIOtemp; |
|
|
vte = model->DIOemissionCoeff * vt; |
|
|
vte = model->DIOemissionCoeff * vt; |
|
|
|
|
|
vtesw = model->DIOswEmissionCoeff * vt; |
|
|
vtebrk = model->DIObrkdEmissionCoeff * vt; |
|
|
vtebrk = model->DIObrkdEmissionCoeff * vt; |
|
|
gspr = here->DIOtConductance; |
|
|
gspr = here->DIOtConductance; |
|
|
|
|
|
gsprsw = here->DIOtConductanceSW; |
|
|
/* |
|
|
/* |
|
|
* initialization |
|
|
* initialization |
|
|
*/ |
|
|
*/ |
|
|
@ -116,9 +117,11 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
if((ckt->CKTsenInfo->SENmode == TRANSEN)&& |
|
|
if((ckt->CKTsenInfo->SENmode == TRANSEN)&& |
|
|
(ckt->CKTmode & MODEINITTRAN)) { |
|
|
(ckt->CKTmode & MODEINITTRAN)) { |
|
|
vd = *(ckt->CKTstate1 + here->DIOvoltage); |
|
|
vd = *(ckt->CKTstate1 + here->DIOvoltage); |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = *(ckt->CKTstate1 + here->DIOvoltageSW); |
|
|
delTemp = *(ckt->CKTstate1 + here->DIOdeltemp); |
|
|
delTemp = *(ckt->CKTstate1 + here->DIOdeltemp); |
|
|
} else{ |
|
|
} else{ |
|
|
vd = *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
vd = *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = *(ckt->CKTstate0 + here->DIOvoltageSW); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -128,24 +131,28 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
goto next1; |
|
|
goto next1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Check_dio=1; |
|
|
|
|
|
|
|
|
Check_dio=1; Check_dio_sw=1; |
|
|
if(ckt->CKTmode & MODEINITSMSIG) { |
|
|
if(ckt->CKTmode & MODEINITSMSIG) { |
|
|
vd= *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
vd= *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = *(ckt->CKTstate0 + here->DIOvoltageSW); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
} else if (ckt->CKTmode & MODEINITTRAN) { |
|
|
} else if (ckt->CKTmode & MODEINITTRAN) { |
|
|
vd= *(ckt->CKTstate1 + here->DIOvoltage); |
|
|
vd= *(ckt->CKTstate1 + here->DIOvoltage); |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = *(ckt->CKTstate1 + here->DIOvoltageSW); |
|
|
delTemp = *(ckt->CKTstate1 + here->DIOdeltemp); |
|
|
delTemp = *(ckt->CKTstate1 + here->DIOdeltemp); |
|
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
|
|
} else if ( (ckt->CKTmode & MODEINITJCT) && |
|
|
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) { |
|
|
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) { |
|
|
vd=here->DIOinitCond; |
|
|
vd=here->DIOinitCond; |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = here->DIOinitCond; |
|
|
} else if ( (ckt->CKTmode & MODEINITJCT) && here->DIOoff) { |
|
|
} else if ( (ckt->CKTmode & MODEINITJCT) && here->DIOoff) { |
|
|
vd=0; |
|
|
|
|
|
|
|
|
vd=vdsw=0; |
|
|
delTemp = 0.0; |
|
|
delTemp = 0.0; |
|
|
} else if ( ckt->CKTmode & MODEINITJCT) { |
|
|
} else if ( ckt->CKTmode & MODEINITJCT) { |
|
|
vd=here->DIOtVcrit; |
|
|
vd=here->DIOtVcrit; |
|
|
|
|
|
vdsw=here->DIOtVcritSW; |
|
|
delTemp = 0.0; |
|
|
delTemp = 0.0; |
|
|
} else if ( ckt->CKTmode & MODEINITFIX && here->DIOoff) { |
|
|
} else if ( ckt->CKTmode & MODEINITFIX && here->DIOoff) { |
|
|
vd=0; |
|
|
|
|
|
|
|
|
vd=vdsw=0; |
|
|
delTemp = 0.0; |
|
|
delTemp = 0.0; |
|
|
} else { |
|
|
} else { |
|
|
#ifndef PREDICTOR |
|
|
#ifndef PREDICTOR |
|
|
@ -164,10 +171,17 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
*(ckt->CKTstate1 + here->DIOdIdio_dT); |
|
|
*(ckt->CKTstate1 + here->DIOdIdio_dT); |
|
|
*(ckt->CKTstate0+here->DIOqth) = |
|
|
*(ckt->CKTstate0+here->DIOqth) = |
|
|
*(ckt->CKTstate1+here->DIOqth); |
|
|
*(ckt->CKTstate1+here->DIOqth); |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
vdsw = DEVpred(ckt,here->DIOvoltageSW); |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOdIdioSW_dT) = |
|
|
|
|
|
*(ckt->CKTstate1 + here->DIOdIdioSW_dT); |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
#endif /* PREDICTOR */ |
|
|
#endif /* PREDICTOR */ |
|
|
vd = *(ckt->CKTrhsOld+here->DIOposPrimeNode)- |
|
|
vd = *(ckt->CKTrhsOld+here->DIOposPrimeNode)- |
|
|
*(ckt->CKTrhsOld + here->DIOnegNode); |
|
|
*(ckt->CKTrhsOld + here->DIOnegNode); |
|
|
|
|
|
if (model->DIOresistSWGiven) vdsw = *(ckt->CKTrhsOld+here->DIOposSwPrimeNode)- |
|
|
|
|
|
*(ckt->CKTrhsOld + here->DIOnegNode); |
|
|
if (selfheat) |
|
|
if (selfheat) |
|
|
delTemp = *(ckt->CKTrhsOld + here->DIOtempNode); |
|
|
delTemp = *(ckt->CKTrhsOld + here->DIOtempNode); |
|
|
else |
|
|
else |
|
|
@ -185,6 +199,11 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
cdhat= *(ckt->CKTstate0 + here->DIOcurrent) + |
|
|
cdhat= *(ckt->CKTstate0 + here->DIOcurrent) + |
|
|
*(ckt->CKTstate0 + here->DIOconduct) * delvd + |
|
|
*(ckt->CKTstate0 + here->DIOconduct) * delvd + |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) * deldelTemp; |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) * deldelTemp; |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
delvdsw=vdsw - *(ckt->CKTstate0 + here->DIOvoltageSW); |
|
|
|
|
|
cdhatsw = *(ckt->CKTstate0 + here->DIOconductSW) * delvdsw + |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOdIdioSW_dT) * deldelTemp; |
|
|
|
|
|
} |
|
|
/* |
|
|
/* |
|
|
* bypass if solution has not changed |
|
|
* bypass if solution has not changed |
|
|
*/ |
|
|
*/ |
|
|
@ -202,16 +221,29 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
(fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), |
|
|
(fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), |
|
|
fabs(*(ckt->CKTstate0+here->DIOdeltemp)))+ |
|
|
fabs(*(ckt->CKTstate0+here->DIOdeltemp)))+ |
|
|
ckt->CKTvoltTol*1e4))) { |
|
|
ckt->CKTvoltTol*1e4))) { |
|
|
|
|
|
if ((!model->DIOresistSWGiven) || (fabs(delvdsw) < ckt->CKTvoltTol + ckt->CKTreltol * |
|
|
|
|
|
MAX(fabs(vdsw),fabs(*(ckt->CKTstate0+here->DIOvoltageSW))))) { |
|
|
|
|
|
if ((!model->DIOresistSWGiven) || (fabs(cdhatsw- *(ckt->CKTstate0 + here->DIOcurrentSW)) |
|
|
|
|
|
< ckt->CKTreltol* MAX(fabs(cdhatsw), |
|
|
|
|
|
fabs(*(ckt->CKTstate0 + here->DIOcurrentSW)))+ckt->CKTabstol)) { |
|
|
vd= *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
vd= *(ckt->CKTstate0 + here->DIOvoltage); |
|
|
cd= *(ckt->CKTstate0 + here->DIOcurrent); |
|
|
cd= *(ckt->CKTstate0 + here->DIOcurrent); |
|
|
gd= *(ckt->CKTstate0 + here->DIOconduct); |
|
|
gd= *(ckt->CKTstate0 + here->DIOconduct); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
delTemp = *(ckt->CKTstate0 + here->DIOdeltemp); |
|
|
dIdio_dT= *(ckt->CKTstate0 + here->DIOdIdio_dT); |
|
|
dIdio_dT= *(ckt->CKTstate0 + here->DIOdIdio_dT); |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
vdsw= *(ckt->CKTstate0 + here->DIOvoltageSW); |
|
|
|
|
|
cdsw= *(ckt->CKTstate0 + here->DIOcurrentSW); |
|
|
|
|
|
gdsw= *(ckt->CKTstate0 + here->DIOconductSW); |
|
|
|
|
|
dIdioSw_dT= *(ckt->CKTstate0 + here->DIOdIdioSW_dT); |
|
|
|
|
|
} |
|
|
goto load; |
|
|
goto load; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
#endif /* NOBYPASS */ |
|
|
#endif /* NOBYPASS */ |
|
|
/* |
|
|
/* |
|
|
* limit new junction voltage |
|
|
* limit new junction voltage |
|
|
@ -228,6 +260,20 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt) |
|
|
vd = DEVpnjlim(vd,*(ckt->CKTstate0 + here->DIOvoltage), |
|
|
vd = DEVpnjlim(vd,*(ckt->CKTstate0 + here->DIOvoltage), |
|
|
vte,here->DIOtVcrit,&Check_dio); |
|
|
vte,here->DIOtVcrit,&Check_dio); |
|
|
} |
|
|
} |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
if ( (model->DIObreakdownVoltageGiven) && |
|
|
|
|
|
(vdsw < MIN(0,-here->DIOtBrkdwnV+10*vtebrk))) { |
|
|
|
|
|
vdtemp = -(vdsw+here->DIOtBrkdwnV); |
|
|
|
|
|
vdtemp = DEVpnjlim(vdtemp, |
|
|
|
|
|
-(*(ckt->CKTstate0 + here->DIOvoltageSW) + |
|
|
|
|
|
here->DIOtBrkdwnV),vtebrk, |
|
|
|
|
|
here->DIOtVcritSW,&Check_dio_sw); |
|
|
|
|
|
vdsw = -(vdtemp+here->DIOtBrkdwnV); |
|
|
|
|
|
} else { |
|
|
|
|
|
vdsw = DEVpnjlim(vdsw,*(ckt->CKTstate0 + here->DIOvoltageSW), |
|
|
|
|
|
vtesw,here->DIOtVcritSW,&Check_dio_sw); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
if (selfheat) |
|
|
if (selfheat) |
|
|
delTemp = DEVlimitlog(delTemp, |
|
|
delTemp = DEVlimitlog(delTemp, |
|
|
*(ckt->CKTstate0 + here->DIOdeltemp), 100, &Check_th); |
|
|
*(ckt->CKTstate0 + here->DIOdeltemp), 100, &Check_th); |
|
|
@ -253,47 +299,45 @@ next1: |
|
|
csatsw = here->DIOtSatSWCur; |
|
|
csatsw = here->DIOtSatSWCur; |
|
|
csatsw_dT = here->DIOtSatSWCur_dT; |
|
|
csatsw_dT = here->DIOtSatSWCur_dT; |
|
|
gspr = here->DIOtConductance; |
|
|
gspr = here->DIOtConductance; |
|
|
|
|
|
gsprsw = here->DIOtConductanceSW; |
|
|
|
|
|
|
|
|
if (model->DIOsatSWCurGiven) { /* sidewall current */ |
|
|
if (model->DIOsatSWCurGiven) { /* sidewall current */ |
|
|
|
|
|
double vds; |
|
|
|
|
|
if (model->DIOresistSWGiven) |
|
|
|
|
|
vds = vdsw; /* sidewall voltage used */ |
|
|
|
|
|
else |
|
|
|
|
|
vds = vd; /* common voltage used */ |
|
|
|
|
|
|
|
|
if (model->DIOswEmissionCoeffGiven) { /* current with own characteristic */ |
|
|
|
|
|
|
|
|
|
|
|
vtesw = model->DIOswEmissionCoeff * vt; |
|
|
|
|
|
|
|
|
if (model->DIOswEmissionCoeffGiven) { /* with own characteristic */ |
|
|
|
|
|
|
|
|
if (vd >= -3*vtesw) { /* forward */ |
|
|
|
|
|
|
|
|
if (vds >= -3*vtesw) { /* forward */ |
|
|
|
|
|
|
|
|
evd = exp(vd/vtesw); |
|
|
|
|
|
|
|
|
evd = exp(vds/vtesw); |
|
|
cdsw = csatsw*(evd-1); |
|
|
cdsw = csatsw*(evd-1); |
|
|
gdsw = csatsw*evd/vtesw; |
|
|
gdsw = csatsw*evd/vtesw; |
|
|
cdsw_dT = csatsw_dT * (evd - 1) - csatsw * vd * evd / (vtesw * Temp); |
|
|
|
|
|
|
|
|
cdsw_dT = csatsw_dT * (evd - 1) - csatsw * vds * evd / (vtesw * Temp); |
|
|
|
|
|
|
|
|
} else if ((!(model->DIObreakdownVoltageGiven)) || |
|
|
} else if ((!(model->DIObreakdownVoltageGiven)) || |
|
|
vd >= -here->DIOtBrkdwnV) { /* reverse */ |
|
|
|
|
|
|
|
|
vds >= -here->DIOtBrkdwnV) { /* reverse */ |
|
|
|
|
|
|
|
|
argsw = 3*vtesw/(vd*CONSTe); |
|
|
|
|
|
|
|
|
argsw = 3*vtesw/(vds*CONSTe); |
|
|
argsw = argsw * argsw * argsw; |
|
|
argsw = argsw * argsw * argsw; |
|
|
argsw_dT = 3 * argsw / Temp; |
|
|
argsw_dT = 3 * argsw / Temp; |
|
|
cdsw = -csatsw*(1+argsw); |
|
|
cdsw = -csatsw*(1+argsw); |
|
|
gdsw = csatsw*3*argsw/vd; |
|
|
|
|
|
|
|
|
gdsw = csatsw*3*argsw/vds; |
|
|
cdsw_dT = -csatsw_dT - (csatsw_dT*argsw + csatsw*argsw_dT); |
|
|
cdsw_dT = -csatsw_dT - (csatsw_dT*argsw + csatsw*argsw_dT); |
|
|
|
|
|
|
|
|
} else { /* breakdown */ |
|
|
|
|
|
|
|
|
} else if (!model->DIOresistSWGiven){ /* breakdown, but not for separate sidewall diode */ |
|
|
double evrev_dT; |
|
|
double evrev_dT; |
|
|
|
|
|
|
|
|
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk); |
|
|
|
|
|
evrev_dT = (here->DIOtBrkdwnV+vd)*evrev/(vtebrk*Temp); |
|
|
|
|
|
|
|
|
evrev = exp(-(here->DIOtBrkdwnV+vds)/vtebrk); |
|
|
|
|
|
evrev_dT = (here->DIOtBrkdwnV+vds)*evrev/(vtebrk*Temp); |
|
|
cdsw = -csatsw*evrev; |
|
|
cdsw = -csatsw*evrev; |
|
|
gdsw = csatsw*evrev/vtebrk; |
|
|
gdsw = csatsw*evrev/vtebrk; |
|
|
cdsw_dT = -(csatsw_dT*evrev + csatsw*evrev_dT); |
|
|
cdsw_dT = -(csatsw_dT*evrev + csatsw*evrev_dT); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} else { /* merge saturation currents and use same characteristic as bottom diode */ |
|
|
|
|
|
|
|
|
|
|
|
csat = csat + csatsw; |
|
|
|
|
|
csat_dT = csat_dT + csatsw_dT; |
|
|
|
|
|
cdsw_dT = 0.0; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
@ -302,12 +346,17 @@ next1: |
|
|
* temperature dependent diode saturation current and derivative |
|
|
* temperature dependent diode saturation current and derivative |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
if (vd >= -3*vte) { /* bottom current forward */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (vd >= -3*vte) { /* bottom and sidewall current forward with common voltage */ |
|
|
|
|
|
/* and with common characteristic */ |
|
|
evd = exp(vd/vte); |
|
|
evd = exp(vd/vte); |
|
|
cdb = csat*(evd-1); |
|
|
cdb = csat*(evd-1); |
|
|
gdb = csat*evd/vte; |
|
|
gdb = csat*evd/vte; |
|
|
cdb_dT = csat_dT * (evd - 1) - csat * vd * evd / (vte * Temp); |
|
|
cdb_dT = csat_dT * (evd - 1) - csat * vd * evd / (vte * Temp); |
|
|
|
|
|
if ((model->DIOsatSWCurGiven)&&(!model->DIOswEmissionCoeffGiven)) { |
|
|
|
|
|
cdsw = csatsw*(evd-1); |
|
|
|
|
|
gdsw = csatsw*evd/vte; |
|
|
|
|
|
cdsw_dT = csatsw_dT * (evd - 1) - csatsw * vd * evd / (vte * Temp); |
|
|
|
|
|
} |
|
|
if (model->DIOrecSatCurGiven) { /* recombination current */ |
|
|
if (model->DIOrecSatCurGiven) { /* recombination current */ |
|
|
double vterec = model->DIOrecEmissionCoeff*vt; |
|
|
double vterec = model->DIOrecEmissionCoeff*vt; |
|
|
evd_rec = exp(vd/(vterec)); |
|
|
evd_rec = exp(vd/(vterec)); |
|
|
@ -337,8 +386,14 @@ next1: |
|
|
cdb = -csat*(1+arg); |
|
|
cdb = -csat*(1+arg); |
|
|
gdb = csat*3*arg/vd; |
|
|
gdb = csat*3*arg/vd; |
|
|
cdb_dT = -csat_dT - (csat_dT*arg + csat*darg_dT); |
|
|
cdb_dT = -csat_dT - (csat_dT*arg + csat*darg_dT); |
|
|
|
|
|
if ((model->DIOsatSWCurGiven)&&(!model->DIOswEmissionCoeffGiven)) { |
|
|
|
|
|
cdsw = -csatsw*(1+arg); |
|
|
|
|
|
gdsw = csatsw*3*arg/vd; |
|
|
|
|
|
cdsw_dT = -csatsw_dT - (csatsw_dT*arg + csatsw*darg_dT); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} else { /* breakdown */ |
|
|
} else { /* breakdown */ |
|
|
|
|
|
|
|
|
double evrev_dT; |
|
|
double evrev_dT; |
|
|
|
|
|
|
|
|
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk); |
|
|
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk); |
|
|
@ -346,6 +401,15 @@ next1: |
|
|
cdb = -csat*evrev; |
|
|
cdb = -csat*evrev; |
|
|
gdb = csat*evrev/vtebrk; |
|
|
gdb = csat*evrev/vtebrk; |
|
|
cdb_dT = -(csat_dT*evrev + csat*evrev_dT); |
|
|
cdb_dT = -(csat_dT*evrev + csat*evrev_dT); |
|
|
|
|
|
if ((model->DIOsatSWCurGiven) |
|
|
|
|
|
&&(!model->DIOresistSWGiven) /* no breakdown for separate sidewall diode */ |
|
|
|
|
|
&&(!model->DIOswEmissionCoeffGiven)) { |
|
|
|
|
|
evrev = exp(-(here->DIOtBrkdwnV+vdsw)/vtebrk); |
|
|
|
|
|
evrev_dT = (here->DIOtBrkdwnV+vdsw)*evrev/(vtebrk*Temp); |
|
|
|
|
|
cdsw = -csatsw*evrev; |
|
|
|
|
|
gdsw = csatsw*evrev/vtebrk; |
|
|
|
|
|
cdsw_dT = -(csatsw_dT*evrev + csatsw*evrev_dT); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -373,34 +437,44 @@ next1: |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
cd = cdb + cdsw; |
|
|
|
|
|
gd = gdb + gdsw; |
|
|
|
|
|
dIdio_dT = cdb_dT + cdsw_dT; |
|
|
|
|
|
|
|
|
|
|
|
if (vd >= -3*vte) { /* limit forward */ |
|
|
if (vd >= -3*vte) { /* limit forward */ |
|
|
|
|
|
|
|
|
if( (model->DIOforwardKneeCurrentGiven) && (cd > 1.0e-18) ) { |
|
|
|
|
|
ikf_area_m = here->DIOforwardKneeCurrent; |
|
|
|
|
|
sqrt_ikf = sqrt(cd/ikf_area_m); |
|
|
|
|
|
gd = ((1+sqrt_ikf)*gd - cd*gd/(2*sqrt_ikf*ikf_area_m))/(1+2*sqrt_ikf + cd/ikf_area_m) + ckt->CKTgmin; |
|
|
|
|
|
cd = cd/(1+sqrt_ikf) + ckt->CKTgmin*vd; |
|
|
|
|
|
} else { |
|
|
|
|
|
gd = gd + ckt->CKTgmin; |
|
|
|
|
|
cd = cd + ckt->CKTgmin*vd; |
|
|
|
|
|
|
|
|
if ( (model->DIOforwardKneeCurrentGiven) && (cdb > 1.0e-18) ) { |
|
|
|
|
|
double ikf_area_m = here->DIOforwardKneeCurrent; |
|
|
|
|
|
sqrt_ikx = sqrt(cdb/ikf_area_m); |
|
|
|
|
|
gdb = ((1+sqrt_ikx)*gdb - cdb*gdb/(2*sqrt_ikx*ikf_area_m))/(1+2*sqrt_ikx + cdb/ikf_area_m); |
|
|
|
|
|
cdb = cdb/(1+sqrt_ikx); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} else { /* limit reverse */ |
|
|
} else { /* limit reverse */ |
|
|
|
|
|
|
|
|
if( (model->DIOreverseKneeCurrentGiven) && (cd < -1.0e-18) ) { |
|
|
|
|
|
ikr_area_m = here->DIOreverseKneeCurrent; |
|
|
|
|
|
sqrt_ikr = sqrt(cd/(-ikr_area_m)); |
|
|
|
|
|
gd = ((1+sqrt_ikr)*gd + cd*gd/(2*sqrt_ikr*ikr_area_m))/(1+2*sqrt_ikr - cd/ikr_area_m) + ckt->CKTgmin; |
|
|
|
|
|
cd = cd/(1+sqrt_ikr) + ckt->CKTgmin*vd; |
|
|
|
|
|
} else { |
|
|
|
|
|
gd = gd + ckt->CKTgmin; |
|
|
|
|
|
cd = cd + ckt->CKTgmin*vd; |
|
|
|
|
|
|
|
|
if ( (model->DIOreverseKneeCurrentGiven) && (cdb < -1.0e-18) ) { |
|
|
|
|
|
double ikr_area_m = here->DIOreverseKneeCurrent; |
|
|
|
|
|
sqrt_ikx = sqrt(cdb/(-ikr_area_m)); |
|
|
|
|
|
gdb = ((1+sqrt_ikx)*gdb + cdb*gdb/(2*sqrt_ikx*ikr_area_m))/(1+2*sqrt_ikx - cdb/ikr_area_m); |
|
|
|
|
|
cdb = cdb/(1+sqrt_ikx); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ( (model->DIOforwardSWKneeCurrentGiven) && (cdsw > 1.0e-18) ) { |
|
|
|
|
|
double ikp_peri_m = here->DIOforwardSWKneeCurrent; |
|
|
|
|
|
sqrt_ikx = sqrt(cdsw/ikp_peri_m); |
|
|
|
|
|
gdsw = ((1+sqrt_ikx)*gdsw - cdsw*gdsw/(2*sqrt_ikx*ikp_peri_m))/(1+2*sqrt_ikx + cdsw/ikp_peri_m); |
|
|
|
|
|
cdsw = cdsw/(1+sqrt_ikx); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!model->DIOresistSWGiven) { |
|
|
|
|
|
cd = cdb + cdsw + ckt->CKTgmin*vd; |
|
|
|
|
|
gd = gdb + gdsw + ckt->CKTgmin; |
|
|
|
|
|
dIdio_dT = cdb_dT + cdsw_dT; |
|
|
|
|
|
} else { |
|
|
|
|
|
cd = cdb + ckt->CKTgmin*vd; |
|
|
|
|
|
gd = gdb + ckt->CKTgmin; |
|
|
|
|
|
cdsw = cdsw + ckt->CKTgmin*vdsw; |
|
|
|
|
|
gdsw = gdsw + ckt->CKTgmin; |
|
|
|
|
|
dIdio_dT = cdb_dT; |
|
|
|
|
|
dIdioSw_dT = cdsw_dT; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) || |
|
|
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) || |
|
|
@ -421,28 +495,40 @@ next1: |
|
|
deplcap = czof2*(here->DIOtF3+here->DIOtGradingCoeff*vd/here->DIOtJctPot); |
|
|
deplcap = czof2*(here->DIOtF3+here->DIOtGradingCoeff*vd/here->DIOtJctPot); |
|
|
} |
|
|
} |
|
|
czeroSW=here->DIOtJctSWCap; |
|
|
czeroSW=here->DIOtJctSWCap; |
|
|
if (vd < here->DIOtDepSWCap){ |
|
|
|
|
|
argSW=1-vd/here->DIOtJctSWPot; |
|
|
|
|
|
|
|
|
double vdx; |
|
|
|
|
|
if (model->DIOresistSWGiven) |
|
|
|
|
|
vdx = vdsw; |
|
|
|
|
|
else |
|
|
|
|
|
vdx = vd; |
|
|
|
|
|
if (vdx < here->DIOtDepSWCap){ |
|
|
|
|
|
argSW=1-vdx/here->DIOtJctSWPot; |
|
|
sargSW=exp(-model->DIOgradingSWCoeff*log(argSW)); |
|
|
sargSW=exp(-model->DIOgradingSWCoeff*log(argSW)); |
|
|
deplchargeSW = here->DIOtJctSWPot*czeroSW*(1-argSW*sargSW)/(1-model->DIOgradingSWCoeff); |
|
|
deplchargeSW = here->DIOtJctSWPot*czeroSW*(1-argSW*sargSW)/(1-model->DIOgradingSWCoeff); |
|
|
deplcapSW = czeroSW*sargSW; |
|
|
deplcapSW = czeroSW*sargSW; |
|
|
} else { |
|
|
} else { |
|
|
czof2SW=czeroSW/here->DIOtF2SW; |
|
|
czof2SW=czeroSW/here->DIOtF2SW; |
|
|
deplchargeSW = czeroSW*here->DIOtF1+czof2SW*(here->DIOtF3SW*(vd-here->DIOtDepSWCap)+ |
|
|
|
|
|
(model->DIOgradingSWCoeff/(here->DIOtJctSWPot+here->DIOtJctSWPot))*(vd*vd-here->DIOtDepSWCap*here->DIOtDepSWCap)); |
|
|
|
|
|
deplcapSW = czof2SW*(here->DIOtF3SW+model->DIOgradingSWCoeff*vd/here->DIOtJctSWPot); |
|
|
|
|
|
|
|
|
deplchargeSW = czeroSW*here->DIOtF1+czof2SW*(here->DIOtF3SW*(vdx-here->DIOtDepSWCap)+ |
|
|
|
|
|
(model->DIOgradingSWCoeff/(here->DIOtJctSWPot+here->DIOtJctSWPot))*(vdx*vdx-here->DIOtDepSWCap*here->DIOtDepSWCap)); |
|
|
|
|
|
deplcapSW = czof2SW*(here->DIOtF3SW+model->DIOgradingSWCoeff*vdx/here->DIOtJctSWPot); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
diffcharge = here->DIOtTransitTime*cd; |
|
|
diffcharge = here->DIOtTransitTime*cd; |
|
|
|
|
|
diffcap = here->DIOtTransitTime*gd; |
|
|
|
|
|
if (!model->DIOresistSWGiven) { |
|
|
*(ckt->CKTstate0 + here->DIOcapCharge) = |
|
|
*(ckt->CKTstate0 + here->DIOcapCharge) = |
|
|
diffcharge + deplcharge + deplchargeSW + (here->DIOcmetal + here->DIOcpoly)*vd; |
|
|
diffcharge + deplcharge + deplchargeSW + (here->DIOcmetal + here->DIOcpoly)*vd; |
|
|
|
|
|
|
|
|
diffcap = here->DIOtTransitTime*gd; |
|
|
|
|
|
|
|
|
|
|
|
capd = diffcap + deplcap + deplcapSW + here->DIOcmetal + here->DIOcpoly; |
|
|
capd = diffcap + deplcap + deplcapSW + here->DIOcmetal + here->DIOcpoly; |
|
|
|
|
|
|
|
|
here->DIOcap = capd; |
|
|
here->DIOcap = capd; |
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcapCharge) = |
|
|
|
|
|
diffcharge + deplcharge + (here->DIOcmetal + here->DIOcpoly)*vd; |
|
|
|
|
|
capd = diffcap + deplcap + here->DIOcmetal + here->DIOcpoly; |
|
|
|
|
|
here->DIOcap = capd; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcapChargeSW) = |
|
|
|
|
|
deplcapSW; |
|
|
|
|
|
capdsw = deplcapSW; |
|
|
|
|
|
here->DIOcapSW = capdsw; |
|
|
|
|
|
} |
|
|
/* |
|
|
/* |
|
|
* store small-signal parameters |
|
|
* store small-signal parameters |
|
|
*/ |
|
|
*/ |
|
|
@ -450,11 +536,18 @@ next1: |
|
|
(!(ckt->CKTmode & MODEUIC)) ) { |
|
|
(!(ckt->CKTmode & MODEUIC)) ) { |
|
|
if (ckt->CKTmode & MODEINITSMSIG){ |
|
|
if (ckt->CKTmode & MODEINITSMSIG){ |
|
|
*(ckt->CKTstate0 + here->DIOcapCurrent) = capd; |
|
|
*(ckt->CKTstate0 + here->DIOcapCurrent) = capd; |
|
|
|
|
|
|
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcapCurrentSW) = capdsw; |
|
|
|
|
|
} |
|
|
if(SenCond){ |
|
|
if(SenCond){ |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
*(ckt->CKTstate0 + here->DIOconduct) = gd; |
|
|
*(ckt->CKTstate0 + here->DIOconduct) = gd; |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) = dIdio_dT; |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) = dIdio_dT; |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcurrentSW) = cdsw; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOconductSW) = gdsw; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOdIdioSW_dT) = dIdioSw_dT; |
|
|
|
|
|
} |
|
|
#ifdef SENSDEBUG |
|
|
#ifdef SENSDEBUG |
|
|
printf("storing small signal parameters\n"); |
|
|
printf("storing small signal parameters\n"); |
|
|
printf("cd = %.7e,vd = %.7e\n",cd,vd); |
|
|
printf("cd = %.7e,vd = %.7e\n",cd,vd); |
|
|
@ -469,6 +562,8 @@ next1: |
|
|
*/ |
|
|
*/ |
|
|
if(SenCond && (ckt->CKTsenInfo->SENmode == TRANSEN)){ |
|
|
if(SenCond && (ckt->CKTsenInfo->SENmode == TRANSEN)){ |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
|
|
|
if (model->DIOresistSWGiven) |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcurrentSW) = cdsw; |
|
|
#ifdef SENSDEBUG |
|
|
#ifdef SENSDEBUG |
|
|
printf("storing parameters for transient sensitivity\n" |
|
|
printf("storing parameters for transient sensitivity\n" |
|
|
); |
|
|
); |
|
|
@ -481,21 +576,29 @@ next1: |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
*(ckt->CKTstate1 + here->DIOcapCharge) = |
|
|
*(ckt->CKTstate1 + here->DIOcapCharge) = |
|
|
*(ckt->CKTstate0 + here->DIOcapCharge); |
|
|
*(ckt->CKTstate0 + here->DIOcapCharge); |
|
|
|
|
|
if (model->DIOresistSWGiven) |
|
|
|
|
|
*(ckt->CKTstate1 + here->DIOcapChargeSW) = |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcapChargeSW); |
|
|
} |
|
|
} |
|
|
error = NIintegrate(ckt,&geq,&ceq,capd,here->DIOcapCharge); |
|
|
error = NIintegrate(ckt,&geq,&ceq,capd,here->DIOcapCharge); |
|
|
if(error) return(error); |
|
|
if(error) return(error); |
|
|
gd=gd+geq; |
|
|
gd=gd+geq; |
|
|
cd=cd+*(ckt->CKTstate0 + here->DIOcapCurrent); |
|
|
cd=cd+*(ckt->CKTstate0 + here->DIOcapCurrent); |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
error = NIintegrate(ckt,&geq,&ceq,capdsw,here->DIOcapChargeSW); |
|
|
|
|
|
if(error) return(error); |
|
|
|
|
|
gdsw=gdsw+geq; |
|
|
|
|
|
cdsw=cdsw+*(ckt->CKTstate0 + here->DIOcapCurrentSW); |
|
|
|
|
|
} |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
*(ckt->CKTstate1 + here->DIOcapCurrent) = |
|
|
*(ckt->CKTstate1 + here->DIOcapCurrent) = |
|
|
*(ckt->CKTstate0 + here->DIOcapCurrent); |
|
|
*(ckt->CKTstate0 + here->DIOcapCurrent); |
|
|
|
|
|
if (model->DIOresistSWGiven) |
|
|
|
|
|
*(ckt->CKTstate1 + here->DIOcapCurrentSW) = |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcapCurrentSW); |
|
|
} |
|
|
} |
|
|
if (selfheat) |
|
|
if (selfheat) |
|
|
{ |
|
|
{ |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
|
|
|
*(ckt->CKTstate1 + here->DIOqth) = |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOqth); |
|
|
|
|
|
} |
|
|
|
|
|
error = NIintegrate(ckt, &gcTt, &ceqqth, model->DIOcth0, here->DIOqth); |
|
|
error = NIintegrate(ckt, &gcTt, &ceqqth, model->DIOcth0, here->DIOqth); |
|
|
if (error) return(error); |
|
|
if (error) return(error); |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
if (ckt->CKTmode & MODEINITTRAN) { |
|
|
@ -512,17 +615,29 @@ next1: |
|
|
* check convergence |
|
|
* check convergence |
|
|
*/ |
|
|
*/ |
|
|
if ( (!(ckt->CKTmode & MODEINITFIX)) || (!(here->DIOoff)) ) { |
|
|
if ( (!(ckt->CKTmode & MODEINITFIX)) || (!(here->DIOoff)) ) { |
|
|
|
|
|
if (!model->DIOresistSWGiven) { |
|
|
if ((Check_th == 1) || (Check_dio == 1)) { |
|
|
if ((Check_th == 1) || (Check_dio == 1)) { |
|
|
ckt->CKTnoncon++; |
|
|
ckt->CKTnoncon++; |
|
|
ckt->CKTtroubleElt = (GENinstance *) here; |
|
|
ckt->CKTtroubleElt = (GENinstance *) here; |
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
if ((Check_th == 1) || (Check_dio == 1) || (Check_dio_sw == 1)) { |
|
|
|
|
|
ckt->CKTnoncon++; |
|
|
|
|
|
ckt->CKTtroubleElt = (GENinstance *) here; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; |
|
|
next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
*(ckt->CKTstate0 + here->DIOcurrent) = cd; |
|
|
*(ckt->CKTstate0 + here->DIOconduct) = gd; |
|
|
*(ckt->CKTstate0 + here->DIOconduct) = gd; |
|
|
*(ckt->CKTstate0 + here->DIOdeltemp) = delTemp; |
|
|
*(ckt->CKTstate0 + here->DIOdeltemp) = delTemp; |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) = dIdio_dT; |
|
|
*(ckt->CKTstate0 + here->DIOdIdio_dT) = dIdio_dT; |
|
|
|
|
|
|
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOvoltageSW) = vdsw; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOcurrentSW) = cdsw; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOconductSW) = gdsw; |
|
|
|
|
|
*(ckt->CKTstate0 + here->DIOdIdioSW_dT) = dIdioSw_dT; |
|
|
|
|
|
} |
|
|
if(SenCond) continue; |
|
|
if(SenCond) continue; |
|
|
|
|
|
|
|
|
#ifndef NOBYPASS |
|
|
#ifndef NOBYPASS |
|
|
@ -531,20 +646,37 @@ next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; |
|
|
if (selfheat) { |
|
|
if (selfheat) { |
|
|
double dIrs_dVrs, dIrs_dgspr, dIth_dIrs; |
|
|
double dIrs_dVrs, dIrs_dgspr, dIth_dIrs; |
|
|
vrs = *(ckt->CKTrhsOld + here->DIOposNode) - *(ckt->CKTrhsOld + here->DIOposPrimeNode); |
|
|
vrs = *(ckt->CKTrhsOld + here->DIOposNode) - *(ckt->CKTrhsOld + here->DIOposPrimeNode); |
|
|
Ith = vd*cd + vrs*vrs*gspr; /* Diode dissipated power */ |
|
|
|
|
|
dIrs_dVrs = gspr; |
|
|
dIrs_dVrs = gspr; |
|
|
dIrs_dgspr = vrs; |
|
|
dIrs_dgspr = vrs; |
|
|
dIrs_dT = dIrs_dgspr * here->DIOtConductance_dT; |
|
|
dIrs_dT = dIrs_dgspr * here->DIOtConductance_dT; |
|
|
|
|
|
Ith = vd*cd + vrs*vrs*gspr; /* Diode dissipated power */ |
|
|
dIth_dVrs = vrs*gspr; |
|
|
dIth_dVrs = vrs*gspr; |
|
|
dIth_dIrs = vrs; |
|
|
dIth_dIrs = vrs; |
|
|
dIth_dVrs = dIth_dVrs + dIth_dIrs*dIrs_dVrs; |
|
|
dIth_dVrs = dIth_dVrs + dIth_dIrs*dIrs_dVrs; |
|
|
dIth_dT = dIth_dIrs*dIrs_dT + dIdio_dT*vd; |
|
|
dIth_dT = dIth_dIrs*dIrs_dT + dIdio_dT*vd; |
|
|
dIth_dVdio = cd + vd*gd; |
|
|
dIth_dVdio = cd + vd*gd; |
|
|
here->DIOdIth_dVrs = dIth_dVrs; |
|
|
here->DIOdIth_dVrs = dIth_dVrs; |
|
|
here->DIOdIth_dVdio = dIth_dVdio; |
|
|
|
|
|
here->DIOdIth_dT = dIth_dT; |
|
|
|
|
|
here->DIOgcTt = gcTt; |
|
|
here->DIOgcTt = gcTt; |
|
|
here->DIOdIrs_dT = dIrs_dT; |
|
|
here->DIOdIrs_dT = dIrs_dT; |
|
|
|
|
|
here->DIOdIth_dVdio = dIth_dVdio; |
|
|
|
|
|
here->DIOdIth_dT = dIth_dT; |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
double dIrssw_dVrssw, dIrssw_dgsprsw, dIth_dIrssw; |
|
|
|
|
|
vrssw = *(ckt->CKTrhsOld + here->DIOposNode) - *(ckt->CKTrhsOld + here->DIOposSwPrimeNode); |
|
|
|
|
|
dIrssw_dVrssw = gsprsw; |
|
|
|
|
|
dIrssw_dgsprsw = vrssw; |
|
|
|
|
|
dIrssw_dT = dIrssw_dgsprsw * here->DIOtConductanceSW_dT; |
|
|
|
|
|
Ith = Ith + vdsw*cdsw + vrssw*vrssw*gsprsw; /* Diode dissipated power */ |
|
|
|
|
|
dIth_dVrssw = vrssw*gsprsw; |
|
|
|
|
|
dIth_dIrssw = vrssw; |
|
|
|
|
|
dIth_dVrssw = dIth_dVrssw + dIth_dIrssw*dIrssw_dVrssw; |
|
|
|
|
|
dIth_dT = dIth_dT + dIth_dIrssw*dIrssw_dT + dIdioSw_dT*vdsw; |
|
|
|
|
|
dIth_dVdioSw = cdsw + vdsw*gdsw; |
|
|
|
|
|
here->DIOdIth_dVrssw = dIth_dVrssw; |
|
|
|
|
|
here->DIOdIth_dVdio = dIth_dVdioSw; |
|
|
|
|
|
here->DIOdIth_dT = dIth_dT; |
|
|
|
|
|
here->DIOdIrssw_dT = dIrssw_dT; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
/* |
|
|
/* |
|
|
* load current vector |
|
|
* load current vector |
|
|
@ -558,6 +690,17 @@ next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; |
|
|
*(ckt->CKTrhs + here->DIOnegNode) += -dIdio_dT*delTemp; |
|
|
*(ckt->CKTrhs + here->DIOnegNode) += -dIdio_dT*delTemp; |
|
|
*(ckt->CKTrhs + here->DIOtempNode) += Ith - dIth_dVdio*vd - dIth_dVrs*vrs - dIth_dT*delTemp - ceqqth; |
|
|
*(ckt->CKTrhs + here->DIOtempNode) += Ith - dIth_dVdio*vd - dIth_dVrs*vrs - dIth_dT*delTemp - ceqqth; |
|
|
} |
|
|
} |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
cdeq=cdsw-gdsw*vdsw; |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOnegNode) += cdeq; |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOposSwPrimeNode) -= cdeq; |
|
|
|
|
|
if (selfheat) { |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOposNode) += dIrssw_dT*delTemp; |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOposSwPrimeNode) += dIdioSw_dT*delTemp - dIrssw_dT*delTemp; |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOnegNode) += -dIdioSw_dT*delTemp; |
|
|
|
|
|
*(ckt->CKTrhs + here->DIOtempNode) += -dIth_dVdioSw*vdsw - dIth_dVrssw*vrssw; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
/* |
|
|
/* |
|
|
* load matrix |
|
|
* load matrix |
|
|
*/ |
|
|
*/ |
|
|
@ -577,6 +720,24 @@ next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd; |
|
|
(*(here->DIOposPrimeTempPtr) += dIdio_dT - dIrs_dT); |
|
|
(*(here->DIOposPrimeTempPtr) += dIdio_dT - dIrs_dT); |
|
|
(*(here->DIOnegTempPtr) += -dIdio_dT); |
|
|
(*(here->DIOnegTempPtr) += -dIdio_dT); |
|
|
} |
|
|
} |
|
|
|
|
|
if (model->DIOresistSWGiven) { |
|
|
|
|
|
*(here->DIOposPosPtr) += gsprsw; |
|
|
|
|
|
*(here->DIOnegNegPtr) += gdsw; |
|
|
|
|
|
*(here->DIOposSwPrimePosSwPrimePtr) += (gdsw + gsprsw); |
|
|
|
|
|
*(here->DIOposPosSwPrimePtr) -= gsprsw; |
|
|
|
|
|
*(here->DIOnegPosSwPrimePtr) -= gdsw; |
|
|
|
|
|
*(here->DIOposSwPrimePosPtr) -= gsprsw; |
|
|
|
|
|
*(here->DIOposSwPrimeNegPtr) -= gdsw; |
|
|
|
|
|
|
|
|
|
|
|
if (selfheat) { |
|
|
|
|
|
(*(here->DIOtempPosPtr) += -dIth_dVrssw); |
|
|
|
|
|
(*(here->DIOtempPosSwPrimePtr) += -dIth_dVdioSw + dIth_dVrssw); |
|
|
|
|
|
(*(here->DIOtempNegPtr) += dIth_dVdioSw); |
|
|
|
|
|
(*(here->DIOposTempPtr) += dIrssw_dT); |
|
|
|
|
|
(*(here->DIOposSwPrimeTempPtr) += dIdioSw_dT - dIrssw_dT); |
|
|
|
|
|
(*(here->DIOnegTempPtr) += -dIdioSw_dT); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return(OK); |
|
|
return(OK); |
|
|
|