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

📄 soi3load.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 5 页
字号:
                 * many compilers can't handle it all at once, so it                 * is split into several successive if statements                 */                /* bypass just needs to check any four voltages have not changed                   so leave as before to avoid hassle */                tempv = MAX(fabs(ibhat),fabs(here->SOI3ibs                        + here->SOI3ibd-here->SOI3iMsb                        - here->SOI3iMdb - here->SOI3iBJTdb                        - here->SOI3iBJTsb))+ckt->CKTabstol;                if((!(ckt->CKTmode & (MODEINITPRED|MODEINITTRAN|MODEINITSMSIG)                        )) && (ckt->CKTbypass) )                if ( (fabs(ibhat-(here->SOI3ibs +                        here->SOI3ibd-here->SOI3iMdb                        - here->SOI3iMsb - here->SOI3iBJTdb                        - here->SOI3iBJTsb)) < ckt->CKTreltol *                        tempv))                if( (fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs),                        fabs(*(ckt->CKTstate0+here->SOI3vbs)))+                        ckt->CKTvoltTol)))                if ( (fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd),                        fabs(*(ckt->CKTstate0+here->SOI3vbd)))+                        ckt->CKTvoltTol)) )                if( (fabs(delvgfs) < (ckt->CKTreltol * MAX(fabs(vgfs),                        fabs(*(ckt->CKTstate0+here->SOI3vgfs)))+                        ckt->CKTvoltTol)))                if( (fabs(delvgbs) < (ckt->CKTreltol * MAX(fabs(vgbs),                        fabs(*(ckt->CKTstate0+here->SOI3vgbs)))+                        ckt->CKTvoltTol)))                if ( (fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds),                        fabs(*(ckt->CKTstate0+here->SOI3vds)))+                        ckt->CKTvoltTol)) )                if ( (fabs(deldeltaT) < (ckt->CKTreltol * MAX(fabs(deltaT),                        fabs(*(ckt->CKTstate0+here->SOI3deltaT)))+                        ckt->CKTvoltTol)) )                if( (fabs(iPthat- here->SOI3iPt) <                        ckt->CKTreltol * MAX(fabs(iPthat),fabs(                        here->SOI3iPt)) + ckt->CKTabstol) )                if( (fabs(idhat- here->SOI3id) <                        ckt->CKTreltol * MAX(fabs(idhat),fabs(                        here->SOI3id)) + ckt->CKTabstol) ) {                    /* bypass code */                    /* nothing interesting has changed since last                     * iteration on this device, so we just                     * copy all the values computed last iteration out                     * and keep going                     */                    vbs = *(ckt->CKTstate0 + here->SOI3vbs);                    vbd = *(ckt->CKTstate0 + here->SOI3vbd);                    vgfs = *(ckt->CKTstate0 + here->SOI3vgfs);                    vgbs = *(ckt->CKTstate0 + here->SOI3vgbs);                    vds = *(ckt->CKTstate0 + here->SOI3vds);                    deltaT = *(ckt->CKTstate0 + here->SOI3deltaT);                    deltaT1 = *(ckt->CKTstate0 + here->SOI3deltaT1);                    deltaT2 = *(ckt->CKTstate0 + here->SOI3deltaT2);                    deltaT3 = *(ckt->CKTstate0 + here->SOI3deltaT3);                    deltaT4 = *(ckt->CKTstate0 + here->SOI3deltaT4);                    deltaT5 = *(ckt->CKTstate0 + here->SOI3deltaT5);                    /* and now the extra ones */                    vsb=-vbs;                    vdb=-vbd;                    vgfb = vgfs - vbs;                    vgbb = vgbs - vbs;                    /* JimB - 15/9/99 */                    /* Code for multiple thermal time constants.  Start by moving all */                    /* rt constants into arrays. */                    rtargs[0]=here->SOI3rt;                    rtargs[1]=here->SOI3rt1;                    rtargs[2]=here->SOI3rt2;                    rtargs[3]=here->SOI3rt3;                    rtargs[4]=here->SOI3rt4;                    /* Set all conductance components to zero. */                    grt[0]=grt[1]=grt[2]=grt[3]=grt[4]=0.0;                    /* Now calculate conductances from rt. */                    /* Don't need to worry about divide by zero when calculating */                    /* grt components, as soi3setup() only creates a thermal node */                    /* if corresponding rt is greater than zero. */                    for(tnodeindex=0;tnodeindex<here->SOI3numThermalNodes;tnodeindex++)                    {                       grt[tnodeindex]=1/rtargs[tnodeindex];                    }                    /* End JimB */                    vgfd = vgfs - vds;                    vgbd = vgbs - vds;                    if (here->SOI3mode==1)                    {                        idrain =  here->SOI3id + here->SOI3ibd - here->SOI3iMdb                                  - here->SOI3iBJTdb;                    }                    else                    {                    		idrain = -here->SOI3id - here->SOI3ibd                                  + here->SOI3iBJTdb;                    }                                        /* Pt doesn't need changing as it's in here->SOI3iPt */                    if((ckt->CKTmode & (MODETRAN | MODEAC)) ||                             (ckt->CKTmode & MODETRANOP))                    {                      cgfgf = *(ckt->CKTstate0 + here->SOI3cgfgf);                      cgfd  = *(ckt->CKTstate0 + here->SOI3cgfd);                      cgfs  = *(ckt->CKTstate0 + here->SOI3cgfs);                      cgfdeltaT  = *(ckt->CKTstate0 + here->SOI3cgfdeltaT);                      cgfgb = *(ckt->CKTstate0 + here->SOI3cgfgb);                      csgf = *(ckt->CKTstate0 + here->SOI3csgf);                      csd  = *(ckt->CKTstate0 + here->SOI3csd);                      css  = *(ckt->CKTstate0 + here->SOI3css);                      csdeltaT  = *(ckt->CKTstate0 + here->SOI3csdeltaT);                      csgb = *(ckt->CKTstate0 + here->SOI3csgb);                      cdgf = *(ckt->CKTstate0 + here->SOI3cdgf);                      cdd  = *(ckt->CKTstate0 + here->SOI3cdd);                      cds  = *(ckt->CKTstate0 + here->SOI3cds);                      cddeltaT  = *(ckt->CKTstate0 + here->SOI3cddeltaT);                      cdgb  = *(ckt->CKTstate0 + here->SOI3cdgb);                      cgbgf = *(ckt->CKTstate0 + here->SOI3cgbgf);                      cgbd  = *(ckt->CKTstate0 + here->SOI3cgbd);                      cgbs  = *(ckt->CKTstate0 + here->SOI3cgbs);                      cgbdeltaT  = *(ckt->CKTstate0 + here->SOI3cgbdeltaT);                      cgbgb = *(ckt->CKTstate0 + here->SOI3cgbgb);                      cbgf = -(cgfgf + cdgf + csgf + cgbgf);                      cbd = -(cgfd + cdd + csd + cgbd);                      cbs = -(cgfs + cds + css + cgbs);                      cbdeltaT = -(cgfdeltaT + cddeltaT + csdeltaT + cgbdeltaT);                      cbgb = -(cgfgb + cdgb + csgb + cgbgb);                      qgatef = *(ckt->CKTstate0 + here->SOI3qgf);                      qdrn = *(ckt->CKTstate0 + here->SOI3qd);                      qsrc = *(ckt->CKTstate0 + here->SOI3qs);                      qgateb = *(ckt->CKTstate0 + here->SOI3qgb);                      qbody = -(qgatef + qdrn + qsrc + qgateb);                      ByPass = 1;                      goto bypass1;                    }                       goto bypass2;                }#endif /*NOBYPASS*/                /* ok - bypass is out, do it the hard way */                von = model->SOI3type * here->SOI3von;#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->SOI3vds) >=0)                {                    vgfs = DEVfetlim(vgfs,*(ckt->CKTstate0 + here->SOI3vgfs)                            ,von);                    vds = vgfs - vgfd;                    vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->SOI3vds));                    vgfd = vgfs - vds;                }                else                {                    vgfd = DEVfetlim(vgfd,vgfdo,von);                    vds = vgfs - vgfd;                    if(!(ckt->CKTfixLimit))                    {                        vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 +                                here->SOI3vds)));                    }                    vgfs = vgfd + vds;                }                if(vds >= 0)                {                    vbs = DEVsoipnjlim(vbs,*(ckt->CKTstate0 + here->SOI3vbs),                            vt,here->SOI3sourceVcrit,&Check);                    vbd = vbs-vds;                }                else                {                    vbd = DEVsoipnjlim(vbd,*(ckt->CKTstate0 + here->SOI3vbd),                            vt,here->SOI3drainVcrit,&Check);                    vbs = vbd + vds;                }                                /* and now some limiting of the temperature rise */                if (deltaT>(10 + *(ckt->CKTstate0 + here->SOI3deltaT)))                {                  deltaT = 10 + *(ckt->CKTstate0 + here->SOI3deltaT);                  /* need limiting, therefore must also impose limits on other                     thermal voltages.                  */                  /* JimB - 19/5/99 */                  if (here->SOI3numThermalNodes == 0)                  {                  	deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0;                  }                  if (here->SOI3numThermalNodes == 1)                  {                  	deltaT1=deltaT;                  	deltaT2=deltaT3=deltaT4=deltaT5=0;                  }                  if (here->SOI3numThermalNodes == 2)                  {                  	deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node));                  	deltaT1 = deltaT - deltaT2;                  	deltaT3=deltaT4=deltaT5=0;                  }                  if (here->SOI3numThermalNodes == 3)                  {                  	deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node));                  	deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3);                  	deltaT1 = deltaT - deltaT2 - deltaT3;                  	deltaT4=deltaT5=0;                  }                  if (here->SOI3numThermalNodes == 4)                  {                  	deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node));                  	deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4);                  	deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3 - deltaT4);                  	deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4;                  	deltaT5=0;                  }                  if (here->SOI3numThermalNodes == 5)                  {                  	deltaT5 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout4Node));                  	deltaT4 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout3Node) - deltaT5);                  	deltaT3 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout2Node) - deltaT4 - deltaT5);                  	deltaT2 = MAX(0,*(ckt->CKTrhsOld+here->SOI3tout1Node) - deltaT3 - deltaT4 - deltaT5);                  	deltaT1 = deltaT - deltaT2 - deltaT3 - deltaT4 - deltaT5;                  }                  Check = 1;                }#endif /*NODELIMITING*/            } 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->SOI3off)                {                    vds= model->SOI3type * here->SOI3icVDS;                    vgfs= model->SOI3type * here->SOI3icVGFS;                    vgbs= model->SOI3type * here->SOI3icVGBS;                    vbs= model->SOI3type * here->SOI3icVBS;                    deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0;                    if((vds==0) && (vgfs==0) && (vbs==0) && (vgbs==0) &&                            ((ckt->CKTmode &                                (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) ||                             (!(ckt->CKTmode & MODEUIC))))                    {                        vbs = -1;                        vgfs = model->SOI3type * here->SOI3tVto;                        vds = 0;                        vgbs = 0;                        deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0;                    }                }                else                {                   vbs=vgfs=vds=vgbs=deltaT=deltaT1=deltaT2=deltaT3=deltaT4=deltaT5=0.0;                }            }            /*             * now all the preliminaries are over - we can start doing the             * real work             */            vbd = vbs - vds;            vgfd = vgfs - vds;            vgbd = vgbs - vds;            vgfb = vgfs - vbs;            vgbb = vgbs - vbs;            vsb = -vbs;            vdb = -vbd;                        /* now to determine whether the user was able to correctly             * identify the source and drain of his device             */            if(vds >= 0) {                /* normal mode */                here->SOI3mode = 1;            } else {                /* inverse mode */                here->SOI3mode = -1;            }            {             /* begin block  */            /*             *     This block works out drain current and derivatives.             *     It does this via the calculation of the surface potential

⌨️ 快捷键说明

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