1 /* $Id: d_mos4.cc,v 1.3 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 * 1985 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_MOS4::_count
= 0;
37 /*--------------------------------------------------------------------------*/
39 /*--------------------------------------------------------------------------*/
40 namespace MODEL_BUILT_IN_MOS4_DISPATCHER
{
41 static DEV_BUILT_IN_MOS p1d
;
42 static MODEL_BUILT_IN_MOS4
p1(&p1d
);
43 static DISPATCHER
<MODEL_CARD
>::INSTALL
44 d1(&model_dispatcher
, "nmos4|pmos4", &p1
);
46 /*--------------------------------------------------------------------------*/
47 void SDP_BUILT_IN_MOS4::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_MOS4
* m
= prechecked_cast
<const MODEL_BUILT_IN_MOS4
*>(c
->model());
55 const CARD_LIST
* par_scope
= m
->scope();
60 double L
= l_eff
/MICRON2METER
;
61 double W
= w_eff
/MICRON2METER
;
62 double CoxWoverL
= 1e-4 * m
->cox
* w_eff
/ l_eff
;
64 this->cgate
= m
->cox
* w_eff
* l_eff
;
66 phi
= m
->phi(L
, W
, 0., par_scope
);
67 //phi = std::max(phi, .1);
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 eta
= m
->eta(L
, W
, 0., par_scope
);
72 etaB
= m
->etaB(L
, W
, 0., par_scope
);
73 etaD
= m
->etaD(L
, W
, 0., par_scope
);
74 mobZero
= m
->mobZero(L
, W
, 0., par_scope
);
75 mobZeroB
= m
->mobZeroB(L
, W
, 0., par_scope
);
76 mobVdd
= m
->mobVdd(L
, W
, 0., par_scope
);
77 mobVddB
= m
->mobVddB(L
, W
, 0., par_scope
);
78 mobVddD
= m
->mobVddD(L
, W
, 0., par_scope
);
79 ugs
= m
->ugs(L
, W
, 0., par_scope
);
80 ugsB
= m
->ugsB(L
, W
, 0., par_scope
);
81 uds
= m
->uds(L
, W
, 0., par_scope
);
82 udsB
= m
->udsB(L
, W
, 0., par_scope
);
83 udsD
= m
->udsD(L
, W
, 0., par_scope
);
84 n0
= m
->n0(L
, W
, 0., par_scope
);
85 nB
= m
->nB(L
, W
, 0., par_scope
);
86 nD
= m
->nD(L
, W
, 0., par_scope
);
88 betaZero
= mobZero
* CoxWoverL
;
89 betaZeroB
= mobZeroB
* CoxWoverL
;
90 betaVdd
= mobVdd
* CoxWoverL
;
91 betaVddB
= mobVddB
* CoxWoverL
;
92 betaVddD
= mobVddD
* CoxWoverL
;
93 vt0
= vfb
+ phi
+ k1
* sqrt(phi
) - k2
* phi
;
96 /*--------------------------------------------------------------------------*/
97 TDP_BUILT_IN_MOS4::TDP_BUILT_IN_MOS4(const DEV_BUILT_IN_MOS
* d
)
98 :TDP_BUILT_IN_MOS_BASE(d
)
101 /*--------------------------------------------------------------------------*/
102 MODEL_BUILT_IN_MOS4::MODEL_BUILT_IN_MOS4(const BASE_SUBCKT
* p
)
103 :MODEL_BUILT_IN_MOS_BASE(p
),
137 if (ENV::run_mode
!= rPRE_MAIN
) {
141 set_default(&mjsw
, NA
);
142 set_default(&pb
, NA
);
143 set_default(&pbsw
, NA
);
144 set_default(&cjo
, 0.0);
145 set_default(&mos_level
, LEVEL
);
147 /*--------------------------------------------------------------------------*/
148 MODEL_BUILT_IN_MOS4::MODEL_BUILT_IN_MOS4(const MODEL_BUILT_IN_MOS4
& p
)
149 :MODEL_BUILT_IN_MOS_BASE(p
),
158 mobZeroB(p
.mobZeroB
),
183 if (ENV::run_mode
!= rPRE_MAIN
) {
185 }else{untested();//194
188 /*--------------------------------------------------------------------------*/
189 std::string
MODEL_BUILT_IN_MOS4::dev_type()const
191 if (polarity
== pN
) {
193 }else if (polarity
== pP
) {
195 }else{untested();//235
196 return MODEL_BUILT_IN_MOS_BASE::dev_type();
199 /*--------------------------------------------------------------------------*/
200 void MODEL_BUILT_IN_MOS4::set_dev_type(const std::string
& new_type
)
202 if (Umatch(new_type
, "nmos4 ")) {
204 }else if (Umatch(new_type
, "pmos4 ")) {
207 MODEL_BUILT_IN_MOS_BASE::set_dev_type(new_type
);
210 /*--------------------------------------------------------------------------*/
211 void MODEL_BUILT_IN_MOS4::precalc_first()
213 const CARD_LIST
* par_scope
= scope();
215 MODEL_BUILT_IN_MOS_BASE::precalc_first();
216 e_val(&(this->dl_u
), 0., par_scope
);
217 e_val(&(this->dw_u
), 0., par_scope
);
218 e_val(&(this->tox_u
), 0., par_scope
);
219 e_val(&(this->vdd
), 0., par_scope
);
220 e_val(&(this->wdf
), 0., par_scope
);
221 e_val(&(this->dell
), 0., par_scope
);
222 e_val(&(this->temp
), 300.15, par_scope
);
223 e_val(&(this->xpart
), 0., par_scope
);
224 // final adjust: code_pre
225 // final adjust: override
234 //pb = std::max(pb, 0.1);
239 //pbsw = std::max(pbsw, 0.1);
240 cmodel
= ((!cmodel
)?1:cmodel
);
242 e_val(&(this->dl_u
), 0., par_scope
);
243 e_val(&(this->dw_u
), 0., par_scope
);
244 e_val(&(this->tox_u
), 0., par_scope
);
245 //this->tox_u = std::max(tox_u, 1e-20);
246 e_val(&(this->vdd
), 0., par_scope
);
247 e_val(&(this->wdf
), 0., par_scope
);
248 e_val(&(this->dell
), 0., par_scope
);
249 e_val(&(this->temp
), 300.15, par_scope
);
250 e_val(&(this->xpart
), 0., par_scope
);
252 // final adjust: calculated
253 dl
= dl_u
*MICRON2METER
;
254 dw
= dw_u
*MICRON2METER
;
255 tox
= tox_u
*MICRON2METER
;
256 cox
= 3.453e-11 /*E_OX*/ / tox
;
257 // final adjust: post
258 // final adjust: done
260 /*--------------------------------------------------------------------------*/
261 void MODEL_BUILT_IN_MOS4::precalc_last()
263 MODEL_BUILT_IN_MOS_BASE::precalc_last();
265 /*--------------------------------------------------------------------------*/
266 SDP_CARD
* MODEL_BUILT_IN_MOS4::new_sdp(COMMON_COMPONENT
* c
)const
269 if (COMMON_BUILT_IN_MOS
* cc
= dynamic_cast<COMMON_BUILT_IN_MOS
*>(c
)) {
275 return new SDP_BUILT_IN_MOS4(c
);
278 return MODEL_BUILT_IN_MOS_BASE::new_sdp(c
);
281 /*--------------------------------------------------------------------------*/
282 void MODEL_BUILT_IN_MOS4::set_param_by_index(int i
, std::string
& value
, int offset
)
284 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i
) {
285 case 0: level
= value
; break; //4
286 case 1: unreachable(); break;
287 case 2: unreachable(); break;
288 case 3: unreachable(); break;
289 case 4: unreachable(); break;
290 case 5: unreachable(); break;
291 case 6: mos_level
= value
; break;
292 case 7: phi
.set_nom(value
); break;
293 case 8: phi
.set_w(value
); break;
294 case 9: phi
.set_l(value
); break;
295 case 10: phi
.set_p(value
); break;
296 case 11: vfb
.set_nom(value
); break;
297 case 12: vfb
.set_w(value
); break;
298 case 13: vfb
.set_l(value
); break;
299 case 14: vfb
.set_p(value
); break;
300 case 15: k1
.set_nom(value
); break;
301 case 16: k1
.set_w(value
); break;
302 case 17: k1
.set_l(value
); break;
303 case 18: k1
.set_p(value
); break;
304 case 19: k2
.set_nom(value
); break;
305 case 20: k2
.set_w(value
); break;
306 case 21: k2
.set_l(value
); break;
307 case 22: k2
.set_p(value
); break;
308 case 23: eta
.set_nom(value
); break;
309 case 24: eta
.set_w(value
); break;
310 case 25: eta
.set_l(value
); break;
311 case 26: eta
.set_p(value
); break;
312 case 27: etaB
.set_nom(value
); break;
313 case 28: etaB
.set_w(value
); break;
314 case 29: etaB
.set_l(value
); break;
315 case 30: etaB
.set_p(value
); break;
316 case 31: etaD
.set_nom(value
); break;
317 case 32: etaD
.set_w(value
); break;
318 case 33: etaD
.set_l(value
); break;
319 case 34: etaD
.set_p(value
); break;
320 case 35: mobZero
.set_nom(value
); break;
321 case 36: mobZero
.set_w(value
); break;
322 case 37: mobZero
.set_l(value
); break;
323 case 38: mobZero
.set_p(value
); break;
324 case 39: mobZeroB
.set_nom(value
); break;
325 case 40: mobZeroB
.set_w(value
); break;
326 case 41: mobZeroB
.set_l(value
); break;
327 case 42: mobZeroB
.set_p(value
); break;
328 case 43: mobVdd
.set_nom(value
); break;
329 case 44: mobVdd
.set_w(value
); break;
330 case 45: mobVdd
.set_l(value
); break;
331 case 46: mobVdd
.set_p(value
); break;
332 case 47: mobVddB
.set_nom(value
); break;
333 case 48: mobVddB
.set_w(value
); break;
334 case 49: mobVddB
.set_l(value
); break;
335 case 50: mobVddB
.set_p(value
); break;
336 case 51: mobVddD
.set_nom(value
); break;
337 case 52: mobVddD
.set_w(value
); break;
338 case 53: mobVddD
.set_l(value
); break;
339 case 54: mobVddD
.set_p(value
); break;
340 case 55: ugs
.set_nom(value
); break;
341 case 56: ugs
.set_w(value
); break;
342 case 57: ugs
.set_l(value
); break;
343 case 58: ugs
.set_p(value
); break;
344 case 59: ugsB
.set_nom(value
); break;
345 case 60: ugsB
.set_w(value
); break;
346 case 61: ugsB
.set_l(value
); break;
347 case 62: ugsB
.set_p(value
); break;
348 case 63: uds
.set_nom(value
); break;
349 case 64: uds
.set_w(value
); break;
350 case 65: uds
.set_l(value
); break;
351 case 66: uds
.set_p(value
); break;
352 case 67: udsB
.set_nom(value
); break;
353 case 68: udsB
.set_w(value
); break;
354 case 69: udsB
.set_l(value
); break;
355 case 70: udsB
.set_p(value
); break;
356 case 71: udsD
.set_nom(value
); break;
357 case 72: udsD
.set_w(value
); break;
358 case 73: udsD
.set_l(value
); break;
359 case 74: udsD
.set_p(value
); break;
360 case 75: n0
.set_nom(value
); break;
361 case 76: n0
.set_w(value
); break;
362 case 77: n0
.set_l(value
); break;
363 case 78: n0
.set_p(value
); break;
364 case 79: nB
.set_nom(value
); break;
365 case 80: nB
.set_w(value
); break;
366 case 81: nB
.set_l(value
); break;
367 case 82: nB
.set_p(value
); break;
368 case 83: nD
.set_nom(value
); break;
369 case 84: nD
.set_w(value
); break;
370 case 85: nD
.set_l(value
); break;
371 case 86: nD
.set_p(value
); break;
372 case 87: dl_u
= value
; break;
373 case 88: dw_u
= value
; break;
374 case 89: tox_u
= value
; break;
375 case 90: vdd
= value
; break;
376 case 91: wdf
= value
; break;
377 case 92: dell
= value
; break;
378 case 93: temp
= value
; break;
379 case 94: xpart
= value
; break;
380 default: MODEL_BUILT_IN_MOS_BASE::set_param_by_index(i
, value
, offset
); break;
383 /*--------------------------------------------------------------------------*/
384 bool MODEL_BUILT_IN_MOS4::param_is_printable(int i
)const
386 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i
) {
387 case 0: return (true);
388 case 1: return (false);
389 case 2: return (false);
390 case 3: return (false);
391 case 4: return (false);
392 case 5: return (false);
393 case 6: return (mos_level
!= LEVEL
);
394 case 7: return (true);
395 case 8: return (phi
.w_has_value());
396 case 9: return (phi
.l_has_value());
397 case 10: return (phi
.p_has_value());
398 case 11: return (true);
399 case 12: return (vfb
.w_has_value());
400 case 13: return (vfb
.l_has_value());
401 case 14: return (vfb
.p_has_value());
402 case 15: return (true);
403 case 16: return (k1
.w_has_value());
404 case 17: return (k1
.l_has_value());
405 case 18: return (k1
.p_has_value());
406 case 19: return (true);
407 case 20: return (k2
.w_has_value());
408 case 21: return (k2
.l_has_value());
409 case 22: return (k2
.p_has_value());
410 case 23: return (true);
411 case 24: return (eta
.w_has_value());
412 case 25: return (eta
.l_has_value());
413 case 26: return (eta
.p_has_value());
414 case 27: return (true);
415 case 28: return (etaB
.w_has_value());
416 case 29: return (etaB
.l_has_value());
417 case 30: return (etaB
.p_has_value());
418 case 31: return (true);
419 case 32: return (etaD
.w_has_value());
420 case 33: return (etaD
.l_has_value());
421 case 34: return (etaD
.p_has_value());
422 case 35: return (true);
423 case 36: return (mobZero
.w_has_value());
424 case 37: return (mobZero
.l_has_value());
425 case 38: return (mobZero
.p_has_value());
426 case 39: return (true);
427 case 40: return (mobZeroB
.w_has_value());
428 case 41: return (mobZeroB
.l_has_value());
429 case 42: return (mobZeroB
.p_has_value());
430 case 43: return (true);
431 case 44: return (mobVdd
.w_has_value());
432 case 45: return (mobVdd
.l_has_value());
433 case 46: return (mobVdd
.p_has_value());
434 case 47: return (true);
435 case 48: return (mobVddB
.w_has_value());
436 case 49: return (mobVddB
.l_has_value());
437 case 50: return (mobVddB
.p_has_value());
438 case 51: return (true);
439 case 52: return (mobVddD
.w_has_value());
440 case 53: return (mobVddD
.l_has_value());
441 case 54: return (mobVddD
.p_has_value());
442 case 55: return (true);
443 case 56: return (ugs
.w_has_value());
444 case 57: return (ugs
.l_has_value());
445 case 58: return (ugs
.p_has_value());
446 case 59: return (true);
447 case 60: return (ugsB
.w_has_value());
448 case 61: return (ugsB
.l_has_value());
449 case 62: return (ugsB
.p_has_value());
450 case 63: return (true);
451 case 64: return (uds
.w_has_value());
452 case 65: return (uds
.l_has_value());
453 case 66: return (uds
.p_has_value());
454 case 67: return (true);
455 case 68: return (udsB
.w_has_value());
456 case 69: return (udsB
.l_has_value());
457 case 70: return (udsB
.p_has_value());
458 case 71: return (true);
459 case 72: return (udsD
.w_has_value());
460 case 73: return (udsD
.l_has_value());
461 case 74: return (udsD
.p_has_value());
462 case 75: return (true);
463 case 76: return (n0
.w_has_value());
464 case 77: return (n0
.l_has_value());
465 case 78: return (n0
.p_has_value());
466 case 79: return (true);
467 case 80: return (nB
.w_has_value());
468 case 81: return (nB
.l_has_value());
469 case 82: return (nB
.p_has_value());
470 case 83: return (true);
471 case 84: return (nD
.w_has_value());
472 case 85: return (nD
.l_has_value());
473 case 86: return (nD
.p_has_value());
474 case 87: return (true);
475 case 88: return (true);
476 case 89: return (true);
477 case 90: return (true);
478 case 91: return (true);
479 case 92: return (true);
480 case 93: return (true);
481 case 94: return (true);
482 default: return MODEL_BUILT_IN_MOS_BASE::param_is_printable(i
);
485 /*--------------------------------------------------------------------------*/
486 std::string
MODEL_BUILT_IN_MOS4::param_name(int i
)const
488 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i
) {
489 case 0: return "level";
490 case 1: return "=====";
491 case 2: return "=====";
492 case 3: return "=====";
493 case 4: return "=====";
494 case 5: return "=====";
495 case 6: return "diodelevel";
496 case 7: return "phi";
497 case 8: return "wphi";
498 case 9: return "lphi";
499 case 10: return "pphi";
500 case 11: return "vfb";
501 case 12: return "wvfb";
502 case 13: return "lvfb";
503 case 14: return "pvfb";
504 case 15: return "k1";
505 case 16: return "wk1";
506 case 17: return "lk1";
507 case 18: return "pk1";
508 case 19: return "k2";
509 case 20: return "wk2";
510 case 21: return "lk2";
511 case 22: return "pk2";
512 case 23: return "eta";
513 case 24: return "weta";
514 case 25: return "leta";
515 case 26: return "peta";
516 case 27: return "x2e";
517 case 28: return "wx2e";
518 case 29: return "lx2e";
519 case 30: return "px2e";
520 case 31: return "x3e";
521 case 32: return "wx3e";
522 case 33: return "lx3e";
523 case 34: return "px3e";
524 case 35: return "muz";
525 case 36: return "wmuz";
526 case 37: return "lmuz";
527 case 38: return "pmuz";
528 case 39: return "x2mz";
529 case 40: return "wx2mz";
530 case 41: return "lx2mz";
531 case 42: return "px2mz";
532 case 43: return "mus";
533 case 44: return "wmus";
534 case 45: return "lmus";
535 case 46: return "pmus";
536 case 47: return "x2ms";
537 case 48: return "wx2ms";
538 case 49: return "lx2ms";
539 case 50: return "px2ms";
540 case 51: return "x3ms";
541 case 52: return "wx3ms";
542 case 53: return "lx3ms";
543 case 54: return "px3ms";
544 case 55: return "u0";
545 case 56: return "wu0";
546 case 57: return "lu0";
547 case 58: return "pu0";
548 case 59: return "x2u0";
549 case 60: return "wx2u0";
550 case 61: return "lx2u0";
551 case 62: return "px2u0";
552 case 63: return "u1";
553 case 64: return "wu1";
554 case 65: return "lu1";
555 case 66: return "pu1";
556 case 67: return "x2u1";
557 case 68: return "wx2u1";
558 case 69: return "lx2u1";
559 case 70: return "px2u1";
560 case 71: return "x3u1";
561 case 72: return "wx3u1";
562 case 73: return "lx3u1";
563 case 74: return "px3u1";
564 case 75: return "n0";
565 case 76: return "wn0";
566 case 77: return "ln0";
567 case 78: return "pn0";
568 case 79: return "nb";
569 case 80: return "wnb";
570 case 81: return "lnb";
571 case 82: return "pnb";
572 case 83: return "nd";
573 case 84: return "wnd";
574 case 85: return "lnd";
575 case 86: return "pnd";
576 case 87: return "dl";
577 case 88: return "dw";
578 case 89: return "tox";
579 case 90: return "vdd";
580 case 91: return "wdf";
581 case 92: return "dell";
582 case 93: return "temp";
583 case 94: return "xpart";
584 default: return MODEL_BUILT_IN_MOS_BASE::param_name(i
);
587 /*--------------------------------------------------------------------------*/
588 std::string
MODEL_BUILT_IN_MOS4::param_name(int i
, int j
)const
591 return param_name(i
);
593 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i
) {
689 default: return MODEL_BUILT_IN_MOS_BASE::param_name(i
, j
);
694 return MODEL_BUILT_IN_MOS_BASE::param_name(i
, j
);
697 /*--------------------------------------------------------------------------*/
698 std::string
MODEL_BUILT_IN_MOS4::param_value(int i
)const
700 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i
) {
702 case 1: unreachable(); return "";
703 case 2: unreachable(); return "";
704 case 3: unreachable(); return "";
705 case 4: unreachable(); return "";
706 case 5: unreachable(); return "";
707 case 6: return mos_level
.string();
708 case 7: return phi
.string();
709 case 8: return phi
.w_string();
710 case 9: return phi
.l_string();
711 case 10: return phi
.p_string();
712 case 11: return vfb
.string();
713 case 12: return vfb
.w_string();
714 case 13: return vfb
.l_string();
715 case 14: return vfb
.p_string();
716 case 15: return k1
.string();
717 case 16: return k1
.w_string();
718 case 17: return k1
.l_string();
719 case 18: return k1
.p_string();
720 case 19: return k2
.string();
721 case 20: return k2
.w_string();
722 case 21: return k2
.l_string();
723 case 22: return k2
.p_string();
724 case 23: return eta
.string();
725 case 24: return eta
.w_string();
726 case 25: return eta
.l_string();
727 case 26: return eta
.p_string();
728 case 27: return etaB
.string();
729 case 28: return etaB
.w_string();
730 case 29: return etaB
.l_string();
731 case 30: return etaB
.p_string();
732 case 31: return etaD
.string();
733 case 32: return etaD
.w_string();
734 case 33: return etaD
.l_string();
735 case 34: return etaD
.p_string();
736 case 35: return mobZero
.string();
737 case 36: return mobZero
.w_string();
738 case 37: return mobZero
.l_string();
739 case 38: return mobZero
.p_string();
740 case 39: return mobZeroB
.string();
741 case 40: return mobZeroB
.w_string();
742 case 41: return mobZeroB
.l_string();
743 case 42: return mobZeroB
.p_string();
744 case 43: return mobVdd
.string();
745 case 44: return mobVdd
.w_string();
746 case 45: return mobVdd
.l_string();
747 case 46: return mobVdd
.p_string();
748 case 47: return mobVddB
.string();
749 case 48: return mobVddB
.w_string();
750 case 49: return mobVddB
.l_string();
751 case 50: return mobVddB
.p_string();
752 case 51: return mobVddD
.string();
753 case 52: return mobVddD
.w_string();
754 case 53: return mobVddD
.l_string();
755 case 54: return mobVddD
.p_string();
756 case 55: return ugs
.string();
757 case 56: return ugs
.w_string();
758 case 57: return ugs
.l_string();
759 case 58: return ugs
.p_string();
760 case 59: return ugsB
.string();
761 case 60: return ugsB
.w_string();
762 case 61: return ugsB
.l_string();
763 case 62: return ugsB
.p_string();
764 case 63: return uds
.string();
765 case 64: return uds
.w_string();
766 case 65: return uds
.l_string();
767 case 66: return uds
.p_string();
768 case 67: return udsB
.string();
769 case 68: return udsB
.w_string();
770 case 69: return udsB
.l_string();
771 case 70: return udsB
.p_string();
772 case 71: return udsD
.string();
773 case 72: return udsD
.w_string();
774 case 73: return udsD
.l_string();
775 case 74: return udsD
.p_string();
776 case 75: return n0
.string();
777 case 76: return n0
.w_string();
778 case 77: return n0
.l_string();
779 case 78: return n0
.p_string();
780 case 79: return nB
.string();
781 case 80: return nB
.w_string();
782 case 81: return nB
.l_string();
783 case 82: return nB
.p_string();
784 case 83: return nD
.string();
785 case 84: return nD
.w_string();
786 case 85: return nD
.l_string();
787 case 86: return nD
.p_string();
788 case 87: return dl_u
.string();
789 case 88: return dw_u
.string();
790 case 89: return tox_u
.string();
791 case 90: return vdd
.string();
792 case 91: return wdf
.string();
793 case 92: return dell
.string();
794 case 93: return temp
.string();
795 case 94: return xpart
.string();
796 default: return MODEL_BUILT_IN_MOS_BASE::param_value(i
);
799 /*--------------------------------------------------------------------------*/
800 bool MODEL_BUILT_IN_MOS4::is_valid(const COMPONENT
* d
)const
803 return MODEL_BUILT_IN_MOS_BASE::is_valid(d
);
805 /*--------------------------------------------------------------------------*/
806 void MODEL_BUILT_IN_MOS4::tr_eval(COMPONENT
* brh
)const
808 DEV_BUILT_IN_MOS
* d
= prechecked_cast
<DEV_BUILT_IN_MOS
*>(brh
);
810 const COMMON_BUILT_IN_MOS
* c
= prechecked_cast
<const COMMON_BUILT_IN_MOS
*>(d
->common());
812 const SDP_BUILT_IN_MOS4
* s
= prechecked_cast
<const SDP_BUILT_IN_MOS4
*>(c
->sdp());
814 const MODEL_BUILT_IN_MOS4
* m
= this;
816 trace3("", d
->vds
, d
->vgs
, d
->vbs
);
817 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
818 d
->reverse_if_needed();
819 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
820 trace2("", m
->dl
, m
->dw
);
821 trace3("", s
->ugs
, s
->ugsB
, d
->vbs
);
822 double Ugs
= s
->ugs
+ s
->ugsB
* d
->vbs
;
831 trace2("", Ugs
, dUgsdVbs
);
833 double Uds
= s
->uds
+ s
->udsB
* d
->vbs
+ s
->udsD
* (d
->vds
- m
->vdd
);
839 dUdsdVbs
= dUdsdVds
= 0.0;
841 double Leff
= s
->l_eff
* 1e6
; /* Leff in um */
843 dUdsdVbs
= s
->udsB
/ Leff
;
844 dUdsdVds
= s
->udsD
/ Leff
;
846 trace3("", Uds
, dUdsdVbs
, dUdsdVds
);
850 Vpb
= s
->phi
- d
->vbs
;
856 double SqrtVpb
= sqrt(Vpb
);
857 trace2("", Vpb
, SqrtVpb
);
858 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
859 /* threshold voltage */
863 double Eta
= s
->eta
+ s
->etaB
* d
->vbs
+ s
->etaD
* (d
->vds
- m
->vdd
);
868 dEtadVds
= dEtadVbs
= 0.0 ;
872 dEtadVds
= dEtadVbs
= 0;
878 trace3("", Eta
, dEtadVds
, dEtadVbs
);
879 d
->von
= s
->vfb
+ s
->phi
+ s
->k1
* SqrtVpb
- s
->k2
* Vpb
- Eta
* d
->vds
;
880 dVthdVds
= -Eta
- dEtadVds
* d
->vds
;
881 dVthdVbs
= s
->k2
- 0.5 * s
->k1
/ SqrtVpb
- dEtadVbs
* d
->vds
;
882 d
->vgst
= d
->vgs
- d
->von
;
883 trace4("", d
->von
, dVthdVds
, dVthdVbs
, d
->vgst
);
885 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
886 double G
= 1. - 1./(1.744+0.8364 * Vpb
);
887 double A
= 1. + 0.5*G
*s
->k1
/SqrtVpb
;
888 A
= std::max(A
, 1.0); /* Modified */
889 double Arg
= std::max((1 + Ugs
* d
->vgst
), 1.0);
890 double dGdVbs
= -0.8364 * (1-G
) * (1-G
);
891 double dAdVbs
= 0.25 * s
->k1
/ SqrtVpb
*(2*dGdVbs
+ G
/Vpb
);
892 trace3("", G
, A
, Arg
);
893 trace2("", dGdVbs
, dAdVbs
);
894 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
895 /* ids and derivatives calculation */
904 trace4("cutoff", d
->ids
, d
->gmf
, d
->gds
, d
->gmbf
);
907 /* Quadratic Interpolation for Beta0 (Beta at d->vgs = 0, vds=Vds) */
912 trace2("", m
->tox
, m
->cox
*1e-4);
913 trace3("", s
->betaVdd
, s
->betaVddB
, d
->vbs
);
914 double BetaVdd
= (s
->betaVdd
+ s
->betaVddB
* d
->vbs
);
915 double dBetaVdd_dVds
= std::max(s
->betaVddD
, 0.0); /* Modified */
916 trace2("", BetaVdd
, dBetaVdd_dVds
);
917 if(d
->vds
> m
->vdd
) {
918 Beta0
= BetaVdd
+ dBetaVdd_dVds
* (d
->vds
- m
->vdd
);
919 dBeta0dVds
= dBetaVdd_dVds
;
920 dBeta0dVbs
= s
->betaVddB
;
921 trace3("vds>vdd", Beta0
, dBeta0dVds
, dBeta0dVbs
);
923 double Beta_Vds_0
= (s
->betaZero
+ s
->betaZeroB
* d
->vbs
);
924 double VddSquare
= m
->vdd
* m
->vdd
;
925 double C1
= (-BetaVdd
+ Beta_Vds_0
+dBetaVdd_dVds
*m
->vdd
) / VddSquare
;
926 double C2
= 2 * (BetaVdd
- Beta_Vds_0
) / m
->vdd
- dBetaVdd_dVds
;
927 trace4("", Beta_Vds_0
, VddSquare
, C1
, C2
);
928 double dBeta_Vds_0_dVbs
= s
->betaZeroB
;
929 double dBetaVdd_dVbs
= s
->betaVddB
;
930 double dC1dVbs
= (dBeta_Vds_0_dVbs
- dBetaVdd_dVbs
) / VddSquare
;
931 double dC2dVbs
= dC1dVbs
* (-2) * m
->vdd
;
932 trace4("", dBeta_Vds_0_dVbs
, dBetaVdd_dVbs
, dC1dVbs
, dC2dVbs
);
933 Beta0
= (C1
* d
->vds
+ C2
) * d
->vds
+ Beta_Vds_0
;
934 dBeta0dVds
= 2*C1
*d
->vds
+ C2
;
935 dBeta0dVbs
= dC1dVbs
* d
->vds
* d
->vds
936 + dC2dVbs
* d
->vds
+ dBeta_Vds_0_dVbs
;
937 trace3("vds<vdd", Beta0
, dBeta0dVds
, dBeta0dVbs
);
941 /*Beta = Beta0 / ( 1 + Ugs * d->vgst );*/
942 double Beta
= Beta0
/ Arg
;
943 double dBetadVgs
= -Beta
* Ugs
/ Arg
;
944 double dBetadVds
= dBeta0dVds
/ Arg
- dBetadVgs
* dVthdVds
;
945 double dBetadVbs
= dBeta0dVbs
/ Arg
946 + Beta
* Ugs
* dVthdVbs
/ Arg
- Beta
* d
->vgst
* dUgsdVbs
/ Arg
;
947 trace4("", Beta
, dBetadVgs
, dBetadVds
, dBetadVbs
);
949 /*d->vdsat = std::max(d->vgst / ( A + Uds * d->vgst ), 0.0);*/
950 double Vc
= Uds
* d
->vgst
/ A
;
956 double Term1
= sqrt(1 + 2 * Vc
);
957 double K
= 0.5 * (1 + Vc
+ Term1
);
958 d
->vdsat
= std::max(d
->vgst
/ (A
* sqrt(K
)) , 0.0);
959 trace4("", Vc
, Term1
, K
, d
->vdsat
);
961 if(d
->vds
< d
->vdsat
) { /* Triode Region */
962 d
->saturated
= false;
963 /*Argl1 = 1 + Uds * d->vds;*/
964 double Argl1
= std::max((1 + Uds
* d
->vds
), (hp_float_t
)1.);
965 double Argl2
= d
->vgst
- 0.5 * A
* d
->vds
;
966 trace2("", Argl1
, Argl2
);
967 d
->ids
= Beta
* Argl2
* d
->vds
/ Argl1
;
968 d
->gmf
= (dBetadVgs
* Argl2
* d
->vds
+ Beta
* d
->vds
) / Argl1
;
969 d
->gds
= (dBetadVds
* Argl2
* d
->vds
970 + Beta
* (d
->vgst
- d
->vds
* dVthdVds
- A
* d
->vds
)
971 - d
->ids
* (d
->vds
* dUdsdVds
+ Uds
)) / Argl1
;
972 d
->gmbf
= (dBetadVbs
* Argl2
* d
->vds
973 + Beta
* d
->vds
* (-dVthdVbs
- 0.5 * d
->vds
* dAdVbs
)
974 - d
->ids
* d
->vds
* dUdsdVbs
) / Argl1
;
975 trace4("triode", d
->ids
, d
->gmf
, d
->gds
, d
->gmbf
);
976 }else{ /* Pinchoff (Saturation) Region */
978 double Args1
= 1. + 1. / Term1
;
979 double dVcdVgs
= Uds
/ A
;
980 double dVcdVds
= d
->vgst
* dUdsdVds
/ A
- dVcdVgs
* dVthdVds
;
981 double dVcdVbs
= (d
->vgst
* dUdsdVbs
982 - Uds
* (dVthdVbs
+ d
->vgst
* dAdVbs
/ A
)) / A
;
983 double dKdVc
= 0.5 * Args1
;
984 double dKdVgs
= dKdVc
* dVcdVgs
;
985 double dKdVds
= dKdVc
* dVcdVds
;
986 double dKdVbs
= dKdVc
* dVcdVbs
;
987 double Args2
= d
->vgst
/ A
/ K
;
988 double Args3
= Args2
* d
->vgst
;
989 trace3("", Args1
, Args2
, Args3
);
990 trace3("", dVcdVgs
, dVcdVds
, dVcdVbs
);
991 trace4("", dKdVc
, dKdVgs
, dKdVds
, dKdVbs
);
992 d
->ids
= 0.5 * Beta
* Args3
;
993 d
->gmf
= 0.5 * Args3
* dBetadVgs
+ Beta
* Args2
- d
->ids
* dKdVgs
/ K
;
994 d
->gds
= 0.5*Args3
*dBetadVds
- Beta
*Args2
*dVthdVds
- d
->ids
*dKdVds
/K
;
995 d
->gmbf
= 0.5 * dBetadVbs
* Args3
- Beta
* Args2
*dVthdVbs
996 - d
->ids
* (dAdVbs
/ A
+ dKdVbs
/ K
);
997 trace4("sat", d
->ids
, d
->gmf
, d
->gds
, d
->gmbf
);
1000 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1001 /* SubthresholdComputation */
1003 /* The following 'if' statement has been modified so that subthreshold *
1004 * current computation is always executed unless N0 >= 200. This should *
1005 * get rid of the Ids kink seen on Ids-Vgs plots at low Vds. *
1008 * Old 'if' statement: (reversed) *
1009 * if( (N0 >= 200) || (d->vgst < Vcut ) || (d->vgst > (-0.5*Vcut))) */
1011 //double Vcut = - 40. * s->n0 * t->vt ;
1013 double N
= s
->n0
+ s
->nB
*d
->vbs
+ s
->nD
*d
->vds
; /* subthreshold slope */
1014 trace4("", s
->n0
, s
->nB
, s
->nD
, N
);
1019 const double ref_temp
= 300.15; // ignore real temp for spice compatibility
1020 const double vt0
= ref_temp
* P_K_Q
;
1021 const double Vtsquare
= vt0
* vt0
;
1022 const double nvt0
= N
* vt0
;
1023 double Warg1
= exp(-d
->vds
/ vt0
);
1024 double Wds
= 1 - Warg1
;
1025 double Wgs
= exp( d
->vgst
/ nvt0
);
1026 double Warg2
= 6.04965 * Vtsquare
* s
->betaZero
;
1027 double Ilimit
= 4.5 * Vtsquare
* s
->betaZero
;
1028 double Iexp
= Warg2
* Wgs
* Wds
;
1029 d
->ids
+= Ilimit
* Iexp
/ (Ilimit
+ Iexp
);
1030 double Temp1
= Ilimit
/ (Ilimit
+ Iexp
);
1031 Temp1
= Temp1
* Temp1
;
1032 double Temp3
= Ilimit
/ (Ilimit
+ Wgs
* Warg2
);
1033 Temp3
= Temp3
* Temp3
* Warg2
* Wgs
;
1034 /* if ( Temp3 > Ilimit ) Temp3=Ilimit;*/
1035 d
->gmf
+= Temp1
* Iexp
/ nvt0
;
1036 /* gds term has been modified to prevent blow up at Vds=0 */
1038 * (Wds
/ nvt0
* (dVthdVds
+ d
->vgst
* s
->nD
/ N
)
1040 d
->gmbf
-= Temp1
* Iexp
* (dVthdVbs
+ d
->vgst
* s
->nB
/ N
) / nvt0
;
1041 trace3("", vt0
, Vtsquare
, nvt0
);
1042 trace4("", Warg1
, Wds
, Wgs
, Warg2
);
1043 trace4("", Ilimit
, Iexp
, Temp1
, Temp3
);
1044 trace4("sub", d
->ids
, d
->gmf
, d
->gds
, d
->gmbf
);
1048 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1049 /* Some Limiting of DC Parameters */
1050 if(d
->ids
< 0.0) d
->ids
= 0.0;
1051 if(d
->gmf
< 0.0) d
->gmf
= 0.0;
1052 if(d
->gds
< 0.0) d
->gds
= 0.0;
1053 if(d
->gmbf
< 0.0) d
->gmbf
= 0.0;
1054 trace4("final", d
->ids
, d
->gmf
, d
->gds
, d
->gmbf
);
1056 trace3("", G
, A
, s
->phi
);
1057 trace1("", m
->xpart
);
1059 double Vth0
= s
->vfb
+ s
->phi
+ s
->k1
* SqrtVpb
; // almost same as d->von
1060 double Vgs_Vth
= d
->vgs
- Vth0
; // almost same as d->vgst
1061 trace2("", Vth0
, Vgs_Vth
);
1062 double Arg1
= A
* d
->vds
;
1063 double Arg2
= Vgs_Vth
- 0.5 * Arg1
;
1064 double Arg3
= d
->vds
- Arg1
;
1065 trace3("", Arg1
, Arg2
, Arg3
);
1066 /*double*/ dVthdVbs
= -0.5 * s
->k1
/ SqrtVpb
;
1067 /*dbl*/ dAdVbs
= 0.5 * s
->k1
* (0.5*G
/Vpb
- 0.8364*(1-G
)*(1-G
)) / SqrtVpb
;
1068 trace2("", dVthdVbs
, dAdVbs
);
1069 double Ent
= std::max(Arg2
,1.0e-8);
1070 double dEntdVds
= -0.5 * A
;
1071 double dEntdVbs
= -dVthdVbs
- 0.5 * d
->vds
* dAdVbs
;
1072 trace3("", Ent
, dEntdVds
, dEntdVbs
);
1073 double VdsPinchoff
= std::max(Vgs_Vth
/ A
, 0.0);
1074 double Vgb
= d
->vgs
- d
->vbs
;
1075 double Vgb_Vfb
= Vgb
- s
->vfb
;
1076 trace3("", VdsPinchoff
, Vgb
, Vgb_Vfb
);
1078 if(Vgb_Vfb
< 0) { /* Accumulation Region */
1080 d
->qgate
= s
->cgate
* Vgb_Vfb
;
1081 d
->qbulk
= -d
->qgate
;
1086 d
->cbgb
= -s
->cgate
;
1092 trace4("", d
->qgate
, d
->cggb
, d
->cgdb
, d
->cgsb
);
1093 trace4("", d
->qbulk
, d
->cbgb
, d
->cbdb
, d
->cbsb
);
1094 trace4("acc", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1095 }else if (d
->vgs
< Vth0
) { /* Subthreshold Region */
1096 d
->qgate
= 0.5*s
->cgate
*s
->k1
*s
->k1
*(-1+sqrt(1+4*Vgb_Vfb
/(s
->k1
*s
->k1
)));
1097 d
->cggb
= s
->cgate
/ sqrt(1 + 4 * Vgb_Vfb
/ (s
->k1
* s
->k1
));
1098 d
->cgdb
= d
->cgsb
= 0.;
1099 d
->qbulk
= -d
->qgate
;
1101 d
->cbdb
= d
->cbsb
= 0.0;
1103 d
->cdgb
= d
->cddb
= d
->cdsb
= 0.0;
1104 trace4("", d
->qgate
, d
->cggb
, d
->cgdb
, d
->cgsb
);
1105 trace4("", d
->qbulk
, d
->cbgb
, d
->cbdb
, d
->cbsb
);
1106 trace4("sub", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1107 }else if (d
->vds
< VdsPinchoff
) { /* triode region */
1108 double EntSquare
= Ent
* Ent
;
1109 trace1("tri", EntSquare
);
1110 double Argl1
= 1.2e1
* EntSquare
;
1111 double Argl2
= 1.0 - A
;
1112 double Argl3
= Arg1
* d
->vds
;
1113 trace3("", Argl1
, Argl2
, Argl3
);
1121 double Argl7
= Argl5
/ 1.2e1
;
1122 double Argl8
= 6.0 * Ent
;
1123 trace3("", Argl5
, Argl7
, Argl8
);
1126 * (d
->vgs
- s
->vfb
- s
->phi
- 0.5 * d
->vds
+ d
->vds
* Argl7
);
1127 d
->cggb
= s
->cgate
* (1.0 - Argl3
/ Argl1
);
1128 d
->cgdb
= s
->cgate
* (-0.5 + Arg1
/ Argl8
- Argl3
* dEntdVds
/ Argl1
);
1129 double cgbb
= s
->cgate
* (d
->vds
*d
->vds
*dAdVbs
*Ent
-Argl3
*dEntdVbs
)/Argl1
;
1130 d
->cgsb
= -(d
->cggb
+ d
->cgdb
+ cgbb
);
1131 trace4("", d
->qgate
, d
->cggb
, d
->cgdb
, d
->cgsb
);
1133 d
->qbulk
= s
->cgate
* (-Vth0
+ s
->vfb
+ s
->phi
+ 0.5*Arg3
- Arg3
*Argl7
);
1134 d
->cbgb
= s
->cgate
* Argl3
* Argl2
/ Argl1
;
1135 d
->cbdb
= s
->cgate
* Argl2
* (0.5 - Arg1
/Argl8
+ Argl3
* dEntdVds
/Argl1
);
1136 double cbbb
= -s
->cgate
* (dVthdVbs
+ 0.5 * d
->vds
* dAdVbs
1137 +d
->vds
*d
->vds
*((1.0-2.0*A
)*dAdVbs
*Ent
-Argl2
*A
*dEntdVbs
)/Argl1
);
1138 d
->cbsb
= -(d
->cbgb
+ d
->cbdb
+ cbbb
);
1139 trace4("", d
->qbulk
, d
->cbgb
, d
->cbdb
, d
->cbsb
);
1141 if (m
->xpart
>= 1) {
1142 /*0/100 partitioning for drain/source chArges at saturation region*/
1143 double Argl9
= 0.125 * Argl5
* Argl5
; //t
1144 d
->qdrn
= -s
->cgate
* (0.5*Vgs_Vth
- 0.75*Arg1
+ 0.125*Arg1
*Argl5
);
1145 d
->cdgb
= -s
->cgate
* (0.5 - Argl9
);
1146 d
->cddb
= s
->cgate
* (0.75*A
- 0.25*A
*Arg1
/Ent
+ Argl9
*dEntdVds
);
1147 double cdbb
= s
->cgate
* (0.5 * dVthdVbs
+ d
->vds
* dAdVbs
*
1148 (0.75 - 0.25 * Argl5
) + Argl9
* dEntdVbs
);
1149 d
->cdsb
= -(d
->cdgb
+ d
->cddb
+ cdbb
);
1150 trace2("", Argl9
, cdbb
);
1151 trace4("tri 0/100", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1153 /*40/60 partitioning for drain/source chArges at saturation region*/
1154 double Vgs_VthSquare
= Vgs_Vth
*Vgs_Vth
;
1155 trace2("", Vgs_Vth
, Vgs_VthSquare
);
1156 double Arg5
= Arg1
*Arg1
;
1157 double Vcom
= Vgs_Vth
*Vgs_Vth
/6.0-1.25e-1*Arg1
*Vgs_Vth
+2.5e-2*Arg5
;
1158 double Argl4
= Vcom
/Ent
/EntSquare
;
1161 Argl6
= Vcom
/ EntSquare
;
1164 Argl6
= 4.0 / 1.5e1
;
1166 d
->qdrn
= -s
->cgate
* (0.5 * (Vgs_Vth
-Arg1
) + Arg1
* Argl6
);
1168 * (0.5 + Arg1
*(4.0*Vgs_Vth
-1.5*Arg1
)/Argl1
- 2.0*Arg1
*Argl4
);
1169 d
->cddb
= s
->cgate
*(0.5*A
+2.0*Arg1
*dEntdVds
*Argl4
-A
*(2.0*Vgs_VthSquare
1170 -3.0*Arg1
*Vgs_Vth
+0.9*Arg5
)/Argl1
);
1171 double cdbb
=s
->cgate
*(0.5*dVthdVbs
+0.5*d
->vds
*dAdVbs
+2.0*Arg1
*dEntdVbs
1172 *Argl4
-d
->vds
*(2.0*Vgs_VthSquare
*dAdVbs
-4.0*A
*Vgs_Vth
*dVthdVbs
-3.0
1173 *Arg1
*Vgs_Vth
*dAdVbs
+1.5*A
*Arg1
*dVthdVbs
+0.9*Arg5
*dAdVbs
)
1175 d
->cdsb
= -(d
->cdgb
+ d
->cddb
+ cdbb
);
1176 trace4("", Vcom
, Argl4
, Argl6
, cdbb
);
1177 trace4("lin 40/60", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1179 }else{ /* saturation region */
1180 assert(d
->vds
>= VdsPinchoff
);
1181 double Args1
= 1.0 / (3.0 * A
);
1182 trace2("sat", s
->cgate
, Args1
);
1184 d
->qgate
= s
->cgate
* (d
->vgs
- s
->vfb
- s
->phi
- Vgs_Vth
* Args1
);
1185 d
->cggb
= s
->cgate
* (1.0 - Args1
);
1187 double cgbb
= s
->cgate
* Args1
* (dVthdVbs
+ Vgs_Vth
* dAdVbs
/ A
);
1188 d
->cgsb
= -(d
->cggb
+ d
->cgdb
+ cgbb
);
1189 trace4("", d
->qgate
, d
->cggb
, d
->cgdb
, d
->cgsb
);
1191 d
->qbulk
= s
->cgate
* (s
->vfb
+ s
->phi
- Vth0
+ (1.0-A
)*Vgs_Vth
*Args1
);
1192 d
->cbgb
= s
->cgate
* (Args1
- 1.0 / 3.0);
1194 double cbbb
= -s
->cgate
* ((2.0 / 3.0 + Args1
) * dVthdVbs
1195 + Vgs_Vth
* Args1
* dAdVbs
/ A
);
1196 d
->cbsb
= -(d
->cbgb
+ d
->cbdb
+ cbbb
);
1197 trace4("", d
->qbulk
, d
->cbgb
, d
->cbdb
, d
->cbsb
);
1199 if (m
->xpart
>= 1) {
1200 /*0/100 partitioning for drain/source chArges at saturation region*/
1205 trace4("sat 0/100", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1207 /*40/60 partitioning for drain/source chArges at saturation region*/
1208 const double co4v15
= 4./15.;
1209 d
->qdrn
= -co4v15
* s
->cgate
* Vgs_Vth
;
1210 d
->cdgb
= -co4v15
* s
->cgate
;
1212 double cdbb
= co4v15
* s
->cgate
* dVthdVbs
;
1213 d
->cdsb
= -(d
->cdgb
+ d
->cddb
+ cdbb
);
1214 trace4("sat 40/60", d
->qdrn
, d
->cdgb
, d
->cddb
, d
->cdsb
);
1221 d
->gmf
= d
->gmbf
= 0;
1223 d
->gmr
= d
->gmbr
= 0.;
1226 /*--------------------------------------------------------------------------*/
1227 /*--------------------------------------------------------------------------*/
1228 /*--------------------------------------------------------------------------*/
1229 /*--------------------------------------------------------------------------*/