📄 b3soild.c
字号:
if (here->B3SOIowner != ARCHme) continue; Check = 0; ByPass = 0; selfheat = (model->B3SOIshMod == 1) && (here->B3SOIrth0 != 0.0); pParam = here->pParam; if ((ckt->CKTmode & MODEINITSMSIG)) { vs = *(ckt->CKTrhsOld + here->B3SOIsNodePrime); if (!here->B3SOIvbsusrGiven) { vbs = *(ckt->CKTstate0 + here->B3SOIvbs); vb = *(ckt->CKTrhsOld + here->B3SOIbNode); } else { vbs = here->B3SOIvbsusr; vb = here->B3SOIvbsusr + vs; } vgs = *(ckt->CKTstate0 + here->B3SOIvgs); ves = *(ckt->CKTstate0 + here->B3SOIves); vps = *(ckt->CKTstate0 + here->B3SOIvps); vds = *(ckt->CKTstate0 + here->B3SOIvds); delTemp = *(ckt->CKTstate0 + here->B3SOIdeltemp); vg = *(ckt->CKTrhsOld + here->B3SOIgNode); vd = *(ckt->CKTrhsOld + here->B3SOIdNodePrime); vp = *(ckt->CKTrhsOld + here->B3SOIpNode); ve = *(ckt->CKTrhsOld + here->B3SOIeNode); } else if ((ckt->CKTmode & MODEINITTRAN)) { vs = *(ckt->CKTrhsOld + here->B3SOIsNodePrime); if (!here->B3SOIvbsusrGiven) { vbs = *(ckt->CKTstate1 + here->B3SOIvbs); vb = *(ckt->CKTrhsOld + here->B3SOIbNode); } else { vbs = here->B3SOIvbsusr; vb = here->B3SOIvbsusr + vs; } vgs = *(ckt->CKTstate1 + here->B3SOIvgs); ves = *(ckt->CKTstate1 + here->B3SOIves); vps = *(ckt->CKTstate1 + here->B3SOIvps); vds = *(ckt->CKTstate1 + here->B3SOIvds); delTemp = *(ckt->CKTstate1 + here->B3SOIdeltemp); vg = *(ckt->CKTrhsOld + here->B3SOIgNode); vd = *(ckt->CKTrhsOld + here->B3SOIdNodePrime); vp = *(ckt->CKTrhsOld + here->B3SOIpNode); ve = *(ckt->CKTrhsOld + here->B3SOIeNode); } else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIoff) { vds = model->B3SOItype * here->B3SOIicVDS; vgs = model->B3SOItype * here->B3SOIicVGS; ves = model->B3SOItype * here->B3SOIicVES; vbs = model->B3SOItype * here->B3SOIicVBS; vps = model->B3SOItype * here->B3SOIicVPS; vg = vd = vs = vp = ve = 0.0; delTemp = 0.0; here->B3SOIphi = pParam->B3SOIphi; if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = 0.0; vgs = model->B3SOItype*0.1 + pParam->B3SOIvth0; vds = 0.0; ves = 0.0; vps = 0.0; } } else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && (here->B3SOIoff)) { delTemp = vps = vbs = vgs = vds = ves = 0.0; vg = vd = vs = vp = ve = 0.0; } else {#ifndef PREDICTOR if ((ckt->CKTmode & MODEINITPRED)) { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->B3SOIvbs) = *(ckt->CKTstate1 + here->B3SOIvbs); vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIvbs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIvbs))); *(ckt->CKTstate0 + here->B3SOIvgs) = *(ckt->CKTstate1 + here->B3SOIvgs); vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIvgs)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIvgs))); *(ckt->CKTstate0 + here->B3SOIves) = *(ckt->CKTstate1 + here->B3SOIves); ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIves)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIves))); *(ckt->CKTstate0 + here->B3SOIvps) = *(ckt->CKTstate1 + here->B3SOIvps); vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIvps)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIvps))); *(ckt->CKTstate0 + here->B3SOIvds) = *(ckt->CKTstate1 + here->B3SOIvds); vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIvds)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIvds))); *(ckt->CKTstate0 + here->B3SOIvbd) = *(ckt->CKTstate0 + here->B3SOIvbs) - *(ckt->CKTstate0 + here->B3SOIvds); *(ckt->CKTstate0 + here->B3SOIvg) = *(ckt->CKTstate1 + here->B3SOIvg); *(ckt->CKTstate0 + here->B3SOIvd) = *(ckt->CKTstate1 + here->B3SOIvd); *(ckt->CKTstate0 + here->B3SOIvs) = *(ckt->CKTstate1 + here->B3SOIvs); *(ckt->CKTstate0 + here->B3SOIvp) = *(ckt->CKTstate1 + here->B3SOIvp); *(ckt->CKTstate0 + here->B3SOIve) = *(ckt->CKTstate1 + here->B3SOIve); /* Only predict ve */ ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIve)) - (xfact * (*(ckt->CKTstate2 + here->B3SOIve))); /* Then update vg, vs, vb, vd, vp base on ve */ vs = ve - model->B3SOItype * ves; vg = model->B3SOItype * vgs + vs; vd = model->B3SOItype * vds + vs; vb = model->B3SOItype * vbs + vs; vp = model->B3SOItype * vps + vs; delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIdeltemp))-(xfact * (*(ckt->CKTstate2 + here->B3SOIdeltemp)));/* v2.2.3 bug fix */ *(ckt->CKTstate0 + here->B3SOIdeltemp) = *(ckt->CKTstate1 + here->B3SOIdeltemp); if (selfheat) { here->B3SOIphi = 2.0 * here->B3SOIvtm * log(pParam->B3SOInpeak / here->B3SOIni); } } else {#endif /* PREDICTOR */ vg = B3SOIlimit(*(ckt->CKTrhsOld + here->B3SOIgNode), *(ckt->CKTstate0 + here->B3SOIvg), 3.0, &Check); vd = B3SOIlimit(*(ckt->CKTrhsOld + here->B3SOIdNodePrime), *(ckt->CKTstate0 + here->B3SOIvd), 3.0, &Check); vs = B3SOIlimit(*(ckt->CKTrhsOld + here->B3SOIsNodePrime), *(ckt->CKTstate0 + here->B3SOIvs), 3.0, &Check); vp = B3SOIlimit(*(ckt->CKTrhsOld + here->B3SOIpNode), *(ckt->CKTstate0 + here->B3SOIvp), 3.0, &Check); ve = B3SOIlimit(*(ckt->CKTrhsOld + here->B3SOIeNode), *(ckt->CKTstate0 + here->B3SOIve), 3.0, &Check); delTemp = *(ckt->CKTrhsOld + here->B3SOItempNode); vbs = model->B3SOItype * (*(ckt->CKTrhsOld+here->B3SOIbNode) - *(ckt->CKTrhsOld+here->B3SOIsNodePrime)); vps = model->B3SOItype * (vp - vs); vgs = model->B3SOItype * (vg - vs); ves = model->B3SOItype * (ve - vs); vds = model->B3SOItype * (vd - vs);#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd = vbs - vds; vgd = vgs - vds; ved = ves - vds; vgdo = *(ckt->CKTstate0 + here->B3SOIvgs) - *(ckt->CKTstate0 + here->B3SOIvds); vedo = *(ckt->CKTstate0 + here->B3SOIves) - *(ckt->CKTstate0 + here->B3SOIvds); delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIvbs); delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIvbd); delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIvgs); delves = ves - *(ckt->CKTstate0 + here->B3SOIves); delvps = vps - *(ckt->CKTstate0 + here->B3SOIvps); deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIdeltemp); delvds = vds - *(ckt->CKTstate0 + here->B3SOIvds); delvgd = vgd - vgdo; delved = ved - vedo; if (here->B3SOImode >= 0) { cdhat = here->B3SOIcd + (here->B3SOIgm-here->B3SOIgjdg) * delvgs + (here->B3SOIgds - here->B3SOIgjdd) * delvds + (here->B3SOIgmbs - here->B3SOIgjdb) * delvbs + (here->B3SOIgme - here->B3SOIgjde) * delves + (here->B3SOIgmT - here->B3SOIgjdT) * deldelTemp; /* v3.0 */ } else { cdhat = here->B3SOIcd + (here->B3SOIgm-here->B3SOIgjdg) * delvgd - (here->B3SOIgds - here->B3SOIgjdd) * delvds + (here->B3SOIgmbs - here->B3SOIgjdb) * delvbd + (here->B3SOIgme - here->B3SOIgjde) * delved + (here->B3SOIgmT - here->B3SOIgjdT) * deldelTemp; /* v3.0 */ } cbhat = here->B3SOIcb + here->B3SOIgbgs * delvgs + here->B3SOIgbbs * delvbs + here->B3SOIgbds * delvds + here->B3SOIgbes * delves + here->B3SOIgbps * delvps + here->B3SOIgbT * deldelTemp; /* v3.0 */#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 ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->B3SOIvbs))) + ckt->CKTvoltTol)) ) if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->B3SOIvbd))) + ckt->CKTvoltTol)) ) if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->B3SOIvgs))) + ckt->CKTvoltTol))) if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), fabs(*(ckt->CKTstate0+here->B3SOIves))) + ckt->CKTvoltTol))) if ( (here->B3SOIbodyMod == 0) || (here->B3SOIbodyMod == 2) || (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), fabs(*(ckt->CKTstate0+here->B3SOIvps))) + ckt->CKTvoltTol)) ) if ( (here->B3SOItempNode == 0) || (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), fabs(*(ckt->CKTstate0+here->B3SOIdeltemp))) + ckt->CKTvoltTol*1e4))) if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->B3SOIvds))) + ckt->CKTvoltTol))) if ((fabs(cdhat - here->B3SOIcd) < ckt->CKTreltol * MAX(fabs(cdhat),fabs(here->B3SOIcd)) + ckt->CKTabstol)) if ((fabs(cbhat - here->B3SOIcb) < ckt->CKTreltol * MAX(fabs(cbhat),fabs(here->B3SOIcb)) + ckt->CKTabstol) ) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->B3SOIvbs); vbd = *(ckt->CKTstate0 + here->B3SOIvbd); vgs = *(ckt->CKTstate0 + here->B3SOIvgs); ves = *(ckt->CKTstate0 + here->B3SOIves); vps = *(ckt->CKTstate0 + here->B3SOIvps); vds = *(ckt->CKTstate0 + here->B3SOIvds); delTemp = *(ckt->CKTstate0 + here->B3SOIdeltemp); /* calculate Vds for temperature conductance calculation in bypass (used later when filling Temp node matrix) */ Vds = here->B3SOImode > 0 ? vds : -vds; vgd = vgs - vds; vgb = vgs - vbs; veb = ves - vbs; if ((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { ByPass = 1; goto line755; } else { goto line850; } }#endif /*NOBYPASS*/ von = here->B3SOIvon; if (*(ckt->CKTstate0 + here->B3SOIvds) >= 0.0) T0 = *(ckt->CKTstate0 + here->B3SOIvbs); else T0 = *(ckt->CKTstate0 + here->B3SOIvbd); if (vds >= 0.0) { vbs = B3SOIlimit(vbs, T0, 0.2, &Check); vbd = vbs - vds; vb = model->B3SOItype * vbs + vs; } else { vbd = B3SOIlimit(vbd, T0, 0.2, &Check); vbs = vbd + vds; vb = model->B3SOItype * vbs + vd; } delTemp =B3SOIlimit(delTemp, *(ckt->CKTstate0 + here->B3SOIdeltemp),5.0,&Check); }/* Calculate temperature dependent values for self-heating effect */ Temp = delTemp + ckt->CKTtemp; dTempRatio_dT = 1 / model->B3SOItnom; TempRatio = Temp * dTempRatio_dT; 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->B3SOInpeak / (ni * ni)); vbi = Vtm * T0; dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -