1 /**** BSIM4.7.0 Released by Darsen Lu 04/08/2011 ****/
2 
3 /**********
4  * Copyright 2006 Regents of the University of California. All rights reserved.
5  * File: b4noi.c of BSIM4.7.0.
6  * Author: 2000 Weidong Liu
7  * Authors: 2001- Xuemei Xi, Mohan Dunga, Ali Niknejad, Chenming Hu.
8  * Authors: 2006- Mohan Dunga, Ali Niknejad, Chenming Hu
9  * Authors: 2007- Mohan Dunga, Wenwei Yang, Ali Niknejad, Chenming Hu
10   * Authors: 2008- Wenwei Yang,  Ali Niknejad, Chenming Hu
11  * Project Director: Prof. Chenming Hu.
12  * Modified by Xuemei Xi, 04/06/2001.
13  * Modified by Xuemei Xi, 10/05/2001.
14  * Modified by Xuemei Xi, 05/09/2003.
15  * Modified by Xuemei Xi, 03/04/2004.
16  * Modified by Xuemei Xi, 07/29/2005.
17  * Modified by Mohan Dunga, 12/13/2006
18  * Modified by Wenwei Yang, 07/31/2008.
19  * Modified by Tanvir Morshed, Darsen Lu 03/27/2011
20  **********/
21 
22 #include "ngspice/ngspice.h"
23 #include "bsim4v7def.h"
24 #include "ngspice/cktdefs.h"
25 #include "ngspice/iferrmsg.h"
26 #include "ngspice/noisedef.h"
27 #include "ngspice/suffix.h"
28 #include "ngspice/const.h"
29 
30 
31 /*
32  * WDL: 1/f noise model has been smoothed out and enhanced with
33  * bulk charge effect as well as physical N* equ. and necessary
34  * conversion into the SI unit system.
35  */
36 
37 static double
Eval1ovFNoise(double Vds,BSIM4v7model * model,BSIM4v7instance * here,double freq,double temp)38 Eval1ovFNoise(
39 double Vds,
40 BSIM4v7model *model,
41 BSIM4v7instance *here,
42 double freq, double temp)
43 {
44 struct bsim4SizeDependParam *pParam;
45 double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq;
46 double T0=0.0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi;
47 
48     pParam = here->pParam;
49     cd = fabs(here->BSIM4v7cd);
50     Leff = pParam->BSIM4v7leff - 2.0 * model->BSIM4v7lintnoi;
51     Leffsq = Leff * Leff;
52     esat = 2.0 * here->BSIM4v7vsattemp / here->BSIM4v7ueff;
53     if(model->BSIM4v7em<=0.0) DelClm = 0.0; /* flicker noise modified -JX  */
54     else {
55             T0 = ((((Vds - here->BSIM4v7Vdseff) / pParam->BSIM4v7litl)
56                        + model->BSIM4v7em) / esat);
57             DelClm = pParam->BSIM4v7litl * log (MAX(T0, N_MINLOG));
58             if (DelClm < 0.0)        DelClm = 0.0;  /* bugfix */
59     }
60     EffFreq = pow(freq, model->BSIM4v7ef);
61     T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4v7ueff;
62     T2 = 1.0e10 * EffFreq * here->BSIM4v7Abulk * model->BSIM4v7coxe * Leffsq;
63     N0 = model->BSIM4v7coxe * here->BSIM4v7Vgsteff / CHARGE;
64     Nl = model->BSIM4v7coxe * here->BSIM4v7Vgsteff
65        * (1.0 - here->BSIM4v7AbovVgst2Vtm * here->BSIM4v7Vdseff) / CHARGE;
66 
67     T3 = model->BSIM4v7oxideTrapDensityA
68        * log(MAX(((N0 + here->BSIM4v7nstar) / (Nl + here->BSIM4v7nstar)), N_MINLOG));
69     T4 = model->BSIM4v7oxideTrapDensityB * (N0 - Nl);
70     T5 = model->BSIM4v7oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
71 
72     T6 = CONSTboltz * temp * cd * cd;
73     T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4v7weff * here->BSIM4v7nf;
74     T8 = model->BSIM4v7oxideTrapDensityA + model->BSIM4v7oxideTrapDensityB * Nl
75        + model->BSIM4v7oxideTrapDensityC * Nl * Nl;
76     T9 = (Nl + here->BSIM4v7nstar) * (Nl + here->BSIM4v7nstar);
77     Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
78     return Ssi;
79 }
80 
81 
82 int
BSIM4v7noise(int mode,int operation,GENmodel * inModel,CKTcircuit * ckt,Ndata * data,double * OnDens)83 BSIM4v7noise (
84 int mode, int operation,
85 GENmodel *inModel,
86 CKTcircuit *ckt,
87 Ndata *data,
88 double *OnDens)
89 {
90 NOISEAN *job = (NOISEAN *) ckt->CKTcurJob;
91 
92 BSIM4v7model *model = (BSIM4v7model *)inModel;
93 BSIM4v7instance *here;
94 struct bsim4SizeDependParam *pParam;
95 double tempOnoise;
96 double tempInoise;
97 double noizDens[BSIM4v7NSRCS];
98 double lnNdens[BSIM4v7NSRCS];
99 
100 double T0, T1, T2, T3, T4, T5, T6, T7, T8, T10, T11;
101 double Vds, Ssi, Swi;
102 double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode;
103 
104 /* tnoiMod=2 (v4.7) */
105 double eta, Leff, Lvsat, gamma, delta, epsilon, GammaGd0=0.0;
106 double npart_c, sigrat=0.0, C0, omega, ctnoi=0.0;
107 
108 int i;
109 
110 double m;
111 
112     /* define the names of the noise sources */
113     static char *BSIM4v7nNames[BSIM4v7NSRCS] =
114     {   /* Note that we have to keep the order */
115         ".rd",              /* noise due to rd */
116         ".rs",              /* noise due to rs */
117         ".rg",              /* noise due to rgeltd */
118         ".rbps",            /* noise due to rbps */
119         ".rbpd",            /* noise due to rbpd */
120         ".rbpb",            /* noise due to rbpb */
121         ".rbsb",            /* noise due to rbsb */
122         ".rbdb",            /* noise due to rbdb */
123         ".id",              /* noise due to id (for tnoiMod2: uncorrelated portion only) */
124         ".1overf",          /* flicker (1/f) noise */
125         ".igs",             /* shot noise due to IGS */
126         ".igd",             /* shot noise due to IGD */
127         ".igb",             /* shot noise due to IGB */
128         ".corl",            /* contribution of correlated drain and induced gate noise */
129         ""                  /* total transistor noise */
130     };
131 
132     for (; model != NULL; model = BSIM4v7nextModel(model))
133     {
134          if(model->BSIM4v7tnoiMod != 2) {
135              noizDens[BSIM4v7CORLNOIZ] = 0.0;
136              lnNdens[BSIM4v7CORLNOIZ] = N_MINLOG;
137          }
138          for (here = BSIM4v7instances(model); here != NULL;
139               here = BSIM4v7nextInstance(here))
140          {    pParam = here->pParam;
141               switch (operation)
142               {  case N_OPEN:
143                      /* see if we have to to produce a summary report */
144                      /* if so, name all the noise generators */
145 
146                       if (job->NStpsSm != 0)
147                       {   switch (mode)
148                           {  case N_DENS:
149                                   for (i = 0; i < BSIM4v7NSRCS; i++)
150                                   {    NOISE_ADD_OUTVAR(ckt, data, "onoise.%s%s", here->BSIM4v7name, BSIM4v7nNames[i]);
151                                   }
152                                   break;
153                              case INT_NOIZ:
154                                   for (i = 0; i < BSIM4v7NSRCS; i++)
155                                   {    NOISE_ADD_OUTVAR(ckt, data, "onoise_total.%s%s", here->BSIM4v7name, BSIM4v7nNames[i]);
156                                        NOISE_ADD_OUTVAR(ckt, data, "inoise_total.%s%s", here->BSIM4v7name, BSIM4v7nNames[i]);
157                                   }
158                                   break;
159                           }
160                       }
161                       break;
162                  case N_CALC:
163                       m = here->BSIM4v7m;
164                       switch (mode)
165                       {  case N_DENS:
166                               if (model->BSIM4v7tnoiMod == 0)
167                               {   if (model->BSIM4v7rdsMod == 0)
168                                   {   gspr = here->BSIM4v7sourceConductance;
169                                       gdpr = here->BSIM4v7drainConductance;
170                                       if (here->BSIM4v7grdsw > 0.0)
171                                           tmp = 1.0 / here->BSIM4v7grdsw; /* tmp used below */
172                                       else
173                                           tmp = 0.0;
174                                   }
175                                   else
176                                   {   gspr = here->BSIM4v7gstot;
177                                       gdpr = here->BSIM4v7gdtot;
178                                       tmp = 0.0;
179                                   }
180                               }
181                               else if(model->BSIM4v7tnoiMod == 1)
182                               {   T5 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
183                                   T5 *= T5;
184                                   npart_beta = model->BSIM4v7rnoia * (1.0 + T5
185                                              * model->BSIM4v7tnoia * pParam->BSIM4v7leff);
186                                   npart_theta = model->BSIM4v7rnoib * (1.0 + T5
187                                               * model->BSIM4v7tnoib * pParam->BSIM4v7leff);
188                                   if(npart_theta > 0.9)
189                                      npart_theta = 0.9;
190                                   if(npart_theta > 0.9 * npart_beta)
191                                      npart_theta = 0.9 * npart_beta; //4.6.2
192 
193                                   if (model->BSIM4v7rdsMod == 0)
194                                   {   gspr = here->BSIM4v7sourceConductance;
195                                       gdpr = here->BSIM4v7drainConductance;
196                                   }
197                                   else
198                                   {   gspr = here->BSIM4v7gstot;
199                                       gdpr = here->BSIM4v7gdtot;
200                                   }
201 
202                                   if ((*(ckt->CKTstates[0] + here->BSIM4v7vds)) >= 0.0)
203                                       gspr = gspr * (1.0 + npart_theta * npart_theta * gspr
204                                            / here->BSIM4v7IdovVds);
205                                   else
206                                       gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr
207                                            / here->BSIM4v7IdovVds);
208                               }
209                               else
210                               {   /* tnoiMod=2 (v4.7) */
211 
212                                   if (model->BSIM4v7rdsMod == 0)
213                                   {   gspr = here->BSIM4v7sourceConductance;
214                                       gdpr = here->BSIM4v7drainConductance;
215                                   }
216                                   else
217                                   {   gspr = here->BSIM4v7gstot;
218                                       gdpr = here->BSIM4v7gdtot;
219                                   }
220 
221                               }
222 
223                               NevalSrc(&noizDens[BSIM4v7RDNOIZ],
224                                        &lnNdens[BSIM4v7RDNOIZ], ckt, THERMNOISE,
225                                        here->BSIM4v7dNodePrime, here->BSIM4v7dNode,
226                                        gdpr * m);
227 
228                               NevalSrc(&noizDens[BSIM4v7RSNOIZ],
229                                        &lnNdens[BSIM4v7RSNOIZ], ckt, THERMNOISE,
230                                        here->BSIM4v7sNodePrime, here->BSIM4v7sNode,
231                                        gspr * m);
232 
233 
234                               if (here->BSIM4v7rgateMod == 1)
235                               {   NevalSrc(&noizDens[BSIM4v7RGNOIZ],
236                                        &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
237                                        here->BSIM4v7gNodePrime, here->BSIM4v7gNodeExt,
238                                        here->BSIM4v7grgeltd * m);
239                               }
240                               else if (here->BSIM4v7rgateMod == 2)
241                               {
242                                 T0 = 1.0 + here->BSIM4v7grgeltd/here->BSIM4v7gcrg;
243                                 T1 = T0 * T0;
244                                   NevalSrc(&noizDens[BSIM4v7RGNOIZ],
245                                        &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
246                                        here->BSIM4v7gNodePrime, here->BSIM4v7gNodeExt,
247                                        here->BSIM4v7grgeltd * m / T1);
248                               }
249                               else if (here->BSIM4v7rgateMod == 3)
250                               {   NevalSrc(&noizDens[BSIM4v7RGNOIZ],
251                                        &lnNdens[BSIM4v7RGNOIZ], ckt, THERMNOISE,
252                                        here->BSIM4v7gNodeMid, here->BSIM4v7gNodeExt,
253                                        here->BSIM4v7grgeltd * m);
254                               }
255                               else
256                               {    noizDens[BSIM4v7RGNOIZ] = 0.0;
257                                    lnNdens[BSIM4v7RGNOIZ] =
258                                           log(MAX(noizDens[BSIM4v7RGNOIZ], N_MINLOG));
259                               }
260 
261                                     bodymode = 5;
262                                     if (here->BSIM4v7rbodyMod == 2)
263                                     {        if( ( !model->BSIM4v7rbps0Given) ||
264                                       ( !model->BSIM4v7rbpd0Given) )
265                                              bodymode = 1;
266                                            else
267                                      if( (!model->BSIM4v7rbsbx0Given && !model->BSIM4v7rbsby0Given) ||
268                                           (!model->BSIM4v7rbdbx0Given && !model->BSIM4v7rbdby0Given) )
269                                              bodymode = 3;
270                                 }
271 
272                               if (here->BSIM4v7rbodyMod)
273                               {
274                                 if(bodymode == 5)
275                                   {
276                                     NevalSrc(&noizDens[BSIM4v7RBPSNOIZ],
277                                              &lnNdens[BSIM4v7RBPSNOIZ], ckt, THERMNOISE,
278                                              here->BSIM4v7bNodePrime, here->BSIM4v7sbNode,
279                                              here->BSIM4v7grbps * m);
280                                     NevalSrc(&noizDens[BSIM4v7RBPDNOIZ],
281                                              &lnNdens[BSIM4v7RBPDNOIZ], ckt, THERMNOISE,
282                                              here->BSIM4v7bNodePrime, here->BSIM4v7dbNode,
283                                              here->BSIM4v7grbpd * m);
284                                     NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
285                                              &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
286                                              here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
287                                              here->BSIM4v7grbpb * m);
288                                     NevalSrc(&noizDens[BSIM4v7RBSBNOIZ],
289                                              &lnNdens[BSIM4v7RBSBNOIZ], ckt, THERMNOISE,
290                                              here->BSIM4v7bNode, here->BSIM4v7sbNode,
291                                              here->BSIM4v7grbsb * m);
292                                     NevalSrc(&noizDens[BSIM4v7RBDBNOIZ],
293                                              &lnNdens[BSIM4v7RBDBNOIZ], ckt, THERMNOISE,
294                                              here->BSIM4v7bNode, here->BSIM4v7dbNode,
295                                              here->BSIM4v7grbdb * m);
296                                   }
297                                 if(bodymode == 3)
298                                   {
299                                     NevalSrc(&noizDens[BSIM4v7RBPSNOIZ],
300                                              &lnNdens[BSIM4v7RBPSNOIZ], ckt, THERMNOISE,
301                                              here->BSIM4v7bNodePrime, here->BSIM4v7sbNode,
302                                              here->BSIM4v7grbps * m);
303                                     NevalSrc(&noizDens[BSIM4v7RBPDNOIZ],
304                                              &lnNdens[BSIM4v7RBPDNOIZ], ckt, THERMNOISE,
305                                              here->BSIM4v7bNodePrime, here->BSIM4v7dbNode,
306                                              here->BSIM4v7grbpd * m);
307                                     NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
308                                              &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
309                                              here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
310                                              here->BSIM4v7grbpb * m);
311                                      noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
312                                      lnNdens[BSIM4v7RBSBNOIZ] =
313                                        log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
314                                      lnNdens[BSIM4v7RBDBNOIZ] =
315                                        log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
316                                   }
317                                 if(bodymode == 1)
318                                   {
319                                     NevalSrc(&noizDens[BSIM4v7RBPBNOIZ],
320                                              &lnNdens[BSIM4v7RBPBNOIZ], ckt, THERMNOISE,
321                                              here->BSIM4v7bNodePrime, here->BSIM4v7bNode,
322                                              here->BSIM4v7grbpb * m);
323                                     noizDens[BSIM4v7RBPSNOIZ] = noizDens[BSIM4v7RBPDNOIZ] = 0.0;
324                                     noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
325                                     lnNdens[BSIM4v7RBPSNOIZ] =
326                                       log(MAX(noizDens[BSIM4v7RBPSNOIZ], N_MINLOG));
327                                     lnNdens[BSIM4v7RBPDNOIZ] =
328                                       log(MAX(noizDens[BSIM4v7RBPDNOIZ], N_MINLOG));
329                                     lnNdens[BSIM4v7RBSBNOIZ] =
330                                       log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
331                                     lnNdens[BSIM4v7RBDBNOIZ] =
332                                       log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
333                                   }
334                               }
335                               else
336                               {   noizDens[BSIM4v7RBPSNOIZ] = noizDens[BSIM4v7RBPDNOIZ] = 0.0;
337                                   noizDens[BSIM4v7RBPBNOIZ] = 0.0;
338                                   noizDens[BSIM4v7RBSBNOIZ] = noizDens[BSIM4v7RBDBNOIZ] = 0.0;
339                                   lnNdens[BSIM4v7RBPSNOIZ] =
340                                           log(MAX(noizDens[BSIM4v7RBPSNOIZ], N_MINLOG));
341                                   lnNdens[BSIM4v7RBPDNOIZ] =
342                                           log(MAX(noizDens[BSIM4v7RBPDNOIZ], N_MINLOG));
343                                   lnNdens[BSIM4v7RBPBNOIZ] =
344                                           log(MAX(noizDens[BSIM4v7RBPBNOIZ], N_MINLOG));
345                                   lnNdens[BSIM4v7RBSBNOIZ] =
346                                           log(MAX(noizDens[BSIM4v7RBSBNOIZ], N_MINLOG));
347                                   lnNdens[BSIM4v7RBDBNOIZ] =
348                                           log(MAX(noizDens[BSIM4v7RBDBNOIZ], N_MINLOG));
349                               }
350 
351                               if(model->BSIM4v7tnoiMod == 2)
352                               {
353                                   eta = 1.0 - here->BSIM4v7Vdseff * here->BSIM4v7AbovVgst2Vtm;
354                                   T0 = 1.0 - eta;
355                                   T1 = 1.0 + eta;
356                                   T2 = T1 + 2.0 * here->BSIM4v7Abulk * model->BSIM4v7vtm / here->BSIM4v7Vgsteff;
357                                   Leff = pParam->BSIM4v7leff;
358                                   Lvsat = Leff * (1.0 + here->BSIM4v7Vdseff / here->BSIM4v7EsatL);
359                                   T6 = Leff / Lvsat;
360 
361                                   T5 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
362                                   T5 = T5 * T5;
363                                   gamma = T6 * (0.5 * T1 + T0 * T0 / (6.0 * T2));
364                                   T3 = T2 * T2;
365                                   T4 = T0 * T0;
366                                   T5 = T3 * T3;
367                                   delta = (T1 / T3 - (5.0 * T1 + T2) * T4 / (15.0 * T5) + T4 * T4 / (9.0 * T5 * T2)) / (6.0 * T6 * T6 * T6);
368                                   T7 = T0 / T2;
369                                   epsilon = (T7 - T7 * T7 * T7 / 3.0) / (6.0 * T6);
370 
371                                   T8 = here->BSIM4v7Vgsteff / here->BSIM4v7EsatL;
372                                   T8 *= T8;
373                                   npart_c = model->BSIM4v7rnoic * (1.0 + T8
374                                           * model->BSIM4v7tnoic * Leff);
375                                   ctnoi = epsilon / sqrt(gamma * delta)
376                                       * (2.5316 * npart_c);
377 
378                                   npart_beta = model->BSIM4v7rnoia * (1.0 + T8
379                                       * model->BSIM4v7tnoia * Leff);
380                                   npart_theta = model->BSIM4v7rnoib * (1.0 + T8
381                                       * model->BSIM4v7tnoib * Leff);
382                                   gamma = gamma * (3.0 * npart_beta * npart_beta);
383                                   delta = delta * (3.75 * npart_theta * npart_theta);
384 
385                                   GammaGd0 = gamma * here->BSIM4v7noiGd0;
386                                   C0 = here->BSIM4v7Coxeff * pParam->BSIM4v7weffCV * here->BSIM4v7nf * pParam->BSIM4v7leffCV;
387                                   T0 = C0 / here->BSIM4v7noiGd0;
388                                   sigrat = T0 * sqrt(delta / gamma);
389                               }
390                               switch(model->BSIM4v7tnoiMod)
391                               {  case 0:
392                                       T0 = here->BSIM4v7ueff * fabs(here->BSIM4v7qinv);
393                                       T1 = T0 * tmp + pParam->BSIM4v7leff
394                                          * pParam->BSIM4v7leff;
395                                       NevalSrc(&noizDens[BSIM4v7IDNOIZ],
396                                                &lnNdens[BSIM4v7IDNOIZ], ckt,
397                                                THERMNOISE, here->BSIM4v7dNodePrime,
398                                                here->BSIM4v7sNodePrime,
399                                                (T0 / T1) * model->BSIM4v7ntnoi * m);
400                                       break;
401                                  case 1:
402                                       T0 = here->BSIM4v7gm + here->BSIM4v7gmbs + here->BSIM4v7gds;
403                                       T0 *= T0;
404                                       igsquare = npart_theta * npart_theta * T0 / here->BSIM4v7IdovVds;
405                                       T1 = npart_beta * (here->BSIM4v7gm
406                                          + here->BSIM4v7gmbs) + here->BSIM4v7gds;
407                                       T2 = T1 * T1 / here->BSIM4v7IdovVds;
408                                       NevalSrc(&noizDens[BSIM4v7IDNOIZ],
409                                                &lnNdens[BSIM4v7IDNOIZ], ckt,
410                                                THERMNOISE, here->BSIM4v7dNodePrime,
411                                                here->BSIM4v7sNodePrime, (T2 - igsquare) * m);
412                                       break;
413                                   case 2:
414                                       T2 = GammaGd0;
415                                       T3 = ctnoi * ctnoi;
416                                       T4 = 1.0 - T3;
417                                       NevalSrc(&noizDens[BSIM4v7IDNOIZ],
418                                                &lnNdens[BSIM4v7IDNOIZ], ckt,
419                                                THERMNOISE, here->BSIM4v7dNodePrime,
420                                                here->BSIM4v7sNodePrime, T2 * T4 * m);
421 
422                                      /* Evaluate output noise due to two correlated noise sources */
423                                      omega = 2.0 * M_PI * data->freq;
424                                      T5 = omega * sigrat;
425                                      T6 = T5 * T5;
426                                      T7 = T6 / (1.0 + T6);
427 
428                                      if (here->BSIM4v7mode >= 0)  {
429                                          NevalSrc2(&noizDens[BSIM4v7CORLNOIZ],
430                                                &lnNdens[BSIM4v7CORLNOIZ], ckt,
431                                                THERMNOISE, here->BSIM4v7dNodePrime,
432                                                here->BSIM4v7sNodePrime, T2 * T3 * m,
433                                                here->BSIM4v7gNodePrime,
434                                                here->BSIM4v7sNodePrime,
435                                                T2 * T7 * m, 0.5 * M_PI);
436                                      }
437                                      else
438                                      {
439                                          NevalSrc2(&noizDens[BSIM4v7CORLNOIZ],
440                                                &lnNdens[BSIM4v7CORLNOIZ], ckt,
441                                                THERMNOISE, here->BSIM4v7sNodePrime,
442                                                here->BSIM4v7dNodePrime, T2 * T3 * m,
443                                                here->BSIM4v7gNodePrime,
444                                                here->BSIM4v7dNodePrime,
445                                                T2 * T7 * m, 0.5 * M_PI);
446                                      }
447                                      break;
448                               }
449 
450                               NevalSrc(&noizDens[BSIM4v7FLNOIZ], (double*) NULL,
451                                        ckt, N_GAIN, here->BSIM4v7dNodePrime,
452                                        here->BSIM4v7sNodePrime, (double) 0.0);
453 
454                               switch(model->BSIM4v7fnoiMod)
455                               {  case 0:
456                                       noizDens[BSIM4v7FLNOIZ] *= m * model->BSIM4v7kf
457                                             * exp(model->BSIM4v7af
458                                             * log(MAX(fabs(here->BSIM4v7cd),
459                                             N_MINLOG)))
460                                             / (pow(data->freq, model->BSIM4v7ef)
461                                             * pParam->BSIM4v7leff
462                                             * pParam->BSIM4v7leff
463                                             * model->BSIM4v7coxe);
464                                       break;
465                                  case 1:
466                                       Vds = *(ckt->CKTstates[0] + here->BSIM4v7vds);
467                                       if (Vds < 0.0)
468                                           Vds = -Vds;
469 
470                                       Ssi = Eval1ovFNoise(Vds, model, here,
471                                           data->freq, ckt->CKTtemp);
472                                       T10 = model->BSIM4v7oxideTrapDensityA
473                                           * CONSTboltz * ckt->CKTtemp;
474                                       T11 = pParam->BSIM4v7weff * here->BSIM4v7nf * pParam->BSIM4v7leff
475                                           * pow(data->freq, model->BSIM4v7ef) * 1.0e10
476                                           * here->BSIM4v7nstar * here->BSIM4v7nstar;
477                                       Swi = T10 / T11 * here->BSIM4v7cd
478                                           * here->BSIM4v7cd;
479                                       T1 = Swi + Ssi;
480                                       if (T1 > 0.0)
481                                           noizDens[BSIM4v7FLNOIZ] *= m * (Ssi * Swi) / T1;
482                                       else
483                                           noizDens[BSIM4v7FLNOIZ] *= 0.0;
484                                       break;
485                               }
486 
487                               lnNdens[BSIM4v7FLNOIZ] =
488                                      log(MAX(noizDens[BSIM4v7FLNOIZ], N_MINLOG));
489 
490 
491                         if(here->BSIM4v7mode >= 0) {  /* bugfix  */
492                               NevalSrc(&noizDens[BSIM4v7IGSNOIZ],
493                                    &lnNdens[BSIM4v7IGSNOIZ], ckt, SHOTNOISE,
494                                    here->BSIM4v7gNodePrime, here->BSIM4v7sNodePrime,
495                                    m * (here->BSIM4v7Igs + here->BSIM4v7Igcs));
496                               NevalSrc(&noizDens[BSIM4v7IGDNOIZ],
497                                    &lnNdens[BSIM4v7IGDNOIZ], ckt, SHOTNOISE,
498                                    here->BSIM4v7gNodePrime, here->BSIM4v7dNodePrime,
499                                    m * (here->BSIM4v7Igd + here->BSIM4v7Igcd));
500                         } else {
501                               NevalSrc(&noizDens[BSIM4v7IGSNOIZ],
502                                    &lnNdens[BSIM4v7IGSNOIZ], ckt, SHOTNOISE,
503                                    here->BSIM4v7gNodePrime, here->BSIM4v7sNodePrime,
504                                    m * (here->BSIM4v7Igs + here->BSIM4v7Igcd));
505                               NevalSrc(&noizDens[BSIM4v7IGDNOIZ],
506                                    &lnNdens[BSIM4v7IGDNOIZ], ckt, SHOTNOISE,
507                                    here->BSIM4v7gNodePrime, here->BSIM4v7dNodePrime,
508                                    m * (here->BSIM4v7Igd + here->BSIM4v7Igcs));
509                         }
510                               NevalSrc(&noizDens[BSIM4v7IGBNOIZ],
511                                    &lnNdens[BSIM4v7IGBNOIZ], ckt, SHOTNOISE,
512                                    here->BSIM4v7gNodePrime, here->BSIM4v7bNodePrime,
513                                    m * here->BSIM4v7Igb);
514 
515 
516                               noizDens[BSIM4v7TOTNOIZ] = noizDens[BSIM4v7RDNOIZ]
517                                      + noizDens[BSIM4v7RSNOIZ] + noizDens[BSIM4v7RGNOIZ]
518                                      + noizDens[BSIM4v7RBPSNOIZ] + noizDens[BSIM4v7RBPDNOIZ]
519                                      + noizDens[BSIM4v7RBPBNOIZ]
520                                      + noizDens[BSIM4v7RBSBNOIZ] + noizDens[BSIM4v7RBDBNOIZ]
521                                      + noizDens[BSIM4v7IDNOIZ] + noizDens[BSIM4v7FLNOIZ]
522                                      + noizDens[BSIM4v7IGSNOIZ] + noizDens[BSIM4v7IGDNOIZ]
523                                      + noizDens[BSIM4v7IGBNOIZ] + noizDens[BSIM4v7CORLNOIZ];
524                               lnNdens[BSIM4v7TOTNOIZ] =
525                                      log(MAX(noizDens[BSIM4v7TOTNOIZ], N_MINLOG));
526 
527                               *OnDens += noizDens[BSIM4v7TOTNOIZ];
528 
529                               if (data->delFreq == 0.0)
530                               {   /* if we haven't done any previous
531                                      integration, we need to initialize our
532                                      "history" variables.
533                                     */
534 
535                                   for (i = 0; i < BSIM4v7NSRCS; i++)
536                                   {    here->BSIM4v7nVar[LNLSTDENS][i] =
537                                              lnNdens[i];
538                                   }
539 
540                                   /* clear out our integration variables
541                                      if it's the first pass
542                                    */
543                                   if (data->freq ==
544                                       job->NstartFreq)
545                                   {   for (i = 0; i < BSIM4v7NSRCS; i++)
546                                       {    here->BSIM4v7nVar[OUTNOIZ][i] = 0.0;
547                                            here->BSIM4v7nVar[INNOIZ][i] = 0.0;
548                                       }
549                                   }
550                               }
551                               else
552                               {   /* data->delFreq != 0.0,
553                                      we have to integrate.
554                                    */
555                                   for (i = 0; i < BSIM4v7NSRCS; i++)
556                                   {    if (i != BSIM4v7TOTNOIZ)
557                                        {   tempOnoise = Nintegrate(noizDens[i],
558                                                 lnNdens[i],
559                                                 here->BSIM4v7nVar[LNLSTDENS][i],
560                                                 data);
561                                            tempInoise = Nintegrate(noizDens[i]
562                                                 * data->GainSqInv, lnNdens[i]
563                                                 + data->lnGainInv,
564                                                 here->BSIM4v7nVar[LNLSTDENS][i]
565                                                 + data->lnGainInv, data);
566                                            here->BSIM4v7nVar[LNLSTDENS][i] =
567                                                 lnNdens[i];
568                                            data->outNoiz += tempOnoise;
569                                            data->inNoise += tempInoise;
570                                            if (job->NStpsSm != 0)
571                                            {   here->BSIM4v7nVar[OUTNOIZ][i]
572                                                      += tempOnoise;
573                                                here->BSIM4v7nVar[OUTNOIZ][BSIM4v7TOTNOIZ]
574                                                      += tempOnoise;
575                                                here->BSIM4v7nVar[INNOIZ][i]
576                                                      += tempInoise;
577                                                here->BSIM4v7nVar[INNOIZ][BSIM4v7TOTNOIZ]
578                                                      += tempInoise;
579                                            }
580                                        }
581                                   }
582                               }
583                               if (data->prtSummary)
584                               {   for (i = 0; i < BSIM4v7NSRCS; i++)
585                                   {    /* print a summary report */
586                                        data->outpVector[data->outNumber++]
587                                              = noizDens[i];
588                                   }
589                               }
590                               break;
591                          case INT_NOIZ:
592                               /* already calculated, just output */
593                               if (job->NStpsSm != 0)
594                               {   for (i = 0; i < BSIM4v7NSRCS; i++)
595                                   {    data->outpVector[data->outNumber++]
596                                              = here->BSIM4v7nVar[OUTNOIZ][i];
597                                        data->outpVector[data->outNumber++]
598                                              = here->BSIM4v7nVar[INNOIZ][i];
599                                   }
600                               }
601                               break;
602                       }
603                       break;
604                  case N_CLOSE:
605                       /* do nothing, the main calling routine will close */
606                       return (OK);
607                       break;   /* the plots */
608               }       /* switch (operation) */
609          }    /* for here */
610     }    /* for model */
611 
612     return(OK);
613 }
614