From 45f52c859b75ae142b0285faf133ab687bd128e0 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 9 Apr 2018 15:33:34 +0200 Subject: [PATCH] enable breakdown capability of parallel bulk diode --- src/spicelib/devices/vdmos/vdmosload.c | 46 +++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/spicelib/devices/vdmos/vdmosload.c b/src/spicelib/devices/vdmos/vdmosload.c index d6eebf519..aa21e3013 100644 --- a/src/spicelib/devices/vdmos/vdmosload.c +++ b/src/spicelib/devices/vdmos/vdmosload.c @@ -159,6 +159,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) /* now some common crunching for some more useful quantities */ + vbs = 0; vbd = vbs - vds; vgd = vgs - vds; vgdo = *(ckt->CKTstate0 + here->VDMOSvgs) - @@ -319,7 +320,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) ((ckt->CKTmode & (MODETRAN | MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { - vbs = -1; + vbs = 0; vgs = model->VDMOStype * here->VDMOStVto; vds = 0; } @@ -666,7 +667,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) double vd; /* current diode voltage */ double vdtemp; double vte; - double vtebrk; + double vtebrk, vbrknp; double cd, cdb, csat, cdeq; double czero; double czof2; @@ -687,6 +688,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) gspr = here->VDIOtConductance; vte = model->VDMOSDn * vt; vtebrk = model->VDIObrkdEmissionCoeff * vt; + vbrknp = model->VDMOStype * here->VDIOtBrkdwnV; Check = 1; if (ckt->CKTmode & MODEINITSMSIG) { @@ -715,8 +717,8 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) } else { #endif /* PREDICTOR */ - vd = *(ckt->CKTrhsOld + here->VDIOposPrimeNode) - - *(ckt->CKTrhsOld + here->VDMOSdNode); + vd = model->VDMOStype * (*(ckt->CKTrhsOld + here->VDIOposPrimeNode) - + *(ckt->CKTrhsOld + here->VDMOSdNode)); #ifndef PREDICTOR } #endif /* PREDICTOR */ @@ -748,13 +750,13 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) * limit new junction voltage */ if ((model->VDMOSDbvGiven) && - (vd < MIN(0, -here->VDIOtBrkdwnV + 10 * vtebrk))) { - vdtemp = -(vd + here->VDIOtBrkdwnV); + (vd < MIN(0, -vbrknp + 10 * vtebrk))) { + vdtemp = -(vd + vbrknp); vdtemp = DEVpnjlim(vdtemp, -(*(ckt->CKTstate0 + here->VDIOvoltage) + - here->VDIOtBrkdwnV), vtebrk, + vbrknp), vtebrk, here->VDIOtVcrit, &Check); - vd = -(vdtemp + here->VDIOtBrkdwnV); + vd = -(vdtemp + vbrknp); } else { vd = DEVpnjlim(vd, *(ckt->CKTstate0 + here->VDIOvoltage), @@ -772,7 +774,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) } else if ((!(model->VDMOSDbvGiven)) || - vd >= -here->VDIOtBrkdwnV) { /* reverse */ + vd >= -vbrknp) { /* reverse */ arg = 3 * vte / (vd*CONSTe); arg = arg * arg * arg; @@ -782,7 +784,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) } else { /* breakdown */ - evrev = exp(-(here->VDIOtBrkdwnV + vd) / vtebrk); + evrev = exp(-(vbrknp + vd) / vtebrk); cdb = -csat*evrev; gdb = csat*evrev / vtebrk; @@ -866,32 +868,30 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt) *(ckt->CKTstate0 + here->VDIOconduct) = gd; #ifndef NOBYPASS - load : +load : #endif /* * load current vector */ cdeq = cd - gd*vd; - *(ckt->CKTrhs + here->VDMOSdNode) += cdeq; - *(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq; + if (model->VDMOStype == 1) { + *(ckt->CKTrhs + here->VDMOSdNode) += cdeq; + *(ckt->CKTrhs + here->VDIOposPrimeNode) -= cdeq; + } + else { + *(ckt->CKTrhs + here->VDMOSdNode) -= cdeq; + *(ckt->CKTrhs + here->VDIOposPrimeNode) += cdeq; + } + /* * load matrix */ - /* - *(here->DIOposPosPtr) += gspr; - *(here->DIOnegNegPtr) += gd; - *(here->DIOposPrimePosPrimePtr) += (gd + gspr); - *(here->DIOposPosPrimePtr) -= gspr; - *(here->DIOnegPosPrimePtr) -= gd; - *(here->DIOposPrimePosPtr) -= gspr; - *(here->DIOposPrimeNegPtr) -= gd; - */ *(here->VDMOSSsPtr) += gspr; *(here->VDMOSDdPtr) += gd; *(here->VDIORPrpPtr) += (gd + gspr); *(here->VDIOSrpPtr) -= gspr; *(here->VDIODrpPtr) -= gd; - *(here->VDIOSrpPtr) -= gspr; + *(here->VDIORPsPtr) -= gspr; *(here->VDIORPdPtr) -= gd; } }