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

📄 mos2load.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
            dudvds = 0.0;            dudvbs = model->MOS2critFieldExp*ufact*dodvbs/vgst;            goto line500;line410:            ufact = 1.0;            ueff = model->MOS2surfaceMobility * 1e-4 /*(m**2/cm**2) */ ;            dudvgs = 0.0;            dudvds = 0.0;            dudvbs = 0.0;            /*             *     evaluate saturation voltage and its derivatives according to             *     grove-frohman equation             */line500:            vgsx = lvgs;            gammad = gamasd/eta;            dgdvbs = dgddvb;            if (model->MOS2fastSurfaceStateDensity != 0 && OxideCap != 0) {                vgsx = MAX(lvgs,von);            }            if (gammad > 0) {                gammd2 = gammad*gammad;                argv = (vgsx-vbin)/eta+phiMinVbs;                if (argv <= 0.0) {                    vdsat = 0.0;                    dsdvgs = 0.0;                    dsdvbs = 0.0;                } else {                    arg = sqrt(1.0+4.0*argv/gammd2);                    vdsat = (vgsx-vbin)/eta+gammd2*(1.0-arg)/2.0;                    vdsat = MAX(vdsat,0.0);                    dsdvgs = (1.0-1.0/arg)/eta;                    dsdvbs = (gammad*(1.0-arg)+2.0*argv/(gammad*arg))/                        eta*dgdvbs+1.0/arg+factor*dsdvgs;                }            } else {                vdsat = (vgsx-vbin)/eta;                vdsat = MAX(vdsat,0.0);                dsdvgs = 1.0;                dsdvbs = 0.0;            }            if (model->MOS2maxDriftVel > 0) {                /*                  *     evaluate saturation voltage and its derivatives                  *     according to baum's theory of scattering velocity                  *     saturation                 */                gammd2 = gammad*gammad;                v1 = (vgsx-vbin)/eta+phiMinVbs;                v2 = phiMinVbs;                xv = model->MOS2maxDriftVel*EffectiveLength/ueff;                a1 = gammad/0.75;                b1 = -2.0*(v1+xv);                c1 = -2.0*gammad*xv;                d1 = 2.0*v1*(v2+xv)-v2*v2-4.0/3.0*gammad*sarg3;                a = -b1;                b = a1*c1-4.0*d1;                c = -d1*(a1*a1-4.0*b1)-c1*c1;                r = -a*a/3.0+b;                s = 2.0*a*a*a/27.0-a*b/3.0+c;                r3 = r*r*r;                s2 = s*s;                p = s2/4.0+r3/27.0;                p0 = FABS(p);                p2 = sqrt(p0);                if (p < 0) {                    ro = sqrt(s2/4.0+p0);                    ro = log(ro)/3.0;                    ro = exp(ro);                    fi = atan(-2.0*p2/s);                    y3 = 2.0*ro*cos(fi/3.0)-a/3.0;                } else {                    p3 = (-s/2.0+p2);                    p3 = exp(log(FABS(p3))/3.0);                    p4 = (-s/2.0-p2);                    p4 = exp(log(FABS(p4))/3.0);                    y3 = p3+p4-a/3.0;                }                iknt = 0;                a3 = sqrt(a1*a1/4.0-b1+y3);                b3 = sqrt(y3*y3/4.0-d1);                for(i = 1;i<=4;i++) {                    a4[i-1] = a1/2.0+sig1[i-1]*a3;                    b4[i-1] = y3/2.0+sig2[i-1]*b3;                    delta4 = a4[i-1]*a4[i-1]/4.0-b4[i-1];                    if (delta4 < 0) continue;                    iknt = iknt+1;                    tmp = sqrt(delta4);                    x4[iknt-1] = -a4[i-1]/2.0+tmp;                    iknt = iknt+1;                    x4[iknt-1] = -a4[i-1]/2.0-tmp;                }                jknt = 0;                for(j = 1;j<=iknt;j++) {                    if (x4[j-1] <= 0) continue;                    /* XXX implement this sanely */                    poly4[j-1] = x4[j-1]*x4[j-1]*x4[j-1]*x4[j-1]+a1*x4[j-1]*                        x4[j-1]*x4[j-1];                    poly4[j-1] = poly4[j-1]+b1*x4[j-1]*x4[j-1]+c1*x4[j-1]+d1;                    if (FABS(poly4[j-1]) > 1.0e-6) continue;                    jknt = jknt+1;                    if (jknt <= 1) {                        xvalid = x4[j-1];                    }                    if (x4[j-1] > xvalid) continue;                    xvalid = x4[j-1];                }                if (jknt > 0) {                    vdsat = xvalid*xvalid-phiMinVbs;                }            }            /*             *  evaluate effective channel length and its derivatives             */            if (lvds != 0.0) {                gammad = gamasd;                if ((lvbs-vdsat) <= 0) {                    bsarg = sqrt(vdsat+phiMinVbs);                    dbsrdb = -0.5/bsarg;                } else {                    bsarg = sphi/(1.0+0.5*(lvbs-vdsat)/here->MOS2tPhi);                    dbsrdb = -0.5*bsarg*bsarg/sphi3;                }                bodys = bsarg*bsarg*bsarg-sarg3;                gdbdvs = 2.0*gammad*(bsarg*bsarg*dbsrdb-sarg*sarg*dsrgdb);                if (model->MOS2maxDriftVel <= 0) {                    if (model->MOS2substrateDoping == 0.0) goto line610;                    if (xlamda > 0.0) goto line610;                    argv = (lvds-vdsat)/4.0;                    sargv = sqrt(1.0+argv*argv);                    arg = sqrt(argv+sargv);                    xlfact = model->MOS2xd/(EffectiveLength*lvds);                    xlamda = xlfact*arg;                    dldsat = lvds*xlamda/(8.0*sargv);                } else {                    argv = (vgsx-vbin)/eta-vdsat;                    xdv = model->MOS2xd/sqrt(model->MOS2channelCharge);                    xlv = model->MOS2maxDriftVel*xdv/(2.0*ueff);                    vqchan = argv-gammad*bsarg;                    dqdsat = -1.0+gammad*dbsrdb;                    vl = model->MOS2maxDriftVel*EffectiveLength;                    dfunds = vl*dqdsat-ueff*vqchan;                    dfundg = (vl-ueff*vdsat)/eta;                    dfundb = -vl*(1.0+dqdsat-factor/eta)+ueff*                        (gdbdvs-dgdvbs*bodys/1.5)/eta;                    dsdvgs = -dfundg/dfunds;                    dsdvbs = -dfundb/dfunds;                    if (model->MOS2substrateDoping == 0.0) goto line610;                    if (xlamda > 0.0) goto line610;                    argv = lvds-vdsat;                    argv = MAX(argv,0.0);                    xls = sqrt(xlv*xlv+argv);                    dldsat = xdv/(2.0*xls);                    xlfact = xdv/(EffectiveLength*lvds);                    xlamda = xlfact*(xls-xlv);                    dldsat = dldsat/EffectiveLength;                }                dldvgs = dldsat*dsdvgs;                dldvds = -xlamda+dldsat;                dldvbs = dldsat*dsdvbs;            } else {line610:                dldvgs = 0.0;                dldvds = 0.0;                dldvbs = 0.0;            }            /*             *     limit channel shortening at punch-through             */            xwb = model->MOS2xd*sbiarg;            xld = EffectiveLength-xwb;            clfact = 1.0-xlamda*lvds;            dldvds = -xlamda-dldvds;            xleff = EffectiveLength*clfact;            deltal = xlamda*lvds*EffectiveLength;            if (model->MOS2substrateDoping == 0.0) xwb = 0.25e-6;            if (xleff < xwb) {                xleff = xwb/(1.0+(deltal-xld)/xwb);                clfact = xleff/EffectiveLength;                dfact = xleff*xleff/(xwb*xwb);                dldvgs = dfact*dldvgs;                dldvds = dfact*dldvds;                dldvbs = dfact*dldvbs;            }            /*             *  evaluate effective beta (effective kp)             */            beta1 = Beta*ufact/clfact;            /*             *  test for mode of operation and branch appropriately             */            gammad = gamasd;            dgdvbs = dgddvb;            if (lvds <= 1.0e-10) {                if (lvgs <= von) {                    if ((model->MOS2fastSurfaceStateDensity == 0.0) ||                            (OxideCap == 0.0)) {                        here->MOS2gds = 0.0;                        goto line1050;                    }                    here->MOS2gds = beta1*(von-vbin-gammad*sarg)*exp(argg*                        (lvgs-von));                    goto line1050;                }                here->MOS2gds = beta1*(lvgs-vbin-gammad*sarg);                goto line1050;            }            if (lvgs > von) goto line900;            /*             *  subthreshold region             */            if (vdsat <= 0) {                here->MOS2gds = 0.0;                if (lvgs > vth) goto doneval;                goto line1050;            }             vdson = MIN(vdsat,lvds);            if (lvds > vdsat) {                barg = bsarg;                dbrgdb = dbsrdb;                body = bodys;                gdbdv = gdbdvs;            }            cdson = beta1*((von-vbin-eta*vdson*0.5)*vdson-gammad*body/1.5);            didvds = beta1*(von-vbin-eta*vdson-gammad*barg);            gdson = -cdson*dldvds/clfact-beta1*dgdvds*body/1.5;            if (lvds < vdsat) gdson = gdson+didvds;            gbson = -cdson*dldvbs/clfact+beta1*                (dodvbs*vdson+factor*vdson-dgdvbs*body/1.5-gdbdv);            if (lvds > vdsat) gbson = gbson+didvds*dsdvbs;            expg = exp(argg*(lvgs-von));            cdrain = cdson*expg;            gmw = cdrain*argg;            here->MOS2gm = gmw;            if (lvds > vdsat) here->MOS2gm = gmw+didvds*dsdvgs*expg;            tmp = gmw*(lvgs-von)/xn;            here->MOS2gds = gdson*expg-here->MOS2gm*dodvds-tmp*dxndvd;            here->MOS2gmbs = gbson*expg-here->MOS2gm*dodvbs-tmp*dxndvb;            goto doneval;line900:            if (lvds <= vdsat) {                /*                 *  linear region                 */                cdrain = beta1*((lvgs-vbin-eta*lvds/2.0)*lvds-gammad*body/1.5);                arg = cdrain*(dudvgs/ufact-dldvgs/clfact);                here->MOS2gm = arg+beta1*lvds;                arg = cdrain*(dudvds/ufact-dldvds/clfact);                here->MOS2gds = arg+beta1*(lvgs-vbin-eta*                    lvds-gammad*barg-dgdvds*body/1.5);                arg = cdrain*(dudvbs/ufact-dldvbs/clfact);                here->MOS2gmbs = arg-beta1*(gdbdv+dgdvbs*body/1.5-factor*lvds);            } else {                /*                  *  saturation region                 */                cdrain = beta1*((lvgs-vbin-eta*                    vdsat/2.0)*vdsat-gammad*bodys/1.5);                arg = cdrain*(dudvgs/ufact-dldvgs/clfact);                here->MOS2gm = arg+beta1*vdsat+beta1*(lvgs-                    vbin-eta*vdsat-gammad*bsarg)*dsdvgs;                here->MOS2gds = -cdrain*dldvds/clfact-beta1*dgdvds*bodys/1.5;                arg = cdrain*(dudvbs/ufact-dldvbs/clfact);                here->MOS2gmbs = arg-beta1*(gdbdvs+dgdvbs*bodys/1.5-factor*                        vdsat)+beta1* (lvgs-vbin-eta*vdsat-gammad*bsarg)*dsdvbs;            }            /*             *     compute charges for "on" region             */            goto doneval;            /*             *  finish special cases             */line1050:            cdrain = 0.0;            here->MOS2gm = 0.0;            here->MOS2gmbs = 0.0;            /*             *  finished             */            }doneval:                here->MOS2von = model->MOS2type * von;            here->MOS2vdsat = model->MOS2type * vdsat;            /*             *  COMPUTE EQUIVALENT DRAIN CURRENT SOURCE             */            here->MOS2cd=here->MOS2mode * cdrain - here->MOS2cbd;            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->MOS2vbs)))+                        ckt->CKTvoltTol)|| senflag)#endif /*CAPBYPASS*/                {                    /* can't bypass the diode capacitance calculations */#ifdef CAPZEROBYPASS                    if(here->MOS2Cbs != 0 || here->MOS2Cbssw != 0) {#endif /*CAPZEROBYPASS*/                    if (vbs < here->MOS2tDepCap){                        arg=1-vbs/here->MOS2tBulkPot;                        /*                         * 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->MOS2bulkJctBotGradingCoeff ==                                model->MOS2bulkJctSideGradingCoeff) {                            if(model->MOS2bulkJctBotGradingCoeff == .5) {                                sarg = sargsw = 1/sqrt(arg);                            } else {                                sarg = sargsw =                                        exp(-model->MOS2bulkJctBotGradingCoeff*                                        log(arg));                            }                        } else {                            if(model->MOS2bulkJctBotGradingCoeff == .5) {                                sarg = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sarg = exp(-model->MOS2bulkJctBotGradingCoeff*                                        log(arg));#ifndef NOSQRT                            }                            if(model->MOS2bulkJctSideGradingCoeff == .5) {                                sargsw = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sargsw =exp(-model->MOS2bulkJctSideGradingCoeff*                                        log(arg));#ifndef NOSQRT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -