📄 b3soifdld.c
字号:
vgs = model->B3SOIFDtype * here->B3SOIFDicVGS; ves = model->B3SOIFDtype * here->B3SOIFDicVES; vbs = model->B3SOIFDtype * here->B3SOIFDicVBS; vps = model->B3SOIFDtype * here->B3SOIFDicVPS; vg = vd = vs = vp = ve = 0.0; here->B3SOIFDiterations = 0; /* initialize iteration number */ delTemp = 0.0; here->B3SOIFDphi = pParam->B3SOIFDphi; if (here->B3SOIFDdebugMod > 2) fprintf(fpdebug, "... INIT JCT ...\n"); if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = 0.0; vgs = model->B3SOIFDtype*0.1 + pParam->B3SOIFDvth0; vds = 0.0; ves = 0.0; vps = 0.0; } } else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && (here->B3SOIFDoff)) { delTemp = vps = vbs = vgs = vds = ves = 0.0; vg = vd = vs = vp = ve = 0.0; here->B3SOIFDiterations = 0; /* initialize iteration number */ } else {#ifndef PREDICTOR if ((ckt->CKTmode & MODEINITPRED)) { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->B3SOIFDvbs) = *(ckt->CKTstate1 + here->B3SOIFDvbs); vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvbs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvbs))); *(ckt->CKTstate0 + here->B3SOIFDvgs) = *(ckt->CKTstate1 + here->B3SOIFDvgs); vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvgs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvgs))); *(ckt->CKTstate0 + here->B3SOIFDves) = *(ckt->CKTstate1 + here->B3SOIFDves); ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDves)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDves))); *(ckt->CKTstate0 + here->B3SOIFDvps) = *(ckt->CKTstate1 + here->B3SOIFDvps); vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvps)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvps))); *(ckt->CKTstate0 + here->B3SOIFDvds) = *(ckt->CKTstate1 + here->B3SOIFDvds); vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDvds)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDvds))); *(ckt->CKTstate0 + here->B3SOIFDvbd) = *(ckt->CKTstate0 + here->B3SOIFDvbs) - *(ckt->CKTstate0 + here->B3SOIFDvds); *(ckt->CKTstate0 + here->B3SOIFDvg) = *(ckt->CKTstate1 + here->B3SOIFDvg); *(ckt->CKTstate0 + here->B3SOIFDvd) = *(ckt->CKTstate1 + here->B3SOIFDvd); *(ckt->CKTstate0 + here->B3SOIFDvs) = *(ckt->CKTstate1 + here->B3SOIFDvs); *(ckt->CKTstate0 + here->B3SOIFDvp) = *(ckt->CKTstate1 + here->B3SOIFDvp); *(ckt->CKTstate0 + here->B3SOIFDve) = *(ckt->CKTstate1 + here->B3SOIFDve); /* Only predict ve */ ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDve)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIFDve))); /* Then update vg, vs, vb, vd, vp base on ve */ vs = ve - model->B3SOIFDtype * ves; vg = model->B3SOIFDtype * vgs + vs; vd = model->B3SOIFDtype * vds + vs; vb = model->B3SOIFDtype * vbs + vs; vp = model->B3SOIFDtype * vps + vs; delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIFDdeltemp))-(xfact * (*(ckt->CKTstate2 + here->B3SOIFDdeltemp))); if (selfheat) { here->B3SOIFDphi = 2.0 * here->B3SOIFDvtm * log (pParam->B3SOIFDnpeak / here->B3SOIFDni); } if (here->B3SOIFDdebugMod > 0) { fprintf(stderr, "Time = %.6e converge with %d iterations\n", ckt->CKTtime, here->B3SOIFDiterations); } if (here->B3SOIFDdebugMod > 2) { fprintf(fpdebug, "... PREDICTOR calculation ....\n"); } here->B3SOIFDiterations = 0; } else {#endif /* PREDICTOR */ vg = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDgNode), *(ckt->CKTstate0 + here->B3SOIFDvg), 3.0, &Check); vd = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDdNodePrime), *(ckt->CKTstate0 + here->B3SOIFDvd), 3.0, &Check); vs = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDsNodePrime), *(ckt->CKTstate0 + here->B3SOIFDvs), 3.0, &Check); vp = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDpNode), *(ckt->CKTstate0 + here->B3SOIFDvp), 3.0, &Check); ve = B3SOIFDlimit(*(ckt->CKTrhsOld + here->B3SOIFDeNode), *(ckt->CKTstate0 + here->B3SOIFDve), 3.0, &Check); delTemp = *(ckt->CKTrhsOld + here->B3SOIFDtempNode); vbs = model->B3SOIFDtype * (*(ckt->CKTrhsOld+here->B3SOIFDbNode) - *(ckt->CKTrhsOld+here->B3SOIFDsNodePrime)); vps = model->B3SOIFDtype * (vp - vs); vgs = model->B3SOIFDtype * (vg - vs); ves = model->B3SOIFDtype * (ve - vs); vds = model->B3SOIFDtype * (vd - vs); if (here->B3SOIFDdebugMod > 2) { fprintf(fpdebug, "... DC calculation ....\n");fprintf(fpdebug, "Vg = %.10f; Vb = %.10f; Vs = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIFDgNode), *(ckt->CKTrhsOld + here->B3SOIFDbNode), *(ckt->CKTrhsOld + here->B3SOIFDsNode));fprintf(fpdebug, "Vd = %.10f; Vsp = %.10f; Vdp = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIFDdNode), *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime), *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime));fprintf(fpdebug, "Ve = %.10f; Vp = %.10f; delTemp = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIFDeNode), *(ckt->CKTrhsOld + here->B3SOIFDpNode), *(ckt->CKTrhsOld + here->B3SOIFDtempNode)); }#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd = vbs - vds; vgd = vgs - vds; ved = ves - vds; vgdo = *(ckt->CKTstate0 + here->B3SOIFDvgs) - *(ckt->CKTstate0 + here->B3SOIFDvds); vedo = *(ckt->CKTstate0 + here->B3SOIFDves) - *(ckt->CKTstate0 + here->B3SOIFDvds); delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIFDvbs); delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIFDvbd); delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIFDvgs); delves = ves - *(ckt->CKTstate0 + here->B3SOIFDves); delvps = vps - *(ckt->CKTstate0 + here->B3SOIFDvps); deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIFDdeltemp); delvds = vds - *(ckt->CKTstate0 + here->B3SOIFDvds); delvgd = vgd - vgdo; delved = ved - vedo; if (here->B3SOIFDmode >= 0) { cdhat = here->B3SOIFDcd + (here->B3SOIFDgm-here->B3SOIFDgjdg) * delvgs + (here->B3SOIFDgds - here->B3SOIFDgjdd) * delvds + (here->B3SOIFDgmbs - here->B3SOIFDgjdb) * delvbs + (here->B3SOIFDgme - here->B3SOIFDgjde) * delves + (here->B3SOIFDgmT - here->B3SOIFDgjdT) * deldelTemp; } else { cdhat = here->B3SOIFDcd + (here->B3SOIFDgm-here->B3SOIFDgjdg) * delvgd - (here->B3SOIFDgds - here->B3SOIFDgjdd) * delvds + (here->B3SOIFDgmbs - here->B3SOIFDgjdb) * delvbd + (here->B3SOIFDgme - here->B3SOIFDgjde) * delved + (here->B3SOIFDgmT - here->B3SOIFDgjdT) * deldelTemp; } cbhat = here->B3SOIFDcb + here->B3SOIFDgbgs * delvgs + here->B3SOIFDgbbs * delvbs + here->B3SOIFDgbds * delvds + here->B3SOIFDgbes * delves + here->B3SOIFDgbps * delvps + here->B3SOIFDgbT * deldelTemp;#ifndef NOBYPASS /* following should be one big if connected by && all over * the place, but some C compilers can't handle that, so * we split it up here to let them digest it in stages */ if (here->B3SOIFDdebugMod > 3) {fprintf(fpdebug, "Convergent Criteria : vbs %d vds %d vgs %d ves %d vps %d temp %d\n", ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->B3SOIFDvbs))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->B3SOIFDvds))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->B3SOIFDvgs))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), fabs(*(ckt->CKTstate0+here->B3SOIFDves))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), fabs(*(ckt->CKTstate0+here->B3SOIFDvps))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), fabs(*(ckt->CKTstate0+here->B3SOIFDdeltemp))) + ckt->CKTvoltTol*1e4))) ? 1 : 0);fprintf(fpdebug, "delCd %.4e, delCb %.4e\n", fabs(cdhat - here->B3SOIFDcd) , fabs(cbhat - here->B3SOIFDcb)); } if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->B3SOIFDvbs))) + ckt->CKTvoltTol)) ) if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->B3SOIFDvbd))) + ckt->CKTvoltTol)) ) if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->B3SOIFDvgs))) + ckt->CKTvoltTol))) if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), fabs(*(ckt->CKTstate0+here->B3SOIFDves))) + ckt->CKTvoltTol))) if ( (here->B3SOIFDbodyMod == 0) || (here->B3SOIFDbodyMod == 2) || (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), fabs(*(ckt->CKTstate0+here->B3SOIFDvps))) + ckt->CKTvoltTol)) ) if ( (here->B3SOIFDtempNode == 0) || (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), fabs(*(ckt->CKTstate0+here->B3SOIFDdeltemp))) + ckt->CKTvoltTol*1e4))) if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->B3SOIFDvds))) + ckt->CKTvoltTol))) if ((fabs(cdhat - here->B3SOIFDcd) < ckt->CKTreltol * MAX(fabs(cdhat),fabs(here->B3SOIFDcd)) + ckt->CKTabstol)) if ((fabs(cbhat - here->B3SOIFDcb) < ckt->CKTreltol * MAX(fabs(cbhat),fabs(here->B3SOIFDcb)) + ckt->CKTabstol) ) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->B3SOIFDvbs); vbd = *(ckt->CKTstate0 + here->B3SOIFDvbd); vgs = *(ckt->CKTstate0 + here->B3SOIFDvgs); ves = *(ckt->CKTstate0 + here->B3SOIFDves); vps = *(ckt->CKTstate0 + here->B3SOIFDvps); vds = *(ckt->CKTstate0 + here->B3SOIFDvds); delTemp = *(ckt->CKTstate0 + here->B3SOIFDdeltemp); /* calculate Vds for temperature conductance calculation in bypass (used later when filling Temp node matrix) */ Vds = here->B3SOIFDmode > 0 ? vds : -vds; vgd = vgs - vds; vgb = vgs - vbs; veb = ves - vbs; if (here->B3SOIFDdebugMod > 2) {fprintf(stderr, "Bypass for %s...\n", here->B3SOIFDname); fprintf(fpdebug, "... By pass ....\n"); fprintf(fpdebug, "vgs=%.4f, vds=%.4f, vbs=%.4f, ", vgs, vds, vbs); fprintf(fpdebug, "ves=%.4f, vps=%.4f\n", ves, vps); } if ((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { ByPass = 1; goto line755; } else { goto line850; } }#endif /*NOBYPASS*/ von = here->B3SOIFDvon; if ((here->B3SOIFDdebugMod > 1) || (here->B3SOIFDdebugMod == -1)) { here->B3SOIFDdum1 = here->B3SOIFDdum2 = here->B3SOIFDdum3 = 0.0; here->B3SOIFDdum4 = here->B3SOIFDdum5 = 0.0; Qac0 = Qsub0 = Qsubs1 = Qsubs2 = Qbf = Qe1 = Qe2 = 0.0; qjs = qjd = Cbg = Cbb = Cbd = Cbe = Xc = qdrn = qgate = 0.0; qbody = qsub = 0.0; } if (here->B3SOIFDdebugMod > 2) { fprintf(fpdebug, "Limited : vgs = %.8f\n", vgs); fprintf(fpdebug, "Limited : vds = %.8f\n", vds); } if (*(ckt->CKTstate0 + here->B3SOIFDvds) >= 0.0) T0 = *(ckt->CKTstate0 + here->B3SOIFDvbs); else T0 = *(ckt->CKTstate0 + here->B3SOIFDvbd); if (here->B3SOIFDdebugMod > 2) fprintf(fpdebug, "Before lim : vbs = %.8f, after = ", T0); if (vds >= 0.0) { vbs = B3SOIFDlimit(vbs, T0, 0.2, &Check); vbs = B3SOIFDSmartVbs(vbs, T0, here, ckt, &Check); vbd = vbs - vds; vb = model->B3SOIFDtype * vbs + vs; if (here->B3SOIFDdebugMod > 2) fprintf(fpdebug, "%.8f\n", vbs); } else { vbd = B3SOIFDlimit(vbd, T0, 0.2, &Check); vbd = B3SOIFDSmartVbs(vbd, T0, here, ckt, &Check); vbs = vbd + vds; vb = model->B3SOIFDtype * vbs + vd; if (here->B3SOIFDdebugMod > 2) fprintf(fpdebug, "%.8f\n", vbd); } delTemp =B3SOIFDlimit(delTemp, *(ckt->CKTstate0 + here->B3SOIFDdeltemp),5.0,&Check); }/* Calculate temperature dependent values for self-heating effect */ Temp = delTemp + ckt->CKTtemp;/* for debugging Temp = ckt->CKTtemp; selfheat = 1; if (here->B3SOIFDname[1] == '2') { Temp += 0.01; } */ TempRatio = Temp / model->B3SOIFDtnom; if (selfheat) { Vtm = KboQ * Temp; T0 = 1108.0 + Temp; T5 = Temp * Temp; Eg = 1.16 - 7.02e-4 * T5 / T0; T1 = ((7.02e-4 * T5) - T0 * (14.04e-4 * Temp)) / T0 / T0; /* T1 = dEg / dT */ T2 = 1.9230584e-4; /* T2 = 1 / 300.15^(3/2) */ T5 = sqrt(Temp); T3 = 1.45e10 * Temp * T5 * T2; T4 = exp(21.5565981 - Eg / (2.0 * Vtm)); ni = T3 * T4; dni_dT = 2.175e10 * T2 * T5 * T4 + T3 * T4 * (-Vtm * T1 + Eg * KboQ) / (2.0 * Vtm * Vtm); T0 = log(1.0e20 * pParam->B3SOIFDnpeak / (ni * ni)); vbi = Vtm * T0; dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni); if (pParam->B3SOIFDnsub > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -