📄 bsimload.c
字号:
/* * Copyright (c) 1985 Hong J. Park, Thomas L. Quarles */#include "prefix.h"#include <stdio.h>#include <math.h>#include "util.h"#include "CKTdefs.h"#include "BSIMdefs.h"#include "TRANdefs.h"#include "CONST.h"#include "SPerror.h"#include "DEVdefs.h"#include "suffix.h"RCSID("BSIMload.c $Revision: 1.1 $ on $Date: 90/10/11 12:41:06 $")intBSIMload(inModel,ckt) GENmodel *inModel; register CKTcircuit *ckt; /* actually load the current value into the * sparse matrix previously provided */{ register BSIMmodel *model = (BSIMmodel*)inModel; register BSIMinstance *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; int ByPass;#ifndef NOBYPASS double tempv;#endif /*NOBYPASS*/ int error; /* loop through all the BSIM device models */ for( ; model != NULL; model = model->BSIMnextModel ) { /* loop through all the instances of the model */ for (here = model->BSIMinstances; here != NULL ; here=here->BSIMnextInstance) { EffectiveLength=here->BSIMl - model->BSIMdeltaL * 1.e-6;/* m */ DrainArea = here->BSIMdrainArea; SourceArea = here->BSIMsourceArea; DrainPerimeter = here->BSIMdrainPerimeter; SourcePerimeter = here->BSIMsourcePerimeter; if( (DrainSatCurrent=DrainArea*model->BSIMjctSatCurDensity) < 1e-15){ DrainSatCurrent = 1.0e-15; } if( (SourceSatCurrent=SourceArea*model->BSIMjctSatCurDensity) <1.0e-15){ SourceSatCurrent = 1.0e-15; } GateSourceOverlapCap = model->BSIMgateSourceOverlapCap *here->BSIMw; GateDrainOverlapCap = model->BSIMgateDrainOverlapCap * here->BSIMw; GateBulkOverlapCap = model->BSIMgateBulkOverlapCap *EffectiveLength; von = model->BSIMtype * here->BSIMvon; vdsat = model->BSIMtype * here->BSIMvdsat; vt0 = model->BSIMtype * here->BSIMvt0; Check=1; ByPass = 0; if((ckt->CKTmode & MODEINITSMSIG)) { vbs= *(ckt->CKTstate0 + here->BSIMvbs); vgs= *(ckt->CKTstate0 + here->BSIMvgs); vds= *(ckt->CKTstate0 + here->BSIMvds); } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs= *(ckt->CKTstate1 + here->BSIMvbs); vgs= *(ckt->CKTstate1 + here->BSIMvgs); vds= *(ckt->CKTstate1 + here->BSIMvds); } else if((ckt->CKTmode & MODEINITJCT) && !here->BSIMoff) { vds= model->BSIMtype * here->BSIMicVDS; vgs= model->BSIMtype * here->BSIMicVGS; vbs= model->BSIMtype * here->BSIMicVBS; 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->BSIMoff)) { vbs=vgs=vds=0; } else {#ifndef PREDICTOR if((ckt->CKTmode & MODEINITPRED)) { xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->BSIMvbs) = *(ckt->CKTstate1 + here->BSIMvbs); vbs = (1+xfact)* (*(ckt->CKTstate1 + here->BSIMvbs)) -(xfact * (*(ckt->CKTstate2 + here->BSIMvbs))); *(ckt->CKTstate0 + here->BSIMvgs) = *(ckt->CKTstate1 + here->BSIMvgs); vgs = (1+xfact)* (*(ckt->CKTstate1 + here->BSIMvgs)) -(xfact * (*(ckt->CKTstate2 + here->BSIMvgs))); *(ckt->CKTstate0 + here->BSIMvds) = *(ckt->CKTstate1 + here->BSIMvds); vds = (1+xfact)* (*(ckt->CKTstate1 + here->BSIMvds)) -(xfact * (*(ckt->CKTstate2 + here->BSIMvds))); *(ckt->CKTstate0 + here->BSIMvbd) = *(ckt->CKTstate0 + here->BSIMvbs)- *(ckt->CKTstate0 + here->BSIMvds); *(ckt->CKTstate0 + here->BSIMcd) = *(ckt->CKTstate1 + here->BSIMcd); *(ckt->CKTstate0 + here->BSIMcbs) = *(ckt->CKTstate1 + here->BSIMcbs); *(ckt->CKTstate0 + here->BSIMcbd) = *(ckt->CKTstate1 + here->BSIMcbd); *(ckt->CKTstate0 + here->BSIMgm) = *(ckt->CKTstate1 + here->BSIMgm); *(ckt->CKTstate0 + here->BSIMgds) = *(ckt->CKTstate1 + here->BSIMgds); *(ckt->CKTstate0 + here->BSIMgmbs) = *(ckt->CKTstate1 + here->BSIMgmbs); *(ckt->CKTstate0 + here->BSIMgbd) = *(ckt->CKTstate1 + here->BSIMgbd); *(ckt->CKTstate0 + here->BSIMgbs) = *(ckt->CKTstate1 + here->BSIMgbs); *(ckt->CKTstate0 + here->BSIMcggb) = *(ckt->CKTstate1 + here->BSIMcggb); *(ckt->CKTstate0 + here->BSIMcbgb) = *(ckt->CKTstate1 + here->BSIMcbgb); *(ckt->CKTstate0 + here->BSIMcbsb) = *(ckt->CKTstate1 + here->BSIMcbsb); *(ckt->CKTstate0 + here->BSIMcgdb) = *(ckt->CKTstate1 + here->BSIMcgdb); *(ckt->CKTstate0 + here->BSIMcgsb) = *(ckt->CKTstate1 + here->BSIMcgsb); *(ckt->CKTstate0 + here->BSIMcbdb) = *(ckt->CKTstate1 + here->BSIMcbdb); *(ckt->CKTstate0 + here->BSIMcdgb) = *(ckt->CKTstate1 + here->BSIMcdgb); *(ckt->CKTstate0 + here->BSIMcddb) = *(ckt->CKTstate1 + here->BSIMcddb); *(ckt->CKTstate0 + here->BSIMcdsb) = *(ckt->CKTstate1 + here->BSIMcdsb); } else {#endif /* PREDICTOR */ vbs = model->BSIMtype * ( *(ckt->CKTrhsOld+here->BSIMbNode) - *(ckt->CKTrhsOld+here->BSIMsNodePrime)); vgs = model->BSIMtype * ( *(ckt->CKTrhsOld+here->BSIMgNode) - *(ckt->CKTrhsOld+here->BSIMsNodePrime)); vds = model->BSIMtype * ( *(ckt->CKTrhsOld+here->BSIMdNodePrime) - *(ckt->CKTrhsOld+here->BSIMsNodePrime));#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd=vbs-vds; vgd=vgs-vds; vgdo = *(ckt->CKTstate0 + here->BSIMvgs) - *(ckt->CKTstate0 + here->BSIMvds); delvbs = vbs - *(ckt->CKTstate0 + here->BSIMvbs); delvbd = vbd - *(ckt->CKTstate0 + here->BSIMvbd); delvgs = vgs - *(ckt->CKTstate0 + here->BSIMvgs); delvds = vds - *(ckt->CKTstate0 + here->BSIMvds); delvgd = vgd-vgdo; if (here->BSIMmode >= 0) { cdhat= *(ckt->CKTstate0 + here->BSIMcd) - *(ckt->CKTstate0 + here->BSIMgbd) * delvbd + *(ckt->CKTstate0 + here->BSIMgmbs) * delvbs + *(ckt->CKTstate0 + here->BSIMgm) * delvgs + *(ckt->CKTstate0 + here->BSIMgds) * delvds ; } else { cdhat= *(ckt->CKTstate0 + here->BSIMcd) - ( *(ckt->CKTstate0 + here->BSIMgbd) - *(ckt->CKTstate0 + here->BSIMgmbs)) * delvbd - *(ckt->CKTstate0 + here->BSIMgm) * delvgd + *(ckt->CKTstate0 + here->BSIMgds) * delvds; } cbhat= *(ckt->CKTstate0 + here->BSIMcbs) + *(ckt->CKTstate0 + here->BSIMcbd) + *(ckt->CKTstate0 + here->BSIMgbd) * delvbd + *(ckt->CKTstate0 + here->BSIMgbs) * 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->BSIMcbs) + *(ckt->CKTstate0 + here->BSIMcbd)))+ckt->CKTabstol; if((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) ) if( (FABS(delvbs) < (ckt->CKTreltol * MAX(FABS(vbs), FABS(*(ckt->CKTstate0+here->BSIMvbs)))+ ckt->CKTvoltTol)) ) if ( (FABS(delvbd) < (ckt->CKTreltol * MAX(FABS(vbd), FABS(*(ckt->CKTstate0+here->BSIMvbd)))+ ckt->CKTvoltTol)) ) if( (FABS(delvgs) < (ckt->CKTreltol * MAX(FABS(vgs), FABS(*(ckt->CKTstate0+here->BSIMvgs)))+ ckt->CKTvoltTol))) if ( (FABS(delvds) < (ckt->CKTreltol * MAX(FABS(vds), FABS(*(ckt->CKTstate0+here->BSIMvds)))+ ckt->CKTvoltTol)) ) if( (FABS(cdhat- *(ckt->CKTstate0 + here->BSIMcd)) < ckt->CKTreltol * MAX(FABS(cdhat),FABS(*(ckt->CKTstate0 + here->BSIMcd))) + ckt->CKTabstol) ) if ( (FABS(cbhat-(*(ckt->CKTstate0 + here->BSIMcbs) + *(ckt->CKTstate0 + here->BSIMcbd))) < ckt->CKTreltol * tempv)) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->BSIMvbs); vbd = *(ckt->CKTstate0 + here->BSIMvbd); vgs = *(ckt->CKTstate0 + here->BSIMvgs); vds = *(ckt->CKTstate0 + here->BSIMvds); vgd = vgs - vds; vgb = vgs - vbs; cd = *(ckt->CKTstate0 + here->BSIMcd); cbs = *(ckt->CKTstate0 + here->BSIMcbs); cbd = *(ckt->CKTstate0 + here->BSIMcbd); cdrain = here->BSIMmode * (cd + cbd); gm = *(ckt->CKTstate0 + here->BSIMgm); gds = *(ckt->CKTstate0 + here->BSIMgds); gmbs = *(ckt->CKTstate0 + here->BSIMgmbs); gbd = *(ckt->CKTstate0 + here->BSIMgbd); gbs = *(ckt->CKTstate0 + here->BSIMgbs); if((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { cggb = *(ckt->CKTstate0 + here->BSIMcggb); cgdb = *(ckt->CKTstate0 + here->BSIMcgdb); cgsb = *(ckt->CKTstate0 + here->BSIMcgsb); cbgb = *(ckt->CKTstate0 + here->BSIMcbgb); cbdb = *(ckt->CKTstate0 + here->BSIMcbdb); cbsb = *(ckt->CKTstate0 + here->BSIMcbsb); cdgb = *(ckt->CKTstate0 + here->BSIMcdgb); cddb = *(ckt->CKTstate0 + here->BSIMcddb); cdsb = *(ckt->CKTstate0 + here->BSIMcdsb); capbs = *(ckt->CKTstate0 + here->BSIMcapbs); capbd = *(ckt->CKTstate0 + here->BSIMcapbd); ByPass = 1; goto line755; } else { goto line850; } }#endif /*NOBYPASS*/ von = model->BSIMtype * here->BSIMvon; if(*(ckt->CKTstate0 + here->BSIMvds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->BSIMvgs) ,von);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -