b3noi.c

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

C
506
字号
/**** BSIM3v3.2.4, Released by Xuemei Xi 12/21/2001 ****//********** * Copyright 2001 Regents of the University of California. All rights reserved. * File: b3noi.c of BSIM3v3.2.4 * Author: 1995 Gary W. Ng and Min-Chie Jeng. * Author: 1997-1999 Weidong Liu. * Author: 2001 Xuemei Xi * Modified by Xuemei Xi, 10/05, 12/21, 2001. * Modified bt Paolo Nenzi 2002 and Dietmar Warning 2003 **********/#include "ngspice.h"#include "bsim3def.h"#include "cktdefs.h"#include "iferrmsg.h"#include "noisedef.h"#include "suffix.h"#include "const.h"  /* jwan *//* * BSIM3noise (mode, operation, firstModel, ckt, data, OnDens) *    This routine names and evaluates all of the noise sources *    associated with MOSFET's.  It starts with the model *firstModel and *    traverses all of its insts.  It then proceeds to any other models *    on the linked list.  The total output noise density generated by *    all of the MOSFET's is summed with the variable "OnDens". *//* Channel thermal and flicker noises are calculated based on the value of model->BSIM3noiMod. If model->BSIM3noiMod = 1,    Channel thermal noise = SPICE2 model    Flicker noise         = SPICE2 model If model->BSIM3noiMod = 2,    Channel thermal noise = BSIM3 model    Flicker noise         = BSIM3 model If model->BSIM3noiMod = 3,    Channel thermal noise = SPICE2 model    Flicker noise         = BSIM3 model If model->BSIM3noiMod = 4,    Channel thermal noise = BSIM3 model    Flicker noise         = SPICE2 model */extern void   NevalSrc();extern double Nintegrate();/*  * The StrongInversionNoiseEval function has been modified in * the release 3.2.4 of BSIM3 model. To accomodate both the old * and the new code, I have renamed according to the following: * * * BSIM3v3.2.4 -> StrongInversionNoiseEvalNew * Previous    -> StrongInversionNoiseEvalOld * * 2002 Paolo Nenzi *//* * JX: 1/f noise model is smoothed out 12/18/01. */doubleStrongInversionNoiseEvalNew(double Vds, BSIM3model *model,			    BSIM3instance *here, double freq, double temp){struct bsim3SizeDependParam *pParam;double cd, esat, DelClm, EffFreq, N0, Nl;double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;    pParam = here->pParam;    cd = fabs(here->BSIM3cd);    esat = 2.0 * pParam->BSIM3vsattemp / here->BSIM3ueff;    if(model->BSIM3em<=0.0) DelClm = 0.0;     else { 	    T0 = ((((Vds - here->BSIM3Vdseff) / pParam->BSIM3litl) 	    	+ model->BSIM3em) / esat);            DelClm = pParam->BSIM3litl * log (MAX(T0, N_MINLOG));    }    EffFreq = pow(freq, model->BSIM3ef);    T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->BSIM3ueff;    T2 = 1.0e8 * EffFreq * here->BSIM3Abulk * model->BSIM3cox       * pParam->BSIM3leff * pParam->BSIM3leff;    N0 = model->BSIM3cox * here->BSIM3Vgsteff / CHARGE;    Nl = model->BSIM3cox * here->BSIM3Vgsteff    	  * (1.0 - here->BSIM3AbovVgst2Vtm * here->BSIM3Vdseff) / CHARGE;    T3 = model->BSIM3oxideTrapDensityA       * log(MAX(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG));    T4 = model->BSIM3oxideTrapDensityB * (N0 - Nl);    T5 = model->BSIM3oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);    T6 = 8.62e-5 * temp * cd * cd;    T7 = 1.0e8 * EffFreq * pParam->BSIM3leff       * pParam->BSIM3leff * pParam->BSIM3weff;    T8 = model->BSIM3oxideTrapDensityA + model->BSIM3oxideTrapDensityB * Nl       + model->BSIM3oxideTrapDensityC * Nl * Nl;    T9 = (Nl + 2.0e14) * (Nl + 2.0e14);    Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;    return Ssi;}/* * The code for releases: BSIM3V32, BSIM3V322, BSIM3V323 * follows */doubleStrongInversionNoiseEvalOld(double vgs, double vds, BSIM3model *model,			    BSIM3instance *here, double freq, double temp){  struct bsim3SizeDependParam *pParam;  double cd, esat, DelClm, EffFreq, N0, Nl, Vgst;  double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;  pParam = here->pParam;  cd = fabs (here->BSIM3cd);  /* Added revision dependent code */  if (model->BSIM3intVersion < BSIM3V323)  {    if (vds > here->BSIM3vdsat)    {      esat = 2.0 * pParam->BSIM3vsattemp / here->BSIM3ueff;      T0 = ((((vds - here->BSIM3vdsat) / pParam->BSIM3litl) +  	   model->BSIM3em) / esat);      DelClm = pParam->BSIM3litl * log (MAX (T0, N_MINLOG));    }    else      DelClm = 0.0;  }  else  {    if (model->BSIM3em <= 0.0)	/* flicker noise modified -JX */      DelClm = 0.0;    else if (vds > here->BSIM3vdsat)    {      esat = 2.0 * pParam->BSIM3vsattemp / here->BSIM3ueff;      T0 = ((((vds - here->BSIM3vdsat) / pParam->BSIM3litl) +  	   model->BSIM3em) / esat);      DelClm = pParam->BSIM3litl * log (MAX (T0, N_MINLOG));    }    else      DelClm = 0.0;  }  EffFreq = pow (freq, model->BSIM3ef);  T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->BSIM3ueff;  T2 = 1.0e8 * EffFreq * model->BSIM3cox     * pParam->BSIM3leff * pParam->BSIM3leff;  Vgst = vgs - here->BSIM3von;  N0 = model->BSIM3cox * Vgst / CHARGE;  if (N0 < 0.0)      N0 = 0.0;  Nl = model->BSIM3cox * (Vgst - MIN (vds, here->BSIM3vdsat)) / CHARGE;  if (Nl < 0.0)      Nl = 0.0;  T3 = model->BSIM3oxideTrapDensityA     * log (MAX (((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG));  T4 = model->BSIM3oxideTrapDensityB * (N0 - Nl);  T5 = model->BSIM3oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);  T6 = 8.62e-5 * temp * cd * cd;  T7 = 1.0e8 * EffFreq * pParam->BSIM3leff     * pParam->BSIM3leff * pParam->BSIM3weff;  T8 = model->BSIM3oxideTrapDensityA + model->BSIM3oxideTrapDensityB * Nl     + model->BSIM3oxideTrapDensityC * Nl * Nl;  T9 = (Nl + 2.0e14) * (Nl + 2.0e14);  Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;  return Ssi;}intBSIM3noise (int mode, int operation, GENmodel *inModel, CKTcircuit *ckt,	    Ndata *data, double *OnDens){BSIM3model *model = (BSIM3model *)inModel;BSIM3instance *here;struct bsim3SizeDependParam *pParam;char name[N_MXVLNTH];double tempOnoise;double tempInoise;double noizDens[BSIM3NSRCS];double lnNdens[BSIM3NSRCS];double vgs, vds, Slimit;double T1, T10, T11;double Ssi, Swi;double m;int i;    /* define the names of the noise sources */    static char *BSIM3nNames[BSIM3NSRCS] =    {   /* Note that we have to keep the order */	".rd",              /* noise due to rd */			    /* consistent with the index definitions */	".rs",              /* noise due to rs */			    /* in BSIM3defs.h */	".id",              /* noise due to id */	".1overf",          /* flicker (1/f) noise */	""                  /* total transistor noise */    };    for (; model != NULL; model = model->BSIM3nextModel)    {    for (here = model->BSIM3instances; here != NULL;	      here = here->BSIM3nextInstance)	 {    pParam = here->pParam;	      switch (operation)	      {  case N_OPEN:		     /* see if we have to to produce a summary report */		     /* if so, name all the noise generators */		      if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0)		      {   switch (mode)			  {  case N_DENS:			          for (i = 0; i < BSIM3NSRCS; i++)				  {    (void) sprintf(name, "onoise.%s%s",					              here->BSIM3name,						      BSIM3nNames[i]);                                       data->namelist = (IFuid *) trealloc(					     (char *) data->namelist,					     (data->numPlots + 1)					     * sizeof(IFuid));                                       if (!data->namelist)					   return(E_NOMEM);		                       (*(SPfrontEnd->IFnewUid)) (ckt,			                  &(data->namelist[data->numPlots++]),			                  (IFuid) NULL, name, UID_OTHER,					  (void **) NULL);				       /* we've added one more plot */			          }			          break;		             case INT_NOIZ:			          for (i = 0; i < BSIM3NSRCS; i++)				  {    (void) sprintf(name, "onoise_total.%s%s",						      here->BSIM3name,						      BSIM3nNames[i]);                                       data->namelist = (IFuid *) trealloc(					     (char *) data->namelist,					     (data->numPlots + 1)					     * sizeof(IFuid));                                       if (!data->namelist)					   return(E_NOMEM);		                       (*(SPfrontEnd->IFnewUid)) (ckt,			                  &(data->namelist[data->numPlots++]),

⌨️ 快捷键说明

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