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 + -
显示快捷键?