⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 b3v1sld.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 5 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1991 JianHui Huang and Min-Chie Jeng.File: b3v1sld.c          1/3/92Modified by Mansun Chan  (1995)Modified by Paolo Nenzi 2002**********/#include "ngspice.h"#include "cktdefs.h"#include "bsim3v1sdef.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.02intBSIM3v1Sload(GENmodel *inModel, CKTcircuit *ckt){BSIM3v1Smodel *model = (BSIM3v1Smodel*)inModel;BSIM3v1Sinstance *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=0.0, cqgate=0.0, cqbulk=0.0, cqdrn=0.0;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;   struct bsim3v1sSizeDependParam *pParam;int ByPass, Check, ChargeComputationNeeded = 0, error;for (; model != NULL; model = model->BSIM3v1SnextModel){  for (here = model->BSIM3v1Sinstances; here != NULL;           here = here->BSIM3v1SnextInstance)     {              	  if (here->BSIM3v1Sowner != ARCHme) 	          continue;          	  Check = 1;          ByPass = 0;	  pParam = here->pParam;          if ((ckt->CKTmode & MODEINITSMSIG))	  {   vbs = *(ckt->CKTstate0 + here->BSIM3v1Svbs);              vgs = *(ckt->CKTstate0 + here->BSIM3v1Svgs);              vds = *(ckt->CKTstate0 + here->BSIM3v1Svds);              qdef = *(ckt->CKTstate0 + here->BSIM3v1Sqcdump);          }	  else if ((ckt->CKTmode & MODEINITTRAN))	  {   vbs = *(ckt->CKTstate1 + here->BSIM3v1Svbs);              vgs = *(ckt->CKTstate1 + here->BSIM3v1Svgs);              vds = *(ckt->CKTstate1 + here->BSIM3v1Svds);              qdef = *(ckt->CKTstate1 + here->BSIM3v1Sqcdump);          }	  else if ((ckt->CKTmode & MODEINITJCT) && !here->BSIM3v1Soff)	  {   vds = model->BSIM3v1Stype * here->BSIM3v1SicVDS;              vgs = model->BSIM3v1Stype * here->BSIM3v1SicVGS;              vbs = model->BSIM3v1Stype * here->BSIM3v1SicVBS;              qdef = 0.0;              if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) &&                   ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP |                   MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC))))	      {                  vgs = pParam->BSIM3v1Svth0 + 0.1;                  if (here->BSIM3v1SgNode == here->BSIM3v1SdNode)                        vds = vgs;                  else                        vds = 0.1;                  if ((here->BSIM3v1SbNode != here->BSIM3v1SsNode)                     && (here->BSIM3v1SbNode != here->BSIM3v1SdNode))                        vbs = -0.1;                  else                        vbs = 0.0;              }          }	  else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) &&                   (here->BSIM3v1Soff))           {    qdef = vbs = vgs = vds = 0.0;	  }          else	  {#ifndef PREDICTOR               if ((ckt->CKTmode & MODEINITPRED))	       {   xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1];                   *(ckt->CKTstate0 + here->BSIM3v1Svbs) =                          *(ckt->CKTstate1 + here->BSIM3v1Svbs);                   vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1Svbs))                         - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1Svbs)));                   *(ckt->CKTstate0 + here->BSIM3v1Svgs) =                          *(ckt->CKTstate1 + here->BSIM3v1Svgs);                   vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1Svgs))                         - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1Svgs)));                   *(ckt->CKTstate0 + here->BSIM3v1Svds) =                          *(ckt->CKTstate1 + here->BSIM3v1Svds);                   vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1Svds))                         - (xfact * (*(ckt->CKTstate2 + here->BSIM3v1Svds)));                   *(ckt->CKTstate0 + here->BSIM3v1Svbd) =                          *(ckt->CKTstate0 + here->BSIM3v1Svbs)                         - *(ckt->CKTstate0 + here->BSIM3v1Svds);                   qdef = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3v1Sqcdump))                           -(xfact * (*(ckt->CKTstate2 + here->BSIM3v1Sqcdump)));               }	       else	       {#endif /* PREDICTOR */                   vbs = model->BSIM3v1Stype                       * (*(ckt->CKTrhsOld + here->BSIM3v1SbNode)                       - *(ckt->CKTrhsOld + here->BSIM3v1SsNodePrime));                   vgs = model->BSIM3v1Stype                       * (*(ckt->CKTrhsOld + here->BSIM3v1SgNode)                        - *(ckt->CKTrhsOld + here->BSIM3v1SsNodePrime));                   vds = model->BSIM3v1Stype                       * (*(ckt->CKTrhsOld + here->BSIM3v1SdNodePrime)                       - *(ckt->CKTrhsOld + here->BSIM3v1SsNodePrime));                   qdef = *(ckt->CKTrhsOld + here->BSIM3v1SqNode);#ifndef PREDICTOR               }#endif /* PREDICTOR */               vbd = vbs - vds;               vgd = vgs - vds;               vgdo = *(ckt->CKTstate0 + here->BSIM3v1Svgs)                    - *(ckt->CKTstate0 + here->BSIM3v1Svds);               delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3v1Svbs);               delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3v1Svbd);               delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3v1Svgs);               delvds = vds - *(ckt->CKTstate0 + here->BSIM3v1Svds);               delvgd = vgd - vgdo;               if (here->BSIM3v1Smode >= 0) 	       {   cdhat = here->BSIM3v1Scd - here->BSIM3v1Sgbd * delvbd                          + here->BSIM3v1Sgmbs * delvbs + here->BSIM3v1Sgm * delvgs                         + here->BSIM3v1Sgds * delvds;	       }               else	       {   cdhat = here->BSIM3v1Scd - (here->BSIM3v1Sgbd - here->BSIM3v1Sgmbs)                         * delvbd - here->BSIM3v1Sgm * delvgd                          + here->BSIM3v1Sgds * delvds;               	       }               cbhat = here->BSIM3v1Scbs + here->BSIM3v1Scbd + here->BSIM3v1Sgbd                     * delvbd + here->BSIM3v1Sgbs * delvbs;           /* 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->BSIM3v1Svbs))) + ckt->CKTvoltTol)))               if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd),                   fabs(*(ckt->CKTstate0+here->BSIM3v1Svbd))) + ckt->CKTvoltTol)))               if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs),                   fabs(*(ckt->CKTstate0+here->BSIM3v1Svgs))) + ckt->CKTvoltTol)))               if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds),                   fabs(*(ckt->CKTstate0+here->BSIM3v1Svds))) + ckt->CKTvoltTol)))               if ((fabs(cdhat - here->BSIM3v1Scd) < ckt->CKTreltol                    * MAX(fabs(cdhat),fabs(here->BSIM3v1Scd)) + ckt->CKTabstol))	       {   tempv = MAX(fabs(cbhat),fabs(here->BSIM3v1Scbs                          + here->BSIM3v1Scbd)) + ckt->CKTabstol;                   if ((fabs(cbhat - (here->BSIM3v1Scbs + here->BSIM3v1Scbd))                       < ckt->CKTreltol * tempv))		   {   /* bypass code */                       vbs = *(ckt->CKTstate0 + here->BSIM3v1Svbs);                       vbd = *(ckt->CKTstate0 + here->BSIM3v1Svbd);                       vgs = *(ckt->CKTstate0 + here->BSIM3v1Svgs);                       vds = *(ckt->CKTstate0 + here->BSIM3v1Svds);                       qcheq = *(ckt->CKTstate0 + here->BSIM3v1Sqcheq);                       vgd = vgs - vds;                       vgb = vgs - vbs;                       cdrain = here->BSIM3v1Smode * (here->BSIM3v1Scd                              + here->BSIM3v1Scbd);                        if ((ckt->CKTmode & (MODETRAN | MODEAC)) ||                            ((ckt->CKTmode & MODETRANOP) &&                            (ckt->CKTmode & MODEUIC)))		       {   ByPass = 1;                           goto line755;                       }		       else		       {   goto line850;		       }                   }               }               von = here->BSIM3v1Svon;               if (*(ckt->CKTstate0 + here->BSIM3v1Svds) >= 0.0)	       {   vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3v1Svgs), von);                   vds = vgs - vgd;                   vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->BSIM3v1Svds));                   vgd = vgs - vds;               }	       else	       {   vgd = DEVfetlim(vgd, vgdo, von);                   vds = vgs - vgd;                   vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0+here->BSIM3v1Svds)));                   vgs = vgd + vds;               }               if (vds >= 0.0)	       {   vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->BSIM3v1Svbs),                                   CONSTvt0, model->BSIM3v1Svcrit, &Check);                   vbd = vbs - vds;               }	       else	       {   vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->BSIM3v1Svbd),                                   CONSTvt0, model->BSIM3v1Svcrit, &Check);                    vbs = vbd + vds;               }          }          /* determine DC current and derivatives */          vbd = vbs - vds;          vgd = vgs - vds;          vgb = vgs - vbs;/* the following code has been changed for the calculation of S/B and D/B diodes*/	  if ((here->BSIM3v1SsourceArea <= 0.0) &&	      (here->BSIM3v1SsourcePerimeter <= 0.0))	  {   SourceSatCurrent = 1.0e-14;	  }	  else	  {   SourceSatCurrent = here->BSIM3v1SsourceArea			       * model->BSIM3v1SjctTempSatCurDensity			       + here->BSIM3v1SsourcePerimeter			       * model->BSIM3v1SjctSidewallTempSatCurDensity;	  }	  Nvtm = model->BSIM3v1Svtm * model->BSIM3v1SjctEmissionCoeff;	  if (SourceSatCurrent <= 0.0)	  {   here->BSIM3v1Sgbs = ckt->CKTgmin;              here->BSIM3v1Scbs = here->BSIM3v1Sgbs * vbs;          }	  else if (vbs < 0.5)	  {   evbs = exp(vbs / Nvtm);              here->BSIM3v1Sgbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin;              here->BSIM3v1Scbs = SourceSatCurrent * (evbs - 1.0)                              + ckt->CKTgmin * vbs;          }	  else	  {   evbs = exp(0.5 / Nvtm);              T0 = SourceSatCurrent * evbs / Nvtm;              here->BSIM3v1Sgbs = T0 + ckt->CKTgmin;              here->BSIM3v1Scbs = SourceSatCurrent * (evbs - 1.0) 			     + T0 * (vbs - 0.5) + ckt->CKTgmin * vbs;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -