📄 hfetload.c
字号:
/**********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 + -