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

📄 hfet2load.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
字号:
/**********Imported from MacSpice3f4 - Antony WilsonModified: Paolo Nenzi**********/#include "ngspice.h"#include "devdefs.h"#include "cktdefs.h"#include "hfet2defs.h"#include "const.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"void Pause(void);static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt,                  double vgs, double vds, double *cdrain, double *gm,                  double *gds, double *capgs, double *capgd);int HFET2load(GENmodel *inModel, CKTcircuit *ckt){  HFET2model *model = (HFET2model*)inModel;  HFET2instance *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;  double cghat = 0.0;  double delvds;  double delvgd;  double delvgs;  double gdpr;  double gds;  double geq;  double ggd;  double ggs;  double gm;  double gspr;  double vcrit;  double vds;  double vgd;  double vgd1;  double vgs;  double vgs1;  double vt;  double vto;  double xfact;  int    icheck;  int    ichk1;  int    error;  int    inverse;  double m;  for( ; model != NULL; model = model->HFET2nextModel ) {    for(here = model->HFET2instances; here != NULL;         here=here->HFET2nextInstance) {      if (here->HFET2owner != ARCHme) continue;      gdpr = model->HFET2drainConduct;      gspr = model->HFET2sourceConduct;      vcrit = VCRIT;      vto = TVTO;      vt  = CONSTKoverQ*TEMP;      icheck = 1;      if( ckt->CKTmode & MODEINITSMSIG) {        vgs = *(ckt->CKTstate0 + here->HFET2vgs);        vgd = *(ckt->CKTstate0 + here->HFET2vgd);      } else if(ckt->CKTmode & MODEINITTRAN) {        vgs = *(ckt->CKTstate1 + here->HFET2vgs);        vgd = *(ckt->CKTstate1 + here->HFET2vgd);      } else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) &&                    (ckt->CKTmode & MODEUIC) ) {        vds = model->HFET2type*here->HFET2icVDS;        vgs = model->HFET2type*here->HFET2icVGS;        vgd = vgs-vds;      } else if ( (ckt->CKTmode & MODEINITJCT) && (here->HFET2off == 0)  ) {        vgs = -1;        vgd = -1;      } else if((ckt->CKTmode & MODEINITJCT) ||                ((ckt->CKTmode & MODEINITFIX) && (here->HFET2off))) {        vgs = 0;        vgd = 0;      } else {#ifndef PREDICTOR        if(ckt->CKTmode & MODEINITPRED) {          xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2];          *(ckt->CKTstate0 + here->HFET2vgs) =                *(ckt->CKTstate1 + here->HFET2vgs);          vgs = (1+xfact) * *(ckt->CKTstate1 + here->HFET2vgs) -               xfact * *(ckt->CKTstate2 + here->HFET2vgs);          *(ckt->CKTstate0 + here->HFET2vgd) =                *(ckt->CKTstate1 + here->HFET2vgd);          vgd = (1+xfact)* *(ckt->CKTstate1 + here->HFET2vgd) -               xfact * *(ckt->CKTstate2 + here->HFET2vgd);          *(ckt->CKTstate0 + here->HFET2cg) =                *(ckt->CKTstate1 + here->HFET2cg);          *(ckt->CKTstate0 + here->HFET2cd) =                *(ckt->CKTstate1 + here->HFET2cd);          *(ckt->CKTstate0 + here->HFET2cgd) =               *(ckt->CKTstate1 + here->HFET2cgd);          *(ckt->CKTstate0 + here->HFET2gm) =               *(ckt->CKTstate1 + here->HFET2gm);          *(ckt->CKTstate0 + here->HFET2gds) =               *(ckt->CKTstate1 + here->HFET2gds);          *(ckt->CKTstate0 + here->HFET2ggs) =               *(ckt->CKTstate1 + here->HFET2ggs);          *(ckt->CKTstate0 + here->HFET2ggd) =               *(ckt->CKTstate1 + here->HFET2ggd);        } else {#endif /* PREDICTOR */          vgs = model->HFET2type*                 (*(ckt->CKTrhsOld+ here->HFET2gateNode)- *(ckt->CKTrhsOld+                  here->HFET2sourcePrimeNode));          vgd = model->HFET2type*                 (*(ckt->CKTrhsOld+here->HFET2gateNode)- *(ckt->CKTrhsOld+                 here->HFET2drainPrimeNode));#ifndef PREDICTOR        }#endif /* PREDICTOR */        delvgs=vgs - *(ckt->CKTstate0 + here->HFET2vgs);        delvgd=vgd - *(ckt->CKTstate0 + here->HFET2vgd);        delvds=delvgs - delvgd;        cghat= *(ckt->CKTstate0 + here->HFET2cg) +                *(ckt->CKTstate0 + here->HFET2ggd)*delvgd +               *(ckt->CKTstate0 + here->HFET2ggs)*delvgs;        cdhat= *(ckt->CKTstate0 + here->HFET2cd) +               *(ckt->CKTstate0 + here->HFET2gm)*delvgs +               *(ckt->CKTstate0 + here->HFET2gds)*delvds -               *(ckt->CKTstate0 + here->HFET2ggd)*delvgd;         //   bypass if solution has not changed          if((ckt->CKTbypass) &&           (!(ckt->CKTmode & MODEINITPRED)) &&           (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),            fabs(*(ckt->CKTstate0 + here->HFET2vgs)))+            ckt->CKTvoltTol) )         if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),            fabs(*(ckt->CKTstate0 + here->HFET2vgd)))+            ckt->CKTvoltTol))         if ( (fabs(cghat-*(ckt->CKTstate0 + here->HFET2cg))             < ckt->CKTreltol*MAX(fabs(cghat),            fabs(*(ckt->CKTstate0 + here->HFET2cg)))+            ckt->CKTabstol) ) if ( /* hack - expression too big */            (fabs(cdhat-*(ckt->CKTstate0 + here->HFET2cd))            < ckt->CKTreltol*MAX(fabs(cdhat),            fabs(*(ckt->CKTstate0 + here->HFET2cd)))+            ckt->CKTabstol) ) {            /* we can do a bypass */            vgs= *(ckt->CKTstate0 + here->HFET2vgs);            vgd= *(ckt->CKTstate0 + here->HFET2vgd);            vds= vgs-vgd;            cg= *(ckt->CKTstate0 + here->HFET2cg);            cd= *(ckt->CKTstate0 + here->HFET2cd);            cgd= *(ckt->CKTstate0 + here->HFET2cgd);            gm= *(ckt->CKTstate0 + here->HFET2gm);            gds= *(ckt->CKTstate0 + here->HFET2gds);            ggs= *(ckt->CKTstate0 + here->HFET2ggs);            ggd= *(ckt->CKTstate0 + here->HFET2ggd);            goto load;          }            //  limit nonlinear branch voltages           ichk1=1;          vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),CONSTvt0,vcrit, &icheck);          vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),CONSTvt0,vcrit,&ichk1);          if(ichk1 == 1) {            icheck=1;          }          vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->HFET2vgs),TVTO);          vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->HFET2vgd),TVTO);        }      cg = 0;      cgd = 0;      ggd = 0;      ggs = 0;      vds  = vgs-vgd;      {        double arg  = -vgs*DEL/vt;        double earg = exp(arg);        double vtn  = N*vt;        double expe = exp(vgs/vtn);        ggs  = JSLW*expe/vtn+GGRLW*earg*(1-arg);        cg   = JSLW*(expe-1)+GGRLW*vgs*earg;        arg  = -vgd*DEL/vt;        earg = exp(arg);        expe = exp(vgd/vtn);        ggd  = JSLW*expe/vtn+GGRLW*earg*(1-arg);        cgd  = JSLW*(expe-1)+GGRLW*vgd*earg;        cg  += cgd;      }            if(vds < 0) {        vds = -vds;        inverse = 1;      } else        inverse = 0;      hfeta2(model,here,ckt,vds>0?vgs:vgd,vds,&cdrain,&gm,&gds,&capgs,&capgd);      if(inverse) {        double temp;        cdrain = -cdrain;        vds = -vds;        temp = capgs;        capgs = capgd;        capgd = temp;      }      cd = cdrain - cgd;      if((ckt->CKTmode & (MODETRAN|MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) &&        (ckt->CKTmode & MODEUIC)) ){        //    charge storage elements         vgs1 = *(ckt->CKTstate1 + here->HFET2vgs);        vgd1 = *(ckt->CKTstate1 + here->HFET2vgd);        if(ckt->CKTmode & MODEINITTRAN) {          *(ckt->CKTstate1 + here->HFET2qgs) = capgs*vgs;          *(ckt->CKTstate1 + here->HFET2qgd) = capgd*vgd;        }        *(ckt->CKTstate0+here->HFET2qgs) = *(ckt->CKTstate1+here->HFET2qgs)                        + capgs*(vgs-vgs1);        *(ckt->CKTstate0+here->HFET2qgd) = *(ckt->CKTstate1+here->HFET2qgd)                        + capgd*(vgd-vgd1);        //   store small-signal parameters         if( (!(ckt->CKTmode & MODETRANOP)) || (!(ckt->CKTmode & MODEUIC)) ) {          if(ckt->CKTmode & MODEINITSMSIG) {            *(ckt->CKTstate0 + here->HFET2qgs) = capgs;            *(ckt->CKTstate0 + here->HFET2qgd) = capgd;            continue; /*go to 1000*/          }                    //   transient analysis           if(ckt->CKTmode & MODEINITTRAN) {            *(ckt->CKTstate1 + here->HFET2qgs) = *(ckt->CKTstate0 + here->HFET2qgs);            *(ckt->CKTstate1 + here->HFET2qgd) = *(ckt->CKTstate0 + here->HFET2qgd);          }          error = NIintegrate(ckt,&geq,&ceq,capgs,here->HFET2qgs);          if(error) return(error);          ggs = ggs + geq;          cg = cg + *(ckt->CKTstate0 + here->HFET2cqgs);          error = NIintegrate(ckt,&geq,&ceq,capgd,here->HFET2qgd);          if(error) return(error);          ggd = ggd + geq;          cg = cg + *(ckt->CKTstate0 + here->HFET2cqgd);          cd = cd - *(ckt->CKTstate0 + here->HFET2cqgd);          cgd = cgd + *(ckt->CKTstate0 + here->HFET2cqgd);          if (ckt->CKTmode & MODEINITTRAN) {            *(ckt->CKTstate1 + here->HFET2cqgs) = *(ckt->CKTstate0 + here->HFET2cqgs);            *(ckt->CKTstate1 + here->HFET2cqgd) = *(ckt->CKTstate0 + here->HFET2cqgd);          }        }      }      //  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->CKTstate0 + here->HFET2vgs) = vgs;      *(ckt->CKTstate0 + here->HFET2vgd) = vgd;      *(ckt->CKTstate0 + here->HFET2cg) = cg;      *(ckt->CKTstate0 + here->HFET2cd) = cd;      *(ckt->CKTstate0 + here->HFET2cgd) = cgd;      *(ckt->CKTstate0 + here->HFET2gm) = gm;      *(ckt->CKTstate0 + here->HFET2gds) = gds;      *(ckt->CKTstate0 + here->HFET2ggs) = ggs;      *(ckt->CKTstate0 + here->HFET2ggd) = ggd;            //    load current vectorload:      m = here->HFET2m;      ceqgd=model->HFET2type*(cgd-ggd*vgd);      ceqgs=model->HFET2type*((cg-cgd)-ggs*vgs);      cdreq=model->HFET2type*((cd+cgd)-gds*vds-gm*vgs);      *(ckt->CKTrhs + here->HFET2gateNode)        += m * (-ceqgs-ceqgd);      *(ckt->CKTrhs + here->HFET2drainPrimeNode)  += m * (-cdreq+ceqgd);      *(ckt->CKTrhs + here->HFET2sourcePrimeNode) += m * (cdreq+ceqgs);      //   load y matrix       *(here->HFET2drainDrainPrimePtr)          += m * (-gdpr);      *(here->HFET2gateDrainPrimePtr)           += m * (-ggd);      *(here->HFET2gateSourcePrimePtr)          += m * (-ggs);      *(here->HFET2sourceSourcePrimePtr)        += m * (-gspr);      *(here->HFET2drainPrimeDrainPtr)          += m * (-gdpr);      *(here->HFET2drainPrimeGatePtr)           += m * (gm-ggd);      *(here->HFET2drainPriHFET2ourcePrimePtr)  += m * (-gds-gm);      *(here->HFET2sourcePrimeGatePtr)          += m * (-ggs-gm);      *(here->HFET2sourcePriHFET2ourcePtr)      += m * (-gspr);      *(here->HFET2sourcePrimeDrainPrimePtr)    += m * (-gds);      *(here->HFET2drainDrainPtr)               += m * (gdpr);      *(here->HFET2gateGatePtr)                 += m * (ggd+ggs);      *(here->HFET2sourceSourcePtr)             += m * (gspr);      *(here->HFET2drainPrimeDrainPrimePtr)     += m * (gdpr+gds+ggd);      *(here->HFET2sourcePriHFET2ourcePrimePtr) += m * (gspr+gds+gm+ggs);    }  }  return(OK);  }static void hfeta2(HFET2model *model, HFET2instance *here, CKTcircuit *ckt,                  double vgs, double vds, double *cdrain, double *gm,                  double *gds, double *capgs, double *capgd){             double vt;  double vgt;  double vgt0;  double sigma;  double vgte;  double isat;  double isatm;  double ns;  double nsm;  double a;  double b;  double c;  double d;  double e;  double g;  double h;  double p;  double q;  double s;  double t;  double u;  double nsc = 0.0;  double nsn = 0.0;  double temp;  double etavth;  double gch;  double gchi;  double gchim;  double vsate;  double vdse;  double cg1;  double cgc;  double rt;  double vl;  double delidgch;  double delgchgchi;  double delgchins;  double delnsnsm;  double delnsmvgt;  double delvgtevgt;  double delidvsate;  double delvsateisat;  double delisatisatm;  double delisatmvgte;  double delisatmgchim;  double delvsategch;  double delidvds;  double delvgtvgs;  double delvsatevgt;  vt     = CONSTKoverQ*TEMP;  etavth = ETA*vt;  vl     = VS/TMU*L;  rt     = RSI+RDI;  vgt0   = vgs - TVTO;  s      = exp((vgt0-VSIGMAT)/VSIGMA);  sigma  = SIGMA0/(1+s);  vgt    = vgt0+sigma*vds;  u      = 0.5*vgt/vt-1;  t      = sqrt(DELTA2+u*u);  vgte   = vt*(2+u+t);  b      = exp(vgt/etavth);  if(model->HFET2eta2Given && model->HFET2d2Given) {    nsc    = N02*exp((vgt+TVTO-VT2)/(ETA2*vt));    nsn    = 2*N0*log(1+0.5*b);    nsm    = nsn*nsc/(nsn+nsc);  } else {    nsm = 2*N0*log(1+0.5*b);  }  if(nsm < 1.0e-38) {    *cdrain = 0;    *gm = 0.0;    *gds = 0.0;    *capgs = CF;    *capgd = CF;    return;  }  c      = pow(nsm/TNMAX,GAMMA);  q      = pow(1+c,1.0/GAMMA);  ns     = nsm/q;  gchi   = GCHI0*ns;  gch    = gchi/(1+gchi*rt);  gchim  = GCHI0*nsm;  h      = sqrt(1+2*gchim*RSI + vgte*vgte/(vl*vl));  p      = 1+gchim*RSI+h;  isatm  = gchim*vgte/p;  g      = pow(isatm/IMAX,GAMMA);  isat   = isatm/pow(1+g,1/GAMMA);  vsate  = isat/gch;  d      = pow(vds/vsate,M);  e      = pow(1+d,1.0/M);  delidgch      = vds*(1+TLAMBDA*vds)/e;  *cdrain       = gch*delidgch;  delidvsate    = (*cdrain)*d/vsate/(1+d);  delidvds      = gch*(1+2*TLAMBDA*vds)/e-(*cdrain)*                  pow(vds/vsate,M-1)/(vsate*(1+d));  a             = 1+gchi*rt;  delgchgchi    = 1.0/(a*a);  delgchins     = GCHI0;  delnsnsm      = ns/nsm*(1-c/(1+c));  delvgtevgt    = 0.5*(1+u/t);  delnsmvgt     = N0/etavth/(1.0/b + 0.5);  if(model->HFET2eta2Given && model->HFET2d2Given)    delnsmvgt     = nsc*(nsc*delnsmvgt+nsn*nsn/(ETA2*vt))/((nsc+nsn)*(nsc+nsn));  delvsateisat  = 1.0/gch;  delisatisatm  = isat/isatm*(1-g/(1+g));  delisatmvgte  = gchim*(p - vgte*vgte/(vl*vl*h))/(p*p);  delvsategch   = -vsate/gch;  delisatmgchim = vgte*(p - gchim*RSI*(1+1.0/h))/(p*p);  delvgtvgs     = 1-vds*SIGMA0/VSIGMA*s/((1+s)*(1+s));  p             = delgchgchi*delgchins*delnsnsm*delnsmvgt;  delvsatevgt   = (delvsateisat*delisatisatm*(delisatmvgte*delvgtevgt +                  delisatmgchim*GCHI0*delnsmvgt)+delvsategch*p);  g             = delidgch*p + delidvsate*delvsatevgt;  *gm           = g*delvgtvgs;  *gds          = delidvds + g*sigma;  // Capacitance calculations  temp          = ETA1*vt;  cg1           = 1/(D1/EPSI+temp*exp(-(vgs-HFET2_VT1)/temp));  cgc           = W*L*(CHARGE*delnsnsm*delnsmvgt*delvgtvgs+cg1);  vdse          = vds*pow(1+pow(vds/vsate,MC),-1.0/MC);  a             = (vsate-vdse)/(2*vsate-vdse);  a             = a*a;  temp          = 2.0/3.0;  p             = PP + (1-PP)*exp(-vds/vsate);  *capgs        = CF+2*temp*cgc*(1-a)/(1+p);  a             = vsate/(2*vsate-vdse);  a             = a*a;  *capgd        = CF+2*p*temp*cgc*(1-a)/(1+p);}

⌨️ 快捷键说明

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