testing
[gnucap-felix.git] / src / d_mos4.cc
blobde656ab5bcc8af9e9856ceab272816ac35d1b961
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)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *------------------------------------------------------------------
22 * MOS BSIM1 model.
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 */
29 #include "globals.h"
30 #include "e_elemnt.h"
31 #include "d_mos4.h"
32 /*--------------------------------------------------------------------------*/
33 const double NA(NOT_INPUT);
34 const double INF(BIGBIG);
35 /*--------------------------------------------------------------------------*/
36 int MODEL_BUILT_IN_MOS4::_count = 0;
37 /*--------------------------------------------------------------------------*/
38 const int LEVEL(4);
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)
49 assert(cc);
50 SDP_BUILT_IN_MOS_BASE::init(cc);
51 const COMMON_BUILT_IN_MOS* c = prechecked_cast<const COMMON_BUILT_IN_MOS*>(cc);
52 assert(c);
53 const MODEL_BUILT_IN_MOS4* m = prechecked_cast<const MODEL_BUILT_IN_MOS4*>(c->model());
54 assert(m);
55 const CARD_LIST* par_scope = m->scope();
56 assert(par_scope);
58 l_eff -= m->dl;
59 w_eff -= m->dw;
60 double L = l_eff/MICRON2METER;
61 double W = w_eff/MICRON2METER;
62 double CoxWoverL = 1e-4 * m->cox * w_eff / l_eff;
63 // adjust: override
64 this->cgate = m->cox * w_eff * l_eff;
65 // adjust: raw
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);
87 // adjust: calculated
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;
94 // code_post
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),
104 phi(0.),
105 vfb(0.),
106 k1(0.),
107 k2(0.),
108 eta(0.),
109 etaB(0.),
110 etaD(0.),
111 mobZero(0.),
112 mobZeroB(0.),
113 mobVdd(0.),
114 mobVddB(0.),
115 mobVddD(0.),
116 ugs(0.),
117 ugsB(0.),
118 uds(0.),
119 udsB(0.),
120 udsD(0.),
121 n0(0.),
122 nB(0.),
123 nD(0.),
124 dl_u(0.),
125 dw_u(0.),
126 tox_u(0.),
127 vdd(0.),
128 wdf(0.),
129 dell(0.),
130 temp(300.15),
131 xpart(0.),
132 dl(NA),
133 dw(NA),
134 tox(NA),
135 cox(NA)
137 if (ENV::run_mode != rPRE_MAIN) {
138 ++_count;
139 }else{
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),
150 phi(p.phi),
151 vfb(p.vfb),
152 k1(p.k1),
153 k2(p.k2),
154 eta(p.eta),
155 etaB(p.etaB),
156 etaD(p.etaD),
157 mobZero(p.mobZero),
158 mobZeroB(p.mobZeroB),
159 mobVdd(p.mobVdd),
160 mobVddB(p.mobVddB),
161 mobVddD(p.mobVddD),
162 ugs(p.ugs),
163 ugsB(p.ugsB),
164 uds(p.uds),
165 udsB(p.udsB),
166 udsD(p.udsD),
167 n0(p.n0),
168 nB(p.nB),
169 nD(p.nD),
170 dl_u(p.dl_u),
171 dw_u(p.dw_u),
172 tox_u(p.tox_u),
173 vdd(p.vdd),
174 wdf(p.wdf),
175 dell(p.dell),
176 temp(p.temp),
177 xpart(p.xpart),
178 dl(p.dl),
179 dw(p.dw),
180 tox(p.tox),
181 cox(p.cox)
183 if (ENV::run_mode != rPRE_MAIN) {
184 ++_count;
185 }else{untested();//194
188 /*--------------------------------------------------------------------------*/
189 std::string MODEL_BUILT_IN_MOS4::dev_type()const
191 if (polarity == pN) {
192 return "nmos4";
193 }else if (polarity == pP) {
194 return "pmos4";
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 ")) {
203 polarity = pN;
204 }else if (Umatch(new_type, "pmos4 ")) {
205 polarity = pP;
206 }else{
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();
214 assert(par_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
226 if (mjsw == NA) {
227 mjsw = .33;
228 }else{
230 if (pb == NA) {
231 pb = 0.1;
232 }else{
234 //pb = std::max(pb, 0.1);
235 if (pbsw == NA) {
236 pbsw = pb;
237 }else{
239 //pbsw = std::max(pbsw, 0.1);
240 cmodel = ((!cmodel)?1:cmodel);
241 // final adjust: raw
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);
251 // final adjust: mid
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
268 assert(c);
269 if (COMMON_BUILT_IN_MOS* cc = dynamic_cast<COMMON_BUILT_IN_MOS*>(c)) {
270 if (cc->_sdp) {
271 cc->_sdp->init(cc);
272 return cc->_sdp;
273 }else{
274 delete cc->_sdp;
275 return new SDP_BUILT_IN_MOS4(c);
277 }else{
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
590 if (j == 0) {
591 return param_name(i);
592 }else if (j == 1) {
593 switch (MODEL_BUILT_IN_MOS4::param_count() - 1 - i) {
594 case 0: return "";
595 case 1: return "";
596 case 2: return "";
597 case 3: return "";
598 case 4: return "";
599 case 5: return "";
600 case 6: return "";
601 case 7: return "";
602 case 8: return "";
603 case 9: return "";
604 case 10: return "";
605 case 11: return "";
606 case 12: return "";
607 case 13: return "";
608 case 14: return "";
609 case 15: return "";
610 case 16: return "";
611 case 17: return "";
612 case 18: return "";
613 case 19: return "";
614 case 20: return "";
615 case 21: return "";
616 case 22: return "";
617 case 23: return "";
618 case 24: return "";
619 case 25: return "";
620 case 26: return "";
621 case 27: return "";
622 case 28: return "";
623 case 29: return "";
624 case 30: return "";
625 case 31: return "";
626 case 32: return "";
627 case 33: return "";
628 case 34: return "";
629 case 35: return "";
630 case 36: return "";
631 case 37: return "";
632 case 38: return "";
633 case 39: return "";
634 case 40: return "";
635 case 41: return "";
636 case 42: return "";
637 case 43: return "";
638 case 44: return "";
639 case 45: return "";
640 case 46: return "";
641 case 47: return "";
642 case 48: return "";
643 case 49: return "";
644 case 50: return "";
645 case 51: return "";
646 case 52: return "";
647 case 53: return "";
648 case 54: return "";
649 case 55: return "";
650 case 56: return "";
651 case 57: return "";
652 case 58: return "";
653 case 59: return "";
654 case 60: return "";
655 case 61: return "";
656 case 62: return "";
657 case 63: return "";
658 case 64: return "";
659 case 65: return "";
660 case 66: return "";
661 case 67: return "";
662 case 68: return "";
663 case 69: return "";
664 case 70: return "";
665 case 71: return "";
666 case 72: return "";
667 case 73: return "";
668 case 74: return "";
669 case 75: return "";
670 case 76: return "";
671 case 77: return "";
672 case 78: return "";
673 case 79: return "";
674 case 80: return "";
675 case 81: return "";
676 case 82: return "";
677 case 83: return "";
678 case 84: return "";
679 case 85: return "";
680 case 86: return "";
681 case 87: return "";
682 case 88: return "";
683 case 89: return "";
684 case 90: return "";
685 case 91: return "";
686 case 92: return "";
687 case 93: return "";
688 case 94: return "";
689 default: return MODEL_BUILT_IN_MOS_BASE::param_name(i, j);
691 }else if (i < 95) {
692 return "";
693 }else{
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) {
701 case 0: return "4";
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
802 assert(d);
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);
809 assert(d);
810 const COMMON_BUILT_IN_MOS* c = prechecked_cast<const COMMON_BUILT_IN_MOS*>(d->common());
811 assert(c);
812 const SDP_BUILT_IN_MOS4* s = prechecked_cast<const SDP_BUILT_IN_MOS4*>(c->sdp());
813 assert(s);
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;
823 double dUgsdVbs;
824 if(Ugs <= 0) {
825 untested();
826 Ugs = 0;
827 dUgsdVbs = 0.0;
828 }else{
829 dUgsdVbs = s->ugsB;
831 trace2("", Ugs, dUgsdVbs);
833 double Uds = s->uds + s->udsB * d->vbs + s->udsD * (d->vds - m->vdd);
834 double dUdsdVbs;
835 double dUdsdVds;
836 if(Uds <= 0) {
837 untested();
838 Uds = 0.0;
839 dUdsdVbs = dUdsdVds = 0.0;
840 }else{
841 double Leff = s->l_eff * 1e6; /* Leff in um */
842 Uds = Uds / Leff;
843 dUdsdVbs = s->udsB / Leff;
844 dUdsdVds = s->udsD / Leff;
846 trace3("", Uds, dUdsdVbs, dUdsdVds);
848 double Vpb;
849 if(d->vbs <= 0) {
850 Vpb = s->phi - d->vbs;
851 d->sbfwd = false;
852 }else{
853 Vpb = s->phi;
854 d->sbfwd = true;
856 double SqrtVpb = sqrt(Vpb);
857 trace2("", Vpb, SqrtVpb);
858 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
859 /* threshold voltage */
860 double dVthdVbs;
861 double dVthdVds;
863 double Eta = s->eta + s->etaB * d->vbs + s->etaD * (d->vds - m->vdd);
864 double dEtadVds;
865 double dEtadVbs;
866 if(Eta <= 0) {
867 Eta = 0;
868 dEtadVds = dEtadVbs = 0.0 ;
869 }else if (Eta > 1) {
870 untested();
871 Eta = 1;
872 dEtadVds = dEtadVbs = 0;
873 }else{
874 untested();
875 dEtadVds = s->etaD;
876 dEtadVbs = s->etaB;
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 */
896 if (d->vgst < 0) {
897 d->cutoff = true;
898 /* cutoff */
899 d->ids = 0;
900 d->gmf = 0;
901 d->gds = 0;
902 d->gmbf = 0;
903 d->vdsat = 0;
904 trace4("cutoff", d->ids, d->gmf, d->gds, d->gmbf);
905 }else{
906 d->cutoff = false;
907 /* Quadratic Interpolation for Beta0 (Beta at d->vgs = 0, vds=Vds) */
908 double Beta0;
909 double dBeta0dVds;
910 double dBeta0dVbs;
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);
922 }else{
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;
951 if(Vc < 0.0) {
952 untested();
953 Vc=0.0;
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 */
977 d->saturated = true;
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. *
1006 * Peter M. Lee *
1007 * 6/8/90 *
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 ;
1012 if (s->n0 < 200) {
1013 double N = s->n0 + s->nB*d->vbs + s->nD*d->vds; /* subthreshold slope */
1014 trace4("", s->n0, s->nB, s->nD, N);
1015 if (N < 0.5) {
1016 untested();
1017 N = 0.5;
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 */
1037 d->gds += Temp3
1038 * (Wds / nvt0 * (dVthdVds + d->vgst * s->nD / N)
1039 + Warg1 / vt0);
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);
1045 }else{
1046 untested();
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 */
1079 untested();
1080 d->qgate = s->cgate * Vgb_Vfb;
1081 d->qbulk = -d->qgate;
1082 d->qdrn = 0. ;
1083 d->cggb = s->cgate;
1084 d->cgdb = 0.;
1085 d->cgsb = 0.;
1086 d->cbgb = -s->cgate;
1087 d->cbdb = 0.;
1088 d->cbsb = 0.;
1089 d->cdgb = 0.;
1090 d->cddb = 0.;
1091 d->cdsb = 0.;
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;
1100 d->cbgb = -d->cggb;
1101 d->cbdb = d->cbsb = 0.0;
1102 d->qdrn = 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);
1114 double Argl5;
1115 if (Ent > 1.0e-8) {
1116 Argl5 = Arg1 / Ent;
1117 }else{
1118 untested();
1119 Argl5 = 2.0;
1121 double Argl7 = Argl5 / 1.2e1;
1122 double Argl8 = 6.0 * Ent;
1123 trace3("", Argl5, Argl7, Argl8);
1125 d->qgate = s->cgate
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);
1152 }else{
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;
1159 double Argl6;
1160 if (Ent > 1.0e-8) {
1161 Argl6 = Vcom / EntSquare;
1162 }else{
1163 untested();
1164 Argl6 = 4.0 / 1.5e1;
1166 d->qdrn = -s->cgate * (0.5 * (Vgs_Vth-Arg1) + Arg1 * Argl6);
1167 d->cdgb = -s->cgate
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)
1174 /Argl1);
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);
1186 d->cgdb = 0.0;
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);
1193 d->cbdb = 0.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*/
1201 d->qdrn = 0.0;
1202 d->cdgb = 0.0;
1203 d->cddb = 0.0;
1204 d->cdsb = 0.0;
1205 trace4("sat 0/100", d->qdrn, d->cdgb, d->cddb, d->cdsb);
1206 }else{
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;
1211 d->cddb = 0.0;
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);
1217 if (d->reversed) {
1218 d->ids *= -1;
1219 d->gmr = d->gmf;
1220 d->gmbr = d->gmbf;
1221 d->gmf = d->gmbf = 0;
1222 }else{
1223 d->gmr = d->gmbr = 0.;
1226 /*--------------------------------------------------------------------------*/
1227 /*--------------------------------------------------------------------------*/
1228 /*--------------------------------------------------------------------------*/
1229 /*--------------------------------------------------------------------------*/