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