b3temp.c

来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 1,044 行 · 第 1/3 页

C
1,044
字号
/**** BSIM3v3.2.4, Released by Xuemei Xi 12/21/2001 ****//********** * Copyright 2001 Regents of the University of California. All rights reserved. * File: b3temp.c of BSIM3v3.2.4 * Author: 1995 Min-Chie Jeng and Mansun Chan.  * Author: 1997-1999 Weidong Liu. * Author: 2001  Xuemei Xi * Modified by Paolo Nenzi 2002 and Dietmar Warning 2003 **********/#include "ngspice.h"#include "smpdefs.h"#include "cktdefs.h"#include "bsim3def.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 MAX_EXP 5.834617425e14#define MIN_EXP 1.713908431e-15#define EXP_THRESHOLD 34.0#define Charge_q 1.60219e-19/* ARGSUSED */intBSIM3temp (GENmodel *inModel, CKTcircuit *ckt){BSIM3model *model = (BSIM3model*) inModel;BSIM3instance *here;struct bsim3SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam;double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom;double Nvtm, SourceSatCurrent, DrainSatCurrent;int Size_Not_Found;    /*  loop through all the BSIM3 device models */    for (; model != NULL; model = model->BSIM3nextModel)    {    Temp = ckt->CKTtemp;         if (model->BSIM3bulkJctPotential < 0.1)  	 {   model->BSIM3bulkJctPotential = 0.1;	     fprintf(stderr, "Given pb is less than 0.1. Pb is set to 0.1.\n");	 }         if (model->BSIM3sidewallJctPotential < 0.1)	 {   model->BSIM3sidewallJctPotential = 0.1;	     fprintf(stderr, "Given pbsw is less than 0.1. Pbsw is set to 0.1.\n");	 }         if (model->BSIM3GatesidewallJctPotential < 0.1)	 {   model->BSIM3GatesidewallJctPotential = 0.1;	     fprintf(stderr, "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n");	 }	 /* va: was memory leakage - free old node, (or better use again?) */	 FREE(model->pSizeDependParamKnot);         model->pSizeDependParamKnot = NULL;	 pLastKnot = NULL;	 Tnom = model->BSIM3tnom;	 TRatio = Temp / Tnom;	 model->BSIM3vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14));         model->BSIM3factor1 = sqrt(EPSSI / EPSOX * model->BSIM3tox);         Vtm0 = KboQ * Tnom;         Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0);         ni = 1.45e10 * (Tnom / 300.15) * sqrt(Tnom / 300.15)             * exp(21.5565981 - Eg0 / (2.0 * Vtm0));         model->BSIM3vtm = KboQ * Temp;         Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0);	 if (Temp != Tnom)	 {   T0 = Eg0 / Vtm0 - Eg / model->BSIM3vtm + model->BSIM3jctTempExponent		* log(Temp / Tnom);	     T1 = exp(T0 / model->BSIM3jctEmissionCoeff);	     model->BSIM3jctTempSatCurDensity = model->BSIM3jctSatCurDensity					      * T1;	     model->BSIM3jctSidewallTempSatCurDensity			 = model->BSIM3jctSidewallSatCurDensity * T1;	 }	 else	 {   model->BSIM3jctTempSatCurDensity = model->BSIM3jctSatCurDensity;	     model->BSIM3jctSidewallTempSatCurDensity			= model->BSIM3jctSidewallSatCurDensity;	 }	 if (model->BSIM3jctTempSatCurDensity < 0.0)	     model->BSIM3jctTempSatCurDensity = 0.0;	 if (model->BSIM3jctSidewallTempSatCurDensity < 0.0)	     model->BSIM3jctSidewallTempSatCurDensity = 0.0;	 /* Temperature dependence of D/B and S/B diode capacitance begins */	 delTemp = ckt->CKTtemp - model->BSIM3tnom;	 T0 = model->BSIM3tcj * delTemp;	 if (T0 >= -1.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitAreaTempJctCap =				model->BSIM3unitAreaJctCap * (1.0 + T0);			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitAreaJctCap *= 1.0 + T0;		}	 }	 else if (model->BSIM3unitAreaJctCap > 0.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitAreaTempJctCap = 0.0;			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitAreaJctCap = 0.0;		}	     fprintf(stderr, "Temperature effect has caused cj to be negative. Cj is clamped to zero.\n");	 }         T0 = model->BSIM3tcjsw * delTemp;	 if (T0 >= -1.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitLengthSidewallTempJctCap =				model->BSIM3unitLengthSidewallJctCap * (1.0 + T0);			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitLengthSidewallJctCap *= 1.0 + T0;		}	 }	 else if (model->BSIM3unitLengthSidewallJctCap > 0.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitLengthSidewallTempJctCap = 0.0;			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitLengthSidewallJctCap = 0.0;		}	     fprintf(stderr, "Temperature effect has caused cjsw to be negative. Cjsw is clamped to zero.\n");	 }         T0 = model->BSIM3tcjswg * delTemp;	 if (T0 >= -1.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitLengthGateSidewallTempJctCap =				model->BSIM3unitLengthGateSidewallJctCap * (1.0 + T0);			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitLengthGateSidewallJctCap *= 1.0 + T0;		}	 }	 else if (model->BSIM3unitLengthGateSidewallJctCap > 0.0)	 {   		/* Added revision dependent code */		switch (model->BSIM3intVersion) {		case BSIM3V324:		case BSIM3V323:			model->BSIM3unitLengthGateSidewallTempJctCap = 0.0;			break;		case BSIM3V322:		case BSIM3V32:		default:			model->BSIM3unitLengthGateSidewallJctCap = 0.0;		}	     fprintf(stderr, "Temperature effect has caused cjswg to be negative. Cjswg is clamped to zero.\n");	 }         model->BSIM3PhiB = model->BSIM3bulkJctPotential			  - model->BSIM3tpb * delTemp;         if (model->BSIM3PhiB < 0.01)	 {   model->BSIM3PhiB = 0.01;	     fprintf(stderr, "Temperature effect has caused pb to be less than 0.01. Pb is clamped to 0.01.\n");	 }         model->BSIM3PhiBSW = model->BSIM3sidewallJctPotential                            - model->BSIM3tpbsw * delTemp;         if (model->BSIM3PhiBSW <= 0.01)	 {   model->BSIM3PhiBSW = 0.01;	     fprintf(stderr, "Temperature effect has caused pbsw to be less than 0.01. Pbsw is clamped to 0.01.\n");	 }	 model->BSIM3PhiBSWG = model->BSIM3GatesidewallJctPotential                             - model->BSIM3tpbswg * delTemp;         if (model->BSIM3PhiBSWG <= 0.01)	 {   model->BSIM3PhiBSWG = 0.01;	     fprintf(stderr, "Temperature effect has caused pbswg to be less than 0.01. Pbswg is clamped to 0.01.\n");	 }         /* End of junction capacitance */         /* loop through all the instances of the model */	 /* MCJ: Length and Width not initialized */         for (here = model->BSIM3instances; here != NULL;              here = here->BSIM3nextInstance) 	 {    	      if (here->BSIM3owner != ARCHme) continue;	      pSizeDependParamKnot = model->pSizeDependParamKnot;	      Size_Not_Found = 1;	      while ((pSizeDependParamKnot != NULL) && Size_Not_Found)	      {   if ((here->BSIM3l == pSizeDependParamKnot->Length)		      && (here->BSIM3w == pSizeDependParamKnot->Width))                  {   Size_Not_Found = 0;		      here->pParam = pSizeDependParamKnot;		      if (model->BSIM3intVersion > BSIM3V322)                      {		        pParam = here->pParam; /*bug-fix  */		      }		  }		  else		  {   pLastKnot = pSizeDependParamKnot;		      pSizeDependParamKnot = pSizeDependParamKnot->pNext;		  }              }	      if (Size_Not_Found)	      {   pParam = (struct bsim3SizeDependParam *)malloc(	                    sizeof(struct bsim3SizeDependParam));                  if (pLastKnot == NULL)		      model->pSizeDependParamKnot = pParam;                  else		      pLastKnot->pNext = pParam;                  pParam->pNext = NULL;                  here->pParam = pParam;		  Ldrn = here->BSIM3l;		  Wdrn = here->BSIM3w;                  pParam->Length = Ldrn;                  pParam->Width = Wdrn;		                    T0 = pow(Ldrn, model->BSIM3Lln);                  T1 = pow(Wdrn, model->BSIM3Lwn);                  tmp1 = model->BSIM3Ll / T0 + model->BSIM3Lw / T1                       + model->BSIM3Lwl / (T0 * T1);                  pParam->BSIM3dl = model->BSIM3Lint + tmp1;                  tmp2 = model->BSIM3Llc / T0 + model->BSIM3Lwc / T1                       + model->BSIM3Lwlc / (T0 * T1);                  pParam->BSIM3dlc = model->BSIM3dlc + tmp2;                  T2 = pow(Ldrn, model->BSIM3Wln);                  T3 = pow(Wdrn, model->BSIM3Wwn);                  tmp1 = model->BSIM3Wl / T2 + model->BSIM3Ww / T3                       + model->BSIM3Wwl / (T2 * T3);                  pParam->BSIM3dw = model->BSIM3Wint + tmp1;                  tmp2 = model->BSIM3Wlc / T2 + model->BSIM3Wwc / T3                       + model->BSIM3Wwlc / (T2 * T3);                  pParam->BSIM3dwc = model->BSIM3dwc + tmp2;                  pParam->BSIM3leff = here->BSIM3l + model->BSIM3xl - 2.0 * pParam->BSIM3dl;                  if (pParam->BSIM3leff <= 0.0)	          {   IFuid namarray[2];                      namarray[0] = model->BSIM3modName;                      namarray[1] = here->BSIM3name;                      (*(SPfrontEnd->IFerror))(ERR_FATAL,                      "BSIM3: mosfet %s, model %s: Effective channel length <= 0",                       namarray);                      return(E_BADPARM);                  }                  pParam->BSIM3weff = here->BSIM3w + model->BSIM3xw - 2.0 * pParam->BSIM3dw;                  if (pParam->BSIM3weff <= 0.0)	          {   IFuid namarray[2];                      namarray[0] = model->BSIM3modName;                      namarray[1] = here->BSIM3name;                      (*(SPfrontEnd->IFerror))(ERR_FATAL,                      "BSIM3: mosfet %s, model %s: Effective channel width <= 0",                       namarray);                      return(E_BADPARM);                  }                  pParam->BSIM3leffCV = here->BSIM3l + model->BSIM3xl - 2.0 * pParam->BSIM3dlc;                  if (pParam->BSIM3leffCV <= 0.0)	          {   IFuid namarray[2];                      namarray[0] = model->BSIM3modName;                      namarray[1] = here->BSIM3name;                      (*(SPfrontEnd->IFerror))(ERR_FATAL,                      "BSIM3: mosfet %s, model %s: Effective channel length for C-V <= 0",                       namarray);                      return(E_BADPARM);                  }                  pParam->BSIM3weffCV = here->BSIM3w + model->BSIM3xw - 2.0 * pParam->BSIM3dwc;                  if (pParam->BSIM3weffCV <= 0.0)	          {   IFuid namarray[2];                      namarray[0] = model->BSIM3modName;                      namarray[1] = here->BSIM3name;                      (*(SPfrontEnd->IFerror))(ERR_FATAL,                      "BSIM3: mosfet %s, model %s: Effective channel width for C-V <= 0",                       namarray);                      return(E_BADPARM);                  }		  if (model->BSIM3binUnit == 1)		  {   Inv_L = 1.0e-6 / pParam->BSIM3leff;		      Inv_W = 1.0e-6 / pParam->BSIM3weff;		      Inv_LW = 1.0e-12 / (pParam->BSIM3leff			     * pParam->BSIM3weff);		  }		  else		  {   Inv_L = 1.0 / pParam->BSIM3leff;		      Inv_W = 1.0 / pParam->BSIM3weff;		      Inv_LW = 1.0 / (pParam->BSIM3leff			     * pParam->BSIM3weff);		  }		  pParam->BSIM3cdsc = model->BSIM3cdsc				    + model->BSIM3lcdsc * Inv_L				    + model->BSIM3wcdsc * Inv_W				    + model->BSIM3pcdsc * Inv_LW;		  pParam->BSIM3cdscb = model->BSIM3cdscb				     + model->BSIM3lcdscb * Inv_L				     + model->BSIM3wcdscb * Inv_W				     + model->BSIM3pcdscb * Inv_LW; 				         		  pParam->BSIM3cdscd = model->BSIM3cdscd				     + model->BSIM3lcdscd * Inv_L				     + model->BSIM3wcdscd * Inv_W				     + model->BSIM3pcdscd * Inv_LW; 				     		  pParam->BSIM3cit = model->BSIM3cit				   + model->BSIM3lcit * Inv_L				   + model->BSIM3wcit * Inv_W				   + model->BSIM3pcit * Inv_LW;		  pParam->BSIM3nfactor = model->BSIM3nfactor				       + model->BSIM3lnfactor * Inv_L				       + model->BSIM3wnfactor * Inv_W				       + model->BSIM3pnfactor * Inv_LW;		  pParam->BSIM3xj = model->BSIM3xj

⌨️ 快捷键说明

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