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.397.2.1 $
43 //
44 //
45 // Current Owner : $Author: erkeite $
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  // Set any non-constant parameter defaults:
2260  if (!given("TEMP"))
2261  temp = getDeviceOptions().temp.getImmutableValue<double>();
2262  if (!given("L"))
2263  l =model_.model_l;
2264  if (!given("W"))
2265  w = model_.model_w;
2266  if (!given("AD"))
2268  if (!given("AS"))
2270 
2271 
2272  // process source/drain series resistance
2274 
2275  if (drainConductance > 0.0)
2277  else
2278  drainConductance = 0.0;
2279 
2281 
2282  if (sourceConductance > 0.0)
2284  else
2285  sourceConductance = 0.0;
2286 
2287  if (given("NQSMOD"))
2288  {
2289  std::string msg = "Instance::Instance";
2290  msg += " nsqMod = 1. Not allowed yet. Setting to 0.\n";
2291  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
2292  nqsMod = 0;
2293  }
2294 
2295  if (getDeviceOptions().verboseLevel > 0 && (l > model_.Lmax || l < model_.Lmin))
2296  {
2297  UserWarning(*this) << "Channel length out of range";
2298  }
2299 
2300  if (getDeviceOptions().verboseLevel > 0 && (w > model_.Wmax || w < model_.Wmin))
2301  {
2302  UserWarning(*this) << "Channel width out of range";
2303  }
2304 
2305  // If there are any time dependent parameters, set their values at for
2306  // the current time.
2307 
2308  // now set the temperature related stuff.
2310 
2311  return true;
2312 }
2313 
2314 //-----------------------------------------------------------------------------
2315 // Function : Instance::Instance
2316 // Purpose : instance block constructor
2317 // Special Notes :
2318 // Scope : public
2319 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
2320 // Creation Date : 11/14/00
2321 //-----------------------------------------------------------------------------
2323  const Configuration & configuration,
2324  const InstanceBlock & IB,
2325  Model &model,
2326  const FactoryBlock & factory_block)
2327  : DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
2328  model_ (model),
2329  dNode (0),
2330  gNode (0),
2331  sNode (0),
2332  bNode (0),
2333  dNodePrime (0),
2334  sNodePrime (0),
2335  qNode (0),
2336  ueff (0.0),
2337  thetavth (0.0),
2338  von (0.0),
2339  vdsat (0.0),
2340  cgdo (0.0),
2341  cgso (0.0),
2342  vjsm (0.0),
2343  IsEvjsm (0.0),
2344  vjdm (0.0),
2345  IsEvjdm (0.0),
2346  l (getDeviceOptions().defl),
2347  w (getDeviceOptions().defw),
2348  drainArea (getDeviceOptions().defad),
2349  sourceArea (getDeviceOptions().defas),
2350  drainSquares (1.0),
2351  sourceSquares (1.0),
2352  drainPerimeter (0.0),
2353  sourcePerimeter (0.0),
2354  sourceConductance (0.0),
2355  drainConductance (0.0),
2356  icVBS (0.0),
2357  icVDS (0.0),
2358  icVGS (0.0),
2359  OFF (false),
2360  mode (0),
2361  nqsMod (0),
2362  numberParallel (1.0),
2363  qinv (0.0),
2364  cd (0.0),
2365  cbs (0.0),
2366  cbd (0.0),
2367  csub (0.0),
2368  cdrain (0.0),
2369  gm (0.0),
2370  gds (0.0),
2371  gmbs (0.0),
2372  gbd (0.0),
2373  gbs (0.0),
2374  gbbs (0.0),
2375  gbgs (0.0),
2376  gbds (0.0),
2377  cggb (0.0),
2378  cgdb (0.0),
2379  cgsb (0.0),
2380  cbgb (0.0),
2381  cbdb (0.0),
2382  cbsb (0.0),
2383  cdgb (0.0),
2384  cddb (0.0),
2385  cdsb (0.0),
2386  capbd (0.0),
2387  capbs (0.0),
2388  cqgb (0.0),
2389  cqdb (0.0),
2390  cqsb (0.0),
2391  cqbb (0.0),
2392  qgate (0.0),
2393  qbulk (0.0),
2394  qdrn (0.0),
2395  gtau (0.0),
2396  gtg (0.0),
2397  gtd (0.0),
2398  gts (0.0),
2399  gtb (0.0),
2400  rds (0.0),
2401  Vgsteff (0.0),
2402  Vdseff (0.0),
2403  Abulk (0.0),
2404  AbovVgst2Vtm (0.0),
2405  limitedFlag (false),
2406  paramPtr (NULL),
2407  icVBSGiven (0),
2408  icVDSGiven (0),
2409  icVGSGiven (0),
2410  temp (getDeviceOptions().temp.getImmutableValue<double>()),
2411  ChargeComputationNeeded (true),
2412  gcbdb (0.0),
2413  gcbgb (0.0),
2414  gcbsb (0.0),
2415  gcddb (0.0),
2416  gcdgb (0.0),
2417  gcdsb (0.0),
2418  gcgdb (0.0),
2419  gcggb (0.0),
2420  gcgsb (0.0),
2421  gcsdb (0.0),
2422  gcsgb (0.0),
2423  gcssb (0.0),
2424  qgd (0.0),
2425  qgs (0.0),
2426  qgb (0.0),
2427  qgdo (0.0),
2428  qgso (0.0),
2429  qsrc (0.0),
2430  CoxWL (0.0),
2431  Cgg (0.0),
2432  Cgd (0.0),
2433  Cgb (0.0),
2434  Cdg (0.0),
2435  Cdd (0.0),
2436  Cds (0.0),
2437  Csg (0.0),
2438  Csd (0.0),
2439  Css (0.0),
2440  Csb (0.0),
2441  Cbg (0.0),
2442  Cbd (0.0),
2443  Cbb (0.0),
2444  CAPcggb (0.0),
2445  CAPcgdb (0.0),
2446  CAPcgsb (0.0),
2447  CAPcbgb (0.0),
2448  CAPcbdb (0.0),
2449  CAPcbsb (0.0),
2450  CAPcdgb (0.0),
2451  CAPcddb (0.0),
2452  CAPcdsb (0.0),
2453  CAPcsgb (0.0),
2454  CAPcsdb (0.0),
2455  CAPcssb (0.0),
2456  Qeqqd_Jdxp (0.0),
2457  Qeqqb_Jdxp (0.0),
2458  Qeqqg_Jdxp (0.0),
2459  dxpart (0.0),
2460  sxpart (0.0),
2461  ggtg (0.0),
2462  ggtd (0.0),
2463  ggts (0.0),
2464  ggtb (0.0),
2465  ddxpart_dVd (0.0),
2466  ddxpart_dVg (0.0),
2467  ddxpart_dVb (0.0),
2468  ddxpart_dVs (0.0),
2469  dsxpart_dVd (0.0),
2470  dsxpart_dVg (0.0),
2471  dsxpart_dVb (0.0),
2472  dsxpart_dVs (0.0),
2473  gbspsp (0.0),
2474  gbbdp (0.0),
2475  gbbsp (0.0),
2476  gbspg (0.0),
2477  gbspb (0.0),
2478  gbspdp (0.0),
2479  gbdpdp (0.0),
2480  gbdpg (0.0),
2481  gbdpb (0.0),
2482  gbdpsp (0.0),
2483  cdreq (0.0),
2484  ceqbd (0.0),
2485  ceqbs (0.0),
2486  Gm (0.0),
2487  Gmbs (0.0),
2488  FwdSum (0.0),
2489  RevSum (0.0),
2490  T1global (0.0),
2491  dVgst_dVg (0.0),
2492  dVgst_dVb (0.0),
2493  dVgs_eff_dVg (0.0),
2494  dDeltaPhi_dVg (0.0),
2495  dDeltaPhi_dVd (0.0),
2496  dDeltaPhi_dVb (0.0),
2497  vtm (0.0),
2498  jctTempSatCurDensity (0.0),
2499  jctSidewallTempSatCurDensity (0.0),
2500  unitAreaJctCapTemp (0.0),
2501  unitLengthSidewallJctCapTemp (0.0),
2502  unitLengthGateSidewallJctCapTemp (0.0),
2503  PhiBTemp (0.0),
2504  PhiBSWTemp (0.0),
2505  PhiBSWGTemp (0.0),
2506  Vd (0.0),
2507  Vs (0.0),
2508  Vg (0.0),
2509  Vb (0.0),
2510  Vsp (0.0),
2511  Vdp (0.0),
2512  Qtotal (0.0),
2513  Vddp (0.0),
2514  Vssp (0.0),
2515  Vbsp (0.0),
2516  Vbdp (0.0),
2517  Vgsp (0.0),
2518  Vgdp (0.0),
2519  Vgb (0.0),
2520  Vdpsp (0.0),
2521  Idrain (0.0),
2522  Isource (0.0),
2523  df1dVdp (0.0),
2524  df2dVdp (0.0),
2525  df1dVsp (0.0),
2526  df2dVsp (0.0),
2527  df1dVg (0.0),
2528  df2dVg (0.0),
2529  df1dVb (0.0),
2530  df2dVb (0.0),
2531  vbd_old (0.0),
2532  vbs_old (0.0),
2533  vgs_old (0.0),
2534  vds_old (0.0),
2535  vgs_orig (0.0),
2536  vds_orig (0.0),
2537  vbs_orig (0.0),
2538  vbd_orig (0.0),
2539  vgd_orig (0.0),
2540  cqdef (0.0),
2541  vgb (0.0),
2542  vgd (0.0),
2543  vbd (0.0),
2544  vbs (0.0),
2545  vgs (0.0),
2546  vds (0.0),
2547  qb (0.0),
2548  qg (0.0),
2549  qd (0.0),
2550  qbs (0.0),
2551  qbd (0.0),
2552  qcheq (0.0),
2553  qcdump (0.0),
2554  qdef (0.0),
2555  gqdef (0.0),
2556  gcqdb (0.0),
2557  gcqsb (0.0),
2558  gcqgb (0.0),
2559  gcqbb (0.0),
2560  ScalingFactor (0.0),
2561  cqgate (0.0),
2562  cqbulk (0.0),
2563  cqdrn (0.0),
2564  cdreq_Jdxp (0.0),
2565  ceqbd_Jdxp (0.0),
2566  ceqbs_Jdxp (0.0),
2567  cqdef_Jdxp (0.0),
2568  ceqqd_Jdxp (0.0),
2569  ceqqb_Jdxp (0.0),
2570  ceqqg_Jdxp (0.0),
2571 // matrix and vectors indices:
2572 // state vector: (local indices)
2573  li_store_vbd (-1),
2574  li_store_vbs (-1),
2575  li_store_vgs (-1),
2576  li_store_vds (-1),
2577  li_store_von (-1),
2578  li_store_dev_id (-1),
2579  li_store_dev_is (-1),
2580  li_store_dev_ig (-1),
2581  li_store_dev_ib (-1),
2582  li_state_qb (-1),
2583  li_state_qg (-1),
2584  li_state_qd (-1),
2585  li_state_qbs (-1),
2586  li_state_qbd (-1),
2587  li_state_qcheq (-1),
2588  li_state_qcdump (-1),
2589  li_state_qdef (-1),
2590 // solution vector: (local indices)
2591  li_Drain (-1),
2592  li_Gate (-1),
2593  li_Source (-1),
2594  li_Bulk (-1),
2595  li_DrainPrime (-1),
2596  li_SourcePrime (-1),
2597  li_Charge (-1),
2598  li_Ibs (-1),
2599  li_Ids (-1),
2600  li_Igs (-1),
2601 // matrix offsets:
2602 // jacobian:
2603 // drain row
2604  ADrainEquDrainNodeOffset (-1),
2605  ADrainEquDrainPrimeNodeOffset (-1),
2606  ADrainEquIdsOffset (-1),
2607 // gate row
2608  AGateEquGateNodeOffset (-1),
2609  AGateEquBulkNodeOffset (-1),
2610  AGateEquDrainPrimeNodeOffset (-1),
2611  AGateEquSourcePrimeNodeOffset (-1),
2612  AGateEquChargeVarOffset (-1),
2613  AGateEquIgsOffset (-1),
2614 // source row
2615  ASourceEquSourceNodeOffset (-1),
2616  ASourceEquSourcePrimeNodeOffset (-1),
2617  ASourceEquIbsOffset (-1),
2618  ASourceEquIdsOffset (-1),
2619  ASourceEquIgsOffset (-1),
2620 // bulk row
2621  ABulkEquGateNodeOffset (-1),
2622  ABulkEquBulkNodeOffset (-1),
2623  ABulkEquDrainPrimeNodeOffset (-1),
2624  ABulkEquSourcePrimeNodeOffset (-1),
2625  ABulkEquChargeVarOffset (-1),
2626  ABulkEquIbsOffset (-1),
2627 // drain' row
2628  ADrainPrimeEquDrainNodeOffset (-1),
2629  ADrainPrimeEquGateNodeOffset (-1),
2630  ADrainPrimeEquBulkNodeOffset (-1),
2631  ADrainPrimeEquDrainPrimeNodeOffset (-1),
2632  ADrainPrimeEquSourcePrimeNodeOffset (-1),
2633  ADrainPrimeEquChargeVarOffset (-1),
2634 // source' row
2635  ASourcePrimeEquGateNodeOffset (-1),
2636  ASourcePrimeEquSourceNodeOffset (-1),
2637  ASourcePrimeEquBulkNodeOffset (-1),
2638  ASourcePrimeEquDrainPrimeNodeOffset (-1),
2639  ASourcePrimeEquSourcePrimeNodeOffset (-1),
2640  ASourcePrimeEquChargeVarOffset (-1),
2641 // Charge row
2642  AChargeEquChargeVarOffset (-1),
2643  AChargeEquDrainPrimeNodeOffset (-1),
2644  AChargeEquGateNodeOffset (-1),
2645  AChargeEquSourcePrimeNodeOffset (-1),
2646  AChargeEquBulkNodeOffset (-1),
2647  icVBSEquVsOffset (-1),
2648  icVBSEquVbOffset (-1),
2649  icVBSEquIbsOffset (-1),
2650  icVDSEquVdOffset (-1),
2651  icVDSEquVsOffset (-1),
2652  icVDSEquIdsOffset (-1),
2653  icVGSEquVgOffset (-1),
2654  icVGSEquVsOffset (-1),
2655  icVGSEquIgsOffset (-1),
2657 //
2658  // V_d Row:
2659  f_DrainEquDrainNodePtr(0), // a
2660  f_DrainEquDrainPrimeNodePtr(0), // b
2661  f_DrainEquIdsPtr(0), // i1
2662 
2663  // V_g Row:
2664  f_GateEquGateNodePtr(0), // c
2665  f_GateEquBulkNodePtr(0), // d
2666  f_GateEquDrainPrimeNodePtr(0), // e
2667  f_GateEquSourcePrimeNodePtr(0), // f
2668  f_GateEquChargeVarPtr(0), // 1
2669  f_GateEquIgsPtr(0), // i2
2670 
2671  // V_s Row:
2672  f_SourceEquSourceNodePtr(0), // g
2673  f_SourceEquSourcePrimeNodePtr(0), // h
2674  f_SourceEquIbsPtr(0), // i3
2675  f_SourceEquIdsPtr(0), // i4
2676  f_SourceEquIgsPtr(0), // i5
2677 
2678  // V_b Row:
2679  f_BulkEquGateNodePtr(0), // i
2680  f_BulkEquBulkNodePtr(0), // j
2681  f_BulkEquDrainPrimeNodePtr(0), // k
2682  f_BulkEquSourcePrimeNodePtr(0), // l
2683  f_BulkEquChargeVarPtr(0), // 2
2684  f_BulkEquIbsPtr(0), // i6
2685 
2686  // V_d' Row:
2687  f_DrainPrimeEquDrainNodePtr(0), // m
2688  f_DrainPrimeEquGateNodePtr(0), // n
2689  f_DrainPrimeEquBulkNodePtr(0), // o
2690  f_DrainPrimeEquDrainPrimeNodePtr(0), // p
2691  f_DrainPrimeEquSourcePrimeNodePtr(0), // q
2692  f_DrainPrimeEquChargeVarPtr(0), // 3
2693 
2694  // V_s' Row:
2695  f_SourcePrimeEquGateNodePtr(0), // r
2696  f_SourcePrimeEquSourceNodePtr(0), // s
2697  f_SourcePrimeEquBulkNodePtr(0), // t
2698  f_SourcePrimeEquDrainPrimeNodePtr(0), // u
2699  f_SourcePrimeEquSourcePrimeNodePtr(0), // v
2700  f_SourcePrimeEquChargeVarPtr(0), // 4
2701 
2702  // MOSFET charge (Q) Row:
2703  f_ChargeEquChargeVarPtr(0), // 5
2704  f_ChargeEquDrainPrimeNodePtr(0), // 6
2705  f_ChargeEquGateNodePtr(0), // 7
2706  f_ChargeEquSourcePrimeNodePtr(0), // 8
2707  f_ChargeEquBulkNodePtr(0), // 9
2708 
2709  // icVBS
2710  f_icVBSEquVsPtr(0), // i7
2711  f_icVBSEquVbPtr(0), // i8
2712  f_icVBSEquIbsPtr(0), // i9
2713 
2714  // icVDS
2715  f_icVDSEquVdPtr(0), // i10
2716  f_icVDSEquVsPtr(0), // i11
2717  f_icVDSEquIdsPtr(0), // i12
2718 
2719  // icVGS
2720  f_icVGSEquVgPtr(0), // i13
2721  f_icVGSEquVsPtr(0), // i14
2722  f_icVGSEquIgsPtr(0), // i15
2723 
2724  // V_d Row:
2725  q_DrainEquDrainNodePtr(0), // a
2726  q_DrainEquDrainPrimeNodePtr(0), // b
2727  q_DrainEquIdsPtr(0), // i1
2728 
2729  // V_g Row:
2730  q_GateEquGateNodePtr(0), // c
2731  q_GateEquBulkNodePtr(0), // d
2732  q_GateEquDrainPrimeNodePtr(0), // e
2733  q_GateEquSourcePrimeNodePtr(0), // f
2734  q_GateEquChargeVarPtr(0), // 1
2735  q_GateEquIgsPtr(0), // i2
2736 
2737  // V_s Row:
2738  q_SourceEquSourceNodePtr(0), // g
2739  q_SourceEquSourcePrimeNodePtr(0), // h
2740  q_SourceEquIbsPtr(0), // i3
2741  q_SourceEquIdsPtr(0), // i4
2742  q_SourceEquIgsPtr(0), // i5
2743 
2744  // V_b Row:
2745  q_BulkEquGateNodePtr(0), // i
2746  q_BulkEquBulkNodePtr(0), // j
2747  q_BulkEquDrainPrimeNodePtr(0), // k
2748  q_BulkEquSourcePrimeNodePtr(0), // l
2749  q_BulkEquChargeVarPtr(0), // 2
2750  q_BulkEquIbsPtr(0), // i6
2751 
2752  // V_d' Row:
2753  q_DrainPrimeEquDrainNodePtr(0), // m
2754  q_DrainPrimeEquGateNodePtr(0), // n
2755  q_DrainPrimeEquBulkNodePtr(0), // o
2756  q_DrainPrimeEquDrainPrimeNodePtr(0), // p
2757  q_DrainPrimeEquSourcePrimeNodePtr(0), // q
2758  q_DrainPrimeEquChargeVarPtr(0), // 3
2759 
2760  // V_s' Row:
2761  q_SourcePrimeEquGateNodePtr(0), // r
2762  q_SourcePrimeEquSourceNodePtr(0), // s
2763  q_SourcePrimeEquBulkNodePtr(0), // t
2764  q_SourcePrimeEquDrainPrimeNodePtr(0), // u
2765  q_SourcePrimeEquSourcePrimeNodePtr(0), // v
2766  q_SourcePrimeEquChargeVarPtr(0), // 4
2767 
2768  // MOSFET charge (Q) Row:
2769  q_ChargeEquChargeVarPtr(0), // 5
2770  q_ChargeEquDrainPrimeNodePtr(0), // 6
2771  q_ChargeEquGateNodePtr(0), // 7
2772  q_ChargeEquSourcePrimeNodePtr(0), // 8
2773  q_ChargeEquBulkNodePtr(0), // 9
2774 
2775  // icVBS
2776  q_icVBSEquVsPtr(0), // i7
2777  q_icVBSEquVbPtr(0), // i8
2778  q_icVBSEquIbsPtr(0), // i9
2779 
2780  // icVDS
2781  q_icVDSEquVdPtr(0), // i10
2782  q_icVDSEquVsPtr(0), // i11
2783  q_icVDSEquIdsPtr(0), // i12
2784 
2785  // icVGS
2786  q_icVGSEquVgPtr(0), // i13
2787  q_icVGSEquVsPtr(0), // i14
2788  q_icVGSEquIgsPtr(0), // i15
2789 //
2790 #endif
2791  blockHomotopyID (0),
2792  randomPerturb (0.0),
2793  // one last thing
2794  updateTemperatureCalled_ (false)
2795 {
2796  numIntVars = 3;
2797  numExtVars = 4;
2798  numStateVars = 12;
2799  setNumStoreVars(5);
2800  numLeadCurrentStoreVars = 4; // drain, gate, source & base lead currents
2801 
2802  devConMap.resize(4);
2803  devConMap[0] = 1;
2804  devConMap[1] = 2;
2805  devConMap[2] = 1;
2806  devConMap[3] = 3;
2807 
2808  blockHomotopyID =
2809  devSupport.getGainScaleBlockID(getDeviceOptions().numGainScaleBlocks);
2810  randomPerturb =
2812 
2813 
2814  if( jacStamp.empty() )
2815  {
2816  jacStamp_DC_SC.resize(6);
2817  jacStamp_DC_SC[0].resize(2);
2818  jacStamp_DC_SC[0][0]=0;
2819  jacStamp_DC_SC[0][1]=4;
2820  jacStamp_DC_SC[1].resize(4);
2821  jacStamp_DC_SC[1][0]=1;
2822  jacStamp_DC_SC[1][1]=3;
2823  jacStamp_DC_SC[1][2]=4;
2824  jacStamp_DC_SC[1][3]=5;
2825  jacStamp_DC_SC[2].resize(2);
2826  jacStamp_DC_SC[2][0]=2;
2827  jacStamp_DC_SC[2][1]=5;
2828  jacStamp_DC_SC[3].resize(4);
2829  jacStamp_DC_SC[3][0]=1;
2830  jacStamp_DC_SC[3][1]=3;
2831  jacStamp_DC_SC[3][2]=4;
2832  jacStamp_DC_SC[3][3]=5;
2833  jacStamp_DC_SC[4].resize(5);
2834  jacStamp_DC_SC[4][0]=0;
2835  jacStamp_DC_SC[4][1]=1;
2836  jacStamp_DC_SC[4][2]=3;
2837  jacStamp_DC_SC[4][3]=4;
2838  jacStamp_DC_SC[4][4]=5;
2839  jacStamp_DC_SC[5].resize(5);
2840  jacStamp_DC_SC[5][0]=1;
2841  jacStamp_DC_SC[5][1]=2;
2842  jacStamp_DC_SC[5][2]=3;
2843  jacStamp_DC_SC[5][3]=4;
2844  jacStamp_DC_SC[5][4]=5;
2845 
2846  jacMap_DC_SC.clear();
2848  jacStamp_DC, jacMap_DC, jacMap2_DC, 5, 2, 6);
2849 
2851  jacStamp_SC, jacMap_SC, jacMap2_SC, 4, 0, 6);
2852 
2854  jacStamp, jacMap, jacMap2, 4, 0, 6);
2855 
2856  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
2857  {
2858  Xyce::dout() << "Instance::Instance jacStampMap_DS_SC" << std::endl;
2859  for (int k = 0; k<jacMap_DC_SC.size(); ++k )
2860  {
2861  Xyce::dout() << "jacStamp_DC_SC[ " << jacMap_DC_SC[k] << " ] = { ";
2862  for (int q = 0; q < jacMap2_DC_SC[k].size(); ++q )
2863  {
2864  Xyce::dout() << jacStamp_DC_SC[jacMap_DC_SC[k]][jacMap2_DC_SC[k][q]] << " ";
2865  }
2866  Xyce::dout() << "}" << std::endl;
2867  }
2868 
2869  Xyce::dout() << "Instance::Instance jacStampMap_DS" << std::endl;
2870  for (int k = 0; k<jacMap_DC.size(); ++k )
2871  {
2872  Xyce::dout() << "jacStamp_DC[ " << jacMap_DC[k] << " ] = { ";
2873  for (int q = 0; q < jacMap2_DC[k].size(); ++q )
2874  {
2875  Xyce::dout() << jacStamp_DC[jacMap_DC[k]][jacMap2_DC[k][q]] << " ";
2876  }
2877  Xyce::dout() << "}" << std::endl;
2878  }
2879 
2880  Xyce::dout() << "Instance::Instance jacStampMap_SC" << std::endl;
2881  for (int k = 0; k<jacMap_SC.size(); ++k )
2882  {
2883  Xyce::dout() << "jacStamp_SC[ " << jacMap_SC[k] << " ] = { ";
2884  for (int q = 0; q < jacMap2_SC[k].size(); ++q )
2885  {
2886  Xyce::dout() << jacStamp_SC[jacMap_SC[k]][jacMap2_SC[k][q]] << " ";
2887  }
2888  Xyce::dout() << "}" << std::endl;
2889  }
2890 
2891  Xyce::dout() << "Instance::Instance jacStampMap" << std::endl;
2892  for (int k = 0; k<jacMap.size(); ++k )
2893  {
2894  Xyce::dout() << "jacStamp[ " << jacMap[k] << " ] = { ";
2895  for (int q = 0; q < jacMap2[k].size(); ++q )
2896  {
2897  Xyce::dout() << jacStamp[jacMap[k]][jacMap2[k][q]] << " ";
2898  }
2899  Xyce::dout() << "}" << std::endl;
2900  }
2901  }
2902  }
2903 
2904  // Set params to constant default values:
2905  setDefaultParams ();
2906 
2907  // Set params according to instance line and constant defaults from metadata:
2908  setParams (IB.params);
2909 
2910  // Calculate any parameters specified as expressions:
2912 
2913  // calculate dependent (ie computed) params and check for errors:
2914  processParams ();
2915 
2916  numIntVars = 0;
2917  if ( sourceConductance!=0.0 ) ++numIntVars;
2918  if ( drainConductance!=0.0 ) ++numIntVars;
2919  if ( nqsMod ) ++numIntVars;
2920 
2921  if (icVDSGiven) ++numIntVars;
2922  if (icVGSGiven) ++numIntVars;
2923  if (icVBSGiven) ++numIntVars;
2924 
2925 
2926  // if we need to, build the jacobian stamp and operating point
2927  // jacobian stamp specificly needed for this device's initial
2928  // conditions
2929 
2930  // There are 4 optional internal variables that may be included in
2931  // this device: charge Q, Vbs, Vds and Vgs. We need to assign these
2932  // variables to columns in our jacobian depending on what's there.
2933  // For example if they're all required than Q is the 7th variable
2934  // and goes in column 6 (numbering from zero), Vbs is 8th in column
2935  // 7, Vds is 9th in column, Vgs is 10th in column 9. If any
2936  // variable is not needed, those in higher columns shift
2937  // down. I.e. if Q isn't needed, then Vbs is in column 6, Vds in
2938  // column 7 and Vgs in column 8.
2939 
2940  int currentCol = 6;
2941  int numExtraCol = 0;
2942  int qCol = -1, icVBSCol = -1, icVDSCol = -1, icVGSCol = -1;
2943  if( nqsMod )
2944  {
2945  qCol = currentCol;
2946  ++currentCol;
2947  ++numExtraCol;
2948  }
2949  if( icVBSGiven )
2950  {
2951  icVBSCol = currentCol;
2952  ++currentCol;
2953  ++numExtraCol;
2954  }
2955  if( icVDSGiven )
2956  {
2957  icVDSCol = currentCol;
2958  ++currentCol;
2959  ++numExtraCol;
2960  }
2961  if( icVGSGiven )
2962  {
2963  icVGSCol = currentCol;
2964  ++currentCol;
2965  ++numExtraCol;
2966  }
2967 
2968  // ok now build this instance's jacobian stamp
2969  if( nqsMod || icVBSGiven || icVDSGiven || icVGSGiven )
2970  {
2971  // we need a special version of the jacStamp for the
2972  jacStampSpecial.resize(6 + numExtraCol);
2973  // row KCL d
2974  int numNonZeros = 2 + (icVDSGiven ? 1:0);
2975  jacStampSpecial[0].resize( numNonZeros );
2976  jacStampSpecial[0][0]=0;
2977  jacStampSpecial[0][1]=4;
2978  currentCol = 2;
2979  if( icVDSGiven )
2980  {
2981  jacStampSpecial[0][currentCol]=icVDSCol;
2982  ++currentCol;
2983  }
2984 
2985  // row KCL g
2986  numNonZeros = 4 + (nqsMod ? 1:0 ) + (icVGSGiven ? 1:0);
2987  jacStampSpecial[1].resize( numNonZeros );
2988  jacStampSpecial[1][0]=1;
2989  jacStampSpecial[1][1]=3;
2990  jacStampSpecial[1][2]=4;
2991  jacStampSpecial[1][3]=5;
2992  currentCol = 4;
2993  if( nqsMod )
2994  {
2995  jacStampSpecial[1][currentCol]=qCol;
2996  ++currentCol;
2997  }
2998  if( icVGSGiven )
2999  {
3000  jacStampSpecial[1][currentCol]=icVGSCol;
3001  }
3002 
3003  // row KCL s
3004  numNonZeros = 2 + (icVBSGiven ? 1:0) + (icVDSGiven ? 1:0) + (icVGSGiven ? 1:0);
3005  jacStampSpecial[2].resize( numNonZeros );
3006  jacStampSpecial[2][0]=2;
3007  jacStampSpecial[2][1]=5;
3008  currentCol = 2;
3009  if ( icVBSGiven )
3010  {
3011  jacStampSpecial[2][currentCol] = icVBSCol;
3012  ++currentCol;
3013  }
3014  if( icVDSGiven )
3015  {
3016  jacStampSpecial[2][currentCol] = icVDSCol;
3017  ++currentCol;
3018  }
3019  if( icVGSGiven )
3020  {
3021  jacStampSpecial[2][currentCol] = icVGSCol;
3022  ++currentCol;
3023  }
3024 
3025  // row KCL b
3026  numNonZeros = 4 + (nqsMod ? 1:0 ) + (icVBSGiven ? 1:0);
3027  jacStampSpecial[3].resize( numNonZeros );
3028  jacStampSpecial[3][0]=1;
3029  jacStampSpecial[3][1]=3;
3030  jacStampSpecial[3][2]=4;
3031  jacStampSpecial[3][3]=5;
3032  currentCol = 4;
3033  if( nqsMod )
3034  {
3035  jacStampSpecial[3][currentCol] = qCol;
3036  ++currentCol;
3037  }
3038  if( icVBSGiven )
3039  {
3040  jacStampSpecial[3][currentCol] = icVBSCol;
3041  ++currentCol;
3042  }
3043 
3044  // row KCL d'
3045  numNonZeros = 5 + (nqsMod ? 1:0 );
3046  jacStampSpecial[4].resize( numNonZeros );
3047  jacStampSpecial[4][0]=0;
3048  jacStampSpecial[4][1]=1;
3049  jacStampSpecial[4][2]=3;
3050  jacStampSpecial[4][3]=4;
3051  jacStampSpecial[4][4]=5;
3052  currentCol = 5;
3053  if( nqsMod )
3054  {
3055  jacStampSpecial[4][currentCol] = qCol;
3056  ++currentCol;
3057  }
3058 
3059  // row KCL s'
3060  numNonZeros = 5 + (nqsMod ? 1:0 );
3061  jacStampSpecial[5].resize( numNonZeros );
3062  jacStampSpecial[5][0]=1;
3063  jacStampSpecial[5][1]=2;
3064  jacStampSpecial[5][2]=3;
3065  jacStampSpecial[5][3]=4;
3066  jacStampSpecial[5][4]=5;
3067  currentCol = 5;
3068  if( nqsMod )
3069  {
3070  jacStampSpecial[5][currentCol] = qCol;
3071  ++currentCol;
3072  }
3073 
3074  int currentRow = 6;
3075 
3076  // Q row if we need it
3077  if( nqsMod )
3078  {
3079  // add in charge row
3080  jacStampSpecial[currentRow].resize( 5 );
3081  jacStampSpecial[currentRow][0] = 1;
3082  jacStampSpecial[currentRow][1] = 3;
3083  jacStampSpecial[currentRow][2] = 4;
3084  jacStampSpecial[currentRow][3] = 5;
3085  jacStampSpecial[currentRow][4] = qCol;
3086  ++currentRow;
3087  }
3088 
3089  // icVBS row if we need it
3090  if( icVBSGiven )
3091  {
3092  jacStampSpecial[currentRow].resize( 3 );
3093  jacStampSpecial[currentRow][0] = 2;
3094  jacStampSpecial[currentRow][1] = 3;
3095  jacStampSpecial[currentRow][2] = icVBSCol;
3096  ++currentRow;
3097  }
3098 
3099  // icVDS row if we need it
3100  if( icVDSGiven )
3101  {
3102  jacStampSpecial[currentRow].resize( 3 );
3103  jacStampSpecial[currentRow][0] = 0;
3104  jacStampSpecial[currentRow][1] = 2;
3105  jacStampSpecial[currentRow][2] = icVDSCol;
3106  ++currentRow;
3107  }
3108 
3109  // icVGS row if we need it
3110  if( icVGSGiven )
3111  {
3112  jacStampSpecial[currentRow].resize( 3 );
3113  jacStampSpecial[currentRow][0] = 1;
3114  jacStampSpecial[currentRow][1] = 2;
3115  jacStampSpecial[currentRow][2] = icVGSCol;
3116  ++currentRow;
3117  }
3118 
3119  // now we just need to merge Vd' and or Vs' nodes if that's called
3120  // for in this device
3121  if ( (drainConductance == 0.0) && (sourceConductance == 0.0) )
3122  {
3123  // temporary to hold intermediate results
3124  std::vector< std::vector<int> > jacStampSpecialMergedTemp;
3125  std::vector<int> jacSpecialMapTemp;
3126  std::vector< std::vector<int> > jacSpecialMapTemp2;
3127 
3129  jacStampSpecialMergedTemp, jacSpecialMapTemp, jacSpecialMapTemp2,
3130  5, 2, jacStampSpecial.size() );
3131 
3132  jacStampMap( jacStampSpecialMergedTemp, jacSpecialMapTemp, jacSpecialMapTemp2,
3134  4, 0, jacStampSpecial.size() );
3135 
3136  }
3137  else if (drainConductance == 0.0)
3138  {
3141  4, 0, jacStampSpecial.size() );
3142 
3143  }
3144  else if (sourceConductance == 0.0)
3145  {
3148  5, 2, jacStampSpecial.size() );
3149  }
3150  else
3151  {
3152  // no rows or columns were merged, but we need to initialize
3153  // jacSpecialMap and jacSpecialMap2 as these will be used to
3154  // index into the jacobian in registerJacLIDs()
3155  // copied from DeviceInstance::jacStampMap initialization
3156 
3157  if (jacSpecialMap.size() == 0)
3158  {
3159  jacSpecialMap.resize(jacStampSpecial.size());
3160  jacSpecialMap2.resize(jacStampSpecial.size());
3161  for (int i=0 ; i<jacStampSpecial.size() ; ++i)
3162  {
3163  jacSpecialMap[i] = i;
3164  jacSpecialMap2[i].resize(jacStampSpecial[i].size());
3165  for (int j=0 ; j<jacStampSpecial[i].size() ; ++j)
3166  {
3167  jacSpecialMap2[i][j] = j;
3168  }
3169  }
3170  }
3171  }
3172  }
3173  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3174  {
3175  Xyce::dout() << "Instance::Instance jacStampSpecial" << std::endl;
3176  for (int k = 0; k<jacSpecialMap.size(); ++k )
3177  {
3178  Xyce::dout() << "jacSpecialMap[" << jacSpecialMap[k] << " ] = { ";
3179  for (int q = 0; q < jacSpecialMap2[k].size(); ++q )
3180  {
3181  Xyce::dout() << jacStampSpecial[jacSpecialMap[k]][jacSpecialMap2[k][q]] <<" ";
3182  }
3183  Xyce::dout() << "}" << std::endl;
3184  }
3185 
3186  Xyce::dout() << "Instance::Instance jacStampSpecialMerged" << std::endl;
3187  for (int k = 0; k<jacSpecialMergedMap.size(); ++k )
3188  {
3189  Xyce::dout() << "jacSpecialMap[" << jacSpecialMergedMap[k] << " ] = { ";
3190  for (int q = 0; q < jacSpecialMergedMap2[k].size(); ++q )
3191  {
3192  Xyce::dout() << jacStampSpecialMerged[jacSpecialMergedMap[k]][jacSpecialMergedMap2[k][q]] <<" ";
3193  }
3194  Xyce::dout() << "}" << std::endl;
3195  }
3196  }
3197 }
3198 
3199 //-----------------------------------------------------------------------------
3200 // Function : Instance::~Instance
3201 // Purpose : destructor
3202 // Special Notes :
3203 // Scope : public
3204 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3205 // Creation Date : 11/14/00
3206 //-----------------------------------------------------------------------------
3208 {
3209 }
3210 
3211 //-----------------------------------------------------------------------------
3212 // Function : Instance::registerLIDs
3213 // Purpose :
3214 // Special Notes :
3215 // Scope : public
3216 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3217 // Creation Date : 6/21/02
3218 //-----------------------------------------------------------------------------
3219 void Instance::registerLIDs( const std::vector<int> & intLIDVecRef,
3220  const std::vector<int> & extLIDVecRef )
3221 {
3222  numIntVars = 0;
3223  if ( sourceConductance!=0.0 ) ++numIntVars;
3224  if ( drainConductance!=0.0 ) ++numIntVars;
3225  if ( nqsMod ) ++numIntVars;
3226  if (icVBSGiven) ++numIntVars;
3227  if (icVDSGiven) ++numIntVars;
3228  if (icVGSGiven) ++numIntVars;
3229 
3230  AssertLIDs(intLIDVecRef.size() == numIntVars);
3231  AssertLIDs(extLIDVecRef.size() == numExtVars);
3232 
3233  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3234  {
3235  Xyce::dout() << section_divider << std::endl;
3236  Xyce::dout() << " In Instance::register LIDs\n\n";
3237  Xyce::dout() << " name = " << getName() << std::endl;
3238  Xyce::dout() << " number of internal variables: " << numIntVars << std::endl;
3239  Xyce::dout() << " number of external variables: " << numExtVars << std::endl;
3240  }
3241 
3242  // copy over the global ID lists.
3243  intLIDVec = intLIDVecRef;
3244  extLIDVec = extLIDVecRef;
3245 
3246  // now use these lists to obtain the indices into the
3247  // linear algebra entities. This assumes an order.
3248  // For the matrix indices, first do the rows.
3249 
3250  li_Drain = extLIDVec[0];
3251  li_Gate = extLIDVec[1];
3252  li_Source = extLIDVec[2];
3253  li_Bulk = extLIDVec[3];
3254 
3255  int intLoc = 0;
3256 
3257  if( drainConductance != 0.0 )
3258  li_DrainPrime = intLIDVec[intLoc++];
3259  else
3261 
3262  if( sourceConductance != 0.0 )
3263  li_SourcePrime = intLIDVec[intLoc++];
3264  else
3266 
3267  if( nqsMod )
3268  li_Charge = intLIDVec[intLoc++];
3269 
3270  if( icVBSGiven )
3271  {
3272  if( li_Bulk == li_Source )
3273  {
3274  DevelFatal(*this).in("Instance::registerLIDs")
3275  << "Tried to specify an initial condition on V_Bulk_Source when Bulk and Source nodes are the same node";
3276  }
3277  li_Ibs = intLIDVec[intLoc++];
3278  }
3279 
3280  if( icVDSGiven )
3281  {
3282  if( li_Drain == li_Source )
3283  {
3284  DevelFatal(*this).in("Instance::registerLIDs")
3285  << "Tried to specify an initial condition on V_Drain_Source when Drain and Source nodes are the same node";
3286  }
3287  li_Ids = intLIDVec[intLoc++];
3288  }
3289 
3290  if( icVGSGiven )
3291  {
3292  if( li_Gate == li_Source )
3293  {
3294  DevelFatal(*this).in("Instance::registerLIDs")
3295  << "Tried to specify an initial condition on V_Gate_Source when Gate and Source nodes are the same node";
3296  }
3297  li_Igs = intLIDVec[intLoc++];
3298  }
3299 
3300  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3301  {
3302  Xyce::dout() << "\n local variable indices:\n";
3303  Xyce::dout() << " li_Drain = " << li_Drain << std::endl;
3304  Xyce::dout() << " li_Gate = " << li_Gate << std::endl;
3305  Xyce::dout() << " li_Source = " << li_Source << std::endl;
3306  Xyce::dout() << " li_Bulk = " << li_Bulk << std::endl;
3307 
3308  if (drainConductance)
3309  Xyce::dout() << " li_DrainPrime = " << li_DrainPrime << std::endl;
3310  if (sourceConductance)
3311  Xyce::dout() << " li_SourcePrime = " << li_SourcePrime << std::endl;
3312 
3313  if (nqsMod)
3314  Xyce::dout() << " li_Charge = " << li_Charge << std::endl;
3315 
3316  if (icVBSGiven)
3317  Xyce::dout() << " li_Ibs = " << li_Ibs << std::endl;
3318 
3319  if (icVDSGiven)
3320  Xyce::dout() << " li_Ids = " << li_Ids << std::endl;
3321 
3322  if (icVGSGiven)
3323  Xyce::dout() << " li_Igs = " << li_Igs << std::endl;
3324  Xyce::dout() << section_divider << std::endl;
3325  }
3326 
3327 }
3328 
3329 //-----------------------------------------------------------------------------
3330 // Function : Instance::loadNodeSymbols
3331 // Purpose :
3332 // Special Notes :
3333 // Scope : public
3334 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
3335 // Creation Date : 05/13/05
3336 //-----------------------------------------------------------------------------
3337 void Instance::loadNodeSymbols(Util::SymbolTable &symbol_table) const
3338 {
3339  if (drainConductance != 0.0)
3340  addInternalNode(symbol_table, li_DrainPrime, getName(), "drainprime");
3341 
3342  if (sourceConductance != 0.0)
3343  addInternalNode(symbol_table, li_SourcePrime, getName(), "sourceprime");
3344 
3345  if (icVDSGiven)
3346  addInternalNode(symbol_table, li_Ids, getName(), "branch_DS");
3347 
3348  if (icVGSGiven)
3349  addInternalNode(symbol_table, li_Igs, getName(), "branch_GS");
3350 
3351  if (icVBSGiven)
3352  addInternalNode(symbol_table, li_Ibs, getName(), "branch_BS");
3353 
3354  if (loadLeadCurrent)
3355  {
3356  addStoreNode(symbol_table, li_store_dev_id, getName(), "DEV_ID");
3357  addStoreNode(symbol_table, li_store_dev_ig, getName(), "DEV_IG");
3358  addStoreNode(symbol_table, li_store_dev_is, getName(), "DEV_IS");
3359  addStoreNode(symbol_table, li_store_dev_ib, getName(), "DEV_IB");
3360  }
3361 }
3362 
3363 //-----------------------------------------------------------------------------
3364 // Function : Instance::registerStateLIDs
3365 // Purpose :
3366 // Special Notes :
3367 // Scope : public
3368 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3369 // Creation Date : 6/21/02
3370 //-----------------------------------------------------------------------------
3371 void Instance::registerStateLIDs( const std::vector<int> & staLIDVecRef )
3372 {
3373  AssertLIDs(staLIDVecRef.size() == numStateVars);
3374 
3375  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3376  {
3377  Xyce::dout() << std::endl;
3378  Xyce::dout() << section_divider << std::endl;
3379  Xyce::dout() << " In Instance::registerStateLIDs\n\n";
3380  Xyce::dout() << " name = " << getName() << std::endl;
3381  Xyce::dout() << " Number of State LIDs: " << numStateVars << std::endl;
3382  }
3383 
3384  // Copy over the global ID lists:
3385  staLIDVec = staLIDVecRef;
3386 
3387  int lid=0;
3388  // Intrinsic capacitors:
3389  li_state_qb = staLIDVec[lid++];
3390  li_state_qg = staLIDVec[lid++];
3391  li_state_qd = staLIDVec[lid++];
3392 
3393  // Parasitic capacitors:
3394  li_state_qbs = staLIDVec[lid++];
3395  li_state_qbd = staLIDVec[lid++];
3396 
3397  // state variables, cheq
3398  li_state_qcheq = staLIDVec[lid++];
3399 
3400  // state variables, cdump
3401  li_state_qcdump = staLIDVec[lid++];
3402 
3403  // state variable, qdef
3404  li_state_qdef = staLIDVec[lid++];
3405 
3406 
3407  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3408  {
3409  Xyce::dout() << " Local State indices:" << std::endl;
3410  Xyce::dout() << std::endl;
3411  Xyce::dout() << " li_state_qb = " << li_state_qb << std::endl;
3412  Xyce::dout() << " li_state_qg = " << li_state_qg << std::endl;
3413  Xyce::dout() << " li_state_qd = " << li_state_qd << std::endl;
3414  Xyce::dout() << " li_state_qbs = " << li_state_qbs << std::endl;
3415  Xyce::dout() << " li_state_qbd = " << li_state_qbd << std::endl;
3416  Xyce::dout() << " li_state_qcheq = " << li_state_qcheq << std::endl;
3417  Xyce::dout() << " li_state_qcdump = " << li_state_qcdump << std::endl;
3418  Xyce::dout() << " li_state_qdef = " << li_state_qdef << std::endl;
3419  Xyce::dout() << section_divider << std::endl;
3420  }
3421 
3422 }
3423 
3424 //-----------------------------------------------------------------------------
3425 // Function : Instance::registerStoreLIDs
3426 // Purpose :
3427 // Special Notes :
3428 // Scope : public
3429 // Creator : Eric Keiter, SNL
3430 // Creation Date : 12/9/11
3431 //-----------------------------------------------------------------------------
3432 void Instance::registerStoreLIDs( const std::vector<int> & stoLIDVecRef )
3433 {
3434  AssertLIDs(stoLIDVecRef.size() == getNumStoreVars());
3435 
3436  // Copy over the global ID lists:
3437  stoLIDVec = stoLIDVecRef;
3438 
3439  int lid=0;
3440  // Voltage drops:
3441  li_store_vbd = stoLIDVec[lid++];
3442  li_store_vbs = stoLIDVec[lid++];
3443  li_store_vgs = stoLIDVec[lid++];
3444  li_store_vds = stoLIDVec[lid++];
3445  li_store_von = stoLIDVec[lid++];
3446 
3447  if( loadLeadCurrent )
3448  {
3449  li_store_dev_id = stoLIDVec[lid++];
3450  li_store_dev_ig = stoLIDVec[lid++];
3451  li_store_dev_is = stoLIDVec[lid++];
3452  li_store_dev_ib = stoLIDVec[lid++];
3453  }
3454 }
3455 
3456 //-----------------------------------------------------------------------------
3457 // Function : Instance::jacobianStamp
3458 // Purpose :
3459 // Special Notes :
3460 // Scope : public
3461 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3462 // Creation Date : 9/4/02
3463 //-----------------------------------------------------------------------------
3464 const std::vector< std::vector<int> > & Instance::jacobianStamp() const
3465 {
3466  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3467  {
3469  {
3470  return jacStampSpecialMerged;
3471  }
3472  else
3473  {
3474  return jacStampSpecial;
3475  }
3476  }
3477  else
3478  {
3480  return jacStamp_DC_SC;
3481  else if( drainConductance && !sourceConductance && !nqsMod )
3482  return jacStamp_DC;
3483  else if( !drainConductance && sourceConductance && !nqsMod )
3484  return jacStamp_SC;
3485  else if( !drainConductance && !sourceConductance && !nqsMod )
3486  return jacStamp;
3487  else
3488  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3489  ": NQSMOD not supported for DIRECT MATRIX ACCESS\n" );
3490  }
3491 
3492  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3493  "Instance::jacobianStamp should not get here!\n" );
3494 
3495  return jacStamp;
3496 }
3497 
3498 //-----------------------------------------------------------------------------
3499 // Function : Instance::registerJacLIDs
3500 // Purpose :
3501 // Special Notes :
3502 // Scope : public
3503 // Creator : Robert Hoekstra, SNL, Parallel Computational Sciences
3504 // Creation Date : 9/4/02
3505 //-----------------------------------------------------------------------------
3506 void Instance::registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec )
3507 {
3508  DeviceInstance::registerJacLIDs( jacLIDVec );
3509  std::vector<int> map;
3510  std::vector< std::vector<int> > map2;
3511 
3512 
3513  if (icVBSGiven || icVDSGiven || icVGSGiven || nqsMod )
3514  {
3516  {
3517  map = jacSpecialMap;
3518  map2 = jacSpecialMap2;
3519  }
3520  else
3521  {
3522  map = jacSpecialMergedMap;
3523  map2 = jacSpecialMergedMap2;
3524  }
3525  }
3526  else
3527  {
3528  if (drainConductance)
3529  {
3530  if (sourceConductance)
3531  {
3532  map = jacMap_DC_SC;
3533  map2 = jacMap2_DC_SC;
3534  }
3535  else
3536  {
3537  map = jacMap_DC;
3538  map2 = jacMap2_DC;
3539  }
3540  }
3541  else
3542  {
3543  if (sourceConductance)
3544  {
3545  map = jacMap_SC;
3546  map2 = jacMap2_SC;
3547  }
3548  else
3549  {
3550  map = jacMap;
3551  map2 = jacMap2;
3552  }
3553  }
3554  }
3555 
3556  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
3557  {
3558  Xyce::dout() << "Instance::registerJacLIDs map selected" << std::endl;
3559  for (int k = 0; k<map.size(); ++k )
3560  {
3561  Xyce::dout() << "map[ " << k << "] = " << map[k] << " map2[] = { ";
3562  for (int q = 0; q < map2[k].size(); ++q )
3563  {
3564  Xyce::dout() << map2[k][q] <<" ";
3565  }
3566  Xyce::dout() << "}" << std::endl;
3567  }
3568 
3569  for(int k = 0; k<jacLIDVec.size(); ++k )
3570  {
3571  Xyce::dout() << "jacLIDVec[ " << k << "] = { ";
3572  for (int q = 0; q < jacLIDVec[k].size(); ++q )
3573  {
3574  Xyce::dout() << jacLIDVec[k][q] <<" ";
3575  }
3576  Xyce::dout() << "}" << std::endl;
3577  }
3578  }
3579 
3580  int nextColumn = 0;
3581 
3582  // V_d row
3583  ADrainEquDrainNodeOffset = jacLIDVec[map[0]][map2[0][0]];
3584  ADrainEquDrainPrimeNodeOffset = jacLIDVec[map[0]][map2[0][1]];
3585  if( icVDSGiven )
3586  {
3587  ADrainEquIdsOffset = jacLIDVec[map[0]][map2[0][2]];
3588  }
3589 
3590  // V_g row
3591  AGateEquGateNodeOffset = jacLIDVec[map[1]][map2[1][0]];
3592  AGateEquBulkNodeOffset = jacLIDVec[map[1]][map2[1][1]];
3593  AGateEquDrainPrimeNodeOffset = jacLIDVec[map[1]][map2[1][2]];
3594  AGateEquSourcePrimeNodeOffset = jacLIDVec[map[1]][map2[1][3]];
3595  nextColumn = 4;
3596  if( nqsMod )
3597  {
3598  AGateEquChargeVarOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3599  ++nextColumn;
3600  }
3601  if( icVGSGiven )
3602  {
3603  AGateEquIgsOffset = jacLIDVec[map[1]][map2[1][nextColumn]];
3604  ++nextColumn;
3605  }
3606 
3607  // V_s row
3608  ASourceEquSourceNodeOffset = jacLIDVec[map[2]][map2[2][0]];
3609  ASourceEquSourcePrimeNodeOffset = jacLIDVec[map[2]][map2[2][1]];
3610  nextColumn = 2;
3611  if( icVBSGiven )
3612  {
3613  ASourceEquIbsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3614  ++nextColumn;
3615  }
3616  if( icVDSGiven )
3617  {
3618  ASourceEquIdsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3619  ++nextColumn;
3620  }
3621  if( icVGSGiven )
3622  {
3623  ASourceEquIgsOffset = jacLIDVec[map[2]][map2[2][nextColumn]];
3624  ++nextColumn;
3625  }
3626 
3627  // V_b row
3628  ABulkEquGateNodeOffset = jacLIDVec[map[3]][map2[3][0]];
3629  ABulkEquBulkNodeOffset = jacLIDVec[map[3]][map2[3][1]];
3630  ABulkEquDrainPrimeNodeOffset = jacLIDVec[map[3]][map2[3][2]];
3631  ABulkEquSourcePrimeNodeOffset = jacLIDVec[map[3]][map2[3][3]];
3632  nextColumn = 4;
3633  if( nqsMod )
3634  {
3635  ABulkEquChargeVarOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3636  ++nextColumn;
3637  }
3638  if( icVBSGiven )
3639  {
3640  ABulkEquIbsOffset = jacLIDVec[map[3]][map2[3][nextColumn]];
3641  ++nextColumn;
3642  }
3643 
3644  // V_d'
3645  ADrainPrimeEquDrainNodeOffset = jacLIDVec[map[4]][map2[4][0]];
3646  ADrainPrimeEquGateNodeOffset = jacLIDVec[map[4]][map2[4][1]];
3647  ADrainPrimeEquBulkNodeOffset = jacLIDVec[map[4]][map2[4][2]];
3648  ADrainPrimeEquDrainPrimeNodeOffset = jacLIDVec[map[4]][map2[4][3]];
3649  ADrainPrimeEquSourcePrimeNodeOffset = jacLIDVec[map[4]][map2[4][4]];
3650  if( nqsMod )
3651  {
3652  ADrainPrimeEquChargeVarOffset = jacLIDVec[map[4]][map2[4][5]];
3653  }
3654 
3655 
3656  // V_s'
3657  ASourcePrimeEquGateNodeOffset = jacLIDVec[map[5]][map2[5][0]];
3658  ASourcePrimeEquSourceNodeOffset = jacLIDVec[map[5]][map2[5][1]];
3659  ASourcePrimeEquBulkNodeOffset = jacLIDVec[map[5]][map2[5][2]];
3660  ASourcePrimeEquDrainPrimeNodeOffset = jacLIDVec[map[5]][map2[5][3]];
3661  ASourcePrimeEquSourcePrimeNodeOffset = jacLIDVec[map[5]][map2[5][4]];
3662  if( nqsMod )
3663  {
3664  ASourcePrimeEquChargeVarOffset = jacLIDVec[map[5]][map2[5][5]];
3665  }
3666 
3667  int nextRow = 6;
3668  if( nqsMod )
3669  {
3670  AChargeEquChargeVarOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3671  AChargeEquDrainPrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3672  AChargeEquGateNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3673  AChargeEquSourcePrimeNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][3]];
3674  AChargeEquBulkNodeOffset = jacLIDVec[map[nextRow]][map2[nextRow][4]];
3675  ++nextRow;
3676  }
3677 
3678 
3679  if( icVBSGiven )
3680  {
3681  icVBSEquVbOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3682  icVBSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3683  icVBSEquIbsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3684  ++nextRow;
3685  }
3686 
3687  if( icVDSGiven )
3688  {
3689  icVDSEquVdOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3690  icVDSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3691  icVDSEquIdsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3692  ++nextRow;
3693  }
3694 
3695  if( icVGSGiven )
3696  {
3697  icVGSEquVgOffset = jacLIDVec[map[nextRow]][map2[nextRow][0]];
3698  icVGSEquVsOffset = jacLIDVec[map[nextRow]][map2[nextRow][1]];
3699  icVGSEquIgsOffset = jacLIDVec[map[nextRow]][map2[nextRow][2]];
3700  ++nextRow;
3701  }
3702 
3703  if (nqsMod)
3704  {
3705  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,
3706  ": NQSMOD not supported.\n" );
3707  }
3708 }
3709 
3710 //-----------------------------------------------------------------------------
3711 // Function : Instance::setupPointers
3712 // Purpose :
3713 // Special Notes :
3714 // Scope : public
3715 // Creator : Eric Keiter, SNL
3716 // Creation Date : 11/30/08
3717 //-----------------------------------------------------------------------------
3719 {
3720 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
3721  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
3722  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
3723 
3724  // V_d row
3727  if( icVDSGiven )
3728  {
3730  }
3731 
3732  // V_g row
3737  if( nqsMod )
3738  {
3740 
3741  }
3742  if( icVGSGiven )
3743  {
3745 
3746  }
3747 
3748  // V_s row // V_s row
3751  if( icVBSGiven )
3752  {
3754 
3755  }
3756  if( icVDSGiven )
3757  {
3759 
3760  }
3761  if( icVGSGiven )
3762  {
3764 
3765  }
3766 
3767  // V_b row
3772  if( nqsMod )
3773  {
3775 
3776  }
3777  if( icVBSGiven )
3778  {
3780 
3781  }
3782 
3783  // V_d'
3789  if( nqsMod )
3790  {
3792  }
3793 
3794 
3795  // V_s'
3801  if( nqsMod )
3802  {
3804  }
3805 
3806  if( nqsMod )
3807  {
3813  }
3814 
3815 
3816  if( icVBSGiven )
3817  {
3821  }
3822 
3823  if( icVDSGiven )
3824  {
3828  }
3829 
3830  if( icVGSGiven )
3831  {
3835  }
3836 
3837 
3838 
3839  // V_d row
3842  if( icVDSGiven )
3843  {
3845  }
3846 
3847  // V_g row
3852  if( nqsMod )
3853  {
3855 
3856  }
3857  if( icVGSGiven )
3858  {
3860 
3861  }
3862 
3863  // V_s row // V_s row
3866  if( icVBSGiven )
3867  {
3869 
3870  }
3871  if( icVDSGiven )
3872  {
3874 
3875  }
3876  if( icVGSGiven )
3877  {
3879 
3880  }
3881 
3882  // V_b row
3887  if( nqsMod )
3888  {
3890 
3891  }
3892  if( icVBSGiven )
3893  {
3895 
3896  }
3897 
3898  // V_d'
3904  if( nqsMod )
3905  {
3907  }
3908 
3909 
3910  // V_s'
3916  if( nqsMod )
3917  {
3919  }
3920 
3921  if( nqsMod )
3922  {
3928  }
3929 
3930 
3931  if( icVBSGiven )
3932  {
3936  }
3937 
3938  if( icVDSGiven )
3939  {
3943  }
3944 
3945  if( icVGSGiven )
3946  {
3950  }
3951 
3952 #endif
3953 }
3954 
3955 //-----------------------------------------------------------------------------
3956 // Function : Instance::updateTemperature
3957 // Purpose : This updates all the instance-owned paramters which
3958 // are temperature dependent.
3959 //
3960 // Special Notes :
3961 // Scope : public
3962 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
3963 // Creation Date : 11/22/00
3964 //-----------------------------------------------------------------------------
3965 bool Instance::updateTemperature (const double & temp_tmp)
3966 {
3967  char msg[128];
3968 
3969  double tmp, tmp1, tmp2, tmp3, Eg;
3970  double T0, T1, T2, T3, T4, T5, Ldrn, Wdrn;
3971  double delTemp, TRatio, Inv_L, Inv_W, Inv_LW;
3972  //double Dw, Dl;
3973  double Tnom;
3974  double Nvtm, SourceSatCurrent, DrainSatCurrent;
3975 
3976  // stuff from model paramters:
3977  double Eg0 = model_.Eg0;
3978  double ni = model_.ni;
3979  double Vtm0 = model_.Vtm0;
3980 
3981  bool bsuccess = true;
3982 
3983  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
3984  {
3985  Xyce::dout() << std::endl << subsection_divider << std::endl;
3986  Xyce::dout() << "Instance::updateTemperature\n";
3987  Xyce::dout() << "name = " << getName() << std::endl;
3988  }
3989 
3990  // first set the instance temperature to the new temperature:
3991  if (temp_tmp != -999.0) temp = temp_tmp;
3992 
3993  Tnom = model_.tnom;
3994  TRatio = temp/Tnom;
3995 
3996  vtm = CONSTKoverQ * temp;
3997  Eg = CONSTEg0 - CONSTalphaEg * temp * temp / (temp + CONSTbetaEg);
3998 
3999  if (temp != Tnom)
4000  {
4001  T0 = Eg0 / Vtm0 - Eg/vtm + model_.jctTempExponent*log(temp/Tnom);
4002  T1 = exp(T0 / model_.jctEmissionCoeff);
4005  }
4006  else
4007  {
4010  }
4011 
4012  if (jctTempSatCurDensity < 0.0) jctTempSatCurDensity = 0.0;
4014 
4015 
4016  // Temperature dependence of D/B and S/B diode capacitance begins
4017  delTemp = temp - Tnom;
4018  T0 = model_.tcj * delTemp;
4019 
4020  if (T0 >= -1.0)
4021  {
4023  }
4024  else if (unitAreaJctCapTemp > 0.0)
4025  {
4026  unitAreaJctCapTemp = 0.0;
4027 
4028  lout() << "Temperature effect has caused cj to be negative. Cj clamped to zero.\n" << std::endl;
4029  }
4030 
4031  T0 = model_.tcjsw * delTemp;
4032 
4033  if (T0 >= -1.0)
4034  {
4036  model_.unitLengthSidewallJctCap *(1.0 + T0);
4037  }
4038  else if (unitLengthSidewallJctCapTemp > 0.0)
4039  {
4041  lout() << "Temperature effect has caused cjsw to be negative. Cjsw clamped to zero.\n" << std::endl;
4042  }
4043 
4044  T0 = model_.tcjswg * delTemp;
4045 
4046  if (T0 >= -1.0)
4047  {
4050  }
4051  else if (unitLengthGateSidewallJctCapTemp > 0.0)
4052  {
4054  lout() << "Temperature effect has caused cjswg to be negative. Cjswg clamped to zero.\n" << std::endl;
4055  }
4056 
4057  PhiBTemp = model_.bulkJctPotential - model_.tpb * delTemp;
4058 
4059  if (PhiBTemp < 0.01)
4060  {
4061  PhiBTemp = 0.01;
4062  lout() << "Temperature effect has caused pb to be < 0.01. Pb clamped to 0.01.\n" << std::endl;
4063  }
4064 
4066 
4067  if (PhiBSWTemp <= 0.01)
4068  {
4069  PhiBSWTemp = 0.01;
4070  lout() << "Temperature effect has caused pbsw to be < 0.01. Pbsw clamped to 0.01.\n" << std::endl;
4071  }
4072 
4074 
4075  if (PhiBSWGTemp <= 0.01)
4076  {
4077  PhiBSWGTemp = 0.01;
4078  lout() << "Temperature effect has caused pbswg to be < 0.01. Pbswg clamped to 0.01.\n" << std::endl;
4079  }
4080  // End of junction capacitance
4081 
4082 
4083  // This next block determines whether or not to use a previously allocated
4084  // set of size dependent parameters. These are stored in a list that is
4085  // owned by the model. If the values for length and width match those of
4086  // a previously allocated set, then use the old set. If not, allocate a new set.
4087 
4088  std::list<SizeDependParam*>::iterator it_dpL =
4089  model_.sizeDependParamList.begin();
4090  std::list<SizeDependParam*>::iterator end_dpL =
4092 
4093  paramPtr = NULL;
4094 
4095  for( ; it_dpL != end_dpL; ++it_dpL )
4096  if( (*it_dpL)->Length == l && (*it_dpL)->Width == w && (*it_dpL)->referenceTemperature == temp_tmp)
4097  paramPtr = (*it_dpL);
4098 
4099  if ( paramPtr != NULL )
4100  {
4101  }
4102  else
4103  {
4104  paramPtr = new SizeDependParam ();
4105 
4106  model_.sizeDependParamList.push_back( paramPtr );
4107  paramPtr->referenceTemperature = temp_tmp;
4108 
4109  Ldrn = l;
4110  Wdrn = w;
4111  paramPtr->Length = Ldrn;
4112  paramPtr->Width = Wdrn;
4113 
4114  T0 = pow(Ldrn, model_.Lln);
4115  T1 = pow(Wdrn, model_.Lwn);
4116 
4117  tmp1 = model_.Ll / T0 + model_.Lw / T1
4118  + model_.Lwl / (T0 * T1);
4119 
4120  paramPtr->dl = model_.Lint + tmp1;
4121 
4122  tmp2 = model_.Llc / T0 + model_.Lwc / T1
4123  + model_.Lwlc / (T0 * T1);
4124 
4125  paramPtr->dlc = model_.dlc + tmp2;
4126 
4127  T2 = pow(Ldrn, model_.Wln);
4128  T3 = pow(Wdrn, model_.Wwn);
4129 
4130  tmp1 = model_.Wl / T2 + model_.Ww / T3
4131  + model_.Wwl / (T2 * T3);
4132 
4133  paramPtr->dw = model_.Wint + tmp1;
4134  tmp2 = model_.Wlc / T2 + model_.Wwc / T3
4135  + model_.Wwlc / (T2 * T3);
4136 
4137  paramPtr->dwc = model_.dwc + tmp2;
4138 
4139  paramPtr->leff = l - 2.0 * paramPtr->dl;
4140  if (paramPtr->leff <= 0.0)
4141  {
4142  UserWarning0(*this) << "Effective channel length <= 0";
4143  }
4144 
4145  paramPtr->weff = w - 2.0 * paramPtr->dw;
4146  if (paramPtr->weff <= 0.0)
4147  {
4148  UserWarning0(*this) << "Effective channel width <= 0";
4149  }
4150 
4151  paramPtr->leffCV = l - 2.0 * paramPtr->dlc;
4152  if (paramPtr->leffCV <= 0.0)
4153  {
4154  UserWarning0(*this) << "Effective channel length for C-V <= 0";
4155  }
4156 
4157  paramPtr->weffCV = w - 2.0 * paramPtr->dwc;
4158  if (paramPtr->weffCV <= 0.0)
4159  {
4160  UserWarning(*this) << "Effective channel width for C-V <= 0";
4161  }
4162 
4163 
4164  if (model_.binUnit == 1)
4165  {
4166  Inv_L = 1.0e-6 / paramPtr->leff;
4167  Inv_W = 1.0e-6 / paramPtr->weff;
4168  Inv_LW = 1.0e-12 / (paramPtr->leff * paramPtr->weff);
4169  }
4170  else
4171  {
4172  Inv_L = 1.0 / paramPtr->leff;
4173  Inv_W = 1.0 / paramPtr->weff;
4174  Inv_LW = 1.0 / (paramPtr->leff * paramPtr->weff);
4175  }
4176 
4178  + model_.lcdsc * Inv_L
4179  + model_.wcdsc * Inv_W
4180  + model_.pcdsc * Inv_LW;
4181 
4183  + model_.lcdscb * Inv_L
4184  + model_.wcdscb * Inv_W
4185  + model_.pcdscb * Inv_LW;
4186 
4188  + model_.lcdscd * Inv_L
4189  + model_.wcdscd * Inv_W
4190  + model_.pcdscd * Inv_LW;
4191 
4192  paramPtr->cit = model_.cit
4193  + model_.lcit * Inv_L
4194  + model_.wcit * Inv_W
4195  + model_.pcit * Inv_LW;
4196 
4198  + model_.lnfactor * Inv_L
4199  + model_.wnfactor * Inv_W
4200  + model_.pnfactor * Inv_LW;
4201 
4202  paramPtr->xj = model_.xj
4203  + model_.lxj * Inv_L
4204  + model_.wxj * Inv_W
4205  + model_.pxj * Inv_LW;
4206 
4208  + model_.lvsat * Inv_L
4209  + model_.wvsat * Inv_W
4210  + model_.pvsat * Inv_LW;
4211 
4212  paramPtr->at = model_.at
4213  + model_.lat * Inv_L
4214  + model_.wat * Inv_W
4215  + model_.pat * Inv_LW;
4216 
4217  paramPtr->a0 = model_.a0
4218  + model_.la0 * Inv_L
4219  + model_.wa0 * Inv_W
4220  + model_.pa0 * Inv_LW;
4221 
4222  paramPtr->ags = model_.ags
4223  + model_.lags * Inv_L
4224  + model_.wags * Inv_W
4225  + model_.pags * Inv_LW;
4226 
4227  paramPtr->a1 = model_.a1
4228  + model_.la1 * Inv_L
4229  + model_.wa1 * Inv_W
4230  + model_.pa1 * Inv_LW;
4231 
4232  paramPtr->a2 = model_.a2
4233  + model_.la2 * Inv_L
4234  + model_.wa2 * Inv_W
4235  + model_.pa2 * Inv_LW;
4236 
4238  + model_.lketa * Inv_L
4239  + model_.wketa * Inv_W
4240  + model_.pketa * Inv_LW;
4241 
4243  + model_.lnsub * Inv_L
4244  + model_.wnsub * Inv_W
4245  + model_.pnsub * Inv_LW;
4246 
4248  + model_.lnpeak * Inv_L
4249  + model_.wnpeak * Inv_W
4250  + model_.pnpeak * Inv_LW;
4251 
4253  + model_.lngate * Inv_L
4254  + model_.wngate * Inv_W
4255  + model_.pngate * Inv_LW;
4256 
4258  + model_.lgamma1 * Inv_L
4259  + model_.wgamma1 * Inv_W
4260  + model_.pgamma1 * Inv_LW;
4261 
4263  + model_.lgamma2 * Inv_L
4264  + model_.wgamma2 * Inv_W
4265  + model_.pgamma2 * Inv_LW;
4266 
4267  paramPtr->vbx = model_.vbx
4268  + model_.lvbx * Inv_L
4269  + model_.wvbx * Inv_W
4270  + model_.pvbx * Inv_LW;
4271 
4272  paramPtr->vbm = model_.vbm
4273  + model_.lvbm * Inv_L
4274  + model_.wvbm * Inv_W
4275  + model_.pvbm * Inv_LW;
4276 
4277  paramPtr->xt = model_.xt
4278  + model_.lxt * Inv_L
4279  + model_.wxt * Inv_W
4280  + model_.pxt * Inv_LW;
4281 
4282  paramPtr->vfb = model_.vfb
4283  + model_.lvfb * Inv_L
4284  + model_.wvfb * Inv_W
4285  + model_.pvfb * Inv_LW;
4286 
4287  paramPtr->k1 = model_.k1
4288  + model_.lk1 * Inv_L
4289  + model_.wk1 * Inv_W
4290  + model_.pk1 * Inv_LW;
4291 
4292  paramPtr->kt1 = model_.kt1
4293  + model_.lkt1 * Inv_L
4294  + model_.wkt1 * Inv_W
4295  + model_.pkt1 * Inv_LW;
4296 
4298  + model_.lkt1l * Inv_L
4299  + model_.wkt1l * Inv_W
4300  + model_.pkt1l * Inv_LW;
4301 
4302  paramPtr->k2 = model_.k2
4303  + model_.lk2 * Inv_L
4304  + model_.wk2 * Inv_W
4305  + model_.pk2 * Inv_LW;
4306 
4307  paramPtr->kt2 = model_.kt2
4308  + model_.lkt2 * Inv_L
4309  + model_.wkt2 * Inv_W
4310  + model_.pkt2 * Inv_LW;
4311 
4312  paramPtr->k3 = model_.k3
4313  + model_.lk3 * Inv_L
4314  + model_.wk3 * Inv_W
4315  + model_.pk3 * Inv_LW;
4316 
4317  paramPtr->k3b = model_.k3b
4318  + model_.lk3b * Inv_L
4319  + model_.wk3b * Inv_W
4320  + model_.pk3b * Inv_LW;
4321 
4322  paramPtr->w0 = model_.w0
4323  + model_.lw0 * Inv_L
4324  + model_.ww0 * Inv_W
4325  + model_.pw0 * Inv_LW;
4326 
4327  paramPtr->nlx = model_.nlx
4328  + model_.lnlx * Inv_L
4329  + model_.wnlx * Inv_W
4330  + model_.pnlx * Inv_LW;
4331 
4333  + model_.ldvt0 * Inv_L
4334  + model_.wdvt0 * Inv_W
4335  + model_.pdvt0 * Inv_LW;
4336 
4338  + model_.ldvt1 * Inv_L
4339  + model_.wdvt1 * Inv_W
4340  + model_.pdvt1 * Inv_LW;
4341 
4343  + model_.ldvt2 * Inv_L
4344  + model_.wdvt2 * Inv_W
4345  + model_.pdvt2 * Inv_LW;
4346 
4348  + model_.ldvt0w * Inv_L
4349  + model_.wdvt0w * Inv_W
4350  + model_.pdvt0w * Inv_LW;
4351 
4353  + model_.ldvt1w * Inv_L
4354  + model_.wdvt1w * Inv_W
4355  + model_.pdvt1w * Inv_LW;
4356 
4358  + model_.ldvt2w * Inv_L
4359  + model_.wdvt2w * Inv_W
4360  + model_.pdvt2w * Inv_LW;
4361 
4363  + model_.ldrout * Inv_L
4364  + model_.wdrout * Inv_W
4365  + model_.pdrout * Inv_LW;
4366 
4368  + model_.ldsub * Inv_L
4369  + model_.wdsub * Inv_W
4370  + model_.pdsub * Inv_LW;
4371 
4373  + model_.lvth0 * Inv_L
4374  + model_.wvth0 * Inv_W
4375  + model_.pvth0 * Inv_LW;
4376 
4377  paramPtr->ua = model_.ua
4378  + model_.lua * Inv_L
4379  + model_.wua * Inv_W
4380  + model_.pua * Inv_LW;
4381 
4382  paramPtr->ua1 = model_.ua1
4383  + model_.lua1 * Inv_L
4384  + model_.wua1 * Inv_W
4385  + model_.pua1 * Inv_LW;
4386 
4387  paramPtr->ub = model_.ub
4388  + model_.lub * Inv_L
4389  + model_.wub * Inv_W
4390  + model_.pub * Inv_LW;
4391 
4392  paramPtr->ub1 = model_.ub1
4393  + model_.lub1 * Inv_L
4394  + model_.wub1 * Inv_W
4395  + model_.pub1 * Inv_LW;
4396 
4397  paramPtr->uc = model_.uc
4398  + model_.luc * Inv_L
4399  + model_.wuc * Inv_W
4400  + model_.puc * Inv_LW;
4401 
4402  paramPtr->uc1 = model_.uc1
4403  + model_.luc1 * Inv_L
4404  + model_.wuc1 * Inv_W
4405  + model_.puc1 * Inv_LW;
4406 
4407  paramPtr->u0 = model_.u0
4408  + model_.lu0 * Inv_L
4409  + model_.wu0 * Inv_W
4410  + model_.pu0 * Inv_LW;
4411 
4412  paramPtr->ute = model_.ute
4413  + model_.lute * Inv_L
4414  + model_.wute * Inv_W
4415  + model_.pute * Inv_LW;
4416 
4418  + model_.lvoff * Inv_L
4419  + model_.wvoff * Inv_W
4420  + model_.pvoff * Inv_LW;
4421 
4423  + model_.ldelta * Inv_L
4424  + model_.wdelta * Inv_W
4425  + model_.pdelta * Inv_LW;
4426 
4428  + model_.lrdsw * Inv_L
4429  + model_.wrdsw * Inv_W
4430  + model_.prdsw * Inv_LW;
4431 
4433  + model_.lprwg * Inv_L
4434  + model_.wprwg * Inv_W
4435  + model_.pprwg * Inv_LW;
4436 
4438  + model_.lprwb * Inv_L
4439  + model_.wprwb * Inv_W
4440  + model_.pprwb * Inv_LW;
4441 
4442  paramPtr->prt = model_.prt
4443  + model_.lprt * Inv_L
4444  + model_.wprt * Inv_W
4445  + model_.pprt * Inv_LW;
4446 
4448  + model_.leta0 * Inv_L
4449  + model_.weta0 * Inv_W
4450  + model_.peta0 * Inv_LW;
4451 
4453  + model_.letab * Inv_L
4454  + model_.wetab * Inv_W
4455  + model_.petab * Inv_LW;
4456 
4458  + model_.lpclm * Inv_L
4459  + model_.wpclm * Inv_W
4460  + model_.ppclm * Inv_LW;
4461 
4463  + model_.lpdibl1 * Inv_L
4464  + model_.wpdibl1 * Inv_W
4465  + model_.ppdibl1 * Inv_LW;
4466 
4468  + model_.lpdibl2 * Inv_L
4469  + model_.wpdibl2 * Inv_W
4470  + model_.ppdibl2 * Inv_LW;
4471 
4473  + model_.lpdiblb * Inv_L
4474  + model_.wpdiblb * Inv_W
4475  + model_.ppdiblb * Inv_LW;
4476 
4478  + model_.lpscbe1 * Inv_L
4479  + model_.wpscbe1 * Inv_W
4480  + model_.ppscbe1 * Inv_LW;
4481 
4483  + model_.lpscbe2 * Inv_L
4484  + model_.wpscbe2 * Inv_W
4485  + model_.ppscbe2 * Inv_LW;
4486 
4488  + model_.lpvag * Inv_L
4489  + model_.wpvag * Inv_W
4490  + model_.ppvag * Inv_LW;
4491 
4492  paramPtr->wr = model_.wr
4493  + model_.lwr * Inv_L
4494  + model_.wwr * Inv_W
4495  + model_.pwr * Inv_LW;
4496 
4497  paramPtr->dwg = model_.dwg
4498  + model_.ldwg * Inv_L
4499  + model_.wdwg * Inv_W
4500  + model_.pdwg * Inv_LW;
4501 
4502  paramPtr->dwb = model_.dwb
4503  + model_.ldwb * Inv_L
4504  + model_.wdwb * Inv_W
4505  + model_.pdwb * Inv_LW;
4506 
4507  paramPtr->b0 = model_.b0
4508  + model_.lb0 * Inv_L
4509  + model_.wb0 * Inv_W
4510  + model_.pb0 * Inv_LW;
4511 
4512  paramPtr->b1 = model_.b1
4513  + model_.lb1 * Inv_L
4514  + model_.wb1 * Inv_W
4515  + model_.pb1 * Inv_LW;
4516 
4518  + model_.lalpha0 * Inv_L
4519  + model_.walpha0 * Inv_W
4520  + model_.palpha0 * Inv_LW;
4521 
4523  + model_.lalpha1 * Inv_L
4524  + model_.walpha1 * Inv_W
4525  + model_.palpha1 * Inv_LW;
4526 
4528  + model_.lbeta0 * Inv_L
4529  + model_.wbeta0 * Inv_W
4530  + model_.pbeta0 * Inv_LW;
4531 
4532  // CV model
4533  paramPtr->elm = model_.elm
4534  + model_.lelm * Inv_L
4535  + model_.welm * Inv_W
4536  + model_.pelm * Inv_LW;
4537 
4539  + model_.lcgsl * Inv_L
4540  + model_.wcgsl * Inv_W
4541  + model_.pcgsl * Inv_LW;
4542 
4544  + model_.lcgdl * Inv_L
4545  + model_.wcgdl * Inv_W
4546  + model_.pcgdl * Inv_LW;
4547 
4549  + model_.lckappa * Inv_L
4550  + model_.wckappa * Inv_W
4551  + model_.pckappa * Inv_LW;
4552 
4553  paramPtr->cf = model_.cf
4554  + model_.lcf * Inv_L
4555  + model_.wcf * Inv_W
4556  + model_.pcf * Inv_LW;
4557 
4558  paramPtr->clc = model_.clc
4559  + model_.lclc * Inv_L
4560  + model_.wclc * Inv_W
4561  + model_.pclc * Inv_LW;
4562 
4563  paramPtr->cle = model_.cle
4564  + model_.lcle * Inv_L
4565  + model_.wcle * Inv_W
4566  + model_.pcle * Inv_LW;
4567 
4569  + model_.lvfbcv * Inv_L
4570  + model_.wvfbcv * Inv_W
4571  + model_.pvfbcv * Inv_LW;
4572 
4574  + model_.lacde * Inv_L
4575  + model_.wacde * Inv_W
4576  + model_.pacde * Inv_LW;
4577 
4579  + model_.lmoin * Inv_L
4580  + model_.wmoin * Inv_W
4581  + model_.pmoin * Inv_LW;
4582 
4584  + model_.lnoff * Inv_L
4585  + model_.wnoff * Inv_W
4586  + model_.pnoff * Inv_LW;
4587 
4589  + model_.lvoffcv * Inv_L
4590  + model_.wvoffcv * Inv_W
4591  + model_.pvoffcv * Inv_LW;
4592 
4593  paramPtr->abulkCVfactor = 1.0
4594  + pow((paramPtr->clc / paramPtr->leffCV), paramPtr->cle);
4595 
4596  T0 = (TRatio - 1.0);
4597 
4598  paramPtr->ua = paramPtr->ua + paramPtr->ua1 * T0;
4599  paramPtr->ub = paramPtr->ub + paramPtr->ub1 * T0;
4600  paramPtr->uc = paramPtr->uc + paramPtr->uc1 * T0;
4601 
4602  if (paramPtr->u0 > 1.0) paramPtr->u0 = paramPtr->u0 / 1.0e4;
4603 
4604  paramPtr->u0temp = paramPtr->u0 * pow(TRatio, paramPtr->ute);
4605 
4606  paramPtr->vsattemp = paramPtr->vsat - paramPtr->at * T0;
4607 
4608  paramPtr->rds0 = (paramPtr->rdsw + paramPtr->prt * T0)
4609  / pow(paramPtr->weff * 1E6, paramPtr->wr);
4610 
4611 #ifdef CHECK_MODEL_DONE
4612  if (checkModel((*M_iter), iterI, ckt))
4613  {
4614  UserError0(*this) << "Error(s) detected during V3.2 parameter checking for " << name.c_str() << " in model " << model_.name;
4615 #endif
4616 
4620 
4621  T0 = paramPtr->leffCV * paramPtr->leffCV;
4622 
4624  * paramPtr->weffCV * paramPtr->leffCV * T0);
4625 
4627  {
4628  T0 = paramPtr->gamma1 * model_.cox;
4629  paramPtr->npeak = 3.021E22 * T0 * T0;
4630  }
4631 
4632  paramPtr->phi = 2.0 * Vtm0 * log(paramPtr->npeak / ni);
4633  paramPtr->sqrtPhi = sqrt(paramPtr->phi);
4635 
4636  paramPtr->Xdep0 = sqrt(2.0 * CONSTEPSSI / (CONSTQ * paramPtr->npeak * 1.0e6))
4637  * paramPtr->sqrtPhi;
4638 
4639  paramPtr->sqrtXdep0 = sqrt(paramPtr->Xdep0);
4640  paramPtr->litl = sqrt(3.0 * paramPtr->xj * model_.tox);
4641 
4642  paramPtr->vbi = Vtm0 * log(1.0e20 * paramPtr->npeak / (ni * ni));
4643 
4644  paramPtr->cdep0 = sqrt(CONSTQ * CONSTEPSSI * paramPtr->npeak * 1.0e6 / 2.0
4645  / paramPtr->phi);
4646 
4647  paramPtr->ldeb = sqrt(CONSTEPSSI * Vtm0 / (CONSTQ
4648  * paramPtr->npeak * 1.0e6)) / 3.0;
4649 
4650  paramPtr->acde *= pow((paramPtr->npeak / 2.0e16), -0.25);
4651 
4652 
4653  if (model_.k1Given || model_.k2Given)
4654  {
4655  if (!model_.k1Given)
4656  {
4657  UserWarning0(*this) << "k1 should be specified with k2.";
4658  paramPtr->k1 = 0.53;
4659  }
4660 
4661  if (!model_.k2Given)
4662  {
4663  UserWarning0(*this) << "k2 should be specified with k1.";
4664  paramPtr->k2 = -0.0186;
4665  }
4666 
4667  if (model_.nsubGiven)
4668  {
4669  UserWarning0(*this) << "nsub is ignored because k1 or k2 is given.";
4670  }
4671 
4672  if (model_.xtGiven)
4673  {
4674  UserWarning0(*this) << "xt is ignored because k1 or k2 is given.";
4675  }
4676 
4677  if (model_.vbxGiven)
4678  {
4679  UserWarning0(*this) << "vbx is ignored because k1 or k2 is given.";
4680  }
4681 
4682  if (model_.gamma1Given)
4683  {
4684  UserWarning0(*this) << "gamma1 is ignored because k1 or k2 is given.";
4685  }
4686 
4687  if (model_.gamma2Given)
4688  {
4689  UserWarning0(*this) << "gamma2 is ignored because k1 or k2 is given.";
4690  }
4691  }
4692  else
4693  {
4694  if (!model_.vbxGiven)
4695  paramPtr->vbx = paramPtr->phi - 7.7348e-4 * paramPtr->npeak
4696  * paramPtr->xt * paramPtr->xt;
4697 
4698  if (paramPtr->vbx > 0.0)
4699  paramPtr->vbx = -paramPtr->vbx;
4700 
4701  if (paramPtr->vbm > 0.0)
4702  paramPtr->vbm = -paramPtr->vbm;
4703 
4704  if (!model_.gamma1Given)
4705  paramPtr->gamma1 = 5.753e-12 * sqrt(paramPtr->npeak) / model_.cox;
4706 
4707  if (!model_.gamma2Given)
4708  paramPtr->gamma2 = 5.753e-12 * sqrt(paramPtr->nsub) / model_.cox;
4709 
4710  T0 = paramPtr->gamma1 - paramPtr->gamma2;
4711  T1 = sqrt(paramPtr->phi - paramPtr->vbx) - paramPtr->sqrtPhi;
4712  T2 = sqrt(paramPtr->phi * (paramPtr->phi - paramPtr->vbm)) - paramPtr->phi;
4713 
4714  paramPtr->k2 = T0 * T1 / (2.0 * T2 + paramPtr->vbm);
4715  paramPtr->k1 = paramPtr->gamma2 - 2.0 * paramPtr->k2 * sqrt(paramPtr->phi
4716  - paramPtr->vbm);
4717  }
4718 
4719  if (paramPtr->k2 < 0.0)
4720  {
4721  T0 = 0.5 * paramPtr->k1 / paramPtr->k2;
4722  paramPtr->vbsc = 0.9 * (paramPtr->phi - T0 * T0);
4723 
4724  if (paramPtr->vbsc > -3.0) paramPtr->vbsc = -3.0;
4725  else if (paramPtr->vbsc < -30.0) paramPtr->vbsc = -30.0;
4726  }
4727  else
4728  {
4729  paramPtr->vbsc = -30.0;
4730  }
4731 
4733 
4734  if (!model_.vfbGiven)
4735  {
4736  if (model_.vth0Given)
4737  {
4740  }
4741  else
4742  { paramPtr->vfb = -1.0;
4743  }
4744  }
4745 
4746  if (!model_.vth0Given)
4747  {
4749  * (paramPtr->vfb + paramPtr->phi + paramPtr->k1
4750  * paramPtr->sqrtPhi);
4751  }
4752 
4755 
4756  T1 = sqrt(CONSTEPSSI / CONSTEPSOX * model_.tox * paramPtr->Xdep0);
4757  T0 = exp(-0.5 * paramPtr->dsub * paramPtr->leff / T1);
4758 
4759  paramPtr->theta0vb0 = (T0 + 2.0 * T0 * T0);
4760 
4761  T0 = exp(-0.5 * paramPtr->drout * paramPtr->leff / T1);
4762  T2 = (T0 + 2.0 * T0 * T0);
4763 
4765 
4766  tmp = sqrt(paramPtr->Xdep0);
4767  tmp1 = paramPtr->vbi - paramPtr->phi;
4768  tmp2 = model_.factor1 * tmp;
4769 
4770  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * paramPtr->leff / tmp2;
4771 
4772  if (T0 > -CONSTEXP_THRESHOLD)
4773  {
4774  T1 = exp(T0);
4775  T2 = T1 * (1.0 + 2.0 * T1);
4776  }
4777  else
4778  {
4779  T1 = CONSTMIN_EXP;
4780  T2 = T1 * (1.0 + 2.0 * T1);
4781  }
4782  T0 = paramPtr->dvt0w * T2;
4783  T2 = T0 * tmp1;
4784 
4785  T0 = -0.5 * paramPtr->dvt1 * paramPtr->leff / tmp2;
4786 
4787  if (T0 > -CONSTEXP_THRESHOLD)
4788  {
4789  T1 = exp(T0);
4790  T3 = T1 * (1.0 + 2.0 * T1);
4791  }
4792  else
4793  {
4794  T1 = CONSTMIN_EXP;
4795  T3 = T1 * (1.0 + 2.0 * T1);
4796  }
4797 
4798  T3 = paramPtr->dvt0 * T3 * tmp1;
4799 
4800  T4 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
4801 
4802  T0 = sqrt(1.0 + paramPtr->nlx / paramPtr->leff);
4803  T5 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
4804  + (paramPtr->kt1 + paramPtr->kt1l / paramPtr->leff) * (TRatio - 1.0);
4805 
4806  tmp3 = model_.dtype * paramPtr->vth0 - T2 - T3 + paramPtr->k3 * T4 + T5;
4807 
4808  paramPtr->vfbzb = tmp3 - paramPtr->phi - paramPtr->k1 * paramPtr->sqrtPhi;
4809 
4810  } // End of vfbzb
4811 
4812  cgso = paramPtr->cgso;
4813  cgdo = paramPtr->cgdo;
4814 
4815  Nvtm = vtm * model_.jctEmissionCoeff;
4816 
4817  if ((sourceArea <= 0.0) &&
4818  (sourcePerimeter <= 0.0))
4819  {
4820  SourceSatCurrent = 1.0e-14;
4821  }
4822  else
4823  {
4824  SourceSatCurrent = sourceArea * jctTempSatCurDensity
4825  + sourcePerimeter
4827  }
4828 
4829  if ((SourceSatCurrent > 0.0) && (model_.ijth > 0.0))
4830  {
4831  vjsm = Nvtm * log(model_.ijth / SourceSatCurrent + 1.0);
4832  IsEvjsm = SourceSatCurrent * exp(vjsm / Nvtm);
4833  }
4834 
4835  if ((drainArea <= 0.0) &&
4836  (drainPerimeter <= 0.0))
4837  {
4838  DrainSatCurrent = 1.0e-14;
4839  }
4840  else
4841  {
4842  DrainSatCurrent = drainArea * jctTempSatCurDensity
4843  + drainPerimeter
4845  }
4846 
4847  if ((DrainSatCurrent > 0.0) && (model_.ijth > 0.0))
4848  {
4849  vjdm = Nvtm * log(model_.ijth / DrainSatCurrent + 1.0);
4850  IsEvjdm = DrainSatCurrent * exp(vjdm / Nvtm);
4851  }
4852 
4853  updateTemperatureCalled_ = true;
4854 
4855  return bsuccess;
4856  }
4857 
4858 //-----------------------------------------------------------------------------
4859 // Function : Instance::updateIntermediateVars
4860 // Purpose :
4861 // Special Notes :
4862 // Scope : public
4863 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
4864 // Creation Date : 01/09/01
4865 //-----------------------------------------------------------------------------
4867 {
4868  bool bsuccess = true;
4869 
4870 // begin the b3ld.c parameters:
4871  double SourceSatCurrent(0.0), DrainSatCurrent(0.0);
4872  double vgdo(0.0);
4873 
4874  double VgstNVt(0.0), ExpVgst(0.0);
4875 
4876  double czbd(0.0), czbdsw(0.0), czbdswg(0.0), czbs(0.0), czbssw(0.0), czbsswg(0.0);
4877  double evbd(0.0), evbs(0.0), arg(0.0), sarg(0.0);
4878 
4879  double Vfbeff(0.0), dVfbeff_dVg(0.0), dVfbeff_dVb(0.0), V3(0.0), V4(0.0);
4880 
4881  double MJ(0.0), MJSW(0.0), MJSWG(0.0);
4882 
4883  double qinoi(0.0);
4884  double Vds(0.0), Vgs(0.0), Vbs(0.0);
4885  double Vgs_eff(0.0), Vfb(0.0);
4886  double Phis(0.0), dPhis_dVb(0.0), sqrtPhis(0.0), dsqrtPhis_dVb(0.0);
4887  double Vth(0.0), dVth_dVb(0.0), dVth_dVd(0.0);
4888  double Vgst(0.0);
4889 
4890  double Nvtm(0.0);
4891  double Vtm(0.0);
4892  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);
4893  double ExpArg(0.0), V0(0.0), CoxWLcen(0.0), QovCox(0.0), LINK(0.0);
4894  double DeltaPhi(0.0);
4895 
4896  double Cox(0.0), Tox(0.0), Tcen(0.0), dTcen_dVg(0.0), dTcen_dVd(0.0), dTcen_dVb(0.0);
4897  double Ccen(0.0), Coxeff(0.0), dCoxeff_dVg(0.0), dCoxeff_dVd(0.0), dCoxeff_dVb(0.0);
4898  double Denomi(0.0), dDenomi_dVg(0.0), dDenomi_dVd(0.0), dDenomi_dVb(0.0);
4899 
4900  double dueff_dVg(0.0), dueff_dVd(0.0), dueff_dVb(0.0);
4901  double Esat(0.0);
4902 
4903  double Vdsat(0.0);
4904 
4905  double EsatL(0.0), dEsatL_dVg(0.0), dEsatL_dVd(0.0), dEsatL_dVb(0.0);
4906 
4907  double dVdsat_dVg(0.0), dVdsat_dVb(0.0), dVdsat_dVd(0.0), Vasat(0.0), dAlphaz_dVg(0.0), dAlphaz_dVb(0.0);
4908  double dVasat_dVg(0.0), dVasat_dVb(0.0), dVasat_dVd(0.0), Va(0.0);
4909 
4910  double dVa_dVd(0.0), dVa_dVg(0.0), dVa_dVb(0.0);
4911  double Vbseff(0.0), dVbseff_dVb(0.0), VbseffCV(0.0), dVbseffCV_dVb(0.0);
4912  double Arg1(0.0);
4913 
4914  double One_Third_CoxWL(0.0), Two_Third_CoxWL(0.0), Alphaz(0.0);
4915 
4916  double T0(0.0), dT0_dVg(0.0), dT0_dVd(0.0), dT0_dVb(0.0);
4917  double T1(0.0), dT1_dVg(0.0), dT1_dVd(0.0), dT1_dVb(0.0);
4918  double T2(0.0), dT2_dVg(0.0), dT2_dVd(0.0), dT2_dVb(0.0);
4919  double T3(0.0), dT3_dVg(0.0), dT3_dVd(0.0), dT3_dVb(0.0);
4920  double T4(0.0);
4921 
4922  double T5(0.0);
4923  double T6(0.0);
4924  double T7(0.0);
4925  double T8(0.0);
4926  double T9(0.0);
4927  double T10(0.0);
4928  double T11(0.0), T12(0.0);
4929 
4930  double tmp(0.0);
4931 
4932  //double Abulk(0.0); // needs to be instance var for noise
4933 
4934  double dAbulk_dVb(0.0), Abulk0(0.0), dAbulk0_dVb(0.0);
4935 
4936  double VACLM(0.0), dVACLM_dVg(0.0), dVACLM_dVd(0.0), dVACLM_dVb(0.0);
4937  double VADIBL(0.0), dVADIBL_dVg(0.0), dVADIBL_dVd(0.0), dVADIBL_dVb(0.0);
4938 
4939  double Xdep(0.0), dXdep_dVb(0.0), lt1(0.0), dlt1_dVb(0.0), ltw(0.0), dltw_dVb(0.0);
4940  double Delt_vth(0.0), dDelt_vth_dVb(0.0);
4941 
4942  double Theta0(0.0), dTheta0_dVb(0.0);
4943 
4944  double TempRatio(0.0), tmp1(0.0), tmp2(0.0), tmp3(0.0), tmp4(0.0);
4945 
4946  double DIBL_Sft(0.0), dDIBL_Sft_dVd(0.0);
4947 
4948  double Lambda(0.0), dLambda_dVg(0.0);
4949 
4950  double a1(0.0);
4951 
4952  //double Vgsteff(0.0); // needs to be an instance var for noise.
4953 
4954  double dVgsteff_dVg(0.0), dVgsteff_dVd(0.0), dVgsteff_dVb(0.0);
4955  //double Vdseff(0.0); // needs to be an instance var for noise.
4956  double dVdseff_dVg(0.0), dVdseff_dVd(0.0), dVdseff_dVb(0.0);
4957  double VdseffCV(0.0), dVdseffCV_dVg(0.0), dVdseffCV_dVd(0.0), dVdseffCV_dVb(0.0);
4958  double diffVds(0.0);
4959 
4960  double dAbulk_dVg(0.0);
4961  double beta(0.0), dbeta_dVg(0.0), dbeta_dVd(0.0), dbeta_dVb(0.0);
4962  double gche(0.0), dgche_dVg(0.0), dgche_dVd(0.0), dgche_dVb(0.0);
4963  double fgche1(0.0), dfgche1_dVg(0.0), dfgche1_dVd(0.0), dfgche1_dVb(0.0);
4964  double fgche2(0.0), dfgche2_dVg(0.0), dfgche2_dVd(0.0), dfgche2_dVb(0.0);
4965  double Idl(0.0), dIdl_dVg(0.0), dIdl_dVd(0.0), dIdl_dVb(0.0);
4966  double Idsa(0.0), dIdsa_dVg(0.0), dIdsa_dVd(0.0), dIdsa_dVb(0.0);
4967  double Ids(0.0);
4968 
4969  double Gds(0.0), Gmb(0.0);
4970  double Isub(0.0);
4971 
4972  double Gbd(0.0), Gbg(0.0), Gbb(0.0);
4973  double VASCBE(0.0), dVASCBE_dVg(0.0), dVASCBE_dVd(0.0), dVASCBE_dVb(0.0);
4974  double CoxWovL(0.0);
4975  double Rds(0.0), dRds_dVg(0.0), dRds_dVb(0.0), WVCox(0.0), WVCoxRds(0.0);
4976  double Vgst2Vtm(0.0), VdsatCV(0.0);
4977 
4978  double dVdsatCV_dVg(0.0), dVdsatCV_dVb(0.0);
4979  double Leff(0.0), Weff(0.0), dWeff_dVg(0.0), dWeff_dVb(0.0);
4980  double AbulkCV(0.0), dAbulkCV_dVb(0.0);
4981 
4982  double gtau_diff(0.0), gtau_drift(0.0);
4983  // these shadow member varables and then are unitialized
4984  // when used in later calculations
4985  // double qcheq(0.0), cqcheq(0.0), qdef(0.0);
4986 
4987  double Cgg1(0.0), Cgb1(0.0), Cgd1(0.0), Cbg1(0.0), Cbb1(0.0), Cbd1(0.0);
4988 
4989  double Qac0(0.0), Qsub0(0.0);
4990  double dQac0_dVg(0.0), dQac0_dVb(0.0), dQsub0_dVg(0.0), dQsub0_dVd(0.0), dQsub0_dVb(0.0);
4991  double von_local(0.0);
4992 
4993  ScalingFactor = 1.0e-9;
4994 
4995  // Don't do charge computations in DC sweeps.
4996  if (getSolverState().tranopFlag || getSolverState().acopFlag || getSolverState().transientFlag)
4997  {
4998  ChargeComputationNeeded = true;
4999  }
5000  else
5001  {
5002  ChargeComputationNeeded = false;
5003  }
5004 
5005  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5006  {
5007  Xyce::dout() << subsection_divider << std::endl;
5008  Xyce::dout() << " Instance::updateIntermediateVars\n";
5009  Xyce::dout() << " name = " << getName();
5010  Xyce::dout() << " model name = " << model_.getName();
5011  Xyce::dout() <<" dtype is " << model_.dtype << std::endl;
5012  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
5013  Xyce::dout() << " " << std::endl;
5014  }
5015 
5016  int Check = 1;
5017 
5018  // The first block of code in b3ld.c basically sets up, locally,
5019  // what the load function should use as values for the various solution
5020  // variables. There is a series of IF statements which are dependent
5021  // upon the mode. (transient, initializing transient, operating point,
5022  // small signal, etc.). Xyce treats the operating point and transient
5023  // calculation in the same way, from the device's point of view, and
5024  // we don't support any of the other modes. Therefore most of these
5025  // mode options are not here - only the transient mode stuff.
5026 
5027  // First get some of the needed solution variables:
5028  Vd = 0.0;
5029  Vs = 0.0;
5030  Vg = 0.0;
5031  Vb = 0.0;
5032  Vsp = 0.0;
5033  Vdp = 0.0;
5034  Qtotal = 0.0;
5035 
5042  if( nqsMod )
5043  {
5045  }
5046  else
5047  {
5048  Qtotal = 0.0;
5049  }
5050 
5051  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5052  {
5053  Xyce::dout() << " Vg = " << Vg << std::endl;
5054  Xyce::dout() << " Vb = " << Vb << std::endl;
5055  Xyce::dout() << " Vs = " << Vs << std::endl;
5056  Xyce::dout() << " Vd = " << Vd << std::endl;
5057  Xyce::dout() << " Vsp = " << Vsp << std::endl;
5058  Xyce::dout() << " Vdp = " << Vdp << std::endl;
5059  Xyce::dout() << " Qtotal = " << Qtotal << std::endl;
5060  }
5061 
5062  Vddp = Vd - Vdp;
5063  Vssp = Vs - Vsp;
5064  Vbsp = Vb - Vsp;
5065  Vbdp = Vb - Vdp;
5066  Vgsp = Vg - Vsp;
5067  Vgdp = Vg - Vdp;
5068  Vgb = Vg - Vb;
5069 
5070  Vdpsp = Vdp - Vsp;
5071 
5072  // modified from b3ld: (see lines 221-230)
5073  vbs = model_.dtype * Vbsp;
5074  vgs = model_.dtype * Vgsp;
5075  vds = model_.dtype * Vdpsp;
5076 
5077  qdef = model_.dtype * Qtotal;
5078 
5079  vbd = vbs - vds;
5080  vgd = vgs - vds;
5081 
5082  origFlag = 1;
5083  limitedFlag = false;
5084  vgs_orig = vgs;
5085  vds_orig = vds;
5086  vbs_orig = vbs;
5087  vbd_orig = vbd;
5088  vgd_orig = vgd;
5089 
5090  // What follows is a block of code designed to impose some limits,
5091  // or initial conditions on the junction voltages. Initial conditions
5092  // should only be imposed on the first Newton step of an operating point.
5093  //
5094  // The first possible limit on the junction voltages has to do with
5095  // limiting the percent change of junction voltages between Newton
5096  // iterations. The second has to do with avoiding extra floating point
5097  // operations in the event that the device has in some sense converged
5098  // (aka BYPASS). Although the primary point of BYPASS is to reduce
5099  // neccessary work, it also seems to reduce the number of Newton iterations.
5100  //
5101  // NOTE: We do not support BYPASS.
5102  //
5103  // The "old" variables should be the values for the previous
5104  // Newton iteration, if indeed there was a previous Newton
5105  // iteration. If not, just set the old values equal to
5106  // the current ones.
5107  //
5108 
5109  // set an initial condition if appropriate:
5110  if (getSolverState().initJctFlag_ && !OFF && getDeviceOptions().voltageLimiterFlag)
5111  {
5112  if (getSolverState().inputOPFlag)
5113  {
5114  Linear::Vector * flagSolVectorPtr = extData.flagSolVectorPtr;
5115  if ((*flagSolVectorPtr)[li_Drain] == 0 || (*flagSolVectorPtr)[li_Gate] == 0 ||
5116  (*flagSolVectorPtr)[li_Source] == 0 || (*flagSolVectorPtr)[li_SourcePrime] == 0 ||
5117  (*flagSolVectorPtr)[li_DrainPrime] == 0 || (*flagSolVectorPtr)[li_Bulk] == 0 )
5118  {
5119  vbs = 0.0;
5120  vgs = model_.dtype * paramPtr->vth0 + 0.1;
5121  vds = 0.1;
5122  origFlag = 0;
5123  }
5124  }
5125  else
5126  {
5127  vbs = 0.0;
5128  vgs = model_.dtype * paramPtr->vth0 + 0.1;
5129  vds = 0.1;
5130  origFlag = 0;
5131  }
5132  vbd = vbs - vds;
5133  vgd = vgs - vds;
5134  //origFlag = 0;
5135  }
5136  else if ((getSolverState().initFixFlag || getSolverState().initJctFlag_) && OFF)
5137  {
5138  qdef = vbs = vgs = vds = 0;
5139  }
5140 
5141 
5142  if (getSolverState().newtonIter == 0)
5143  {
5144 
5145  if (!getSolverState().dcopFlag || (getSolverState().locaEnabledFlag && getSolverState().dcopFlag))
5146  // ie, first newton step of a transient time step or DCOP continuation step.
5147  {
5152  von_local = (extData.currStoVectorRawPtr)[li_store_von];
5153  }
5154  else
5155  { // no history
5156  vbs_old = vbs;
5157  vbd_old = vbd;
5158  vgs_old = vgs;
5159  vds_old = vds;
5160  von_local = 0.0;
5161  }
5162  }
5163  else
5164  {
5169  von_local = (extData.nextStoVectorRawPtr)[li_store_von];
5170  }
5171 
5172  vgdo = vgs_old - vds_old;
5173 
5174  // This next block performs checks on the junction voltages and
5175  // imposes limits on them if they are too big.
5176  // Note: In the level=1 von is multiplied by dtype. Here it is not. They
5177  // are both right.
5178 
5180  {
5181 
5182  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5183  {
5184  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
5185  Xyce::dout() << " von_local = " << von_local << std::endl;
5186  Xyce::dout() << " CONSTvt0 = " << CONSTvt0 << std::endl;
5187  Xyce::dout() << " vcrit = " << model_.vcrit << std::endl;
5188  Xyce::dout().width(3);
5189  Xyce::dout() << getSolverState().newtonIter;
5190  Xyce::dout().width(5);Xyce::dout() << getName();
5191  Xyce::dout() << " old :";
5192  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5193  Xyce::dout() << vgs_old;
5194  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5195  Xyce::dout() << vds_old;
5196  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5197  Xyce::dout() << vbs_old;
5198  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5199  Xyce::dout() << vbd_old << std::endl;
5200  Xyce::dout().width(3);
5201  Xyce::dout() << getSolverState().newtonIter;
5202  Xyce::dout().width(5);Xyce::dout() << getName();
5203  Xyce::dout() << " Blim:";
5204  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5205  Xyce::dout() << vgs;
5206  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5207  Xyce::dout() << vds;
5208  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5209  Xyce::dout() << vbs;
5210  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5211  Xyce::dout() << vbd << std::endl;
5212  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
5213  }
5214 
5215  // only do this if we are beyond the first Newton iteration. On the
5216  // first newton iteration, the "old" values are from a previous time
5217  // step.
5218 
5219  if (getSolverState().newtonIter >= 0)
5220  {
5221  if (vds_old >= 0.0)
5222  {
5223  vgs = devSupport.fetlim( vgs, vgs_old, von_local);
5224  vds = vgs - vgd;
5225  vds = devSupport.limvds( vds, vds_old);
5226  vgd = vgs - vds;
5227  }
5228  else
5229  {
5230  vgd = devSupport.fetlim( vgd, vgdo, von_local);
5231  vds = vgs - vgd;
5232  vds = -devSupport.limvds( -vds, -vds_old );
5233  vgs = vgd + vds;
5234  }
5235 
5236  if (vds >= 0.0)
5237  {
5239  model_.vcrit, &Check);
5240  vbd = vbs - vds;
5241  }
5242  else
5243  {
5245  model_.vcrit, &Check);
5246  vbs = vbd + vds;
5247  }
5248  }
5249 
5250  // set the origFlag:
5251 #ifdef Xyce_NEW_ORIG_TEST
5252  double vgs_diff = fabs(vgs - vgs_orig);
5253  double vds_diff = fabs(vds - vds_orig);
5254  double vbs_diff = fabs(vbs - vbs_orig);
5255  double vgd_diff = fabs(vgd - vgd_orig);
5256 
5257  bool noOrigFlag_vgs = 0;
5258  bool noOrigFlag_vds = 0;
5259  bool noOrigFlag_vbs = 0;
5260  bool noOrigFlag_vgd = 0;
5261 
5262  if (vgs_diff != 0.0)
5263  {
5264  if (vgs_orig != 0.0)
5265  {
5266  if ( fabs(vgs_diff/vgs_orig) > reltol) noOrigFlag_vgs = 1;
5267  }
5268  else
5269  {
5270  if ( fabs(vgs_diff) > voltTol ) noOrigFlag_vgs = 1;
5271  }
5272  }
5273 
5274  if (vds_diff != 0.0)
5275  {
5276  if (vds_orig != 0.0)
5277  {
5278  if ( fabs(vds_diff/vds_orig) > reltol) noOrigFlag_vds = 1;
5279  }
5280  else
5281  {
5282  if ( fabs(vds_diff) > voltTol ) noOrigFlag_vds = 1;
5283  }
5284  }
5285 
5286  if (vbs_diff != 0.0)
5287  {
5288  if (vbs_orig != 0.0)
5289  {
5290  if ( fabs(vbs_diff/vbs_orig) > reltol) noOrigFlag_vbs = 1;
5291  }
5292  else
5293  {
5294  if ( fabs(vbs_diff) > voltTol ) noOrigFlag_vbs = 1;
5295  }
5296  }
5297 
5298  if (vgd_diff != 0.0)
5299  {
5300  if (vgd_orig != 0.0)
5301  {
5302  if ( fabs(vgd_diff/vgd_orig) > reltol) noOrigFlag_vgd = 1;
5303  }
5304  else
5305  {
5306  if ( fabs(vgd_diff) > voltTol ) noOrigFlag_vgd = 1;
5307  }
5308  }
5309 
5310  origFlag = !( noOrigFlag_vgs || noOrigFlag_vds ||
5311  noOrigFlag_vbs || noOrigFlag_vgd);
5312 
5313 #else
5314  if (vgs_orig != vgs || vds_orig != vds ||
5315  vbs_orig != vbs || vbd_orig != vbd || vgd_orig != vgd) origFlag = 0;
5316 #endif
5317 
5318  // for convergence testing:
5319  if (Check == 1) limitedFlag=true;
5320 
5321  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5322  {
5323  Xyce::dout().width(3);
5324  Xyce::dout() << getSolverState().newtonIter;
5325  Xyce::dout().width(5);Xyce::dout() << getName();
5326  Xyce::dout() << " Alim:";
5327  Xyce::dout()<<" vgs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5328  Xyce::dout() << vgs;
5329  Xyce::dout()<<" vds:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5330  Xyce::dout() << vds;
5331  Xyce::dout()<<" vbs:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5332  Xyce::dout() << vbs;
5333  Xyce::dout()<<" vbd:";Xyce::dout().width(10);Xyce::dout().precision(3);Xyce::dout().setf(std::ios::scientific);
5334  Xyce::dout() << vbd;
5335  if (origFlag) Xyce::dout() << " SAME";
5336  else Xyce::dout() << " DIFF";
5337  Xyce::dout() << std::endl;
5338  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
5339  }
5340 
5341  } // getDeviceOptions().voltageLimiterFlag
5342 
5343  // Finished with what would have been the series of CKTmode
5344  // IF statements...
5345 
5346  // file: b3ld.c line: 345
5347  // determine DC current and derivatives
5348  vbd = vbs - vds;
5349  vgd = vgs - vds;
5350  vgb = vgs - vbs;
5351 
5352  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5353  {
5354  Xyce::dout() << " mod type = " << model_.modType << std::endl;
5355  Xyce::dout() << "dtype = " << model_.dtype << std::endl;
5356  Xyce::dout() << " vbs = " << vbs << std::endl;
5357  Xyce::dout() << " vds = " << vds << std::endl;
5358  Xyce::dout() << " vgs = " << vgs << std::endl;
5359 
5360  Xyce::dout() << " vbd = " << vbd << std::endl;
5361  Xyce::dout() << " vgd = " << vgd << std::endl;
5362  Xyce::dout() << " vgb = " << vgs << std::endl;
5363  Xyce::dout() << " qdef = " << qdef << std::endl;
5364  }
5365 
5366  // Source/drain junction diode DC model begins
5367  Nvtm = vtm * model_.jctEmissionCoeff;
5368 
5369  if ((sourceArea <= 0.0) && (sourcePerimeter <= 0.0))
5370  {
5371  SourceSatCurrent = 1.0e-14;
5372  }
5373  else
5374  {
5375  SourceSatCurrent = sourceArea
5377  + sourcePerimeter
5379  }
5380 
5381  if (SourceSatCurrent <= 0.0)
5382  {
5384  cbs = gbs * vbs;
5385  }
5386  else
5387  {
5388  if (model_.ijth == 0.0)
5389  {
5390  evbs = exp(vbs / Nvtm);
5391  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5392  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5393  }
5394  else
5395  {
5396  if (vbs < vjsm)
5397  {
5398  evbs = exp(vbs / Nvtm);
5399  gbs = SourceSatCurrent * evbs / Nvtm + getDeviceOptions().gmin;
5400  cbs = SourceSatCurrent * (evbs - 1.0) + getDeviceOptions().gmin * vbs;
5401  }
5402  else
5403  {
5404  T0 = IsEvjsm / Nvtm;
5405  gbs = T0 + getDeviceOptions().gmin;
5406  cbs = IsEvjsm - SourceSatCurrent
5407  + T0 * (vbs - vjsm)
5408  + getDeviceOptions().gmin * vbs;
5409  }
5410  }
5411  }
5412 
5413  if ((drainArea <= 0.0) && (drainPerimeter <= 0.0))
5414  {
5415  DrainSatCurrent = 1.0e-14;
5416  }
5417  else
5418  {
5419  DrainSatCurrent = drainArea
5421  + drainPerimeter
5423  }
5424 
5425  if (DrainSatCurrent <= 0.0)
5426  {
5428  cbd = gbd * vbd;
5429  }
5430  else
5431  {
5432  if (model_.ijth == 0.0)
5433  {
5434  evbd = exp(vbd / Nvtm);
5435  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5436  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5437  }
5438  else
5439  {
5440  if (vbd < vjdm)
5441  {
5442  evbd = exp(vbd / Nvtm);
5443  gbd = DrainSatCurrent * evbd / Nvtm + getDeviceOptions().gmin;
5444  cbd = DrainSatCurrent * (evbd - 1.0) + getDeviceOptions().gmin * vbd;
5445  }
5446  else
5447  {
5448  T0 = IsEvjdm / Nvtm;
5449  gbd = T0 + getDeviceOptions().gmin;
5450  cbd = IsEvjdm - DrainSatCurrent
5451  + T0 * (vbd - vjdm)
5452  + getDeviceOptions().gmin * vbd;
5453  }
5454  }
5455  }
5456  // End of diode DC model
5457 
5458  if (vds >= 0.0)
5459  { // normal mode
5460  mode = 1;
5461  Vds = vds;
5462  Vgs = vgs;
5463  Vbs = vbs;
5464  }
5465  else
5466  { // inverse mode
5467  mode = -1;
5468  Vds = -vds;
5469  Vgs = vgd;
5470  Vbs = vbd;
5471  }
5472 
5473  // mosfet continuation.
5474  // This idea is based, loosely, on a paper by Jaijeet
5475  // Rosychowdhury. If the artificial parameter flag has been enabled,
5476  // modify Vds and Vgs.
5477  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5478  {
5479  Xyce::dout() << "HOMOTOPY INFO: gainscale = " << getSolverState().gainScale_[blockHomotopyID] << std::endl
5480  << "HOMOTOPY INFO: before vds = " << Vds << std::endl
5481  << "HOMOTOPY INFO: before vgst = " << Vgs << std::endl;
5482  }
5483  if (getSolverState().artParameterFlag_)
5484  {
5485 
5486  double alpha = getSolverState().gainScale_[blockHomotopyID];
5487  if (getDeviceOptions().staggerGainScale)
5488  {
5489  alpha *= (0.3 * randomPerturb + 1.0);
5490  if (alpha > 1.0)
5491  {
5492  alpha = 1.0;
5493  }
5494  }
5495  double vgstConst = getDeviceOptions().vgstConst;
5496  if (getDeviceOptions().randomizeVgstConst)
5497  {
5498  vgstConst *= randomPerturb;
5499  }
5500 
5501  Vds = devSupport.contVds (Vds,getSolverState().nltermScale_, getDeviceOptions().vdsScaleMin);
5502  Vgs = devSupport.contVgst(Vgs, alpha, vgstConst);
5503  }
5504  if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
5505  {
5506  Xyce::dout() << "HOMOTOPY INFO: after vds = " << Vds << std::endl;
5507  Xyce::dout() << "HOMOTOPY INFO: after vgst = " << Vgs << std::endl;
5508  }
5509  // end of mosfet continuation block.
5510 
5511  T0 = Vbs - paramPtr->vbsc - 0.001;
5512  T1global = sqrt(T0 * T0 - 0.004 * paramPtr->vbsc);
5513  Vbseff = paramPtr->vbsc + 0.5 * (T0 + T1global);
5514  dVbseff_dVb = 0.5 * (1.0 + T0 / T1global);
5515 
5516  if (Vbseff < Vbs) Vbseff = Vbs;
5517 
5518  if (Vbseff > 0.0)
5519  {
5520  T0 = paramPtr->phi / (paramPtr->phi + Vbseff);
5521  Phis = paramPtr->phi * T0;
5522  dPhis_dVb = -T0 * T0;
5523  sqrtPhis = paramPtr->phis3 / (paramPtr->phi + 0.5 * Vbseff);
5524  dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / paramPtr->phis3;
5525  }
5526  else
5527  {
5528  Phis = paramPtr->phi - Vbseff;
5529  dPhis_dVb = -1.0;
5530  sqrtPhis = sqrt(Phis);
5531  dsqrtPhis_dVb = -0.5 / sqrtPhis;
5532  }
5533 
5534  Xdep = paramPtr->Xdep0 * sqrtPhis / paramPtr->sqrtPhi;
5535  dXdep_dVb = (paramPtr->Xdep0 / paramPtr->sqrtPhi) * dsqrtPhis_dVb;
5536 
5537  Leff = paramPtr->leff;
5538  Vtm = vtm;
5539  // Vth Calculation
5540  T3 = sqrt(Xdep);
5541  V0 = paramPtr->vbi - paramPtr->phi;
5542 
5543  T0 = paramPtr->dvt2 * Vbseff;
5544  if (T0 >= - 0.5)
5545  {
5546  T1 = 1.0 + T0;
5547  T2 = paramPtr->dvt2;
5548  }
5549  else // Added to avoid any discontinuity problems caused by dvt2
5550  {
5551  T4 = 1.0 / (3.0 + 8.0 * T0);
5552  T1 = (1.0 + 3.0 * T0) * T4;
5553  T2 = paramPtr->dvt2 * T4 * T4;
5554  }
5555 
5556  lt1 = model_.factor1 * T3 * T1;
5557  dlt1_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5558 
5559  T0 = paramPtr->dvt2w * Vbseff;
5560  if (T0 >= - 0.5)
5561  {
5562  T1 = 1.0 + T0;
5563  T2 = paramPtr->dvt2w;
5564  }
5565  else // Added to avoid any discontinuity problems caused by dvt2w
5566  {
5567  T4 = 1.0 / (3.0 + 8.0 * T0);
5568  T1 = (1.0 + 3.0 * T0) * T4;
5569  T2 = paramPtr->dvt2w * T4 * T4;
5570  }
5571 
5572  ltw = model_.factor1 * T3 * T1;
5573  dltw_dVb = model_.factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
5574 
5575  T0 = -0.5 * paramPtr->dvt1 * Leff / lt1;
5576  if (T0 > -CONSTEXP_THRESHOLD)
5577  {
5578  T1 = exp(T0);
5579  Theta0 = T1 * (1.0 + 2.0 * T1);
5580  dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb;
5581  dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5582  }
5583  else
5584  {
5585  T1 = CONSTMIN_EXP;
5586  Theta0 = T1 * (1.0 + 2.0 * T1);
5587  dTheta0_dVb = 0.0;
5588  }
5589 
5590  thetavth = paramPtr->dvt0 * Theta0;
5591  Delt_vth = thetavth * V0;
5592  dDelt_vth_dVb = paramPtr->dvt0 * dTheta0_dVb * V0;
5593 
5594  T0 = -0.5 * paramPtr->dvt1w * paramPtr->weff * Leff / ltw;
5595  if (T0 > -CONSTEXP_THRESHOLD)
5596  {
5597  T1 = exp(T0);
5598  T2 = T1 * (1.0 + 2.0 * T1);
5599  dT1_dVb = -T0 / ltw * T1 * dltw_dVb;
5600  dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
5601  }
5602  else
5603  {
5604  T1 = CONSTMIN_EXP;
5605  T2 = T1 * (1.0 + 2.0 * T1);
5606  dT2_dVb = 0.0;
5607  }
5608 
5609  T0 = paramPtr->dvt0w * T2;
5610  T2 = T0 * V0;
5611  dT2_dVb = paramPtr->dvt0w * dT2_dVb * V0;
5612 
5613  TempRatio = temp / model_.tnom - 1.0;
5614  T0 = sqrt(1.0 + paramPtr->nlx / Leff);
5615  T1 = paramPtr->k1ox * (T0 - 1.0) * paramPtr->sqrtPhi
5616  + (paramPtr->kt1 + paramPtr->kt1l / Leff
5617  + paramPtr->kt2 * Vbseff) * TempRatio;
5618 
5619  tmp2 = model_.tox * paramPtr->phi / (paramPtr->weff + paramPtr->w0);
5620 
5621  T3 = paramPtr->eta0 + paramPtr->etab * Vbseff;
5622  if (T3 < 1.0e-4) // avoid discontinuity problems caused by etab
5623  {
5624  T9 = 1.0 / (3.0 - 2.0e4 * T3);
5625  T3 = (2.0e-4 - T3) * T9;
5626  T4 = T9 * T9;
5627  }
5628  else
5629  {
5630  T4 = 1.0;
5631  }
5632 
5633  dDIBL_Sft_dVd = T3 * paramPtr->theta0vb0;
5634  DIBL_Sft = dDIBL_Sft_dVd * Vds;
5635 
5636  Vth = model_.dtype * paramPtr->vth0 - paramPtr->k1
5637  * paramPtr->sqrtPhi + paramPtr->k1ox * sqrtPhis
5638  - paramPtr->k2ox * Vbseff - Delt_vth - T2 + (paramPtr->k3
5639  + paramPtr->k3b * Vbseff) * tmp2 + T1 - DIBL_Sft;
5640 
5641  von = Vth;
5642 
5643  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb - paramPtr->k2ox
5644  - dDelt_vth_dVb - dT2_dVb + paramPtr->k3b * tmp2
5645  - paramPtr->etab * Vds * paramPtr->theta0vb0 * T4
5646  + paramPtr->kt2 * TempRatio;
5647 
5648  dVth_dVd = -dDIBL_Sft_dVd;
5649 
5650  // Calculate n
5651  tmp2 = paramPtr->nfactor * CONSTEPSSI / Xdep;
5652  tmp3 = paramPtr->cdsc + paramPtr->cdscb * Vbseff
5653  + paramPtr->cdscd * Vds;
5654  tmp4 = (tmp2 + tmp3 * Theta0 + paramPtr->cit) / model_.cox;
5655 
5656  if (tmp4 >= -0.5)
5657  {
5658  n = 1.0 + tmp4;
5659  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5660  + paramPtr->cdscb * Theta0) / model_.cox;
5661  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox;
5662  }
5663  else // avoid discontinuity problems caused by tmp4
5664  {
5665  T0 = 1.0 / (3.0 + 8.0 * tmp4);
5666  n = (1.0 + 3.0 * tmp4) * T0;
5667  T0 *= T0;
5668  dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
5669  + paramPtr->cdscb * Theta0) / model_.cox * T0;
5670  dn_dVd = paramPtr->cdscd * Theta0 / model_.cox * T0;
5671  }
5672 
5673  // Poly Gate Si Depletion Effect
5674  T0 = paramPtr->vfb + paramPtr->phi;
5675 
5676  // added to avoid the problem caused by ngate
5677  if ((paramPtr->ngate > 1.e18) && (paramPtr->ngate < 1.e25) && (Vgs > T0))
5678  {
5679  T1 = 1.0e6 * CONSTQ * CONSTEPSSI * paramPtr->ngate
5680  / (model_.cox * model_.cox);
5681  T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1);
5682 
5683  T2 = T1 * (T4 - 1.0);
5684  T3 = 0.5 * T2 * T2 / T1; // T3 = Vpoly
5685  T7 = 1.12 - T3 - 0.05;
5686  T6 = sqrt(T7 * T7 + 0.224);
5687  T5 = 1.12 - 0.5 * (T7 + T6);
5688  Vgs_eff = Vgs - T5;
5689  dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6);
5690  }
5691  else
5692  {
5693  Vgs_eff = Vgs;
5694  dVgs_eff_dVg = 1.0;
5695  }
5696  Vgst = Vgs_eff - Vth;
5697 
5698  // Effective Vgst (Vgsteff) Calculation
5699  T10 = 2.0 * n * Vtm;
5700  VgstNVt = Vgst / T10;
5701  ExpArg = (2.0 * paramPtr->voff - Vgst) / T10;
5702 
5703  // MCJ: Very small Vgst
5704  if (VgstNVt > CONSTEXP_THRESHOLD)
5705  {
5706  Vgsteff = Vgst;
5707  dVgsteff_dVg = dVgs_eff_dVg;
5708  dVgsteff_dVd = -dVth_dVd;
5709  dVgsteff_dVb = -dVth_dVb;
5710  }
5711  else if (ExpArg > CONSTEXP_THRESHOLD)
5712  {
5713  T0 = (Vgst - paramPtr->voff) / (n * Vtm);
5714  ExpVgst = exp(T0);
5715  Vgsteff = Vtm * paramPtr->cdep0 / model_.cox * ExpVgst;
5716  dVgsteff_dVg = Vgsteff / (n * Vtm);
5717  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd);
5718  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb);
5719  dVgsteff_dVg *= dVgs_eff_dVg;
5720  }
5721  else
5722  {
5723  ExpVgst = exp(VgstNVt);
5724  T1 = T10 * log(1.0 + ExpVgst);
5725  dT1_dVg = ExpVgst / (1.0 + ExpVgst);
5726  dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb;
5727  dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd;
5728 
5729  dT2_dVg = -model_.cox / (Vtm * paramPtr->cdep0) * exp(ExpArg);
5730  T2 = 1.0 - T10 * dT2_dVg;
5731 
5732  dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd)
5733  + (T2 - 1.0) / n * dn_dVd;
5734 
5735  dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb)
5736  + (T2 - 1.0) / n * dn_dVb;
5737 
5738  Vgsteff = T1 / T2;
5739  T3 = T2 * T2;
5740 
5741  dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg;
5742  dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3;
5743  dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3;
5744  }
5745 
5746  // Calculate Effective Channel Geometry
5747  T9 = sqrtPhis - paramPtr->sqrtPhi;
5748  Weff = paramPtr->weff -2.0 *(paramPtr->dwg * Vgsteff + paramPtr->dwb * T9);
5749  dWeff_dVg = -2.0 * paramPtr->dwg;
5750  dWeff_dVb = -2.0 * paramPtr->dwb * dsqrtPhis_dVb;
5751 
5752  if (Weff < 2.0e-8) // to avoid the discontinuity problem due to Weff
5753  {
5754  T0 = 1.0 / (6.0e-8 - 2.0 * Weff);
5755  Weff = 2.0e-8 * (4.0e-8 - Weff) * T0;
5756  T0 *= T0 * 4.0e-16;
5757  dWeff_dVg *= T0;
5758  dWeff_dVb *= T0;
5759  }
5760 
5761  T0 = paramPtr->prwg * Vgsteff + paramPtr->prwb * T9;
5762  if (T0 >= -0.9)
5763  {
5764  Rds = paramPtr->rds0 * (1.0 + T0);
5765  dRds_dVg = paramPtr->rds0 * paramPtr->prwg;
5766  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb;
5767  }
5768  else // to avoid the discontinuity problem due to prwg and prwb
5769  {
5770  T1 = 1.0 / (17.0 + 20.0 * T0);
5771  Rds = paramPtr->rds0 * (0.8 + T0) * T1;
5772  T1 *= T1;
5773  dRds_dVg = paramPtr->rds0 * paramPtr->prwg * T1;
5774  dRds_dVb = paramPtr->rds0 * paramPtr->prwb * dsqrtPhis_dVb * T1;
5775  }
5776 
5777  // Calculate Abulk
5778  T1 = 0.5 * paramPtr->k1ox / sqrtPhis;
5779  dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb;
5780 
5781  T9 = sqrt(paramPtr->xj * Xdep);
5782  tmp1 = Leff + 2.0 * T9;
5783  T5 = Leff / tmp1;
5784  tmp2 = paramPtr->a0 * T5;
5785  tmp3 = paramPtr->weff + paramPtr->b1;
5786  tmp4 = paramPtr->b0 / tmp3;
5787  T2 = tmp2 + tmp4;
5788  dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb;
5789  T6 = T5 * T5;
5790  T7 = T5 * T6;
5791 
5792  Abulk0 = 1.0 + T1 * T2;
5793  dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb;
5794 
5795  T8 = paramPtr->ags * paramPtr->a0 * T7;
5796  dAbulk_dVg = -T1 * T8;
5797  Abulk = Abulk0 + dAbulk_dVg * Vgsteff;
5798  dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb);
5799 
5800  if (Abulk0 < 0.1) // added to avoid the problems caused by Abulk0
5801  {
5802  T9 = 1.0 / (3.0 - 20.0 * Abulk0);
5803  Abulk0 = (0.2 - Abulk0) * T9;
5804  dAbulk0_dVb *= T9 * T9;
5805  }
5806 
5807  if (Abulk < 0.1) // added to avoid the problems caused by Abulk
5808  {
5809  T9 = 1.0 / (3.0 - 20.0 * Abulk);
5810  Abulk = (0.2 - Abulk) * T9;
5811  T10 = T9 * T9;
5812  dAbulk_dVb *= T10;
5813  dAbulk_dVg *= T10;
5814  }
5815 
5816  T2 = paramPtr->keta * Vbseff;
5817  if (T2 >= -0.9)
5818  {
5819  T0 = 1.0 / (1.0 + T2);
5820  dT0_dVb = -paramPtr->keta * T0 * T0;
5821  }
5822  else // added to avoid the problems caused by Keta
5823  {
5824  T1 = 1.0 / (0.8 + T2);
5825  T0 = (17.0 + 20.0 * T2) * T1;
5826  dT0_dVb = -paramPtr->keta * T1 * T1;
5827  }
5828 
5829  dAbulk_dVg *= T0;
5830  dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb;
5831  dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb;
5832  Abulk *= T0;
5833  Abulk0 *= T0;
5834 
5835  // Mobility calculation
5836  if (model_.mobMod == 1)
5837  {
5838  T0 = Vgsteff + Vth + Vth;
5839  T2 = paramPtr->ua + paramPtr->uc * Vbseff;
5840  T3 = T0 / model_.tox;
5841  T5 = T3 * (T2 + paramPtr->ub * T3);
5842  dDenomi_dVg = (T2 + 2.0 * paramPtr->ub * T3) / model_.tox;
5843  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5844  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T3;
5845  }
5846  else if (model_.mobMod == 2)
5847  {
5848  T5 = Vgsteff / model_.tox * (paramPtr->ua
5849  + paramPtr->uc * Vbseff + paramPtr->ub * Vgsteff / model_.tox);
5850 
5851  dDenomi_dVg = (paramPtr->ua + paramPtr->uc * Vbseff
5852  + 2.0 * paramPtr->ub * Vgsteff / model_.tox) / model_.tox;
5853 
5854  dDenomi_dVd = 0.0;
5855  dDenomi_dVb = Vgsteff * paramPtr->uc / model_.tox;
5856  }
5857  else
5858  {
5859  T0 = Vgsteff + Vth + Vth;
5860  T2 = 1.0 + paramPtr->uc * Vbseff;
5861  T3 = T0 / model_.tox;
5862  T4 = T3 * (paramPtr->ua + paramPtr->ub * T3);
5863  T5 = T4 * T2;
5864 
5865  dDenomi_dVg = (paramPtr->ua + 2.0 * paramPtr->ub * T3) * T2 /model_.tox;
5866  dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
5867  dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + paramPtr->uc * T4;
5868  }
5869 
5870  if (T5 >= -0.8)
5871  {
5872  Denomi = 1.0 + T5;
5873  }
5874  else // Added to avoid the discontinuity problem caused by ua and ub
5875  {
5876  T9 = 1.0 / (7.0 + 10.0 * T5);
5877  Denomi = (0.6 + T5) * T9;
5878  T9 *= T9;
5879  dDenomi_dVg *= T9;
5880  dDenomi_dVd *= T9;
5881  dDenomi_dVb *= T9;
5882  }
5883 
5884  ueff = paramPtr->u0temp / Denomi;
5885  T9 = -ueff / Denomi;
5886  dueff_dVg = T9 * dDenomi_dVg;
5887  dueff_dVd = T9 * dDenomi_dVd;
5888  dueff_dVb = T9 * dDenomi_dVb;
5889 
5890  // Saturation Drain Voltage Vdsat
5891  WVCox = Weff * paramPtr->vsattemp * model_.cox;
5892  WVCoxRds = WVCox * Rds;
5893 
5894  Esat = 2.0 * paramPtr->vsattemp / ueff;
5895  EsatL = Esat * Leff;
5896  T0 = -EsatL /ueff;
5897  dEsatL_dVg = T0 * dueff_dVg;
5898  dEsatL_dVd = T0 * dueff_dVd;
5899  dEsatL_dVb = T0 * dueff_dVb;
5900 
5901  // Sqrt()
5902  a1 = paramPtr->a1;
5903  if (a1 == 0.0)
5904  {
5905  Lambda = paramPtr->a2;
5906  dLambda_dVg = 0.0;
5907  }
5908  else if (a1 > 0.0) // Added to avoid the discontinuity problem
5909  // caused by a1 and a2 (Lambda)
5910  {
5911  T0 = 1.0 - paramPtr->a2;
5912  T1 = T0 - paramPtr->a1 * Vgsteff - 0.0001;
5913  T2 = sqrt(T1 * T1 + 0.0004 * T0);
5914  Lambda = paramPtr->a2 + T0 - 0.5 * (T1 + T2);
5915  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5916  }
5917  else
5918  {
5919  T1 = paramPtr->a2 + paramPtr->a1 * Vgsteff - 0.0001;
5920  T2 = sqrt(T1 * T1 + 0.0004 * paramPtr->a2);
5921  Lambda = 0.5 * (T1 + T2);
5922  dLambda_dVg = 0.5 * paramPtr->a1 * (1.0 + T1 / T2);
5923  }
5924 
5925  Vgst2Vtm = Vgsteff + 2.0 * Vtm;
5926  if (Rds > 0)
5927  {
5928  tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff;
5929  tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff;
5930  }
5931  else
5932  {
5933  tmp2 = dWeff_dVg / Weff;
5934  tmp3 = dWeff_dVb / Weff;
5935  }
5936 
5937  if ((Rds == 0.0) && (Lambda == 1.0))
5938  {
5939  T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm);
5940  tmp1 = 0.0;
5941  T1 = T0 * T0;
5942  T2 = Vgst2Vtm * T0;
5943  T3 = EsatL * Vgst2Vtm;
5944  Vdsat = T3 * T0;
5945 
5946  dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1;
5947  dT0_dVd = -(Abulk * dEsatL_dVd) * T1;
5948  dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1;
5949 
5950  dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0;
5951  dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd;
5952  dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb;
5953  }
5954  else
5955  {
5956  tmp1 = dLambda_dVg / (Lambda * Lambda);
5957  T9 = Abulk * WVCoxRds;
5958  T8 = Abulk * T9;
5959  T7 = Vgst2Vtm * T9;
5960  T6 = Vgst2Vtm * WVCoxRds;
5961  T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda);
5962  dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1
5963  + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg);
5964 
5965  dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3)
5966  + (1.0 / Lambda - 1.0) * dAbulk_dVb);
5967  dT0_dVd = 0.0;
5968  T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7;
5969 
5970  dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1
5971  + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9
5972  + T7 * tmp2 + T6 * dAbulk_dVg);
5973 
5974  dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb
5975  + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3);
5976 
5977  dT1_dVd = Abulk * dEsatL_dVd;
5978 
5979  T2 = Vgst2Vtm * (EsatL + 2.0 * T6);
5980  dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg
5981  + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2);
5982 
5983  dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3);
5984  dT2_dVd = Vgst2Vtm * dEsatL_dVd;
5985 
5986  T3 = sqrt(T1 * T1 - 2.0 * T0 * T2);
5987  Vdsat = (T1 - T3) / T0;
5988 
5989  dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3;
5990  dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3;
5991  dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3;
5992 
5993  dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2
5994  - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0;
5995 
5996  dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2
5997  - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0;
5998 
5999  dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0;
6000  }
6001  vdsat = Vdsat;
6002 
6003  // Effective Vds (Vdseff) Calculation
6004  T1 = Vdsat - Vds - paramPtr->delta;
6005  dT1_dVg = dVdsat_dVg;
6006  dT1_dVd = dVdsat_dVd - 1.0;
6007  dT1_dVb = dVdsat_dVb;
6008 
6009  T2 = sqrt(T1 * T1 + 4.0 * paramPtr->delta * Vdsat);
6010  T0 = T1 / T2;
6011  T3 = 2.0 * paramPtr->delta / T2;
6012  dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg;
6013  dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd;
6014  dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb;
6015 
6016  Vdseff = Vdsat - 0.5 * (T1 + T2);
6017  dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg);
6018  dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd);
6019  dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb);
6020 
6021  // Added to eliminate non-zero Vdseff at Vds=0.0
6022  if (Vds == 0.0)
6023  {
6024  Vdseff = 0.0;
6025  dVdseff_dVg = 0.0;
6026  dVdseff_dVb = 0.0;
6027  }
6028 
6029  // Calculate VAsat
6030  tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm;
6031  T9 = WVCoxRds * Vgsteff;
6032  T8 = T9 / Vgst2Vtm;
6033  T0 = EsatL + Vdsat + 2.0 * T9 * tmp4;
6034 
6035  T7 = 2.0 * WVCoxRds * tmp4;
6036  dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff)
6037  - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm
6038  + Vdsat * dAbulk_dVg);
6039 
6040  dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff
6041  - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
6042  dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd;
6043 
6044  T9 = WVCoxRds * Abulk;
6045  T1 = 2.0 / Lambda - 1.0 + T9;
6046  dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg);
6047  dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3;
6048 
6049  Vasat = T0 / T1;
6050  dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1;
6051  dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1;
6052  dVasat_dVd = dT0_dVd / T1;
6053 
6054  if (Vdseff > Vds) Vdseff = Vds;
6055 
6056  diffVds = Vds - Vdseff;
6057 
6058  // Calculate VACLM
6059  if ((paramPtr->pclm > 0.0) && (diffVds > 1.0e-10))
6060  {
6061  T0 = 1.0 / (paramPtr->pclm * Abulk * paramPtr->litl);
6062  dT0_dVb = -T0 / Abulk * dAbulk_dVb;
6063  dT0_dVg = -T0 / Abulk * dAbulk_dVg;
6064 
6065  T2 = Vgsteff / EsatL;
6066  T1 = Leff * (Abulk + T2);
6067  dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg);
6068  dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL);
6069  dT1_dVd = -T2 * dEsatL_dVd / Esat;
6070 
6071  T9 = T0 * T1;
6072  VACLM = T9 * diffVds;
6073  dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg
6074  + T1 * diffVds * dT0_dVg;
6075 
6076  dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds
6077  - T9 * dVdseff_dVb;
6078 
6079  dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd);
6080  }
6081  else
6082  {
6083  VACLM = CONSTMAX_EXP;
6084  dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0;
6085  }
6086 
6087  // Calculate VADIBL
6088  if (paramPtr->thetaRout > 0.0)
6089  {
6090  T8 = Abulk * Vdsat;
6091  T0 = Vgst2Vtm * T8;
6092  dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8
6093  + Vgst2Vtm * Vdsat * dAbulk_dVg;
6094 
6095  dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);
6096  dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd;
6097 
6098  T1 = Vgst2Vtm + T8;
6099  dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg;
6100  dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat;
6101  dT1_dVd = Abulk * dVdsat_dVd;
6102 
6103  T9 = T1 * T1;
6104  T2 = paramPtr->thetaRout;
6105 
6106  VADIBL = (Vgst2Vtm - T0 / T1) / T2;
6107  dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2;
6108  dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2;
6109  dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2;
6110 
6111  T7 = paramPtr->pdiblb * Vbseff;
6112  if (T7 >= -0.9)
6113  {
6114  T3 = 1.0 / (1.0 + T7);
6115  VADIBL *= T3;
6116  dVADIBL_dVg *= T3;
6117  dVADIBL_dVb = (dVADIBL_dVb - VADIBL * paramPtr->pdiblb) * T3;
6118  dVADIBL_dVd *= T3;
6119  }
6120  else // Added to avoid the discontinuity problem caused by pdiblcb
6121  {
6122  T4 = 1.0 / (0.8 + T7);
6123  T3 = (17.0 + 20.0 * T7) * T4;
6124  dVADIBL_dVg *= T3;
6125  dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * paramPtr->pdiblb * T4 * T4;
6126 
6127  dVADIBL_dVd *= T3;
6128  VADIBL *= T3;
6129  }
6130  }
6131  else
6132  {
6133  VADIBL = CONSTMAX_EXP;
6134  dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0;
6135  }
6136 
6137  // Calculate VA
6138  T8 = paramPtr->pvag / EsatL;
6139  T9 = T8 * Vgsteff;
6140  if (T9 > -0.9)
6141  {
6142  T0 = 1.0 + T9;
6143  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL);
6144  dT0_dVb = -T9 * dEsatL_dVb / EsatL;
6145  dT0_dVd = -T9 * dEsatL_dVd / EsatL;
6146  }
6147  else /* Added to avoid the discontinuity problems caused by pvag */
6148  {
6149  T1 = 1.0 / (17.0 + 20.0 * T9);
6150  T0 = (0.8 + T9) * T1;
6151  T1 *= T1;
6152  dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1;
6153 
6154  T9 *= T1 / EsatL;
6155  dT0_dVb = -T9 * dEsatL_dVb;
6156  dT0_dVd = -T9 * dEsatL_dVd;
6157  }
6158 
6159  tmp1 = VACLM * VACLM;
6160  tmp2 = VADIBL * VADIBL;
6161  tmp3 = VACLM + VADIBL;
6162 
6163  T1 = VACLM * VADIBL / tmp3;
6164  tmp3 *= tmp3;
6165  dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3;
6166  dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3;
6167  dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3;
6168 
6169  Va = Vasat + T0 * T1;
6170  dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg;
6171  dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd;
6172  dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb;
6173 
6174  // Calculate VASCBE
6175  if (paramPtr->pscbe2 > 0.0)
6176  {
6177  if (diffVds > paramPtr->pscbe1 * paramPtr->litl / CONSTEXP_THRESHOLD)
6178  {
6179  T0 = paramPtr->pscbe1 * paramPtr->litl / diffVds;
6180  VASCBE = Leff * exp(T0) / paramPtr->pscbe2;
6181  T1 = T0 * VASCBE / diffVds;
6182  dVASCBE_dVg = T1 * dVdseff_dVg;
6183  dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd);
6184  dVASCBE_dVb = T1 * dVdseff_dVb;
6185  }
6186  else
6187  {
6188  VASCBE = CONSTMAX_EXP * Leff/paramPtr->pscbe2;
6189  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
6190  }
6191  }
6192  else
6193  {
6194  VASCBE = CONSTMAX_EXP;
6195  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
6196  }
6197 
6198  // Calculate Ids
6199  CoxWovL = model_.cox * Weff / Leff;
6200  beta = ueff * CoxWovL;
6201  dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff;
6202  dbeta_dVd = CoxWovL * dueff_dVd;
6203  dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff;
6204 
6205  T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm;
6206  dT0_dVg = -0.5 * (Abulk * dVdseff_dVg
6207  - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm;
6208  dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm;
6209  dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm;
6210 
6211  fgche1 = Vgsteff * T0;
6212  dfgche1_dVg = Vgsteff * dT0_dVg + T0;
6213  dfgche1_dVd = Vgsteff * dT0_dVd;
6214  dfgche1_dVb = Vgsteff * dT0_dVb;
6215 
6216  T9 = Vdseff / EsatL;
6217  fgche2 = 1.0 + T9;
6218  dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL;
6219  dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL;
6220  dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL;
6221 
6222  gche = beta * fgche1 / fgche2;
6223  dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg
6224  - gche * dfgche2_dVg) / fgche2;
6225 
6226  dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd
6227  - gche * dfgche2_dVd) / fgche2;
6228 
6229  dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb
6230  - gche * dfgche2_dVb) / fgche2;
6231 
6232  T0 = 1.0 + gche * Rds;
6233  T9 = Vdseff / T0;
6234  Idl = gche * T9;
6235 
6236  dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0
6237  - Idl * gche / T0 * dRds_dVg ;
6238 
6239  dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0;
6240  dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb
6241  - Idl * dRds_dVb * gche) / T0;
6242 
6243  T9 = diffVds / Va;
6244  T0 = 1.0 + T9;
6245  Idsa = Idl * T0;
6246  dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va;
6247  dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd
6248  - T9 * dVa_dVd) / Va;
6249 
6250  dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va;
6251 
6252  T9 = diffVds / VASCBE;
6253  T0 = 1.0 + T9;
6254  Ids = Idsa * T0;
6255 
6256  Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE;
6257  Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd
6258  - T9 * dVASCBE_dVd) / VASCBE;
6259  Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb
6260  + T9 * dVASCBE_dVb) / VASCBE;
6261 
6262  Gds += Gm * dVgsteff_dVd;
6263  Gmb += Gm * dVgsteff_dVb;
6264  Gm *= dVgsteff_dVg;
6265  Gmb *= dVbseff_dVb;
6266 
6267  // Substrate current begins
6268  tmp = paramPtr->alpha0 + paramPtr->alpha1 * Leff;
6269  if ((tmp <= 0.0) || (paramPtr->beta0 <= 0.0))
6270  {
6271  Isub = Gbd = Gbb = Gbg = 0.0;
6272  }
6273  else
6274  {
6275  T2 = tmp / Leff;
6276  if (diffVds > paramPtr->beta0 / CONSTEXP_THRESHOLD)
6277  {
6278  T0 = -paramPtr->beta0 / diffVds;
6279  T1 = T2 * diffVds * exp(T0);
6280  T3 = T1 / diffVds * (T0 - 1.0);
6281  dT1_dVg = T3 * dVdseff_dVg;
6282  dT1_dVd = T3 * (dVdseff_dVd - 1.0);
6283  dT1_dVb = T3 * dVdseff_dVb;
6284  }
6285  else
6286  {
6287  T3 = T2 * CONSTMIN_EXP;
6288  T1 = T3 * diffVds;
6289  dT1_dVg = -T3 * dVdseff_dVg;
6290  dT1_dVd = T3 * (1.0 - dVdseff_dVd);
6291  dT1_dVb = -T3 * dVdseff_dVb;
6292  }
6293  Isub = T1 * Idsa;
6294  Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg;
6295  Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd;
6296  Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb;
6297 
6298  Gbd += Gbg * dVgsteff_dVd;
6299  Gbb += Gbg * dVgsteff_dVb;
6300  Gbg *= dVgsteff_dVg;
6301  Gbb *= dVbseff_dVb; // bug fixing
6302  }
6303 
6304  // copy over local drain (channel) current vars to instance vars:
6305  cdrain = Ids;
6306  gds = Gds;
6307  gm = Gm;
6308  gmbs = Gmb;
6309 
6310  // copy over local substrate current vars to instance vars:
6311  gbbs = Gbb;
6312  gbgs = Gbg;
6313  gbds = Gbd;
6314 
6315  csub = Isub;
6316 
6317  // thermal noise Qinv calculated from all capMod
6318  // * 0, 1, 2 & 3 stored in iterI->qinv 1/1998
6319  if ((model_.xpart < 0) || (!ChargeComputationNeeded))
6320  {
6321  qgate = qdrn = qsrc = qbulk = 0.0;
6322  cggb = cgsb = cgdb = 0.0;
6323  cdgb = cdsb = cddb = 0.0;
6324  cbgb = cbsb = cbdb = 0.0;
6325  cqdb = cqsb = cqgb = cqbb = 0.0;
6326 
6327  gtau = 0.0;
6328  goto finished;
6329  }
6330  else if (model_.capMod == 0)
6331  {
6332  if (Vbseff < 0.0)
6333  {
6334  Vbseff = Vbs;
6335  dVbseff_dVb = 1.0;
6336  }
6337  else
6338  {
6339  Vbseff = paramPtr->phi - Phis;
6340  dVbseff_dVb = -dPhis_dVb;
6341  }
6342 
6343  Vfb = paramPtr->vfbcv;
6344  Vth = Vfb + paramPtr->phi + paramPtr->k1ox * sqrtPhis;
6345  Vgst = Vgs_eff - Vth;
6346  dVth_dVb = paramPtr->k1ox * dsqrtPhis_dVb;
6347  dVgst_dVb = -dVth_dVb;
6349 
6351  Arg1 = Vgs_eff - Vbseff - Vfb;
6352 
6353  if (Arg1 <= 0.0)
6354  {
6355  qgate = CoxWL * Arg1;
6356  qbulk = -qgate;
6357  qdrn = 0.0;
6358 
6359  cggb = CoxWL * dVgs_eff_dVg;
6360  cgdb = 0.0;
6361  cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg);
6362 
6363  cdgb = 0.0;
6364  cddb = 0.0;
6365  cdsb = 0.0;
6366 
6367  cbgb = -CoxWL * dVgs_eff_dVg;
6368  cbdb = 0.0;
6369  cbsb = -cgsb;
6370  qinv = 0.0;
6371  }
6372  else if (Vgst <= 0.0)
6373  {
6374  T1 = 0.5 * paramPtr->k1ox;
6375  T2 = sqrt(T1 * T1 + Arg1);
6376  qgate = CoxWL * paramPtr->k1ox * (T2 - T1);
6377  qbulk = -qgate;
6378  qdrn = 0.0;
6379 
6380  T0 = CoxWL * T1 / T2;
6381  cggb = T0 * dVgs_eff_dVg;
6382  cgdb = 0.0;
6383  cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg);
6384 
6385  cdgb = 0.0;
6386  cddb = 0.0;
6387  cdsb = 0.0;
6388 
6389  cbgb = -cggb;
6390  cbdb = 0.0;
6391  cbsb = -cgsb;
6392  qinv = 0.0;
6393  }
6394  else
6395  {
6396  One_Third_CoxWL = CoxWL / 3.0;
6397  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6398 
6399  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6400  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6401 
6402  Vdsat = Vgst / AbulkCV;
6403  dVdsat_dVg = dVgs_eff_dVg / AbulkCV;
6404  dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV;
6405 
6406  if (model_.xpart > 0.5)
6407  { // 0/100 Charge partition model
6408  if (Vdsat <= Vds)
6409  { // saturation region
6410  T1 = Vdsat / 3.0;
6411  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6412 
6413  T2 = -Two_Third_CoxWL * Vgst;
6414  qbulk = -(qgate + T2);
6415  qdrn = 0.0;
6416 
6417  cggb = One_Third_CoxWL * (3.0 - dVdsat_dVg)* dVgs_eff_dVg;
6418  T2 = -One_Third_CoxWL * dVdsat_dVb;
6419 
6420  cgsb = -(cggb + T2);
6421  cgdb = 0.0;
6422 
6423  cdgb = 0.0;
6424  cddb = 0.0;
6425  cdsb = 0.0;
6426 
6427  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6428  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6429 
6430  cbsb = -(cbgb + T3);
6431  cbdb = 0.0;
6432  qinv = -(qgate + qbulk);
6433  }
6434  else
6435  { // linear region
6436  Alphaz = Vgst / Vdsat;
6437  T1 = 2.0 * Vdsat - Vds;
6438  T2 = Vds / (3.0 * T1);
6439  T3 = T2 * Vds;
6440  T9 = 0.25 * CoxWL;
6441  T4 = T9 * Alphaz;
6442  T7 = 2.0 * Vds - T1 - 3.0 * T3;
6443  T8 = T3 - T1 - 2.0 * Vds;
6444  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6445 
6446  T10 = T4 * T8;
6447  qdrn = T4 * T7;
6448  qbulk = -(qgate + qdrn + T10);
6449 
6450  T5 = T3 / T1;
6451  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6452 
6453  T11 = -CoxWL * T5 * dVdsat_dVb;
6454  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6455  cgsb = -(cggb + T11 + cgdb);
6456 
6457  T6 = 1.0 / Vdsat;
6458  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6459  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6460 
6461  T7 = T9 * T7;
6462  T8 = T9 * T8;
6463  T9 = 2.0 * T4 * (1.0 - 3.0 * T5);
6464  cdgb = (T7 * dAlphaz_dVg - T9* dVdsat_dVg) * dVgs_eff_dVg;
6465 
6466  T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb;
6467  cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5);
6468  cdsb = -(cdgb + T12 + cddb);
6469 
6470  T9 = 2.0 * T4 * (1.0 + T5);
6471  T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) * dVgs_eff_dVg;
6472  T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb;
6473  T12 = T4 * (2.0 * T2 + T5 - 1.0);
6474  T0 = -(T10 + T11 + T12);
6475 
6476 
6477  cbgb = -(cggb + cdgb + T10);
6478  cbdb = -(cgdb + cddb + T12);
6479  cbsb = -(cgsb + cdsb + T0);
6480  qinv = -(qgate + qbulk);
6481  }
6482  }
6483  else if (model_.xpart < 0.5)
6484  { // 40/60 Charge partition model
6485  if (Vds >= Vdsat)
6486  { // saturation region
6487  T1 = Vdsat / 3.0;
6488  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6489 
6490  T2 = -Two_Third_CoxWL * Vgst;
6491  qbulk = -(qgate + T2);
6492  qdrn = 0.4 * T2;
6493 
6494  cggb = One_Third_CoxWL* (3.0 - dVdsat_dVg) * dVgs_eff_dVg;
6495 
6496  T2 = -One_Third_CoxWL * dVdsat_dVb;
6497  cgsb = -(cggb + T2);
6498  cgdb = 0.0;
6499 
6500  T3 = 0.4 * Two_Third_CoxWL;
6501  cdgb = -T3 * dVgs_eff_dVg;
6502  cddb = 0.0;
6503 
6504  T4 = T3 * dVth_dVb;
6505  cdsb = -(T4 + cdgb);
6506 
6507  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6508  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6509  cbsb = -(cbgb + T3);
6510  cbdb = 0.0;
6511  qinv = -(qgate + qbulk);
6512  }
6513  else
6514  { // linear region
6515  Alphaz = Vgst / Vdsat;
6516  T1 = 2.0 * Vdsat - Vds;
6517  T2 = Vds / (3.0 * T1);
6518  T3 = T2 * Vds;
6519  T9 = 0.25 * CoxWL;
6520  T4 = T9 * Alphaz;
6521  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3));
6522 
6523  T5 = T3 / T1;
6524  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6525  tmp = -CoxWL * T5 * dVdsat_dVb;
6526  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6527  cgsb = -(cggb + cgdb + tmp);
6528 
6529  T6 = 1.0 / Vdsat;
6530  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6531  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6532 
6533  T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + 1.2 * Vds * Vds;
6534  T8 = T2 / T1;
6535  T7 = Vds - T1 - T8 * T6;
6536  qdrn = T4 * T7;
6537  T7 *= T9;
6538  tmp = T8 / T1;
6539  tmp1 = T4*(2.0 - 4.0 * tmp * T6 + T8 *(16.0 * Vdsat - 6.0 *Vds));
6540 
6541  cdgb = (T7 *dAlphaz_dVg - tmp1 *dVdsat_dVg) *dVgs_eff_dVg;
6542 
6543  T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb;
6544  cddb = T4 * (2.0 - (1.0 / (3.0 * T1
6545  * T1) + 2.0 * tmp) * T6 + T8
6546  * (6.0 * Vdsat - 2.4 * Vds));
6547 
6548  cdsb = -(cdgb + T10 + cddb);
6549 
6550  T7 = 2.0 * (T1 + T3);
6551  qbulk = -(qgate - T4 * T7);
6552  T7 *= T9;
6553  T0 = 4.0 * T4 * (1.0 - T5);
6554  T12 = (-T7 * dAlphaz_dVg - cdgb
6555  - T0 * dVdsat_dVg) * dVgs_eff_dVg;
6556  T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb;
6557  T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5)
6558  - cddb;
6559 
6560  tmp = -(T10 + T11 + T12);
6561 
6562  cbgb = -(cggb + cdgb + T12);
6563  cbdb = -(cgdb + cddb + T11);
6564  cbsb = -(cgsb + cdsb + tmp);
6565  qinv = -(qgate + qbulk);
6566  }
6567  }
6568  else
6569  { // 50/50 partitioning
6570  if (Vds >= Vdsat)
6571  { // saturation region
6572  T1 = Vdsat / 3.0;
6573  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - T1);
6574  T2 = -Two_Third_CoxWL * Vgst;
6575  qbulk = -(qgate + T2);
6576  qdrn = 0.5 * T2;
6577 
6578  cggb = One_Third_CoxWL * (3.0 -dVdsat_dVg) * dVgs_eff_dVg;
6579  T2 = -One_Third_CoxWL * dVdsat_dVb;
6580  cgsb = -(cggb + T2);
6581  cgdb = 0.0;
6582 
6583  cdgb = -One_Third_CoxWL * dVgs_eff_dVg;
6584  cddb = 0.0;
6585  T4 = One_Third_CoxWL * dVth_dVb;
6586  cdsb = -(T4 + cdgb);
6587 
6588  cbgb = -(cggb - Two_Third_CoxWL * dVgs_eff_dVg);
6589  T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
6590  cbsb = -(cbgb + T3);
6591  cbdb = 0.0;
6592  qinv = -(qgate + qbulk);
6593  }
6594  else
6595  { // linear region
6596  Alphaz = Vgst / Vdsat;
6597  T1 = 2.0 * Vdsat - Vds;
6598  T2 = Vds / (3.0 * T1);
6599  T3 = T2 * Vds;
6600  T9 = 0.25 * CoxWL;
6601  T4 = T9 * Alphaz;
6602  qgate = CoxWL * (Vgs_eff - Vfb - paramPtr->phi - 0.5 * (Vds - T3))
6603  ;
6604 
6605  T5 = T3 / T1;
6606  cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) * dVgs_eff_dVg;
6607 
6608  tmp = -CoxWL * T5 * dVdsat_dVb;
6609  cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
6610  cgsb = -(cggb + cgdb + tmp);
6611 
6612  T6 = 1.0 / Vdsat;
6613  dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
6614  dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
6615 
6616  T7 = T1 + T3;
6617  qdrn = -T4 * T7;
6618  qbulk = - (qgate + qdrn + qdrn);
6619  T7 *= T9;
6620  T0 = T4 * (2.0 * T5 - 2.0);
6621 
6622  cdgb = (T0 * dVdsat_dVg - T7 *dAlphaz_dVg) *dVgs_eff_dVg;
6623  T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb;
6624  cddb = T4 * (1.0 - 2.0 * T2 - T5);
6625  cdsb = -(cdgb + T12 + cddb);
6626 
6627  cbgb = -(cggb + 2.0 * cdgb);
6628  cbdb = -(cgdb + 2.0 * cddb);
6629  cbsb = -(cgsb + 2.0 * cdsb);
6630  qinv = -(qgate + qbulk);
6631  }
6632  }
6633  }
6634  }
6635  else
6636  {
6637  if (Vbseff < 0.0)
6638  {
6639  VbseffCV = Vbseff;
6640  dVbseffCV_dVb = 1.0;
6641  }
6642  else
6643  {
6644  VbseffCV = paramPtr->phi - Phis;
6645  dVbseffCV_dVb = -dPhis_dVb;
6646  }
6647 
6649 
6650  // Seperate VgsteffCV with noff and voffcv
6651  noff = n * paramPtr->noff;
6652  dnoff_dVd = paramPtr->noff * dn_dVd;
6653  dnoff_dVb = paramPtr->noff * dn_dVb;
6654  T0 = Vtm * noff;
6655  voffcv = paramPtr->voffcv;
6656  VgstNVt = (Vgst - voffcv) / T0;
6657 
6658  if (VgstNVt > CONSTEXP_THRESHOLD)
6659  {
6660  Vgsteff = Vgst - voffcv;
6661  dVgsteff_dVg = dVgs_eff_dVg;
6662  dVgsteff_dVd = -dVth_dVd;
6663  dVgsteff_dVb = -dVth_dVb;
6664  }
6665  else if (VgstNVt < -CONSTEXP_THRESHOLD)
6666  {
6667  Vgsteff = T0 * log(1.0 + CONSTMIN_EXP);
6668  dVgsteff_dVg = 0.0;
6669  dVgsteff_dVd = Vgsteff / noff;
6670  dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb;
6671  dVgsteff_dVd *= dnoff_dVd;
6672  }
6673  else
6674  {
6675  ExpVgst = exp(VgstNVt);
6676  Vgsteff = T0 * log(1.0 + ExpVgst);
6677  dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst);
6678  dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv)
6679  / noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd;
6680  dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv)
6681  / noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb;
6682  dVgsteff_dVg *= dVgs_eff_dVg;
6683  } // End of VgsteffCV
6684 
6685  if (model_.capMod == 1)
6686  {
6687  Vfb = paramPtr->vfbzb;
6688  Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff;
6689 
6690  if (Arg1 <= 0.0)
6691  {
6692  qgate = CoxWL * Arg1;
6693  Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg);
6694  Cgd = -CoxWL * dVgsteff_dVd;
6695  Cgb = -CoxWL * (dVbseffCV_dVb + dVgsteff_dVb);
6696  }
6697  else
6698  {
6699  T0 = 0.5 * paramPtr->k1ox;
6700  T1 = sqrt(T0 * T0 + Arg1);
6701  T2 = CoxWL * T0 / T1;
6702 
6703  qgate = CoxWL * paramPtr->k1ox * (T1 - T0);
6704 
6705  Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg);
6706  Cgd = -T2 * dVgsteff_dVd;
6707  Cgb = -T2 * (dVbseffCV_dVb + dVgsteff_dVb);
6708  }
6709  qbulk = -qgate;
6710  Cbg = -Cgg;
6711  Cbd = -Cgd;
6712  Cbb = -Cgb;
6713 
6714  One_Third_CoxWL = CoxWL / 3.0;
6715  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
6716  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6717  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6718  VdsatCV = Vgsteff / AbulkCV;
6719 
6720  if (VdsatCV < Vds)
6721  {
6722  dVdsatCV_dVg = 1.0 / AbulkCV;
6723  dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV;
6724  T0 = Vgsteff - VdsatCV / 3.0;
6725  dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0;
6726  dT0_dVb = -dVdsatCV_dVb / 3.0;
6727  qgate += CoxWL * T0;
6728  Cgg1 = CoxWL * dT0_dVg;
6729  Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb;
6730  Cgd1 = Cgg1 * dVgsteff_dVd;
6731  Cgg1 *= dVgsteff_dVg;
6732  Cgg += Cgg1;
6733  Cgb += Cgb1;
6734  Cgd += Cgd1;
6735 
6736  T0 = VdsatCV - Vgsteff;
6737  dT0_dVg = dVdsatCV_dVg - 1.0;
6738  dT0_dVb = dVdsatCV_dVb;
6739  qbulk += One_Third_CoxWL * T0;
6740  Cbg1 = One_Third_CoxWL * dT0_dVg;
6741  Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb;
6742  Cbd1 = Cbg1 * dVgsteff_dVd;
6743  Cbg1 *= dVgsteff_dVg;
6744  Cbg += Cbg1;
6745  Cbb += Cbb1;
6746  Cbd += Cbd1;
6747 
6748  if (model_.xpart > 0.5) T0 = -Two_Third_CoxWL;
6749  else if (model_.xpart < 0.5) T0 = -0.4 * CoxWL;
6750  else T0 = -One_Third_CoxWL;
6751 
6752  qsrc = T0 * Vgsteff;
6753  Csg = T0 * dVgsteff_dVg;
6754  Csb = T0 * dVgsteff_dVb;
6755  Csd = T0 * dVgsteff_dVd;
6756  Cgb *= dVbseff_dVb;
6757  Cbb *= dVbseff_dVb;
6758  Csb *= dVbseff_dVb;
6759  }
6760  else
6761  {
6762  T0 = AbulkCV * Vds;
6763  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20);
6764  T2 = Vds / T1;
6765  T3 = T0 * T2;
6766  dT3_dVg = -12.0 * T2 * T2 * AbulkCV;
6767  dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5;
6768  dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff;
6769 
6770  qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3);
6771  Cgg1 = CoxWL * (1.0 + dT3_dVg);
6772  Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb;
6773  Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd;
6774  Cgg1 *= dVgsteff_dVg;
6775  Cgg += Cgg1;
6776  Cgb += Cgb1;
6777  Cgd += Cgd1;
6778 
6779  qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3);
6780  Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg);
6781  Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb
6782  + (0.5 * Vds - T3) * dAbulkCV_dVb)
6783  + Cbg1 * dVgsteff_dVb;
6784  Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd
6785  + Cbg1 * dVgsteff_dVd;
6786  Cbg1 *= dVgsteff_dVg;
6787  Cbg += Cbg1;
6788  Cbb += Cbb1;
6789  Cbd += Cbd1;
6790 
6791  if (model_.xpart > 0.5)
6792  { // 0/100 Charge petition model
6793  T1 = T1 + T1;
6794  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6795  Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1 * AbulkCV);
6796  Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb
6797  - 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0)
6798  * dAbulkCV_dVb) + Csg * dVgsteff_dVb;
6799  Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0
6800  / T1 / T1 * (4.0 * Vgsteff - T0))
6801  + Csg * dVgsteff_dVd;
6802  Csg *= dVgsteff_dVg;
6803  }
6804  else if (model_.xpart < 0.5)
6805  { // 40/60 Charge petition model
6806  T1 = T1 / 12.0;
6807  T2 = 0.5 * CoxWL / (T1 * T1);
6808  T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff
6809  * (Vgsteff - 4.0 * T0 / 3.0))
6810  - 2.0 * T0 * T0 * T0 / 15.0;
6811  qsrc = -T2 * T3;
6812  T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6813  + 0.4 * T0 * T0;
6814  Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6815  * Vgsteff - 8.0 * T0 / 3.0)
6816  + 2.0 * T0 * T0 / 3.0);
6817  Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb
6818  + Csg * dVgsteff_dVb;
6819  Csd = (qsrc / T1 + T2 * T4) * AbulkCV
6820  + Csg * dVgsteff_dVd;
6821  Csg *= dVgsteff_dVg;
6822  }
6823  else
6824  { // 50/50 Charge petition model
6825  qsrc = -0.5 * (qgate + qbulk);
6826  Csg = -0.5 * (Cgg1 + Cbg1);
6827  Csb = -0.5 * (Cgb1 + Cbb1);
6828  Csd = -0.5 * (Cgd1 + Cbd1);
6829  }
6830  Cgb *= dVbseff_dVb;
6831  Cbb *= dVbseff_dVb;
6832  Csb *= dVbseff_dVb;
6833  }
6834  qdrn = -(qgate + qbulk + qsrc);
6835  cggb = Cgg;
6836  cgsb = -(Cgg + Cgd + Cgb);
6837  cgdb = Cgd;
6838  cdgb = -(Cgg + Cbg + Csg);
6839  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
6840  cddb = -(Cgd + Cbd + Csd);
6841  cbgb = Cbg;
6842  cbsb = -(Cbg + Cbd + Cbb);
6843  cbdb = Cbd;
6844  qinv = -(qgate + qbulk);
6845  }
6846  else if (model_.capMod == 2)
6847  {
6848  Vfb = paramPtr->vfbzb;
6849  V3 = Vfb - Vgs_eff + VbseffCV - CONSTDELTA_3;
6850  if (Vfb <= 0.0)
6851  {
6852  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * Vfb);
6853  T2 = -CONSTDELTA_3 / T0;
6854  }
6855  else
6856  {
6857  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * Vfb);
6858  T2 = CONSTDELTA_3 / T0;
6859  }
6860 
6861  T1 = 0.5 * (1.0 + V3 / T0);
6862  Vfbeff = Vfb - 0.5 * (V3 + T0);
6863  dVfbeff_dVg = T1 * dVgs_eff_dVg;
6864  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
6865  Qac0 = CoxWL * (Vfbeff - Vfb);
6866  dQac0_dVg = CoxWL * dVfbeff_dVg;
6867  dQac0_dVb = CoxWL * dVfbeff_dVb;
6868 
6869  T0 = 0.5 * paramPtr->k1ox;
6870  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
6871  if (paramPtr->k1ox == 0.0)
6872  {
6873  T1 = 0.0;
6874  T2 = 0.0;
6875  }
6876  else if (T3 < 0.0)
6877  {
6878  T1 = T0 + T3 / paramPtr->k1ox;
6879  T2 = CoxWL;
6880  }
6881  else
6882  {
6883  T1 = sqrt(T0 * T0 + T3);
6884  T2 = CoxWL * T0 / T1;
6885  }
6886 
6887  Qsub0 = CoxWL * paramPtr->k1ox * (T1 - T0);
6888 
6889  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg);
6890  dQsub0_dVd = -T2 * dVgsteff_dVd;
6891  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb);
6892 
6893  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
6894  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
6895  VdsatCV = Vgsteff / AbulkCV;
6896 
6897  V4 = VdsatCV - Vds - CONSTDELTA_4;
6898  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
6899  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
6900  T1 = 0.5 * (1.0 + V4 / T0);
6901  T2 = CONSTDELTA_4 / T0;
6902  T3 = (1.0 - T1 - T2) / AbulkCV;
6903  dVdseffCV_dVg = T3;
6904  dVdseffCV_dVd = T1;
6905  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
6906  // Added to eliminate non-zero VdseffCV at Vds=0.0
6907  if (Vds == 0.0)
6908  {
6909  VdseffCV = 0.0;
6910  dVdseffCV_dVg = 0.0;
6911  dVdseffCV_dVb = 0.0;
6912  }
6913 
6914  T0 = AbulkCV * VdseffCV;
6915  T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20);
6916  T2 = VdseffCV / T1;
6917  T3 = T0 * T2;
6918 
6919  T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV);
6920  T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5);
6921  T6 = 12.0 * T2 * T2 * Vgsteff;
6922 
6923  qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3);
6924  qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3);
6925  Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6926  Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd;
6927  Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6928  + Cgg1 * dVgsteff_dVb;
6929  Cgg1 *= dVgsteff_dVg;
6930 
6931  T7 = 1.0 - AbulkCV;
6932  qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3);
6933  T4 = -T7 * (T4 - 1.0);
6934  T5 = -T7 * T5;
6935  T6 = -(T7 * T6 + (0.5 * VdseffCV - T3));
6936  Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6937  Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd;
6938  Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6939  + Cbg1 * dVgsteff_dVb;
6940  Cbg1 *= dVgsteff_dVg;
6941 
6942  if (model_.xpart > 0.5)
6943  { // 0/100 Charge petition model
6944  T1 = T1 + T1;
6945  qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - T0 * T0 / T1);
6946  T7 = (4.0 * Vgsteff - T0) / (T1 * T1);
6947  T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1));
6948  T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7);
6949  T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7);
6950  Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg);
6951  Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6952  Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6953  + Csg * dVgsteff_dVb;
6954  Csg *= dVgsteff_dVg;
6955  }
6956  else if (model_.xpart < 0.5)
6957  { // 40/60 Charge petition model
6958  T1 = T1 / 12.0;
6959  T2 = 0.5 * CoxWL / (T1 * T1);
6960  T3 = Vgsteff *(2.0 * T0 *T0/3.0 +Vgsteff *(Vgsteff - 4.0 *T0/ 3.0))
6961  - 2.0 * T0 * T0 * T0 / 15.0;
6962  qsrc = -T2 * T3;
6963  T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
6964  + 0.4 * T0 * T0;
6965  T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
6966  * Vgsteff - 8.0 * T0 / 3.0)
6967  + 2.0 * T0 * T0 / 3.0);
6968  T5 = (qsrc / T1 + T2 * T7) * AbulkCV;
6969  T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV);
6970  Csg = (T4 + T5 * dVdseffCV_dVg);
6971  Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
6972  Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
6973  + Csg * dVgsteff_dVb;
6974  Csg *= dVgsteff_dVg;
6975  }
6976  else
6977  { // 50/50 Charge petition model
6978  qsrc = -0.5 * (qgate + qbulk);
6979  Csg = -0.5 * (Cgg1 + Cbg1);
6980  Csb = -0.5 * (Cgb1 + Cbb1);
6981  Csd = -0.5 * (Cgd1 + Cbd1);
6982  }
6983 
6984  qgate += Qac0 + Qsub0;
6985  qbulk -= (Qac0 + Qsub0);
6986  qdrn = -(qgate + qbulk + qsrc);
6987 
6988  Cgg = dQac0_dVg + dQsub0_dVg + Cgg1;
6989  Cgd = dQsub0_dVd + Cgd1;
6990  Cgb = dQac0_dVb + dQsub0_dVb + Cgb1;
6991 
6992  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
6993  Cbd = Cbd1 - dQsub0_dVd;
6994  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
6995 
6996  Cgb *= dVbseff_dVb;
6997  Cbb *= dVbseff_dVb;
6998  Csb *= dVbseff_dVb;
6999 
7000  cggb = Cgg;
7001  cgsb = -(Cgg + Cgd + Cgb);
7002  cgdb = Cgd;
7003  cdgb = -(Cgg + Cbg + Csg);
7004  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
7005  cddb = -(Cgd + Cbd + Csd);
7006  cbgb = Cbg;
7007  cbsb = -(Cbg + Cbd + Cbb);
7008  cbdb = Cbd;
7009  qinv = qinoi;
7010  }
7011 
7012  // New Charge-Thickness capMod (CTM) begins
7013  else if (model_.capMod == 3)
7014  {
7015  V3 = paramPtr->vfbzb - Vgs_eff + VbseffCV - CONSTDELTA_3;
7016  if (paramPtr->vfbzb <= 0.0)
7017  {
7018  T0 = sqrt(V3 * V3 - 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
7019  T2 = -CONSTDELTA_3 / T0;
7020  }
7021  else
7022  {
7023  T0 = sqrt(V3 * V3 + 4.0 * CONSTDELTA_3 * paramPtr->vfbzb);
7024  T2 = CONSTDELTA_3 / T0;
7025  }
7026 
7027  T1 = 0.5 * (1.0 + V3 / T0);
7028  Vfbeff = paramPtr->vfbzb - 0.5 * (V3 + T0);
7029  dVfbeff_dVg = T1 * dVgs_eff_dVg;
7030  dVfbeff_dVb = -T1 * dVbseffCV_dVb;
7031 
7032  Cox = model_.cox;
7033  Tox = 1.0e8 * model_.tox;
7034  T0 = (Vgs_eff - VbseffCV - paramPtr->vfbzb) / Tox;
7035  dT0_dVg = dVgs_eff_dVg / Tox;
7036  dT0_dVb = -dVbseffCV_dVb / Tox;
7037 
7038  tmp = T0 * paramPtr->acde;
7039  if ((-CONSTEXP_THRESHOLD < tmp) && (tmp < CONSTEXP_THRESHOLD))
7040  {
7041  Tcen = paramPtr->ldeb * exp(tmp);
7042  dTcen_dVg = paramPtr->acde * Tcen;
7043  dTcen_dVb = dTcen_dVg * dT0_dVb;
7044  dTcen_dVg *= dT0_dVg;
7045  }
7046  else if (tmp <= -CONSTEXP_THRESHOLD)
7047  {
7048  Tcen = paramPtr->ldeb * CONSTMIN_EXP;
7049  dTcen_dVg = dTcen_dVb = 0.0;
7050  }
7051  else
7052  {
7053  Tcen = paramPtr->ldeb * CONSTMAX_EXP;
7054  dTcen_dVg = dTcen_dVb = 0.0;
7055  }
7056 
7057  LINK = 1.0e-3 * model_.tox;
7058  V3 = paramPtr->ldeb - Tcen - LINK;
7059  V4 = sqrt(V3 * V3 + 4.0 * LINK * paramPtr->ldeb);
7060  Tcen = paramPtr->ldeb - 0.5 * (V3 + V4);
7061  T1 = 0.5 * (1.0 + V3 / V4);
7062  dTcen_dVg *= T1;
7063  dTcen_dVb *= T1;
7064 
7065  Ccen = CONSTEPSSI / Tcen;
7066  T2 = Cox / (Cox + Ccen);
7067  Coxeff = T2 * Ccen;
7068  T3 = -Ccen / Tcen;
7069  dCoxeff_dVg = T2 * T2 * T3;
7070  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
7071  dCoxeff_dVg *= dTcen_dVg;
7072  CoxWLcen = CoxWL * Coxeff / Cox;
7073 
7074  Qac0 = CoxWLcen * (Vfbeff - paramPtr->vfbzb);
7075  QovCox = Qac0 / Coxeff;
7076  dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg;
7077  dQac0_dVb = CoxWLcen * dVfbeff_dVb + QovCox * dCoxeff_dVb;
7078 
7079  T0 = 0.5 * paramPtr->k1ox;
7080  T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
7081  if (paramPtr->k1ox == 0.0)
7082  {
7083  T1 = 0.0;
7084  T2 = 0.0;
7085  }
7086  else if (T3 < 0.0)
7087  {
7088  T1 = T0 + T3 / paramPtr->k1ox;
7089  T2 = CoxWLcen;
7090  }
7091  else
7092  {
7093  T1 = sqrt(T0 * T0 + T3);
7094  T2 = CoxWLcen * T0 / T1;
7095  }
7096 
7097  Qsub0 = CoxWLcen * paramPtr->k1ox * (T1 - T0);
7098  QovCox = Qsub0 / Coxeff;
7099  dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg)
7100  + QovCox * dCoxeff_dVg;
7101  dQsub0_dVd = -T2 * dVgsteff_dVd;
7102  dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb)
7103  + QovCox * dCoxeff_dVb;
7104 
7105  // Gate-bias dependent delta Phis begins */
7106  if (paramPtr->k1ox <= 0.0)
7107  {
7108  Denomi = 0.25 * paramPtr->moin * Vtm;
7109  T0 = 0.5 * paramPtr->sqrtPhi;
7110  }
7111  else
7112  {
7113  Denomi = paramPtr->moin * Vtm * paramPtr->k1ox * paramPtr->k1ox;
7114  T0 = paramPtr->k1ox * paramPtr->sqrtPhi;
7115  }
7116  T1 = 2.0 * T0 + Vgsteff;
7117 
7118  DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi);
7119  dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff);
7120  dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd;
7121  dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb;
7122  // End of delta Phis
7123 
7124  T3 = 4.0 * (Vth - paramPtr->vfbzb - paramPtr->phi);
7125  Tox += Tox;
7126  if (T3 >= 0.0)
7127  { T0 = (Vgsteff + T3) / Tox;
7128  dT0_dVd = (dVgsteff_dVd + 4.0 * dVth_dVd) / Tox;
7129  dT0_dVb = (dVgsteff_dVb + 4.0 * dVth_dVb) / Tox;
7130  }
7131  else
7132  { T0 = (Vgsteff + 1.0e-20) / Tox;
7133  dT0_dVd = dVgsteff_dVd / Tox;
7134  dT0_dVb = dVgsteff_dVb / Tox;
7135  }
7136  tmp = exp(0.7 * log(T0));
7137  T1 = 1.0 + tmp;
7138  T2 = 0.7 * tmp / (T0 * Tox);
7139  Tcen = 1.9e-9 / T1;
7140  dTcen_dVg = -1.9e-9 * T2 / T1 /T1;
7141  dTcen_dVd = Tox * dTcen_dVg;
7142  dTcen_dVb = dTcen_dVd * dT0_dVb;
7143  dTcen_dVd *= dT0_dVd;
7144  dTcen_dVg *= dVgsteff_dVg;
7145 
7146  Ccen = CONSTEPSSI / Tcen;
7147  T0 = Cox / (Cox + Ccen);
7148  Coxeff = T0 * Ccen;
7149  T1 = -Ccen / Tcen;
7150  dCoxeff_dVg = T0 * T0 * T1;
7151  dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd;
7152  dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
7153  dCoxeff_dVg *= dTcen_dVg;
7154  CoxWLcen = CoxWL * Coxeff / Cox;
7155 
7156  AbulkCV = Abulk0 * paramPtr->abulkCVfactor;
7157  dAbulkCV_dVb = paramPtr->abulkCVfactor * dAbulk0_dVb;
7158  VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV;
7159  V4 = VdsatCV - Vds - CONSTDELTA_4;
7160  T0 = sqrt(V4 * V4 + 4.0 * CONSTDELTA_4 * VdsatCV);
7161  VdseffCV = VdsatCV - 0.5 * (V4 + T0);
7162  T1 = 0.5 * (1.0 + V4 / T0);
7163  T2 = CONSTDELTA_4 / T0;
7164  T3 = (1.0 - T1 - T2) / AbulkCV;
7165  T4 = T3 * ( 1.0 - dDeltaPhi_dVg);
7166  dVdseffCV_dVg = T4;
7167  dVdseffCV_dVd = T1;
7168  dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
7169 
7170  // Added to eliminate non-zero VdseffCV at Vds=0.0
7171  if (Vds == 0.0)
7172  { VdseffCV = 0.0;
7173  dVdseffCV_dVg = 0.0;
7174  dVdseffCV_dVb = 0.0;
7175  }
7176 
7177  T0 = AbulkCV * VdseffCV;
7178  T1 = Vgsteff - DeltaPhi;
7179  T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20);
7180  T3 = T0 / T2;
7181  T4 = 1.0 - 12.0 * T3 * T3;
7182  T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5);
7183  T6 = T5 * VdseffCV / AbulkCV;
7184 
7185  qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3));
7186  QovCox = qgate / Coxeff;
7187  Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + T5 * dVdseffCV_dVg);
7188  Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1
7189  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
7190  Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
7191  + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
7192  Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
7193 
7194 
7195  T7 = 1.0 - AbulkCV;
7196  T8 = T2 * T2;
7197  T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV);
7198  T10 = T9 * (1.0 - dDeltaPhi_dVg);
7199  T11 = -T7 * T5 / AbulkCV;
7200  T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2));
7201 
7202  qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2);
7203  QovCox = qbulk / Coxeff;
7204  Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg);
7205  Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1
7206  * dVgsteff_dVd + QovCox * dCoxeff_dVd;
7207  Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb)
7208  + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
7209  Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
7210 
7211  if (model_.xpart > 0.5)
7212  { // 0/100 partition
7213  qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - 0.5 * T0 * T0 / T2);
7214  QovCox = qsrc / Coxeff;
7215  T2 += T2;
7216  T3 = T2 * T2;
7217  T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3);
7218  T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg);
7219  T5 = T7 * AbulkCV;
7220  T6 = T7 * VdseffCV;
7221 
7222  Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg);
7223  Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd
7224  + QovCox * dCoxeff_dVd;
7225  Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
7226  + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb;
7227  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
7228  }
7229  else if (model_.xpart < 0.5)
7230  { // 40/60 partition
7231  T2 = T2 / 12.0;
7232  T3 = 0.5 * CoxWLcen / (T2 * T2);
7233  T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0
7234  * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0;
7235  qsrc = -T3 * T4;
7236  QovCox = qsrc / Coxeff;
7237  T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0;
7238  T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0
7239  * T0 / 3.0) + 2.0 * T0 * T0 / 3.0);
7240  T6 = AbulkCV * (qsrc / T2 + T3 * T8);
7241  T7 = T6 * VdseffCV / AbulkCV;
7242 
7243  Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg;
7244  Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd
7245  + QovCox * dCoxeff_dVd;
7246  Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb
7247  + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb;
7248  Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
7249  }
7250  else
7251  { // 50/50 partition
7252  qsrc = -0.5 * qgate;
7253  Csg = -0.5 * Cgg1;
7254  Csd = -0.5 * Cgd1;
7255  Csb = -0.5 * Cgb1;
7256  }
7257 
7258  qgate += Qac0 + Qsub0 - qbulk;
7259  qbulk -= (Qac0 + Qsub0);
7260  qdrn = -(qgate + qbulk + qsrc);
7261 
7262  Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
7263  Cbd = Cbd1 - dQsub0_dVd;
7264  Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
7265 
7266  Cgg = Cgg1 - Cbg;
7267  Cgd = Cgd1 - Cbd;
7268  Cgb = Cgb1 - Cbb;
7269 
7270  Cgb *= dVbseff_dVb;
7271  Cbb *= dVbseff_dVb;
7272  Csb *= dVbseff_dVb;
7273 
7274  cggb = Cgg;
7275  cgsb = -(Cgg + Cgd + Cgb);
7276  cgdb = Cgd;
7277  cdgb = -(Cgg + Cbg + Csg);
7278  cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + Csg + Csd + Csb);
7279  cddb = -(Cgd + Cbd + Csd);
7280  cbgb = Cbg;
7281  cbsb = -(Cbg + Cbd + Cbb);
7282  cbdb = Cbd;
7283  qinv = -qinoi;
7284  } // End of CTM
7285  }
7286 
7287  finished:
7288  // Returning Values to Calling Routine
7289  // COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
7290 
7291  // copy local "cdrain" variable over to instance variable cd.
7292  cd = cdrain;
7293 
7294  // charge storage elements:
7295  // bulk-drain and bulk-source depletion capacitances
7296  // czbd : zero bias drain junction capacitance
7297  // czbs : zero bias source junction capacitance
7298  // czbdsw: zero bias drain junction sidewall capacitance
7299  // along field oxide
7300  // czbssw: zero bias source junction sidewall capacitance
7301  // along field oxide
7302  // czbdswg: zero bias drain junction sidewall capacitance
7303  // along gate side
7304  // czbsswg: zero bias source junction sidewall capacitance
7305  // along gate side
7307  {
7308  czbd = unitAreaJctCapTemp * drainArea;
7309  czbs = unitAreaJctCapTemp * sourceArea;
7310  if (drainPerimeter < paramPtr->weff)
7311  {
7313  czbdsw = 0.0;
7314  }
7315  else
7316  {
7318  * (drainPerimeter - paramPtr->weff);
7319 
7321  }
7322  if (sourcePerimeter < paramPtr->weff)
7323  {
7324  czbssw = 0.0;
7326  }
7327  else
7328  {
7330  * (sourcePerimeter - paramPtr->weff);
7332  }
7333 
7337 
7338  // Source Bulk Junction
7339  if (vbs == 0.0)
7340  {
7341  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
7342  qbs = 0.0;
7343  capbs = czbs + czbssw + czbsswg;
7344  }
7345  else if (vbs < 0.0)
7346  {
7347  if (czbs > 0.0)
7348  {
7349  arg = 1.0 - vbs / PhiBTemp;
7350 
7351  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
7352  else sarg = exp(-MJ * log(arg));
7353 
7354  //*(ckt->CKTstate0 + iterI->qbs) =
7355  qbs = PhiBTemp * czbs * (1.0 - arg * sarg) / (1.0 - MJ);
7356 
7357  capbs = czbs * sarg;
7358  }
7359  else
7360  {
7361  //*(ckt->CKTstate0 + iterI->qbs) = 0.0;
7362  qbs = 0.0;
7363  capbs = 0.0;
7364  }
7365 
7366  if (czbssw > 0.0)
7367  {
7368  arg = 1.0 - vbs / PhiBSWTemp;
7369  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7370  else sarg = exp(-MJSW * log(arg));
7371 
7372  //*(ckt->CKTstate0 + iterI->qbs) +=
7373  qbs += PhiBSWTemp * czbssw * (1.0 - arg * sarg) / (1.0 - MJSW);
7374 
7375  capbs += czbssw * sarg;
7376  }
7377 
7378  if (czbsswg > 0.0)
7379  {
7380  arg = 1.0 - vbs / PhiBSWGTemp;
7381  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7382  else sarg = exp(-MJSWG * log(arg));
7383 
7384  //*(ckt->CKTstate0 + iterI->qbs) +=
7385  qbs += PhiBSWGTemp * czbsswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7386 
7387  capbs += czbsswg * sarg;
7388  }
7389 
7390  }
7391  else
7392  {
7393  T0 = czbs + czbssw + czbsswg;
7394  T1 = vbs * (czbs * MJ / PhiBTemp + czbssw * MJSW
7395  / PhiBSWTemp + czbsswg * MJSWG / PhiBSWGTemp);
7396 
7397  //*(ckt->CKTstate0 + iterI->
7398  qbs = vbs * (T0 + 0.5 * T1);
7399  capbs = T0 + T1;
7400  }
7401 
7402  // Drain Bulk Junction
7403  if (vbd == 0.0)
7404  {
7405  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7406  qbd = 0.0;
7407  capbd = czbd + czbdsw + czbdswg;
7408  }
7409  else if (vbd < 0.0)
7410  {
7411  if (czbd > 0.0)
7412  {
7413  arg = 1.0 - vbd / PhiBTemp;
7414  if (MJ == 0.5) sarg = 1.0 / sqrt(arg);
7415  else sarg = exp(-MJ * log(arg));
7416 
7417  //*(ckt->CKTstate0 + iterI->qbd) =
7418  qbd = PhiBTemp * czbd * (1.0 - arg * sarg) / (1.0 - MJ);
7419  capbd = czbd * sarg;
7420  }
7421  else
7422  {
7423  //*(ckt->CKTstate0 + iterI->qbd) = 0.0;
7424  qbd = 0.0;
7425  capbd = 0.0;
7426  }
7427 
7428  if (czbdsw > 0.0)
7429  {
7430  arg = 1.0 - vbd / PhiBSWTemp;
7431  if (MJSW == 0.5) sarg = 1.0 / sqrt(arg);
7432  else sarg = exp(-MJSW * log(arg));
7433 
7434  //*(ckt->CKTstate0 + iterI->qbd) +=
7435  qbd += PhiBSWTemp * czbdsw * (1.0 - arg * sarg) / (1.0 - MJSW);
7436  capbd += czbdsw * sarg;
7437  }
7438 
7439  if (czbdswg > 0.0)
7440  {
7441  arg = 1.0 - vbd / PhiBSWGTemp;
7442  if (MJSWG == 0.5) sarg = 1.0 / sqrt(arg);
7443  else sarg = exp(-MJSWG * log(arg));
7444 
7445  //*(ckt->CKTstate0 + iterI->qbd) +=
7446  qbd += PhiBSWGTemp * czbdswg * (1.0 - arg * sarg) / (1.0 - MJSWG);
7447  capbd += czbdswg * sarg;
7448  }
7449  }
7450  else
7451  {
7452  T0 = czbd + czbdsw + czbdswg;
7453  T1 = vbd * (czbd * MJ / PhiBTemp + czbdsw * MJSW
7454  / PhiBSWTemp + czbdswg * MJSWG / PhiBSWGTemp);
7455 
7456  //*(ckt->CKTstate0 + iterI->qbd) = vbd * (T0 + 0.5 * T1);
7457  qbd = vbd * (T0 + 0.5 * T1);
7458  capbd = T0 + T1;
7459  }
7460  }
7461 
7462  // There is a spice3f5 convergence check that would happen here.
7463  // (line 2404) skipping...
7464 
7465  // In 3f5, loading a bunch of things into the state vector at this point.
7466  // (line 2433) skipping...
7467 
7468  // bulk and channel charge plus overlaps
7469 
7471  {
7472  // NQS begins
7473  if (nqsMod)
7474  {
7475  qcheq = -(qbulk + qgate);
7476 
7477  cqgb = -(cggb + cbgb);
7478  cqdb = -(cgdb + cbdb);
7479  cqsb = -(cgsb + cbsb);
7480  cqbb = -(cqgb + cqdb + cqsb);
7481 
7482  gtau_drift = fabs(paramPtr->tconst * qcheq) * ScalingFactor;
7483  T0 = paramPtr->leffCV * paramPtr->leffCV;
7484  gtau_diff = 16.0 * paramPtr->u0temp * model_.vtm / T0 * ScalingFactor;
7485 
7486  gtau = gtau_drift + gtau_diff;
7487  }
7488 
7489  if (model_.capMod == 0)
7490  {
7491  if (vgd < 0.0)
7492  {
7493  cgdo = paramPtr->cgdo;
7494  qgdo = paramPtr->cgdo * vgd;
7495  }
7496  else
7497  {
7498  cgdo = paramPtr->cgdo;
7499  qgdo = paramPtr->cgdo * vgd;
7500  }
7501 
7502  if (vgs < 0.0)
7503  {
7504  cgso = paramPtr->cgso;
7505  qgso = paramPtr->cgso * vgs;
7506  }
7507  else
7508  {
7509  cgso = paramPtr->cgso;
7510  qgso = paramPtr->cgso * vgs;
7511  }
7512  }
7513  else if (model_.capMod == 1)
7514  {
7515  if (vgd < 0.0)
7516  {
7517  T1 = sqrt(1.0 - 4.0 * vgd / paramPtr->ckappa);
7518  cgdo = paramPtr->cgdo + paramPtr->weffCV * paramPtr->cgdl / T1;
7519 
7520  qgdo = paramPtr->cgdo * vgd - paramPtr->weffCV * 0.5
7521  * paramPtr->cgdl * paramPtr->ckappa * (T1 - 1.0);
7522  }
7523  else
7524  {
7527  }
7528 
7529  if (vgs < 0.0)
7530  {
7531  T1 = sqrt(1.0 - 4.0 * vgs / paramPtr->ckappa);
7532  cgso = paramPtr->cgso + paramPtr->weffCV * paramPtr->cgsl / T1;
7533  qgso = paramPtr->cgso * vgs - paramPtr->weffCV * 0.5
7534  * paramPtr->cgsl * paramPtr->ckappa * (T1 - 1.0);
7535  }
7536  else
7537  {
7540  }
7541  }
7542  else
7543  {
7544  T0 = vgd + CONSTDELTA_1;
7545  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7546  T2 = 0.5 * (T0 - T1);
7547 
7548  T3 = paramPtr->weffCV * paramPtr->cgdl;
7549  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7550  cgdo = paramPtr->cgdo + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7551 
7552  qgdo = (paramPtr->cgdo + T3) * vgd - T3 * (T2
7553  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7554 
7555  T0 = vgs + CONSTDELTA_1;
7556  T1 = sqrt(T0 * T0 + 4.0 * CONSTDELTA_1);
7557  T2 = 0.5 * (T0 - T1);
7558  T3 = paramPtr->weffCV * paramPtr->cgsl;
7559  T4 = sqrt(1.0 - 4.0 * T2 / paramPtr->ckappa);
7560  cgso = paramPtr->cgso + T3 - T3 * (1.0 - 1.0 / T4) * (0.5 - 0.5 * T0 / T1);
7561  qgso = (paramPtr->cgso + T3) * vgs - T3 * (T2
7562  + 0.5 * paramPtr->ckappa * (T4 - 1.0));
7563  }
7564 
7565  //cgdo = cgdo;
7566  //cgso = cgso;
7567 
7570 
7571  //cqdef = cqcheq = 0.0;
7572  cqdef = 0.0;
7573 
7574  // set some state variables:
7575  qg = qgate;
7576  qd = qdrn - qbd;
7577  qb = qbulk + qbd + qbs;
7578  if (nqsMod) qcdump = qdef * ScalingFactor;
7579 
7580  } // end of ChargeComputationNeeded if statement.
7581 
7582  // store small signal parameters
7583  //if (ckt->CKTmode & MODEINITSMSIG) goto line1000;
7584  // Note: in 3f5, line1000 is at the end of the load, after
7585  // the loads to the rhs and the matrix. So it looks
7586  // like this goto essentially means return.
7587 
7588 
7589  // Setting up a few currents for the RHS load:
7592 
7593  // Put this kludge in because the matrix load needs T1 but it is used
7594  // all over the place:
7595  T1global = T1;
7596 
7597  return bsuccess;
7598 }
7599 
7600 //-----------------------------------------------------------------------------
7601 // Function : Instance::updatePrimaryState
7602 //
7603 // Purpose : This function sets up the primaray state variables into
7604 // the primary state vector.
7605 //
7606 // These variables include qb, qg, qd and, in the
7607 // event that nqsMod=1, qcdump and qcheq.
7608 //
7609 // Special Notes :
7610 // Scope : public
7611 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7612 // Creation Date : 01/09/01
7613 //-----------------------------------------------------------------------------
7615 {
7616  bool bsuccess = true;
7617  double * staVec = extData.nextStaVectorRawPtr;
7618  double * stoVec = extData.nextStoVectorRawPtr;
7619 
7620  bsuccess = updateIntermediateVars ();
7621 
7622  // voltage drops:
7623  stoVec[li_store_vbs] = vbs;
7624  stoVec[li_store_vgs] = vgs;
7625  stoVec[li_store_vds] = vds;
7626  stoVec[li_store_vbd] = vbd;
7627  stoVec[li_store_von] = von;
7628 
7629  // intrinsic capacitors:
7630  staVec[li_state_qb] = qb;
7631  staVec[li_state_qg] = qg;
7632  staVec[li_state_qd] = qd;
7633 
7634  // parasitic capacitors:
7635  staVec[li_state_qbs] = qbs;
7636  staVec[li_state_qbd] = qbd;
7637 
7638  if( nqsMod )
7639  {
7640  staVec[li_state_qcheq] = qcheq;
7641  staVec[li_state_qcdump] = qcdump;
7642  }
7643 
7644  // if this is the first newton step of the first time step
7645  // of the transient simulation, we need to enforce that the
7646  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
7647  // compatibility. ERK.
7648 
7649  // Note: I think this kind of thing is enforced (or should be enforced,
7650  // anyway) at the time integration level. So I'm not sure this step is
7651  // really needed, at least for new-DAE. Derivatives out of the DCOP
7652  // are supposed to be zero at the first newton step.
7653 
7654  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag_ && getSolverState().newtonIter==0)
7655  {
7656  // re-set the state vector pointer that we are using to the "current"
7657  // pointer, rather than the "next" pointer.
7658  double * currStaVec = extData.currStaVectorRawPtr;
7659 
7660  // intrinsic capacitors:
7661  currStaVec[li_state_qb] = qb;
7662  currStaVec[li_state_qg] = qg;
7663  currStaVec[li_state_qd] = qd;
7664 
7665  // parasitic capacitors:
7666  currStaVec[li_state_qbs] = qbs;
7667  currStaVec[li_state_qbd] = qbd;
7668 
7669  if( nqsMod )
7670  {
7671  currStaVec[li_state_qcheq] = qcheq;
7672  currStaVec[li_state_qcdump] = qcdump;
7673  }
7674  }
7675 
7676  return bsuccess;
7677 }
7678 
7679 // Noise functions
7680 
7681 //-----------------------------------------------------------------------------
7682 // Function : Xyce::Device::MOSFET_B3::Instance::StrongInversionNoiseEval
7683 // Purpose :
7684 // Special Notes :
7685 // Scope : public
7686 // Creator : Eric Keiter, SNL
7687 // Creation Date : 1/13/2015
7688 //-----------------------------------------------------------------------------
7689 double Instance::StrongInversionNoiseEval(double Vds, double freq, double temp)
7690 {
7691  double cdAbs, esat, DelClm, EffFreq, N0, Nl, Vgst, Leff, Leffsq;
7692  double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi;
7693 
7694  cdAbs = fabs(cd);
7695  Leff = paramPtr->leff - 2.0 * model_.lintnoi;
7696  Leffsq = Leff * Leff;
7697  esat = 2.0 * paramPtr->vsattemp / ueff;
7698  if(model_.em<=0.0)
7699  {
7700  DelClm = 0.0;
7701  }
7702  else
7703  {
7704  T0 = ((((Vds - Vdseff) / paramPtr->litl)
7705  + model_.em) / esat);
7706  DelClm = paramPtr->litl * std::log (std::max(T0, N_MINLOG));
7707  if (DelClm < 0.0) DelClm = 0.0; /* bugfix */
7708  }
7709 
7710  EffFreq = pow(freq, model_.ef);
7711  T1 = CONSTQ * CONSTQ * 8.62e-5 * cdAbs * temp * ueff;
7712  T2 = 1.0e8 * EffFreq * Abulk * model_.cox * Leffsq;
7713  N0 = model_.cox * Vgsteff / CONSTQ;
7714  Nl = model_.cox * Vgsteff * (1.0 - AbovVgst2Vtm * Vdseff) / CONSTQ;
7715 
7716  T3 = model_.oxideTrapDensityA * std::log(std::max(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG));
7717  T4 = model_.oxideTrapDensityB * (N0 - Nl);
7718  T5 = model_.oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl);
7719 
7720  T6 = 8.62e-5 * temp * cdAbs * cdAbs;
7721  T7 = 1.0e8 * EffFreq * Leffsq * paramPtr->weff;
7723  + model_.oxideTrapDensityC * Nl * Nl;
7724 
7725  T9 = (Nl + 2.0e14) * (Nl + 2.0e14);
7726 
7727  Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9;
7728  return Ssi;
7729 }
7730 
7731 //-----------------------------------------------------------------------------
7732 // Function : Xyce::Device::MOSFET_B3::Instance::getNumNoiseSources
7733 // Purpose :
7734 // Special Notes :
7735 // Scope : public
7736 // Creator : Eric Keiter, SNL
7737 // Creation Date : 1/13/2015
7738 //-----------------------------------------------------------------------------
7740 {
7741  return 4;
7742 }
7743 
7744 //-----------------------------------------------------------------------------
7745 // Function : Xyce::Device::MOSFET_B3::Instance::setupNoiseSources
7746 // Purpose :
7747 // Special Notes :
7748 // Scope : public
7749 // Creator : Eric Keiter
7750 // Creation Date : 1/13/2015
7751 //-----------------------------------------------------------------------------
7753 {
7754  int numSources=4;
7755  noiseData.numSources = numSources;
7756  noiseData.resize(numSources);
7757 
7758  noiseData.deviceName = getName().getEncodedName();
7759 
7760  noiseData.noiseNames[0] = "onoise_" + getName().getEncodedName()+
7761  std::string("_rd"); // noise due to rd
7762  noiseData.noiseNames[1] = "onoise_" + getName().getEncodedName()+
7763  std::string("_rs"); // noise due to rs
7764  noiseData.noiseNames[2] = "onoise_" + getName().getEncodedName()+
7765  std::string("_id"); // noise due to id
7766  noiseData.noiseNames[3] = "onoise_" + getName().getEncodedName()+
7767  std::string("_1overf"); // flicker (1/f) noise
7768 
7769  // RD thermal:
7770  noiseData.li_Pos[0] = li_DrainPrime;
7771  noiseData.li_Neg[0] = li_Drain;
7772 
7773  // RS thermal:
7774  noiseData.li_Pos[1] = li_SourcePrime;
7775  noiseData.li_Neg[1] = li_Source;
7776 
7777  // ID thermal:
7778  noiseData.li_Pos[2] = li_DrainPrime;
7779  noiseData.li_Neg[2] = li_SourcePrime;
7780 
7781  // flicker:
7782  noiseData.li_Pos[3] = li_DrainPrime;
7783  noiseData.li_Neg[3] = li_SourcePrime;
7784 
7785 }
7786 
7787 //-----------------------------------------------------------------------------
7788 // Function : Xyce::Device::MOSFET_B3::Instance::getNoiseSources
7789 // Purpose :
7790 // Special Notes :
7791 //
7792 // Channel thermal and flicker noises are calculated based on the value
7793 // of model->BSIM3noiMod.
7794 // If model->BSIM3noiMod = 1,
7795 // Channel thermal noise = SPICE2 model
7796 // Flicker noise = SPICE2 model
7797 // If model->BSIM3noiMod = 2,
7798 // Channel thermal noise = BSIM3 model
7799 // Flicker noise = BSIM3 model
7800 // If model->BSIM3noiMod = 3,
7801 // Channel thermal noise = SPICE2 model
7802 // Flicker noise = BSIM3 model
7803 // If model->BSIM3noiMod = 4,
7804 // Channel thermal noise = BSIM3 model
7805 // Flicker noise = SPICE2 model
7806 // If model->BSIM3noiMod = 5,
7807 // Channel thermal noise = SPICE2 model with linear/sat fix
7808 // Flicker noise = SPICE2 model
7809 // If model->BSIM3noiMod = 6,
7810 // Channel thermal noise = SPICE2 model with linear/sat fix
7811 // Flicker noise = BSIM3 model
7812 //
7813 // Scope : public
7814 // Creator : Eric Keiter
7815 // Creation Date : 1/13/2015
7816 //-----------------------------------------------------------------------------
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 // Function : Instance::loadDAEQVector
7913 //
7914 // Purpose : Loads the Q-vector contributions for a single
7915 // bsim3 instance.
7916 //
7917 // Special Notes : The "Q" vector is part of a standard DAE formalism in
7918 // which the system of equations is represented as:
7919 //
7920 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
7921 //
7922 // Scope : public
7923 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
7924 // Creation Date : 04/07/04
7925 //-----------------------------------------------------------------------------
7927 {
7928  double * qVec = extData.daeQVectorRawPtr;
7929  double * dQdxdVp = extData.dQdxdVpVectorRawPtr;
7930 
7932 
7933  double Qeqqg = 0.0; // gate charge
7934  double Qeqqb = 0.0; // bulk charge
7935  double Qeqqd = 0.0; // drain charge
7936  double Qqdef = 0.0; // nqs-related charge.
7937  double Qqcheq = 0.0; // nqs-related charge.
7938 
7939  // These 3 vars are class variables, and are set up elsewhere.
7940  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
7941  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
7942  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
7943 
7944  if (model_.dtype > 0)
7945  {
7946  Qeqqg = qg;
7947  Qeqqb = qb;
7948  Qeqqd = qd;
7949  Qqdef = qcdump; // this needs to be fixed...
7950  Qqcheq = qcheq;
7951  }
7952  else // need to convert these to charges.
7953  {
7954  Qeqqg = -qg;
7955  Qeqqb = -qb;
7956  Qeqqd = -qd;
7957  Qqdef = -qcdump;
7958  Qqcheq = -qcheq;
7959  }
7960 
7961  qVec[li_Gate] += Qeqqg*numberParallel;
7962  qVec[li_Bulk] += (Qeqqb)*numberParallel;
7963  qVec[li_DrainPrime] += (-(-Qeqqd))*numberParallel;
7964  qVec[li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7965 
7966  if( loadLeadCurrent )
7967  {
7968  double * storeLeadQ = extData.storeLeadCurrQCompRawPtr;
7969  if (drainConductance == 0.0)
7970  {
7971  storeLeadQ[li_store_dev_id] = (-(-Qeqqd))*numberParallel;
7972  }
7973  if (sourceConductance == 0.0)
7974  {
7975  storeLeadQ[li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*numberParallel;
7976  }
7977  storeLeadQ[li_store_dev_ig] = Qeqqg*numberParallel;
7978  storeLeadQ[li_store_dev_ib] = (Qeqqb)*numberParallel;
7979  }
7980 
7981  if (nqsMod)
7982  {
7983  // 7 equ. for nqs modification. charge equation.
7984  qVec[li_Charge] += -(Qqcheq - Qqdef)*numberParallel;
7985  }
7986 
7987  //////////////////////////////////////////////////
7988  // limiting section:
7990  {
7991  // Need the following:
7992  // Qeqqg_Jdxp
7993  // Qeqqb_Jdxp
7994  // Qeqqd_Jdxp
7995  if (model_.dtype > 0)
7996  {
7997  // no-op:
8001  }
8002  else
8003  {
8007  }
8008 
8009  if (!origFlag)
8010  {
8011  dQdxdVp[li_Gate] += -Qeqqg_Jdxp*numberParallel;
8012  dQdxdVp[li_Bulk] += -(+Qeqqb_Jdxp)*numberParallel;
8013  dQdxdVp[li_DrainPrime] += (-Qeqqd_Jdxp)*numberParallel;
8014  dQdxdVp[li_SourcePrime] += (+Qeqqg_Jdxp+Qeqqb_Jdxp+Qeqqd_Jdxp) *numberParallel;
8015  } // orig flag.
8016  } // limiter flag
8017 
8018  return true;
8019 }
8020 
8021 //-----------------------------------------------------------------------------
8022 // Function : Instance::auxChargeCalculations
8023 //
8024 // Purpose : This function does some final "cleanup" calculations
8025 // having to do with the capacitors.
8026 //
8027 // Special Notes : About all this function really does is set up some
8028 // voltlim terms, and some unused nqs stuff.
8029 //
8030 // Scope : public
8031 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8032 // Creation Date : 04/18/04
8033 //-----------------------------------------------------------------------------
8035 {
8036  double T0, T1;
8037 
8039  {
8040  sxpart = (1.0 - (dxpart = (mode > 0) ? 0.4 : 0.6));
8043 
8044  if (nqsMod)
8045  {
8046  gtau = 16.0 * paramPtr->u0temp * model_.vtm
8048  }
8049  else
8050  {
8051  gtau = 0.0;
8052  }
8053  }
8054  else // ChargeComputation is needed
8055  {
8056  double vgb_orig = vgs_orig - vbs_orig;
8057 
8058  Qeqqg_Jdxp = 0.0;
8059  if (!origFlag)
8060  {
8061  Qeqqg_Jdxp = - CAPcggb * (vgb-vgb_orig)
8062  + CAPcgdb * (vbd-vbd_orig)
8063  + CAPcgsb * (vbs-vbs_orig);
8064  }
8065 
8066  Qeqqb_Jdxp = 0.0;
8067  if (!origFlag)
8068  {
8069  Qeqqb_Jdxp = - CAPcbgb * (vgb-vgb_orig)
8070  + CAPcbdb * (vbd-vbd_orig)
8071  + CAPcbsb * (vbs-vbs_orig);
8072  }
8073 
8074  Qeqqd_Jdxp = 0.0;
8075  if (!origFlag)
8076  {
8077  Qeqqd_Jdxp = - CAPcdgb * (vgb-vgb_orig)
8078  + CAPcddb * (vbd-vbd_orig)
8079  + CAPcdsb * (vbs-vbs_orig);
8080  }
8081 
8082  // Note: nqs stuff is not yet finished, especially the voltage
8083  // limiting aspect. For limiting, need to re-do T0 and the term
8084  // added to ceqqd.
8085  if (nqsMod)
8086  {
8087  std::string msg;
8088  msg = "Instance::auxChargeCalculations ()";
8089  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8090  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8091 
8092  T0 = ggtg * vgb - ggtd * vbd - ggts * vbs;
8093  ceqqg += T0;
8094  T1 = qdef * gtau;
8095  ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd
8096  * vbd - ddxpart_dVs * vbs);
8097 
8098  //cqdef = cqcdump - gqdef * qdef;
8099 
8100  //if (!origFlag)
8101  //{
8102  //double tmp = - (gcqgb * (vgb-vgb_orig)
8103  //- gcqdb * (vbd-vbd_orig)
8104  //- gcqsb * (vbs-vbs_orig)) + T0;
8105  //cqcheq += tmp;
8106  //cqcheq_Jdxp = tmp;
8107  //}
8108  }
8109  } // !ChargeComputationNeeded
8110 
8111  return true;
8112 }
8113 
8114 //-----------------------------------------------------------------------------
8115 // Function : Instance::setupCapacitors_newDAE ()
8116 //
8117 // Purpose : This takes a lot of the individual capacitive terms and
8118 // sums them together for loading into the Jacobian.
8119 //
8120 // Special Notes : This was extracted from updateIntermediateVars.
8121 // Different variables are used, and nothing is multiplied
8122 // by ag0 = solState.pdt. The new-dae formulation handles
8123 // all the 1/dt - related stuff up in the time integrator.
8124 //
8125 // NOTE: nqs not even close to being supported.
8126 //
8127 // Scope : public
8128 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8129 // Creation Date : 04/23/04
8130 //-----------------------------------------------------------------------------
8132 {
8133  if (mode > 0)
8134  {
8135  if (nqsMod == 0)
8136  {
8137  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
8138  CAPcgdb = (cgdb - cgdo);
8139  CAPcgsb = (cgsb - cgso);
8140 
8141  CAPcdgb = (cdgb - cgdo);
8142  CAPcddb = (cddb + capbd + cgdo);
8143  CAPcdsb = cdsb;
8144 
8145  CAPcsgb = -(cggb + cbgb + cdgb + cgso);
8146  CAPcsdb = -(cgdb + cbdb + cddb);
8147  CAPcssb = (capbs + cgso - (cgsb + cbsb + cdsb));
8148 
8149  CAPcbgb = (cbgb - paramPtr->cgbo);
8150  CAPcbdb = (cbdb - capbd);
8151  CAPcbsb = (cbsb - capbs);
8152  }
8153  else // nqsMode != 0
8154  {
8155 
8156  } // nqsMod
8157  }
8158  else
8159  {
8160  if (nqsMod == 0)
8161  {
8162  CAPcggb = (cggb + cgdo + cgso + paramPtr->cgbo );
8163  CAPcgdb = (cgsb - cgdo);
8164  CAPcgsb = (cgdb - cgso);
8165 
8166  CAPcdgb = -(cggb + cbgb + cdgb + cgdo);
8167  CAPcddb = (capbd + cgdo - (cgsb + cbsb + cdsb));
8168  CAPcdsb = -(cgdb + cbdb + cddb);
8169 
8170  CAPcsgb = (cdgb - cgso);
8171  CAPcsdb = cdsb;
8172  CAPcssb = (cddb + capbs + cgso);
8173 
8174  CAPcbgb = (cbgb - paramPtr->cgbo);
8175  CAPcbdb = (cbsb - capbd);
8176  CAPcbsb = (cbdb - capbs);
8177  }
8178  else // nqsMode != 0
8179  {
8180 
8181  }
8182  }
8183 
8184  return true;
8185 }
8186 
8187 //-----------------------------------------------------------------------------
8188 // Function : Instance::setupCapacitors_oldDAE ()
8189 // Purpose : Same as new-DAE version, but including pdt, essentially.
8190 // Special Notes :
8191 //
8192 // Scope : public
8193 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8194 // Creation Date : 12/17/06
8195 //-----------------------------------------------------------------------------
8197 {
8198  double ag0 = getSolverState().pdt_;
8199  double T0 = 0.0;
8200 
8201  // ERK. 12/17/2006.
8202  // It is necessary to set ag0=0.0, because for the first time step out of
8203  // the DCOP, all the time derivatives are forced to be zero. Thus, all
8204  // their derivatives should also be zero. If it wasn't for that, then ag0
8205  // could always be pdt. (it used to be, before the -jacobian_test capability).
8206  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag_ && getSolverState().newtonIter==0)
8207  {
8208  ag0 = 0.0;
8209  }
8210 
8211  if (mode > 0)
8212  {
8213  if (nqsMod == 0)
8214  {
8215  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
8216  gcgdb = (cgdb - cgdo) * ag0;
8217  gcgsb = (cgsb - cgso) * ag0;
8218 
8219  gcdgb = (cdgb - cgdo) * ag0;
8220  gcddb = (cddb + capbd + cgdo) * ag0;
8221  gcdsb = cdsb * ag0;
8222 
8223  gcsgb = -(cggb + cbgb + cdgb + cgso) * ag0;
8224  gcsdb = -(cgdb + cbdb + cddb) * ag0;
8225  gcssb = (capbs + cgso - (cgsb + cbsb + cdsb)) * ag0;
8226 
8227  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
8228  gcbdb = (cbdb - capbd) * ag0;
8229  gcbsb = (cbsb - capbs) * ag0;
8230 
8231  qgd = qgdo;
8232  qgs = qgso;
8233  qgb = paramPtr->cgbo * vgb;
8234  qgate += qgd + qgs + qgb;
8235  qbulk -= qgb;
8236  qdrn -= qgd;
8237  qsrc = -(qgate + qbulk + qdrn);
8238 
8239  ggtg = ggtd = ggtb = ggts = 0.0;
8240  sxpart = 0.6;
8241  dxpart = 0.4;
8244  }
8245  else // nqsMode != 0
8246  {
8247  if (qcheq > 0.0)
8248  {
8249  T0 = paramPtr->tconst * qdef * ScalingFactor;
8250  }
8251  else
8252  {
8253  T0 = -paramPtr->tconst * qdef * ScalingFactor;
8254  }
8255 
8256  ggtg = gtg = T0 * cqgb;
8257  ggtd = gtd = T0 * cqdb;
8258  ggts = gts = T0 * cqsb;
8259  ggtb = gtb = T0 * cqbb;
8260  gqdef = ScalingFactor * ag0;
8261 
8262  gcqgb = cqgb * ag0;
8263  gcqdb = cqdb * ag0;
8264  gcqsb = cqsb * ag0;
8265  gcqbb = cqbb * ag0;
8266 
8267  gcggb = (cgdo + cgso + paramPtr->cgbo ) * ag0;
8268  gcgdb = -cgdo * ag0;
8269  gcgsb = -cgso * ag0;
8270 
8271  gcdgb = -cgdo * ag0;
8272  gcddb = (capbd + cgdo) * ag0;
8273  gcdsb = 0.0;
8274 
8275  gcsgb = -cgso * ag0;
8276  gcsdb = 0.0;
8277  gcssb = (capbs + cgso) * ag0;
8278 
8279  gcbgb = -paramPtr->cgbo * ag0;
8280  gcbdb = -capbd * ag0;
8281  gcbsb = -capbs * ag0;
8282 
8284 
8285  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
8286  {
8287  if (model_.xpart < 0.5) dxpart = 0.4;
8288  else if (model_.xpart > 0.5) dxpart = 0.0;
8289  else dxpart = 0.5;
8290 
8292  }
8293  else
8294  {
8295  dxpart = qdrn / qcheq;
8296  Cdd = cddb;
8297  Csd = -(cgdb + cddb + cbdb);
8298  ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
8299  Cdg = cdgb;
8300  Csg = -(cggb + cdgb + cbgb);
8301  ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
8302 
8303  Cds = cdsb;
8304  Css = -(cgsb + cdsb + cbsb);
8305  ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
8306 
8308  }
8309  sxpart = 1.0 - dxpart;
8314 
8315  qgd = qgdo;
8316  qgs = qgso;
8317  qgb = paramPtr->cgbo * vgb;
8318  qgate = qgd + qgs + qgb;
8319  qbulk = -qgb;
8320  qdrn = -qgd;
8321  qsrc = -(qgate + qbulk + qdrn);
8322  } // nqsMod
8323  }
8324  else
8325  {
8326  if (nqsMod == 0)
8327  {
8328  gcggb = (cggb + cgdo + cgso + paramPtr->cgbo ) * ag0;
8329  gcgdb = (cgsb - cgdo) * ag0;
8330  gcgsb = (cgdb - cgso) * ag0;
8331 
8332  gcdgb = -(cggb + cbgb + cdgb + cgdo) * ag0;
8333  gcddb = (capbd + cgdo - (cgsb + cbsb + cdsb)) * ag0;
8334  gcdsb = -(cgdb + cbdb + cddb) * ag0;
8335 
8336  gcsgb = (cdgb - cgso) * ag0;
8337  gcsdb = cdsb * ag0;
8338  gcssb = (cddb + capbs + cgso) * ag0;
8339 
8340  gcbgb = (cbgb - paramPtr->cgbo) * ag0;
8341  gcbdb = (cbsb - capbd) * ag0;
8342  gcbsb = (cbdb - capbs) * ag0;
8343 
8344  qgd = qgdo;
8345  qgs = qgso;
8346  qgb = paramPtr->cgbo * vgb;
8347  qgate += qgd + qgs + qgb;
8348  qbulk -= qgb;
8349  qsrc = qdrn - qgs;
8350  qdrn = -(qgate + qbulk + qsrc);
8351 
8352  ggtg = ggtd = ggtb = ggts = 0.0;
8353  sxpart = 0.4;
8354  dxpart = 0.6;
8357  }
8358  else // nqsMode != 0
8359  {
8360  if (qcheq > 0.0)
8361  {
8362  T0 = paramPtr->tconst * qdef * ScalingFactor;
8363  }
8364  else
8365  {
8366  T0 = -paramPtr->tconst * qdef * ScalingFactor;
8367  }
8368 
8369  ggtg = gtg = T0 * cqgb;
8370  ggts = gtd = T0 * cqdb;
8371  ggtd = gts = T0 * cqsb;
8372  ggtb = gtb = T0 * cqbb;
8373  gqdef = ScalingFactor * ag0;
8374 
8375  gcqgb = cqgb * ag0;
8376  gcqdb = cqsb * ag0;
8377  gcqsb = cqdb * ag0;
8378  gcqbb = cqbb * ag0;
8379 
8380  gcggb = (cgdo + cgso + paramPtr->cgbo) * ag0;
8381  gcgdb = -cgdo * ag0;
8382  gcgsb = -cgso * ag0;
8383 
8384  gcdgb = -cgdo * ag0;
8385  gcddb = (capbd + cgdo) * ag0;
8386  gcdsb = 0.0;
8387 
8388  gcsgb = -cgso * ag0;
8389  gcsdb = 0.0;
8390  gcssb = (capbs + cgso) * ag0;
8391 
8392  gcbgb = -paramPtr->cgbo * ag0;
8393  gcbdb = -capbd * ag0;
8394  gcbsb = -capbs * ag0;
8395 
8397 
8398  if (fabs(qcheq) <= 1.0e-5 * CoxWL)
8399  {
8400  if (model_.xpart < 0.5) sxpart = 0.4;
8401  else if (model_.xpart > 0.5) sxpart = 0.0;
8402  else sxpart = 0.5;
8403 
8405  }
8406  else
8407  {
8408  sxpart = qdrn / qcheq;
8409  Css = cddb;
8410  Cds = -(cgdb + cddb + cbdb);
8411  dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
8412  Csg = cdgb;
8413  Cdg = -(cggb + cdgb + cbgb);
8414  dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
8415 
8416  Csd = cdsb;
8417  Cdd = -(cgsb + cdsb + cbsb);
8418  dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
8419 
8421  }
8422 
8423  dxpart = 1.0 - sxpart;
8428 
8429  qgd = qgdo;
8430  qgs = qgso;
8431  qgb = paramPtr->cgbo * vgb;
8432  qgate = qgd + qgs + qgb;
8433  qbulk = -qgb;
8434  qsrc = -qgs;
8435  qdrn = -(qgate + qbulk + qsrc);
8436  }
8437  }
8438 
8439  return true;
8440 }
8441 
8442 //-----------------------------------------------------------------------------
8443 // Function : Instance::loadDAEFVector
8444 //
8445 // Purpose : Loads the F-vector contributions for a single
8446 // bsim3 instance.
8447 //
8448 // Special Notes :
8449 //
8450 // Scope : public
8451 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8452 // Creation Date : 04/07/04
8453 //-----------------------------------------------------------------------------
8455 {
8456  double * fVec = extData.daeFVectorRawPtr;
8457  double * dFdxdVp = extData.dFdxdVpVectorRawPtr;
8458 
8459  double coef(0.0);
8460 
8461  cdreq_Jdxp = 0.0;
8462  ceqbd_Jdxp = 0.0;
8463  ceqbs_Jdxp = 0.0;
8464 
8465  // Do a few auxilliary calculations, derived from 3f5.
8466  // load current vector
8467  if (mode >= 0)
8468  {
8469  Gm = gm;
8470  Gmbs = gmbs;
8471  FwdSum = Gm + Gmbs;
8472  RevSum = 0.0;
8473 
8474  cdreq = model_.dtype * (cd);
8475  ceqbd = -model_.dtype * (csub);
8476 
8477  ceqbs = 0.0;
8478 
8479  gbbdp = -gbds;
8480  gbbsp = (gbds + gbgs + gbbs);
8481 
8482  gbdpg = gbgs;
8483  gbdpdp = gbds;
8484  gbdpb = gbbs;
8485  gbdpsp = -(gbdpg + gbdpdp + gbdpb);
8486 
8487  gbspg = 0.0;
8488  gbspdp = 0.0;
8489  gbspb = 0.0;
8490  gbspsp = 0.0;
8491  }
8492  else
8493  {
8494  Gm = -gm;
8495  Gmbs = -gmbs;
8496  FwdSum = 0.0;
8497  RevSum = -(Gm + Gmbs);
8498 
8499  cdreq = -model_.dtype * (cd);
8500  ceqbs = -model_.dtype * (csub);
8501 
8502  ceqbd = 0.0;
8503 
8504  gbbsp = -gbds;
8505  gbbdp = (gbds + gbgs + gbbs);
8506 
8507  gbdpg = 0.0;
8508  gbdpsp = 0.0;
8509  gbdpb = 0.0;
8510  gbdpdp = 0.0;
8511 
8512  gbspg = gbgs;
8513  gbspsp = gbds;
8514  gbspb = gbbs;
8515  gbspdp = -(gbspg + gbspsp + gbspb);
8516  }
8517 
8518  if (model_.dtype > 0)
8519  {
8520  ceqbs += (cbs);
8521  ceqbd += (cbd);
8522  }
8523  else
8524  {
8525  ceqbs -= (cbs);
8526  ceqbd -= (cbd);
8527  }
8528 
8529  if (drainConductance != 0.0)
8530  {
8531  fVec[li_Drain] += Idrain*numberParallel;
8532  }
8533  if (sourceConductance != 0.0)
8534  {
8535  fVec[li_Source] += Isource*numberParallel;
8536  }
8537  fVec[li_Bulk] += (ceqbs + ceqbd)*numberParallel;
8538  fVec[li_DrainPrime] += (-(ceqbd - cdreq)-Idrain)*numberParallel;
8540 
8541  // lead current support
8542  if( loadLeadCurrent )
8543  {
8544  double * storeLeadF = extData.nextStoVectorRawPtr;
8545  if (drainConductance != 0.0)
8546  {
8547  storeLeadF[li_store_dev_id] = Idrain*numberParallel;
8548  }
8549  else
8550  {
8551  storeLeadF[li_store_dev_id] = (-(ceqbd - cdreq)-Idrain)*numberParallel;
8552  }
8553  if (sourceConductance != 0.0)
8554  {
8555  storeLeadF[li_store_dev_is] = Isource*numberParallel;
8556  }
8557  else
8558  {
8559  storeLeadF[li_store_dev_is] = (-(cdreq + ceqbs)-Isource)*numberParallel;
8560  }
8561  storeLeadF[li_store_dev_ig] = 0.0;
8562  storeLeadF[li_store_dev_ib] = (ceqbs + ceqbd)*numberParallel;
8563  }
8564 
8565  // Initial condition support
8566 
8568  {
8570  fVec[li_Drain] += coef;
8571  fVec[li_Source] += -coef;
8572  if( loadLeadCurrent )
8573  {
8574  double * storeLeadF = extData.nextStoVectorRawPtr;
8575  storeLeadF[li_store_dev_id]= coef;
8576  storeLeadF[li_store_dev_is]= -coef;
8577  }
8578  }
8579 
8581  {
8583  fVec[li_Gate] += coef;
8584  fVec[li_Source] += -coef;
8585  if( loadLeadCurrent )
8586  {
8587  double * storeLeadF = extData.nextStoVectorRawPtr;
8588  storeLeadF[li_store_dev_ig]= coef;
8589  storeLeadF[li_store_dev_is]= -coef;
8590  }
8591  }
8592 
8593 
8595  {
8597  fVec[li_Bulk] += coef;
8598  fVec[li_Source] += -coef;
8599  if( loadLeadCurrent )
8600  {
8601  double * storeLeadF = extData.nextStoVectorRawPtr;
8602  storeLeadF[li_store_dev_ib]= coef;
8603  storeLeadF[li_store_dev_is]= -coef;
8604  }
8605  }
8606 
8607 
8608 
8609  //////////////////////////////////////////////////
8610  // limiting section:
8612  {
8613  if (!origFlag)
8614  {
8615  if (mode >= 0)
8616  {
8617  // option 1
8618  double tmp = model_.dtype * (-gds * (vds-vds_orig) -
8619  Gm * (vgs-vgs_orig) -
8620  Gmbs * (vbs-vbs_orig));
8621 
8622  cdreq_Jdxp += tmp;
8623  cdreq += tmp;
8624 
8625  tmp = -model_.dtype * (-gbds * (vds-vds_orig) -
8626  gbgs * (vgs-vgs_orig) -
8627  gbbs * (vbs-vbs_orig));
8628  ceqbd_Jdxp += tmp;
8629  ceqbd += tmp;
8630  }
8631  else
8632  {
8633  // option 2
8634  double tmp = -model_.dtype * (gds * (vds-vds_orig) +
8635  Gm * (vgd-vgd_orig) +
8636  Gmbs * (vbd-vbd_orig));
8637  cdreq_Jdxp += tmp;
8638  cdreq += tmp;
8639 
8640  tmp = -model_.dtype * (gbds * (vds-vds_orig) -
8641  gbgs * (vgd-vgd_orig) -
8642  gbbs * (vbd-vbd_orig));
8643  ceqbd_Jdxp += tmp;
8644  ceqbd += tmp;
8645  }
8646 
8647 
8648  if (model_.dtype > 0)
8649  {
8650  ceqbs_Jdxp += (-gbs*(vbs-vbs_orig));
8651  ceqbs += (-gbs*(vbs-vbs_orig));
8652 
8653  ceqbd_Jdxp += (-gbd*(vbd-vbd_orig));
8654  ceqbd += (-gbd*(vbd-vbd_orig));
8655  }
8656  else
8657  {
8658  ceqbs_Jdxp -= (-gbs*(vbs-vbs_orig) );
8659  ceqbs -= (-gbs*(vbs-vbs_orig) );
8660 
8661  ceqbd_Jdxp -= (-gbd*(vbd-vbd_orig) );
8662  ceqbd -= (-gbd*(vbd-vbd_orig) );
8663  }
8667  } // orig flag.
8668  } // voltage limiter flag
8669 
8670  // Row associated with icVBS
8672  {
8673  // get the voltage drop from the previous solution
8674  double cVs = extData.nextSolVectorRawPtr[li_Source];
8675  double cVb = extData.nextSolVectorRawPtr[li_Bulk];
8676  fVec[li_Ibs] += (cVb - cVs - icVBS);
8677  }
8678 
8679  // Row associated with icVDS
8681  {
8682  // get the voltage drop from the previous solution
8683  double cVd = extData.nextSolVectorRawPtr[li_Drain];
8684  double cVs = extData.nextSolVectorRawPtr[li_Source];
8685  fVec[li_Ids] += (cVd - cVs - icVDS);
8686  }
8687 
8688  // Row associated with icVGS
8690  {
8691  // get the voltage drop from the previous solution
8692  double cVg = extData.nextSolVectorRawPtr[li_Gate];
8693  double cVs = extData.nextSolVectorRawPtr[li_Source];
8694 
8695  fVec[li_Igs] += (cVg - cVs - icVGS);
8696  }
8697 
8698  return true;
8699 }
8700 
8701 //-----------------------------------------------------------------------------
8702 // Function : Instance::loadDAEdQdx
8703 //
8704 // Purpose : Loads the Q-vector contributions for a single
8705 // bsim3 instance.
8706 //
8707 // Special Notes : The "Q" vector is part of a standard DAE formalism in
8708 // which the system of equations is represented as:
8709 //
8710 // f(x) = dQ(x)/dt + F(x) - B(t) = 0
8711 //
8712 // Scope : public
8713 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8714 // Creation Date : 04/07/04
8715 //-----------------------------------------------------------------------------
8717 {
8718  {
8719  Linear::Matrix & dQdx = *(extData.dQdxMatrixPtr);
8720 
8721  // Row corresponding to the KCL for the drain node: NOTHING
8722 
8723  // Row corresponding to the KCL for the source node: NOTHING
8724 
8725  // Row corresponding to the KCL for the gate node:
8726  // Check this later. ERK. See the comments in the function
8727  // loadDAEdQdx, regarding ggtg, ggtb, etc.
8728  //
8729  // For now I am leaving out the gg terms, as they are zero when
8730  // nqsMod=0, which is always true.
8731  //
8733  += (CAPcggb )*numberParallel;
8737  += (CAPcgdb )*numberParallel;
8739  += (CAPcgsb )*numberParallel;
8740 
8741  // Row corresponding to the KCL for the bulk node:
8743  += (CAPcbgb)*numberParallel;
8744 
8747 
8749  += (CAPcbdb)*numberParallel;
8750 
8752  += (CAPcbsb)*numberParallel;
8753 
8754 
8755  // Row corresponding to the KCL for the drain prime node:
8757  -= (+ CAPcdgb + CAPcddb + CAPcdsb )*numberParallel;
8758 
8760  += (CAPcdgb) *numberParallel;
8761 
8763  += (+ CAPcddb )*numberParallel;
8764 
8766  -= (- CAPcdsb) *numberParallel;
8767 
8768  // Row corresponding to the KCL for the source prime node:
8770  += (CAPcsgb) *numberParallel;
8771 
8773  -= (+ CAPcsgb + CAPcsdb + CAPcssb) *numberParallel;
8774 
8776  -= (- CAPcsdb) *numberParallel;
8777 
8779  += (+ CAPcssb) *numberParallel;
8780 
8781  // Row associated with the charge equation
8782  // This is currently not supported.
8783  if (nqsMod)
8784  {
8785  std::string msg;
8786  msg = "Instance::loadDAEdQdx";
8787  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8788  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8789  }
8790  }
8791  return true;
8792 }
8793 
8794 //-----------------------------------------------------------------------------
8795 // Function : Instance::loadDAEdFdx ()
8796 //
8797 // Purpose : Loads the F-vector contributions for a single
8798 // bsim3 instance.
8799 //
8800 // Special Notes :
8801 //
8802 // Scope : public
8803 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
8804 // Creation Date : 04/07/04
8805 //-----------------------------------------------------------------------------
8807 {
8808  Linear::Matrix & dFdx = *(extData.dFdxMatrixPtr);
8809 
8810  // Row corresponding to the KCL for the drain node:
8815 
8816  // Extra term for initial conditions on Vds in operating point
8818  {
8819  dFdx[li_Drain][ADrainEquIdsOffset] += 1.0;
8820  }
8821 
8822  // Row corresponding to the KCL for the source node:
8827 
8828  // Extra term for initial conditions on Vbs in operating point
8830  {
8831  dFdx[li_Source][ASourceEquIbsOffset] -= 1.0;
8832  }
8833  // Extra term for initial conditions on Vds in operating point
8835  {
8836  dFdx[li_Source][ASourceEquIdsOffset] -= 1.0;
8837  }
8838  // Extra term for initial conditions on Vgs in operating point
8840  {
8841  dFdx[li_Source][ASourceEquIgsOffset] -= 1.0;
8842  }
8843 
8844  // Row corresponding to the KCL for the gate node: NOTHING
8845  // Check this later. ERK.
8846  //
8847  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
8848  // belong here. I'm not sure aboug the gg terms. On one hand, the
8849  // rhs vector component for the gate node ONLY seems to take
8850  // capacitive currents, which implies that all of these are capacitive
8851  // conductances. On the other hand, the gg terms do not appear to
8852  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
8853  // capacitive conductances are of the form g = C/dt, and the gg terms
8854  // do not have this form.
8855  //
8856  // For now, the gg issue is moot b/c those terms are only nonzero
8857  // if nqsMod = 1, which is not a supported option.
8858 
8859  // However, the gg
8860  // terms (ggtg, ggtb, ggtd and ggts)
8861  //
8862  //(*JMatPtr)[li_Gate][AGateEquGateNodeOffset]
8863  // += (gcggb - ggtg)*numberParallel;
8864  //(*JMatPtr)[li_Gate][AGateEquBulkNodeOffset]
8865  // -= (gcggb + gcgdb + gcgsb + ggtb)*numberParallel;
8866  //(*JMatPtr)[li_Gate][AGateEquDrainPrimeNodeOffset]
8867  // += (gcgdb - ggtd)*numberParallel;
8868  //(*JMatPtr)[li_Gate][AGateEquSourcePrimeNodeOffset]
8869  // += (gcgsb - ggts)*numberParallel;
8870 
8871  // initial conditions on gate node
8872  // Extra term for initial conditions on Vgs in operating point
8874  {
8875  dFdx[li_Gate][AGateEquIgsOffset] += 1.0;
8876  }
8877 
8878  // Row corresponding to the KCL for the bulk node:
8880  += (- gbgs)*numberParallel;
8881 
8883  += (gbd + gbs - gbbs)*numberParallel;
8884 
8886  += (- gbd + gbbdp)*numberParallel;
8887 
8889  += (- gbs + gbbsp)*numberParallel;
8890 
8891  // Extra term for initial conditions on Vbs in operating point
8893  {
8894  dFdx[li_Bulk][ABulkEquIbsOffset] += 1.0;
8895  }
8896 
8897  // Row corresponding to the KCL for the drain prime node:
8900 
8902  -= (gbd - Gmbs - dxpart*ggtb
8903  - T1global*ddxpart_dVb - gbdpb)*numberParallel;
8904 
8906  += (Gm + dxpart*ggtg + T1global*ddxpart_dVg + gbdpg)
8907  *numberParallel;
8908 
8911  + T1global*ddxpart_dVd + gbdpdp)*numberParallel;
8912 
8915  *numberParallel;
8916 
8917  // Row corresponding to the KCL for the source prime node:
8919  += (- Gm + sxpart*ggtg + T1global*dsxpart_dVg + gbspg)
8920  *numberParallel;
8921 
8923  -= (gbs + Gmbs - sxpart*ggtb
8924  - T1global*dsxpart_dVb - gbspb)*numberParallel;
8925 
8928 
8931  *numberParallel;
8932 
8935  + T1global*dsxpart_dVs + gbspsp)*numberParallel;
8936 
8937  // Row associated with the charge equation
8938  if (nqsMod)
8939  {
8940  std::string msg;
8941  msg = "Instance::loadDAEdFdx";
8942  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
8943  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
8944  }
8945 
8946  // Initial condition rows
8947  // Row associated with icVBS
8948  if( icVBSGiven )
8949  {
8950  if( getSolverState().dcopFlag )
8951  {
8952  dFdx[li_Ibs][icVBSEquVbOffset] += 1.0;
8953  dFdx[li_Ibs][icVBSEquVsOffset] -= 1.0;
8954  }
8955  else
8956  {
8957  dFdx[li_Ibs][icVBSEquIbsOffset] += 1.0;
8958  }
8959  }
8960 
8961  // Row associated with icVDS
8962  if( icVDSGiven )
8963  {
8964  if( getSolverState().dcopFlag )
8965  {
8966  dFdx[li_Ids][icVDSEquVdOffset] += 1.0;
8967  dFdx[li_Ids][icVDSEquVsOffset] -= 1.0;
8968  }
8969  else
8970  {
8971  dFdx[li_Ids][icVDSEquIdsOffset] += 1.0;
8972  }
8973  }
8974 
8975  // Row associated with icVGS
8976  if( icVGSGiven )
8977  {
8978  if( getSolverState().dcopFlag )
8979  {
8980  dFdx[li_Igs][icVGSEquVgOffset] += 1.0;
8981  dFdx[li_Igs][icVGSEquVsOffset] -= 1.0;
8982  }
8983  else
8984  {
8985  dFdx[li_Igs][icVGSEquIgsOffset] += 1.0;
8986  }
8987  }
8988 
8989  return true;
8990 }
8991 
8992 //-----------------------------------------------------------------------------
8993 // Function : Instance::setIC
8994 // Purpose :
8995 // Special Notes :
8996 // Scope : public
8997 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
8998 // Creation Date : 01/10/02
8999 //-----------------------------------------------------------------------------
9001 {
9002  bool bsuccess = true;
9003 
9004  if( icVBSGiven )
9005  {
9008  }
9009 
9010  if( icVDSGiven )
9011  {
9014  }
9015 
9016  if( icVGSGiven )
9017  {
9020  }
9021 
9022  return bsuccess;
9023 }
9024 
9025 
9026 // Additional Declarations
9027 
9028 // Class Model
9029 
9030 //-----------------------------------------------------------------------------
9031 // Function : Model::processParams
9032 // Purpose :
9033 // Special Notes :
9034 // Scope : public
9035 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9036 // Creation Date : 6/03/02
9037 //-----------------------------------------------------------------------------
9039 {
9040  std::string msg;
9041  cox = 3.453133e-11 / tox;
9042  if (!given("TOXM")) toxm = tox;
9043  if (!given("DSUB")) dsub = drout;
9044  if (!given("LLC")) Llc = Ll;
9045  if (!given("LWC")) Lwc = Lw;
9046  if (!given("LWLC")) Lwlc = Lwl;
9047  if (!given("WLC")) Wlc = Wl;
9048  if (!given("WWL")) Wwlc = Wwl;
9049  if (!given("WWLC")) Wwlc = Wwl;
9050  if (!given("DWC")) dwc = Wint;
9051  if (!given("DLC")) dlc = Lint;
9052 
9053  if (!given("CF"))
9054  {
9055  double C1 = 2.0 * CONSTEPSOX;
9056  double C5 = M_PI;
9057  double C2 = 1.0 + (0.4e-6 / tox);
9058  double C3 = log(C2);
9059  cf = C1*C3/C5;
9060  }
9061 
9062  if (!given("CGDO"))
9063  {
9064  if (given("DLC") && (dlc > 0.0)) cgdo = dlc * cox - cgdl ;
9065  else cgdo = 0.6 * xj * cox;
9066  }
9067 
9068  if (!given("CGSO"))
9069  {
9070  if (given("DLC") && (dlc > 0.0)) cgso = dlc * cox - cgsl ;
9071  else cgso = 0.6 * xj * cox;
9072  }
9073 
9074  if (!given("CGBO")) cgbo = 2.0 * dwc * cox;
9075 
9076  if (!given("CJSWG"))
9077  unitLengthGateSidewallJctCap = unitLengthSidewallJctCap ;
9078 
9079  if (!given("PBSWG"))
9080  GatesidewallJctPotential = sidewallJctPotential;
9081 
9082  if (!given("MJSWG"))
9083  bulkJctGateSideGradingCoeff = bulkJctSideGradingCoeff;
9084 
9085 
9086  // More initializations: taken from b3temp.c:
9087  if (bulkJctPotential < 0.1)
9088  {
9089  bulkJctPotential = 0.1;
9090  msg = "Given pb is less than 0.1. Pb is set to 0.1.\n";
9091  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
9092  }
9093 
9094  if (sidewallJctPotential < 0.1)
9095  {
9096  sidewallJctPotential = 0.1;
9097  msg = "Given pbsw is less than 0.1. Pbsw is set to 0.1.\n";
9098  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
9099  }
9100 
9101  if (GatesidewallJctPotential < 0.1)
9102  {
9103  GatesidewallJctPotential = 0.1;
9104  msg = "Given pbswg is less than 0.1. Pbswg is set to 0.1.\n";
9105  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::USR_WARNING_0,msg);
9106  }
9107 
9108  vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14));
9109  factor1 = sqrt(CONSTEPSSI / CONSTEPSOX * tox);
9110 
9111  Vtm0 = CONSTKoverQ * tnom;
9112  Eg0 = CONSTEg0 - CONSTalphaEg * tnom * tnom / (tnom + CONSTbetaEg);
9113  ni = CONSTNi0 * (tnom / CONSTREFTEMP) * sqrt(tnom / CONSTREFTEMP)
9114  * exp(21.5565981 - Eg0 / (2.0 * Vtm0));
9115 
9116  // If there are any time dependent parameters, set their values at for
9117  // the current time.
9118 
9119  // We have changed model parameters (maybe) and so all size dependent params
9120  // we may have stored may be invalid. Clear them
9121  clearTemperatureData();
9122 
9123  return true;
9124 }
9125 
9126 //----------------------------------------------------------------------------
9127 // Function : Model::processInstanceParams
9128 // Purpose :
9129 // Special Notes :
9130 // Scope : public
9131 // Creator : Dave Shirely, PSSI
9132 // Creation Date : 03/23/06
9133 //----------------------------------------------------------------------------
9135 {
9136  std::vector<Instance*>::iterator iter;
9137  std::vector<Instance*>::iterator first = instanceContainer.begin();
9138  std::vector<Instance*>::iterator last = instanceContainer.end();
9139 
9140  for (iter=first; iter!=last; ++iter)
9141  {
9142  (*iter)->processParams();
9143  }
9144 
9145  return true;
9146 }
9147 
9148 //-----------------------------------------------------------------------------
9149 // Function : Model::Model
9150 // Purpose : model block constructor
9151 // Special Notes :
9152 // Scope : public
9153 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9154 // Creation Date : 11/14/00
9155 //-----------------------------------------------------------------------------
9157  const Configuration & configuration,
9158  const ModelBlock & MB,
9159  const FactoryBlock & factory_block)
9160  : DeviceModel(MB, configuration.getModelParameters(), factory_block),
9161  modType (0),
9162  dtype (CONSTNMOS),
9163  mobMod (0),
9164  capMod (0),
9165  noiMod (1),
9166  binUnit (0),
9167  paramChk (0),
9168  version ("3.2.2"),
9169  tox (0.0),
9170  toxm (0.0),
9171  cdsc (0.0),
9172  cdscb (0.0),
9173  cdscd (0.0),
9174  cit (0.0),
9175  nfactor (0.0),
9176  xj (0.0),
9177  vsat (0.0),
9178  at (0.0),
9179  a0 (0.0),
9180  ags (0.0),
9181  a1 (0.0),
9182  a2 (0.0),
9183  keta (0.0),
9184  nsub (0.0),
9185  npeak (0.0),
9186  ngate (0.0),
9187  gamma1 (0.0),
9188  gamma2 (0.0),
9189  vbx (0.0),
9190  vbm (0.0),
9191  xt (0.0),
9192  k1 (0.0),
9193  kt1 (0.0),
9194  kt1l (0.0),
9195  kt2 (0.0),
9196  k2 (0.0),
9197  k3 (0.0),
9198  k3b (0.0),
9199  w0 (0.0),
9200  nlx (0.0),
9201  dvt0 (0.0),
9202  dvt1 (0.0),
9203  dvt2 (0.0),
9204  dvt0w (0.0),
9205  dvt1w (0.0),
9206  dvt2w (0.0),
9207  drout (0.0),
9208  dsub (0.0),
9209  vth0 (0.0),
9210  ua (0.0),
9211  ua1 (0.0),
9212  ub (0.0),
9213  ub1 (0.0),
9214  uc (0.0),
9215  uc1 (0.0),
9216  u0 (0.0),
9217  ute (0.0),
9218  voff (0.0),
9219  delta (0.0),
9220  rdsw (0.0),
9221  prwg (0.0),
9222  prwb (0.0),
9223  prt (0.0),
9224  eta0 (0.0),
9225  etab (0.0),
9226  pclm (0.0),
9227  pdibl1 (0.0),
9228  pdibl2 (0.0),
9229  pdiblb (0.0),
9230  pscbe1 (0.0),
9231  pscbe2 (0.0),
9232  pvag (0.0),
9233  wr (0.0),
9234  dwg (0.0),
9235  dwb (0.0),
9236  b0 (0.0),
9237  b1 (0.0),
9238  alpha0 (0.0),
9239  alpha1 (0.0),
9240  beta0 (0.0),
9241  ijth (0.0),
9242  vfb (0.0),
9243  elm (0.0),
9244  cgsl (0.0),
9245  cgdl (0.0),
9246  ckappa (0.0),
9247  cf (0.0),
9248  vfbcv (0.0),
9249  clc (0.0),
9250  cle (0.0),
9251  dwc (0.0),
9252  dlc (0.0),
9253  noff (0.0),
9254  voffcv (0.0),
9255  acde (0.0),
9256  moin (0.0),
9257  tcj (0.0),
9258  tcjsw (0.0),
9259  tcjswg (0.0),
9260  tpb (0.0),
9261  tpbsw (0.0),
9262  tpbswg (0.0),
9263  lcdsc (0.0),
9264  lcdscb (0.0),
9265  lcdscd (0.0),
9266  lcit (0.0),
9267  lnfactor (0.0),
9268  lxj (0.0),
9269  lvsat (0.0),
9270  lat (0.0),
9271  la0 (0.0),
9272  lags (0.0),
9273  la1 (0.0),
9274  la2 (0.0),
9275  lketa (0.0),
9276  lnsub (0.0),
9277  lnpeak (0.0),
9278  lngate (0.0),
9279  lgamma1 (0.0),
9280  lgamma2 (0.0),
9281  lvbx (0.0),
9282  lvbm (0.0),
9283  lxt (0.0),
9284  lk1 (0.0),
9285  lkt1 (0.0),
9286  lkt1l (0.0),
9287  lkt2 (0.0),
9288  lk2 (0.0),
9289  lk3 (0.0),
9290  lk3b (0.0),
9291  lw0 (0.0),
9292  lnlx (0.0),
9293  ldvt0 (0.0),
9294  ldvt1 (0.0),
9295  ldvt2 (0.0),
9296  ldvt0w (0.0),
9297  ldvt1w (0.0),
9298  ldvt2w (0.0),
9299  ldrout (0.0),
9300  ldsub (0.0),
9301  lvth0 (0.0),
9302  lua (0.0),
9303  lua1 (0.0),
9304  lub (0.0),
9305  lub1 (0.0),
9306  luc (0.0),
9307  luc1 (0.0),
9308  lu0 (0.0),
9309  lute (0.0),
9310  lvoff (0.0),
9311  ldelta (0.0),
9312  lrdsw (0.0),
9313  lprwg (0.0),
9314  lprwb (0.0),
9315  lprt (0.0),
9316  leta0 (0.0),
9317  letab (0.0),
9318  lpclm (0.0),
9319  lpdibl1 (0.0),
9320  lpdibl2 (0.0),
9321  lpdiblb (0.0),
9322  lpscbe1 (0.0),
9323  lpscbe2 (0.0),
9324  lpvag (0.0),
9325  lwr (0.0),
9326  ldwg (0.0),
9327  ldwb (0.0),
9328  lb0 (0.0),
9329  lb1 (0.0),
9330  lalpha0 (0.0),
9331  lalpha1 (0.0),
9332  lbeta0 (0.0),
9333  lvfb (0.0),
9334  lelm (0.0),
9335  lcgsl (0.0),
9336  lcgdl (0.0),
9337  lckappa (0.0),
9338  lcf (0.0),
9339  lclc (0.0),
9340  lcle (0.0),
9341  lvfbcv (0.0),
9342  lnoff (0.0),
9343  lvoffcv (0.0),
9344  lacde (0.0),
9345  lmoin (0.0),
9346  wcdsc (0.0),
9347  wcdscb (0.0),
9348  wcdscd (0.0),
9349  wcit (0.0),
9350  wnfactor (0.0),
9351  wxj (0.0),
9352  wvsat (0.0),
9353  wat (0.0),
9354  wa0 (0.0),
9355  wags (0.0),
9356  wa1 (0.0),
9357  wa2 (0.0),
9358  wketa (0.0),
9359  wnsub (0.0),
9360  wnpeak (0.0),
9361  wngate (0.0),
9362  wgamma1 (0.0),
9363  wgamma2 (0.0),
9364  wvbx (0.0),
9365  wvbm (0.0),
9366  wxt (0.0),
9367  wk1 (0.0),
9368  wkt1 (0.0),
9369  wkt1l (0.0),
9370  wkt2 (0.0),
9371  wk2 (0.0),
9372  wk3 (0.0),
9373  wk3b (0.0),
9374  ww0 (0.0),
9375  wnlx (0.0),
9376  wdvt0 (0.0),
9377  wdvt1 (0.0),
9378  wdvt2 (0.0),
9379  wdvt0w (0.0),
9380  wdvt1w (0.0),
9381  wdvt2w (0.0),
9382  wdrout (0.0),
9383  wdsub (0.0),
9384  wvth0 (0.0),
9385  wua (0.0),
9386  wua1 (0.0),
9387  wub (0.0),
9388  wub1 (0.0),
9389  wuc (0.0),
9390  wuc1 (0.0),
9391  wu0 (0.0),
9392  wute (0.0),
9393  wvoff (0.0),
9394  wdelta (0.0),
9395  wrdsw (0.0),
9396  wprwg (0.0),
9397  wprwb (0.0),
9398  wprt (0.0),
9399  weta0 (0.0),
9400  wetab (0.0),
9401  wpclm (0.0),
9402  wpdibl1 (0.0),
9403  wpdibl2 (0.0),
9404  wpdiblb (0.0),
9405  wpscbe1 (0.0),
9406  wpscbe2 (0.0),
9407  wpvag (0.0),
9408  wwr (0.0),
9409  wdwg (0.0),
9410  wdwb (0.0),
9411  wb0 (0.0),
9412  wb1 (0.0),
9413  walpha0 (0.0),
9414  walpha1 (0.0),
9415  wbeta0 (0.0),
9416  wvfb (0.0),
9417  welm (0.0),
9418  wcgsl (0.0),
9419  wcgdl (0.0),
9420  wckappa (0.0),
9421  wcf (0.0),
9422  wclc (0.0),
9423  wcle (0.0),
9424  wvfbcv (0.0),
9425  wnoff (0.0),
9426  wvoffcv (0.0),
9427  wacde (0.0),
9428  wmoin (0.0),
9429  pcdsc (0.0),
9430  pcdscb (0.0),
9431  pcdscd (0.0),
9432  pcit (0.0),
9433  pnfactor (0.0),
9434  pxj (0.0),
9435  pvsat (0.0),
9436  pat (0.0),
9437  pa0 (0.0),
9438  pags (0.0),
9439  pa1 (0.0),
9440  pa2 (0.0),
9441  pketa (0.0),
9442  pnsub (0.0),
9443  pnpeak (0.0),
9444  pngate (0.0),
9445  pgamma1 (0.0),
9446  pgamma2 (0.0),
9447  pvbx (0.0),
9448  pvbm (0.0),
9449  pxt (0.0),
9450  pk1 (0.0),
9451  pkt1 (0.0),
9452  pkt1l (0.0),
9453  pkt2 (0.0),
9454  pk2 (0.0),
9455  pk3 (0.0),
9456  pk3b (0.0),
9457  pw0 (0.0),
9458  pnlx (0.0),
9459  pdvt0 (0.0),
9460  pdvt1 (0.0),
9461  pdvt2 (0.0),
9462  pdvt0w (0.0),
9463  pdvt1w (0.0),
9464  pdvt2w (0.0),
9465  pdrout (0.0),
9466  pdsub (0.0),
9467  pvth0 (0.0),
9468  pua (0.0),
9469  pua1 (0.0),
9470  pub (0.0),
9471  pub1 (0.0),
9472  puc (0.0),
9473  puc1 (0.0),
9474  pu0 (0.0),
9475  pute (0.0),
9476  pvoff (0.0),
9477  pdelta (0.0),
9478  prdsw (0.0),
9479  pprwg (0.0),
9480  pprwb (0.0),
9481  pprt (0.0),
9482  peta0 (0.0),
9483  petab (0.0),
9484  ppclm (0.0),
9485  ppdibl1 (0.0),
9486  ppdibl2 (0.0),
9487  ppdiblb (0.0),
9488  ppscbe1 (0.0),
9489  ppscbe2 (0.0),
9490  ppvag (0.0),
9491  pwr (0.0),
9492  pdwg (0.0),
9493  pdwb (0.0),
9494  pb0 (0.0),
9495  pb1 (0.0),
9496  palpha0 (0.0),
9497  palpha1 (0.0),
9498  pbeta0 (0.0),
9499  pvfb (0.0),
9500  pelm (0.0),
9501  pcgsl (0.0),
9502  pcgdl (0.0),
9503  pckappa (0.0),
9504  pcf (0.0),
9505  pclc (0.0),
9506  pcle (0.0),
9507  pvfbcv (0.0),
9508  pnoff (0.0),
9509  pvoffcv (0.0),
9510  pacde (0.0),
9511  pmoin (0.0),
9512  tnom (getDeviceOptions().tnom),
9513  cgso (0.0),
9514  cgdo (0.0),
9515  cgbo (0.0),
9516  xpart (0.0),
9517  cFringOut (0.0),
9518  cFringMax (0.0),
9519  sheetResistance (0.0),
9520  jctSatCurDensity (0.0),
9521  jctSidewallSatCurDensity (0.0),
9522  bulkJctPotential (0.0),
9523  bulkJctBotGradingCoeff (0.0),
9524  bulkJctSideGradingCoeff (0.0),
9525  bulkJctGateSideGradingCoeff (0.0),
9526  sidewallJctPotential (0.0),
9527  GatesidewallJctPotential (0.0),
9528  unitAreaJctCap (0.0),
9529  unitLengthSidewallJctCap (0.0),
9530  unitLengthGateSidewallJctCap (0.0),
9531  jctEmissionCoeff (0.0),
9532  jctTempExponent (0.0),
9533  Lint (0.0),
9534  Ll (0.0),
9535  Llc (0.0),
9536  Lln (0.0),
9537  Lw (0.0),
9538  Lwc (0.0),
9539  Lwn (0.0),
9540  Lwl (0.0),
9541  Lwlc (0.0),
9542  model_l (0.0),
9543  model_w (0.0),
9544  Lmin (0.0),
9545  Lmax (0.0),
9546  Wmin (0.0),
9547  Wmax (0.0),
9548  Wint (0.0),
9549  Wl (0.0),
9550  Wlc (0.0),
9551  Wln (0.0),
9552  Ww (0.0),
9553  Wwc (0.0),
9554  Wwn (0.0),
9555  Wwl (0.0),
9556  Wwlc (0.0),
9557  vtm (0.0),
9558  cox (0.0),
9559  cof1 (0.0),
9560  cof2 (0.0),
9561  cof3 (0.0),
9562  cof4 (0.0),
9563  vcrit (0.0),
9564  factor1 (0.0),
9565  PhiB (0.0),
9566  PhiBSW (0.0),
9567  PhiBSWG (0.0),
9568  oxideTrapDensityA (0.0),
9569  oxideTrapDensityB (0.0),
9570  oxideTrapDensityC (0.0),
9571  em (0.0),
9572  ef (0.0),
9573  af (0.0),
9574  kf (0.0),
9575  lintnoi (0.0),
9576  npeakGiven (0.0),
9577  gamma1Given (0.0),
9578  gamma2Given (0.0),
9579  k1Given (0.0),
9580  k2Given (0.0),
9581  nsubGiven (0.0),
9582  xtGiven (0.0),
9583  vbxGiven (0.0),
9584  vbmGiven (0.0),
9585  vfbGiven (0.0),
9586  vth0Given (0.0),
9587  Vtm0 (0.0),
9588  Eg0 (0.0),
9589  ni (0.0)
9590 {
9591  if (getType() != "")
9592  {
9593  if (getType() == "NMOS") {
9594  dtype = CONSTNMOS;
9595  }
9596  else if (getType() == "PMOS") {
9597  dtype = CONSTPMOS;
9598  }
9599  else
9600  {
9601  UserError0(*this) << "Could not recognize the type for model " << getName();
9602  }
9603  }
9604 
9605  // Set params to constant default values:
9606  setDefaultParams();
9607 
9608  // Set params according to .model line and constant defaults from metadata:
9609  setModParams(MB.params);
9610 
9611  // Set any non-constant parameter defaults:
9612 #ifdef Xyce_BSIM3_USE_DEFL
9613  if (!given("L"))
9615  if (!given("W"))
9617 #endif
9618  if (!given("TNOM"))
9620 
9621  if (!given("TNOM") && tnom == 0.0)
9622  Report::DevelFatal0() << "TNOM is zero";
9623 
9624 // Calculate any parameters specified as expressions:
9626 
9627  // calculate dependent (ie computed) params and check for errors:
9628  if (!given("VTH0"))
9629  vth0 = (dtype == CONSTNMOS) ? 0.7 : -0.7;
9630  if (!given("UC"))
9631  uc = (mobMod == 3) ? -0.0465 : -0.0465e-9;
9632  if (!given("UC1"))
9633  uc1 = (mobMod == 3) ? -0.056 : -0.056e-9;
9634  if (!given("U0"))
9635  u0 = (dtype == CONSTNMOS) ? 0.067 : 0.025;
9636  if (!given("NOIA"))
9637  {
9638  if (dtype == CONSTNMOS)
9639  oxideTrapDensityA = 1e20;
9640  else
9641  oxideTrapDensityA = 9.9e18;
9642  }
9643  if (!given("NOIB"))
9644  {
9645  if (dtype == CONSTNMOS)
9646  oxideTrapDensityB = 5e4;
9647  else
9648  oxideTrapDensityB = 2.4e3;
9649  }
9650  if (!given("NOIC"))
9651  {
9652  if (dtype == CONSTNMOS)
9653  oxideTrapDensityC = -1.4e-12;
9654  else
9655  oxideTrapDensityC = 1.4e-12;
9656  }
9657 
9658  processParams ();
9659 }
9660 
9661 //-----------------------------------------------------------------------------
9662 // Function : Model::~Model
9663 // Purpose : destructor
9664 // Special Notes :
9665 // Scope : public
9666 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9667 // Creation Date : 11/14/00
9668 //-----------------------------------------------------------------------------
9670 {
9671  std::list<SizeDependParam*>::iterator it_dpL =
9672  sizeDependParamList.begin();
9673  std::list<SizeDependParam*>::iterator end_dpL =
9674  sizeDependParamList.end();
9675  for( ; it_dpL != end_dpL; ++it_dpL )
9676  delete (*it_dpL);
9677 
9678  sizeDependParamList.clear ();
9679 
9680  std::vector<Instance*>::iterator iter;
9681  std::vector<Instance*>::iterator first = instanceContainer.begin();
9682  std::vector<Instance*>::iterator last = instanceContainer.end();
9683 
9684  for (iter=first; iter!=last; ++iter)
9685  {
9686  delete (*iter);
9687  }
9688 }
9689 
9690 
9691 //-----------------------------------------------------------------------------
9692 // Function : Model::printOutInstances
9693 // Purpose : debugging tool.
9694 // Special Notes :
9695 // Scope : public
9696 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
9697 // Creation Date : 4/03/00
9698 //-----------------------------------------------------------------------------
9699 std::ostream &Model::printOutInstances (std::ostream &os) const
9700 {
9701  std::vector<Instance*>::const_iterator iter;
9702  std::vector<Instance*>::const_iterator first = instanceContainer.begin();
9703  std::vector<Instance*>::const_iterator last = instanceContainer.end();
9704 
9705  int i;
9706  os << std::endl;
9707  os << " name modelName Parameters" << std::endl;
9708 
9709  for (i=0, iter=first; iter!=last; ++iter,++i)
9710  {
9711  os << " " << i << ": " << (*iter)->getName() << "\t";
9712  os << getName();
9713  os << std::endl;
9714  }
9715 
9716  os << std::endl;
9717 
9718  return os;
9719 }
9720 
9721 //-----------------------------------------------------------------------------
9722 // Function : Model::forEachInstance
9723 // Purpose :
9724 // Special Notes :
9725 // Scope : public
9726 // Creator : David Baur
9727 // Creation Date : 2/4/2014
9728 //-----------------------------------------------------------------------------
9729 /// Apply a device instance "op" to all instances associated with this
9730 /// model
9731 ///
9732 /// @param[in] op Operator to apply to all instances.
9733 ///
9734 ///
9735 void Model::forEachInstance(DeviceInstanceOp &op) const /* override */
9736 {
9737  for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
9738  op(*it);
9739 }
9740 
9741 
9742 
9743 //----------------------------------------------------------------------------
9744 // Function : Model::clearTemperatureData
9745 //
9746 // Purpose : This is mainly here to delete rid of the size
9747 // dependent parameters, which are also temperature dependent.
9748 //
9749 // Special Notes : This is called right before the circuit temperature is
9750 // changed.
9751 //
9752 // Scope : public
9753 // Creator : Eric R. Keiter, 9233, computation sciences
9754 // Creation Date : 10/26/2004
9755 //----------------------------------------------------------------------------
9757 {
9758  std::list<SizeDependParam*>::iterator it_dpL =
9759  sizeDependParamList.begin();
9760  std::list<SizeDependParam*>::iterator end_dpL =
9761  sizeDependParamList.end();
9762  for( ; it_dpL != end_dpL; ++it_dpL )
9763  delete (*it_dpL);
9764 
9765  sizeDependParamList.clear ();
9766 
9767  return true;
9768 }
9769 
9770 //-----------------------------------------------------------------------------
9771 // MOSFET_B3 Master functions:
9772 //-----------------------------------------------------------------------------
9773 
9774 //-----------------------------------------------------------------------------
9775 // Function : Master::updateState
9776 // Purpose :
9777 // Special Notes :
9778 // Scope : public
9779 // Creator : Eric Keiter, SNL
9780 // Creation Date : 12/02/08
9781 //-----------------------------------------------------------------------------
9782 bool Master::updateState (double * solVec, double * staVec, double * stoVec)
9783 {
9784  bool bsuccess = true;
9785  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9786  {
9787  Instance & mi = *(*it);
9788 
9789  bool btmp = mi.updateIntermediateVars ();
9790  bsuccess = bsuccess && btmp;
9791 
9792  // voltage drops:
9793  double * stoVec = mi.extData.nextStoVectorRawPtr;
9794  stoVec[mi.li_store_vbs] = mi.vbs;
9795  stoVec[mi.li_store_vgs] = mi.vgs;
9796  stoVec[mi.li_store_vds] = mi.vds;
9797  stoVec[mi.li_store_vbd] = mi.vbd;
9798  stoVec[mi.li_store_von] = mi.von;
9799 
9800  // intrinsic capacitors:
9801  staVec[mi.li_state_qb] = mi.qb;
9802  staVec[mi.li_state_qg] = mi.qg;
9803  staVec[mi.li_state_qd] = mi.qd;
9804 
9805  // parasitic capacitors:
9806  staVec[mi.li_state_qbs] = mi.qbs;
9807  staVec[mi.li_state_qbd] = mi.qbd;
9808 
9809  if( mi.nqsMod )
9810  {
9811  staVec[mi.li_state_qcheq] = mi.qcheq;
9812  staVec[mi.li_state_qcdump] = mi.qcdump;
9813  }
9814 
9815  // if this is the first newton step of the first time step
9816  // of the transient simulation, we need to enforce that the
9817  // time derivatives w.r.t. charge are zero. This is to maintain 3f5
9818  // compatibility. ERK.
9819 
9820  // Note: I think this kind of thing is enforced (or should be enforced,
9821  // anyway) at the time integration level. So I'm not sure this step is
9822  // really needed, at least for new-DAE. Derivatives out of the DCOP
9823  // are supposed to be zero at the first newton step.
9824 
9825  if (!(getSolverState().dcopFlag) && getSolverState().initTranFlag_ && getSolverState().newtonIter==0)
9826  {
9827  // re-set the state vector pointer that we are using to the "current"
9828  // pointer, rather than the "next" pointer.
9829  double * currStaVec = mi.extData.currStaVectorRawPtr;
9830 
9831  // intrinsic capacitors:
9832  currStaVec[mi.li_state_qb] = mi.qb;
9833  currStaVec[mi.li_state_qg] = mi.qg;
9834  currStaVec[mi.li_state_qd] = mi.qd;
9835 
9836  // parasitic capacitors:
9837  currStaVec[mi.li_state_qbs] = mi.qbs;
9838  currStaVec[mi.li_state_qbd] = mi.qbd;
9839 
9840  if( mi.nqsMod )
9841  {
9842  currStaVec[mi.li_state_qcheq] = mi.qcheq;
9843  currStaVec[mi.li_state_qcdump] = mi.qcdump;
9844  }
9845  }
9846  }
9847 
9848  return bsuccess;
9849 }
9850 
9851 //-----------------------------------------------------------------------------
9852 // Function : Master::loadDAEVectors
9853 // Purpose :
9854 // Special Notes :
9855 // Scope : public
9856 // Creator : Eric Keiter, SNL
9857 // Creation Date : 12/02/08
9858 //-----------------------------------------------------------------------------
9859 bool Master::loadDAEVectors (double * solVec, double * fVec, double *qVec, double * bVec, double * storeLeadF, double * storeLeadQ, double * leadF, double * leadQ, double * junctionV)
9860 {
9861  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
9862  {
9863  Instance & mi = *(*it);
9864 
9865  double * dFdxdVp = mi.extData.dFdxdVpVectorRawPtr;
9866  double * dQdxdVp = mi.extData.dQdxdVpVectorRawPtr;
9867 
9868  double coef(0.0);
9869  // F-vector:
9870  mi.cdreq_Jdxp = 0.0;
9871  mi.ceqbd_Jdxp = 0.0;
9872  mi.ceqbs_Jdxp = 0.0;
9873 
9874  // Do a few auxilliary calculations, derived from 3f5.
9875  // load current vector
9876  if (mi.mode >= 0)
9877  {
9878  mi.Gm = mi.gm;
9879  mi.Gmbs = mi.gmbs;
9880  mi.FwdSum = mi.Gm + mi.Gmbs;
9881  mi.RevSum = 0.0;
9882 
9883  mi.cdreq = mi.model_.dtype * (mi.cd);
9884  mi.ceqbd = -mi.model_.dtype * (mi.csub);
9885 
9886  mi.ceqbs = 0.0;
9887 
9888  mi.gbbdp = -mi.gbds;
9889  mi.gbbsp = (mi.gbds + mi.gbgs + mi.gbbs);
9890 
9891  mi.gbdpg = mi.gbgs;
9892  mi.gbdpdp = mi.gbds;
9893  mi.gbdpb = mi.gbbs;
9894  mi.gbdpsp = -(mi.gbdpg + mi.gbdpdp + mi.gbdpb);
9895 
9896  mi.gbspg = 0.0;
9897  mi.gbspdp = 0.0;
9898  mi.gbspb = 0.0;
9899  mi.gbspsp = 0.0;
9900  }
9901  else
9902  {
9903  mi.Gm = -mi.gm;
9904  mi.Gmbs = -mi.gmbs;
9905  mi.FwdSum = 0.0;
9906  mi.RevSum = -(mi.Gm + mi.Gmbs);
9907 
9908  mi.cdreq = -mi.model_.dtype * (mi.cd);
9909  mi.ceqbs = -mi.model_.dtype * (mi.csub);
9910 
9911  mi.ceqbd = 0.0;
9912 
9913  mi.gbbsp = -mi.gbds;
9914  mi.gbbdp = (mi.gbds + mi.gbgs + mi.gbbs);
9915 
9916  mi.gbdpg = 0.0;
9917  mi.gbdpsp = 0.0;
9918  mi.gbdpb = 0.0;
9919  mi.gbdpdp = 0.0;
9920 
9921  mi.gbspg = mi.gbgs;
9922  mi.gbspsp = mi.gbds;
9923  mi.gbspb = mi.gbbs;
9924  mi.gbspdp = -(mi.gbspg + mi.gbspsp + mi.gbspb);
9925  }
9926 
9927  if (mi.model_.dtype > 0)
9928  {
9929  mi.ceqbs += (mi.cbs);
9930  mi.ceqbd += (mi.cbd);
9931  }
9932  else
9933  {
9934  mi.ceqbs -= (mi.cbs);
9935  mi.ceqbd -= (mi.cbd);
9936  }
9937 
9938  if (mi.drainConductance != 0.0)
9939  {
9940  fVec[mi.li_Drain] += mi.Idrain*mi.numberParallel;
9941  }
9942  if (mi.sourceConductance != 0.0)
9943  {
9944  fVec[mi.li_Source] += mi.Isource*mi.numberParallel;
9945  }
9946 
9947  fVec[mi.li_Bulk] += (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9948  fVec[mi.li_DrainPrime] += (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9949  fVec[mi.li_SourcePrime] += (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9950 
9951  if( mi.loadLeadCurrent )
9952  {
9953  if (mi.drainConductance != 0.0)
9954  {
9955  storeLeadF[mi.li_store_dev_id] = mi.Idrain*mi.numberParallel;
9956  }
9957  else
9958  {
9959  storeLeadF[mi.li_store_dev_id] = (-(mi.ceqbd - mi.cdreq)-mi.Idrain)*mi.numberParallel;
9960  }
9961  if (mi.sourceConductance != 0.0)
9962  {
9963  storeLeadF[mi.li_store_dev_is] = mi.Isource*mi.numberParallel;
9964  }
9965  else
9966  {
9967  storeLeadF[mi.li_store_dev_is] = (-(mi.cdreq + mi.ceqbs)-mi.Isource)*mi.numberParallel;
9968  }
9969  storeLeadF[mi.li_store_dev_ig] = 0.0;
9970  storeLeadF[mi.li_store_dev_ib] = (mi.ceqbs + mi.ceqbd)*mi.numberParallel;
9971  }
9972 
9973  // Initial condition support
9974 
9975  if( getSolverState().dcopFlag && mi.icVDSGiven )
9976  {
9977  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ids];
9978  fVec[mi.li_Drain] += coef;
9979  fVec[mi.li_Source] += -coef;
9980  if( mi.loadLeadCurrent )
9981  {
9982  storeLeadF[mi.li_store_dev_id]= coef;
9983  storeLeadF[mi.li_store_dev_is]= -coef;
9984  }
9985  }
9986 
9987  if( getSolverState().dcopFlag && mi.icVGSGiven )
9988  {
9989  coef = mi.extData.nextSolVectorRawPtr[mi.li_Igs];
9990  fVec[mi.li_Gate] += coef;
9991  fVec[mi.li_Source] += -coef;
9992  if( mi.loadLeadCurrent )
9993  {
9994  storeLeadF[mi.li_store_dev_ig]= coef;
9995  storeLeadF[mi.li_store_dev_is]= -coef;
9996  }
9997  }
9998 
9999 
10000  if( getSolverState().dcopFlag && mi.icVBSGiven )
10001  {
10002  coef = mi.extData.nextSolVectorRawPtr[mi.li_Ibs];
10003  fVec[mi.li_Bulk] += coef;
10004  fVec[mi.li_Source] += -coef;
10005  if( mi.loadLeadCurrent )
10006  {
10007  storeLeadF[mi.li_store_dev_ib]= coef;
10008  storeLeadF[mi.li_store_dev_is]= -coef;
10009  }
10010  }
10011 
10012  //////////////////////////////////////////////////
10013  // limiting section:
10015  {
10016  if (!mi.origFlag)
10017  {
10018  if (mi.mode >= 0)
10019  {
10020  // option 1
10021  double tmp = mi.model_.dtype * (-mi.gds * (mi.vds-mi.vds_orig) -
10022  mi.Gm * (mi.vgs-mi.vgs_orig) -
10023  mi.Gmbs * (mi.vbs-mi.vbs_orig));
10024 
10025  mi.cdreq_Jdxp += tmp;
10026  mi.cdreq += tmp;
10027 
10028  tmp = -mi.model_.dtype * (-mi.gbds * (mi.vds-mi.vds_orig) -
10029  mi.gbgs * (mi.vgs-mi.vgs_orig) -
10030  mi.gbbs * (mi.vbs-mi.vbs_orig));
10031  mi.ceqbd_Jdxp += tmp;
10032  mi.ceqbd += tmp;
10033  }
10034  else
10035  {
10036  // option 2
10037  double tmp = -mi.model_.dtype * (mi.gds * (mi.vds-mi.vds_orig) +
10038  mi.Gm * (mi.vgd-mi.vgd_orig) +
10039  mi.Gmbs * (mi.vbd-mi.vbd_orig));
10040  mi.cdreq_Jdxp += tmp;
10041  mi.cdreq += tmp;
10042 
10043  tmp = -mi.model_.dtype * (mi.gbds * (mi.vds-mi.vds_orig) -
10044  mi.gbgs * (mi.vgd-mi.vgd_orig) -
10045  mi.gbbs * (mi.vbd-mi.vbd_orig));
10046  mi.ceqbd_Jdxp += tmp;
10047  mi.ceqbd += tmp;
10048  }
10049 
10050 
10051  if (mi.model_.dtype > 0)
10052  {
10053  mi.ceqbs_Jdxp += (-mi.gbs*(mi.vbs-mi.vbs_orig));
10054  mi.ceqbs += (-mi.gbs*(mi.vbs-mi.vbs_orig));
10055 
10056  mi.ceqbd_Jdxp += (-mi.gbd*(mi.vbd-mi.vbd_orig));
10057  mi.ceqbd += (-mi.gbd*(mi.vbd-mi.vbd_orig));
10058  }
10059  else
10060  {
10061  mi.ceqbs_Jdxp -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
10062  mi.ceqbs -= (-mi.gbs*(mi.vbs-mi.vbs_orig) );
10063 
10064  mi.ceqbd_Jdxp -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
10065  mi.ceqbd -= (-mi.gbd*(mi.vbd-mi.vbd_orig) );
10066  }
10067 
10068  dFdxdVp[mi.li_Bulk] += -(mi.ceqbs_Jdxp+mi.ceqbd_Jdxp)*mi.numberParallel;
10069  dFdxdVp[mi.li_DrainPrime] += (mi.ceqbd_Jdxp-mi.cdreq_Jdxp)*mi.numberParallel;
10070  dFdxdVp[mi.li_SourcePrime] += (mi.cdreq_Jdxp+mi.ceqbs_Jdxp)*mi.numberParallel;
10071 
10072  } // orig flag.
10073  } // voltage limiter flag
10074 
10075  // Row associated with icVBS
10076  if( getSolverState().dcopFlag && mi.icVBSGiven )
10077  {
10078  // get the voltage drop from the previous solution
10079  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
10080  double cVb = mi.extData.nextSolVectorRawPtr[mi.li_Bulk];
10081 
10082  fVec[mi.li_Ibs] += (cVb - cVs - mi.icVBS);
10083  }
10084 
10085  // Row associated with icVDS
10086  if( getSolverState().dcopFlag && mi.icVDSGiven )
10087  {
10088  // get the voltage drop from the previous solution
10089  double cVd = mi.extData.nextSolVectorRawPtr[mi.li_Drain];
10090  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
10091 
10092  fVec[mi.li_Ids] += (cVd - cVs - mi.icVDS);
10093  }
10094 
10095  // Row associated with icVGS
10096  if( getSolverState().dcopFlag && mi.icVGSGiven )
10097  {
10098  // get the voltage drop from the previous solution
10099  double cVg = mi.extData.nextSolVectorRawPtr[mi.li_Gate];
10100  double cVs = mi.extData.nextSolVectorRawPtr[mi.li_Source];
10101 
10102  fVec[mi.li_Igs] += (cVg - cVs - mi.icVGS);
10103  }
10104 
10105  // Q-vector:
10106 
10107  mi.auxChargeCalculations ();
10108 
10109  double Qeqqg = 0.0; // gate charge
10110  double Qeqqb = 0.0; // bulk charge
10111  double Qeqqd = 0.0; // drain charge
10112  double Qqdef = 0.0; // nqs-related charge.
10113  double Qqcheq = 0.0; // nqs-related charge.
10114 
10115  // These 3 vars are class variables, and are set up elsewhere.
10116  //double Qeqqg_Jdxp = 0.0; // limiter, related to gate cap.
10117  //double Qeqqb_Jdxp = 0.0; // limiter, related to bulk cap.
10118  //double Qeqqd_Jdxp = 0.0; // limiter, related to drain cap.
10119 
10120  if (mi.model_.dtype > 0)
10121  {
10122  Qeqqg = mi.qg;
10123  Qeqqb = mi.qb;
10124  Qeqqd = mi.qd;
10125  Qqdef = mi.qcdump; // this needs to be fixed...
10126  Qqcheq = mi.qcheq;
10127  }
10128  else // need to convert these to charges.
10129  {
10130  Qeqqg = -mi.qg;
10131  Qeqqb = -mi.qb;
10132  Qeqqd = -mi.qd;
10133  Qqdef = -mi.qcdump;
10134  Qqcheq = -mi.qcheq;
10135  }
10136 
10137  qVec[mi.li_Gate] += Qeqqg*mi.numberParallel;
10138  qVec[mi.li_Bulk] += (Qeqqb)*mi.numberParallel;
10139  qVec[mi.li_DrainPrime] += (-(-Qeqqd))*mi.numberParallel;
10140  qVec[mi.li_SourcePrime] += (-(+ Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
10141 
10142  if (mi.nqsMod)
10143  {
10144  // 7 equ. for nqs modification. charge equation.
10145  qVec[mi.li_Charge] += -(Qqcheq - Qqdef)*mi.numberParallel;
10146  }
10147 
10148  if( mi.loadLeadCurrent )
10149  {
10150  if (mi.drainConductance == 0.0)
10151  {
10152  storeLeadQ[mi.li_store_dev_id] = (-(-Qeqqd))*mi.numberParallel;
10153  }
10154  if (mi.sourceConductance == 0.0)
10155  {
10156  storeLeadQ[mi.li_store_dev_is] = (-(Qeqqg + Qeqqb + Qeqqd))*mi.numberParallel;
10157  }
10158  storeLeadQ[mi.li_store_dev_ig] = Qeqqg*mi.numberParallel;
10159  storeLeadQ[mi.li_store_dev_ib] = (Qeqqb)*mi.numberParallel;
10160  }
10161 
10162  //////////////////////////////////////////////////
10163  // limiting section:
10165  {
10166  // Need the following:
10167  // Qeqqg_Jdxp
10168  // Qeqqb_Jdxp
10169  // Qeqqd_Jdxp
10170  if (mi.model_.dtype > 0)
10171  {
10172 #if 0
10173  // no-op:
10174  mi.Qeqqg_Jdxp = mi.Qeqqg_Jdxp;
10175  mi.Qeqqb_Jdxp = mi.Qeqqb_Jdxp;
10176  mi.Qeqqd_Jdxp = mi.Qeqqd_Jdxp;
10177 #endif
10178  }
10179  else
10180  {
10181  mi.Qeqqg_Jdxp = -mi.Qeqqg_Jdxp;
10182  mi.Qeqqb_Jdxp = -mi.Qeqqb_Jdxp;
10183  mi.Qeqqd_Jdxp = -mi.Qeqqd_Jdxp;
10184  }
10185 
10186  if (!mi.origFlag)
10187  {
10188  dQdxdVp[mi.li_Gate] += -mi.Qeqqg_Jdxp*mi.numberParallel;
10189  dQdxdVp[mi.li_Bulk] += -(+mi.Qeqqb_Jdxp)*mi.numberParallel;
10190  dQdxdVp[mi.li_DrainPrime] += (-mi.Qeqqd_Jdxp)*mi.numberParallel;
10191  dQdxdVp[mi.li_SourcePrime] += (+mi.Qeqqg_Jdxp+mi.Qeqqb_Jdxp+mi.Qeqqd_Jdxp) *mi.numberParallel;
10192  } // orig flag.
10193  } // limiter flag
10194  }
10195  return true;
10196 }
10197 
10198 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
10199 //-----------------------------------------------------------------------------
10200 // Function : Master::loadDAEMatrices
10201 // Purpose :
10202 // Special Notes :
10203 // Scope : public
10204 // Creator : Eric Keiter, SNL
10205 // Creation Date : 12/02/08
10206 //-----------------------------------------------------------------------------
10207 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
10208 {
10209  for (InstanceVector::const_iterator it = getInstanceBegin(); it != getInstanceEnd(); ++it)
10210  {
10211  Instance & mi = *(*it);
10212 
10213  // F-matrix:
10214  // Row corresponding to the KCL for the drain node:
10215 
10218 
10221 
10222  // Extra term for initial conditions on Vds in operating point
10223  if( getSolverState().dcopFlag && mi.icVDSGiven )
10224  {
10225  *mi.f_DrainEquIdsPtr += 1.0;
10226  }
10227 
10228  // Row corresponding to the KCL for the source node:
10229 
10232 
10235 
10236  // Extra term for initial conditions on Vbs in operating point
10237  if( getSolverState().dcopFlag && mi.icVBSGiven )
10238  {
10239  *mi.f_SourceEquIbsPtr -= 1.0;
10240  }
10241  // Extra term for initial conditions on Vds in operating point
10242  if( getSolverState().dcopFlag && mi.icVDSGiven )
10243  {
10244  *mi.f_SourceEquIdsPtr -= 1.0;
10245  }
10246  // Extra term for initial conditions on Vgs in operating point
10247  if( getSolverState().dcopFlag && mi.icVGSGiven )
10248  {
10249  *mi.f_SourceEquIgsPtr -= 1.0;
10250  }
10251 
10252  // Row corresponding to the KCL for the gate node: NOTHING
10253  // Check this later. ERK.
10254  //
10255  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
10256  // belong here. I'm not sure aboug the gg terms. On one hand, the
10257  // rhs vector component for the gate node ONLY seems to take
10258  // capacitive currents, which implies that all of these are capacitive
10259  // conductances. On the other hand, the gg terms do not appear to
10260  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
10261  // capacitive conductances are of the form g = C/dt, and the gg terms
10262  // do not have this form.
10263  //
10264  // For now, the gg issue is moot b/c those terms are only nonzero
10265  // if mi.nqsMod = 1, which is not a supported option.
10266 
10267  // However, the gg
10268  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
10269  //
10270  //(*JMatPtr)[GateEquGateNodePtr
10271  // += (gcggb - mi.ggtg)*mi.numberParallel;
10272  //(*JMatPtr)[GateEquBulkNodePtr
10273  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
10274  //(*JMatPtr)[GateEquDrainPrimeNodePtr
10275  // += (gcgdb - ggtd)*mi.numberParallel;
10276  //(*JMatPtr)[GateEquSourcePrimeNodePtr
10277  // += (gcgsb - ggts)*mi.numberParallel;
10278 
10279  // initial conditions on gate node
10280  // Extra term for initial conditions on Vgs in operating point
10281  if( getSolverState().dcopFlag && mi.icVGSGiven )
10282  {
10283  *mi.f_GateEquIgsPtr += 1.0;
10284  }
10285 
10286  // Row corresponding to the KCL for the bulk node:
10287 
10289  += (- mi.gbgs)*mi.numberParallel;
10290 
10291 
10293  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
10294 
10295 
10297  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
10298 
10299 
10301  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
10302 
10303  // Extra term for initial conditions on Vbs in operating point
10304  if( getSolverState().dcopFlag && mi.icVBSGiven )
10305  {
10306  *mi.f_BulkEquIbsPtr += 1.0;
10307  }
10308 
10309  // Row corresponding to the KCL for the drain prime node:
10310 
10313 
10315  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
10316  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
10317 
10319  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
10320  *mi.numberParallel;
10321 
10323  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
10324  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
10325 
10327  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
10328  *mi.numberParallel;
10329 
10330  // Row corresponding to the KCL for the source prime node:
10332  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
10333  *mi.numberParallel;
10334 
10336  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
10337  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
10338 
10341 
10343  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
10344  *mi.numberParallel;
10345 
10347  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
10348  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
10349 
10350  // Row associated with the charge equation
10351  if (mi.nqsMod)
10352  {
10353  std::string msg;
10354  msg = "Instance::loadDAEMatrices";
10355  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10356  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10357  }
10358 
10359  // Initial condition rows
10360  // Row associated with mi.icVBS
10361  if( mi.icVBSGiven )
10362  {
10363  if( getSolverState().dcopFlag )
10364  {
10365  *mi.f_icVBSEquVbPtr += 1.0;
10366  *mi.f_icVBSEquVsPtr -= 1.0;
10367  }
10368  else
10369  {
10370  *mi.f_icVBSEquIbsPtr += 1.0;
10371  }
10372  }
10373 
10374  // Row associated with mi.icVDS
10375  if( mi.icVDSGiven )
10376  {
10377  if( getSolverState().dcopFlag )
10378  {
10379  *mi.f_icVDSEquVdPtr += 1.0;
10380  *mi.f_icVDSEquVsPtr -= 1.0;
10381  }
10382  else
10383  {
10384  *mi.f_icVDSEquIdsPtr += 1.0;
10385  }
10386  }
10387 
10388  // Row associated with mi.icVGS
10389  if( mi.icVGSGiven )
10390  {
10391  if( getSolverState().dcopFlag )
10392  {
10393  *mi.f_icVGSEquVgPtr += 1.0;
10394  *mi.f_icVGSEquVsPtr -= 1.0;
10395  }
10396  else
10397  {
10398  *mi.f_icVGSEquIgsPtr += 1.0;
10399  }
10400  }
10401 
10402 
10403  {
10404  // Row corresponding to the KCL for the drain node: NOTHING
10405 
10406  // Row corresponding to the KCL for the source node: NOTHING
10407 
10408  // Row corresponding to the KCL for the gate node:
10409  // Check this later. ERK. See the comments in the function
10410  // loadDAE*mi.q_, regarding ggtg, ggtb, etc.
10411  //
10412  // For now I am leaving out the gg terms, as they are zero when
10413  // nqsMod=0, which is always true.
10414  //
10416  += (mi.CAPcggb )*mi.numberParallel;
10418  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
10420  += (mi.CAPcgdb )*mi.numberParallel;
10422  += (mi.CAPcgsb )*mi.numberParallel;
10423 
10424  // Row corresponding to the KCL for the bulk node:
10426  += (mi.CAPcbgb)*mi.numberParallel;
10427 
10429  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
10430 
10432  += (mi.CAPcbdb)*mi.numberParallel;
10433 
10435  += (mi.CAPcbsb)*mi.numberParallel;
10436 
10437 
10438  // Row corresponding to the KCL for the drain prime node:
10440  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
10441 
10443  += (mi.CAPcdgb) *mi.numberParallel;
10444 
10446  += (+ mi.CAPcddb )*mi.numberParallel;
10447 
10449  -= (- mi.CAPcdsb) *mi.numberParallel;
10450 
10451  // Row corresponding to the KCL for the source prime node:
10453  += (mi.CAPcsgb) *mi.numberParallel;
10454 
10456  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
10457 
10459  -= (- mi.CAPcsdb) *mi.numberParallel;
10460 
10462  += (+ mi.CAPcssb) *mi.numberParallel;
10463 
10464  // Row associated with the charge equation
10465  // This is currently not supported.
10466  if (mi.nqsMod)
10467  {
10468  std::string msg;
10469  msg = "Master::loadDAEMatrices";
10470  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10471  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10472  }
10473  }
10474  }
10475  return true;
10476 }
10477 
10478 #else
10479 //-----------------------------------------------------------------------------
10480 // Function : Master::loadDAEMatrices
10481 // Purpose :
10482 // Special Notes :
10483 // Scope : public
10484 // Creator : Eric Keiter, SNL
10485 // Creation Date : 12/02/08
10486 //-----------------------------------------------------------------------------
10487 bool Master::loadDAEMatrices (Linear::Matrix & dFdx, Linear::Matrix & dQdx)
10488 {
10489  int sizeInstances = instanceContainer_.size();
10490  for (int i=0; i<sizeInstances; ++i)
10491  {
10492  Instance & mi = *(instanceContainer_.at(i));
10493 
10494  int count = 0;
10495  // F-matrix:
10496  // Row corresponding to the KCL for the drain node:
10497 
10498  dFdx [mi.li_Drain][mi.ADrainEquDrainNodeOffset]
10500 
10503 
10504  // Extra term for initial conditions on Vds in operating point
10505  if( getSolverState().dcopFlag && mi.icVDSGiven )
10506  {
10507  dFdx[mi.li_Drain][mi.ADrainEquIdsOffset] += 1.0;
10508  }
10509 
10510  // Row corresponding to the KCL for the source node:
10511 
10514 
10517 
10518  // Extra term for initial conditions on Vbs in operating point
10519  if( getSolverState().dcopFlag && mi.icVBSGiven )
10520  {
10521  dFdx[mi.li_Source][mi.ASourceEquIbsOffset] -= 1.0;
10522  }
10523  // Extra term for initial conditions on Vds in operating point
10524  if( getSolverState().dcopFlag && mi.icVDSGiven )
10525  {
10526  dFdx[mi.li_Source][mi.ASourceEquIdsOffset] -= 1.0;
10527  }
10528  // Extra term for initial conditions on Vgs in operating point
10529  if( getSolverState().dcopFlag && mi.icVGSGiven )
10530  {
10531  dFdx[mi.li_Source][mi.ASourceEquIgsOffset] -= 1.0;
10532  }
10533 
10534  // Row corresponding to the KCL for the gate node: NOTHING
10535  // Check this later. ERK.
10536  //
10537  // The terms beginning with "gc" (gcggb, etc.) definately do NOT
10538  // belong here. I'm not sure aboug the gg terms. On one hand, the
10539  // rhs vector component for the gate node ONLY seems to take
10540  // capacitive currents, which implies that all of these are capacitive
10541  // conductances. On the other hand, the gg terms do not appear to
10542  // have been created by multiplying by ag0 = pdt = 1/dt. Generally
10543  // capacitive conductances are of the form g = C/dt, and the gg terms
10544  // do not have this form.
10545  //
10546  // For now, the gg issue is moot b/c those terms are only nonzero
10547  // if mi.nqsMod = 1, which is not a supported option.
10548 
10549  // However, the gg
10550  // terms (mi.ggtg, mi.ggtb, ggtd and ggts)
10551  //
10552  //(*JMatPtr)[mi.li_Gate][mi.AGateEquGateNodeOffset]
10553  // += (gcggb - mi.ggtg)*mi.numberParallel;
10554  //(*JMatPtr)[mi.li_Gate][mi.AGateEquBulkNodeOffset]
10555  // -= (gcggb + gcgdb + gcgsb + mi.ggtb)*mi.numberParallel;
10556  //(*JMatPtr)[mi.li_Gate][mi.AGateEquDrainPrimeNodeOffset]
10557  // += (gcgdb - ggtd)*mi.numberParallel;
10558  //(*JMatPtr)[mi.li_Gate][mi.AGateEquSourcePrimeNodeOffset]
10559  // += (gcgsb - ggts)*mi.numberParallel;
10560 
10561  // initial conditions on gate node
10562  // Extra term for initial conditions on Vgs in operating point
10563  if( getSolverState().dcopFlag && mi.icVGSGiven )
10564  {
10565  dFdx[mi.li_Gate][mi.AGateEquIgsOffset] += 1.0;
10566  }
10567 
10568  // Row corresponding to the KCL for the bulk node:
10569 
10570  dFdx [mi.li_Bulk][mi.ABulkEquGateNodeOffset]
10571  += (- mi.gbgs)*mi.numberParallel;
10572 
10573 
10574  dFdx [mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
10575  += (mi.gbd + mi.gbs - mi.gbbs)*mi.numberParallel;
10576 
10577 
10579  += (- mi.gbd + mi.gbbdp)*mi.numberParallel;
10580 
10581 
10583  += (- mi.gbs + mi.gbbsp)*mi.numberParallel;
10584 
10585  // Extra term for initial conditions on Vbs in operating point
10586  if( getSolverState().dcopFlag && mi.icVBSGiven )
10587  {
10588  dFdx[mi.li_Bulk][mi.ABulkEquIbsOffset] += 1.0;
10589  }
10590 
10591  // Row corresponding to the KCL for the drain prime node:
10592 
10595 
10596 
10598  -= (mi.gbd - mi.Gmbs - mi.dxpart*mi.ggtb
10599  - mi.T1global*mi.ddxpart_dVb - mi.gbdpb)*mi.numberParallel;
10600 
10601 
10603  += (mi.Gm + mi.dxpart*mi.ggtg + mi.T1global*mi.ddxpart_dVg + mi.gbdpg)
10604  *mi.numberParallel;
10605 
10606 
10608  += (mi.drainConductance + mi.gds + mi.gbd + mi.RevSum + mi.dxpart*mi.ggtd
10609  + mi.T1global*mi.ddxpart_dVd + mi.gbdpdp)*mi.numberParallel;
10610 
10611 
10613  -= (mi.gds + mi.FwdSum - mi.dxpart*mi.ggts - mi.T1global*mi.ddxpart_dVs - mi.gbdpsp)
10614  *mi.numberParallel;
10615 
10616  // Row corresponding to the KCL for the source prime node:
10617 
10619  += (- mi.Gm + mi.sxpart*mi.ggtg + mi.T1global*mi.dsxpart_dVg + mi.gbspg)
10620  *mi.numberParallel;
10621 
10622 
10624  -= (mi.gbs + mi.Gmbs - mi.sxpart*mi.ggtb
10625  - mi.T1global*mi.dsxpart_dVb - mi.gbspb)*mi.numberParallel;
10626 
10627 
10630 
10631 
10633  -= (mi.gds + mi.RevSum - mi.sxpart*mi.ggtd - mi.T1global*mi.dsxpart_dVd - mi.gbspdp)
10634  *mi.numberParallel;
10635 
10636 
10638  += (mi.sourceConductance + mi.gds + mi.gbs + mi.FwdSum + mi.sxpart*mi.ggts
10639  + mi.T1global*mi.dsxpart_dVs + mi.gbspsp)*mi.numberParallel;
10640 
10641  // Row associated with the charge equation
10642  if (mi.nqsMod)
10643  {
10644  std::string msg;
10645  msg = "Master::loadDAEMatrices";
10646  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10647  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10648  }
10649 
10650  // Initial condition rows
10651  // Row associated with mi.icVBS
10652  if( mi.icVBSGiven )
10653  {
10654  if( getSolverState().dcopFlag )
10655  {
10656  dFdx[mi.li_Ibs][mi.icVBSEquVbOffset] += 1.0;
10657  dFdx[mi.li_Ibs][mi.icVBSEquVsOffset] -= 1.0;
10658  }
10659  else
10660  {
10661  dFdx[mi.li_Ibs][mi.icVBSEquIbsOffset] += 1.0;
10662  }
10663  }
10664 
10665  // Row associated with mi.icVDS
10666  if( mi.icVDSGiven )
10667  {
10668  if( getSolverState().dcopFlag )
10669  {
10670  dFdx[mi.li_Ids][mi.icVDSEquVdOffset] += 1.0;
10671  dFdx[mi.li_Ids][mi.icVDSEquVsOffset] -= 1.0;
10672  }
10673  else
10674  {
10675  dFdx[mi.li_Ids][mi.icVDSEquIdsOffset] += 1.0;
10676  }
10677  }
10678 
10679  // Row associated with mi.icVGS
10680  if( mi.icVGSGiven )
10681  {
10682  if( getSolverState().dcopFlag )
10683  {
10684  dFdx[mi.li_Igs][mi.icVGSEquVgOffset] += 1.0;
10685  dFdx[mi.li_Igs][mi.icVGSEquVsOffset] -= 1.0;
10686  }
10687  else
10688  {
10689  dFdx[mi.li_Igs][mi.icVGSEquIgsOffset] += 1.0;
10690  }
10691  }
10692 
10693  {
10694  // Row corresponding to the KCL for the drain node: NOTHING
10695 
10696  // Row corresponding to the KCL for the source node: NOTHING
10697 
10698  // Row corresponding to the KCL for the gate node:
10699  // Check this later. ERK. See the comments in the function
10700  // loadDAEdQdx, regarding ggtg, ggtb, etc.
10701  //
10702  // For now I am leaving out the gg terms, as they are zero when
10703  // nqsMod=0, which is always true.
10704  //
10705  dQdx[mi.li_Gate][mi.AGateEquGateNodeOffset]
10706  += (mi.CAPcggb )*mi.numberParallel;
10707  dQdx[mi.li_Gate][mi.AGateEquBulkNodeOffset]
10708  -= (mi.CAPcggb + mi.CAPcgdb + mi.CAPcgsb )*mi.numberParallel;
10710  += (mi.CAPcgdb )*mi.numberParallel;
10712  += (mi.CAPcgsb )*mi.numberParallel;
10713 
10714  // Row corresponding to the KCL for the bulk node:
10715  dQdx[mi.li_Bulk][mi.ABulkEquGateNodeOffset]
10716  += (mi.CAPcbgb)*mi.numberParallel;
10717 
10718  dQdx[mi.li_Bulk][mi.ABulkEquBulkNodeOffset]
10719  += (- mi.CAPcbgb - mi.CAPcbdb - mi.CAPcbsb)*mi.numberParallel;
10720 
10722  += (mi.CAPcbdb)*mi.numberParallel;
10723 
10725  += (mi.CAPcbsb)*mi.numberParallel;
10726 
10727 
10728  // Row corresponding to the KCL for the drain prime node:
10730  -= (+ mi.CAPcdgb + mi.CAPcddb + mi.CAPcdsb )*mi.numberParallel;
10731 
10733  += (mi.CAPcdgb) *mi.numberParallel;
10734 
10736  += (+ mi.CAPcddb )*mi.numberParallel;
10737 
10739  -= (- mi.CAPcdsb) *mi.numberParallel;
10740 
10741  // Row corresponding to the KCL for the source prime node:
10743  += (mi.CAPcsgb) *mi.numberParallel;
10744 
10746  -= (+ mi.CAPcsgb + mi.CAPcsdb + mi.CAPcssb) *mi.numberParallel;
10747 
10749  -= (- mi.CAPcsdb) *mi.numberParallel;
10750 
10752  += (+ mi.CAPcssb) *mi.numberParallel;
10753 
10754  // Row associated with the charge equation
10755  // This is currently not supported.
10756  if (mi.nqsMod)
10757  {
10758  std::string msg;
10759  msg = "Master::loadDAEMatrices";
10760  msg += " nqsMod=1 is not ready yet. Re-run with nqsMod=0\n";
10761  N_ERH_ErrorMgr::report ( N_ERH_ErrorMgr::DEV_FATAL,msg);
10762  }
10763  }
10764  }
10765  return true;
10766 }
10767 #endif
10768 
10769 Device *Traits::factory(const Configuration &configuration, const FactoryBlock &factory_block)
10770 {
10771  return new Master(configuration, factory_block, factory_block.solverState_, factory_block.deviceOptions_);
10772 }
10773 
10775 {
10777  .registerDevice("m", 9)
10778  .registerDevice("m", 49)
10779  .registerModelType("pmos", 9)
10780  .registerModelType("nmos", 9)
10781  .registerModelType("pmos", 49)
10782  .registerModelType("nmos", 49);
10783 }
10784 
10785 } // namespace MOSFET_B3
10786 } // namespace Device
10787 } // namespace Xyce
10788 
const InstanceName & getName() const
double defad
MOS drain diffusion area.
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
#define CONSTPMOS
Definition: N_DEV_Const.h:80
#define CONSTDELTA_3
Definition: N_DEV_Const.h:102
double defw
MOS channel width.
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:73
#define CONSTDELTA_4
Definition: N_DEV_Const.h:103
static std::vector< std::vector< int > > jacMap2
double pdt_
Previous delta time alpha/dt (Many devices)
#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:98
static std::vector< int > jacMap_SC
void setNumStoreVars(int num_store_vars)
std::vector< double > gainScale_
MOSFET Devices, ArtificialParameters.
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:83
#define AssertLIDs(cmp)
std::vector< int > li_Pos
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
#define CONSTNMOS
Definition: N_DEV_Const.h:79
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)
double defl
MOS channel length.
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
double tnom
nominal temperature for device params.
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:108
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:100
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:97
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:82
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
double defas
MOS source diffusion area.
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:75
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
#define CONSTEXP_THRESHOLD
Definition: N_DEV_Const.h:96
#define Xyce_NONPOINTER_MATRIX_LOAD
Definition: N_DEV_Bsrc.C:97
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
double gmin
minimum allowed conductance.
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:74
Manages parameter binding for class C.
Definition: N_DEV_Pars.h:214
InstanceBlock represent a device instance line from the netlist.
Util::Param temp
operating temperature of ckt.
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
#define CONSTvt0
Definition: N_DEV_Const.h:67
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:77
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > &params)