📄 b3soifdld.c
字号:
/**********Copyright 1999 Regents of the University of California. All rights reserved.Author: Weidong Liu and Pin Su Feb 1999Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen TangModified by Pin Su, Wei Jin 99/9/27Modified by Paolo Nenzi 2002File: b3soifdld.c 98/5/01**********//* * Revision 2.1 99/9/27 Pin Su * BSIMFD2.1 release */#include "ngspice.h"#include "cktdefs.h"#include "b3soifddef.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 KboQ 8.617087e-5 /* Kb / q */#define Eg300 1.115 /* energy gap at 300K */#define DELTA_1 0.02#define DELTA_2 0.02#define DELTA_3 0.02#define DELTA_4 0.02#define DELT_Vbs0eff 0.02#define DELT_Vbsmos 0.005#define DELT_Vbseff 0.005#define DELT_Xcsat 0.2#define DELT_Vbs0dio 1e-7#define DELTA_VFB 0.02#define DELTA_Vcscv 0.0004#define DELT_Vbsdio 0.01#define CONST_2OV3 0.6666666666#define OFF_Vbsdio 2e-2#define OFF_Vbs0_dio 2.02e-2#define QEX_FACT 20 /* B3SOIFDSmartVbs(Vbs, Old, here, check) * Smart Vbs guess. */doubleB3SOIFDSmartVbs(double New, double Old, B3SOIFDinstance *here, CKTcircuit *ckt, int *check){ /* only do it for floating body and DC */ if (here->B3SOIFDfloat && (ckt->CKTmode & (MODEDC | MODEDCOP))) { /* Vbs cannot be negative in DC */ if (New < 0.0) New = 0.0; } return(New);} /* B3SOIFDlimit(vnew,vold) * limits the per-iteration change of any absolute voltage value */doubleB3SOIFDlimit(double vnew, double vold, double limit, int *check){ double T0, T1; if (isnan (vnew) || isnan (vold)) { fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); fprintf(stderr, "New prediction returns to 0.0!\n"); vnew = 0.0; *check = 1; } T0 = vnew - vold; T1 = fabs(T0); if (T1 > limit) { if (T0 > 0.0) vnew = vold + limit; else vnew = vold - limit; *check = 1; } return vnew;}intB3SOIFDload(GENmodel *inModel, CKTcircuit *ckt){B3SOIFDmodel *model = (B3SOIFDmodel*)inModel;B3SOIFDinstance *here;int selfheat;double ag0, qgd, qgs, von, cbhat, VgstNVt, ExpVgst = 0.0;double cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq;double delvbd, delvbs, delvds, delvgd, delvgs;double Vfbeff, dVfbeff_dVd, dVfbeff_dVb, V3, V4;double gcgdb, gcggb, gcgsb, gcgeb, gcgT;double gcsdb, gcsgb, gcssb, gcseb, gcsT;double gcddb, gcdgb, gcdsb, gcdeb, gcdT;double gcbdb, gcbgb, gcbsb, gcbeb, gcbT;double gcedb, gcegb, gcesb, gceeb, gceT;double gcTt, gTtg, gTtb, gTte, gTtdp, gTtt, gTtsp;double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact;double vg, vd, vs, vp, ve, vb;double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum;double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVfb_dT;double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth = 0.0, dVth_dVb;double dVth_dVd, dVth_dT;double Vgst, dVgs_eff_dVg;double n, dn_dVb, Vtm;double ExpArg, V0;double ueff = 0.0, dueff_dVg, dueff_dVd, dueff_dVb, dueff_dT;double Esat, Vdsat = 0.0;double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb, dEsatL_dT;double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, dVdsat_dT, Vasat;double dVasat_dVg, dVasat_dVb, dVasat_dVd, dVasat_dT;double Va, dVa_dVd, dVa_dVg, dVa_dVb, dVa_dT;double Vbseff, dVbseff_dVb;double One_Third_CoxWL, Two_Third_CoxWL, CoxWL;double T0, dT0_dVg, dT0_dVd, dT0_dVb, dT0_dVc, dT0_dVe, dT0_dT;double T1, dT1_dVg, dT1_dVd, dT1_dVb, dT1_dVc, dT1_dVe, dT1_dT;double T2, dT2_dVg, dT2_dVd, dT2_dVb, dT2_dVc, dT2_dVe, dT2_dT;double T3, dT3_dVg, dT3_dVd, dT3_dVb, dT3_dVc, dT3_dVe, dT3_dT;double T4, dT4_dVg, dT4_dVd, dT4_dVb, dT4_dVe, dT4_dT;double T5, dT5_dVe;double T6, dT6_dVe, dT6_dT;double T7;double T8;double T9;double T10;double T11;double Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb;double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb, dVACLM_dT;double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb, dVADIBL_dT;double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb;double Delt_vth, dDelt_vth_dVb, dDelt_vth_dT;double Theta0, dTheta0_dVb;double TempRatio, tmp1, tmp2, tmp3, tmp4;double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg;double a1; double Vgsteff = 0.0, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb;double dVgsteff_dVe, dVgsteff_dT;double Vdseff = 0.0, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb, dVdseff_dT;double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb;double diffVds;double dAbulk_dVg, dn_dVd ;double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb, dbeta_dT;double gche, dgche_dVg, dgche_dVd, dgche_dVb, dgche_dT;double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb, dfgche1_dT;double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb, dfgche2_dT;double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb, dIdl_dT;double Ids = 0.0, Gm, Gds = 0.0, Gmb;double CoxWovL;double Rds, dRds_dVg, dRds_dVb, dRds_dT, WVCox, WVCoxRds;double Vgst2Vtm, dVgst2Vtm_dT, VdsatCV, dVdsatCV_dVg, dVdsatCV_dVb;double Leff, Weff, dWeff_dVg, dWeff_dVb;double AbulkCV, dAbulkCV_dVb;double qgdo, qgso, cgdo, cgso; double dxpart, sxpart; struct b3soifdSizeDependParam *pParam;int ByPass, Check, ChargeComputationNeeded = 0, error; double gbbsp, gbbdp, gbbg, gbbb, gbbe, gbbp, gbbT;double gddpsp, gddpdp, gddpg, gddpb, gddpe, gddpT;double gsspsp, gsspdp, gsspg, gsspb, gsspe, gsspT;double Gbpbs, Gbpgs, Gbpds, Gbpes, Gbpps, GbpT;double ves, ved, veb, vge = 0.0, delves, vedo, delved;double vps, vpd, Vps, delvps;double Vbd, Ves, Vesfb, sqrtXdep, DeltVthtemp, dDeltVthtemp_dT;double Vbp, dVbp_dVp, dVbp_dVb, dVbp_dVg, dVbp_dVd, dVbp_dVe, dVbp_dT;double Vpsdio, dVpsdio_dVg, dVpsdio_dVd, dVpsdio_dVe, dVpsdio_dVp, dVpsdio_dT;double DeltVthw, dDeltVthw_dVb, dDeltVthw_dT;double dVbseff_dVd, dVbseff_dVe, dVbseff_dT;double dVdsat_dVc, dVasat_dVc, dVACLM_dVc, dVADIBL_dVc, dVa_dVc;double dfgche1_dVc, dfgche2_dVc, dgche_dVc, dVdseff_dVc, dIdl_dVc;double Gm0, Gds0, Gmb0, GmT0, Gmc, Gme, GmT, dVbseff_dVg;double dDIBL_Sft_dVb;double diffVdsii ;double Idgidl = 0.0, Gdgidld, Gdgidlg, Isgidl = 0.0, Gsgidlg;double Gjsd, Gjsb, GjsT, Gjdd, Gjdb, GjdT;double Ibp = 0.0, Iii = 0.0, Giid, Giig, Giib, Giie, GiiT, Gcd, Gcb, GcT;double ceqbody, ceqbodcon = 0.0;double gppg = 0.0, gppdp = 0.0, gppb = 0.0, gppe = 0.0;double gppp = 0.0, gppsp = 0.0, gppT;double delTemp, deldelTemp, Temp;double ceqth, ceqqth;double K1;double qjs = 0.0, gcjsbs, gcjsT;double qjd = 0.0, gcjdbs, gcjdds, gcjdT;double qge;double ceqqe;double ni, Eg, Cbox, Nfb, CboxWL;double dVfbeff_dVrg, Cbe = 0.0;double qinv = 0.0, qgate = 0.0, qbody = 0.0, qdrn = 0.0, qsrc, qsub = 0.0;double cqgate, cqbody = 0.0, cqdrn = 0.0, cqsub, cqtemp;double Cgg, Cgd, Cgb, Cge;double Csg, Csd, Csb, Cse, Cbg = 0.0, Cbd = 0.0, Cbb = 0.0;double Cgg1, Cgb1, Cgd1, Csg1, Csd1, Csb1;double Vbs0t = 0.0, dVbs0t_dT ;double Vbs0 = 0.0,dVbs0_dVe, dVbs0_dT;double Vbs0eff = 0.0 ,dVbs0eff_dVg ,dVbs0eff_dVd ,dVbs0eff_dVe, dVbs0eff_dT;double Vbs0teff = 0.0, dVbs0teff_dVg, dVbs0teff_dVd;double dVbs0teff_dVe, dVbs0teff_dT;double dVbsdio_dVg, dVbsdio_dVd, dVbsdio_dVe;double dVbsdio_dVb, dVbsdio_dT;double Vthfd = 0.0,dVthfd_dVd ,dVthfd_dVe, dVthfd_dT;double Vbs0mos = 0.0 ,dVbs0mos_dVe, dVbs0mos_dT;double Vbsmos ,dVbsmos_dVg ,dVbsmos_dVb ,dVbsmos_dVd, dVbsmos_dVe, dVbsmos_dT;double Abeff ,dAbeff_dVg ,dAbeff_dVb, dAbeff_dVc;double Vcs ,dVcs_dVg ,dVcs_dVb ,dVcs_dVd ,dVcs_dVe, dVcs_dT;double Xcsat = 0.0 ,dXcsat_dVg , dXcsat_dVc;double Vdsatii ,dVdsatii_dVg ,dVdsatii_dVd, dVdsatii_dVb, dVdsatii_dT;double Vdseffii ,dVdseffii_dVg ,dVdseffii_dVd, dVdseffii_dVb, dVdseffii_dT;double VcsCV = 0.0;double VdsCV = 0.0, dVdsCV_dVg = 0.0, dVdsCV_dVb = 0.0;double dVdsCV_dVd = 0.0, dVdsCV_dVc = 0.0;double Phisd ,dPhisd_dVg ,dPhisd_dVb ,dPhisd_dVd, dPhisd_dVc;double sqrtPhisd;double Xc = 0.0;double Ic = 0.0;double Ibs = 0.0;double Ibd = 0.0;double Denomi ,dDenomi_dVg ,dDenomi_dVd ,dDenomi_dVb , dDenomi_dT;double Qbf = 0.0;double Qsubs1 = 0.0;double Qsubs2 = 0.0;double Qsub0 = 0.0 ,dQsub0_dVg ,dQsub0_dVb ,dQsub0_dVd ;double Qac0 = 0.0 ,dQac0_dVb ,dQac0_dVd;double Qdep0 ,dQdep0_dVb;double Qe1 = 0.0;double Ce1g ,Ce1b ,Ce1d ,Ce1e, Ce1T;double Ce2g ,Ce2b ,Ce2d ,Ce2e, Ce2T;double Qe2 = 0.0;double dQac0_dVrg, Vbsdio = 0.0, dQsub0_dVrg;/* for self-heating */double vbi, vfbb, phi, sqrtPhi, Xdep0, jbjt, jdif, jrec, jtun, u0temp, vsattemp;double rds0, ua, ub, uc;double dvbi_dT, dvfbb_dT, djbjt_dT, djdif_dT, djrec_dT, djtun_dT, du0temp_dT;double dvsattemp_dT, drds0_dT, dua_dT, dub_dT, duc_dT, dni_dT, dVtm_dT;double dVfbeff_dT, dQac0_dT, dQsub0_dT, dVdsCV_dT = 0.0, dPhisd_dT;double CbT, CsT, CgT;double Qex, dQex_dVg, dQex_dVb, dQex_dVd, dQex_dVe, dQex_dT;/* clean up last */FILE *fpdebug = NULL;/* end clean up */int nandetect;static int nanfound = 0;char nanmessage [12];double m;for (; model != NULL; model = model->B3SOIFDnextModel){ for (here = model->B3SOIFDinstances; here != NULL; here = here->B3SOIFDnextInstance) { if (here->B3SOIFDowner != ARCHme) continue; Check = 0; ByPass = 0; selfheat = (model->B3SOIFDshMod == 1) && (here->B3SOIFDrth0 != 0.0); pParam = here->pParam; if (here->B3SOIFDdebugMod > 3) { if (model->B3SOIFDtype > 0) fpdebug = fopen("b3soifdn.log", "a"); else fpdebug = fopen("b3soifdp.log", "a"); fprintf(fpdebug, "******* Time : %.5e ******* Device: %s Iteration: %d\n", ckt->CKTtime, here->B3SOIFDname, here->B3SOIFDiterations); } if ((ckt->CKTmode & MODEINITSMSIG)) { vbs = *(ckt->CKTstate0 + here->B3SOIFDvbs); vgs = *(ckt->CKTstate0 + here->B3SOIFDvgs); ves = *(ckt->CKTstate0 + here->B3SOIFDves); vps = *(ckt->CKTstate0 + here->B3SOIFDvps); vds = *(ckt->CKTstate0 + here->B3SOIFDvds); delTemp = *(ckt->CKTstate0 + here->B3SOIFDdeltemp); vg = *(ckt->CKTrhsOld + here->B3SOIFDgNode); vd = *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime); vs = *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime); vp = *(ckt->CKTrhsOld + here->B3SOIFDpNode); ve = *(ckt->CKTrhsOld + here->B3SOIFDeNode); vb = *(ckt->CKTrhsOld + here->B3SOIFDbNode); if (here->B3SOIFDdebugMod > 2) { fprintf(fpdebug, "... INIT SMSIG ...\n"); } if (here->B3SOIFDdebugMod > 0) { fprintf(stderr, "DC op. point converge with %d iterations\n", here->B3SOIFDiterations); } } else if ((ckt->CKTmode & MODEINITTRAN)) { vbs = *(ckt->CKTstate1 + here->B3SOIFDvbs); vgs = *(ckt->CKTstate1 + here->B3SOIFDvgs); ves = *(ckt->CKTstate1 + here->B3SOIFDves); vps = *(ckt->CKTstate1 + here->B3SOIFDvps); vds = *(ckt->CKTstate1 + here->B3SOIFDvds); delTemp = *(ckt->CKTstate1 + here->B3SOIFDdeltemp); vg = *(ckt->CKTrhsOld + here->B3SOIFDgNode); vd = *(ckt->CKTrhsOld + here->B3SOIFDdNodePrime); vs = *(ckt->CKTrhsOld + here->B3SOIFDsNodePrime); vp = *(ckt->CKTrhsOld + here->B3SOIFDpNode); ve = *(ckt->CKTrhsOld + here->B3SOIFDeNode); vb = *(ckt->CKTrhsOld + here->B3SOIFDbNode); if (here->B3SOIFDdebugMod > 2) { fprintf(fpdebug, "... Init Transient ....\n"); } if (here->B3SOIFDdebugMod > 0) { fprintf(stderr, "Transient operation point converge with %d iterations\n",here->B3SOIFDiterations); } here->B3SOIFDiterations = 0; } else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIFDoff) { vds = model->B3SOIFDtype * here->B3SOIFDicVDS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -