📄 b3soipdtemp.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen TangFile: b3soipdtemp.c 98/5/01Modified by Pin Su 99/2/15Modified by Pin Su 99/4/30Modified by Pin Su, Wei Jin 99/9/27Modified by Pin Su 00/3/1Modified by Pin Su 01/2/15Modified by Pin Su and Hui Wan 02/3/5Modified by Paolo Nenzi 2002**********//* * Revision 2.2.3 02/3/5 Pin Su * BSIMPD2.2.3 release *//* Lmin, Lmax, Wmin, Wmax */#include "ngspice.h"#include "smpdefs.h"#include "cktdefs.h"#include "b3soipddef.h"#include "const.h"#include "sperror.h"#include "suffix.h"#define Kb 1.3806226e-23#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */#define EPSOX 3.453133e-11#define EPSSI 1.03594e-10#define PI 3.141592654#define Charge_q 1.60219e-19#define Eg300 1.115 /* energy gap at 300K */#define MAX_EXPL 2.688117142e+43#define MIN_EXPL 3.720075976e-44#define EXPL_THRESHOLD 100.0#define DEXP(A,B) { \ if (A > EXPL_THRESHOLD) { \ B = MAX_EXPL*(1.0+(A)-EXPL_THRESHOLD); \ } else if (A < -EXPL_THRESHOLD) { \ B = MIN_EXPL; \ } else { \ B = exp(A); \ } \ }/* ARGSUSED */intB3SOIPDtemp(GENmodel *inModel, CKTcircuit *ckt){B3SOIPDmodel *model = (B3SOIPDmodel*) inModel;B3SOIPDinstance *here;struct b3soipdSizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam=NULL;double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;double Temp, TempRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom;double SDphi, SDgamma;int Size_Not_Found;/* v2.0 release */double tmp3, T7; /* loop through all the B3SOIPD device models */ for (; model != NULL; model = model->B3SOIPDnextModel) { Temp = ckt->CKTtemp; if (model->B3SOIPDGatesidewallJctPotential < 0.1) model->B3SOIPDGatesidewallJctPotential = 0.1; model->pSizeDependParamKnot = NULL; pLastKnot = NULL; Tnom = model->B3SOIPDtnom; TempRatio = Temp / Tnom; model->B3SOIPDvcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); model->B3SOIPDfactor1 = sqrt(EPSSI / EPSOX * model->B3SOIPDtox); Vtm0 = KboQ * Tnom; Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); model->B3SOIPDeg0 = Eg0; model->B3SOIPDvtm = KboQ * Temp; Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); /* ni is in cm^-3 */ ni = 1.45e10 * (Temp / 300.15) * sqrt(Temp / 300.15) * exp(21.5565981 - Eg / (2.0 * model->B3SOIPDvtm)); /* loop through all the instances of the model */ /* MCJ: Length and Width not initialized */ for (here = model->B3SOIPDinstances; here != NULL; here = here->B3SOIPDnextInstance) { if (here->B3SOIPDowner != ARCHme) continue; here->B3SOIPDrbodyext = here->B3SOIPDbodySquares * model->B3SOIPDrbsh; pSizeDependParamKnot = model->pSizeDependParamKnot; Size_Not_Found = 1; while ((pSizeDependParamKnot != NULL) && Size_Not_Found) { if ((here->B3SOIPDl == pSizeDependParamKnot->Length) && (here->B3SOIPDw == pSizeDependParamKnot->Width) && (here->B3SOIPDrth0 == pSizeDependParamKnot->Rth0) && (here->B3SOIPDcth0 == pSizeDependParamKnot->Cth0)) { Size_Not_Found = 0; here->pParam = pSizeDependParamKnot; pParam = here->pParam; /* v2.2.3 bug fix */ } else { pLastKnot = pSizeDependParamKnot; pSizeDependParamKnot = pSizeDependParamKnot->pNext; } } if (Size_Not_Found) { pParam = (struct b3soipdSizeDependParam *)tmalloc( sizeof(struct b3soipdSizeDependParam)); if (pLastKnot == NULL) model->pSizeDependParamKnot = pParam; else pLastKnot->pNext = pParam; pParam->pNext = NULL; here->pParam = pParam; Ldrn = here->B3SOIPDl; Wdrn = here->B3SOIPDw; pParam->Length = Ldrn; pParam->Width = Wdrn; pParam->Rth0 = here->B3SOIPDrth0; pParam->Cth0 = here->B3SOIPDcth0; T0 = pow(Ldrn, model->B3SOIPDLln); T1 = pow(Wdrn, model->B3SOIPDLwn); tmp1 = model->B3SOIPDLl / T0 + model->B3SOIPDLw / T1 + model->B3SOIPDLwl / (T0 * T1); pParam->B3SOIPDdl = model->B3SOIPDLint + tmp1;/* v2.2.3 */ tmp1 = model->B3SOIPDLlc / T0 + model->B3SOIPDLwc / T1 + model->B3SOIPDLwlc / (T0 * T1); pParam->B3SOIPDdlc = model->B3SOIPDdlc + tmp1; T2 = pow(Ldrn, model->B3SOIPDWln); T3 = pow(Wdrn, model->B3SOIPDWwn); tmp2 = model->B3SOIPDWl / T2 + model->B3SOIPDWw / T3 + model->B3SOIPDWwl / (T2 * T3); pParam->B3SOIPDdw = model->B3SOIPDWint + tmp2;/* v2.2.3 */ tmp2 = model->B3SOIPDWlc / T2 + model->B3SOIPDWwc / T3 + model->B3SOIPDWwlc / (T2 * T3); pParam->B3SOIPDdwc = model->B3SOIPDdwc + tmp2; pParam->B3SOIPDleff = here->B3SOIPDl - 2.0 * pParam->B3SOIPDdl; if (pParam->B3SOIPDleff <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel length <= 0", namarray); return(E_BADPARM); } pParam->B3SOIPDweff = here->B3SOIPDw - here->B3SOIPDnbc * model->B3SOIPDdwbc - (2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdw; if (pParam->B3SOIPDweff <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel width <= 0", namarray); return(E_BADPARM); } pParam->B3SOIPDwdiod = pParam->B3SOIPDweff / here->B3SOIPDnseg + here->B3SOIPDpdbcp; pParam->B3SOIPDwdios = pParam->B3SOIPDweff / here->B3SOIPDnseg + here->B3SOIPDpsbcp; pParam->B3SOIPDleffCV = here->B3SOIPDl - 2.0 * pParam->B3SOIPDdlc; if (pParam->B3SOIPDleffCV <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V <= 0", namarray); return(E_BADPARM); } pParam->B3SOIPDweffCV = here->B3SOIPDw - here->B3SOIPDnbc * model->B3SOIPDdwbc - (2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwc; if (pParam->B3SOIPDweffCV <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel width for C-V <= 0", namarray); return(E_BADPARM); } pParam->B3SOIPDwdiodCV = pParam->B3SOIPDweffCV / here->B3SOIPDnseg + here->B3SOIPDpdbcp; pParam->B3SOIPDwdiosCV = pParam->B3SOIPDweffCV / here->B3SOIPDnseg + here->B3SOIPDpsbcp; pParam->B3SOIPDleffCVb = here->B3SOIPDl - 2.0 * pParam->B3SOIPDdlc - model->B3SOIPDdlcb; if (pParam->B3SOIPDleffCVb <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V (body) <= 0", namarray); return(E_BADPARM); } pParam->B3SOIPDleffCVbg = pParam->B3SOIPDleffCVb + 2 * model->B3SOIPDdlbg; if (pParam->B3SOIPDleffCVbg <= 0.0) { IFuid namarray[2]; namarray[0] = model->B3SOIPDmodName; namarray[1] = here->B3SOIPDname; (*(SPfrontEnd->IFerror))(ERR_FATAL, "B3SOIPD: mosfet %s, model %s: Effective channel length for C-V (backgate) <= 0", namarray); return(E_BADPARM); } /* Not binned - START */ pParam->B3SOIPDat = model->B3SOIPDat; pParam->B3SOIPDgamma1 = model->B3SOIPDgamma1; pParam->B3SOIPDgamma2 = model->B3SOIPDgamma2; pParam->B3SOIPDvbx = model->B3SOIPDvbx; pParam->B3SOIPDvbm = model->B3SOIPDvbm; pParam->B3SOIPDxt = model->B3SOIPDxt; pParam->B3SOIPDkt1 = model->B3SOIPDkt1; pParam->B3SOIPDkt1l = model->B3SOIPDkt1l; pParam->B3SOIPDkt2 = model->B3SOIPDkt2; pParam->B3SOIPDua1 = model->B3SOIPDua1; pParam->B3SOIPDub1 = model->B3SOIPDub1; pParam->B3SOIPDuc1 = model->B3SOIPDuc1; pParam->B3SOIPDute = model->B3SOIPDute; pParam->B3SOIPDprt = model->B3SOIPDprt; /* Not binned - END */ /* CV model */ pParam->B3SOIPDcgsl = model->B3SOIPDcgsl; pParam->B3SOIPDcgdl = model->B3SOIPDcgdl; pParam->B3SOIPDckappa = model->B3SOIPDckappa; pParam->B3SOIPDcf = model->B3SOIPDcf; pParam->B3SOIPDclc = model->B3SOIPDclc; pParam->B3SOIPDcle = model->B3SOIPDcle; pParam->B3SOIPDabulkCVfactor = 1.0 + pow((pParam->B3SOIPDclc / pParam->B3SOIPDleff), pParam->B3SOIPDcle); /* Added for binning - START */ if (model->B3SOIPDbinUnit == 1) { Inv_L = 1.0e-6 / pParam->B3SOIPDleff; Inv_W = 1.0e-6 / pParam->B3SOIPDweff; Inv_LW = 1.0e-12 / (pParam->B3SOIPDleff * pParam->B3SOIPDweff); } else { Inv_L = 1.0 / pParam->B3SOIPDleff; Inv_W = 1.0 / pParam->B3SOIPDweff; Inv_LW = 1.0 / (pParam->B3SOIPDleff * pParam->B3SOIPDweff); } pParam->B3SOIPDnpeak = model->B3SOIPDnpeak + model->B3SOIPDlnpeak * Inv_L + model->B3SOIPDwnpeak * Inv_W + model->B3SOIPDpnpeak * Inv_LW; pParam->B3SOIPDnsub = model->B3SOIPDnsub + model->B3SOIPDlnsub * Inv_L + model->B3SOIPDwnsub * Inv_W + model->B3SOIPDpnsub * Inv_LW; pParam->B3SOIPDngate = model->B3SOIPDngate + model->B3SOIPDlngate * Inv_L + model->B3SOIPDwngate * Inv_W + model->B3SOIPDpngate * Inv_LW; pParam->B3SOIPDvth0 = model->B3SOIPDvth0 + model->B3SOIPDlvth0 * Inv_L + model->B3SOIPDwvth0 * Inv_W + model->B3SOIPDpvth0 * Inv_LW; pParam->B3SOIPDk1 = model->B3SOIPDk1 + model->B3SOIPDlk1 * Inv_L + model->B3SOIPDwk1 * Inv_W + model->B3SOIPDpk1 * Inv_LW; pParam->B3SOIPDk2 = model->B3SOIPDk2 + model->B3SOIPDlk2 * Inv_L + model->B3SOIPDwk2 * Inv_W + model->B3SOIPDpk2 * Inv_LW; pParam->B3SOIPDk1w1 = model->B3SOIPDk1w1 + model->B3SOIPDlk1w1 * Inv_L + model->B3SOIPDwk1w1 * Inv_W + model->B3SOIPDpk1w1 * Inv_LW; pParam->B3SOIPDk1w2 = model->B3SOIPDk1w2 + model->B3SOIPDlk1w2 * Inv_L + model->B3SOIPDwk1w2 * Inv_W + model->B3SOIPDpk1w2 * Inv_LW; pParam->B3SOIPDk3 = model->B3SOIPDk3 + model->B3SOIPDlk3 * Inv_L + model->B3SOIPDwk3 * Inv_W + model->B3SOIPDpk3 * Inv_LW; pParam->B3SOIPDk3b = model->B3SOIPDk3b + model->B3SOIPDlk3b * Inv_L + model->B3SOIPDwk3b * Inv_W + model->B3SOIPDpk3b * Inv_LW; pParam->B3SOIPDkb1 = model->B3SOIPDkb1 + model->B3SOIPDlkb1 * Inv_L + model->B3SOIPDwkb1 * Inv_W + model->B3SOIPDpkb1 * Inv_LW; pParam->B3SOIPDw0 = model->B3SOIPDw0 + model->B3SOIPDlw0 * Inv_L + model->B3SOIPDww0 * Inv_W + model->B3SOIPDpw0 * Inv_LW; pParam->B3SOIPDnlx = model->B3SOIPDnlx + model->B3SOIPDlnlx * Inv_L + model->B3SOIPDwnlx * Inv_W + model->B3SOIPDpnlx * Inv_LW; pParam->B3SOIPDdvt0 = model->B3SOIPDdvt0 + model->B3SOIPDldvt0 * Inv_L + model->B3SOIPDwdvt0 * Inv_W + model->B3SOIPDpdvt0 * Inv_LW; pParam->B3SOIPDdvt1 = model->B3SOIPDdvt1 + model->B3SOIPDldvt1 * Inv_L + model->B3SOIPDwdvt1 * Inv_W + model->B3SOIPDpdvt1 * Inv_LW; pParam->B3SOIPDdvt2 = model->B3SOIPDdvt2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -