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

📄 mos3load.c

📁 linux平台下类似著名的电路板作图软件 Spice的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                    1e4 /*(cm**2/m**2)*/ *EffectiveLength*here->MOS3w/OxideCap;                cdonco = qbonco/(phibs+phibs);                xn = 1.0+csonco+cdonco;                von = vth+vt*xn;                dxndvb = dqbdvb/(phibs+phibs)-qbonco*dsqdvb/(phibs*sqphbs);                dvodvd = dvtdvd;                dvodvb = dvtdvb+vt*dxndvb;            } else {                /*                 *.....cutoff region                 */                if ( (here->MOS3mode==1?vgs:vgd) <= von ) {                    cdrain = 0.0;                    here->MOS3gm = 0.0;                    here->MOS3gds = 0.0;                    here->MOS3gmbs = 0.0;                    goto innerline1000;                }            }            /*             *.....device is on             */            vgsx = MAX((here->MOS3mode==1?vgs:vgd),von);            /*             *.....mobility modulation by gate voltage             */            onfg = 1.0+model->MOS3theta*(vgsx-vth);            fgate = 1.0/onfg;            us = here->MOS3tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate;            dfgdvg = -model->MOS3theta*fgate*fgate;            dfgdvd = -dfgdvg*dvtdvd;            dfgdvb = -dfgdvg*dvtdvb;            /*             *.....saturation voltage             */            vdsat = (vgsx-vth)*onfbdy;            if ( model->MOS3maxDriftVel <= 0.0 ) {                dvsdvg = onfbdy;                dvsdvd = -dvsdvg*dvtdvd;                dvsdvb = -dvsdvg*dvtdvb-vdsat*dfbdvb*onfbdy;            } else {                vdsc = EffectiveLength*model->MOS3maxDriftVel/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->MOS3mode*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->MOS3gm = vdsx;            here->MOS3gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx;            here->MOS3gmbs = dcodvb*vdsx;            /*              *.....drain current without velocity saturation effect             */            cd1 = Beta*cdnorm;            Beta = Beta*fgate;            cdrain = Beta*cdnorm;            here->MOS3gm = Beta*here->MOS3gm+dfgdvg*cd1;            here->MOS3gds = Beta*here->MOS3gds+dfgdvd*cd1;            here->MOS3gmbs = Beta*here->MOS3gmbs;            /*             *.....velocity saturation factor             */            if ( model->MOS3maxDriftVel != 0.0 ) {                fdrain = 1.0/(1.0+vdsx*onvdsc);                fd2 = fdrain*fdrain;                arga = fd2*vdsx*onvdsc*onfg;                dfddvg = -dfgdvg*arga;                dfddvd = -dfgdvd*arga-fd2*onvdsc;                dfddvb = -dfgdvb*arga;                /*                 *.....drain current                 */                here->MOS3gm = fdrain*here->MOS3gm+dfddvg*cdrain;                here->MOS3gds = fdrain*here->MOS3gds+dfddvd*cdrain;                here->MOS3gmbs = fdrain*here->MOS3gmbs+dfddvb*cdrain;                cdrain = fdrain*cdrain;                Beta = Beta*fdrain;            }            /*             *.....channel length modulation             */            if ( (here->MOS3mode*vds) <= vdsat ) goto line700;            if ( model->MOS3maxDriftVel <= 0.0 ) goto line510;            if (model->MOS3alpha == 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->MOS3gm-gdonfd*dfddvg+gdonfg*dfgdvg;            dgdvd = gdoncd*here->MOS3gds-gdonfd*dfddvd+gdonfg*dfgdvd;            dgdvb = gdoncd*here->MOS3gmbs-gdonfd*dfddvb+gdonfg*dfgdvb;	    if (ckt->CKTbadMos3)		    emax = cdsat*oneoverxl/gdsat;	    else		    emax = model->MOS3kappa * cdsat*oneoverxl/gdsat;            emoncd = emax/cdsat;            emongd = emax/gdsat;            demdvg = emoncd*here->MOS3gm-emongd*dgdvg;            demdvd = emoncd*here->MOS3gds-emongd*dgdvd;            demdvb = emoncd*here->MOS3gmbs-emongd*dgdvb;            arga = 0.5*emax*model->MOS3alpha;            argc = model->MOS3kappa*model->MOS3alpha;            argb = sqrt(arga*arga+argc*((here->MOS3mode*vds)-vdsat));            delxl = argb-arga;            dldvd = argc/(argb+argb);            dldem = 0.5*(arga/argb-1.0)*model->MOS3alpha;            ddldvg = dldem*demdvg;            ddldvd = dldem*demdvd-dldvd;            ddldvb = dldem*demdvb;            goto line520;line510:            delxl = sqrt(model->MOS3kappa*((here->MOS3mode*vds)-vdsat)*                model->MOS3alpha);            dldvd = 0.5*delxl/((here->MOS3mode*vds)-vdsat);            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);            cdrain = cdrain*xlfact;            diddl = cdrain/(EffectiveLength-delxl);            here->MOS3gm = here->MOS3gm*xlfact+diddl*ddldvg;            gds0 = here->MOS3gds*xlfact+diddl*ddldvd;            here->MOS3gmbs = here->MOS3gmbs*xlfact+diddl*ddldvb;            here->MOS3gm = here->MOS3gm+gds0*dvsdvg;            here->MOS3gmbs = here->MOS3gmbs+gds0*dvsdvb;            here->MOS3gds = gds0*dvsdvd+diddl*dldvd;            /*             *.....finish strong inversion case             */line700:            if ( (here->MOS3mode==1?vgs:vgd) < von ) {                /*                 *.....weak inversion                 */                onxn = 1.0/xn;                ondvt = onxn/vt;                wfact = exp( ((here->MOS3mode==1?vgs:vgd)-von)*ondvt );                cdrain = cdrain*wfact;                gms = here->MOS3gm*wfact;                gmw = cdrain*ondvt;                here->MOS3gm = gmw;                if ((here->MOS3mode*vds) > vdsat) {                    here->MOS3gm = here->MOS3gm+gds0*dvsdvg*wfact;                }                here->MOS3gds = here->MOS3gds*wfact+(gms-gmw)*dvodvd;                here->MOS3gmbs = here->MOS3gmbs*wfact+(gms-gmw)*dvodvb-gmw*                    ((here->MOS3mode==1?vgs:vgd)-von)*onxn*dxndvb;            }            /*             *.....charge computation             */            goto innerline1000;            /*             *.....special case of vds = 0.0d0             */line900:            Beta = Beta*fgate;            cdrain = 0.0;            here->MOS3gm = 0.0;            here->MOS3gds = Beta*(vgsx-vth);            here->MOS3gmbs = 0.0;            if ( (model->MOS3fastSurfaceStateDensity != 0.0) &&                     ((here->MOS3mode==1?vgs:vgd) < von) ) {                here->MOS3gds *=exp(((here->MOS3mode==1?vgs:vgd)-von)/(vt*xn));            }innerline1000:;            /*              *.....done             */            }#ifdef DETAILPROFasm("   .globl mos3ptg");asm("mos3ptg:");#endif /* DETAILPROF */            /* now deal with n vs p polarity */            here->MOS3von = model->MOS3type * von;            here->MOS3vdsat = model->MOS3type * vdsat;            /* line 490 */            /*             *  COMPUTE EQUIVALENT DRAIN CURRENT SOURCE             */            here->MOS3cd=here->MOS3mode * cdrain - here->MOS3cbd;            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->MOS3vbs)))+                        ckt->CKTvoltTol)|| senflag )#endif /*CAPBYPASS*/                {                    /* can't bypass the diode capacitance calculations */#ifdef CAPZEROBYPASS                    if(here->MOS3Cbs != 0 || here->MOS3Cbssw != 0 ) {#endif /*CAPZEROBYPASS*/                    if (vbs < here->MOS3tDepCap){                        arg=1-vbs/here->MOS3tBulkPot;                        /*                         * 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->MOS3bulkJctBotGradingCoeff ==                                model->MOS3bulkJctSideGradingCoeff) {                            if(model->MOS3bulkJctBotGradingCoeff == .5) {                                sarg = sargsw = 1/sqrt(arg);                            } else {                                sarg = sargsw =                                        exp(-model->MOS3bulkJctBotGradingCoeff*                                        log(arg));                            }                        } else {                            if(model->MOS3bulkJctBotGradingCoeff == .5) {                                sarg = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sarg = exp(-model->MOS3bulkJctBotGradingCoeff*                                        log(arg));#ifndef NOSQRT                            }                            if(model->MOS3bulkJctSideGradingCoeff == .5) {                                sargsw = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sargsw =exp(-model->MOS3bulkJctSideGradingCoeff*                                        log(arg));#ifndef NOSQRT                            }                        }#endif /*NOSQRT*/                        *(ckt->CKTstate0 + here->MOS3qbs) =                            here->MOS3tBulkPot*(here->MOS3Cbs*                            (1-arg*sarg)/(1-model->MOS3bulkJctBotGradingCoeff)                            +here->MOS3Cbssw*                            (1-arg*sargsw)/                            (1-model->MOS3bulkJctSideGradingCoeff));                        here->MOS3capbs=here->MOS3Cbs*sarg+                                here->MOS3Cbssw*sargsw;                    } else {                        *(ckt->CKTstate0 + here->MOS3qbs) = here->MOS3f4s +                                vbs*(here->MOS3f2s+vbs*(here->MOS3f3s/2));                        here->MOS3capbs=here->MOS3f2s+here->MOS3f3s*vbs;                    }#ifdef CAPZEROBYPASS                    } else {                        *(ckt->CKTstate0 + here->MOS3qbs) = 0;                        here->MOS3capbs=0;                    }#endif /*CAPZEROBYPASS*/                }#ifdef CAPBYPASS                if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) ||                        FABS(delvbd) >= ckt->CKTreltol * MAX(FABS(vbd),                        FABS(*(ckt->CKTstate0+here->MOS3vbd)))+                        ckt->CKTvoltTol)|| senflag )#endif /*CAPBYPASS*/                    /* can't bypass the diode capacitance calculations */                {#ifdef CAPZEROBYPASS                    if(here->MOS3Cbd != 0 || here->MOS3Cbdsw != 0 ) {#endif /*CAPZEROBYPASS*/                    if (vbd < here->MOS3tDepCap) {                        arg=1-vbd/here->MOS3tBulkPot;                        /*                         * 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->MOS3bulkJctBotGradingCoeff == .5 &&                                model->MOS3bulkJctSideGradingCoeff == .5) {                            sarg = sargsw = 1/sqrt(arg);                        } else {                            if(model->MOS3bulkJctBotGradingCoeff == .5) {                                sarg = 1/sqrt(arg);                            } else {

⌨️ 快捷键说明

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