Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_MOSFET_B3.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_MOSFET_B3.C,v $
27 //
28 // Purpose : This file implements the BSIM3 MOSFET model. It
29 // is intended to be compatible with the Berkeley SPICE
30 // (3f5) version, BSIM3 version 3.2.2.
31 //
32 // Special Notes :
33 //
34 //
35 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
36 //
37 // Creation Date : 01/12/01
38 //
39 // Revision Information:
40 // ---------------------
41 //
42 // Revision Number: $Revision: 1.375 $
43 //
44 //
45 // Current Owner : $Author: erkeite $
46 //-------------------------------------------------------------------------
47 
48 #include <Xyce_config.h>
49 
50 
51 // ---------- Standard Includes ----------
52 
53 #ifdef HAVE_CSTDIO
54 #include <cstdio>
55 #else
56 #include <stdio.h>
57 #endif
58 
59 #ifdef HAVE_CMATH
60 #include <cmath>
61 #else
62 #include <math.h>
63 #endif
64 
65 // ---------- Xyce Includes ----------
66 
67 #ifndef Xyce_USE_BSIM3_CONST
68 #include <N_DEV_Const.h>
69 #endif
70 
71 #include <N_DEV_DeviceOptions.h>
72 #include <N_DEV_ExternData.h>
73 #include <N_DEV_MOSFET_B3.h>
74 #include <N_DEV_MatrixLoadData.h>
75 #include <N_DEV_SolverState.h>
76 #include <N_DEV_Message.h>
77 #include <N_ERH_ErrorMgr.h>
78 
79 #include <N_DEV_MOSFET1.h>
80 
81 #include <N_LAS_Matrix.h>
82 #include <N_LAS_Vector.h>
83 
84 // ---------- BSIM3 constants ---------------
85 // Normally, these should be obtained from N_DEV_Const.h
86 // I have them here, for purposes of comparison to spice.
87 #ifdef Xyce_USE_BSIM3_CONST
88 
89 #define CONSTMAX_EXP 5.834617425e+14
90 #define CONSTMIN_EXP 1.713908431e-15
91 
92 #define CONSTEXP_THRESHOLD 34.0
93 #define CONSTEPSOX 3.453133e-11
94 #define CONSTEPSSI 1.03594e-10
95 
96 #define CONSTQ 1.60219e-19
97 
98 #define CONSTDELTA_1 0.02
99 #define CONSTDELTA_2 0.02
100 #define CONSTDELTA_3 0.02
101 #define CONSTDELTA_4 0.02
102 
103 #define CONSTroot2 sqrt(2.0)
104 #define CONSTCtoK (273.15)
105 #define CONSTREFTEMP (300.15)
106 
107 #define CONSTboltz 1.3806226e-23
108 #define CONSTKoverQ 8.617087e-5 // Kb / q where q = 1.60219e-19
109 
110 #define CONSTvt0 (CONSTboltz * (27.0 +CONSTCtoK)/CONSTQ)
111 
112 #define CONSTEg300 (1.1150877) // band gap for Si at T=300.15K (room temp)
113 #define CONSTEg0 (1.16) // band gap for Si at T=0K. (eV)
114 #define CONSTalphaEg (7.02e-4) // (eV/K)
115 #define CONSTbetaEg (1108.0) // (K)
116 
117 #define CONSTNi0 (1.45e10) // carrier concentration at room temp.
118 
119 #define CONSTNMOS 1
120 #define CONSTPMOS -1
121 
122 #endif
123 
124 
125 namespace Xyce {
126 namespace Device {
127 
128 
129 namespace MOSFET_B3 {
130 
131 
133 {
134  // Set up configuration constants:
135 // Set up double precision variables:
136  p.addPar ("TEMP", 0.0, false, TIME_DEP,
138  NULL, STANDARD, CAT_NONE, "Device temperature");
139 
140  p.addPar ("L", 0.0, true, NO_DEP,
142  NULL, U_METER, CAT_GEOMETRY, "Channel length");
143 
144  p.addPar ("W", 0.0, true, NO_DEP,
146  NULL, U_METER, CAT_GEOMETRY, "Channel width");
147 
148  p.addPar ("AD", 0.0, false, NO_DEP,
150  NULL, U_METER2, CAT_GEOMETRY, "Drain diffusion area");
151 
152  p.addPar ("AS", 0.0, false, NO_DEP,
154  NULL, U_METER2, CAT_GEOMETRY, "Source diffusion area");
155 
156  p.addPar ("NRD", 1.0, false, NO_DEP,
158  NULL, U_SQUARES, CAT_GEOMETRY, "Multiplier for RSH to yield parasitic resistance of drain");
159 
160  p.addPar ("NRS", 1.0, false, NO_DEP,
162  NULL, U_SQUARES, CAT_GEOMETRY, "Multiplier for RSH to yield parasitic resistance of source");
163 
164  p.addPar ("PD", 0.0, false, NO_DEP,
166  NULL, U_METER, CAT_GEOMETRY, "Drain diffusion perimeter");
167 
168  p.addPar ("PS", 0.0, false, NO_DEP,
170  NULL, U_METER, CAT_GEOMETRY, "Source diffusion perimeter");
171 
172  p.addPar ("M", 1.0, false, NO_DEP,
174  NULL, U_NONE, CAT_CONTROL, "Multiplier for M devices connected in parallel");
175 
176  p.addPar ("IC1", 0.0, false, NO_DEP,
179  U_VOLT, CAT_VOLT, "Initial condition on Vds");
180 
181  p.addPar ("IC2", 0.0, false, NO_DEP,
184  U_VOLT, CAT_VOLT, "Initial condition on Vgs");
185 
186  p.addPar ("IC3", 0.0, false, NO_DEP,
189  U_VOLT, CAT_VOLT, "Initial condition on Vbs");
190 
191  // Set up non-double precision variables:
192  p.addPar ("NQSMOD", 0, false, NO_DEP,
194  U_NONE, CAT_CONTROL, "Flag for NQS model");
195  p.addPar ("OFF",false,false, NO_DEP,
197  NULL, U_LOGIC, CAT_VOLT,
198  "Initial condition of no voltage drops accross device");
199 
200  // This tells the parser that IC1, IC2, and IC3 are to be input as a vector of "IC"
201  p.makeVector ("IC", 3);
202 }
203 
205 {
206  // Set up map for normal (double) param variables:
207  p.addPar ("TOX", 150.e-10, true, NO_DEP,
209  NULL,
210  U_METER, CAT_GEOMETRY, "Gate oxide thickness");
211 
212  p.addPar ("TOXM", 0.0, false, NO_DEP,
214  NULL, U_METER, CAT_PROCESS, "Gate oxide thickness used in extraction");
215 
216  p.addPar ("CDSC", 2.4e-4, false, NO_DEP,
218  NULL, U_FARADMM2, CAT_DC, "Drain/source to channel coupling capacitance");
219 
220  p.addPar ("CDSCB", 0.0, false, NO_DEP,
222  NULL, U_FVM1MM2, CAT_DC, "Body-bias sensitivity of CDSC");
223 
224  p.addPar ("CDSCD", 0.0, false, NO_DEP,
226  NULL, U_FVM1MM2, CAT_DC, "Drain-bias sensitivity of CDSC");
227 
228  p.addPar ("CIT", 0.0, false, NO_DEP,
230  NULL, U_FARADMM2, CAT_DC, "Interface trap capacitance");
231 
232  p.addPar ("NFACTOR", 1.0, false, NO_DEP,
234  NULL, U_NONE, CAT_DC, "Subthreshold swing factor");
235 
236  p.addPar ("XJ", 0.15e-6, false, NO_DEP,
238  NULL, U_METER, CAT_GEOMETRY, "Junction depth");
239 
240  p.addPar ("VSAT", 8.0e4, false, NO_DEP,
242  NULL, U_MSM1, CAT_DC, "Saturation velocity at temp = TNOM");
243 
244  p.addPar ("AT", 3.3e4, false, NO_DEP,
246  NULL, U_MSM1, CAT_TEMP, "Temperature coefficient for saturation velocity");
247 
248  p.addPar ("A0", 1.0, false, NO_DEP,
250  NULL, U_NONE, CAT_DC, "Bulk charge effect coefficient for channel length");
251 
252  p.addPar ("AGS", 0.0, false, NO_DEP,
254  NULL, U_VOLTM1, CAT_DC, "Gate-bias coefficient of abulk");
255 
256  p.addPar ("A1", 0.0, false, NO_DEP,
258  NULL, U_VOLTM1, CAT_DC, "First non-saturation effect parameter");
259 
260  p.addPar ("A2", 1.0, false, NO_DEP,
262  NULL, U_NONE, CAT_DC, "Second non-saturation factor");
263 
264  p.addPar ("KETA", -0.047, false, NO_DEP,
266  NULL, U_VOLTM1, CAT_DC, "Body-bias coefficient of bulk charge effect");
267 
268  p.addPar ("NSUB", 6.0e16, false, NO_DEP,
271 
272  U_CMM3, CAT_DOPING, "Substrate doping density");
273 
274  p.addPar ("NCH", 1.7e17, false, NO_DEP,
277  U_CMM3, CAT_PROCESS, "Channel doping concentration");
278 
279  p.addPar ("NGATE", 0.0, false, NO_DEP,
281  NULL, U_CMM3, CAT_DC, "Poly gate doping concentration");
282 
283  p.addPar ("GAMMA1", 0.0, false, NO_DEP,
286  U_VOLTH, CAT_PROCESS, "Body effect coefficient near the surface");
287 
288  p.addPar ("GAMMA2", 0.0, false, NO_DEP,
291  U_VOLTH, CAT_PROCESS, "Body effect coefficient in the bulk");
292 
293  p.addPar ("VBX", 0.0, false, NO_DEP,
296  U_VOLT, CAT_PROCESS, "Vbs at which the depetion region = XT");
297 
298  p.addPar ("VBM", -3.0, false, NO_DEP,
301  U_VOLT, CAT_DC, "Maximum applied body-bias in threshold voltage calculation");
302 
303  p.addPar ("XT", 1.55e-7, false, NO_DEP,
306  U_METER, CAT_PROCESS, "Doping depth");
307 
308  p.addPar ("K1", 0.0, false, NO_DEP,
311  U_VOLTH, CAT_DC, "First-order body effect coefficient");
312 
313  p.addPar ("KT1", -0.11, false, NO_DEP,
315  NULL, U_VOLT, CAT_TEMP, "Themperature coefficient for threshold voltage");
316 
317  p.addPar ("KT1L", 0.0, false, NO_DEP,
319  NULL, U_VM, CAT_TEMP, "Channel length dependence of the temerature coefficient for the threshold voltage");
320 
321  p.addPar ("KT2", 0.022, false, NO_DEP,
323  NULL, U_NONE, CAT_TEMP, "Body-bias coefficient fo the threshold voltage temperature effect");
324 
325  p.addPar ("K2", 0.0, false, NO_DEP,
328  U_NONE, CAT_DC, "second-order body effect coefficient");
329 
330  p.addPar ("K3", 80.0, false, NO_DEP,
332  NULL, U_NONE, CAT_DC, "Narrow width coefficient");
333 
334  p.addPar ("K3B", 0.0, false, NO_DEP,
336  NULL, U_VOLTM1, CAT_DC, "Body effect coefficient of K3");
337 
338  p.addPar ("W0", 2.5e-6, false, NO_DEP,
340  NULL, U_METER, CAT_DC, "Narrow-width paameter");
341 
342  p.addPar ("NLX", 1.74e-7, false, NO_DEP,
344  NULL, U_METER, CAT_DC, "Lateral non-uniform doping parameter");
345 
346  p.addPar ("DVT0", 2.2, false, NO_DEP,
348  NULL, U_NONE, CAT_DC, "First coefficient of short-channel effect effect on threshold voltage");
349 
350  p.addPar ("DVT1", 0.53, false, NO_DEP,
352  NULL, U_NONE, CAT_DC, "Second coefficient of short-channel effect effect on threshold voltage");
353 
354  p.addPar ("DVT2", -0.032, false, NO_DEP,
356  NULL, U_VOLTM1, CAT_DC, "Body-bias coefficient of short-channel effect effect on threshold voltage");
357 
358  p.addPar ("DVT0W", 0.0, false, NO_DEP,
360  NULL, U_METERM1, CAT_DC, "First coefficient of narrow-width effect effect on threshold voltage for small channel length");
361 
362  p.addPar ("DVT1W", 5.3e6, false, NO_DEP,
364  NULL, U_METERM1, CAT_DC, "Second coefficient of narrow-width effect effect on threshold voltage for small channel length");
365 
366  p.addPar ("DVT2W", -0.032, false, NO_DEP,
368  NULL, U_VOLTM1, CAT_DC, "Body-bias coefficient of narrow-width effect effect on threshold voltage for small channel length");
369 
370  p.addPar ("DROUT", 0.56, false, NO_DEP,
372  NULL, U_NONE, CAT_DC, "L-depedance Coefficient of the DIBL correction parameter in Rout");
373 
374  p.addPar ("DSUB", 0.0, false, NO_DEP,
376  NULL, U_NONE, CAT_DC, "DIBL coefficient exponent in subthreshhold region");
377 
378  p.addPar ("VTH0", 0.0, false, NO_DEP,
381  U_VOLT, CAT_DC, "Threshold voltage at Vbs = 0 for large L");
382 
383  p.addPar ("UA", 2.25e-9, false, NO_DEP,
385  NULL, U_MVM1, CAT_DC, "First-order mobility degradation coefficient");
386 
387  p.addPar ("UA1", 4.31e-9, false, NO_DEP,
389  NULL, U_MVM1, CAT_TEMP, "Temperature coefficient for UA");
390 
391  p.addPar ("UB", 5.87e-19, false, NO_DEP,
393  NULL, U_M2VM2, CAT_DC, "First-order mobility degradation coefficient");
394 
395  p.addPar ("UB1", -7.61e-18, false, NO_DEP,
397  NULL, U_M2VM2, CAT_TEMP, "Temperature coefficient for UB");
398 
399  p.addPar ("UC", 0.0, false, NO_DEP,
401  NULL, U_MVM2, CAT_DC, "Body effect of mobility degridation coefficient");
402 
403  p.addPar ("UC1", 0.0, false, NO_DEP,
405  NULL, U_MVM2DEGCM1, CAT_TEMP, "Temperature coefficient for UC");
406 
407  p.addPar ("U0", 0.0, false, NO_DEP,
409  NULL,
410  U_CMM2VM1SM1, CAT_PROCESS, "Surface mobility");
411 
412  p.addPar ("UTE", -1.5, false, NO_DEP,
414  NULL, U_NONE, CAT_TEMP, "Mobility temerature exponent");
415 
416  p.addPar ("VOFF", -0.08, false, NO_DEP,
418  NULL, U_VOLT, CAT_DC, "Offset voltage in the subthreshold region at large W and L");
419 
420  p.addPar ("RDSW", 0.0, false, NO_DEP,
422  NULL, U_OHMMICRON, CAT_DC, "Parasitic resistance per unit width");
423 
424  p.addPar ("PRWG", 0.0, false, NO_DEP,
426  NULL, U_VOLTM1, CAT_DC, "Gate-bias effect coefficient of RDSW");
427 
428  p.addPar ("PRWB", 0.0, false, NO_DEP,
430  NULL, U_VOLTMH, CAT_DC, "Body effect coefficient of RDSW");
431 
432  p.addPar ("PRT", 0.0, false, NO_DEP,
434  NULL, U_OHMMICRON, CAT_TEMP, "Temerature coefficient for RDSW");
435 
436  p.addPar ("ETA0", 0.08, false, NO_DEP,
438  NULL, U_NONE, CAT_DC, "DIBL coefficient in subthreshold region");
439 
440  p.addPar ("ETAB", -0.07, false, NO_DEP,
442  NULL, U_VOLTM1, CAT_DC, "Body-bias coefficient for the subthreshold DIBL effect");
443 
444  p.addPar ("PCLM", 1.3, false, NO_DEP,
446  NULL, U_NONE, CAT_DC, "Channel length modulation parameter");
447 
448  p.addPar ("PDIBLC1", 0.39, false, NO_DEP,
450  NULL, U_NONE, CAT_DC, "First output resistance DIBL effect correction parameter");
451 
452  p.addPar ("PDIBLC2", 0.0086, false, NO_DEP,
454  NULL, U_NONE, CAT_DC, "Second output resistance DIBL effect correction parameter");
455 
456  p.addPar ("PDIBLCB", 0.0, false, NO_DEP,
458  NULL, U_VOLTM1, CAT_DC, "Body effect coefficient of DIBL correction parameter");
459 
460  p.addPar ("PSCBE1", 4.24e8, false, NO_DEP,
462  NULL, U_VMM1, CAT_DC, "First substrate current body effect parameter");
463 
464  p.addPar ("PSCBE2", 1.0e-5, false, NO_DEP,
466  NULL, U_VMM1, CAT_DC, "second substrate current body effect parameter");
467 
468  p.addPar ("PVAG", 0.0, false, NO_DEP,
470  NULL, U_NONE, CAT_DC, "Gate dependence of early voltage");
471 
472  p.addPar ("DELTA", 0.01, false, NO_DEP,
474  NULL, U_VOLT, CAT_DC, "Effective Vds parameter");
475 
476  p.addPar ("WR", 1.0, false, NO_DEP,
478  NULL, U_NONE, CAT_DC, "Width offset from Weff for Rds Calculation");
479 
480  p.addPar ("DWG", 0.0, false, NO_DEP,
482  NULL, U_MVMH, CAT_DC, "Coefficient of gate depedence of Weff");
483 
484  p.addPar ("DWB", 0.0, false, NO_DEP,
486  NULL, U_MVMH, CAT_DC, "Coefficient of substrate body bias dependence of Weff");
487 
488  p.addPar ("B0", 0.0, false, NO_DEP,
490  NULL, U_METER, CAT_DC, "Bulk charge effect coefficient for channel width");
491 
492  p.addPar ("B1", 0.0, false, NO_DEP,
494  NULL, U_METER, CAT_DC, "Bulk charge effect offset");
495 
496  p.addPar ("ALPHA0", 0.0, false, NO_DEP,
498  NULL, U_MVM1, CAT_DC, "First parameter of impact-ionization current");
499 
500  p.addPar ("ALPHA1", 0.0, false, NO_DEP,
502  NULL, U_VOLTM1, CAT_DC, "Isub parameter for length scaling");
503 
504  p.addPar ("BETA0", 30.0, false, NO_DEP,
506  NULL, U_VOLT, CAT_DC, "Second parameter of impact-ionization current");
507 
508  p.addPar ("IJTH", 0.1, false, NO_DEP,
510  NULL, U_AMP, CAT_DC, "Diode limiting current");
511 
512  p.addPar ("VFB", 0.0, false, NO_DEP,
515  U_VOLT, CAT_DC, "Flat-band voltage");
516 
517  p.addPar ("ELM", 5.0, false, NO_DEP,
519  NULL, U_NONE, CAT_NQS, "Elmore constant of the channel");
520 
521  p.addPar ("CGSL", 0.0, false, NO_DEP,
523  NULL, U_FARADMM1, CAT_CAP, "Light-doped source-gate region overlap capacitance");
524 
525  p.addPar ("CGDL", 0.0, false, NO_DEP,
527  NULL, U_FARADMM1, CAT_CAP, "Light-doped drain-gate region overlap capacitance");
528 
529  p.addPar ("CKAPPA", 0.6, false, NO_DEP,
531  NULL, U_FARADMM1, CAT_CAP, "Coefficient for lightly doped region overlap capacitance fireing field capacitance");
532 
533  p.addPar ("CF", 0.0, false, NO_DEP,
535  NULL, U_FARADMM1, CAT_CAP, "Firing field capacitance");
536 
537  p.addPar ("VFBCV", -1.0, false, NO_DEP,
539  NULL, U_VOLT, CAT_CAP, "Flat-band voltage parameter (for CAPMOD = 0 only)");
540 
541  p.addPar ("CLC", 0.1e-6, false, NO_DEP,
543  NULL, U_METER, CAT_CAP, "Constant term for short-channel model");
544 
545  p.addPar ("CLE", 0.6, false, NO_DEP,
547  NULL, U_NONE, CAT_CAP, "Exponetial term for the short-channel model");
548 
549  p.addPar ("DWC", 0.0, false, NO_DEP,
551  NULL, U_METER, CAT_CAP, "Width offset fitting parameter from C-V");
552 
553  p.addPar ("DLC", 0.0, false, NO_DEP,
555  NULL, U_METER, CAT_CAP, "Length offset fitting parameter from C-V");
556 
557  p.addPar ("NOFF", 1.0, false, NO_DEP,
559  NULL, U_NONE, CAT_CAP, "CV parameter in Vgsteff, CV for weak to strong inversion");
560 
561  p.addPar ("VOFFCV", 0.0, false, NO_DEP,
563  NULL, U_VOLT, CAT_CAP, "CV parameter in Vgsteff, CV for weak to strong inversion");
564 
565  p.addPar ("ACDE", 1.0, false, NO_DEP,
567  NULL, U_MVM1, CAT_CAP, "Exponetial coefficient for charge thickness in capmod = 3 for accumulation and depletion regions");
568 
569  p.addPar ("MOIN", 15.0, false, NO_DEP,
571  NULL, U_NONE, CAT_CAP, "Coefficient for the gate-bias dependent surface potential");
572 
573  p.addPar ("TCJ", 0.0, false, NO_DEP,
575  NULL, U_KM1, CAT_TEMP, "Temperature coefficient of Cj");
576 
577  p.addPar ("TCJSW", 0.0, false, NO_DEP,
579  NULL, U_KM1, CAT_TEMP, "Temperature coefficient of Cswj");
580 
581  p.addPar ("TCJSWG", 0.0, false, NO_DEP,
583  NULL, U_KM1, CAT_TEMP, "Temperature coefficient of Cjswg");
584 
585  p.addPar ("TPB", 0.0, false, NO_DEP,
587  NULL, U_VKM1, CAT_TEMP, "Temperature coefficient of Pb");
588 
589  p.addPar ("TPBSW", 0.0, false, NO_DEP,
591  NULL, U_VKM1, CAT_TEMP, "Temperature coefficient of Pbsw");
592 
593  p.addPar ("TPBSWG", 0.0, false, NO_DEP,
595  NULL, U_VKM1, CAT_TEMP, "Temperature coefficient of Pbswg");
596 
597  p.addPar ("LCDSC", 0.0, false, NO_DEP,
599  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of cdsc");
600 
601  p.addPar ("LCDSCB", 0.0, false, NO_DEP,
603  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of cdscb");
604 
605  p.addPar ("LCDSCD", 0.0, false, NO_DEP,
607  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of cdscd");
608 
609  p.addPar ("LCIT", 0.0, false, NO_DEP,
611  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of cit");
612 
613  p.addPar ("LNFACTOR", 0.0, false, NO_DEP,
615  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of nfactor");
616 
617  p.addPar ("LXJ", 0.0, false, NO_DEP,
619  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of xj");
620 
621  p.addPar ("LVSAT", 0.0, false, NO_DEP,
623  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of vsat");
624 
625  p.addPar ("LAT", 0.0, false, NO_DEP,
627  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of at");
628 
629  p.addPar ("LA0", 0.0, false, NO_DEP,
631  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of a0");
632 
633  p.addPar ("LAGS", 0.0, false, NO_DEP,
635  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ags");
636 
637  p.addPar ("LA1", 0.0, false, NO_DEP,
639  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of a1");
640 
641  p.addPar ("LA2", 0.0, false, NO_DEP,
643  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of a2");
644 
645  p.addPar ("LKETA", 0.0, false, NO_DEP,
647  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of keta");
648 
649  p.addPar ("LNSUB", 0.0, false, NO_DEP,
651  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of nsub");
652 
653  p.addPar ("LNCH", 0.0, false, NO_DEP,
655  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of nch");
656 
657  p.addPar ("LNGATE", 0.0, false, NO_DEP,
659  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ngate");
660 
661  p.addPar ("LGAMMA1", 0.0, false, NO_DEP,
663  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of gamma1");
664 
665  p.addPar ("LGAMMA2", 0.0, false, NO_DEP,
667  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of gamma2");
668 
669  p.addPar ("LVBX", 0.0, false, NO_DEP,
671  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VBX");
672 
673  p.addPar ("LVBM", 0.0, false, NO_DEP,
675  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VBM");
676 
677  p.addPar ("LXT", 0.0, false, NO_DEP,
679  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of XT");
680 
681  p.addPar ("LK1", 0.0, false, NO_DEP,
683  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of K1");
684 
685  p.addPar ("LKT1", 0.0, false, NO_DEP,
687  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of KT1");
688 
689  p.addPar ("LKT1L", 0.0, false, NO_DEP,
691  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of KT1L");
692 
693  p.addPar ("LKT2", 0.0, false, NO_DEP,
695  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of KT2");
696 
697  p.addPar ("LK2", 0.0, false, NO_DEP,
699  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of K2");
700 
701  p.addPar ("LK3", 0.0, false, NO_DEP,
703  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of K3");
704 
705  p.addPar ("LK3B", 0.0, false, NO_DEP,
707  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of K3B");
708 
709  p.addPar ("LW0", 0.0, false, NO_DEP,
711  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of W0");
712 
713  p.addPar ("LNLX", 0.0, false, NO_DEP,
715  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of NLX");
716 
717  p.addPar ("LDVT0", 0.0, false, NO_DEP,
719  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT0");
720 
721  p.addPar ("LDVT1", 0.0, false, NO_DEP,
723  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT1");
724 
725  p.addPar ("LDVT2", 0.0, false, NO_DEP,
727  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT2");
728 
729  p.addPar ("LDVT0W", 0.0, false, NO_DEP,
731  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT0W");
732 
733  p.addPar ("LDVT1W", 0.0, false, NO_DEP,
735  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT1W");
736 
737  p.addPar ("LDVT2W", 0.0, false, NO_DEP,
739  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DVT2W");
740 
741  p.addPar ("LDROUT", 0.0, false, NO_DEP,
743  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DROUT");
744 
745  p.addPar ("LDSUB", 0.0, false, NO_DEP,
747  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of LDSUB");
748 
749  p.addPar ("LVTH0", 0.0, false, NO_DEP,
751  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VT0");
752 
753  p.addPar ("LUA", 0.0, false, NO_DEP,
755  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UA");
756 
757  p.addPar ("LUA1", 0.0, false, NO_DEP,
759  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UA1");
760 
761  p.addPar ("LUB", 0.0, false, NO_DEP,
763  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UB");
764 
765  p.addPar ("LUB1", 0.0, false, NO_DEP,
767  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UB1");
768 
769  p.addPar ("LUC", 0.0, false, NO_DEP,
771  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UC");
772 
773  p.addPar ("LUC1", 0.0, false, NO_DEP,
775  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UC1");
776 
777  p.addPar ("LU0", 0.0, false, NO_DEP,
779  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of U0");
780 
781  p.addPar ("LUTE", 0.0, false, NO_DEP,
783  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of UTE");
784 
785  p.addPar ("LVOFF", 0.0, false, NO_DEP,
787  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VOFF");
788 
789  p.addPar ("LRDSW", 0.0, false, NO_DEP,
791  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of RDSW");
792 
793  p.addPar ("LPRWG", 0.0, false, NO_DEP,
795  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PRWG");
796 
797  p.addPar ("LPRWB", 0.0, false, NO_DEP,
799  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PRWB");
800 
801  p.addPar ("LPRT", 0.0, false, NO_DEP,
803  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PRT");
804 
805  p.addPar ("LETA0", 0.0, false, NO_DEP,
807  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ETA0");
808 
809  p.addPar ("LETAB", 0.0, false, NO_DEP,
811  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ETAB");
812 
813  p.addPar ("LPCLM", 0.0, false, NO_DEP,
815  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PCLM");
816 
817  p.addPar ("LPDIBLC1", 0.0, false, NO_DEP,
819  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PDIBLC1");
820 
821  p.addPar ("LPDIBLC2", 0.0, false, NO_DEP,
823  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PDIBLC2");
824 
825  p.addPar ("LPDIBLCB", 0.0, false, NO_DEP,
827  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PDIBLCB");
828 
829  p.addPar ("LPSCBE1", 0.0, false, NO_DEP,
831  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PSCBE1");
832 
833  p.addPar ("LPSCBE2", 0.0, false, NO_DEP,
835  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PSCBE2");
836 
837  p.addPar ("LPVAG", 0.0, false, NO_DEP,
839  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of PVAG");
840 
841  p.addPar ("LDELTA", 0.0, false, NO_DEP,
843  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DELTA");
844 
845  p.addPar ("LWR", 0.0, false, NO_DEP,
847  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of WR");
848 
849  p.addPar ("LDWG", 0.0, false, NO_DEP,
851  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DWG");
852 
853  p.addPar ("LDWB", 0.0, false, NO_DEP,
855  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of DWB");
856 
857  p.addPar ("LB0", 0.0, false, NO_DEP,
859  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of B0");
860 
861  p.addPar ("LB1", 0.0, false, NO_DEP,
863  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of B1");
864 
865  p.addPar ("LALPHA0", 0.0, false, NO_DEP,
867  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ALPHA0");
868 
869  p.addPar ("LALPHA1", 0.0, false, NO_DEP,
871  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ALPHA1");
872 
873  p.addPar ("LBETA0", 0.0, false, NO_DEP,
875  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of BETA0");
876 
877  p.addPar ("LVFB", 0.0, false, NO_DEP,
879  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VFB");
880 
881  p.addPar ("LELM", 0.0, false, NO_DEP,
883  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ELM");
884 
885  p.addPar ("LCGSL", 0.0, false, NO_DEP,
887  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CGSL");
888 
889  p.addPar ("LCGDL", 0.0, false, NO_DEP,
891  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CGDL");
892 
893  p.addPar ("LCKAPPA", 0.0, false, NO_DEP,
895  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CKAPPA");
896 
897  p.addPar ("LCF", 0.0, false, NO_DEP,
899  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CF");
900 
901  p.addPar ("LCLC", 0.0, false, NO_DEP,
903  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CLC");
904 
905  p.addPar ("LCLE", 0.0, false, NO_DEP,
907  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of CLE");
908 
909  p.addPar ("LVFBCV", 0.0, false, NO_DEP,
911  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VFBCV");
912 
913  p.addPar ("LNOFF", 0.0, false, NO_DEP,
915  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of NOFF");
916 
917  p.addPar ("LVOFFCV", 0.0, false, NO_DEP,
919  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of VOFFCV");
920 
921  p.addPar ("LACDE", 0.0, false, NO_DEP,
923  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of ACDE");
924 
925  p.addPar ("LMOIN", 0.0, false, NO_DEP,
927  NULL, U_INVALID, CAT_DEPENDENCY, "Length dependence of MOIN");
928 
929  p.addPar ("WCDSC", 0.0, false, NO_DEP,
931  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CDSC");
932 
933  p.addPar ("WCDSCB", 0.0, false, NO_DEP,
935  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CDSCB");
936 
937  p.addPar ("WCDSCD", 0.0, false, NO_DEP,
939  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CDSCD");
940 
941  p.addPar ("WCIT", 0.0, false, NO_DEP,
943  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CIT");
944 
945  p.addPar ("WNFACTOR", 0.0, false, NO_DEP,
947  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NFACTOR");
948 
949  p.addPar ("WXJ", 0.0, false, NO_DEP,
951  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of XJ");
952 
953  p.addPar ("WVSAT", 0.0, false, NO_DEP,
955  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VSAT");
956 
957  p.addPar ("WAT", 0.0, false, NO_DEP,
959  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of AT");
960 
961  p.addPar ("WA0", 0.0, false, NO_DEP,
963  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of A0");
964 
965  p.addPar ("WAGS", 0.0, false, NO_DEP,
967  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of AGS");
968 
969  p.addPar ("WA1", 0.0, false, NO_DEP,
971  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of A1");
972 
973  p.addPar ("WA2", 0.0, false, NO_DEP,
975  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of A2");
976 
977  p.addPar ("WKETA", 0.0, false, NO_DEP,
979  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of KETA");
980 
981  p.addPar ("WNSUB", 0.0, false, NO_DEP,
983  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NSUB");
984 
985  p.addPar ("WNCH", 0.0, false, NO_DEP,
987  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NCH");
988 
989  p.addPar ("WNGATE", 0.0, false, NO_DEP,
991  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NGATE");
992 
993  p.addPar ("WGAMMA1", 0.0, false, NO_DEP,
995  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of GAMMA1");
996 
997  p.addPar ("WGAMMA2", 0.0, false, NO_DEP,
999  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of GAMMA2");
1000 
1001  p.addPar ("WVBX", 0.0, false, NO_DEP,
1003  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VBX");
1004 
1005  p.addPar ("WVBM", 0.0, false, NO_DEP,
1007  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VBM");
1008 
1009  p.addPar ("WXT", 0.0, false, NO_DEP,
1011  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of XT");
1012 
1013  p.addPar ("WK1", 0.0, false, NO_DEP,
1015  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of K1");
1016 
1017  p.addPar ("WKT1", 0.0, false, NO_DEP,
1019  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of KT1");
1020 
1021  p.addPar ("WKT1L", 0.0, false, NO_DEP,
1023  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of KT1L");
1024 
1025  p.addPar ("WKT2", 0.0, false, NO_DEP,
1027  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of KT2");
1028 
1029  p.addPar ("WK2", 0.0, false, NO_DEP,
1031  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of K2");
1032 
1033  p.addPar ("WK3", 0.0, false, NO_DEP,
1035  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of K3");
1036 
1037  p.addPar ("WK3B", 0.0, false, NO_DEP,
1039  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of K3B");
1040 
1041  p.addPar ("WW0", 0.0, false, NO_DEP,
1043  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of W0");
1044 
1045  p.addPar ("WNLX", 0.0, false, NO_DEP,
1047  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NLX");
1048 
1049  p.addPar ("WDVT0", 0.0, false, NO_DEP,
1051  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT0");
1052 
1053  p.addPar ("WDVT1", 0.0, false, NO_DEP,
1055  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT1");
1056 
1057  p.addPar ("WDVT2", 0.0, false, NO_DEP,
1059  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT2");
1060 
1061  p.addPar ("WDVT0W", 0.0, false, NO_DEP,
1063  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT0W");
1064 
1065  p.addPar ("WDVT1W", 0.0, false, NO_DEP,
1067  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT1W");
1068 
1069  p.addPar ("WDVT2W", 0.0, false, NO_DEP,
1071  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DVT2W");
1072 
1073  p.addPar ("WDROUT", 0.0, false, NO_DEP,
1075  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DROUT");
1076 
1077  p.addPar ("WDSUB", 0.0, false, NO_DEP,
1079  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DSUB");
1080 
1081  p.addPar ("WVTH0", 0.0, false, NO_DEP,
1083  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VTO");
1084 
1085  p.addPar ("WUA", 0.0, false, NO_DEP,
1087  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UA");
1088 
1089  p.addPar ("WUA1", 0.0, false, NO_DEP,
1091  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UA1");
1092 
1093  p.addPar ("WUB", 0.0, false, NO_DEP,
1095  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UB");
1096 
1097  p.addPar ("WUB1", 0.0, false, NO_DEP,
1099  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UB1");
1100 
1101  p.addPar ("WUC", 0.0, false, NO_DEP,
1103  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UC");
1104 
1105  p.addPar ("WUC1", 0.0, false, NO_DEP,
1107  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UC1");
1108 
1109  p.addPar ("WU0", 0.0, false, NO_DEP,
1111  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of U0");
1112 
1113  p.addPar ("WUTE", 0.0, false, NO_DEP,
1115  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of UTE");
1116 
1117  p.addPar ("WVOFF", 0.0, false, NO_DEP,
1119  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VOFF");
1120 
1121  p.addPar ("WRDSW", 0.0, false, NO_DEP,
1123  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of RDSW");
1124 
1125  p.addPar ("WPRWG", 0.0, false, NO_DEP,
1127  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PRWG");
1128 
1129  p.addPar ("WPRWB", 0.0, false, NO_DEP,
1131  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PRWB");
1132 
1133  p.addPar ("WPRT", 0.0, false, NO_DEP,
1135  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PRT");
1136 
1137  p.addPar ("WETA0", 0.0, false, NO_DEP,
1139  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ETA0");
1140 
1141  p.addPar ("WETAB", 0.0, false, NO_DEP,
1143  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ETAB");
1144 
1145  p.addPar ("WPCLM", 0.0, false, NO_DEP,
1147  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PCLM");
1148 
1149  p.addPar ("WPDIBLC1", 0.0, false, NO_DEP,
1151  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PDIBLC1");
1152 
1153  p.addPar ("WPDIBLC2", 0.0, false, NO_DEP,
1155  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PDIBLC2");
1156 
1157  p.addPar ("WPDIBLCB", 0.0, false, NO_DEP,
1159  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PDIBLCB");
1160 
1161  p.addPar ("WPSCBE1", 0.0, false, NO_DEP,
1163  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PSCBE1");
1164 
1165  p.addPar ("WPSCBE2", 0.0, false, NO_DEP,
1167  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PSCBE2");
1168 
1169  p.addPar ("WPVAG", 0.0, false, NO_DEP,
1171  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of PVAG");
1172 
1173  p.addPar ("WDELTA", 0.0, false, NO_DEP,
1175  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DELTA");
1176 
1177  p.addPar ("WWR", 0.0, false, NO_DEP,
1179  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of WR");
1180 
1181  p.addPar ("WDWG", 0.0, false, NO_DEP,
1183  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of WG");
1184 
1185  p.addPar ("WDWB", 0.0, false, NO_DEP,
1187  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of DWB");
1188 
1189  p.addPar ("WB0", 0.0, false, NO_DEP,
1191  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of B0");
1192 
1193  p.addPar ("WB1", 0.0, false, NO_DEP,
1195  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of B1");
1196 
1197  p.addPar ("WALPHA0", 0.0, false, NO_DEP,
1199  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ALPHA0");
1200 
1201  p.addPar ("WALPHA1", 0.0, false, NO_DEP,
1203  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ALPHA1");
1204 
1205  p.addPar ("WBETA0", 0.0, false, NO_DEP,
1207  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of BETA0");
1208 
1209  p.addPar ("WVFB", 0.0, false, NO_DEP,
1211  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VFB");
1212 
1213  p.addPar ("WELM", 0.0, false, NO_DEP,
1215  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ELM");
1216 
1217  p.addPar ("WCGSL", 0.0, false, NO_DEP,
1219  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CGSL");
1220 
1221  p.addPar ("WCGDL", 0.0, false, NO_DEP,
1223  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CGDL");
1224 
1225  p.addPar ("WCKAPPA", 0.0, false, NO_DEP,
1227  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CKAPPA");
1228 
1229  p.addPar ("WCF", 0.0, false, NO_DEP,
1231  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CF");
1232 
1233  p.addPar ("WCLC", 0.0, false, NO_DEP,
1235  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CLC");
1236 
1237  p.addPar ("WCLE", 0.0, false, NO_DEP,
1239  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of CLE");
1240 
1241  p.addPar ("WVFBCV", 0.0, false, NO_DEP,
1243  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VFBCV");
1244 
1245  p.addPar ("WNOFF", 0.0, false, NO_DEP,
1247  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of NOFF");
1248 
1249  p.addPar ("WVOFFCV", 0.0, false, NO_DEP,
1251  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of VOFFCV");
1252 
1253  p.addPar ("WACDE", 0.0, false, NO_DEP,
1255  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of ACDE");
1256 
1257  p.addPar ("WMOIN", 0.0, false, NO_DEP,
1259  NULL, U_INVALID, CAT_DEPENDENCY, "Width dependence of MOIN");
1260 
1261  p.addPar ("PCDSC", 0.0, false, NO_DEP,
1263  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CDSC");
1264 
1265  p.addPar ("PCDSCB", 0.0, false, NO_DEP,
1267  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CDSCB");
1268 
1269  p.addPar ("PCDSCD", 0.0, false, NO_DEP,
1271  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CDSCD");
1272 
1273  p.addPar ("PCIT", 0.0, false, NO_DEP,
1275  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CIT");
1276 
1277  p.addPar ("PNFACTOR", 0.0, false, NO_DEP,
1279  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NFACTOR");
1280 
1281  p.addPar ("PXJ", 0.0, false, NO_DEP,
1283  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of XJ");
1284 
1285  p.addPar ("PVSAT", 0.0, false, NO_DEP,
1287  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VSAT");
1288 
1289  p.addPar ("PAT", 0.0, false, NO_DEP,
1291  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of AT");
1292 
1293  p.addPar ("PA0", 0.0, false, NO_DEP,
1295  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of A0");
1296 
1297  p.addPar ("PAGS", 0.0, false, NO_DEP,
1299  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of AGS");
1300 
1301  p.addPar ("PA1", 0.0, false, NO_DEP,
1303  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of A1");
1304 
1305  p.addPar ("PA2", 0.0, false, NO_DEP,
1307  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of A2");
1308 
1309  p.addPar ("PKETA", 0.0, false, NO_DEP,
1311  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of KETA");
1312 
1313  p.addPar ("PNSUB", 0.0, false, NO_DEP,
1315  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NSUB");
1316 
1317  p.addPar ("PNCH", 0.0, false, NO_DEP,
1319  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NCH");
1320 
1321  p.addPar ("PNGATE", 0.0, false, NO_DEP,
1323  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NGATE");
1324 
1325  p.addPar ("PGAMMA1", 0.0, false, NO_DEP,
1327  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of GAMMA1");
1328 
1329  p.addPar ("PGAMMA2", 0.0, false, NO_DEP,
1331  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of GAMMA2");
1332 
1333  p.addPar ("PVBX", 0.0, false, NO_DEP,
1335  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VBX");
1336 
1337  p.addPar ("PVBM", 0.0, false, NO_DEP,
1339  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VBM");
1340 
1341  p.addPar ("PXT", 0.0, false, NO_DEP,
1343  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of XT");
1344 
1345  p.addPar ("PK1", 0.0, false, NO_DEP,
1347  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of K1");
1348 
1349  p.addPar ("PKT1", 0.0, false, NO_DEP,
1351  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of KT1");
1352 
1353  p.addPar ("PKT1L", 0.0, false, NO_DEP,
1355  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of KT1L");
1356 
1357  p.addPar ("PKT2", 0.0, false, NO_DEP,
1359  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of KT2");
1360 
1361  p.addPar ("PK2", 0.0, false, NO_DEP,
1363  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of K2");
1364 
1365  p.addPar ("PK3", 0.0, false, NO_DEP,
1367  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of K3");
1368 
1369  p.addPar ("PK3B", 0.0, false, NO_DEP,
1371  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of K3B");
1372 
1373  p.addPar ("PW0", 0.0, false, NO_DEP,
1375  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of W0");
1376 
1377  p.addPar ("PNLX", 0.0, false, NO_DEP,
1379  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NLX");
1380 
1381  p.addPar ("PDVT0", 0.0, false, NO_DEP,
1383  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT0");
1384 
1385  p.addPar ("PDVT1", 0.0, false, NO_DEP,
1387  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT1");
1388 
1389  p.addPar ("PDVT2", 0.0, false, NO_DEP,
1391  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT2");
1392 
1393  p.addPar ("PDVT0W", 0.0, false, NO_DEP,
1395  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT0W");
1396 
1397  p.addPar ("PDVT1W", 0.0, false, NO_DEP,
1399  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT1W");
1400 
1401  p.addPar ("PDVT2W", 0.0, false, NO_DEP,
1403  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DVT2W");
1404 
1405  p.addPar ("PDROUT", 0.0, false, NO_DEP,
1407  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DROUT");
1408 
1409  p.addPar ("PDSUB", 0.0, false, NO_DEP,
1411  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DSUB");
1412 
1413  p.addPar ("PVTH0", 0.0, false, NO_DEP,
1415  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VT0");
1416 
1417  p.addPar ("PUA", 0.0, false, NO_DEP,
1419  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UA");
1420 
1421  p.addPar ("PUA1", 0.0, false, NO_DEP,
1423  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UA1");
1424 
1425  p.addPar ("PUB", 0.0, false, NO_DEP,
1427  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UB");
1428 
1429  p.addPar ("PUB1", 0.0, false, NO_DEP,
1431  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UB1");
1432 
1433  p.addPar ("PUC", 0.0, false, NO_DEP,
1435  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UC");
1436 
1437  p.addPar ("PUC1", 0.0, false, NO_DEP,
1439  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UC1");
1440 
1441  p.addPar ("PU0", 0.0, false, NO_DEP,
1443  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of U0");
1444 
1445  p.addPar ("PUTE", 0.0, false, NO_DEP,
1447  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of UTE");
1448 
1449  p.addPar ("PVOFF", 0.0, false, NO_DEP,
1451  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VOFF");
1452 
1453  p.addPar ("PRDSW", 0.0, false, NO_DEP,
1455  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of RDSW");
1456 
1457  p.addPar ("PPRWG", 0.0, false, NO_DEP,
1459  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PRWG");
1460 
1461  p.addPar ("PPRWB", 0.0, false, NO_DEP,
1463  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PRWB");
1464 
1465  p.addPar ("PPRT", 0.0, false, NO_DEP,
1467  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PRT");
1468 
1469  p.addPar ("PETA0", 0.0, false, NO_DEP,
1471  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ETA0");
1472 
1473  p.addPar ("PETAB", 0.0, false, NO_DEP,
1475  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ETAB");
1476 
1477  p.addPar ("PPCLM", 0.0, false, NO_DEP,
1479  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PCLM");
1480 
1481  p.addPar ("PPDIBLC1", 0.0, false, NO_DEP,
1483  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PDIBLC1");
1484 
1485  p.addPar ("PPDIBLC2", 0.0, false, NO_DEP,
1487  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PDIBLC2");
1488 
1489  p.addPar ("PPDIBLCB", 0.0, false, NO_DEP,
1491  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PDIBLCB");
1492 
1493  p.addPar ("PPSCBE1", 0.0, false, NO_DEP,
1495  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PSCBE1");
1496 
1497  p.addPar ("PPSCBE2", 0.0, false, NO_DEP,
1499  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PSCBE2");
1500 
1501  p.addPar ("PPVAG", 0.0, false, NO_DEP,
1503  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of PVAG");
1504 
1505  p.addPar ("PDELTA", 0.0, false, NO_DEP,
1507  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DELTA");
1508 
1509  p.addPar ("PWR", 0.0, false, NO_DEP,
1511  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of WR");
1512 
1513  p.addPar ("PDWG", 0.0, false, NO_DEP,
1515  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DWG");
1516 
1517  p.addPar ("PDWB", 0.0, false, NO_DEP,
1519  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of DWB");
1520 
1521  p.addPar ("PB0", 0.0, false, NO_DEP,
1523  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of B0");
1524 
1525  p.addPar ("PB1", 0.0, false, NO_DEP,
1527  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of B1");
1528 
1529  p.addPar ("PALPHA0", 0.0, false, NO_DEP,
1531  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ALPHA0");
1532 
1533  p.addPar ("PALPHA1", 0.0, false, NO_DEP,
1535  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ALPHA1");
1536 
1537  p.addPar ("PBETA0", 0.0, false, NO_DEP,
1539  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of BETA0");
1540 
1541  p.addPar ("PVFB", 0.0, false, NO_DEP,
1543  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VFB");
1544 
1545  p.addPar ("PELM", 0.0, false, NO_DEP,
1547  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ELM");
1548 
1549  p.addPar ("PCGSL", 0.0, false, NO_DEP,
1551  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CGSL");
1552 
1553  p.addPar ("PCGDL", 0.0, false, NO_DEP,
1555  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CGDL");
1556 
1557  p.addPar ("PCKAPPA", 0.0, false, NO_DEP,
1559  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CKAPPA");
1560 
1561  p.addPar ("PCF", 0.0, false, NO_DEP,
1563  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CF");
1564 
1565  p.addPar ("PCLC", 0.0, false, NO_DEP,
1567  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CLC");
1568 
1569  p.addPar ("PCLE", 0.0, false, NO_DEP,
1571  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of CLE");
1572 
1573  p.addPar ("PVFBCV", 0.0, false, NO_DEP,
1575  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VFBCV");
1576 
1577  p.addPar ("PNOFF", 0.0, false, NO_DEP,
1579  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of NOFF");
1580 
1581  p.addPar ("PVOFFCV", 0.0, false, NO_DEP,
1583  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of VOFFCV");
1584 
1585  p.addPar ("PACDE", 0.0, false, NO_DEP,
1587  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of ACDE");
1588 
1589  p.addPar ("PMOIN", 0.0, false, NO_DEP,
1591  NULL, U_INVALID, CAT_DEPENDENCY, "Cross-term dependence of MOIN");
1592 
1593 #ifdef FRINGE_DONE
1594  p.addPar ("USEFRINGE", 0.0, false, NO_DEP,
1595  &MOSFET_B3::Model::useFring,
1596  NULL, U_UNKNOWN, CAT_INVALID, "NOT in BSIM3");
1597 
1598 #endif
1599  p.addPar ("TNOM", 0.0, false, NO_DEP,
1601  NULL, STANDARD, CAT_NONE, "");
1602 
1603  p.addPar ("CGSO", 0.0, false, NO_DEP,
1605  NULL, U_FARADMM1, CAT_CAP, "Non-LLD region source-gate overlap capacitance per unit channel length");
1606 
1607  p.addPar ("CGDO", 0.0, false, NO_DEP,
1609  NULL, U_FARADMM1, CAT_CAP, "Non-LLD region drain-gate overlap capacitance per unit channel length");
1610 
1611  p.addPar ("CGBO", 0.0, false, NO_DEP,
1613  NULL, U_FARADMM1, CAT_CAP, "Gate-bulk overlap capacitance per unit channel length");
1614 
1615  p.addPar ("XPART", 0.0, false, NO_DEP,
1617  NULL, U_NONE, CAT_CAP, "Charge partitioning rate flag");
1618 
1619  p.addPar ("RSH", 0.0, false, MIN_RES,
1621  NULL, U_OHM, CAT_RES, "Drain, source diffusion sheet resistance");
1622 
1623  p.addPar ("JS", 1.e-4, false, NO_DEP,
1625  NULL, U_AMPMM2, CAT_PROCESS, "Bulk p-n saturation current density");
1626 
1627  p.addPar ("JSW", 0.0, false, NO_DEP,
1629  NULL, U_AMPMM1, CAT_DC, "Sidewall saturation current per unit length");
1630 
1631  p.addPar ("PB", 1.0, false, NO_DEP,
1633  NULL, U_VOLT, CAT_VOLT, "Bulk p-n bottom potential");
1634 
1635  p.addPar ("MJ", 0.5, false, NO_DEP,
1637  NULL, U_NONE, CAT_DOPING, "Bulk p-n bottom grading coefficient");
1638 
1639  p.addPar ("PBSW", 1.0, false, NO_DEP,
1641  NULL, U_VOLT, CAT_CAP, "Source/drain side junction built-in potential");
1642 
1643  p.addPar ("PBSWG", 0.0, false, NO_DEP,
1645  NULL, U_VOLT, CAT_CAP, "Source/drain gate sidewall junction built-in potential");
1646 
1647  p.addPar ("MJSW", 0.33, false, NO_DEP,
1649  NULL, U_NONE, CAT_DOPING, "Bulk p-n sidewall grading coefficient");
1650 
1651  p.addPar ("CJ", 5.e-4, false, NO_DEP,
1653  NULL, U_FARADMM2, CAT_CAP, "Bulk p-n zero-bias bottom capacitance/area");
1654 
1655  p.addPar ("CJSW", 5.e-10, false, NO_DEP,
1657  NULL, U_FARADMM2, CAT_CAP, "Bulk p-n zero-bias sidewall capacitance/area");
1658 
1659  p.addPar ("MJSWG", 0.0, false, NO_DEP,
1661  NULL, U_NONE, CAT_CAP, "Source/grain gate sidewall junction capacitance grading coeficient");
1662 
1663  p.addPar ("CJSWG", 0.0, false, NO_DEP,
1665  NULL, U_FARADMM1, CAT_CAP, "Source/grain gate sidewall junction capacitance per unit width");
1666 
1667  p.addPar ("NJ", 1.0, false, NO_DEP,
1669  NULL, U_NONE, CAT_TEMP, "Emission coefficient of junction");
1670 
1671  p.addPar ("XTI", 3.0, false, NO_DEP,
1673  NULL, U_NONE, CAT_TEMP, "Junction current temperature exponent coefficient");
1674 
1675  p.addPar ("NOIA", 0.0, false, NO_DEP,
1677  NULL, U_NONE, CAT_FLICKER, "Noise parameter a");
1678 
1679  p.addPar ("NOIB", 0.0, false, NO_DEP,
1681  NULL, U_NONE, CAT_FLICKER, "Noise parameter b");
1682 
1683  p.addPar ("NOIC", 0.0, false, NO_DEP,
1685  NULL, U_NONE, CAT_FLICKER, "Noise parameter c");
1686 
1687  p.addPar ("EM", 4.1e7, false, NO_DEP,
1689  NULL, U_VMM1, CAT_FLICKER, "Saturation field");
1690 
1691  p.addPar ("EF", 1.0, false, NO_DEP,
1693  NULL, U_NONE, CAT_FLICKER, "Flicker exponent");
1694 
1695  p.addPar ("AF", 1.0, false, NO_DEP,
1697  NULL, U_NONE, CAT_FLICKER, "Flicker noise exponent");
1698 
1699  p.addPar ("KF", 0.0, false, NO_DEP,
1701  NULL, U_NONE, CAT_FLICKER, "Flicker noise coefficient");
1702 
1703  p.addPar ("LINT", 0.0, false, NO_DEP,
1705  NULL, U_METER, CAT_DC, "Length of offset fiting parameter from I-V without bias");
1706 
1707  p.addPar ("LL", 0.0, false, NO_DEP,
1709  NULL, U_MEXPLL, CAT_GEOMETRY, "Coefficient of length dependence for length offset");
1710 
1711  p.addPar ("LLC", 0.0, false, NO_DEP,
1713  NULL, U_MEXPLL, CAT_GEOMETRY, "Coefficient of length dependence for CV channel length offset");
1714 
1715  p.addPar ("LLN", 0.0, false, NO_DEP,
1717  NULL, U_NONE, CAT_GEOMETRY, "Power of length dependence for length offset");
1718 
1719  p.addPar ("LW", 0.0, false, NO_DEP,
1721  NULL, U_MEXPLW, CAT_GEOMETRY, "Coefficient of width dependence for length offset");
1722 
1723  p.addPar ("LWC", 0.0, false, NO_DEP,
1725  NULL, U_MEXPLW, CAT_GEOMETRY, "Coefficient of width dependence for channel length offset");
1726 
1727  p.addPar ("LWN", 0.0, false, NO_DEP,
1729  NULL, U_NONE, CAT_GEOMETRY, "Power of width dependence for length offset");
1730 
1731  p.addPar ("LWL", 0.0, false, NO_DEP,
1733  NULL, U_MEXPLLLW, CAT_GEOMETRY, "Coefficient of length and width cross term for length offset");
1734 
1735  p.addPar ("LWLC", 0.0, false, NO_DEP,
1737  NULL, U_MEXPLLLW, CAT_GEOMETRY, "Coefficient of length and width dependence for CV channel length offset");
1738 
1739  p.addPar ("WINT", 0.0, false, NO_DEP,
1741  NULL, U_METER, CAT_DC, "Width-offset fitting parameter from I-V without bias");
1742 
1743  p.addPar ("WL", 0.0, false, NO_DEP,
1745  NULL, U_MEXPWL, CAT_GEOMETRY, "Coefficient of length dependence for width offset");
1746 
1747  p.addPar ("WLC", 0.0, false, NO_DEP,
1749  NULL, U_MEXPWL, CAT_GEOMETRY, "Coefficient of length dependence for CV channel width offset");
1750 
1751  p.addPar ("WLN", 0.0, false, NO_DEP,
1753  NULL, U_NONE, CAT_GEOMETRY, "Power of length dependece of width offset");
1754 
1755  p.addPar ("WW", 0.0, false, NO_DEP,
1757  NULL, U_MEXPWW, CAT_GEOMETRY, "Coefficient of width dependence for width offset");
1758 
1759  p.addPar ("WWC", 0.0, false, NO_DEP,
1761  NULL, U_MEXPWW, CAT_GEOMETRY, "Coefficient of width dependence for CV channel width offset");
1762 
1763  p.addPar ("WWN", 0.0, false, NO_DEP,
1765  NULL, U_NONE, CAT_GEOMETRY, "Power of width dependence of width offset");
1766 
1767  p.addPar ("WWL", 0.0, false, NO_DEP,
1769  NULL, U_MEXPWLWW, CAT_GEOMETRY, "Coefficient of length and width cross term for width offset");
1770 
1771  p.addPar ("WWLC", 0.0, false, NO_DEP,
1773  NULL, U_MEXPWLWW, CAT_GEOMETRY, "Coefficient of length and width dependence for CV channel width offset");
1774 
1775  p.addPar ("L", 5.e-6, false, NO_DEP,
1777  NULL, U_METER, CAT_GEOMETRY, "Channel length");
1778 
1779  p.addPar ("W", 5.e-6, false, NO_DEP,
1781  NULL, U_METER, CAT_GEOMETRY, "Channel width");
1782 
1783  p.addPar ("LMAX", 1.0, false, NO_DEP,
1785  NULL, U_METER, CAT_BIN, "Maximum channel length");
1786 
1787  p.addPar ("LMIN", 0.0, false, NO_DEP,
1789  NULL, U_METER, CAT_BIN, "Minimum channel length");
1790 
1791  p.addPar ("WMAX", 1.0, false, NO_DEP,
1793  NULL, U_METER, CAT_BIN, "Maximum channel width");
1794 
1795  p.addPar ("WMIN", 0.0, false, NO_DEP,
1797  NULL, U_METER, CAT_BIN, "Minimum channel width");
1798 
1799  // Set up exceptions (ie variables that are not doubles):
1800  p.addPar ("MOBMOD", 1, false, NO_DEP,
1801  &MOSFET_B3::Model::mobMod, NULL,
1802  U_NONE, CAT_CONTROL, "Mobility model selector");
1803  p.addPar ("BINUNIT", 1, false, NO_DEP,
1805  U_NONE, CAT_CONTROL, "Binning unit selector");
1806  p.addPar ("CAPMOD", 3, false, NO_DEP,
1807  &MOSFET_B3::Model::capMod, NULL,
1808  U_NONE, CAT_CONTROL, "Flag for capacitance models");
1809  p.addPar ("PARAMCHK", 0, false, NO_DEP,
1811  U_NONE, CAT_CONTROL, "Parameter value check");
1812  p.addPar ("NOIMOD", 1, false, NO_DEP,
1813  &MOSFET_B3::Model::noiMod, NULL,
1814  U_NONE, CAT_CONTROL, "Flag for noise models");
1815  p.addPar ("VERSION", std::string("3.2.2"), false, NO_DEP,
1817  U_NONE, CAT_CONTROL, "Version number");
1818 }
1819 
1820 
1821 
1822 std::vector< std::vector<int> > Instance::jacStamp_DC_SC;
1823 std::vector< std::vector<int> > Instance::jacStamp_DC;
1824 std::vector< std::vector<int> > Instance::jacStamp_SC;
1825 std::vector< std::vector<int> > Instance::jacStamp;
1826 
1827 std::vector<int> Instance::jacMap_DC_SC;
1828 std::vector<int> Instance::jacMap_DC;
1829 std::vector<int> Instance::jacMap_SC;
1830 std::vector<int> Instance::jacMap;
1831 
1832 std::vector< std::vector<int> > Instance::jacMap2_DC_SC;
1833 std::vector< std::vector<int> > Instance::jacMap2_DC;
1834 std::vector< std::vector<int> > Instance::jacMap2_SC;
1835 std::vector< std::vector<int> > Instance::jacMap2;
1836 
1837 // Class Instance
1838 //-----------------------------------------------------------------------------
1839 // Function : Instance::processParams
1840 // Purpose :
1841 // Special Notes :
1842 // Scope : public
1843 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1844 //-----------------------------------------------------------------------------
1846 {
1847 
1848  // process source/drain series resistance
1850 
1851  if (drainConductance > 0.0)
1853  else
1854  drainConductance = 0.0;
1855 
1857 
1858  if (sourceConductance > 0.0)
1860  else
1861  sourceConductance = 0.0;
1862 
1863  numIntVars = 0;
1864  if ( sourceConductance!=0.0 ) ++numIntVars;
1865  if ( drainConductance!=0.0 ) ++numIntVars;
1866  if ( nqsMod ) ++numIntVars;
1867 
1868  if (icVDSGiven) ++numIntVars;
1869  if (icVGSGiven) ++numIntVars;
1870  if (icVBSGiven) ++numIntVars;
1871 
1872 
1873  // If there are any time dependent parameters, set their values at for
1874  // the current time.
1875 
1876  // now set the temperature related stuff.
1878 
1879  return true;
1880 }
1881 
1882 //-----------------------------------------------------------------------------
1883 // Function : Instance::Instance
1884 // Purpose : instance block constructor
1885 // Special Notes :
1886 // Scope : public
1887 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1888 // Creation Date : 11/14/00
1889 //-----------------------------------------------------------------------------
1891  const Configuration & configuration,
1892  const InstanceBlock & IB,
1893  Model &model,
1894  const FactoryBlock & factory_block)
1895  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
1896  model_ (model),
1897  dNode (0),
1898  gNode (0),
1899  sNode (0),
1900  bNode (0),
1901  dNodePrime (0),
1902  sNodePrime (0),
1903  qNode (0),
1904  ueff (0.0),
1905  thetavth (0.0),
1906  von (0.0),
1907  vdsat (0.0),
1908  cgdo (0.0),
1909  cgso (0.0),
1910  vjsm (0.0),
1911  IsEvjsm (0.0),
1912  vjdm (0.0),
1913  IsEvjdm (0.0),
1914  l (getDeviceOptions().defl),
1915  w (getDeviceOptions().defw),
1916  drainArea (getDeviceOptions().defad),
1917  sourceArea (getDeviceOptions().defas),
1918  drainSquares (1.0),
1919  sourceSquares (1.0),
1920  drainPerimeter (0.0),
1921  sourcePerimeter (0.0),
1922  sourceConductance (0.0),
1923  drainConductance (0.0),
1924  icVBS (0.0),
1925  icVDS (0.0),
1926  icVGS (0.0),
1927  OFF (false),
1928  mode (0),
1929  nqsMod (0),
1930  numberParallel (1.0),
1931  qinv (0.0),
1932  cd (0.0),
1933  cbs (0.0),
1934  cbd (0.0),
1935  csub (0.0),
1936  cdrain (0.0),
1937  gm (0.0),
1938  gds (0.0),
1939  gmbs (0.0),
1940  gbd (0.0),
1941  gbs (0.0),
1942  gbbs (0.0),
1943  gbgs (0.0),
1944  gbds (0.0),
1945  cggb (0.0),
1946  cgdb (0.0),
1947  cgsb (0.0),
1948  cbgb (0.0),
1949  cbdb (0.0),
1950  cbsb (0.0),
1951  cdgb (0.0),
1952  cddb (0.0),
1953  cdsb (0.0),
1954  capbd (0.0),
1955  capbs (0.0),
1956  cqgb (0.0),
1957  cqdb (0.0),
1958  cqsb (0.0),
1959  cqbb (0.0),
1960  qgate (0.0),
1961  qbulk (0.0),
1962  qdrn (0.0),
1963  gtau (0.0),
1964  gtg (0.0),
1965  gtd (0.0),
1966  gts (0.0),
1967  gtb (0.0),
1968  limitedFlag (false),
1969  paramPtr (NULL),
1970  icVBSGiven (0),
1971  icVDSGiven (0),
1972  icVGSGiven (0),
1973  temp (getDeviceOptions().temp.getImmutableValue<double>()),
1974  ChargeComputationNeeded (true),
1975  gcbdb (0.0),
1976  gcbgb (0.0),
1977  gcbsb (0.0),
1978  gcddb (0.0),
1979  gcdgb (0.0),
1980  gcdsb (0.0),
1981  gcgdb (0.0),
1982  gcggb (0.0),
1983  gcgsb (0.0),
1984  gcsdb (0.0),
1985  gcsgb (0.0),
1986  gcssb (0.0),
1987  qgd (0.0),
1988  qgs (0.0),
1989  qgb (0.0),
1990  qgdo (0.0),
1991  qgso (0.0),
1992  qsrc (0.0),
1993  CoxWL (0.0),
1994  Cgg (0.0),
1995  Cgd (0.0),
1996  Cgb (0.0),
1997  Cdg (0.0),
1998  Cdd (0.0),
1999  Cds (0.0),
2000  Csg (0.0),
2001  Csd (0.0),
2002  Css (0.0),
2003  Csb (0.0),
2004  Cbg (0.0),
2005  Cbd (0.0),
2006  Cbb (0.0),
2007  CAPcggb (0.0),
2008  CAPcgdb (0.0),
2009  CAPcgsb (0.0),
2010  CAPcbgb (0.0),
2011  CAPcbdb (0.0),
2012  CAPcbsb (0.0),
2013  CAPcdgb (0.0),
2014  CAPcddb (0.0),
2015  CAPcdsb (0.0),
2016  CAPcsgb (0.0),
2017  CAPcsdb (0.0),
2018  CAPcssb (0.0),
2019  Qeqqd_Jdxp (0.0),
2020  Qeqqb_Jdxp (0.0),
2021  Qeqqg_Jdxp (0.0),
2022  dxpart (0.0),
2023  sxpart (0.0),
2024  ggtg (0.0),
2025  ggtd (0.0),
2026  ggts (0.0),
2027  ggtb (0.0),
2028  ddxpart_dVd (0.0),
2029  ddxpart_dVg (0.0),
2030  ddxpart_dVb (0.0),
2031  ddxpart_dVs (0.0),
2032  dsxpart_dVd (0.0),
2033  dsxpart_dVg (0.0),
2034  dsxpart_dVb (0.0),
2035  dsxpart_dVs (0.0),
2036  gbspsp (0.0),
2037  gbbdp (0.0),
2038  gbbsp (0.0),
2039  gbspg (0.0),
2040  gbspb (0.0),
2041  gbspdp (0.0),
2042  gbdpdp (0.0),
2043  gbdpg (0.0),
2044  gbdpb (0.0),
2045  gbdpsp (0.0),
2046  cdreq (0.0),
2047  ceqbd (0.0),
2048  ceqbs (0.0),
2049  Gm (0.0),
2050  Gmbs (0.0),
2051  FwdSum (0.0),
2052  RevSum (0.0),
2053  T1global (0.0),
2054  dVgst_dVg (0.0),
2055  dVgst_dVb (0.0),
2056  dVgs_eff_dVg (0.0),
2057  dDeltaPhi_dVg (0.0),
2058  dDeltaPhi_dVd (0.0),
2059  dDeltaPhi_dVb (0.0),
2060  vtm (0.0),
2061  jctTempSatCurDensity (0.0),
2062  jctSidewallTempSatCurDensity (0.0),
2063  unitAreaJctCapTemp (0.0),
2064  unitLengthSidewallJctCapTemp (0.0),
2065  unitLengthGateSidewallJctCapTemp (0.0),
2066  PhiBTemp (0.0),
2067  PhiBSWTemp (0.0),
2068  PhiBSWGTemp (0.0),
2069  Vd (0.0),
2070  Vs (0.0),
2071  Vg (0.0),
2072  Vb (0.0),
2073  Vsp (0.0),
2074  Vdp (0.0),
2075  Qtotal (0.0),
2076  Vddp (0.0),
2077  Vssp (0.0),
2078  Vbsp (0.0),
2079  Vbdp (0.0),
2080  Vgsp (0.0),
2081  Vgdp (0.0),
2082  Vgb (0.0),
2083  Vdpsp (0.0),
2084  Idrain (0.0),
2085  Isource (0.0),
2086  df1dVdp (0.0),
2087  df2dVdp (0.0),
2088  df1dVsp (0.0),
2089  df2dVsp (0.0),
2090  df1dVg (0.0),
2091  df2dVg (0.0),
2092  df1dVb (0.0),
2093  df2dVb (0.0),
2094  vbd_old (0.0),
2095  vbs_old (0.0),
2096  vgs_old (0.0),
2097  vds_old (0.0),
2098  vgs_orig (0.0),
2099  vds_orig (0.0),
2100  vbs_orig (0.0),
2101  vbd_orig (0.0),
2102  vgd_orig (0.0),
2103  newtonIterOld (0),
2104  cqdef (0.0),
2105  vgb (0.0),
2106  vgd (0.0),
2107  vbd (0.0),
2108  vbs (0.0),
2109  vgs (0.0),
2110  vds (0.0),
2111  qb (0.0),
2112  qg (0.0),
2113  qd (0.0),
2114  qbs (0.0),
2115  qbd (0.0),
2116  qcheq (0.0),
2117  qcdump (0.0),
2118  qdef (0.0),
2119  gqdef (0.0),
2120  gcqdb (0.0),
2121  gcqsb (0.0),
2122  gcqgb (0.0),
2123  gcqbb (0.0),
2124  ScalingFactor (0.0),
2125  cqgate (0.0),
2126  cqbulk (0.0),
2127  cqdrn (0.0),
2128  cdreq_Jdxp (0.0),
2129  ceqbd_Jdxp (0.0),
2130  ceqbs_Jdxp (0.0),
2131  cqdef_Jdxp (0.0),
2132  ceqqd_Jdxp (0.0),
2133  ceqqb_Jdxp (0.0),
2134  ceqqg_Jdxp (0.0),
2135 // matrix and vectors indices:
2136 // state vector: (local indices)
2137  li_store_vbd (-1),
2138  li_store_vbs (-1),
2139  li_store_vgs (-1),
2140  li_store_vds (-1),
2141  li_store_von (-1),
2142  li_store_dev_id (-1),
2143  li_store_dev_is (-1),
2144  li_store_dev_ig (-1),
2145  li_store_dev_ib (-1),
2146  li_state_qb (-1),
2147  li_state_qg (-1),
2148  li_state_qd (-1),
2149  li_state_qbs (-1),
2150  li_state_qbd (-1),
2151  li_state_qcheq (-1),
2152  li_state_qcdump (-1),
2153  li_state_qdef (-1),
2154 // solution vector: (local indices)
2155  li_Drain (-1),
2156  li_Gate (-1),
2157  li_Source (-1),
2158  li_Bulk (-1),
2159  li_DrainPrime (-1),
2160  li_SourcePrime (-1),
2161  li_Charge (-1),
2162  li_Ibs (-1),
2163  li_Ids (-1),
2164  li_Igs (-1),
2165 // matrix offsets:
2166 // jacobian:
2167 // drain row
2168  ADrainEquDrainNodeOffset (-1),
2169  ADrainEquDrainPrimeNodeOffset (-1),
2170  ADrainEquIdsOffset (-1),
2171 // gate row
2172  AGateEquGateNodeOffset (-1),
2173  AGateEquBulkNodeOffset (-1),
2174  AGateEquDrainPrimeNodeOffset (-1),
2175  AGateEquSourcePrimeNodeOffset (-1),
2176  AGateEquChargeVarOffset (-1),
2177  AGateEquIgsOffset (-1),
2178 // source row
2179  ASourceEquSourceNodeOffset (-1),
2180  ASourceEquSourcePrimeNodeOffset (-1),
2181  ASourceEquIbsOffset (-1),
2182  ASourceEquIdsOffset (-1),
2183  ASourceEquIgsOffset (-1),
2184 // bulk row
2185  ABulkEquGateNodeOffset (-1),
2186  ABulkEquBulkNodeOffset (-1),
2187  ABulkEquDrainPrimeNodeOffset (-1),
2188  ABulkEquSourcePrimeNodeOffset (-1),
2189  ABulkEquChargeVarOffset (-1),
2190  ABulkEquIbsOffset (-1),
2191 // drain' row
2192  ADrainPrimeEquDrainNodeOffset (-1),
2193  ADrainPrimeEquGateNodeOffset (-1),
2194  ADrainPrimeEquBulkNodeOffset (-1),
2195  ADrainPrimeEquDrainPrimeNodeOffset (-1),
2196  ADrainPrimeEquSourcePrimeNodeOffset (-1),
2197  ADrainPrimeEquChargeVarOffset (-1),
2198 // source' row
2199  ASourcePrimeEquGateNodeOffset (-1),
2200  ASourcePrimeEquSourceNodeOffset (-1),
2201  ASourcePrimeEquBulkNodeOffset (-1),
2202  ASourcePrimeEquDrainPrimeNodeOffset (-1),
2203  ASourcePrimeEquSourcePrimeNodeOffset (-1),
2204  ASourcePrimeEquChargeVarOffset (-1),
2205 // Charge row
2206  AChargeEquChargeVarOffset (-1),
2207  AChargeEquDrainPrimeNodeOffset (-1),
2208  AChargeEquGateNodeOffset (-1),
2209  AChargeEquSourcePrimeNodeOffset (-1),
2210  AChargeEquBulkNodeOffset (-1),
2211  icVBSEquVsOffset (-1),
2212  icVBSEquVbOffset (-1),
2213  icVBSEquIbsOffset (-1),
2214  icVDSEquVdOffset (-1),
2215  icVDSEquVsOffset (-1),
2216  icVDSEquIdsOffset (-1),
2217  icVGSEquVgOffset (-1),
2218  icVGSEquVsOffset (-1),
2219  icVGSEquIgsOffset (-1),
2221 //
2222  // V_d Row:
2223  f_DrainEquDrainNodePtr(0), // a
2224  f_DrainEquDrainPrimeNodePtr(0), // b
2225  f_DrainEquIdsPtr(0), // i1
2226 
2227  // V_g Row:
2228  f_GateEquGateNodePtr(0), // c
2229  f_GateEquBulkNodePtr(0), // d
2230  f_GateEquDrainPrimeNodePtr(0), // e
2231  f_GateEquSourcePrimeNodePtr(0), // f
2232  f_GateEquChargeVarPtr(0), // 1
2233  f_GateEquIgsPtr(0), // i2
2234 
2235  // V_s Row:
2236  f_SourceEquSourceNodePtr(0), // g
2237  f_SourceEquSourcePrimeNodePtr(0), // h
2238  f_SourceEquIbsPtr(0), // i3
2239  f_SourceEquIdsPtr(0), // i4
2240  f_SourceEquIgsPtr(0), // i5
2241 
2242  // V_b Row:
2243  f_BulkEquGateNodePtr(0), // i
2244  f_BulkEquBulkNodePtr(0), // j
2245  f_BulkEquDrainPrimeNodePtr(0), // k
2246  f_BulkEquSourcePrimeNodePtr(0), // l
2247  f_BulkEquChargeVarPtr(0), // 2
2248  f_BulkEquIbsPtr(0), // i6
2249 
2250  // V_d' Row:
2251  f_DrainPrimeEquDrainNodePtr(0), // m
2252  f_DrainPrimeEquGateNodePtr(0), // n
2253  f_DrainPrimeEquBulkNodePtr(0), // o
2254  f_DrainPrimeEquDrainPrimeNodePtr(0), // p
2255  f_DrainPrimeEquSourcePrimeNodePtr(0), // q
2256  f_DrainPrimeEquChargeVarPtr(0), // 3
2257 
2258  // V_s' Row:
2259  f_SourcePrimeEquGateNodePtr(0), // r
2260  f_SourcePrimeEquSourceNodePtr(0), // s
2261  f_SourcePrimeEquBulkNodePtr(0), // t
2262  f_SourcePrimeEquDrainPrimeNodePtr(0), // u
2263  f_SourcePrimeEquSourcePrimeNodePtr(0), // v
2264  f_SourcePrimeEquChargeVarPtr(0), // 4
2265 
2266  // MOSFET charge (Q) Row:
2267  f_ChargeEquChargeVarPtr(0), // 5
2268  f_ChargeEquDrainPrimeNodePtr(0), // 6
2269  f_ChargeEquGateNodePtr(0), // 7
2270  f_ChargeEquSourcePrimeNodePtr(0), // 8
2271  f_ChargeEquBulkNodePtr(0), // 9
2272 
2273  // icVBS
2274  f_icVBSEquVsPtr(0), // i7
2275  f_icVBSEquVbPtr(0), // i8
2276  f_icVBSEquIbsPtr(0), // i9
2277 
2278  // icVDS
2279  f_icVDSEquVdPtr(0), // i10
2280  f_icVDSEquVsPtr(0), // i11
2281  f_icVDSEquIdsPtr(0), // i12
2282 
2283  // icVGS
2284  f_icVGSEquVgPtr(0), // i13
2285  f_icVGSEquVsPtr(0), // i14
2286  f_icVGSEquIgsPtr(0), // i15
2287 
2288  // V_d Row:
2289  q_DrainEquDrainNodePtr(0), // a
2290  q_DrainEquDrainPrimeNodePtr(0), // b
2291  q_DrainEquIdsPtr(0), // i1
2292 
2293  // V_g Row:
2294  q_GateEquGateNodePtr(0), // c
2295  q_GateEquBulkNodePtr(0), // d
2296  q_GateEquDrainPrimeNodePtr(0), // e
2297  q_GateEquSourcePrimeNodePtr(0), // f
2298  q_GateEquChargeVarPtr(0), // 1
2299  q_GateEquIgsPtr(0), // i2
2300 
2301  // V_s Row:
2302  q_SourceEquSourceNodePtr(0), // g
2303  q_SourceEquSourcePrimeNodePtr(0), // h
2304  q_SourceEquIbsPtr(0), // i3
2305  q_SourceEquIdsPtr(0), // i4
2306  q_SourceEquIgsPtr(0), // i5
2307 
2308  // V_b Row:
2309  q_BulkEquGateNodePtr(0), // i
2310  q_BulkEquBulkNodePtr(0), // j
2311  q_BulkEquDrainPrimeNodePtr(0), // k
2312  q_BulkEquSourcePrimeNodePtr(0), // l
2313  q_BulkEquChargeVarPtr(0), // 2
2314  q_BulkEquIbsPtr(0), // i6
2315 
2316  // V_d' Row:
2317  q_DrainPrimeEquDrainNodePtr(0), // m
2318  q_DrainPrimeEquGateNodePtr(0), // n
2319  q_DrainPrimeEquBulkNodePtr(0), // o
2320  q_DrainPrimeEquDrainPrimeNodePtr(0), // p
2321  q_DrainPrimeEquSourcePrimeNodePtr(0), // q
2322  q_DrainPrimeEquChargeVarPtr(0), // 3
2323 
2324  // V_s' Row:
2325  q_SourcePrimeEquGateNodePtr(0), // r
2326  q_SourcePrimeEquSourceNodePtr(0), // s
2327  q_SourcePrimeEquBulkNodePtr(0), // t
2328  q_SourcePrimeEquDrainPrimeNodePtr(0), // u
2329  q_SourcePrimeEquSourcePrimeNodePtr(0), // v
2330  q_SourcePrimeEquChargeVarPtr(0), // 4
2331 
2332  // MOSFET charge (Q) Row:
2333  q_ChargeEquChargeVarPtr(0), // 5
2334  q_ChargeEquDrainPrimeNodePtr(0), // 6
2335  q_ChargeEquGateNodePtr(0), // 7
2336  q_ChargeEquSourcePrimeNodePtr(0), // 8
2337  q_ChargeEquBulkNodePtr(0), // 9
2338 
2339  // icVBS
2340  q_icVBSEquVsPtr(0), // i7
2341  q_icVBSEquVbPtr(0), // i8
2342  q_icVBSEquIbsPtr(0), // i9
2343 
2344  // icVDS
2345  q_icVDSEquVdPtr(0), // i10
2346  q_icVDSEquVsPtr(0), // i11
2347  q_icVDSEquIdsPtr(0), // i12
2348 
2349  // icVGS
2350  q_icVGSEquVgPtr(0), // i13
2351  q_icVGSEquVsPtr(0), // i14
2352  q_icVGSEquIgsPtr(0), // i15
2353 //
2354 #endif
2355  blockHomotopyID (0),
2356  randomPerturb (0.0),
2357  // one last thing
2358  updateTemperatureCalled_ (false)
2359 {
2360  numIntVars = 3;
2361  numExtVars = 4;
2362  numStateVars = 12;
2363  setNumStoreVars(5);
2364  numLeadCurrentStoreVars = 4; // drain, gate, source & base lead currents
2365 
2366  devConMap.resize(4);
2367  devConMap[0] = 1;
2368  devConMap[1] = 2;
2369  devConMap[2] = 1;
2370  devConMap[3] = 3;
2371 
2372  blockHomotopyID =
2373  devSupport.getGainScaleBlockID(getDeviceOptions().numGainScaleBlocks);
2374  randomPerturb =
2376 
2377 
2378  if( jacStamp.empty() )
2379  {
2380  jacStamp_DC_SC.resize(6);
2381  jacStamp_DC_SC[0].resize(2);
2382  jacStamp_DC_SC[0][0]=0;
2383  jacStamp_DC_SC[0][1]=4;
2384  jacStamp_DC_SC[1].resize(4);
2385  jacStamp_DC_SC[1][0]=1;
2386  jacStamp_DC_SC[1][1]=3;
2387  jacStamp_DC_SC[1][2]=4;
2388  jacStamp_DC_SC[1][3]=5;
2389  jacStamp_DC_SC[2].resize(2);
2390  jacStamp_DC_SC[2][0]=2;
2391  jacStamp_DC_SC[2][1]=5;
2392  jacStamp_DC_SC[3].resize(4);
2393  jacStamp_DC_SC[3][0]=1;
2394  jacStamp_DC_SC[3][1]=3;
2395  jacStamp_DC_SC[3][2]=4;
2396  jacStamp_DC_SC[3][3]=5;
2397  jacStamp_DC_SC[4].resize(5);
2398  jacStamp_DC_SC[4][0]=0;
2399  jacStamp_DC_SC[4][1]=1;
2400  jacStamp_DC_SC[4][2]=3;
2401  jacStamp_DC_SC[4][3]=4;
2402  jacStamp_DC_SC[4][4]=5;
2403  jacStamp_DC_SC[5].resize(5);
2404  jacStamp_DC_SC[5][0]=1;
2405  jacStamp_DC_SC[5][1]=2;
2406  jacStamp_DC_SC[5][2]=3;
2407  jacStamp_DC_SC[5][3]=4;
2408  jacStamp_DC_SC[5][4]=5;
2409 
2410  jacMap_DC_SC.clear();
2412  jacStamp_DC, jacMap_DC, jacMap2_DC, 5, 2, 6);
2413 
2415  jacStamp_SC, jacMap_SC, jacMap2_SC, 4, 0, 6);
2416 
2418  jacStamp, jacMap, jacMap2, 4, 0, 6);
2419 
2420 #ifdef Xyce_DEBUG_DEVICE
2421  if (getDeviceOptions().debugLevel > 0)
2422  {
2423  Xyce::dout() << "Instance::Instance jacStampMap_DS_SC" << std::endl;
2424  for (int k = 0; k<jacMap_DC_SC.size(); ++k )
2425  {
2426  Xyce::dout() << "jacStamp_DC_SC[ " << jacMap_DC_SC[k] << " ] = { ";
2427  for (int q = 0; q < jacMap2_DC_SC[k].size(); ++q )
2428  {
2429  Xyce::dout() << jacStamp_DC_SC[jacMap_DC_SC[k]][jacMap2_DC_SC[k][q]] << " ";
2430  }
2431  Xyce::dout() << "}" << std::endl;
2432  }
2433 
2434  Xyce::dout() << "Instance::Instance jacStampMap_DS" << std::endl;
2435  for (int k = 0; k<jacMap_DC.size(); ++k )
2436  {
2437  Xyce::dout() << "jacStamp_DC[ " << jacMap_DC[k] << " ] = { ";
2438  for (int q = 0; q < jacMap2_DC[k].size(); ++q )
2439  {
2440  Xyce::dout() << jacStamp_DC[jacMap_DC[k]][jacMap2_DC[k][q]] << " ";
2441  }
2442  Xyce::dout() << "}" << std::endl;
2443  }
2444 
2445  Xyce::dout() << "Instance::Instance jacStampMap_SC" << std::endl;
2446  for (int k = 0; k<jacMap_SC.size(); ++k )
2447  {
2448  Xyce::dout() << "jacStamp_SC[ " << jacMap_SC[k] << " ] = { ";
2449  for (int q = 0; q < jacMap2_SC[k].size(); ++q )
2450  {
2451  Xyce::dout() << jacStamp_SC[jacMap_SC[k]][jacMap2_SC[k][q]] << " ";
2452  }
2453  Xyce::dout() << "}" << std::endl;
2454  }
2455 
2456  Xyce::dout() << "Instance::Instance jacStampMap" << std::endl;
2457  for (int k = 0; k<jacMap.size(); ++k )
2458  {
2459  Xyce::dout() << "jacStamp[ " << jacMap[k] << " ] = { ";
2460  for (int q = 0; q < jacMap2[k].size(); ++q )
2461  {
2462  Xyce::dout() << jacStamp[jacMap[k]][jacMap2[k][q]] << " ";
2463  }
2464  Xyce::dout() << "}" << std::endl;
2465  }
2466  }
2467 #endif
2468  }
2469 
2470  // Set params to constant default values:
2471  setDefaultParams ();
2472 
2473  // Set params according to instance line and constant defaults from metadata:
2474  setParams (IB.params);
2475 
2476  // Set any non-constant parameter defaults:
2477  if (!given("TEMP"))
2478  temp = getDeviceOptions().temp.getImmutableValue<double>();
2479  if (!given("L"))
2480  l =model_.model_l;
2481  if (!given("W"))
2482  w = model_.model_w;
2483  if (!given("AD"))
2485  if (!given("AS"))
2487 
2488  // Calculate any parameters specified as expressions:
2490 
2491  // calculate dependent (ie computed) params and check for errors:
2492  processParams ();
2493 
2494  if (given("NQSMOD"))
2495  {
2496  std::string msg = "Instance::Instance";
2497  msg += " nsqMod = 1. Not allowed yet. Setting to 0.\n";
2498  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
2499  }
2500 
2501  if (getDeviceOptions().verboseLevel > 0 && (l > model_.Lmax || l < model_.Lmin))
2502  {
2503  UserWarning(*this) << "Channel length out of range";
2504  }
2505 
2506  if (getDeviceOptions().verboseLevel > 0 && (w > model_.Wmax || w < model_.Wmin))
2507  {
2508  UserWarning(*this) << "Channel width out of range";
2509  }
2510 
2511  // if we need to, build the jacobian stamp and operating point
2512  // jacobian stamp specificly needed for this device's initial
2513  // conditions
2514 
2515  // There are 4 optional internal variables that may be included in
2516  // this device: charge Q, Vbs, Vds and Vgs. We need to assign these
2517  // variables to columns in our jacobian depending on what's there.
2518  // For example if they're all required than Q is the 7th variable
2519  // and goes in column 6 (numbering from zero), Vbs is 8th in column
2520  // 7, Vds is 9th in column, Vgs is 10th in column 9. If any
2521  // variable is not needed, those in higher columns shift
2522  // down. I.e. if Q isn't needed, then Vbs is in column 6, Vds in
2523  // column 7 and Vgs in column 8.
2524 
2525  int currentCol = 6;
2526  int numExtraCol = 0;
2527  int qCol = -1, icVBSCol = -1, icVDSCol = -1, icVGSCol = -1;
2528  if( nqsMod )
2529  {
2530  qCol = currentCol;
2531  ++currentCol;
2532  ++numExtraCol;
2533  }
2534  if( icVBSGiven )
2535  {
2536  icVBSCol = currentCol;
2537  ++currentCol;
2538  ++numExtraCol;
2539  }
2540  if( icVDSGiven )
2541  {
2542  icVDSCol = currentCol;
2543  ++currentCol;
2544  ++numExtraCol;
2545  }
2546  if( icVGSGiven )
2547  {
2548  icVGSCol = currentCol;
2549  ++currentCol;
2550  ++numExtraCol;
2551  }
2552 
2553  // ok now build this instance's jacobian stamp
2554  if( nqsMod || icVBSGiven || icVDSGiven || icVGSGiven )
2555  {
2556  // we need a special version of the jacStamp for the
2557  jacStampSpecial.resize(6 + numExtraCol);
2558  // row KCL d
2559  int numNonZeros = 2 + (icVDSGiven ? 1:0);
2560  jacStampSpecial[0].resize( numNonZeros );
2561  jacStampSpecial[0][0]=0;
2562  jacStampSpecial[0][1]=4;
2563  currentCol = 2;
2564  if( icVDSGiven )
2565  {
2566  jacStampSpecial[0][currentCol]=icVDSCol;
2567  ++currentCol;
2568  }
2569 
2570  // row KCL g
2571  numNonZeros = 4 + (nqsMod ? 1:0 ) + (icVGSGiven ? 1:0);
2572  jacStampSpecial[1].resize( numNonZeros );
2573  jacStampSpecial[1][0]=1;
2574  jacStampSpecial[1][1]=3;
2575  jacStampSpecial[1][2]=4;
2576  jacStampSpecial[1][3]=5;
2577  currentCol = 4;
2578  if( nqsMod )
2579  {
2580  jacStampSpecial[1][currentCol]=qCol;
2581  ++currentCol;
2582  }
2583  if( icVGSGiven )
2584  {
2585  jacStampSpecial[1][currentCol]=icVGSCol;
2586  }
2587 
2588  // row KCL s
2589  numNonZeros = 2 + (icVBSGiven ? 1:0) + (icVDSGiven ? 1:0) + (icVGSGiven ? 1:0);
2590  jacStampSpecial[2].resize( numNonZeros );
2591  jacStampSpecial[2][0]=2;
2592  jacStampSpecial[2][1]=5;
2593  currentCol = 2;
2594  if ( icVBSGiven )
2595  {
2596  jacStampSpecial[2][currentCol] = icVBSCol;
2597  ++currentCol;
2598  }
2599  if( icVDSGiven )
2600  {
2601  jacStampSpecial[2][currentCol] = icVDSCol;
2602  ++currentCol;
2603  }
2604  if( icVGSGiven )
2605  {
2606  jacStampSpecial[2][currentCol] = icVGSCol;
2607  ++currentCol;
2608  }
2609 
2610  // row KCL b
2611  numNonZeros = 4 + (nqsMod ? 1:0 ) + (icVBSGiven ? 1:0);
2612  jacStampSpecial[3].resize( numNonZeros );
2613  jacStampSpecial[3][0]=1;
2614  jacStampSpecial[3][1]=3;
2615  jacStampSpecial[3][2]=4;
2616  jacStampSpecial[3][3]=5;
2617  currentCol = 4;
2618  if( nqsMod )
2619  {
2620  jacStampSpecial[3][currentCol] = qCol;
2621  ++currentCol;
2622  }
2623  if( icVBSGiven )
2624  {
2625  jacStampSpecial[3][currentCol] = icVBSCol;
2626  ++currentCol;
2627  }
2628 
2629  // row KCL d'
2630  numNonZeros = 5 + (nqsMod ? 1:0 );
2631  jacStampSpecial[4].resize( numNonZeros );
2632  jacStampSpecial[4][0]=0;
2633  jacStampSpecial[4][1]=1;
2634  jacStampSpecial[4][2]=3;
2635  jacStampSpecial[4][3]=4;
2636  jacStampSpecial[4][4]=5;
2637  currentCol = 5;
2638  if( nqsMod )
2639  {
2640  jacStampSpecial[4][currentCol] = qCol;
2641  ++currentCol;
2642  }
2643 
2644  // row KCL s'
2645  numNonZeros = 5 + (nqsMod ? 1:0 );
2646  jacStampSpecial[5].resize( numNonZeros );
2647  jacStampSpecial[5][0]=1;
2648  jacStampSpecial[5][1]=2;
2649  jacStampSpecial[5][2]=3;
2650  jacStampSpecial[5][3]=4;
2651  jacStampSpecial[5][4]=5;
2652  currentCol = 5;
2653  if( nqsMod )
2654  {
2655  jacStampSpecial[5][currentCol] = qCol;
2656  ++currentCol;
2657  }
2658 
2659  int currentRow = 6;
2660 
2661  // Q row if we need it
2662  if( nqsMod )
2663  {
2664  // add in charge row
2665  jacStampSpecial[currentRow].resize( 5 );
2666  jacStampSpecial[currentRow][0] = 1;
2667  jacStampSpecial[currentRow][1] = 3;
2668  jacStampSpecial[currentRow][2] = 4;
2669  jacStampSpecial[currentRow][3] = 5;
2670  jacStampSpecial[currentRow][4] = qCol;
2671  ++currentRow;
2672  }
2673 
2674  // icVBS row if we need it
2675  if( icVBSGiven )
2676  {
2677  jacStampSpecial[currentRow].resize( 3 );
2678  jacStampSpecial[currentRow][0] = 2;
2679  jacStampSpecial[currentRow][1] = 3;
2680  jacStampSpecial[currentRow][2] = icVBSCol;
2681  ++currentRow;
2682  }
2683 
2684  // icVDS row if we need it
2685  if( icVDSGiven )
2686  {
2687  jacStampSpecial[currentRow].resize( 3 );
2688  jacStampSpecial[currentRow][0] = 0;
2689  jacStampSpecial[currentRow][1] = 2;
2690  jacStampSpecial[currentRow][2] = icVDSCol;
2691  ++currentRow;
2692  }
2693 
2694  // icVGS row if we need it
2695  if( icVGSGiven )
2696  {
2697  jacStampSpecial[currentRow].resize( 3 );
2698  jacStampSpecial[currentRow][0] = 1;
2699  jacStampSpecial[currentRow][1] = 2;
2700  jacStampSpecial[currentRow][2] = icVGSCol;
2701  ++currentRow;
2702  }
2703 
2704  // now we just need to merge Vd' and or Vs' nodes if that's called
2705  // for in this device
2706  if ( (drainConductance == 0.0) && (sourceConductance == 0.0) )
2707  {
2708  // temporary to hold intermediate results
2709  std::vector< std::vector<int> > jacStampSpecialMergedTemp;
2710  std::vector<int> jacSpecialMapTemp;
2711  std::vector< std::vector<int> > jacSpecialMapTemp2;
2712 
2714  jacStampSpecialMergedTemp, jacSpecialMapTemp, jacSpecialMapTemp2,
2715  5, 2, jacStampSpecial.size() );
2716 
2717  jacStampMap( jacStampSpecialMergedTemp, jacSpecialMapTemp, jacSpecialMapTemp2,
2719  4, 0, jacStampSpecial.size() );
2720 
2721  }
2722  else if (drainConductance == 0.0)
2723  {
2726  4, 0, jacStampSpecial.size() );
2727 
2728  }
2729  else if (sourceConductance == 0.0)
2730  {
2733  5, 2, jacStampSpecial.size() );
2734  }
2735  else
2736  {
2737  // no rows or columns were merged, but we need to initialize
2738  // jacSpecialMap and jacSpecialMap2 as these will be used to
2739  // index into the jacobian in registerJacLIDs()
2740  // copied from DeviceInstance::jacStampMap initialization
2741 
2742  if (jacSpecialMap.size() == 0)
2743  {
2744  jacSpecialMap.resize(jacStampSpecial.size());
2745  jacSpecialMap2.resize(jacStampSpecial.size());
2746  for (int i=0 ; i<jacStampSpecial.size() ; ++i)
2747  {
2748  jacSpecialMap[i] = i;
2749  jacSpecialMap2[i].resize(jacStampSpecial[i].size());
2750  for (int j=0 ; j<jacStampSpecial[i].size() ; ++j)
2751  {
2752  jacSpecialMap2[i][j] = j;
2753  }
2754  }
2755  }
2756  }
2757  }
2758 #ifdef Xyce_DEBUG_DEVICE
2759  if (getDeviceOptions().debugLevel > 0)
2760  {
2761  Xyce::dout() << "Instance::Instance jacStampSpecial" << std::endl;
2762  for (int k = 0; k<jacSpecialMap.size(); ++k )
2763  {
2764  Xyce::dout() << "jacSpecialMap[" << jacSpecialMap[k] << " ] = { ";
2765  for (int q = 0; q < jacSpecialMap2[k].size(); ++q )
2766  {
2767  Xyce::dout() << jacStampSpecial[jacSpecialMap[k]][jacSpecialMap2[k][q]] <<" ";
2768  }
2769  Xyce::dout() << "}" << std::endl;
2770  }
2771 
2772  Xyce::dout() << "Instance::Instance jacStampSpecialMerged" << std::endl;
2773  for (int k = 0; k<jacSpecialMergedMap.size(); ++k )
2774  {
2775  Xyce::dout() << "jacSpecialMap[" << jacSpecialMergedMap[k] << " ] = { ";
2776  for (int q = 0; q < jacSpecialMergedMap2[k].size(); ++q )
2777  {
2778  Xyce::dout() << jacStampSpecialMerged[jacSpecialMergedMap[k]][jacSpecialMergedMap2[k][q]] <<" ";
2779  }
2780  Xyce::dout() << "}" << std::endl;
2781  }
2782  }
2783 #endif
2784 
2785 }
2786 
2787 //-----------------------------------------------------------------------------
2788 // Function : Instance::~Instance
2789 // Purpose : destructor
2790 // Special Notes :
2791 // Scope : public
2792 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2793 // Creation Date : 11/14/00
2794 //-----------------------------------------------------------------------------
2796 {
2797 }
2798 
2799 //-----------------------------------------------------------------------------
2800 // Function : Instance::registerLIDs
2801 // Purpose :
2802 // Special Notes :
2803 // Scope : public
2804 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2805 // Creation Date : 6/21/02
2806 //-----------------------------------------------------------------------------
2807 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
2808  const std::vector<int> & extLIDVecRef )
2809 {
2810  numIntVars = 0;
2811  if ( sourceConductance!=0.0 ) ++numIntVars;
2812  if ( drainConductance!=0.0 ) ++numIntVars;
2813  if ( nqsMod ) ++numIntVars;
2814  if (icVBSGiven) ++numIntVars;
2815  if (icVDSGiven) ++numIntVars;
2816  if (icVGSGiven) ++numIntVars;
2817 
2818  AssertLIDs(intLIDVecRef.size() == numIntVars);
2819  AssertLIDs(extLIDVecRef.size() == numExtVars);
2820 
2821 #ifdef Xyce_DEBUG_DEVICE
2822  if (getDeviceOptions().debugLevel > 0)
2823  {
2824  Xyce::dout() << section_divider << std::endl;
2825  Xyce::dout() << " In Instance::register LIDs\n\n";
2826  Xyce::dout() << " name = " << getName() << std::endl;
2827  Xyce::dout() << " number of internal variables: " << numIntVars << std::endl;
2828  Xyce::dout() << " number of external variables: " << numExtVars << std::endl;
2829  }
2830 #endif
2831 
2832  // copy over the global ID lists.
2833  intLIDVec = intLIDVecRef;
2834  extLIDVec = extLIDVecRef;
2835 
2836  // now use these lists to obtain the indices into the
2837  // linear algebra entities. This assumes an order.
2838  // For the matrix indices, first do the rows.
2839 
2840  li_Drain = extLIDVec[0];
2841  li_Gate = extLIDVec[1];
2842  li_Source = extLIDVec[2];
2843  li_Bulk = extLIDVec[3];
2844 
2845  int intLoc = 0;
2846 
2847  if( drainConductance != 0.0 )
2848  li_DrainPrime = intLIDVec[intLoc++];
2849  else
2851 
2852  if( sourceConductance != 0.0 )
2853  li_SourcePrime = intLIDVec[intLoc++];
2854  else
2856 
2857  if( nqsMod )
2858  li_Charge = intLIDVec[intLoc++];
2859 
2860  if( icVBSGiven )
2861  {
2862  if( li_Bulk == li_Source )
2863  {
2864  DevelFatal(*this).in("Instance::registerLIDs")
2865  << "Tried to specify an initial condition on V_Bulk_Source when Bulk and Source nodes are the same node";
2866  }
2867  li_Ibs = intLIDVec[intLoc++];
2868  }
2869 
2870  if( icVDSGiven )
2871  {
2872  if( li_Drain == li_Source )
2873  {
2874  DevelFatal(*this).in("Instance::registerLIDs")
2875  << "Tried to specify an initial condition on V_Drain_Source when Drain and Source nodes are the same node";
2876  }
2877  li_Ids = intLIDVec[intLoc++];
2878  }
2879 
2880  if( icVGSGiven )
2881  {
2882  if( li_Gate == li_Source )
2883  {
2884  DevelFatal(*this).in("Instance::registerLIDs")
2885  << "Tried to specify an initial condition on V_Gate_Source when Gate and Source nodes are the same node";
2886  }
2887  li_Igs = intLIDVec[intLoc++];
2888  }
2889 
2890 #ifdef Xyce_DEBUG_DEVICE
2891  if (getDeviceOptions().debugLevel > 0)
2892  {
2893  Xyce::dout() << "\n local variable indices:\n";
2894  Xyce::dout() << " li_Drain = " << li_Drain << std::endl;
2895  Xyce::dout() << " li_Gate = " << li_Gate << std::endl;
2896  Xyce::dout() << " li_Source = " << li_Source << std::endl;
2897  Xyce::dout() << " li_Bulk = " << li_Bulk << std::endl;
2898 
2899  if (drainConductance)
2900  Xyce::dout() << " li_DrainPrime = " << li_DrainPrime << std::endl;
2901  if (sourceConductance)
2902  Xyce::dout() << " li_SourcePrime = " << li_SourcePrime << std::endl;
2903 
2904  if (nqsMod)
2905  Xyce::dout() << " li_Charge = " << li_Charge << std::endl;
2906 
2907  if (icVBSGiven)
2908  Xyce::dout() << " li_Ibs = " << li_Ibs << std::endl;
2909 
2910  if (icVDSGiven)
2911  Xyce::dout() << " li_Ids = " << li_Ids << std::endl;
2912 
2913  if (icVGSGiven)
2914  Xyce::dout() << " li_Igs = " << li_Igs << std::endl;
2915  Xyce::dout() << section_divider << std::endl;
2916  }
2917 #endif
2918 
2919 }
2920 
2921 //-----------------------------------------------------------------------------
2922 // Function : Instance::getIntNameMap
2923 // Purpose :
2924 // Special Notes :
2925 // Scope : public
2926 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2927 // Creation Date : 05/13/05
2928 //-----------------------------------------------------------------------------
2929 std::map<int,std::string> & Instance::getIntNameMap ()
2930 {
2931  // set up the internal name map, if it hasn't been already.
2932  if (intNameMap.empty ())
2933  {
2934  if ( drainConductance!=0.0 )
2935  {
2936  intNameMap[ li_DrainPrime ] = spiceInternalName(getName(), "drainprime");
2937  }
2938 
2939  if ( sourceConductance != 0.0 )
2940  {
2941  intNameMap[ li_SourcePrime ] = spiceInternalName(getName(), "sourceprime");
2942  }
2943 
2944  if (icVDSGiven)
2945  {
2946  intNameMap[li_Ids] = spiceInternalName(getName(), "branch_DS");
2947  }
2948 
2949  if (icVGSGiven)
2950  {
2951  intNameMap[li_Igs] = spiceInternalName(getName(), "branch_GS");
2952  }
2953 
2954  if (icVBSGiven)
2955  {
2956  intNameMap[li_Ibs] = spiceInternalName(getName(), "branch_BS");
2957  }
2958  }
2959 
2960  return intNameMap;
2961 }
2962 
2963 
2964 //-----------------------------------------------------------------------------
2965 // Function : Instance::getStoreNameMap
2966 // Purpose :
2967 // Special Notes :
2968 // Scope : public
2969 // Creator : Richard Schiek, Electrical Systems Modeling
2970 // Creation Date : 4/3/2013
2971 //-----------------------------------------------------------------------------
2972 std::map<int,std::string> & Instance::getStoreNameMap ()
2973 {
2974  // set up the internal name map, if it hasn't been already.
2975  if( loadLeadCurrent && storeNameMap.empty ())
2976  {
2981  }
2982 
2983  return storeNameMap;
2984 }
2985 //-----------------------------------------------------------------------------
2986 // Function : Instance::registerStateLIDs
2987 // Purpose :
2988 // Special Notes :
2989 // Scope : public
2990 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
2991 // Creation Date : 6/21/02
2992 //-----------------------------------------------------------------------------
2993 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
2994 {
2995  AssertLIDs(staLIDVecRef.size() == numStateVars);
2996 
2997 #ifdef Xyce_DEBUG_DEVICE
2998  if (getDeviceOptions().debugLevel > 0)
2999  {
3000  Xyce::dout() << std::endl;
3001  Xyce::dout() << section_divider << std::endl;
3002  Xyce::dout() << " In Instance::registerStateLIDs\n\n";
3003  Xyce::dout() << " name = " << getName() << std::endl;
3004  Xyce::dout() << " Number of State LIDs: " << numStateVars << std::endl;
3005  }
3006 #endif
3007 
3008  // Copy over the global ID lists:
3009  staLIDVec = staLIDVecRef;
3010 
3011  int lid=0;
3012  // Intrinsic capacitors:
3013  li_state_qb = staLIDVec[lid++];
3014  li_state_qg = staLIDVec[lid++];
3015  li_state_qd = staLIDVec[lid++];
3016 
3017  // Parasitic capacitors:
3018  li_state_qbs = staLIDVec[lid++];
3019  li_state_qbd = staLIDVec[lid++];
3020 
3021  // state variables, cheq
3022  li_state_qcheq = staLIDVec[lid++];
3023 
3024  // state variables, cdump
3025  li_state_qcdump = staLIDVec[lid++];
3026 
3027  // state variable, qdef
3028  li_state_qdef = staLIDVec[lid++];
3029 
3030 
3031 #ifdef Xyce_DEBUG_DEVICE
3032  if (getDeviceOptions().debugLevel > 0)
3033  {
3034  Xyce::dout() << " Local State indices:" << std::endl;
3035  Xyce::dout() << std::endl;
3036  Xyce::dout() << " li_state_qb = " << li_state_qb << std::endl;
3037  Xyce::dout() << " li_state_qg = " << li_state_qg << std::endl;
3038  Xyce::dout() << " li_state_qd = " << li_state_qd << std::endl;
3039  Xyce::dout() << " li_state_qbs = " << li_state_qbs << std::endl;
3040  Xyce::dout() << " li_state_qbd = " << li_state_qbd << std::endl;
3041  Xyce::dout() << " li_state_qcheq = " << li_state_qcheq << std::endl;
3042  Xyce::dout() << " li_state_qcdump = " << li_state_qcdump << std::endl;
3043  Xyce::dout() << " li_state_qdef = " << li_state_qdef << std::endl;
3044  Xyce::dout() << section_divider << std::endl;
3045  }
3046 #endif
3047 
3048 }
3049 
3050 //-----------------------------------------------------------------------------
3051 // Function : Instance::registerStoreLIDs
3052 // Purpose :
3053 // Special Notes :
3054 // Scope : public
3055 // Creator : Eric Keiter, SNL
3056 // Creation Date : 12/9/11
3057 //-----------------------------------------------------------------------------
3058 void Instance::registerStoreLIDs( const std::vector<int> & stoLIDVecRef )
3059 {
3060  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
3061 
3062  // Copy over the global ID lists:
3063  stoLIDVec = stoLIDVecRef;
3064 
3065  int lid=0;
3066  // Voltage drops:
3067  li_store_vbd = stoLIDVec[lid++];
3068  li_store_vbs = stoLIDVec[lid++];
3069  li_store_vgs = stoLIDVec[lid++];
3070  li_store_vds = stoLIDVec[lid++];
3071  li_store_von = stoLIDVec[lid++];
3072 
3073  if( loadLeadCurrent )
3074  {
3075  li_store_dev_id = stoLIDVec[lid++];
3076  li_store_dev_ig = stoLIDVec[lid++];
3077  li_store_dev_is = stoLIDVec[lid++];
3078  li_store_dev_ib = stoLIDVec[lid++];
3079  }
3080 }
3081 
3082 //-----------------------------------------------------------------------------
3083 // Function : Instance::jacobianStamp
3084 // Purpose :
3085 // Special Notes :
3086 // Scope : public
3087 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3088 // Creation Date : 9/4/02
3089 //-----------------------------------------------------------------------------
3090 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
3091 {
3092  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3093  {
3095  {
3096  return jacStampSpecialMerged;
3097  }
3098  else
3099  {
3100  return jacStampSpecial;
3101  }
3102  }
3103  else
3104  {
3106  return jacStamp_DC_SC;
3107  else if( drainConductance && !sourceConductance && !nqsMod )
3108  return jacStamp_DC;
3109  else if( !drainConductance && sourceConductance && !nqsMod )
3110  return jacStamp_SC;
3111  else if( !drainConductance && !sourceConductance && !nqsMod )
3112  return jacStamp;
3113  else
3114  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3115  ": NQSMOD not supported for DIRECT MATRIX ACCESS\n" );
3116  }
3117 
3118  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3119  "Instance::jacobianStamp should not get here!\n" );
3120 
3121  return jacStamp;
3122 }
3123 
3124 //-----------------------------------------------------------------------------
3125 // Function : Instance::registerJacLIDs
3126 // Purpose :
3127 // Special Notes :
3128 // Scope : public
3129 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3130 // Creation Date : 9/4/02
3131 //-----------------------------------------------------------------------------
3132 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
3133 {
3134  DeviceInstance::registerJacLIDs( jacLIDVec );
3135  std::vector<int> map;
3136  std::vector< std::vector<int> > map2;
3137 
3138 
3139  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3140  {
3142  {
3143  map = jacSpecialMap;
3144  map2 = jacSpecialMap2;
3145  }
3146  else
3147  {
3148  map = jacSpecialMergedMap;
3149  map2 = jacSpecialMergedMap2;
3150  }
3151  }
3152  else
3153  {
3154  if (drainConductance)
3155  {
3156  if (sourceConductance)
3157  {
3158  map = jacMap_DC_SC;
3159  map2 = jacMap2_DC_SC;
3160  }
3161  else
3162  {
3163  map = jacMap_DC;
3164  map2 = jacMap2_DC;
3165  }
3166  }
3167  else
3168  {
3169  if (sourceConductance)
3170  {
3171  map = jacMap_SC;
3172  map2 = jacMap2_SC;
3173  }
3174  else
3175  {
3176  map = jacMap;
3177  map2 = jacMap2;
3178  }
3179  }
3180  }
3181 
3182 #ifdef Xyce_DEBUG_DEVICE
3183  if (getDeviceOptions().debugLevel > 0)
3184  {
3185  Xyce::dout() << "Instance::registerJacLIDs map selected" << std::endl;
3186  for (int k = 0; k<map.size(); ++k )
3187  {
3188  Xyce::dout() << "map[ " << k << "] = " << map[k] << " map2[] = { ";
3189  for (int q = 0; q < map2[k].size(); ++q )
3190  {
3191  Xyce::dout() << map2[k][q] <<" ";
3192  }
3193  Xyce::dout() << "}" << std::endl;
3194  }
3195 
3196  for(int k = 0; k<jacLIDVec.size(); ++k )
3197  {
3198  Xyce::dout() << "jacLIDVec[ " << k << "] = { ";
3199  for (int q = 0; q < jacLIDVec[k].size(); ++q )
3200  {
3201  Xyce::dout() << jacLIDVec[k][q] <<" ";
3202  }
3203  Xyce::dout() << "}" << std::endl;
3204  }
3205  }
3206 #endif
3207 
3208  int nextColumn = 0;
3209 
3210  // V_d row
3211  ADrainEquDrainNodeOffset = jacLIDVec[map[0]][map2[0][0]];
3212  ADrainEquDrainPrimeNodeOffset = jacLIDVec[map[0]][map2[0][1]];
3213  if( icVDSGiven )
3214  {
3215  ADrainEquIdsOffset = jacLIDVec[map[0]][map2[0][2]];
3216  }
3217 
3218  // V_g row
3219  AGateEquGateNodeOffset = jacLIDVec[map[1]][map2[1][0]];
3220  AGateEquBulkNodeOffset = jacLIDVec[map[1]][map2[1][1]];
3221  AGateEquDrainPrimeNodeOffset = jacLIDVec[map[1]][map2[1][2]];
3222  AGateEquSourcePrimeNodeOffset = jacLIDVec[map[1]][map2[1][3]];
3223  nextColumn = 4;
3224  if( nqsMod )
3225  {
3226  AGateEquChargeVarOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3227  ++nextColumn;
3228  }
3229  if( icVGSGiven )
3230  {
3231  AGateEquIgsOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3232  ++nextColumn;
3233  }
3234 
3235  // V_s row
3236  ASourceEquSourceNodeOffset = jacLIDVec[map[2]][map2[2][0]];
3237  ASourceEquSourcePrimeNodeOffset = jacLIDVec[map[2]][map2[2][1]];
3238  nextColumn = 2;
3239  if( icVBSGiven )
3240  {
3241  ASourceEquIbsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3242  ++nextColumn;
3243  }
3244  if( icVDSGiven )
3245  {
3246  ASourceEquIdsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3247  ++nextColumn;
3248  }
3249  if( icVGSGiven )
3250  {
3251  ASourceEquIgsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3252  ++nextColumn;
3253  }
3254 
3255  // V_b row
3256  ABulkEquGateNodeOffset = jacLIDVec[map[3]][map2[3][0]];
3257  ABulkEquBulkNodeOffset = jacLIDVec[map[3]][map2[3][1]];
3258  ABulkEquDrainPrimeNodeOffset = jacLIDVec[map[3]][map2[3][2]];
3259  ABulkEquSourcePrimeNodeOffset = jacLIDVec[map[3]][map2[3][3]];
3260  nextColumn = 4;
3261  if( nqsMod )
3262  {
3263  ABulkEquChargeVarOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3264  ++nextColumn;
3265  }
3266  if( icVBSGiven )
3267  {
3268  ABulkEquIbsOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3269  ++nextColumn;
3270  }
3271 
3272  // V_d'
3273  ADrainPrimeEquDrainNodeOffset = jacLIDVec[map[4]][map2[4][0]];
3274  ADrainPrimeEquGateNodeOffset = jacLIDVec[map[4]][map2[4][1]];
3275  ADrainPrimeEquBulkNodeOffset = jacLIDVec[map[4]][map2[4][2]];
3276  ADrainPrimeEquDrainPrimeNodeOffset = jacLIDVec[map[4]][map2[4][3]];
3277  ADrainPrimeEquSourcePrimeNodeOffset = jacLIDVec[map[4]][map2[4][4]];
3278  if( nqsMod )
3279  {
3280  ADrainPrimeEquChargeVarOffset = jacLIDVec[map[4]][map2[4][5]];
3281  }
3282 
3283 
3284  // V_s'
3285  ASourcePrimeEquGateNodeOffset = jacLIDVec[map[5]][map2[5][0]];
3286  ASourcePrimeEquSourceNodeOffset = jacLIDVec[map[5]][map2[5][1]];
3287  ASourcePrimeEquBulkNodeOffset = jacLIDVec[map[5]][map2[5][2]];
3288  ASourcePrimeEquDrainPrimeNodeOffset = jacLIDVec[map[5]][map2[5][3]];
3289  ASourcePrimeEquSourcePrimeNodeOffset = jacLIDVec[map[5]][map2[5][4]];
3290  if( nqsMod )
3291  {
3292  ASourcePrimeEquChargeVarOffset = jacLIDVec[map[5]][map2[5][5]];
3293  }
3294 
3295  int nextRow = 6;
3296  if( nqsMod )
3297  {
3298  AChargeEquChargeVarOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3299  AChargeEquDrainPrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3300  AChargeEquGateNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3301  AChargeEquSourcePrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][3]];
3302  AChargeEquBulkNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][4]];
3303  ++nextRow;
3304  }
3305 
3306 
3307  if( icVBSGiven )
3308  {
3309  icVBSEquVbOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3310  icVBSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3311  icVBSEquIbsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3312  ++nextRow;
3313  }
3314 
3315  if( icVDSGiven )
3316  {
3317  icVDSEquVdOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3318  icVDSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3319  icVDSEquIdsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3320  ++nextRow;
3321  }
3322 
3323  if( icVGSGiven )
3324  {
3325  icVGSEquVgOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3326  icVGSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3327  icVGSEquIgsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3328  ++nextRow;
3329  }
3330 
3331  if (nqsMod)
3332  {
3333  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3334  ": NQSMOD not supported.\n" );
3335  }
3336 }
3337 
3338 //-----------------------------------------------------------------------------
3339 // Function : Instance::setupPointers
3340 // Purpose :
3341 // Special Notes :
3342 // Scope : public
3343 // Creator : Eric Keiter, SNL
3344 // Creation Date : 11/30/08
3345 //-----------------------------------------------------------------------------
3347 {
3348 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
3349  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
3350  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
3351 
3352  // V_d row
3355  if( icVDSGiven )
3356  {
3358  }
3359 
3360  // V_g row
3365  if( nqsMod )
3366  {
3368 
3369  }
3370  if( icVGSGiven )
3371  {
3373 
3374  }
3375 
3376  // V_s row // V_s row
3379  if( icVBSGiven )
3380  {
3382 
3383  }
3384  if( icVDSGiven )
3385  {
3387 
3388  }
3389  if( icVGSGiven )
3390  {
3392 
3393  }
3394 
3395  // V_b row
3400  if( nqsMod )
3401  {
3403 
3404  }
3405  if( icVBSGiven )
3406  {
3408 
3409  }
3410 
3411  // V_d'
3417  if( nqsMod )
3418  {
3420  }
3421 
3422 
3423  // V_s'
3429  if( nqsMod )
3430  {
3432  }
3433 
3434  if( nqsMod )
3435  {
3441  }
3442 
3443 
3444  if( icVBSGiven )
3445  {
3449  }
3450 
3451  if( icVDSGiven )
3452  {
3456  }
3457 
3458  if( icVGSGiven )
3459  {
3463  }
3464 
3465 
3466 
3467  // V_d row
3470  if( icVDSGiven )
3471  {
3473  }
3474 
3475  // V_g row
3480  if( nqsMod )
3481  {
3483 
3484  }
3485  if( icVGSGiven )
3486  {
3488 
3489  }
3490 
3491  // V_s row // V_s row
3494  if( icVBSGiven )
3495  {
3497 
3498  }
3499  if( icVDSGiven )
3500  {
3502 
3503  }
3504  if( icVGSGiven )
3505  {
3507 
3508  }
3509 
3510  // V_b row
3515  if( nqsMod )
3516  {
3518 
3519  }
3520  if( icVBSGiven )
3521  {
3523 
3524  }
3525 
3526  // V_d'
3532  if( nqsMod )
3533  {
3535  }
3536 
3537 
3538  // V_s'
3544  if( nqsMod )
3545  {
3547  }
3548 
3549  if( nqsMod )
3550  {
3556  }
3557 
3558 
3559  if( icVBSGiven )
3560  {
3564  }
3565 
3566  if( icVDSGiven )
3567  {
3571  }
3572 
3573  if( icVGSGiven )
3574  {
3578  }
3579 
3580 #endif
3581 }
3582 
3583 //-----------------------------------------------------------------------------
3584 // Function : Instance::updateTemperature
3585 // Purpose : This updates all the instance-owned paramters which
3586 // are temperature dependent.
3587 //
3588 // Special Notes :
3589 // Scope : public
3590 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3591 // Creation Date : 11/22/00
3592 //-----------------------------------------------------------------------------
3593 bool Instance::updateTemperature (const double & temp_tmp)
3594 {
3595  char msg[128];
3596 
3597  double tmp, tmp1, tmp2, tmp3, Eg;
3598  double T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;
3599  double delTemp, TRatio, Inv_L, Inv_W, Inv_LW;
3600  //double Dw, Dl;
3601  double Tnom;
3602  double Nvtm, SourceSatCurrent, DrainSatCurrent;
3603 
3604  // stuff from model paramters:
3605  double Eg0 = model_.Eg0;
3606  double ni = model_.ni;
3607  double Vtm0 = model_.Vtm0;
3608 
3609  bool bsuccess = true;
3610 
3611 #ifdef Xyce_DEBUG_DEVICE
3612  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
3613  {
3614  Xyce::dout() << std::endl << subsection_divider << std::endl;
3615  Xyce::dout() << "Instance::updateTemperature\n";
3616  Xyce::dout() << "name = " << getName() << std::endl;
3617  }
3618 #endif
3619 
3620  // first set the instance temperature to the new temperature:
3621  if (temp_tmp != -999.0) temp = temp_tmp;
3622 
3623  Tnom = model_.tnom;
3624  TRatio = temp/Tnom;
3625 
3626  vtm = CONSTKoverQ * temp;
3627  Eg = CONSTEg0 - CONSTalphaEg * temp * temp / (temp + CONSTbetaEg);
3628 
3629  if (temp != Tnom)
3630  {
3631  T0 = Eg0 / Vtm0 - Eg/vtm + model_.jctTempExponent*log(temp/Tnom);
3632  T1 = exp(T0 / model_.jctEmissionCoeff);
3635  }
3636  else
3637  {
3640  }
3641 
3642  if (jctTempSatCurDensity < 0.0) jctTempSatCurDensity = 0.0;
3644 
3645 
3646  // Temperature dependence of D/B and S/B diode capacitance begins
3647  delTemp = temp - Tnom;
3648  T0 = model_.tcj * delTemp;
3649 
3650  if (T0 >= -1.0)
3651  {
3653  }
3654  else if (unitAreaJctCapTemp > 0.0)
3655  {
3656  unitAreaJctCapTemp = 0.0;
3657 
3658  lout() << "Temperature effect has caused cj to be negative. Cj clamped to zero.\n" << std::endl;
3659  }
3660 
3661  T0 = model_.tcjsw * delTemp;
3662 
3663  if (T0 >= -1.0)
3664  {
3666  model_.unitLengthSidewallJctCap *(1.0 + T0);
3667  }
3668  else if (unitLengthSidewallJctCapTemp > 0.0)
3669  {
3671  lout() << "Temperature effect has caused cjsw to be negative. Cjsw clamped to zero.\n" << std::endl;
3672  }
3673 
3674  T0 = model_.tcjswg * delTemp;
3675 
3676  if (T0 >= -1.0)
3677  {
3680  }
3681  else if (unitLengthGateSidewallJctCapTemp > 0.0)
3682  {
3684  lout() << "Temperature effect has caused cjswg to be negative. Cjswg clamped to zero.\n" << std::endl;
3685  }
3686 
3687  PhiBTemp = model_.bulkJctPotential - model_.tpb * delTemp;
3688 
3689  if (PhiBTemp < 0.01)
3690  {
3691  PhiBTemp = 0.01;
3692  lout() << "Temperature effect has caused pb to be < 0.01. Pb clamped to 0.01.\n" << std::endl;
3693  }
3694 
3696 
3697  if (PhiBSWTemp <= 0.01)
3698  {
3699  PhiBSWTemp = 0.01;
3700  lout() << "Temperature effect has caused pbsw to be < 0.01. Pbsw clamped to 0.01.\n" << std::endl;
3701  }
3702 
3704 
3705  if (PhiBSWGTemp <= 0.01)
3706  {
3707  PhiBSWGTemp = 0.01;
3708  lout() << "Temperature effect has caused pbswg to be < 0.01. Pbswg clamped to 0.01.\n" << std::endl;
3709  }
3710  // End of junction capacitance
3711 
3712 
3713  // This next block determines whether or not to use a previously allocated
3714  // set of size dependent parameters. These are stored in a list that is
3715  // owned by the model. If the values for length and width match those of
3716  // a previously allocated set, then use the old set. If not, allocate a new set.
3717 
3718  std::list<SizeDependParam*>::iterator it_dpL =
3719  model_.sizeDependParamList.begin();
3720  std::list<SizeDependParam*>::iterator end_dpL =
3722 
3723  paramPtr = NULL;
3724 
3725  for( ; it_dpL != end_dpL; ++it_dpL )
3726  if( (*it_dpL)->Length == l && (*it_dpL)->Width == w )
3727  paramPtr = (*it_dpL);
3728 
3729  if ( paramPtr != NULL )
3730  {
3731  }
3732  else
3733  {
3734  paramPtr = new SizeDependParam ();
3735 
3736  model_.sizeDependParamList.push_back( paramPtr );
3737  paramPtr->referenceTemperature = temp_tmp;
3738 
3739  Ldrn = l;
3740  Wdrn = w;
3741  paramPtr->Length = Ldrn;
3742  paramPtr->Width = Wdrn;
3743 
3744  T0 = pow(Ldrn, model_.Lln);
3745  T1 = pow(Wdrn, model_.Lwn);
3746 
3747  tmp1 = model_.Ll / T0 + model_.Lw / T1
3748  + model_.Lwl / (T0 * T1);
3749 
3750  paramPtr->dl = model_.Lint + tmp1;
3751 
3752  tmp2 = model_.Llc / T0 + model_.Lwc / T1
3753  + model_.Lwlc / (T0 * T1);
3754 
3755  paramPtr->dlc = model_.dlc + tmp2;
3756 
3757  T2 = pow(Ldrn, model_.Wln);
3758  T3 = pow(Wdrn, model_.Wwn);
3759 
3760  tmp1 = model_.Wl / T2 + model_.Ww / T3
3761  + model_.Wwl / (T2 * T3);
3762 
3763  paramPtr->dw = model_.Wint + tmp1;
3764  tmp2 = model_.Wlc / T2 + model_.Wwc / T3
3765  + model_.Wwlc / (T2 * T3);
3766 
3767  paramPtr->dwc = model_.dwc + tmp2;
3768 
3769  paramPtr->leff = l - 2.0 * paramPtr->dl;
3770  if (paramPtr->leff <= 0.0)
3771  {
3772  UserWarning0(*this) << "Effective channel length <= 0";
3773  }
3774 
3775  paramPtr->weff = w - 2.0 * paramPtr->dw;
3776  if (paramPtr->weff <= 0.0)
3777  {
3778  UserWarning0(*this) << "Effective channel width <= 0";
3779  }
3780 
3781  paramPtr->leffCV = l - 2.0 * paramPtr->dlc;
3782  if (paramPtr->leffCV <= 0.0)
3783  {
3784  UserWarning0(*this) << "Effective channel length for C-V <= 0";
3785  }
3786 
3787  paramPtr->weffCV = w - 2.0 * paramPtr->dwc;
3788  if (paramPtr->weffCV <= 0.0)
3789  {
3790  UserWarning(*this) << "Effective channel width for C-V <= 0";
3791  }
3792 
3793 
3794  if (model_.binUnit == 1)
3795  {
3796  Inv_L = 1.0e-6 / paramPtr->leff;
3797  Inv_W = 1.0e-6 / paramPtr->weff;
3798  Inv_LW = 1.0e-12 / (paramPtr->leff * paramPtr->weff);
3799  }
3800  else
3801  {
3802  Inv_L = 1.0 / paramPtr->leff;
3803  Inv_W = 1.0 / paramPtr->weff;
3804  Inv_LW = 1.0 / (paramPtr->leff * paramPtr->weff);
3805  }
3806 
3808  + model_.lcdsc * Inv_L
3809  + model_.wcdsc * Inv_W
3810  + model_.pcdsc * Inv_LW;
3811 
3813  + model_.lcdscb * Inv_L
3814  + model_.wcdscb * Inv_W
3815  + model_.pcdscb * Inv_LW;
3816 
3818  + model_.lcdscd * Inv_L
3819  + model_.wcdscd * Inv_W
3820  + model_.pcdscd * Inv_LW;
3821 
3822  paramPtr->cit = model_.cit
3823  + model_.lcit * Inv_L
3824  + model_.wcit * Inv_W
3825  + model_.pcit * Inv_LW;
3826 
3828  + model_.lnfactor * Inv_L
3829  + model_.wnfactor * Inv_W
3830  + model_.pnfactor * Inv_LW;
3831 
3832  paramPtr->xj = model_.xj
3833  + model_.lxj * Inv_L
3834  + model_.wxj * Inv_W
3835  + model_.pxj * Inv_LW;
3836 
3838  + model_.lvsat * Inv_L
3839  + model_.wvsat * Inv_W
3840  + model_.pvsat * Inv_LW;
3841 
3842  paramPtr->at = model_.at
3843  + model_.lat * Inv_L
3844  + model_.wat * Inv_W
3845  + model_.pat * Inv_LW;
3846 
3847  paramPtr->a0 = model_.a0
3848  + model_.la0 * Inv_L
3849  + model_.wa0 * Inv_W
3850  + model_.pa0 * Inv_LW;
3851 
3852  paramPtr->ags = model_.ags
3853  + model_.lags * Inv_L
3854  + model_.wags * Inv_W
3855  + model_.pags * Inv_LW;
3856 
3857  paramPtr->a1 = model_.a1
3858  + model_.la1 * Inv_L
3859  + model_.wa1 * Inv_W
3860  + model_.pa1 * Inv_LW;
3861 
3862  paramPtr->a2 = model_.a2
3863  + model_.la2 * Inv_L
3864  + model_.wa2 * Inv_W
3865  + model_.pa2 * Inv_LW;
3866 
3868  + model_.lketa * Inv_L
3869  + model_.wketa * Inv_W
3870  + model_.pketa * Inv_LW;
3871 
3873  + model_.lnsub * Inv_L
3874  + model_.wnsub * Inv_W
3875  + model_.pnsub * Inv_LW;
3876 
3878  + model_.lnpeak * Inv_L
3879  + model_.wnpeak * Inv_W
3880  + model_.pnpeak * Inv_LW;
3881 
3883  + model_.lngate * Inv_L
3884  + model_.wngate * Inv_W
3885  + model_.pngate * Inv_LW;
3886 
3888  + model_.lgamma1 * Inv_L
3889  + model_.wgamma1 * Inv_W
3890  + model_.pgamma1 * Inv_LW;
3891 
3893  + model_.lgamma2 * Inv_L
3894  + model_.wgamma2 * Inv_W
3895  + model_.pgamma2 * Inv_LW;
3896 
3897  paramPtr->vbx = model_.vbx
3898  + model_.lvbx * Inv_L
3899  + model_.wvbx * Inv_W
3900  + model_.pvbx * Inv_LW;
3901 
3902  paramPtr->vbm = model_.vbm
3903  + model_.lvbm * Inv_L
3904  + model_.wvbm * Inv_W
3905  + model_.pvbm * Inv_LW;
3906 
3907  paramPtr->xt = model_.xt
3908  + model_.lxt * Inv_L
3909  + model_.wxt * Inv_W
3910  + model_.pxt * Inv_LW;
3911 
3912  paramPtr->vfb = model_.vfb
3913  + model_.lvfb * Inv_L
3914  + model_.wvfb * Inv_W
3915  + model_.pvfb * Inv_LW;
3916 
3917  paramPtr->k1 = model_.k1
3918  + model_.lk1 * Inv_L
3919  + model_.wk1 * Inv_W
3920  + model_.pk1 * Inv_LW;
3921 
3922  paramPtr->kt1 = model_.kt1
3923  + model_.lkt1 * Inv_L
3924  + model_.wkt1 * Inv_W
3925  + model_.pkt1 * Inv_LW;
3926 
3928  + model_.lkt1l * Inv_L
3929  + model_.wkt1l * Inv_W
3930  + model_.pkt1l * Inv_LW;
3931 
3932  paramPtr->k2 = model_.k2
3933  + model_.lk2 * Inv_L
3934  + model_.wk2 * Inv_W
3935  + model_.pk2 * Inv_LW;
3936 
3937  paramPtr->kt2 = model_.kt2
3938  + model_.lkt2 * Inv_L
3939  + model_.wkt2 * Inv_W
3940  + model_.pkt2 * Inv_LW;
3941 
3942  paramPtr->k3 = model_.k3
3943  + model_.lk3 * Inv_L
3944  + model_.wk3 * Inv_W
3945  + model_.pk3 * Inv_LW;
3946 
3947  paramPtr->k3b = model_.k3b
3948  + model_.lk3b * Inv_L
3949  + model_.wk3b * Inv_W
3950  + model_.pk3b * Inv_LW;
3951 
3952  paramPtr->w0 = model_.w0
3953  + model_.lw0 * Inv_L
3954  + model_.ww0 * Inv_W
3955  + model_.pw0 * Inv_LW;
3956 
3957  paramPtr->nlx = model_.nlx
3958  + model_.lnlx * Inv_L
3959  + model_.wnlx * Inv_W
3960  + model_.pnlx * Inv_LW;
3961 
3963  + model_.ldvt0 * Inv_L
3964  + model_.wdvt0 * Inv_W
3965  + model_.pdvt0 * Inv_LW;
3966 
3968  + model_.ldvt1 * Inv_L
3969  + model_.wdvt1 * Inv_W
3970  + model_.pdvt1 * Inv_LW;
3971 
3973  + model_.ldvt2 * Inv_L
3974  + model_.wdvt2 * Inv_W
3975  + model_.pdvt2 * Inv_LW;
3976 
3978  + model_.ldvt0w * Inv_L
3979  + model_.wdvt0w * Inv_W
3980  + model_.pdvt0w * Inv_LW;
3981 
3983  + model_.ldvt1w * Inv_L
3984  + model_.wdvt1w * Inv_W
3985  + model_.pdvt1w * Inv_LW;
3986 
3988  + model_.ldvt2w * Inv_L
3989  + model_.wdvt2w * Inv_W
3990  + model_.pdvt2w * Inv_LW;
3991 
3993  + model_.ldrout * Inv_L
3994  + model_.wdrout * Inv_W
3995  + model_.pdrout * Inv_LW;
3996 
3998  + model_.ldsub * Inv_L
3999  + model_.wdsub * Inv_W
4000  + model_.pdsub * Inv_LW;
4001 
4003  + model_.lvth0 * Inv_L
4004  + model_.wvth0 * Inv_W
4005  + model_.pvth0 * Inv_LW;
4006 
4007  paramPtr->ua = model_.ua
4008  + model_.lua * Inv_L
4009  + model_.wua * Inv_W
4010  + model_.pua * Inv_LW;
4011 
4012  paramPtr->ua1 = model_.ua1
4013  + model_.lua1 * Inv_L
4014  + model_.wua1 * Inv_W
4015  + model_.pua1 * Inv_LW;
4016 
4017  paramPtr->ub = model_.ub
4018  + model_.lub * Inv_L
4019  + model_.wub * Inv_W
4020  + model_.pub * Inv_LW;
4021 
4022  paramPtr->ub1 = model_.ub1
4023  + model_.lub1 * Inv_L
4024  + model_.wub1 * Inv_W
4025  + model_.pub1 * Inv_LW;
4026 
4027  paramPtr->uc = model_.uc
4028  + model_.luc * Inv_L
4029  + model_.wuc * Inv_W
4030  + model_.puc * Inv_LW;
4031 
4032  paramPtr->uc1 = model_.uc1
4033  + model_.luc1 * Inv_L
4034  + model_.wuc1 * Inv_W
4035  + model_.puc1 * Inv_LW;
4036 
4037  paramPtr->u0 = model_.u0
4038  + model_.lu0 * Inv_L
4039  + model_.wu0 * Inv_W
4040  + model_.pu0 * Inv_LW;
4041 
4042  paramPtr->ute = model_.ute
4043  + model_.lute * Inv_L
4044  + model_.wute * Inv_W
4045  + model_.pute * Inv_LW;
4046 
4048  + model_.lvoff * Inv_L
4049  + model_.wvoff * Inv_W
4050  + model_.pvoff * Inv_LW;
4051 
4053  + model_.ldelta * Inv_L
4054  + model_.wdelta * Inv_W
4055  + model_.pdelta * Inv_LW;
4056 
4058  + model_.lrdsw * Inv_L
4059  + model_.wrdsw * Inv_W
4060  + model_.prdsw * Inv_LW;
4061 
4063  + model_.lprwg * Inv_L
4064  + model_.wprwg * Inv_W
4065  + model_.pprwg * Inv_LW;
4066 
4068  + model_.lprwb * Inv_L
4069  + model_.wprwb * Inv_W
4070  + model_.pprwb * Inv_LW;
4071 
4072  paramPtr->prt = model_.prt
4073  + model_.lprt * Inv_L
4074  + model_.wprt * Inv_W
4075  + model_.pprt * Inv_LW;
4076 
4078  + model_.leta0 * Inv_L
4079  + model_.weta0 * Inv_W
4080  + model_.peta0 * Inv_LW;
4081 
4083  + model_.letab * Inv_L
4084  + model_.wetab * Inv_W
4085  + model_.petab * Inv_LW;
4086 
4088  + model_.lpclm * Inv_L
4089  + model_.wpclm * Inv_W
4090  + model_.ppclm * Inv_LW;
4091 
4093  + model_.lpdibl1 * Inv_L
4094  + model_.wpdibl1 * Inv_W
4095  + model_.ppdibl1 * Inv_LW;
4096 
4098  + model_.lpdibl2 * Inv_L
4099  + model_.wpdibl2 * Inv_W
4100  + model_.ppdibl2 * Inv_LW;
4101 
4103  + model_.lpdiblb * Inv_L
4104  + model_.wpdiblb * Inv_W
4105  + model_.ppdiblb * Inv_LW;
4106 
4108  + model_.lpscbe1 * Inv_L
4109  + model_.wpscbe1 * Inv_W
4110  + model_.ppscbe1 * Inv_LW;
4111 
4113  + model_.lpscbe2 * Inv_L
4114  + model_.wpscbe2 * Inv_W
4115  + model_.ppscbe2 * Inv_LW;
4116 
4118  + model_.lpvag * Inv_L
4119  + model_.wpvag * Inv_W
4120  + model_.ppvag * Inv_LW;
4121 
4122  paramPtr->wr = model_.wr
4123  + model_.lwr * Inv_L
4124  + model_.wwr * Inv_W
4125  + model_.pwr * Inv_LW;
4126 
4127  paramPtr->dwg = model_.dwg
4128  + model_.ldwg * Inv_L
4129  + model_.wdwg * Inv_W
4130  + model_.pdwg * Inv_LW;
4131 
4132  paramPtr->dwb = model_.dwb
4133  + model_.ldwb * Inv_L
4134  + model_.wdwb * Inv_W
4135  + model_.pdwb * Inv_LW;
4136 
4137  paramPtr->b0 = model_.b0
4138  + model_.lb0 * Inv_L
4139  + model_.wb0 * Inv_W
4140  + model_.pb0 * Inv_LW;
4141 
4142  paramPtr->b1 = model_.b1
4143  + model_.lb1 * Inv_L
4144  + model_.wb1 * Inv_W
4145  + model_.pb1 * Inv_LW;
4146 
4148  + model_.lalpha0 * Inv_L
4149  + model_.walpha0 * Inv_W
4150  + model_.palpha0 * Inv_LW;
4151 
4153  + model_.lalpha1 * Inv_L
4154  + model_.walpha1 * Inv_W
4155  + model_.palpha1 * Inv_LW;
4156 
4158  + model_.lbeta0 * Inv_L
4159  + model_.wbeta0 * Inv_W
4160  + model_.pbeta0 * Inv_LW;
4161 
4162  // CV model
4163  paramPtr->elm = model_.elm
4164  + model_.lelm * Inv_L
4165  + model_.welm * Inv_W
4166  + model_.pelm * Inv_LW;
4167 
4169  + model_.lcgsl * Inv_L
4170  + model_.wcgsl * Inv_W
4171  + model_.pcgsl * Inv_LW;
4172 
4174  + model_.lcgdl * Inv_L
4175  + model_.wcgdl * Inv_W
4176  + model_.pcgdl * Inv_LW;
4177 
4179  + model_.lckappa * Inv_L
4180  + model_.wckappa * Inv_W
4181  + model_.pckappa * Inv_LW;
4182 
4183  paramPtr->cf = model_.cf
4184  + model_.lcf * Inv_L
4185  + model_.wcf * Inv_W
4186  + model_.pcf * Inv_LW;
4187 
4188  paramPtr->clc = model_.clc
4189  + model_.lclc * Inv_L
4190  + model_.wclc * Inv_W
4191  + model_.pclc * Inv_LW;
4192 
4193  paramPtr->cle = model_.cle
4194  + model_.lcle * Inv_L
4195  + model_.wcle * Inv_W
4196  + model_.pcle * Inv_LW;
4197 
4199  + model_.lvfbcv * Inv_L
4200  + model_.wvfbcv * Inv_W
4201  + model_.pvfbcv * Inv_LW;
4202 
4204  + model_.lacde * Inv_L
4205  + model_.wacde * Inv_W
4206  + model_.pacde * Inv_LW;
4207 
4209  + model_.lmoin * Inv_L
4210  + model_.wmoin * Inv_W
4211  + model_.pmoin * Inv_LW;
4212 
4214  + model_.lnoff * Inv_L
4215  + model_.wnoff * Inv_W
4216  + model_.pnoff * Inv_LW;
4217 
4219  + model_.lvoffcv * Inv_L
4220  + model_.wvoffcv * Inv_W
4221  + model_.pvoffcv * Inv_LW;
4222 
4223  paramPtr->abulkCVfactor = 1.0
4224  + pow((paramPtr->clc / paramPtr->leffCV), paramPtr->cle);
4225 
4226  T0 = (TRatio - 1.0);
4227 
4228  paramPtr->ua = paramPtr->ua + paramPtr->ua1 * T0;
4229  paramPtr->ub = paramPtr->ub + paramPtr->ub1 * T0;
4230  paramPtr->uc = paramPtr->uc + paramPtr->uc1 * T0;
4231 
4232  if (paramPtr->u0 > 1.0) paramPtr->u0 = paramPtr->u0 / 1.0e4;
4233 
4234  paramPtr->u0temp = paramPtr->u0 * pow(TRatio, paramPtr->ute);
4235 
4236  paramPtr->vsattemp = paramPtr->vsat - paramPtr->at * T0;
4237 
4238  paramPtr->rds0 = (paramPtr->rdsw + paramPtr->prt * T0)
4239  / pow(paramPtr->weff * 1E6, paramPtr->wr);
4240 
4241 #ifdef CHECK_MODEL_DONE
4242  if (checkModel((*M_iter), iterI, ckt))
4243  {
4244  UserError0(*this) << "Error(s) detected during V3.2 parameter checking for " << name.c_str() << " in model " << model_.name;
4245 #endif
4246 
4250 
4251  T0 = paramPtr->leffCV * paramPtr->leffCV;
4252 
4254  * paramPtr->weffCV * paramPtr->leffCV * T0);
4255 
4257  {
4258  T0 = paramPtr->gamma1 * model_.cox;
4259  paramPtr->npeak = 3.021E22 * T0 * T0;
4260  }
4261 
4262  paramPtr->phi = 2.0 * Vtm0 * log(paramPtr->npeak / ni);
4263  paramPtr->sqrtPhi = sqrt(paramPtr->phi);
4265 
4266  paramPtr->Xdep0 = sqrt(2.0 * CONSTEPSSI / (CONSTQ * paramPtr->npeak * 1.0e6))
4267  * paramPtr->sqrtPhi;
4268 
4269  paramPtr->sqrtXdep0 = sqrt(paramPtr->Xdep0);
4270  paramPtr->litl = sqrt(3.0 * paramPtr->xj * model_.tox);
4271 
4272  paramPtr->vbi = Vtm0 * log(1.0e20 * paramPtr->npeak / (ni * ni));
4273 
4274  paramPtr->cdep0 = sqrt(CONSTQ * CONSTEPSSI * paramPtr->npeak * 1.0e6 / 2.0
4275  / paramPtr->phi);
4276 
4277  paramPtr->ldeb = sqrt(CONSTEPSSI * Vtm0 / (CONSTQ
4278  * paramPtr->npeak * 1.0e6)) / 3.0;
4279 
4280  paramPtr->acde *= pow((paramPtr->npeak / 2.0e16), -0.25);
4281 
4282 
4283  if (model_.k1Given || model_.k2Given)
4284  {
4285  if (!model_.k1Given)
4286  {
4287  UserWarning0(*this) << "k1 should be specified with k2.";
4288  paramPtr->k1 = 0.53;
4289  }
4290 
4291  if (!model_.k2Given)
4292  {
4293  UserWarning0(*this) << "k2 should be specified with k1.";
4294  paramPtr->k2 = -0.0186;
4295  }
4296 
4297  if (model_.nsubGiven)
4298  {
4299  UserWarning0(*this) << "nsub is ignored because k1 or k2 is given.";
4300  }
4301 
4302  if (model_.xtGiven)
4303  {
4304  UserWarning0(*this) << "xt is ignored because k1 or k2 is given.";
4305  }
4306 
4307  if (model_.vbxGiven)
4308  {
4309  UserWarning0(*this) << "vbx is ignored because k1 or k2 is given.";
4310  }
4311 
4312  if (model_.gamma1Given)
4313  {
4314  UserWarning0(*this) << "gamma1 is ignored because k1 or k2 is given.";
4315  }
4316 
4317  if (model_.gamma2Given)
4318  {
4319  UserWarning0(*this) << "gamma2 is ignored because k1 or k2 is given.";
4320  }
4321  }
4322  else
4323  {
4324  if (!model_.vbxGiven)
4325  paramPtr->vbx = paramPtr->phi - 7.7348e-4 * paramPtr->npeak
4326  * paramPtr->xt * paramPtr->xt;
4327 
4328  if (paramPtr->vbx > 0.0)
4329  paramPtr->vbx = -paramPtr->vbx;
4330 
4331  if (paramPtr->vbm > 0.0)
4332  paramPtr->vbm = -paramPtr->vbm;
4333 
4334  if (!model_.gamma1Given)
4335  paramPtr->gamma1 = 5.753e-12 * sqrt(paramPtr->npeak) / model_.cox;
4336 
4337  if (!model_.gamma2Given)
4338  paramPtr->gamma2 = 5.753e-12 * sqrt(paramPtr->nsub) / model_.cox;
4339 
4340  T0 = paramPtr->gamma1 - paramPtr->gamma2;
4341  T1 = sqrt(paramPtr->phi - paramPtr->vbx) - paramPtr->sqrtPhi;
4342  T2 = sqrt(paramPtr->phi * (paramPtr->phi - paramPtr->vbm)) - paramPtr->phi;
4343 
4344  paramPtr->k2 = T0 * T1 / (2.0 * T2 + paramPtr->vbm);
4345  paramPtr->k1 = paramPtr->gamma2 - 2.0 * paramPtr->k2 * sqrt(paramPtr->phi
4346  - paramPtr->vbm);
4347  }
4348 
4349  if (paramPtr->k2 < 0.0)
4350  {
4351  T0 = 0.5 * paramPtr->k1 / paramPtr->k2;
4352  paramPtr->vbsc = 0.9 * (paramPtr->phi - T0 * T0);
4353 
4354  if (paramPtr->vbsc > -3.0) paramPtr->vbsc = -3.0;
4355  else if (paramPtr->vbsc < -30.0) paramPtr->vbsc = -30.0;
4356  }
4357  else
4358  {
4359  paramPtr->vbsc = -30.0;
4360  }
4361 
4363 
4364  if (!model_.vfbGiven)
4365  {
4366  if (model_.vth0Given)
4367  {
4370  }
4371  else
4372  { paramPtr->vfb = -1.0;
4373  }
4374  }
4375 
4376  if (!model_.vth0Given)
4377  {
4379  * (paramPtr->vfb + paramPtr->phi + paramPtr->k1
4380  * paramPtr->sqrtPhi);
4381  }
4382 
4385 
4386  T1 = sqrt(CONSTEPSSI / CONSTEPSOX * model_.tox * paramPtr->Xdep0);
4387  T0 = exp(-0.5 * paramPtr->dsub * paramPtr->leff / T1);
4388 
4389  paramPtr->theta0vb0 = (T0 + 2.0 * T0 * T0);
4390 
4391  T0 = exp(-0.5 * paramPtr->drout * paramPtr->leff / T1);
4392  T2 = (T0 + 2.0 * T0 * T0);
4393 
4395 
4396  tmp = sqrt(paramPtr->Xdep0);
4397  tmp1 = paramPtr->vbi - paramPtr->phi;
4398  tmp2 = model_.factor1 * tmp;
4399 
4400  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * paramPtr->leff / tmp2;
4401 
4402  if (T0 > -CONSTEXP_THRESHOLD)
4403  {
4404  T1 = exp(T0);
4405  T2 = T1 * (1.0 + 2.0 * T1);
4406  }
4407  else
4408  {
4409  T1 = CONSTMIN_EXP;
4410  T2 = T1 * (1.0 + 2.0 * T1);
4411  }
4412  T0 = paramPtr->dvt0w * T2;
4413  T2 = T0 * tmp1;
4414 
4415  T0 = -0.5 * paramPtr->dvt1 * paramPtr->leff / tmp2;
4416 
4417  if (T0 > -CONSTEXP_THRESHOLD)
4418  {
4419  T1 = exp(T0);
4420  T3 = T1 * (1.0 + 2.0 * T1);
4421  }
4422  else
4423  {
4424  T1 = CONSTMIN_EXP;
4425  T3 = T1 * (1.0 + 2.0 * T1);
4426  }
4427 
4428  T3 = paramPtr->dvt0 * T3 * tmp1;
4429 
4430  T4 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
4431 
4432  T0 = sqrt(1.0 + paramPtr->nlx / paramPtr->leff);
4433  T5 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
4434  + (paramPtr->kt1 + paramPtr->kt1l / paramPtr->leff) * (TRatio - 1.0);
4435 
4436  tmp3 = model_.dtype * paramPtr->vth0 - T2 - T3 + paramPtr->k3 * T4 + T5;
4437 
4438  paramPtr->vfbzb = tmp3 - paramPtr->phi - paramPtr->k1 * paramPtr->sqrtPhi;
4439 
4440  } // End of vfbzb
4441 
4442  cgso = paramPtr->cgso;
4443  cgdo = paramPtr->cgdo;
4444 
4445  Nvtm = vtm * model_.jctEmissionCoeff;
4446 
4447  if ((sourceArea <= 0.0) &&
4448  (sourcePerimeter <= 0.0))
4449  {
4450  SourceSatCurrent = 1.0e-14;
4451  }
4452  else
4453  {
4454  SourceSatCurrent = sourceArea * jctTempSatCurDensity
4455  + sourcePerimeter
4457  }
4458 
4459  if ((SourceSatCurrent > 0.0) && (model_.ijth > 0.0))
4460  {
4461  vjsm = Nvtm * log(model_.ijth / SourceSatCurrent + 1.0);
4462  IsEvjsm = SourceSatCurrent * exp(vjsm / Nvtm);
4463  }
4464 
4465  if ((drainArea <= 0.0) &&
4466  (drainPerimeter <= 0.0))
4467  {
4468  DrainSatCurrent = 1.0e-14;
4469  }
4470  else
4471  {
4472  DrainSatCurrent = drainArea * jctTempSatCurDensity
4473  + drainPerimeter
4475  }
4476 
4477  if ((DrainSatCurrent > 0.0) && (model_.ijth > 0.0))
4478  {
4479  vjdm = Nvtm * log(model_.ijth / DrainSatCurrent + 1.0);
4480  IsEvjdm = DrainSatCurrent * exp(vjdm / Nvtm);
4481  }
4482 
4483  updateTemperatureCalled_ = true;
4484 
4485  return bsuccess;
4486  }
4487 
4488 //-----------------------------------------------------------------------------
4489 // Function : Instance::updateIntermediateVars
4490 // Purpose :
4491 // Special Notes :
4492 // Scope : public
4493 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
4494 // Creation Date : 01/09/01
4495 //-----------------------------------------------------------------------------
4497  {
4498  bool bsuccess = true;
4499 
4500 // begin the b3ld.c parameters:
4501  double SourceSatCurrent(0.0), DrainSatCurrent(0.0);
4502  double vgdo(0.0);
4503 
4504  double VgstNVt(0.0), ExpVgst(0.0);
4505 
4506  double czbd(0.0), czbdsw(0.0), czbdswg(0.0), czbs(0.0), czbssw(0.0), czbsswg(0.0);
4507  double evbd(0.0), evbs(0.0), arg(0.0), sarg(0.0);
4508 
4509  double Vfbeff(0.0), dVfbeff_dVg(0.0), dVfbeff_dVb(0.0), V3(0.0), V4(0.0);
4510 
4511  double MJ(0.0), MJSW(0.0), MJSWG(0.0);
4512 
4513  double qinoi(0.0);
4514  double Vds(0.0), Vgs(0.0), Vbs(0.0);
4515  double Vgs_eff(0.0), Vfb(0.0);
4516  double Phis(0.0), dPhis_dVb(0.0), sqrtPhis(0.0), dsqrtPhis_dVb(0.0);
4517  double Vth(0.0), dVth_dVb(0.0), dVth_dVd(0.0);
4518  double Vgst(0.0);
4519 
4520  double Nvtm(0.0);
4521  double Vtm(0.0);
4522  double n(0.0), dn_dVb(0.0), dn_dVd(0.0), voffcv(0.0), noff(0.0), dnoff_dVd(0.0), dnoff_dVb(0.0);
4523  double ExpArg(0.0), V0(0.0), CoxWLcen(0.0), QovCox(0.0), LINK(0.0);
4524  double DeltaPhi(0.0);
4525 
4526  double Cox(0.0), Tox(0.0), Tcen(0.0), dTcen_dVg(0.0), dTcen_dVd(0.0), dTcen_dVb(0.0);
4527  double Ccen(0.0), Coxeff(0.0), dCoxeff_dVg(0.0), dCoxeff_dVd(0.0), dCoxeff_dVb(0.0);
4528  double Denomi(0.0), dDenomi_dVg(0.0), dDenomi_dVd(0.0), dDenomi_dVb(0.0);
4529 
4530  double dueff_dVg(0.0), dueff_dVd(0.0), dueff_dVb(0.0);
4531  double Esat(0.0);
4532 
4533  double Vdsat(0.0);
4534 
4535  double EsatL(0.0), dEsatL_dVg(0.0), dEsatL_dVd(0.0), dEsatL_dVb(0.0);
4536 
4537  double dVdsat_dVg(0.0), dVdsat_dVb(0.0), dVdsat_dVd(0.0), Vasat(0.0), dAlphaz_dVg(0.0), dAlphaz_dVb(0.0);
4538  double dVasat_dVg(0.0), dVasat_dVb(0.0), dVasat_dVd(0.0), Va(0.0);
4539 
4540  double dVa_dVd(0.0), dVa_dVg(0.0), dVa_dVb(0.0);
4541  double Vbseff(0.0), dVbseff_dVb(0.0), VbseffCV(0.0), dVbseffCV_dVb(0.0);
4542  double Arg1(0.0);
4543 
4544  double One_Third_CoxWL(0.0), Two_Third_CoxWL(0.0), Alphaz(0.0);
4545 
4546  double T0(0.0), dT0_dVg(0.0), dT0_dVd(0.0), dT0_dVb(0.0);
4547  double T1(0.0), dT1_dVg(0.0), dT1_dVd(0.0), dT1_dVb(0.0);
4548  double T2(0.0), dT2_dVg(0.0), dT2_dVd(0.0), dT2_dVb(0.0);
4549  double T3(0.0), dT3_dVg(0.0), dT3_dVd(0.0), dT3_dVb(0.0);
4550  double T4(0.0);
4551 
4552  double T5(0.0);
4553  double T6(0.0);
4554  double T7(0.0);
4555  double T8(0.0);
4556  double T9(0.0);
4557  double T10(0.0);
4558  double T11(0.0), T12(0.0);
4559 
4560  double tmp(0.0), Abulk(0.0), dAbulk_dVb(0.0), Abulk0(0.0), dAbulk0_dVb(0.0);
4561 
4562  double VACLM(0.0), dVACLM_dVg(0.0), dVACLM_dVd(0.0), dVACLM_dVb(0.0);
4563  double VADIBL(0.0), dVADIBL_dVg(0.0), dVADIBL_dVd(0.0), dVADIBL_dVb(0.0);
4564 
4565  double Xdep(0.0), dXdep_dVb(0.0), lt1(0.0), dlt1_dVb(0.0), ltw(0.0), dltw_dVb(0.0);
4566  double Delt_vth(0.0), dDelt_vth_dVb(0.0);
4567 
4568  double Theta0(0.0), dTheta0_dVb(0.0);
4569 
4570  double TempRatio(0.0), tmp1(0.0), tmp2(0.0), tmp3(0.0), tmp4(0.0);
4571 
4572  double DIBL_Sft(0.0), dDIBL_Sft_dVd(0.0);
4573 
4574  double Lambda(0.0), dLambda_dVg(0.0);
4575 
4576  double a1(0.0);
4577 
4578  double Vgsteff(0.0), dVgsteff_dVg(0.0), dVgsteff_dVd(0.0), dVgsteff_dVb(0.0);
4579  double Vdseff(0.0), dVdseff_dVg(0.0), dVdseff_dVd(0.0), dVdseff_dVb(0.0);
4580  double VdseffCV(0.0), dVdseffCV_dVg(0.0), dVdseffCV_dVd(0.0), dVdseffCV_dVb(0.0);
4581  double diffVds(0.0);
4582 
4583  double dAbulk_dVg(0.0);
4584  double beta(0.0), dbeta_dVg(0.0), dbeta_dVd(0.0), dbeta_dVb(0.0);
4585  double gche(0.0), dgche_dVg(0.0), dgche_dVd(0.0), dgche_dVb(0.0);
4586  double fgche1(0.0), dfgche1_dVg(0.0), dfgche1_dVd(0.0), dfgche1_dVb(0.0);
4587  double fgche2(0.0), dfgche2_dVg(0.0), dfgche2_dVd(0.0), dfgche2_dVb(0.0);
4588  double Idl(0.0), dIdl_dVg(0.0), dIdl_dVd(0.0), dIdl_dVb(0.0);
4589  double Idsa(0.0), dIdsa_dVg(0.0), dIdsa_dVd(0.0), dIdsa_dVb(0.0);
4590  double Ids(0.0);
4591 
4592  double Gds(0.0), Gmb(0.0);
4593  double Isub(0.0);
4594 
4595  double Gbd(0.0), Gbg(0.0), Gbb(0.0);
4596  double VASCBE(0.0), dVASCBE_dVg(0.0), dVASCBE_dVd(0.0), dVASCBE_dVb(0.0);
4597  double CoxWovL(0.0);
4598  double Rds(0.0), dRds_dVg(0.0), dRds_dVb(0.0), WVCox(0.0), WVCoxRds(0.0);
4599  double Vgst2Vtm(0.0), VdsatCV(0.0);
4600 
4601  double dVdsatCV_dVg(0.0), dVdsatCV_dVb(0.0);
4602  double Leff(0.0), Weff(0.0), dWeff_dVg(0.0), dWeff_dVb(0.0);
4603  double AbulkCV(0.0), dAbulkCV_dVb(0.0);
4604 
4605  double gtau_diff(0.0), gtau_drift(0.0);
4606  // these shadow member varables and then are unitialized
4607  // when used in later calculations
4608  // double qcheq(0.0), cqcheq(0.0), qdef(0.0);
4609 
4610  double Cgg1(0.0), Cgb1(0.0), Cgd1(0.0), Cbg1(0.0), Cbb1(0.0), Cbd1(0.0);
4611 
4612  double Qac0(0.0), Qsub0(0.0);
4613  double dQac0_dVg(0.0), dQac0_dVb(0.0), dQsub0_dVg(0.0), dQsub0_dVd(0.0), dQsub0_dVb(0.0);
4614  double von_local(0.0);
4615 
4616  ScalingFactor = 1.0e-9;
4617 
4618  // Don't do charge computations in DC sweeps.
4619  if (getSolverState().tranopFlag || getSolverState().acopFlag || getSolverState().transientFlag)
4620  {
4621  ChargeComputationNeeded = true;
4622  }
4623  else
4624  {
4625  ChargeComputationNeeded = false;
4626  }
4627 
4628 #ifdef Xyce_DEBUG_DEVICE
4629  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
4630  {
4631  Xyce::dout() << subsection_divider << std::endl;
4632  Xyce::dout() << " Instance::updateIntermediateVars\n";
4633  Xyce::dout() << " name = " << getName();
4634  Xyce::dout() << " model name = " << model_.getName();
4635  Xyce::dout() <<" dtype is " << model_.dtype << std::endl;
4636  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4637  Xyce::dout() << " " << std::endl;
4638  }
4639 #endif
4640 
4641  int Check = 1;
4642 
4643  // The first block of code in b3ld.c basically sets up, locally,
4644  // what the load function should use as values for the various solution
4645  // variables. There is a series of IF statements which are dependent
4646  // upon the mode. (transient, initializing transient, operating point,
4647  // small signal, etc.). Xyce treats the operating point and transient
4648  // calculation in the same way, from the device's point of view, and
4649  // we don't support any of the other modes. Therefore most of these
4650  // mode options are not here - only the transient mode stuff.
4651 
4652  // First get some of the needed solution variables:
4653  Vd = 0.0;
4654  Vs = 0.0;
4655  Vg = 0.0;
4656  Vb = 0.0;
4657  Vsp = 0.0;
4658  Vdp = 0.0;
4659  Qtotal = 0.0;
4660 
4667  if( nqsMod )
4668  {
4670  }
4671  else
4672  {
4673  Qtotal = 0.0;
4674  }
4675 
4676 #ifdef Xyce_DEBUG_DEVICE
4678  {
4679  Xyce::dout() << " Vg = " << Vg << std::endl;
4680  Xyce::dout() << " Vb = " << Vb << std::endl;
4681  Xyce::dout() << " Vs = " << Vs << std::endl;
4682  Xyce::dout() << " Vd = " << Vd << std::endl;
4683  Xyce::dout() << " Vsp = " << Vsp << std::endl;
4684  Xyce::dout() << " Vdp = " << Vdp << std::endl;
4685  Xyce::dout() << " Qtotal = " << Qtotal << std::endl;
4686  }
4687 #endif
4688 
4689  Vddp = Vd - Vdp;
4690  Vssp = Vs - Vsp;
4691  Vbsp = Vb - Vsp;
4692  Vbdp = Vb - Vdp;
4693  Vgsp = Vg - Vsp;
4694  Vgdp = Vg - Vdp;
4695  Vgb = Vg - Vb;
4696 
4697  Vdpsp = Vdp - Vsp;
4698 
4699  // modified from b3ld: (see lines 221-230)
4700  vbs = model_.dtype * Vbsp;
4701  vgs = model_.dtype * Vgsp;
4702  vds = model_.dtype * Vdpsp;
4703 
4704  qdef = model_.dtype * Qtotal;
4705 
4706  vbd = vbs - vds;
4707  vgd = vgs - vds;
4708 
4709  origFlag = 1;
4710  limitedFlag = false;
4711  vgs_orig = vgs;
4712  vds_orig = vds;
4713  vbs_orig = vbs;
4714  vbd_orig = vbd;
4715  vgd_orig = vgd;
4716 
4717  // What follows is a block of code designed to impose some limits,
4718  // or initial conditions on the junction voltages. Initial conditions
4719  // should only be imposed on the first Newton step of an operating point.
4720  //
4721  // The first possible limit on the junction voltages has to do with
4722  // limiting the percent change of junction voltages between Newton
4723  // iterations. The second has to do with avoiding extra floating point
4724  // operations in the event that the device has in some sense converged
4725  // (aka BYPASS). Although the primary point of BYPASS is to reduce
4726  // neccessary work, it also seems to reduce the number of Newton iterations.
4727  //
4728  // NOTE: We do not support BYPASS.
4729  //
4730  // The "old" variables should be the values for the previous
4731  // Newton iteration, if indeed there was a previous Newton
4732  // iteration. If not, just set the old values equal to
4733  // the current ones.
4734  //
4735 
4736  // set an initial condition if appropriate:
4737  if (getSolverState().initJctFlag && !OFF && getDeviceOptions().voltageLimiterFlag)
4738  {
4739  if (getSolverState().inputOPFlag)
4740  {
4741  N_LAS_Vector * flagSolVectorPtr = extData.flagSolVectorPtr;
4742  if ((*flagSolVectorPtr)[li_Drain] == 0 || (*flagSolVectorPtr)[li_Gate] == 0 ||
4743  (*flagSolVectorPtr)[li_Source] == 0 || (*flagSolVectorPtr)[li_SourcePrime] == 0 ||
4744  (*flagSolVectorPtr)[li_DrainPrime] == 0 || (*flagSolVectorPtr)[li_Bulk] == 0 )
4745  {
4746  vbs = 0.0;
4747  vgs = model_.dtype * paramPtr->vth0 + 0.1;
4748  vds = 0.1;
4749  origFlag = 0;
4750  }
4751  }
4752  else
4753  {
4754  vbs = 0.0;
4755  vgs = model_.dtype * paramPtr->vth0 + 0.1;
4756  vds = 0.1;
4757  origFlag = 0;
4758  }
4759  vbd = vbs - vds;
4760  vgd = vgs - vds;
4761  //origFlag = 0;
4762  }
4763  else if ((getSolverState().initFixFlag || getSolverState().initJctFlag) && OFF)
4764  {
4765  qdef = vbs = vgs = vds = 0;
4766  }
4767 
4768 
4769  if (getSolverState().newtonIter == 0)
4770  {
4771  newtonIterOld = 0;
4772 
4773  if (!getSolverState().dcopFlag || (getSolverState().locaEnabledFlag && getSolverState().dcopFlag))
4774  // ie, first newton step of a transient time step or DCOP continuation step.
4775  {
4780  von_local = (extData.currStoVectorRawPtr)[li_store_von];
4781  }
4782  else
4783  { // no history
4784  vbs_old = vbs;
4785  vbd_old = vbd;
4786  vgs_old = vgs;
4787  vds_old = vds;
4788  von_local = 0.0;
4789  }
4790  }
4791  else
4792  {
4797  von_local = (extData.nextStoVectorRawPtr)[li_store_von];
4798  }
4799 
4800  vgdo = vgs_old - vds_old;
4801 
4802  // This next block performs checks on the junction voltages and
4803  // imposes limits on them if they are too big.
4804  // Note: In the level=1 von is multiplied by dtype. Here it is not. They
4805  // are both right.
4806 
4808  {
4809 
4810 #ifdef Xyce_DEBUG_DEVICE
4812  {
4813  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4814  Xyce::dout() << " von_local = " << von_local << std::endl;
4815  Xyce::dout() << " CONSTvt0 = " << CONSTvt0 << std::endl;
4816  Xyce::dout() << " vcrit = " << model_.vcrit << std::endl;
4817  Xyce::dout().width(3);
4818  Xyce::dout() << getSolverState().newtonIter;
4819  Xyce::dout().width(5);Xyce::dout() << getName();
4820  Xyce::dout() << " old :";
4821  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4822  Xyce::dout() << vgs_old;
4823  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4824  Xyce::dout() << vds_old;
4825  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4826  Xyce::dout() << vbs_old;
4827  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4828  Xyce::dout() << vbd_old << std::endl;
4829  Xyce::dout().width(3);
4830  Xyce::dout() << getSolverState().newtonIter;
4831  Xyce::dout().width(5);Xyce::dout() << getName();
4832  Xyce::dout() << " Blim:";
4833  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4834  Xyce::dout() << vgs;
4835  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4836  Xyce::dout() << vds;
4837  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4838  Xyce::dout() << vbs;
4839  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4840  Xyce::dout() << vbd << std::endl;
4841  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4842  }
4843 #endif
4844 
4845  // only do this if we are beyond the first Newton iteration. On the
4846  // first newton iteration, the "old" values are from a previous time
4847  // step.
4848 
4849  if (getSolverState().newtonIter >= 0)
4850  {
4851  if (vds_old >= 0.0)
4852  {
4853  vgs = devSupport.fetlim( vgs, vgs_old, von_local);
4854  vds = vgs - vgd;
4855  vds = devSupport.limvds( vds, vds_old);
4856  vgd = vgs - vds;
4857  }
4858  else
4859  {
4860  vgd = devSupport.fetlim( vgd, vgdo, von_local);
4861  vds = vgs - vgd;
4862  vds = -devSupport.limvds( -vds, -vds_old );
4863  vgs = vgd + vds;
4864  }
4865 
4866  if (vds >= 0.0)
4867  {
4869  model_.vcrit, &Check);
4870  vbd = vbs - vds;
4871  }
4872  else
4873  {
4875  model_.vcrit, &Check);
4876  vbs = vbd + vds;
4877  }
4878  }
4879 
4880  // set the origFlag:
4881 #ifdef Xyce_NEW_ORIG_TEST
4882  double vgs_diff = fabs(vgs - vgs_orig);
4883  double vds_diff = fabs(vds - vds_orig);
4884  double vbs_diff = fabs(vbs - vbs_orig);
4885  double vgd_diff = fabs(vgd - vgd_orig);
4886 
4887  bool noOrigFlag_vgs = 0;
4888  bool noOrigFlag_vds = 0;
4889  bool noOrigFlag_vbs = 0;
4890  bool noOrigFlag_vgd = 0;
4891 
4892  if (vgs_diff != 0.0)
4893  {
4894  if (vgs_orig != 0.0)
4895  {
4896  if ( fabs(vgs_diff/vgs_orig) > reltol) noOrigFlag_vgs = 1;
4897  }
4898  else
4899  {
4900  if ( fabs(vgs_diff) > voltTol ) noOrigFlag_vgs = 1;
4901  }
4902  }
4903 
4904  if (vds_diff != 0.0)
4905  {
4906  if (vds_orig != 0.0)
4907  {
4908  if ( fabs(vds_diff/vds_orig) > reltol) noOrigFlag_vds = 1;
4909  }
4910  else
4911  {
4912  if ( fabs(vds_diff) > voltTol ) noOrigFlag_vds = 1;
4913  }
4914  }
4915 
4916  if (vbs_diff != 0.0)
4917  {
4918  if (vbs_orig != 0.0)
4919  {
4920  if ( fabs(vbs_diff/vbs_orig) > reltol) noOrigFlag_vbs = 1;
4921  }
4922  else
4923  {
4924  if ( fabs(vbs_diff) > voltTol ) noOrigFlag_vbs = 1;
4925  }
4926  }
4927 
4928  if (vgd_diff != 0.0)
4929  {
4930  if (vgd_orig != 0.0)
4931  {
4932  if ( fabs(vgd_diff/vgd_orig) > reltol) noOrigFlag_vgd = 1;
4933  }
4934  else
4935  {
4936  if ( fabs(vgd_diff) > voltTol ) noOrigFlag_vgd = 1;
4937  }
4938  }
4939 
4940  origFlag = !( noOrigFlag_vgs || noOrigFlag_vds ||
4941  noOrigFlag_vbs || noOrigFlag_vgd);
4942 
4943 #else
4944  if (vgs_orig != vgs || vds_orig != vds ||
4945  vbs_orig != vbs || vbd_orig != vbd || vgd_orig != vgd) origFlag = 0;
4946 #endif
4947 
4948  // for convergence testing:
4949  if (Check == 1) limitedFlag=true;
4950 
4951 #ifdef Xyce_DEBUG_DEVICE
4953  {
4954  Xyce::dout().width(3);
4955  Xyce::dout() << getSolverState().newtonIter;
4956  Xyce::dout().width(5);Xyce::dout() << getName();
4957  Xyce::dout() << " Alim:";
4958  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4959  Xyce::dout() << vgs;
4960  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4961  Xyce::dout() << vds;
4962  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4963  Xyce::dout() << vbs;
4964  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4965  Xyce::dout() << vbd;
4966  if (origFlag) Xyce::dout() << " SAME";
4967  else Xyce::dout() << " DIFF";
4968  Xyce::dout() << std::endl;
4969  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4970  }
4971 #endif
4972 
4973  } // getDeviceOptions().voltageLimiterFlag
4974 
4975  // update the "old" variables:
4976  if (getSolverState().newtonIter != 0 && getSolverState().newtonIter != newtonIterOld)
4977  {
4979  }
4980 
4981  // Finished with what would have been the series of CKTmode
4982  // IF statements...
4983 
4984  // file: b3ld.c line: 345
4985  // determine DC current and derivatives
4986  vbd = vbs - vds;
4987  vgd = vgs - vds;
4988  vgb = vgs - vbs;
4989 
4990 #ifdef Xyce_DEBUG_DEVICE
4991  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
4992  {
4993  Xyce::dout() << " mod type = " << model_.modType << std::endl;
4994  Xyce::dout() << "dtype = " << model_.dtype << std::endl;
4995  Xyce::dout() << " vbs = " << vbs << std::endl;
4996  Xyce::dout() << " vds = " << vds << std::endl;
4997  Xyce::dout() << " vgs = " << vgs << std::endl;
4998 
4999  Xyce::dout() << " vbd = " << vbd << std::endl;
5000  Xyce::dout() << " vgd = " << vgd << std::endl;
5001  Xyce::dout() << " vgb = " << vgs << std::endl;
5002  Xyce::dout() << " qdef = " << qdef << std::endl;
5003  }
5004 #endif
5005 
5006  // Source/drain junction diode DC model begins
5007  Nvtm = vtm * model_.jctEmissionCoeff;
5008 
5009  if ((sourceArea <= 0.0) && (sourcePerimeter <= 0.0))
5010  {
5011  SourceSatCurrent = 1.0e-14;
5012  }
5013  else
5014  {
5015  SourceSatCurrent = sourceArea
5017  + sourcePerimeter
5019  }
5020 
5021  if (SourceSatCurrent <= 0.0)
5022  {
5024  cbs = gbs * vbs;
5025  }
5026  else
5027  {
5028  if (model_.ijth == 0.0)
5029  {
5030  evbs = exp(vbs / Nvtm);
5031  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5032  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5033  }
5034  else
5035  {
5036  if (vbs < vjsm)
5037  {
5038  evbs = exp(vbs / Nvtm);
5039  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5040  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5041  }
5042  else
5043  {
5044  T0 = IsEvjsm / Nvtm;
5045  gbs = T0 + getDeviceOptions().gmin;
5046  cbs = IsEvjsm - SourceSatCurrent
5047  + T0 * (vbs - vjsm)
5048  + getDeviceOptions().gmin * vbs;
5049  }
5050  }
5051  }
5052 
5053  if ((drainArea <= 0.0) && (drainPerimeter <= 0.0))
5054  {
5055  DrainSatCurrent = 1.0e-14;
5056  }
5057  else
5058  {
5059  DrainSatCurrent = drainArea
5061  + drainPerimeter
5063  }
5064 
5065  if (DrainSatCurrent <= 0.0)
5066  {
5068  cbd = gbd * vbd;
5069  }
5070  else
5071  {
5072  if (model_.ijth == 0.0)
5073  {
5074  evbd = exp(vbd / Nvtm);
5075  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5076  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5077  }
5078  else
5079  {
5080  if (vbd < vjdm)
5081  {
5082  evbd = exp(vbd / Nvtm);
5083  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5084  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5085  }
5086  else
5087  {
5088  T0 = IsEvjdm / Nvtm;
5089  gbd = T0 + getDeviceOptions().gmin;
5090  cbd = IsEvjdm - DrainSatCurrent
5091  + T0 * (vbd - vjdm)
5092  + getDeviceOptions().gmin * vbd;
5093  }
5094  }
5095  }
5096  // End of diode DC model
5097 
5098  if (vds >= 0.0)
5099  { // normal mode
5100  mode = 1;
5101  Vds = vds;
5102  Vgs = vgs;
5103  Vbs = vbs;
5104  }
5105  else
5106  { // inverse mode
5107  mode = -1;
5108  Vds = -vds;
5109  Vgs = vgd;
5110  Vbs = vbd;
5111  }
5112 
5113  // mosfet continuation.
5114  // This idea is based, loosely, on a paper by Jaijeet
5115  // Rosychowdhury. If the artificial parameter flag has been enabled,
5116  // modify Vds and Vgs.
5117 #ifdef Xyce_DEBUG_DEVICE
5119  {
5120  Xyce::dout() << "HOMOTOPY INFO: gainscale = "
5121  << getSolverState().gainScale[blockHomotopyID] << std::endl;
5122  Xyce::dout() << "HOMOTOPY INFO: before vds = " << Vds << std::endl;
5123  Xyce::dout() << "HOMOTOPY INFO: before vgst = " << Vgs << std::endl;
5124  }
5125 #endif
5126  if (getSolverState().artParameterFlag)
5127  {
5128 
5129  double alpha = getSolverState().gainScale[blockHomotopyID];
5130  if (getDeviceOptions().staggerGainScale)
5131  {
5132  alpha *= (0.3 * randomPerturb + 1.0);
5133  if (alpha > 1.0)
5134  {
5135  alpha = 1.0;
5136  }
5137  }
5138  double vgstConst = getDeviceOptions().vgstConst;
5139  if (getDeviceOptions().randomizeVgstConst)
5140  {
5141  vgstConst *= randomPerturb;
5142  }
5143 
5144  Vds = devSupport.contVds (Vds,getSolverState().nltermScale,getDeviceOptions().vdsScaleMin);
5145  Vgs = devSupport.contVgst(Vgs, alpha, vgstConst);
5146  }
5147 #ifdef Xyce_DEBUG_DEVICE
5148  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
5149  {
5150  Xyce::dout() << "HOMOTOPY INFO: after vds = " << Vds << std::endl;
5151  Xyce::dout() << "HOMOTOPY INFO: after vgst = " << Vgs << std::endl;
5152  }
5153 #endif
5154  // end of mosfet continuation block.
5155 
5156  T0 = Vbs - paramPtr->vbsc - 0.001;
5157  T1global = sqrt(T0 * T0 - 0.004 * paramPtr->vbsc);
5158  Vbseff = paramPtr->vbsc + 0.5 * (T0 + T1global);
5159  dVbseff_dVb = 0.5 * (1.0 + T0 / T1global);
5160 
5161  if (Vbseff < Vbs) Vbseff = Vbs;
5162 
5163  if (Vbseff > 0.0)
5164  {
5165  T0 = paramPtr->phi / (paramPtr->phi + Vbseff);
5166  Phis = paramPtr->phi * T0;
5167  dPhis_dVb = -T0 * T0;
5168  sqrtPhis = paramPtr->phis3 / (paramPtr->phi + 0.5 * Vbseff);
5169  dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / paramPtr->phis3;
5170  }
5171  else
5172  {
5173  Phis = paramPtr->phi - Vbseff;
5174  dPhis_dVb = -1.0;
5175  sqrtPhis = sqrt(Phis);
5176  dsqrtPhis_dVb = -0.5 / sqrtPhis;
5177  }
5178 
5179  Xdep = paramPtr->Xdep0 * sqrtPhis / paramPtr->sqrtPhi;
5180  dXdep_dVb = (paramPtr->Xdep0 / paramPtr->sqrtPhi) * dsqrtPhis_dVb;
5181 
5182  Leff = paramPtr->leff;
5183  Vtm = vtm;
5184  // Vth Calculation
5185  T3 = sqrt(Xdep);
5186  V0 = paramPtr->vbi - paramPtr->phi;
5187 
5188  T0 = paramPtr->dvt2 * Vbseff;
5189  if (T0 >= - 0.5)
5190  {
5191  T1 = 1.0 + T0;
5192  T2 = paramPtr->dvt2;
5193  }
5194  else // Added to avoid any discontinuity problems caused by dvt2
5195  {
5196  T4 = 1.0 / (3.0 + 8.0 * T0);
5197  T1 = (1.0 + 3.0 * T0) * T4;
5198  T2 = paramPtr->dvt2 * T4 * T4;
5199  }
5200 
5201  lt1 = model_.factor1 * T3 * T1;
5202  dlt1_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5203 
5204  T0 = paramPtr->dvt2w * Vbseff;
5205  if (T0 >= - 0.5)
5206  {
5207  T1 = 1.0 + T0;
5208  T2 = paramPtr->dvt2w;
5209  }
5210  else // Added to avoid any discontinuity problems caused by dvt2w
5211  {
5212  T4 = 1.0 / (3.0 + 8.0 * T0);
5213  T1 = (1.0 + 3.0 * T0) * T4;
5214  T2 = paramPtr->dvt2w * T4 * T4;
5215  }
5216 
5217  ltw = model_.factor1 * T3 * T1;
5218  dltw_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5219 
5220  T0 = -0.5 * paramPtr->dvt1 * Leff / lt1;
5221  if (T0 > -CONSTEXP_THRESHOLD)
5222  {
5223  T1 = exp(T0);
5224  Theta0 = T1 * (1.0 + 2.0 * T1);
5225  dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb;
5226  dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5227  }
5228  else
5229  {
5230  T1 = CONSTMIN_EXP;
5231  Theta0 = T1 * (1.0 + 2.0 * T1);
5232  dTheta0_dVb = 0.0;
5233  }
5234 
5235  thetavth = paramPtr->dvt0 * Theta0;
5236  Delt_vth = thetavth * V0;
5237  dDelt_vth_dVb = paramPtr->dvt0 * dTheta0_dVb * V0;
5238 
5239  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * Leff / ltw;
5240  if (T0 > -CONSTEXP_THRESHOLD)
5241  {
5242  T1 = exp(T0);
5243  T2 = T1 * (1.0 + 2.0 * T1);
5244  dT1_dVb = -T0 / ltw * T1 * dltw_dVb;
5245  dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5246  }
5247  else
5248  {
5249  T1 = CONSTMIN_EXP;
5250  T2 = T1 * (1.0 + 2.0 * T1);
5251  dT2_dVb = 0.0;
5252  }
5253 
5254  T0 = paramPtr->dvt0w * T2;
5255  T2 = T0 * V0;
5256  dT2_dVb = paramPtr->dvt0w * dT2_dVb * V0;
5257 
5258  TempRatio = temp / model_.tnom - 1.0;
5259  T0 = sqrt(1.0 + paramPtr->nlx / Leff);
5260  T1 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
5261  + (paramPtr->kt1 + paramPtr->kt1l / Leff
5262  + paramPtr->kt2 * Vbseff) * TempRatio;
5263 
5264  tmp2 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
5265 
5266  T3 = paramPtr->eta0 + paramPtr->etab * Vbseff;
5267  if (T3 < 1.0e-4) // avoid discontinuity problems caused by etab
5268  {
5269  T9 = 1.0 / (3.0 - 2.0e4 * T3);
5270  T3 = (2.0e-4 - T3) * T9;
5271  T4 = T9 * T9;
5272  }
5273  else
5274  {
5275  T4 = 1.0;
5276  }
5277 
5278  dDIBL_Sft_dVd = T3 * paramPtr->theta0vb0;
5279  DIBL_Sft = dDIBL_Sft_dVd * Vds;
5280 
5281  Vth = model_.dtype * paramPtr->vth0 - paramPtr->k1
5282  * paramPtr->sqrtPhi + paramPtr->k1ox * sqrtPhis
5283  - paramPtr->k2ox * Vbseff - Delt_vth - T2 + (paramPtr->k3
5284  + paramPtr->k3b * Vbseff) * tmp2 + T1 - DIBL_Sft;
5285 
5286  von = Vth;
5287 
5288  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb - paramPtr->k2ox
5289  - dDelt_vth_dVb - dT2_dVb + paramPtr->k3b * tmp2
5290  - paramPtr->etab * Vds * paramPtr->theta0vb0 * T4
5291  + paramPtr->kt2 * TempRatio;
5292 
5293  dVth_dVd = -dDIBL_Sft_dVd;
5294 
5295  // Calculate n
5296  tmp2 = paramPtr->nfactor * CONSTEPSSI / Xdep;
5297  tmp3 = paramPtr->cdsc + paramPtr->cdscb * Vbseff
5298  + paramPtr->cdscd * Vds;
5299  tmp4 = (tmp2 + tmp3 * Theta0 + paramPtr->cit) / model_.cox;
5300 
5301  if (tmp4 >= -0.5)
5302  {
5303  n = 1.0 + tmp4;
5304  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5305  + paramPtr->cdscb * Theta0) / model_.cox;
5306  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox;
5307  }
5308  else // avoid discontinuity problems caused by tmp4
5309  {
5310  T0 = 1.0 / (3.0 + 8.0 * tmp4);
5311  n = (1.0 + 3.0 * tmp4) * T0;
5312  T0 *= T0;
5313  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5314  + paramPtr->cdscb * Theta0) / model_.cox * T0;
5315  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox * T0;
5316  }
5317 
5318  // Poly Gate Si Depletion Effect
5319  T0 = paramPtr->vfb + paramPtr->phi;
5320 
5321  // added to avoid the problem caused by ngate
5322  if ((paramPtr->ngate > 1.e18) && (paramPtr->ngate < 1.e25) && (Vgs > T0))
5323  {
5324  T1 = 1.0e6 * CONSTQ * CONSTEPSSI * paramPtr->ngate
5325  / (model_.cox * model_.cox);
5326  T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1);
5327 
5328  T2 = T1 * (T4 - 1.0);
5329  T3 = 0.5 * T2 * T2 / T1; // T3 = Vpoly
5330  T7 = 1.12 - T3 - 0.05;
5331  T6 = sqrt(T7 * T7 + 0.224);
5332  T5 = 1.12 - 0.5 * (T7 + T6);
5333  Vgs_eff = Vgs - T5;
5334  dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6);
5335  }
5336  else
5337  {
5338  Vgs_eff = Vgs;
5339  dVgs_eff_dVg = 1.0;
5340  }
5341  Vgst = Vgs_eff - Vth;
5342 
5343  // Effective Vgst (Vgsteff) Calculation
5344  T10 = 2.0 * n * Vtm;
5345  VgstNVt = Vgst / T10;
5346  ExpArg = (2.0 * paramPtr->voff - Vgst) / T10;
5347 
5348  // MCJ: Very small Vgst
5349  if (VgstNVt > CONSTEXP_THRESHOLD)
5350  {
5351  Vgsteff = Vgst;
5352  dVgsteff_dVg = dVgs_eff_dVg;
5353  dVgsteff_dVd = -dVth_dVd;
5354  dVgsteff_dVb = -dVth_dVb;
5355  }
5356  else if (ExpArg > CONSTEXP_THRESHOLD)
5357  {
5358  T0 = (Vgst - paramPtr->voff) / (n * Vtm);
5359  ExpVgst = exp(T0);
5360  Vgsteff = Vtm * paramPtr->cdep0 / model_.cox * ExpVgst;
5361  dVgsteff_dVg = Vgsteff / (n * Vtm);
5362  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd);
5363  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb);
5364  dVgsteff_dVg *= dVgs_eff_dVg;
5365  }
5366  else
5367  {
5368  ExpVgst = exp(VgstNVt);
5369  T1 = T10 * log(1.0 + ExpVgst);
5370  dT1_dVg = ExpVgst / (1.0 + ExpVgst);
5371  dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb;
5372  dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd;
5373 
5374  dT2_dVg = -model_.cox / (Vtm * paramPtr->cdep0) * exp(ExpArg);
5375  T2 = 1.0 - T10 * dT2_dVg;
5376 
5377  dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd)
5378  + (T2 - 1.0) / n * dn_dVd;
5379 
5380  dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb)
5381  + (T2 - 1.0) / n * dn_dVb;
5382 
5383  Vgsteff = T1 / T2;
5384  T3 = T2 * T2;
5385 
5386  dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg;
5387  dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3;
5388  dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3;
5389  }
5390 
5391  // Calculate Effective Channel Geometry
5392  T9 = sqrtPhis - paramPtr->sqrtPhi;
5393  Weff = paramPtr->weff -2.0 *(paramPtr->dwg * Vgsteff + paramPtr->dwb * T9);
5394  dWeff_dVg = -2.0 * paramPtr->dwg;
5395  dWeff_dVb = -2.0 * paramPtr->dwb * dsqrtPhis_dVb;
5396 
5397  if (Weff < 2.0e-8) // to avoid the discontinuity problem due to Weff
5398  {
5399  T0 = 1.0 / (6.0e-8 - 2.0 * Weff);
5400  Weff = 2.0e-8 * (4.0e-8 - Weff) * T0;
5401  T0 *= T0 * 4.0e-16;
5402  dWeff_dVg *= T0;
5403  dWeff_dVb *= T0;
5404  }
5405 
5406  T0 = paramPtr->prwg * Vgsteff + paramPtr->prwb * T9;
5407  if (T0 >= -0.9)
5408  {
5409  Rds = paramPtr->rds0 * (1.0 + T0);
5410  dRds_dVg = paramPtr->rds0 * paramPtr->prwg;
5411  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb;
5412  }
5413  else // to avoid the discontinuity problem due to prwg and prwb
5414  {
5415  T1 = 1.0 / (17.0 + 20.0 * T0);
5416  Rds = paramPtr->rds0 * (0.8 + T0) * T1;
5417  T1 *= T1;
5418  dRds_dVg = paramPtr->rds0 * paramPtr->prwg * T1;
5419  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb * T1;
5420  }
5421 
5422  // Calculate Abulk
5423  T1 = 0.5 * paramPtr->k1ox / sqrtPhis;
5424  dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb;
5425 
5426  T9 = sqrt(paramPtr->xj * Xdep);
5427  tmp1 = Leff + 2.0 * T9;
5428  T5 = Leff / tmp1;
5429  tmp2 = paramPtr->a0 * T5;
5430  tmp3 = paramPtr->weff + paramPtr->b1;
5431  tmp4 = paramPtr->b0 / tmp3;
5432  T2 = tmp2 + tmp4;
5433  dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb;
5434  T6 = T5 * T5;
5435  T7 = T5 * T6;
5436 
5437  Abulk0 = 1.0 + T1 * T2;
5438  dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb;
5439 
5440  T8 = paramPtr->ags * paramPtr->a0 * T7;
5441  dAbulk_dVg = -T1 * T8;
5442  Abulk = Abulk0 + dAbulk_dVg * Vgsteff;
5443  dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb);
5444 
5445  if (Abulk0 < 0.1) // added to avoid the problems caused by Abulk0
5446  {
5447  T9 = 1.0 / (3.0 - 20.0 * Abulk0);
5448  Abulk0 = (0.2 - Abulk0) * T9;
5449  dAbulk0_dVb *= T9 * T9;
5450  }
5451 
5452  if (Abulk < 0.1) // added to avoid the problems caused by Abulk
5453  {
5454  T9 = 1.0 / (3.0 - 20.0 * Abulk);
5455  Abulk = (0.2 - Abulk) * T9;
5456  T10 = T9 * T9;
5457  dAbulk_dVb *= T10;
5458  dAbulk_dVg *= T10;
5459  }
5460 
5461  T2 = paramPtr->keta * Vbseff;
5462  if (T2 >= -0.9)
5463  {
5464  T0 = 1.0 / (1.0 + T2);
5465  dT0_dVb = -paramPtr->keta * T0 * T0;
5466  }
5467  else // added to avoid the problems caused by Keta
5468  {
5469  T1 = 1.0 / (0.8 + T2);
5470  T0 = (17.0 + 20.0 * T2) * T1;
5471  dT0_dVb = -paramPtr->keta * T1 * T1;
5472  }
5473 
5474  dAbulk_dVg *= T0;
5475  dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb;
5476  dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb;
5477  Abulk *= T0;
5478  Abulk0 *= T0;
5479 
5480  // Mobility calculation
5481  if (model_.mobMod == 1)
5482  {
5483  T0 = Vgsteff + Vth + Vth;
5484  T2 = paramPtr->ua + paramPtr->uc * Vbseff;
5485  T3 = T0 / model_.tox;
5486  T5 = T3 * (T2 + paramPtr->ub * T3);
5487  dDenomi_dVg = (T2 + 2.0 * paramPtr->ub * T3) / model_.tox;
5488  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5489  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T3;
5490  }
5491  else if (model_.mobMod == 2)
5492  {
5493  T5 = Vgsteff / model_.tox * (paramPtr->ua
5494  + paramPtr->uc * Vbseff + paramPtr->ub * Vgsteff / model_.tox);
5495 
5496  dDenomi_dVg = (paramPtr->ua + paramPtr->uc * Vbseff
5497  + 2.0 * paramPtr->ub * Vgsteff / model_.tox) / model_.tox;
5498 
5499  dDenomi_dVd = 0.0;
5500  dDenomi_dVb = Vgsteff * paramPtr->uc / model_.tox;
5501  }
5502  else
5503  {
5504  T0 = Vgsteff + Vth + Vth;
5505  T2 = 1.0 + paramPtr->uc * Vbseff;
5506  T3 = T0 / model_.tox;
5507  T4 = T3 * (paramPtr->ua + paramPtr->ub * T3);
5508  T5 = T4 * T2;
5509 
5510  dDenomi_dVg = (paramPtr->ua + 2.0 * paramPtr->ub * T3) * T2 /model_.tox;
5511  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5512  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T4;
5513  }
5514 
5515  if (T5 >= -0.8)
5516  {
5517  Denomi = 1.0 + T5;
5518  }
5519  else // Added to avoid the discontinuity problem caused by ua and ub
5520  {
5521  T9 = 1.0 / (7.0 + 10.0 * T5);
5522  Denomi = (0.6 + T5) * T9;
5523  T9 *= T9;
5524  dDenomi_dVg *= T9;
5525  dDenomi_dVd *= T9;
5526  dDenomi_dVb *= T9;
5527  }
5528 
5529  ueff = paramPtr->u0temp / Denomi;
5530  T9 = -ueff / Denomi;
5531  dueff_dVg = T9 * dDenomi_dVg;
5532  dueff_dVd = T9 * dDenomi_dVd;
5533  dueff_dVb = T9 * dDenomi_dVb;
5534 
5535  // Saturation Drain Voltage Vdsat
5536  WVCox = Weff * paramPtr->vsattemp * model_.cox;
5537  WVCoxRds = WVCox * Rds;
5538 
5539  Esat = 2.0 * paramPtr->vsattemp / ueff;
5540  EsatL = Esat * Leff;
5541  T0 = -EsatL /ueff;
5542  dEsatL_dVg = T0 * dueff_dVg;
5543  dEsatL_dVd = T0 * dueff_dVd;
5544  dEsatL_dVb = T0 * dueff_dVb;
5545 
5546  // Sqrt()
5547  a1 = paramPtr->a1;
5548  if (a1 == 0.0)
5549  {
5550  Lambda = paramPtr->a2;
5551  dLambda_dVg = 0.0;
5552  }
5553  else if (a1 > 0.0) // Added to avoid the discontinuity problem
5554  // caused by a1 and a2 (Lambda)
5555  {
5556  T0 = 1.0 - paramPtr->a2;
5557  T1 = T0 - paramPtr->a1 * Vgsteff - 0.0001;
5558  T2 = sqrt(T1 * T1 + 0.0004 * T0);
5559  Lambda = paramPtr->a2 + T0 - 0.5 * (T1 + T2);
5560  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5561  }
5562  else
5563  {
5564  T1 = paramPtr->a2 + paramPtr->a1 * Vgsteff - 0.0001;
5565  T2 = sqrt(T1 * T1 + 0.0004 * paramPtr->a2);
5566  Lambda = 0.5 * (T1 + T2);
5567  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5568  }
5569 
5570  Vgst2Vtm = Vgsteff + 2.0 * Vtm;
5571  if (Rds > 0)
5572  {
5573  tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff;
5574  tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff;
5575  }
5576  else
5577  {
5578  tmp2 = dWeff_dVg / Weff;
5579  tmp3 = dWeff_dVb / Weff;
5580  }
5581 
5582  if ((Rds == 0.0) && (Lambda == 1.0))
5583  {
5584  T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm);
5585  tmp1 = 0.0;
5586  T1 = T0 * T0;
5587  T2 = Vgst2Vtm * T0;
5588  T3 = EsatL * Vgst2Vtm;
5589  Vdsat = T3 * T0;
5590 
5591  dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1;
5592  dT0_dVd = -(Abulk * dEsatL_dVd) * T1;
5593  dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1;
5594 
5595  dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0;
5596  dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd;
5597  dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb;
5598  }
5599  else
5600  {
5601  tmp1 = dLambda_dVg / (Lambda * Lambda);
5602  T9 = Abulk * WVCoxRds;
5603  T8 = Abulk * T9;
5604  T7 = Vgst2Vtm * T9;
5605  T6 = Vgst2Vtm * WVCoxRds;
5606  T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda);
5607  dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1
5608  + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg);
5609 
5610  dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3)
5611  + (1.0 / Lambda - 1.0) * dAbulk_dVb);
5612  dT0_dVd = 0.0;
5613  T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7;
5614 
5615  dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1
5616  + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9
5617  + T7 * tmp2 + T6 * dAbulk_dVg);
5618 
5619  dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb
5620  + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3);
5621 
5622  dT1_dVd = Abulk * dEsatL_dVd;
5623 
5624  T2 = Vgst2Vtm * (EsatL + 2.0 * T6);
5625  dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg
5626  + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2);
5627 
5628  dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3);
5629  dT2_dVd = Vgst2Vtm * dEsatL_dVd;
5630 
5631  T3 = sqrt(T1 * T1 - 2.0 * T0 * T2);
5632  Vdsat = (T1 - T3) / T0;
5633 
5634  dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3;
5635  dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3;
5636  dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3;
5637 
5638  dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2
5639  - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0;
5640 
5641  dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2
5642  - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0;
5643 
5644  dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0;
5645  }
5646  vdsat = Vdsat;
5647 
5648  // Effective Vds (Vdseff) Calculation
5649  T1 = Vdsat - Vds - paramPtr->delta;
5650  dT1_dVg = dVdsat_dVg;
5651  dT1_dVd = dVdsat_dVd - 1.0;
5652  dT1_dVb = dVdsat_dVb;
5653 
5654  T2 = sqrt(T1 * T1 + 4.0 * paramPtr->delta * Vdsat);
5655  T0 = T1 / T2;
5656  T3 = 2.0 * paramPtr->delta / T2;
5657  dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg;
5658  dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd;
5659  dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb;
5660 
5661  Vdseff = Vdsat - 0.5 * (T1 + T2);
5662  dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg);
5663  dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd);
5664  dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb);
5665 
5666  // Added to eliminate non-zero Vdseff at Vds=0.0
5667  if (Vds == 0.0)
5668  {
5669  Vdseff = 0.0;
5670  dVdseff_dVg = 0.0;
5671  dVdseff_dVb = 0.0;
5672  }
5673 
5674  // Calculate VAsat
5675  tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm;
5676  T9 = WVCoxRds * Vgsteff;
5677  T8 = T9 / Vgst2Vtm;
5678  T0 = EsatL + Vdsat + 2.0 * T9 * tmp4;
5679 
5680  T7 = 2.0 * WVCoxRds * tmp4;
5681  dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff)
5682  - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm
5683  + Vdsat * dAbulk_dVg);
5684 
5685  dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff
5686  - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
5687  dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd;
5688 
5689  T9 = WVCoxRds * Abulk;
5690  T1 = 2.0 / Lambda - 1.0 + T9;
5691  dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg);
5692  dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3;
5693 
5694  Vasat = T0 / T1;
5695  dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1;
5696  dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1;
5697  dVasat_dVd = dT0_dVd / T1;
5698 
5699  if (Vdseff > Vds) Vdseff = Vds;
5700 
5701  diffVds = Vds - Vdseff;
5702 
5703  // Calculate VACLM
5704  if ((paramPtr->pclm > 0.0) && (diffVds > 1.0e-10))
5705  {
5706  T0 = 1.0 / (paramPtr->pclm * Abulk * paramPtr->litl);
5707  dT0_dVb = -T0 / Abulk * dAbulk_dVb;
5708  dT0_dVg = -T0 / Abulk * dAbulk_dVg;
5709 
5710  T2 = Vgsteff / EsatL;
5711  T1 = Leff * (Abulk + T2);
5712  dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg);
5713  dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL);
5714  dT1_dVd = -T2 * dEsatL_dVd / Esat;
5715 
5716  T9 = T0 * T1;
5717  VACLM = T9 * diffVds;
5718  dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg
5719  + T1 * diffVds * dT0_dVg;
5720 
5721  dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds
5722  - T9 * dVdseff_dVb;
5723 
5724  dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd);
5725  }
5726  else
5727  {
5728  VACLM = CONSTMAX_EXP;
5729  dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0;
5730  }
5731 
5732  // Calculate VADIBL
5733  if (paramPtr->thetaRout > 0.0)
5734  {
5735  T8 = Abulk * Vdsat;
5736  T0 = Vgst2Vtm * T8;
5737  dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8
5738  + Vgst2Vtm * Vdsat * dAbulk_dVg;
5739 
5740  dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
5741  dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd;
5742 
5743  T1 = Vgst2Vtm + T8;
5744  dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg;
5745  dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat;
5746  dT1_dVd = Abulk * dVdsat_dVd;
5747 
5748  T9 = T1 * T1;
5749  T2 = paramPtr->thetaRout;
5750 
5751  VADIBL = (Vgst2Vtm - T0 / T1) / T2;
5752  dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2;
5753  dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2;
5754  dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2;
5755 
5756  T7 = paramPtr->pdiblb * Vbseff;
5757  if (T7 >= -0.9)
5758  {
5759  T3 = 1.0 / (1.0 + T7);
5760  VADIBL *= T3;
5761  dVADIBL_dVg *= T3;
5762  dVADIBL_dVb = (dVADIBL_dVb - VADIBL * paramPtr->pdiblb) * T3;
5763  dVADIBL_dVd *= T3;
5764  }
5765  else // Added to avoid the discontinuity problem caused by pdiblcb
5766  {
5767  T4 = 1.0 / (0.8 + T7);
5768  T3 = (17.0 + 20.0 * T7) * T4;
5769  dVADIBL_dVg *= T3;
5770  dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * paramPtr->pdiblb * T4 * T4;
5771 
5772  dVADIBL_dVd *= T3;
5773  VADIBL *= T3;
5774  }
5775  }
5776  else
5777  {
5778  VADIBL = CONSTMAX_EXP;
5779  dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0;
5780  }
5781 
5782  // Calculate VA
5783  T8 = paramPtr->pvag / EsatL;
5784  T9 = T8 * Vgsteff;
5785  if (T9 > -0.9)
5786  {
5787  T0 = 1.0 + T9;
5788  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL);
5789  dT0_dVb = -T9 * dEsatL_dVb / EsatL;
5790  dT0_dVd = -T9 * dEsatL_dVd / EsatL;
5791  }
5792  else /* Added to avoid the discontinuity problems caused by pvag */
5793  {
5794  T1 = 1.0 / (17.0 + 20.0 * T9);
5795  T0 = (0.8 + T9) * T1;
5796  T1 *= T1;
5797  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1;
5798 
5799  T9 *= T1 / EsatL;
5800  dT0_dVb = -T9 * dEsatL_dVb;
5801  dT0_dVd = -T9 * dEsatL_dVd;
5802  }
5803 
5804  tmp1 = VACLM * VACLM;
5805  tmp2 = VADIBL * VADIBL;
5806  tmp3 = VACLM + VADIBL;
5807 
5808  T1 = VACLM * VADIBL / tmp3;
5809  tmp3 *= tmp3;
5810  dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3;
5811  dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3;
5812  dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3;
5813 
5814  Va = Vasat + T0 * T1;
5815  dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg;
5816  dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd;
5817  dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb;
5818 
5819  // Calculate VASCBE
5820  if (paramPtr->pscbe2 > 0.0)
5821  {
5822  if (diffVds > paramPtr->pscbe1 * paramPtr->litl / CONSTEXP_THRESHOLD)
5823  {
5824  T0 = paramPtr->pscbe1 * paramPtr->litl / diffVds;
5825  VASCBE = Leff * exp(T0) / paramPtr->pscbe2;
5826  T1 = T0 * VASCBE / diffVds;
5827  dVASCBE_dVg = T1 * dVdseff_dVg;
5828  dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd);
5829  dVASCBE_dVb = T1 * dVdseff_dVb;
5830  }
5831  else
5832  {
5833  VASCBE = CONSTMAX_EXP * Leff/paramPtr->pscbe2;
5834  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
5835  }
5836  }
5837  else
5838  {
5839  VASCBE = CONSTMAX_EXP;
5840  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
5841  }
5842 
5843  // Calculate Ids
5844  CoxWovL = model_.cox * Weff / Leff;
5845  beta = ueff * CoxWovL;
5846  dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff;
5847  dbeta_dVd = CoxWovL * dueff_dVd;
5848  dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff;
5849 
5850  T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm;
5851  dT0_dVg = -0.5 * (Abulk * dVdseff_dVg
5852  - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm;
5853  dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm;
5854  dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm;
5855 
5856  fgche1 = Vgsteff * T0;
5857  dfgche1_dVg = Vgsteff * dT0_dVg + T0;
5858  dfgche1_dVd = Vgsteff * dT0_dVd;
5859  dfgche1_dVb = Vgsteff * dT0_dVb;
5860 
5861  T9 = Vdseff / EsatL;
5862  fgche2 = 1.0 + T9;
5863  dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL;
5864  dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL;
5865  dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL;
5866 
5867  gche = beta * fgche1 / fgche2;
5868  dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg
5869  - gche * dfgche2_dVg) / fgche2;
5870 
5871  dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd
5872  - gche * dfgche2_dVd) / fgche2;
5873 
5874  dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb
5875  - gche * dfgche2_dVb) / fgche2;
5876 
5877  T0 = 1.0 + gche * Rds;
5878  T9 = Vdseff / T0;
5879  Idl = gche * T9;
5880 
5881  dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0
5882  - Idl * gche / T0 * dRds_dVg ;
5883 
5884  dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0;
5885  dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb
5886  - Idl * dRds_dVb * gche) / T0;
5887 
5888  T9 = diffVds / Va;
5889  T0 = 1.0 + T9;
5890  Idsa = Idl * T0;
5891  dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va;
5892  dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd
5893  - T9 * dVa_dVd) / Va;
5894 
5895  dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va;
5896 
5897  T9 = diffVds / VASCBE;
5898  T0 = 1.0 + T9;
5899  Ids = Idsa * T0;
5900 
5901  Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE;
5902  Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd
5903  - T9 * dVASCBE_dVd) / VASCBE;
5904  Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb
5905  + T9 * dVASCBE_dVb) / VASCBE;
5906 
5907  Gds += Gm * dVgsteff_dVd;
5908  Gmb += Gm * dVgsteff_dVb;
5909  Gm *= dVgsteff_dVg;
5910  Gmb *= dVbseff_dVb;
5911 
5912  // Substrate current begins
5913  tmp = paramPtr->alpha0 + paramPtr->alpha1 * Leff;
5914  if ((tmp <= 0.0) || (paramPtr->beta0 <= 0.0))
5915  {
5916  Isub = Gbd = Gbb = Gbg = 0.0;
5917  }
5918  else
5919  {
5920  T2 = tmp / Leff;
5921  if (diffVds > paramPtr->beta0 / CONSTEXP_THRESHOLD)
5922  {
5923  T0 = -paramPtr->beta0 / diffVds;
5924  T1 = T2 * diffVds * exp(T0);
5925  T3 = T1 / diffVds * (T0 - 1.0);
5926  dT1_dVg = T3 * dVdseff_dVg;
5927  dT1_dVd = T3 * (dVdseff_dVd - 1.0);
5928  dT1_dVb = T3 * dVdseff_dVb;
5929  }
5930  else
5931  {
5932  T3 = T2 * CONSTMIN_EXP;
5933  T1 = T3 * diffVds;
5934  dT1_dVg = -T3 * dVdseff_dVg;
5935  dT1_dVd = T3 * (1.0 - dVdseff_dVd);
5936  dT1_dVb = -T3 * dVdseff_dVb;
5937  }
5938  Isub = T1 * Idsa;
5939  Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg;
5940  Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd;
5941  Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb;
5942 
5943  Gbd += Gbg * dVgsteff_dVd;
5944  Gbb += Gbg * dVgsteff_dVb;
5945  Gbg *= dVgsteff_dVg;
5946  Gbb *= dVbseff_dVb; // bug fixing
5947  }
5948 
5949  // copy over local drain (channel) current vars to instance vars:
5950  cdrain = Ids;
5951  gds = Gds;
5952  gm = Gm;
5953  gmbs = Gmb;
5954 
5955  // copy over local substrate current vars to instance vars:
5956  gbbs = Gbb;
5957  gbgs = Gbg;
5958  gbds = Gbd;
5959 
5960  csub = Isub;
5961 
5962  // thermal noise Qinv calculated from all capMod
5963  // * 0, 1, 2 & 3 stored in iterI->qinv 1/1998
5964  if ((model_.xpart < 0) || (!ChargeComputationNeeded))
5965  {
5966  qgate = qdrn = qsrc = qbulk = 0.0;
5967  cggb = cgsb = cgdb = 0.0;
5968  cdgb = cdsb = cddb = 0.0;
5969  cbgb = cbsb = cbdb = 0.0;
5970  cqdb = cqsb = cqgb = cqbb = 0.0;
5971 
5972  gtau = 0.0;
5973  goto finished;
5974  }
5975  else if (model_.capMod == 0)
5976  {
5977  if (Vbseff < 0.0)
5978  {
5979  Vbseff = Vbs;
5980  dVbseff_dVb = 1.0;
5981  }
5982  else
5983  {
5984  Vbseff = paramPtr->phi - Phis;
5985  dVbseff_dVb = -dPhis_dVb;
5986  }
5987 
5988  Vfb = paramPtr->vfbcv;
5989  Vth = Vfb + paramPtr->phi + paramPtr->k1ox * sqrtPhis;
5990  Vgst = Vgs_eff - Vth;
5991  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb;
5992  dVgst_dVb = -dVth_dVb;
5994 
5996  Arg1 = Vgs_eff - Vbseff - Vfb;
5997 
5998  if (Arg1 <= 0.0)
5999  {
6000  qgate = CoxWL * Arg1;
6001  qbulk = -qgate;
6002  qdrn = 0.0;
6003 
6004  cggb = CoxWL * dVgs_eff_dVg;
6005  cgdb = 0.0;
6006  cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg);
6007 
6008  cdgb = 0.0;
6009  cddb = 0.0;
6010  cdsb = 0.0;
6011 
6012  cbgb = -CoxWL * dVgs_eff_dVg;
6013  cbdb = 0.0;
6014  cbsb = -cgsb;
6015  qinv = 0.0;
6016  }
6017  else if (Vgst <= 0.0)
6018  {
6019  T1 = 0.5 * paramPtr->k1ox;
6020  T2 = sqrt(T1 * T1 + Arg1);
6021  qgate = CoxWL * paramPtr->k1ox * (T2 - T1);
6022  qbulk = -qgate;
6023  qdrn = 0.0;
6024 
6025  T0 = CoxWL * T1 / T2;
6026  cggb = T0 * dVgs_eff_dVg;
6027  cgdb = 0.0;
6028  cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg);
6029 
6030  cdgb = 0.0;
6031  cddb = 0.0;
6032  cdsb = 0.0;
6033 
6034  cbgb = -cggb;
6035  cbdb = 0.0;
6036  cbsb = -cgsb;
6037  qinv = 0.0;
6038  }
6039  else
6040  {
6041  One_Third_CoxWL = CoxWL / 3.0;
6042  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6043 
6044  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6045  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6046 
6047  Vdsat = Vgst / AbulkCV;
6048  dVdsat_dVg = dVgs_eff_dVg / AbulkCV;
6049  dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV;
6050 
6051  if (model_.xpart > 0.5)
6052  { // 0/100 Charge partition model
6053  if (Vdsat <= Vds)
6054  { // saturation region
6055  T1 = Vdsat / 3.0;
6056  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6057 
6058  T2 = -Two_Third_CoxWL * Vgst;
6059  qbulk = -(qgate + T2);
6060  qdrn = 0.0;
6061 
6062  cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg)* dVgs_eff_dVg;
6063  T2 = -One_Third_CoxWL * dVdsat_dVb;
6064 
6065  cgsb = -(cggb + T2);
6066  cgdb = 0.0;
6067 
6068  cdgb = 0.0;
6069  cddb = 0.0;
6070  cdsb = 0.0;
6071 
6072  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6073  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6074 
6075  cbsb = -(cbgb + T3);
6076  cbdb = 0.0;
6077  qinv = -(qgate + qbulk);
6078  }
6079  else
6080  { // linear region
6081  Alphaz = Vgst / Vdsat;
6082  T1 = 2.0 * Vdsat - Vds;
6083  T2 = Vds / (3.0 * T1);
6084  T3 = T2 * Vds;
6085  T9 = 0.25 * CoxWL;
6086  T4 = T9 * Alphaz;
6087  T7 = 2.0 * Vds - T1 - 3.0 * T3;
6088  T8 = T3 - T1 - 2.0 * Vds;
6089  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6090 
6091  T10 = T4 * T8;
6092  qdrn = T4 * T7;
6093  qbulk = -(qgate + qdrn + T10);
6094 
6095  T5 = T3 / T1;
6096  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6097 
6098  T11 = -CoxWL * T5 * dVdsat_dVb;
6099  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6100  cgsb = -(cggb + T11 + cgdb);
6101 
6102  T6 = 1.0 / Vdsat;
6103  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6104  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6105 
6106  T7 = T9 * T7;
6107  T8 = T9 * T8;
6108  T9 = 2.0 * T4 * (1.0 - 3.0 * T5);
6109  cdgb = (T7 * dAlphaz_dVg - T9* dVdsat_dVg) * dVgs_eff_dVg;
6110 
6111  T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb;
6112  cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5);
6113  cdsb = -(cdgb + T12 + cddb);
6114 
6115  T9 = 2.0 * T4 * (1.0 + T5);
6116  T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg;
6117  T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb;
6118  T12 = T4 * (2.0 * T2 + T5 - 1.0);
6119  T0 = -(T10 + T11 + T12);
6120 
6121 
6122  cbgb = -(cggb + cdgb + T10);
6123  cbdb = -(cgdb + cddb + T12);
6124  cbsb = -(cgsb + cdsb + T0);
6125  qinv = -(qgate + qbulk);
6126  }
6127  }
6128  else if (model_.xpart < 0.5)
6129  { // 40/60 Charge partition model
6130  if (Vds >= Vdsat)
6131  { // saturation region
6132  T1 = Vdsat / 3.0;
6133  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6134 
6135  T2 = -Two_Third_CoxWL * Vgst;
6136  qbulk = -(qgate + T2);
6137  qdrn = 0.4 * T2;
6138 
6139  cggb = One_Third_CoxWL* (3.0 - dVdsat_dVg) * dVgs_eff_dVg;
6140 
6141  T2 = -One_Third_CoxWL * dVdsat_dVb;
6142  cgsb = -(cggb + T2);
6143  cgdb = 0.0;
6144 
6145  T3 = 0.4 * Two_Third_CoxWL;
6146  cdgb = -T3 * dVgs_eff_dVg;
6147  cddb = 0.0;
6148 
6149  T4 = T3 * dVth_dVb;
6150  cdsb = -(T4 + cdgb);
6151 
6152  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6153  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6154  cbsb = -(cbgb + T3);
6155  cbdb = 0.0;
6156  qinv = -(qgate + qbulk);
6157  }
6158  else
6159  { // linear region
6160  Alphaz = Vgst / Vdsat;
6161  T1 = 2.0 * Vdsat - Vds;
6162  T2 = Vds / (3.0 * T1);
6163  T3 = T2 * Vds;
6164  T9 = 0.25 * CoxWL;
6165  T4 = T9 * Alphaz;
6166  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6167 
6168  T5 = T3 / T1;
6169  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6170  tmp = -CoxWL * T5 * dVdsat_dVb;
6171  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6172  cgsb = -(cggb + cgdb + tmp);
6173 
6174  T6 = 1.0 / Vdsat;
6175  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6176  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6177 
6178  T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + 1.2 * Vds * Vds;
6179  T8 = T2 / T1;
6180  T7 = Vds - T1 - T8 * T6;
6181  qdrn = T4 * T7;
6182  T7 *= T9;
6183  tmp = T8 / T1;
6184  tmp1 = T4*(2.0 - 4.0 * tmp * T6 + T8 *(16.0 * Vdsat - 6.0 *Vds));
6185 
6186  cdgb = (T7 *dAlphaz_dVg - tmp1 *dVdsat_dVg) *dVgs_eff_dVg;
6187 
6188  T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb;
6189  cddb = T4 * (2.0 - (1.0 / (3.0 * T1
6190  * T1) + 2.0 * tmp) * T6 + T8
6191  * (6.0 * Vdsat - 2.4 * Vds));
6192 
6193  cdsb = -(cdgb + T10 + cddb);
6194 
6195  T7 = 2.0 * (T1 + T3);
6196  qbulk = -(qgate - T4 * T7);
6197  T7 *= T9;
6198  T0 = 4.0 * T4 * (1.0 - T5);
6199  T12 = (-T7 * dAlphaz_dVg - cdgb
6200  - T0 * dVdsat_dVg) * dVgs_eff_dVg;
6201  T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb;
6202  T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5)
6203  - cddb;
6204 
6205  tmp = -(T10 + T11 + T12);
6206 
6207  cbgb = -(cggb + cdgb + T12);
6208  cbdb = -(cgdb + cddb + T11);
6209  cbsb = -(cgsb + cdsb + tmp);
6210  qinv = -(qgate + qbulk);
6211  }
6212  }
6213  else
6214  { // 50/50 partitioning
6215  if (Vds >= Vdsat)
6216  { // saturation region
6217  T1 = Vdsat / 3.0;
6218  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6219  T2 = -Two_Third_CoxWL * Vgst;
6220  qbulk = -(qgate + T2);
6221  qdrn = 0.5 * T2;
6222 
6223  cggb = One_Third_CoxWL * (3.0 -dVdsat_dVg) * dVgs_eff_dVg;
6224  T2 = -One_Third_CoxWL * dVdsat_dVb;
6225  cgsb = -(cggb + T2);
6226  cgdb = 0.0;
6227 
6228  cdgb = -One_Third_CoxWL * dVgs_eff_dVg;
6229  cddb = 0.0;
6230  T4 = One_Third_CoxWL * dVth_dVb;
6231  cdsb = -(T4 + cdgb);
6232 
6233  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6234  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6235  cbsb = -(cbgb + T3);
6236  cbdb = 0.0;
6237  qinv = -(qgate + qbulk);
6238  }
6239  else
6240  { // linear region
6241  Alphaz = Vgst / Vdsat;
6242  T1 = 2.0 * Vdsat - Vds;
6243  T2 = Vds / (3.0 * T1);
6244  T3 = T2 * Vds;
6245  T9 = 0.25 * CoxWL;
6246  T4 = T9 * Alphaz;
6247  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3))
6248  ;
6249 
6250  T5 = T3 / T1;
6251  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6252 
6253  tmp = -CoxWL * T5 * dVdsat_dVb;
6254  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6255  cgsb = -(cggb + cgdb + tmp);
6256 
6257  T6 = 1.0 / Vdsat;
6258  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6259  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6260 
6261  T7 = T1 + T3;
6262  qdrn = -T4 * T7;
6263  qbulk = - (qgate + qdrn + qdrn);
6264  T7 *= T9;
6265  T0 = T4 * (2.0 * T5 - 2.0);
6266 
6267  cdgb = (T0 * dVdsat_dVg - T7 *dAlphaz_dVg) *dVgs_eff_dVg;
6268  T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb;
6269  cddb = T4 * (1.0 - 2.0 * T2 - T5);
6270  cdsb = -(cdgb + T12 + cddb);
6271 
6272  cbgb = -(cggb + 2.0 * cdgb);
6273  cbdb = -(cgdb + 2.0 * cddb);
6274  cbsb = -(cgsb + 2.0 * cdsb);
6275  qinv = -(qgate + qbulk);
6276  }
6277  }
6278  }
6279  }
6280  else
6281  {
6282  if (Vbseff < 0.0)
6283  {
6284  VbseffCV = Vbseff;
6285  dVbseffCV_dVb = 1.0;
6286  }
6287  else
6288  {
6289  VbseffCV = paramPtr->phi - Phis;
6290  dVbseffCV_dVb = -dPhis_dVb;
6291  }
6292 
6294 
6295  // Seperate VgsteffCV with noff and voffcv
6296  noff = n * paramPtr->noff;
6297  dnoff_dVd = paramPtr->noff * dn_dVd;
6298  dnoff_dVb = paramPtr->noff * dn_dVb;
6299  T0 = Vtm * noff;
6300  voffcv = paramPtr->voffcv;
6301  VgstNVt = (Vgst - voffcv) / T0;
6302 
6303  if (VgstNVt > CONSTEXP_THRESHOLD)
6304  {
6305  Vgsteff = Vgst - voffcv;
6306  dVgsteff_dVg = dVgs_eff_dVg;
6307  dVgsteff_dVd = -dVth_dVd;
6308  dVgsteff_dVb = -dVth_dVb;
6309  }
6310  else if (VgstNVt < -CONSTEXP_THRESHOLD)
6311  {
6312  Vgsteff = T0 * log(1.0 + CONSTMIN_EXP);
6313  dVgsteff_dVg = 0.0;
6314  dVgsteff_dVd = Vgsteff / noff;
6315  dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb;
6316  dVgsteff_dVd *= dnoff_dVd;
6317  }
6318  else
6319  {
6320  ExpVgst = exp(VgstNVt);
6321  Vgsteff = T0 * log(1.0 + ExpVgst);
6322  dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst);
6323  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv)
6324  / noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd;
6325  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv)
6326  / noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb;
6327  dVgsteff_dVg *= dVgs_eff_dVg;
6328  } // End of VgsteffCV
6329 
6330  if (model_.capMod == 1)
6331  {
6332  Vfb = paramPtr->vfbzb;
6333  Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff;
6334 
6335  if (Arg1 <= 0.0)
6336  {
6337  qgate = CoxWL * Arg1;
6338  Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg);
6339  Cgd = -CoxWL * dVgsteff_dVd;
6340  Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb);
6341  }
6342  else
6343  {
6344  T0 = 0.5 * paramPtr->k1ox;
6345  T1 = sqrt(T0 * T0 + Arg1);
6346  T2 = CoxWL * T0 / T1;
6347 
6348  qgate = CoxWL * paramPtr->k1ox * (T1 - T0);
6349 
6350  Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg);
6351  Cgd = -T2 * dVgsteff_dVd;
6352  Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb);
6353  }
6354  qbulk = -qgate;
6355  Cbg = -Cgg;
6356  Cbd = -Cgd;
6357  Cbb = -Cgb;
6358 
6359  One_Third_CoxWL = CoxWL / 3.0;
6360  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6361  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6362  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6363  VdsatCV = Vgsteff / AbulkCV;
6364 
6365  if (VdsatCV < Vds)
6366  {
6367  dVdsatCV_dVg = 1.0 / AbulkCV;
6368  dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV;
6369  T0 = Vgsteff - VdsatCV / 3.0;
6370  dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0;
6371  dT0_dVb = -dVdsatCV_dVb / 3.0;
6372  qgate += CoxWL * T0;
6373  Cgg1 = CoxWL * dT0_dVg;
6374  Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb;
6375  Cgd1 = Cgg1 * dVgsteff_dVd;
6376  Cgg1 *= dVgsteff_dVg;
6377  Cgg += Cgg1;
6378  Cgb += Cgb1;
6379  Cgd += Cgd1;
6380 
6381  T0 = VdsatCV - Vgsteff;
6382  dT0_dVg = dVdsatCV_dVg - 1.0;
6383  dT0_dVb = dVdsatCV_dVb;
6384  qbulk += One_Third_CoxWL * T0;
6385  Cbg1 = One_Third_CoxWL * dT0_dVg;
6386  Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb;
6387  Cbd1 = Cbg1 * dVgsteff_dVd;
6388  Cbg1 *= dVgsteff_dVg;
6389  Cbg += Cbg1;
6390  Cbb += Cbb1;
6391  Cbd += Cbd1;
6392 
6393  if (model_.xpart > 0.5) T0 = -Two_Third_CoxWL;
6394  else if (model_.xpart < 0.5) T0 = -0.4 * CoxWL;
6395  else T0 = -One_Third_CoxWL;
6396 
6397  qsrc = T0 * Vgsteff;
6398  Csg = T0 * dVgsteff_dVg;
6399  Csb = T0 * dVgsteff_dVb;
6400  Csd = T0 * dVgsteff_dVd;
6401  Cgb *= dVbseff_dVb;
6402  Cbb *= dVbseff_dVb;
6403  Csb *= dVbseff_dVb;
6404  }
6405  else
6406  {
6407  T0 = AbulkCV * Vds;
6408  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20);
6409  T2 = Vds / T1;
6410  T3 = T0 * T2;
6411  dT3_dVg = -12.0 * T2 * T2 * AbulkCV;
6412  dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5;
6413  dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff;
6414 
6415  qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3);
6416  Cgg1 = CoxWL * (1.0 + dT3_dVg);
6417  Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb;
6418  Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd;
6419  Cgg1 *= dVgsteff_dVg;
6420  Cgg += Cgg1;
6421  Cgb += Cgb1;
6422  Cgd += Cgd1;
6423 
6424  qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3);
6425  Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg);
6426  Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb
6427  + (0.5 * Vds - T3) * dAbulkCV_dVb)
6428  + Cbg1 * dVgsteff_dVb;
6429  Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd
6430  + Cbg1 * dVgsteff_dVd;
6431  Cbg1 *= dVgsteff_dVg;
6432  Cbg += Cbg1;
6433  Cbb += Cbb1;
6434  Cbd += Cbd1;
6435 
6436  if (model_.xpart > 0.5)
6437  { // 0/100 Charge petition model
6438  T1 = T1 + T1;
6439  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6440  Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1 * AbulkCV);
6441  Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb
6442  - 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0)
6443  * dAbulkCV_dVb) + Csg * dVgsteff_dVb;
6444  Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0
6445  / T1 / T1 * (4.0 * Vgsteff - T0))
6446  + Csg * dVgsteff_dVd;
6447  Csg *= dVgsteff_dVg;
6448  }
6449  else if (model_.xpart < 0.5)
6450  { // 40/60 Charge petition model
6451  T1 = T1 / 12.0;
6452  T2 = 0.5 * CoxWL / (T1 * T1);
6453  T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff
6454  * (Vgsteff - 4.0 * T0 / 3.0))
6455  - 2.0 * T0 * T0 * T0 / 15.0;
6456  qsrc = -T2 * T3;
6457  T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6458  + 0.4 * T0 * T0;
6459  Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6460  * Vgsteff - 8.0 * T0 / 3.0)
6461  + 2.0 * T0 * T0 / 3.0);
6462  Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb
6463  + Csg * dVgsteff_dVb;
6464  Csd = (qsrc / T1 + T2 * T4) * AbulkCV
6465  + Csg * dVgsteff_dVd;
6466  Csg *= dVgsteff_dVg;
6467  }
6468  else
6469  { // 50/50 Charge petition model
6470  qsrc = -0.5 * (qgate + qbulk);
6471  Csg = -0.5 * (Cgg1 + Cbg1);
6472  Csb = -0.5 * (Cgb1 + Cbb1);
6473  Csd = -0.5 * (Cgd1 + Cbd1);
6474  }
6475  Cgb *= dVbseff_dVb;
6476  Cbb *= dVbseff_dVb;
6477  Csb *= dVbseff_dVb;
6478  }
6479  qdrn = -(qgate + qbulk + qsrc);
6480  cggb = Cgg;
6481  cgsb = -(Cgg + Cgd + Cgb);
6482  cgdb = Cgd;
6483  cdgb = -(Cgg + Cbg + Csg);
6484  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6485  cddb = -(Cgd + Cbd + Csd);
6486  cbgb = Cbg;
6487  cbsb = -(Cbg + Cbd + Cbb);
6488  cbdb = Cbd;
6489  qinv = -(qgate + qbulk);
6490  }
6491  else if (model_.capMod == 2)
6492  {
6493  Vfb = paramPtr->vfbzb;
6494  V3 = Vfb - Vgs_eff + VbseffCV - CONSTDELTA_3;
6495  if (Vfb <= 0.0)
6496  {
6497  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * Vfb);
6498  T2 = -CONSTDELTA_3 / T0;
6499  }
6500  else
6501  {
6502  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * Vfb);
6503  T2 = CONSTDELTA_3 / T0;
6504  }
6505 
6506  T1 = 0.5 * (1.0 + V3 / T0);
6507  Vfbeff = Vfb - 0.5 * (V3 + T0);
6508  dVfbeff_dVg = T1 * dVgs_eff_dVg;
6509  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
6510  Qac0 = CoxWL * (Vfbeff - Vfb);
6511  dQac0_dVg = CoxWL * dVfbeff_dVg;
6512  dQac0_dVb = CoxWL * dVfbeff_dVb;
6513 
6514  T0 = 0.5 * paramPtr->k1ox;
6515  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
6516  if (paramPtr->k1ox == 0.0)
6517  {
6518  T1 = 0.0;
6519  T2 = 0.0;
6520  }
6521  else if (T3 < 0.0)
6522  {
6523  T1 = T0 + T3 / paramPtr->k1ox;
6524  T2 = CoxWL;
6525  }
6526  else
6527  {
6528  T1 = sqrt(T0 * T0 + T3);
6529  T2 = CoxWL * T0 / T1;
6530  }
6531 
6532  Qsub0 = CoxWL * paramPtr->k1ox * (T1 - T0);
6533 
6534  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg);
6535  dQsub0_dVd = -T2 * dVgsteff_dVd;
6536  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb);
6537 
6538  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6539  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6540  VdsatCV = Vgsteff / AbulkCV;
6541 
6542  V4 = VdsatCV - Vds - CONSTDELTA_4;
6543  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
6544  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
6545  T1 = 0.5 * (1.0 + V4 / T0);
6546  T2 = CONSTDELTA_4 / T0;
6547  T3 = (1.0 - T1 - T2) / AbulkCV;
6548  dVdseffCV_dVg = T3;
6549  dVdseffCV_dVd = T1;
6550  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
6551  // Added to eliminate non-zero VdseffCV at Vds=0.0
6552  if (Vds == 0.0)
6553  {
6554  VdseffCV = 0.0;
6555  dVdseffCV_dVg = 0.0;
6556  dVdseffCV_dVb = 0.0;
6557  }
6558 
6559  T0 = AbulkCV * VdseffCV;
6560  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20);
6561  T2 = VdseffCV / T1;
6562  T3 = T0 * T2;
6563 
6564  T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV);
6565  T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5);
6566  T6 = 12.0 * T2 * T2 * Vgsteff;
6567 
6568  qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3);
6569  qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3);
6570  Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6571  Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd;
6572  Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6573  + Cgg1 * dVgsteff_dVb;
6574  Cgg1 *= dVgsteff_dVg;
6575 
6576  T7 = 1.0 - AbulkCV;
6577  qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3);
6578  T4 = -T7 * (T4 - 1.0);
6579  T5 = -T7 * T5;
6580  T6 = -(T7 * T6 + (0.5 * VdseffCV - T3));
6581  Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6582  Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd;
6583  Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6584  + Cbg1 * dVgsteff_dVb;
6585  Cbg1 *= dVgsteff_dVg;
6586 
6587  if (model_.xpart > 0.5)
6588  { // 0/100 Charge petition model
6589  T1 = T1 + T1;
6590  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6591  T7 = (4.0 * Vgsteff - T0) / (T1 * T1);
6592  T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1));
6593  T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7);
6594  T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7);
6595  Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6596  Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6597  Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6598  + Csg * dVgsteff_dVb;
6599  Csg *= dVgsteff_dVg;
6600  }
6601  else if (model_.xpart < 0.5)
6602  { // 40/60 Charge petition model
6603  T1 = T1 / 12.0;
6604  T2 = 0.5 * CoxWL / (T1 * T1);
6605  T3 = Vgsteff *(2.0 * T0 *T0/3.0 +Vgsteff *(Vgsteff - 4.0 *T0/ 3.0))
6606  - 2.0 * T0 * T0 * T0 / 15.0;
6607  qsrc = -T2 * T3;
6608  T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6609  + 0.4 * T0 * T0;
6610  T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6611  * Vgsteff - 8.0 * T0 / 3.0)
6612  + 2.0 * T0 * T0 / 3.0);
6613  T5 = (qsrc / T1 + T2 * T7) * AbulkCV;
6614  T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV);
6615  Csg = (T4 + T5 * dVdseffCV_dVg);
6616  Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6617  Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6618  + Csg * dVgsteff_dVb;
6619  Csg *= dVgsteff_dVg;
6620  }
6621  else
6622  { // 50/50 Charge petition model
6623  qsrc = -0.5 * (qgate + qbulk);
6624  Csg = -0.5 * (Cgg1 + Cbg1);
6625  Csb = -0.5 * (Cgb1 + Cbb1);
6626  Csd = -0.5 * (Cgd1 + Cbd1);
6627  }
6628 
6629  qgate += Qac0 + Qsub0;
6630  qbulk -= (Qac0 + Qsub0);
6631  qdrn = -(qgate + qbulk + qsrc);
6632 
6633  Cgg = dQac0_dVg + dQsub0_dVg + Cgg1;
6634  Cgd = dQsub0_dVd + Cgd1;
6635  Cgb = dQac0_dVb + dQsub0_dVb + Cgb1;
6636 
6637  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
6638  Cbd = Cbd1 - dQsub0_dVd;
6639  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
6640 
6641  Cgb *= dVbseff_dVb;
6642  Cbb *= dVbseff_dVb;
6643  Csb *= dVbseff_dVb;
6644 
6645  cggb = Cgg;
6646  cgsb = -(Cgg + Cgd + Cgb);
6647  cgdb = Cgd;
6648  cdgb = -(Cgg + Cbg + Csg);
6649  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6650  cddb = -(Cgd + Cbd + Csd);
6651  cbgb = Cbg;
6652  cbsb = -(Cbg + Cbd + Cbb);
6653  cbdb = Cbd;
6654  qinv = qinoi;
6655  }
6656 
6657  // New Charge-Thickness capMod (CTM) begins
6658  else if (model_.capMod == 3)
6659  {
6660  V3 = paramPtr->vfbzb - Vgs_eff + VbseffCV - CONSTDELTA_3;
6661  if (paramPtr->vfbzb <= 0.0)
6662  {
6663  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
6664  T2 = -CONSTDELTA_3 / T0;
6665  }
6666  else
6667  {
6668  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
6669  T2 = CONSTDELTA_3 / T0;
6670  }
6671 
6672  T1 = 0.5 * (1.0 + V3 / T0);
6673  Vfbeff = paramPtr->vfbzb - 0.5 * (V3 + T0);
6674  dVfbeff_dVg = T1 * dVgs_eff_dVg;
6675  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
6676 
6677  Cox = model_.cox;
6678  Tox = 1.0e8 * model_.tox;
6679  T0 = (Vgs_eff - VbseffCV - paramPtr->vfbzb) / Tox;
6680  dT0_dVg = dVgs_eff_dVg / Tox;
6681  dT0_dVb = -dVbseffCV_dVb / Tox;
6682 
6683  tmp = T0 * paramPtr->acde;
6684  if ((-CONSTEXP_THRESHOLD < tmp) && (tmp < CONSTEXP_THRESHOLD))
6685  {
6686  Tcen = paramPtr->ldeb * exp(tmp);
6687  dTcen_dVg = paramPtr->acde * Tcen;
6688  dTcen_dVb = dTcen_dVg * dT0_dVb;
6689  dTcen_dVg *= dT0_dVg;
6690  }
6691  else if (tmp <= -CONSTEXP_THRESHOLD)
6692  {
6693  Tcen = paramPtr->ldeb * CONSTMIN_EXP;
6694  dTcen_dVg = dTcen_dVb = 0.0;
6695  }
6696  else
6697  {
6698  Tcen = paramPtr->ldeb * CONSTMAX_EXP;
6699  dTcen_dVg = dTcen_dVb = 0.0;
6700  }
6701 
6702  LINK = 1.0e-3 * model_.tox;
6703  V3 = paramPtr->ldeb - Tcen - LINK;
6704  V4 = sqrt(V3 * V3 + 4.0 * LINK * paramPtr->ldeb);
6705  Tcen = paramPtr->ldeb - 0.5 * (V3 + V4);
6706  T1 = 0.5 * (1.0 + V3 / V4);
6707  dTcen_dVg *= T1;
6708  dTcen_dVb *= T1;
6709 
6710  Ccen = CONSTEPSSI / Tcen;
6711  T2 = Cox / (Cox + Ccen);
6712  Coxeff = T2 * Ccen;
6713  T3 = -Ccen / Tcen;
6714  dCoxeff_dVg = T2 * T2 * T3;
6715  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
6716  dCoxeff_dVg *= dTcen_dVg;
6717  CoxWLcen = CoxWL * Coxeff / Cox;
6718 
6719  Qac0 = CoxWLcen * (Vfbeff - paramPtr->vfbzb);
6720  QovCox = Qac0 / Coxeff;
6721  dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg;
6722  dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb;
6723 
6724  T0 = 0.5 * paramPtr->k1ox;
6725  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
6726  if (paramPtr->k1ox == 0.0)
6727  {
6728  T1 = 0.0;
6729  T2 = 0.0;
6730  }
6731  else if (T3 < 0.0)
6732  {
6733  T1 = T0 + T3 / paramPtr->k1ox;
6734  T2 = CoxWLcen;
6735  }
6736  else
6737  {
6738  T1 = sqrt(T0 * T0 + T3);
6739  T2 = CoxWLcen * T0 / T1;
6740  }
6741 
6742  Qsub0 = CoxWLcen * paramPtr->k1ox * (T1 - T0);
6743  QovCox = Qsub0 / Coxeff;
6744  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg)
6745  + QovCox * dCoxeff_dVg;
6746  dQsub0_dVd = -T2 * dVgsteff_dVd;
6747  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb)
6748  + QovCox * dCoxeff_dVb;
6749 
6750  // Gate-bias dependent delta Phis begins */
6751  if (paramPtr->k1ox <= 0.0)
6752  {
6753  Denomi = 0.25 * paramPtr->moin * Vtm;
6754  T0 = 0.5 * paramPtr->sqrtPhi;
6755  }
6756  else
6757  {
6758  Denomi = paramPtr->moin * Vtm * paramPtr->k1ox * paramPtr->k1ox;
6759  T0 = paramPtr->k1ox * paramPtr->sqrtPhi;
6760  }
6761  T1 = 2.0 * T0 + Vgsteff;
6762 
6763  DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi);
6764  dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff);
6765  dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd;
6766  dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb;
6767  // End of delta Phis
6768 
6769  T3 = 4.0 * (Vth - paramPtr->vfbzb - paramPtr->phi);
6770  Tox += Tox;
6771  if (T3 >= 0.0)
6772  { T0 = (Vgsteff + T3) / Tox;
6773  dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox;
6774  dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox;
6775  }
6776  else
6777  { T0 = (Vgsteff + 1.0e-20) / Tox;
6778  dT0_dVd = dVgsteff_dVd / Tox;
6779  dT0_dVb = dVgsteff_dVb / Tox;
6780  }
6781  tmp = exp(0.7 * log(T0));
6782  T1 = 1.0 + tmp;
6783  T2 = 0.7 * tmp / (T0 * Tox);
6784  Tcen = 1.9e-9 / T1;
6785  dTcen_dVg = -1.9e-9 * T2 / T1 /T1;
6786  dTcen_dVd = Tox * dTcen_dVg;
6787  dTcen_dVb = dTcen_dVd * dT0_dVb;
6788  dTcen_dVd *= dT0_dVd;
6789  dTcen_dVg *= dVgsteff_dVg;
6790 
6791  Ccen = CONSTEPSSI / Tcen;
6792  T0 = Cox / (Cox + Ccen);
6793  Coxeff = T0 * Ccen;
6794  T1 = -Ccen / Tcen;
6795  dCoxeff_dVg = T0 * T0 * T1;
6796  dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd;
6797  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
6798  dCoxeff_dVg *= dTcen_dVg;
6799  CoxWLcen = CoxWL * Coxeff / Cox;
6800 
6801  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6802  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6803  VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV;
6804  V4 = VdsatCV - Vds - CONSTDELTA_4;
6805  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
6806  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
6807  T1 = 0.5 * (1.0 + V4 / T0);
6808  T2 = CONSTDELTA_4 / T0;
6809  T3 = (1.0 - T1 - T2) / AbulkCV;
6810  T4 = T3 * ( 1.0 - dDeltaPhi_dVg);
6811  dVdseffCV_dVg = T4;
6812  dVdseffCV_dVd = T1;
6813  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
6814 
6815  // Added to eliminate non-zero VdseffCV at Vds=0.0
6816  if (Vds == 0.0)
6817  { VdseffCV = 0.0;
6818  dVdseffCV_dVg = 0.0;
6819  dVdseffCV_dVb = 0.0;
6820  }
6821 
6822  T0 = AbulkCV * VdseffCV;
6823  T1 = Vgsteff - DeltaPhi;
6824  T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20);
6825  T3 = T0 / T2;
6826  T4 = 1.0 - 12.0 * T3 * T3;
6827  T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5);
6828  T6 = T5 * VdseffCV / AbulkCV;
6829 
6830  qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3));
6831  QovCox = qgate / Coxeff;
6832  Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + T5 * dVdseffCV_dVg);
6833  Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1
6834  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
6835  Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6836  + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6837  Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6838 
6839 
6840  T7 = 1.0 - AbulkCV;
6841  T8 = T2 * T2;
6842  T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV);
6843  T10 = T9 * (1.0 - dDeltaPhi_dVg);
6844  T11 = -T7 * T5 / AbulkCV;
6845  T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2));
6846 
6847  qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2);
6848  QovCox = qbulk / Coxeff;
6849  Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg);
6850  Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1
6851  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
6852  Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb)
6853  + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6854  Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6855 
6856  if (model_.xpart > 0.5)
6857  { // 0/100 partition
6858  qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2);
6859  QovCox = qsrc / Coxeff;
6860  T2 += T2;
6861  T3 = T2 * T2;
6862  T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3);
6863  T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg);
6864  T5 = T7 * AbulkCV;
6865  T6 = T7 * VdseffCV;
6866 
6867  Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg);
6868  Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd
6869  + QovCox * dCoxeff_dVd;
6870  Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6871  + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6872  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6873  }
6874  else if (model_.xpart < 0.5)
6875  { // 40/60 partition
6876  T2 = T2 / 12.0;
6877  T3 = 0.5 * CoxWLcen / (T2 * T2);
6878  T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0
6879  * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0;
6880  qsrc = -T3 * T4;
6881  QovCox = qsrc / Coxeff;
6882  T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0;
6883  T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0
6884  * T0 / 3.0) + 2.0 * T0 * T0 / 3.0);
6885  T6 = AbulkCV * (qsrc / T2 + T3 * T8);
6886  T7 = T6 * VdseffCV / AbulkCV;
6887 
6888  Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg;
6889  Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd
6890  + QovCox * dCoxeff_dVd;
6891  Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb
6892  + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb;
6893  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6894  }
6895  else
6896  { // 50/50 partition
6897  qsrc = -0.5 * qgate;
6898  Csg = -0.5 * Cgg1;
6899  Csd = -0.5 * Cgd1;
6900  Csb = -0.5 * Cgb1;
6901  }
6902 
6903  qgate += Qac0 + Qsub0 - qbulk;
6904  qbulk -= (Qac0 + Qsub0);
6905  qdrn = -(qgate + qbulk + qsrc);
6906 
6907  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
6908  Cbd = Cbd1 - dQsub0_dVd;
6909  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
6910 
6911  Cgg = Cgg1 - Cbg;
6912  Cgd = Cgd1 - Cbd;
6913  Cgb = Cgb1 - Cbb;
6914 
6915  Cgb *= dVbseff_dVb;
6916  Cbb *= dVbseff_dVb;
6917  Csb *= dVbseff_dVb;
6918 
6919  cggb = Cgg;
6920  cgsb = -(Cgg + Cgd + Cgb);
6921  cgdb = Cgd;
6922  cdgb = -(Cgg + Cbg + Csg);
6923  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6924  cddb = -(Cgd + Cbd + Csd);
6925  cbgb = Cbg;
6926  cbsb = -(Cbg + Cbd + Cbb);
6927  cbdb = Cbd;
6928  qinv = -qinoi;
6929  } // End of CTM
6930  }
6931 
6932  finished:
6933  // Returning Values to Calling Routine
6934  // COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
6935 
6936  // copy local "cdrain" variable over to instance variable cd.
6937  cd = cdrain;
6938 
6939  // charge storage elements:
6940  // bulk-drain and bulk-source depletion capacitances
6941  // czbd : zero bias drain junction capacitance
6942  // czbs : zero bias source junction capacitance
6943  // czbdsw: zero bias drain junction sidewall capacitance
6944  // along field oxide
6945  // czbssw: zero bias source junction sidewall capacitance
6946  // along field oxide
6947  // czbdswg: zero bias drain junction sidewall capacitance
6948  // along gate side
6949  // czbsswg: zero bias source junction sidewall capacitance
6950  // along gate side
6952  {
6953  czbd = unitAreaJctCapTemp * drainArea;
6954  czbs = unitAreaJctCapTemp * sourceArea;
6955  if (drainPerimeter < paramPtr->weff)
6956  {
6958  czbdsw = 0.0;
6959  }
6960  else
6961  {
6963  * (drainPerimeter - paramPtr->weff);
6964 
6966  }
6967  if (sourcePerimeter < paramPtr->weff)
6968  {
6969  czbssw = 0.0;
6971  }
6972  else
6973  {
6975  * (sourcePerimeter - paramPtr->weff);
6977  }
6978 
6982 
6983  // Source Bulk Junction
6984  if (vbs == 0.0)
6985  {
6986  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
6987  qbs = 0.0;
6988  capbs = czbs + czbssw + czbsswg;
6989  }
6990  else if (vbs < 0.0)
6991  {
6992  if (czbs > 0.0)
6993  {
6994  arg = 1.0 - vbs / PhiBTemp;
6995 
6996  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
6997  else sarg = exp(-MJ * log(arg));
6998 
6999  //*(ckt->CKTstate0 + iterI->qbs) =
7000  qbs = PhiBTemp * czbs * (1.0 - arg * sarg) / (1.0 - MJ);
7001 
7002  capbs = czbs * sarg;
7003  }
7004  else
7005  {
7006  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
7007  qbs = 0.0;
7008  capbs = 0.0;
7009  }
7010 
7011  if (czbssw > 0.0)
7012  {
7013  arg = 1.0 - vbs / PhiBSWTemp;
7014  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7015  else sarg = exp(-MJSW * log(arg));
7016 
7017  //*(ckt->CKTstate0 + iterI->qbs) +=
7018  qbs += PhiBSWTemp * czbssw * (1.0 - arg * sarg) / (1.0 - MJSW);
7019 
7020  capbs += czbssw * sarg;
7021  }
7022 
7023  if (czbsswg > 0.0)
7024  {
7025  arg = 1.0 - vbs / PhiBSWGTemp;
7026  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7027  else sarg = exp(-MJSWG * log(arg));
7028 
7029  //*(ckt->CKTstate0 + iterI->qbs) +=
7030  qbs += PhiBSWGTemp * czbsswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7031 
7032  capbs += czbsswg * sarg;
7033  }
7034 
7035  }
7036  else
7037  {
7038  T0 = czbs + czbssw + czbsswg;
7039  T1 = vbs * (czbs * MJ / PhiBTemp + czbssw * MJSW
7040  / PhiBSWTemp + czbsswg * MJSWG / PhiBSWGTemp);
7041 
7042  //*(ckt->CKTstate0 + iterI->
7043  qbs = vbs * (T0 + 0.5 * T1);
7044  capbs = T0 + T1;
7045  }
7046 
7047  // Drain Bulk Junction
7048  if (vbd == 0.0)
7049  {
7050  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7051  qbd = 0.0;
7052  capbd = czbd + czbdsw + czbdswg;
7053  }
7054  else if (vbd < 0.0)
7055  {
7056  if (czbd > 0.0)
7057  {
7058  arg = 1.0 - vbd / PhiBTemp;
7059  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
7060  else sarg = exp(-MJ * log(arg));
7061 
7062  //*(ckt->CKTstate0 + iterI->qbd) =
7063  qbd = PhiBTemp * czbd * (1.0 - arg * sarg) / (1.0 - MJ);
7064  capbd = czbd * sarg;
7065  }
7066  else
7067  {
7068  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7069  qbd = 0.0;
7070  capbd = 0.0;
7071  }
7072 
7073  if (czbdsw > 0.0)
7074  {
7075  arg = 1.0 - vbd / PhiBSWTemp;
7076  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7077  else sarg = exp(-MJSW * log(arg));
7078 
7079  //*(ckt->CKTstate0 + iterI->qbd) +=
7080  qbd += PhiBSWTemp * czbdsw * (1.0 - arg * sarg) / (1.0 - MJSW);
7081  capbd += czbdsw * sarg;
7082  }
7083 
7084  if (czbdswg > 0.0)
7085  {
7086  arg = 1.0 - vbd / PhiBSWGTemp;
7087  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7088  else sarg = exp(-MJSWG * log(arg));
7089 
7090  //*(ckt->CKTstate0 + iterI->qbd) +=
7091  qbd += PhiBSWGTemp * czbdswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7092  capbd += czbdswg * sarg;
7093  }
7094  }
7095  else
7096  {
7097  T0 = czbd + czbdsw + czbdswg;
7098  T1 = vbd * (czbd * MJ / PhiBTemp + czbdsw * MJSW
7099  / PhiBSWTemp + czbdswg * MJSWG / PhiBSWGTemp);
7100 
7101  //*(ckt->CKTstate0 + iterI->qbd) = vbd * (T0 + 0.5 * T1);
7102  qbd = vbd * (T0 + 0.5 * T1);
7103  capbd = T0 + T1;
7104  }
7105  }
7106 
7107  // There is a spice3f5 convergence check that would happen here.
7108  // (line 2404) skipping...
7109 
7110  // In 3f5, loading a bunch of things into the state vector at this point.
7111  // (line 2433) skipping...
7112 
7113  // bulk and channel charge plus overlaps
7114 
7116  {
7117  // NQS begins
7118  if (nqsMod)
7119  {
7120  qcheq = -(qbulk + qgate);
7121 
7122  cqgb = -(cggb + cbgb);
7123  cqdb = -(cgdb + cbdb);
7124  cqsb = -(cgsb + cbsb);
7125  cqbb = -(cqgb + cqdb + cqsb);
7126 
7127  gtau_drift = fabs(paramPtr->tconst * qcheq) * ScalingFactor;
7128  T0 = paramPtr->leffCV * paramPtr->leffCV;
7129  gtau_diff = 16.0 * paramPtr->u0temp * model_.vtm / T0 * ScalingFactor;
7130 
7131  gtau = gtau_drift + gtau_diff;
7132  }
7133 
7134  if (model_.capMod == 0)
7135  {
7136  if (vgd < 0.0)
7137  {
7138  cgdo = paramPtr->cgdo;
7139  qgdo = paramPtr->cgdo * vgd;
7140  }
7141  else
7142  {
7143  cgdo = paramPtr->cgdo;
7144  qgdo = paramPtr->cgdo * vgd;
7145  }
7146 
7147  if (vgs < 0.0)
7148  {
7149  cgso = paramPtr->cgso;
7150  qgso = paramPtr->cgso * vgs;
7151  }
7152  else
7153  {
7154  cgso = paramPtr->cgso;
7155  qgso = paramPtr->cgso * vgs;
7156  }
7157  }
7158  else if (model_.capMod == 1)
7159  {
7160  if (vgd < 0.0)
7161  {
7162  T1 = sqrt(1.0 - 4.0 * vgd / paramPtr->ckappa);
7163  cgdo = paramPtr->cgdo + paramPtr->weffCV * paramPtr->cgdl / T1;
7164 
7165  qgdo = paramPtr->cgdo * vgd - paramPtr->weffCV * 0.5
7166  * paramPtr->cgdl * paramPtr->ckappa * (T1 - 1.0);
7167  }
7168  else
7169  {
7172  }
7173 
7174  if (vgs < 0.0)
7175  {
7176  T1 = sqrt(1.0 - 4.0 * vgs / paramPtr->ckappa);
7177  cgso = paramPtr->cgso + paramPtr->weffCV * paramPtr->cgsl / T1;
7178  qgso = paramPtr->cgso * vgs - paramPtr->weffCV * 0.5
7179  * paramPtr->cgsl * paramPtr->ckappa * (T1 - 1.0);
7180  }
7181  else
7182  {
7185  }
7186  }
7187  else
7188  {
7189  T0 = vgd + CONSTDELTA_1;
7190  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7191  T2 = 0.5 * (T0 - T1);
7192 
7193  T3 = paramPtr->weffCV * paramPtr->cgdl;
7194  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7195  cgdo = paramPtr->cgdo + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7196 
7197  qgdo = (paramPtr->cgdo + T3) * vgd - T3 * (T2
7198  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7199 
7200  T0 = vgs + CONSTDELTA_1;
7201  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7202  T2 = 0.5 * (T0 - T1);
7203  T3 = paramPtr->weffCV * paramPtr->cgsl;
7204  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7205  cgso = paramPtr->cgso + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7206  qgso = (paramPtr->cgso + T3) * vgs - T3 * (T2
7207  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7208  }
7209 
7210  //cgdo = cgdo;
7211  //cgso = cgso;
7212 
7215 
7216  //cqdef = cqcheq = 0.0;
7217  cqdef = 0.0;
7218 
7219  // set some state variables:
7220  qg = qgate;
7221  qd = qdrn - qbd;
7222  qb = qbulk + qbd + qbs;
7223  if (nqsMod) qcdump = qdef * ScalingFactor;
7224 
7225  } // end of ChargeComputationNeeded if statement.
7226 
7227  // store small signal parameters
7228  //if (ckt->CKTmode & MODEINITSMSIG) goto line1000;
7229  // Note: in 3f5, line1000 is at the end of the load, after
7230  // the loads to the rhs and the matrix. So it looks
7231  // like this goto essentially means return.
7232 
7233 
7234  // Setting up a few currents for the RHS load:
7237 
7238  // Put this kludge in because the matrix load needs T1 but it is used
7239  // all over the place:
7240  T1global = T1;
7241 
7242  return bsuccess;
7243  }
7244 
7245 //-----------------------------------------------------------------------------
7246 // Function : Instance::updatePrimaryState
7247 //
7248 // Purpose : This function sets up the primaray state variables into
7249 // the primary state vector.
7250 //
7251 // These variables include qb, qg, qd and, in the
7252 // event that nqsMod=1, qcdump and qcheq.
7253 //
7254 // Special Notes :
7255 // Scope : public
7256 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7257 // Creation Date : 01/09/01
7258 //-----------------------------------------------------------------------------
7260  {
7261  bool bsuccess = true;
7262  double * staVec = extData.nextStaVectorRawPtr;
7263  double * stoVec = extData.nextStoVectorRawPtr;
7264 
7265  bsuccess = updateIntermediateVars ();
7266 
7267  // voltage drops:
7268  stoVec[li_store_vbs] = vbs;
7269  stoVec[li_store_vgs] = vgs;
7270  stoVec[li_store_vds] = vds;
7271  stoVec[li_store_vbd] = vbd;
7272  stoVec[li_store_von] = von;
7273 
7274  // intrinsic capacitors:
7275  staVec[li_state_qb] = qb;
7276  staVec[li_state_qg] = qg;
7277  staVec[li_state_qd] = qd;
7278 
7279  // parasitic capacitors:
7280  staVec[li_state_qbs] = qbs;
7281  staVec[li_state_qbd] = qbd;
7282 
7283  if( nqsMod )
7284  {
7285  staVec[li_state_qcheq] = qcheq;
7286  staVec[li_state_qcdump] = qcdump;
7287  }
7288 
7289  // if this is the first newton step of the first time step
7290  // of the transient simulation, we need to enforce that the
7291  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
7292  // compatibility. ERK.
7293 
7294  // Note: I think this kind of thing is enforced (or should be enforced,
7295  // anyway) at the time integration level. So I'm not sure this step is
7296  // really needed, at least for new-DAE. Derivatives out of the DCOP
7297  // are supposed to be zero at the first newton step.
7298 
7299  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
7300  {
7301  // re-set the state vector pointer that we are using to the "current"
7302  // pointer, rather than the "next" pointer.
7303  double * currStaVec = extData.currStaVectorRawPtr;
7304 
7305  // intrinsic capacitors:
7306  currStaVec[li_state_qb] = qb;
7307  currStaVec[li_state_qg] = qg;
7308  currStaVec[li_state_qd] = qd;
7309 
7310  // parasitic capacitors:
7311  currStaVec[li_state_qbs] = qbs;
7312  currStaVec[li_state_qbd] = qbd;
7313 
7314  if( nqsMod )
7315  {
7316  currStaVec[li_state_qcheq] = qcheq;
7317  currStaVec[li_state_qcdump] = qcdump;
7318  }
7319  }
7320 
7321  return bsuccess;
7322  }
7323 
7324 //-----------------------------------------------------------------------------
7325 // Function : Instance::loadDAEQVector
7326 //
7327 // Purpose : Loads the Q-vector contributions for a single
7328 // bsim3 instance.
7329 //
7330 // Special Notes : The "Q" vector is part of a standard DAE formalism in
7331 // which the system of equations is represented as:
7332 //
7333 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
7334 //
7335 // Scope : public
7336 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7337 // Creation Date : 04/07/04
7338 //-----------------------------------------------------------------------------
7340  {
7341  double * qVec = extData.daeQVectorRawPtr;
7342  double * dQdxdVp = extData.dQdxdVpVectorRawPtr;
7343 
7345 
7346  double Qeqqg = 0.0; // gate charge
7347  double Qeqqb = 0.0; // bulk charge
7348  double Qeqqd = 0.0; // drain charge
7349  double Qqdef = 0.0; // nqs-related charge.
7350  double Qqcheq = 0.0; // nqs-related charge.
7351 
7352  // These 3 vars are class variables, and are set up elsewhere.
7353  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
7354  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
7355  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
7356 
7357  if (model_.dtype > 0)
7358  {
7359  Qeqqg = qg;
7360  Qeqqb = qb;
7361  Qeqqd = qd;
7362  Qqdef = qcdump; // this needs to be fixed...
7363  Qqcheq = qcheq;
7364  }
7365  else // need to convert these to charges.
7366  {
7367  Qeqqg = -qg;
7368  Qeqqb = -qb;
7369  Qeqqd = -qd;
7370  Qqdef = -qcdump;
7371  Qqcheq = -qcheq;
7372  }
7373 
7374  qVec[li_Gate] += Qeqqg*numberParallel;
7375  qVec[li_Bulk] += (Qeqqb)*numberParallel;
7376  qVec[li_DrainPrime] += (-(-Qeqqd))*numberParallel;
7377  qVec[li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7378 
7379  if( loadLeadCurrent )
7380  {
7381  double * storeLeadQ = extData.storeLeadCurrQCompRawPtr;
7382  if (drainConductance == 0.0)
7383  {
7384  storeLeadQ[li_store_dev_id] = (-(-Qeqqd))*numberParallel;
7385  }
7386  if (sourceConductance == 0.0)
7387  {
7388  storeLeadQ[li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7389  }
7390  storeLeadQ[li_store_dev_ig] = Qeqqg*numberParallel;
7391  storeLeadQ[li_store_dev_ib] = (Qeqqb)*numberParallel;
7392  }
7393 
7394  if (nqsMod)
7395  {
7396  // 7 equ. for nqs modification. charge equation.
7397  qVec[li_Charge] += -(Qqcheq - Qqdef)*numberParallel;
7398  }
7399 
7400  //////////////////////////////////////////////////
7401  // limiting section:
7403  {
7404  // Need the following:
7405  // Qeqqg_Jdxp
7406  // Qeqqb_Jdxp
7407  // Qeqqd_Jdxp
7408  if (model_.dtype > 0)
7409  {
7410  // no-op:
7414  }
7415  else
7416  {
7420  }
7421 
7422  if (!origFlag)
7423  {
7424  dQdxdVp[li_Gate] += -Qeqqg_Jdxp*numberParallel;
7425  dQdxdVp[li_Bulk] += -(+Qeqqb_Jdxp)*numberParallel;
7426  dQdxdVp[li_DrainPrime] += (-Qeqqd_Jdxp)*numberParallel;
7427  dQdxdVp[li_SourcePrime] += (+Qeqqg_Jdxp+Qeqqb_Jdxp+Qeqqd_Jdxp) *numberParallel;
7428  } // orig flag.
7429  } // limiter flag
7430 
7431  return true;
7432  }
7433 
7434 //-----------------------------------------------------------------------------
7435 // Function : Instance::auxChargeCalculations
7436 //
7437 // Purpose : This function does some final "cleanup" calculations
7438 // having to do with the capacitors.
7439 //
7440 // Special Notes : About all this function really does is set up some
7441 // voltlim terms, and some unused nqs stuff.
7442 //
7443 // Scope : public
7444 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7445 // Creation Date : 04/18/04
7446 //-----------------------------------------------------------------------------
7448  {
7449  double T0, T1;
7450 
7452  {
7453  sxpart = (1.0 - (dxpart = (mode > 0) ? 0.4 : 0.6));
7456 
7457  if (nqsMod)
7458  {
7459  gtau = 16.0 * paramPtr->u0temp * model_.vtm
7461  }
7462  else
7463  {
7464  gtau = 0.0;
7465  }
7466  }
7467  else // ChargeComputation is needed
7468  {
7469  double vgb_orig = vgs_orig - vbs_orig;
7470 
7471  Qeqqg_Jdxp = 0.0;
7472  if (!origFlag)
7473  {
7474  Qeqqg_Jdxp = - CAPcggb * (vgb-vgb_orig)
7475  + CAPcgdb * (vbd-vbd_orig)
7476  + CAPcgsb * (vbs-vbs_orig);
7477  }
7478 
7479  Qeqqb_Jdxp = 0.0;
7480  if (!origFlag)
7481  {
7482  Qeqqb_Jdxp = - CAPcbgb * (vgb-vgb_orig)
7483  + CAPcbdb * (vbd-vbd_orig)
7484  + CAPcbsb * (vbs-vbs_orig);
7485  }
7486 
7487  Qeqqd_Jdxp = 0.0;
7488  if (!origFlag)
7489  {
7490  Qeqqd_Jdxp = - CAPcdgb * (vgb-vgb_orig)
7491  + CAPcddb * (vbd-vbd_orig)
7492  + CAPcdsb * (vbs-vbs_orig);
7493  }
7494 
7495  // Note: nqs stuff is not yet finished, especially the voltage
7496  // limiting aspect. For limiting, need to re-do T0 and the term
7497  // added to ceqqd.
7498  if (nqsMod)
7499  {
7500  std::string msg;
7501  msg = "Instance::auxChargeCalculations ()";
7502  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
7503  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
7504 
7505  T0 = ggtg * vgb - ggtd * vbd - ggts * vbs;
7506  ceqqg += T0;
7507  T1 = qdef * gtau;
7508  ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd
7509  * vbd - ddxpart_dVs * vbs);
7510 
7511  //cqdef = cqcdump - gqdef * qdef;
7512 
7513  //if (!origFlag)
7514  //{
7515  //double tmp = - (gcqgb * (vgb-vgb_orig)
7516  //- gcqdb * (vbd-vbd_orig)
7517  //- gcqsb * (vbs-vbs_orig)) + T0;
7518  //cqcheq += tmp;
7519  //cqcheq_Jdxp = tmp;
7520  //}
7521  }
7522  } // !ChargeComputationNeeded
7523 
7524  return true;
7525  }
7526 
7527 //-----------------------------------------------------------------------------
7528 // Function : Instance::setupCapacitors_newDAE ()
7529 //
7530 // Purpose : This takes a lot of the individual capacitive terms and
7531 // sums them together for loading into the Jacobian.
7532 //
7533 // Special Notes : This was extracted from updateIntermediateVars.
7534 // Different variables are used, and nothing is multiplied
7535 // by ag0 = solState.pdt. The new-dae formulation handles
7536 // all the 1/dt - related stuff up in the time integrator.
7537 //
7538 // NOTE: nqs not even close to being supported.
7539 //
7540 // Scope : public
7541 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7542 // Creation Date : 04/23/04
7543 //-----------------------------------------------------------------------------
7545  {
7546 
7547  if (mode > 0)
7548  {
7549  if (nqsMod == 0)
7550  {
7551  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
7552  CAPcgdb = (cgdb - cgdo);
7553  CAPcgsb = (cgsb - cgso);
7554 
7555  CAPcdgb = (cdgb - cgdo);
7556  CAPcddb = (cddb + capbd + cgdo);
7557  CAPcdsb = cdsb;
7558 
7559  CAPcsgb = -(cggb + cbgb + cdgb + cgso);
7560  CAPcsdb = -(cgdb + cbdb + cddb);
7561  CAPcssb = (capbs + cgso - (cgsb + cbsb + cdsb));
7562 
7563  CAPcbgb = (cbgb - paramPtr->cgbo);
7564  CAPcbdb = (cbdb - capbd);
7565  CAPcbsb = (cbsb - capbs);
7566  }
7567  else // nqsMode != 0
7568  {
7569 
7570  } // nqsMod
7571  }
7572  else
7573  {
7574  if (nqsMod == 0)
7575  {
7576  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
7577  CAPcgdb = (cgsb - cgdo);
7578  CAPcgsb = (cgdb - cgso);
7579 
7580  CAPcdgb = -(cggb + cbgb + cdgb + cgdo);
7581  CAPcddb = (capbd + cgdo - (cgsb + cbsb + cdsb));
7582  CAPcdsb = -(cgdb + cbdb + cddb);
7583 
7584  CAPcsgb = (cdgb - cgso);
7585  CAPcsdb = cdsb;
7586  CAPcssb = (cddb + capbs + cgso);
7587 
7588  CAPcbgb = (cbgb - paramPtr->cgbo);
7589  CAPcbdb = (cbsb - capbd);
7590  CAPcbsb = (cbdb - capbs);
7591  }
7592  else // nqsMode != 0
7593  {
7594 
7595  }
7596  }
7597 
7598  return true;
7599  }
7600 
7601 //-----------------------------------------------------------------------------
7602 // Function : Instance::setupCapacitors_oldDAE ()
7603 // Purpose : Same as new-DAE version, but including pdt, essentially.
7604 // Special Notes :
7605 //
7606 // Scope : public
7607 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7608 // Creation Date : 12/17/06
7609 //-----------------------------------------------------------------------------
7611  {
7612 
7613  double ag0 = getSolverState().pdt;
7614  double T0 = 0.0;
7615 
7616  // ERK. 12/17/2006.
7617  // It is necessary to set ag0=0.0, because for the first time step out of
7618  // the DCOP, all the time derivatives are forced to be zero. Thus, all
7619  // their derivatives should also be zero. If it wasn't for that, then ag0
7620  // could always be pdt. (it used to be, before the -jacobian_test capability).
7621  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
7622  {
7623  ag0 = 0.0;
7624  }
7625 
7626  if (mode > 0)
7627  {
7628  if (nqsMod == 0)
7629  {
7630  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
7631  gcgdb = (cgdb - cgdo) * ag0;
7632  gcgsb = (cgsb - cgso) * ag0;
7633 
7634  gcdgb = (cdgb - cgdo) * ag0;
7635  gcddb = (cddb + capbd + cgdo) * ag0;
7636  gcdsb = cdsb * ag0;
7637 
7638  gcsgb = -(cggb + cbgb + cdgb + cgso) * ag0;
7639  gcsdb = -(cgdb + cbdb + cddb) * ag0;
7640  gcssb = (capbs + cgso - (cgsb + cbsb + cdsb)) * ag0;
7641 
7642  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
7643  gcbdb = (cbdb - capbd) * ag0;
7644  gcbsb = (cbsb - capbs) * ag0;
7645 
7646  qgd = qgdo;
7647  qgs = qgso;
7648  qgb = paramPtr->cgbo * vgb;
7649  qgate += qgd + qgs + qgb;
7650  qbulk -= qgb;
7651  qdrn -= qgd;
7652  qsrc = -(qgate + qbulk + qdrn);
7653 
7654  ggtg = ggtd = ggtb = ggts = 0.0;
7655  sxpart = 0.6;
7656  dxpart = 0.4;
7659  }
7660  else // nqsMode != 0
7661  {
7662  if (qcheq > 0.0)
7663  {
7664  T0 = paramPtr->tconst * qdef * ScalingFactor;
7665  }
7666  else
7667  {
7668  T0 = -paramPtr->tconst * qdef * ScalingFactor;
7669  }
7670 
7671  ggtg = gtg = T0 * cqgb;
7672  ggtd = gtd = T0 * cqdb;
7673  ggts = gts = T0 * cqsb;
7674  ggtb = gtb = T0 * cqbb;
7675  gqdef = ScalingFactor * ag0;
7676 
7677  gcqgb = cqgb * ag0;
7678  gcqdb = cqdb * ag0;
7679  gcqsb = cqsb * ag0;
7680  gcqbb = cqbb * ag0;
7681 
7682  gcggb = (cgdo + cgso + paramPtr->cgbo ) * ag0;
7683  gcgdb = -cgdo * ag0;
7684  gcgsb = -cgso * ag0;
7685 
7686  gcdgb = -cgdo * ag0;
7687  gcddb = (capbd + cgdo) * ag0;
7688  gcdsb = 0.0;
7689 
7690  gcsgb = -cgso * ag0;
7691  gcsdb = 0.0;
7692  gcssb = (capbs + cgso) * ag0;
7693 
7694  gcbgb = -paramPtr->cgbo * ag0;
7695  gcbdb = -capbd * ag0;
7696  gcbsb = -capbs * ag0;
7697 
7699 
7700  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
7701  {
7702  if (model_.xpart < 0.5) dxpart = 0.4;
7703  else if (model_.xpart > 0.5) dxpart = 0.0;
7704  else dxpart = 0.5;
7705 
7707  }
7708  else
7709  {
7710  dxpart = qdrn / qcheq;
7711  Cdd = cddb;
7712  Csd = -(cgdb + cddb + cbdb);
7713  ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
7714  Cdg = cdgb;
7715  Csg = -(cggb + cdgb + cbgb);
7716  ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
7717 
7718  Cds = cdsb;
7719  Css = -(cgsb + cdsb + cbsb);
7720  ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
7721 
7723  }
7724  sxpart = 1.0 - dxpart;
7729 
7730  qgd = qgdo;
7731  qgs = qgso;
7732  qgb = paramPtr->cgbo * vgb;
7733  qgate = qgd + qgs + qgb;
7734  qbulk = -qgb;
7735  qdrn = -qgd;
7736  qsrc = -(qgate + qbulk + qdrn);
7737  } // nqsMod
7738  }
7739  else
7740  {
7741  if (nqsMod == 0)
7742  {
7743  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
7744  gcgdb = (cgsb - cgdo) * ag0;
7745  gcgsb = (cgdb - cgso) * ag0;
7746 
7747  gcdgb = -(cggb + cbgb + cdgb + cgdo) * ag0;
7748  gcddb = (capbd + cgdo - (cgsb + cbsb + cdsb)) * ag0;
7749  gcdsb = -(cgdb + cbdb + cddb) * ag0;
7750 
7751  gcsgb = (cdgb - cgso) * ag0;
7752  gcsdb = cdsb * ag0;
7753  gcssb = (cddb + capbs + cgso) * ag0;
7754 
7755  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
7756  gcbdb = (cbsb - capbd) * ag0;
7757  gcbsb = (cbdb - capbs) * ag0;
7758 
7759  qgd = qgdo;
7760  qgs = qgso;
7761  qgb = paramPtr->cgbo * vgb;
7762  qgate += qgd + qgs + qgb;
7763  qbulk -= qgb;
7764  qsrc = qdrn - qgs;
7765  qdrn = -(qgate + qbulk + qsrc);
7766 
7767  ggtg = ggtd = ggtb = ggts = 0.0;
7768  sxpart = 0.4;
7769  dxpart = 0.6;
7772  }
7773  else // nqsMode != 0
7774  {
7775  if (qcheq > 0.0)
7776  {
7777  T0 = paramPtr->tconst * qdef * ScalingFactor;
7778  }
7779  else
7780  {
7781  T0 = -paramPtr->tconst * qdef * ScalingFactor;
7782  }
7783 
7784  ggtg = gtg = T0 * cqgb;
7785  ggts = gtd = T0 * cqdb;
7786  ggtd = gts = T0 * cqsb;
7787  ggtb = gtb = T0 * cqbb;
7788  gqdef = ScalingFactor * ag0;
7789 
7790  gcqgb = cqgb * ag0;
7791  gcqdb = cqsb * ag0;
7792  gcqsb = cqdb * ag0;
7793  gcqbb = cqbb * ag0;
7794 
7795  gcggb = (cgdo + cgso + paramPtr->cgbo) * ag0;
7796  gcgdb = -cgdo * ag0;
7797  gcgsb = -cgso * ag0;
7798 
7799  gcdgb = -cgdo * ag0;
7800  gcddb = (capbd + cgdo) * ag0;
7801  gcdsb = 0.0;
7802 
7803  gcsgb = -cgso * ag0;
7804  gcsdb = 0.0;
7805  gcssb = (capbs + cgso) * ag0;
7806 
7807  gcbgb = -paramPtr->cgbo * ag0;
7808  gcbdb = -capbd * ag0;
7809  gcbsb = -capbs * ag0;
7810 
7812 
7813  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
7814  {
7815  if (model_.xpart < 0.5) sxpart = 0.4;
7816  else if (model_.xpart > 0.5) sxpart = 0.0;
7817  else sxpart = 0.5;
7818 
7820  }
7821  else
7822  {
7823  sxpart = qdrn / qcheq;
7824  Css = cddb;
7825  Cds = -(cgdb + cddb + cbdb);
7826  dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
7827  Csg = cdgb;
7828  Cdg = -(cggb + cdgb + cbgb);
7829  dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
7830 
7831  Csd = cdsb;
7832  Cdd = -(cgsb + cdsb + cbsb);
7833  dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
7834 
7836  }
7837 
7838  dxpart = 1.0 - sxpart;
7843 
7844  qgd = qgdo;
7845  qgs = qgso;
7846  qgb = paramPtr->cgbo * vgb;
7847  qgate = qgd + qgs + qgb;
7848  qbulk = -qgb;
7849  qsrc = -qgs;
7850  qdrn = -(qgate + qbulk + qsrc);
7851  }
7852  }
7853 
7854  return true;
7855  }
7856 
7857 //-----------------------------------------------------------------------------
7858 // Function : Instance::loadDAEFVector
7859 //
7860 // Purpose : Loads the F-vector contributions for a single
7861 // bsim3 instance.
7862 //
7863 // Special Notes :
7864 //
7865 // Scope : public
7866 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7867 // Creation Date : 04/07/04
7868 //-----------------------------------------------------------------------------
7870  {
7871  double * fVec = extData.daeFVectorRawPtr;
7872  double * dFdxdVp = extData.dFdxdVpVectorRawPtr;
7873 
7874  double coef(0.0);
7875 
7876  cdreq_Jdxp = 0.0;
7877  ceqbd_Jdxp = 0.0;
7878  ceqbs_Jdxp = 0.0;
7879 
7880  // Do a few auxilliary calculations, derived from 3f5.
7881  // load current vector
7882  if (mode >= 0)
7883  {
7884  Gm = gm;
7885  Gmbs = gmbs;
7886  FwdSum = Gm + Gmbs;
7887  RevSum = 0.0;
7888 
7889  cdreq = model_.dtype * (cd);
7890  ceqbd = -model_.dtype * (csub);
7891 
7892  ceqbs = 0.0;
7893 
7894  gbbdp = -gbds;
7895  gbbsp = (gbds + gbgs + gbbs);
7896 
7897  gbdpg = gbgs;
7898  gbdpdp = gbds;
7899  gbdpb = gbbs;
7900  gbdpsp = -(gbdpg + gbdpdp + gbdpb);
7901 
7902  gbspg = 0.0;
7903  gbspdp = 0.0;
7904  gbspb = 0.0;
7905  gbspsp = 0.0;
7906  }
7907  else
7908  {
7909  Gm = -gm;
7910  Gmbs = -gmbs;
7911  FwdSum = 0.0;
7912  RevSum = -(Gm + Gmbs);
7913 
7914  cdreq = -model_.dtype * (cd);
7915  ceqbs = -model_.dtype * (csub);
7916 
7917  ceqbd = 0.0;
7918 
7919  gbbsp = -gbds;
7920  gbbdp = (gbds + gbgs + gbbs);
7921 
7922  gbdpg = 0.0;
7923  gbdpsp = 0.0;
7924  gbdpb = 0.0;
7925  gbdpdp = 0.0;
7926 
7927  gbspg = gbgs;
7928  gbspsp = gbds;
7929  gbspb = gbbs;
7930  gbspdp = -(gbspg + gbspsp + gbspb);
7931  }
7932 
7933  if (model_.dtype > 0)
7934  {
7935  ceqbs += (cbs);
7936  ceqbd += (cbd);
7937  }
7938  else
7939  {
7940  ceqbs -= (cbs);
7941  ceqbd -= (cbd);
7942  }
7943 
7944  if (drainConductance != 0.0)
7945  {
7946  fVec[li_Drain] += Idrain*numberParallel;
7947  }
7948  if (sourceConductance != 0.0)
7949  {
7950  fVec[li_Source] += Isource*numberParallel;
7951  }
7952  fVec[li_Bulk] += (ceqbs + ceqbd)*numberParallel;
7953  fVec[li_DrainPrime] += (-(ceqbd - cdreq)-Idrain)*numberParallel;
7955 
7956  // lead current support
7957  if( loadLeadCurrent )
7958  {
7959  double * storeLeadF = extData.nextStoVectorRawPtr;
7960  if (drainConductance != 0.0)
7961  {
7962  storeLeadF[li_store_dev_id] = Idrain*numberParallel;
7963  }
7964  else
7965  {
7966  storeLeadF[li_store_dev_id] = (-(ceqbd - cdreq)-Idrain)*numberParallel;
7967  }
7968  if (sourceConductance != 0.0)
7969  {
7970  storeLeadF[li_store_dev_is] = Isource*numberParallel;
7971  }
7972  else
7973  {
7974  storeLeadF[li_store_dev_is] = (-(cdreq + ceqbs)-Isource)*numberParallel;
7975  }
7976  storeLeadF[li_store_dev_ig] = 0.0;
7977  storeLeadF[li_store_dev_ib] = (ceqbs + ceqbd)*numberParallel;
7978  }
7979 
7980  // Initial condition support
7981 
7983  {
7985  fVec[li_Drain] += coef;
7986  fVec[li_Source] += -coef;
7987  if( loadLeadCurrent )
7988  {
7989  double * storeLeadF = extData.nextStoVectorRawPtr;
7990  storeLeadF[li_store_dev_id]= coef;
7991  storeLeadF[li_store_dev_is]= -coef;
7992  }
7993  }
7994 
7996  {
7998  fVec[li_Gate] += coef;
7999  fVec[li_Source] += -coef;
8000  if( loadLeadCurrent )
8001  {
8002  double * storeLeadF = extData.nextStoVectorRawPtr;
8003  storeLeadF[li_store_dev_ig]= coef;
8004  storeLeadF[li_store_dev_is]= -coef;
8005  }
8006  }
8007 
8008 
8010  {
8012  fVec[li_Bulk] += coef;
8013  fVec[li_Source] += -coef;
8014  if( loadLeadCurrent )
8015  {
8016  double * storeLeadF = extData.nextStoVectorRawPtr;
8017  storeLeadF[li_store_dev_ib]= coef;
8018  storeLeadF[li_store_dev_is]= -coef;
8019  }
8020  }
8021 
8022 
8023 
8024  //////////////////////////////////////////////////
8025  // limiting section:
8027  {
8028  if (!origFlag)
8029  {
8030  if (mode >= 0)
8031  {
8032  // option 1
8033  double tmp = model_.dtype * (-gds * (vds-vds_orig) -
8034  Gm * (vgs-vgs_orig) -
8035  Gmbs * (vbs-vbs_orig));
8036 
8037  cdreq_Jdxp += tmp;
8038  cdreq += tmp;
8039 
8040  tmp = -model_.dtype * (-gbds * (vds-vds_orig) -
8041  gbgs * (vgs-vgs_orig) -
8042  gbbs * (vbs-vbs_orig));
8043  ceqbd_Jdxp += tmp;
8044  ceqbd += tmp;
8045  }
8046  else
8047  {
8048  // option 2
8049  double tmp = -model_.dtype * (gds * (vds-vds_orig) +
8050  Gm * (vgd-vgd_orig) +
8051  Gmbs * (vbd-vbd_orig));
8052  cdreq_Jdxp += tmp;
8053  cdreq += tmp;
8054 
8055  tmp = -model_.dtype * (gbds * (vds-vds_orig) -
8056  gbgs * (vgd-vgd_orig) -
8057  gbbs * (vbd-vbd_orig));
8058  ceqbd_Jdxp += tmp;
8059  ceqbd += tmp;
8060  }
8061 
8062 
8063  if (model_.dtype > 0)
8064  {
8065  ceqbs_Jdxp += (-gbs*(vbs-vbs_orig));
8066  ceqbs += (-gbs*(vbs-vbs_orig));
8067 
8068  ceqbd_Jdxp += (-gbd*(vbd-vbd_orig));
8069  ceqbd += (-gbd*(vbd-vbd_orig));
8070  }
8071  else
8072  {
8073  ceqbs_Jdxp -= (-gbs*(vbs-vbs_orig) );
8074  ceqbs -= (-gbs*(vbs-vbs_orig) );
8075 
8076  ceqbd_Jdxp -= (-gbd*(vbd-vbd_orig) );
8077  ceqbd -= (-gbd*(vbd-vbd_orig) );
8078  }
8082  } // orig flag.
8083  } // voltage limiter flag
8084 
8085  // Row associated with icVBS
8087  {
8088  // get the voltage drop from the previous solution
8089  double cVs = extData.nextSolVectorRawPtr[li_Source];
8090  double cVb = extData.nextSolVectorRawPtr[li_Bulk];
8091  fVec[li_Ibs] += (cVb - cVs - icVBS);
8092  }
8093 
8094  // Row associated with icVDS
8096  {
8097  // get the voltage drop from the previous solution
8098  double cVd = extData.nextSolVectorRawPtr[li_Drain];
8099  double cVs = extData.nextSolVectorRawPtr[li_Source];
8100  fVec[li_Ids] += (cVd - cVs - icVDS);
8101  }
8102 
8103  // Row associated with icVGS
8105  {
8106  // get the voltage drop from the previous solution
8107  double cVg = extData.nextSolVectorRawPtr[li_Gate];
8108  double cVs = extData.nextSolVectorRawPtr[li_Source];
8109 
8110  fVec[li_Igs] += (cVg - cVs - icVGS);
8111  }
8112 
8113  return true;
8114  }
8115 
8116 //-----------------------------------------------------------------------------
8117 // Function : Instance::loadDAEdQdx
8118 //
8119 // Purpose : Loads the Q-vector contributions for a single
8120 // bsim3 instance.
8121 //
8122 // Special Notes : The "Q" vector is part of a standard DAE formalism in
8123 // which the system of equations is represented as:
8124 //
8125 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
8126 //
8127 // Scope : public
8128 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8129 // Creation Date : 04/07/04
8130 //-----------------------------------------------------------------------------
8132  {
8133  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
8134  {
8135  // do nothing, as for this special case q is always zero.
8136  }
8137  else
8138  {
8139  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
8140 
8141  // Row corresponding to the KCL for the drain node: NOTHING
8142 
8143  // Row corresponding to the KCL for the source node: NOTHING
8144 
8145  // Row corresponding to the KCL for the gate node:
8146  // Check this later. ERK. See the comments in the function
8147  // loadDAEdQdx, regarding ggtg, ggtb, etc.
8148  //
8149  // For now I am leaving out the gg terms, as they are zero when
8150  // nqsMod=0, which is always true.
8151  //
8153  += (CAPcggb )*numberParallel;
8157  += (CAPcgdb )*numberParallel;
8159  += (CAPcgsb )*numberParallel;
8160 
8161  // Row corresponding to the KCL for the bulk node:
8163  += (CAPcbgb)*numberParallel;
8164 
8167 
8169  += (CAPcbdb)*numberParallel;
8170 
8172  += (CAPcbsb)*numberParallel;
8173 
8174 
8175  // Row corresponding to the KCL for the drain prime node:
8177  -= (+ CAPcdgb + CAPcddb + CAPcdsb )*numberParallel;
8178 
8180  += (CAPcdgb) *numberParallel;
8181 
8183  += (+ CAPcddb )*numberParallel;
8184 
8186  -= (- CAPcdsb) *numberParallel;
8187 
8188  // Row corresponding to the KCL for the source prime node:
8190  += (CAPcsgb) *numberParallel;
8191 
8193  -= (+ CAPcsgb + CAPcsdb + CAPcssb) *numberParallel;
8194 
8196  -= (- CAPcsdb) *numberParallel;
8197 
8199  += (+ CAPcssb) *numberParallel;
8200 
8201  // Row associated with the charge equation
8202  // This is currently not supported.
8203  if (nqsMod)
8204  {
8205  std::string msg;
8206  msg = "Instance::loadDAEdQdx";
8207  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8208  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8209  }
8210  }
8211  return true;
8212  }
8213 
8214 //-----------------------------------------------------------------------------
8215 // Function : Instance::loadDAEdFdx ()
8216 //
8217 // Purpose : Loads the F-vector contributions for a single
8218 // bsim3 instance.
8219 //
8220 // Special Notes :
8221 //
8222 // Scope : public
8223 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8224 // Creation Date : 04/07/04
8225 //-----------------------------------------------------------------------------
8227  {
8228  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
8229 
8230  // Row corresponding to the KCL for the drain node:
8235 
8236  // Extra term for initial conditions on Vds in operating point
8238  {
8239  dFdx[li_Drain][ADrainEquIdsOffset] += 1.0;
8240  }
8241 
8242  // Row corresponding to the KCL for the source node:
8247 
8248  // Extra term for initial conditions on Vbs in operating point
8250  {
8251  dFdx[li_Source][ASourceEquIbsOffset] -= 1.0;
8252  }
8253  // Extra term for initial conditions on Vds in operating point
8255  {
8256  dFdx[li_Source][ASourceEquIdsOffset] -= 1.0;
8257  }
8258  // Extra term for initial conditions on Vgs in operating point
8260  {
8261  dFdx[li_Source][ASourceEquIgsOffset] -= 1.0;
8262  }
8263 
8264  // Row corresponding to the KCL for the gate node: NOTHING
8265  // Check this later. ERK.
8266  //
8267  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
8268  // belong here. I'm not sure aboug the gg terms. On one hand, the
8269  // rhs vector component for the gate node ONLY seems to take
8270  // capacitive currents, which implies that all of these are capacitive
8271  // conductances. On the other hand, the gg terms do not appear to
8272  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
8273  // capacitive conductances are of the form g = C/dt, and the gg terms
8274  // do not have this form.
8275  //
8276  // For now, the gg issue is moot b/c those terms are only nonzero
8277  // if nqsMod = 1, which is not a supported option.
8278 
8279  // However, the gg
8280  // terms (ggtg, ggtb, ggtd and ggts)
8281  //
8282  //(*JMatPtr)[li_Gate][AGateEquGateNodeOffset]
8283  // += (gcggb - ggtg)*numberParallel;
8284  //(*JMatPtr)[li_Gate][AGateEquBulkNodeOffset]
8285  // -= (gcggb + gcgdb + gcgsb + ggtb)*numberParallel;
8286  //(*JMatPtr)[li_Gate][AGateEquDrainPrimeNodeOffset]
8287  // += (gcgdb - ggtd)*numberParallel;
8288  //(*JMatPtr)[li_Gate][AGateEquSourcePrimeNodeOffset]
8289  // += (gcgsb - ggts)*numberParallel;
8290 
8291  // initial conditions on gate node
8292  // Extra term for initial conditions on Vgs in operating point
8294  {
8295  dFdx[li_Gate][AGateEquIgsOffset] += 1.0;
8296  }
8297 
8298  // Row corresponding to the KCL for the bulk node:
8300  += (- gbgs)*numberParallel;
8301 
8303  += (gbd + gbs - gbbs)*numberParallel;
8304 
8306  += (- gbd + gbbdp)*numberParallel;
8307 
8309  += (- gbs + gbbsp)*numberParallel;
8310 
8311  // Extra term for initial conditions on Vbs in operating point
8313  {
8314  dFdx[li_Bulk][ABulkEquIbsOffset] += 1.0;
8315  }
8316 
8317  // Row corresponding to the KCL for the drain prime node:
8320 
8322  -= (gbd - Gmbs - dxpart*ggtb
8323  - T1global*ddxpart_dVb - gbdpb)*numberParallel;
8324 
8326  += (Gm + dxpart*ggtg + T1global*ddxpart_dVg + gbdpg)
8327  *numberParallel;
8328 
8331  + T1global*ddxpart_dVd + gbdpdp)*numberParallel;
8332 
8335  *numberParallel;
8336 
8337  // Row corresponding to the KCL for the source prime node:
8339  += (- Gm + sxpart*ggtg + T1global*dsxpart_dVg + gbspg)
8340  *numberParallel;
8341 
8343  -= (gbs + Gmbs - sxpart*ggtb
8344  - T1global*dsxpart_dVb - gbspb)*numberParallel;
8345 
8348 
8351  *numberParallel;
8352 
8355  + T1global*dsxpart_dVs + gbspsp)*numberParallel;
8356 
8357  // Row associated with the charge equation
8358  if (nqsMod)
8359  {
8360  std::string msg;
8361  msg = "Instance::loadDAEdFdx";
8362  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8363  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8364  }
8365 
8366  // Initial condition rows
8367  // Row associated with icVBS
8368  if( icVBSGiven )
8369  {
8370  if( getSolverState().dcopFlag )
8371  {
8372  dFdx[li_Ibs][icVBSEquVbOffset] += 1.0;
8373  dFdx[li_Ibs][icVBSEquVsOffset] -= 1.0;
8374  }
8375  else
8376  {
8377  dFdx[li_Ibs][icVBSEquIbsOffset] += 1.0;
8378  }
8379  }
8380 
8381  // Row associated with icVDS
8382  if( icVDSGiven )
8383  {
8384  if( getSolverState().dcopFlag )
8385  {
8386  dFdx[li_Ids][icVDSEquVdOffset] += 1.0;
8387  dFdx[li_Ids][icVDSEquVsOffset] -= 1.0;
8388  }
8389  else
8390  {
8391  dFdx[li_Ids][icVDSEquIdsOffset] += 1.0;
8392  }
8393  }
8394 
8395  // Row associated with icVGS
8396  if( icVGSGiven )
8397  {
8398  if( getSolverState().dcopFlag )
8399  {
8400  dFdx[li_Igs][icVGSEquVgOffset] += 1.0;
8401  dFdx[li_Igs][icVGSEquVsOffset] -= 1.0;
8402  }
8403  else
8404  {
8405  dFdx[li_Igs][icVGSEquIgsOffset] += 1.0;
8406  }
8407  }
8408 
8409  return true;
8410  }
8411 
8412 //-----------------------------------------------------------------------------
8413 // Function : Instance::setIC
8414 // Purpose :
8415 // Special Notes :
8416 // Scope : public
8417 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
8418 // Creation Date : 01/10/02
8419 //-----------------------------------------------------------------------------
8421  {
8422  bool bsuccess = true;
8423 
8424  if( icVBSGiven )
8425  {
8428  }
8429 
8430  if( icVDSGiven )
8431  {
8434  }
8435 
8436  if( icVGSGiven )
8437  {
8440  }
8441 
8442  return bsuccess;
8443  }
8444 
8445 
8446 // Additional Declarations
8447 
8448 // Class Model
8449 
8450 //-----------------------------------------------------------------------------
8451 // Function : Model::processParams
8452 // Purpose :
8453 // Special Notes :
8454 // Scope : public
8455 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8456 // Creation Date : 6/03/02
8457 //-----------------------------------------------------------------------------
8459  {
8460  std::string msg;
8461  cox = 3.453133e-11 / tox;
8462  if (!given("TOXM")) toxm = tox;
8463  if (!given("DSUB")) dsub = drout;
8464  if (!given("LLC")) Llc = Ll;
8465  if (!given("LWC")) Lwc = Lw;
8466  if (!given("LWLC")) Lwlc = Lwl;
8467  if (!given("WLC")) Wlc = Wl;
8468  if (!given("WWL")) Wwlc = Wwl;
8469  if (!given("WWLC")) Wwlc = Wwl;
8470  if (!given("DWC")) dwc = Wint;
8471  if (!given("DLC")) dlc = Lint;
8472 
8473  if (!given("CF"))
8474  {
8475  double C1 = 2.0 * CONSTEPSOX;
8476  double C5 = M_PI;
8477  double C2 = 1.0 + (0.4e-6 / tox);
8478  double C3 = log(C2);
8479  cf = C1*C3/C5;
8480  }
8481 
8482  if (!given("CGDO"))
8483  {
8484  if (given("DLC") && (dlc > 0.0)) cgdo = dlc * cox - cgdl ;
8485  else cgdo = 0.6 * xj * cox;
8486  }
8487 
8488  if (!given("CGSO"))
8489  {
8490  if (given("DLC") && (dlc > 0.0)) cgso = dlc * cox - cgsl ;
8491  else cgso = 0.6 * xj * cox;
8492  }
8493 
8494  if (!given("CGBO")) cgbo = 2.0 * dwc * cox;
8495 
8496  if (!given("CJSWG"))
8497  unitLengthGateSidewallJctCap = unitLengthSidewallJctCap ;
8498 
8499  if (!given("PBSWG"))
8500  GatesidewallJctPotential = sidewallJctPotential;
8501 
8502  if (!given("MJSWG"))
8503  bulkJctGateSideGradingCoeff = bulkJctSideGradingCoeff;
8504 
8505 
8506  // More initializations: taken from b3temp.c:
8507  if (bulkJctPotential < 0.1)
8508  {
8509  bulkJctPotential = 0.1;
8510  msg = "Given pb is less than 0.1. Pb is set to 0.1.\n";
8511  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8512  }
8513 
8514  if (sidewallJctPotential < 0.1)
8515  {
8516  sidewallJctPotential = 0.1;
8517  msg = "Given pbsw is less than 0.1. Pbsw is set to 0.1.\n";
8518  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8519  }
8520 
8521  if (GatesidewallJctPotential < 0.1)
8522  {
8523  GatesidewallJctPotential = 0.1;
8524  msg = "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n";
8525  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8526  }
8527 
8528  vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14));
8529  factor1 = sqrt(CONSTEPSSI / CONSTEPSOX * tox);
8530 
8531  Vtm0 = CONSTKoverQ * tnom;
8532  Eg0 = CONSTEg0 - CONSTalphaEg * tnom * tnom / (tnom + CONSTbetaEg);
8533  ni = CONSTNi0 * (tnom / CONSTREFTEMP) * sqrt(tnom / CONSTREFTEMP)
8534  * exp(21.5565981 - Eg0 / (2.0 * Vtm0));
8535 
8536  // If there are any time dependent parameters, set their values at for
8537  // the current time.
8538 
8539  return true;
8540  }
8541 
8542 //----------------------------------------------------------------------------
8543 // Function : Model::processInstanceParams
8544 // Purpose :
8545 // Special Notes :
8546 // Scope : public
8547 // Creator : Dave Shirely, PSSI
8548 // Creation Date : 03/23/06
8549 //----------------------------------------------------------------------------
8551  {
8552 
8553  std::vector<Instance*>::iterator iter;
8554  std::vector<Instance*>::iterator first = instanceContainer.begin();
8555  std::vector<Instance*>::iterator last = instanceContainer.end();
8556 
8557  for (iter=first; iter!=last; ++iter)
8558  {
8559  (*iter)->processParams();
8560  }
8561 
8562  return true;
8563  }
8564 
8565 //-----------------------------------------------------------------------------
8566 // Function : Model::Model
8567 // Purpose : model block constructor
8568 // Special Notes :
8569 // Scope : public
8570 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8571 // Creation Date : 11/14/00
8572 //-----------------------------------------------------------------------------
8574  const Configuration & configuration,
8575  const ModelBlock & MB,
8576  const FactoryBlock & factory_block)
8577  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
8578  modType (0),
8579  dtype (CONSTNMOS),
8580  mobMod (0),
8581  capMod (0),
8582  noiMod (0),
8583  binUnit (0),
8584  paramChk (0),
8585  version ("3.2.2"),
8586  tox (0),
8587  toxm (0),
8588  cdsc (0),
8589  cdscb (0),
8590  cdscd (0),
8591  cit (0),
8592  nfactor (0),
8593  xj (0),
8594  vsat (0),
8595  at (0),
8596  a0 (0),
8597  ags (0),
8598  a1 (0),
8599  a2 (0),
8600  keta (0),
8601  nsub (0),
8602  npeak (0),
8603  ngate (0),
8604  gamma1 (0),
8605  gamma2 (0),
8606  vbx (0),
8607  vbm (0),
8608  xt (0),
8609  k1 (0),
8610  kt1 (0),
8611  kt1l (0),
8612  kt2 (0),
8613  k2 (0),
8614  k3 (0),
8615  k3b (0),
8616  w0 (0),
8617  nlx (0),
8618  dvt0 (0),
8619  dvt1 (0),
8620  dvt2 (0),
8621  dvt0w (0),
8622  dvt1w (0),
8623  dvt2w (0),
8624  drout (0),
8625  dsub (0),
8626  vth0 (0),
8627  ua (0),
8628  ua1 (0),
8629  ub (0),
8630  ub1 (0),
8631  uc (0),
8632  uc1 (0),
8633  u0 (0),
8634  ute (0),
8635  voff (0),
8636  delta (0),
8637  rdsw (0),
8638  prwg (0),
8639  prwb (0),
8640  prt (0),
8641  eta0 (0),
8642  etab (0),
8643  pclm (0),
8644  pdibl1 (0),
8645  pdibl2 (0),
8646  pdiblb (0),
8647  pscbe1 (0),
8648  pscbe2 (0),
8649  pvag (0),
8650  wr (0),
8651  dwg (0),
8652  dwb (0),
8653  b0 (0),
8654  b1 (0),
8655  alpha0 (0),
8656  alpha1 (0),
8657  beta0 (0),
8658  ijth (0),
8659  vfb (0),
8660  elm (0),
8661  cgsl (0),
8662  cgdl (0),
8663  ckappa (0),
8664  cf (0),
8665  vfbcv (0),
8666  clc (0),
8667  cle (0),
8668  dwc (0),
8669  dlc (0),
8670  noff (0),
8671  voffcv (0),
8672  acde (0),
8673  moin (0),
8674  tcj (0),
8675  tcjsw (0),
8676  tcjswg (0),
8677  tpb (0),
8678  tpbsw (0),
8679  tpbswg (0),
8680  lcdsc (0),
8681  lcdscb (0),
8682  lcdscd (0),
8683  lcit (0),
8684  lnfactor (0),
8685  lxj (0),
8686  lvsat (0),
8687  lat (0),
8688  la0 (0),
8689  lags (0),
8690  la1 (0),
8691  la2 (0),
8692  lketa (0),
8693  lnsub (0),
8694  lnpeak (0),
8695  lngate (0),
8696  lgamma1 (0),
8697  lgamma2 (0),
8698  lvbx (0),
8699  lvbm (0),
8700  lxt (0),
8701  lk1 (0),
8702  lkt1 (0),
8703  lkt1l (0),
8704  lkt2 (0),
8705  lk2 (0),
8706  lk3 (0),
8707  lk3b (0),
8708  lw0 (0),
8709  lnlx (0),
8710  ldvt0 (0),
8711  ldvt1 (0),
8712  ldvt2 (0),
8713  ldvt0w (0),
8714  ldvt1w (0),
8715  ldvt2w (0),
8716  ldrout (0),
8717  ldsub (0),
8718  lvth0 (0),
8719  lua (0),
8720  lua1 (0),
8721  lub (0),
8722  lub1 (0),
8723  luc (0),
8724  luc1 (0),
8725  lu0 (0),
8726  lute (0),
8727  lvoff (0),
8728  ldelta (0),
8729  lrdsw (0),
8730  lprwg (0),
8731  lprwb (0),
8732  lprt (0),
8733  leta0 (0),
8734  letab (0),
8735  lpclm (0),
8736  lpdibl1 (0),
8737  lpdibl2 (0),
8738  lpdiblb (0),
8739  lpscbe1 (0),
8740  lpscbe2 (0),
8741  lpvag (0),
8742  lwr (0),
8743  ldwg (0),
8744  ldwb (0),
8745  lb0 (0),
8746  lb1 (0),
8747  lalpha0 (0),
8748  lalpha1 (0),
8749  lbeta0 (0),
8750  lvfb (0),
8751  lelm (0),
8752  lcgsl (0),
8753  lcgdl (0),
8754  lckappa (0),
8755  lcf (0),
8756  lclc (0),
8757  lcle (0),
8758  lvfbcv (0),
8759  lnoff (0),
8760  lvoffcv (0),
8761  lacde (0),
8762  lmoin (0),
8763  wcdsc (0),
8764  wcdscb (0),
8765  wcdscd (0),
8766  wcit (0),
8767  wnfactor (0),
8768  wxj (0),
8769  wvsat (0),
8770  wat (0),
8771  wa0 (0),
8772  wags (0),
8773  wa1 (0),
8774  wa2 (0),
8775  wketa (0),
8776  wnsub (0),
8777  wnpeak (0),
8778  wngate (0),
8779  wgamma1 (0),
8780  wgamma2 (0),
8781  wvbx (0),
8782  wvbm (0),
8783  wxt (0),
8784  wk1 (0),
8785  wkt1 (0),
8786  wkt1l (0),
8787  wkt2 (0),
8788  wk2 (0),
8789  wk3 (0),
8790  wk3b (0),
8791  ww0 (0),
8792  wnlx (0),
8793  wdvt0 (0),
8794  wdvt1 (0),
8795  wdvt2 (0),
8796  wdvt0w (0),
8797  wdvt1w (0),
8798  wdvt2w (0),
8799  wdrout (0),
8800  wdsub (0),
8801  wvth0 (0),
8802  wua (0),
8803  wua1 (0),
8804  wub (0),
8805  wub1 (0),
8806  wuc (0),
8807  wuc1 (0),
8808  wu0 (0),
8809  wute (0),
8810  wvoff (0),
8811  wdelta (0),
8812  wrdsw (0),
8813  wprwg (0),
8814  wprwb (0),
8815  wprt (0),
8816  weta0 (0),
8817  wetab (0),
8818  wpclm (0),
8819  wpdibl1 (0),
8820  wpdibl2 (0),
8821  wpdiblb (0),
8822  wpscbe1 (0),
8823  wpscbe2 (0),
8824  wpvag (0),
8825  wwr (0),
8826  wdwg (0),
8827  wdwb (0),
8828  wb0 (0),
8829  wb1 (0),
8830  walpha0 (0),
8831  walpha1 (0),
8832  wbeta0 (0),
8833  wvfb (0),
8834  welm (0),
8835  wcgsl (0),
8836  wcgdl (0),
8837  wckappa (0),
8838  wcf (0),
8839  wclc (0),
8840  wcle (0),
8841  wvfbcv (0),
8842  wnoff (0),
8843  wvoffcv (0),
8844  wacde (0),
8845  wmoin (0),
8846  pcdsc (0),
8847  pcdscb (0),
8848  pcdscd (0),
8849  pcit (0),
8850  pnfactor (0),
8851  pxj (0),
8852  pvsat (0),
8853  pat (0),
8854  pa0 (0),
8855  pags (0),
8856  pa1 (0),
8857  pa2 (0),
8858  pketa (0),
8859  pnsub (0),
8860  pnpeak (0),
8861  pngate (0),
8862  pgamma1 (0),
8863  pgamma2 (0),
8864  pvbx (0),
8865  pvbm (0),
8866  pxt (0),
8867  pk1 (0),
8868  pkt1 (0),
8869  pkt1l (0),
8870  pkt2 (0),
8871  pk2 (0),
8872  pk3 (0),
8873  pk3b (0),
8874  pw0 (0),
8875  pnlx (0),
8876  pdvt0 (0),
8877  pdvt1 (0),
8878  pdvt2 (0),
8879  pdvt0w (0),
8880  pdvt1w (0),
8881  pdvt2w (0),
8882  pdrout (0),
8883  pdsub (0),
8884  pvth0 (0),
8885  pua (0),
8886  pua1 (0),
8887  pub (0),
8888  pub1 (0),
8889  puc (0),
8890  puc1 (0),
8891  pu0 (0),
8892  pute (0),
8893  pvoff (0),
8894  pdelta (0),
8895  prdsw (0),
8896  pprwg (0),
8897  pprwb (0),
8898  pprt (0),
8899  peta0 (0),
8900  petab (0),
8901  ppclm (0),
8902  ppdibl1 (0),
8903  ppdibl2 (0),
8904  ppdiblb (0),
8905  ppscbe1 (0),
8906  ppscbe2 (0),
8907  ppvag (0),
8908  pwr (0),
8909  pdwg (0),
8910  pdwb (0),
8911  pb0 (0),
8912  pb1 (0),
8913  palpha0 (0),
8914  palpha1 (0),
8915  pbeta0 (0),
8916  pvfb (0),
8917  pelm (0),
8918  pcgsl (0),
8919  pcgdl (0),
8920  pckappa (0),
8921  pcf (0),
8922  pclc (0),
8923  pcle (0),
8924  pvfbcv (0),
8925  pnoff (0),
8926  pvoffcv (0),
8927  pacde (0),
8928  pmoin (0),
8929  tnom (getDeviceOptions().tnom),
8930  cgso (0),
8931  cgdo (0),
8932  cgbo (0),
8933  xpart (0),
8934  cFringOut (0),
8935  cFringMax (0),
8936  sheetResistance (0),
8937  jctSatCurDensity (0),
8938  jctSidewallSatCurDensity (0),
8939  bulkJctPotential (0),
8940  bulkJctBotGradingCoeff (0),
8941  bulkJctSideGradingCoeff (0),
8942  bulkJctGateSideGradingCoeff (0),
8943  sidewallJctPotential (0),
8944  GatesidewallJctPotential (0),
8945  unitAreaJctCap (0),
8946  unitLengthSidewallJctCap (0),
8947  unitLengthGateSidewallJctCap (0),
8948  jctEmissionCoeff (0),
8949  jctTempExponent (0),
8950  Lint (0),
8951  Ll (0),
8952  Llc (0),
8953  Lln (0),
8954  Lw (0),
8955  Lwc (0),
8956  Lwn (0),
8957  Lwl (0),
8958  Lwlc (0),
8959  model_l (0),
8960  model_w (0),
8961  Lmin (0),
8962  Lmax (0),
8963  Wmin (0),
8964  Wmax (0),
8965  Wint (0),
8966  Wl (0),
8967  Wlc (0),
8968  Wln (0),
8969  Ww (0),
8970  Wwc (0),
8971  Wwn (0),
8972  Wwl (0),
8973  Wwlc (0),
8974  vtm (0),
8975  cox (0),
8976  cof1 (0),
8977  cof2 (0),
8978  cof3 (0),
8979  cof4 (0),
8980  vcrit (0),
8981  factor1 (0),
8982  PhiB (0),
8983  PhiBSW (0),
8984  PhiBSWG (0),
8985  oxideTrapDensityA (0),
8986  oxideTrapDensityB (0),
8987  oxideTrapDensityC (0),
8988  em (0),
8989  ef (0),
8990  af (0),
8991  kf (0),
8992  npeakGiven (0),
8993  gamma1Given (0),
8994  gamma2Given (0),
8995  k1Given (0),
8996  k2Given (0),
8997  nsubGiven (0),
8998  xtGiven (0),
8999  vbxGiven (0),
9000  vbmGiven (0),
9001  vfbGiven (0),
9002  vth0Given (0),
9003  Vtm0 (0.0),
9004  Eg0 (0.0),
9005  ni (0.0)
9006  {
9007  if (getType() != "")
9008  {
9009  if (getType() == "NMOS") {
9010  dtype = CONSTNMOS;
9011  }
9012  else if (getType() == "PMOS") {
9013  dtype = CONSTPMOS;
9014  }
9015  else
9016  {
9017  UserError0(*this) << "Could not recognize the type for model " << getName();
9018  }
9019  }
9020 
9021  // Set params to constant default values:
9022  setDefaultParams();
9023 
9024  // Set params according to .model line and constant defaults from metadata:
9025  setModParams(MB.params);
9026 
9027  // Set any non-constant parameter defaults:
9028 #ifdef Xyce_BSIM3_USE_DEFL
9029  if (!given("L"))
9031  if (!given("W"))
9033 #endif
9034  if (!given("TNOM"))
9036 
9037  if (!given("TNOM") && tnom == 0.0)
9038  Report::DevelFatal0() << "TNOM is zero";
9039 
9040 // Calculate any parameters specified as expressions:
9042 
9043  // calculate dependent (ie computed) params and check for errors:
9044  if (!given("VTH0"))
9045  vth0 = (dtype == CONSTNMOS) ? 0.7 : -0.7;
9046  if (!given("UC"))
9047  uc = (mobMod == 3) ? -0.0465 : -0.0465e-9;
9048  if (!given("UC1"))
9049  uc1 = (mobMod == 3) ? -0.056 : -0.056e-9;
9050  if (!given("U0"))
9051  u0 = (dtype == CONSTNMOS) ? 0.067 : 0.025;
9052  if (!given("NOIA"))
9053  {
9054  if (dtype == CONSTNMOS)
9055  oxideTrapDensityA = 1e20;
9056  else
9057  oxideTrapDensityA = 9.9e18;
9058  }
9059  if (!given("NOIB"))
9060  {
9061  if (dtype == CONSTNMOS)
9062  oxideTrapDensityB = 5e4;
9063  else
9064  oxideTrapDensityB = 2.4e3;
9065  }
9066  if (!given("NOIC"))
9067  {
9068  if (dtype == CONSTNMOS)
9069  oxideTrapDensityC = -1.4e-12;
9070  else
9071  oxideTrapDensityC = 1.4e-12;
9072  }
9073 
9074  processParams ();
9075  }
9076 
9077 //-----------------------------------------------------------------------------
9078 // Function : Model::~Model
9079 // Purpose : destructor
9080 // Special Notes :
9081 // Scope : public
9082 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9083 // Creation Date : 11/14/00
9084 //-----------------------------------------------------------------------------
9086  {
9087  std::list<SizeDependParam*>::iterator it_dpL =
9088  sizeDependParamList.begin();
9089  std::list<SizeDependParam*>::iterator end_dpL =
9090  sizeDependParamList.end();
9091  for( ; it_dpL != end_dpL; ++it_dpL )
9092  delete (*it_dpL);
9093 
9094  sizeDependParamList.clear ();
9095 
9096  std::vector<Instance*>::iterator iter;
9097  std::vector<Instance*>::iterator first = instanceContainer.begin();
9098  std::vector<Instance*>::iterator last = instanceContainer.end();
9099 
9100  for (iter=first; iter!=last; ++iter)
9101  {
9102  delete (*iter);
9103  }
9104 
9105  }
9106 
9107 
9108 //-----------------------------------------------------------------------------
9109 // Function : Model::printOutInstances
9110 // Purpose : debugging tool.
9111 // Special Notes :
9112 // Scope : public
9113 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9114 // Creation Date : 4/03/00
9115 //-----------------------------------------------------------------------------
9116  std::ostream &Model::printOutInstances (std::ostream &os) const
9117  {
9118  std::vector<Instance*>::const_iterator iter;
9119  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
9120  std::vector<Instance*>::const_iterator last = instanceContainer.end();
9121 
9122  int i;
9123  os << std::endl;
9124  os << " name modelName Parameters" << std::endl;
9125 
9126  for (i=0, iter=first; iter!=last; ++iter,++i)
9127  {
9128  os << " " << i << ": " << (*iter)->getName() << "\t";
9129  os << getName();
9130  os << std::endl;
9131  }
9132 
9133  os << std::endl;
9134 
9135  return os;
9136  }
9137 
9138 //-----------------------------------------------------------------------------
9139 // Function : Model::forEachInstance
9140 // Purpose :
9141 // Special Notes :
9142 // Scope : public
9143 // Creator : David Baur
9144 // Creation Date : 2/4/2014
9145 //-----------------------------------------------------------------------------
9146 /// Apply a device instance "op" to all instances associated with this
9147 /// model
9148 ///
9149 /// @param[in] op Operator to apply to all instances.
9150 ///
9151 ///
9152  void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
9153 {
9154  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
9155  op(*it);
9156  }
9157 
9158 
9159 
9160 //----------------------------------------------------------------------------
9161 // Function : Model::clearTemperatureData
9162 //
9163 // Purpose : This is mainly here to delete rid of the size
9164 // dependent parameters, which are also temperature dependent.
9165 //
9166 // Special Notes : This is called right before the circuit temperature is
9167 // changed.
9168 //
9169 // Scope : public
9170 // Creator : Eric R. Keiter, 9233, computation sciences
9171 // Creation Date : 10/26/2004
9172 //----------------------------------------------------------------------------
9174  {
9175  std::list<SizeDependParam*>::iterator it_dpL =
9176  sizeDependParamList.begin();
9177  std::list<SizeDependParam*>::iterator end_dpL =
9178  sizeDependParamList.end();
9179  for( ; it_dpL != end_dpL; ++it_dpL )
9180  delete (*it_dpL);
9181 
9182  sizeDependParamList.clear ();
9183 
9184  return true;
9185  }
9186 
9187 //-----------------------------------------------------------------------------
9188 // MOSFET_B3 Master functions:
9189 //-----------------------------------------------------------------------------
9190 
9191 //-----------------------------------------------------------------------------
9192 // Function : Master::updateState
9193 // Purpose :
9194 // Special Notes :
9195 // Scope : public
9196 // Creator : Eric Keiter, SNL
9197 // Creation Date : 12/02/08
9198 //-----------------------------------------------------------------------------
9199  bool Master::updateState (double * solVec, double * staVec, double * stoVec)
9200  {
9201  bool bsuccess = true;
9202  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9203  {
9204  Instance & mi = *(*it);
9205 
9206  bool btmp = mi.updateIntermediateVars ();
9207  bsuccess = bsuccess && btmp;
9208 
9209  // voltage drops:
9210  double * stoVec = mi.extData.nextStoVectorRawPtr;
9211  stoVec[mi.li_store_vbs] = mi.vbs;
9212  stoVec[mi.li_store_vgs] = mi.vgs;
9213  stoVec[mi.li_store_vds] = mi.vds;
9214  stoVec[mi.li_store_vbd] = mi.vbd;
9215  stoVec[mi.li_store_von] = mi.von;
9216 
9217  // intrinsic capacitors:
9218  staVec[mi.li_state_qb] = mi.qb;
9219  staVec[mi.li_state_qg] = mi.qg;
9220  staVec[mi.li_state_qd] = mi.qd;
9221 
9222  // parasitic capacitors:
9223  staVec[mi.li_state_qbs] = mi.qbs;
9224  staVec[mi.li_state_qbd] = mi.qbd;
9225 
9226  if( mi.nqsMod )
9227  {
9228  staVec[mi.li_state_qcheq] = mi.qcheq;
9229  staVec[mi.li_state_qcdump] = mi.qcdump;
9230  }
9231 
9232  // if this is the first newton step of the first time step
9233  // of the transient simulation, we need to enforce that the
9234  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
9235  // compatibility. ERK.
9236 
9237  // Note: I think this kind of thing is enforced (or should be enforced,
9238  // anyway) at the time integration level. So I'm not sure this step is
9239  // really needed, at least for new-DAE. Derivatives out of the DCOP
9240  // are supposed to be zero at the first newton step.
9241 
9242  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
9243  {
9244  // re-set the state vector pointer that we are using to the "current"
9245  // pointer, rather than the "next" pointer.
9246  double * currStaVec = mi.extData.currStaVectorRawPtr;
9247 
9248  // intrinsic capacitors:
9249  currStaVec[mi.li_state_qb] = mi.qb;
9250  currStaVec[mi.li_state_qg] = mi.qg;
9251  currStaVec[mi.li_state_qd] = mi.qd;
9252 
9253  // parasitic capacitors:
9254  currStaVec[mi.li_state_qbs] = mi.qbs;
9255  currStaVec[mi.li_state_qbd] = mi.qbd;
9256 
9257  if( mi.nqsMod )
9258  {
9259  currStaVec[mi.li_state_qcheq] = mi.qcheq;
9260  currStaVec[mi.li_state_qcdump] = mi.qcdump;
9261  }
9262  }
9263  }
9264 
9265  return bsuccess;
9266  }
9267 
9268 //-----------------------------------------------------------------------------
9269 // Function : Master::loadDAEVectors
9270 // Purpose :
9271 // Special Notes :
9272 // Scope : public
9273 // Creator : Eric Keiter, SNL
9274 // Creation Date : 12/02/08
9275 //-----------------------------------------------------------------------------
9276 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ)
9277  {
9278  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9279  {
9280  Instance & mi = *(*it);
9281 
9282  double * dFdxdVp = mi.extData.dFdxdVpVectorRawPtr;
9283  double * dQdxdVp = mi.extData.dQdxdVpVectorRawPtr;
9284 
9285  double coef(0.0);
9286  // F-vector:
9287  mi.cdreq_Jdxp = 0.0;
9288  mi.ceqbd_Jdxp = 0.0;
9289  mi.ceqbs_Jdxp = 0.0;
9290 
9291  // Do a few auxilliary calculations, derived from 3f5.
9292  // load current vector
9293  if (mi.mode >= 0)
9294  {
9295  mi.Gm = mi.gm;
9296  mi.Gmbs = mi.gmbs;
9297  mi.FwdSum = mi.Gm + mi.Gmbs;
9298  mi.RevSum = 0.0;
9299 
9300  mi.cdreq = mi.model_.dtype * (mi.cd);
9301  mi.ceqbd = -mi.model_.dtype * (mi.csub);
9302 
9303  mi.ceqbs = 0.0;
9304 
9305  mi.gbbdp = -mi.gbds;
9306  mi.gbbsp = (mi.gbds + mi.gbgs + mi.gbbs);
9307 
9308  mi.gbdpg = mi.gbgs;
9309  mi.gbdpdp = mi.gbds;
9310  mi.gbdpb = mi.gbbs;
9311  mi.gbdpsp = -(mi.gbdpg + mi.gbdpdp + mi.gbdpb);
9312 
9313  mi.gbspg = 0.0;
9314  mi.gbspdp = 0.0;
9315  mi.gbspb = 0.0;
9316  mi.gbspsp = 0.0;
9317  }
9318  else
9319  {
9320  mi.Gm = -mi.gm;
9321  mi.Gmbs = -mi.gmbs;
9322  mi.FwdSum = 0.0;
9323  mi.RevSum = -(mi.Gm + mi.Gmbs);
9324 
9325  mi.cdreq = -mi.model_.dtype * (mi.cd);
9326  mi.ceqbs = -mi.model_.dtype * (mi.csub);
9327 
9328  mi.ceqbd = 0.0;
9329 
9330  mi.gbbsp = -mi.gbds;
9331  mi.gbbdp = (mi.gbds + mi.gbgs + mi.gbbs);
9332 
9333  mi.gbdpg = 0.0;
9334  mi.gbdpsp = 0.0;
9335  mi.gbdpb = 0.0;
9336  mi.gbdpdp = 0.0;
9337 
9338  mi.gbspg = mi.gbgs;
9339  mi.gbspsp = mi.gbds;
9340  mi.gbspb = mi.gbbs;
9341  mi.gbspdp = -(mi.gbspg + mi.gbspsp + mi.gbspb);
9342  }
9343 
9344  if (mi.model_.dtype > 0)
9345  {
9346  mi.ceqbs += (mi.cbs);
9347  mi.ceqbd += (mi.cbd);
9348  }
9349  else
9350  {
9351  mi.ceqbs -= (mi.cbs);
9352  mi.ceqbd -= (mi.cbd);
9353  }
9354 
9355  if (mi.drainConductance != 0.0)
9356  {
9357  fVec[mi.li_Drain] += mi.Idrain*mi.numberParallel;
9358  }
9359  if (mi.sourceConductance != 0.0)
9360  {
9361  fVec[mi.li_Source] += mi.Isource*mi.numberParallel;
9362  }
9363 
9364  fVec[mi.li_Bulk] += (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9365  fVec[mi.li_DrainPrime] += (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9366  fVec[mi.li_SourcePrime] += (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9367 
9368  if( mi.loadLeadCurrent )
9369  {
9370  if (mi.drainConductance != 0.0)
9371  {
9372  storeLeadF[mi.li_store_dev_id] = mi.Idrain*mi.numberParallel;
9373  }
9374  else
9375  {
9376  storeLeadF[mi.li_store_dev_id] = (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9377  }
9378  if (mi.sourceConductance != 0.0)
9379  {
9380  storeLeadF[mi.li_store_dev_is] = mi.Isource*mi.numberParallel;
9381  }
9382  else
9383  {
9384  storeLeadF[mi.li_store_dev_is] = (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9385  }
9386  storeLeadF[mi.li_store_dev_ig] = 0.0;
9387  storeLeadF[mi.li_store_dev_ib] = (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9388  }
9389 
9390  // Initial condition support
9391 
9392  if( getSolverState().dcopFlag && mi.icVDSGiven )
9393  {
9394  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ids];
9395  fVec[mi.li_Drain] += coef;
9396  fVec[mi.li_Source] += -coef;
9397  if( mi.loadLeadCurrent )
9398  {
9399  storeLeadF[mi.li_store_dev_id]= coef;
9400  storeLeadF[mi.li_store_dev_is]= -coef;
9401  }
9402  }
9403 
9404  if( getSolverState().dcopFlag && mi.icVGSGiven )
9405  {
9406  coef = mi.extData.nextSolVectorRawPtr[mi.li_Igs];
9407  fVec[mi.li_Gate] += coef;
9408  fVec[mi.li_Source] += -coef;
9409  if( mi.loadLeadCurrent )
9410  {
9411  storeLeadF[mi.li_store_dev_ig]= coef;
9412  storeLeadF[mi.li_store_dev_is]= -coef;
9413  }
9414  }
9415 
9416 
9417  if( getSolverState().dcopFlag && mi.icVBSGiven )
9418  {
9419  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ibs];
9420  fVec[mi.li_Bulk] += coef;
9421  fVec[mi.li_Source] += -coef;
9422  if( mi.loadLeadCurrent )
9423  {
9424  storeLeadF[mi.li_store_dev_ib]= coef;
9425  storeLeadF[mi.li_store_dev_is]= -coef;
9426  }
9427  }
9428 
9429  //////////////////////////////////////////////////
9430  // limiting section:
9432  {
9433  if (!mi.origFlag)
9434  {
9435  if (mi.mode >= 0)
9436  {
9437  // option 1
9438  double tmp = mi.model_.dtype * (-mi.gds * (mi.vds-mi.vds_orig) -
9439  mi.Gm * (mi.vgs-mi.vgs_orig) -
9440  mi.Gmbs * (mi.vbs-mi.vbs_orig));
9441 
9442  mi.cdreq_Jdxp += tmp;
9443  mi.cdreq += tmp;
9444 
9445  tmp = -mi.model_.dtype * (-mi.gbds * (mi.vds-mi.vds_orig) -
9446  mi.gbgs * (mi.vgs-mi.vgs_orig) -
9447  mi.gbbs * (mi.vbs-mi.vbs_orig));
9448  mi.ceqbd_Jdxp += tmp;
9449  mi.ceqbd += tmp;
9450  }
9451  else
9452  {
9453  // option 2
9454  double tmp = -mi.model_.dtype * (mi.gds * (mi.vds-mi.vds_orig) +
9455  mi.Gm * (mi.vgd-mi.vgd_orig) +
9456  mi.Gmbs * (mi.vbd-mi.vbd_orig));
9457  mi.cdreq_Jdxp += tmp;
9458  mi.cdreq += tmp;
9459 
9460  tmp = -mi.model_.dtype * (mi.gbds * (mi.vds-mi.vds_orig) -
9461  mi.gbgs * (mi.vgd-mi.vgd_orig) -
9462  mi.gbbs * (mi.vbd-mi.vbd_orig));
9463  mi.ceqbd_Jdxp += tmp;
9464  mi.ceqbd += tmp;
9465  }
9466 
9467 
9468  if (mi.model_.dtype > 0)
9469  {
9470  mi.ceqbs_Jdxp += (-mi.gbs*(mi.vbs-mi.vbs_orig));
9471  mi.ceqbs += (-mi.gbs*(mi.vbs-mi.vbs_orig));
9472 
9473  mi.ceqbd_Jdxp += (-mi.gbd*(mi.vbd-mi.vbd_orig));
9474  mi.ceqbd += (-mi.gbd*(mi.vbd-mi.vbd_orig));
9475  }
9476  else
9477  {
9478  mi.ceqbs_Jdxp -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
9479  mi.ceqbs -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
9480 
9481  mi.ceqbd_Jdxp -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
9482  mi.ceqbd -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
9483  }
9484 
9485  dFdxdVp[mi.li_Bulk] += -(mi.ceqbs_Jdxp+mi.ceqbd_Jdxp)*mi.numberParallel;
9486  dFdxdVp[mi.li_DrainPrime] += (mi.ceqbd_Jdxp-mi.cdreq_Jdxp)*mi.numberParallel;
9487  dFdxdVp[mi.li_SourcePrime] += (mi.cdreq_Jdxp+mi.ceqbs_Jdxp)*mi.numberParallel;
9488 
9489  } // orig flag.
9490  } // voltage limiter flag
9491 
9492  // Row associated with icVBS
9493  if( getSolverState().dcopFlag && mi.icVBSGiven )
9494  {
9495  // get the voltage drop from the previous solution
9496  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9497  double cVb = mi.extData.nextSolVectorRawPtr[mi.li_Bulk];
9498 
9499  fVec[mi.li_Ibs] += (cVb - cVs - mi.icVBS);
9500  }
9501 
9502  // Row associated with icVDS
9503  if( getSolverState().dcopFlag && mi.icVDSGiven )
9504  {
9505  // get the voltage drop from the previous solution
9506  double cVd = mi.extData.nextSolVectorRawPtr[mi.li_Drain];
9507  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9508 
9509  fVec[mi.li_Ids] += (cVd - cVs - mi.icVDS);
9510  }
9511 
9512  // Row associated with icVGS
9513  if( getSolverState().dcopFlag && mi.icVGSGiven )
9514  {
9515  // get the voltage drop from the previous solution
9516  double cVg = mi.extData.nextSolVectorRawPtr[mi.li_Gate];
9517  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9518 
9519  fVec[mi.li_Igs] += (cVg - cVs - mi.icVGS);
9520  }
9521 
9522  // Q-vector:
9523 
9524  mi.auxChargeCalculations ();
9525 
9526  double Qeqqg = 0.0; // gate charge
9527  double Qeqqb = 0.0; // bulk charge
9528  double Qeqqd = 0.0; // drain charge
9529  double Qqdef = 0.0; // nqs-related charge.
9530  double Qqcheq = 0.0; // nqs-related charge.
9531 
9532  // These 3 vars are class variables, and are set up elsewhere.
9533  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
9534  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
9535  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
9536 
9537  if (mi.model_.dtype > 0)
9538  {
9539  Qeqqg = mi.qg;
9540  Qeqqb = mi.qb;
9541  Qeqqd = mi.qd;
9542  Qqdef = mi.qcdump; // this needs to be fixed...
9543  Qqcheq = mi.qcheq;
9544  }
9545  else // need to convert these to charges.
9546  {
9547  Qeqqg = -mi.qg;
9548  Qeqqb = -mi.qb;
9549  Qeqqd = -mi.qd;
9550  Qqdef = -mi.qcdump;
9551  Qqcheq = -mi.qcheq;
9552  }
9553 
9554  qVec[mi.li_Gate] += Qeqqg*mi.numberParallel;
9555  qVec[mi.li_Bulk] += (Qeqqb)*mi.numberParallel;
9556  qVec[mi.li_DrainPrime] += (-(-Qeqqd))*mi.numberParallel;
9557  qVec[mi.li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
9558 
9559  if (mi.nqsMod)
9560  {
9561  // 7 equ. for nqs modification. charge equation.
9562  qVec[mi.li_Charge] += -(Qqcheq - Qqdef)*mi.numberParallel;
9563  }
9564 
9565  if( mi.loadLeadCurrent )
9566  {
9567  if (mi.drainConductance == 0.0)
9568  {
9569  storeLeadQ[mi.li_store_dev_id] = (-(-Qeqqd))*mi.numberParallel;
9570  }
9571  if (mi.sourceConductance == 0.0)
9572  {
9573  storeLeadQ[mi.li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
9574  }
9575  storeLeadQ[mi.li_store_dev_ig] = Qeqqg*mi.numberParallel;
9576  storeLeadQ[mi.li_store_dev_ib] = (Qeqqb)*mi.numberParallel;
9577  }
9578 
9579  //////////////////////////////////////////////////
9580  // limiting section:
9582  {
9583  // Need the following:
9584  // Qeqqg_Jdxp
9585  // Qeqqb_Jdxp
9586  // Qeqqd_Jdxp
9587  if (mi.model_.dtype > 0)
9588  {
9589 #if 0
9590  // no-op:
9591  mi.Qeqqg_Jdxp = mi.Qeqqg_Jdxp;
9592  mi.Qeqqb_Jdxp = mi.Qeqqb_Jdxp;
9593  mi.Qeqqd_Jdxp = mi.Qeqqd_Jdxp;
9594 #endif
9595  }
9596  else
9597  {
9598  mi.Qeqqg_Jdxp = -mi.Qeqqg_Jdxp;
9599  mi.Qeqqb_Jdxp = -mi.Qeqqb_Jdxp;
9600  mi.Qeqqd_Jdxp = -mi.Qeqqd_Jdxp;
9601  }
9602 
9603  if (!mi.origFlag)
9604  {
9605  dQdxdVp[mi.li_Gate] += -mi.Qeqqg_Jdxp*mi.numberParallel;
9606  dQdxdVp[mi.li_Bulk] += -(+mi.Qeqqb_Jdxp)*mi.numberParallel;
9607  dQdxdVp[mi.li_DrainPrime] += (-mi.Qeqqd_Jdxp)*mi.numberParallel;
9608  dQdxdVp[mi.li_SourcePrime] += (+mi.Qeqqg_Jdxp+mi.Qeqqb_Jdxp+mi.Qeqqd_Jdxp) *mi.numberParallel;
9609  } // orig flag.
9610  } // limiter flag
9611  }
9612  return true;
9613  }
9614 
9615 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
9616 //-----------------------------------------------------------------------------
9617 // Function : Master::loadDAEMatrices
9618 // Purpose :
9619 // Special Notes :
9620 // Scope : public
9621 // Creator : Eric Keiter, SNL
9622 // Creation Date : 12/02/08
9623 //-----------------------------------------------------------------------------
9624  bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
9625  {
9626  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9627  {
9628  Instance & mi = *(*it);
9629 
9630  // F-matrix:
9631  // Row corresponding to the KCL for the drain node:
9632 
9635 
9638 
9639  // Extra term for initial conditions on Vds in operating point
9640  if( getSolverState().dcopFlag && mi.icVDSGiven )
9641  {
9642  *mi.f_DrainEquIdsPtr += 1.0;
9643  }
9644 
9645  // Row corresponding to the KCL for the source node:
9646 
9649 
9652 
9653  // Extra term for initial conditions on Vbs in operating point
9654  if( getSolverState().dcopFlag && mi.icVBSGiven )
9655  {
9656  *mi.f_SourceEquIbsPtr -= 1.0;
9657  }
9658  // Extra term for initial conditions on Vds in operating point
9659  if( getSolverState().dcopFlag && mi.icVDSGiven )
9660  {
9661  *mi.f_SourceEquIdsPtr -= 1.0;
9662  }
9663  // Extra term for initial conditions on Vgs in operating point
9664  if( getSolverState().dcopFlag && mi.icVGSGiven )
9665  {
9666  *mi.f_SourceEquIgsPtr -= 1.0;
9667  }
9668 
9669  // Row corresponding to the KCL for the gate node: NOTHING
9670  // Check this later. ERK.
9671  //
9672  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
9673  // belong here. I'm not sure aboug the gg terms. On one hand, the
9674  // rhs vector component for the gate node ONLY seems to take
9675  // capacitive currents, which implies that all of these are capacitive
9676  // conductances. On the other hand, the gg terms do not appear to
9677  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
9678  // capacitive conductances are of the form g = C/dt, and the gg terms
9679  // do not have this form.
9680  //
9681  // For now, the gg issue is moot b/c those terms are only nonzero
9682  // if mi.nqsMod = 1, which is not a supported option.
9683 
9684  // However, the gg
9685  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
9686  //
9687  //(*JMatPtr)[GateEquGateNodePtr
9688  // += (gcggb - mi.ggtg)*mi.numberParallel;
9689  //(*JMatPtr)[GateEquBulkNodePtr
9690  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
9691  //(*JMatPtr)[GateEquDrainPrimeNodePtr
9692  // += (gcgdb - ggtd)*mi.numberParallel;
9693  //(*JMatPtr)[GateEquSourcePrimeNodePtr
9694  // += (gcgsb - ggts)*mi.numberParallel;
9695 
9696  // initial conditions on gate node
9697  // Extra term for initial conditions on Vgs in operating point
9698  if( getSolverState().dcopFlag && mi.icVGSGiven )
9699  {
9700  *mi.f_GateEquIgsPtr += 1.0;
9701  }
9702 
9703  // Row corresponding to the KCL for the bulk node:
9704 
9706  += (- mi.gbgs)*mi.numberParallel;
9707 
9708 
9710  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
9711 
9712 
9714  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
9715 
9716 
9718  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
9719 
9720  // Extra term for initial conditions on Vbs in operating point
9721  if( getSolverState().dcopFlag && mi.icVBSGiven )
9722  {
9723  *mi.f_BulkEquIbsPtr += 1.0;
9724  }
9725 
9726  // Row corresponding to the KCL for the drain prime node:
9727 
9730 
9732  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
9733  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
9734 
9736  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
9737  *mi.numberParallel;
9738 
9740  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
9741  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
9742 
9744  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
9745  *mi.numberParallel;
9746 
9747  // Row corresponding to the KCL for the source prime node:
9749  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
9750  *mi.numberParallel;
9751 
9753  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
9754  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
9755 
9758 
9760  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
9761  *mi.numberParallel;
9762 
9764  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
9765  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
9766 
9767  // Row associated with the charge equation
9768  if (mi.nqsMod)
9769  {
9770  std::string msg;
9771  msg = "Instance::loadDAEMatrices";
9772  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
9773  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
9774  }
9775 
9776  // Initial condition rows
9777  // Row associated with mi.icVBS
9778  if( mi.icVBSGiven )
9779  {
9780  if( getSolverState().dcopFlag )
9781  {
9782  *mi.f_icVBSEquVbPtr += 1.0;
9783  *mi.f_icVBSEquVsPtr -= 1.0;
9784  }
9785  else
9786  {
9787  *mi.f_icVBSEquIbsPtr += 1.0;
9788  }
9789  }
9790 
9791  // Row associated with mi.icVDS
9792  if( mi.icVDSGiven )
9793  {
9794  if( getSolverState().dcopFlag )
9795  {
9796  *mi.f_icVDSEquVdPtr += 1.0;
9797  *mi.f_icVDSEquVsPtr -= 1.0;
9798  }
9799  else
9800  {
9801  *mi.f_icVDSEquIdsPtr += 1.0;
9802  }
9803  }
9804 
9805  // Row associated with mi.icVGS
9806  if( mi.icVGSGiven )
9807  {
9808  if( getSolverState().dcopFlag )
9809  {
9810  *mi.f_icVGSEquVgPtr += 1.0;
9811  *mi.f_icVGSEquVsPtr -= 1.0;
9812  }
9813  else
9814  {
9815  *mi.f_icVGSEquIgsPtr += 1.0;
9816  }
9817  }
9818 
9819 
9820  // Q-matrix:
9821  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
9822  {
9823  // do nothing, as for this special case q is always zero.
9824  }
9825  else
9826  {
9827  // Row corresponding to the KCL for the drain node: NOTHING
9828 
9829  // Row corresponding to the KCL for the source node: NOTHING
9830 
9831  // Row corresponding to the KCL for the gate node:
9832  // Check this later. ERK. See the comments in the function
9833  // loadDAE*mi.q_, regarding ggtg, ggtb, etc.
9834  //
9835  // For now I am leaving out the gg terms, as they are zero when
9836  // nqsMod=0, which is always true.
9837  //
9839  += (mi.CAPcggb )*mi.numberParallel;
9841  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
9843  += (mi.CAPcgdb )*mi.numberParallel;
9845  += (mi.CAPcgsb )*mi.numberParallel;
9846 
9847  // Row corresponding to the KCL for the bulk node:
9849  += (mi.CAPcbgb)*mi.numberParallel;
9850 
9852  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
9853 
9855  += (mi.CAPcbdb)*mi.numberParallel;
9856 
9858  += (mi.CAPcbsb)*mi.numberParallel;
9859 
9860 
9861  // Row corresponding to the KCL for the drain prime node:
9863  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
9864 
9866  += (mi.CAPcdgb) *mi.numberParallel;
9867 
9869  += (+ mi.CAPcddb )*mi.numberParallel;
9870 
9872  -= (- mi.CAPcdsb) *mi.numberParallel;
9873 
9874  // Row corresponding to the KCL for the source prime node:
9876  += (mi.CAPcsgb) *mi.numberParallel;
9877 
9879  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
9880 
9882  -= (- mi.CAPcsdb) *mi.numberParallel;
9883 
9885  += (+ mi.CAPcssb) *mi.numberParallel;
9886 
9887  // Row associated with the charge equation
9888  // This is currently not supported.
9889  if (mi.nqsMod)
9890  {
9891  std::string msg;
9892  msg = "Master::loadDAEMatrices";
9893  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
9894  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
9895  }
9896  }
9897  }
9898  return true;
9899  }
9900 
9901 #else
9902 //-----------------------------------------------------------------------------
9903 // Function : Master::loadDAEMatrices
9904 // Purpose :
9905 // Special Notes :
9906 // Scope : public
9907 // Creator : Eric Keiter, SNL
9908 // Creation Date : 12/02/08
9909 //-----------------------------------------------------------------------------
9910  bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
9911  {
9912  int sizeInstances = instanceContainer_.size();
9913  for (int i=0; i<sizeInstances; ++i)
9914  {
9915  Instance & mi = *(instanceContainer_.at(i));
9916 
9917  int count = 0;
9918  // F-matrix:
9919  // Row corresponding to the KCL for the drain node:
9920 
9921  dFdx [mi.li_Drain][mi.ADrainEquDrainNodeOffset]
9923 
9926 
9927  // Extra term for initial conditions on Vds in operating point
9928  if( getSolverState().dcopFlag && mi.icVDSGiven )
9929  {
9930  dFdx[mi.li_Drain][mi.ADrainEquIdsOffset] += 1.0;
9931  }
9932 
9933  // Row corresponding to the KCL for the source node:
9934 
9937 
9940 
9941  // Extra term for initial conditions on Vbs in operating point
9942  if( getSolverState().dcopFlag && mi.icVBSGiven )
9943  {
9944  dFdx[mi.li_Source][mi.ASourceEquIbsOffset] -= 1.0;
9945  }
9946  // Extra term for initial conditions on Vds in operating point
9947  if( getSolverState().dcopFlag && mi.icVDSGiven )
9948  {
9949  dFdx[mi.li_Source][mi.ASourceEquIdsOffset] -= 1.0;
9950  }
9951  // Extra term for initial conditions on Vgs in operating point
9952  if( getSolverState().dcopFlag && mi.icVGSGiven )
9953  {
9954  dFdx[mi.li_Source][mi.ASourceEquIgsOffset] -= 1.0;
9955  }
9956 
9957  // Row corresponding to the KCL for the gate node: NOTHING
9958  // Check this later. ERK.
9959  //
9960  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
9961  // belong here. I'm not sure aboug the gg terms. On one hand, the
9962  // rhs vector component for the gate node ONLY seems to take
9963  // capacitive currents, which implies that all of these are capacitive
9964  // conductances. On the other hand, the gg terms do not appear to
9965  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
9966  // capacitive conductances are of the form g = C/dt, and the gg terms
9967  // do not have this form.
9968  //
9969  // For now, the gg issue is moot b/c those terms are only nonzero
9970  // if mi.nqsMod = 1, which is not a supported option.
9971 
9972  // However, the gg
9973  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
9974  //
9975  //(*JMatPtr)[mi.li_Gate][mi.AGateEquGateNodeOffset]
9976  // += (gcggb - mi.ggtg)*mi.numberParallel;
9977  //(*JMatPtr)[mi.li_Gate][mi.AGateEquBulkNodeOffset]
9978  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
9979  //(*JMatPtr)[mi.li_Gate][mi.AGateEquDrainPrimeNodeOffset]
9980  // += (gcgdb - ggtd)*mi.numberParallel;
9981  //(*JMatPtr)[mi.li_Gate][mi.AGateEquSourcePrimeNodeOffset]
9982  // += (gcgsb - ggts)*mi.numberParallel;
9983 
9984  // initial conditions on gate node
9985  // Extra term for initial conditions on Vgs in operating point
9986  if( getSolverState().dcopFlag && mi.icVGSGiven )
9987  {
9988  dFdx[mi.li_Gate][mi.AGateEquIgsOffset] += 1.0;
9989  }
9990 
9991  // Row corresponding to the KCL for the bulk node:
9992 
9993  dFdx [mi.li_Bulk][mi.ABulkEquGateNodeOffset]
9994  += (- mi.gbgs)*mi.numberParallel;
9995 
9996 
9997  dFdx [mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
9998  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
9999 
10000 
10002  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
10003 
10004 
10006  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
10007 
10008  // Extra term for initial conditions on Vbs in operating point
10009  if( getSolverState().dcopFlag && mi.icVBSGiven )
10010  {
10011  dFdx[mi.li_Bulk][mi.ABulkEquIbsOffset] += 1.0;
10012  }
10013 
10014  // Row corresponding to the KCL for the drain prime node:
10015 
10018 
10019 
10021  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
10022  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
10023 
10024 
10026  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
10027  *mi.numberParallel;
10028 
10029 
10031  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
10032  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
10033 
10034 
10036  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
10037  *mi.numberParallel;
10038 
10039  // Row corresponding to the KCL for the source prime node:
10040 
10042  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
10043  *mi.numberParallel;
10044 
10045 
10047  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
10048  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
10049 
10050 
10053 
10054 
10056  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
10057  *mi.numberParallel;
10058 
10059 
10061  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
10062  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
10063 
10064  // Row associated with the charge equation
10065  if (mi.nqsMod)
10066  {
10067  std::string msg;
10068  msg = "Master::loadDAEMatrices";
10069  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10070  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10071  }
10072 
10073  // Initial condition rows
10074  // Row associated with mi.icVBS
10075  if( mi.icVBSGiven )
10076  {
10077  if( getSolverState().dcopFlag )
10078  {
10079  dFdx[mi.li_Ibs][mi.icVBSEquVbOffset] += 1.0;
10080  dFdx[mi.li_Ibs][mi.icVBSEquVsOffset] -= 1.0;
10081  }
10082  else
10083  {
10084  dFdx[mi.li_Ibs][mi.icVBSEquIbsOffset] += 1.0;
10085  }
10086  }
10087 
10088  // Row associated with mi.icVDS
10089  if( mi.icVDSGiven )
10090  {
10091  if( getSolverState().dcopFlag )
10092  {
10093  dFdx[mi.li_Ids][mi.icVDSEquVdOffset] += 1.0;
10094  dFdx[mi.li_Ids][mi.icVDSEquVsOffset] -= 1.0;
10095  }
10096  else
10097  {
10098  dFdx[mi.li_Ids][mi.icVDSEquIdsOffset] += 1.0;
10099  }
10100  }
10101 
10102  // Row associated with mi.icVGS
10103  if( mi.icVGSGiven )
10104  {
10105  if( getSolverState().dcopFlag )
10106  {
10107  dFdx[mi.li_Igs][mi.icVGSEquVgOffset] += 1.0;
10108  dFdx[mi.li_Igs][mi.icVGSEquVsOffset] -= 1.0;
10109  }
10110  else
10111  {
10112  dFdx[mi.li_Igs][mi.icVGSEquIgsOffset] += 1.0;
10113  }
10114  }
10115 
10116 
10117  // Q-matrix:
10118  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
10119  {
10120  // do nothing, as for this special case q is always zero.
10121  }
10122  else
10123  {
10124  // Row corresponding to the KCL for the drain node: NOTHING
10125 
10126  // Row corresponding to the KCL for the source node: NOTHING
10127 
10128  // Row corresponding to the KCL for the gate node:
10129  // Check this later. ERK. See the comments in the function
10130  // loadDAEdQdx, regarding ggtg, ggtb, etc.
10131  //
10132  // For now I am leaving out the gg terms, as they are zero when
10133  // nqsMod=0, which is always true.
10134  //
10135  dQdx[mi.li_Gate][mi.AGateEquGateNodeOffset]
10136  += (mi.CAPcggb )*mi.numberParallel;
10137  dQdx[mi.li_Gate][mi.AGateEquBulkNodeOffset]
10138  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
10140  += (mi.CAPcgdb )*mi.numberParallel;
10142  += (mi.CAPcgsb )*mi.numberParallel;
10143 
10144  // Row corresponding to the KCL for the bulk node:
10145  dQdx[mi.li_Bulk][mi.ABulkEquGateNodeOffset]
10146  += (mi.CAPcbgb)*mi.numberParallel;
10147 
10148  dQdx[mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
10149  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
10150 
10152  += (mi.CAPcbdb)*mi.numberParallel;
10153 
10155  += (mi.CAPcbsb)*mi.numberParallel;
10156 
10157 
10158  // Row corresponding to the KCL for the drain prime node:
10160  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
10161 
10163  += (mi.CAPcdgb) *mi.numberParallel;
10164 
10166  += (+ mi.CAPcddb )*mi.numberParallel;
10167 
10169  -= (- mi.CAPcdsb) *mi.numberParallel;
10170 
10171  // Row corresponding to the KCL for the source prime node:
10173  += (mi.CAPcsgb) *mi.numberParallel;
10174 
10176  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
10177 
10179  -= (- mi.CAPcsdb) *mi.numberParallel;
10180 
10182  += (+ mi.CAPcssb) *mi.numberParallel;
10183 
10184  // Row associated with the charge equation
10185  // This is currently not supported.
10186  if (mi.nqsMod)
10187  {
10188  std::string msg;
10189  msg = "Master::loadDAEMatrices";
10190  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10191  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10192  }
10193  }
10194  }
10195  return true;
10196  }
10197 #endif
10198 
10199  Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
10200  {
10201 
10202  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
10203  }
10204 
10206  {
10208  .registerDevice("m", 9)
10209  .registerDevice("m", 49)
10210  .registerModelType("pmos", 9)
10211  .registerModelType("nmos", 9)
10212  .registerModelType("pmos", 49)
10213  .registerModelType("nmos", 49);
10214  }
10215 
10216 } // namespace MOSFET_B3
10217 } // namespace Device
10218 } // namespace Xyce
10219