b3v1ld.c
来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 1,693 行 · 第 1/5 页
C
1,693 行
/********** * Copyright 1990 Regents of the University of California. All rights reserved. * File: b3v1ld.c * Author: 1995 Min-Chie Jeng and Mansun Chan. * Modified by Mansun Chan (1995) * Modified by Paolo Nenzi 2002 **********/ /* * Release Notes: * BSIM3v3.1, Released by yuhua 96/12/08 */#include "ngspice.h"#include "cktdefs.h"#include "bsim3v1def.h"#include "trandefs.h"#include "const.h"#include "sperror.h"#include "devdefs.h"#include "suffix.h"#define MAX_EXP 5.834617425e14#define MIN_EXP 1.713908431e-15#define EXP_THRESHOLD 34.0#define EPSOX 3.453133e-11#define EPSSI 1.03594e-10#define Charge_q 1.60219e-19#define DELTA_1 0.02#define DELTA_2 0.02#define DELTA_3 0.02#define DELTA_4 0.02intBSIM3v1load(GENmodel *inModel, CKTcircuit *ckt){BSIM3v1model *model = (BSIM3v1model*)inModel;BSIM3v1instance *here;double SourceSatCurrent, DrainSatCurrent;double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst = 0.0;double cdrain, cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq;double czbd, czbdsw, czbdswg, czbs, czbssw, czbsswg, evbd, evbs, arg, sarg;double delvbd, delvbs, delvds, delvgd, delvgs;double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4;double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb;double gcsgb, gcssb, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG;double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact;double qgate = 0.0, qbulk = 0.0, qdrn = 0.0, qsrc, cqgate, cqbulk, cqdrn;double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum;double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd;double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd;double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm;double n, dn_dVb, Vtm;double ExpArg, V0;double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb;double ueff, dueff_dVg, dueff_dVd, dueff_dVb; double Esat, Vdsat;double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb;double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; double T0, dT0_dVg, dT0_dVd, dT0_dVb;double T1, dT1_dVg, dT1_dVd, dT1_dVb;double T2, dT2_dVg, dT2_dVd, dT2_dVb;double T3, dT3_dVg, dT3_dVd, dT3_dVb;double T4;double T5;double T6;double T7;double T8;double T9;double T10;double T11, T12;double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb;double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb;double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb;double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb;double Theta0, dTheta0_dVb;double TempRatio, tmp1, tmp2, tmp3, tmp4;double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg;double tempv, a1;double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; double diffVds;double dAbulk_dVg, dn_dVd ;double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb;double gche, dgche_dVg, dgche_dVd, dgche_dVb;double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb;double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb;double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb;double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb;double Ids, Gm, Gds, Gmb;double Isub, Gbd, Gbg, Gbb;double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb;double CoxWovL;double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds;double Vgst2Vtm, VdsatCV, dVdsatCV_dVg, dVdsatCV_dVb;double Leff = 0.0, Weff, dWeff_dVg, dWeff_dVb;double AbulkCV, dAbulkCV_dVb;double qgdo, qgso, cgdo, cgso;double qcheq, qdef, gqdef, cqdef, cqcheq, gtau_diff, gtau_drift;double gcqdb,gcqsb,gcqgb,gcqbb;double dxpart, sxpart;double gbspsp, gbbdp, gbbsp, gbspg, gbspb, gbspdp; double gbdpdp, gbdpg, gbdpb, gbdpsp; double Cgg, Cgd, Cgb;double Csg, Csd, Csb, Cbg, Cbd, Cbb;double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0;double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb;double m = 0.0; struct bsim3v1SizeDependParam *pParam;int ByPass, Check, ChargeComputationNeeded = 0, error;for (; model != NULL; model = model->BSIM3v1nextModel){ for (here = model->BSIM3v1instances; here != NULL; here = here->BSIM3v1nextInstance) { if (here->BSIM3v1owner != ARCHme) continue; Check = 1; ByPass = 0; pParam = here->pParam; if ((ckt->CKTmode & MODEINITSMSIG)) { vbs = *(ckt->CKTstate0 + here->BSIM3v1vbs); vgs = *(ckt->CKTstate0 + here->BSIM3v1vgs); vds = *(ckt->CKTstate0 + here->BSIM3v1vds); qdef = *(ckt->CKTstate0 + here->BSIM3v1qcdump); } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs = *(ckt->CKTstate1 + here->BSIM3v1vbs); vgs = *(ckt->CKTstate1 + here->BSIM3v1vgs); vds = *(ckt->CKTstate1 + here->BSIM3v1vds); qdef = *(ckt->CKTstate1 + here->BSIM3v1qcdump); } else if ((ckt->CKTmode & MODEINITJCT) && !here->BSIM3v1off) { vds = model->BSIM3v1type * here->BSIM3v1icVDS; vgs = model->BSIM3v1type * here->BSIM3v1icVGS; vbs = model->BSIM3v1type * here->BSIM3v1icVBS; qdef = 0.0; if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = 0.0; vgs = pParam->BSIM3v1vth0 + 0.1; vds = 0.1; } } else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && (here->BSIM3v1off)) { qdef = vbs = vgs = vds = 0.0; } else {#ifndef PREDICTOR if ((ckt->CKTmode & MODEINITPRED)) { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; *(ckt->CKTstate0 + here->BSIM3v1vbs) = *(ckt->CKTstate1 + here->BSIM3v1vbs); vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1vbs)) - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1vbs))); *(ckt->CKTstate0 + here->BSIM3v1vgs) = *(ckt->CKTstate1 + here->BSIM3v1vgs); vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1vgs)) - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1vgs))); *(ckt->CKTstate0 + here->BSIM3v1vds) = *(ckt->CKTstate1 + here->BSIM3v1vds); vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1vds)) - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1vds))); *(ckt->CKTstate0 + here->BSIM3v1vbd) = *(ckt->CKTstate0 + here->BSIM3v1vbs) - *(ckt->CKTstate0 + here->BSIM3v1vds); qdef = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1qcdump)) -(xfact * (*(ckt->CKTstate2 + here->BSIM3v1qcdump))); } else {#endif /* PREDICTOR */ vbs = model->BSIM3v1type * (*(ckt->CKTrhsOld + here->BSIM3v1bNode) - *(ckt->CKTrhsOld + here->BSIM3v1sNodePrime)); vgs = model->BSIM3v1type * (*(ckt->CKTrhsOld + here->BSIM3v1gNode) - *(ckt->CKTrhsOld + here->BSIM3v1sNodePrime)); vds = model->BSIM3v1type * (*(ckt->CKTrhsOld + here->BSIM3v1dNodePrime) - *(ckt->CKTrhsOld + here->BSIM3v1sNodePrime)); qdef = *(ckt->CKTrhsOld + here->BSIM3v1qNode);#ifndef PREDICTOR }#endif /* PREDICTOR */ vbd = vbs - vds; vgd = vgs - vds; vgdo = *(ckt->CKTstate0 + here->BSIM3v1vgs) - *(ckt->CKTstate0 + here->BSIM3v1vds); delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3v1vbs); delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3v1vbd); delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3v1vgs); delvds = vds - *(ckt->CKTstate0 + here->BSIM3v1vds); delvgd = vgd - vgdo; if (here->BSIM3v1mode >= 0) { cdhat = here->BSIM3v1cd - here->BSIM3v1gbd * delvbd + here->BSIM3v1gmbs * delvbs + here->BSIM3v1gm * delvgs + here->BSIM3v1gds * delvds; } else { cdhat = here->BSIM3v1cd - (here->BSIM3v1gbd - here->BSIM3v1gmbs) * delvbd - here->BSIM3v1gm * delvgd + here->BSIM3v1gds * delvds; } cbhat = here->BSIM3v1cbs + here->BSIM3v1cbd + here->BSIM3v1gbd * delvbd + here->BSIM3v1gbs * delvbs;#ifndef NOBYPASS /* 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 */ if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass)) if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->BSIM3v1vbs))) + ckt->CKTvoltTol))) if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->BSIM3v1vbd))) + ckt->CKTvoltTol))) if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->BSIM3v1vgs))) + ckt->CKTvoltTol))) if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->BSIM3v1vds))) + ckt->CKTvoltTol))) if ((fabs(cdhat - here->BSIM3v1cd) < ckt->CKTreltol * MAX(fabs(cdhat),fabs(here->BSIM3v1cd)) + ckt->CKTabstol)) { tempv = MAX(fabs(cbhat),fabs(here->BSIM3v1cbs + here->BSIM3v1cbd)) + ckt->CKTabstol; if ((fabs(cbhat - (here->BSIM3v1cbs + here->BSIM3v1cbd)) < ckt->CKTreltol * tempv)) { /* bypass code */ vbs = *(ckt->CKTstate0 + here->BSIM3v1vbs); vbd = *(ckt->CKTstate0 + here->BSIM3v1vbd); vgs = *(ckt->CKTstate0 + here->BSIM3v1vgs); vds = *(ckt->CKTstate0 + here->BSIM3v1vds); qcheq = *(ckt->CKTstate0 + here->BSIM3v1qcheq); vgd = vgs - vds; vgb = vgs - vbs; cdrain = here->BSIM3v1mode * (here->BSIM3v1cd + here->BSIM3v1cbd); if ((ckt->CKTmode & (MODETRAN | MODEAC)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { ByPass = 1; goto line755; } else { goto line850; } } }#endif /*NOBYPASS*/ von = here->BSIM3v1von; if (*(ckt->CKTstate0 + here->BSIM3v1vds) >= 0.0) { vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3v1vgs), von); vds = vgs - vgd; vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->BSIM3v1vds)); vgd = vgs - vds; } else { vgd = DEVfetlim(vgd, vgdo, von); vds = vgs - vgd; vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0+here->BSIM3v1vds))); vgs = vgd + vds; } if (vds >= 0.0) { vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->BSIM3v1vbs), CONSTvt0, model->BSIM3v1vcrit, &Check); vbd = vbs - vds; } else { vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->BSIM3v1vbd), CONSTvt0, model->BSIM3v1vcrit, &Check); vbs = vbd + vds; } } /* determine DC current and derivatives */ vbd = vbs - vds; vgd = vgs - vds; vgb = vgs - vbs; m = here->BSIM3v1m; /* the following code has been changed for the calculation of S/B and D/B diodes*/ if ((here->BSIM3v1sourceArea <= 0.0) && (here->BSIM3v1sourcePerimeter <= 0.0)) { SourceSatCurrent = 1.0e-14; } else { SourceSatCurrent = here->BSIM3v1sourceArea * model->BSIM3v1jctTempSatCurDensity + here->BSIM3v1sourcePerimeter * model->BSIM3v1jctSidewallTempSatCurDensity; } Nvtm = model->BSIM3v1vtm * model->BSIM3v1jctEmissionCoeff; if (SourceSatCurrent <= 0.0) { here->BSIM3v1gbs = ckt->CKTgmin; here->BSIM3v1cbs = here->BSIM3v1gbs * vbs; } else if (vbs < 0.5) { evbs = exp(vbs / Nvtm); here->BSIM3v1gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin; here->BSIM3v1cbs = SourceSatCurrent * (evbs - 1.0) + ckt->CKTgmin * vbs; } else { evbs = exp(0.5 / Nvtm); T0 = SourceSatCurrent * evbs / Nvtm; here->BSIM3v1gbs = T0 + ckt->CKTgmin; here->BSIM3v1cbs = SourceSatCurrent * (evbs - 1.0) + T0 * (vbs - 0.5) + ckt->CKTgmin * vbs; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?