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