📄 b3soiddld.c
字号:
{ fprintf(stderr,"DC op. point converge with %d iterations\n", here->B3SOIDDiterations); } } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs = *(ckt->CKTstate1 + here->B3SOIDDvbs); vgs = *(ckt->CKTstate1 + here->B3SOIDDvgs); ves = *(ckt->CKTstate1 + here->B3SOIDDves); vps = *(ckt->CKTstate1 + here->B3SOIDDvps); vds = *(ckt->CKTstate1 + here->B3SOIDDvds); delTemp = *(ckt->CKTstate1 + here->B3SOIDDdeltemp); vg = *(ckt->CKTrhsOld + here->B3SOIDDgNode); vd = *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime); vs = *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime); vp = *(ckt->CKTrhsOld + here->B3SOIDDpNode); ve = *(ckt->CKTrhsOld + here->B3SOIDDeNode); vb = *(ckt->CKTrhsOld + here->B3SOIDDbNode); if (here->B3SOIDDdebugMod > 2) { fprintf(fpdebug, "... Init Transient ....\n"); } if (here->B3SOIDDdebugMod > 0) { fprintf(stderr, "Transient operation point converge with %d iterations\n",here->B3SOIDDiterations); } here->B3SOIDDiterations = 0; } else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIDDoff) { vds = model->B3SOIDDtype * here->B3SOIDDicVDS; vgs = model->B3SOIDDtype * here->B3SOIDDicVGS; ves = model->B3SOIDDtype * here->B3SOIDDicVES; vbs = model->B3SOIDDtype * here->B3SOIDDicVBS; vps = model->B3SOIDDtype * here->B3SOIDDicVPS; vg = vd = vs = vp = ve = 0.0; here->B3SOIDDiterations = 0; /* initialize iteration number */ delTemp = 0.0; here->B3SOIDDphi = pParam->B3SOIDDphi; if (here->B3SOIDDdebugMod > 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->B3SOIDDtype*0.1 + pParam->B3SOIDDvth0; vds = 0.0; ves = 0.0; vps = 0.0; } } else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && (here->B3SOIDDoff)) { delTemp = vps = vbs = vgs = vds = ves = 0.0; vg = vd = vs = vp = ve = 0.0; here->B3SOIDDiterations = 0; /* initialize iteration number */ } else {#ifndef PREDICTOR if ((ckt->CKTmode & MODEINITPRED)) { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->B3SOIDDvbs) = *(ckt->CKTstate1 + here->B3SOIDDvbs); vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvbs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvbs))); *(ckt->CKTstate0 + here->B3SOIDDvgs) = *(ckt->CKTstate1 + here->B3SOIDDvgs); vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvgs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvgs))); *(ckt->CKTstate0 + here->B3SOIDDves) = *(ckt->CKTstate1 + here->B3SOIDDves); ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDves)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDves))); *(ckt->CKTstate0 + here->B3SOIDDvps) = *(ckt->CKTstate1 + here->B3SOIDDvps); vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvps)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvps))); *(ckt->CKTstate0 + here->B3SOIDDvds) = *(ckt->CKTstate1 + here->B3SOIDDvds); vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvds)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvds))); *(ckt->CKTstate0 + here->B3SOIDDvbd) = *(ckt->CKTstate0 + here->B3SOIDDvbs) - *(ckt->CKTstate0 + here->B3SOIDDvds); *(ckt->CKTstate0 + here->B3SOIDDvg) = *(ckt->CKTstate1 + here->B3SOIDDvg); *(ckt->CKTstate0 + here->B3SOIDDvd) = *(ckt->CKTstate1 + here->B3SOIDDvd); *(ckt->CKTstate0 + here->B3SOIDDvs) = *(ckt->CKTstate1 + here->B3SOIDDvs); *(ckt->CKTstate0 + here->B3SOIDDvp) = *(ckt->CKTstate1 + here->B3SOIDDvp); *(ckt->CKTstate0 + here->B3SOIDDve) = *(ckt->CKTstate1 + here->B3SOIDDve); /* Only predict ve */ ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDve)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDve))); /* Then update vg, vs, vb, vd, vp base on ve */ vs = ve - model->B3SOIDDtype * ves; vg = model->B3SOIDDtype * vgs + vs; vd = model->B3SOIDDtype * vds + vs; vb = model->B3SOIDDtype * vbs + vs; vp = model->B3SOIDDtype * vps + vs; delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDdeltemp))-(xfact * (*(ckt->CKTstate2 + here->B3SOIDDdeltemp))); if (selfheat) { here->B3SOIDDphi = 2.0 * here->B3SOIDDvtm * log (pParam->B3SOIDDnpeak / here->B3SOIDDni); } if (here->B3SOIDDdebugMod > 0) { fprintf(stderr, "Time = %.6e converge with %d iterations\n", ckt->CKTtime, here->B3SOIDDiterations); } if (here->B3SOIDDdebugMod > 2) { fprintf(fpdebug, "... PREDICTOR calculation ....\n"); } here->B3SOIDDiterations = 0; } else {#endif /* PREDICTOR */ vg = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDgNode), *(ckt->CKTstate0 + here->B3SOIDDvg), 3.0, &Check); vd = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDdNodePrime), *(ckt->CKTstate0 + here->B3SOIDDvd), 3.0, &Check); vs = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), *(ckt->CKTstate0 + here->B3SOIDDvs), 3.0, &Check); vp = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDpNode), *(ckt->CKTstate0 + here->B3SOIDDvp), 3.0, &Check); ve = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDeNode), *(ckt->CKTstate0 + here->B3SOIDDve), 3.0, &Check); delTemp = *(ckt->CKTrhsOld + here->B3SOIDDtempNode); vbs = model->B3SOIDDtype * (*(ckt->CKTrhsOld+here->B3SOIDDbNode) - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); vps = model->B3SOIDDtype * (vp - vs); vgs = model->B3SOIDDtype * (vg - vs); ves = model->B3SOIDDtype * (ve - vs); vds = model->B3SOIDDtype * (vd - vs); if (here->B3SOIDDdebugMod > 2) { fprintf(fpdebug, "... DC calculation ....\n");fprintf(fpdebug, "Vg = %.10f; Vb = %.10f; Vs = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIDDgNode), *(ckt->CKTrhsOld + here->B3SOIDDbNode), *(ckt->CKTrhsOld + here->B3SOIDDsNode));fprintf(fpdebug, "Vd = %.10f; Vsp = %.10f; Vdp = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIDDdNode), *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime));fprintf(fpdebug, "Ve = %.10f; Vp = %.10f; delTemp = %.10f\n", *(ckt->CKTrhsOld + here->B3SOIDDeNode), *(ckt->CKTrhsOld + here->B3SOIDDpNode), *(ckt->CKTrhsOld + here->B3SOIDDtempNode)); }#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd = vbs - vds; vgd = vgs - vds; ved = ves - vds; vgdo = *(ckt->CKTstate0 + here->B3SOIDDvgs) - *(ckt->CKTstate0 + here->B3SOIDDvds); vedo = *(ckt->CKTstate0 + here->B3SOIDDves) - *(ckt->CKTstate0 + here->B3SOIDDvds); delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIDDvbs); delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIDDvbd); delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIDDvgs); delves = ves - *(ckt->CKTstate0 + here->B3SOIDDves); delvps = vps - *(ckt->CKTstate0 + here->B3SOIDDvps); deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIDDdeltemp); delvds = vds - *(ckt->CKTstate0 + here->B3SOIDDvds); delvgd = vgd - vgdo; delved = ved - vedo; if (here->B3SOIDDmode >= 0) { cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgs + (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbs + (here->B3SOIDDgme - here->B3SOIDDgjde) * delves + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; } else { cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgd - (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbd + (here->B3SOIDDgme - here->B3SOIDDgjde) * delved + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; } cbhat = here->B3SOIDDcb + here->B3SOIDDgbgs * delvgs + here->B3SOIDDgbbs * delvbs + here->B3SOIDDgbds * delvds + here->B3SOIDDgbes * delves + here->B3SOIDDgbps * delvps + here->B3SOIDDgbT * 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->B3SOIDDdebugMod > 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->B3SOIDDvbs))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol))) ? 1 : 0, ((fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + ckt->CKTvoltTol*1e4))) ? 1 : 0);fprintf(fpdebug, "delCd %.4e, delCb %.4e\n", fabs(cdhat - here->B3SOIDDcd) , fabs(cbhat - here->B3SOIDDcb)); } if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->B3SOIDDvbs))) + ckt->CKTvoltTol)) ) if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->B3SOIDDvbd))) + ckt->CKTvoltTol)) ) if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) if ( (here->B3SOIDDbodyMod == 0) || (here->B3SOIDDbodyMod == 2) || (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol)) ) if ( (here->B3SOIDDtempNode == 0) || (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + ckt->CKTvoltTol*1e4))) if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) if ((fabs(cdhat - here->B3SOIDDcd) < ckt->CKTreltol * MAX(fabs(cdhat),fabs(here->B3SOIDDcd)) + ckt->CKTabstol)) if ((fabs(cbhat - here->B3SOIDDcb) < ckt->CKTreltol * MAX(fabs(cbhat),fabs(here->B3SOIDDcb)) + ckt->CKTabstol) ) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->B3SOIDDvbs); vbd = *(ckt->CKTstate0 + here->B3SOIDDvbd); vgs = *(ckt->CKTstate0 + here->B3SOIDDvgs); ves = *(ckt->CKTstate0 + here->B3SOIDDves); vps = *(ckt->CKTstate0 + here->B3SOIDDvps); vds = *(ckt->CKTstate0 + here->B3SOIDDvds); delTemp = *(ckt->CKTstate0 + here->B3SOIDDdeltemp); /* calculate Vds for temperature conductance calculation in bypass (used later when filling Temp node matrix) */ Vds = here->B3SOIDDmode > 0 ? vds : -vds; vgd = vgs - vds; vgb = vgs - vbs; veb = ves - vbs; if (here->B3SOIDDdebugMod > 2) {fprintf(stderr, "Bypass for %s...\n", here->B3SOIDDname); 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->B3SOIDDvon; if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) { here->B3SOIDDdum1 = here->B3SOIDDdum2 = here->B3SOIDDdum3 = 0.0; here->B3SOIDDdum4 = here->B3SOIDDdum5 = 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->B3SOIDDdebugMod > 2) { fprintf(fpdebug, "Limited : vgs = %.8f\n", vgs); fprintf(fpdebug, "Limited : vds = %.8f\n", vds); } if (*(ckt->CKTstate0 + here->B3SOIDDvds) >= 0.0) T0 = *(ckt->CKTstate0 + here->B3SOIDDvbs); else T0 = *(ckt->CKTstate0 + here->B3SOIDDvbd); if (here->B3SOIDDdebugMod > 2) fprintf(fpdebug, "Before lim : vbs = %.8f, after = ", T0); if (vds >= 0.0) { vbs = B3SOIDDlimit(vbs, T0, 0.2, &Check); vbs = B3SOIDDSmartVbs(vbs, T0, here, ckt, &Check); vbd = vbs - vds; vb = model->B3SOIDDtype * vbs + vs; if (here->B3SOIDDdebugMod > 2) fprintf(fpdebug, "%.8f\n", vbs); } else { vbd = B3SOIDDlimit(vbd, T0, 0.2, &Check); vbd = B3SOIDDSmartVbs(vbd, T0, here, ckt, &Check); vbs = vbd + vds; vb = model->B3SOIDDtype * vbs + vd; if (here->B3SOIDDdebugMod > 2) fprintf(fpdebug, "%.8f\n", vbd); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -