⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mos9load.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 + -