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.372.2.3 $
43 //
44 //
45 // Current Owner : $Author: tvrusso $
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  // set up the internal names map
2935  std::string tmpstr;
2936  if ( drainConductance!=0.0 )
2937  {
2938  tmpstr = getName()+"_drainprime";
2939  spiceInternalName (tmpstr);
2940  intNameMap[ li_DrainPrime ] = tmpstr;
2941  }
2942 
2943  if ( sourceConductance != 0.0 )
2944  {
2945  tmpstr = getName()+"_sourceprime";
2946  spiceInternalName (tmpstr);
2947  intNameMap[ li_SourcePrime ] = tmpstr;
2948  }
2949  if (icVDSGiven)
2950  {
2951  tmpstr = getName()+"_branch_DS";
2952  spiceInternalName (tmpstr);
2953  intNameMap[li_Ids] = tmpstr;
2954  }
2955  if (icVGSGiven)
2956  {
2957  tmpstr = getName()+"_branch_GS";
2958  spiceInternalName (tmpstr);
2959  intNameMap[li_Igs] = tmpstr;
2960  }
2961  if (icVBSGiven)
2962  {
2963  tmpstr = getName()+"_branch_BS";
2964  spiceInternalName (tmpstr);
2965  intNameMap[li_Ibs] = tmpstr;
2966  }
2967  }
2968 
2969  return intNameMap;
2970 }
2971 
2972 
2973 //-----------------------------------------------------------------------------
2974 // Function : Instance::getStoreNameMap
2975 // Purpose :
2976 // Special Notes :
2977 // Scope : public
2978 // Creator : Richard Schiek, Electrical Systems Modeling
2979 // Creation Date : 4/3/2013
2980 //-----------------------------------------------------------------------------
2981 std::map<int,std::string> & Instance::getStoreNameMap ()
2982 {
2983  // set up the internal name map, if it hasn't been already.
2984  if( loadLeadCurrent && storeNameMap.empty ())
2985  {
2986  // change subcircuitname:devicetype_deviceName to
2987  // devicetype:subcircuitName:deviceName
2988  std::string modName(getName());
2989  spiceInternalName(modName);
2990  std::string tmpstr;
2991  tmpstr = modName+":DEV_ID";
2992  storeNameMap[ li_store_dev_id ] = tmpstr;
2993  tmpstr = modName+":DEV_IG";
2994  storeNameMap[ li_store_dev_ig ] = tmpstr;
2995  tmpstr = modName+":DEV_IS";
2996  storeNameMap[ li_store_dev_is ] = tmpstr;
2997  tmpstr = modName+":DEV_IB";
2998  storeNameMap[ li_store_dev_ib ] = tmpstr;
2999  }
3000 
3001  return storeNameMap;
3002 }
3003 //-----------------------------------------------------------------------------
3004 // Function : Instance::registerStateLIDs
3005 // Purpose :
3006 // Special Notes :
3007 // Scope : public
3008 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3009 // Creation Date : 6/21/02
3010 //-----------------------------------------------------------------------------
3011 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
3012 {
3013  AssertLIDs(staLIDVecRef.size() == numStateVars);
3014 
3015 #ifdef Xyce_DEBUG_DEVICE
3016  if (getDeviceOptions().debugLevel > 0)
3017  {
3018  Xyce::dout() << std::endl;
3019  Xyce::dout() << section_divider << std::endl;
3020  Xyce::dout() << " In Instance::registerStateLIDs\n\n";
3021  Xyce::dout() << " name = " << getName() << std::endl;
3022  Xyce::dout() << " Number of State LIDs: " << numStateVars << std::endl;
3023  }
3024 #endif
3025 
3026  // Copy over the global ID lists:
3027  staLIDVec = staLIDVecRef;
3028 
3029  int lid=0;
3030  // Intrinsic capacitors:
3031  li_state_qb = staLIDVec[lid++];
3032  li_state_qg = staLIDVec[lid++];
3033  li_state_qd = staLIDVec[lid++];
3034 
3035  // Parasitic capacitors:
3036  li_state_qbs = staLIDVec[lid++];
3037  li_state_qbd = staLIDVec[lid++];
3038 
3039  // state variables, cheq
3040  li_state_qcheq = staLIDVec[lid++];
3041 
3042  // state variables, cdump
3043  li_state_qcdump = staLIDVec[lid++];
3044 
3045  // state variable, qdef
3046  li_state_qdef = staLIDVec[lid++];
3047 
3048 
3049 #ifdef Xyce_DEBUG_DEVICE
3050  if (getDeviceOptions().debugLevel > 0)
3051  {
3052  Xyce::dout() << " Local State indices:" << std::endl;
3053  Xyce::dout() << std::endl;
3054  Xyce::dout() << " li_state_qb = " << li_state_qb << std::endl;
3055  Xyce::dout() << " li_state_qg = " << li_state_qg << std::endl;
3056  Xyce::dout() << " li_state_qd = " << li_state_qd << std::endl;
3057  Xyce::dout() << " li_state_qbs = " << li_state_qbs << std::endl;
3058  Xyce::dout() << " li_state_qbd = " << li_state_qbd << std::endl;
3059  Xyce::dout() << " li_state_qcheq = " << li_state_qcheq << std::endl;
3060  Xyce::dout() << " li_state_qcdump = " << li_state_qcdump << std::endl;
3061  Xyce::dout() << " li_state_qdef = " << li_state_qdef << std::endl;
3062  Xyce::dout() << section_divider << std::endl;
3063  }
3064 #endif
3065 
3066 }
3067 
3068 //-----------------------------------------------------------------------------
3069 // Function : Instance::registerStoreLIDs
3070 // Purpose :
3071 // Special Notes :
3072 // Scope : public
3073 // Creator : Eric Keiter, SNL
3074 // Creation Date : 12/9/11
3075 //-----------------------------------------------------------------------------
3076 void Instance::registerStoreLIDs( const std::vector<int> & stoLIDVecRef )
3077 {
3078  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
3079 
3080  // Copy over the global ID lists:
3081  stoLIDVec = stoLIDVecRef;
3082 
3083  int lid=0;
3084  // Voltage drops:
3085  li_store_vbd = stoLIDVec[lid++];
3086  li_store_vbs = stoLIDVec[lid++];
3087  li_store_vgs = stoLIDVec[lid++];
3088  li_store_vds = stoLIDVec[lid++];
3089  li_store_von = stoLIDVec[lid++];
3090 
3091  if( loadLeadCurrent )
3092  {
3093  li_store_dev_id = stoLIDVec[lid++];
3094  li_store_dev_ig = stoLIDVec[lid++];
3095  li_store_dev_is = stoLIDVec[lid++];
3096  li_store_dev_ib = stoLIDVec[lid++];
3097  }
3098 }
3099 
3100 //-----------------------------------------------------------------------------
3101 // Function : Instance::jacobianStamp
3102 // Purpose :
3103 // Special Notes :
3104 // Scope : public
3105 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3106 // Creation Date : 9/4/02
3107 //-----------------------------------------------------------------------------
3108 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
3109 {
3110  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3111  {
3113  {
3114  return jacStampSpecialMerged;
3115  }
3116  else
3117  {
3118  return jacStampSpecial;
3119  }
3120  }
3121  else
3122  {
3124  return jacStamp_DC_SC;
3125  else if( drainConductance && !sourceConductance && !nqsMod )
3126  return jacStamp_DC;
3127  else if( !drainConductance && sourceConductance && !nqsMod )
3128  return jacStamp_SC;
3129  else if( !drainConductance && !sourceConductance && !nqsMod )
3130  return jacStamp;
3131  else
3132  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3133  ": NQSMOD not supported for DIRECT MATRIX ACCESS\n" );
3134  }
3135 
3136  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3137  "Instance::jacobianStamp should not get here!\n" );
3138 
3139  return jacStamp;
3140 }
3141 
3142 //-----------------------------------------------------------------------------
3143 // Function : Instance::registerJacLIDs
3144 // Purpose :
3145 // Special Notes :
3146 // Scope : public
3147 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3148 // Creation Date : 9/4/02
3149 //-----------------------------------------------------------------------------
3150 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
3151 {
3152  DeviceInstance::registerJacLIDs( jacLIDVec );
3153  std::vector<int> map;
3154  std::vector< std::vector<int> > map2;
3155 
3156 
3157  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3158  {
3160  {
3161  map = jacSpecialMap;
3162  map2 = jacSpecialMap2;
3163  }
3164  else
3165  {
3166  map = jacSpecialMergedMap;
3167  map2 = jacSpecialMergedMap2;
3168  }
3169  }
3170  else
3171  {
3172  if (drainConductance)
3173  {
3174  if (sourceConductance)
3175  {
3176  map = jacMap_DC_SC;
3177  map2 = jacMap2_DC_SC;
3178  }
3179  else
3180  {
3181  map = jacMap_DC;
3182  map2 = jacMap2_DC;
3183  }
3184  }
3185  else
3186  {
3187  if (sourceConductance)
3188  {
3189  map = jacMap_SC;
3190  map2 = jacMap2_SC;
3191  }
3192  else
3193  {
3194  map = jacMap;
3195  map2 = jacMap2;
3196  }
3197  }
3198  }
3199 
3200 #ifdef Xyce_DEBUG_DEVICE
3201  if (getDeviceOptions().debugLevel > 0)
3202  {
3203  Xyce::dout() << "Instance::registerJacLIDs map selected" << std::endl;
3204  for (int k = 0; k<map.size(); ++k )
3205  {
3206  Xyce::dout() << "map[ " << k << "] = " << map[k] << " map2[] = { ";
3207  for (int q = 0; q < map2[k].size(); ++q )
3208  {
3209  Xyce::dout() << map2[k][q] <<" ";
3210  }
3211  Xyce::dout() << "}" << std::endl;
3212  }
3213 
3214  for(int k = 0; k<jacLIDVec.size(); ++k )
3215  {
3216  Xyce::dout() << "jacLIDVec[ " << k << "] = { ";
3217  for (int q = 0; q < jacLIDVec[k].size(); ++q )
3218  {
3219  Xyce::dout() << jacLIDVec[k][q] <<" ";
3220  }
3221  Xyce::dout() << "}" << std::endl;
3222  }
3223  }
3224 #endif
3225 
3226  int nextColumn = 0;
3227 
3228  // V_d row
3229  ADrainEquDrainNodeOffset = jacLIDVec[map[0]][map2[0][0]];
3230  ADrainEquDrainPrimeNodeOffset = jacLIDVec[map[0]][map2[0][1]];
3231  if( icVDSGiven )
3232  {
3233  ADrainEquIdsOffset = jacLIDVec[map[0]][map2[0][2]];
3234  }
3235 
3236  // V_g row
3237  AGateEquGateNodeOffset = jacLIDVec[map[1]][map2[1][0]];
3238  AGateEquBulkNodeOffset = jacLIDVec[map[1]][map2[1][1]];
3239  AGateEquDrainPrimeNodeOffset = jacLIDVec[map[1]][map2[1][2]];
3240  AGateEquSourcePrimeNodeOffset = jacLIDVec[map[1]][map2[1][3]];
3241  nextColumn = 4;
3242  if( nqsMod )
3243  {
3244  AGateEquChargeVarOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3245  ++nextColumn;
3246  }
3247  if( icVGSGiven )
3248  {
3249  AGateEquIgsOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3250  ++nextColumn;
3251  }
3252 
3253  // V_s row
3254  ASourceEquSourceNodeOffset = jacLIDVec[map[2]][map2[2][0]];
3255  ASourceEquSourcePrimeNodeOffset = jacLIDVec[map[2]][map2[2][1]];
3256  nextColumn = 2;
3257  if( icVBSGiven )
3258  {
3259  ASourceEquIbsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3260  ++nextColumn;
3261  }
3262  if( icVDSGiven )
3263  {
3264  ASourceEquIdsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3265  ++nextColumn;
3266  }
3267  if( icVGSGiven )
3268  {
3269  ASourceEquIgsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3270  ++nextColumn;
3271  }
3272 
3273  // V_b row
3274  ABulkEquGateNodeOffset = jacLIDVec[map[3]][map2[3][0]];
3275  ABulkEquBulkNodeOffset = jacLIDVec[map[3]][map2[3][1]];
3276  ABulkEquDrainPrimeNodeOffset = jacLIDVec[map[3]][map2[3][2]];
3277  ABulkEquSourcePrimeNodeOffset = jacLIDVec[map[3]][map2[3][3]];
3278  nextColumn = 4;
3279  if( nqsMod )
3280  {
3281  ABulkEquChargeVarOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3282  ++nextColumn;
3283  }
3284  if( icVBSGiven )
3285  {
3286  ABulkEquIbsOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3287  ++nextColumn;
3288  }
3289 
3290  // V_d'
3291  ADrainPrimeEquDrainNodeOffset = jacLIDVec[map[4]][map2[4][0]];
3292  ADrainPrimeEquGateNodeOffset = jacLIDVec[map[4]][map2[4][1]];
3293  ADrainPrimeEquBulkNodeOffset = jacLIDVec[map[4]][map2[4][2]];
3294  ADrainPrimeEquDrainPrimeNodeOffset = jacLIDVec[map[4]][map2[4][3]];
3295  ADrainPrimeEquSourcePrimeNodeOffset = jacLIDVec[map[4]][map2[4][4]];
3296  if( nqsMod )
3297  {
3298  ADrainPrimeEquChargeVarOffset = jacLIDVec[map[4]][map2[4][5]];
3299  }
3300 
3301 
3302  // V_s'
3303  ASourcePrimeEquGateNodeOffset = jacLIDVec[map[5]][map2[5][0]];
3304  ASourcePrimeEquSourceNodeOffset = jacLIDVec[map[5]][map2[5][1]];
3305  ASourcePrimeEquBulkNodeOffset = jacLIDVec[map[5]][map2[5][2]];
3306  ASourcePrimeEquDrainPrimeNodeOffset = jacLIDVec[map[5]][map2[5][3]];
3307  ASourcePrimeEquSourcePrimeNodeOffset = jacLIDVec[map[5]][map2[5][4]];
3308  if( nqsMod )
3309  {
3310  ASourcePrimeEquChargeVarOffset = jacLIDVec[map[5]][map2[5][5]];
3311  }
3312 
3313  int nextRow = 6;
3314  if( nqsMod )
3315  {
3316  AChargeEquChargeVarOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3317  AChargeEquDrainPrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3318  AChargeEquGateNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3319  AChargeEquSourcePrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][3]];
3320  AChargeEquBulkNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][4]];
3321  ++nextRow;
3322  }
3323 
3324 
3325  if( icVBSGiven )
3326  {
3327  icVBSEquVbOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3328  icVBSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3329  icVBSEquIbsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3330  ++nextRow;
3331  }
3332 
3333  if( icVDSGiven )
3334  {
3335  icVDSEquVdOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3336  icVDSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3337  icVDSEquIdsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3338  ++nextRow;
3339  }
3340 
3341  if( icVGSGiven )
3342  {
3343  icVGSEquVgOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3344  icVGSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3345  icVGSEquIgsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3346  ++nextRow;
3347  }
3348 
3349  if (nqsMod)
3350  {
3351  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3352  ": NQSMOD not supported.\n" );
3353  }
3354 }
3355 
3356 //-----------------------------------------------------------------------------
3357 // Function : Instance::setupPointers
3358 // Purpose :
3359 // Special Notes :
3360 // Scope : public
3361 // Creator : Eric Keiter, SNL
3362 // Creation Date : 11/30/08
3363 //-----------------------------------------------------------------------------
3365 {
3366 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
3367  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
3368  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
3369 
3370  // V_d row
3373  if( icVDSGiven )
3374  {
3376  }
3377 
3378  // V_g row
3383  if( nqsMod )
3384  {
3386 
3387  }
3388  if( icVGSGiven )
3389  {
3391 
3392  }
3393 
3394  // V_s row // V_s row
3397  if( icVBSGiven )
3398  {
3400 
3401  }
3402  if( icVDSGiven )
3403  {
3405 
3406  }
3407  if( icVGSGiven )
3408  {
3410 
3411  }
3412 
3413  // V_b row
3418  if( nqsMod )
3419  {
3421 
3422  }
3423  if( icVBSGiven )
3424  {
3426 
3427  }
3428 
3429  // V_d'
3435  if( nqsMod )
3436  {
3438  }
3439 
3440 
3441  // V_s'
3447  if( nqsMod )
3448  {
3450  }
3451 
3452  if( nqsMod )
3453  {
3459  }
3460 
3461 
3462  if( icVBSGiven )
3463  {
3467  }
3468 
3469  if( icVDSGiven )
3470  {
3474  }
3475 
3476  if( icVGSGiven )
3477  {
3481  }
3482 
3483 
3484 
3485  // V_d row
3488  if( icVDSGiven )
3489  {
3491  }
3492 
3493  // V_g row
3498  if( nqsMod )
3499  {
3501 
3502  }
3503  if( icVGSGiven )
3504  {
3506 
3507  }
3508 
3509  // V_s row // V_s row
3512  if( icVBSGiven )
3513  {
3515 
3516  }
3517  if( icVDSGiven )
3518  {
3520 
3521  }
3522  if( icVGSGiven )
3523  {
3525 
3526  }
3527 
3528  // V_b row
3533  if( nqsMod )
3534  {
3536 
3537  }
3538  if( icVBSGiven )
3539  {
3541 
3542  }
3543 
3544  // V_d'
3550  if( nqsMod )
3551  {
3553  }
3554 
3555 
3556  // V_s'
3562  if( nqsMod )
3563  {
3565  }
3566 
3567  if( nqsMod )
3568  {
3574  }
3575 
3576 
3577  if( icVBSGiven )
3578  {
3582  }
3583 
3584  if( icVDSGiven )
3585  {
3589  }
3590 
3591  if( icVGSGiven )
3592  {
3596  }
3597 
3598 #endif
3599 }
3600 
3601 //-----------------------------------------------------------------------------
3602 // Function : Instance::updateTemperature
3603 // Purpose : This updates all the instance-owned paramters which
3604 // are temperature dependent.
3605 //
3606 // Special Notes :
3607 // Scope : public
3608 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3609 // Creation Date : 11/22/00
3610 //-----------------------------------------------------------------------------
3611 bool Instance::updateTemperature (const double & temp_tmp)
3612 {
3613  char msg[128];
3614 
3615  double tmp, tmp1, tmp2, tmp3, Eg;
3616  double T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;
3617  double delTemp, TRatio, Inv_L, Inv_W, Inv_LW;
3618  //double Dw, Dl;
3619  double Tnom;
3620  double Nvtm, SourceSatCurrent, DrainSatCurrent;
3621 
3622  // stuff from model paramters:
3623  double Eg0 = model_.Eg0;
3624  double ni = model_.ni;
3625  double Vtm0 = model_.Vtm0;
3626 
3627  bool bsuccess = true;
3628 
3629 #ifdef Xyce_DEBUG_DEVICE
3630  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
3631  {
3632  Xyce::dout() << std::endl << subsection_divider << std::endl;
3633  Xyce::dout() << "Instance::updateTemperature\n";
3634  Xyce::dout() << "name = " << getName() << std::endl;
3635  }
3636 #endif
3637 
3638  // first set the instance temperature to the new temperature:
3639  if (temp_tmp != -999.0) temp = temp_tmp;
3640 
3641  Tnom = model_.tnom;
3642  TRatio = temp/Tnom;
3643 
3644  vtm = CONSTKoverQ * temp;
3645  Eg = CONSTEg0 - CONSTalphaEg * temp * temp / (temp + CONSTbetaEg);
3646 
3647  if (temp != Tnom)
3648  {
3649  T0 = Eg0 / Vtm0 - Eg/vtm + model_.jctTempExponent*log(temp/Tnom);
3650  T1 = exp(T0 / model_.jctEmissionCoeff);
3653  }
3654  else
3655  {
3658  }
3659 
3660  if (jctTempSatCurDensity < 0.0) jctTempSatCurDensity = 0.0;
3662 
3663 
3664  // Temperature dependence of D/B and S/B diode capacitance begins
3665  delTemp = temp - Tnom;
3666  T0 = model_.tcj * delTemp;
3667 
3668  if (T0 >= -1.0)
3669  {
3671  }
3672  else if (unitAreaJctCapTemp > 0.0)
3673  {
3674  unitAreaJctCapTemp = 0.0;
3675 
3676  lout() << "Temperature effect has caused cj to be negative. Cj clamped to zero.\n" << std::endl;
3677  }
3678 
3679  T0 = model_.tcjsw * delTemp;
3680 
3681  if (T0 >= -1.0)
3682  {
3684  model_.unitLengthSidewallJctCap *(1.0 + T0);
3685  }
3686  else if (unitLengthSidewallJctCapTemp > 0.0)
3687  {
3689  lout() << "Temperature effect has caused cjsw to be negative. Cjsw clamped to zero.\n" << std::endl;
3690  }
3691 
3692  T0 = model_.tcjswg * delTemp;
3693 
3694  if (T0 >= -1.0)
3695  {
3698  }
3699  else if (unitLengthGateSidewallJctCapTemp > 0.0)
3700  {
3702  lout() << "Temperature effect has caused cjswg to be negative. Cjswg clamped to zero.\n" << std::endl;
3703  }
3704 
3705  PhiBTemp = model_.bulkJctPotential - model_.tpb * delTemp;
3706 
3707  if (PhiBTemp < 0.01)
3708  {
3709  PhiBTemp = 0.01;
3710  lout() << "Temperature effect has caused pb to be < 0.01. Pb clamped to 0.01.\n" << std::endl;
3711  }
3712 
3714 
3715  if (PhiBSWTemp <= 0.01)
3716  {
3717  PhiBSWTemp = 0.01;
3718  lout() << "Temperature effect has caused pbsw to be < 0.01. Pbsw clamped to 0.01.\n" << std::endl;
3719  }
3720 
3722 
3723  if (PhiBSWGTemp <= 0.01)
3724  {
3725  PhiBSWGTemp = 0.01;
3726  lout() << "Temperature effect has caused pbswg to be < 0.01. Pbswg clamped to 0.01.\n" << std::endl;
3727  }
3728  // End of junction capacitance
3729 
3730 
3731  // This next block determines whether or not to use a previously allocated
3732  // set of size dependent parameters. These are stored in a list that is
3733  // owned by the model. If the values for length and width match those of
3734  // a previously allocated set, then use the old set. If not, allocate a new set.
3735 
3736  std::list<SizeDependParam*>::iterator it_dpL =
3737  model_.sizeDependParamList.begin();
3738  std::list<SizeDependParam*>::iterator end_dpL =
3740 
3741  paramPtr = NULL;
3742 
3743  for( ; it_dpL != end_dpL; ++it_dpL )
3744  if( (*it_dpL)->Length == l && (*it_dpL)->Width == w )
3745  paramPtr = (*it_dpL);
3746 
3747  if ( paramPtr != NULL )
3748  {
3749  }
3750  else
3751  {
3752  paramPtr = new SizeDependParam ();
3753 
3754  model_.sizeDependParamList.push_back( paramPtr );
3755  paramPtr->referenceTemperature = temp_tmp;
3756 
3757  Ldrn = l;
3758  Wdrn = w;
3759  paramPtr->Length = Ldrn;
3760  paramPtr->Width = Wdrn;
3761 
3762  T0 = pow(Ldrn, model_.Lln);
3763  T1 = pow(Wdrn, model_.Lwn);
3764 
3765  tmp1 = model_.Ll / T0 + model_.Lw / T1
3766  + model_.Lwl / (T0 * T1);
3767 
3768  paramPtr->dl = model_.Lint + tmp1;
3769 
3770  tmp2 = model_.Llc / T0 + model_.Lwc / T1
3771  + model_.Lwlc / (T0 * T1);
3772 
3773  paramPtr->dlc = model_.dlc + tmp2;
3774 
3775  T2 = pow(Ldrn, model_.Wln);
3776  T3 = pow(Wdrn, model_.Wwn);
3777 
3778  tmp1 = model_.Wl / T2 + model_.Ww / T3
3779  + model_.Wwl / (T2 * T3);
3780 
3781  paramPtr->dw = model_.Wint + tmp1;
3782  tmp2 = model_.Wlc / T2 + model_.Wwc / T3
3783  + model_.Wwlc / (T2 * T3);
3784 
3785  paramPtr->dwc = model_.dwc + tmp2;
3786 
3787  paramPtr->leff = l - 2.0 * paramPtr->dl;
3788  if (paramPtr->leff <= 0.0)
3789  {
3790  sprintf(msg,
3791  ": mosfet %s, model %s: Effective channel length <= 0",
3792  getName().c_str(), model_.getName().c_str());
3793  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
3794  }
3795 
3796  paramPtr->weff = w - 2.0 * paramPtr->dw;
3797  if (paramPtr->weff <= 0.0)
3798  {
3799  sprintf(msg,
3800  ": mosfet %s, model %s: Effective channel width <= 0",
3801  getName().c_str(), model_.getName().c_str());
3802  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
3803  }
3804 
3805  paramPtr->leffCV = l - 2.0 * paramPtr->dlc;
3806  if (paramPtr->leffCV <= 0.0)
3807  {
3808  sprintf(msg,
3809  ": mosfet %s, model %s: Effective channel length for C-V <= 0",
3810  getName().c_str(), model_.getName().c_str());
3811  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
3812  }
3813 
3814  paramPtr->weffCV = w - 2.0 * paramPtr->dwc;
3815  if (paramPtr->weffCV <= 0.0)
3816  {
3817  sprintf(msg,
3818  ": mosfet %s, model %s: Effective channel width for C-V <= 0",
3819  getName().c_str(), model_.getName().c_str());
3820  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
3821  }
3822 
3823 
3824  if (model_.binUnit == 1)
3825  {
3826  Inv_L = 1.0e-6 / paramPtr->leff;
3827  Inv_W = 1.0e-6 / paramPtr->weff;
3828  Inv_LW = 1.0e-12 / (paramPtr->leff * paramPtr->weff);
3829  }
3830  else
3831  {
3832  Inv_L = 1.0 / paramPtr->leff;
3833  Inv_W = 1.0 / paramPtr->weff;
3834  Inv_LW = 1.0 / (paramPtr->leff * paramPtr->weff);
3835  }
3836 
3838  + model_.lcdsc * Inv_L
3839  + model_.wcdsc * Inv_W
3840  + model_.pcdsc * Inv_LW;
3841 
3843  + model_.lcdscb * Inv_L
3844  + model_.wcdscb * Inv_W
3845  + model_.pcdscb * Inv_LW;
3846 
3848  + model_.lcdscd * Inv_L
3849  + model_.wcdscd * Inv_W
3850  + model_.pcdscd * Inv_LW;
3851 
3852  paramPtr->cit = model_.cit
3853  + model_.lcit * Inv_L
3854  + model_.wcit * Inv_W
3855  + model_.pcit * Inv_LW;
3856 
3858  + model_.lnfactor * Inv_L
3859  + model_.wnfactor * Inv_W
3860  + model_.pnfactor * Inv_LW;
3861 
3862  paramPtr->xj = model_.xj
3863  + model_.lxj * Inv_L
3864  + model_.wxj * Inv_W
3865  + model_.pxj * Inv_LW;
3866 
3868  + model_.lvsat * Inv_L
3869  + model_.wvsat * Inv_W
3870  + model_.pvsat * Inv_LW;
3871 
3872  paramPtr->at = model_.at
3873  + model_.lat * Inv_L
3874  + model_.wat * Inv_W
3875  + model_.pat * Inv_LW;
3876 
3877  paramPtr->a0 = model_.a0
3878  + model_.la0 * Inv_L
3879  + model_.wa0 * Inv_W
3880  + model_.pa0 * Inv_LW;
3881 
3882  paramPtr->ags = model_.ags
3883  + model_.lags * Inv_L
3884  + model_.wags * Inv_W
3885  + model_.pags * Inv_LW;
3886 
3887  paramPtr->a1 = model_.a1
3888  + model_.la1 * Inv_L
3889  + model_.wa1 * Inv_W
3890  + model_.pa1 * Inv_LW;
3891 
3892  paramPtr->a2 = model_.a2
3893  + model_.la2 * Inv_L
3894  + model_.wa2 * Inv_W
3895  + model_.pa2 * Inv_LW;
3896 
3898  + model_.lketa * Inv_L
3899  + model_.wketa * Inv_W
3900  + model_.pketa * Inv_LW;
3901 
3903  + model_.lnsub * Inv_L
3904  + model_.wnsub * Inv_W
3905  + model_.pnsub * Inv_LW;
3906 
3908  + model_.lnpeak * Inv_L
3909  + model_.wnpeak * Inv_W
3910  + model_.pnpeak * Inv_LW;
3911 
3913  + model_.lngate * Inv_L
3914  + model_.wngate * Inv_W
3915  + model_.pngate * Inv_LW;
3916 
3918  + model_.lgamma1 * Inv_L
3919  + model_.wgamma1 * Inv_W
3920  + model_.pgamma1 * Inv_LW;
3921 
3923  + model_.lgamma2 * Inv_L
3924  + model_.wgamma2 * Inv_W
3925  + model_.pgamma2 * Inv_LW;
3926 
3927  paramPtr->vbx = model_.vbx
3928  + model_.lvbx * Inv_L
3929  + model_.wvbx * Inv_W
3930  + model_.pvbx * Inv_LW;
3931 
3932  paramPtr->vbm = model_.vbm
3933  + model_.lvbm * Inv_L
3934  + model_.wvbm * Inv_W
3935  + model_.pvbm * Inv_LW;
3936 
3937  paramPtr->xt = model_.xt
3938  + model_.lxt * Inv_L
3939  + model_.wxt * Inv_W
3940  + model_.pxt * Inv_LW;
3941 
3942  paramPtr->vfb = model_.vfb
3943  + model_.lvfb * Inv_L
3944  + model_.wvfb * Inv_W
3945  + model_.pvfb * Inv_LW;
3946 
3947  paramPtr->k1 = model_.k1
3948  + model_.lk1 * Inv_L
3949  + model_.wk1 * Inv_W
3950  + model_.pk1 * Inv_LW;
3951 
3952  paramPtr->kt1 = model_.kt1
3953  + model_.lkt1 * Inv_L
3954  + model_.wkt1 * Inv_W
3955  + model_.pkt1 * Inv_LW;
3956 
3958  + model_.lkt1l * Inv_L
3959  + model_.wkt1l * Inv_W
3960  + model_.pkt1l * Inv_LW;
3961 
3962  paramPtr->k2 = model_.k2
3963  + model_.lk2 * Inv_L
3964  + model_.wk2 * Inv_W
3965  + model_.pk2 * Inv_LW;
3966 
3967  paramPtr->kt2 = model_.kt2
3968  + model_.lkt2 * Inv_L
3969  + model_.wkt2 * Inv_W
3970  + model_.pkt2 * Inv_LW;
3971 
3972  paramPtr->k3 = model_.k3
3973  + model_.lk3 * Inv_L
3974  + model_.wk3 * Inv_W
3975  + model_.pk3 * Inv_LW;
3976 
3977  paramPtr->k3b = model_.k3b
3978  + model_.lk3b * Inv_L
3979  + model_.wk3b * Inv_W
3980  + model_.pk3b * Inv_LW;
3981 
3982  paramPtr->w0 = model_.w0
3983  + model_.lw0 * Inv_L
3984  + model_.ww0 * Inv_W
3985  + model_.pw0 * Inv_LW;
3986 
3987  paramPtr->nlx = model_.nlx
3988  + model_.lnlx * Inv_L
3989  + model_.wnlx * Inv_W
3990  + model_.pnlx * Inv_LW;
3991 
3993  + model_.ldvt0 * Inv_L
3994  + model_.wdvt0 * Inv_W
3995  + model_.pdvt0 * Inv_LW;
3996 
3998  + model_.ldvt1 * Inv_L
3999  + model_.wdvt1 * Inv_W
4000  + model_.pdvt1 * Inv_LW;
4001 
4003  + model_.ldvt2 * Inv_L
4004  + model_.wdvt2 * Inv_W
4005  + model_.pdvt2 * Inv_LW;
4006 
4008  + model_.ldvt0w * Inv_L
4009  + model_.wdvt0w * Inv_W
4010  + model_.pdvt0w * Inv_LW;
4011 
4013  + model_.ldvt1w * Inv_L
4014  + model_.wdvt1w * Inv_W
4015  + model_.pdvt1w * Inv_LW;
4016 
4018  + model_.ldvt2w * Inv_L
4019  + model_.wdvt2w * Inv_W
4020  + model_.pdvt2w * Inv_LW;
4021 
4023  + model_.ldrout * Inv_L
4024  + model_.wdrout * Inv_W
4025  + model_.pdrout * Inv_LW;
4026 
4028  + model_.ldsub * Inv_L
4029  + model_.wdsub * Inv_W
4030  + model_.pdsub * Inv_LW;
4031 
4033  + model_.lvth0 * Inv_L
4034  + model_.wvth0 * Inv_W
4035  + model_.pvth0 * Inv_LW;
4036 
4037  paramPtr->ua = model_.ua
4038  + model_.lua * Inv_L
4039  + model_.wua * Inv_W
4040  + model_.pua * Inv_LW;
4041 
4042  paramPtr->ua1 = model_.ua1
4043  + model_.lua1 * Inv_L
4044  + model_.wua1 * Inv_W
4045  + model_.pua1 * Inv_LW;
4046 
4047  paramPtr->ub = model_.ub
4048  + model_.lub * Inv_L
4049  + model_.wub * Inv_W
4050  + model_.pub * Inv_LW;
4051 
4052  paramPtr->ub1 = model_.ub1
4053  + model_.lub1 * Inv_L
4054  + model_.wub1 * Inv_W
4055  + model_.pub1 * Inv_LW;
4056 
4057  paramPtr->uc = model_.uc
4058  + model_.luc * Inv_L
4059  + model_.wuc * Inv_W
4060  + model_.puc * Inv_LW;
4061 
4062  paramPtr->uc1 = model_.uc1
4063  + model_.luc1 * Inv_L
4064  + model_.wuc1 * Inv_W
4065  + model_.puc1 * Inv_LW;
4066 
4067  paramPtr->u0 = model_.u0
4068  + model_.lu0 * Inv_L
4069  + model_.wu0 * Inv_W
4070  + model_.pu0 * Inv_LW;
4071 
4072  paramPtr->ute = model_.ute
4073  + model_.lute * Inv_L
4074  + model_.wute * Inv_W
4075  + model_.pute * Inv_LW;
4076 
4078  + model_.lvoff * Inv_L
4079  + model_.wvoff * Inv_W
4080  + model_.pvoff * Inv_LW;
4081 
4083  + model_.ldelta * Inv_L
4084  + model_.wdelta * Inv_W
4085  + model_.pdelta * Inv_LW;
4086 
4088  + model_.lrdsw * Inv_L
4089  + model_.wrdsw * Inv_W
4090  + model_.prdsw * Inv_LW;
4091 
4093  + model_.lprwg * Inv_L
4094  + model_.wprwg * Inv_W
4095  + model_.pprwg * Inv_LW;
4096 
4098  + model_.lprwb * Inv_L
4099  + model_.wprwb * Inv_W
4100  + model_.pprwb * Inv_LW;
4101 
4102  paramPtr->prt = model_.prt
4103  + model_.lprt * Inv_L
4104  + model_.wprt * Inv_W
4105  + model_.pprt * Inv_LW;
4106 
4108  + model_.leta0 * Inv_L
4109  + model_.weta0 * Inv_W
4110  + model_.peta0 * Inv_LW;
4111 
4113  + model_.letab * Inv_L
4114  + model_.wetab * Inv_W
4115  + model_.petab * Inv_LW;
4116 
4118  + model_.lpclm * Inv_L
4119  + model_.wpclm * Inv_W
4120  + model_.ppclm * Inv_LW;
4121 
4123  + model_.lpdibl1 * Inv_L
4124  + model_.wpdibl1 * Inv_W
4125  + model_.ppdibl1 * Inv_LW;
4126 
4128  + model_.lpdibl2 * Inv_L
4129  + model_.wpdibl2 * Inv_W
4130  + model_.ppdibl2 * Inv_LW;
4131 
4133  + model_.lpdiblb * Inv_L
4134  + model_.wpdiblb * Inv_W
4135  + model_.ppdiblb * Inv_LW;
4136 
4138  + model_.lpscbe1 * Inv_L
4139  + model_.wpscbe1 * Inv_W
4140  + model_.ppscbe1 * Inv_LW;
4141 
4143  + model_.lpscbe2 * Inv_L
4144  + model_.wpscbe2 * Inv_W
4145  + model_.ppscbe2 * Inv_LW;
4146 
4148  + model_.lpvag * Inv_L
4149  + model_.wpvag * Inv_W
4150  + model_.ppvag * Inv_LW;
4151 
4152  paramPtr->wr = model_.wr
4153  + model_.lwr * Inv_L
4154  + model_.wwr * Inv_W
4155  + model_.pwr * Inv_LW;
4156 
4157  paramPtr->dwg = model_.dwg
4158  + model_.ldwg * Inv_L
4159  + model_.wdwg * Inv_W
4160  + model_.pdwg * Inv_LW;
4161 
4162  paramPtr->dwb = model_.dwb
4163  + model_.ldwb * Inv_L
4164  + model_.wdwb * Inv_W
4165  + model_.pdwb * Inv_LW;
4166 
4167  paramPtr->b0 = model_.b0
4168  + model_.lb0 * Inv_L
4169  + model_.wb0 * Inv_W
4170  + model_.pb0 * Inv_LW;
4171 
4172  paramPtr->b1 = model_.b1
4173  + model_.lb1 * Inv_L
4174  + model_.wb1 * Inv_W
4175  + model_.pb1 * Inv_LW;
4176 
4178  + model_.lalpha0 * Inv_L
4179  + model_.walpha0 * Inv_W
4180  + model_.palpha0 * Inv_LW;
4181 
4183  + model_.lalpha1 * Inv_L
4184  + model_.walpha1 * Inv_W
4185  + model_.palpha1 * Inv_LW;
4186 
4188  + model_.lbeta0 * Inv_L
4189  + model_.wbeta0 * Inv_W
4190  + model_.pbeta0 * Inv_LW;
4191 
4192  // CV model
4193  paramPtr->elm = model_.elm
4194  + model_.lelm * Inv_L
4195  + model_.welm * Inv_W
4196  + model_.pelm * Inv_LW;
4197 
4199  + model_.lcgsl * Inv_L
4200  + model_.wcgsl * Inv_W
4201  + model_.pcgsl * Inv_LW;
4202 
4204  + model_.lcgdl * Inv_L
4205  + model_.wcgdl * Inv_W
4206  + model_.pcgdl * Inv_LW;
4207 
4209  + model_.lckappa * Inv_L
4210  + model_.wckappa * Inv_W
4211  + model_.pckappa * Inv_LW;
4212 
4213  paramPtr->cf = model_.cf
4214  + model_.lcf * Inv_L
4215  + model_.wcf * Inv_W
4216  + model_.pcf * Inv_LW;
4217 
4218  paramPtr->clc = model_.clc
4219  + model_.lclc * Inv_L
4220  + model_.wclc * Inv_W
4221  + model_.pclc * Inv_LW;
4222 
4223  paramPtr->cle = model_.cle
4224  + model_.lcle * Inv_L
4225  + model_.wcle * Inv_W
4226  + model_.pcle * Inv_LW;
4227 
4229  + model_.lvfbcv * Inv_L
4230  + model_.wvfbcv * Inv_W
4231  + model_.pvfbcv * Inv_LW;
4232 
4234  + model_.lacde * Inv_L
4235  + model_.wacde * Inv_W
4236  + model_.pacde * Inv_LW;
4237 
4239  + model_.lmoin * Inv_L
4240  + model_.wmoin * Inv_W
4241  + model_.pmoin * Inv_LW;
4242 
4244  + model_.lnoff * Inv_L
4245  + model_.wnoff * Inv_W
4246  + model_.pnoff * Inv_LW;
4247 
4249  + model_.lvoffcv * Inv_L
4250  + model_.wvoffcv * Inv_W
4251  + model_.pvoffcv * Inv_LW;
4252 
4253  paramPtr->abulkCVfactor = 1.0
4254  + pow((paramPtr->clc / paramPtr->leffCV), paramPtr->cle);
4255 
4256  T0 = (TRatio - 1.0);
4257 
4258  paramPtr->ua = paramPtr->ua + paramPtr->ua1 * T0;
4259  paramPtr->ub = paramPtr->ub + paramPtr->ub1 * T0;
4260  paramPtr->uc = paramPtr->uc + paramPtr->uc1 * T0;
4261 
4262  if (paramPtr->u0 > 1.0) paramPtr->u0 = paramPtr->u0 / 1.0e4;
4263 
4264  paramPtr->u0temp = paramPtr->u0 * pow(TRatio, paramPtr->ute);
4265 
4266  paramPtr->vsattemp = paramPtr->vsat - paramPtr->at * T0;
4267 
4268  paramPtr->rds0 = (paramPtr->rdsw + paramPtr->prt * T0)
4269  / pow(paramPtr->weff * 1E6, paramPtr->wr);
4270 
4271 #ifdef CHECK_MODEL_DONE
4272  if (checkModel((*M_iter), iterI, ckt))
4273  {
4274  UserError0(*this) << "Error(s) detected during V3.2 parameter checking for " << name.c_str() << " in model " << model_.name;
4275 #endif
4276 
4280 
4281  T0 = paramPtr->leffCV * paramPtr->leffCV;
4282 
4284  * paramPtr->weffCV * paramPtr->leffCV * T0);
4285 
4287  {
4288  T0 = paramPtr->gamma1 * model_.cox;
4289  paramPtr->npeak = 3.021E22 * T0 * T0;
4290  }
4291 
4292  paramPtr->phi = 2.0 * Vtm0 * log(paramPtr->npeak / ni);
4293  paramPtr->sqrtPhi = sqrt(paramPtr->phi);
4295 
4296  paramPtr->Xdep0 = sqrt(2.0 * CONSTEPSSI / (CONSTQ * paramPtr->npeak * 1.0e6))
4297  * paramPtr->sqrtPhi;
4298 
4299  paramPtr->sqrtXdep0 = sqrt(paramPtr->Xdep0);
4300  paramPtr->litl = sqrt(3.0 * paramPtr->xj * model_.tox);
4301 
4302  paramPtr->vbi = Vtm0 * log(1.0e20 * paramPtr->npeak / (ni * ni));
4303 
4304  paramPtr->cdep0 = sqrt(CONSTQ * CONSTEPSSI * paramPtr->npeak * 1.0e6 / 2.0
4305  / paramPtr->phi);
4306 
4307  paramPtr->ldeb = sqrt(CONSTEPSSI * Vtm0 / (CONSTQ
4308  * paramPtr->npeak * 1.0e6)) / 3.0;
4309 
4310  paramPtr->acde *= pow((paramPtr->npeak / 2.0e16), -0.25);
4311 
4312 
4313  if (model_.k1Given || model_.k2Given)
4314  {
4315  if (!model_.k1Given)
4316  {
4317  UserWarning0(*this) << "k1 should be specified with k2.";
4318  paramPtr->k1 = 0.53;
4319  }
4320 
4321  if (!model_.k2Given)
4322  {
4323  UserWarning0(*this) << "k2 should be specified with k1.";
4324  paramPtr->k2 = -0.0186;
4325  }
4326 
4327  if (model_.nsubGiven)
4328  {
4329  UserWarning0(*this) << "nsub is ignored because k1 or k2 is given.";
4330  }
4331 
4332  if (model_.xtGiven)
4333  {
4334  UserWarning0(*this) << "xt is ignored because k1 or k2 is given.";
4335  }
4336 
4337  if (model_.vbxGiven)
4338  {
4339  UserWarning0(*this) << "vbx is ignored because k1 or k2 is given.";
4340  }
4341 
4342  if (model_.gamma1Given)
4343  {
4344  UserWarning0(*this) << "gamma1 is ignored because k1 or k2 is given.";
4345  }
4346 
4347  if (model_.gamma2Given)
4348  {
4349  UserWarning0(*this) << "gamma2 is ignored because k1 or k2 is given.";
4350  }
4351  }
4352  else
4353  {
4354  if (!model_.vbxGiven)
4355  paramPtr->vbx = paramPtr->phi - 7.7348e-4 * paramPtr->npeak
4356  * paramPtr->xt * paramPtr->xt;
4357 
4358  if (paramPtr->vbx > 0.0)
4359  paramPtr->vbx = -paramPtr->vbx;
4360 
4361  if (paramPtr->vbm > 0.0)
4362  paramPtr->vbm = -paramPtr->vbm;
4363 
4364  if (!model_.gamma1Given)
4365  paramPtr->gamma1 = 5.753e-12 * sqrt(paramPtr->npeak) / model_.cox;
4366 
4367  if (!model_.gamma2Given)
4368  paramPtr->gamma2 = 5.753e-12 * sqrt(paramPtr->nsub) / model_.cox;
4369 
4370  T0 = paramPtr->gamma1 - paramPtr->gamma2;
4371  T1 = sqrt(paramPtr->phi - paramPtr->vbx) - paramPtr->sqrtPhi;
4372  T2 = sqrt(paramPtr->phi * (paramPtr->phi - paramPtr->vbm)) - paramPtr->phi;
4373 
4374  paramPtr->k2 = T0 * T1 / (2.0 * T2 + paramPtr->vbm);
4375  paramPtr->k1 = paramPtr->gamma2 - 2.0 * paramPtr->k2 * sqrt(paramPtr->phi
4376  - paramPtr->vbm);
4377  }
4378 
4379  if (paramPtr->k2 < 0.0)
4380  {
4381  T0 = 0.5 * paramPtr->k1 / paramPtr->k2;
4382  paramPtr->vbsc = 0.9 * (paramPtr->phi - T0 * T0);
4383 
4384  if (paramPtr->vbsc > -3.0) paramPtr->vbsc = -3.0;
4385  else if (paramPtr->vbsc < -30.0) paramPtr->vbsc = -30.0;
4386  }
4387  else
4388  {
4389  paramPtr->vbsc = -30.0;
4390  }
4391 
4393 
4394  if (!model_.vfbGiven)
4395  {
4396  if (model_.vth0Given)
4397  {
4400  }
4401  else
4402  { paramPtr->vfb = -1.0;
4403  }
4404  }
4405 
4406  if (!model_.vth0Given)
4407  {
4409  * (paramPtr->vfb + paramPtr->phi + paramPtr->k1
4410  * paramPtr->sqrtPhi);
4411  }
4412 
4415 
4416  T1 = sqrt(CONSTEPSSI / CONSTEPSOX * model_.tox * paramPtr->Xdep0);
4417  T0 = exp(-0.5 * paramPtr->dsub * paramPtr->leff / T1);
4418 
4419  paramPtr->theta0vb0 = (T0 + 2.0 * T0 * T0);
4420 
4421  T0 = exp(-0.5 * paramPtr->drout * paramPtr->leff / T1);
4422  T2 = (T0 + 2.0 * T0 * T0);
4423 
4425 
4426  tmp = sqrt(paramPtr->Xdep0);
4427  tmp1 = paramPtr->vbi - paramPtr->phi;
4428  tmp2 = model_.factor1 * tmp;
4429 
4430  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * paramPtr->leff / tmp2;
4431 
4432  if (T0 > -CONSTEXP_THRESHOLD)
4433  {
4434  T1 = exp(T0);
4435  T2 = T1 * (1.0 + 2.0 * T1);
4436  }
4437  else
4438  {
4439  T1 = CONSTMIN_EXP;
4440  T2 = T1 * (1.0 + 2.0 * T1);
4441  }
4442  T0 = paramPtr->dvt0w * T2;
4443  T2 = T0 * tmp1;
4444 
4445  T0 = -0.5 * paramPtr->dvt1 * paramPtr->leff / tmp2;
4446 
4447  if (T0 > -CONSTEXP_THRESHOLD)
4448  {
4449  T1 = exp(T0);
4450  T3 = T1 * (1.0 + 2.0 * T1);
4451  }
4452  else
4453  {
4454  T1 = CONSTMIN_EXP;
4455  T3 = T1 * (1.0 + 2.0 * T1);
4456  }
4457 
4458  T3 = paramPtr->dvt0 * T3 * tmp1;
4459 
4460  T4 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
4461 
4462  T0 = sqrt(1.0 + paramPtr->nlx / paramPtr->leff);
4463  T5 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
4464  + (paramPtr->kt1 + paramPtr->kt1l / paramPtr->leff) * (TRatio - 1.0);
4465 
4466  tmp3 = model_.dtype * paramPtr->vth0 - T2 - T3 + paramPtr->k3 * T4 + T5;
4467 
4468  paramPtr->vfbzb = tmp3 - paramPtr->phi - paramPtr->k1 * paramPtr->sqrtPhi;
4469 
4470  } // End of vfbzb
4471 
4472  cgso = paramPtr->cgso;
4473  cgdo = paramPtr->cgdo;
4474 
4475  Nvtm = vtm * model_.jctEmissionCoeff;
4476 
4477  if ((sourceArea <= 0.0) &&
4478  (sourcePerimeter <= 0.0))
4479  {
4480  SourceSatCurrent = 1.0e-14;
4481  }
4482  else
4483  {
4484  SourceSatCurrent = sourceArea * jctTempSatCurDensity
4485  + sourcePerimeter
4487  }
4488 
4489  if ((SourceSatCurrent > 0.0) && (model_.ijth > 0.0))
4490  {
4491  vjsm = Nvtm * log(model_.ijth / SourceSatCurrent + 1.0);
4492  IsEvjsm = SourceSatCurrent * exp(vjsm / Nvtm);
4493  }
4494 
4495  if ((drainArea <= 0.0) &&
4496  (drainPerimeter <= 0.0))
4497  {
4498  DrainSatCurrent = 1.0e-14;
4499  }
4500  else
4501  {
4502  DrainSatCurrent = drainArea * jctTempSatCurDensity
4503  + drainPerimeter
4505  }
4506 
4507  if ((DrainSatCurrent > 0.0) && (model_.ijth > 0.0))
4508  {
4509  vjdm = Nvtm * log(model_.ijth / DrainSatCurrent + 1.0);
4510  IsEvjdm = DrainSatCurrent * exp(vjdm / Nvtm);
4511  }
4512 
4513  updateTemperatureCalled_ = true;
4514 
4515  return bsuccess;
4516  }
4517 
4518 //-----------------------------------------------------------------------------
4519 // Function : Instance::updateIntermediateVars
4520 // Purpose :
4521 // Special Notes :
4522 // Scope : public
4523 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
4524 // Creation Date : 01/09/01
4525 //-----------------------------------------------------------------------------
4527  {
4528  bool bsuccess = true;
4529 
4530 // begin the b3ld.c parameters:
4531  double SourceSatCurrent(0.0), DrainSatCurrent(0.0);
4532  double vgdo(0.0);
4533 
4534  double VgstNVt(0.0), ExpVgst(0.0);
4535 
4536  double czbd(0.0), czbdsw(0.0), czbdswg(0.0), czbs(0.0), czbssw(0.0), czbsswg(0.0);
4537  double evbd(0.0), evbs(0.0), arg(0.0), sarg(0.0);
4538 
4539  double Vfbeff(0.0), dVfbeff_dVg(0.0), dVfbeff_dVb(0.0), V3(0.0), V4(0.0);
4540 
4541  double MJ(0.0), MJSW(0.0), MJSWG(0.0);
4542 
4543  double qinoi(0.0);
4544  double Vds(0.0), Vgs(0.0), Vbs(0.0);
4545  double Vgs_eff(0.0), Vfb(0.0);
4546  double Phis(0.0), dPhis_dVb(0.0), sqrtPhis(0.0), dsqrtPhis_dVb(0.0);
4547  double Vth(0.0), dVth_dVb(0.0), dVth_dVd(0.0);
4548  double Vgst(0.0);
4549 
4550  double Nvtm(0.0);
4551  double Vtm(0.0);
4552  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);
4553  double ExpArg(0.0), V0(0.0), CoxWLcen(0.0), QovCox(0.0), LINK(0.0);
4554  double DeltaPhi(0.0);
4555 
4556  double Cox(0.0), Tox(0.0), Tcen(0.0), dTcen_dVg(0.0), dTcen_dVd(0.0), dTcen_dVb(0.0);
4557  double Ccen(0.0), Coxeff(0.0), dCoxeff_dVg(0.0), dCoxeff_dVd(0.0), dCoxeff_dVb(0.0);
4558  double Denomi(0.0), dDenomi_dVg(0.0), dDenomi_dVd(0.0), dDenomi_dVb(0.0);
4559 
4560  double dueff_dVg(0.0), dueff_dVd(0.0), dueff_dVb(0.0);
4561  double Esat(0.0);
4562 
4563  double Vdsat(0.0);
4564 
4565  double EsatL(0.0), dEsatL_dVg(0.0), dEsatL_dVd(0.0), dEsatL_dVb(0.0);
4566 
4567  double dVdsat_dVg(0.0), dVdsat_dVb(0.0), dVdsat_dVd(0.0), Vasat(0.0), dAlphaz_dVg(0.0), dAlphaz_dVb(0.0);
4568  double dVasat_dVg(0.0), dVasat_dVb(0.0), dVasat_dVd(0.0), Va(0.0);
4569 
4570  double dVa_dVd(0.0), dVa_dVg(0.0), dVa_dVb(0.0);
4571  double Vbseff(0.0), dVbseff_dVb(0.0), VbseffCV(0.0), dVbseffCV_dVb(0.0);
4572  double Arg1(0.0);
4573 
4574  double One_Third_CoxWL(0.0), Two_Third_CoxWL(0.0), Alphaz(0.0);
4575 
4576  double T0(0.0), dT0_dVg(0.0), dT0_dVd(0.0), dT0_dVb(0.0);
4577  double T1(0.0), dT1_dVg(0.0), dT1_dVd(0.0), dT1_dVb(0.0);
4578  double T2(0.0), dT2_dVg(0.0), dT2_dVd(0.0), dT2_dVb(0.0);
4579  double T3(0.0), dT3_dVg(0.0), dT3_dVd(0.0), dT3_dVb(0.0);
4580  double T4(0.0);
4581 
4582  double T5(0.0);
4583  double T6(0.0);
4584  double T7(0.0);
4585  double T8(0.0);
4586  double T9(0.0);
4587  double T10(0.0);
4588  double T11(0.0), T12(0.0);
4589 
4590  double tmp(0.0), Abulk(0.0), dAbulk_dVb(0.0), Abulk0(0.0), dAbulk0_dVb(0.0);
4591 
4592  double VACLM(0.0), dVACLM_dVg(0.0), dVACLM_dVd(0.0), dVACLM_dVb(0.0);
4593  double VADIBL(0.0), dVADIBL_dVg(0.0), dVADIBL_dVd(0.0), dVADIBL_dVb(0.0);
4594 
4595  double Xdep(0.0), dXdep_dVb(0.0), lt1(0.0), dlt1_dVb(0.0), ltw(0.0), dltw_dVb(0.0);
4596  double Delt_vth(0.0), dDelt_vth_dVb(0.0);
4597 
4598  double Theta0(0.0), dTheta0_dVb(0.0);
4599 
4600  double TempRatio(0.0), tmp1(0.0), tmp2(0.0), tmp3(0.0), tmp4(0.0);
4601 
4602  double DIBL_Sft(0.0), dDIBL_Sft_dVd(0.0);
4603 
4604  double Lambda(0.0), dLambda_dVg(0.0);
4605 
4606  double a1(0.0);
4607 
4608  double Vgsteff(0.0), dVgsteff_dVg(0.0), dVgsteff_dVd(0.0), dVgsteff_dVb(0.0);
4609  double Vdseff(0.0), dVdseff_dVg(0.0), dVdseff_dVd(0.0), dVdseff_dVb(0.0);
4610  double VdseffCV(0.0), dVdseffCV_dVg(0.0), dVdseffCV_dVd(0.0), dVdseffCV_dVb(0.0);
4611  double diffVds(0.0);
4612 
4613  double dAbulk_dVg(0.0);
4614  double beta(0.0), dbeta_dVg(0.0), dbeta_dVd(0.0), dbeta_dVb(0.0);
4615  double gche(0.0), dgche_dVg(0.0), dgche_dVd(0.0), dgche_dVb(0.0);
4616  double fgche1(0.0), dfgche1_dVg(0.0), dfgche1_dVd(0.0), dfgche1_dVb(0.0);
4617  double fgche2(0.0), dfgche2_dVg(0.0), dfgche2_dVd(0.0), dfgche2_dVb(0.0);
4618  double Idl(0.0), dIdl_dVg(0.0), dIdl_dVd(0.0), dIdl_dVb(0.0);
4619  double Idsa(0.0), dIdsa_dVg(0.0), dIdsa_dVd(0.0), dIdsa_dVb(0.0);
4620  double Ids(0.0);
4621 
4622  double Gds(0.0), Gmb(0.0);
4623  double Isub(0.0);
4624 
4625  double Gbd(0.0), Gbg(0.0), Gbb(0.0);
4626  double VASCBE(0.0), dVASCBE_dVg(0.0), dVASCBE_dVd(0.0), dVASCBE_dVb(0.0);
4627  double CoxWovL(0.0);
4628  double Rds(0.0), dRds_dVg(0.0), dRds_dVb(0.0), WVCox(0.0), WVCoxRds(0.0);
4629  double Vgst2Vtm(0.0), VdsatCV(0.0);
4630 
4631  double dVdsatCV_dVg(0.0), dVdsatCV_dVb(0.0);
4632  double Leff(0.0), Weff(0.0), dWeff_dVg(0.0), dWeff_dVb(0.0);
4633  double AbulkCV(0.0), dAbulkCV_dVb(0.0);
4634 
4635  double gtau_diff(0.0), gtau_drift(0.0);
4636  // these shadow member varables and then are unitialized
4637  // when used in later calculations
4638  // double qcheq(0.0), cqcheq(0.0), qdef(0.0);
4639 
4640  double Cgg1(0.0), Cgb1(0.0), Cgd1(0.0), Cbg1(0.0), Cbb1(0.0), Cbd1(0.0);
4641 
4642  double Qac0(0.0), Qsub0(0.0);
4643  double dQac0_dVg(0.0), dQac0_dVb(0.0), dQsub0_dVg(0.0), dQsub0_dVd(0.0), dQsub0_dVb(0.0);
4644  double von_local(0.0);
4645 
4646  ScalingFactor = 1.0e-9;
4647 
4648  // Don't do charge computations in DC sweeps.
4649  if (getSolverState().tranopFlag || getSolverState().acopFlag || getSolverState().transientFlag)
4650  {
4651  ChargeComputationNeeded = true;
4652  }
4653  else
4654  {
4655  ChargeComputationNeeded = false;
4656  }
4657 
4658 #ifdef Xyce_DEBUG_DEVICE
4659  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
4660  {
4661  Xyce::dout() << subsection_divider << std::endl;
4662  Xyce::dout() << " Instance::updateIntermediateVars\n";
4663  Xyce::dout() << " name = " << getName();
4664  Xyce::dout() << " model name = " << model_.getName();
4665  Xyce::dout() <<" dtype is " << model_.dtype << std::endl;
4666  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4667  Xyce::dout() << " " << std::endl;
4668  }
4669 #endif
4670 
4671  int Check = 1;
4672 
4673  // The first block of code in b3ld.c basically sets up, locally,
4674  // what the load function should use as values for the various solution
4675  // variables. There is a series of IF statements which are dependent
4676  // upon the mode. (transient, initializing transient, operating point,
4677  // small signal, etc.). Xyce treats the operating point and transient
4678  // calculation in the same way, from the device's point of view, and
4679  // we don't support any of the other modes. Therefore most of these
4680  // mode options are not here - only the transient mode stuff.
4681 
4682  // First get some of the needed solution variables:
4683  Vd = 0.0;
4684  Vs = 0.0;
4685  Vg = 0.0;
4686  Vb = 0.0;
4687  Vsp = 0.0;
4688  Vdp = 0.0;
4689  Qtotal = 0.0;
4690 
4697  if( nqsMod )
4698  {
4700  }
4701  else
4702  {
4703  Qtotal = 0.0;
4704  }
4705 
4706 #ifdef Xyce_DEBUG_DEVICE
4708  {
4709  Xyce::dout() << " Vg = " << Vg << std::endl;
4710  Xyce::dout() << " Vb = " << Vb << std::endl;
4711  Xyce::dout() << " Vs = " << Vs << std::endl;
4712  Xyce::dout() << " Vd = " << Vd << std::endl;
4713  Xyce::dout() << " Vsp = " << Vsp << std::endl;
4714  Xyce::dout() << " Vdp = " << Vdp << std::endl;
4715  Xyce::dout() << " Qtotal = " << Qtotal << std::endl;
4716  }
4717 #endif
4718 
4719  Vddp = Vd - Vdp;
4720  Vssp = Vs - Vsp;
4721  Vbsp = Vb - Vsp;
4722  Vbdp = Vb - Vdp;
4723  Vgsp = Vg - Vsp;
4724  Vgdp = Vg - Vdp;
4725  Vgb = Vg - Vb;
4726 
4727  Vdpsp = Vdp - Vsp;
4728 
4729  // modified from b3ld: (see lines 221-230)
4730  vbs = model_.dtype * Vbsp;
4731  vgs = model_.dtype * Vgsp;
4732  vds = model_.dtype * Vdpsp;
4733 
4734  qdef = model_.dtype * Qtotal;
4735 
4736  vbd = vbs - vds;
4737  vgd = vgs - vds;
4738 
4739  origFlag = 1;
4740  limitedFlag = false;
4741  vgs_orig = vgs;
4742  vds_orig = vds;
4743  vbs_orig = vbs;
4744  vbd_orig = vbd;
4745  vgd_orig = vgd;
4746 
4747  // What follows is a block of code designed to impose some limits,
4748  // or initial conditions on the junction voltages. Initial conditions
4749  // should only be imposed on the first Newton step of an operating point.
4750  //
4751  // The first possible limit on the junction voltages has to do with
4752  // limiting the percent change of junction voltages between Newton
4753  // iterations. The second has to do with avoiding extra floating point
4754  // operations in the event that the device has in some sense converged
4755  // (aka BYPASS). Although the primary point of BYPASS is to reduce
4756  // neccessary work, it also seems to reduce the number of Newton iterations.
4757  //
4758  // NOTE: We do not support BYPASS.
4759  //
4760  // The "old" variables should be the values for the previous
4761  // Newton iteration, if indeed there was a previous Newton
4762  // iteration. If not, just set the old values equal to
4763  // the current ones.
4764  //
4765 
4766  // set an initial condition if appropriate:
4767  if (getSolverState().initJctFlag && !OFF && getDeviceOptions().voltageLimiterFlag)
4768  {
4769  if (getSolverState().inputOPFlag)
4770  {
4771  N_LAS_Vector * flagSolVectorPtr = extData.flagSolVectorPtr;
4772  if ((*flagSolVectorPtr)[li_Drain] == 0 || (*flagSolVectorPtr)[li_Gate] == 0 ||
4773  (*flagSolVectorPtr)[li_Source] == 0 || (*flagSolVectorPtr)[li_SourcePrime] == 0 ||
4774  (*flagSolVectorPtr)[li_DrainPrime] == 0 || (*flagSolVectorPtr)[li_Bulk] == 0 )
4775  {
4776  vbs = 0.0;
4777  vgs = model_.dtype * paramPtr->vth0 + 0.1;
4778  vds = 0.1;
4779  origFlag = 0;
4780  }
4781  }
4782  else
4783  {
4784  vbs = 0.0;
4785  vgs = model_.dtype * paramPtr->vth0 + 0.1;
4786  vds = 0.1;
4787  origFlag = 0;
4788  }
4789  vbd = vbs - vds;
4790  vgd = vgs - vds;
4791  //origFlag = 0;
4792  }
4793  else if ((getSolverState().initFixFlag || getSolverState().initJctFlag) && OFF)
4794  {
4795  qdef = vbs = vgs = vds = 0;
4796  }
4797 
4798 
4799  if (getSolverState().newtonIter == 0)
4800  {
4801  newtonIterOld = 0;
4802 
4803  if (!getSolverState().dcopFlag || (getSolverState().locaEnabledFlag && getSolverState().dcopFlag))
4804  // ie, first newton step of a transient time step or DCOP continuation step.
4805  {
4810  von_local = (extData.currStoVectorRawPtr)[li_store_von];
4811  }
4812  else
4813  { // no history
4814  vbs_old = vbs;
4815  vbd_old = vbd;
4816  vgs_old = vgs;
4817  vds_old = vds;
4818  von_local = 0.0;
4819  }
4820  }
4821  else
4822  {
4827  von_local = (extData.nextStoVectorRawPtr)[li_store_von];
4828  }
4829 
4830  vgdo = vgs_old - vds_old;
4831 
4832  // This next block performs checks on the junction voltages and
4833  // imposes limits on them if they are too big.
4834  // Note: In the level=1 von is multiplied by dtype. Here it is not. They
4835  // are both right.
4836 
4838  {
4839 
4840 #ifdef Xyce_DEBUG_DEVICE
4842  {
4843  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4844  Xyce::dout() << " von_local = " << von_local << std::endl;
4845  Xyce::dout() << " CONSTvt0 = " << CONSTvt0 << std::endl;
4846  Xyce::dout() << " vcrit = " << model_.vcrit << std::endl;
4847  Xyce::dout().width(3);
4848  Xyce::dout() << getSolverState().newtonIter;
4849  Xyce::dout().width(5);Xyce::dout() << getName();
4850  Xyce::dout() << " old :";
4851  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4852  Xyce::dout() << vgs_old;
4853  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4854  Xyce::dout() << vds_old;
4855  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4856  Xyce::dout() << vbs_old;
4857  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4858  Xyce::dout() << vbd_old << std::endl;
4859  Xyce::dout().width(3);
4860  Xyce::dout() << getSolverState().newtonIter;
4861  Xyce::dout().width(5);Xyce::dout() << getName();
4862  Xyce::dout() << " Blim:";
4863  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4864  Xyce::dout() << vgs;
4865  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4866  Xyce::dout() << vds;
4867  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4868  Xyce::dout() << vbs;
4869  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4870  Xyce::dout() << vbd << std::endl;
4871  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
4872  }
4873 #endif
4874 
4875  // only do this if we are beyond the first Newton iteration. On the
4876  // first newton iteration, the "old" values are from a previous time
4877  // step.
4878 
4879  if (getSolverState().newtonIter >= 0)
4880  {
4881  if (vds_old >= 0.0)
4882  {
4883  vgs = devSupport.fetlim( vgs, vgs_old, von_local);
4884  vds = vgs - vgd;
4885  vds = devSupport.limvds( vds, vds_old);
4886  vgd = vgs - vds;
4887  }
4888  else
4889  {
4890  vgd = devSupport.fetlim( vgd, vgdo, von_local);
4891  vds = vgs - vgd;
4892  vds = -devSupport.limvds( -vds, -vds_old );
4893  vgs = vgd + vds;
4894  }
4895 
4896  if (vds >= 0.0)
4897  {
4899  model_.vcrit, &Check);
4900  vbd = vbs - vds;
4901  }
4902  else
4903  {
4905  model_.vcrit, &Check);
4906  vbs = vbd + vds;
4907  }
4908  }
4909 
4910  // set the origFlag:
4911 #ifdef Xyce_NEW_ORIG_TEST
4912  double vgs_diff = fabs(vgs - vgs_orig);
4913  double vds_diff = fabs(vds - vds_orig);
4914  double vbs_diff = fabs(vbs - vbs_orig);
4915  double vgd_diff = fabs(vgd - vgd_orig);
4916 
4917  bool noOrigFlag_vgs = 0;
4918  bool noOrigFlag_vds = 0;
4919  bool noOrigFlag_vbs = 0;
4920  bool noOrigFlag_vgd = 0;
4921 
4922  if (vgs_diff != 0.0)
4923  {
4924  if (vgs_orig != 0.0)
4925  {
4926  if ( fabs(vgs_diff/vgs_orig) > reltol) noOrigFlag_vgs = 1;
4927  }
4928  else
4929  {
4930  if ( fabs(vgs_diff) > voltTol ) noOrigFlag_vgs = 1;
4931  }
4932  }
4933 
4934  if (vds_diff != 0.0)
4935  {
4936  if (vds_orig != 0.0)
4937  {
4938  if ( fabs(vds_diff/vds_orig) > reltol) noOrigFlag_vds = 1;
4939  }
4940  else
4941  {
4942  if ( fabs(vds_diff) > voltTol ) noOrigFlag_vds = 1;
4943  }
4944  }
4945 
4946  if (vbs_diff != 0.0)
4947  {
4948  if (vbs_orig != 0.0)
4949  {
4950  if ( fabs(vbs_diff/vbs_orig) > reltol) noOrigFlag_vbs = 1;
4951  }
4952  else
4953  {
4954  if ( fabs(vbs_diff) > voltTol ) noOrigFlag_vbs = 1;
4955  }
4956  }
4957 
4958  if (vgd_diff != 0.0)
4959  {
4960  if (vgd_orig != 0.0)
4961  {
4962  if ( fabs(vgd_diff/vgd_orig) > reltol) noOrigFlag_vgd = 1;
4963  }
4964  else
4965  {
4966  if ( fabs(vgd_diff) > voltTol ) noOrigFlag_vgd = 1;
4967  }
4968  }
4969 
4970  origFlag = !( noOrigFlag_vgs || noOrigFlag_vds ||
4971  noOrigFlag_vbs || noOrigFlag_vgd);
4972 
4973 #else
4974  if (vgs_orig != vgs || vds_orig != vds ||
4975  vbs_orig != vbs || vbd_orig != vbd || vgd_orig != vgd) origFlag = 0;
4976 #endif
4977 
4978  // for convergence testing:
4979  if (Check == 1) limitedFlag=true;
4980 
4981 #ifdef Xyce_DEBUG_DEVICE
4983  {
4984  Xyce::dout().width(3);
4985  Xyce::dout() << getSolverState().newtonIter;
4986  Xyce::dout().width(5);Xyce::dout() << getName();
4987  Xyce::dout() << " Alim:";
4988  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4989  Xyce::dout() << vgs;
4990  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4991  Xyce::dout() << vds;
4992  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4993  Xyce::dout() << vbs;
4994  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
4995  Xyce::dout() << vbd;
4996  if (origFlag) Xyce::dout() << " SAME";
4997  else Xyce::dout() << " DIFF";
4998  Xyce::dout() << std::endl;
4999  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
5000  }
5001 #endif
5002 
5003  } // getDeviceOptions().voltageLimiterFlag
5004 
5005  // update the "old" variables:
5006  if (getSolverState().newtonIter != 0 && getSolverState().newtonIter != newtonIterOld)
5007  {
5009  }
5010 
5011  // Finished with what would have been the series of CKTmode
5012  // IF statements...
5013 
5014  // file: b3ld.c line: 345
5015  // determine DC current and derivatives
5016  vbd = vbs - vds;
5017  vgd = vgs - vds;
5018  vgb = vgs - vbs;
5019 
5020 #ifdef Xyce_DEBUG_DEVICE
5021  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
5022  {
5023  Xyce::dout() << " mod type = " << model_.modType << std::endl;
5024  Xyce::dout() << "dtype = " << model_.dtype << std::endl;
5025  Xyce::dout() << " vbs = " << vbs << std::endl;
5026  Xyce::dout() << " vds = " << vds << std::endl;
5027  Xyce::dout() << " vgs = " << vgs << std::endl;
5028 
5029  Xyce::dout() << " vbd = " << vbd << std::endl;
5030  Xyce::dout() << " vgd = " << vgd << std::endl;
5031  Xyce::dout() << " vgb = " << vgs << std::endl;
5032  Xyce::dout() << " qdef = " << qdef << std::endl;
5033  }
5034 #endif
5035 
5036  // Source/drain junction diode DC model begins
5037  Nvtm = vtm * model_.jctEmissionCoeff;
5038 
5039  if ((sourceArea <= 0.0) && (sourcePerimeter <= 0.0))
5040  {
5041  SourceSatCurrent = 1.0e-14;
5042  }
5043  else
5044  {
5045  SourceSatCurrent = sourceArea
5047  + sourcePerimeter
5049  }
5050 
5051  if (SourceSatCurrent <= 0.0)
5052  {
5054  cbs = gbs * vbs;
5055  }
5056  else
5057  {
5058  if (model_.ijth == 0.0)
5059  {
5060  evbs = exp(vbs / Nvtm);
5061  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5062  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5063  }
5064  else
5065  {
5066  if (vbs < vjsm)
5067  {
5068  evbs = exp(vbs / Nvtm);
5069  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5070  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5071  }
5072  else
5073  {
5074  T0 = IsEvjsm / Nvtm;
5075  gbs = T0 + getDeviceOptions().gmin;
5076  cbs = IsEvjsm - SourceSatCurrent
5077  + T0 * (vbs - vjsm)
5078  + getDeviceOptions().gmin * vbs;
5079  }
5080  }
5081  }
5082 
5083  if ((drainArea <= 0.0) && (drainPerimeter <= 0.0))
5084  {
5085  DrainSatCurrent = 1.0e-14;
5086  }
5087  else
5088  {
5089  DrainSatCurrent = drainArea
5091  + drainPerimeter
5093  }
5094 
5095  if (DrainSatCurrent <= 0.0)
5096  {
5098  cbd = gbd * vbd;
5099  }
5100  else
5101  {
5102  if (model_.ijth == 0.0)
5103  {
5104  evbd = exp(vbd / Nvtm);
5105  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5106  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5107  }
5108  else
5109  {
5110  if (vbd < vjdm)
5111  {
5112  evbd = exp(vbd / Nvtm);
5113  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5114  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5115  }
5116  else
5117  {
5118  T0 = IsEvjdm / Nvtm;
5119  gbd = T0 + getDeviceOptions().gmin;
5120  cbd = IsEvjdm - DrainSatCurrent
5121  + T0 * (vbd - vjdm)
5122  + getDeviceOptions().gmin * vbd;
5123  }
5124  }
5125  }
5126  // End of diode DC model
5127 
5128  if (vds >= 0.0)
5129  { // normal mode
5130  mode = 1;
5131  Vds = vds;
5132  Vgs = vgs;
5133  Vbs = vbs;
5134  }
5135  else
5136  { // inverse mode
5137  mode = -1;
5138  Vds = -vds;
5139  Vgs = vgd;
5140  Vbs = vbd;
5141  }
5142 
5143  // mosfet continuation.
5144  // This idea is based, loosely, on a paper by Jaijeet
5145  // Rosychowdhury. If the artificial parameter flag has been enabled,
5146  // modify Vds and Vgs.
5147 #ifdef Xyce_DEBUG_DEVICE
5149  {
5150  Xyce::dout() << "HOMOTOPY INFO: gainscale = "
5151  << getSolverState().gainScale[blockHomotopyID] << std::endl;
5152  Xyce::dout() << "HOMOTOPY INFO: before vds = " << Vds << std::endl;
5153  Xyce::dout() << "HOMOTOPY INFO: before vgst = " << Vgs << std::endl;
5154  }
5155 #endif
5156  if (getSolverState().artParameterFlag)
5157  {
5158 
5159  double alpha = getSolverState().gainScale[blockHomotopyID];
5160  if (getDeviceOptions().staggerGainScale)
5161  {
5162  alpha *= (0.3 * randomPerturb + 1.0);
5163  if (alpha > 1.0)
5164  {
5165  alpha = 1.0;
5166  }
5167  }
5168  double vgstConst = getDeviceOptions().vgstConst;
5169  if (getDeviceOptions().randomizeVgstConst)
5170  {
5171  vgstConst *= randomPerturb;
5172  }
5173 
5174  Vds = devSupport.contVds (Vds,getSolverState().nltermScale,getDeviceOptions().vdsScaleMin);
5175  Vgs = devSupport.contVgst(Vgs, alpha, vgstConst);
5176  }
5177 #ifdef Xyce_DEBUG_DEVICE
5178  if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
5179  {
5180  Xyce::dout() << "HOMOTOPY INFO: after vds = " << Vds << std::endl;
5181  Xyce::dout() << "HOMOTOPY INFO: after vgst = " << Vgs << std::endl;
5182  }
5183 #endif
5184  // end of mosfet continuation block.
5185 
5186  T0 = Vbs - paramPtr->vbsc - 0.001;
5187  T1global = sqrt(T0 * T0 - 0.004 * paramPtr->vbsc);
5188  Vbseff = paramPtr->vbsc + 0.5 * (T0 + T1global);
5189  dVbseff_dVb = 0.5 * (1.0 + T0 / T1global);
5190 
5191  if (Vbseff < Vbs) Vbseff = Vbs;
5192 
5193  if (Vbseff > 0.0)
5194  {
5195  T0 = paramPtr->phi / (paramPtr->phi + Vbseff);
5196  Phis = paramPtr->phi * T0;
5197  dPhis_dVb = -T0 * T0;
5198  sqrtPhis = paramPtr->phis3 / (paramPtr->phi + 0.5 * Vbseff);
5199  dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / paramPtr->phis3;
5200  }
5201  else
5202  {
5203  Phis = paramPtr->phi - Vbseff;
5204  dPhis_dVb = -1.0;
5205  sqrtPhis = sqrt(Phis);
5206  dsqrtPhis_dVb = -0.5 / sqrtPhis;
5207  }
5208 
5209  Xdep = paramPtr->Xdep0 * sqrtPhis / paramPtr->sqrtPhi;
5210  dXdep_dVb = (paramPtr->Xdep0 / paramPtr->sqrtPhi) * dsqrtPhis_dVb;
5211 
5212  Leff = paramPtr->leff;
5213  Vtm = vtm;
5214  // Vth Calculation
5215  T3 = sqrt(Xdep);
5216  V0 = paramPtr->vbi - paramPtr->phi;
5217 
5218  T0 = paramPtr->dvt2 * Vbseff;
5219  if (T0 >= - 0.5)
5220  {
5221  T1 = 1.0 + T0;
5222  T2 = paramPtr->dvt2;
5223  }
5224  else // Added to avoid any discontinuity problems caused by dvt2
5225  {
5226  T4 = 1.0 / (3.0 + 8.0 * T0);
5227  T1 = (1.0 + 3.0 * T0) * T4;
5228  T2 = paramPtr->dvt2 * T4 * T4;
5229  }
5230 
5231  lt1 = model_.factor1 * T3 * T1;
5232  dlt1_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5233 
5234  T0 = paramPtr->dvt2w * Vbseff;
5235  if (T0 >= - 0.5)
5236  {
5237  T1 = 1.0 + T0;
5238  T2 = paramPtr->dvt2w;
5239  }
5240  else // Added to avoid any discontinuity problems caused by dvt2w
5241  {
5242  T4 = 1.0 / (3.0 + 8.0 * T0);
5243  T1 = (1.0 + 3.0 * T0) * T4;
5244  T2 = paramPtr->dvt2w * T4 * T4;
5245  }
5246 
5247  ltw = model_.factor1 * T3 * T1;
5248  dltw_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5249 
5250  T0 = -0.5 * paramPtr->dvt1 * Leff / lt1;
5251  if (T0 > -CONSTEXP_THRESHOLD)
5252  {
5253  T1 = exp(T0);
5254  Theta0 = T1 * (1.0 + 2.0 * T1);
5255  dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb;
5256  dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5257  }
5258  else
5259  {
5260  T1 = CONSTMIN_EXP;
5261  Theta0 = T1 * (1.0 + 2.0 * T1);
5262  dTheta0_dVb = 0.0;
5263  }
5264 
5265  thetavth = paramPtr->dvt0 * Theta0;
5266  Delt_vth = thetavth * V0;
5267  dDelt_vth_dVb = paramPtr->dvt0 * dTheta0_dVb * V0;
5268 
5269  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * Leff / ltw;
5270  if (T0 > -CONSTEXP_THRESHOLD)
5271  {
5272  T1 = exp(T0);
5273  T2 = T1 * (1.0 + 2.0 * T1);
5274  dT1_dVb = -T0 / ltw * T1 * dltw_dVb;
5275  dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5276  }
5277  else
5278  {
5279  T1 = CONSTMIN_EXP;
5280  T2 = T1 * (1.0 + 2.0 * T1);
5281  dT2_dVb = 0.0;
5282  }
5283 
5284  T0 = paramPtr->dvt0w * T2;
5285  T2 = T0 * V0;
5286  dT2_dVb = paramPtr->dvt0w * dT2_dVb * V0;
5287 
5288  TempRatio = temp / model_.tnom - 1.0;
5289  T0 = sqrt(1.0 + paramPtr->nlx / Leff);
5290  T1 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
5291  + (paramPtr->kt1 + paramPtr->kt1l / Leff
5292  + paramPtr->kt2 * Vbseff) * TempRatio;
5293 
5294  tmp2 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
5295 
5296  T3 = paramPtr->eta0 + paramPtr->etab * Vbseff;
5297  if (T3 < 1.0e-4) // avoid discontinuity problems caused by etab
5298  {
5299  T9 = 1.0 / (3.0 - 2.0e4 * T3);
5300  T3 = (2.0e-4 - T3) * T9;
5301  T4 = T9 * T9;
5302  }
5303  else
5304  {
5305  T4 = 1.0;
5306  }
5307 
5308  dDIBL_Sft_dVd = T3 * paramPtr->theta0vb0;
5309  DIBL_Sft = dDIBL_Sft_dVd * Vds;
5310 
5311  Vth = model_.dtype * paramPtr->vth0 - paramPtr->k1
5312  * paramPtr->sqrtPhi + paramPtr->k1ox * sqrtPhis
5313  - paramPtr->k2ox * Vbseff - Delt_vth - T2 + (paramPtr->k3
5314  + paramPtr->k3b * Vbseff) * tmp2 + T1 - DIBL_Sft;
5315 
5316  von = Vth;
5317 
5318  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb - paramPtr->k2ox
5319  - dDelt_vth_dVb - dT2_dVb + paramPtr->k3b * tmp2
5320  - paramPtr->etab * Vds * paramPtr->theta0vb0 * T4
5321  + paramPtr->kt2 * TempRatio;
5322 
5323  dVth_dVd = -dDIBL_Sft_dVd;
5324 
5325  // Calculate n
5326  tmp2 = paramPtr->nfactor * CONSTEPSSI / Xdep;
5327  tmp3 = paramPtr->cdsc + paramPtr->cdscb * Vbseff
5328  + paramPtr->cdscd * Vds;
5329  tmp4 = (tmp2 + tmp3 * Theta0 + paramPtr->cit) / model_.cox;
5330 
5331  if (tmp4 >= -0.5)
5332  {
5333  n = 1.0 + tmp4;
5334  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5335  + paramPtr->cdscb * Theta0) / model_.cox;
5336  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox;
5337  }
5338  else // avoid discontinuity problems caused by tmp4
5339  {
5340  T0 = 1.0 / (3.0 + 8.0 * tmp4);
5341  n = (1.0 + 3.0 * tmp4) * T0;
5342  T0 *= T0;
5343  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5344  + paramPtr->cdscb * Theta0) / model_.cox * T0;
5345  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox * T0;
5346  }
5347 
5348  // Poly Gate Si Depletion Effect
5349  T0 = paramPtr->vfb + paramPtr->phi;
5350 
5351  // added to avoid the problem caused by ngate
5352  if ((paramPtr->ngate > 1.e18) && (paramPtr->ngate < 1.e25) && (Vgs > T0))
5353  {
5354  T1 = 1.0e6 * CONSTQ * CONSTEPSSI * paramPtr->ngate
5355  / (model_.cox * model_.cox);
5356  T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1);
5357 
5358  T2 = T1 * (T4 - 1.0);
5359  T3 = 0.5 * T2 * T2 / T1; // T3 = Vpoly
5360  T7 = 1.12 - T3 - 0.05;
5361  T6 = sqrt(T7 * T7 + 0.224);
5362  T5 = 1.12 - 0.5 * (T7 + T6);
5363  Vgs_eff = Vgs - T5;
5364  dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6);
5365  }
5366  else
5367  {
5368  Vgs_eff = Vgs;
5369  dVgs_eff_dVg = 1.0;
5370  }
5371  Vgst = Vgs_eff - Vth;
5372 
5373  // Effective Vgst (Vgsteff) Calculation
5374  T10 = 2.0 * n * Vtm;
5375  VgstNVt = Vgst / T10;
5376  ExpArg = (2.0 * paramPtr->voff - Vgst) / T10;
5377 
5378  // MCJ: Very small Vgst
5379  if (VgstNVt > CONSTEXP_THRESHOLD)
5380  {
5381  Vgsteff = Vgst;
5382  dVgsteff_dVg = dVgs_eff_dVg;
5383  dVgsteff_dVd = -dVth_dVd;
5384  dVgsteff_dVb = -dVth_dVb;
5385  }
5386  else if (ExpArg > CONSTEXP_THRESHOLD)
5387  {
5388  T0 = (Vgst - paramPtr->voff) / (n * Vtm);
5389  ExpVgst = exp(T0);
5390  Vgsteff = Vtm * paramPtr->cdep0 / model_.cox * ExpVgst;
5391  dVgsteff_dVg = Vgsteff / (n * Vtm);
5392  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd);
5393  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb);
5394  dVgsteff_dVg *= dVgs_eff_dVg;
5395  }
5396  else
5397  {
5398  ExpVgst = exp(VgstNVt);
5399  T1 = T10 * log(1.0 + ExpVgst);
5400  dT1_dVg = ExpVgst / (1.0 + ExpVgst);
5401  dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb;
5402  dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd;
5403 
5404  dT2_dVg = -model_.cox / (Vtm * paramPtr->cdep0) * exp(ExpArg);
5405  T2 = 1.0 - T10 * dT2_dVg;
5406 
5407  dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd)
5408  + (T2 - 1.0) / n * dn_dVd;
5409 
5410  dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb)
5411  + (T2 - 1.0) / n * dn_dVb;
5412 
5413  Vgsteff = T1 / T2;
5414  T3 = T2 * T2;
5415 
5416  dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg;
5417  dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3;
5418  dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3;
5419  }
5420 
5421  // Calculate Effective Channel Geometry
5422  T9 = sqrtPhis - paramPtr->sqrtPhi;
5423  Weff = paramPtr->weff -2.0 *(paramPtr->dwg * Vgsteff + paramPtr->dwb * T9);
5424  dWeff_dVg = -2.0 * paramPtr->dwg;
5425  dWeff_dVb = -2.0 * paramPtr->dwb * dsqrtPhis_dVb;
5426 
5427  if (Weff < 2.0e-8) // to avoid the discontinuity problem due to Weff
5428  {
5429  T0 = 1.0 / (6.0e-8 - 2.0 * Weff);
5430  Weff = 2.0e-8 * (4.0e-8 - Weff) * T0;
5431  T0 *= T0 * 4.0e-16;
5432  dWeff_dVg *= T0;
5433  dWeff_dVb *= T0;
5434  }
5435 
5436  T0 = paramPtr->prwg * Vgsteff + paramPtr->prwb * T9;
5437  if (T0 >= -0.9)
5438  {
5439  Rds = paramPtr->rds0 * (1.0 + T0);
5440  dRds_dVg = paramPtr->rds0 * paramPtr->prwg;
5441  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb;
5442  }
5443  else // to avoid the discontinuity problem due to prwg and prwb
5444  {
5445  T1 = 1.0 / (17.0 + 20.0 * T0);
5446  Rds = paramPtr->rds0 * (0.8 + T0) * T1;
5447  T1 *= T1;
5448  dRds_dVg = paramPtr->rds0 * paramPtr->prwg * T1;
5449  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb * T1;
5450  }
5451 
5452  // Calculate Abulk
5453  T1 = 0.5 * paramPtr->k1ox / sqrtPhis;
5454  dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb;
5455 
5456  T9 = sqrt(paramPtr->xj * Xdep);
5457  tmp1 = Leff + 2.0 * T9;
5458  T5 = Leff / tmp1;
5459  tmp2 = paramPtr->a0 * T5;
5460  tmp3 = paramPtr->weff + paramPtr->b1;
5461  tmp4 = paramPtr->b0 / tmp3;
5462  T2 = tmp2 + tmp4;
5463  dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb;
5464  T6 = T5 * T5;
5465  T7 = T5 * T6;
5466 
5467  Abulk0 = 1.0 + T1 * T2;
5468  dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb;
5469 
5470  T8 = paramPtr->ags * paramPtr->a0 * T7;
5471  dAbulk_dVg = -T1 * T8;
5472  Abulk = Abulk0 + dAbulk_dVg * Vgsteff;
5473  dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb);
5474 
5475  if (Abulk0 < 0.1) // added to avoid the problems caused by Abulk0
5476  {
5477  T9 = 1.0 / (3.0 - 20.0 * Abulk0);
5478  Abulk0 = (0.2 - Abulk0) * T9;
5479  dAbulk0_dVb *= T9 * T9;
5480  }
5481 
5482  if (Abulk < 0.1) // added to avoid the problems caused by Abulk
5483  {
5484  T9 = 1.0 / (3.0 - 20.0 * Abulk);
5485  Abulk = (0.2 - Abulk) * T9;
5486  T10 = T9 * T9;
5487  dAbulk_dVb *= T10;
5488  dAbulk_dVg *= T10;
5489  }
5490 
5491  T2 = paramPtr->keta * Vbseff;
5492  if (T2 >= -0.9)
5493  {
5494  T0 = 1.0 / (1.0 + T2);
5495  dT0_dVb = -paramPtr->keta * T0 * T0;
5496  }
5497  else // added to avoid the problems caused by Keta
5498  {
5499  T1 = 1.0 / (0.8 + T2);
5500  T0 = (17.0 + 20.0 * T2) * T1;
5501  dT0_dVb = -paramPtr->keta * T1 * T1;
5502  }
5503 
5504  dAbulk_dVg *= T0;
5505  dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb;
5506  dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb;
5507  Abulk *= T0;
5508  Abulk0 *= T0;
5509 
5510  // Mobility calculation
5511  if (model_.mobMod == 1)
5512  {
5513  T0 = Vgsteff + Vth + Vth;
5514  T2 = paramPtr->ua + paramPtr->uc * Vbseff;
5515  T3 = T0 / model_.tox;
5516  T5 = T3 * (T2 + paramPtr->ub * T3);
5517  dDenomi_dVg = (T2 + 2.0 * paramPtr->ub * T3) / model_.tox;
5518  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5519  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T3;
5520  }
5521  else if (model_.mobMod == 2)
5522  {
5523  T5 = Vgsteff / model_.tox * (paramPtr->ua
5524  + paramPtr->uc * Vbseff + paramPtr->ub * Vgsteff / model_.tox);
5525 
5526  dDenomi_dVg = (paramPtr->ua + paramPtr->uc * Vbseff
5527  + 2.0 * paramPtr->ub * Vgsteff / model_.tox) / model_.tox;
5528 
5529  dDenomi_dVd = 0.0;
5530  dDenomi_dVb = Vgsteff * paramPtr->uc / model_.tox;
5531  }
5532  else
5533  {
5534  T0 = Vgsteff + Vth + Vth;
5535  T2 = 1.0 + paramPtr->uc * Vbseff;
5536  T3 = T0 / model_.tox;
5537  T4 = T3 * (paramPtr->ua + paramPtr->ub * T3);
5538  T5 = T4 * T2;
5539 
5540  dDenomi_dVg = (paramPtr->ua + 2.0 * paramPtr->ub * T3) * T2 /model_.tox;
5541  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5542  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T4;
5543  }
5544 
5545  if (T5 >= -0.8)
5546  {
5547  Denomi = 1.0 + T5;
5548  }
5549  else // Added to avoid the discontinuity problem caused by ua and ub
5550  {
5551  T9 = 1.0 / (7.0 + 10.0 * T5);
5552  Denomi = (0.6 + T5) * T9;
5553  T9 *= T9;
5554  dDenomi_dVg *= T9;
5555  dDenomi_dVd *= T9;
5556  dDenomi_dVb *= T9;
5557  }
5558 
5559  ueff = paramPtr->u0temp / Denomi;
5560  T9 = -ueff / Denomi;
5561  dueff_dVg = T9 * dDenomi_dVg;
5562  dueff_dVd = T9 * dDenomi_dVd;
5563  dueff_dVb = T9 * dDenomi_dVb;
5564 
5565  // Saturation Drain Voltage Vdsat
5566  WVCox = Weff * paramPtr->vsattemp * model_.cox;
5567  WVCoxRds = WVCox * Rds;
5568 
5569  Esat = 2.0 * paramPtr->vsattemp / ueff;
5570  EsatL = Esat * Leff;
5571  T0 = -EsatL /ueff;
5572  dEsatL_dVg = T0 * dueff_dVg;
5573  dEsatL_dVd = T0 * dueff_dVd;
5574  dEsatL_dVb = T0 * dueff_dVb;
5575 
5576  // Sqrt()
5577  a1 = paramPtr->a1;
5578  if (a1 == 0.0)
5579  {
5580  Lambda = paramPtr->a2;
5581  dLambda_dVg = 0.0;
5582  }
5583  else if (a1 > 0.0) // Added to avoid the discontinuity problem
5584  // caused by a1 and a2 (Lambda)
5585  {
5586  T0 = 1.0 - paramPtr->a2;
5587  T1 = T0 - paramPtr->a1 * Vgsteff - 0.0001;
5588  T2 = sqrt(T1 * T1 + 0.0004 * T0);
5589  Lambda = paramPtr->a2 + T0 - 0.5 * (T1 + T2);
5590  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5591  }
5592  else
5593  {
5594  T1 = paramPtr->a2 + paramPtr->a1 * Vgsteff - 0.0001;
5595  T2 = sqrt(T1 * T1 + 0.0004 * paramPtr->a2);
5596  Lambda = 0.5 * (T1 + T2);
5597  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5598  }
5599 
5600  Vgst2Vtm = Vgsteff + 2.0 * Vtm;
5601  if (Rds > 0)
5602  {
5603  tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff;
5604  tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff;
5605  }
5606  else
5607  {
5608  tmp2 = dWeff_dVg / Weff;
5609  tmp3 = dWeff_dVb / Weff;
5610  }
5611 
5612  if ((Rds == 0.0) && (Lambda == 1.0))
5613  {
5614  T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm);
5615  tmp1 = 0.0;
5616  T1 = T0 * T0;
5617  T2 = Vgst2Vtm * T0;
5618  T3 = EsatL * Vgst2Vtm;
5619  Vdsat = T3 * T0;
5620 
5621  dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1;
5622  dT0_dVd = -(Abulk * dEsatL_dVd) * T1;
5623  dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1;
5624 
5625  dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0;
5626  dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd;
5627  dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb;
5628  }
5629  else
5630  {
5631  tmp1 = dLambda_dVg / (Lambda * Lambda);
5632  T9 = Abulk * WVCoxRds;
5633  T8 = Abulk * T9;
5634  T7 = Vgst2Vtm * T9;
5635  T6 = Vgst2Vtm * WVCoxRds;
5636  T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda);
5637  dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1
5638  + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg);
5639 
5640  dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3)
5641  + (1.0 / Lambda - 1.0) * dAbulk_dVb);
5642  dT0_dVd = 0.0;
5643  T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7;
5644 
5645  dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1
5646  + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9
5647  + T7 * tmp2 + T6 * dAbulk_dVg);
5648 
5649  dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb
5650  + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3);
5651 
5652  dT1_dVd = Abulk * dEsatL_dVd;
5653 
5654  T2 = Vgst2Vtm * (EsatL + 2.0 * T6);
5655  dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg
5656  + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2);
5657 
5658  dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3);
5659  dT2_dVd = Vgst2Vtm * dEsatL_dVd;
5660 
5661  T3 = sqrt(T1 * T1 - 2.0 * T0 * T2);
5662  Vdsat = (T1 - T3) / T0;
5663 
5664  dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3;
5665  dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3;
5666  dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3;
5667 
5668  dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2
5669  - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0;
5670 
5671  dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2
5672  - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0;
5673 
5674  dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0;
5675  }
5676  vdsat = Vdsat;
5677 
5678  // Effective Vds (Vdseff) Calculation
5679  T1 = Vdsat - Vds - paramPtr->delta;
5680  dT1_dVg = dVdsat_dVg;
5681  dT1_dVd = dVdsat_dVd - 1.0;
5682  dT1_dVb = dVdsat_dVb;
5683 
5684  T2 = sqrt(T1 * T1 + 4.0 * paramPtr->delta * Vdsat);
5685  T0 = T1 / T2;
5686  T3 = 2.0 * paramPtr->delta / T2;
5687  dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg;
5688  dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd;
5689  dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb;
5690 
5691  Vdseff = Vdsat - 0.5 * (T1 + T2);
5692  dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg);
5693  dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd);
5694  dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb);
5695 
5696  // Added to eliminate non-zero Vdseff at Vds=0.0
5697  if (Vds == 0.0)
5698  {
5699  Vdseff = 0.0;
5700  dVdseff_dVg = 0.0;
5701  dVdseff_dVb = 0.0;
5702  }
5703 
5704  // Calculate VAsat
5705  tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm;
5706  T9 = WVCoxRds * Vgsteff;
5707  T8 = T9 / Vgst2Vtm;
5708  T0 = EsatL + Vdsat + 2.0 * T9 * tmp4;
5709 
5710  T7 = 2.0 * WVCoxRds * tmp4;
5711  dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff)
5712  - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm
5713  + Vdsat * dAbulk_dVg);
5714 
5715  dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff
5716  - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
5717  dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd;
5718 
5719  T9 = WVCoxRds * Abulk;
5720  T1 = 2.0 / Lambda - 1.0 + T9;
5721  dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg);
5722  dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3;
5723 
5724  Vasat = T0 / T1;
5725  dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1;
5726  dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1;
5727  dVasat_dVd = dT0_dVd / T1;
5728 
5729  if (Vdseff > Vds) Vdseff = Vds;
5730 
5731  diffVds = Vds - Vdseff;
5732 
5733  // Calculate VACLM
5734  if ((paramPtr->pclm > 0.0) && (diffVds > 1.0e-10))
5735  {
5736  T0 = 1.0 / (paramPtr->pclm * Abulk * paramPtr->litl);
5737  dT0_dVb = -T0 / Abulk * dAbulk_dVb;
5738  dT0_dVg = -T0 / Abulk * dAbulk_dVg;
5739 
5740  T2 = Vgsteff / EsatL;
5741  T1 = Leff * (Abulk + T2);
5742  dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg);
5743  dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL);
5744  dT1_dVd = -T2 * dEsatL_dVd / Esat;
5745 
5746  T9 = T0 * T1;
5747  VACLM = T9 * diffVds;
5748  dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg
5749  + T1 * diffVds * dT0_dVg;
5750 
5751  dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds
5752  - T9 * dVdseff_dVb;
5753 
5754  dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd);
5755  }
5756  else
5757  {
5758  VACLM = CONSTMAX_EXP;
5759  dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0;
5760  }
5761 
5762  // Calculate VADIBL
5763  if (paramPtr->thetaRout > 0.0)
5764  {
5765  T8 = Abulk * Vdsat;
5766  T0 = Vgst2Vtm * T8;
5767  dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8
5768  + Vgst2Vtm * Vdsat * dAbulk_dVg;
5769 
5770  dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
5771  dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd;
5772 
5773  T1 = Vgst2Vtm + T8;
5774  dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg;
5775  dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat;
5776  dT1_dVd = Abulk * dVdsat_dVd;
5777 
5778  T9 = T1 * T1;
5779  T2 = paramPtr->thetaRout;
5780 
5781  VADIBL = (Vgst2Vtm - T0 / T1) / T2;
5782  dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2;
5783  dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2;
5784  dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2;
5785 
5786  T7 = paramPtr->pdiblb * Vbseff;
5787  if (T7 >= -0.9)
5788  {
5789  T3 = 1.0 / (1.0 + T7);
5790  VADIBL *= T3;
5791  dVADIBL_dVg *= T3;
5792  dVADIBL_dVb = (dVADIBL_dVb - VADIBL * paramPtr->pdiblb) * T3;
5793  dVADIBL_dVd *= T3;
5794  }
5795  else // Added to avoid the discontinuity problem caused by pdiblcb
5796  {
5797  T4 = 1.0 / (0.8 + T7);
5798  T3 = (17.0 + 20.0 * T7) * T4;
5799  dVADIBL_dVg *= T3;
5800  dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * paramPtr->pdiblb * T4 * T4;
5801 
5802  dVADIBL_dVd *= T3;
5803  VADIBL *= T3;
5804  }
5805  }
5806  else
5807  {
5808  VADIBL = CONSTMAX_EXP;
5809  dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0;
5810  }
5811 
5812  // Calculate VA
5813  T8 = paramPtr->pvag / EsatL;
5814  T9 = T8 * Vgsteff;
5815  if (T9 > -0.9)
5816  {
5817  T0 = 1.0 + T9;
5818  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL);
5819  dT0_dVb = -T9 * dEsatL_dVb / EsatL;
5820  dT0_dVd = -T9 * dEsatL_dVd / EsatL;
5821  }
5822  else /* Added to avoid the discontinuity problems caused by pvag */
5823  {
5824  T1 = 1.0 / (17.0 + 20.0 * T9);
5825  T0 = (0.8 + T9) * T1;
5826  T1 *= T1;
5827  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1;
5828 
5829  T9 *= T1 / EsatL;
5830  dT0_dVb = -T9 * dEsatL_dVb;
5831  dT0_dVd = -T9 * dEsatL_dVd;
5832  }
5833 
5834  tmp1 = VACLM * VACLM;
5835  tmp2 = VADIBL * VADIBL;
5836  tmp3 = VACLM + VADIBL;
5837 
5838  T1 = VACLM * VADIBL / tmp3;
5839  tmp3 *= tmp3;
5840  dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3;
5841  dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3;
5842  dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3;
5843 
5844  Va = Vasat + T0 * T1;
5845  dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg;
5846  dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd;
5847  dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb;
5848 
5849  // Calculate VASCBE
5850  if (paramPtr->pscbe2 > 0.0)
5851  {
5852  if (diffVds > paramPtr->pscbe1 * paramPtr->litl / CONSTEXP_THRESHOLD)
5853  {
5854  T0 = paramPtr->pscbe1 * paramPtr->litl / diffVds;
5855  VASCBE = Leff * exp(T0) / paramPtr->pscbe2;
5856  T1 = T0 * VASCBE / diffVds;
5857  dVASCBE_dVg = T1 * dVdseff_dVg;
5858  dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd);
5859  dVASCBE_dVb = T1 * dVdseff_dVb;
5860  }
5861  else
5862  {
5863  VASCBE = CONSTMAX_EXP * Leff/paramPtr->pscbe2;
5864  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
5865  }
5866  }
5867  else
5868  {
5869  VASCBE = CONSTMAX_EXP;
5870  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
5871  }
5872 
5873  // Calculate Ids
5874  CoxWovL = model_.cox * Weff / Leff;
5875  beta = ueff * CoxWovL;
5876  dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff;
5877  dbeta_dVd = CoxWovL * dueff_dVd;
5878  dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff;
5879 
5880  T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm;
5881  dT0_dVg = -0.5 * (Abulk * dVdseff_dVg
5882  - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm;
5883  dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm;
5884  dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm;
5885 
5886  fgche1 = Vgsteff * T0;
5887  dfgche1_dVg = Vgsteff * dT0_dVg + T0;
5888  dfgche1_dVd = Vgsteff * dT0_dVd;
5889  dfgche1_dVb = Vgsteff * dT0_dVb;
5890 
5891  T9 = Vdseff / EsatL;
5892  fgche2 = 1.0 + T9;
5893  dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL;
5894  dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL;
5895  dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL;
5896 
5897  gche = beta * fgche1 / fgche2;
5898  dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg
5899  - gche * dfgche2_dVg) / fgche2;
5900 
5901  dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd
5902  - gche * dfgche2_dVd) / fgche2;
5903 
5904  dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb
5905  - gche * dfgche2_dVb) / fgche2;
5906 
5907  T0 = 1.0 + gche * Rds;
5908  T9 = Vdseff / T0;
5909  Idl = gche * T9;
5910 
5911  dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0
5912  - Idl * gche / T0 * dRds_dVg ;
5913 
5914  dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0;
5915  dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb
5916  - Idl * dRds_dVb * gche) / T0;
5917 
5918  T9 = diffVds / Va;
5919  T0 = 1.0 + T9;
5920  Idsa = Idl * T0;
5921  dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va;
5922  dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd
5923  - T9 * dVa_dVd) / Va;
5924 
5925  dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va;
5926 
5927  T9 = diffVds / VASCBE;
5928  T0 = 1.0 + T9;
5929  Ids = Idsa * T0;
5930 
5931  Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE;
5932  Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd
5933  - T9 * dVASCBE_dVd) / VASCBE;
5934  Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb
5935  + T9 * dVASCBE_dVb) / VASCBE;
5936 
5937  Gds += Gm * dVgsteff_dVd;
5938  Gmb += Gm * dVgsteff_dVb;
5939  Gm *= dVgsteff_dVg;
5940  Gmb *= dVbseff_dVb;
5941 
5942  // Substrate current begins
5943  tmp = paramPtr->alpha0 + paramPtr->alpha1 * Leff;
5944  if ((tmp <= 0.0) || (paramPtr->beta0 <= 0.0))
5945  {
5946  Isub = Gbd = Gbb = Gbg = 0.0;
5947  }
5948  else
5949  {
5950  T2 = tmp / Leff;
5951  if (diffVds > paramPtr->beta0 / CONSTEXP_THRESHOLD)
5952  {
5953  T0 = -paramPtr->beta0 / diffVds;
5954  T1 = T2 * diffVds * exp(T0);
5955  T3 = T1 / diffVds * (T0 - 1.0);
5956  dT1_dVg = T3 * dVdseff_dVg;
5957  dT1_dVd = T3 * (dVdseff_dVd - 1.0);
5958  dT1_dVb = T3 * dVdseff_dVb;
5959  }
5960  else
5961  {
5962  T3 = T2 * CONSTMIN_EXP;
5963  T1 = T3 * diffVds;
5964  dT1_dVg = -T3 * dVdseff_dVg;
5965  dT1_dVd = T3 * (1.0 - dVdseff_dVd);
5966  dT1_dVb = -T3 * dVdseff_dVb;
5967  }
5968  Isub = T1 * Idsa;
5969  Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg;
5970  Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd;
5971  Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb;
5972 
5973  Gbd += Gbg * dVgsteff_dVd;
5974  Gbb += Gbg * dVgsteff_dVb;
5975  Gbg *= dVgsteff_dVg;
5976  Gbb *= dVbseff_dVb; // bug fixing
5977  }
5978 
5979  // copy over local drain (channel) current vars to instance vars:
5980  cdrain = Ids;
5981  gds = Gds;
5982  gm = Gm;
5983  gmbs = Gmb;
5984 
5985  // copy over local substrate current vars to instance vars:
5986  gbbs = Gbb;
5987  gbgs = Gbg;
5988  gbds = Gbd;
5989 
5990  csub = Isub;
5991 
5992  // thermal noise Qinv calculated from all capMod
5993  // * 0, 1, 2 & 3 stored in iterI->qinv 1/1998
5994  if ((model_.xpart < 0) || (!ChargeComputationNeeded))
5995  {
5996  qgate = qdrn = qsrc = qbulk = 0.0;
5997  cggb = cgsb = cgdb = 0.0;
5998  cdgb = cdsb = cddb = 0.0;
5999  cbgb = cbsb = cbdb = 0.0;
6000  cqdb = cqsb = cqgb = cqbb = 0.0;
6001 
6002  gtau = 0.0;
6003  goto finished;
6004  }
6005  else if (model_.capMod == 0)
6006  {
6007  if (Vbseff < 0.0)
6008  {
6009  Vbseff = Vbs;
6010  dVbseff_dVb = 1.0;
6011  }
6012  else
6013  {
6014  Vbseff = paramPtr->phi - Phis;
6015  dVbseff_dVb = -dPhis_dVb;
6016  }
6017 
6018  Vfb = paramPtr->vfbcv;
6019  Vth = Vfb + paramPtr->phi + paramPtr->k1ox * sqrtPhis;
6020  Vgst = Vgs_eff - Vth;
6021  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb;
6022  dVgst_dVb = -dVth_dVb;
6024 
6026  Arg1 = Vgs_eff - Vbseff - Vfb;
6027 
6028  if (Arg1 <= 0.0)
6029  {
6030  qgate = CoxWL * Arg1;
6031  qbulk = -qgate;
6032  qdrn = 0.0;
6033 
6034  cggb = CoxWL * dVgs_eff_dVg;
6035  cgdb = 0.0;
6036  cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg);
6037 
6038  cdgb = 0.0;
6039  cddb = 0.0;
6040  cdsb = 0.0;
6041 
6042  cbgb = -CoxWL * dVgs_eff_dVg;
6043  cbdb = 0.0;
6044  cbsb = -cgsb;
6045  qinv = 0.0;
6046  }
6047  else if (Vgst <= 0.0)
6048  {
6049  T1 = 0.5 * paramPtr->k1ox;
6050  T2 = sqrt(T1 * T1 + Arg1);
6051  qgate = CoxWL * paramPtr->k1ox * (T2 - T1);
6052  qbulk = -qgate;
6053  qdrn = 0.0;
6054 
6055  T0 = CoxWL * T1 / T2;
6056  cggb = T0 * dVgs_eff_dVg;
6057  cgdb = 0.0;
6058  cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg);
6059 
6060  cdgb = 0.0;
6061  cddb = 0.0;
6062  cdsb = 0.0;
6063 
6064  cbgb = -cggb;
6065  cbdb = 0.0;
6066  cbsb = -cgsb;
6067  qinv = 0.0;
6068  }
6069  else
6070  {
6071  One_Third_CoxWL = CoxWL / 3.0;
6072  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6073 
6074  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6075  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6076 
6077  Vdsat = Vgst / AbulkCV;
6078  dVdsat_dVg = dVgs_eff_dVg / AbulkCV;
6079  dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV;
6080 
6081  if (model_.xpart > 0.5)
6082  { // 0/100 Charge partition model
6083  if (Vdsat <= Vds)
6084  { // saturation region
6085  T1 = Vdsat / 3.0;
6086  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6087 
6088  T2 = -Two_Third_CoxWL * Vgst;
6089  qbulk = -(qgate + T2);
6090  qdrn = 0.0;
6091 
6092  cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg)* dVgs_eff_dVg;
6093  T2 = -One_Third_CoxWL * dVdsat_dVb;
6094 
6095  cgsb = -(cggb + T2);
6096  cgdb = 0.0;
6097 
6098  cdgb = 0.0;
6099  cddb = 0.0;
6100  cdsb = 0.0;
6101 
6102  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6103  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6104 
6105  cbsb = -(cbgb + T3);
6106  cbdb = 0.0;
6107  qinv = -(qgate + qbulk);
6108  }
6109  else
6110  { // linear region
6111  Alphaz = Vgst / Vdsat;
6112  T1 = 2.0 * Vdsat - Vds;
6113  T2 = Vds / (3.0 * T1);
6114  T3 = T2 * Vds;
6115  T9 = 0.25 * CoxWL;
6116  T4 = T9 * Alphaz;
6117  T7 = 2.0 * Vds - T1 - 3.0 * T3;
6118  T8 = T3 - T1 - 2.0 * Vds;
6119  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6120 
6121  T10 = T4 * T8;
6122  qdrn = T4 * T7;
6123  qbulk = -(qgate + qdrn + T10);
6124 
6125  T5 = T3 / T1;
6126  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6127 
6128  T11 = -CoxWL * T5 * dVdsat_dVb;
6129  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6130  cgsb = -(cggb + T11 + cgdb);
6131 
6132  T6 = 1.0 / Vdsat;
6133  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6134  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6135 
6136  T7 = T9 * T7;
6137  T8 = T9 * T8;
6138  T9 = 2.0 * T4 * (1.0 - 3.0 * T5);
6139  cdgb = (T7 * dAlphaz_dVg - T9* dVdsat_dVg) * dVgs_eff_dVg;
6140 
6141  T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb;
6142  cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5);
6143  cdsb = -(cdgb + T12 + cddb);
6144 
6145  T9 = 2.0 * T4 * (1.0 + T5);
6146  T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg;
6147  T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb;
6148  T12 = T4 * (2.0 * T2 + T5 - 1.0);
6149  T0 = -(T10 + T11 + T12);
6150 
6151 
6152  cbgb = -(cggb + cdgb + T10);
6153  cbdb = -(cgdb + cddb + T12);
6154  cbsb = -(cgsb + cdsb + T0);
6155  qinv = -(qgate + qbulk);
6156  }
6157  }
6158  else if (model_.xpart < 0.5)
6159  { // 40/60 Charge partition model
6160  if (Vds >= Vdsat)
6161  { // saturation region
6162  T1 = Vdsat / 3.0;
6163  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6164 
6165  T2 = -Two_Third_CoxWL * Vgst;
6166  qbulk = -(qgate + T2);
6167  qdrn = 0.4 * T2;
6168 
6169  cggb = One_Third_CoxWL* (3.0 - dVdsat_dVg) * dVgs_eff_dVg;
6170 
6171  T2 = -One_Third_CoxWL * dVdsat_dVb;
6172  cgsb = -(cggb + T2);
6173  cgdb = 0.0;
6174 
6175  T3 = 0.4 * Two_Third_CoxWL;
6176  cdgb = -T3 * dVgs_eff_dVg;
6177  cddb = 0.0;
6178 
6179  T4 = T3 * dVth_dVb;
6180  cdsb = -(T4 + cdgb);
6181 
6182  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6183  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6184  cbsb = -(cbgb + T3);
6185  cbdb = 0.0;
6186  qinv = -(qgate + qbulk);
6187  }
6188  else
6189  { // linear region
6190  Alphaz = Vgst / Vdsat;
6191  T1 = 2.0 * Vdsat - Vds;
6192  T2 = Vds / (3.0 * T1);
6193  T3 = T2 * Vds;
6194  T9 = 0.25 * CoxWL;
6195  T4 = T9 * Alphaz;
6196  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6197 
6198  T5 = T3 / T1;
6199  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6200  tmp = -CoxWL * T5 * dVdsat_dVb;
6201  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6202  cgsb = -(cggb + cgdb + tmp);
6203 
6204  T6 = 1.0 / Vdsat;
6205  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6206  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6207 
6208  T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + 1.2 * Vds * Vds;
6209  T8 = T2 / T1;
6210  T7 = Vds - T1 - T8 * T6;
6211  qdrn = T4 * T7;
6212  T7 *= T9;
6213  tmp = T8 / T1;
6214  tmp1 = T4*(2.0 - 4.0 * tmp * T6 + T8 *(16.0 * Vdsat - 6.0 *Vds));
6215 
6216  cdgb = (T7 *dAlphaz_dVg - tmp1 *dVdsat_dVg) *dVgs_eff_dVg;
6217 
6218  T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb;
6219  cddb = T4 * (2.0 - (1.0 / (3.0 * T1
6220  * T1) + 2.0 * tmp) * T6 + T8
6221  * (6.0 * Vdsat - 2.4 * Vds));
6222 
6223  cdsb = -(cdgb + T10 + cddb);
6224 
6225  T7 = 2.0 * (T1 + T3);
6226  qbulk = -(qgate - T4 * T7);
6227  T7 *= T9;
6228  T0 = 4.0 * T4 * (1.0 - T5);
6229  T12 = (-T7 * dAlphaz_dVg - cdgb
6230  - T0 * dVdsat_dVg) * dVgs_eff_dVg;
6231  T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb;
6232  T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5)
6233  - cddb;
6234 
6235  tmp = -(T10 + T11 + T12);
6236 
6237  cbgb = -(cggb + cdgb + T12);
6238  cbdb = -(cgdb + cddb + T11);
6239  cbsb = -(cgsb + cdsb + tmp);
6240  qinv = -(qgate + qbulk);
6241  }
6242  }
6243  else
6244  { // 50/50 partitioning
6245  if (Vds >= Vdsat)
6246  { // saturation region
6247  T1 = Vdsat / 3.0;
6248  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6249  T2 = -Two_Third_CoxWL * Vgst;
6250  qbulk = -(qgate + T2);
6251  qdrn = 0.5 * T2;
6252 
6253  cggb = One_Third_CoxWL * (3.0 -dVdsat_dVg) * dVgs_eff_dVg;
6254  T2 = -One_Third_CoxWL * dVdsat_dVb;
6255  cgsb = -(cggb + T2);
6256  cgdb = 0.0;
6257 
6258  cdgb = -One_Third_CoxWL * dVgs_eff_dVg;
6259  cddb = 0.0;
6260  T4 = One_Third_CoxWL * dVth_dVb;
6261  cdsb = -(T4 + cdgb);
6262 
6263  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6264  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6265  cbsb = -(cbgb + T3);
6266  cbdb = 0.0;
6267  qinv = -(qgate + qbulk);
6268  }
6269  else
6270  { // linear region
6271  Alphaz = Vgst / Vdsat;
6272  T1 = 2.0 * Vdsat - Vds;
6273  T2 = Vds / (3.0 * T1);
6274  T3 = T2 * Vds;
6275  T9 = 0.25 * CoxWL;
6276  T4 = T9 * Alphaz;
6277  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3))
6278  ;
6279 
6280  T5 = T3 / T1;
6281  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6282 
6283  tmp = -CoxWL * T5 * dVdsat_dVb;
6284  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6285  cgsb = -(cggb + cgdb + tmp);
6286 
6287  T6 = 1.0 / Vdsat;
6288  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6289  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6290 
6291  T7 = T1 + T3;
6292  qdrn = -T4 * T7;
6293  qbulk = - (qgate + qdrn + qdrn);
6294  T7 *= T9;
6295  T0 = T4 * (2.0 * T5 - 2.0);
6296 
6297  cdgb = (T0 * dVdsat_dVg - T7 *dAlphaz_dVg) *dVgs_eff_dVg;
6298  T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb;
6299  cddb = T4 * (1.0 - 2.0 * T2 - T5);
6300  cdsb = -(cdgb + T12 + cddb);
6301 
6302  cbgb = -(cggb + 2.0 * cdgb);
6303  cbdb = -(cgdb + 2.0 * cddb);
6304  cbsb = -(cgsb + 2.0 * cdsb);
6305  qinv = -(qgate + qbulk);
6306  }
6307  }
6308  }
6309  }
6310  else
6311  {
6312  if (Vbseff < 0.0)
6313  {
6314  VbseffCV = Vbseff;
6315  dVbseffCV_dVb = 1.0;
6316  }
6317  else
6318  {
6319  VbseffCV = paramPtr->phi - Phis;
6320  dVbseffCV_dVb = -dPhis_dVb;
6321  }
6322 
6324 
6325  // Seperate VgsteffCV with noff and voffcv
6326  noff = n * paramPtr->noff;
6327  dnoff_dVd = paramPtr->noff * dn_dVd;
6328  dnoff_dVb = paramPtr->noff * dn_dVb;
6329  T0 = Vtm * noff;
6330  voffcv = paramPtr->voffcv;
6331  VgstNVt = (Vgst - voffcv) / T0;
6332 
6333  if (VgstNVt > CONSTEXP_THRESHOLD)
6334  {
6335  Vgsteff = Vgst - voffcv;
6336  dVgsteff_dVg = dVgs_eff_dVg;
6337  dVgsteff_dVd = -dVth_dVd;
6338  dVgsteff_dVb = -dVth_dVb;
6339  }
6340  else if (VgstNVt < -CONSTEXP_THRESHOLD)
6341  {
6342  Vgsteff = T0 * log(1.0 + CONSTMIN_EXP);
6343  dVgsteff_dVg = 0.0;
6344  dVgsteff_dVd = Vgsteff / noff;
6345  dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb;
6346  dVgsteff_dVd *= dnoff_dVd;
6347  }
6348  else
6349  {
6350  ExpVgst = exp(VgstNVt);
6351  Vgsteff = T0 * log(1.0 + ExpVgst);
6352  dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst);
6353  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv)
6354  / noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd;
6355  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv)
6356  / noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb;
6357  dVgsteff_dVg *= dVgs_eff_dVg;
6358  } // End of VgsteffCV
6359 
6360  if (model_.capMod == 1)
6361  {
6362  Vfb = paramPtr->vfbzb;
6363  Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff;
6364 
6365  if (Arg1 <= 0.0)
6366  {
6367  qgate = CoxWL * Arg1;
6368  Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg);
6369  Cgd = -CoxWL * dVgsteff_dVd;
6370  Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb);
6371  }
6372  else
6373  {
6374  T0 = 0.5 * paramPtr->k1ox;
6375  T1 = sqrt(T0 * T0 + Arg1);
6376  T2 = CoxWL * T0 / T1;
6377 
6378  qgate = CoxWL * paramPtr->k1ox * (T1 - T0);
6379 
6380  Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg);
6381  Cgd = -T2 * dVgsteff_dVd;
6382  Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb);
6383  }
6384  qbulk = -qgate;
6385  Cbg = -Cgg;
6386  Cbd = -Cgd;
6387  Cbb = -Cgb;
6388 
6389  One_Third_CoxWL = CoxWL / 3.0;
6390  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6391  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6392  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6393  VdsatCV = Vgsteff / AbulkCV;
6394 
6395  if (VdsatCV < Vds)
6396  {
6397  dVdsatCV_dVg = 1.0 / AbulkCV;
6398  dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV;
6399  T0 = Vgsteff - VdsatCV / 3.0;
6400  dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0;
6401  dT0_dVb = -dVdsatCV_dVb / 3.0;
6402  qgate += CoxWL * T0;
6403  Cgg1 = CoxWL * dT0_dVg;
6404  Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb;
6405  Cgd1 = Cgg1 * dVgsteff_dVd;
6406  Cgg1 *= dVgsteff_dVg;
6407  Cgg += Cgg1;
6408  Cgb += Cgb1;
6409  Cgd += Cgd1;
6410 
6411  T0 = VdsatCV - Vgsteff;
6412  dT0_dVg = dVdsatCV_dVg - 1.0;
6413  dT0_dVb = dVdsatCV_dVb;
6414  qbulk += One_Third_CoxWL * T0;
6415  Cbg1 = One_Third_CoxWL * dT0_dVg;
6416  Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb;
6417  Cbd1 = Cbg1 * dVgsteff_dVd;
6418  Cbg1 *= dVgsteff_dVg;
6419  Cbg += Cbg1;
6420  Cbb += Cbb1;
6421  Cbd += Cbd1;
6422 
6423  if (model_.xpart > 0.5) T0 = -Two_Third_CoxWL;
6424  else if (model_.xpart < 0.5) T0 = -0.4 * CoxWL;
6425  else T0 = -One_Third_CoxWL;
6426 
6427  qsrc = T0 * Vgsteff;
6428  Csg = T0 * dVgsteff_dVg;
6429  Csb = T0 * dVgsteff_dVb;
6430  Csd = T0 * dVgsteff_dVd;
6431  Cgb *= dVbseff_dVb;
6432  Cbb *= dVbseff_dVb;
6433  Csb *= dVbseff_dVb;
6434  }
6435  else
6436  {
6437  T0 = AbulkCV * Vds;
6438  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20);
6439  T2 = Vds / T1;
6440  T3 = T0 * T2;
6441  dT3_dVg = -12.0 * T2 * T2 * AbulkCV;
6442  dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5;
6443  dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff;
6444 
6445  qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3);
6446  Cgg1 = CoxWL * (1.0 + dT3_dVg);
6447  Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb;
6448  Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd;
6449  Cgg1 *= dVgsteff_dVg;
6450  Cgg += Cgg1;
6451  Cgb += Cgb1;
6452  Cgd += Cgd1;
6453 
6454  qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3);
6455  Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg);
6456  Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb
6457  + (0.5 * Vds - T3) * dAbulkCV_dVb)
6458  + Cbg1 * dVgsteff_dVb;
6459  Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd
6460  + Cbg1 * dVgsteff_dVd;
6461  Cbg1 *= dVgsteff_dVg;
6462  Cbg += Cbg1;
6463  Cbb += Cbb1;
6464  Cbd += Cbd1;
6465 
6466  if (model_.xpart > 0.5)
6467  { // 0/100 Charge petition model
6468  T1 = T1 + T1;
6469  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6470  Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1 * AbulkCV);
6471  Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb
6472  - 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0)
6473  * dAbulkCV_dVb) + Csg * dVgsteff_dVb;
6474  Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0
6475  / T1 / T1 * (4.0 * Vgsteff - T0))
6476  + Csg * dVgsteff_dVd;
6477  Csg *= dVgsteff_dVg;
6478  }
6479  else if (model_.xpart < 0.5)
6480  { // 40/60 Charge petition model
6481  T1 = T1 / 12.0;
6482  T2 = 0.5 * CoxWL / (T1 * T1);
6483  T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff
6484  * (Vgsteff - 4.0 * T0 / 3.0))
6485  - 2.0 * T0 * T0 * T0 / 15.0;
6486  qsrc = -T2 * T3;
6487  T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6488  + 0.4 * T0 * T0;
6489  Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6490  * Vgsteff - 8.0 * T0 / 3.0)
6491  + 2.0 * T0 * T0 / 3.0);
6492  Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb
6493  + Csg * dVgsteff_dVb;
6494  Csd = (qsrc / T1 + T2 * T4) * AbulkCV
6495  + Csg * dVgsteff_dVd;
6496  Csg *= dVgsteff_dVg;
6497  }
6498  else
6499  { // 50/50 Charge petition model
6500  qsrc = -0.5 * (qgate + qbulk);
6501  Csg = -0.5 * (Cgg1 + Cbg1);
6502  Csb = -0.5 * (Cgb1 + Cbb1);
6503  Csd = -0.5 * (Cgd1 + Cbd1);
6504  }
6505  Cgb *= dVbseff_dVb;
6506  Cbb *= dVbseff_dVb;
6507  Csb *= dVbseff_dVb;
6508  }
6509  qdrn = -(qgate + qbulk + qsrc);
6510  cggb = Cgg;
6511  cgsb = -(Cgg + Cgd + Cgb);
6512  cgdb = Cgd;
6513  cdgb = -(Cgg + Cbg + Csg);
6514  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6515  cddb = -(Cgd + Cbd + Csd);
6516  cbgb = Cbg;
6517  cbsb = -(Cbg + Cbd + Cbb);
6518  cbdb = Cbd;
6519  qinv = -(qgate + qbulk);
6520  }
6521  else if (model_.capMod == 2)
6522  {
6523  Vfb = paramPtr->vfbzb;
6524  V3 = Vfb - Vgs_eff + VbseffCV - CONSTDELTA_3;
6525  if (Vfb <= 0.0)
6526  {
6527  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * Vfb);
6528  T2 = -CONSTDELTA_3 / T0;
6529  }
6530  else
6531  {
6532  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * Vfb);
6533  T2 = CONSTDELTA_3 / T0;
6534  }
6535 
6536  T1 = 0.5 * (1.0 + V3 / T0);
6537  Vfbeff = Vfb - 0.5 * (V3 + T0);
6538  dVfbeff_dVg = T1 * dVgs_eff_dVg;
6539  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
6540  Qac0 = CoxWL * (Vfbeff - Vfb);
6541  dQac0_dVg = CoxWL * dVfbeff_dVg;
6542  dQac0_dVb = CoxWL * dVfbeff_dVb;
6543 
6544  T0 = 0.5 * paramPtr->k1ox;
6545  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
6546  if (paramPtr->k1ox == 0.0)
6547  {
6548  T1 = 0.0;
6549  T2 = 0.0;
6550  }
6551  else if (T3 < 0.0)
6552  {
6553  T1 = T0 + T3 / paramPtr->k1ox;
6554  T2 = CoxWL;
6555  }
6556  else
6557  {
6558  T1 = sqrt(T0 * T0 + T3);
6559  T2 = CoxWL * T0 / T1;
6560  }
6561 
6562  Qsub0 = CoxWL * paramPtr->k1ox * (T1 - T0);
6563 
6564  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg);
6565  dQsub0_dVd = -T2 * dVgsteff_dVd;
6566  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb);
6567 
6568  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6569  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6570  VdsatCV = Vgsteff / AbulkCV;
6571 
6572  V4 = VdsatCV - Vds - CONSTDELTA_4;
6573  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
6574  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
6575  T1 = 0.5 * (1.0 + V4 / T0);
6576  T2 = CONSTDELTA_4 / T0;
6577  T3 = (1.0 - T1 - T2) / AbulkCV;
6578  dVdseffCV_dVg = T3;
6579  dVdseffCV_dVd = T1;
6580  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
6581  // Added to eliminate non-zero VdseffCV at Vds=0.0
6582  if (Vds == 0.0)
6583  {
6584  VdseffCV = 0.0;
6585  dVdseffCV_dVg = 0.0;
6586  dVdseffCV_dVb = 0.0;
6587  }
6588 
6589  T0 = AbulkCV * VdseffCV;
6590  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20);
6591  T2 = VdseffCV / T1;
6592  T3 = T0 * T2;
6593 
6594  T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV);
6595  T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5);
6596  T6 = 12.0 * T2 * T2 * Vgsteff;
6597 
6598  qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3);
6599  qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3);
6600  Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6601  Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd;
6602  Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6603  + Cgg1 * dVgsteff_dVb;
6604  Cgg1 *= dVgsteff_dVg;
6605 
6606  T7 = 1.0 - AbulkCV;
6607  qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3);
6608  T4 = -T7 * (T4 - 1.0);
6609  T5 = -T7 * T5;
6610  T6 = -(T7 * T6 + (0.5 * VdseffCV - T3));
6611  Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6612  Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd;
6613  Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6614  + Cbg1 * dVgsteff_dVb;
6615  Cbg1 *= dVgsteff_dVg;
6616 
6617  if (model_.xpart > 0.5)
6618  { // 0/100 Charge petition model
6619  T1 = T1 + T1;
6620  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6621  T7 = (4.0 * Vgsteff - T0) / (T1 * T1);
6622  T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1));
6623  T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7);
6624  T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7);
6625  Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6626  Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6627  Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6628  + Csg * dVgsteff_dVb;
6629  Csg *= dVgsteff_dVg;
6630  }
6631  else if (model_.xpart < 0.5)
6632  { // 40/60 Charge petition model
6633  T1 = T1 / 12.0;
6634  T2 = 0.5 * CoxWL / (T1 * T1);
6635  T3 = Vgsteff *(2.0 * T0 *T0/3.0 +Vgsteff *(Vgsteff - 4.0 *T0/ 3.0))
6636  - 2.0 * T0 * T0 * T0 / 15.0;
6637  qsrc = -T2 * T3;
6638  T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6639  + 0.4 * T0 * T0;
6640  T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6641  * Vgsteff - 8.0 * T0 / 3.0)
6642  + 2.0 * T0 * T0 / 3.0);
6643  T5 = (qsrc / T1 + T2 * T7) * AbulkCV;
6644  T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV);
6645  Csg = (T4 + T5 * dVdseffCV_dVg);
6646  Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6647  Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6648  + Csg * dVgsteff_dVb;
6649  Csg *= dVgsteff_dVg;
6650  }
6651  else
6652  { // 50/50 Charge petition model
6653  qsrc = -0.5 * (qgate + qbulk);
6654  Csg = -0.5 * (Cgg1 + Cbg1);
6655  Csb = -0.5 * (Cgb1 + Cbb1);
6656  Csd = -0.5 * (Cgd1 + Cbd1);
6657  }
6658 
6659  qgate += Qac0 + Qsub0;
6660  qbulk -= (Qac0 + Qsub0);
6661  qdrn = -(qgate + qbulk + qsrc);
6662 
6663  Cgg = dQac0_dVg + dQsub0_dVg + Cgg1;
6664  Cgd = dQsub0_dVd + Cgd1;
6665  Cgb = dQac0_dVb + dQsub0_dVb + Cgb1;
6666 
6667  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
6668  Cbd = Cbd1 - dQsub0_dVd;
6669  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
6670 
6671  Cgb *= dVbseff_dVb;
6672  Cbb *= dVbseff_dVb;
6673  Csb *= dVbseff_dVb;
6674 
6675  cggb = Cgg;
6676  cgsb = -(Cgg + Cgd + Cgb);
6677  cgdb = Cgd;
6678  cdgb = -(Cgg + Cbg + Csg);
6679  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6680  cddb = -(Cgd + Cbd + Csd);
6681  cbgb = Cbg;
6682  cbsb = -(Cbg + Cbd + Cbb);
6683  cbdb = Cbd;
6684  qinv = qinoi;
6685  }
6686 
6687  // New Charge-Thickness capMod (CTM) begins
6688  else if (model_.capMod == 3)
6689  {
6690  V3 = paramPtr->vfbzb - Vgs_eff + VbseffCV - CONSTDELTA_3;
6691  if (paramPtr->vfbzb <= 0.0)
6692  {
6693  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
6694  T2 = -CONSTDELTA_3 / T0;
6695  }
6696  else
6697  {
6698  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
6699  T2 = CONSTDELTA_3 / T0;
6700  }
6701 
6702  T1 = 0.5 * (1.0 + V3 / T0);
6703  Vfbeff = paramPtr->vfbzb - 0.5 * (V3 + T0);
6704  dVfbeff_dVg = T1 * dVgs_eff_dVg;
6705  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
6706 
6707  Cox = model_.cox;
6708  Tox = 1.0e8 * model_.tox;
6709  T0 = (Vgs_eff - VbseffCV - paramPtr->vfbzb) / Tox;
6710  dT0_dVg = dVgs_eff_dVg / Tox;
6711  dT0_dVb = -dVbseffCV_dVb / Tox;
6712 
6713  tmp = T0 * paramPtr->acde;
6714  if ((-CONSTEXP_THRESHOLD < tmp) && (tmp < CONSTEXP_THRESHOLD))
6715  {
6716  Tcen = paramPtr->ldeb * exp(tmp);
6717  dTcen_dVg = paramPtr->acde * Tcen;
6718  dTcen_dVb = dTcen_dVg * dT0_dVb;
6719  dTcen_dVg *= dT0_dVg;
6720  }
6721  else if (tmp <= -CONSTEXP_THRESHOLD)
6722  {
6723  Tcen = paramPtr->ldeb * CONSTMIN_EXP;
6724  dTcen_dVg = dTcen_dVb = 0.0;
6725  }
6726  else
6727  {
6728  Tcen = paramPtr->ldeb * CONSTMAX_EXP;
6729  dTcen_dVg = dTcen_dVb = 0.0;
6730  }
6731 
6732  LINK = 1.0e-3 * model_.tox;
6733  V3 = paramPtr->ldeb - Tcen - LINK;
6734  V4 = sqrt(V3 * V3 + 4.0 * LINK * paramPtr->ldeb);
6735  Tcen = paramPtr->ldeb - 0.5 * (V3 + V4);
6736  T1 = 0.5 * (1.0 + V3 / V4);
6737  dTcen_dVg *= T1;
6738  dTcen_dVb *= T1;
6739 
6740  Ccen = CONSTEPSSI / Tcen;
6741  T2 = Cox / (Cox + Ccen);
6742  Coxeff = T2 * Ccen;
6743  T3 = -Ccen / Tcen;
6744  dCoxeff_dVg = T2 * T2 * T3;
6745  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
6746  dCoxeff_dVg *= dTcen_dVg;
6747  CoxWLcen = CoxWL * Coxeff / Cox;
6748 
6749  Qac0 = CoxWLcen * (Vfbeff - paramPtr->vfbzb);
6750  QovCox = Qac0 / Coxeff;
6751  dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg;
6752  dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb;
6753 
6754  T0 = 0.5 * paramPtr->k1ox;
6755  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
6756  if (paramPtr->k1ox == 0.0)
6757  {
6758  T1 = 0.0;
6759  T2 = 0.0;
6760  }
6761  else if (T3 < 0.0)
6762  {
6763  T1 = T0 + T3 / paramPtr->k1ox;
6764  T2 = CoxWLcen;
6765  }
6766  else
6767  {
6768  T1 = sqrt(T0 * T0 + T3);
6769  T2 = CoxWLcen * T0 / T1;
6770  }
6771 
6772  Qsub0 = CoxWLcen * paramPtr->k1ox * (T1 - T0);
6773  QovCox = Qsub0 / Coxeff;
6774  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg)
6775  + QovCox * dCoxeff_dVg;
6776  dQsub0_dVd = -T2 * dVgsteff_dVd;
6777  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb)
6778  + QovCox * dCoxeff_dVb;
6779 
6780  // Gate-bias dependent delta Phis begins */
6781  if (paramPtr->k1ox <= 0.0)
6782  {
6783  Denomi = 0.25 * paramPtr->moin * Vtm;
6784  T0 = 0.5 * paramPtr->sqrtPhi;
6785  }
6786  else
6787  {
6788  Denomi = paramPtr->moin * Vtm * paramPtr->k1ox * paramPtr->k1ox;
6789  T0 = paramPtr->k1ox * paramPtr->sqrtPhi;
6790  }
6791  T1 = 2.0 * T0 + Vgsteff;
6792 
6793  DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi);
6794  dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff);
6795  dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd;
6796  dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb;
6797  // End of delta Phis
6798 
6799  T3 = 4.0 * (Vth - paramPtr->vfbzb - paramPtr->phi);
6800  Tox += Tox;
6801  if (T3 >= 0.0)
6802  { T0 = (Vgsteff + T3) / Tox;
6803  dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox;
6804  dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox;
6805  }
6806  else
6807  { T0 = (Vgsteff + 1.0e-20) / Tox;
6808  dT0_dVd = dVgsteff_dVd / Tox;
6809  dT0_dVb = dVgsteff_dVb / Tox;
6810  }
6811  tmp = exp(0.7 * log(T0));
6812  T1 = 1.0 + tmp;
6813  T2 = 0.7 * tmp / (T0 * Tox);
6814  Tcen = 1.9e-9 / T1;
6815  dTcen_dVg = -1.9e-9 * T2 / T1 /T1;
6816  dTcen_dVd = Tox * dTcen_dVg;
6817  dTcen_dVb = dTcen_dVd * dT0_dVb;
6818  dTcen_dVd *= dT0_dVd;
6819  dTcen_dVg *= dVgsteff_dVg;
6820 
6821  Ccen = CONSTEPSSI / Tcen;
6822  T0 = Cox / (Cox + Ccen);
6823  Coxeff = T0 * Ccen;
6824  T1 = -Ccen / Tcen;
6825  dCoxeff_dVg = T0 * T0 * T1;
6826  dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd;
6827  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
6828  dCoxeff_dVg *= dTcen_dVg;
6829  CoxWLcen = CoxWL * Coxeff / Cox;
6830 
6831  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6832  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6833  VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV;
6834  V4 = VdsatCV - Vds - CONSTDELTA_4;
6835  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
6836  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
6837  T1 = 0.5 * (1.0 + V4 / T0);
6838  T2 = CONSTDELTA_4 / T0;
6839  T3 = (1.0 - T1 - T2) / AbulkCV;
6840  T4 = T3 * ( 1.0 - dDeltaPhi_dVg);
6841  dVdseffCV_dVg = T4;
6842  dVdseffCV_dVd = T1;
6843  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
6844 
6845  // Added to eliminate non-zero VdseffCV at Vds=0.0
6846  if (Vds == 0.0)
6847  { VdseffCV = 0.0;
6848  dVdseffCV_dVg = 0.0;
6849  dVdseffCV_dVb = 0.0;
6850  }
6851 
6852  T0 = AbulkCV * VdseffCV;
6853  T1 = Vgsteff - DeltaPhi;
6854  T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20);
6855  T3 = T0 / T2;
6856  T4 = 1.0 - 12.0 * T3 * T3;
6857  T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5);
6858  T6 = T5 * VdseffCV / AbulkCV;
6859 
6860  qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3));
6861  QovCox = qgate / Coxeff;
6862  Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + T5 * dVdseffCV_dVg);
6863  Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1
6864  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
6865  Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6866  + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6867  Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6868 
6869 
6870  T7 = 1.0 - AbulkCV;
6871  T8 = T2 * T2;
6872  T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV);
6873  T10 = T9 * (1.0 - dDeltaPhi_dVg);
6874  T11 = -T7 * T5 / AbulkCV;
6875  T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2));
6876 
6877  qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2);
6878  QovCox = qbulk / Coxeff;
6879  Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg);
6880  Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1
6881  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
6882  Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb)
6883  + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6884  Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6885 
6886  if (model_.xpart > 0.5)
6887  { // 0/100 partition
6888  qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2);
6889  QovCox = qsrc / Coxeff;
6890  T2 += T2;
6891  T3 = T2 * T2;
6892  T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3);
6893  T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg);
6894  T5 = T7 * AbulkCV;
6895  T6 = T7 * VdseffCV;
6896 
6897  Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg);
6898  Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd
6899  + QovCox * dCoxeff_dVd;
6900  Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6901  + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb;
6902  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6903  }
6904  else if (model_.xpart < 0.5)
6905  { // 40/60 partition
6906  T2 = T2 / 12.0;
6907  T3 = 0.5 * CoxWLcen / (T2 * T2);
6908  T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0
6909  * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0;
6910  qsrc = -T3 * T4;
6911  QovCox = qsrc / Coxeff;
6912  T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0;
6913  T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0
6914  * T0 / 3.0) + 2.0 * T0 * T0 / 3.0);
6915  T6 = AbulkCV * (qsrc / T2 + T3 * T8);
6916  T7 = T6 * VdseffCV / AbulkCV;
6917 
6918  Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg;
6919  Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd
6920  + QovCox * dCoxeff_dVd;
6921  Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb
6922  + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb;
6923  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
6924  }
6925  else
6926  { // 50/50 partition
6927  qsrc = -0.5 * qgate;
6928  Csg = -0.5 * Cgg1;
6929  Csd = -0.5 * Cgd1;
6930  Csb = -0.5 * Cgb1;
6931  }
6932 
6933  qgate += Qac0 + Qsub0 - qbulk;
6934  qbulk -= (Qac0 + Qsub0);
6935  qdrn = -(qgate + qbulk + qsrc);
6936 
6937  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
6938  Cbd = Cbd1 - dQsub0_dVd;
6939  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
6940 
6941  Cgg = Cgg1 - Cbg;
6942  Cgd = Cgd1 - Cbd;
6943  Cgb = Cgb1 - Cbb;
6944 
6945  Cgb *= dVbseff_dVb;
6946  Cbb *= dVbseff_dVb;
6947  Csb *= dVbseff_dVb;
6948 
6949  cggb = Cgg;
6950  cgsb = -(Cgg + Cgd + Cgb);
6951  cgdb = Cgd;
6952  cdgb = -(Cgg + Cbg + Csg);
6953  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6954  cddb = -(Cgd + Cbd + Csd);
6955  cbgb = Cbg;
6956  cbsb = -(Cbg + Cbd + Cbb);
6957  cbdb = Cbd;
6958  qinv = -qinoi;
6959  } // End of CTM
6960  }
6961 
6962  finished:
6963  // Returning Values to Calling Routine
6964  // COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
6965 
6966  // copy local "cdrain" variable over to instance variable cd.
6967  cd = cdrain;
6968 
6969  // charge storage elements:
6970  // bulk-drain and bulk-source depletion capacitances
6971  // czbd : zero bias drain junction capacitance
6972  // czbs : zero bias source junction capacitance
6973  // czbdsw: zero bias drain junction sidewall capacitance
6974  // along field oxide
6975  // czbssw: zero bias source junction sidewall capacitance
6976  // along field oxide
6977  // czbdswg: zero bias drain junction sidewall capacitance
6978  // along gate side
6979  // czbsswg: zero bias source junction sidewall capacitance
6980  // along gate side
6982  {
6983  czbd = unitAreaJctCapTemp * drainArea;
6984  czbs = unitAreaJctCapTemp * sourceArea;
6985  if (drainPerimeter < paramPtr->weff)
6986  {
6988  czbdsw = 0.0;
6989  }
6990  else
6991  {
6993  * (drainPerimeter - paramPtr->weff);
6994 
6996  }
6997  if (sourcePerimeter < paramPtr->weff)
6998  {
6999  czbssw = 0.0;
7001  }
7002  else
7003  {
7005  * (sourcePerimeter - paramPtr->weff);
7007  }
7008 
7012 
7013  // Source Bulk Junction
7014  if (vbs == 0.0)
7015  {
7016  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
7017  qbs = 0.0;
7018  capbs = czbs + czbssw + czbsswg;
7019  }
7020  else if (vbs < 0.0)
7021  {
7022  if (czbs > 0.0)
7023  {
7024  arg = 1.0 - vbs / PhiBTemp;
7025 
7026  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
7027  else sarg = exp(-MJ * log(arg));
7028 
7029  //*(ckt->CKTstate0 + iterI->qbs) =
7030  qbs = PhiBTemp * czbs * (1.0 - arg * sarg) / (1.0 - MJ);
7031 
7032  capbs = czbs * sarg;
7033  }
7034  else
7035  {
7036  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
7037  qbs = 0.0;
7038  capbs = 0.0;
7039  }
7040 
7041  if (czbssw > 0.0)
7042  {
7043  arg = 1.0 - vbs / PhiBSWTemp;
7044  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7045  else sarg = exp(-MJSW * log(arg));
7046 
7047  //*(ckt->CKTstate0 + iterI->qbs) +=
7048  qbs += PhiBSWTemp * czbssw * (1.0 - arg * sarg) / (1.0 - MJSW);
7049 
7050  capbs += czbssw * sarg;
7051  }
7052 
7053  if (czbsswg > 0.0)
7054  {
7055  arg = 1.0 - vbs / PhiBSWGTemp;
7056  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7057  else sarg = exp(-MJSWG * log(arg));
7058 
7059  //*(ckt->CKTstate0 + iterI->qbs) +=
7060  qbs += PhiBSWGTemp * czbsswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7061 
7062  capbs += czbsswg * sarg;
7063  }
7064 
7065  }
7066  else
7067  {
7068  T0 = czbs + czbssw + czbsswg;
7069  T1 = vbs * (czbs * MJ / PhiBTemp + czbssw * MJSW
7070  / PhiBSWTemp + czbsswg * MJSWG / PhiBSWGTemp);
7071 
7072  //*(ckt->CKTstate0 + iterI->
7073  qbs = vbs * (T0 + 0.5 * T1);
7074  capbs = T0 + T1;
7075  }
7076 
7077  // Drain Bulk Junction
7078  if (vbd == 0.0)
7079  {
7080  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7081  qbd = 0.0;
7082  capbd = czbd + czbdsw + czbdswg;
7083  }
7084  else if (vbd < 0.0)
7085  {
7086  if (czbd > 0.0)
7087  {
7088  arg = 1.0 - vbd / PhiBTemp;
7089  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
7090  else sarg = exp(-MJ * log(arg));
7091 
7092  //*(ckt->CKTstate0 + iterI->qbd) =
7093  qbd = PhiBTemp * czbd * (1.0 - arg * sarg) / (1.0 - MJ);
7094  capbd = czbd * sarg;
7095  }
7096  else
7097  {
7098  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7099  qbd = 0.0;
7100  capbd = 0.0;
7101  }
7102 
7103  if (czbdsw > 0.0)
7104  {
7105  arg = 1.0 - vbd / PhiBSWTemp;
7106  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7107  else sarg = exp(-MJSW * log(arg));
7108 
7109  //*(ckt->CKTstate0 + iterI->qbd) +=
7110  qbd += PhiBSWTemp * czbdsw * (1.0 - arg * sarg) / (1.0 - MJSW);
7111  capbd += czbdsw * sarg;
7112  }
7113 
7114  if (czbdswg > 0.0)
7115  {
7116  arg = 1.0 - vbd / PhiBSWGTemp;
7117  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7118  else sarg = exp(-MJSWG * log(arg));
7119 
7120  //*(ckt->CKTstate0 + iterI->qbd) +=
7121  qbd += PhiBSWGTemp * czbdswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7122  capbd += czbdswg * sarg;
7123  }
7124  }
7125  else
7126  {
7127  T0 = czbd + czbdsw + czbdswg;
7128  T1 = vbd * (czbd * MJ / PhiBTemp + czbdsw * MJSW
7129  / PhiBSWTemp + czbdswg * MJSWG / PhiBSWGTemp);
7130 
7131  //*(ckt->CKTstate0 + iterI->qbd) = vbd * (T0 + 0.5 * T1);
7132  qbd = vbd * (T0 + 0.5 * T1);
7133  capbd = T0 + T1;
7134  }
7135  }
7136 
7137  // There is a spice3f5 convergence check that would happen here.
7138  // (line 2404) skipping...
7139 
7140  // In 3f5, loading a bunch of things into the state vector at this point.
7141  // (line 2433) skipping...
7142 
7143  // bulk and channel charge plus overlaps
7144 
7146  {
7147  // NQS begins
7148  if (nqsMod)
7149  {
7150  qcheq = -(qbulk + qgate);
7151 
7152  cqgb = -(cggb + cbgb);
7153  cqdb = -(cgdb + cbdb);
7154  cqsb = -(cgsb + cbsb);
7155  cqbb = -(cqgb + cqdb + cqsb);
7156 
7157  gtau_drift = fabs(paramPtr->tconst * qcheq) * ScalingFactor;
7158  T0 = paramPtr->leffCV * paramPtr->leffCV;
7159  gtau_diff = 16.0 * paramPtr->u0temp * model_.vtm / T0 * ScalingFactor;
7160 
7161  gtau = gtau_drift + gtau_diff;
7162  }
7163 
7164  if (model_.capMod == 0)
7165  {
7166  if (vgd < 0.0)
7167  {
7168  cgdo = paramPtr->cgdo;
7169  qgdo = paramPtr->cgdo * vgd;
7170  }
7171  else
7172  {
7173  cgdo = paramPtr->cgdo;
7174  qgdo = paramPtr->cgdo * vgd;
7175  }
7176 
7177  if (vgs < 0.0)
7178  {
7179  cgso = paramPtr->cgso;
7180  qgso = paramPtr->cgso * vgs;
7181  }
7182  else
7183  {
7184  cgso = paramPtr->cgso;
7185  qgso = paramPtr->cgso * vgs;
7186  }
7187  }
7188  else if (model_.capMod == 1)
7189  {
7190  if (vgd < 0.0)
7191  {
7192  T1 = sqrt(1.0 - 4.0 * vgd / paramPtr->ckappa);
7193  cgdo = paramPtr->cgdo + paramPtr->weffCV * paramPtr->cgdl / T1;
7194 
7195  qgdo = paramPtr->cgdo * vgd - paramPtr->weffCV * 0.5
7196  * paramPtr->cgdl * paramPtr->ckappa * (T1 - 1.0);
7197  }
7198  else
7199  {
7202  }
7203 
7204  if (vgs < 0.0)
7205  {
7206  T1 = sqrt(1.0 - 4.0 * vgs / paramPtr->ckappa);
7207  cgso = paramPtr->cgso + paramPtr->weffCV * paramPtr->cgsl / T1;
7208  qgso = paramPtr->cgso * vgs - paramPtr->weffCV * 0.5
7209  * paramPtr->cgsl * paramPtr->ckappa * (T1 - 1.0);
7210  }
7211  else
7212  {
7215  }
7216  }
7217  else
7218  {
7219  T0 = vgd + CONSTDELTA_1;
7220  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7221  T2 = 0.5 * (T0 - T1);
7222 
7223  T3 = paramPtr->weffCV * paramPtr->cgdl;
7224  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7225  cgdo = paramPtr->cgdo + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7226 
7227  qgdo = (paramPtr->cgdo + T3) * vgd - T3 * (T2
7228  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7229 
7230  T0 = vgs + CONSTDELTA_1;
7231  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7232  T2 = 0.5 * (T0 - T1);
7233  T3 = paramPtr->weffCV * paramPtr->cgsl;
7234  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7235  cgso = paramPtr->cgso + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7236  qgso = (paramPtr->cgso + T3) * vgs - T3 * (T2
7237  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7238  }
7239 
7240  //cgdo = cgdo;
7241  //cgso = cgso;
7242 
7245 
7246  //cqdef = cqcheq = 0.0;
7247  cqdef = 0.0;
7248 
7249  // set some state variables:
7250  qg = qgate;
7251  qd = qdrn - qbd;
7252  qb = qbulk + qbd + qbs;
7253  if (nqsMod) qcdump = qdef * ScalingFactor;
7254 
7255  } // end of ChargeComputationNeeded if statement.
7256 
7257  // store small signal parameters
7258  //if (ckt->CKTmode & MODEINITSMSIG) goto line1000;
7259  // Note: in 3f5, line1000 is at the end of the load, after
7260  // the loads to the rhs and the matrix. So it looks
7261  // like this goto essentially means return.
7262 
7263 
7264  // Setting up a few currents for the RHS load:
7267 
7268  // Put this kludge in because the matrix load needs T1 but it is used
7269  // all over the place:
7270  T1global = T1;
7271 
7272  return bsuccess;
7273  }
7274 
7275 //-----------------------------------------------------------------------------
7276 // Function : Instance::updatePrimaryState
7277 //
7278 // Purpose : This function sets up the primaray state variables into
7279 // the primary state vector.
7280 //
7281 // These variables include qb, qg, qd and, in the
7282 // event that nqsMod=1, qcdump and qcheq.
7283 //
7284 // Special Notes :
7285 // Scope : public
7286 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7287 // Creation Date : 01/09/01
7288 //-----------------------------------------------------------------------------
7290  {
7291  bool bsuccess = true;
7292  double * staVec = extData.nextStaVectorRawPtr;
7293  double * stoVec = extData.nextStoVectorRawPtr;
7294 
7295  bsuccess = updateIntermediateVars ();
7296 
7297  // voltage drops:
7298  stoVec[li_store_vbs] = vbs;
7299  stoVec[li_store_vgs] = vgs;
7300  stoVec[li_store_vds] = vds;
7301  stoVec[li_store_vbd] = vbd;
7302  stoVec[li_store_von] = von;
7303 
7304  // intrinsic capacitors:
7305  staVec[li_state_qb] = qb;
7306  staVec[li_state_qg] = qg;
7307  staVec[li_state_qd] = qd;
7308 
7309  // parasitic capacitors:
7310  staVec[li_state_qbs] = qbs;
7311  staVec[li_state_qbd] = qbd;
7312 
7313  if( nqsMod )
7314  {
7315  staVec[li_state_qcheq] = qcheq;
7316  staVec[li_state_qcdump] = qcdump;
7317  }
7318 
7319  // if this is the first newton step of the first time step
7320  // of the transient simulation, we need to enforce that the
7321  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
7322  // compatibility. ERK.
7323 
7324  // Note: I think this kind of thing is enforced (or should be enforced,
7325  // anyway) at the time integration level. So I'm not sure this step is
7326  // really needed, at least for new-DAE. Derivatives out of the DCOP
7327  // are supposed to be zero at the first newton step.
7328 
7329  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
7330  {
7331  // re-set the state vector pointer that we are using to the "current"
7332  // pointer, rather than the "next" pointer.
7333  double * currStaVec = extData.currStaVectorRawPtr;
7334 
7335  // intrinsic capacitors:
7336  currStaVec[li_state_qb] = qb;
7337  currStaVec[li_state_qg] = qg;
7338  currStaVec[li_state_qd] = qd;
7339 
7340  // parasitic capacitors:
7341  currStaVec[li_state_qbs] = qbs;
7342  currStaVec[li_state_qbd] = qbd;
7343 
7344  if( nqsMod )
7345  {
7346  currStaVec[li_state_qcheq] = qcheq;
7347  currStaVec[li_state_qcdump] = qcdump;
7348  }
7349  }
7350 
7351  return bsuccess;
7352  }
7353 
7354 //-----------------------------------------------------------------------------
7355 // Function : Instance::loadDAEQVector
7356 //
7357 // Purpose : Loads the Q-vector contributions for a single
7358 // bsim3 instance.
7359 //
7360 // Special Notes : The "Q" vector is part of a standard DAE formalism in
7361 // which the system of equations is represented as:
7362 //
7363 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
7364 //
7365 // Scope : public
7366 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7367 // Creation Date : 04/07/04
7368 //-----------------------------------------------------------------------------
7370  {
7371  double * qVec = extData.daeQVectorRawPtr;
7372  double * dQdxdVp = extData.dQdxdVpVectorRawPtr;
7373 
7375 
7376  double Qeqqg = 0.0; // gate charge
7377  double Qeqqb = 0.0; // bulk charge
7378  double Qeqqd = 0.0; // drain charge
7379  double Qqdef = 0.0; // nqs-related charge.
7380  double Qqcheq = 0.0; // nqs-related charge.
7381 
7382  // These 3 vars are class variables, and are set up elsewhere.
7383  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
7384  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
7385  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
7386 
7387  if (model_.dtype > 0)
7388  {
7389  Qeqqg = qg;
7390  Qeqqb = qb;
7391  Qeqqd = qd;
7392  Qqdef = qcdump; // this needs to be fixed...
7393  Qqcheq = qcheq;
7394  }
7395  else // need to convert these to charges.
7396  {
7397  Qeqqg = -qg;
7398  Qeqqb = -qb;
7399  Qeqqd = -qd;
7400  Qqdef = -qcdump;
7401  Qqcheq = -qcheq;
7402  }
7403 
7404  qVec[li_Gate] += Qeqqg*numberParallel;
7405  qVec[li_Bulk] += (Qeqqb)*numberParallel;
7406  qVec[li_DrainPrime] += (-(-Qeqqd))*numberParallel;
7407  qVec[li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7408 
7409  if( loadLeadCurrent )
7410  {
7411  double * storeLeadQ = extData.storeLeadCurrQCompRawPtr;
7412  if (drainConductance == 0.0)
7413  {
7414  storeLeadQ[li_store_dev_id] = (-(-Qeqqd))*numberParallel;
7415  }
7416  if (sourceConductance == 0.0)
7417  {
7418  storeLeadQ[li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7419  }
7420  storeLeadQ[li_store_dev_ig] = Qeqqg*numberParallel;
7421  storeLeadQ[li_store_dev_ib] = (Qeqqb)*numberParallel;
7422  }
7423 
7424  if (nqsMod)
7425  {
7426  // 7 equ. for nqs modification. charge equation.
7427  qVec[li_Charge] += -(Qqcheq - Qqdef)*numberParallel;
7428  }
7429 
7430  //////////////////////////////////////////////////
7431  // limiting section:
7433  {
7434  // Need the following:
7435  // Qeqqg_Jdxp
7436  // Qeqqb_Jdxp
7437  // Qeqqd_Jdxp
7438  if (model_.dtype > 0)
7439  {
7440  // no-op:
7444  }
7445  else
7446  {
7450  }
7451 
7452  if (!origFlag)
7453  {
7454  dQdxdVp[li_Gate] += -Qeqqg_Jdxp*numberParallel;
7455  dQdxdVp[li_Bulk] += -(+Qeqqb_Jdxp)*numberParallel;
7456  dQdxdVp[li_DrainPrime] += (-Qeqqd_Jdxp)*numberParallel;
7457  dQdxdVp[li_SourcePrime] += (+Qeqqg_Jdxp+Qeqqb_Jdxp+Qeqqd_Jdxp) *numberParallel;
7458  } // orig flag.
7459  } // limiter flag
7460 
7461  return true;
7462  }
7463 
7464 //-----------------------------------------------------------------------------
7465 // Function : Instance::auxChargeCalculations
7466 //
7467 // Purpose : This function does some final "cleanup" calculations
7468 // having to do with the capacitors.
7469 //
7470 // Special Notes : About all this function really does is set up some
7471 // voltlim terms, and some unused nqs stuff.
7472 //
7473 // Scope : public
7474 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7475 // Creation Date : 04/18/04
7476 //-----------------------------------------------------------------------------
7478  {
7479  double T0, T1;
7480 
7482  {
7483  sxpart = (1.0 - (dxpart = (mode > 0) ? 0.4 : 0.6));
7486 
7487  if (nqsMod)
7488  {
7489  gtau = 16.0 * paramPtr->u0temp * model_.vtm
7491  }
7492  else
7493  {
7494  gtau = 0.0;
7495  }
7496  }
7497  else // ChargeComputation is needed
7498  {
7499  double vgb_orig = vgs_orig - vbs_orig;
7500 
7501  Qeqqg_Jdxp = 0.0;
7502  if (!origFlag)
7503  {
7504  Qeqqg_Jdxp = - CAPcggb * (vgb-vgb_orig)
7505  + CAPcgdb * (vbd-vbd_orig)
7506  + CAPcgsb * (vbs-vbs_orig);
7507  }
7508 
7509  Qeqqb_Jdxp = 0.0;
7510  if (!origFlag)
7511  {
7512  Qeqqb_Jdxp = - CAPcbgb * (vgb-vgb_orig)
7513  + CAPcbdb * (vbd-vbd_orig)
7514  + CAPcbsb * (vbs-vbs_orig);
7515  }
7516 
7517  Qeqqd_Jdxp = 0.0;
7518  if (!origFlag)
7519  {
7520  Qeqqd_Jdxp = - CAPcdgb * (vgb-vgb_orig)
7521  + CAPcddb * (vbd-vbd_orig)
7522  + CAPcdsb * (vbs-vbs_orig);
7523  }
7524 
7525  // Note: nqs stuff is not yet finished, especially the voltage
7526  // limiting aspect. For limiting, need to re-do T0 and the term
7527  // added to ceqqd.
7528  if (nqsMod)
7529  {
7530  std::string msg;
7531  msg = "Instance::auxChargeCalculations ()";
7532  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
7533  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
7534 
7535  T0 = ggtg * vgb - ggtd * vbd - ggts * vbs;
7536  ceqqg += T0;
7537  T1 = qdef * gtau;
7538  ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd
7539  * vbd - ddxpart_dVs * vbs);
7540 
7541  //cqdef = cqcdump - gqdef * qdef;
7542 
7543  //if (!origFlag)
7544  //{
7545  //double tmp = - (gcqgb * (vgb-vgb_orig)
7546  //- gcqdb * (vbd-vbd_orig)
7547  //- gcqsb * (vbs-vbs_orig)) + T0;
7548  //cqcheq += tmp;
7549  //cqcheq_Jdxp = tmp;
7550  //}
7551  }
7552  } // !ChargeComputationNeeded
7553 
7554  return true;
7555  }
7556 
7557 //-----------------------------------------------------------------------------
7558 // Function : Instance::setupCapacitors_newDAE ()
7559 //
7560 // Purpose : This takes a lot of the individual capacitive terms and
7561 // sums them together for loading into the Jacobian.
7562 //
7563 // Special Notes : This was extracted from updateIntermediateVars.
7564 // Different variables are used, and nothing is multiplied
7565 // by ag0 = solState.pdt. The new-dae formulation handles
7566 // all the 1/dt - related stuff up in the time integrator.
7567 //
7568 // NOTE: nqs not even close to being supported.
7569 //
7570 // Scope : public
7571 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7572 // Creation Date : 04/23/04
7573 //-----------------------------------------------------------------------------
7575  {
7576 
7577  if (mode > 0)
7578  {
7579  if (nqsMod == 0)
7580  {
7581  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
7582  CAPcgdb = (cgdb - cgdo);
7583  CAPcgsb = (cgsb - cgso);
7584 
7585  CAPcdgb = (cdgb - cgdo);
7586  CAPcddb = (cddb + capbd + cgdo);
7587  CAPcdsb = cdsb;
7588 
7589  CAPcsgb = -(cggb + cbgb + cdgb + cgso);
7590  CAPcsdb = -(cgdb + cbdb + cddb);
7591  CAPcssb = (capbs + cgso - (cgsb + cbsb + cdsb));
7592 
7593  CAPcbgb = (cbgb - paramPtr->cgbo);
7594  CAPcbdb = (cbdb - capbd);
7595  CAPcbsb = (cbsb - capbs);
7596  }
7597  else // nqsMode != 0
7598  {
7599 
7600  } // nqsMod
7601  }
7602  else
7603  {
7604  if (nqsMod == 0)
7605  {
7606  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
7607  CAPcgdb = (cgsb - cgdo);
7608  CAPcgsb = (cgdb - cgso);
7609 
7610  CAPcdgb = -(cggb + cbgb + cdgb + cgdo);
7611  CAPcddb = (capbd + cgdo - (cgsb + cbsb + cdsb));
7612  CAPcdsb = -(cgdb + cbdb + cddb);
7613 
7614  CAPcsgb = (cdgb - cgso);
7615  CAPcsdb = cdsb;
7616  CAPcssb = (cddb + capbs + cgso);
7617 
7618  CAPcbgb = (cbgb - paramPtr->cgbo);
7619  CAPcbdb = (cbsb - capbd);
7620  CAPcbsb = (cbdb - capbs);
7621  }
7622  else // nqsMode != 0
7623  {
7624 
7625  }
7626  }
7627 
7628  return true;
7629  }
7630 
7631 //-----------------------------------------------------------------------------
7632 // Function : Instance::setupCapacitors_oldDAE ()
7633 // Purpose : Same as new-DAE version, but including pdt, essentially.
7634 // Special Notes :
7635 //
7636 // Scope : public
7637 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7638 // Creation Date : 12/17/06
7639 //-----------------------------------------------------------------------------
7641  {
7642 
7643  double ag0 = getSolverState().pdt;
7644  double T0 = 0.0;
7645 
7646  // ERK. 12/17/2006.
7647  // It is necessary to set ag0=0.0, because for the first time step out of
7648  // the DCOP, all the time derivatives are forced to be zero. Thus, all
7649  // their derivatives should also be zero. If it wasn't for that, then ag0
7650  // could always be pdt. (it used to be, before the -jacobian_test capability).
7651  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
7652  {
7653  ag0 = 0.0;
7654  }
7655 
7656  if (mode > 0)
7657  {
7658  if (nqsMod == 0)
7659  {
7660  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
7661  gcgdb = (cgdb - cgdo) * ag0;
7662  gcgsb = (cgsb - cgso) * ag0;
7663 
7664  gcdgb = (cdgb - cgdo) * ag0;
7665  gcddb = (cddb + capbd + cgdo) * ag0;
7666  gcdsb = cdsb * ag0;
7667 
7668  gcsgb = -(cggb + cbgb + cdgb + cgso) * ag0;
7669  gcsdb = -(cgdb + cbdb + cddb) * ag0;
7670  gcssb = (capbs + cgso - (cgsb + cbsb + cdsb)) * ag0;
7671 
7672  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
7673  gcbdb = (cbdb - capbd) * ag0;
7674  gcbsb = (cbsb - capbs) * ag0;
7675 
7676  qgd = qgdo;
7677  qgs = qgso;
7678  qgb = paramPtr->cgbo * vgb;
7679  qgate += qgd + qgs + qgb;
7680  qbulk -= qgb;
7681  qdrn -= qgd;
7682  qsrc = -(qgate + qbulk + qdrn);
7683 
7684  ggtg = ggtd = ggtb = ggts = 0.0;
7685  sxpart = 0.6;
7686  dxpart = 0.4;
7689  }
7690  else // nqsMode != 0
7691  {
7692  if (qcheq > 0.0)
7693  {
7694  T0 = paramPtr->tconst * qdef * ScalingFactor;
7695  }
7696  else
7697  {
7698  T0 = -paramPtr->tconst * qdef * ScalingFactor;
7699  }
7700 
7701  ggtg = gtg = T0 * cqgb;
7702  ggtd = gtd = T0 * cqdb;
7703  ggts = gts = T0 * cqsb;
7704  ggtb = gtb = T0 * cqbb;
7705  gqdef = ScalingFactor * ag0;
7706 
7707  gcqgb = cqgb * ag0;
7708  gcqdb = cqdb * ag0;
7709  gcqsb = cqsb * ag0;
7710  gcqbb = cqbb * ag0;
7711 
7712  gcggb = (cgdo + cgso + paramPtr->cgbo ) * ag0;
7713  gcgdb = -cgdo * ag0;
7714  gcgsb = -cgso * ag0;
7715 
7716  gcdgb = -cgdo * ag0;
7717  gcddb = (capbd + cgdo) * ag0;
7718  gcdsb = 0.0;
7719 
7720  gcsgb = -cgso * ag0;
7721  gcsdb = 0.0;
7722  gcssb = (capbs + cgso) * ag0;
7723 
7724  gcbgb = -paramPtr->cgbo * ag0;
7725  gcbdb = -capbd * ag0;
7726  gcbsb = -capbs * ag0;
7727 
7729 
7730  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
7731  {
7732  if (model_.xpart < 0.5) dxpart = 0.4;
7733  else if (model_.xpart > 0.5) dxpart = 0.0;
7734  else dxpart = 0.5;
7735 
7737  }
7738  else
7739  {
7740  dxpart = qdrn / qcheq;
7741  Cdd = cddb;
7742  Csd = -(cgdb + cddb + cbdb);
7743  ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
7744  Cdg = cdgb;
7745  Csg = -(cggb + cdgb + cbgb);
7746  ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
7747 
7748  Cds = cdsb;
7749  Css = -(cgsb + cdsb + cbsb);
7750  ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
7751 
7753  }
7754  sxpart = 1.0 - dxpart;
7759 
7760  qgd = qgdo;
7761  qgs = qgso;
7762  qgb = paramPtr->cgbo * vgb;
7763  qgate = qgd + qgs + qgb;
7764  qbulk = -qgb;
7765  qdrn = -qgd;
7766  qsrc = -(qgate + qbulk + qdrn);
7767  } // nqsMod
7768  }
7769  else
7770  {
7771  if (nqsMod == 0)
7772  {
7773  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
7774  gcgdb = (cgsb - cgdo) * ag0;
7775  gcgsb = (cgdb - cgso) * ag0;
7776 
7777  gcdgb = -(cggb + cbgb + cdgb + cgdo) * ag0;
7778  gcddb = (capbd + cgdo - (cgsb + cbsb + cdsb)) * ag0;
7779  gcdsb = -(cgdb + cbdb + cddb) * ag0;
7780 
7781  gcsgb = (cdgb - cgso) * ag0;
7782  gcsdb = cdsb * ag0;
7783  gcssb = (cddb + capbs + cgso) * ag0;
7784 
7785  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
7786  gcbdb = (cbsb - capbd) * ag0;
7787  gcbsb = (cbdb - capbs) * ag0;
7788 
7789  qgd = qgdo;
7790  qgs = qgso;
7791  qgb = paramPtr->cgbo * vgb;
7792  qgate += qgd + qgs + qgb;
7793  qbulk -= qgb;
7794  qsrc = qdrn - qgs;
7795  qdrn = -(qgate + qbulk + qsrc);
7796 
7797  ggtg = ggtd = ggtb = ggts = 0.0;
7798  sxpart = 0.4;
7799  dxpart = 0.6;
7802  }
7803  else // nqsMode != 0
7804  {
7805  if (qcheq > 0.0)
7806  {
7807  T0 = paramPtr->tconst * qdef * ScalingFactor;
7808  }
7809  else
7810  {
7811  T0 = -paramPtr->tconst * qdef * ScalingFactor;
7812  }
7813 
7814  ggtg = gtg = T0 * cqgb;
7815  ggts = gtd = T0 * cqdb;
7816  ggtd = gts = T0 * cqsb;
7817  ggtb = gtb = T0 * cqbb;
7818  gqdef = ScalingFactor * ag0;
7819 
7820  gcqgb = cqgb * ag0;
7821  gcqdb = cqsb * ag0;
7822  gcqsb = cqdb * ag0;
7823  gcqbb = cqbb * ag0;
7824 
7825  gcggb = (cgdo + cgso + paramPtr->cgbo) * ag0;
7826  gcgdb = -cgdo * ag0;
7827  gcgsb = -cgso * ag0;
7828 
7829  gcdgb = -cgdo * ag0;
7830  gcddb = (capbd + cgdo) * ag0;
7831  gcdsb = 0.0;
7832 
7833  gcsgb = -cgso * ag0;
7834  gcsdb = 0.0;
7835  gcssb = (capbs + cgso) * ag0;
7836 
7837  gcbgb = -paramPtr->cgbo * ag0;
7838  gcbdb = -capbd * ag0;
7839  gcbsb = -capbs * ag0;
7840 
7842 
7843  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
7844  {
7845  if (model_.xpart < 0.5) sxpart = 0.4;
7846  else if (model_.xpart > 0.5) sxpart = 0.0;
7847  else sxpart = 0.5;
7848 
7850  }
7851  else
7852  {
7853  sxpart = qdrn / qcheq;
7854  Css = cddb;
7855  Cds = -(cgdb + cddb + cbdb);
7856  dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
7857  Csg = cdgb;
7858  Cdg = -(cggb + cdgb + cbgb);
7859  dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
7860 
7861  Csd = cdsb;
7862  Cdd = -(cgsb + cdsb + cbsb);
7863  dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
7864 
7866  }
7867 
7868  dxpart = 1.0 - sxpart;
7873 
7874  qgd = qgdo;
7875  qgs = qgso;
7876  qgb = paramPtr->cgbo * vgb;
7877  qgate = qgd + qgs + qgb;
7878  qbulk = -qgb;
7879  qsrc = -qgs;
7880  qdrn = -(qgate + qbulk + qsrc);
7881  }
7882  }
7883 
7884  return true;
7885  }
7886 
7887 //-----------------------------------------------------------------------------
7888 // Function : Instance::loadDAEFVector
7889 //
7890 // Purpose : Loads the F-vector contributions for a single
7891 // bsim3 instance.
7892 //
7893 // Special Notes :
7894 //
7895 // Scope : public
7896 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7897 // Creation Date : 04/07/04
7898 //-----------------------------------------------------------------------------
7900  {
7901  double * fVec = extData.daeFVectorRawPtr;
7902  double * dFdxdVp = extData.dFdxdVpVectorRawPtr;
7903 
7904  double coef(0.0);
7905 
7906  cdreq_Jdxp = 0.0;
7907  ceqbd_Jdxp = 0.0;
7908  ceqbs_Jdxp = 0.0;
7909 
7910  // Do a few auxilliary calculations, derived from 3f5.
7911  // load current vector
7912  if (mode >= 0)
7913  {
7914  Gm = gm;
7915  Gmbs = gmbs;
7916  FwdSum = Gm + Gmbs;
7917  RevSum = 0.0;
7918 
7919  cdreq = model_.dtype * (cd);
7920  ceqbd = -model_.dtype * (csub);
7921 
7922  ceqbs = 0.0;
7923 
7924  gbbdp = -gbds;
7925  gbbsp = (gbds + gbgs + gbbs);
7926 
7927  gbdpg = gbgs;
7928  gbdpdp = gbds;
7929  gbdpb = gbbs;
7930  gbdpsp = -(gbdpg + gbdpdp + gbdpb);
7931 
7932  gbspg = 0.0;
7933  gbspdp = 0.0;
7934  gbspb = 0.0;
7935  gbspsp = 0.0;
7936  }
7937  else
7938  {
7939  Gm = -gm;
7940  Gmbs = -gmbs;
7941  FwdSum = 0.0;
7942  RevSum = -(Gm + Gmbs);
7943 
7944  cdreq = -model_.dtype * (cd);
7945  ceqbs = -model_.dtype * (csub);
7946 
7947  ceqbd = 0.0;
7948 
7949  gbbsp = -gbds;
7950  gbbdp = (gbds + gbgs + gbbs);
7951 
7952  gbdpg = 0.0;
7953  gbdpsp = 0.0;
7954  gbdpb = 0.0;
7955  gbdpdp = 0.0;
7956 
7957  gbspg = gbgs;
7958  gbspsp = gbds;
7959  gbspb = gbbs;
7960  gbspdp = -(gbspg + gbspsp + gbspb);
7961  }
7962 
7963  if (model_.dtype > 0)
7964  {
7965  ceqbs += (cbs);
7966  ceqbd += (cbd);
7967  }
7968  else
7969  {
7970  ceqbs -= (cbs);
7971  ceqbd -= (cbd);
7972  }
7973 
7974  if (drainConductance != 0.0)
7975  {
7976  fVec[li_Drain] += Idrain*numberParallel;
7977  }
7978  if (sourceConductance != 0.0)
7979  {
7980  fVec[li_Source] += Isource*numberParallel;
7981  }
7982  fVec[li_Bulk] += (ceqbs + ceqbd)*numberParallel;
7983  fVec[li_DrainPrime] += (-(ceqbd - cdreq)-Idrain)*numberParallel;
7985 
7986  // lead current support
7987  if( loadLeadCurrent )
7988  {
7989  double * storeLeadF = extData.nextStoVectorRawPtr;
7990  if (drainConductance != 0.0)
7991  {
7992  storeLeadF[li_store_dev_id] = Idrain*numberParallel;
7993  }
7994  else
7995  {
7996  storeLeadF[li_store_dev_id] = (-(ceqbd - cdreq)-Idrain)*numberParallel;
7997  }
7998  if (sourceConductance != 0.0)
7999  {
8000  storeLeadF[li_store_dev_is] = Isource*numberParallel;
8001  }
8002  else
8003  {
8004  storeLeadF[li_store_dev_is] = (-(cdreq + ceqbs)-Isource)*numberParallel;
8005  }
8006  storeLeadF[li_store_dev_ig] = 0.0;
8007  storeLeadF[li_store_dev_ib] = (ceqbs + ceqbd)*numberParallel;
8008  }
8009 
8010  // Initial condition support
8011 
8013  {
8015  fVec[li_Drain] += coef;
8016  fVec[li_Source] += -coef;
8017  if( loadLeadCurrent )
8018  {
8019  double * storeLeadF = extData.nextStoVectorRawPtr;
8020  storeLeadF[li_store_dev_id]= coef;
8021  storeLeadF[li_store_dev_is]= -coef;
8022  }
8023  }
8024 
8026  {
8028  fVec[li_Gate] += coef;
8029  fVec[li_Source] += -coef;
8030  if( loadLeadCurrent )
8031  {
8032  double * storeLeadF = extData.nextStoVectorRawPtr;
8033  storeLeadF[li_store_dev_ig]= coef;
8034  storeLeadF[li_store_dev_is]= -coef;
8035  }
8036  }
8037 
8038 
8040  {
8042  fVec[li_Bulk] += coef;
8043  fVec[li_Source] += -coef;
8044  if( loadLeadCurrent )
8045  {
8046  double * storeLeadF = extData.nextStoVectorRawPtr;
8047  storeLeadF[li_store_dev_ib]= coef;
8048  storeLeadF[li_store_dev_is]= -coef;
8049  }
8050  }
8051 
8052 
8053 
8054  //////////////////////////////////////////////////
8055  // limiting section:
8057  {
8058  if (!origFlag)
8059  {
8060  if (mode >= 0)
8061  {
8062  // option 1
8063  double tmp = model_.dtype * (-gds * (vds-vds_orig) -
8064  Gm * (vgs-vgs_orig) -
8065  Gmbs * (vbs-vbs_orig));
8066 
8067  cdreq_Jdxp += tmp;
8068  cdreq += tmp;
8069 
8070  tmp = -model_.dtype * (-gbds * (vds-vds_orig) -
8071  gbgs * (vgs-vgs_orig) -
8072  gbbs * (vbs-vbs_orig));
8073  ceqbd_Jdxp += tmp;
8074  ceqbd += tmp;
8075  }
8076  else
8077  {
8078  // option 2
8079  double tmp = -model_.dtype * (gds * (vds-vds_orig) +
8080  Gm * (vgd-vgd_orig) +
8081  Gmbs * (vbd-vbd_orig));
8082  cdreq_Jdxp += tmp;
8083  cdreq += tmp;
8084 
8085  tmp = -model_.dtype * (gbds * (vds-vds_orig) -
8086  gbgs * (vgd-vgd_orig) -
8087  gbbs * (vbd-vbd_orig));
8088  ceqbd_Jdxp += tmp;
8089  ceqbd += tmp;
8090  }
8091 
8092 
8093  if (model_.dtype > 0)
8094  {
8095  ceqbs_Jdxp += (-gbs*(vbs-vbs_orig));
8096  ceqbs += (-gbs*(vbs-vbs_orig));
8097 
8098  ceqbd_Jdxp += (-gbd*(vbd-vbd_orig));
8099  ceqbd += (-gbd*(vbd-vbd_orig));
8100  }
8101  else
8102  {
8103  ceqbs_Jdxp -= (-gbs*(vbs-vbs_orig) );
8104  ceqbs -= (-gbs*(vbs-vbs_orig) );
8105 
8106  ceqbd_Jdxp -= (-gbd*(vbd-vbd_orig) );
8107  ceqbd -= (-gbd*(vbd-vbd_orig) );
8108  }
8112  } // orig flag.
8113  } // voltage limiter flag
8114 
8115  // Row associated with icVBS
8117  {
8118  // get the voltage drop from the previous solution
8119  double cVs = extData.nextSolVectorRawPtr[li_Source];
8120  double cVb = extData.nextSolVectorRawPtr[li_Bulk];
8121  fVec[li_Ibs] += (cVb - cVs - icVBS);
8122  }
8123 
8124  // Row associated with icVDS
8126  {
8127  // get the voltage drop from the previous solution
8128  double cVd = extData.nextSolVectorRawPtr[li_Drain];
8129  double cVs = extData.nextSolVectorRawPtr[li_Source];
8130  fVec[li_Ids] += (cVd - cVs - icVDS);
8131  }
8132 
8133  // Row associated with icVGS
8135  {
8136  // get the voltage drop from the previous solution
8137  double cVg = extData.nextSolVectorRawPtr[li_Gate];
8138  double cVs = extData.nextSolVectorRawPtr[li_Source];
8139 
8140  fVec[li_Igs] += (cVg - cVs - icVGS);
8141  }
8142 
8143  return true;
8144  }
8145 
8146 //-----------------------------------------------------------------------------
8147 // Function : Instance::loadDAEdQdx
8148 //
8149 // Purpose : Loads the Q-vector contributions for a single
8150 // bsim3 instance.
8151 //
8152 // Special Notes : The "Q" vector is part of a standard DAE formalism in
8153 // which the system of equations is represented as:
8154 //
8155 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
8156 //
8157 // Scope : public
8158 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8159 // Creation Date : 04/07/04
8160 //-----------------------------------------------------------------------------
8162  {
8163  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
8164  {
8165  // do nothing, as for this special case q is always zero.
8166  }
8167  else
8168  {
8169  N_LAS_Matrix & dQdx = *(extData.dQdxMatrixPtr);
8170 
8171  // Row corresponding to the KCL for the drain node: NOTHING
8172 
8173  // Row corresponding to the KCL for the source node: NOTHING
8174 
8175  // Row corresponding to the KCL for the gate node:
8176  // Check this later. ERK. See the comments in the function
8177  // loadDAEdQdx, regarding ggtg, ggtb, etc.
8178  //
8179  // For now I am leaving out the gg terms, as they are zero when
8180  // nqsMod=0, which is always true.
8181  //
8183  += (CAPcggb )*numberParallel;
8187  += (CAPcgdb )*numberParallel;
8189  += (CAPcgsb )*numberParallel;
8190 
8191  // Row corresponding to the KCL for the bulk node:
8193  += (CAPcbgb)*numberParallel;
8194 
8197 
8199  += (CAPcbdb)*numberParallel;
8200 
8202  += (CAPcbsb)*numberParallel;
8203 
8204 
8205  // Row corresponding to the KCL for the drain prime node:
8207  -= (+ CAPcdgb + CAPcddb + CAPcdsb )*numberParallel;
8208 
8210  += (CAPcdgb) *numberParallel;
8211 
8213  += (+ CAPcddb )*numberParallel;
8214 
8216  -= (- CAPcdsb) *numberParallel;
8217 
8218  // Row corresponding to the KCL for the source prime node:
8220  += (CAPcsgb) *numberParallel;
8221 
8223  -= (+ CAPcsgb + CAPcsdb + CAPcssb) *numberParallel;
8224 
8226  -= (- CAPcsdb) *numberParallel;
8227 
8229  += (+ CAPcssb) *numberParallel;
8230 
8231  // Row associated with the charge equation
8232  // This is currently not supported.
8233  if (nqsMod)
8234  {
8235  std::string msg;
8236  msg = "Instance::loadDAEdQdx";
8237  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8238  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8239  }
8240  }
8241  return true;
8242  }
8243 
8244 //-----------------------------------------------------------------------------
8245 // Function : Instance::loadDAEdFdx ()
8246 //
8247 // Purpose : Loads the F-vector contributions for a single
8248 // bsim3 instance.
8249 //
8250 // Special Notes :
8251 //
8252 // Scope : public
8253 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8254 // Creation Date : 04/07/04
8255 //-----------------------------------------------------------------------------
8257  {
8258  N_LAS_Matrix & dFdx = *(extData.dFdxMatrixPtr);
8259 
8260  // Row corresponding to the KCL for the drain node:
8265 
8266  // Extra term for initial conditions on Vds in operating point
8268  {
8269  dFdx[li_Drain][ADrainEquIdsOffset] += 1.0;
8270  }
8271 
8272  // Row corresponding to the KCL for the source node:
8277 
8278  // Extra term for initial conditions on Vbs in operating point
8280  {
8281  dFdx[li_Source][ASourceEquIbsOffset] -= 1.0;
8282  }
8283  // Extra term for initial conditions on Vds in operating point
8285  {
8286  dFdx[li_Source][ASourceEquIdsOffset] -= 1.0;
8287  }
8288  // Extra term for initial conditions on Vgs in operating point
8290  {
8291  dFdx[li_Source][ASourceEquIgsOffset] -= 1.0;
8292  }
8293 
8294  // Row corresponding to the KCL for the gate node: NOTHING
8295  // Check this later. ERK.
8296  //
8297  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
8298  // belong here. I'm not sure aboug the gg terms. On one hand, the
8299  // rhs vector component for the gate node ONLY seems to take
8300  // capacitive currents, which implies that all of these are capacitive
8301  // conductances. On the other hand, the gg terms do not appear to
8302  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
8303  // capacitive conductances are of the form g = C/dt, and the gg terms
8304  // do not have this form.
8305  //
8306  // For now, the gg issue is moot b/c those terms are only nonzero
8307  // if nqsMod = 1, which is not a supported option.
8308 
8309  // However, the gg
8310  // terms (ggtg, ggtb, ggtd and ggts)
8311  //
8312  //(*JMatPtr)[li_Gate][AGateEquGateNodeOffset]
8313  // += (gcggb - ggtg)*numberParallel;
8314  //(*JMatPtr)[li_Gate][AGateEquBulkNodeOffset]
8315  // -= (gcggb + gcgdb + gcgsb + ggtb)*numberParallel;
8316  //(*JMatPtr)[li_Gate][AGateEquDrainPrimeNodeOffset]
8317  // += (gcgdb - ggtd)*numberParallel;
8318  //(*JMatPtr)[li_Gate][AGateEquSourcePrimeNodeOffset]
8319  // += (gcgsb - ggts)*numberParallel;
8320 
8321  // initial conditions on gate node
8322  // Extra term for initial conditions on Vgs in operating point
8324  {
8325  dFdx[li_Gate][AGateEquIgsOffset] += 1.0;
8326  }
8327 
8328  // Row corresponding to the KCL for the bulk node:
8330  += (- gbgs)*numberParallel;
8331 
8333  += (gbd + gbs - gbbs)*numberParallel;
8334 
8336  += (- gbd + gbbdp)*numberParallel;
8337 
8339  += (- gbs + gbbsp)*numberParallel;
8340 
8341  // Extra term for initial conditions on Vbs in operating point
8343  {
8344  dFdx[li_Bulk][ABulkEquIbsOffset] += 1.0;
8345  }
8346 
8347  // Row corresponding to the KCL for the drain prime node:
8350 
8352  -= (gbd - Gmbs - dxpart*ggtb
8353  - T1global*ddxpart_dVb - gbdpb)*numberParallel;
8354 
8356  += (Gm + dxpart*ggtg + T1global*ddxpart_dVg + gbdpg)
8357  *numberParallel;
8358 
8361  + T1global*ddxpart_dVd + gbdpdp)*numberParallel;
8362 
8365  *numberParallel;
8366 
8367  // Row corresponding to the KCL for the source prime node:
8369  += (- Gm + sxpart*ggtg + T1global*dsxpart_dVg + gbspg)
8370  *numberParallel;
8371 
8373  -= (gbs + Gmbs - sxpart*ggtb
8374  - T1global*dsxpart_dVb - gbspb)*numberParallel;
8375 
8378 
8381  *numberParallel;
8382 
8385  + T1global*dsxpart_dVs + gbspsp)*numberParallel;
8386 
8387  // Row associated with the charge equation
8388  if (nqsMod)
8389  {
8390  std::string msg;
8391  msg = "Instance::loadDAEdFdx";
8392  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8393  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8394  }
8395 
8396  // Initial condition rows
8397  // Row associated with icVBS
8398  if( icVBSGiven )
8399  {
8400  if( getSolverState().dcopFlag )
8401  {
8402  dFdx[li_Ibs][icVBSEquVbOffset] += 1.0;
8403  dFdx[li_Ibs][icVBSEquVsOffset] -= 1.0;
8404  }
8405  else
8406  {
8407  dFdx[li_Ibs][icVBSEquIbsOffset] += 1.0;
8408  }
8409  }
8410 
8411  // Row associated with icVDS
8412  if( icVDSGiven )
8413  {
8414  if( getSolverState().dcopFlag )
8415  {
8416  dFdx[li_Ids][icVDSEquVdOffset] += 1.0;
8417  dFdx[li_Ids][icVDSEquVsOffset] -= 1.0;
8418  }
8419  else
8420  {
8421  dFdx[li_Ids][icVDSEquIdsOffset] += 1.0;
8422  }
8423  }
8424 
8425  // Row associated with icVGS
8426  if( icVGSGiven )
8427  {
8428  if( getSolverState().dcopFlag )
8429  {
8430  dFdx[li_Igs][icVGSEquVgOffset] += 1.0;
8431  dFdx[li_Igs][icVGSEquVsOffset] -= 1.0;
8432  }
8433  else
8434  {
8435  dFdx[li_Igs][icVGSEquIgsOffset] += 1.0;
8436  }
8437  }
8438 
8439  return true;
8440  }
8441 
8442 //-----------------------------------------------------------------------------
8443 // Function : Instance::setIC
8444 // Purpose :
8445 // Special Notes :
8446 // Scope : public
8447 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
8448 // Creation Date : 01/10/02
8449 //-----------------------------------------------------------------------------
8451  {
8452  bool bsuccess = true;
8453 
8454  if( icVBSGiven )
8455  {
8458  }
8459 
8460  if( icVDSGiven )
8461  {
8464  }
8465 
8466  if( icVGSGiven )
8467  {
8470  }
8471 
8472  return bsuccess;
8473  }
8474 
8475 
8476 // Additional Declarations
8477 
8478 // Class Model
8479 
8480 //-----------------------------------------------------------------------------
8481 // Function : Model::processParams
8482 // Purpose :
8483 // Special Notes :
8484 // Scope : public
8485 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8486 // Creation Date : 6/03/02
8487 //-----------------------------------------------------------------------------
8489  {
8490  std::string msg;
8491  cox = 3.453133e-11 / tox;
8492  if (!given("TOXM")) toxm = tox;
8493  if (!given("DSUB")) dsub = drout;
8494  if (!given("LLC")) Llc = Ll;
8495  if (!given("LWC")) Lwc = Lw;
8496  if (!given("LWLC")) Lwlc = Lwl;
8497  if (!given("WLC")) Wlc = Wl;
8498  if (!given("WWL")) Wwlc = Wwl;
8499  if (!given("WWLC")) Wwlc = Wwl;
8500  if (!given("DWC")) dwc = Wint;
8501  if (!given("DLC")) dlc = Lint;
8502 
8503  if (!given("CF"))
8504  {
8505  double C1 = 2.0 * CONSTEPSOX;
8506  double C5 = M_PI;
8507  double C2 = 1.0 + (0.4e-6 / tox);
8508  double C3 = log(C2);
8509  cf = C1*C3/C5;
8510  }
8511 
8512  if (!given("CGDO"))
8513  {
8514  if (given("DLC") && (dlc > 0.0)) cgdo = dlc * cox - cgdl ;
8515  else cgdo = 0.6 * xj * cox;
8516  }
8517 
8518  if (!given("CGSO"))
8519  {
8520  if (given("DLC") && (dlc > 0.0)) cgso = dlc * cox - cgsl ;
8521  else cgso = 0.6 * xj * cox;
8522  }
8523 
8524  if (!given("CGBO")) cgbo = 2.0 * dwc * cox;
8525 
8526  if (!given("CJSWG"))
8527  unitLengthGateSidewallJctCap = unitLengthSidewallJctCap ;
8528 
8529  if (!given("PBSWG"))
8530  GatesidewallJctPotential = sidewallJctPotential;
8531 
8532  if (!given("MJSWG"))
8533  bulkJctGateSideGradingCoeff = bulkJctSideGradingCoeff;
8534 
8535 
8536  // More initializations: taken from b3temp.c:
8537  if (bulkJctPotential < 0.1)
8538  {
8539  bulkJctPotential = 0.1;
8540  msg = "Given pb is less than 0.1. Pb is set to 0.1.\n";
8541  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8542  }
8543 
8544  if (sidewallJctPotential < 0.1)
8545  {
8546  sidewallJctPotential = 0.1;
8547  msg = "Given pbsw is less than 0.1. Pbsw is set to 0.1.\n";
8548  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8549  }
8550 
8551  if (GatesidewallJctPotential < 0.1)
8552  {
8553  GatesidewallJctPotential = 0.1;
8554  msg = "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n";
8555  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
8556  }
8557 
8558  vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14));
8559  factor1 = sqrt(CONSTEPSSI / CONSTEPSOX * tox);
8560 
8561  Vtm0 = CONSTKoverQ * tnom;
8562  Eg0 = CONSTEg0 - CONSTalphaEg * tnom * tnom / (tnom + CONSTbetaEg);
8563  ni = CONSTNi0 * (tnom / CONSTREFTEMP) * sqrt(tnom / CONSTREFTEMP)
8564  * exp(21.5565981 - Eg0 / (2.0 * Vtm0));
8565 
8566  // If there are any time dependent parameters, set their values at for
8567  // the current time.
8568 
8569  return true;
8570  }
8571 
8572 //----------------------------------------------------------------------------
8573 // Function : Model::processInstanceParams
8574 // Purpose :
8575 // Special Notes :
8576 // Scope : public
8577 // Creator : Dave Shirely, PSSI
8578 // Creation Date : 03/23/06
8579 //----------------------------------------------------------------------------
8581  {
8582 
8583  std::vector<Instance*>::iterator iter;
8584  std::vector<Instance*>::iterator first = instanceContainer.begin();
8585  std::vector<Instance*>::iterator last = instanceContainer.end();
8586 
8587  for (iter=first; iter!=last; ++iter)
8588  {
8589  (*iter)->processParams();
8590  }
8591 
8592  return true;
8593  }
8594 
8595 //-----------------------------------------------------------------------------
8596 // Function : Model::Model
8597 // Purpose : model block constructor
8598 // Special Notes :
8599 // Scope : public
8600 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8601 // Creation Date : 11/14/00
8602 //-----------------------------------------------------------------------------
8604  const Configuration & configuration,
8605  const ModelBlock & MB,
8606  const FactoryBlock & factory_block)
8607  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
8608  modType (0),
8609  dtype (CONSTNMOS),
8610  mobMod (0),
8611  capMod (0),
8612  noiMod (0),
8613  binUnit (0),
8614  paramChk (0),
8615  version ("3.2.2"),
8616  tox (0),
8617  toxm (0),
8618  cdsc (0),
8619  cdscb (0),
8620  cdscd (0),
8621  cit (0),
8622  nfactor (0),
8623  xj (0),
8624  vsat (0),
8625  at (0),
8626  a0 (0),
8627  ags (0),
8628  a1 (0),
8629  a2 (0),
8630  keta (0),
8631  nsub (0),
8632  npeak (0),
8633  ngate (0),
8634  gamma1 (0),
8635  gamma2 (0),
8636  vbx (0),
8637  vbm (0),
8638  xt (0),
8639  k1 (0),
8640  kt1 (0),
8641  kt1l (0),
8642  kt2 (0),
8643  k2 (0),
8644  k3 (0),
8645  k3b (0),
8646  w0 (0),
8647  nlx (0),
8648  dvt0 (0),
8649  dvt1 (0),
8650  dvt2 (0),
8651  dvt0w (0),
8652  dvt1w (0),
8653  dvt2w (0),
8654  drout (0),
8655  dsub (0),
8656  vth0 (0),
8657  ua (0),
8658  ua1 (0),
8659  ub (0),
8660  ub1 (0),
8661  uc (0),
8662  uc1 (0),
8663  u0 (0),
8664  ute (0),
8665  voff (0),
8666  delta (0),
8667  rdsw (0),
8668  prwg (0),
8669  prwb (0),
8670  prt (0),
8671  eta0 (0),
8672  etab (0),
8673  pclm (0),
8674  pdibl1 (0),
8675  pdibl2 (0),
8676  pdiblb (0),
8677  pscbe1 (0),
8678  pscbe2 (0),
8679  pvag (0),
8680  wr (0),
8681  dwg (0),
8682  dwb (0),
8683  b0 (0),
8684  b1 (0),
8685  alpha0 (0),
8686  alpha1 (0),
8687  beta0 (0),
8688  ijth (0),
8689  vfb (0),
8690  elm (0),
8691  cgsl (0),
8692  cgdl (0),
8693  ckappa (0),
8694  cf (0),
8695  vfbcv (0),
8696  clc (0),
8697  cle (0),
8698  dwc (0),
8699  dlc (0),
8700  noff (0),
8701  voffcv (0),
8702  acde (0),
8703  moin (0),
8704  tcj (0),
8705  tcjsw (0),
8706  tcjswg (0),
8707  tpb (0),
8708  tpbsw (0),
8709  tpbswg (0),
8710  lcdsc (0),
8711  lcdscb (0),
8712  lcdscd (0),
8713  lcit (0),
8714  lnfactor (0),
8715  lxj (0),
8716  lvsat (0),
8717  lat (0),
8718  la0 (0),
8719  lags (0),
8720  la1 (0),
8721  la2 (0),
8722  lketa (0),
8723  lnsub (0),
8724  lnpeak (0),
8725  lngate (0),
8726  lgamma1 (0),
8727  lgamma2 (0),
8728  lvbx (0),
8729  lvbm (0),
8730  lxt (0),
8731  lk1 (0),
8732  lkt1 (0),
8733  lkt1l (0),
8734  lkt2 (0),
8735  lk2 (0),
8736  lk3 (0),
8737  lk3b (0),
8738  lw0 (0),
8739  lnlx (0),
8740  ldvt0 (0),
8741  ldvt1 (0),
8742  ldvt2 (0),
8743  ldvt0w (0),
8744  ldvt1w (0),
8745  ldvt2w (0),
8746  ldrout (0),
8747  ldsub (0),
8748  lvth0 (0),
8749  lua (0),
8750  lua1 (0),
8751  lub (0),
8752  lub1 (0),
8753  luc (0),
8754  luc1 (0),
8755  lu0 (0),
8756  lute (0),
8757  lvoff (0),
8758  ldelta (0),
8759  lrdsw (0),
8760  lprwg (0),
8761  lprwb (0),
8762  lprt (0),
8763  leta0 (0),
8764  letab (0),
8765  lpclm (0),
8766  lpdibl1 (0),
8767  lpdibl2 (0),
8768  lpdiblb (0),
8769  lpscbe1 (0),
8770  lpscbe2 (0),
8771  lpvag (0),
8772  lwr (0),
8773  ldwg (0),
8774  ldwb (0),
8775  lb0 (0),
8776  lb1 (0),
8777  lalpha0 (0),
8778  lalpha1 (0),
8779  lbeta0 (0),
8780  lvfb (0),
8781  lelm (0),
8782  lcgsl (0),
8783  lcgdl (0),
8784  lckappa (0),
8785  lcf (0),
8786  lclc (0),
8787  lcle (0),
8788  lvfbcv (0),
8789  lnoff (0),
8790  lvoffcv (0),
8791  lacde (0),
8792  lmoin (0),
8793  wcdsc (0),
8794  wcdscb (0),
8795  wcdscd (0),
8796  wcit (0),
8797  wnfactor (0),
8798  wxj (0),
8799  wvsat (0),
8800  wat (0),
8801  wa0 (0),
8802  wags (0),
8803  wa1 (0),
8804  wa2 (0),
8805  wketa (0),
8806  wnsub (0),
8807  wnpeak (0),
8808  wngate (0),
8809  wgamma1 (0),
8810  wgamma2 (0),
8811  wvbx (0),
8812  wvbm (0),
8813  wxt (0),
8814  wk1 (0),
8815  wkt1 (0),
8816  wkt1l (0),
8817  wkt2 (0),
8818  wk2 (0),
8819  wk3 (0),
8820  wk3b (0),
8821  ww0 (0),
8822  wnlx (0),
8823  wdvt0 (0),
8824  wdvt1 (0),
8825  wdvt2 (0),
8826  wdvt0w (0),
8827  wdvt1w (0),
8828  wdvt2w (0),
8829  wdrout (0),
8830  wdsub (0),
8831  wvth0 (0),
8832  wua (0),
8833  wua1 (0),
8834  wub (0),
8835  wub1 (0),
8836  wuc (0),
8837  wuc1 (0),
8838  wu0 (0),
8839  wute (0),
8840  wvoff (0),
8841  wdelta (0),
8842  wrdsw (0),
8843  wprwg (0),
8844  wprwb (0),
8845  wprt (0),
8846  weta0 (0),
8847  wetab (0),
8848  wpclm (0),
8849  wpdibl1 (0),
8850  wpdibl2 (0),
8851  wpdiblb (0),
8852  wpscbe1 (0),
8853  wpscbe2 (0),
8854  wpvag (0),
8855  wwr (0),
8856  wdwg (0),
8857  wdwb (0),
8858  wb0 (0),
8859  wb1 (0),
8860  walpha0 (0),
8861  walpha1 (0),
8862  wbeta0 (0),
8863  wvfb (0),
8864  welm (0),
8865  wcgsl (0),
8866  wcgdl (0),
8867  wckappa (0),
8868  wcf (0),
8869  wclc (0),
8870  wcle (0),
8871  wvfbcv (0),
8872  wnoff (0),
8873  wvoffcv (0),
8874  wacde (0),
8875  wmoin (0),
8876  pcdsc (0),
8877  pcdscb (0),
8878  pcdscd (0),
8879  pcit (0),
8880  pnfactor (0),
8881  pxj (0),
8882  pvsat (0),
8883  pat (0),
8884  pa0 (0),
8885  pags (0),
8886  pa1 (0),
8887  pa2 (0),
8888  pketa (0),
8889  pnsub (0),
8890  pnpeak (0),
8891  pngate (0),
8892  pgamma1 (0),
8893  pgamma2 (0),
8894  pvbx (0),
8895  pvbm (0),
8896  pxt (0),
8897  pk1 (0),
8898  pkt1 (0),
8899  pkt1l (0),
8900  pkt2 (0),
8901  pk2 (0),
8902  pk3 (0),
8903  pk3b (0),
8904  pw0 (0),
8905  pnlx (0),
8906  pdvt0 (0),
8907  pdvt1 (0),
8908  pdvt2 (0),
8909  pdvt0w (0),
8910  pdvt1w (0),
8911  pdvt2w (0),
8912  pdrout (0),
8913  pdsub (0),
8914  pvth0 (0),
8915  pua (0),
8916  pua1 (0),
8917  pub (0),
8918  pub1 (0),
8919  puc (0),
8920  puc1 (0),
8921  pu0 (0),
8922  pute (0),
8923  pvoff (0),
8924  pdelta (0),
8925  prdsw (0),
8926  pprwg (0),
8927  pprwb (0),
8928  pprt (0),
8929  peta0 (0),
8930  petab (0),
8931  ppclm (0),
8932  ppdibl1 (0),
8933  ppdibl2 (0),
8934  ppdiblb (0),
8935  ppscbe1 (0),
8936  ppscbe2 (0),
8937  ppvag (0),
8938  pwr (0),
8939  pdwg (0),
8940  pdwb (0),
8941  pb0 (0),
8942  pb1 (0),
8943  palpha0 (0),
8944  palpha1 (0),
8945  pbeta0 (0),
8946  pvfb (0),
8947  pelm (0),
8948  pcgsl (0),
8949  pcgdl (0),
8950  pckappa (0),
8951  pcf (0),
8952  pclc (0),
8953  pcle (0),
8954  pvfbcv (0),
8955  pnoff (0),
8956  pvoffcv (0),
8957  pacde (0),
8958  pmoin (0),
8959  tnom (getDeviceOptions().tnom),
8960  cgso (0),
8961  cgdo (0),
8962  cgbo (0),
8963  xpart (0),
8964  cFringOut (0),
8965  cFringMax (0),
8966  sheetResistance (0),
8967  jctSatCurDensity (0),
8968  jctSidewallSatCurDensity (0),
8969  bulkJctPotential (0),
8970  bulkJctBotGradingCoeff (0),
8971  bulkJctSideGradingCoeff (0),
8972  bulkJctGateSideGradingCoeff (0),
8973  sidewallJctPotential (0),
8974  GatesidewallJctPotential (0),
8975  unitAreaJctCap (0),
8976  unitLengthSidewallJctCap (0),
8977  unitLengthGateSidewallJctCap (0),
8978  jctEmissionCoeff (0),
8979  jctTempExponent (0),
8980  Lint (0),
8981  Ll (0),
8982  Llc (0),
8983  Lln (0),
8984  Lw (0),
8985  Lwc (0),
8986  Lwn (0),
8987  Lwl (0),
8988  Lwlc (0),
8989  model_l (0),
8990  model_w (0),
8991  Lmin (0),
8992  Lmax (0),
8993  Wmin (0),
8994  Wmax (0),
8995  Wint (0),
8996  Wl (0),
8997  Wlc (0),
8998  Wln (0),
8999  Ww (0),
9000  Wwc (0),
9001  Wwn (0),
9002  Wwl (0),
9003  Wwlc (0),
9004  vtm (0),
9005  cox (0),
9006  cof1 (0),
9007  cof2 (0),
9008  cof3 (0),
9009  cof4 (0),
9010  vcrit (0),
9011  factor1 (0),
9012  PhiB (0),
9013  PhiBSW (0),
9014  PhiBSWG (0),
9015  oxideTrapDensityA (0),
9016  oxideTrapDensityB (0),
9017  oxideTrapDensityC (0),
9018  em (0),
9019  ef (0),
9020  af (0),
9021  kf (0),
9022  npeakGiven (0),
9023  gamma1Given (0),
9024  gamma2Given (0),
9025  k1Given (0),
9026  k2Given (0),
9027  nsubGiven (0),
9028  xtGiven (0),
9029  vbxGiven (0),
9030  vbmGiven (0),
9031  vfbGiven (0),
9032  vth0Given (0),
9033  Vtm0 (0.0),
9034  Eg0 (0.0),
9035  ni (0.0)
9036  {
9037  if (getType() != "")
9038  {
9039  if (getType() == "NMOS") {
9040  dtype = CONSTNMOS;
9041  }
9042  else if (getType() == "PMOS") {
9043  dtype = CONSTPMOS;
9044  }
9045  else
9046  {
9047  UserError0(*this) << "Could not recognize the type for model " << getName();
9048  }
9049  }
9050 
9051  // Set params to constant default values:
9052  setDefaultParams();
9053 
9054  // Set params according to .model line and constant defaults from metadata:
9055  setModParams(MB.params);
9056 
9057  // Set any non-constant parameter defaults:
9058 #ifdef Xyce_BSIM3_USE_DEFL
9059  if (!given("L"))
9061  if (!given("W"))
9063 #endif
9064  if (!given("TNOM"))
9066 
9067  if (!given("TNOM") && tnom == 0.0)
9068  Report::DevelFatal0() << "TNOM is zero";
9069 
9070 // Calculate any parameters specified as expressions:
9072 
9073  // calculate dependent (ie computed) params and check for errors:
9074  if (!given("VTH0"))
9075  vth0 = (dtype == CONSTNMOS) ? 0.7 : -0.7;
9076  if (!given("UC"))
9077  uc = (mobMod == 3) ? -0.0465 : -0.0465e-9;
9078  if (!given("UC1"))
9079  uc1 = (mobMod == 3) ? -0.056 : -0.056e-9;
9080  if (!given("U0"))
9081  u0 = (dtype == CONSTNMOS) ? 0.067 : 0.025;
9082  if (!given("NOIA"))
9083  {
9084  if (dtype == CONSTNMOS)
9085  oxideTrapDensityA = 1e20;
9086  else
9087  oxideTrapDensityA = 9.9e18;
9088  }
9089  if (!given("NOIB"))
9090  {
9091  if (dtype == CONSTNMOS)
9092  oxideTrapDensityB = 5e4;
9093  else
9094  oxideTrapDensityB = 2.4e3;
9095  }
9096  if (!given("NOIC"))
9097  {
9098  if (dtype == CONSTNMOS)
9099  oxideTrapDensityC = -1.4e-12;
9100  else
9101  oxideTrapDensityC = 1.4e-12;
9102  }
9103 
9104  processParams ();
9105  }
9106 
9107 //-----------------------------------------------------------------------------
9108 // Function : Model::~Model
9109 // Purpose : destructor
9110 // Special Notes :
9111 // Scope : public
9112 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9113 // Creation Date : 11/14/00
9114 //-----------------------------------------------------------------------------
9116  {
9117  std::list<SizeDependParam*>::iterator it_dpL =
9118  sizeDependParamList.begin();
9119  std::list<SizeDependParam*>::iterator end_dpL =
9120  sizeDependParamList.end();
9121  for( ; it_dpL != end_dpL; ++it_dpL )
9122  delete (*it_dpL);
9123 
9124  sizeDependParamList.clear ();
9125 
9126  std::vector<Instance*>::iterator iter;
9127  std::vector<Instance*>::iterator first = instanceContainer.begin();
9128  std::vector<Instance*>::iterator last = instanceContainer.end();
9129 
9130  for (iter=first; iter!=last; ++iter)
9131  {
9132  delete (*iter);
9133  }
9134 
9135  }
9136 
9137 
9138 //-----------------------------------------------------------------------------
9139 // Function : Model::printOutInstances
9140 // Purpose : debugging tool.
9141 // Special Notes :
9142 // Scope : public
9143 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9144 // Creation Date : 4/03/00
9145 //-----------------------------------------------------------------------------
9146  std::ostream &Model::printOutInstances (std::ostream &os) const
9147  {
9148  std::vector<Instance*>::const_iterator iter;
9149  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
9150  std::vector<Instance*>::const_iterator last = instanceContainer.end();
9151 
9152  int i;
9153  os << std::endl;
9154  os << " name modelName Parameters" << std::endl;
9155 
9156  for (i=0, iter=first; iter!=last; ++iter,++i)
9157  {
9158  os << " " << i << ": " << (*iter)->getName() << "\t";
9159  os << getName();
9160  os << std::endl;
9161  }
9162 
9163  os << std::endl;
9164 
9165  return os;
9166  }
9167 
9168 //-----------------------------------------------------------------------------
9169 // Function : Model::forEachInstance
9170 // Purpose :
9171 // Special Notes :
9172 // Scope : public
9173 // Creator : David Baur
9174 // Creation Date : 2/4/2014
9175 //-----------------------------------------------------------------------------
9176 /// Apply a device instance "op" to all instances associated with this
9177 /// model
9178 ///
9179 /// @param[in] op Operator to apply to all instances.
9180 ///
9181 ///
9182  void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
9183 {
9184  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
9185  op(*it);
9186  }
9187 
9188 
9189 
9190 //----------------------------------------------------------------------------
9191 // Function : Model::clearTemperatureData
9192 //
9193 // Purpose : This is mainly here to delete rid of the size
9194 // dependent parameters, which are also temperature dependent.
9195 //
9196 // Special Notes : This is called right before the circuit temperature is
9197 // changed.
9198 //
9199 // Scope : public
9200 // Creator : Eric R. Keiter, 9233, computation sciences
9201 // Creation Date : 10/26/2004
9202 //----------------------------------------------------------------------------
9204  {
9205  std::list<SizeDependParam*>::iterator it_dpL =
9206  sizeDependParamList.begin();
9207  std::list<SizeDependParam*>::iterator end_dpL =
9208  sizeDependParamList.end();
9209  for( ; it_dpL != end_dpL; ++it_dpL )
9210  delete (*it_dpL);
9211 
9212  sizeDependParamList.clear ();
9213 
9214  return true;
9215  }
9216 
9217 //-----------------------------------------------------------------------------
9218 // MOSFET_B3 Master functions:
9219 //-----------------------------------------------------------------------------
9220 
9221 //-----------------------------------------------------------------------------
9222 // Function : Master::updateState
9223 // Purpose :
9224 // Special Notes :
9225 // Scope : public
9226 // Creator : Eric Keiter, SNL
9227 // Creation Date : 12/02/08
9228 //-----------------------------------------------------------------------------
9229  bool Master::updateState (double * solVec, double * staVec, double * stoVec)
9230  {
9231  bool bsuccess = true;
9232  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9233  {
9234  Instance & mi = *(*it);
9235 
9236  bool btmp = mi.updateIntermediateVars ();
9237  bsuccess = bsuccess && btmp;
9238 
9239  // voltage drops:
9240  double * stoVec = mi.extData.nextStoVectorRawPtr;
9241  stoVec[mi.li_store_vbs] = mi.vbs;
9242  stoVec[mi.li_store_vgs] = mi.vgs;
9243  stoVec[mi.li_store_vds] = mi.vds;
9244  stoVec[mi.li_store_vbd] = mi.vbd;
9245  stoVec[mi.li_store_von] = mi.von;
9246 
9247  // intrinsic capacitors:
9248  staVec[mi.li_state_qb] = mi.qb;
9249  staVec[mi.li_state_qg] = mi.qg;
9250  staVec[mi.li_state_qd] = mi.qd;
9251 
9252  // parasitic capacitors:
9253  staVec[mi.li_state_qbs] = mi.qbs;
9254  staVec[mi.li_state_qbd] = mi.qbd;
9255 
9256  if( mi.nqsMod )
9257  {
9258  staVec[mi.li_state_qcheq] = mi.qcheq;
9259  staVec[mi.li_state_qcdump] = mi.qcdump;
9260  }
9261 
9262  // if this is the first newton step of the first time step
9263  // of the transient simulation, we need to enforce that the
9264  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
9265  // compatibility. ERK.
9266 
9267  // Note: I think this kind of thing is enforced (or should be enforced,
9268  // anyway) at the time integration level. So I'm not sure this step is
9269  // really needed, at least for new-DAE. Derivatives out of the DCOP
9270  // are supposed to be zero at the first newton step.
9271 
9272  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
9273  {
9274  // re-set the state vector pointer that we are using to the "current"
9275  // pointer, rather than the "next" pointer.
9276  double * currStaVec = mi.extData.currStaVectorRawPtr;
9277 
9278  // intrinsic capacitors:
9279  currStaVec[mi.li_state_qb] = mi.qb;
9280  currStaVec[mi.li_state_qg] = mi.qg;
9281  currStaVec[mi.li_state_qd] = mi.qd;
9282 
9283  // parasitic capacitors:
9284  currStaVec[mi.li_state_qbs] = mi.qbs;
9285  currStaVec[mi.li_state_qbd] = mi.qbd;
9286 
9287  if( mi.nqsMod )
9288  {
9289  currStaVec[mi.li_state_qcheq] = mi.qcheq;
9290  currStaVec[mi.li_state_qcdump] = mi.qcdump;
9291  }
9292  }
9293  }
9294 
9295  return bsuccess;
9296  }
9297 
9298 //-----------------------------------------------------------------------------
9299 // Function : Master::loadDAEVectors
9300 // Purpose :
9301 // Special Notes :
9302 // Scope : public
9303 // Creator : Eric Keiter, SNL
9304 // Creation Date : 12/02/08
9305 //-----------------------------------------------------------------------------
9306  bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * storeLeadF, double * storeLeadQ)
9307  {
9308  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9309  {
9310  Instance & mi = *(*it);
9311 
9312  double * dFdxdVp = mi.extData.dFdxdVpVectorRawPtr;
9313  double * dQdxdVp = mi.extData.dQdxdVpVectorRawPtr;
9314 
9315  double coef(0.0);
9316  // F-vector:
9317  mi.cdreq_Jdxp = 0.0;
9318  mi.ceqbd_Jdxp = 0.0;
9319  mi.ceqbs_Jdxp = 0.0;
9320 
9321  // Do a few auxilliary calculations, derived from 3f5.
9322  // load current vector
9323  if (mi.mode >= 0)
9324  {
9325  mi.Gm = mi.gm;
9326  mi.Gmbs = mi.gmbs;
9327  mi.FwdSum = mi.Gm + mi.Gmbs;
9328  mi.RevSum = 0.0;
9329 
9330  mi.cdreq = mi.model_.dtype * (mi.cd);
9331  mi.ceqbd = -mi.model_.dtype * (mi.csub);
9332 
9333  mi.ceqbs = 0.0;
9334 
9335  mi.gbbdp = -mi.gbds;
9336  mi.gbbsp = (mi.gbds + mi.gbgs + mi.gbbs);
9337 
9338  mi.gbdpg = mi.gbgs;
9339  mi.gbdpdp = mi.gbds;
9340  mi.gbdpb = mi.gbbs;
9341  mi.gbdpsp = -(mi.gbdpg + mi.gbdpdp + mi.gbdpb);
9342 
9343  mi.gbspg = 0.0;
9344  mi.gbspdp = 0.0;
9345  mi.gbspb = 0.0;
9346  mi.gbspsp = 0.0;
9347  }
9348  else
9349  {
9350  mi.Gm = -mi.gm;
9351  mi.Gmbs = -mi.gmbs;
9352  mi.FwdSum = 0.0;
9353  mi.RevSum = -(mi.Gm + mi.Gmbs);
9354 
9355  mi.cdreq = -mi.model_.dtype * (mi.cd);
9356  mi.ceqbs = -mi.model_.dtype * (mi.csub);
9357 
9358  mi.ceqbd = 0.0;
9359 
9360  mi.gbbsp = -mi.gbds;
9361  mi.gbbdp = (mi.gbds + mi.gbgs + mi.gbbs);
9362 
9363  mi.gbdpg = 0.0;
9364  mi.gbdpsp = 0.0;
9365  mi.gbdpb = 0.0;
9366  mi.gbdpdp = 0.0;
9367 
9368  mi.gbspg = mi.gbgs;
9369  mi.gbspsp = mi.gbds;
9370  mi.gbspb = mi.gbbs;
9371  mi.gbspdp = -(mi.gbspg + mi.gbspsp + mi.gbspb);
9372  }
9373 
9374  if (mi.model_.dtype > 0)
9375  {
9376  mi.ceqbs += (mi.cbs);
9377  mi.ceqbd += (mi.cbd);
9378  }
9379  else
9380  {
9381  mi.ceqbs -= (mi.cbs);
9382  mi.ceqbd -= (mi.cbd);
9383  }
9384 
9385  if (mi.drainConductance != 0.0)
9386  {
9387  fVec[mi.li_Drain] += mi.Idrain*mi.numberParallel;
9388  }
9389  if (mi.sourceConductance != 0.0)
9390  {
9391  fVec[mi.li_Source] += mi.Isource*mi.numberParallel;
9392  }
9393 
9394  fVec[mi.li_Bulk] += (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9395  fVec[mi.li_DrainPrime] += (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9396  fVec[mi.li_SourcePrime] += (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9397 
9398  if( mi.loadLeadCurrent )
9399  {
9400  if (mi.drainConductance != 0.0)
9401  {
9402  storeLeadF[mi.li_store_dev_id] = mi.Idrain*mi.numberParallel;
9403  }
9404  else
9405  {
9406  storeLeadF[mi.li_store_dev_id] = (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9407  }
9408  if (mi.sourceConductance != 0.0)
9409  {
9410  storeLeadF[mi.li_store_dev_is] = mi.Isource*mi.numberParallel;
9411  }
9412  else
9413  {
9414  storeLeadF[mi.li_store_dev_is] = (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9415  }
9416  storeLeadF[mi.li_store_dev_ig] = 0.0;
9417  storeLeadF[mi.li_store_dev_ib] = (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9418  }
9419 
9420  // Initial condition support
9421 
9422  if( getSolverState().dcopFlag && mi.icVDSGiven )
9423  {
9424  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ids];
9425  fVec[mi.li_Drain] += coef;
9426  fVec[mi.li_Source] += -coef;
9427  if( mi.loadLeadCurrent )
9428  {
9429  storeLeadF[mi.li_store_dev_id]= coef;
9430  storeLeadF[mi.li_store_dev_is]= -coef;
9431  }
9432  }
9433 
9434  if( getSolverState().dcopFlag && mi.icVGSGiven )
9435  {
9436  coef = mi.extData.nextSolVectorRawPtr[mi.li_Igs];
9437  fVec[mi.li_Gate] += coef;
9438  fVec[mi.li_Source] += -coef;
9439  if( mi.loadLeadCurrent )
9440  {
9441  storeLeadF[mi.li_store_dev_ig]= coef;
9442  storeLeadF[mi.li_store_dev_is]= -coef;
9443  }
9444  }
9445 
9446 
9447  if( getSolverState().dcopFlag && mi.icVBSGiven )
9448  {
9449  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ibs];
9450  fVec[mi.li_Bulk] += coef;
9451  fVec[mi.li_Source] += -coef;
9452  if( mi.loadLeadCurrent )
9453  {
9454  storeLeadF[mi.li_store_dev_ib]= coef;
9455  storeLeadF[mi.li_store_dev_is]= -coef;
9456  }
9457  }
9458 
9459  //////////////////////////////////////////////////
9460  // limiting section:
9462  {
9463  if (!mi.origFlag)
9464  {
9465  if (mi.mode >= 0)
9466  {
9467  // option 1
9468  double tmp = mi.model_.dtype * (-mi.gds * (mi.vds-mi.vds_orig) -
9469  mi.Gm * (mi.vgs-mi.vgs_orig) -
9470  mi.Gmbs * (mi.vbs-mi.vbs_orig));
9471 
9472  mi.cdreq_Jdxp += tmp;
9473  mi.cdreq += tmp;
9474 
9475  tmp = -mi.model_.dtype * (-mi.gbds * (mi.vds-mi.vds_orig) -
9476  mi.gbgs * (mi.vgs-mi.vgs_orig) -
9477  mi.gbbs * (mi.vbs-mi.vbs_orig));
9478  mi.ceqbd_Jdxp += tmp;
9479  mi.ceqbd += tmp;
9480  }
9481  else
9482  {
9483  // option 2
9484  double tmp = -mi.model_.dtype * (mi.gds * (mi.vds-mi.vds_orig) +
9485  mi.Gm * (mi.vgd-mi.vgd_orig) +
9486  mi.Gmbs * (mi.vbd-mi.vbd_orig));
9487  mi.cdreq_Jdxp += tmp;
9488  mi.cdreq += tmp;
9489 
9490  tmp = -mi.model_.dtype * (mi.gbds * (mi.vds-mi.vds_orig) -
9491  mi.gbgs * (mi.vgd-mi.vgd_orig) -
9492  mi.gbbs * (mi.vbd-mi.vbd_orig));
9493  mi.ceqbd_Jdxp += tmp;
9494  mi.ceqbd += tmp;
9495  }
9496 
9497 
9498  if (mi.model_.dtype > 0)
9499  {
9500  mi.ceqbs_Jdxp += (-mi.gbs*(mi.vbs-mi.vbs_orig));
9501  mi.ceqbs += (-mi.gbs*(mi.vbs-mi.vbs_orig));
9502 
9503  mi.ceqbd_Jdxp += (-mi.gbd*(mi.vbd-mi.vbd_orig));
9504  mi.ceqbd += (-mi.gbd*(mi.vbd-mi.vbd_orig));
9505  }
9506  else
9507  {
9508  mi.ceqbs_Jdxp -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
9509  mi.ceqbs -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
9510 
9511  mi.ceqbd_Jdxp -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
9512  mi.ceqbd -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
9513  }
9514 
9515  dFdxdVp[mi.li_Bulk] += -(mi.ceqbs_Jdxp+mi.ceqbd_Jdxp)*mi.numberParallel;
9516  dFdxdVp[mi.li_DrainPrime] += (mi.ceqbd_Jdxp-mi.cdreq_Jdxp)*mi.numberParallel;
9517  dFdxdVp[mi.li_SourcePrime] += (mi.cdreq_Jdxp+mi.ceqbs_Jdxp)*mi.numberParallel;
9518 
9519  } // orig flag.
9520  } // voltage limiter flag
9521 
9522  // Row associated with icVBS
9523  if( getSolverState().dcopFlag && mi.icVBSGiven )
9524  {
9525  // get the voltage drop from the previous solution
9526  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9527  double cVb = mi.extData.nextSolVectorRawPtr[mi.li_Bulk];
9528 
9529  fVec[mi.li_Ibs] += (cVb - cVs - mi.icVBS);
9530  }
9531 
9532  // Row associated with icVDS
9533  if( getSolverState().dcopFlag && mi.icVDSGiven )
9534  {
9535  // get the voltage drop from the previous solution
9536  double cVd = mi.extData.nextSolVectorRawPtr[mi.li_Drain];
9537  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9538 
9539  fVec[mi.li_Ids] += (cVd - cVs - mi.icVDS);
9540  }
9541 
9542  // Row associated with icVGS
9543  if( getSolverState().dcopFlag && mi.icVGSGiven )
9544  {
9545  // get the voltage drop from the previous solution
9546  double cVg = mi.extData.nextSolVectorRawPtr[mi.li_Gate];
9547  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
9548 
9549  fVec[mi.li_Igs] += (cVg - cVs - mi.icVGS);
9550  }
9551 
9552  // Q-vector:
9553 
9554  mi.auxChargeCalculations ();
9555 
9556  double Qeqqg = 0.0; // gate charge
9557  double Qeqqb = 0.0; // bulk charge
9558  double Qeqqd = 0.0; // drain charge
9559  double Qqdef = 0.0; // nqs-related charge.
9560  double Qqcheq = 0.0; // nqs-related charge.
9561 
9562  // These 3 vars are class variables, and are set up elsewhere.
9563  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
9564  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
9565  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
9566 
9567  if (mi.model_.dtype > 0)
9568  {
9569  Qeqqg = mi.qg;
9570  Qeqqb = mi.qb;
9571  Qeqqd = mi.qd;
9572  Qqdef = mi.qcdump; // this needs to be fixed...
9573  Qqcheq = mi.qcheq;
9574  }
9575  else // need to convert these to charges.
9576  {
9577  Qeqqg = -mi.qg;
9578  Qeqqb = -mi.qb;
9579  Qeqqd = -mi.qd;
9580  Qqdef = -mi.qcdump;
9581  Qqcheq = -mi.qcheq;
9582  }
9583 
9584  qVec[mi.li_Gate] += Qeqqg*mi.numberParallel;
9585  qVec[mi.li_Bulk] += (Qeqqb)*mi.numberParallel;
9586  qVec[mi.li_DrainPrime] += (-(-Qeqqd))*mi.numberParallel;
9587  qVec[mi.li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
9588 
9589  if (mi.nqsMod)
9590  {
9591  // 7 equ. for nqs modification. charge equation.
9592  qVec[mi.li_Charge] += -(Qqcheq - Qqdef)*mi.numberParallel;
9593  }
9594 
9595  if( mi.loadLeadCurrent )
9596  {
9597  if (mi.drainConductance == 0.0)
9598  {
9599  storeLeadQ[mi.li_store_dev_id] = (-(-Qeqqd))*mi.numberParallel;
9600  }
9601  if (mi.sourceConductance == 0.0)
9602  {
9603  storeLeadQ[mi.li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
9604  }
9605  storeLeadQ[mi.li_store_dev_ig] = Qeqqg*mi.numberParallel;
9606  storeLeadQ[mi.li_store_dev_ib] = (Qeqqb)*mi.numberParallel;
9607  }
9608 
9609  //////////////////////////////////////////////////
9610  // limiting section:
9612  {
9613  // Need the following:
9614  // Qeqqg_Jdxp
9615  // Qeqqb_Jdxp
9616  // Qeqqd_Jdxp
9617  if (mi.model_.dtype > 0)
9618  {
9619 #if 0
9620  // no-op:
9621  mi.Qeqqg_Jdxp = mi.Qeqqg_Jdxp;
9622  mi.Qeqqb_Jdxp = mi.Qeqqb_Jdxp;
9623  mi.Qeqqd_Jdxp = mi.Qeqqd_Jdxp;
9624 #endif
9625  }
9626  else
9627  {
9628  mi.Qeqqg_Jdxp = -mi.Qeqqg_Jdxp;
9629  mi.Qeqqb_Jdxp = -mi.Qeqqb_Jdxp;
9630  mi.Qeqqd_Jdxp = -mi.Qeqqd_Jdxp;
9631  }
9632 
9633  if (!mi.origFlag)
9634  {
9635  dQdxdVp[mi.li_Gate] += -mi.Qeqqg_Jdxp*mi.numberParallel;
9636  dQdxdVp[mi.li_Bulk] += -(+mi.Qeqqb_Jdxp)*mi.numberParallel;
9637  dQdxdVp[mi.li_DrainPrime] += (-mi.Qeqqd_Jdxp)*mi.numberParallel;
9638  dQdxdVp[mi.li_SourcePrime] += (+mi.Qeqqg_Jdxp+mi.Qeqqb_Jdxp+mi.Qeqqd_Jdxp) *mi.numberParallel;
9639  } // orig flag.
9640  } // limiter flag
9641  }
9642  return true;
9643  }
9644 
9645 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
9646 //-----------------------------------------------------------------------------
9647 // Function : Master::loadDAEMatrices
9648 // Purpose :
9649 // Special Notes :
9650 // Scope : public
9651 // Creator : Eric Keiter, SNL
9652 // Creation Date : 12/02/08
9653 //-----------------------------------------------------------------------------
9654  bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
9655  {
9656  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9657  {
9658  Instance & mi = *(*it);
9659 
9660  // F-matrix:
9661  // Row corresponding to the KCL for the drain node:
9662 
9665 
9668 
9669  // Extra term for initial conditions on Vds in operating point
9670  if( getSolverState().dcopFlag && mi.icVDSGiven )
9671  {
9672  *mi.f_DrainEquIdsPtr += 1.0;
9673  }
9674 
9675  // Row corresponding to the KCL for the source node:
9676 
9679 
9682 
9683  // Extra term for initial conditions on Vbs in operating point
9684  if( getSolverState().dcopFlag && mi.icVBSGiven )
9685  {
9686  *mi.f_SourceEquIbsPtr -= 1.0;
9687  }
9688  // Extra term for initial conditions on Vds in operating point
9689  if( getSolverState().dcopFlag && mi.icVDSGiven )
9690  {
9691  *mi.f_SourceEquIdsPtr -= 1.0;
9692  }
9693  // Extra term for initial conditions on Vgs in operating point
9694  if( getSolverState().dcopFlag && mi.icVGSGiven )
9695  {
9696  *mi.f_SourceEquIgsPtr -= 1.0;
9697  }
9698 
9699  // Row corresponding to the KCL for the gate node: NOTHING
9700  // Check this later. ERK.
9701  //
9702  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
9703  // belong here. I'm not sure aboug the gg terms. On one hand, the
9704  // rhs vector component for the gate node ONLY seems to take
9705  // capacitive currents, which implies that all of these are capacitive
9706  // conductances. On the other hand, the gg terms do not appear to
9707  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
9708  // capacitive conductances are of the form g = C/dt, and the gg terms
9709  // do not have this form.
9710  //
9711  // For now, the gg issue is moot b/c those terms are only nonzero
9712  // if mi.nqsMod = 1, which is not a supported option.
9713 
9714  // However, the gg
9715  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
9716  //
9717  //(*JMatPtr)[GateEquGateNodePtr
9718  // += (gcggb - mi.ggtg)*mi.numberParallel;
9719  //(*JMatPtr)[GateEquBulkNodePtr
9720  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
9721  //(*JMatPtr)[GateEquDrainPrimeNodePtr
9722  // += (gcgdb - ggtd)*mi.numberParallel;
9723  //(*JMatPtr)[GateEquSourcePrimeNodePtr
9724  // += (gcgsb - ggts)*mi.numberParallel;
9725 
9726  // initial conditions on gate node
9727  // Extra term for initial conditions on Vgs in operating point
9728  if( getSolverState().dcopFlag && mi.icVGSGiven )
9729  {
9730  *mi.f_GateEquIgsPtr += 1.0;
9731  }
9732 
9733  // Row corresponding to the KCL for the bulk node:
9734 
9736  += (- mi.gbgs)*mi.numberParallel;
9737 
9738 
9740  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
9741 
9742 
9744  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
9745 
9746 
9748  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
9749 
9750  // Extra term for initial conditions on Vbs in operating point
9751  if( getSolverState().dcopFlag && mi.icVBSGiven )
9752  {
9753  *mi.f_BulkEquIbsPtr += 1.0;
9754  }
9755 
9756  // Row corresponding to the KCL for the drain prime node:
9757 
9760 
9762  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
9763  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
9764 
9766  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
9767  *mi.numberParallel;
9768 
9770  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
9771  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
9772 
9774  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
9775  *mi.numberParallel;
9776 
9777  // Row corresponding to the KCL for the source prime node:
9779  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
9780  *mi.numberParallel;
9781 
9783  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
9784  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
9785 
9788 
9790  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
9791  *mi.numberParallel;
9792 
9794  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
9795  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
9796 
9797  // Row associated with the charge equation
9798  if (mi.nqsMod)
9799  {
9800  std::string msg;
9801  msg = "Instance::loadDAEMatrices";
9802  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
9803  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
9804  }
9805 
9806  // Initial condition rows
9807  // Row associated with mi.icVBS
9808  if( mi.icVBSGiven )
9809  {
9810  if( getSolverState().dcopFlag )
9811  {
9812  *mi.f_icVBSEquVbPtr += 1.0;
9813  *mi.f_icVBSEquVsPtr -= 1.0;
9814  }
9815  else
9816  {
9817  *mi.f_icVBSEquIbsPtr += 1.0;
9818  }
9819  }
9820 
9821  // Row associated with mi.icVDS
9822  if( mi.icVDSGiven )
9823  {
9824  if( getSolverState().dcopFlag )
9825  {
9826  *mi.f_icVDSEquVdPtr += 1.0;
9827  *mi.f_icVDSEquVsPtr -= 1.0;
9828  }
9829  else
9830  {
9831  *mi.f_icVDSEquIdsPtr += 1.0;
9832  }
9833  }
9834 
9835  // Row associated with mi.icVGS
9836  if( mi.icVGSGiven )
9837  {
9838  if( getSolverState().dcopFlag )
9839  {
9840  *mi.f_icVGSEquVgPtr += 1.0;
9841  *mi.f_icVGSEquVsPtr -= 1.0;
9842  }
9843  else
9844  {
9845  *mi.f_icVGSEquIgsPtr += 1.0;
9846  }
9847  }
9848 
9849 
9850  // Q-matrix:
9851  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
9852  {
9853  // do nothing, as for this special case q is always zero.
9854  }
9855  else
9856  {
9857  // Row corresponding to the KCL for the drain node: NOTHING
9858 
9859  // Row corresponding to the KCL for the source node: NOTHING
9860 
9861  // Row corresponding to the KCL for the gate node:
9862  // Check this later. ERK. See the comments in the function
9863  // loadDAE*mi.q_, regarding ggtg, ggtb, etc.
9864  //
9865  // For now I am leaving out the gg terms, as they are zero when
9866  // nqsMod=0, which is always true.
9867  //
9869  += (mi.CAPcggb )*mi.numberParallel;
9871  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
9873  += (mi.CAPcgdb )*mi.numberParallel;
9875  += (mi.CAPcgsb )*mi.numberParallel;
9876 
9877  // Row corresponding to the KCL for the bulk node:
9879  += (mi.CAPcbgb)*mi.numberParallel;
9880 
9882  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
9883 
9885  += (mi.CAPcbdb)*mi.numberParallel;
9886 
9888  += (mi.CAPcbsb)*mi.numberParallel;
9889 
9890 
9891  // Row corresponding to the KCL for the drain prime node:
9893  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
9894 
9896  += (mi.CAPcdgb) *mi.numberParallel;
9897 
9899  += (+ mi.CAPcddb )*mi.numberParallel;
9900 
9902  -= (- mi.CAPcdsb) *mi.numberParallel;
9903 
9904  // Row corresponding to the KCL for the source prime node:
9906  += (mi.CAPcsgb) *mi.numberParallel;
9907 
9909  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
9910 
9912  -= (- mi.CAPcsdb) *mi.numberParallel;
9913 
9915  += (+ mi.CAPcssb) *mi.numberParallel;
9916 
9917  // Row associated with the charge equation
9918  // This is currently not supported.
9919  if (mi.nqsMod)
9920  {
9921  std::string msg;
9922  msg = "Master::loadDAEMatrices";
9923  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
9924  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
9925  }
9926  }
9927  }
9928  return true;
9929  }
9930 
9931 #else
9932 //-----------------------------------------------------------------------------
9933 // Function : Master::loadDAEMatrices
9934 // Purpose :
9935 // Special Notes :
9936 // Scope : public
9937 // Creator : Eric Keiter, SNL
9938 // Creation Date : 12/02/08
9939 //-----------------------------------------------------------------------------
9940  bool Master::loadDAEMatrices (N_LAS_Matrix & dFdx, N_LAS_Matrix & dQdx)
9941  {
9942  int sizeInstances = instanceContainer_.size();
9943  for (int i=0; i<sizeInstances; ++i)
9944  {
9945  Instance & mi = *(instanceContainer_.at(i));
9946 
9947  int count = 0;
9948  // F-matrix:
9949  // Row corresponding to the KCL for the drain node:
9950 
9951  dFdx [mi.li_Drain][mi.ADrainEquDrainNodeOffset]
9953 
9956 
9957  // Extra term for initial conditions on Vds in operating point
9958  if( getSolverState().dcopFlag && mi.icVDSGiven )
9959  {
9960  dFdx[mi.li_Drain][mi.ADrainEquIdsOffset] += 1.0;
9961  }
9962 
9963  // Row corresponding to the KCL for the source node:
9964 
9967 
9970 
9971  // Extra term for initial conditions on Vbs in operating point
9972  if( getSolverState().dcopFlag && mi.icVBSGiven )
9973  {
9974  dFdx[mi.li_Source][mi.ASourceEquIbsOffset] -= 1.0;
9975  }
9976  // Extra term for initial conditions on Vds in operating point
9977  if( getSolverState().dcopFlag && mi.icVDSGiven )
9978  {
9979  dFdx[mi.li_Source][mi.ASourceEquIdsOffset] -= 1.0;
9980  }
9981  // Extra term for initial conditions on Vgs in operating point
9982  if( getSolverState().dcopFlag && mi.icVGSGiven )
9983  {
9984  dFdx[mi.li_Source][mi.ASourceEquIgsOffset] -= 1.0;
9985  }
9986 
9987  // Row corresponding to the KCL for the gate node: NOTHING
9988  // Check this later. ERK.
9989  //
9990  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
9991  // belong here. I'm not sure aboug the gg terms. On one hand, the
9992  // rhs vector component for the gate node ONLY seems to take
9993  // capacitive currents, which implies that all of these are capacitive
9994  // conductances. On the other hand, the gg terms do not appear to
9995  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
9996  // capacitive conductances are of the form g = C/dt, and the gg terms
9997  // do not have this form.
9998  //
9999  // For now, the gg issue is moot b/c those terms are only nonzero
10000  // if mi.nqsMod = 1, which is not a supported option.
10001 
10002  // However, the gg
10003  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
10004  //
10005  //(*JMatPtr)[mi.li_Gate][mi.AGateEquGateNodeOffset]
10006  // += (gcggb - mi.ggtg)*mi.numberParallel;
10007  //(*JMatPtr)[mi.li_Gate][mi.AGateEquBulkNodeOffset]
10008  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
10009  //(*JMatPtr)[mi.li_Gate][mi.AGateEquDrainPrimeNodeOffset]
10010  // += (gcgdb - ggtd)*mi.numberParallel;
10011  //(*JMatPtr)[mi.li_Gate][mi.AGateEquSourcePrimeNodeOffset]
10012  // += (gcgsb - ggts)*mi.numberParallel;
10013 
10014  // initial conditions on gate node
10015  // Extra term for initial conditions on Vgs in operating point
10016  if( getSolverState().dcopFlag && mi.icVGSGiven )
10017  {
10018  dFdx[mi.li_Gate][mi.AGateEquIgsOffset] += 1.0;
10019  }
10020 
10021  // Row corresponding to the KCL for the bulk node:
10022 
10023  dFdx [mi.li_Bulk][mi.ABulkEquGateNodeOffset]
10024  += (- mi.gbgs)*mi.numberParallel;
10025 
10026 
10027  dFdx [mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
10028  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
10029 
10030 
10032  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
10033 
10034 
10036  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
10037 
10038  // Extra term for initial conditions on Vbs in operating point
10039  if( getSolverState().dcopFlag && mi.icVBSGiven )
10040  {
10041  dFdx[mi.li_Bulk][mi.ABulkEquIbsOffset] += 1.0;
10042  }
10043 
10044  // Row corresponding to the KCL for the drain prime node:
10045 
10048 
10049 
10051  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
10052  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
10053 
10054 
10056  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
10057  *mi.numberParallel;
10058 
10059 
10061  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
10062  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
10063 
10064 
10066  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
10067  *mi.numberParallel;
10068 
10069  // Row corresponding to the KCL for the source prime node:
10070 
10072  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
10073  *mi.numberParallel;
10074 
10075 
10077  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
10078  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
10079 
10080 
10083 
10084 
10086  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
10087  *mi.numberParallel;
10088 
10089 
10091  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
10092  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
10093 
10094  // Row associated with the charge equation
10095  if (mi.nqsMod)
10096  {
10097  std::string msg;
10098  msg = "Master::loadDAEMatrices";
10099  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10100  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10101  }
10102 
10103  // Initial condition rows
10104  // Row associated with mi.icVBS
10105  if( mi.icVBSGiven )
10106  {
10107  if( getSolverState().dcopFlag )
10108  {
10109  dFdx[mi.li_Ibs][mi.icVBSEquVbOffset] += 1.0;
10110  dFdx[mi.li_Ibs][mi.icVBSEquVsOffset] -= 1.0;
10111  }
10112  else
10113  {
10114  dFdx[mi.li_Ibs][mi.icVBSEquIbsOffset] += 1.0;
10115  }
10116  }
10117 
10118  // Row associated with mi.icVDS
10119  if( mi.icVDSGiven )
10120  {
10121  if( getSolverState().dcopFlag )
10122  {
10123  dFdx[mi.li_Ids][mi.icVDSEquVdOffset] += 1.0;
10124  dFdx[mi.li_Ids][mi.icVDSEquVsOffset] -= 1.0;
10125  }
10126  else
10127  {
10128  dFdx[mi.li_Ids][mi.icVDSEquIdsOffset] += 1.0;
10129  }
10130  }
10131 
10132  // Row associated with mi.icVGS
10133  if( mi.icVGSGiven )
10134  {
10135  if( getSolverState().dcopFlag )
10136  {
10137  dFdx[mi.li_Igs][mi.icVGSEquVgOffset] += 1.0;
10138  dFdx[mi.li_Igs][mi.icVGSEquVsOffset] -= 1.0;
10139  }
10140  else
10141  {
10142  dFdx[mi.li_Igs][mi.icVGSEquIgsOffset] += 1.0;
10143  }
10144  }
10145 
10146 
10147  // Q-matrix:
10148  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag && getSolverState().newtonIter==0)
10149  {
10150  // do nothing, as for this special case q is always zero.
10151  }
10152  else
10153  {
10154  // Row corresponding to the KCL for the drain node: NOTHING
10155 
10156  // Row corresponding to the KCL for the source node: NOTHING
10157 
10158  // Row corresponding to the KCL for the gate node:
10159  // Check this later. ERK. See the comments in the function
10160  // loadDAEdQdx, regarding ggtg, ggtb, etc.
10161  //
10162  // For now I am leaving out the gg terms, as they are zero when
10163  // nqsMod=0, which is always true.
10164  //
10165  dQdx[mi.li_Gate][mi.AGateEquGateNodeOffset]
10166  += (mi.CAPcggb )*mi.numberParallel;
10167  dQdx[mi.li_Gate][mi.AGateEquBulkNodeOffset]
10168  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
10170  += (mi.CAPcgdb )*mi.numberParallel;
10172  += (mi.CAPcgsb )*mi.numberParallel;
10173 
10174  // Row corresponding to the KCL for the bulk node:
10175  dQdx[mi.li_Bulk][mi.ABulkEquGateNodeOffset]
10176  += (mi.CAPcbgb)*mi.numberParallel;
10177 
10178  dQdx[mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
10179  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
10180 
10182  += (mi.CAPcbdb)*mi.numberParallel;
10183 
10185  += (mi.CAPcbsb)*mi.numberParallel;
10186 
10187 
10188  // Row corresponding to the KCL for the drain prime node:
10190  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
10191 
10193  += (mi.CAPcdgb) *mi.numberParallel;
10194 
10196  += (+ mi.CAPcddb )*mi.numberParallel;
10197 
10199  -= (- mi.CAPcdsb) *mi.numberParallel;
10200 
10201  // Row corresponding to the KCL for the source prime node:
10203  += (mi.CAPcsgb) *mi.numberParallel;
10204 
10206  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
10207 
10209  -= (- mi.CAPcsdb) *mi.numberParallel;
10210 
10212  += (+ mi.CAPcssb) *mi.numberParallel;
10213 
10214  // Row associated with the charge equation
10215  // This is currently not supported.
10216  if (mi.nqsMod)
10217  {
10218  std::string msg;
10219  msg = "Master::loadDAEMatrices";
10220  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10221  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10222  }
10223  }
10224  }
10225  return true;
10226  }
10227 #endif
10228 
10229  Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
10230  {
10231 
10232  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
10233  }
10234 
10236  {
10238  .registerDevice("m", 9)
10239  .registerDevice("m", 49)
10240  .registerModelType("pmos", 9)
10241  .registerModelType("nmos", 9)
10242  .registerModelType("pmos", 49)
10243  .registerModelType("nmos", 49);
10244  }
10245 
10246 } // namespace MOSFET_B3
10247 } // namespace Device
10248 } // namespace Xyce
10249