📄 mesaload.c
字号:
/**********Copyright 1993: T. Ytterdal, K. Lee, M. Shur and T. A. Fjeldly. All rights reserved.Author: Trond Ytterdal**********/#include "ngspice.h"#include "devdefs.h"#include "cktdefs.h"#include "mesadefs.h"#include "const.h"#include "trandefs.h"#include "sperror.h"#include "suffix.h"/*#define true 1#define false 0*/#define EPSILONGAAS (12.244*8.85418e-12)#define W (here->MESAwidth)#define L (here->MESAlength)static void mesa1(MESAmodel*, MESAinstance*, double, double, double, double*, double*, double*, double*,double*);static void mesa2(MESAmodel*, MESAinstance*, double, double, double, double*, double*, double*, double*,double*); static void mesa3(MESAmodel*, MESAinstance*, double, double, double, double*, double*, double*, double*,double*);void Pause(void);intMESAload(GENmodel *inModel, CKTcircuit *ckt){ MESAmodel *model = (MESAmodel*)inModel; MESAinstance *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 cgs; double cghat = 0.0; double arg; double earg; double delvds; double delvgd; double delvgs; double delvgspp=0; double delvgdpp=0; double evgd; double evgs; double gds; double geq; double ggd; double ggs; double gm; double ggspp=0; double cgspp=0; double ggdpp=0; double cgdpp=0; double vcrits; double vcritd; double vds=0; double vgd=0; double vgs=0; double vgspp=0; double vgdpp=0; double vgs1=0; double vgd1=0; double xfact; double temp; double vted; double vtes; double vtd; double vts; double von; double ccorr; int inverse=FALSE; int icheck; int ichk1; int error; double m; /* loop through all the models */ for( ; model != NULL; model = model->MESAnextModel ) { /* loop through all the instances of the model */ for (here = model->MESAinstances; here != NULL ; here=here->MESAnextInstance) { if (here->MESAowner != ARCHme) continue; /* * dc model parameters */ vcrits = here->MESAvcrits; vcritd = here->MESAvcritd; vtd = CONSTKoverQ * here->MESAtd; vts = CONSTKoverQ * here->MESAts; vted = model->MESAn*vtd; vtes = model->MESAn*vts; /* * initialization */ icheck = 1; if( ckt->CKTmode & MODEINITSMSIG) { vgs = *(ckt->CKTstate0 + here->MESAvgs); vgd = *(ckt->CKTstate0 + here->MESAvgd); vgspp = *(ckt->CKTstate0 + here->MESAvgspp); vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); } else if (ckt->CKTmode & MODEINITTRAN) { vgs = *(ckt->CKTstate1 + here->MESAvgs); vgd = *(ckt->CKTstate1 + here->MESAvgd); vgspp = *(ckt->CKTstate1 + here->MESAvgspp); vgdpp = *(ckt->CKTstate1 + here->MESAvgdpp); } else if ( (ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) { vds = here->MESAicVDS; vgs = here->MESAicVGS; vgd = vgs-vds; vgspp = vgs; vgdpp = vgd; } else if ( (ckt->CKTmode & MODEINITJCT) && (here->MESAoff == 0) ) { vgs = -1; vgd = -1; vgspp = 0; vgdpp = 0; } else if( (ckt->CKTmode & MODEINITJCT) || ((ckt->CKTmode & MODEINITFIX) && (here->MESAoff))) { vgs = 0; vgd = 0; vgspp = 0; vgdpp = 0; } else {#ifndef PREDICTOR if(ckt->CKTmode & MODEINITPRED) { xfact = ckt->CKTdelta/ckt->CKTdeltaOld[2]; *(ckt->CKTstate0 + here->MESAvgs) = *(ckt->CKTstate1 + here->MESAvgs); vgs = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgs) - xfact * *(ckt->CKTstate2 + here->MESAvgs); *(ckt->CKTstate0 + here->MESAvgspp) = *(ckt->CKTstate1 + here->MESAvgspp); vgspp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgspp) - xfact * *(ckt->CKTstate2 + here->MESAvgspp); *(ckt->CKTstate0 + here->MESAvgd) = *(ckt->CKTstate1 + here->MESAvgd); vgd = (1+xfact)* *(ckt->CKTstate1 + here->MESAvgd) - xfact * *(ckt->CKTstate2 + here->MESAvgd); *(ckt->CKTstate0 + here->MESAvgdpp) = *(ckt->CKTstate1 + here->MESAvgdpp); vgdpp = (1+xfact) * *(ckt->CKTstate1 + here->MESAvgdpp) - xfact * *(ckt->CKTstate2 + here->MESAvgdpp); *(ckt->CKTstate0 + here->MESAcg) = *(ckt->CKTstate1 + here->MESAcg); *(ckt->CKTstate0 + here->MESAcd) = *(ckt->CKTstate1 + here->MESAcd); *(ckt->CKTstate0 + here->MESAcgd) = *(ckt->CKTstate1 + here->MESAcgd); *(ckt->CKTstate0 + here->MESAcgs) = *(ckt->CKTstate1 + here->MESAcgs); *(ckt->CKTstate0 + here->MESAgm) = *(ckt->CKTstate1 + here->MESAgm); *(ckt->CKTstate0 + here->MESAgds) = *(ckt->CKTstate1 + here->MESAgds); *(ckt->CKTstate0 + here->MESAggs) = *(ckt->CKTstate1 + here->MESAggs); *(ckt->CKTstate0 + here->MESAggd) = *(ckt->CKTstate1 + here->MESAggd); *(ckt->CKTstate0 + here->MESAggspp) = *(ckt->CKTstate1 + here->MESAggspp); *(ckt->CKTstate0 + here->MESAcgspp) = *(ckt->CKTstate1 + here->MESAcgspp); *(ckt->CKTstate0 + here->MESAggdpp) = *(ckt->CKTstate1 + here->MESAggdpp); *(ckt->CKTstate0 + here->MESAcgdpp) = *(ckt->CKTstate1 + here->MESAcgdpp); } else {#endif /* PREDICTOR */ /* * compute new nonlinear branch voltages */ vgs = (*(ckt->CKTrhsOld+ here->MESAgatePrimeNode)- *(ckt->CKTrhsOld+here->MESAsourcePrimeNode)); vgd = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- *(ckt->CKTrhsOld+here->MESAdrainPrimeNode)); vgspp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- *(ckt->CKTrhsOld+here->MESAsourcePrmPrmNode)); vgdpp = (*(ckt->CKTrhsOld+here->MESAgatePrimeNode)- *(ckt->CKTrhsOld+here->MESAdrainPrmPrmNode)); #ifndef PREDICTOR }#endif /* PREDICTOR */ delvgs=vgs - *(ckt->CKTstate0 + here->MESAvgs); delvgd=vgd - *(ckt->CKTstate0 + here->MESAvgd); delvds=delvgs - delvgd; delvgspp = vgspp - *(ckt->CKTstate0 + here->MESAvgspp); delvgdpp = vgdpp - *(ckt->CKTstate0 + here->MESAvgdpp); cghat= *(ckt->CKTstate0 + here->MESAcg) + *(ckt->CKTstate0 + here->MESAggd)*delvgd + *(ckt->CKTstate0 + here->MESAggs)*delvgs + *(ckt->CKTstate0 + here->MESAggspp)*delvgspp+ *(ckt->CKTstate0 + here->MESAggdpp)*delvgdpp; cdhat= *(ckt->CKTstate0 + here->MESAcd) + *(ckt->CKTstate0 + here->MESAgm)*delvgs + *(ckt->CKTstate0 + here->MESAgds)*delvds - *(ckt->CKTstate0 + here->MESAggd)*delvgd; /* * bypass if solution has not changed */ if((ckt->CKTbypass) && (!(ckt->CKTmode & MODEINITPRED)) && (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs), fabs(*(ckt->CKTstate0 + here->MESAvgs)))+ ckt->CKTvoltTol) ) if((fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd), fabs(*(ckt->CKTstate0 + here->MESAvgd)))+ ckt->CKTvoltTol)) if((fabs(delvgspp) < ckt->CKTreltol*MAX(fabs(vgspp), fabs(*(ckt->CKTstate0 + here->MESAvgspp)))+ ckt->CKTvoltTol)) if((fabs(delvgdpp) < ckt->CKTreltol*MAX(fabs(vgdpp), fabs(*(ckt->CKTstate0 + here->MESAvgdpp)))+ ckt->CKTvoltTol)) if((fabs(cghat-*(ckt->CKTstate0 + here->MESAcg)) < ckt->CKTreltol*MAX(fabs(cghat), fabs(*(ckt->CKTstate0 + here->MESAcg)))+ ckt->CKTabstol)) if((fabs(cdhat-*(ckt->CKTstate0 + here->MESAcd)) < ckt->CKTreltol*MAX(fabs(cdhat), fabs(*(ckt->CKTstate0 + here->MESAcd)))+ ckt->CKTabstol)) { /* we can do a bypass */ vgs= *(ckt->CKTstate0 + here->MESAvgs); vgd= *(ckt->CKTstate0 + here->MESAvgd); vds= vgs-vgd; vgspp = *(ckt->CKTstate0 + here->MESAvgspp); vgdpp = *(ckt->CKTstate0 + here->MESAvgdpp); cg= *(ckt->CKTstate0 + here->MESAcg); cd= *(ckt->CKTstate0 + here->MESAcd); cgs= *(ckt->CKTstate0 + here->MESAcgs); cgd= *(ckt->CKTstate0 + here->MESAcgd); gm= *(ckt->CKTstate0 + here->MESAgm); gds= *(ckt->CKTstate0 + here->MESAgds); ggs= *(ckt->CKTstate0 + here->MESAggs); ggd= *(ckt->CKTstate0 + here->MESAggd); ggspp = *(ckt->CKTstate0 + here->MESAggspp); cgspp = *(ckt->CKTstate0 + here->MESAcgspp); ggdpp = *(ckt->CKTstate0 + here->MESAggdpp); cgdpp = *(ckt->CKTstate0 + here->MESAcgdpp); goto load; } /* * limit nonlinear branch voltages */ ichk1=1; vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->MESAvgs),vtes, vcrits, &icheck); vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->MESAvgd),vted, vcritd,&ichk1); if (ichk1 == 1) { icheck=1; } vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MESAvgs), here->MESAtVto); vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->MESAvgd), here->MESAtVto); if(here->MESAsourcePrmPrmNode == here->MESAsourcePrimeNode) vgspp = vgs; if(here->MESAdrainPrmPrmNode == here->MESAdrainPrimeNode) vgdpp = vgd; } /* * determine dc current and derivatives */ vds = vgs-vgd; arg = -vgs*model->MESAdel/vts; earg = exp(arg); evgs = exp(vgs/vtes); ggs = here->MESAcsatfs*evgs/vtes+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; cgs = here->MESAcsatfs*(evgs-1)+here->MESAggrwl*vgs*earg+ ckt->CKTgmin*vgs; cg = cgs; arg = -vgd*model->MESAdel/vtd; earg = exp(arg); evgd = exp(vgd/vted); ggd = here->MESAcsatfd*evgd/vted+here->MESAggrwl*earg*(1-arg)+ckt->CKTgmin; cgd = here->MESAcsatfd*(evgd-1)+here->MESAggrwl*vgd*earg+ ckt->CKTgmin*vgd; cg = cg+cgd; if(vds < 0) { vds = -vds; inverse = TRUE; } von = here->MESAtVto+model->MESAks*(*(ckt->CKTrhsOld+here->MESAsourcePrimeNode)-model->MESAvsg); if(model->MESAlevel == 2) mesa1(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); else if(model->MESAlevel == 3) mesa2(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); else if(model->MESAlevel == 4) mesa3(model,here,inverse?vgd:vgs,vds,von,&cdrain,&gm,&gds,&capgs,&capgd); if(inverse) { cdrain = -cdrain; vds = -vds; temp = capgs; capgs = capgd; capgd = temp; } /* * compute equivalent drain current source */ cd = cdrain - cgd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -