📄 mos9load.c
字号:
dvodvb = dvtdvb+vt*dxndvb; } else { /* *.....cutoff region */ if ( (here->MOS9mode==1?vgs:vgd) <= von ) { cdrain = 0.0; here->MOS9gm = 0.0; here->MOS9gds = 0.0; here->MOS9gmbs = 0.0; goto innerline1000; } } /* *.....device is on */ vgsx = MAX((here->MOS9mode==1?vgs:vgd),von); /* *.....mobility modulation by gate voltage */ onfg = 1.0+model->MOS9theta*(vgsx-vth); fgate = 1.0/onfg; us = here->MOS9tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate; dfgdvg = -model->MOS9theta*fgate*fgate; dfgdvd = -dfgdvg*dvtdvd; dfgdvb = -dfgdvg*dvtdvb; /* *.....saturation voltage */ vdsat = (vgsx-vth)*onfbdy; if ( model->MOS9maxDriftVel <= 0.0 ) { dvsdvg = onfbdy; dvsdvd = -dvsdvg*dvtdvd; dvsdvb = -dvsdvg*dvtdvb-vdsat*dfbdvb*onfbdy; } else { vdsc = EffectiveLength*model->MOS9maxDriftVel/us; onvdsc = 1.0/vdsc; arga = (vgsx-vth)*onfbdy; argb = sqrt(arga*arga+vdsc*vdsc); vdsat = arga+vdsc-argb; dvsdga = (1.0-arga/argb)*onfbdy; dvsdvg = dvsdga-(1.0-vdsc/argb)*vdsc*dfgdvg*onfg; dvsdvd = -dvsdvg*dvtdvd; dvsdvb = -dvsdvg*dvtdvb-arga*dvsdga*dfbdvb; } /* *.....current factors in linear region */ vdsx = MIN((here->MOS9mode*vds),vdsat); if ( vdsx == 0.0 ) goto line900; cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx; dcodvb = -dvtdvb-0.5*dfbdvb*vdsx; /* *.....normalized drain current */ cdnorm = cdo*vdsx; here->MOS9gm = vdsx; if ((here->MOS9mode*vds) > vdsat) here->MOS9gds = -dvtdvd*vdsx; else here->MOS9gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx; here->MOS9gmbs = dcodvb*vdsx; /* *.....drain current without velocity saturation effect */ cd1 = Beta*cdnorm; Beta = Beta*fgate; cdrain = Beta*cdnorm; here->MOS9gm = Beta*here->MOS9gm+dfgdvg*cd1; here->MOS9gds = Beta*here->MOS9gds+dfgdvd*cd1; here->MOS9gmbs = Beta*here->MOS9gmbs+dfgdvb*cd1; /* *.....velocity saturation factor */ if ( model->MOS9maxDriftVel > 0.0 ) { fdrain = 1.0/(1.0+vdsx*onvdsc); fd2 = fdrain*fdrain; arga = fd2*vdsx*onvdsc*onfg; dfddvg = -dfgdvg*arga; if ((here->MOS9mode*vds) > vdsat) dfddvd = -dfgdvd*arga; else dfddvd = -dfgdvd*arga-fd2*onvdsc; dfddvb = -dfgdvb*arga; /* *.....drain current */ here->MOS9gm = fdrain*here->MOS9gm+dfddvg*cdrain; here->MOS9gds = fdrain*here->MOS9gds+dfddvd*cdrain; here->MOS9gmbs = fdrain*here->MOS9gmbs+dfddvb*cdrain; cdrain = fdrain*cdrain; Beta = Beta*fdrain; } /* *.....channel length modulation */ if ((here->MOS9mode*vds) <= vdsat) { if ( (model->MOS9maxDriftVel > 0.0) || (model->MOS9alpha == 0.0) || (ckt->CKTbadMos3) ) goto line700; else { arga = (here->MOS9mode*vds)/vdsat; delxl = sqrt(model->MOS9kappa*model->MOS9alpha*vdsat/8); dldvd = 4*delxl*arga*arga*arga/vdsat; arga *= arga; arga *= arga; delxl *= arga; ddldvg = 0.0; ddldvd = -dldvd; ddldvb = 0.0; goto line520; }; }; if ( model->MOS9maxDriftVel <= 0.0 ) goto line510; if (model->MOS9alpha == 0.0) goto line700; cdsat = cdrain; gdsat = cdsat*(1.0-fdrain)*onvdsc; gdsat = MAX(1.0e-12,gdsat); gdoncd = gdsat/cdsat; gdonfd = gdsat/(1.0-fdrain); gdonfg = gdsat*onfg; dgdvg = gdoncd*here->MOS9gm-gdonfd*dfddvg+gdonfg*dfgdvg; dgdvd = gdoncd*here->MOS9gds-gdonfd*dfddvd+gdonfg*dfgdvd; dgdvb = gdoncd*here->MOS9gmbs-gdonfd*dfddvb+gdonfg*dfgdvb; if (ckt->CKTbadMos3) emax = cdsat*oneoverxl/gdsat; else emax = model->MOS9kappa * cdsat*oneoverxl/gdsat; emoncd = emax/cdsat; emongd = emax/gdsat; demdvg = emoncd*here->MOS9gm-emongd*dgdvg; demdvd = emoncd*here->MOS9gds-emongd*dgdvd; demdvb = emoncd*here->MOS9gmbs-emongd*dgdvb; arga = 0.5*emax*model->MOS9alpha; argc = model->MOS9kappa*model->MOS9alpha; argb = sqrt(arga*arga+argc*((here->MOS9mode*vds)-vdsat)); delxl = argb-arga; dldvd = argc/(argb+argb); dldem = 0.5*(arga/argb-1.0)*model->MOS9alpha; ddldvg = dldem*demdvg; ddldvd = dldem*demdvd-dldvd; ddldvb = dldem*demdvb; goto line520;line510: if (ckt->CKTbadMos3) { delxl = sqrt(model->MOS9kappa*((here->MOS9mode*vds)-vdsat)* model->MOS9alpha); dldvd = 0.5*delxl/((here->MOS9mode*vds)-vdsat); } else { delxl = sqrt(model->MOS9kappa*model->MOS9alpha* ((here->MOS9mode*vds)-vdsat+(vdsat/8))); dldvd = 0.5*delxl/((here->MOS9mode*vds)-vdsat+(vdsat/8)); }; ddldvg = 0.0; ddldvd = -dldvd; ddldvb = 0.0; /* *.....punch through approximation */line520: if ( delxl > (0.5*EffectiveLength) ) { delxl = EffectiveLength-(EffectiveLength*EffectiveLength/ (4.0*delxl)); arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/ (EffectiveLength*EffectiveLength); ddldvg = ddldvg*arga; ddldvd = ddldvd*arga; ddldvb = ddldvb*arga; dldvd = dldvd*arga; } /* *.....saturation region */ dlonxl = delxl*oneoverxl; xlfact = 1.0/(1.0-dlonxl); cd1 = cdrain; cdrain = cdrain*xlfact; diddl = cdrain/(EffectiveLength-delxl); here->MOS9gm = here->MOS9gm*xlfact+diddl*ddldvg; here->MOS9gmbs = here->MOS9gmbs*xlfact+diddl*ddldvb; gds0 = diddl*ddldvd; here->MOS9gm = here->MOS9gm+gds0*dvsdvg; here->MOS9gmbs = here->MOS9gmbs+gds0*dvsdvb; here->MOS9gds = here->MOS9gds*xlfact+diddl*dldvd+gds0*dvsdvd;/* here->MOS9gds = (here->MOS9gds*xlfact)+gds0*dvsdvd- (cd1*ddldvd/(EffectiveLength*(1-2*dlonxl+dlonxl*dlonxl)));*/ /* *.....finish strong inversion case */line700: if ( (here->MOS9mode==1?vgs:vgd) < von ) { /* *.....weak inversion */ onxn = 1.0/xn; ondvt = onxn/vt; wfact = exp( ((here->MOS9mode==1?vgs:vgd)-von)*ondvt ); cdrain = cdrain*wfact; gms = here->MOS9gm*wfact; gmw = cdrain*ondvt; here->MOS9gm = gmw; if ((here->MOS9mode*vds) > vdsat) { here->MOS9gm = here->MOS9gm+gds0*dvsdvg*wfact; } here->MOS9gds = here->MOS9gds*wfact+(gms-gmw)*dvodvd; here->MOS9gmbs = here->MOS9gmbs*wfact+(gms-gmw)*dvodvb-gmw* ((here->MOS9mode==1?vgs:vgd)-von)*onxn*dxndvb; } /* *.....charge computation */ goto innerline1000; /* *.....special case of vds = 0.0d0 */line900: Beta = Beta*fgate; cdrain = 0.0; here->MOS9gm = 0.0; here->MOS9gds = Beta*(vgsx-vth); here->MOS9gmbs = 0.0; if ( (model->MOS9fastSurfaceStateDensity != 0.0) && ((here->MOS9mode==1?vgs:vgd) < von) ) { here->MOS9gds *=exp(((here->MOS9mode==1?vgs:vgd)-von)/(vt*xn)); }innerline1000:; /* *.....done */ } /* now deal with n vs p polarity */ here->MOS9von = model->MOS9type * von; here->MOS9vdsat = model->MOS9type * vdsat; /* line 490 */ /* * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE */ here->MOS9cd=here->MOS9mode * cdrain - here->MOS9cbd; if (ckt->CKTmode & (MODETRAN | MODETRANOP | MODEINITSMSIG)) { /* * now we do the hard part of the bulk-drain and bulk-source * diode - we evaluate the non-linear capacitance and * charge * * the basic equations are not hard, but the implementation * is somewhat long in an attempt to avoid log/exponential * evaluations */ /* * charge storage elements * *.. bulk-drain and bulk-source depletion capacitances */#ifdef CAPBYPASS if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) || fabs(delvbs) >= ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->MOS9vbs)))+ ckt->CKTvoltTol)|| senflag )#endif /*CAPBYPASS*/ { /* can't bypass the diode capacitance calculations */#ifdef CAPZEROBYPASS if(here->MOS9Cbs != 0 || here->MOS9Cbssw != 0 ) {#endif /*CAPZEROBYPASS*/ if (vbs < here->MOS9tDepCap){ arg=1-vbs/here->MOS9tBulkPot; /* * the following block looks somewhat long and messy, * but since most users use the default grading * coefficients of .5, and sqrt is MUCH faster than an * exp(log()) we use this special case code to buy time. * (as much as 10% of total job time!) */#ifndef NOSQRT if(model->MOS9bulkJctBotGradingCoeff == model->MOS9bulkJctSideGradingCoeff) { if(model->MOS9bulkJctBotGradingCoeff == .5) { sarg = sargsw = 1/sqrt(arg); } else { sarg = sargsw = exp(-model->MOS9bulkJctBotGradingCoeff* log(arg)); } } else { if(model->MOS9bulkJctBotGradingCoeff == .5) { sarg = 1/sqrt(arg); } else {#endif /*NOSQRT*/ sarg = exp(-model->MOS9bulkJctBotGradingCoeff* log(arg));#ifndef NOSQRT } if(model->MOS9bulkJctSideGradingCoeff == .5) { sargsw = 1/sqrt(arg); } else {#endif /*NOSQRT*/ sargsw =exp(-model->MOS9bulkJctSideGradingCoeff* log(arg));#ifndef NOSQRT } }#endif /*NOSQRT*/ *(ckt->CKTstate0 + here->MOS9qbs) = here->MOS9tBulkPot*(here->MOS9Cbs* (1-arg*sarg)/(1-model->MOS9bulkJctBotGradingCoeff) +here->MOS9Cbssw* (1-arg*sargsw)/ (1-model->MOS9bulkJctSideGradingCoeff)); here->MOS9capbs=here->MOS9Cbs*sarg+ here->MOS9Cbssw*sargsw; } else { *(ckt->CKTstate0 + here->MOS9qbs) = here->MOS9f4s + vbs*(here->MOS9f2s+vbs*(here->MOS9f3s/2)); here->MOS9capbs=here->MOS9f2s+here->MOS9f3s*vbs; }#ifdef CAPZEROBYPASS } else { *(ckt->CKTstate0 + here->MOS9qbs) = 0; here->MOS9capbs=0; }#endif /*CAPZEROBYPASS*/ }#ifdef CAPBYPASS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -