📄 b2ld.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Hong J. Park, Thomas L. Quarles**********/#include "spice.h"#include <stdio.h>#include "util.h"#include "cktdefs.h"#include "bsim2def.h"#include "trandefs.h"#include "const.h"#include "sperror.h"#include "devdefs.h"#include "suffix.h"intB2load(inModel,ckt) GENmodel *inModel; register CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */{ register B2model *model = (B2model*)inModel; register B2instance *here; double DrainSatCurrent; double EffectiveLength; double GateBulkOverlapCap; double GateDrainOverlapCap; double GateSourceOverlapCap; double SourceSatCurrent; double DrainArea; double SourceArea; double DrainPerimeter; double SourcePerimeter; double arg; double capbd; double capbs; double cbd; double cbhat; double cbs; double cd; double cdrain; double cdhat; double cdreq; double ceq; double ceqbd; double ceqbs; double ceqqb; double ceqqd; double ceqqg; double czbd; double czbdsw; double czbs; double czbssw; double delvbd; double delvbs; double delvds; double delvgd; double delvgs; double evbd; double evbs; double gbd; double gbs; double gcbdb; double gcbgb; double gcbsb; double gcddb; double gcdgb; double gcdsb; double gcgdb; double gcggb; double gcgsb; double gcsdb; double gcsgb; double gcssb; double gds; double geq; double gm; double gmbs; double sarg; double sargsw; double tol; double vbd; double vbs; double vcrit; double vds; double vdsat; double vgb; double vgd; double vgdo; double vgs; double von; double xfact; double xnrm; double xrev; int Check; double cgdb; double cgsb; double cbdb; double cdgb; double cddb; double cdsb; double cggb; double cbgb; double cbsb; double csgb; double cssb; double csdb; double PhiB; double PhiBSW; double MJ; double MJSW; double argsw; double qgate; double qbulk; double qdrn; double qsrc; double cqgate; double cqbulk; double cqdrn; double vt0; double args[7]; int ByPass;#ifndef NOBYPASS double tempv;#endif /*NOBYPASS*/ int error; /* loop through all the B2 device models */ for( ; model != NULL; model = model->B2nextModel ) { /* loop through all the instances of the model */ for (here = model->B2instances; here != NULL ; here=here->B2nextInstance) { EffectiveLength=here->B2l - model->B2deltaL * 1.e-6;/* m */ DrainArea = here->B2drainArea; SourceArea = here->B2sourceArea; DrainPerimeter = here->B2drainPerimeter; SourcePerimeter = here->B2sourcePerimeter; if( (DrainSatCurrent=DrainArea*model->B2jctSatCurDensity) < 1e-15){ DrainSatCurrent = 1.0e-15; } if( (SourceSatCurrent=SourceArea*model->B2jctSatCurDensity) <1.0e-15){ SourceSatCurrent = 1.0e-15; } GateSourceOverlapCap = model->B2gateSourceOverlapCap *here->B2w; GateDrainOverlapCap = model->B2gateDrainOverlapCap * here->B2w; GateBulkOverlapCap = model->B2gateBulkOverlapCap *EffectiveLength; von = model->B2type * here->B2von; vdsat = model->B2type * here->B2vdsat; vt0 = model->B2type * here->pParam->B2vt0; Check=1; ByPass = 0; if((ckt->CKTmode & MODEINITSMSIG)) { vbs= *(ckt->CKTstate0 + here->B2vbs); vgs= *(ckt->CKTstate0 + here->B2vgs); vds= *(ckt->CKTstate0 + here->B2vds); } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs= *(ckt->CKTstate1 + here->B2vbs); vgs= *(ckt->CKTstate1 + here->B2vgs); vds= *(ckt->CKTstate1 + here->B2vds); } else if((ckt->CKTmode & MODEINITJCT) && !here->B2off) { vds= model->B2type * here->B2icVDS; vgs= model->B2type * here->B2icVGS; vbs= model->B2type * here->B2icVBS; if((vds==0) && (vgs==0) && (vbs==0) && ((ckt->CKTmode & (MODETRAN|MODEAC|MODEDCOP|MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = -1; vgs = vt0; vds = 0; } } else if((ckt->CKTmode & (MODEINITJCT | MODEINITFIX) ) && (here->B2off)) { vbs=vgs=vds=0; } else {#ifndef PREDICTOR if((ckt->CKTmode & MODEINITPRED)) { xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->B2vbs) = *(ckt->CKTstate1 + here->B2vbs); vbs = (1+xfact)* (*(ckt->CKTstate1 + here->B2vbs)) -(xfact * (*(ckt->CKTstate2 + here->B2vbs))); *(ckt->CKTstate0 + here->B2vgs) = *(ckt->CKTstate1 + here->B2vgs); vgs = (1+xfact)* (*(ckt->CKTstate1 + here->B2vgs)) -(xfact * (*(ckt->CKTstate2 + here->B2vgs))); *(ckt->CKTstate0 + here->B2vds) = *(ckt->CKTstate1 + here->B2vds); vds = (1+xfact)* (*(ckt->CKTstate1 + here->B2vds)) -(xfact * (*(ckt->CKTstate2 + here->B2vds))); *(ckt->CKTstate0 + here->B2vbd) = *(ckt->CKTstate0 + here->B2vbs)- *(ckt->CKTstate0 + here->B2vds); *(ckt->CKTstate0 + here->B2cd) = *(ckt->CKTstate1 + here->B2cd); *(ckt->CKTstate0 + here->B2cbs) = *(ckt->CKTstate1 + here->B2cbs); *(ckt->CKTstate0 + here->B2cbd) = *(ckt->CKTstate1 + here->B2cbd); *(ckt->CKTstate0 + here->B2gm) = *(ckt->CKTstate1 + here->B2gm); *(ckt->CKTstate0 + here->B2gds) = *(ckt->CKTstate1 + here->B2gds); *(ckt->CKTstate0 + here->B2gmbs) = *(ckt->CKTstate1 + here->B2gmbs); *(ckt->CKTstate0 + here->B2gbd) = *(ckt->CKTstate1 + here->B2gbd); *(ckt->CKTstate0 + here->B2gbs) = *(ckt->CKTstate1 + here->B2gbs); *(ckt->CKTstate0 + here->B2cggb) = *(ckt->CKTstate1 + here->B2cggb); *(ckt->CKTstate0 + here->B2cbgb) = *(ckt->CKTstate1 + here->B2cbgb); *(ckt->CKTstate0 + here->B2cbsb) = *(ckt->CKTstate1 + here->B2cbsb); *(ckt->CKTstate0 + here->B2cgdb) = *(ckt->CKTstate1 + here->B2cgdb); *(ckt->CKTstate0 + here->B2cgsb) = *(ckt->CKTstate1 + here->B2cgsb); *(ckt->CKTstate0 + here->B2cbdb) = *(ckt->CKTstate1 + here->B2cbdb); *(ckt->CKTstate0 + here->B2cdgb) = *(ckt->CKTstate1 + here->B2cdgb); *(ckt->CKTstate0 + here->B2cddb) = *(ckt->CKTstate1 + here->B2cddb); *(ckt->CKTstate0 + here->B2cdsb) = *(ckt->CKTstate1 + here->B2cdsb); } else {#endif /* PREDICTOR */ vbs = model->B2type * ( *(ckt->CKTrhsOld+here->B2bNode) - *(ckt->CKTrhsOld+here->B2sNodePrime)); vgs = model->B2type * ( *(ckt->CKTrhsOld+here->B2gNode) - *(ckt->CKTrhsOld+here->B2sNodePrime)); vds = model->B2type * ( *(ckt->CKTrhsOld+here->B2dNodePrime) - *(ckt->CKTrhsOld+here->B2sNodePrime));#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd=vbs-vds; vgd=vgs-vds; vgdo = *(ckt->CKTstate0 + here->B2vgs) - *(ckt->CKTstate0 + here->B2vds); delvbs = vbs - *(ckt->CKTstate0 + here->B2vbs); delvbd = vbd - *(ckt->CKTstate0 + here->B2vbd); delvgs = vgs - *(ckt->CKTstate0 + here->B2vgs); delvds = vds - *(ckt->CKTstate0 + here->B2vds); delvgd = vgd-vgdo; if (here->B2mode >= 0) { cdhat= *(ckt->CKTstate0 + here->B2cd) - *(ckt->CKTstate0 + here->B2gbd) * delvbd + *(ckt->CKTstate0 + here->B2gmbs) * delvbs + *(ckt->CKTstate0 + here->B2gm) * delvgs + *(ckt->CKTstate0 + here->B2gds) * delvds ; } else { cdhat= *(ckt->CKTstate0 + here->B2cd) - ( *(ckt->CKTstate0 + here->B2gbd) - *(ckt->CKTstate0 + here->B2gmbs)) * delvbd - *(ckt->CKTstate0 + here->B2gm) * delvgd + *(ckt->CKTstate0 + here->B2gds) * delvds; } cbhat= *(ckt->CKTstate0 + here->B2cbs) + *(ckt->CKTstate0 + here->B2cbd) + *(ckt->CKTstate0 + here->B2gbd) * delvbd + *(ckt->CKTstate0 + here->B2gbs) * delvbs ;#ifndef NOBYPASS /* now lets see if we can bypass (ugh) */ /* following should be one big if connected by && all over * the place, but some C compilers can't handle that, so * we split it up here to let them digest it in stages */ tempv = MAX(FABS(cbhat),FABS(*(ckt->CKTstate0 + here->B2cbs) + *(ckt->CKTstate0 + here->B2cbd)))+ckt->CKTabstol; if((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) ) if( (FABS(delvbs) < (ckt->CKTreltol * MAX(FABS(vbs), FABS(*(ckt->CKTstate0+here->B2vbs)))+ ckt->CKTvoltTol)) ) if ( (FABS(delvbd) < (ckt->CKTreltol * MAX(FABS(vbd), FABS(*(ckt->CKTstate0+here->B2vbd)))+ ckt->CKTvoltTol)) ) if( (FABS(delvgs) < (ckt->CKTreltol * MAX(FABS(vgs), FABS(*(ckt->CKTstate0+here->B2vgs)))+ ckt->CKTvoltTol))) if ( (FABS(delvds) < (ckt->CKTreltol * MAX(FABS(vds), FABS(*(ckt->CKTstate0+here->B2vds)))+ ckt->CKTvoltTol)) ) if( (FABS(cdhat- *(ckt->CKTstate0 + here->B2cd)) < ckt->CKTreltol * MAX(FABS(cdhat),FABS(*(ckt->CKTstate0 + here->B2cd))) + ckt->CKTabstol) ) if ( (FABS(cbhat-(*(ckt->CKTstate0 + here->B2cbs) + *(ckt->CKTstate0 + here->B2cbd))) < ckt->CKTreltol * tempv)) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->B2vbs); vbd = *(ckt->CKTstate0 + here->B2vbd); vgs = *(ckt->CKTstate0 + here->B2vgs); vds = *(ckt->CKTstate0 + here->B2vds); vgd = vgs - vds; vgb = vgs - vbs; cd = *(ckt->CKTstate0 + here->B2cd); cbs = *(ckt->CKTstate0 + here->B2cbs); cbd = *(ckt->CKTstate0 + here->B2cbd); cdrain = here->B2mode * (cd + cbd); gm = *(ckt->CKTstate0 + here->B2gm); gds = *(ckt->CKTstate0 + here->B2gds); gmbs = *(ckt->CKTstate0 + here->B2gmbs); gbd = *(ckt->CKTstate0 + here->B2gbd); gbs = *(ckt->CKTstate0 + here->B2gbs); if((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { cggb = *(ckt->CKTstate0 + here->B2cggb); cgdb = *(ckt->CKTstate0 + here->B2cgdb); cgsb = *(ckt->CKTstate0 + here->B2cgsb); cbgb = *(ckt->CKTstate0 + here->B2cbgb); cbdb = *(ckt->CKTstate0 + here->B2cbdb); cbsb = *(ckt->CKTstate0 + here->B2cbsb); cdgb = *(ckt->CKTstate0 + here->B2cdgb); cddb = *(ckt->CKTstate0 + here->B2cddb); cdsb = *(ckt->CKTstate0 + here->B2cdsb); capbs = *(ckt->CKTstate0 + here->B2capbs); capbd = *(ckt->CKTstate0 + here->B2capbd); ByPass = 1; goto line755; } else { goto line850; } }#endif /*NOBYPASS*/ von = model->B2type * here->B2von; if(*(ckt->CKTstate0 + here->B2vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->B2vgs) ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->B2vds)); vgd = vgs - vds; } else { vgd = DEVfetlim(vgd,vgdo,von); vds = vgs - vgd; vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + here->B2vds))); vgs = vgd + vds; } if(vds >= 0) { vcrit = CONSTvt0 *log(CONSTvt0/(CONSTroot2*SourceSatCurrent)); vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->B2vbs), CONSTvt0,vcrit,&Check); /* B2 test */ vbd = vbs-vds; } else { vcrit = CONSTvt0 * log(CONSTvt0/(CONSTroot2*DrainSatCurrent));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -