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)
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
21 *------------------------------------------------------------------
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 */
32 /*--------------------------------------------------------------------------*/
33 const double NA(NOT_INPUT
);
34 const double INF(BIGBIG
);
35 /*--------------------------------------------------------------------------*/
36 int MODEL_BUILT_IN_MOS5::_count
= 0;
37 /*--------------------------------------------------------------------------*/
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
)
50 SDP_BUILT_IN_MOS_BASE::init(cc
);
51 const COMMON_BUILT_IN_MOS
* c
= prechecked_cast
<const COMMON_BUILT_IN_MOS
*>(cc
);
53 const MODEL_BUILT_IN_MOS5
* m
= prechecked_cast
<const MODEL_BUILT_IN_MOS5
*>(c
->model());
55 const CARD_LIST
* par_scope
= m
->scope();
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
;
65 this->cgate
= m
->cox
* w_eff
* l_eff
;
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
;
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
;
125 double tmp
= betas0
- beta0
- beta0B
* m
->vbb
;
126 if ((-betasB
* m
->vbb
) > tmp
) {
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
),
197 if (ENV::run_mode
!= rPRE_MAIN
) {
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
),
267 if (ENV::run_mode
!= rPRE_MAIN
) {
269 }else{untested();//194
272 /*--------------------------------------------------------------------------*/
273 std::string
MODEL_BUILT_IN_MOS5::dev_type()const
275 if (polarity
== pN
) {
277 }else if (polarity
== pP
) {
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 ")) {
288 }else if (Umatch(new_type
, "pmos5 ")) {
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();
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
320 //pb = std::max(pb, 0.1);
325 //pbsw = std::max(pbsw, 0.1);
326 cmodel
= ((!cmodel
)?1:cmodel
);
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
);
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
;
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
361 if (COMMON_BUILT_IN_MOS
* cc
= dynamic_cast<COMMON_BUILT_IN_MOS
*>(c
)) {
367 return new SDP_BUILT_IN_MOS5(c
);
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
905 return param_name(i
);
907 switch (MODEL_BUILT_IN_MOS5::param_count() - 1 - i
) {
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) {
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
) {
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
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
);
1272 const COMMON_BUILT_IN_MOS
* c
= prechecked_cast
<const COMMON_BUILT_IN_MOS
*>(d
->common());
1274 const SDP_BUILT_IN_MOS5
* s
= prechecked_cast
<const SDP_BUILT_IN_MOS5
*>(c
->sdp());
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
;
1294 Phisb
= s
->phi
- Vbs
;
1297 dT1s_dVb
= -0.5 / T1s
;
1298 trace4("-", Phisb
, dPhisb_dVb
, T1s
, dT1s_dVb
);
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
;
1330 dAa_dVb
= (Aa
- 1.0) * (dGg_dVb
/ Gg
- dT1s_dVb
/ T1s
);
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)) {
1344 dVgeff_dVd
= -dVth_dVd
;
1345 dVgeff_dVb
= -dVth_dVb
;
1346 trace0("vgst>vghigh");
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");
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
)))
1404 dVgeff_dVg
= (Coeffb
+ d
->vgst
*(2.0*Coeffc
+3.0*d
->vgst
*Coeffd
)) *delta
;
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
;
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
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
;
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
1463 trace3("", T8
, T9
, Vc
);
1464 trace3("", dVc_dVg
, dVc_dVd
, dVc_dVb
);
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
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
;
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
);
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
);
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
);
1630 d
->saturated
= false;
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
;
1648 // reachable only if vghigh and vgst both negative
1650 dVdsat_dVd
= dVdsat_dVg
= dVdsat_dVb
= 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
;
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
);
1687 d
->cgsb
= -d
->cggb
* (1.0 - dVbseff_dVb
);
1693 d
->cbgb
= -s
->cgate
;
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
);
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
);
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
);
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
;
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
);
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
);
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
);
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
;
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
);
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
);
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
);
1843 d
->gmf
= d
->gmbf
= 0;
1845 d
->gmr
= d
->gmbr
= 0.;
1848 /*--------------------------------------------------------------------------*/
1849 /*--------------------------------------------------------------------------*/
1850 /*--------------------------------------------------------------------------*/
1851 /*--------------------------------------------------------------------------*/