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