Fixed the diode scaling bug reported by A. Buermen
This commit is contained in:
parent
727f11edf0
commit
4bd5ebe3e3
|
|
@ -60,7 +60,7 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
|
||||||
* This is an old analysis anyway....
|
* This is an old analysis anyway....
|
||||||
*/
|
*/
|
||||||
|
|
||||||
csat=(here->DIOtSatCur*here->DIOarea+here->DIOtSatSWCur*here->DIOpj)*here->DIOm;
|
csat=here->DIOtSatCur+here->DIOtSatSWCur; // area and multiplier are already counted in tSatCur and tSatSWCur
|
||||||
vt = CONSTKoverQ * here->DIOtemp;
|
vt = CONSTKoverQ * here->DIOtemp;
|
||||||
vte=model->DIOemissionCoeff * vt;
|
vte=model->DIOemissionCoeff * vt;
|
||||||
vd = *(ckt->CKTrhsOld + (here->DIOposPrimeNode)) -
|
vd = *(ckt->CKTrhsOld + (here->DIOposPrimeNode)) -
|
||||||
|
|
@ -113,7 +113,7 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
|
||||||
/*
|
/*
|
||||||
* junction charge storage elements
|
* junction charge storage elements
|
||||||
*/
|
*/
|
||||||
czero=here->DIOtJctCap*here->DIOarea*here->DIOm;
|
czero=here->DIOtJctCap; // area and multiplier are already counted in DIOtJctCap
|
||||||
if (czero != 0.0) {
|
if (czero != 0.0) {
|
||||||
if (vd < here->DIOtDepCap){
|
if (vd < here->DIOtDepCap){
|
||||||
arg=1-vd/model->DIOjunctionPot;
|
arg=1-vd/model->DIOjunctionPot;
|
||||||
|
|
@ -143,7 +143,7 @@ DIOdSetup(DIOmodel *model, CKTcircuit *ckt)
|
||||||
{
|
{
|
||||||
cjunc1 = cjunc2 = cjunc3 = 0.0;
|
cjunc1 = cjunc2 = cjunc3 = 0.0;
|
||||||
}
|
}
|
||||||
czeroSW=+here->DIOtJctSWCap*here->DIOpj*here->DIOm;
|
czeroSW=+here->DIOtJctSWCap; // pj and multiplier are already counted in DIOtJctSWCap
|
||||||
if (czeroSW != 0.0) {
|
if (czeroSW != 0.0) {
|
||||||
if (vd < here->DIOtDepCap){
|
if (vd < here->DIOtDepCap){
|
||||||
arg=1-vd/model->DIOjunctionSWPot;
|
arg=1-vd/model->DIOjunctionSWPot;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ DIOnoise(int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
|
||||||
|
|
||||||
NevalSrcInstanceTemp(&noizDens[DIORSNOIZ],&lnNdens[DIORSNOIZ],
|
NevalSrcInstanceTemp(&noizDens[DIORSNOIZ],&lnNdens[DIORSNOIZ],
|
||||||
ckt, THERMNOISE, inst->DIOposPrimeNode, inst->DIOposNode,
|
ckt, THERMNOISE, inst->DIOposPrimeNode, inst->DIOposNode,
|
||||||
inst->DIOtConductance * inst->DIOarea * inst->DIOm, dtemp);
|
inst->DIOtConductance, dtemp);
|
||||||
|
|
||||||
NevalSrc(&noizDens[DIOIDNOIZ],&lnNdens[DIOIDNOIZ],
|
NevalSrc(&noizDens[DIOIDNOIZ],&lnNdens[DIOIDNOIZ],
|
||||||
ckt, SHOTNOISE, inst->DIOposPrimeNode, inst->DIOnegNode,
|
ckt, SHOTNOISE, inst->DIOposPrimeNode, inst->DIOnegNode,
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ pertvd: /* Perturbation of Diode Voltage */
|
||||||
*(here->DIOsenCeq + 2)= *(ckt->CKTstate0 + here->DIOcapCurrent);
|
*(here->DIOsenCeq + 2)= *(ckt->CKTstate0 + here->DIOcapCurrent);
|
||||||
*(ckt->CKTstate0 + here->DIOvoltage) = A0;
|
*(ckt->CKTstate0 + here->DIOvoltage) = A0;
|
||||||
}
|
}
|
||||||
gspr=here->DIOtConductance*here->DIOarea;
|
gspr=here->DIOtConductance;
|
||||||
geq = *(here->DIOsenGeq + 2);
|
geq = *(here->DIOsenGeq + 2);
|
||||||
xceq = *(here->DIOsenCeq + 2) * ckt->CKTomega;
|
xceq = *(here->DIOsenCeq + 2) * ckt->CKTomega;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,8 +296,6 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
here->DIOm = 1;
|
here->DIOm = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
here->DIOarea = here->DIOarea * here->DIOm;
|
|
||||||
here->DIOpj = here->DIOpj * here->DIOm;
|
|
||||||
here->DIOcmetal = 0.0;
|
here->DIOcmetal = 0.0;
|
||||||
here->DIOcpoly = 0.0;
|
here->DIOcpoly = 0.0;
|
||||||
if (model->DIOlevel == 3) {
|
if (model->DIOlevel == 3) {
|
||||||
|
|
@ -331,10 +329,10 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
|
||||||
* (wp * scale + model->DIOpolyMaskOffset)
|
* (wp * scale + model->DIOpolyMaskOffset)
|
||||||
* (lp * scale + model->DIOpolyMaskOffset);
|
* (lp * scale + model->DIOpolyMaskOffset);
|
||||||
}
|
}
|
||||||
here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea;
|
here->DIOforwardKneeCurrent = model->DIOforwardKneeCurrent * here->DIOarea * here->DIOm;
|
||||||
here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea;
|
here->DIOreverseKneeCurrent = model->DIOreverseKneeCurrent * here->DIOarea * here->DIOm;
|
||||||
here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea;
|
here->DIOjunctionCap = model->DIOjunctionCap * here->DIOarea * here->DIOm;
|
||||||
here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj;
|
here->DIOjunctionSWCap = model->DIOjunctionSWCap * here->DIOpj * here->DIOm;
|
||||||
|
|
||||||
here->DIOstate = *states;
|
here->DIOstate = *states;
|
||||||
*states += DIOnumStates;
|
*states += DIOnumStates;
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vte*Temp);
|
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vte*Temp);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOemissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOemissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOemissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOemissionCoeff / Temp;
|
||||||
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * exp(arg1 + arg2);
|
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * here->DIOm * exp(arg1 + arg2);
|
||||||
here->DIOtSatCur_dT = here->DIOtSatCur * (arg1_dT + arg2_dT);
|
here->DIOtSatCur_dT = here->DIOtSatCur * (arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg1 = ((Temp / model->DIOnomTemp) - 1) * model->DIOactivationEnergy / vts;
|
arg1 = ((Temp / model->DIOnomTemp) - 1) * model->DIOactivationEnergy / vts;
|
||||||
|
|
@ -124,7 +124,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vts*Temp);
|
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vts*Temp);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff / Temp;
|
||||||
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * exp(arg1 + arg2);
|
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * here->DIOm * exp(arg1 + arg2);
|
||||||
here->DIOtSatSWCur_dT = here->DIOtSatSWCur * (arg1_dT + arg2_dT);
|
here->DIOtSatSWCur_dT = here->DIOtSatSWCur * (arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg1 = ((Temp/model->DIOnomTemp)-1) * model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy / vtt;
|
arg1 = ((Temp/model->DIOnomTemp)-1) * model->DIOtunEGcorrectionFactor*model->DIOactivationEnergy / vtt;
|
||||||
|
|
@ -132,10 +132,10 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vtt*Temp);
|
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vtt*Temp);
|
||||||
arg2 = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff * lnTRatio;
|
arg2 = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff / Temp;
|
arg2_dT = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff / Temp;
|
||||||
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * exp(arg1 + arg2);
|
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * here->DIOm * exp(arg1 + arg2);
|
||||||
here->DIOtTunSatCur_dT = here->DIOtTunSatCur * (arg1_dT + arg2_dT);
|
here->DIOtTunSatCur_dT = here->DIOtTunSatCur * (arg1_dT + arg2_dT);
|
||||||
|
|
||||||
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * exp(arg1 + arg2);
|
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * here->DIOm * exp(arg1 + arg2);
|
||||||
here->DIOtTunSatSWCur_dT = here->DIOtTunSatSWCur * (arg1_dT + arg2_dT);
|
here->DIOtTunSatSWCur_dT = here->DIOtTunSatSWCur * (arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg1 = ((Temp / model->DIOnomTemp) - 1) * model->DIOactivationEnergy / vtr;
|
arg1 = ((Temp / model->DIOnomTemp) - 1) * model->DIOactivationEnergy / vtr;
|
||||||
|
|
@ -143,7 +143,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vtr*Temp);
|
- model->DIOactivationEnergy*(Temp/model->DIOnomTemp -1)/(vtr*Temp);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff / Temp;
|
||||||
here->DIOtRecSatCur = model->DIOrecSatCur * here->DIOarea * exp(arg1 + arg2);
|
here->DIOtRecSatCur = model->DIOrecSatCur * here->DIOarea * here->DIOm * exp(arg1 + arg2);
|
||||||
here->DIOtRecSatCur_dT = here->DIOtRecSatCur * (arg1_dT + arg2_dT);
|
here->DIOtRecSatCur_dT = here->DIOtRecSatCur * (arg1_dT + arg2_dT);
|
||||||
} else {
|
} else {
|
||||||
arg0 = egfet1 / (model->DIOemissionCoeff * vtnom);
|
arg0 = egfet1 / (model->DIOemissionCoeff * vtnom);
|
||||||
|
|
@ -151,7 +151,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
arg1_dT = (egfet_dT * vte - egfet * vte_dT) / (egfet*egfet);
|
arg1_dT = (egfet_dT * vte - egfet * vte_dT) / (egfet*egfet);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOemissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOemissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOemissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOemissionCoeff / Temp;
|
||||||
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * exp(arg0 - arg1 + arg2);
|
here->DIOtSatCur = model->DIOsatCur * here->DIOarea * here->DIOm * exp(arg0 - arg1 + arg2);
|
||||||
here->DIOtSatCur_dT = here->DIOtSatCur * (-arg1_dT + arg2_dT);
|
here->DIOtSatCur_dT = here->DIOtSatCur * (-arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg0 = egfet1 / (model->DIOswEmissionCoeff * vtnom);
|
arg0 = egfet1 / (model->DIOswEmissionCoeff * vtnom);
|
||||||
|
|
@ -159,7 +159,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
arg1_dT = (egfet_dT * vts - egfet * vts_dT) / (egfet*egfet);
|
arg1_dT = (egfet_dT * vts - egfet * vts_dT) / (egfet*egfet);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOswEmissionCoeff / Temp;
|
||||||
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * exp(arg0 - arg1 + arg2);
|
here->DIOtSatSWCur = model->DIOsatSWCur * here->DIOpj * here->DIOm * exp(arg0 - arg1 + arg2);
|
||||||
here->DIOtSatSWCur_dT = here->DIOtSatSWCur * (-arg1_dT + arg2_dT);
|
here->DIOtSatSWCur_dT = here->DIOtSatSWCur * (-arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg0 = model->DIOtunEGcorrectionFactor * egfet1 / (model->DIOtunEmissionCoeff * vtnom);
|
arg0 = model->DIOtunEGcorrectionFactor * egfet1 / (model->DIOtunEmissionCoeff * vtnom);
|
||||||
|
|
@ -167,10 +167,10 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
arg1_dT = model->DIOtunEGcorrectionFactor * (egfet_dT * vtt - egfet * vtt_dT) / (egfet*egfet);
|
arg1_dT = model->DIOtunEGcorrectionFactor * (egfet_dT * vtt - egfet * vtt_dT) / (egfet*egfet);
|
||||||
arg2 = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff * lnTRatio;
|
arg2 = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff / Temp;
|
arg2_dT = model->DIOtunSaturationCurrentExp / model->DIOtunEmissionCoeff / Temp;
|
||||||
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * exp(arg0 - arg1 + arg2);
|
here->DIOtTunSatCur = model->DIOtunSatCur * here->DIOarea * here->DIOm * exp(arg0 - arg1 + arg2);
|
||||||
here->DIOtTunSatCur_dT = here->DIOtTunSatCur * (-arg1_dT + arg2_dT);
|
here->DIOtTunSatCur_dT = here->DIOtTunSatCur * (-arg1_dT + arg2_dT);
|
||||||
|
|
||||||
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * exp(arg0 - arg1 + arg2);
|
here->DIOtTunSatSWCur = model->DIOtunSatSWCur * here->DIOpj * here->DIOm * exp(arg0 - arg1 + arg2);
|
||||||
here->DIOtTunSatSWCur_dT = here->DIOtTunSatSWCur * (-arg1_dT + arg2_dT);
|
here->DIOtTunSatSWCur_dT = here->DIOtTunSatSWCur * (-arg1_dT + arg2_dT);
|
||||||
|
|
||||||
arg0 = egfet1 / (model->DIOrecEmissionCoeff * vtnom);
|
arg0 = egfet1 / (model->DIOrecEmissionCoeff * vtnom);
|
||||||
|
|
@ -178,7 +178,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
arg1_dT = (egfet_dT * vtr - egfet * vtr_dT) / (egfet*egfet);
|
arg1_dT = (egfet_dT * vtr - egfet * vtr_dT) / (egfet*egfet);
|
||||||
arg2 = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff * lnTRatio;
|
arg2 = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff * lnTRatio;
|
||||||
arg2_dT = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff / Temp;
|
arg2_dT = model->DIOsaturationCurrentExp / model->DIOrecEmissionCoeff / Temp;
|
||||||
here->DIOtRecSatCur = model->DIOrecSatCur * here->DIOarea * exp(arg0 - arg1 + arg2);
|
here->DIOtRecSatCur = model->DIOrecSatCur * here->DIOarea * here->DIOm * exp(arg0 - arg1 + arg2);
|
||||||
here->DIOtRecSatCur_dT = here->DIOtRecSatCur * (-arg1_dT + arg2_dT);
|
here->DIOtRecSatCur_dT = here->DIOtRecSatCur * (-arg1_dT + arg2_dT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,7 +209,7 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
if (model->DIOlevel == 1) {
|
if (model->DIOlevel == 1) {
|
||||||
cbv = here->DIOm * model->DIObreakdownCurrent;
|
cbv = here->DIOm * model->DIObreakdownCurrent;
|
||||||
} else { /* level=3 */
|
} else { /* level=3 */
|
||||||
cbv = model->DIObreakdownCurrent * here->DIOarea;
|
cbv = model->DIObreakdownCurrent * here->DIOarea * here->DIOm;
|
||||||
}
|
}
|
||||||
if (cbv < here->DIOtSatCur * tBreakdownVoltage/vt) {
|
if (cbv < here->DIOtSatCur * tBreakdownVoltage/vt) {
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
|
|
@ -244,12 +244,12 @@ void DIOtempUpdate(DIOmodel *inModel, DIOinstance *here, double Temp, CKTcircuit
|
||||||
here->DIOtTransitTime = model->DIOtransitTime * factor;
|
here->DIOtTransitTime = model->DIOtransitTime * factor;
|
||||||
|
|
||||||
/* Series resistance temperature adjust */
|
/* Series resistance temperature adjust */
|
||||||
here->DIOtConductance = model->DIOconductance * here->DIOarea;
|
here->DIOtConductance = model->DIOconductance * here->DIOarea * here->DIOm;
|
||||||
if(model->DIOresistGiven && model->DIOresist!=0.0) {
|
if(model->DIOresistGiven && model->DIOresist!=0.0) {
|
||||||
factor = 1.0 + (model->DIOresistTemp1) * dt
|
factor = 1.0 + (model->DIOresistTemp1) * dt
|
||||||
+ (model->DIOresistTemp2 * dt * dt);
|
+ (model->DIOresistTemp2 * dt * dt);
|
||||||
here->DIOtConductance = model->DIOconductance * here->DIOarea / factor;
|
here->DIOtConductance = model->DIOconductance * here->DIOarea * here->DIOm / factor;
|
||||||
here->DIOtConductance_dT = -model->DIOconductance * here->DIOarea *
|
here->DIOtConductance_dT = -model->DIOconductance * here->DIOarea * here->DIOm *
|
||||||
(model->DIOresistTemp1 + model->DIOresistTemp2 * dt) / (factor*factor);
|
(model->DIOresistTemp1 + model->DIOresistTemp2 * dt) / (factor*factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue