testing
[gnucap-felix.git] / src / d_mos5.cc
blob70c7f1c005e2c96155d10eae930c63809a5e5974
1 /* $Id: d_mos5.cc,v 1.4 2010-07-09 12:14:21 felix Exp $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *------------------------------------------------------------------
22 * Spice BSIM2 model
23 * derived from Spice3f4,Copyright 1990 Regents of the University of California
24 * 1988 Min-Chie Jeng, Hong J. Park, Thomas L. Quarles
25 * Recoded for Gnucap model compiler, Al Davis, 2000
27 /* This file is automatically generated. DO NOT EDIT */
29 #include "globals.h"
30 #include "e_elemnt.h"
31 #include "d_mos5.h"
32 /*--------------------------------------------------------------------------*/
33 const double NA(NOT_INPUT);
34 const double INF(BIGBIG);
35 /*--------------------------------------------------------------------------*/
36 int MODEL_BUILT_IN_MOS5::_count = 0;
37 /*--------------------------------------------------------------------------*/
38 const int LEVEL(5);
39 /*--------------------------------------------------------------------------*/
40 namespace MODEL_BUILT_IN_MOS5_DISPATCHER {
41 static DEV_BUILT_IN_MOS p1d;
42 static MODEL_BUILT_IN_MOS5 p1(&p1d);
43 static DISPATCHER<MODEL_CARD>::INSTALL
44 d1(&model_dispatcher, "nmos5|pmos5", &p1);
46 /*--------------------------------------------------------------------------*/
47 void SDP_BUILT_IN_MOS5::init(const COMMON_COMPONENT* cc)
49 assert(cc);
50 SDP_BUILT_IN_MOS_BASE::init(cc);
51 const COMMON_BUILT_IN_MOS* c = prechecked_cast<const COMMON_BUILT_IN_MOS*>(cc);
52 assert(c);
53 const MODEL_BUILT_IN_MOS5* m = prechecked_cast<const MODEL_BUILT_IN_MOS5*>(c->model());
54 assert(m);
55 const CARD_LIST* par_scope = m->scope();
56 assert(par_scope);
58 l_eff -= m->dl;
59 w_eff -= m->dw;
60 cgate = m->cox * w_eff * l_eff;
61 double L = l_eff/MICRON2METER;
62 double W = w_eff/MICRON2METER;
63 double CoxWoverL = 1e-4 * m->cox * w_eff / l_eff;
64 // adjust: override
65 this->cgate = m->cox * w_eff * l_eff;
66 // adjust: raw
67 phi = m->phi(L, W, 0., par_scope);
68 vfb = m->vfb(L, W, 0., par_scope);
69 k1 = m->k1(L, W, 0., par_scope);
70 k2 = m->k2(L, W, 0., par_scope);
71 eta0 = m->eta0(L, W, 0., par_scope);
72 etaB = m->etaB(L, W, 0., par_scope);
73 mob0 = m->mob0(L, W, 0., par_scope);
74 mob0B = m->mob0B(L, W, 0., par_scope);
75 mobs0 = m->mobs0(L, W, 0., par_scope);
76 mobsB = m->mobsB(L, W, 0., par_scope);
77 mob20 = m->mob20(L, W, 0., par_scope);
78 mob2B = m->mob2B(L, W, 0., par_scope);
79 mob2G = m->mob2G(L, W, 0., par_scope);
80 mob30 = m->mob30(L, W, 0., par_scope);
81 mob3B = m->mob3B(L, W, 0., par_scope);
82 mob3G = m->mob3G(L, W, 0., par_scope);
83 mob40 = m->mob40(L, W, 0., par_scope);
84 mob4B = m->mob4B(L, W, 0., par_scope);
85 mob4G = m->mob4G(L, W, 0., par_scope);
86 ua0 = m->ua0(L, W, 0., par_scope);
87 uaB = m->uaB(L, W, 0., par_scope);
88 ub0 = m->ub0(L, W, 0., par_scope);
89 ubB = m->ubB(L, W, 0., par_scope);
90 u10 = m->u10(L, W, 0., par_scope);
91 u1B = m->u1B(L, W, 0., par_scope);
92 u1D = m->u1D(L, W, 0., par_scope);
93 n0 = m->n0(L, W, 0., par_scope);
94 nB = m->nB(L, W, 0., par_scope);
95 nD = m->nD(L, W, 0., par_scope);
96 vof0 = m->vof0(L, W, 0., par_scope);
97 vofB = m->vofB(L, W, 0., par_scope);
98 vofD = m->vofD(L, W, 0., par_scope);
99 ai0 = m->ai0(L, W, 0., par_scope);
100 aiB = m->aiB(L, W, 0., par_scope);
101 bi0 = m->bi0(L, W, 0., par_scope);
102 biB = m->biB(L, W, 0., par_scope);
103 vghigh = m->vghigh(L, W, 0., par_scope);
104 vglow = m->vglow(L, W, 0., par_scope);
105 // adjust: calculated
106 beta0 = mob0 * CoxWoverL;
107 beta0B = mob0B * CoxWoverL;
108 betas0 = mobs0 * CoxWoverL;
109 //betas0 = std::max(betas0, 1.01*beta0);
110 betasB = mobsB * CoxWoverL;
111 beta20 = mob20;
112 beta2B = mob2B;
113 beta2G = mob2G;
114 beta30 = mob30 * CoxWoverL;
115 beta3B = mob3B * CoxWoverL;
116 beta3G = mob3G * CoxWoverL;
117 beta40 = mob40 * CoxWoverL;
118 beta4B = mob4B * CoxWoverL;
119 beta4G = mob4G * CoxWoverL;
120 Phis3 = sqrt(phi) * phi;
121 One_Third_CoxWL = cgate / 3.0;
122 Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
123 // code_post
125 double tmp = betas0 - beta0 - beta0B * m->vbb;
126 if ((-betasB * m->vbb) > tmp) {
127 untested();
128 betasB = -tmp / m->vbb;
130 Arg = betasB - beta0B - m->vdd * (beta3B - m->vdd * beta4B);
132 /*--------------------------------------------------------------------------*/
133 TDP_BUILT_IN_MOS5::TDP_BUILT_IN_MOS5(const DEV_BUILT_IN_MOS* d)
134 :TDP_BUILT_IN_MOS_BASE(d)
137 /*--------------------------------------------------------------------------*/
138 MODEL_BUILT_IN_MOS5::MODEL_BUILT_IN_MOS5(const BASE_SUBCKT* p)
139 :MODEL_BUILT_IN_MOS_BASE(p),
140 phi(0.),
141 vfb(0.),
142 k1(0.),
143 k2(0.),
144 eta0(0.),
145 etaB(0.),
146 mob0(0.),
147 mob0B(0.),
148 mobs0(0.),
149 mobsB(0.),
150 mob20(0.),
151 mob2B(0.),
152 mob2G(0.),
153 mob30(0.),
154 mob3B(0.),
155 mob3G(0.),
156 mob40(0.),
157 mob4B(0.),
158 mob4G(0.),
159 ua0(0.),
160 uaB(0.),
161 ub0(0.),
162 ubB(0.),
163 u10(0.),
164 u1B(0.),
165 u1D(0.),
166 n0(0.),
167 nB(0.),
168 nD(0.),
169 vof0(0.),
170 vofB(0.),
171 vofD(0.),
172 ai0(0.),
173 aiB(0.),
174 bi0(0.),
175 biB(0.),
176 vghigh(0.),
177 vglow(0.),
178 dl_u(0.),
179 dw_u(0.),
180 tox_u(0.),
181 vdd(0.),
182 vgg(0.),
183 vbb(0.),
184 wdf(0.),
185 dell(0.),
186 temp_c(27.),
187 xpart(0.),
188 dl(NA),
189 dw(NA),
190 tox(NA),
191 cox(NA),
192 vdd2(NA),
193 vgg2(NA),
194 vbb2(NA),
195 Vtm(NA)
197 if (ENV::run_mode != rPRE_MAIN) {
198 ++_count;
199 }else{
201 set_default(&mjsw, NA);
202 set_default(&pb, NA);
203 set_default(&pbsw, NA);
204 set_default(&cjo, 0.0);
205 set_default(&mos_level, LEVEL);
207 /*--------------------------------------------------------------------------*/
208 MODEL_BUILT_IN_MOS5::MODEL_BUILT_IN_MOS5(const MODEL_BUILT_IN_MOS5& p)
209 :MODEL_BUILT_IN_MOS_BASE(p),
210 phi(p.phi),
211 vfb(p.vfb),
212 k1(p.k1),
213 k2(p.k2),
214 eta0(p.eta0),
215 etaB(p.etaB),
216 mob0(p.mob0),
217 mob0B(p.mob0B),
218 mobs0(p.mobs0),
219 mobsB(p.mobsB),
220 mob20(p.mob20),
221 mob2B(p.mob2B),
222 mob2G(p.mob2G),
223 mob30(p.mob30),
224 mob3B(p.mob3B),
225 mob3G(p.mob3G),
226 mob40(p.mob40),
227 mob4B(p.mob4B),
228 mob4G(p.mob4G),
229 ua0(p.ua0),
230 uaB(p.uaB),
231 ub0(p.ub0),
232 ubB(p.ubB),
233 u10(p.u10),
234 u1B(p.u1B),
235 u1D(p.u1D),
236 n0(p.n0),
237 nB(p.nB),
238 nD(p.nD),
239 vof0(p.vof0),
240 vofB(p.vofB),
241 vofD(p.vofD),
242 ai0(p.ai0),
243 aiB(p.aiB),
244 bi0(p.bi0),
245 biB(p.biB),
246 vghigh(p.vghigh),
247 vglow(p.vglow),
248 dl_u(p.dl_u),
249 dw_u(p.dw_u),
250 tox_u(p.tox_u),
251 vdd(p.vdd),
252 vgg(p.vgg),
253 vbb(p.vbb),
254 wdf(p.wdf),
255 dell(p.dell),
256 temp_c(p.temp_c),
257 xpart(p.xpart),
258 dl(p.dl),
259 dw(p.dw),
260 tox(p.tox),
261 cox(p.cox),
262 vdd2(p.vdd2),
263 vgg2(p.vgg2),
264 vbb2(p.vbb2),
265 Vtm(p.Vtm)
267 if (ENV::run_mode != rPRE_MAIN) {
268 ++_count;
269 }else{untested();//194
272 /*--------------------------------------------------------------------------*/
273 std::string MODEL_BUILT_IN_MOS5::dev_type()const
275 if (polarity == pN) {
276 return "nmos5";
277 }else if (polarity == pP) {
278 return "pmos5";
279 }else{untested();//235
280 return MODEL_BUILT_IN_MOS_BASE::dev_type();
283 /*--------------------------------------------------------------------------*/
284 void MODEL_BUILT_IN_MOS5::set_dev_type(const std::string& new_type)
286 if (Umatch(new_type, "nmos5 ")) {
287 polarity = pN;
288 }else if (Umatch(new_type, "pmos5 ")) {
289 polarity = pP;
290 }else{
291 MODEL_BUILT_IN_MOS_BASE::set_dev_type(new_type);
294 /*--------------------------------------------------------------------------*/
295 void MODEL_BUILT_IN_MOS5::precalc_first()
297 const CARD_LIST* par_scope = scope();
298 assert(par_scope);
299 MODEL_BUILT_IN_MOS_BASE::precalc_first();
300 e_val(&(this->dl_u), 0., par_scope);
301 e_val(&(this->dw_u), 0., par_scope);
302 e_val(&(this->tox_u), 0., par_scope);
303 e_val(&(this->vdd), 0., par_scope);
304 e_val(&(this->vgg), 0., par_scope);
305 e_val(&(this->vbb), 0., par_scope);
306 e_val(&(this->wdf), 0., par_scope);
307 e_val(&(this->dell), 0., par_scope);
308 e_val(&(this->temp_c), 27., par_scope);
309 e_val(&(this->xpart), 0., par_scope);
310 // final adjust: code_pre
311 // final adjust: override
312 if (mjsw == NA) {
313 mjsw = .33;
314 }else{
316 if (pb == NA) {
317 pb = 0.1;
318 }else{
320 //pb = std::max(pb, 0.1);
321 if (pbsw == NA) {
322 pbsw = pb;
323 }else{
325 //pbsw = std::max(pbsw, 0.1);
326 cmodel = ((!cmodel)?1:cmodel);
327 // final adjust: raw
328 e_val(&(this->dl_u), 0., par_scope);
329 e_val(&(this->dw_u), 0., par_scope);
330 e_val(&(this->tox_u), 0., par_scope);
331 //this->tox_u = std::max(tox_u, 1e-20);
332 e_val(&(this->vdd), 0., par_scope);
333 e_val(&(this->vgg), 0., par_scope);
334 e_val(&(this->vbb), 0., par_scope);
335 e_val(&(this->wdf), 0., par_scope);
336 e_val(&(this->dell), 0., par_scope);
337 e_val(&(this->temp_c), 27., par_scope);
338 e_val(&(this->xpart), 0., par_scope);
339 // final adjust: mid
340 // final adjust: calculated
341 dl = dl_u*MICRON2METER;
342 dw = dw_u*MICRON2METER;
343 tox = tox_u*MICRON2METER;
344 cox = 3.453e-11 /*E_OX*/ / tox;
345 vdd2 = 2 * vdd;
346 vgg2 = 2 * vgg;
347 vbb2 = 2 * vbb;
348 Vtm = 8.625e-5 /*K/Q*/ * (temp_c + P_CELSIUS0 -.15);
349 // final adjust: post
350 // final adjust: done
352 /*--------------------------------------------------------------------------*/
353 void MODEL_BUILT_IN_MOS5::precalc_last()
355 MODEL_BUILT_IN_MOS_BASE::precalc_last();
357 /*--------------------------------------------------------------------------*/
358 SDP_CARD* MODEL_BUILT_IN_MOS5::new_sdp(COMMON_COMPONENT* c)const
360 assert(c);
361 if (COMMON_BUILT_IN_MOS* cc = dynamic_cast<COMMON_BUILT_IN_MOS*>(c)) {
362 if (cc->_sdp) {
363 cc->_sdp->init(cc);
364 return cc->_sdp;
365 }else{
366 delete cc->_sdp;
367 return new SDP_BUILT_IN_MOS5(c);
369 }else{
370 return MODEL_BUILT_IN_MOS_BASE::new_sdp(c);
373 /*--------------------------------------------------------------------------*/
374 void MODEL_BUILT_IN_MOS5::set_param_by_index(int i, std::string& value, int offset)
376 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i) {
377 case 0: level = value; break; //5
378 case 1: unreachable(); break;
379 case 2: unreachable(); break;
380 case 3: unreachable(); break;
381 case 4: unreachable(); break;
382 case 5: unreachable(); break;
383 case 6: mos_level = value; break;
384 case 7: phi.set_nom(value); break;
385 case 8: phi.set_w(value); break;
386 case 9: phi.set_l(value); break;
387 case 10: phi.set_p(value); break;
388 case 11: vfb.set_nom(value); break;
389 case 12: vfb.set_w(value); break;
390 case 13: vfb.set_l(value); break;
391 case 14: vfb.set_p(value); break;
392 case 15: k1.set_nom(value); break;
393 case 16: k1.set_w(value); break;
394 case 17: k1.set_l(value); break;
395 case 18: k1.set_p(value); break;
396 case 19: k2.set_nom(value); break;
397 case 20: k2.set_w(value); break;
398 case 21: k2.set_l(value); break;
399 case 22: k2.set_p(value); break;
400 case 23: eta0.set_nom(value); break;
401 case 24: eta0.set_w(value); break;
402 case 25: eta0.set_l(value); break;
403 case 26: eta0.set_p(value); break;
404 case 27: etaB.set_nom(value); break;
405 case 28: etaB.set_w(value); break;
406 case 29: etaB.set_l(value); break;
407 case 30: etaB.set_p(value); break;
408 case 31: mob0.set_nom(value); break;
409 case 32: mob0.set_w(value); break;
410 case 33: mob0.set_l(value); break;
411 case 34: mob0.set_p(value); break;
412 case 35: mob0B.set_nom(value); break;
413 case 36: mob0B.set_w(value); break;
414 case 37: mob0B.set_l(value); break;
415 case 38: mob0B.set_p(value); break;
416 case 39: mobs0.set_nom(value); break;
417 case 40: mobs0.set_w(value); break;
418 case 41: mobs0.set_l(value); break;
419 case 42: mobs0.set_p(value); break;
420 case 43: mobsB.set_nom(value); break;
421 case 44: mobsB.set_w(value); break;
422 case 45: mobsB.set_l(value); break;
423 case 46: mobsB.set_p(value); break;
424 case 47: mob20.set_nom(value); break;
425 case 48: mob20.set_w(value); break;
426 case 49: mob20.set_l(value); break;
427 case 50: mob20.set_p(value); break;
428 case 51: mob2B.set_nom(value); break;
429 case 52: mob2B.set_w(value); break;
430 case 53: mob2B.set_l(value); break;
431 case 54: mob2B.set_p(value); break;
432 case 55: mob2G.set_nom(value); break;
433 case 56: mob2G.set_w(value); break;
434 case 57: mob2G.set_l(value); break;
435 case 58: mob2G.set_p(value); break;
436 case 59: mob30.set_nom(value); break;
437 case 60: mob30.set_w(value); break;
438 case 61: mob30.set_l(value); break;
439 case 62: mob30.set_p(value); break;
440 case 63: mob3B.set_nom(value); break;
441 case 64: mob3B.set_w(value); break;
442 case 65: mob3B.set_l(value); break;
443 case 66: mob3B.set_p(value); break;
444 case 67: mob3G.set_nom(value); break;
445 case 68: mob3G.set_w(value); break;
446 case 69: mob3G.set_l(value); break;
447 case 70: mob3G.set_p(value); break;
448 case 71: mob40.set_nom(value); break;
449 case 72: mob40.set_w(value); break;
450 case 73: mob40.set_l(value); break;
451 case 74: mob40.set_p(value); break;
452 case 75: mob4B.set_nom(value); break;
453 case 76: mob4B.set_w(value); break;
454 case 77: mob4B.set_l(value); break;
455 case 78: mob4B.set_p(value); break;
456 case 79: mob4G.set_nom(value); break;
457 case 80: mob4G.set_w(value); break;
458 case 81: mob4G.set_l(value); break;
459 case 82: mob4G.set_p(value); break;
460 case 83: ua0.set_nom(value); break;
461 case 84: ua0.set_w(value); break;
462 case 85: ua0.set_l(value); break;
463 case 86: ua0.set_p(value); break;
464 case 87: uaB.set_nom(value); break;
465 case 88: uaB.set_w(value); break;
466 case 89: uaB.set_l(value); break;
467 case 90: uaB.set_p(value); break;
468 case 91: ub0.set_nom(value); break;
469 case 92: ub0.set_w(value); break;
470 case 93: ub0.set_l(value); break;
471 case 94: ub0.set_p(value); break;
472 case 95: ubB.set_nom(value); break;
473 case 96: ubB.set_w(value); break;
474 case 97: ubB.set_l(value); break;
475 case 98: ubB.set_p(value); break;
476 case 99: u10.set_nom(value); break;
477 case 100: u10.set_w(value); break;
478 case 101: u10.set_l(value); break;
479 case 102: u10.set_p(value); break;
480 case 103: u1B.set_nom(value); break;
481 case 104: u1B.set_w(value); break;
482 case 105: u1B.set_l(value); break;
483 case 106: u1B.set_p(value); break;
484 case 107: u1D.set_nom(value); break;
485 case 108: u1D.set_w(value); break;
486 case 109: u1D.set_l(value); break;
487 case 110: u1D.set_p(value); break;
488 case 111: n0.set_nom(value); break;
489 case 112: n0.set_w(value); break;
490 case 113: n0.set_l(value); break;
491 case 114: n0.set_p(value); break;
492 case 115: nB.set_nom(value); break;
493 case 116: nB.set_w(value); break;
494 case 117: nB.set_l(value); break;
495 case 118: nB.set_p(value); break;
496 case 119: nD.set_nom(value); break;
497 case 120: nD.set_w(value); break;
498 case 121: nD.set_l(value); break;
499 case 122: nD.set_p(value); break;
500 case 123: vof0.set_nom(value); break;
501 case 124: vof0.set_w(value); break;
502 case 125: vof0.set_l(value); break;
503 case 126: vof0.set_p(value); break;
504 case 127: vofB.set_nom(value); break;
505 case 128: vofB.set_w(value); break;
506 case 129: vofB.set_l(value); break;
507 case 130: vofB.set_p(value); break;
508 case 131: vofD.set_nom(value); break;
509 case 132: vofD.set_w(value); break;
510 case 133: vofD.set_l(value); break;
511 case 134: vofD.set_p(value); break;
512 case 135: ai0.set_nom(value); break;
513 case 136: ai0.set_w(value); break;
514 case 137: ai0.set_l(value); break;
515 case 138: ai0.set_p(value); break;
516 case 139: aiB.set_nom(value); break;
517 case 140: aiB.set_w(value); break;
518 case 141: aiB.set_l(value); break;
519 case 142: aiB.set_p(value); break;
520 case 143: bi0.set_nom(value); break;
521 case 144: bi0.set_w(value); break;
522 case 145: bi0.set_l(value); break;
523 case 146: bi0.set_p(value); break;
524 case 147: biB.set_nom(value); break;
525 case 148: biB.set_w(value); break;
526 case 149: biB.set_l(value); break;
527 case 150: biB.set_p(value); break;
528 case 151: vghigh.set_nom(value); break;
529 case 152: vghigh.set_w(value); break;
530 case 153: vghigh.set_l(value); break;
531 case 154: vghigh.set_p(value); break;
532 case 155: vglow.set_nom(value); break;
533 case 156: vglow.set_w(value); break;
534 case 157: vglow.set_l(value); break;
535 case 158: vglow.set_p(value); break;
536 case 159: dl_u = value; break;
537 case 160: dw_u = value; break;
538 case 161: tox_u = value; break;
539 case 162: vdd = value; break;
540 case 163: vgg = value; break;
541 case 164: vbb = value; break;
542 case 165: wdf = value; break;
543 case 166: dell = value; break;
544 case 167: temp_c = value; break;
545 case 168: xpart = value; break;
546 default: MODEL_BUILT_IN_MOS_BASE::set_param_by_index(i, value, offset); break;
549 /*--------------------------------------------------------------------------*/
550 bool MODEL_BUILT_IN_MOS5::param_is_printable(int i)const
552 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i) {
553 case 0: return (true);
554 case 1: return (false);
555 case 2: return (false);
556 case 3: return (false);
557 case 4: return (false);
558 case 5: return (false);
559 case 6: return (mos_level != LEVEL);
560 case 7: return (true);
561 case 8: return (phi.w_has_value());
562 case 9: return (phi.l_has_value());
563 case 10: return (phi.p_has_value());
564 case 11: return (true);
565 case 12: return (vfb.w_has_value());
566 case 13: return (vfb.l_has_value());
567 case 14: return (vfb.p_has_value());
568 case 15: return (true);
569 case 16: return (k1.w_has_value());
570 case 17: return (k1.l_has_value());
571 case 18: return (k1.p_has_value());
572 case 19: return (true);
573 case 20: return (k2.w_has_value());
574 case 21: return (k2.l_has_value());
575 case 22: return (k2.p_has_value());
576 case 23: return (true);
577 case 24: return (eta0.w_has_value());
578 case 25: return (eta0.l_has_value());
579 case 26: return (eta0.p_has_value());
580 case 27: return (true);
581 case 28: return (etaB.w_has_value());
582 case 29: return (etaB.l_has_value());
583 case 30: return (etaB.p_has_value());
584 case 31: return (true);
585 case 32: return (mob0.w_has_value());
586 case 33: return (mob0.l_has_value());
587 case 34: return (mob0.p_has_value());
588 case 35: return (true);
589 case 36: return (mob0B.w_has_value());
590 case 37: return (mob0B.l_has_value());
591 case 38: return (mob0B.p_has_value());
592 case 39: return (true);
593 case 40: return (mobs0.w_has_value());
594 case 41: return (mobs0.l_has_value());
595 case 42: return (mobs0.p_has_value());
596 case 43: return (true);
597 case 44: return (mobsB.w_has_value());
598 case 45: return (mobsB.l_has_value());
599 case 46: return (mobsB.p_has_value());
600 case 47: return (true);
601 case 48: return (mob20.w_has_value());
602 case 49: return (mob20.l_has_value());
603 case 50: return (mob20.p_has_value());
604 case 51: return (true);
605 case 52: return (mob2B.w_has_value());
606 case 53: return (mob2B.l_has_value());
607 case 54: return (mob2B.p_has_value());
608 case 55: return (true);
609 case 56: return (mob2G.w_has_value());
610 case 57: return (mob2G.l_has_value());
611 case 58: return (mob2G.p_has_value());
612 case 59: return (true);
613 case 60: return (mob30.w_has_value());
614 case 61: return (mob30.l_has_value());
615 case 62: return (mob30.p_has_value());
616 case 63: return (true);
617 case 64: return (mob3B.w_has_value());
618 case 65: return (mob3B.l_has_value());
619 case 66: return (mob3B.p_has_value());
620 case 67: return (true);
621 case 68: return (mob3G.w_has_value());
622 case 69: return (mob3G.l_has_value());
623 case 70: return (mob3G.p_has_value());
624 case 71: return (true);
625 case 72: return (mob40.w_has_value());
626 case 73: return (mob40.l_has_value());
627 case 74: return (mob40.p_has_value());
628 case 75: return (true);
629 case 76: return (mob4B.w_has_value());
630 case 77: return (mob4B.l_has_value());
631 case 78: return (mob4B.p_has_value());
632 case 79: return (true);
633 case 80: return (mob4G.w_has_value());
634 case 81: return (mob4G.l_has_value());
635 case 82: return (mob4G.p_has_value());
636 case 83: return (true);
637 case 84: return (ua0.w_has_value());
638 case 85: return (ua0.l_has_value());
639 case 86: return (ua0.p_has_value());
640 case 87: return (true);
641 case 88: return (uaB.w_has_value());
642 case 89: return (uaB.l_has_value());
643 case 90: return (uaB.p_has_value());
644 case 91: return (true);
645 case 92: return (ub0.w_has_value());
646 case 93: return (ub0.l_has_value());
647 case 94: return (ub0.p_has_value());
648 case 95: return (true);
649 case 96: return (ubB.w_has_value());
650 case 97: return (ubB.l_has_value());
651 case 98: return (ubB.p_has_value());
652 case 99: return (true);
653 case 100: return (u10.w_has_value());
654 case 101: return (u10.l_has_value());
655 case 102: return (u10.p_has_value());
656 case 103: return (true);
657 case 104: return (u1B.w_has_value());
658 case 105: return (u1B.l_has_value());
659 case 106: return (u1B.p_has_value());
660 case 107: return (true);
661 case 108: return (u1D.w_has_value());
662 case 109: return (u1D.l_has_value());
663 case 110: return (u1D.p_has_value());
664 case 111: return (true);
665 case 112: return (n0.w_has_value());
666 case 113: return (n0.l_has_value());
667 case 114: return (n0.p_has_value());
668 case 115: return (true);
669 case 116: return (nB.w_has_value());
670 case 117: return (nB.l_has_value());
671 case 118: return (nB.p_has_value());
672 case 119: return (true);
673 case 120: return (nD.w_has_value());
674 case 121: return (nD.l_has_value());
675 case 122: return (nD.p_has_value());
676 case 123: return (true);
677 case 124: return (vof0.w_has_value());
678 case 125: return (vof0.l_has_value());
679 case 126: return (vof0.p_has_value());
680 case 127: return (true);
681 case 128: return (vofB.w_has_value());
682 case 129: return (vofB.l_has_value());
683 case 130: return (vofB.p_has_value());
684 case 131: return (true);
685 case 132: return (vofD.w_has_value());
686 case 133: return (vofD.l_has_value());
687 case 134: return (vofD.p_has_value());
688 case 135: return (true);
689 case 136: return (ai0.w_has_value());
690 case 137: return (ai0.l_has_value());
691 case 138: return (ai0.p_has_value());
692 case 139: return (true);
693 case 140: return (aiB.w_has_value());
694 case 141: return (aiB.l_has_value());
695 case 142: return (aiB.p_has_value());
696 case 143: return (true);
697 case 144: return (bi0.w_has_value());
698 case 145: return (bi0.l_has_value());
699 case 146: return (bi0.p_has_value());
700 case 147: return (true);
701 case 148: return (biB.w_has_value());
702 case 149: return (biB.l_has_value());
703 case 150: return (biB.p_has_value());
704 case 151: return (true);
705 case 152: return (vghigh.w_has_value());
706 case 153: return (vghigh.l_has_value());
707 case 154: return (vghigh.p_has_value());
708 case 155: return (true);
709 case 156: return (vglow.w_has_value());
710 case 157: return (vglow.l_has_value());
711 case 158: return (vglow.p_has_value());
712 case 159: return (true);
713 case 160: return (true);
714 case 161: return (true);
715 case 162: return (true);
716 case 163: return (true);
717 case 164: return (true);
718 case 165: return (true);
719 case 166: return (true);
720 case 167: return (true);
721 case 168: return (true);
722 default: return MODEL_BUILT_IN_MOS_BASE::param_is_printable(i);
725 /*--------------------------------------------------------------------------*/
726 std::string MODEL_BUILT_IN_MOS5::param_name(int i)const
728 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i) {
729 case 0: return "level";
730 case 1: return "=====";
731 case 2: return "=====";
732 case 3: return "=====";
733 case 4: return "=====";
734 case 5: return "=====";
735 case 6: return "diodelevel";
736 case 7: return "phi";
737 case 8: return "wphi";
738 case 9: return "lphi";
739 case 10: return "pphi";
740 case 11: return "vfb";
741 case 12: return "wvfb";
742 case 13: return "lvfb";
743 case 14: return "pvfb";
744 case 15: return "k1";
745 case 16: return "wk1";
746 case 17: return "lk1";
747 case 18: return "pk1";
748 case 19: return "k2";
749 case 20: return "wk2";
750 case 21: return "lk2";
751 case 22: return "pk2";
752 case 23: return "eta0";
753 case 24: return "weta0";
754 case 25: return "leta0";
755 case 26: return "peta0";
756 case 27: return "etab";
757 case 28: return "wetab";
758 case 29: return "letab";
759 case 30: return "petab";
760 case 31: return "mu0";
761 case 32: return "wmu0";
762 case 33: return "lmu0";
763 case 34: return "pmu0";
764 case 35: return "mu0b";
765 case 36: return "wmu0b";
766 case 37: return "lmu0b";
767 case 38: return "pmu0b";
768 case 39: return "mus0";
769 case 40: return "wmus0";
770 case 41: return "lmus0";
771 case 42: return "pmus0";
772 case 43: return "musb";
773 case 44: return "wmusb";
774 case 45: return "lmusb";
775 case 46: return "pmusb";
776 case 47: return "mu20";
777 case 48: return "wmu20";
778 case 49: return "lmu20";
779 case 50: return "pmu20";
780 case 51: return "mu2b";
781 case 52: return "wmu2b";
782 case 53: return "lmu2b";
783 case 54: return "pmu2b";
784 case 55: return "mu2g";
785 case 56: return "wmu2g";
786 case 57: return "lmu2g";
787 case 58: return "pmu2g";
788 case 59: return "mu30";
789 case 60: return "wmu30";
790 case 61: return "lmu30";
791 case 62: return "pmu30";
792 case 63: return "mu3b";
793 case 64: return "wmu3b";
794 case 65: return "lmu3b";
795 case 66: return "pmu3b";
796 case 67: return "mu3g";
797 case 68: return "wmu3g";
798 case 69: return "lmu3g";
799 case 70: return "pmu3g";
800 case 71: return "mu40";
801 case 72: return "wmu40";
802 case 73: return "lmu40";
803 case 74: return "pmu40";
804 case 75: return "mu4b";
805 case 76: return "wmu4b";
806 case 77: return "lmu4b";
807 case 78: return "pmu4b";
808 case 79: return "mu4g";
809 case 80: return "wmu4g";
810 case 81: return "lmu4g";
811 case 82: return "pmu4g";
812 case 83: return "ua0";
813 case 84: return "wua0";
814 case 85: return "lua0";
815 case 86: return "pua0";
816 case 87: return "uab";
817 case 88: return "wuab";
818 case 89: return "luab";
819 case 90: return "puab";
820 case 91: return "ub0";
821 case 92: return "wub0";
822 case 93: return "lub0";
823 case 94: return "pub0";
824 case 95: return "ubb";
825 case 96: return "wubb";
826 case 97: return "lubb";
827 case 98: return "pubb";
828 case 99: return "u10";
829 case 100: return "wu10";
830 case 101: return "lu10";
831 case 102: return "pu10";
832 case 103: return "u1b";
833 case 104: return "wu1b";
834 case 105: return "lu1b";
835 case 106: return "pu1b";
836 case 107: return "u1d";
837 case 108: return "wu1d";
838 case 109: return "lu1d";
839 case 110: return "pu1d";
840 case 111: return "n0";
841 case 112: return "wn0";
842 case 113: return "ln0";
843 case 114: return "pn0";
844 case 115: return "nb";
845 case 116: return "wnb";
846 case 117: return "lnb";
847 case 118: return "pnb";
848 case 119: return "nd";
849 case 120: return "wnd";
850 case 121: return "lnd";
851 case 122: return "pnd";
852 case 123: return "vof0";
853 case 124: return "wvof0";
854 case 125: return "lvof0";
855 case 126: return "pvof0";
856 case 127: return "vofb";
857 case 128: return "wvofb";
858 case 129: return "lvofb";
859 case 130: return "pvofb";
860 case 131: return "vofd";
861 case 132: return "wvofd";
862 case 133: return "lvofd";
863 case 134: return "pvofd";
864 case 135: return "ai0";
865 case 136: return "wai0";
866 case 137: return "lai0";
867 case 138: return "pai0";
868 case 139: return "aib";
869 case 140: return "waib";
870 case 141: return "laib";
871 case 142: return "paib";
872 case 143: return "bi0";
873 case 144: return "wbi0";
874 case 145: return "lbi0";
875 case 146: return "pbi0";
876 case 147: return "bib";
877 case 148: return "wbib";
878 case 149: return "lbib";
879 case 150: return "pbib";
880 case 151: return "vghigh";
881 case 152: return "wvghigh";
882 case 153: return "lvghigh";
883 case 154: return "pvghigh";
884 case 155: return "vglow";
885 case 156: return "wvglow";
886 case 157: return "lvglow";
887 case 158: return "pvglow";
888 case 159: return "dl";
889 case 160: return "dw";
890 case 161: return "tox";
891 case 162: return "vdd";
892 case 163: return "vgg";
893 case 164: return "vbb";
894 case 165: return "wdf";
895 case 166: return "dell";
896 case 167: return "temp";
897 case 168: return "xpart";
898 default: return MODEL_BUILT_IN_MOS_BASE::param_name(i);
901 /*--------------------------------------------------------------------------*/
902 std::string MODEL_BUILT_IN_MOS5::param_name(int i, int j)const
904 if (j == 0) {
905 return param_name(i);
906 }else if (j == 1) {
907 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i) {
908 case 0: return "";
909 case 1: return "";
910 case 2: return "";
911 case 3: return "";
912 case 4: return "";
913 case 5: return "";
914 case 6: return "";
915 case 7: return "";
916 case 8: return "";
917 case 9: return "";
918 case 10: return "";
919 case 11: return "";
920 case 12: return "";
921 case 13: return "";
922 case 14: return "";
923 case 15: return "";
924 case 16: return "";
925 case 17: return "";
926 case 18: return "";
927 case 19: return "";
928 case 20: return "";
929 case 21: return "";
930 case 22: return "";
931 case 23: return "";
932 case 24: return "";
933 case 25: return "";
934 case 26: return "";
935 case 27: return "";
936 case 28: return "";
937 case 29: return "";
938 case 30: return "";
939 case 31: return "";
940 case 32: return "";
941 case 33: return "";
942 case 34: return "";
943 case 35: return "";
944 case 36: return "";
945 case 37: return "";
946 case 38: return "";
947 case 39: return "";
948 case 40: return "";
949 case 41: return "";
950 case 42: return "";
951 case 43: return "";
952 case 44: return "";
953 case 45: return "";
954 case 46: return "";
955 case 47: return "";
956 case 48: return "";
957 case 49: return "";
958 case 50: return "";
959 case 51: return "";
960 case 52: return "";
961 case 53: return "";
962 case 54: return "";
963 case 55: return "";
964 case 56: return "";
965 case 57: return "";
966 case 58: return "";
967 case 59: return "";
968 case 60: return "";
969 case 61: return "";
970 case 62: return "";
971 case 63: return "";
972 case 64: return "";
973 case 65: return "";
974 case 66: return "";
975 case 67: return "";
976 case 68: return "";
977 case 69: return "";
978 case 70: return "";
979 case 71: return "";
980 case 72: return "";
981 case 73: return "";
982 case 74: return "";
983 case 75: return "";
984 case 76: return "";
985 case 77: return "";
986 case 78: return "";
987 case 79: return "";
988 case 80: return "";
989 case 81: return "";
990 case 82: return "";
991 case 83: return "";
992 case 84: return "";
993 case 85: return "";
994 case 86: return "";
995 case 87: return "";
996 case 88: return "";
997 case 89: return "";
998 case 90: return "";
999 case 91: return "";
1000 case 92: return "";
1001 case 93: return "";
1002 case 94: return "";
1003 case 95: return "";
1004 case 96: return "";
1005 case 97: return "";
1006 case 98: return "";
1007 case 99: return "";
1008 case 100: return "";
1009 case 101: return "";
1010 case 102: return "";
1011 case 103: return "";
1012 case 104: return "";
1013 case 105: return "";
1014 case 106: return "";
1015 case 107: return "";
1016 case 108: return "";
1017 case 109: return "";
1018 case 110: return "";
1019 case 111: return "";
1020 case 112: return "";
1021 case 113: return "";
1022 case 114: return "";
1023 case 115: return "";
1024 case 116: return "";
1025 case 117: return "";
1026 case 118: return "";
1027 case 119: return "";
1028 case 120: return "";
1029 case 121: return "";
1030 case 122: return "";
1031 case 123: return "";
1032 case 124: return "";
1033 case 125: return "";
1034 case 126: return "";
1035 case 127: return "";
1036 case 128: return "";
1037 case 129: return "";
1038 case 130: return "";
1039 case 131: return "";
1040 case 132: return "";
1041 case 133: return "";
1042 case 134: return "";
1043 case 135: return "";
1044 case 136: return "";
1045 case 137: return "";
1046 case 138: return "";
1047 case 139: return "";
1048 case 140: return "";
1049 case 141: return "";
1050 case 142: return "";
1051 case 143: return "";
1052 case 144: return "";
1053 case 145: return "";
1054 case 146: return "";
1055 case 147: return "";
1056 case 148: return "";
1057 case 149: return "";
1058 case 150: return "";
1059 case 151: return "";
1060 case 152: return "";
1061 case 153: return "";
1062 case 154: return "";
1063 case 155: return "";
1064 case 156: return "";
1065 case 157: return "";
1066 case 158: return "";
1067 case 159: return "";
1068 case 160: return "";
1069 case 161: return "";
1070 case 162: return "";
1071 case 163: return "";
1072 case 164: return "";
1073 case 165: return "";
1074 case 166: return "";
1075 case 167: return "";
1076 case 168: return "";
1077 default: return MODEL_BUILT_IN_MOS_BASE::param_name(i, j);
1079 }else if (i < 169) {
1080 return "";
1081 }else{
1082 return MODEL_BUILT_IN_MOS_BASE::param_name(i, j);
1085 /*--------------------------------------------------------------------------*/
1086 std::string MODEL_BUILT_IN_MOS5::param_value(int i)const
1088 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i) {
1089 case 0: return "5";
1090 case 1: unreachable(); return "";
1091 case 2: unreachable(); return "";
1092 case 3: unreachable(); return "";
1093 case 4: unreachable(); return "";
1094 case 5: unreachable(); return "";
1095 case 6: return mos_level.string();
1096 case 7: return phi.string();
1097 case 8: return phi.w_string();
1098 case 9: return phi.l_string();
1099 case 10: return phi.p_string();
1100 case 11: return vfb.string();
1101 case 12: return vfb.w_string();
1102 case 13: return vfb.l_string();
1103 case 14: return vfb.p_string();
1104 case 15: return k1.string();
1105 case 16: return k1.w_string();
1106 case 17: return k1.l_string();
1107 case 18: return k1.p_string();
1108 case 19: return k2.string();
1109 case 20: return k2.w_string();
1110 case 21: return k2.l_string();
1111 case 22: return k2.p_string();
1112 case 23: return eta0.string();
1113 case 24: return eta0.w_string();
1114 case 25: return eta0.l_string();
1115 case 26: return eta0.p_string();
1116 case 27: return etaB.string();
1117 case 28: return etaB.w_string();
1118 case 29: return etaB.l_string();
1119 case 30: return etaB.p_string();
1120 case 31: return mob0.string();
1121 case 32: return mob0.w_string();
1122 case 33: return mob0.l_string();
1123 case 34: return mob0.p_string();
1124 case 35: return mob0B.string();
1125 case 36: return mob0B.w_string();
1126 case 37: return mob0B.l_string();
1127 case 38: return mob0B.p_string();
1128 case 39: return mobs0.string();
1129 case 40: return mobs0.w_string();
1130 case 41: return mobs0.l_string();
1131 case 42: return mobs0.p_string();
1132 case 43: return mobsB.string();
1133 case 44: return mobsB.w_string();
1134 case 45: return mobsB.l_string();
1135 case 46: return mobsB.p_string();
1136 case 47: return mob20.string();
1137 case 48: return mob20.w_string();
1138 case 49: return mob20.l_string();
1139 case 50: return mob20.p_string();
1140 case 51: return mob2B.string();
1141 case 52: return mob2B.w_string();
1142 case 53: return mob2B.l_string();
1143 case 54: return mob2B.p_string();
1144 case 55: return mob2G.string();
1145 case 56: return mob2G.w_string();
1146 case 57: return mob2G.l_string();
1147 case 58: return mob2G.p_string();
1148 case 59: return mob30.string();
1149 case 60: return mob30.w_string();
1150 case 61: return mob30.l_string();
1151 case 62: return mob30.p_string();
1152 case 63: return mob3B.string();
1153 case 64: return mob3B.w_string();
1154 case 65: return mob3B.l_string();
1155 case 66: return mob3B.p_string();
1156 case 67: return mob3G.string();
1157 case 68: return mob3G.w_string();
1158 case 69: return mob3G.l_string();
1159 case 70: return mob3G.p_string();
1160 case 71: return mob40.string();
1161 case 72: return mob40.w_string();
1162 case 73: return mob40.l_string();
1163 case 74: return mob40.p_string();
1164 case 75: return mob4B.string();
1165 case 76: return mob4B.w_string();
1166 case 77: return mob4B.l_string();
1167 case 78: return mob4B.p_string();
1168 case 79: return mob4G.string();
1169 case 80: return mob4G.w_string();
1170 case 81: return mob4G.l_string();
1171 case 82: return mob4G.p_string();
1172 case 83: return ua0.string();
1173 case 84: return ua0.w_string();
1174 case 85: return ua0.l_string();
1175 case 86: return ua0.p_string();
1176 case 87: return uaB.string();
1177 case 88: return uaB.w_string();
1178 case 89: return uaB.l_string();
1179 case 90: return uaB.p_string();
1180 case 91: return ub0.string();
1181 case 92: return ub0.w_string();
1182 case 93: return ub0.l_string();
1183 case 94: return ub0.p_string();
1184 case 95: return ubB.string();
1185 case 96: return ubB.w_string();
1186 case 97: return ubB.l_string();
1187 case 98: return ubB.p_string();
1188 case 99: return u10.string();
1189 case 100: return u10.w_string();
1190 case 101: return u10.l_string();
1191 case 102: return u10.p_string();
1192 case 103: return u1B.string();
1193 case 104: return u1B.w_string();
1194 case 105: return u1B.l_string();
1195 case 106: return u1B.p_string();
1196 case 107: return u1D.string();
1197 case 108: return u1D.w_string();
1198 case 109: return u1D.l_string();
1199 case 110: return u1D.p_string();
1200 case 111: return n0.string();
1201 case 112: return n0.w_string();
1202 case 113: return n0.l_string();
1203 case 114: return n0.p_string();
1204 case 115: return nB.string();
1205 case 116: return nB.w_string();
1206 case 117: return nB.l_string();
1207 case 118: return nB.p_string();
1208 case 119: return nD.string();
1209 case 120: return nD.w_string();
1210 case 121: return nD.l_string();
1211 case 122: return nD.p_string();
1212 case 123: return vof0.string();
1213 case 124: return vof0.w_string();
1214 case 125: return vof0.l_string();
1215 case 126: return vof0.p_string();
1216 case 127: return vofB.string();
1217 case 128: return vofB.w_string();
1218 case 129: return vofB.l_string();
1219 case 130: return vofB.p_string();
1220 case 131: return vofD.string();
1221 case 132: return vofD.w_string();
1222 case 133: return vofD.l_string();
1223 case 134: return vofD.p_string();
1224 case 135: return ai0.string();
1225 case 136: return ai0.w_string();
1226 case 137: return ai0.l_string();
1227 case 138: return ai0.p_string();
1228 case 139: return aiB.string();
1229 case 140: return aiB.w_string();
1230 case 141: return aiB.l_string();
1231 case 142: return aiB.p_string();
1232 case 143: return bi0.string();
1233 case 144: return bi0.w_string();
1234 case 145: return bi0.l_string();
1235 case 146: return bi0.p_string();
1236 case 147: return biB.string();
1237 case 148: return biB.w_string();
1238 case 149: return biB.l_string();
1239 case 150: return biB.p_string();
1240 case 151: return vghigh.string();
1241 case 152: return vghigh.w_string();
1242 case 153: return vghigh.l_string();
1243 case 154: return vghigh.p_string();
1244 case 155: return vglow.string();
1245 case 156: return vglow.w_string();
1246 case 157: return vglow.l_string();
1247 case 158: return vglow.p_string();
1248 case 159: return dl_u.string();
1249 case 160: return dw_u.string();
1250 case 161: return tox_u.string();
1251 case 162: return vdd.string();
1252 case 163: return vgg.string();
1253 case 164: return vbb.string();
1254 case 165: return wdf.string();
1255 case 166: return dell.string();
1256 case 167: return temp_c.string();
1257 case 168: return xpart.string();
1258 default: return MODEL_BUILT_IN_MOS_BASE::param_value(i);
1261 /*--------------------------------------------------------------------------*/
1262 bool MODEL_BUILT_IN_MOS5::is_valid(const COMPONENT* d)const
1264 assert(d);
1265 return MODEL_BUILT_IN_MOS_BASE::is_valid(d);
1267 /*--------------------------------------------------------------------------*/
1268 void MODEL_BUILT_IN_MOS5::tr_eval(COMPONENT* brh)const
1270 DEV_BUILT_IN_MOS* d = prechecked_cast<DEV_BUILT_IN_MOS*>(brh);
1271 assert(d);
1272 const COMMON_BUILT_IN_MOS* c = prechecked_cast<const COMMON_BUILT_IN_MOS*>(d->common());
1273 assert(c);
1274 const SDP_BUILT_IN_MOS5* s = prechecked_cast<const SDP_BUILT_IN_MOS5*>(c->sdp());
1275 assert(s);
1276 const MODEL_BUILT_IN_MOS5* m = this;
1278 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1279 trace3("", d->vds, d->vgs, d->vbs);
1280 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1281 d->reverse_if_needed();
1282 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1283 trace2("", m->dl, m->dw);
1285 double Vbs = std::max(m->vbb2, (double) d->vbs);
1286 double Vgs = std::min(m->vgg2, (double) d->vgs);
1287 double Vds = std::min(m->vdd2, (double) d->vds);
1288 trace3("", Vbs, Vgs, Vds);
1290 /* Threshold Voltage. */
1291 double Phisb, dPhisb_dVb, T1s, dT1s_dVb;
1292 if (Vbs <= 0.0) {
1293 d->sbfwd = false;
1294 Phisb = s->phi - Vbs;
1295 dPhisb_dVb = -1.0;
1296 T1s = sqrt(Phisb);
1297 dT1s_dVb = -0.5 / T1s;
1298 trace4("-", Phisb, dPhisb_dVb, T1s, dT1s_dVb);
1299 }else{
1300 d->sbfwd = true;
1301 double tmp = s->phi / (s->phi + Vbs);
1302 Phisb = s->phi * tmp;
1303 dPhisb_dVb = -tmp * tmp;
1304 T1s = s->Phis3 / (s->phi + 0.5 * Vbs);
1305 dT1s_dVb = -0.5 * T1s * T1s / s->Phis3;
1306 trace4("+", Phisb, dPhisb_dVb, T1s, dT1s_dVb);
1309 double Eta = s->eta0 + s->etaB * Vbs;
1310 double Ua = s->ua0 + s->uaB * Vbs;
1311 double Ub = s->ub0 + s->ubB * Vbs;
1312 double U1s = s->u10 + s->u1B * Vbs;
1313 trace4("", Eta, Ua, Ub, U1s);
1315 d->von = s->vfb + s->phi + s->k1*T1s - s->k2*Phisb - Eta*Vds;
1316 double dVth_dVd = -Eta;
1317 double dVth_dVb = s->k1 * dT1s_dVb + s->k2 - s->etaB * Vds;
1318 d->vgst = Vgs - d->von;
1319 trace4("", d->von, dVth_dVd, dVth_dVb, d->vgst);
1321 double Aa, dAa_dVb, Inv_Aa;
1323 double tmp = 1.0 / (1.744 + 0.8364 * Phisb);
1324 double Gg = 1.0 - tmp;
1325 double dGg_dVb = 0.8364 * tmp * tmp * dPhisb_dVb;
1326 double T0 = Gg / T1s;
1327 trace4("", tmp, Gg, dGg_dVb, T0);
1328 double tmp1 = 0.5 * T0 * s->k1;
1329 Aa = 1.0 + tmp1;
1330 dAa_dVb = (Aa - 1.0) * (dGg_dVb / Gg - dT1s_dVb / T1s);
1331 Inv_Aa = 1.0 / Aa;
1332 trace4("", tmp1, Aa, dAa_dVb, Inv_Aa);
1335 trace3("", s->vghigh, s->vglow, d->vgst);
1337 double Exp0, Exp1, n, Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb;
1338 if ((d->vgst >= s->vghigh) || (s->n0 == 0.0)) {
1339 Exp0 = NOT_VALID;
1340 Exp1 = NOT_VALID;
1341 n = NOT_VALID;
1342 Vgeff = d->vgst;
1343 dVgeff_dVg = 1.0;
1344 dVgeff_dVd = -dVth_dVd;
1345 dVgeff_dVb = -dVth_dVb;
1346 trace0("vgst>vghigh");
1347 }else{
1348 double Vof = s->vof0 + s->vofB * Vbs + s->vofD * Vds;
1349 n = s->n0 + s->nB / T1s + s->nD * Vds;
1350 double tmp = 0.5 / (n * m->Vtm);
1351 trace3("", Vof, n, tmp);
1353 double ExpArg1 = -Vds / m->Vtm;
1354 ExpArg1 = std::max(ExpArg1, -30.0);
1355 Exp1 = exp(ExpArg1);
1356 double tmp1 = 1.0 - Exp1;
1357 tmp1 = std::max(tmp1, 1.0e-18);
1358 double tmp2 = 2.0 * Aa * tmp1;
1359 trace4("", ExpArg1, Exp1, tmp1, tmp2);
1361 // exports Exp0, Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb
1362 if (d->vgst <= s->vglow) {
1363 double ExpArg = d->vgst * tmp;
1364 ExpArg = std::max(ExpArg, -30.0);
1365 Exp0 = exp(0.5 * Vof + ExpArg);
1366 Vgeff = sqrt(tmp2) * m->Vtm * Exp0;
1367 double T0 = n * m->Vtm;
1368 dVgeff_dVg = Vgeff * tmp;
1369 dVgeff_dVd = dVgeff_dVg * (n / tmp1 * Exp1 - dVth_dVd
1370 - d->vgst * s->nD / n + T0 * s->vofD);
1371 dVgeff_dVb = dVgeff_dVg * (s->vofB * T0 - dVth_dVb
1372 + s->nB * d->vgst / (n * T1s * T1s) * dT1s_dVb
1373 + T0 * Inv_Aa * dAa_dVb);
1374 trace0("vgst<vglow");
1375 }else{
1376 double ExpArg = s->vglow * tmp;
1377 ExpArg = std::max(ExpArg, -30.0);
1378 Exp0 = exp(0.5 * Vof + ExpArg);
1379 Vgeff = sqrt(2.0 * Aa * (1.0 - Exp1)) * m->Vtm * Exp0;
1380 double Con1 = s->vghigh;
1381 double Con3 = Vgeff;
1382 double Con4 = Con3 * tmp;
1383 double SqrVghigh = s->vghigh * s->vghigh;
1384 double SqrVglow = s->vglow * s->vglow;
1385 double CubVghigh = s->vghigh * SqrVghigh;
1386 double CubVglow = s->vglow * SqrVglow;
1387 double T0 = 2.0 * s->vghigh;
1388 double T1 = 2.0 * s->vglow;
1389 double T2 = 3.0 * SqrVghigh;
1390 double T3 = 3.0 * SqrVglow;
1391 double T4 = s->vghigh - s->vglow;
1392 double T5 = SqrVghigh - SqrVglow;
1393 double T6 = CubVghigh - CubVglow;
1394 double T7 = Con1 - Con3;
1395 double delta = (T1-T0) * T6 + (T2-T3) * T5 + (T0*T3 - T1*T2) * T4;
1396 delta = 1.0 / delta;
1397 double Coeffb = (T1 - Con4 * T0) * T6 + (Con4 * T2 - T3) * T5
1398 + (T0 * T3 - T1 * T2) * T7;
1399 double Coeffc = (Con4-1.0) * T6 + (T2-T3) * T7 + (T3 - Con4*T2) * T4;
1400 double Coeffd = (T1-T0) * T7 + (1.0-Con4) * T5 + (Con4*T0 - T1) * T4;
1401 double Coeffa = SqrVghigh * (Coeffc + Coeffd * T0);
1402 Vgeff = (Coeffa + d->vgst * (Coeffb + d->vgst*(Coeffc+d->vgst*Coeffd)))
1403 *delta;
1404 dVgeff_dVg = (Coeffb + d->vgst*(2.0*Coeffc+3.0*d->vgst*Coeffd)) *delta;
1405 T7 = Con3 * tmp;
1406 double T8 = dT1s_dVb * s->nB / (T1s * T1s * n);
1407 double T9 = n * m->Vtm;
1408 double dCon3_dVd = T7*(n*Exp1/tmp1 -s->vglow*s->nD/n + T9*s->vofD);
1409 double dCon3_dVb = T7*(T9*Inv_Aa*dAa_dVb + s->vglow*T8 + T9*s->vofB);
1410 double dCon4_dVd = tmp * dCon3_dVd - T7 * s->nD / n;
1411 double dCon4_dVb = tmp * dCon3_dVb + T7 * T8;
1413 double dCoeffb_dVd = dCon4_dVd*(T2*T5-T0*T6) + dCon3_dVd*(T1*T2-T0*T3);
1414 double dCoeffc_dVd = dCon4_dVd * (T6 - T2*T4) + dCon3_dVd * (T3 - T2);
1415 double dCoeffd_dVd = dCon4_dVd * (T0*T4 - T5) + dCon3_dVd * (T0 - T1);
1416 double dCoeffa_dVd = SqrVghigh * (dCoeffc_dVd + dCoeffd_dVd * T0);
1418 dVgeff_dVd = -dVgeff_dVg * dVth_dVd + (dCoeffa_dVd
1419 + d->vgst * (dCoeffb_dVd + d->vgst
1420 * (dCoeffc_dVd + d->vgst * dCoeffd_dVd))) * delta;
1422 double dCoeffb_dVb = dCon4_dVb*(T2*T5-T0*T6) + dCon3_dVb*(T1*T2-T0*T3);
1423 double dCoeffc_dVb = dCon4_dVb * (T6 - T2*T4) + dCon3_dVb * (T3 - T2);
1424 double dCoeffd_dVb = dCon4_dVb * (T0*T4 - T5) + dCon3_dVb * (T0 - T1);
1425 double dCoeffa_dVb = SqrVghigh * (dCoeffc_dVb + dCoeffd_dVb * T0);
1427 dVgeff_dVb = -dVgeff_dVg * dVth_dVb + (dCoeffa_dVb
1428 + d->vgst * (dCoeffb_dVb + d->vgst
1429 * (dCoeffc_dVb + d->vgst * dCoeffd_dVb))) * delta;
1430 trace0("else");
1433 trace3("", Exp0, Exp1, n);
1434 trace4("", Vgeff, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb);
1436 double dVdsat_dVd, dVdsat_dVg, dVdsat_dVb;
1437 if (Vgeff > 0.0) { // normal operation
1438 d->cutoff = false;
1439 double Uvert = 1.0 + Vgeff * (Ua + Vgeff * Ub);
1440 Uvert = std::max(Uvert, 0.2);
1441 double Inv_Uvert = 1.0 / Uvert;
1442 double dUvert_dVg, dUvert_dVd, dUvert_dVb;
1444 double T8 = Ua + 2.0 * Ub * Vgeff;
1445 dUvert_dVg = T8 * dVgeff_dVg;
1446 dUvert_dVd = T8 * dVgeff_dVd;
1447 dUvert_dVb = T8 * dVgeff_dVb + Vgeff * (s->uaB + Vgeff * s->ubB);
1448 trace2("", T8, Uvert);
1449 trace3("", dUvert_dVg, dUvert_dVd, dUvert_dVb);
1452 double Vc, dVc_dVg, dVc_dVd, dVc_dVb;
1454 double T8 = U1s * Inv_Aa * Inv_Uvert;
1455 Vc = T8 * Vgeff;
1456 double T9 = Vc * Inv_Uvert;
1457 dVc_dVg = T8 * dVgeff_dVg - T9 * dUvert_dVg;
1458 dVc_dVd = T8 * dVgeff_dVd - T9 * dUvert_dVd;
1459 dVc_dVb = T8 * dVgeff_dVb
1460 + s->u1B * Vgeff * Inv_Aa * Inv_Uvert
1461 - Vc * Inv_Aa * dAa_dVb
1462 - T9 * dUvert_dVb;
1463 trace3("", T8, T9, Vc);
1464 trace3("", dVc_dVg, dVc_dVd, dVc_dVb);
1467 double Kk, dKk_dVc;
1469 double tmp2 = sqrt(1.0 + 2.0 * Vc);
1470 Kk = 0.5 * (1.0 + Vc + tmp2);
1471 dKk_dVc = 0.5 + 0.5 / tmp2;
1472 trace3("", tmp2, Kk, dKk_dVc);
1476 double T8 = Inv_Aa / sqrt(Kk);
1477 d->vdsat = std::max(Vgeff * T8, 1.0e-18);
1478 double T9 = 0.5 * d->vdsat * dKk_dVc / Kk;
1479 dVdsat_dVd = T8 * dVgeff_dVd - T9 * dVc_dVd;
1480 dVdsat_dVg = T8 * dVgeff_dVg - T9 * dVc_dVg;
1481 dVdsat_dVb = T8 * dVgeff_dVb - T9 * dVc_dVb - d->vdsat*Inv_Aa*dAa_dVb;
1482 trace3("", T8, T9, d->vdsat);
1483 trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb);
1486 double Beta, dBeta_dVd, dBeta_dVg, dBeta_dVb;
1488 double Beta0 = s->beta0 + s->beta0B * Vbs;
1489 double Betas = s->betas0 + s->betasB * Vbs;
1490 double Beta2 = s->beta20 + s->beta2B * Vbs + s->beta2G * Vgs;
1491 double Beta3 = s->beta30 + s->beta3B * Vbs + s->beta3G * Vgs;
1492 double Beta4 = s->beta40 + s->beta4B * Vbs + s->beta4G * Vgs;
1493 double Beta1 = Betas - (Beta0 + m->vdd * (Beta3 - m->vdd * Beta4));
1494 trace4("", Beta0, s->beta0, s->beta0B, Vbs);
1495 trace4("", Betas, s->betas0, s->betasB, Vgs);
1496 trace4("", Beta2, s->beta20, s->beta2B, s->beta2G);
1497 trace4("", Beta3, s->beta30, s->beta3B, s->beta3G);
1498 trace4("", Beta4, s->beta40, s->beta4B, s->beta4G);
1499 trace2("", Beta1, m->vdd);
1501 double T0 = Vds * Beta2 / d->vdsat;
1502 T0 = std::min(T0, 30.0);
1503 double T1 = exp(T0);
1504 double T2 = T1 * T1;
1505 double T3 = T2 + 1.0;
1506 trace4("", T0, T1, T2, T3);
1507 double tanh = (T2 - 1.0) / T3;
1508 double Sqrsech = 4.0 * T2 / (T3 * T3);
1509 trace2("", tanh, Sqrsech);
1511 Beta = Beta0 + Beta1 * tanh + Vds * (Beta3 - Beta4 * Vds);
1512 double T4 = Beta1 * Sqrsech / d->vdsat;
1513 double T5 = m->vdd * tanh;
1514 dBeta_dVd = Beta3 - 2.0*Beta4*Vds + T4*(Beta2-T0*dVdsat_dVd);
1515 dBeta_dVg = T4 * (s->beta2G * Vds - T0 * dVdsat_dVg)
1516 + s->beta3G * (Vds - T5)
1517 - s->beta4G * (Vds * Vds - m->vdd * T5);
1518 double dBeta1_dVb = s->Arg;
1519 dBeta_dVb = s->beta0B
1520 + dBeta1_dVb * tanh
1521 + Vds * (s->beta3B - Vds * s->beta4B)
1522 + T4 * (s->beta2B * Vds - T0 * dVdsat_dVb);
1523 trace3("", T4, T5, dBeta1_dVb);
1524 trace4("", Beta, dBeta_dVd, dBeta_dVg, dBeta_dVb);
1527 if (d->vgst > s->vglow) { // not subthreshold
1528 d->subthreshold = false;
1529 if (Vds <= d->vdsat) { // triode region
1530 d->saturated = false;
1531 double T3 = Vds / d->vdsat;
1532 double T4 = T3 - 1.0;
1533 double T2 = 1.0 - s->u1D * T4 * T4;
1534 double U1 = U1s * T2;
1535 double Utot = Uvert + U1 * Vds;
1536 Utot = std::max(Utot, 0.5);
1537 double Inv_Utot = 1.0 / Utot;
1538 double T5 = 2.0 * U1s * s->u1D * T4 / d->vdsat;
1539 double dU1_dVd = T5 * (T3 * dVdsat_dVd - 1.0);
1540 double dU1_dVg = T5 * T3 * dVdsat_dVg;
1541 double dU1_dVb = T5 * T3 * dVdsat_dVb + s->u1B * T2;
1542 double dUtot_dVd = dUvert_dVd + U1 + Vds * dU1_dVd;
1543 double dUtot_dVg = dUvert_dVg + Vds * dU1_dVg;
1544 double dUtot_dVb = dUvert_dVb + Vds * dU1_dVb;
1546 double tmp1 = (Vgeff - 0.5 * Aa * Vds);
1547 double tmp3 = tmp1 * Vds;
1548 double Betaeff = Beta * Inv_Utot;
1549 d->ids = Betaeff * tmp3;
1550 double T6 = d->ids / Betaeff * Inv_Utot;
1551 d->gds = T6 * (dBeta_dVd - Betaeff * dUtot_dVd)
1552 + Betaeff * (tmp1 + (dVgeff_dVd - 0.5 * Aa) * Vds);
1553 d->gmf = T6 * (dBeta_dVg - Betaeff * dUtot_dVg)
1554 + Betaeff * Vds * dVgeff_dVg;
1555 d->gmbf = T6 * (dBeta_dVb - Betaeff * dUtot_dVb)
1556 + Betaeff * Vds * (dVgeff_dVb - 0.5 * Vds * dAa_dVb);
1557 }else{ // Saturation
1558 d->saturated = true;
1559 double Inv_Kk = 1.0 / Kk;
1560 double tmp1 = Vgeff * Inv_Aa * Inv_Kk;
1561 double tmp3 = 0.5 * Vgeff * tmp1;
1562 double Betaeff = Beta * Inv_Uvert;
1563 d->ids = Betaeff * tmp3;
1564 double T0 = d->ids / Betaeff * Inv_Uvert;
1565 double T1 = Betaeff * Vgeff * Inv_Aa * Inv_Kk;
1566 double T2 = d->ids * Inv_Kk * dKk_dVc;
1568 if (s->ai0 != 0.0) {
1569 double Ai = s->ai0 + s->aiB * Vbs;
1570 double Bi = s->bi0 + s->biB * Vbs;
1571 double T5 = Bi / (Vds - d->vdsat);
1572 T5 = std::min(T5, 30.0);
1573 double T6 = exp(-T5);
1574 double FR = 1.0 + Ai * T6;
1575 double T7 = T5 / (Vds - d->vdsat);
1576 double T8 = (1.0 - FR) * T7;
1577 double dFR_dVd = T8 * (dVdsat_dVd - 1.0);
1578 double dFR_dVg = T8 * dVdsat_dVg;
1579 double dFR_dVb = T8 * dVdsat_dVb
1580 + T6 * (s->aiB - Ai * s->biB / (Vds - d->vdsat));
1582 d->gds = (T0 * (dBeta_dVd - Betaeff * dUvert_dVd)
1583 + T1 * dVgeff_dVd - T2 * dVc_dVd) * FR + d->ids * dFR_dVd;
1584 d->gmf = (T0 * (dBeta_dVg - Betaeff * dUvert_dVg)
1585 + T1 * dVgeff_dVg - T2 * dVc_dVg) * FR + d->ids * dFR_dVg;
1586 d->gmbf = (T0 * (dBeta_dVb - Betaeff * dUvert_dVb)
1587 + T1 * dVgeff_dVb - T2 * dVc_dVb
1588 - d->ids * Inv_Aa * dAa_dVb) * FR + d->ids * dFR_dVb;
1589 d->ids *= FR;
1590 }else{
1591 d->gds = T0 * (dBeta_dVd - Betaeff * dUvert_dVd)
1592 + T1 * dVgeff_dVd - T2 * dVc_dVd;
1593 d->gmf = T0 * (dBeta_dVg - Betaeff * dUvert_dVg)
1594 + T1 * dVgeff_dVg - T2 * dVc_dVg;
1595 d->gmbf = T0 * (dBeta_dVb - Betaeff * dUvert_dVb)
1596 + T1 * dVgeff_dVb - T2 * dVc_dVb - d->ids * Inv_Aa * dAa_dVb;
1599 }else{ // subthreshold
1600 d->subthreshold = true;
1601 assert(Exp0 != NOT_VALID);
1602 double T0 = Exp0 * Exp0;
1603 assert(Exp1 != NOT_VALID);
1604 double T1 = Exp1;
1605 trace4("sub", Exp0, Exp1, T0, T1);
1606 trace2("", n, m->Vtm);
1607 d->ids = Beta * m->Vtm * m->Vtm * T0 * (1.0 - T1);
1608 double T2 = d->ids / Beta;
1609 double T4 = n * m->Vtm;
1610 double T3 = d->ids / T4;
1611 trace4("", d->ids, T2, T4, T3);
1612 double FR, dFR_dVd, dFR_dVg, dFR_dVb;
1613 if ((Vds > d->vdsat) && s->ai0 != 0.0) {
1614 d->saturated = true;
1615 double Ai = s->ai0 + s->aiB * Vbs;
1616 double Bi = s->bi0 + s->biB * Vbs;
1617 double T5 = Bi / (Vds - d->vdsat);
1618 trace3("", Ai, Bi, T5);
1619 T5 = std::min(T5, 30.0);
1620 double T6 = exp(-T5);
1621 FR = 1.0 + Ai * T6;
1622 double T7 = T5 / (Vds - d->vdsat);
1623 double T8 = (1.0 - FR) * T7;
1624 trace4("", T5, T6, T7, T8);
1625 dFR_dVd = T8 * (dVdsat_dVd - 1.0);
1626 dFR_dVg = T8 * dVdsat_dVg;
1627 dFR_dVb = T8 * dVdsat_dVb + T6 * (s->aiB-Ai*s->biB/(Vds-d->vdsat));
1628 trace4("ai0!=0", FR, dFR_dVd, dFR_dVg, dFR_dVb);
1629 }else{
1630 d->saturated = false;
1631 FR = 1.0;
1632 dFR_dVd = 0.0;
1633 dFR_dVg = 0.0;
1634 dFR_dVb = 0.0;
1635 trace4("ai0==0", FR, dFR_dVd, dFR_dVg, dFR_dVb);
1638 d->gds = (T2 * dBeta_dVd
1639 + T3 * (s->vofD * T4 - dVth_dVd - s->nD * d->vgst / n)
1640 + Beta * m->Vtm * T0 * T1) * FR + d->ids * dFR_dVd;
1641 d->gmf = (T2 * dBeta_dVg + T3) * FR + d->ids * dFR_dVg;
1642 d->gmbf = (T2 * dBeta_dVb + T3 * (s->vofB * T4 - dVth_dVb + s->nB
1643 * d->vgst / (n * T1s * T1s) * dT1s_dVb)) * FR + d->ids*dFR_dVb;
1644 d->ids *= FR;
1646 }else{ // cutoff???
1647 d->cutoff = true;
1648 // reachable only if vghigh and vgst both negative
1649 d->vdsat = 0.0;
1650 dVdsat_dVd = dVdsat_dVg = dVdsat_dVb = 0.0;
1651 d->ids = 0.0;
1652 d->gmf = 0.0;
1653 d->gds = 0.0;
1654 d->gmbf = 0.0;
1656 trace4("", d->vdsat, dVdsat_dVd, dVdsat_dVg, dVdsat_dVb);
1657 trace4("", d->ids, d->gmf, d->gds, d->gmbf);
1659 /* Some Limiting of DC Parameters */
1660 d->gds = std::max(d->gds, 1.0e-20);
1661 d->ids = std::max(d->ids, (hp_float_t) 1.0e-50);
1662 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1663 double Vbseff, dVbseff_dVb;
1664 if (Vbs < 0.0) {
1665 Vbseff = Vbs;
1666 dVbseff_dVb = 1.0;
1667 }else{
1668 Vbseff = s->phi - Phisb;
1669 dVbseff_dVb = -dPhisb_dVb;
1671 trace3("", Vbs, Vbseff, dVbseff_dVb);
1673 double Arg1 = Vgs - Vbseff - s->vfb;
1674 double Arg2 = Arg1 - d->vgst;
1675 trace2("", Arg1, Arg2);
1676 double Qbulk = s->One_Third_CoxWL * Arg2;
1677 double dQbulk_dVb = s->One_Third_CoxWL * (dVth_dVb - dVbseff_dVb);
1678 double dQbulk_dVd = s->One_Third_CoxWL * dVth_dVd;
1679 trace3("", Qbulk, dQbulk_dVb, dQbulk_dVd);
1680 if (Arg1 <= 0.0) { // accumulation region
1681 d->qgate = s->cgate * Arg1;
1682 d->qbulk = -(d->qgate);
1683 d->qdrn = 0.0;
1685 d->cggb = s->cgate;
1686 d->cgdb = 0.0;
1687 d->cgsb = -d->cggb * (1.0 - dVbseff_dVb);
1689 d->cdgb = 0.0;
1690 d->cddb = 0.0;
1691 d->cdsb = 0.0;
1693 d->cbgb = -s->cgate;
1694 d->cbdb = 0.0;
1695 d->cbsb = -d->cgsb;
1696 trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb);
1697 trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb);
1698 trace4("acc", d->qdrn, d->cdgb, d->cddb, d->cdsb);
1699 }else if (d->vgst <= 0.0) { // subthreshold
1700 double T2 = Arg1 / Arg2;
1701 double T3 = T2 * T2 * (s->cgate - s->Two_Third_CoxWL * T2);
1703 d->qgate = s->cgate * Arg1 * (1.0 - T2 * (1.0 - T2 / 3.0));
1704 d->qbulk = -(d->qgate);
1705 d->qdrn = 0.0;
1707 d->cggb = s->cgate * (1.0 - T2 * (2.0 - T2));
1708 d->cgdb = T3 * dVth_dVd;
1709 double tmp = T3 * dVth_dVb - (d->cggb + T3) * dVbseff_dVb;
1710 d->cgsb = -(d->cggb + d->cgdb + tmp);
1712 d->cbgb = -d->cggb;
1713 d->cbdb = -d->cgdb;
1714 d->cbsb = -d->cgsb;
1716 d->cdgb = 0.0;
1717 d->cddb = 0.0;
1718 d->cdsb = 0.0;
1719 trace3("", T2, T3, tmp);
1720 trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb);
1721 trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb);
1722 trace4("sub", d->qdrn, d->cdgb, d->cddb, d->cdsb);
1723 }else{
1724 double Vdsat; // changes dVdsat_dVd, dVdsat_dVg, dVdsat_dVb;
1725 if (d->vgst < s->vghigh) {
1726 double Uvert = 1.0 + d->vgst * (Ua + d->vgst * Ub);
1727 Uvert = std::max(Uvert, 0.2);
1728 double Inv_Uvert = 1.0 / Uvert;
1729 double dUvert_dVg = Ua + 2.0 * Ub * d->vgst;
1730 double dUvert_dVd = -dUvert_dVg * dVth_dVd;
1731 double dUvert_dVb = -dUvert_dVg * dVth_dVb
1732 + d->vgst * (s->uaB + d->vgst * s->ubB);
1733 trace2("", Uvert, Inv_Uvert);
1734 trace3("", dUvert_dVg, dUvert_dVd, dUvert_dVb);
1736 double T8 = U1s * Inv_Aa * Inv_Uvert;
1737 double Vc = T8 * d->vgst;
1738 double T9 = Vc * Inv_Uvert;
1739 double dVc_dVg = T8 - T9 * dUvert_dVg;
1740 double dVc_dVd = -T8 * dVth_dVd - T9 * dUvert_dVd;
1741 double dVc_dVb = -T8 * dVth_dVb
1742 + s->u1B * d->vgst * Inv_Aa * Inv_Uvert
1743 - Vc * Inv_Aa * dAa_dVb - T9 * dUvert_dVb;
1744 trace3("", T8, T9, Vc);
1745 trace3("", dVc_dVg, dVc_dVd, dVc_dVb);
1747 double tmp2 = sqrt(1.0 + 2.0 * Vc);
1748 double Kk = 0.5 * (1.0 + Vc + tmp2);
1749 double dKk_dVc = 0.5 + 0.5 / tmp2;
1750 trace3("", tmp2, Kk, dKk_dVc);
1752 T8 = Inv_Aa / sqrt(Kk);
1753 Vdsat = d->vgst * T8;
1754 T9 = 0.5 * Vdsat * dKk_dVc / Kk;
1755 trace2("", T8, T9);
1756 dVdsat_dVd = -T8 * dVth_dVd - T9 * dVc_dVd;
1757 dVdsat_dVg = T8 - T9 * dVc_dVg;
1758 dVdsat_dVb = -T8*dVth_dVb - T9*dVc_dVb - Vdsat*Inv_Aa*dAa_dVb;
1759 trace2("new", d->vdsat, Vdsat);
1760 trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb);
1761 }else{
1762 Vdsat = d->vdsat;
1763 trace2("keep", d->vdsat, Vdsat);
1764 trace3("", dVdsat_dVd, dVdsat_dVg, dVdsat_dVb);
1765 // keep dVdsat_dVd, dVdsat_dVg, dVdsat_dVb;
1767 if (Vds >= Vdsat) { /* saturation region */
1768 d->cggb = s->Two_Third_CoxWL;
1769 d->cgdb = -d->cggb * dVth_dVd + dQbulk_dVd;
1770 double tmp = -d->cggb * dVth_dVb + dQbulk_dVb;
1771 d->cgsb = -(d->cggb + d->cgdb + tmp);
1772 trace1("", tmp);
1774 d->cbgb = 0.0;
1775 d->cbdb = -dQbulk_dVd;
1776 d->cbsb = dQbulk_dVd + dQbulk_dVb;
1778 d->cdgb = -0.4 * d->cggb;
1779 d->cddb = -d->cdgb * dVth_dVd;
1780 tmp = -d->cdgb * dVth_dVb;
1781 d->cdsb = -(d->cdgb + d->cddb + tmp);
1782 trace1("", tmp);
1784 d->qbulk = -Qbulk;
1785 d->qgate = s->Two_Third_CoxWL * d->vgst + Qbulk;
1786 d->qdrn = d->cdgb * d->vgst;
1787 trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb);
1788 trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb);
1789 trace4("sat", d->qdrn, d->cdgb, d->cddb, d->cdsb);
1790 }else{ /* linear region */
1791 double T7 = Vds / Vdsat;
1792 double T8 = d->vgst / Vdsat;
1793 double T6 = T7 * T8;
1794 double T9 = 1.0 - T7;
1795 double Vgdt = d->vgst * T9;
1796 double T0 = d->vgst / (d->vgst + Vgdt);
1797 double T1 = Vgdt / (d->vgst + Vgdt);
1798 double T5 = T0 * T1;
1799 double T2 = 1.0 - T1 + T5;
1800 double T3 = 1.0 - T0 + T5;
1801 trace4("", T7, T8, T6, T9);
1802 trace2("", Vgdt, T0);
1803 trace4("", T1, T5, T2, T3);
1805 double dVgdt_dVg = T9 + T6 * dVdsat_dVg;
1806 double dVgdt_dVd = T6 * dVdsat_dVd - T8 -T9 * dVth_dVd;
1807 double dVgdt_dVb = T6 * dVdsat_dVb -T9 * dVth_dVb;
1808 trace3("", dVgdt_dVg, dVgdt_dVd, dVgdt_dVb);
1810 d->qgate = s->Two_Third_CoxWL * (d->vgst + Vgdt
1811 - Vgdt * T0) + Qbulk;
1812 d->qbulk = -Qbulk;
1813 d->qdrn = -s->One_Third_CoxWL * (0.2 * Vgdt
1814 + 0.8 * d->vgst + Vgdt * T1
1815 + 0.2 * T5 * (Vgdt - d->vgst));
1817 d->cggb = s->Two_Third_CoxWL * (T2 + T3 * dVgdt_dVg);
1818 d->cgdb = s->Two_Third_CoxWL * (T3*dVgdt_dVd-T2*dVth_dVd) + dQbulk_dVd;
1819 double tmp = dQbulk_dVb +s->Two_Third_CoxWL*(T3*dVgdt_dVb-T2*dVth_dVb);
1820 d->cgsb = -(d->cggb + d->cgdb + tmp);
1821 trace1("", tmp);
1823 T2 = 0.8 - 0.4 * T1 * (2.0 * T1 + T0 + T0 * (T1 - T0));
1824 T3 = 0.2 + T1 + T0 * (1.0 - 0.4 * T0 * (T1 + 3.0 * T0));
1825 d->cdgb = -s->One_Third_CoxWL * (T2 + T3 * dVgdt_dVg);
1826 d->cddb = s->One_Third_CoxWL * (T2 * dVth_dVd - T3 * dVgdt_dVd);
1827 tmp = s->One_Third_CoxWL * (T2 * dVth_dVb - T3 * dVgdt_dVb);
1828 d->cdsb = -(d->cdgb + tmp + d->cddb);
1829 trace3("", T2, T3, tmp);
1831 d->cbgb = 0.0;
1832 d->cbdb = -dQbulk_dVd;
1833 d->cbsb = dQbulk_dVd + dQbulk_dVb;
1834 trace4("", d->qgate, d->cggb, d->cgdb, d->cgsb);
1835 trace4("", d->qbulk, d->cbgb, d->cbdb, d->cbsb);
1836 trace4("lin", d->qdrn, d->cdgb, d->cddb, d->cdsb);
1839 if (d->reversed) {
1840 d->ids *= -1;
1841 d->gmr = d->gmf;
1842 d->gmbr = d->gmbf;
1843 d->gmf = d->gmbf = 0;
1844 }else{
1845 d->gmr = d->gmbr = 0.;
1848 /*--------------------------------------------------------------------------*/
1849 /*--------------------------------------------------------------------------*/
1850 /*--------------------------------------------------------------------------*/
1851 /*--------------------------------------------------------------------------*/