📄 b1ld.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 "bsim1def.h"#include "trandefs.h"#include "const.h"#include "sperror.h"#include "devdefs.h"#include "suffix.h"intB1load(inModel,ckt) GENmodel *inModel; register CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */{ register B1model *model = (B1model*)inModel; register B1instance *here; double DrainSatCurrent = 0.0; double EffectiveLength = 0.0; double GateBulkOverlapCap = 0.0; double GateDrainOverlapCap = 0.0; double GateSourceOverlapCap = 0.0; double SourceSatCurrent = 0.0; double DrainArea = 0.0; double SourceArea = 0.0; double DrainPerimeter = 0.0; double SourcePerimeter = 0.0; double arg = 0.0; double capbd = 0.0; double capbs = 0.0; double cbd = 0.0; double cbhat = 0.0; double cbs = 0.0; double cd = 0.0; double cdrain = 0.0; double cdhat = 0.0; double cdreq = 0.0; double ceq = 0.0; double ceqbd = 0.0; double ceqbs = 0.0; double ceqqb = 0.0; double ceqqd = 0.0; double ceqqg = 0.0; double czbd = 0.0; double czbdsw = 0.0; double czbs = 0.0; double czbssw = 0.0; double delvbd = 0.0; double delvbs = 0.0; double delvds = 0.0; double delvgd = 0.0; double delvgs = 0.0; double evbd = 0.0; double evbs = 0.0; double gbd = 0.0; double gbs = 0.0; double gcbdb = 0.0; double gcbgb = 0.0; double gcbsb = 0.0; double gcddb = 0.0; double gcdgb = 0.0; double gcdsb = 0.0; double gcgdb = 0.0; double gcggb = 0.0; double gcgsb = 0.0; double gcsdb = 0.0; double gcsgb = 0.0; double gcssb = 0.0; double gds = 0.0; double geq = 0.0; double gm = 0.0; double gmbs = 0.0; double sarg = 0.0; double sargsw = 0.0; double tol = 0.0; double vbd = 0.0; double vbs = 0.0; double vcrit = 0.0; double vds = 0.0; double vdsat = 0.0; double vgb = 0.0; double vgd = 0.0; double vgdo = 0.0; double vgs = 0.0; double von = 0.0; double xfact = 0.0; double xnrm = 0.0; double xrev = 0.0; int Check = 0; double cgdb = 0.0; double cgsb = 0.0; double cbdb = 0.0; double cdgb = 0.0; double cddb = 0.0; double cdsb = 0.0; double cggb = 0.0; double cbgb = 0.0; double cbsb = 0.0; double csgb = 0.0; double cssb = 0.0; double csdb = 0.0; double PhiB = 0.0; double PhiBSW = 0.0; double MJ = 0.0; double MJSW = 0.0; double argsw = 0.0; double qgate = 0.0; double qbulk = 0.0; double qdrn = 0.0; double qsrc = 0.0; double cqgate = 0.0; double cqbulk = 0.0; double cqdrn = 0.0; double vt0 = 0.0; double args[8]; int ByPass = 0;#ifndef NOBYPASS double tempv = 0.0;#endif /*NOBYPASS*/ int error = 0; /* loop through all the B1 device models */ for( ; model != NULL; model = model->B1nextModel ) { /* loop through all the instances of the model */ for (here = model->B1instances; here != NULL ; here=here->B1nextInstance) { if (here->B1owner != ARCHme) continue; EffectiveLength=here->B1l - model->B1deltaL * 1.e-6;/* m */ DrainArea = here->B1drainArea; SourceArea = here->B1sourceArea; DrainPerimeter = here->B1drainPerimeter; SourcePerimeter = here->B1sourcePerimeter; if( (DrainSatCurrent=DrainArea*model->B1jctSatCurDensity) < 1e-15){ DrainSatCurrent = 1.0e-15; } if( (SourceSatCurrent=SourceArea*model->B1jctSatCurDensity) <1.0e-15){ SourceSatCurrent = 1.0e-15; } GateSourceOverlapCap = model->B1gateSourceOverlapCap *here->B1w; GateDrainOverlapCap = model->B1gateDrainOverlapCap * here->B1w; GateBulkOverlapCap = model->B1gateBulkOverlapCap *EffectiveLength; von = model->B1type * here->B1von; vdsat = model->B1type * here->B1vdsat; vt0 = model->B1type * here->B1vt0; Check=1; ByPass = 0; if((ckt->CKTmode & MODEINITSMSIG)) { vbs= *(ckt->CKTstate0 + here->B1vbs); vgs= *(ckt->CKTstate0 + here->B1vgs); vds= *(ckt->CKTstate0 + here->B1vds); } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs= *(ckt->CKTstate1 + here->B1vbs); vgs= *(ckt->CKTstate1 + here->B1vgs); vds= *(ckt->CKTstate1 + here->B1vds); } else if((ckt->CKTmode & MODEINITJCT) && !here->B1off) { vds= model->B1type * here->B1icVDS; vgs= model->B1type * here->B1icVGS; vbs= model->B1type * here->B1icVBS; 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->B1off)) { vbs=vgs=vds=0; } else {#ifndef PREDICTOR if((ckt->CKTmode & MODEINITPRED)) { xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->B1vbs) = *(ckt->CKTstate1 + here->B1vbs); vbs = (1+xfact)* (*(ckt->CKTstate1 + here->B1vbs)) -(xfact * (*(ckt->CKTstate2 + here->B1vbs))); *(ckt->CKTstate0 + here->B1vgs) = *(ckt->CKTstate1 + here->B1vgs); vgs = (1+xfact)* (*(ckt->CKTstate1 + here->B1vgs)) -(xfact * (*(ckt->CKTstate2 + here->B1vgs))); *(ckt->CKTstate0 + here->B1vds) = *(ckt->CKTstate1 + here->B1vds); vds = (1+xfact)* (*(ckt->CKTstate1 + here->B1vds)) -(xfact * (*(ckt->CKTstate2 + here->B1vds))); *(ckt->CKTstate0 + here->B1vbd) = *(ckt->CKTstate0 + here->B1vbs)- *(ckt->CKTstate0 + here->B1vds); *(ckt->CKTstate0 + here->B1cd) = *(ckt->CKTstate1 + here->B1cd); *(ckt->CKTstate0 + here->B1cbs) = *(ckt->CKTstate1 + here->B1cbs); *(ckt->CKTstate0 + here->B1cbd) = *(ckt->CKTstate1 + here->B1cbd); *(ckt->CKTstate0 + here->B1gm) = *(ckt->CKTstate1 + here->B1gm); *(ckt->CKTstate0 + here->B1gds) = *(ckt->CKTstate1 + here->B1gds); *(ckt->CKTstate0 + here->B1gmbs) = *(ckt->CKTstate1 + here->B1gmbs); *(ckt->CKTstate0 + here->B1gbd) = *(ckt->CKTstate1 + here->B1gbd); *(ckt->CKTstate0 + here->B1gbs) = *(ckt->CKTstate1 + here->B1gbs); *(ckt->CKTstate0 + here->B1cggb) = *(ckt->CKTstate1 + here->B1cggb); *(ckt->CKTstate0 + here->B1cbgb) = *(ckt->CKTstate1 + here->B1cbgb); *(ckt->CKTstate0 + here->B1cbsb) = *(ckt->CKTstate1 + here->B1cbsb); *(ckt->CKTstate0 + here->B1cgdb) = *(ckt->CKTstate1 + here->B1cgdb); *(ckt->CKTstate0 + here->B1cgsb) = *(ckt->CKTstate1 + here->B1cgsb); *(ckt->CKTstate0 + here->B1cbdb) = *(ckt->CKTstate1 + here->B1cbdb); *(ckt->CKTstate0 + here->B1cdgb) = *(ckt->CKTstate1 + here->B1cdgb); *(ckt->CKTstate0 + here->B1cddb) = *(ckt->CKTstate1 + here->B1cddb); *(ckt->CKTstate0 + here->B1cdsb) = *(ckt->CKTstate1 + here->B1cdsb); } else {#endif /* PREDICTOR */ vbs = model->B1type * ( *(ckt->CKTrhsOld+here->B1bNode) - *(ckt->CKTrhsOld+here->B1sNodePrime)); vgs = model->B1type * ( *(ckt->CKTrhsOld+here->B1gNode) - *(ckt->CKTrhsOld+here->B1sNodePrime)); vds = model->B1type * ( *(ckt->CKTrhsOld+here->B1dNodePrime) - *(ckt->CKTrhsOld+here->B1sNodePrime));#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd=vbs-vds; vgd=vgs-vds; vgdo = *(ckt->CKTstate0 + here->B1vgs) - *(ckt->CKTstate0 + here->B1vds); delvbs = vbs - *(ckt->CKTstate0 + here->B1vbs); delvbd = vbd - *(ckt->CKTstate0 + here->B1vbd); delvgs = vgs - *(ckt->CKTstate0 + here->B1vgs); delvds = vds - *(ckt->CKTstate0 + here->B1vds); delvgd = vgd-vgdo; if (here->B1mode >= 0) { cdhat= *(ckt->CKTstate0 + here->B1cd) - *(ckt->CKTstate0 + here->B1gbd) * delvbd + *(ckt->CKTstate0 + here->B1gmbs) * delvbs + *(ckt->CKTstate0 + here->B1gm) * delvgs + *(ckt->CKTstate0 + here->B1gds) * delvds ; } else { cdhat= *(ckt->CKTstate0 + here->B1cd) - ( *(ckt->CKTstate0 + here->B1gbd) - *(ckt->CKTstate0 + here->B1gmbs)) * delvbd - *(ckt->CKTstate0 + here->B1gm) * delvgd + *(ckt->CKTstate0 + here->B1gds) * delvds; } cbhat= *(ckt->CKTstate0 + here->B1cbs) + *(ckt->CKTstate0 + here->B1cbd) + *(ckt->CKTstate0 + here->B1gbd) * delvbd + *(ckt->CKTstate0 + here->B1gbs) * 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->B1cbs) + *(ckt->CKTstate0 + here->B1cbd)))+ckt->CKTabstol; if((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) ) if( (FABS(delvbs) < (ckt->CKTreltol * MAX(FABS(vbs), FABS(*(ckt->CKTstate0+here->B1vbs)))+ ckt->CKTvoltTol)) ) if ( (FABS(delvbd) < (ckt->CKTreltol * MAX(FABS(vbd), FABS(*(ckt->CKTstate0+here->B1vbd)))+ ckt->CKTvoltTol)) ) if( (FABS(delvgs) < (ckt->CKTreltol * MAX(FABS(vgs), FABS(*(ckt->CKTstate0+here->B1vgs)))+ ckt->CKTvoltTol))) if ( (FABS(delvds) < (ckt->CKTreltol * MAX(FABS(vds), FABS(*(ckt->CKTstate0+here->B1vds)))+ ckt->CKTvoltTol)) ) if( (FABS(cdhat- *(ckt->CKTstate0 + here->B1cd)) < ckt->CKTreltol * MAX(FABS(cdhat),FABS(*(ckt->CKTstate0 + here->B1cd))) + ckt->CKTabstol) ) if ( (FABS(cbhat-(*(ckt->CKTstate0 + here->B1cbs) + *(ckt->CKTstate0 + here->B1cbd))) < ckt->CKTreltol * tempv)) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->B1vbs); vbd = *(ckt->CKTstate0 + here->B1vbd); vgs = *(ckt->CKTstate0 + here->B1vgs); vds = *(ckt->CKTstate0 + here->B1vds); vgd = vgs - vds; vgb = vgs - vbs; cd = *(ckt->CKTstate0 + here->B1cd); cbs = *(ckt->CKTstate0 + here->B1cbs); cbd = *(ckt->CKTstate0 + here->B1cbd); cdrain = here->B1mode * (cd + cbd); gm = *(ckt->CKTstate0 + here->B1gm); gds = *(ckt->CKTstate0 + here->B1gds); gmbs = *(ckt->CKTstate0 + here->B1gmbs); gbd = *(ckt->CKTstate0 + here->B1gbd); gbs = *(ckt->CKTstate0 + here->B1gbs); if((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { cggb = *(ckt->CKTstate0 + here->B1cggb); cgdb = *(ckt->CKTstate0 + here->B1cgdb); cgsb = *(ckt->CKTstate0 + here->B1cgsb); cbgb = *(ckt->CKTstate0 + here->B1cbgb); cbdb = *(ckt->CKTstate0 + here->B1cbdb); cbsb = *(ckt->CKTstate0 + here->B1cbsb); cdgb = *(ckt->CKTstate0 + here->B1cdgb); cddb = *(ckt->CKTstate0 + here->B1cddb); cdsb = *(ckt->CKTstate0 + here->B1cdsb); capbs = *(ckt->CKTstate0 + here->B1capbs); capbd = *(ckt->CKTstate0 + here->B1capbd); ByPass = 1; goto line755; } else { goto line850; } }#endif /*NOBYPASS*/ von = model->B1type * here->B1von; if(*(ckt->CKTstate0 + here->B1vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->B1vgs) ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->B1vds)); vgd = vgs - vds; } else { vgd = DEVfetlim(vgd,vgdo,von); vds = vgs - vgd; vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + here->B1vds))); vgs = vgd + vds; } if(vds >= 0) { vcrit =CONSTvt0*log(CONSTvt0/(CONSTroot2*SourceSatCurrent)); vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->B1vbs), CONSTvt0,vcrit,&Check); /* B1 test */ vbd = vbs-vds; } else { vcrit = CONSTvt0*log(CONSTvt0/(CONSTroot2*DrainSatCurrent)); vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->B1vbd), CONSTvt0,vcrit,&Check); /* B1 test*/ vbs = vbd + vds; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -