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

📄 mos6load.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 3 页
字号:
*/#ifdef DETAILPROFasm("   .globl mosptc");asm("mosptc:");#endif /*DETAILPROF*/                /* ok - bypass is out, do it the hard way */                von = model->MOS6type * here->MOS6von;#ifndef NODELIMITING                /*                  * limiting                 *  we want to keep device voltages from changing                 * so fast that the exponentials churn out overflows                 * and similar rudeness                 */                if(*(ckt->CKTstate0 + here->MOS6vds) >=0) {                    vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS6vgs)                            ,von);                    vds = vgs - vgd;                    vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS6vds));                    vgd = vgs - vds;                } else {                    vgd = DEVfetlim(vgd,vgdo,von);                    vds = vgs - vgd;                    if(!(ckt->CKTfixLimit)) {                        vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 +                                 here->MOS6vds)));                    }                    vgs = vgd + vds;                }                if(vds >= 0) {                    vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS6vbs),                            vt,here->MOS6sourceVcrit,&Check);                    vbd = vbs-vds;                } else {                    vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS6vbd),                            vt,here->MOS6drainVcrit,&Check);                    vbs = vbd + vds;                }#endif /*NODELIMITING*//**/#ifdef DETAILPROFasm("   .globl mosptd");asm("mosptd:");#endif /*DETAILPROF*/            } else {                /* ok - not one of the simple cases, so we have to                 * look at all of the possibilities for why we were                 * called.  We still just initialize the three voltages                 */                if((ckt->CKTmode & MODEINITJCT) && !here->MOS6off) {                    vds= model->MOS6type * here->MOS6icVDS;                    vgs= model->MOS6type * here->MOS6icVGS;                    vbs= model->MOS6type * here->MOS6icVBS;                    if((vds==0) && (vgs==0) && (vbs==0) &&                             ((ckt->CKTmode &                                 (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) ||                             (!(ckt->CKTmode & MODEUIC)))) {                        vbs = -1;                        vgs = model->MOS6type * here->MOS6tVto;                        vds = 0;                    }                } else {                    vbs=vgs=vds=0;                }             }/**/#ifdef DETAILPROFasm("   .globl mospte");asm("mospte:");#endif /*DETAILPROF*/            /*             * now all the preliminaries are over - we can start doing the             * real work             */            vbd = vbs - vds;            vgd = vgs - vds;            vgb = vgs - vbs;            /*             * bulk-source and bulk-drain diodes             *   here we just evaluate the ideal diode current and the             *   corresponding derivative (conductance).             */next1:      if(vbs <= 0) {                here->MOS6gbs = SourceSatCur/vt;                here->MOS6cbs = here->MOS6gbs*vbs;                here->MOS6gbs += ckt->CKTgmin;            } else {                evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));                here->MOS6gbs = SourceSatCur*evbs/vt + ckt->CKTgmin;                here->MOS6cbs = SourceSatCur * (evbs-1);            }            if(vbd <= 0) {                here->MOS6gbd = DrainSatCur/vt;                here->MOS6cbd = here->MOS6gbd *vbd;                here->MOS6gbd += ckt->CKTgmin;            } else {                evbd = exp(MIN(MAX_EXP_ARG,vbd/vt));                here->MOS6gbd = DrainSatCur*evbd/vt +ckt->CKTgmin;                here->MOS6cbd = DrainSatCur *(evbd-1);            }            /* now to determine whether the user was able to correctly             * identify the source and drain of his device             */            if(vds >= 0) {                /* normal mode */                here->MOS6mode = 1;            } else {                /* inverse mode */                here->MOS6mode = -1;            }/**/#ifdef DETAILPROFasm("   .globl mosptf");asm("mosptf:");#endif /*DETAILPROF*/            {            /*             *     this block of code evaluates the drain current and its              *     derivatives using the n-th power MOS model and the              *     charges associated with the gate, channel and bulk for              *     mosfets             *             */            /* the following 14 variables are local to this code block until              * it is obvious that they can be made global              */            double arg;            double sarg;            double vgon;            double vdshere, vbsvbd;	    double idsat, lambda, vonbm;	    double vdst, vdst1, vdst2, ivdst1, vdstg;		vbsvbd = (here->MOS6mode==1?vbs:vbd);                if (vbsvbd <= 0 ) {                    sarg = sqrt(here->MOS6tPhi - vbsvbd);                } else {                    sarg = sqrt(here->MOS6tPhi);                    sarg = sarg - vbsvbd / (sarg+sarg);                    sarg = MAX(0,sarg);                }		vdshere = vds * here->MOS6mode;                von=(here->MOS6tVbi*model->MOS6type)+model->MOS6gamma*sarg		    - model->MOS6gamma1 * vbsvbd;		    - model->MOS6sigma  * vdshere;                vgon = (here->MOS6mode==1?vgs:vgd) - von;                if (vgon <= 0) {                    /*                     *     cutoff region                     */		    vdsat = 0;                    cdrain=0;                    here->MOS6gm=0;                    here->MOS6gds=0;                    here->MOS6gmbs=0;                } else {                    if (sarg <= 0) {                        arg=0;                    } else {                	if ((here->MOS6mode==1?vbs:vbd) <= 0 ) {                            vonbm = model->MOS6gamma1			          + model->MOS6gamma / (sarg + sarg);			} else {                            vonbm = model->MOS6gamma1			          + model->MOS6gamma / 2 / sqrt(here->MOS6tPhi);			}                    }		    sarg = log(vgon);		    vdsat = model->MOS6kv * exp(sarg * model->MOS6nv);		    idsat = betac * exp(sarg * model->MOS6nc);		    lambda = model->MOS6lamda0 - model->MOS6lamda1 * vbsvbd;                    /*                     *     saturation region                     */		    cdrain = idsat * (1 + lambda * vdshere);		    here->MOS6gm = cdrain * model->MOS6nc / vgon;		    here->MOS6gds = here->MOS6gm * model->MOS6sigma 				  + idsat * lambda;		    here->MOS6gmbs = here->MOS6gm * vonbm 				   - idsat * model->MOS6lamda1 * vdshere;                    if (vdsat > vdshere){                    /*                     *     linear region                     */			vdst = vdshere / vdsat;                        vdst2 = (2 - vdst) * vdst;			vdstg = - vdst * model->MOS6nv / vgon;			ivdst1 = cdrain * (2 - vdst - vdst);                        cdrain = cdrain * vdst2;                        here->MOS6gm = here->MOS6gm * vdst2 + ivdst1 * vdstg;                        here->MOS6gds = here->MOS6gds * vdst2 + ivdst1 				      * (1 / vdsat + vdstg * model->MOS6sigma);                        here->MOS6gmbs = here->MOS6gmbs * vdst2 				       + ivdst1 * vdstg * vonbm;                    }                }                /*                 *     finished                 */            }/**/#ifdef DETAILPROFasm("   .globl mosptg");asm("mosptg:");#endif /*DETAILPROF*/            /* now deal with n vs p polarity */            here->MOS6von = model->MOS6type * von;            here->MOS6vdsat = model->MOS6type * vdsat;            /* line 490 */            /*             *  COMPUTE EQUIVALENT DRAIN CURRENT SOURCE             */            here->MOS6cd=here->MOS6mode * cdrain - here->MOS6cbd;            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->MOS6vbs)))+                        ckt->CKTvoltTol)|| senflag)#endif /*CAPBYPASS*/                {                    /* can't bypass the diode capacitance calculations */#ifdef CAPZEROBYPASS                    if(here->MOS6Cbs != 0 || here->MOS6Cbssw != 0 ) {#endif /*CAPZEROBYPASS*/                    if (vbs < here->MOS6tDepCap){                        arg=1-vbs/here->MOS6tBulkPot;                        /*                         * 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->MOS6bulkJctBotGradingCoeff ==                                model->MOS6bulkJctSideGradingCoeff) {                            if(model->MOS6bulkJctBotGradingCoeff == .5) {                                sarg = sargsw = 1/sqrt(arg);                            } else {                                sarg = sargsw =                                        exp(-model->MOS6bulkJctBotGradingCoeff*                                        log(arg));                            }                        } else {                            if(model->MOS6bulkJctBotGradingCoeff == .5) {                                sarg = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sarg = exp(-model->MOS6bulkJctBotGradingCoeff*                                        log(arg));#ifndef NOSQRT                            }                            if(model->MOS6bulkJctSideGradingCoeff == .5) {                                sargsw = 1/sqrt(arg);                            } else {#endif /*NOSQRT*/                                sargsw =exp(-model->MOS6bulkJctSideGradingCoeff*                                        log(arg));#ifndef NOSQRT                            }                        }#endif /*NOSQRT*/                        *(ckt->CKTstate0 + here->MOS6qbs) =                            here->MOS6tBulkPot*(here->MOS6Cbs*                            (1-arg*sarg)/(1-model->MOS6bulkJctBotGradingCoeff)                            +here->MOS6Cbssw*                            (1-arg*sargsw)/                            (1-model->MOS6bulkJctSideGradingCoeff));                        here->MOS6capbs=here->MOS6Cbs*sarg+                                here->MOS6Cbssw*sargsw;                    } else {                        *(ckt->CKTstate0 + here->MOS6qbs) = here->MOS6f4s +                                vbs*(here->MOS6f2s+vbs*(here->MOS6f3s/2));                        here->MOS6capbs=here->MOS6f2s+here->MOS6f3s*vbs;                    }#ifdef CAPZEROBYPASS                    } else {                        *(ckt->CKTstate0 + here->MOS6qbs) = 0;                        here->MOS6capbs=0;                    }#endif /*CAPZEROBYPASS*/                }#ifdef CAPBYPASS                if(((ckt->CKTmode & (MODEINITPRED | MODEINITTRAN) ) ||                        FABS(delvbd) >= ckt->CKTreltol * MAX(FABS(vbd),                        FABS(*(ckt->CKTstate0+here->MOS6vbd)))+                        ckt->CKTvoltTol)|| senflag)#endif /*CAPBYPASS*/                    /* can't bypass the diode capacitance calculations */                {#ifdef CAPZEROBYPASS                    if(here->MOS6Cbd != 0 || here->MOS6Cbdsw != 0 ) {#endif /*CAPZEROBYPASS*/                    if (vbd < here->MOS6tDepCap) {                        arg=1-vbd/here->MOS6tBulkPot;                        /*                         * 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->MOS6bulkJctBotGradingCoeff == .5 &&

⌨️ 快捷键说明

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