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

📄 hfetload.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Imported from MacSpice3f4 - Antony WilsonModified: Paolo Nenzi**********/#include "ngspice.h"#include "devdefs.h"#include "cktdefs.h"#include "hfetdefs.h"#include "const.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"/*#define true 1#define false 0*///#define PHIB 0.5double diode(double);static void leak(double gmin, double vt, double v, double rs, double is1, 				 double is2, double m1, double m2, double *il, double *gl);                 static void hfeta(HFETAmodel *model, HFETAinstance *here, CKTcircuit *ckt,                  double vgs, double vds, double *cdrain, double *gm,                  double *gds, double *capgs, double *capgd,                  double *cgd, double *gmg, double *gmd,                  double *cgs, double *ggs);                 void Pause(void);int HFETAload(GENmodel *inModel, CKTcircuit *ckt){    HFETAmodel *model = (HFETAmodel*)inModel;    HFETAinstance *here;    double capgd;    double capgs;    double cd;    double cdhat = 0.0;    double cdrain;    double cdreq;    double ceq;    double ceqgd;    double ceqgs;    double cg;    double cgd=0;    double cgs=0;    double cghat = 0.0;    double delvds;    double delvgd;    double delvgs;    double delvgdpp=0;    double delvgspp=0;    double gds;    double geq;    double ggd=0;    double ggs=0;    double gm;    double vcrit;    double vds;    double vgd;    double vgs;    double vgs1;    double vgd1;    double vds1;    double xfact;    double temp;    double vt;    double vgspp=0;    double vgdpp=0;    double cgspp=0;    double cgdpp=0;    double ggspp=0;    double ggdpp=0;    double gmg=0;    double gmd=0;        int inverse=FALSE;    int icheck;    int error;    double m;    for( ; model != NULL; model = model->HFETAnextModel ) {        for (here = model->HFETAinstances; here != NULL ;                here=here->HFETAnextInstance) {                        if (here->HFETAowner != ARCHme) continue;            vcrit = here->HFETAvcrit;            vt  = CONSTKoverQ * here->HFETAtemp;            icheck = 0;            if( ckt->CKTmode & MODEINITSMSIG) {                vgs = *(ckt->CKTstate0 + here->HFETAvgs);                vgd = *(ckt->CKTstate0 + here->HFETAvgd);                vgspp = *(ckt->CKTstate0 + here->HFETAvgspp);                vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp);            } else if (ckt->CKTmode & MODEINITTRAN) {                vgs = *(ckt->CKTstate1 + here->HFETAvgs);                vgd = *(ckt->CKTstate1 + here->HFETAvgd);                vgspp = *(ckt->CKTstate1 + here->HFETAvgspp);                vgdpp = *(ckt->CKTstate1 + here->HFETAvgdpp);            } else if ( (ckt->CKTmode & MODEINITJCT) &&                    (ckt->CKTmode & MODETRANOP) &&                    (ckt->CKTmode & MODEUIC) ) {                vds = model->HFETAtype*here->HFETAicVDS;                vgs = model->HFETAtype*here->HFETAicVGS;                vgd = vgs-vds;                vgspp = vgs;                vgdpp = vgd;            } else if ( (ckt->CKTmode & MODEINITJCT) &&                    (here->HFETAoff == 0)  ) {                vgs = -1;                vgd = -1;                vgspp = 0;                vgdpp = 0;            } else if( (ckt->CKTmode & MODEINITJCT) ||                    ((ckt->CKTmode & MODEINITFIX) && (here->HFETAoff))) {                vgs = 0;                vgd = 0;                vgspp = 0;                vgdpp = 0;            } else {#ifndef PREDICTOR                if(ckt->CKTmode & MODEINITPRED) {                    xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2];                    *(ckt->CKTstate0 + here->HFETAvgs) =                            *(ckt->CKTstate1 + here->HFETAvgs);                    vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgs) -                           xfact * *(ckt->CKTstate2 + here->HFETAvgs);                    *(ckt->CKTstate0 + here->HFETAvgspp) =                             *(ckt->CKTstate1 + here->HFETAvgspp);                    vgspp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgspp) -                           xfact * *(ckt->CKTstate2 + here->HFETAvgspp);                    *(ckt->CKTstate0 + here->HFETAvgd) =                             *(ckt->CKTstate1 + here->HFETAvgd);                    vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFETAvgd) -                           xfact * *(ckt->CKTstate2 + here->HFETAvgd);                    *(ckt->CKTstate0 + here->HFETAvgdpp) =                             *(ckt->CKTstate1 + here->HFETAvgdpp);                    vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->HFETAvgdpp) -                           xfact * *(ckt->CKTstate2 + here->HFETAvgdpp);                    *(ckt->CKTstate0 + here->HFETAcg) =                             *(ckt->CKTstate1 + here->HFETAcg);                    *(ckt->CKTstate0 + here->HFETAcd) =                             *(ckt->CKTstate1 + here->HFETAcd);                    *(ckt->CKTstate0 + here->HFETAcgd) =                            *(ckt->CKTstate1 + here->HFETAcgd);                    *(ckt->CKTstate0 + here->HFETAcgs) =                            *(ckt->CKTstate1 + here->HFETAcgs);                    *(ckt->CKTstate0 + here->HFETAcgspp) =                            *(ckt->CKTstate1 + here->HFETAcgspp);                    *(ckt->CKTstate0 + here->HFETAcgdpp) =                            *(ckt->CKTstate1 + here->HFETAcgdpp);                    *(ckt->CKTstate0 + here->HFETAgm) =                            *(ckt->CKTstate1 + here->HFETAgm);                    *(ckt->CKTstate0 + here->HFETAgds) =                            *(ckt->CKTstate1 + here->HFETAgds);                    *(ckt->CKTstate0 + here->HFETAggs) =                            *(ckt->CKTstate1 + here->HFETAggs);                    *(ckt->CKTstate0 + here->HFETAggspp) =                            *(ckt->CKTstate1 + here->HFETAggspp);                    *(ckt->CKTstate0 + here->HFETAggd) =                            *(ckt->CKTstate1 + here->HFETAggd);                    *(ckt->CKTstate0 + here->HFETAggdpp) =                            *(ckt->CKTstate1 + here->HFETAggdpp);                    *(ckt->CKTstate0 + here->HFETAgmg) =                            *(ckt->CKTstate1 + here->HFETAgmg);                    *(ckt->CKTstate0 + here->HFETAgmd) =                            *(ckt->CKTstate1 + here->HFETAgmd);                        } else {#endif /* PREDICTOR */                    /*                     *  compute new nonlinear branch voltages                      */                    vgs = model->HFETAtype*                        (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-                        *(ckt->CKTrhsOld+                         here->HFETAsourcePrimeNode));                    vgd = model->HFETAtype*                        (*(ckt->CKTrhsOld+here->HFETAgatePrimeNode)-                        *(ckt->CKTrhsOld+                        here->HFETAdrainPrimeNode));                    vgspp = model->HFETAtype*                        (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-                        *(ckt->CKTrhsOld+                         here->HFETAsourcePrmPrmNode));                    vgdpp = model->HFETAtype*                        (*(ckt->CKTrhsOld+ here->HFETAgatePrimeNode)-                        *(ckt->CKTrhsOld+                         here->HFETAdrainPrmPrmNode));                        #ifndef PREDICTOR                }#endif /* PREDICTOR */                delvgs=vgs - *(ckt->CKTstate0 + here->HFETAvgs);                delvgd=vgd - *(ckt->CKTstate0 + here->HFETAvgd);                delvds=delvgs - delvgd;                delvgspp=vgspp - *(ckt->CKTstate0 + here->HFETAvgspp);                delvgdpp=vgdpp - *(ckt->CKTstate0 + here->HFETAvgdpp);                cghat= *(ckt->CKTstate0 + here->HFETAcg) +                         *(ckt->CKTstate0 + here->HFETAgmg)*delvgs -                        *(ckt->CKTstate0 + here->HFETAgmd)*delvds +                                        *(ckt->CKTstate0 + here->HFETAggd)*delvgd +                        *(ckt->CKTstate0 + here->HFETAggs)*delvgs +                        *(ckt->CKTstate0 + here->HFETAggdpp)*delvgdpp +                        *(ckt->CKTstate0 + here->HFETAggspp)*delvgspp;                cdhat= *(ckt->CKTstate0 + here->HFETAcd) +                        *(ckt->CKTstate0 + here->HFETAgm)*delvgs +                        *(ckt->CKTstate0 + here->HFETAgds)*delvds -                        *(ckt->CKTstate0 + here->HFETAggd)*delvgd -                        (*(ckt->CKTstate0 + here->HFETAgmg)*delvgs -                        *(ckt->CKTstate0 + here->HFETAgmd)*delvds);                /*                 *   bypass if solution has not changed                  */                if((ckt->CKTbypass) &&                    (!(ckt->CKTmode & MODEINITPRED)) &&                    (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),                        fabs(*(ckt->CKTstate0 + here->HFETAvgs)))+                        ckt->CKTvoltTol) )                if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),                        fabs(*(ckt->CKTstate0 + here->HFETAvgd)))+                        ckt->CKTvoltTol))                if ( (fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp),                        fabs(*(ckt->CKTstate0 + here->HFETAvgspp)))+                        ckt->CKTvoltTol))                if ( (fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp),                        fabs(*(ckt->CKTstate0 + here->HFETAvgdpp)))+                        ckt->CKTvoltTol))                if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFETAcg))                         < ckt->CKTreltol*MAX(fabs(cghat),                        fabs(*(ckt->CKTstate0 + here->HFETAcg)))+                        ckt->CKTabstol) ) if ( /* hack - expression too big */                    (fabs(cdhat-*(ckt->CKTstate0 + here->HFETAcd))                        < ckt->CKTreltol*MAX(fabs(cdhat),                        fabs(*(ckt->CKTstate0 + here->HFETAcd)))+                        ckt->CKTabstol) ) {                    /* we can do a bypass */                    vgs   = *(ckt->CKTstate0 + here->HFETAvgs);                    vgd   = *(ckt->CKTstate0 + here->HFETAvgd);                    vds   = vgs-vgd;                    vgspp = *(ckt->CKTstate0 + here->HFETAvgspp);                    vgdpp = *(ckt->CKTstate0 + here->HFETAvgdpp);                    cg    = *(ckt->CKTstate0 + here->HFETAcg);                    cd    = *(ckt->CKTstate0 + here->HFETAcd);                    cgd   = *(ckt->CKTstate0 + here->HFETAcgd);                    cgs   = *(ckt->CKTstate0 + here->HFETAcgs);                    cgdpp = *(ckt->CKTstate0 + here->HFETAcgdpp);                    cgspp = *(ckt->CKTstate0 + here->HFETAcgspp);                    gm    = *(ckt->CKTstate0 + here->HFETAgm);                    gds   = *(ckt->CKTstate0 + here->HFETAgds);                    ggs   = *(ckt->CKTstate0 + here->HFETAggs);                    ggd   = *(ckt->CKTstate0 + here->HFETAggd);                    ggdpp = *(ckt->CKTstate0 + here->HFETAggdpp);                    ggspp = *(ckt->CKTstate0 + here->HFETAggspp);                    gmg   = *(ckt->CKTstate0 + here->HFETAgmg);                    gmd   = *(ckt->CKTstate0 + here->HFETAgmd);                    goto load;                }                /*                 *  limit nonlinear branch voltages                  */                vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFETAvgs),TVTO);                vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFETAvgd),TVTO);            }            /*             *   determine dc current and derivatives              */            vds = vgs-vgd;            if(model->HFETAgatemod == 0) {              double arg;              double earg;              if(IS1S == 0 || IS2S == 0) {                cgs = 0;                ggs = 0;              } else                leak(ckt->CKTgmin,vt,vgs,RGS,IS1S,IS2S,M1S,M2S,&cgs,&ggs);              arg = -vgs*DEL/vt;              earg = exp(arg);              cgs += GGRWL*vgs*earg;              ggs += GGRWL*earg*(1-arg);                if(IS1D == 0 || IS2D == 0) {                cgd = 0;                ggd = 0;              } else                leak(ckt->CKTgmin,vt,vgd,RGD,IS1D,IS2D,M1D,M2D,&cgd,&ggd);              arg = -vgd*DEL/vt;              earg = exp(arg);              cgd += GGRWL*vgd*earg;              ggd += GGRWL*earg*(1-arg);              } else              ggd = 0;            if(vds < 0) {              vds = -vds;              inverse = TRUE;            }            hfeta(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd,                  &cgd,&gmg,&gmd,&cgs,&ggs);            cg = cgs+cgd;            if(inverse) {              cdrain = -cdrain;              vds = -vds;              temp = capgs;              capgs = capgd;              capgd = temp;            }            /*             *   compute equivalent drain current source              */            cd = cdrain - cgd;            if ( (ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) ||                    ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){                /*                  *    charge storage elements                  */                vgs1 = *(ckt->CKTstate1 + here->HFETAvgspp);                vgd1 = *(ckt->CKTstate1 + here->HFETAvgdpp);                vds1 = *(ckt->CKTstate1 + here->HFETAvgs)-                       *(ckt->CKTstate1 + here->HFETAvgd);                if(ckt->CKTmode & MODEINITTRAN) {                    *(ckt->CKTstate1 + here->HFETAqgs) = capgs*vgspp;                    *(ckt->CKTstate1 + here->HFETAqgd) = capgd*vgdpp;                    *(ckt->CKTstate1 + here->HFETAqds) = CDS*vds;                }                *(ckt->CKTstate0+here->HFETAqgs) = *(ckt->CKTstate1 + here->HFETAqgs) +                                                   capgs*(vgspp-vgs1);                *(ckt->CKTstate0+here->HFETAqgd) = *(ckt->CKTstate1 + here->HFETAqgd) +                                                   capgd*(vgdpp-vgd1);                *(ckt->CKTstate0+here->HFETAqds) = *(ckt->CKTstate1 + here->HFETAqds) +                                                   CDS*(vds-vds1);                /*                 *   store small-signal parameters                  */                if( (!(ckt->CKTmode & MODETRANOP)) ||                         (!(ckt->CKTmode & MODEUIC)) ) {                    if(ckt->CKTmode & MODEINITSMSIG) {                        *(ckt->CKTstate0 + here->HFETAqgs) = capgs;                        *(ckt->CKTstate0 + here->HFETAqgd) = capgd;                        *(ckt->CKTstate0 + here->HFETAqds) = CDS;                        continue; /*go to 1000*/                    }                    /*                     *   transient analysis                      */                    if(ckt->CKTmode & MODEINITTRAN) {                        *(ckt->CKTstate1 + here->HFETAqgs) =                                *(ckt->CKTstate0 + here->HFETAqgs);                        *(ckt->CKTstate1 + here->HFETAqgd) =                                *(ckt->CKTstate0 + here->HFETAqgd);                        *(ckt->CKTstate1 + here->HFETAqds) =                                *(ckt->CKTstate0 + here->HFETAqds);                            }                    error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFETAqgs);                    if(error) return(error);                    ggspp = geq;                    cgspp = *(ckt->CKTstate0 + here->HFETAcqgs);                    cg = cg + cgspp;                    error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFETAqgd);                    if(error) return(error);                    ggdpp = geq;                    cgdpp = *(ckt->CKTstate0 + here->HFETAcqgd);                    cg = cg + cgdpp;                    cd = cd - cgdpp;                    error = NIintegrate(ckt,&geq,&ceq,CDS,here->HFETAqds);                    if(error) return(error);                    gds += geq;                    cd  += *(ckt->CKTstate0 + here->HFETAcqds);                    if (ckt->CKTmode & MODEINITTRAN) {                        *(ckt->CKTstate1 + here->HFETAcqgs) =                                *(ckt->CKTstate0 + here->HFETAcqgs);                        *(ckt->CKTstate1 + here->HFETAcqgd) =                                *(ckt->CKTstate0 + here->HFETAcqgd);                        *(ckt->CKTstate1 + here->HFETAcqds) =                                *(ckt->CKTstate0 + here->HFETAcqds);                    }                }            }            /*             *  check convergence              */            if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) {                if( (icheck == 1)                         || (fabs(cghat-cg) >= ckt->CKTreltol*                            MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) ||                        (fabs(cdhat-cd) > ckt->CKTreltol*                            MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)                         ) {                    ckt->CKTnoncon++;                     ckt->CKTtroubleElt = (GENinstance *) here;                }            }            *(ckt->CKTstate0 + here->HFETAvgs)   = vgs;            *(ckt->CKTstate0 + here->HFETAvgd)   = vgd;

⌨️ 快捷键说明

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