b4noi.c

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

C
489
字号
/**** BSIM4.4.0  Released by Xuemei (Jane) Xi 03/04/2004 ****//********** * Copyright 2004 Regents of the University of California. All rights reserved. * File: b4noi.c of BSIM4.4.0. * Author: 2000 Weidong Liu * Authors: 2001- Xuemei Xi, Jin He, Kanyu Cao, Mohan Dunga, Mansun Chan, Ali Niknejad, Chenming Hu. * Project Director: Prof. Chenming Hu. * Modified by Xuemei Xi, 04/06/2001. * Modified by Xuemei Xi, 10/05/2001. * Modified by Xuemei Xi, 11/15/2002. * Modified by Xuemei Xi, 05/09/2003. * Modified by Xuemei Xi, 03/04/2004. **********/#include "ngspice.h"#include "bsim4def.h"#include "cktdefs.h"#include "iferrmsg.h"#include "noisedef.h"#include "suffix.h"#include "const.h"extern void   NevalSrc();extern double Nintegrate();/* * WDL: 1/f noise model has been smoothed out and enhanced with * bulk charge effect as well as physical N* equ. and necessary * conversion into the SI unit system. */doubleEval1ovFNoise(Vds, model, here, freq, temp)double Vds, freq, temp;BSIM4model *model;BSIM4instance *here;{struct bsim4SizeDependParam *pParam;double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq;double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;    pParam = here->pParam;    cd = fabs(here->BSIM4cd);    Leff = pParam->BSIM4leff - 2.0 * model->BSIM4lintnoi;    Leffsq = Leff * Leff;    esat = 2.0 * here->BSIM4vsattemp / here->BSIM4ueff;    if(model->BSIM4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX  */    else {    	T0 = ((((Vds - here->BSIM4Vdseff) / pParam->BSIM4litl)       		+ model->BSIM4em) / esat);    	DelClm = pParam->BSIM4litl * log (MAX(T0, N_MINLOG));    }    EffFreq = pow(freq, model->BSIM4ef);    T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4ueff;    T2 = 1.0e10 * EffFreq * here->BSIM4Abulk * model->BSIM4coxe * Leffsq;    N0 = model->BSIM4coxe * here->BSIM4Vgsteff / CHARGE;    Nl = model->BSIM4coxe * here->BSIM4Vgsteff       * (1.0 - here->BSIM4AbovVgst2Vtm * here->BSIM4Vdseff) / CHARGE;    T3 = model->BSIM4oxideTrapDensityA       * log(MAX(((N0 + here->BSIM4nstar) / (Nl + here->BSIM4nstar)), N_MINLOG));    T4 = model->BSIM4oxideTrapDensityB * (N0 - Nl);    T5 = model->BSIM4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);    T6 = CONSTboltz * temp * cd * cd;    T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4weff;    T8 = model->BSIM4oxideTrapDensityA + model->BSIM4oxideTrapDensityB * Nl       + model->BSIM4oxideTrapDensityC * Nl * Nl;    T9 = (Nl + here->BSIM4nstar) * (Nl + here->BSIM4nstar);    Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;    return Ssi;}intBSIM4noise (mode, operation, inModel, ckt, data, OnDens)int mode, operation;GENmodel *inModel;CKTcircuit *ckt;Ndata *data;double *OnDens;{BSIM4model *model = (BSIM4model *)inModel;BSIM4instance *here;struct bsim4SizeDependParam *pParam;char name[N_MXVLNTH];double tempOnoise;double tempInoise;double noizDens[BSIM4NSRCS];double lnNdens[BSIM4NSRCS];double T0, T1, T2, T5, T10, T11;double Vds, Ssi, Swi;double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare;double m;int i;    /* define the names of the noise sources */    static char *BSIM4nNames[BSIM4NSRCS] =    {   /* Note that we have to keep the order */	".rd",              /* noise due to rd */	".rs",              /* noise due to rs */        ".rg",              /* noise due to rgeltd */        ".rbps",            /* noise due to rbps */        ".rbpd",            /* noise due to rbpd */        ".rbpb",            /* noise due to rbpb */        ".rbsb",            /* noise due to rbsb */        ".rbdb",            /* noise due to rbdb */	".id",              /* noise due to id */	".1overf",          /* flicker (1/f) noise */        ".igs",             /* shot noise due to IGS */        ".igd",             /* shot noise due to IGD */        ".igb",             /* shot noise due to IGB */	""                  /* total transistor noise */    };    for (; model != NULL; model = model->BSIM4nextModel)    {    for (here = model->BSIM4instances; here != NULL;	      here = here->BSIM4nextInstance)	 {    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 < BSIM4NSRCS; i++)				  {    (void) sprintf(name, "onoise.%s%s",					              here->BSIM4name,						      BSIM4nNames[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 < BSIM4NSRCS; i++)				  {    (void) sprintf(name, "onoise_total.%s%s",						      here->BSIM4name,						      BSIM4nNames[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 */			               (void) sprintf(name, "inoise_total.%s%s",						      here->BSIM4name,						      BSIM4nNames[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;		          }		      }		      break;	         case N_CALC:		      m = here->BSIM4m;		      switch (mode)		      {  case N_DENS:			      if (model->BSIM4tnoiMod == 0)			      {   if (model->BSIM4rdsMod == 0)				  {   gspr = here->BSIM4sourceConductance;                                      gdpr = here->BSIM4drainConductance;				      if (here->BSIM4grdsw > 0.0)				          tmp = 1.0 / here->BSIM4grdsw; /* tmp used below */ 				      else					  tmp = 0.0;				  }				  else				  {   gspr = here->BSIM4gstot;                                      gdpr = here->BSIM4gdtot;                                      tmp = 0.0;				  }			      }			      else			      {   T5 = here->BSIM4Vgsteff / here->BSIM4EsatL;				  T5 *= T5;				  npart_beta = model->BSIM4rnoia * (1.0 + T5					     * model->BSIM4tnoia * pParam->BSIM4leff);				  npart_theta = model->BSIM4rnoib * (1.0 + T5                                              * model->BSIM4tnoib * pParam->BSIM4leff);				  if (model->BSIM4rdsMod == 0)                                  {   gspr = here->BSIM4sourceConductance;                                      gdpr = here->BSIM4drainConductance;                                  }                                  else                                  {   gspr = here->BSIM4gstot;                                      gdpr = here->BSIM4gdtot;                                  }				  if ((*(ckt->CKTstates[0] + here->BSIM4vds)) >= 0.0)			              gspr = gspr / (1.0 + npart_theta * npart_theta * gspr				 	   / here->BSIM4IdovVds);  /* bugfix */				  else				      gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr                                           / here->BSIM4IdovVds);			      } 		              NevalSrc(&noizDens[BSIM4RDNOIZ],				       &lnNdens[BSIM4RDNOIZ], ckt, THERMNOISE,				       here->BSIM4dNodePrime, here->BSIM4dNode,				       gdpr * m);		              NevalSrc(&noizDens[BSIM4RSNOIZ],				       &lnNdens[BSIM4RSNOIZ], ckt, THERMNOISE,				       here->BSIM4sNodePrime, here->BSIM4sNode,				       gspr * m);			      if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2))			      {   NevalSrc(&noizDens[BSIM4RGNOIZ],                                       &lnNdens[BSIM4RGNOIZ], ckt, THERMNOISE,                                       here->BSIM4gNodePrime, here->BSIM4gNodeExt,                                       here->BSIM4grgeltd * m);

⌨️ 快捷键说明

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