From 504ab3b0f90df00a873d0c5e7ff8e570270f5360 Mon Sep 17 00:00:00 2001 From: pnenzi Date: Sun, 21 Jan 2001 17:07:40 +0000 Subject: [PATCH] Added support fot bsim3soi dynamic depletion device (initial commit) --- src/spicelib/devices/bsim3soi_dd/Makefile.am | 34 + src/spicelib/devices/bsim3soi_dd/b3soidd.c | 479 ++ .../devices/bsim3soi_dd/b3soiddacld.c | 462 ++ src/spicelib/devices/bsim3soi_dd/b3soiddask.c | 215 + .../devices/bsim3soi_dd/b3soiddcheck.c | 504 ++ .../devices/bsim3soi_dd/b3soiddcvtest.c | 90 + src/spicelib/devices/bsim3soi_dd/b3soidddef.h | 1991 ++++++++ src/spicelib/devices/bsim3soi_dd/b3soidddel.c | 41 + .../devices/bsim3soi_dd/b3soidddest.c | 39 + src/spicelib/devices/bsim3soi_dd/b3soiddext.h | 54 + .../devices/bsim3soi_dd/b3soiddgetic.c | 51 + .../devices/bsim3soi_dd/b3soiddinit.c | 62 + .../devices/bsim3soi_dd/b3soiddinit.h | 13 + src/spicelib/devices/bsim3soi_dd/b3soidditf.h | 14 + src/spicelib/devices/bsim3soi_dd/b3soiddld.c | 4475 +++++++++++++++++ .../devices/bsim3soi_dd/b3soiddmask.c | 1207 +++++ .../devices/bsim3soi_dd/b3soiddmdel.c | 48 + .../devices/bsim3soi_dd/b3soiddmpar.c | 1625 ++++++ src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c | 395 ++ src/spicelib/devices/bsim3soi_dd/b3soiddpar.c | 128 + .../devices/bsim3soi_dd/b3soiddpzld.c | 153 + src/spicelib/devices/bsim3soi_dd/b3soiddset.c | 1353 +++++ .../devices/bsim3soi_dd/b3soiddtemp.c | 816 +++ .../devices/bsim3soi_dd/b3soiddtrunc.c | 52 + 24 files changed, 14301 insertions(+) create mode 100644 src/spicelib/devices/bsim3soi_dd/Makefile.am create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soidd.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddacld.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddask.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soidddef.h create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soidddel.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soidddest.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddext.h create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddinit.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddinit.h create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soidditf.h create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddld.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddmask.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddpar.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddset.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c create mode 100644 src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c diff --git a/src/spicelib/devices/bsim3soi_dd/Makefile.am b/src/spicelib/devices/bsim3soi_dd/Makefile.am new file mode 100644 index 000000000..7dd8b444c --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/Makefile.am @@ -0,0 +1,34 @@ +## Process this file with automake to produce Makefile.in + +pkglib_LTLIBRARIES = libbsim3soidd.la + +libbsim3soidd_la_SOURCES = \ + b3soidd.c \ + b3soiddacld.c \ + b3soiddask.c \ + b3soiddcheck.c \ + b3soiddcvtest.c \ + b3soidddel.c \ + b3soidddest.c \ + b3soiddgetic.c \ + b3soiddld.c \ + b3soiddmask.c \ + b3soiddmdel.c \ + b3soiddmpar.c \ + b3soiddnoi.c \ + b3soiddpar.c \ + b3soiddpzld.c \ + b3soiddset.c \ + b3soiddtemp.c \ + b3soiddtrunc.c \ + b3soidddef.h \ + b3soiddext.h \ + b3soiddinit.c \ + b3soiddinit.h \ + b3soidditf.h + + + +INCLUDES = -I$(top_srcdir)/src/include + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidd.c b/src/spicelib/devices/bsim3soi_dd/b3soidd.c new file mode 100644 index 000000000..9b064a70a --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidd.c @@ -0,0 +1,479 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidd.c 98/5/01 +Modified by Wei Jin 99/9/27 +**********/ + + +#include "ngspice.h" +#include +#include "devdefs.h" +#include "b3soidddef.h" +#include "suffix.h" + +IFparm B3SOIDDpTable[] = { /* parameters */ +IOP( "l", B3SOIDD_L, IF_REAL , "Length"), +IOP( "w", B3SOIDD_W, IF_REAL , "Width"), +IOP( "ad", B3SOIDD_AD, IF_REAL , "Drain area"), +IOP( "as", B3SOIDD_AS, IF_REAL , "Source area"), +IOP( "pd", B3SOIDD_PD, IF_REAL , "Drain perimeter"), +IOP( "ps", B3SOIDD_PS, IF_REAL , "Source perimeter"), +IOP( "nrd", B3SOIDD_NRD, IF_REAL , "Number of squares in drain"), +IOP( "nrs", B3SOIDD_NRS, IF_REAL , "Number of squares in source"), +IOP( "off", B3SOIDD_OFF, IF_FLAG , "Device is initially off"), +IP( "ic", B3SOIDD_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), +OP( "gmbs", B3SOIDD_GMBS, IF_REAL, "Gmb"), +OP( "gm", B3SOIDD_GM, IF_REAL, "Gm"), +OP( "gm/ids", B3SOIDD_GMID, IF_REAL, "Gm/Ids"), +OP( "gds", B3SOIDD_GDS, IF_REAL, "Gds"), +OP( "vdsat", B3SOIDD_VDSAT, IF_REAL, "Vdsat"), +OP( "vth", B3SOIDD_VON, IF_REAL, "Vth"), +OP( "ids", B3SOIDD_CD, IF_REAL, "Ids"), +OP( "vbs", B3SOIDD_VBS, IF_REAL, "Vbs"), +OP( "vgs", B3SOIDD_VGS, IF_REAL, "Vgs"), +OP( "vds", B3SOIDD_VDS, IF_REAL, "Vds"), +OP( "ves", B3SOIDD_VES, IF_REAL, "Ves"), +IOP( "bjtoff", B3SOIDD_BJTOFF, IF_INTEGER, "BJT on/off flag"), +IOP( "debug", B3SOIDD_DEBUG, IF_INTEGER, "BJT on/off flag"), +IOP( "rth0", B3SOIDD_RTH0, IF_REAL, "Instance Thermal Resistance"), +IOP( "cth0", B3SOIDD_CTH0, IF_REAL, "Instance Thermal Capacitance"), +IOP( "nrb", B3SOIDD_NRB, IF_REAL, "Number of squares in body"), +}; + +IFparm B3SOIDDmPTable[] = { /* model parameters */ +IOP( "capmod", B3SOIDD_MOD_CAPMOD, IF_INTEGER, "Capacitance model selector"), +IOP( "mobmod", B3SOIDD_MOD_MOBMOD, IF_INTEGER, "Mobility model selector"), +IOP( "noimod", B3SOIDD_MOD_NOIMOD, IF_INTEGER, "Noise model selector"), +IOP( "paramchk", B3SOIDD_MOD_PARAMCHK, IF_INTEGER, "Model parameter checking selector"), +IOP( "binunit", B3SOIDD_MOD_BINUNIT, IF_INTEGER, "Bin unit selector"), +IOP( "version", B3SOIDD_MOD_VERSION, IF_REAL, " parameter for model version"), +IOP( "tox", B3SOIDD_MOD_TOX, IF_REAL, "Gate oxide thickness in meters"), + +IOP( "cdsc", B3SOIDD_MOD_CDSC, IF_REAL, "Drain/Source and channel coupling capacitance"), +IOP( "cdscb", B3SOIDD_MOD_CDSCB, IF_REAL, "Body-bias dependence of cdsc"), +IOP( "cdscd", B3SOIDD_MOD_CDSCD, IF_REAL, "Drain-bias dependence of cdsc"), +IOP( "cit", B3SOIDD_MOD_CIT, IF_REAL, "Interface state capacitance"), +IOP( "nfactor", B3SOIDD_MOD_NFACTOR, IF_REAL, "Subthreshold swing Coefficient"), +IOP( "vsat", B3SOIDD_MOD_VSAT, IF_REAL, "Saturation velocity at tnom"), +IOP( "at", B3SOIDD_MOD_AT, IF_REAL, "Temperature coefficient of vsat"), +IOP( "a0", B3SOIDD_MOD_A0, IF_REAL, "Non-uniform depletion width effect coefficient."), +IOP( "ags", B3SOIDD_MOD_AGS, IF_REAL, "Gate bias coefficient of Abulk."), +IOP( "a1", B3SOIDD_MOD_A1, IF_REAL, "Non-saturation effect coefficient"), +IOP( "a2", B3SOIDD_MOD_A2, IF_REAL, "Non-saturation effect coefficient"), +IOP( "keta", B3SOIDD_MOD_KETA, IF_REAL, "Body-bias coefficient of non-uniform depletion width effect."), +IOP( "nsub", B3SOIDD_MOD_NSUB, IF_REAL, "Substrate doping concentration with polarity"), +IOP( "nch", B3SOIDD_MOD_NPEAK, IF_REAL, "Channel doping concentration"), +IOP( "ngate", B3SOIDD_MOD_NGATE, IF_REAL, "Poly-gate doping concentration"), +IOP( "gamma1", B3SOIDD_MOD_GAMMA1, IF_REAL, "Vth body coefficient"), +IOP( "gamma2", B3SOIDD_MOD_GAMMA2, IF_REAL, "Vth body coefficient"), +IOP( "vbx", B3SOIDD_MOD_VBX, IF_REAL, "Vth transition body Voltage"), +IOP( "vbm", B3SOIDD_MOD_VBM, IF_REAL, "Maximum body voltage"), + +IOP( "xt", B3SOIDD_MOD_XT, IF_REAL, "Doping depth"), +IOP( "k1", B3SOIDD_MOD_K1, IF_REAL, "Bulk effect coefficient 1"), +IOP( "kt1", B3SOIDD_MOD_KT1, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt1l", B3SOIDD_MOD_KT1L, IF_REAL, "Temperature coefficient of Vth"), +IOP( "kt2", B3SOIDD_MOD_KT2, IF_REAL, "Body-coefficient of kt1"), +IOP( "k2", B3SOIDD_MOD_K2, IF_REAL, "Bulk effect coefficient 2"), +IOP( "k3", B3SOIDD_MOD_K3, IF_REAL, "Narrow width effect coefficient"), +IOP( "k3b", B3SOIDD_MOD_K3B, IF_REAL, "Body effect coefficient of k3"), +IOP( "w0", B3SOIDD_MOD_W0, IF_REAL, "Narrow width effect parameter"), +IOP( "nlx", B3SOIDD_MOD_NLX, IF_REAL, "Lateral non-uniform doping effect"), +IOP( "dvt0", B3SOIDD_MOD_DVT0, IF_REAL, "Short channel effect coeff. 0"), +IOP( "dvt1", B3SOIDD_MOD_DVT1, IF_REAL, "Short channel effect coeff. 1"), +IOP( "dvt2", B3SOIDD_MOD_DVT2, IF_REAL, "Short channel effect coeff. 2"), +IOP( "dvt0w", B3SOIDD_MOD_DVT0W, IF_REAL, "Narrow Width coeff. 0"), +IOP( "dvt1w", B3SOIDD_MOD_DVT1W, IF_REAL, "Narrow Width effect coeff. 1"), +IOP( "dvt2w", B3SOIDD_MOD_DVT2W, IF_REAL, "Narrow Width effect coeff. 2"), +IOP( "drout", B3SOIDD_MOD_DROUT, IF_REAL, "DIBL coefficient of output resistance"), +IOP( "dsub", B3SOIDD_MOD_DSUB, IF_REAL, "DIBL coefficient in the subthreshold region"), +IOP( "vth0", B3SOIDD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "vtho", B3SOIDD_MOD_VTH0, IF_REAL,"Threshold voltage"), +IOP( "ua", B3SOIDD_MOD_UA, IF_REAL, "Linear gate dependence of mobility"), +IOP( "ua1", B3SOIDD_MOD_UA1, IF_REAL, "Temperature coefficient of ua"), +IOP( "ub", B3SOIDD_MOD_UB, IF_REAL, "Quadratic gate dependence of mobility"), +IOP( "ub1", B3SOIDD_MOD_UB1, IF_REAL, "Temperature coefficient of ub"), +IOP( "uc", B3SOIDD_MOD_UC, IF_REAL, "Body-bias dependence of mobility"), +IOP( "uc1", B3SOIDD_MOD_UC1, IF_REAL, "Temperature coefficient of uc"), +IOP( "u0", B3SOIDD_MOD_U0, IF_REAL, "Low-field mobility at Tnom"), +IOP( "ute", B3SOIDD_MOD_UTE, IF_REAL, "Temperature coefficient of mobility"), +IOP( "voff", B3SOIDD_MOD_VOFF, IF_REAL, "Threshold voltage offset"), +IOP( "tnom", B3SOIDD_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), +IOP( "cgso", B3SOIDD_MOD_CGSO, IF_REAL, "Gate-source overlap capacitance per width"), +IOP( "cgdo", B3SOIDD_MOD_CGDO, IF_REAL, "Gate-drain overlap capacitance per width"), +IOP( "cgeo", B3SOIDD_MOD_CGEO, IF_REAL, "Gate-substrate overlap capacitance"), +IOP( "xpart", B3SOIDD_MOD_XPART, IF_REAL, "Channel charge partitioning"), +IOP( "delta", B3SOIDD_MOD_DELTA, IF_REAL, "Effective Vds parameter"), +IOP( "rsh", B3SOIDD_MOD_RSH, IF_REAL, "Source-drain sheet resistance"), +IOP( "rdsw", B3SOIDD_MOD_RDSW, IF_REAL, "Source-drain resistance per width"), + +IOP( "prwg", B3SOIDD_MOD_PRWG, IF_REAL, "Gate-bias effect on parasitic resistance "), +IOP( "prwb", B3SOIDD_MOD_PRWB, IF_REAL, "Body-effect on parasitic resistance "), + +IOP( "prt", B3SOIDD_MOD_PRT, IF_REAL, "Temperature coefficient of parasitic resistance "), +IOP( "eta0", B3SOIDD_MOD_ETA0, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "etab", B3SOIDD_MOD_ETAB, IF_REAL, "Subthreshold region DIBL coefficient"), +IOP( "pclm", B3SOIDD_MOD_PCLM, IF_REAL, "Channel length modulation Coefficient"), +IOP( "pdiblc1", B3SOIDD_MOD_PDIBL1, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblc2", B3SOIDD_MOD_PDIBL2, IF_REAL, "Drain-induced barrier lowering coefficient"), +IOP( "pdiblcb", B3SOIDD_MOD_PDIBLB, IF_REAL, "Body-effect on drain-induced barrier lowering"), + +IOP( "pvag", B3SOIDD_MOD_PVAG, IF_REAL, "Gate dependence of output resistance parameter"), + +IOP( "shmod", B3SOIDD_MOD_SHMOD, IF_INTEGER, "Self heating mode selector"), +IOP( "tbox", B3SOIDD_MOD_TBOX, IF_REAL, "Back gate oxide thickness in meters"), +IOP( "tsi", B3SOIDD_MOD_TSI, IF_REAL, "Silicon-on-insulator thickness in meters"), +IOP( "xj", B3SOIDD_MOD_XJ, IF_REAL, "Junction Depth"), +IOP( "kb1", B3SOIDD_MOD_KB1, IF_REAL, "Backgate coupling coefficient at strong inversion"), +IOP( "kb3", B3SOIDD_MOD_KB3, IF_REAL, "Backgate coupling coefficient at subthreshold"), +IOP( "dvbd0", B3SOIDD_MOD_DVBD0, IF_REAL, "First coefficient of short-channel effect on Vbs0t"), +IOP( "dvbd1", B3SOIDD_MOD_DVBD1, IF_REAL, "Second coefficient of short-channel effect on Vbs0t"), +IOP( "vbsa", B3SOIDD_MOD_VBSA, IF_REAL, "Vbs0t offset voltage"), +IOP( "delp", B3SOIDD_MOD_DELP, IF_REAL, "Offset constant for limiting Vbseff to Phis"), +IOP( "rbody", B3SOIDD_MOD_RBODY, IF_REAL, "Intrinsic body contact sheet resistance"), +IOP( "rbsh", B3SOIDD_MOD_RBSH, IF_REAL, "Extrinsic body contact sheet resistance"), +IOP( "adice0", B3SOIDD_MOD_ADICE0, IF_REAL, "DICE constant for bulk charge effect"), +IOP( "abp", B3SOIDD_MOD_ABP, IF_REAL, "Gate bias coefficient for Xcsat calculation"), +IOP( "mxc", B3SOIDD_MOD_MXC, IF_REAL, "A smoothing parameter for Xcsat calculation"), +IOP( "rth0", B3SOIDD_MOD_RTH0, IF_REAL, "Self-heating thermal resistance"), +IOP( "cth0", B3SOIDD_MOD_CTH0, IF_REAL, "Self-heating thermal capacitance"), +IOP( "aii", B3SOIDD_MOD_AII, IF_REAL, "1st Vdsatii parameter"), +IOP( "bii", B3SOIDD_MOD_BII, IF_REAL, "2nd Vdsatii parameter"), +IOP( "cii", B3SOIDD_MOD_CII, IF_REAL, "3rd Vdsatii parameter"), +IOP( "dii", B3SOIDD_MOD_DII, IF_REAL, "4th Vdsatii parameter"), +IOP( "ngidl", B3SOIDD_MOD_NGIDL, IF_REAL, "GIDL first parameter"), +IOP( "agidl", B3SOIDD_MOD_AGIDL, IF_REAL, "GIDL second parameter"), +IOP( "bgidl", B3SOIDD_MOD_BGIDL, IF_REAL, "GIDL third parameter"), +IOP( "ndiode", B3SOIDD_MOD_NDIODE, IF_REAL, "Diode non-ideality factor"), +IOP( "ntun", B3SOIDD_MOD_NTUN, IF_REAL, "Reverse tunneling non-ideality factor"), +IOP( "isbjt", B3SOIDD_MOD_ISBJT, IF_REAL, "BJT emitter injection constant"), +IOP( "isdif", B3SOIDD_MOD_ISDIF, IF_REAL, "Body to S/D injection constant"), +IOP( "isrec", B3SOIDD_MOD_ISREC, IF_REAL, "Recombination in depletion constant"), +IOP( "istun", B3SOIDD_MOD_ISTUN, IF_REAL, "Tunneling diode constant"), +IOP( "xbjt", B3SOIDD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isbjt"), +IOP( "xdif", B3SOIDD_MOD_XBJT, IF_REAL, "Temperature coefficient for Isdif"), +IOP( "xrec", B3SOIDD_MOD_XREC, IF_REAL, "Temperature coefficient for Isrec"), +IOP( "xtun", B3SOIDD_MOD_XTUN, IF_REAL, "Temperature coefficient for Istun"), +IOP( "edl", B3SOIDD_MOD_EDL, IF_REAL, "Electron diffusion length"), +IOP( "kbjt1", B3SOIDD_MOD_KBJT1, IF_REAL, "Vds dependency on BJT base width"), +IOP( "tt", B3SOIDD_MOD_TT, IF_REAL, "Diffusion capacitance transit time coefficient"), +IOP( "vsdth", B3SOIDD_MOD_VSDTH, IF_REAL, "Source/Drain diffusion threshold voltage"), +IOP( "vsdfb", B3SOIDD_MOD_VSDFB, IF_REAL, "Source/Drain diffusion flatband voltage"), +IOP( "csdmin", B3SOIDD_MOD_CSDMIN, IF_REAL, "Source/Drain diffusion bottom minimum capacitance"), +IOP( "asd", B3SOIDD_MOD_ASD, IF_REAL, "Source/Drain diffusion smoothing parameter"), + +IOP( "pbswg", B3SOIDD_MOD_PBSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance built in potential"), +IOP( "mjswg", B3SOIDD_MOD_MJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance grading coefficient"), + +IOP( "cjswg", B3SOIDD_MOD_CJSWG, IF_REAL, "Source/drain (gate side) sidewall junction capacitance per unit width"), +IOP( "csdesw", B3SOIDD_MOD_CSDESW, IF_REAL, "Source/drain sidewall fringing constant"), +IOP( "lint", B3SOIDD_MOD_LINT, IF_REAL, "Length reduction parameter"), +IOP( "ll", B3SOIDD_MOD_LL, IF_REAL, "Length reduction parameter"), +IOP( "lln", B3SOIDD_MOD_LLN, IF_REAL, "Length reduction parameter"), +IOP( "lw", B3SOIDD_MOD_LW, IF_REAL, "Length reduction parameter"), +IOP( "lwn", B3SOIDD_MOD_LWN, IF_REAL, "Length reduction parameter"), +IOP( "lwl", B3SOIDD_MOD_LWL, IF_REAL, "Length reduction parameter"), + +IOP( "wr", B3SOIDD_MOD_WR, IF_REAL, "Width dependence of rds"), +IOP( "wint", B3SOIDD_MOD_WINT, IF_REAL, "Width reduction parameter"), +IOP( "dwg", B3SOIDD_MOD_DWG, IF_REAL, "Width reduction parameter"), +IOP( "dwb", B3SOIDD_MOD_DWB, IF_REAL, "Width reduction parameter"), + +IOP( "wl", B3SOIDD_MOD_WL, IF_REAL, "Width reduction parameter"), +IOP( "wln", B3SOIDD_MOD_WLN, IF_REAL, "Width reduction parameter"), +IOP( "ww", B3SOIDD_MOD_WW, IF_REAL, "Width reduction parameter"), +IOP( "wwn", B3SOIDD_MOD_WWN, IF_REAL, "Width reduction parameter"), +IOP( "wwl", B3SOIDD_MOD_WWL, IF_REAL, "Width reduction parameter"), + +IOP( "b0", B3SOIDD_MOD_B0, IF_REAL, "Abulk narrow width parameter"), +IOP( "b1", B3SOIDD_MOD_B1, IF_REAL, "Abulk narrow width parameter"), + +IOP( "cgsl", B3SOIDD_MOD_CGSL, IF_REAL, "New C-V model parameter"), +IOP( "cgdl", B3SOIDD_MOD_CGDL, IF_REAL, "New C-V model parameter"), +IOP( "ckappa", B3SOIDD_MOD_CKAPPA, IF_REAL, "New C-V model parameter"), +IOP( "cf", B3SOIDD_MOD_CF, IF_REAL, "Fringe capacitance parameter"), +IOP( "clc", B3SOIDD_MOD_CLC, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "cle", B3SOIDD_MOD_CLE, IF_REAL, "Vdsat parameter for C-V model"), +IOP( "dwc", B3SOIDD_MOD_DWC, IF_REAL, "Delta W for C-V model"), +IOP( "dlc", B3SOIDD_MOD_DLC, IF_REAL, "Delta L for C-V model"), + +IOP( "alpha0", B3SOIDD_MOD_ALPHA0, IF_REAL, "substrate current model parameter"), +IOP( "alpha1", B3SOIDD_MOD_ALPHA1, IF_REAL, "substrate current model parameter"), +IOP( "beta0", B3SOIDD_MOD_BETA0, IF_REAL, "substrate current model parameter"), + +IOP( "noia", B3SOIDD_MOD_NOIA, IF_REAL, "Flicker noise parameter"), +IOP( "noib", B3SOIDD_MOD_NOIB, IF_REAL, "Flicker noise parameter"), +IOP( "noic", B3SOIDD_MOD_NOIC, IF_REAL, "Flicker noise parameter"), +IOP( "em", B3SOIDD_MOD_EM, IF_REAL, "Flicker noise parameter"), +IOP( "ef", B3SOIDD_MOD_EF, IF_REAL, "Flicker noise frequency exponent"), +IOP( "af", B3SOIDD_MOD_AF, IF_REAL, "Flicker noise exponent"), +IOP( "kf", B3SOIDD_MOD_KF, IF_REAL, "Flicker noise coefficient"), +IOP( "noif", B3SOIDD_MOD_NOIF, IF_REAL, "Floating body excess noise ideality factor"), + +/* Added for binning - START */ +/* Length Dependence */ +IOP( "lnch", B3SOIDD_MOD_LNPEAK, IF_REAL, "Length dependence of nch"), +IOP( "lnsub", B3SOIDD_MOD_LNSUB, IF_REAL, "Length dependence of nsub"), +IOP( "lngate", B3SOIDD_MOD_LNGATE, IF_REAL, "Length dependence of ngate"), +IOP( "lvth0", B3SOIDD_MOD_LVTH0, IF_REAL,"Length dependence of vto"), +IOP( "lk1", B3SOIDD_MOD_LK1, IF_REAL, "Length dependence of k1"), +IOP( "lk2", B3SOIDD_MOD_LK2, IF_REAL, "Length dependence of k2"), +IOP( "lk3", B3SOIDD_MOD_LK3, IF_REAL, "Length dependence of k3"), +IOP( "lk3b", B3SOIDD_MOD_LK3B, IF_REAL, "Length dependence of k3b"), +IOP( "lvbsa", B3SOIDD_MOD_LVBSA, IF_REAL, "Length dependence of vbsa"), +IOP( "ldelp", B3SOIDD_MOD_LDELP, IF_REAL, "Length dependence of delp"), +IOP( "lkb1", B3SOIDD_MOD_LKB1, IF_REAL, "Length dependence of kb1"), +IOP( "lkb3", B3SOIDD_MOD_LKB3, IF_REAL, "Length dependence of kb3"), +IOP( "ldvbd0", B3SOIDD_MOD_LDVBD0, IF_REAL, "Length dependence of dvbd0"), +IOP( "ldvbd1", B3SOIDD_MOD_LDVBD1, IF_REAL, "Length dependence of dvbd1"), +IOP( "lw0", B3SOIDD_MOD_LW0, IF_REAL, "Length dependence of w0"), +IOP( "lnlx", B3SOIDD_MOD_LNLX, IF_REAL, "Length dependence of nlx"), +IOP( "ldvt0", B3SOIDD_MOD_LDVT0, IF_REAL, "Length dependence of dvt0"), +IOP( "ldvt1", B3SOIDD_MOD_LDVT1, IF_REAL, "Length dependence of dvt1"), +IOP( "ldvt2", B3SOIDD_MOD_LDVT2, IF_REAL, "Length dependence of dvt2"), +IOP( "ldvt0w", B3SOIDD_MOD_LDVT0W, IF_REAL, "Length dependence of dvt0w"), +IOP( "ldvt1w", B3SOIDD_MOD_LDVT1W, IF_REAL, "Length dependence of dvt1w"), +IOP( "ldvt2w", B3SOIDD_MOD_LDVT2W, IF_REAL, "Length dependence of dvt2w"), +IOP( "lu0", B3SOIDD_MOD_LU0, IF_REAL, "Length dependence of u0"), +IOP( "lua", B3SOIDD_MOD_LUA, IF_REAL, "Length dependence of ua"), +IOP( "lub", B3SOIDD_MOD_LUB, IF_REAL, "Length dependence of ub"), +IOP( "luc", B3SOIDD_MOD_LUC, IF_REAL, "Length dependence of uc"), +IOP( "lvsat", B3SOIDD_MOD_LVSAT, IF_REAL, "Length dependence of vsat"), +IOP( "la0", B3SOIDD_MOD_LA0, IF_REAL, "Length dependence of a0"), +IOP( "lags", B3SOIDD_MOD_LAGS, IF_REAL, "Length dependence of ags"), +IOP( "lb0", B3SOIDD_MOD_LB0, IF_REAL, "Length dependence of b0"), +IOP( "lb1", B3SOIDD_MOD_LB1, IF_REAL, "Length dependence of b1"), +IOP( "lketa", B3SOIDD_MOD_LKETA, IF_REAL, "Length dependence of keta"), +IOP( "labp", B3SOIDD_MOD_LABP, IF_REAL, "Length dependence of abp"), +IOP( "lmxc", B3SOIDD_MOD_LMXC, IF_REAL, "Length dependence of mxc"), +IOP( "ladice0", B3SOIDD_MOD_LADICE0, IF_REAL, "Length dependence of adice0"), +IOP( "la1", B3SOIDD_MOD_LA1, IF_REAL, "Length dependence of a1"), +IOP( "la2", B3SOIDD_MOD_LA2, IF_REAL, "Length dependence of a2"), +IOP( "lrdsw", B3SOIDD_MOD_LRDSW, IF_REAL, "Length dependence of rdsw "), +IOP( "lprwb", B3SOIDD_MOD_LPRWB, IF_REAL, "Length dependence of prwb "), +IOP( "lprwg", B3SOIDD_MOD_LPRWG, IF_REAL, "Length dependence of prwg "), +IOP( "lwr", B3SOIDD_MOD_LWR, IF_REAL, "Length dependence of wr"), +IOP( "lnfactor", B3SOIDD_MOD_LNFACTOR, IF_REAL, "Length dependence of nfactor"), +IOP( "ldwg", B3SOIDD_MOD_LDWG, IF_REAL, "Length dependence of dwg"), +IOP( "ldwb", B3SOIDD_MOD_LDWB, IF_REAL, "Length dependence of dwb"), +IOP( "lvoff", B3SOIDD_MOD_LVOFF, IF_REAL, "Length dependence of voff"), +IOP( "leta0", B3SOIDD_MOD_LETA0, IF_REAL, "Length dependence of eta0"), +IOP( "letab", B3SOIDD_MOD_LETAB, IF_REAL, "Length dependence of etab"), +IOP( "ldsub", B3SOIDD_MOD_LDSUB, IF_REAL, "Length dependence of dsub"), +IOP( "lcit", B3SOIDD_MOD_LCIT, IF_REAL, "Length dependence of cit"), +IOP( "lcdsc", B3SOIDD_MOD_LCDSC, IF_REAL, "Length dependence of cdsc"), +IOP( "lcdscb", B3SOIDD_MOD_LCDSCB, IF_REAL, "Length dependence of cdscb"), +IOP( "lcdscd", B3SOIDD_MOD_LCDSCD, IF_REAL, "Length dependence of cdscd"), +IOP( "lpclm", B3SOIDD_MOD_LPCLM, IF_REAL, "Length dependence of pclm"), +IOP( "lpdiblc1", B3SOIDD_MOD_LPDIBL1, IF_REAL, "Length dependence of pdiblc1"), +IOP( "lpdiblc2", B3SOIDD_MOD_LPDIBL2, IF_REAL, "Length dependence of pdiblc2"), +IOP( "lpdiblcb", B3SOIDD_MOD_LPDIBLB, IF_REAL, "Length dependence of pdiblcb"), +IOP( "ldrout", B3SOIDD_MOD_LDROUT, IF_REAL, "Length dependence of drout"), +IOP( "lpvag", B3SOIDD_MOD_LPVAG, IF_REAL, "Length dependence of pvag"), +IOP( "ldelta", B3SOIDD_MOD_LDELTA, IF_REAL, "Length dependence of delta"), +IOP( "laii", B3SOIDD_MOD_LAII, IF_REAL, "Length dependence of aii"), +IOP( "lbii", B3SOIDD_MOD_LBII, IF_REAL, "Length dependence of bii"), +IOP( "lcii", B3SOIDD_MOD_LCII, IF_REAL, "Length dependence of cii"), +IOP( "ldii", B3SOIDD_MOD_LDII, IF_REAL, "Length dependence of dii"), +IOP( "lalpha0", B3SOIDD_MOD_LALPHA0, IF_REAL, "Length dependence of alpha0"), +IOP( "lalpha1", B3SOIDD_MOD_LALPHA1, IF_REAL, "Length dependence of alpha1"), +IOP( "lbeta0", B3SOIDD_MOD_LBETA0, IF_REAL, "Length dependence of beta0"), +IOP( "lagidl", B3SOIDD_MOD_LAGIDL, IF_REAL, "Length dependence of agidl"), +IOP( "lbgidl", B3SOIDD_MOD_LBGIDL, IF_REAL, "Length dependence of bgidl"), +IOP( "lngidl", B3SOIDD_MOD_LNGIDL, IF_REAL, "Length dependence of ngidl"), +IOP( "lntun", B3SOIDD_MOD_LNTUN, IF_REAL, "Length dependence of ntun"), +IOP( "lndiode", B3SOIDD_MOD_LNDIODE, IF_REAL, "Length dependence of ndiode"), +IOP( "lisbjt", B3SOIDD_MOD_LISBJT, IF_REAL, "Length dependence of isbjt"), +IOP( "lisdif", B3SOIDD_MOD_LISDIF, IF_REAL, "Length dependence of isdif"), +IOP( "lisrec", B3SOIDD_MOD_LISREC, IF_REAL, "Length dependence of isrec"), +IOP( "listun", B3SOIDD_MOD_LISTUN, IF_REAL, "Length dependence of istun"), +IOP( "ledl", B3SOIDD_MOD_LEDL, IF_REAL, "Length dependence of edl"), +IOP( "lkbjt1", B3SOIDD_MOD_LKBJT1, IF_REAL, "Length dependence of kbjt1"), +IOP( "lvsdfb", B3SOIDD_MOD_LVSDFB, IF_REAL, "Length dependence of vsdfb"), +IOP( "lvsdth", B3SOIDD_MOD_LVSDTH, IF_REAL, "Length dependence of vsdth"), +/* Width Dependence */ +IOP( "wnch", B3SOIDD_MOD_WNPEAK, IF_REAL, "Width dependence of nch"), +IOP( "wnsub", B3SOIDD_MOD_WNSUB, IF_REAL, "Width dependence of nsub"), +IOP( "wngate", B3SOIDD_MOD_WNGATE, IF_REAL, "Width dependence of ngate"), +IOP( "wvth0", B3SOIDD_MOD_WVTH0, IF_REAL,"Width dependence of vto"), +IOP( "wk1", B3SOIDD_MOD_WK1, IF_REAL, "Width dependence of k1"), +IOP( "wk2", B3SOIDD_MOD_WK2, IF_REAL, "Width dependence of k2"), +IOP( "wk3", B3SOIDD_MOD_WK3, IF_REAL, "Width dependence of k3"), +IOP( "wk3b", B3SOIDD_MOD_WK3B, IF_REAL, "Width dependence of k3b"), +IOP( "wvbsa", B3SOIDD_MOD_WVBSA, IF_REAL, "Width dependence of vbsa"), +IOP( "wdelp", B3SOIDD_MOD_WDELP, IF_REAL, "Width dependence of delp"), +IOP( "wkb1", B3SOIDD_MOD_WKB1, IF_REAL, "Width dependence of kb1"), +IOP( "wkb3", B3SOIDD_MOD_WKB3, IF_REAL, "Width dependence of kb3"), +IOP( "wdvbd0", B3SOIDD_MOD_WDVBD0, IF_REAL, "Width dependence of dvbd0"), +IOP( "wdvbd1", B3SOIDD_MOD_WDVBD1, IF_REAL, "Width dependence of dvbd1"), +IOP( "ww0", B3SOIDD_MOD_WW0, IF_REAL, "Width dependence of w0"), +IOP( "wnlx", B3SOIDD_MOD_WNLX, IF_REAL, "Width dependence of nlx"), +IOP( "wdvt0", B3SOIDD_MOD_WDVT0, IF_REAL, "Width dependence of dvt0"), +IOP( "wdvt1", B3SOIDD_MOD_WDVT1, IF_REAL, "Width dependence of dvt1"), +IOP( "wdvt2", B3SOIDD_MOD_WDVT2, IF_REAL, "Width dependence of dvt2"), +IOP( "wdvt0w", B3SOIDD_MOD_WDVT0W, IF_REAL, "Width dependence of dvt0w"), +IOP( "wdvt1w", B3SOIDD_MOD_WDVT1W, IF_REAL, "Width dependence of dvt1w"), +IOP( "wdvt2w", B3SOIDD_MOD_WDVT2W, IF_REAL, "Width dependence of dvt2w"), +IOP( "wu0", B3SOIDD_MOD_WU0, IF_REAL, "Width dependence of u0"), +IOP( "wua", B3SOIDD_MOD_WUA, IF_REAL, "Width dependence of ua"), +IOP( "wub", B3SOIDD_MOD_WUB, IF_REAL, "Width dependence of ub"), +IOP( "wuc", B3SOIDD_MOD_WUC, IF_REAL, "Width dependence of uc"), +IOP( "wvsat", B3SOIDD_MOD_WVSAT, IF_REAL, "Width dependence of vsat"), +IOP( "wa0", B3SOIDD_MOD_WA0, IF_REAL, "Width dependence of a0"), +IOP( "wags", B3SOIDD_MOD_WAGS, IF_REAL, "Width dependence of ags"), +IOP( "wb0", B3SOIDD_MOD_WB0, IF_REAL, "Width dependence of b0"), +IOP( "wb1", B3SOIDD_MOD_WB1, IF_REAL, "Width dependence of b1"), +IOP( "wketa", B3SOIDD_MOD_WKETA, IF_REAL, "Width dependence of keta"), +IOP( "wabp", B3SOIDD_MOD_WABP, IF_REAL, "Width dependence of abp"), +IOP( "wmxc", B3SOIDD_MOD_WMXC, IF_REAL, "Width dependence of mxc"), +IOP( "wadice0", B3SOIDD_MOD_WADICE0, IF_REAL, "Width dependence of adice0"), +IOP( "wa1", B3SOIDD_MOD_WA1, IF_REAL, "Width dependence of a1"), +IOP( "wa2", B3SOIDD_MOD_WA2, IF_REAL, "Width dependence of a2"), +IOP( "wrdsw", B3SOIDD_MOD_WRDSW, IF_REAL, "Width dependence of rdsw "), +IOP( "wprwb", B3SOIDD_MOD_WPRWB, IF_REAL, "Width dependence of prwb "), +IOP( "wprwg", B3SOIDD_MOD_WPRWG, IF_REAL, "Width dependence of prwg "), +IOP( "wwr", B3SOIDD_MOD_WWR, IF_REAL, "Width dependence of wr"), +IOP( "wnfactor", B3SOIDD_MOD_WNFACTOR, IF_REAL, "Width dependence of nfactor"), +IOP( "wdwg", B3SOIDD_MOD_WDWG, IF_REAL, "Width dependence of dwg"), +IOP( "wdwb", B3SOIDD_MOD_WDWB, IF_REAL, "Width dependence of dwb"), +IOP( "wvoff", B3SOIDD_MOD_WVOFF, IF_REAL, "Width dependence of voff"), +IOP( "weta0", B3SOIDD_MOD_WETA0, IF_REAL, "Width dependence of eta0"), +IOP( "wetab", B3SOIDD_MOD_WETAB, IF_REAL, "Width dependence of etab"), +IOP( "wdsub", B3SOIDD_MOD_WDSUB, IF_REAL, "Width dependence of dsub"), +IOP( "wcit", B3SOIDD_MOD_WCIT, IF_REAL, "Width dependence of cit"), +IOP( "wcdsc", B3SOIDD_MOD_WCDSC, IF_REAL, "Width dependence of cdsc"), +IOP( "wcdscb", B3SOIDD_MOD_WCDSCB, IF_REAL, "Width dependence of cdscb"), +IOP( "wcdscd", B3SOIDD_MOD_WCDSCD, IF_REAL, "Width dependence of cdscd"), +IOP( "wpclm", B3SOIDD_MOD_WPCLM, IF_REAL, "Width dependence of pclm"), +IOP( "wpdiblc1", B3SOIDD_MOD_WPDIBL1, IF_REAL, "Width dependence of pdiblc1"), +IOP( "wpdiblc2", B3SOIDD_MOD_WPDIBL2, IF_REAL, "Width dependence of pdiblc2"), +IOP( "wpdiblcb", B3SOIDD_MOD_WPDIBLB, IF_REAL, "Width dependence of pdiblcb"), +IOP( "wdrout", B3SOIDD_MOD_WDROUT, IF_REAL, "Width dependence of drout"), +IOP( "wpvag", B3SOIDD_MOD_WPVAG, IF_REAL, "Width dependence of pvag"), +IOP( "wdelta", B3SOIDD_MOD_WDELTA, IF_REAL, "Width dependence of delta"), +IOP( "waii", B3SOIDD_MOD_WAII, IF_REAL, "Width dependence of aii"), +IOP( "wbii", B3SOIDD_MOD_WBII, IF_REAL, "Width dependence of bii"), +IOP( "wcii", B3SOIDD_MOD_WCII, IF_REAL, "Width dependence of cii"), +IOP( "wdii", B3SOIDD_MOD_WDII, IF_REAL, "Width dependence of dii"), +IOP( "walpha0", B3SOIDD_MOD_WALPHA0, IF_REAL, "Width dependence of alpha0"), +IOP( "walpha1", B3SOIDD_MOD_WALPHA1, IF_REAL, "Width dependence of alpha1"), +IOP( "wbeta0", B3SOIDD_MOD_WBETA0, IF_REAL, "Width dependence of beta0"), +IOP( "wagidl", B3SOIDD_MOD_WAGIDL, IF_REAL, "Width dependence of agidl"), +IOP( "wbgidl", B3SOIDD_MOD_WBGIDL, IF_REAL, "Width dependence of bgidl"), +IOP( "wngidl", B3SOIDD_MOD_WNGIDL, IF_REAL, "Width dependence of ngidl"), +IOP( "wntun", B3SOIDD_MOD_WNTUN, IF_REAL, "Width dependence of ntun"), +IOP( "wndiode", B3SOIDD_MOD_WNDIODE, IF_REAL, "Width dependence of ndiode"), +IOP( "wisbjt", B3SOIDD_MOD_WISBJT, IF_REAL, "Width dependence of isbjt"), +IOP( "wisdif", B3SOIDD_MOD_WISDIF, IF_REAL, "Width dependence of isdif"), +IOP( "wisrec", B3SOIDD_MOD_WISREC, IF_REAL, "Width dependence of isrec"), +IOP( "wistun", B3SOIDD_MOD_WISTUN, IF_REAL, "Width dependence of istun"), +IOP( "wedl", B3SOIDD_MOD_WEDL, IF_REAL, "Width dependence of edl"), +IOP( "wkbjt1", B3SOIDD_MOD_WKBJT1, IF_REAL, "Width dependence of kbjt1"), +IOP( "wvsdfb", B3SOIDD_MOD_WVSDFB, IF_REAL, "Width dependence of vsdfb"), +IOP( "wvsdth", B3SOIDD_MOD_WVSDTH, IF_REAL, "Width dependence of vsdth"), +/* Cross-term Dependence */ +IOP( "pnch", B3SOIDD_MOD_PNPEAK, IF_REAL, "Cross-term dependence of nch"), +IOP( "pnsub", B3SOIDD_MOD_PNSUB, IF_REAL, "Cross-term dependence of nsub"), +IOP( "pngate", B3SOIDD_MOD_PNGATE, IF_REAL, "Cross-term dependence of ngate"), +IOP( "pvth0", B3SOIDD_MOD_PVTH0, IF_REAL,"Cross-term dependence of vto"), +IOP( "pk1", B3SOIDD_MOD_PK1, IF_REAL, "Cross-term dependence of k1"), +IOP( "pk2", B3SOIDD_MOD_PK2, IF_REAL, "Cross-term dependence of k2"), +IOP( "pk3", B3SOIDD_MOD_PK3, IF_REAL, "Cross-term dependence of k3"), +IOP( "pk3b", B3SOIDD_MOD_PK3B, IF_REAL, "Cross-term dependence of k3b"), +IOP( "pvbsa", B3SOIDD_MOD_PVBSA, IF_REAL, "Cross-term dependence of vbsa"), +IOP( "pdelp", B3SOIDD_MOD_PDELP, IF_REAL, "Cross-term dependence of delp"), +IOP( "pkb1", B3SOIDD_MOD_PKB1, IF_REAL, "Cross-term dependence of kb1"), +IOP( "pkb3", B3SOIDD_MOD_PKB3, IF_REAL, "Cross-term dependence of kb3"), +IOP( "pdvbd0", B3SOIDD_MOD_PDVBD0, IF_REAL, "Cross-term dependence of dvbd0"), +IOP( "pdvbd1", B3SOIDD_MOD_PDVBD1, IF_REAL, "Cross-term dependence of dvbd1"), +IOP( "pw0", B3SOIDD_MOD_PW0, IF_REAL, "Cross-term dependence of w0"), +IOP( "pnlx", B3SOIDD_MOD_PNLX, IF_REAL, "Cross-term dependence of nlx"), +IOP( "pdvt0", B3SOIDD_MOD_PDVT0, IF_REAL, "Cross-term dependence of dvt0"), +IOP( "pdvt1", B3SOIDD_MOD_PDVT1, IF_REAL, "Cross-term dependence of dvt1"), +IOP( "pdvt2", B3SOIDD_MOD_PDVT2, IF_REAL, "Cross-term dependence of dvt2"), +IOP( "pdvt0w", B3SOIDD_MOD_PDVT0W, IF_REAL, "Cross-term dependence of dvt0w"), +IOP( "pdvt1w", B3SOIDD_MOD_PDVT1W, IF_REAL, "Cross-term dependence of dvt1w"), +IOP( "pdvt2w", B3SOIDD_MOD_PDVT2W, IF_REAL, "Cross-term dependence of dvt2w"), +IOP( "pu0", B3SOIDD_MOD_PU0, IF_REAL, "Cross-term dependence of u0"), +IOP( "pua", B3SOIDD_MOD_PUA, IF_REAL, "Cross-term dependence of ua"), +IOP( "pub", B3SOIDD_MOD_PUB, IF_REAL, "Cross-term dependence of ub"), +IOP( "puc", B3SOIDD_MOD_PUC, IF_REAL, "Cross-term dependence of uc"), +IOP( "pvsat", B3SOIDD_MOD_PVSAT, IF_REAL, "Cross-term dependence of vsat"), +IOP( "pa0", B3SOIDD_MOD_PA0, IF_REAL, "Cross-term dependence of a0"), +IOP( "pags", B3SOIDD_MOD_PAGS, IF_REAL, "Cross-term dependence of ags"), +IOP( "pb0", B3SOIDD_MOD_PB0, IF_REAL, "Cross-term dependence of b0"), +IOP( "pb1", B3SOIDD_MOD_PB1, IF_REAL, "Cross-term dependence of b1"), +IOP( "pketa", B3SOIDD_MOD_PKETA, IF_REAL, "Cross-term dependence of keta"), +IOP( "pabp", B3SOIDD_MOD_PABP, IF_REAL, "Cross-term dependence of abp"), +IOP( "pmxc", B3SOIDD_MOD_PMXC, IF_REAL, "Cross-term dependence of mxc"), +IOP( "padice0", B3SOIDD_MOD_PADICE0, IF_REAL, "Cross-term dependence of adice0"), +IOP( "pa1", B3SOIDD_MOD_PA1, IF_REAL, "Cross-term dependence of a1"), +IOP( "pa2", B3SOIDD_MOD_PA2, IF_REAL, "Cross-term dependence of a2"), +IOP( "prdsw", B3SOIDD_MOD_PRDSW, IF_REAL, "Cross-term dependence of rdsw "), +IOP( "pprwb", B3SOIDD_MOD_PPRWB, IF_REAL, "Cross-term dependence of prwb "), +IOP( "pprwg", B3SOIDD_MOD_PPRWG, IF_REAL, "Cross-term dependence of prwg "), +IOP( "pwr", B3SOIDD_MOD_PWR, IF_REAL, "Cross-term dependence of wr"), +IOP( "pnfactor", B3SOIDD_MOD_PNFACTOR, IF_REAL, "Cross-term dependence of nfactor"), +IOP( "pdwg", B3SOIDD_MOD_PDWG, IF_REAL, "Cross-term dependence of dwg"), +IOP( "pdwb", B3SOIDD_MOD_PDWB, IF_REAL, "Cross-term dependence of dwb"), +IOP( "pvoff", B3SOIDD_MOD_PVOFF, IF_REAL, "Cross-term dependence of voff"), +IOP( "peta0", B3SOIDD_MOD_PETA0, IF_REAL, "Cross-term dependence of eta0"), +IOP( "petab", B3SOIDD_MOD_PETAB, IF_REAL, "Cross-term dependence of etab"), +IOP( "pdsub", B3SOIDD_MOD_PDSUB, IF_REAL, "Cross-term dependence of dsub"), +IOP( "pcit", B3SOIDD_MOD_PCIT, IF_REAL, "Cross-term dependence of cit"), +IOP( "pcdsc", B3SOIDD_MOD_PCDSC, IF_REAL, "Cross-term dependence of cdsc"), +IOP( "pcdscb", B3SOIDD_MOD_PCDSCB, IF_REAL, "Cross-term dependence of cdscb"), +IOP( "pcdscd", B3SOIDD_MOD_PCDSCD, IF_REAL, "Cross-term dependence of cdscd"), +IOP( "ppclm", B3SOIDD_MOD_PPCLM, IF_REAL, "Cross-term dependence of pclm"), +IOP( "ppdiblc1", B3SOIDD_MOD_PPDIBL1, IF_REAL, "Cross-term dependence of pdiblc1"), +IOP( "ppdiblc2", B3SOIDD_MOD_PPDIBL2, IF_REAL, "Cross-term dependence of pdiblc2"), +IOP( "ppdiblcb", B3SOIDD_MOD_PPDIBLB, IF_REAL, "Cross-term dependence of pdiblcb"), +IOP( "pdrout", B3SOIDD_MOD_PDROUT, IF_REAL, "Cross-term dependence of drout"), +IOP( "ppvag", B3SOIDD_MOD_PPVAG, IF_REAL, "Cross-term dependence of pvag"), +IOP( "pdelta", B3SOIDD_MOD_PDELTA, IF_REAL, "Cross-term dependence of delta"), +IOP( "paii", B3SOIDD_MOD_PAII, IF_REAL, "Cross-term dependence of aii"), +IOP( "pbii", B3SOIDD_MOD_PBII, IF_REAL, "Cross-term dependence of bii"), +IOP( "pcii", B3SOIDD_MOD_PCII, IF_REAL, "Cross-term dependence of cii"), +IOP( "pdii", B3SOIDD_MOD_PDII, IF_REAL, "Cross-term dependence of dii"), +IOP( "palpha0", B3SOIDD_MOD_PALPHA0, IF_REAL, "Cross-term dependence of alpha0"), +IOP( "palpha1", B3SOIDD_MOD_PALPHA1, IF_REAL, "Cross-term dependence of alpha1"), +IOP( "pbeta0", B3SOIDD_MOD_PBETA0, IF_REAL, "Cross-term dependence of beta0"), +IOP( "pagidl", B3SOIDD_MOD_PAGIDL, IF_REAL, "Cross-term dependence of agidl"), +IOP( "pbgidl", B3SOIDD_MOD_PBGIDL, IF_REAL, "Cross-term dependence of bgidl"), +IOP( "pngidl", B3SOIDD_MOD_PNGIDL, IF_REAL, "Cross-term dependence of ngidl"), +IOP( "pntun", B3SOIDD_MOD_PNTUN, IF_REAL, "Cross-term dependence of ntun"), +IOP( "pndiode", B3SOIDD_MOD_PNDIODE, IF_REAL, "Cross-term dependence of ndiode"), +IOP( "pisbjt", B3SOIDD_MOD_PISBJT, IF_REAL, "Cross-term dependence of isbjt"), +IOP( "pisdif", B3SOIDD_MOD_PISDIF, IF_REAL, "Cross-term dependence of isdif"), +IOP( "pisrec", B3SOIDD_MOD_PISREC, IF_REAL, "Cross-term dependence of isrec"), +IOP( "pistun", B3SOIDD_MOD_PISTUN, IF_REAL, "Cross-term dependence of istun"), +IOP( "pedl", B3SOIDD_MOD_PEDL, IF_REAL, "Cross-term dependence of edl"), +IOP( "pkbjt1", B3SOIDD_MOD_PKBJT1, IF_REAL, "Cross-term dependence of kbjt1"), +IOP( "pvsdfb", B3SOIDD_MOD_PVSDFB, IF_REAL, "Cross-term dependence of vsdfb"), +IOP( "pvsdth", B3SOIDD_MOD_PVSDTH, IF_REAL, "Cross-term dependence of vsdth"), +/* Added for binning - END */ + +IP( "nmos", B3SOIDD_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), +IP( "pmos", B3SOIDD_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), +}; + +char *B3SOIDDnames[] = { + "Drain", + "Gate", + "Source", + "Backgate", + "", + "Body", + "Temp", + "Charge", +}; + +int B3SOIDDnSize = NUMELEMS(B3SOIDDnames); +int B3SOIDDpTSize = NUMELEMS(B3SOIDDpTable); +int B3SOIDDmPTSize = NUMELEMS(B3SOIDDmPTable); +int B3SOIDDiSize = sizeof(B3SOIDDinstance); +int B3SOIDDmSize = sizeof(B3SOIDDmodel); + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c new file mode 100644 index 000000000..6b18858e1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddacld.c @@ -0,0 +1,462 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddacld.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDacLoad(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +register int selfheat; +double xcggb, xcgdb, xcgsb, xcgeb, xcgT; +double xcdgb, xcddb, xcdsb, xcdeb, xcdT; +double xcsgb, xcsdb, xcssb, xcseb, xcsT; +double xcbgb, xcbdb, xcbsb, xcbeb, xcbT; +double xcegb, xcedb, xcesb, xceeb, xceT; +double gdpr, gspr, gds; +double cggb, cgdb, cgsb, cgeb, cgT; +double cdgb, cddb, cdsb, cdeb, cdT; +double cbgb, cbdb, cbsb, cbeb, cbT; +double cegb, cedb, cesb, ceeb, ceT; +double GSoverlapCap, GDoverlapCap, GEoverlapCap, FwdSum, RevSum, Gm, Gmbs, Gme, GmT; +double omega; +double dxpart, sxpart; +double gbbg, gbbdp, gbbb, gbbe, gbbp, gbbsp, gbbT; +double gddpg, gddpdp, gddpsp, gddpb, gddpe, gddpT; +double gsspg, gsspdp, gsspsp, gsspb, gsspe, gsspT; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double xcTt, cTt, gcTt, gTtt, gTtg, gTtb, gTte, gTtdp, gTtsp; + +double Dum1, Dum2, Dum3, Dum4, Dum5; +FILE *fpdebug; + + omega = ckt->CKTomega; + for (; model != NULL; model = model->B3SOIDDnextModel) + { + + for (here = model->B3SOIDDinstances; here!= NULL; + here = here->B3SOIDDnextInstance) + { + selfheat = (model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0 != 0.0); + if (here->B3SOIDDdebugMod > 2) + { + fpdebug = fopen("b3soiDDac.log", "a"); + fprintf(fpdebug, ".......omega=%.5e\n", omega); + } + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + Gme = here->B3SOIDDgme; + GmT = model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbsb; + cbdb = here->B3SOIDDcbdb; + cbeb = here->B3SOIDDcbeb; + cbT = model->B3SOIDDtype * here->B3SOIDDcbT; + + cegb = here->B3SOIDDcegb; + cesb = here->B3SOIDDcesb; + cedb = here->B3SOIDDcedb; + ceeb = here->B3SOIDDceeb; + ceT = model->B3SOIDDtype * here->B3SOIDDceT; + + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgsb; + cgdb = here->B3SOIDDcgdb; + cgeb = here->B3SOIDDcgeb; + cgT = model->B3SOIDDtype * here->B3SOIDDcgT; + + cdgb = here->B3SOIDDcdgb; + cdsb = here->B3SOIDDcdsb; + cddb = here->B3SOIDDcddb; + cdeb = here->B3SOIDDcdeb; + cdT = model->B3SOIDDtype * here->B3SOIDDcdT; + + cTt = here->pParam->B3SOIDDcth; + + gbbg = -here->B3SOIDDgbgs; + gbbdp = -here->B3SOIDDgbds; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjdg; + gddpdp = -here->B3SOIDDgjdd; + gddpb = -here->B3SOIDDgjdb; + gddpe = -here->B3SOIDDgjde; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjsg; + gsspdp = -here->B3SOIDDgjsd; + gsspb = -here->B3SOIDDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppdp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + + sxpart = 0.6; + dxpart = 0.4; + + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + Gme = -here->B3SOIDDgme; + GmT = -model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = 0.0; + RevSum = -Gm - Gmbs - Gme; + + cdgb = - (here->B3SOIDDcdgb + here->B3SOIDDcggb + here->B3SOIDDcbgb + + here->B3SOIDDcegb); + cdsb = - (here->B3SOIDDcddb + here->B3SOIDDcgdb + here->B3SOIDDcbdb + + here->B3SOIDDcedb); + cddb = - (here->B3SOIDDcdsb + here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcesb); + cdeb = - (here->B3SOIDDcdeb + here->B3SOIDDcgeb + here->B3SOIDDcbeb + + here->B3SOIDDceeb); + cdT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + + here->B3SOIDDcdT + here->B3SOIDDceT); + + cegb = here->B3SOIDDcegb; + cesb = here->B3SOIDDcedb; + cedb = here->B3SOIDDcesb; + ceeb = here->B3SOIDDceeb; + ceT = model->B3SOIDDtype * here->B3SOIDDceT; + + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgdb; + cgdb = here->B3SOIDDcgsb; + cgeb = here->B3SOIDDcgeb; + cgT = model->B3SOIDDtype * here->B3SOIDDcgT; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbdb; + cbdb = here->B3SOIDDcbsb; + cbeb = here->B3SOIDDcbeb; + cbT = model->B3SOIDDtype * here->B3SOIDDcbT; + + cTt = here->pParam->B3SOIDDcth; + + gbbg = -here->B3SOIDDgbgs; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbsp = -here->B3SOIDDgbds; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjsg; + gddpsp = -here->B3SOIDDgjsd; + gddpb = -here->B3SOIDDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjdg; + gsspsp = -here->B3SOIDDgjdd; + gsspb = -here->B3SOIDDgjdb; + gsspe = -here->B3SOIDDgjde; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppsp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtt = here->B3SOIDDgtempT; + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtsp = - (gTtt + gTtg + gTtb + gTte + gTtdp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtsp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + + sxpart = 0.6; + sxpart = 0.4; + dxpart = 0.6; + } + + gdpr=here->B3SOIDDdrainConductance; + gspr=here->B3SOIDDsourceConductance; + gds= here->B3SOIDDgds; + + GSoverlapCap = here->B3SOIDDcgso; + GDoverlapCap = here->B3SOIDDcgdo; + GEoverlapCap = here->pParam->B3SOIDDcgeo; + + xcegb = (cegb - GEoverlapCap) * omega; + xcedb = cedb * omega; + xcesb = cesb * omega; + xceeb = (ceeb + GEoverlapCap) * omega; + xceT = ceT * omega; + + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GEoverlapCap) + * omega; + xcgdb = (cgdb - GDoverlapCap ) * omega; + xcgsb = (cgsb - GSoverlapCap) * omega; + xcgeb = (cgeb - GEoverlapCap) * omega; + xcgT = cgT * omega; + + xcdgb = (cdgb - GDoverlapCap) * omega; + xcddb = (cddb + GDoverlapCap) * omega; + xcdsb = cdsb * omega; + xcdeb = cdeb * omega; + xcdT = cdT * omega; + + xcsgb = -(cggb + cbgb + cdgb + cegb + GSoverlapCap) * omega; + xcsdb = -(cgdb + cbdb + cddb + cedb) * omega; + xcssb = (GSoverlapCap - (cgsb + cbsb + cdsb + cesb)) * omega; + xcseb = -(cgeb + cbeb + cdeb + ceeb) * omega; + xcsT = -(cgT + cbT + cdT + ceT) * omega; + + xcbgb = cbgb * omega; + xcbdb = cbdb * omega; + xcbsb = cbsb * omega; + xcbeb = cbeb * omega; + xcbT = cbT * omega; + + xcTt = cTt * omega; + + *(here->B3SOIDDEgPtr +1) += xcegb; + *(here->B3SOIDDEdpPtr +1) += xcedb; + *(here->B3SOIDDEspPtr +1) += xcesb; + *(here->B3SOIDDGePtr +1) += xcgeb; + *(here->B3SOIDDDPePtr +1) += xcdeb; + *(here->B3SOIDDSPePtr +1) += xcseb; + + *(here->B3SOIDDEePtr +1) += xceeb; + + *(here->B3SOIDDGgPtr +1) += xcggb; + *(here->B3SOIDDGdpPtr +1) += xcgdb; + *(here->B3SOIDDGspPtr +1) += xcgsb; + + *(here->B3SOIDDDPgPtr +1) += xcdgb; + *(here->B3SOIDDDPdpPtr +1) += xcddb; + *(here->B3SOIDDDPspPtr +1) += xcdsb; + + *(here->B3SOIDDSPgPtr +1) += xcsgb; + *(here->B3SOIDDSPdpPtr +1) += xcsdb; + *(here->B3SOIDDSPspPtr +1) += xcssb; + + *(here->B3SOIDDBePtr +1) += xcbeb; + *(here->B3SOIDDBgPtr +1) += xcbgb; + *(here->B3SOIDDBdpPtr +1) += xcbdb; + *(here->B3SOIDDBspPtr +1) += xcbsb; + + *(here->B3SOIDDEbPtr +1) -= xcegb + xcedb + xcesb + xceeb; + *(here->B3SOIDDGbPtr +1) -= xcggb + xcgdb + xcgsb + xcgeb; + *(here->B3SOIDDDPbPtr +1) -= xcdgb + xcddb + xcdsb + xcdeb; + *(here->B3SOIDDSPbPtr +1) -= xcsgb + xcsdb + xcssb + xcseb; + *(here->B3SOIDDBbPtr +1) -= xcbgb + xcbdb + xcbsb + xcbeb; + + if (selfheat) + { + *(here->B3SOIDDTemptempPtr + 1) += xcTt; + *(here->B3SOIDDDPtempPtr + 1) += xcdT; + *(here->B3SOIDDSPtempPtr + 1) += xcsT; + *(here->B3SOIDDBtempPtr + 1) += xcbT; + *(here->B3SOIDDEtempPtr + 1) += xceT; + *(here->B3SOIDDGtempPtr + 1) += xcgT; + } + + +if (here->B3SOIDDdebugMod > 3) +{ +fprintf(fpdebug, "Cbg+Cbs+Cbe = %.5e; Cbd = %.5e;\n", +(xcbgb+xcbsb+xcbeb)/omega, xcbdb/omega); +fprintf(fpdebug, "gbs = %.5e; gbd = %.5e\n", gbbsp, gbbdp); + + + fprintf(fpdebug, "AC condunctance...\n"); + fprintf(fpdebug, "Eg=%.5e; Edp=%.5e; Esp=%.5e;\nEb=%.5e; Ee=%.5e\n", +xcegb, xcedb, xcesb, -(xcegb+xcedb+xcesb+xceeb), xceeb); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", +xcggb, xcgdb, xcgsb, -(xcggb+xcgdb+xcgsb+xcgeb), xcgeb); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +xcbgb, xcbdb, xcbsb, -(xcbgb+xcbdb+xcbsb+xcbeb), xcbeb); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", +xcdgb, xcddb, xcdsb, -(xcdgb+xcddb+xcdsb+xcdeb), xcdeb); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", +xcsgb, xcsdb, xcssb, -(xcsgb+xcsdb+xcssb+xcseb), xcseb); +} + + + + *(here->B3SOIDDEgPtr) += 0.0; + *(here->B3SOIDDEdpPtr) += 0.0; + *(here->B3SOIDDEspPtr) += 0.0; + *(here->B3SOIDDGePtr) -= 0.0; + *(here->B3SOIDDDPePtr) += Gme + gddpe; + *(here->B3SOIDDSPePtr) += gsspe - Gme; + + *(here->B3SOIDDEePtr) += 0.0; + + *(here->B3SOIDDDPgPtr) += Gm + gddpg; + *(here->B3SOIDDDPdpPtr) += gdpr + gds + gddpdp + RevSum ; + *(here->B3SOIDDDPspPtr) -= gds + FwdSum - gddpsp; + *(here->B3SOIDDDPdPtr) -= gdpr; + + *(here->B3SOIDDSPgPtr) -= Gm - gsspg; + *(here->B3SOIDDSPdpPtr) -= gds + RevSum - gsspdp; + *(here->B3SOIDDSPspPtr) += gspr + gds + FwdSum + gsspsp; + *(here->B3SOIDDSPsPtr) -= gspr; + + *(here->B3SOIDDBePtr) += gbbe; + *(here->B3SOIDDBgPtr) += gbbg; + *(here->B3SOIDDBdpPtr) += gbbdp; + *(here->B3SOIDDBspPtr) += gbbsp; + *(here->B3SOIDDBbPtr) += gbbb; + *(here->B3SOIDDEbPtr) += 0.0; + *(here->B3SOIDDSPbPtr) -= Gmbs - gsspb; + *(here->B3SOIDDDPbPtr) -= (-gddpb - Gmbs); + + if (selfheat) + { + *(here->B3SOIDDDPtempPtr) += GmT + gddpT; + *(here->B3SOIDDSPtempPtr) += -GmT + gsspT; + *(here->B3SOIDDBtempPtr) += gbbT; + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDPtempPtr) += gppT); + } + + *(here->B3SOIDDTemptempPtr) += gTtt + 1/here->pParam->B3SOIDDrth; + *(here->B3SOIDDTempgPtr) += gTtg; + *(here->B3SOIDDTempbPtr) += gTtb; + *(here->B3SOIDDTempePtr) += gTte; + *(here->B3SOIDDTempdpPtr) += gTtdp; + *(here->B3SOIDDTempspPtr) += gTtsp; + } + +if (here->B3SOIDDdebugMod > 3) +{ + fprintf(fpdebug, "Static condunctance...\n"); + fprintf(fpdebug, "Gg=%.5e; Gdp=%.5e; Gsp=%.5e;\nGb=%.5e; Ge=%.5e\n", + *(here->B3SOIDDGgPtr), *(here->B3SOIDDGdpPtr), + *(here->B3SOIDDGspPtr), *(here->B3SOIDDGbPtr), + *(here->B3SOIDDGePtr)); + fprintf(fpdebug, "DPg=%.5e; DPdp=%.5e; DPsp=%.5e;\nDPb=%.5e; DPe=%.5e\n", + *(here->B3SOIDDDPgPtr), *(here->B3SOIDDDPdpPtr), + *(here->B3SOIDDDPspPtr), *(here->B3SOIDDDPbPtr), + *(here->B3SOIDDDPePtr)); + fprintf(fpdebug, "SPg=%.5e; SPdp=%.5e; SPsp=%.5e;\nSPb=%.5e; SPe=%.5e\n", + *(here->B3SOIDDSPgPtr), *(here->B3SOIDDSPdpPtr), + *(here->B3SOIDDSPspPtr), *(here->B3SOIDDSPbPtr), + *(here->B3SOIDDSPePtr)); + fprintf(fpdebug, "Bg=%.5e; Bdp=%.5e; Bsp=%.5e;\nBb=%.5e; Be=%.5e\n", +gbbg, gbbdp, gbbsp, gbbb, gbbe); +} + + *(here->B3SOIDDDdPtr) += gdpr; + *(here->B3SOIDDDdpPtr) -= gdpr; + *(here->B3SOIDDSsPtr) += gspr; + *(here->B3SOIDDSspPtr) -= gspr; + + + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDBpPtr) -= gppp); + (*(here->B3SOIDDPbPtr) += gppb); + (*(here->B3SOIDDPpPtr) += gppp); + (*(here->B3SOIDDPgPtr) += gppg); + (*(here->B3SOIDDPdpPtr) += gppdp); + (*(here->B3SOIDDPspPtr) += gppsp); + (*(here->B3SOIDDPePtr) += gppe); + } + if (here->B3SOIDDdebugMod > 1) + { + *(here->B3SOIDDVbsPtr) += 1; + *(here->B3SOIDDIdsPtr) += 1; + *(here->B3SOIDDIcPtr) += 1; + *(here->B3SOIDDIbsPtr) += 1; + *(here->B3SOIDDIbdPtr) += 1; + *(here->B3SOIDDIiiPtr) += 1; + *(here->B3SOIDDIgidlPtr) += 1; + *(here->B3SOIDDItunPtr) += 1; + *(here->B3SOIDDIbpPtr) += 1; + *(here->B3SOIDDAbeffPtr) += 1; + *(here->B3SOIDDVbs0effPtr) += 1; + *(here->B3SOIDDVbseffPtr) += 1; + *(here->B3SOIDDXcPtr) += 1; + *(here->B3SOIDDCbgPtr) += 1; + *(here->B3SOIDDCbbPtr) += 1; + *(here->B3SOIDDCbdPtr) += 1; + *(here->B3SOIDDqbPtr) += 1; + *(here->B3SOIDDQbfPtr) += 1; + *(here->B3SOIDDQjsPtr) += 1; + *(here->B3SOIDDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIDDGmPtr) += 1; + *(here->B3SOIDDGmbsPtr) += 1; + *(here->B3SOIDDGdsPtr) += 1; + *(here->B3SOIDDGmePtr) += 1; + *(here->B3SOIDDVbs0teffPtr) += 1; + *(here->B3SOIDDVgsteffPtr) += 1; + *(here->B3SOIDDCbePtr) += 1; + *(here->B3SOIDDVthPtr) += 1; + *(here->B3SOIDDXcsatPtr) += 1; + *(here->B3SOIDDVdscvPtr) += 1; + *(here->B3SOIDDVcscvPtr) += 1; + *(here->B3SOIDDQaccPtr) += 1; + *(here->B3SOIDDQsub0Ptr) += 1; + *(here->B3SOIDDQsubs1Ptr) += 1; + *(here->B3SOIDDQsubs2Ptr) += 1; + *(here->B3SOIDDqgPtr) += 1; + *(here->B3SOIDDqdPtr) += 1; + *(here->B3SOIDDqePtr) += 1; + *(here->B3SOIDDDum1Ptr) += 1; + *(here->B3SOIDDDum2Ptr) += 1; + *(here->B3SOIDDDum3Ptr) += 1; + *(here->B3SOIDDDum4Ptr) += 1; + *(here->B3SOIDDDum5Ptr) += 1; + } + + if (here->B3SOIDDdebugMod > 2) + fclose(fpdebug); + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddask.c b/src/spicelib/devices/bsim3soi_dd/b3soiddask.c new file mode 100644 index 000000000..b3bd25047 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddask.c @@ -0,0 +1,215 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiask.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDask(ckt,inst,which,value,select) +CKTcircuit *ckt; +GENinstance *inst; +int which; +IFvalue *value; +IFvalue *select; +{ +B3SOIDDinstance *here = (B3SOIDDinstance*)inst; + + switch(which) + { case B3SOIDD_L: + value->rValue = here->B3SOIDDl; + return(OK); + case B3SOIDD_W: + value->rValue = here->B3SOIDDw; + return(OK); + case B3SOIDD_AS: + value->rValue = here->B3SOIDDsourceArea; + return(OK); + case B3SOIDD_AD: + value->rValue = here->B3SOIDDdrainArea; + return(OK); + case B3SOIDD_PS: + value->rValue = here->B3SOIDDsourcePerimeter; + return(OK); + case B3SOIDD_PD: + value->rValue = here->B3SOIDDdrainPerimeter; + return(OK); + case B3SOIDD_NRS: + value->rValue = here->B3SOIDDsourceSquares; + return(OK); + case B3SOIDD_NRD: + value->rValue = here->B3SOIDDdrainSquares; + return(OK); + case B3SOIDD_OFF: + value->rValue = here->B3SOIDDoff; + return(OK); + case B3SOIDD_BJTOFF: + value->iValue = here->B3SOIDDbjtoff; + return(OK); + case B3SOIDD_RTH0: + value->rValue = here->B3SOIDDrth0; + return(OK); + case B3SOIDD_CTH0: + value->rValue = here->B3SOIDDcth0; + return(OK); + case B3SOIDD_NRB: + value->rValue = here->B3SOIDDbodySquares; + return(OK); + case B3SOIDD_IC_VBS: + value->rValue = here->B3SOIDDicVBS; + return(OK); + case B3SOIDD_IC_VDS: + value->rValue = here->B3SOIDDicVDS; + return(OK); + case B3SOIDD_IC_VGS: + value->rValue = here->B3SOIDDicVGS; + return(OK); + case B3SOIDD_IC_VES: + value->rValue = here->B3SOIDDicVES; + return(OK); + case B3SOIDD_IC_VPS: + value->rValue = here->B3SOIDDicVPS; + return(OK); + case B3SOIDD_DNODE: + value->iValue = here->B3SOIDDdNode; + return(OK); + case B3SOIDD_GNODE: + value->iValue = here->B3SOIDDgNode; + return(OK); + case B3SOIDD_SNODE: + value->iValue = here->B3SOIDDsNode; + return(OK); + case B3SOIDD_BNODE: + value->iValue = here->B3SOIDDbNode; + return(OK); + case B3SOIDD_ENODE: + value->iValue = here->B3SOIDDeNode; + return(OK); + case B3SOIDD_DNODEPRIME: + value->iValue = here->B3SOIDDdNodePrime; + return(OK); + case B3SOIDD_SNODEPRIME: + value->iValue = here->B3SOIDDsNodePrime; + return(OK); + case B3SOIDD_SOURCECONDUCT: + value->rValue = here->B3SOIDDsourceConductance; + return(OK); + case B3SOIDD_DRAINCONDUCT: + value->rValue = here->B3SOIDDdrainConductance; + return(OK); + case B3SOIDD_VBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvbd); + return(OK); + case B3SOIDD_VBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvbs); + return(OK); + case B3SOIDD_VGS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvgs); + return(OK); + case B3SOIDD_VES: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDves); + return(OK); + case B3SOIDD_VDS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDvds); + return(OK); + case B3SOIDD_CD: + value->rValue = here->B3SOIDDcd; + return(OK); + case B3SOIDD_CBS: + value->rValue = here->B3SOIDDcjs; + return(OK); + case B3SOIDD_CBD: + value->rValue = here->B3SOIDDcjd; + return(OK); + case B3SOIDD_GM: + value->rValue = here->B3SOIDDgm; + return(OK); + case B3SOIDD_GMID: + value->rValue = here->B3SOIDDgm/here->B3SOIDDcd; + return(OK); + case B3SOIDD_GDS: + value->rValue = here->B3SOIDDgds; + return(OK); + case B3SOIDD_GMBS: + value->rValue = here->B3SOIDDgmbs; + return(OK); + case B3SOIDD_GBD: + value->rValue = here->B3SOIDDgjdb; + return(OK); + case B3SOIDD_GBS: + value->rValue = here->B3SOIDDgjsb; + return(OK); + case B3SOIDD_QB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqb); + return(OK); + case B3SOIDD_CQB: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqb); + return(OK); + case B3SOIDD_QG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqg); + return(OK); + case B3SOIDD_CQG: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqg); + return(OK); + case B3SOIDD_QD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqd); + return(OK); + case B3SOIDD_CQD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDcqd); + return(OK); + case B3SOIDD_CGG: + value->rValue = here->B3SOIDDcggb; + return(OK); + case B3SOIDD_CGD: + value->rValue = here->B3SOIDDcgdb; + return(OK); + case B3SOIDD_CGS: + value->rValue = here->B3SOIDDcgsb; + return(OK); + case B3SOIDD_CDG: + value->rValue = here->B3SOIDDcdgb; + return(OK); + case B3SOIDD_CDD: + value->rValue = here->B3SOIDDcddb; + return(OK); + case B3SOIDD_CDS: + value->rValue = here->B3SOIDDcdsb; + return(OK); + case B3SOIDD_CBG: + value->rValue = here->B3SOIDDcbgb; + return(OK); + case B3SOIDD_CBDB: + value->rValue = here->B3SOIDDcbdb; + return(OK); + case B3SOIDD_CBSB: + value->rValue = here->B3SOIDDcbsb; + return(OK); + case B3SOIDD_VON: + value->rValue = here->B3SOIDDvon; + return(OK); + case B3SOIDD_VDSAT: + value->rValue = here->B3SOIDDvdsat; + return(OK); + case B3SOIDD_QBS: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqbs); + return(OK); + case B3SOIDD_QBD: + value->rValue = *(ckt->CKTstate0 + here->B3SOIDDqbd); + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c b/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c new file mode 100644 index 000000000..74c5b7099 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddcheck.c @@ -0,0 +1,504 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddcheck.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +B3SOIDDcheckModel(model, here, ckt) +register B3SOIDDmodel *model; +register B3SOIDDinstance *here; +CKTcircuit *ckt; +{ +struct b3soiddSizeDependParam *pParam; +int Fatal_Flag = 0; +FILE *fplog; + + if ((fplog = fopen("b3soiddv1check.log", "w")) != NULL) + { pParam = here->pParam; + fprintf(fplog, "B3SOIDDV3 Parameter Check\n"); + fprintf(fplog, "Model = %s\n", model->B3SOIDDmodName); + fprintf(fplog, "W = %g, L = %g\n", here->B3SOIDDw, here->B3SOIDDl); + + + if (pParam->B3SOIDDnlx < -pParam->B3SOIDDleff) + { fprintf(fplog, "Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIDDnlx); + printf("Fatal: Nlx = %g is less than -Leff.\n", + pParam->B3SOIDDnlx); + Fatal_Flag = 1; + } + + if (model->B3SOIDDtox <= 0.0) + { fprintf(fplog, "Fatal: Tox = %g is not positive.\n", + model->B3SOIDDtox); + printf("Fatal: Tox = %g is not positive.\n", model->B3SOIDDtox); + Fatal_Flag = 1; + } + + if (model->B3SOIDDtbox <= 0.0) + { fprintf(fplog, "Fatal: Tbox = %g is not positive.\n", + model->B3SOIDDtbox); + printf("Fatal: Tbox = %g is not positive.\n", model->B3SOIDDtbox); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDnpeak <= 0.0) + { fprintf(fplog, "Fatal: Nch = %g is not positive.\n", + pParam->B3SOIDDnpeak); + printf("Fatal: Nch = %g is not positive.\n", + pParam->B3SOIDDnpeak); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDngate < 0.0) + { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", + pParam->B3SOIDDngate); + printf("Fatal: Ngate = %g Ngate is not positive.\n", + pParam->B3SOIDDngate); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDngate > 1.e25) + { fprintf(fplog, "Fatal: Ngate = %g is too high.\n", + pParam->B3SOIDDngate); + printf("Fatal: Ngate = %g Ngate is too high\n", + pParam->B3SOIDDngate); + Fatal_Flag = 1; + } + + if (model->B3SOIDDdvbd1 < 0.0) + { fprintf(fplog, "Fatal: Dvbd1 = %g is negative.\n", + model->B3SOIDDdvbd1); + printf("Fatal: Dvbd1 = %g is negative.\n", model->B3SOIDDdvbd1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdvt1 < 0.0) + { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", + pParam->B3SOIDDdvt1); + printf("Fatal: Dvt1 = %g is negative.\n", pParam->B3SOIDDdvt1); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdvt1w < 0.0) + { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", + pParam->B3SOIDDdvt1w); + printf("Fatal: Dvt1w = %g is negative.\n", pParam->B3SOIDDdvt1w); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDw0 == -pParam->B3SOIDDweff) + { fprintf(fplog, "Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + printf("Fatal: (W0 + Weff) = 0 cauing divided-by-zero.\n"); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdsub < 0.0) + { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->B3SOIDDdsub); + printf("Fatal: Dsub = %g is negative.\n", pParam->B3SOIDDdsub); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDb1 == -pParam->B3SOIDDweff) + { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; + } + if (pParam->B3SOIDDu0temp <= 0.0) + { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->B3SOIDDu0temp); + printf("Fatal: u0 at current temperature = %g is not positive.\n", + pParam->B3SOIDDu0temp); + Fatal_Flag = 1; + } + +/* Check delta parameter */ + if (pParam->B3SOIDDdelta < 0.0) + { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", + pParam->B3SOIDDdelta); + printf("Fatal: Delta = %g is less than zero.\n", pParam->B3SOIDDdelta); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDvsattemp <= 0.0) + { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->B3SOIDDvsattemp); + printf("Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->B3SOIDDvsattemp); + Fatal_Flag = 1; + } +/* Check Rout parameters */ + if (pParam->B3SOIDDpclm <= 0.0) + { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->B3SOIDDpclm); + printf("Fatal: Pclm = %g is not positive.\n", pParam->B3SOIDDpclm); + Fatal_Flag = 1; + } + + if (pParam->B3SOIDDdrout < 0.0) + { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->B3SOIDDdrout); + printf("Fatal: Drout = %g is negative.\n", pParam->B3SOIDDdrout); + Fatal_Flag = 1; + } + if ( model->B3SOIDDunitLengthGateSidewallJctCap > 0.0) + { + if (here->B3SOIDDdrainPerimeter < pParam->B3SOIDDweff) + { fprintf(fplog, "Warning: Pd = %g is less than W.\n", + here->B3SOIDDdrainPerimeter); + printf("Warning: Pd = %g is less than W.\n", + here->B3SOIDDdrainPerimeter); + here->B3SOIDDdrainPerimeter =pParam->B3SOIDDweff; + } + if (here->B3SOIDDsourcePerimeter < pParam->B3SOIDDweff) + { fprintf(fplog, "Warning: Ps = %g is less than W.\n", + here->B3SOIDDsourcePerimeter); + printf("Warning: Ps = %g is less than W.\n", + here->B3SOIDDsourcePerimeter); + here->B3SOIDDsourcePerimeter =pParam->B3SOIDDweff; + } + } +/* Check capacitance parameters */ + if (pParam->B3SOIDDclc < 0.0) + { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->B3SOIDDclc); + printf("Fatal: Clc = %g is negative.\n", pParam->B3SOIDDclc); + Fatal_Flag = 1; + } + if (model->B3SOIDDparamChk ==1) + { +/* Check L and W parameters */ + if (pParam->B3SOIDDleff <= 5.0e-8) + { fprintf(fplog, "Warning: Leff = %g may be too small.\n", + pParam->B3SOIDDleff); + printf("Warning: Leff = %g may be too small.\n", + pParam->B3SOIDDleff); + } + + if (pParam->B3SOIDDleffCV <= 5.0e-8) + { fprintf(fplog, "Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIDDleffCV); + printf("Warning: Leff for CV = %g may be too small.\n", + pParam->B3SOIDDleffCV); + } + + if (pParam->B3SOIDDweff <= 1.0e-7) + { fprintf(fplog, "Warning: Weff = %g may be too small.\n", + pParam->B3SOIDDweff); + printf("Warning: Weff = %g may be too small.\n", + pParam->B3SOIDDweff); + } + + if (pParam->B3SOIDDweffCV <= 1.0e-7) + { fprintf(fplog, "Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIDDweffCV); + printf("Warning: Weff for CV = %g may be too small.\n", + pParam->B3SOIDDweffCV); + } + +/* Check threshold voltage parameters */ + if (pParam->B3SOIDDnlx < 0.0) + { fprintf(fplog, "Warning: Nlx = %g is negative.\n", pParam->B3SOIDDnlx); + printf("Warning: Nlx = %g is negative.\n", pParam->B3SOIDDnlx); + } + if (model->B3SOIDDtox < 1.0e-9) + { fprintf(fplog, "Warning: Tox = %g is less than 10A.\n", + model->B3SOIDDtox); + printf("Warning: Tox = %g is less than 10A.\n", model->B3SOIDDtox); + } + + if (pParam->B3SOIDDnpeak <= 1.0e15) + { fprintf(fplog, "Warning: Nch = %g may be too small.\n", + pParam->B3SOIDDnpeak); + printf("Warning: Nch = %g may be too small.\n", + pParam->B3SOIDDnpeak); + } + else if (pParam->B3SOIDDnpeak >= 1.0e21) + { fprintf(fplog, "Warning: Nch = %g may be too large.\n", + pParam->B3SOIDDnpeak); + printf("Warning: Nch = %g may be too large.\n", + pParam->B3SOIDDnpeak); + } + + if (fabs(pParam->B3SOIDDnsub) >= 1.0e21) + { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", + pParam->B3SOIDDnsub); + printf("Warning: Nsub = %g may be too large.\n", + pParam->B3SOIDDnsub); + } + + if ((pParam->B3SOIDDngate > 0.0) && + (pParam->B3SOIDDngate <= 1.e18)) + { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIDDngate); + printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->B3SOIDDngate); + } + + if (model->B3SOIDDdvbd0 < 0.0) + { fprintf(fplog, "Warning: Dvbd0 = %g is negative.\n", + model->B3SOIDDdvbd0); + printf("Warning: Dvbd0 = %g is negative.\n", model->B3SOIDDdvbd0); + } + + if (pParam->B3SOIDDdvt0 < 0.0) + { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", + pParam->B3SOIDDdvt0); + printf("Warning: Dvt0 = %g is negative.\n", pParam->B3SOIDDdvt0); + } + + if (fabs(1.0e-6 / (pParam->B3SOIDDw0 + pParam->B3SOIDDweff)) > 10.0) + { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf("Warning: (W0 + Weff) may be too small.\n"); + } + +/* Check subthreshold parameters */ + if (pParam->B3SOIDDnfactor < 0.0) + { fprintf(fplog, "Warning: Nfactor = %g is negative.\n", + pParam->B3SOIDDnfactor); + printf("Warning: Nfactor = %g is negative.\n", pParam->B3SOIDDnfactor); + } + if (model->B3SOIDDkb3 < 0.0) + { fprintf(fplog, "Warning: Kb3 = %g is negative.\n", + model->B3SOIDDkb3); + printf("Warning: Kb3 = %g is negative.\n", model->B3SOIDDkb3); + } + + if (pParam->B3SOIDDcdsc < 0.0) + { fprintf(fplog, "Warning: Cdsc = %g is negative.\n", + pParam->B3SOIDDcdsc); + printf("Warning: Cdsc = %g is negative.\n", pParam->B3SOIDDcdsc); + } + if (pParam->B3SOIDDcdscd < 0.0) + { fprintf(fplog, "Warning: Cdscd = %g is negative.\n", + pParam->B3SOIDDcdscd); + printf("Warning: Cdscd = %g is negative.\n", pParam->B3SOIDDcdscd); + } +/* Check DIBL parameters */ + if (pParam->B3SOIDDeta0 < 0.0) + { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", + pParam->B3SOIDDeta0); + printf("Warning: Eta0 = %g is negative.\n", pParam->B3SOIDDeta0); + } + +/* Check Abulk parameters */ + if (fabs(1.0e-6 / (pParam->B3SOIDDb1 + pParam->B3SOIDDweff)) > 10.0) + { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf("Warning: (B1 + Weff) may be too small.\n"); + } + + if (model->B3SOIDDadice0 > 1.0) + { fprintf(fplog, "Warning: Adice0 = %g should be smaller than 1.\n", + model->B3SOIDDadice0); + printf("Warning: Adice0 = %g should be smaller than 1.\n", model->B3SOIDDadice0); + } + + if (model->B3SOIDDabp < 0.2) + { fprintf(fplog, "Warning: Abp = %g is too small.\n", + model->B3SOIDDabp); + printf("Warning: Abp = %g is too small.\n", model->B3SOIDDabp); + } + + if ((model->B3SOIDDmxc < -1.0) || (model->B3SOIDDmxc > 1.0)) + { fprintf(fplog, "Warning: Mxc = %g should be within (-1, 1).\n", + model->B3SOIDDmxc); + printf("Warning: Mxc = %g should be within (-1, 1).\n", model->B3SOIDDmxc); + } + +/* Check Saturation parameters */ + if (pParam->B3SOIDDa2 < 0.01) + { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->B3SOIDDa2); + printf("Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->B3SOIDDa2); + pParam->B3SOIDDa2 = 0.01; + } + else if (pParam->B3SOIDDa2 > 1.0) + { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIDDa2); + printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->B3SOIDDa2); + pParam->B3SOIDDa2 = 1.0; + pParam->B3SOIDDa1 = 0.0; + + } + + if (pParam->B3SOIDDrdsw < 0.0) + { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIDDrdsw); + printf("Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->B3SOIDDrdsw); + pParam->B3SOIDDrdsw = 0.0; + pParam->B3SOIDDrds0 = 0.0; + } + else if ((pParam->B3SOIDDrds0 > 0.0) && (pParam->B3SOIDDrds0 < 0.001)) + { fprintf(fplog, "Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIDDrds0); + printf("Warning: Rds at current temperature = %g is less than 0.001 ohm. Set to zero.\n", + pParam->B3SOIDDrds0); + pParam->B3SOIDDrds0 = 0.0; + } + if (pParam->B3SOIDDvsattemp < 1.0e3) + { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIDDvsattemp); + printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->B3SOIDDvsattemp); + } + + if (pParam->B3SOIDDpdibl1 < 0.0) + { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", + pParam->B3SOIDDpdibl1); + printf("Warning: Pdibl1 = %g is negative.\n", pParam->B3SOIDDpdibl1); + } + if (pParam->B3SOIDDpdibl2 < 0.0) + { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", + pParam->B3SOIDDpdibl2); + printf("Warning: Pdibl2 = %g is negative.\n", pParam->B3SOIDDpdibl2); + } +/* Check overlap capacitance parameters */ + if (model->B3SOIDDcgdo < 0.0) + { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIDDcgdo); + printf("Warning: cgdo = %g is negative. Set to zero.\n", model->B3SOIDDcgdo); + model->B3SOIDDcgdo = 0.0; + } + if (model->B3SOIDDcgso < 0.0) + { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIDDcgso); + printf("Warning: cgso = %g is negative. Set to zero.\n", model->B3SOIDDcgso); + model->B3SOIDDcgso = 0.0; + } + if (model->B3SOIDDcgeo < 0.0) + { fprintf(fplog, "Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIDDcgeo); + printf("Warning: cgeo = %g is negative. Set to zero.\n", model->B3SOIDDcgeo); + model->B3SOIDDcgeo = 0.0; + } + + if (model->B3SOIDDntun < 0.0) + { fprintf(fplog, "Warning: Ntun = %g is negative.\n", + model->B3SOIDDntun); + printf("Warning: Ntun = %g is negative.\n", model->B3SOIDDntun); + } + + if (model->B3SOIDDndiode < 0.0) + { fprintf(fplog, "Warning: Ndiode = %g is negative.\n", + model->B3SOIDDndiode); + printf("Warning: Ndiode = %g is negative.\n", model->B3SOIDDndiode); + } + + if (model->B3SOIDDisbjt < 0.0) + { fprintf(fplog, "Warning: Isbjt = %g is negative.\n", + model->B3SOIDDisbjt); + printf("Warning: Isbjt = %g is negative.\n", model->B3SOIDDisbjt); + } + + if (model->B3SOIDDisdif < 0.0) + { fprintf(fplog, "Warning: Isdif = %g is negative.\n", + model->B3SOIDDisdif); + printf("Warning: Isdif = %g is negative.\n", model->B3SOIDDisdif); + } + + if (model->B3SOIDDisrec < 0.0) + { fprintf(fplog, "Warning: Isrec = %g is negative.\n", + model->B3SOIDDisrec); + printf("Warning: Isrec = %g is negative.\n", model->B3SOIDDisrec); + } + + if (model->B3SOIDDistun < 0.0) + { fprintf(fplog, "Warning: Istun = %g is negative.\n", + model->B3SOIDDistun); + printf("Warning: Istun = %g is negative.\n", model->B3SOIDDistun); + } + + if (model->B3SOIDDedl < 0.0) + { fprintf(fplog, "Warning: Edl = %g is negative.\n", + model->B3SOIDDedl); + printf("Warning: Edl = %g is negative.\n", model->B3SOIDDedl); + } + + if (model->B3SOIDDkbjt1 < 0.0) + { fprintf(fplog, "Warning: Kbjt1 = %g is negative.\n", + model->B3SOIDDkbjt1); + printf("Warning: kbjt1 = %g is negative.\n", model->B3SOIDDkbjt1); + } + + if (model->B3SOIDDtt < 0.0) + { fprintf(fplog, "Warning: Tt = %g is negative.\n", + model->B3SOIDDtt); + printf("Warning: Tt = %g is negative.\n", model->B3SOIDDtt); + } + + if (model->B3SOIDDcsdmin < 0.0) + { fprintf(fplog, "Warning: Csdmin = %g is negative.\n", + model->B3SOIDDcsdmin); + printf("Warning: Csdmin = %g is negative.\n", model->B3SOIDDcsdmin); + } + + if (model->B3SOIDDcsdesw < 0.0) + { fprintf(fplog, "Warning: Csdesw = %g is negative.\n", + model->B3SOIDDcsdesw); + printf("Warning: Csdesw = %g is negative.\n", model->B3SOIDDcsdesw); + } + + if ((model->B3SOIDDasd < 0.0) || (model->B3SOIDDmxc > 1.0)) + { fprintf(fplog, "Warning: Asd = %g should be within (0, 1).\n", + model->B3SOIDDasd); + printf("Warning: Asd = %g should be within (0, 1).\n", model->B3SOIDDasd); + } + + if (model->B3SOIDDrth0 < 0.0) + { fprintf(fplog, "Warning: Rth0 = %g is negative.\n", + model->B3SOIDDrth0); + printf("Warning: Rth0 = %g is negative.\n", model->B3SOIDDrth0); + } + + if (model->B3SOIDDcth0 < 0.0) + { fprintf(fplog, "Warning: Cth0 = %g is negative.\n", + model->B3SOIDDcth0); + printf("Warning: Cth0 = %g is negative.\n", model->B3SOIDDcth0); + } + + if (model->B3SOIDDrbody < 0.0) + { fprintf(fplog, "Warning: Rbody = %g is negative.\n", + model->B3SOIDDrbody); + printf("Warning: Rbody = %g is negative.\n", model->B3SOIDDrbody); + } + + if (model->B3SOIDDrbsh < 0.0) + { fprintf(fplog, "Warning: Rbsh = %g is negative.\n", + model->B3SOIDDrbsh); + printf("Warning: Rbsh = %g is negative.\n", model->B3SOIDDrbsh); + } + + if (model->B3SOIDDxj > model->B3SOIDDtsi) + { fprintf(fplog, "Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIDDxj, model->B3SOIDDtsi); + printf("Warning: Xj = %g is thicker than Tsi = %g.\n", + model->B3SOIDDxj, model->B3SOIDDtsi); + } + + if (model->B3SOIDDcapMod < 2) + { fprintf(fplog, "Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + printf("Warning: Warning: capMod < 2 is not supported by BSIM3SOI.\n"); + } + + if (model->B3SOIDDcii > 2.0) + { fprintf(fplog, "Warning: Cii = %g is larger than 2.0.\n", model->B3SOIDDcii); + printf("Warning: Cii = %g is larger than 2.0.\n", model->B3SOIDDcii); + } + + if (model->B3SOIDDdii > 1.5) + { fprintf(fplog, "Warning: Dii = %g is larger than 1.5.\n", model->B3SOIDDcii); + printf("Warning: Dii = %g is too larger than 1.5.\n", model->B3SOIDDcii); + } + + }/* loop for the parameter check for warning messages */ + fclose(fplog); + } + else + { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); + } + + return(Fatal_Flag); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c b/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c new file mode 100644 index 000000000..7fc6e818c --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddcvtest.c @@ -0,0 +1,90 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddcvtest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDconvTest(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; +double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; + + /* loop through all the B3SOIDD device models */ + for (; model != NULL; model = model->B3SOIDDnextModel) + { /* loop through all the instances of the model */ + for (here = model->B3SOIDDinstances; here != NULL ; + here=here->B3SOIDDnextInstance) + { vbs = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDbNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vgs = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDgNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vds = model->B3SOIDDtype + * (*(ckt->CKTrhsOld+here->B3SOIDDdNodePrime) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + vbd = vbs - vds; + vgd = vgs - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIDDvgs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIDDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIDDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIDDvgs); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvgd = vgd-vgdo; + + cd = here->B3SOIDDcd; + if (here->B3SOIDDmode >= 0) + { cdhat = cd - here->B3SOIDDgjdb * delvbd + + here->B3SOIDDgmbs * delvbs + here->B3SOIDDgm * delvgs + + here->B3SOIDDgds * delvds; + } + else + { cdhat = cd - (here->B3SOIDDgjdb - here->B3SOIDDgmbs) * delvbd + - here->B3SOIDDgm * delvgd + here->B3SOIDDgds * delvds; + } + + /* + * check convergence + */ + if ((here->B3SOIDDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd)) + + ckt->CKTabstol; + if (fabs(cdhat - cd) >= tol) + { ckt->CKTnoncon++; + return(OK); + } + cbs = here->B3SOIDDcjs; + cbd = here->B3SOIDDcjd; + cbhat = cbs + cbd + here->B3SOIDDgjdb * delvbd + + here->B3SOIDDgjsb * delvbs; + tol = ckt->CKTreltol * MAX(fabs(cbhat), fabs(cbs + cbd)) + + ckt->CKTabstol; + if (fabs(cbhat - (cbs + cbd)) > tol) + { ckt->CKTnoncon++; + return(OK); + } + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddef.h b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h new file mode 100644 index 000000000..3dcc46c6b --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h @@ -0,0 +1,1991 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soidddef.h +**********/ + +#ifndef B3SOIDD +#define B3SOIDD + +#define SOICODE +/* #define BULKCODE */ + +#include "ifsim.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "noisedef.h" + +typedef struct sB3SOIDDinstance +{ + struct sB3SOIDDmodel *B3SOIDDmodPtr; + struct sB3SOIDDinstance *B3SOIDDnextInstance; + IFuid B3SOIDDname; + int B3SOIDDstates; /* index into state table for this device */ + int B3SOIFDowner; + int B3SOIDDdNode; + int B3SOIDDgNode; + int B3SOIDDsNode; + int B3SOIDDeNode; + int B3SOIDDbNode; + int B3SOIDDtempNode; + int B3SOIDDpNode; + int B3SOIDDdNodePrime; + int B3SOIDDsNodePrime; + + int B3SOIDDvbsNode; + /* for Debug */ + int B3SOIDDidsNode; + int B3SOIDDicNode; + int B3SOIDDibsNode; + int B3SOIDDibdNode; + int B3SOIDDiiiNode; + int B3SOIDDigidlNode; + int B3SOIDDitunNode; + int B3SOIDDibpNode; + int B3SOIDDabeffNode; + int B3SOIDDvbs0effNode; + int B3SOIDDvbseffNode; + int B3SOIDDxcNode; + int B3SOIDDcbbNode; + int B3SOIDDcbdNode; + int B3SOIDDcbeNode; + int B3SOIDDcbgNode; + int B3SOIDDqbNode; + int B3SOIDDqbfNode; + int B3SOIDDqjsNode; + int B3SOIDDqjdNode; + +/* clean up last */ + int B3SOIDDgmNode; + int B3SOIDDgmbsNode; + int B3SOIDDgdsNode; + int B3SOIDDgmeNode; + int B3SOIDDqgNode; + int B3SOIDDqdNode; + int B3SOIDDqeNode; + int B3SOIDDiterations; + int B3SOIDDvbs0teffNode; + int B3SOIDDvthNode; + int B3SOIDDvgsteffNode; + int B3SOIDDxcsatNode; + int B3SOIDDqaccNode; + int B3SOIDDqsub0Node; + int B3SOIDDqsubs1Node; + int B3SOIDDqsubs2Node; + int B3SOIDDvcscvNode; + int B3SOIDDvdscvNode; + int B3SOIDDdum1Node; + int B3SOIDDdum2Node; + int B3SOIDDdum3Node; + int B3SOIDDdum4Node; + int B3SOIDDdum5Node; +/* end clean up last */ + + double B3SOIDDphi; + double B3SOIDDvtm; + double B3SOIDDni; + double B3SOIDDueff; + double B3SOIDDthetavth; + double B3SOIDDvon; + double B3SOIDDvbsdio; + double B3SOIDDvdsat; + double B3SOIDDcgdo; + double B3SOIDDcgso; + double B3SOIDDcgeo; + + double B3SOIDDids; + double B3SOIDDic; + double B3SOIDDibs; + double B3SOIDDibd; + double B3SOIDDiii; + double B3SOIDDigidl; + double B3SOIDDitun; + double B3SOIDDibp; + double B3SOIDDabeff; + double B3SOIDDvbs0eff; + double B3SOIDDvbseff; + double B3SOIDDxc; + double B3SOIDDcbg; + double B3SOIDDcbb; + double B3SOIDDcbd; + double B3SOIDDqb; + double B3SOIDDqbf; + double B3SOIDDqjs; + double B3SOIDDqjd; + double B3SOIDDminIsub; + int B3SOIDDfloat; + +/* clean up last */ + double B3SOIDDdum1; + double B3SOIDDdum2; + double B3SOIDDdum3; + double B3SOIDDdum4; + double B3SOIDDdum5; +/* end clean up last */ + + double B3SOIDDl; + double B3SOIDDw; + double B3SOIDDdrainArea; + double B3SOIDDsourceArea; + double B3SOIDDdrainSquares; + double B3SOIDDsourceSquares; + double B3SOIDDdrainPerimeter; + double B3SOIDDsourcePerimeter; + double B3SOIDDsourceConductance; + double B3SOIDDdrainConductance; + + double B3SOIDDicVBS; + double B3SOIDDicVDS; + double B3SOIDDicVGS; + double B3SOIDDicVES; + double B3SOIDDicVPS; + int B3SOIDDbjtoff; + int B3SOIDDbodyMod; + int B3SOIDDdebugMod; + double B3SOIDDrth0; + double B3SOIDDcth0; + double B3SOIDDbodySquares; + double B3SOIDDrbodyext; + + double B3SOIDDcsbox; + double B3SOIDDcdbox; + double B3SOIDDcsmin; + double B3SOIDDcdmin; + double B3SOIDDst4; + double B3SOIDDdt4; + + int B3SOIDDoff; + int B3SOIDDmode; + + /* OP point */ + double B3SOIDDqinv; + double B3SOIDDcd; + double B3SOIDDcjs; + double B3SOIDDcjd; + double B3SOIDDcbody; + double B3SOIDDcbodcon; + double B3SOIDDcth; + double B3SOIDDcsubstrate; + + double B3SOIDDgm; + double B3SOIDDgme; + double B3SOIDDcb; + double B3SOIDDcdrain; + double B3SOIDDgds; + double B3SOIDDgmbs; + double B3SOIDDgmT; + + double B3SOIDDgbbs; + double B3SOIDDgbgs; + double B3SOIDDgbds; + double B3SOIDDgbes; + double B3SOIDDgbps; + double B3SOIDDgbT; + + double B3SOIDDgjsd; + double B3SOIDDgjsb; + double B3SOIDDgjsg; + double B3SOIDDgjsT; + + double B3SOIDDgjdb; + double B3SOIDDgjdd; + double B3SOIDDgjdg; + double B3SOIDDgjde; + double B3SOIDDgjdT; + + double B3SOIDDgbpbs; + double B3SOIDDgbpgs; + double B3SOIDDgbpds; + double B3SOIDDgbpes; + double B3SOIDDgbpps; + double B3SOIDDgbpT; + + double B3SOIDDgtempb; + double B3SOIDDgtempg; + double B3SOIDDgtempd; + double B3SOIDDgtempe; + double B3SOIDDgtempT; + + double B3SOIDDcggb; + double B3SOIDDcgdb; + double B3SOIDDcbs; /* XXX PN */ + double B3SOIDDcgsb; + double B3SOIDDcgeb; + double B3SOIDDcgT; + + double B3SOIDDcbgb; + double B3SOIDDcbdb; + double B3SOIDDcbsb; + double B3SOIDDcbeb; + double B3SOIDDcbT; + + double B3SOIDDcdgb; + double B3SOIDDcddb; + double B3SOIDDcdsb; + double B3SOIDDcdeb; + double B3SOIDDcdT; + + double B3SOIDDcegb; + double B3SOIDDcedb; + double B3SOIDDcesb; + double B3SOIDDceeb; + double B3SOIDDceT; + + double B3SOIDDqse; + double B3SOIDDgcse; + double B3SOIDDqde; + double B3SOIDDgcde; + + struct b3soiddSizeDependParam *pParam; + + unsigned B3SOIDDlGiven :1; + unsigned B3SOIDDwGiven :1; + unsigned B3SOIDDdrainAreaGiven :1; + unsigned B3SOIDDsourceAreaGiven :1; + unsigned B3SOIDDdrainSquaresGiven :1; + unsigned B3SOIDDsourceSquaresGiven :1; + unsigned B3SOIDDdrainPerimeterGiven :1; + unsigned B3SOIDDsourcePerimeterGiven :1; + unsigned B3SOIDDdNodePrimeSet :1; + unsigned B3SOIDDsNodePrimeSet :1; + unsigned B3SOIDDicVBSGiven :1; + unsigned B3SOIDDicVDSGiven :1; + unsigned B3SOIDDicVGSGiven :1; + unsigned B3SOIDDicVESGiven :1; + unsigned B3SOIDDicVPSGiven :1; + unsigned B3SOIDDbjtoffGiven :1; + unsigned B3SOIDDdebugModGiven :1; + unsigned B3SOIDDrth0Given :1; + unsigned B3SOIDDcth0Given :1; + unsigned B3SOIDDbodySquaresGiven :1; + unsigned B3SOIDDoffGiven :1; + + double *B3SOIDDEePtr; + double *B3SOIDDEbPtr; + double *B3SOIDDBePtr; + double *B3SOIDDEgPtr; + double *B3SOIDDEdpPtr; + double *B3SOIDDEspPtr; + double *B3SOIDDTemptempPtr; + double *B3SOIDDTempdpPtr; + double *B3SOIDDTempspPtr; + double *B3SOIDDTempgPtr; + double *B3SOIDDTempbPtr; + double *B3SOIDDTempePtr; + double *B3SOIDDGtempPtr; + double *B3SOIDDDPtempPtr; + double *B3SOIDDSPtempPtr; + double *B3SOIDDEtempPtr; + double *B3SOIDDBtempPtr; + double *B3SOIDDPtempPtr; + double *B3SOIDDBpPtr; + double *B3SOIDDPbPtr; + double *B3SOIDDPpPtr; + double *B3SOIDDPgPtr; + double *B3SOIDDPdpPtr; + double *B3SOIDDPspPtr; + double *B3SOIDDPePtr; + double *B3SOIDDDPePtr; + double *B3SOIDDSPePtr; + double *B3SOIDDGePtr; + double *B3SOIDDDdPtr; + double *B3SOIDDGgPtr; + double *B3SOIDDSsPtr; + double *B3SOIDDBbPtr; + double *B3SOIDDDPdpPtr; + double *B3SOIDDSPspPtr; + double *B3SOIDDDdpPtr; + double *B3SOIDDGbPtr; + double *B3SOIDDGdpPtr; + double *B3SOIDDGspPtr; + double *B3SOIDDSspPtr; + double *B3SOIDDBdpPtr; + double *B3SOIDDBspPtr; + double *B3SOIDDDPspPtr; + double *B3SOIDDDPdPtr; + double *B3SOIDDBgPtr; + double *B3SOIDDDPgPtr; + double *B3SOIDDSPgPtr; + double *B3SOIDDSPsPtr; + double *B3SOIDDDPbPtr; + double *B3SOIDDSPbPtr; + double *B3SOIDDSPdpPtr; + + double *B3SOIDDVbsPtr; + /* Debug */ + double *B3SOIDDIdsPtr; + double *B3SOIDDIcPtr; + double *B3SOIDDIbsPtr; + double *B3SOIDDIbdPtr; + double *B3SOIDDIiiPtr; + double *B3SOIDDIgidlPtr; + double *B3SOIDDItunPtr; + double *B3SOIDDIbpPtr; + double *B3SOIDDAbeffPtr; + double *B3SOIDDVbs0effPtr; + double *B3SOIDDVbseffPtr; + double *B3SOIDDXcPtr; + double *B3SOIDDCbbPtr; + double *B3SOIDDCbdPtr; + double *B3SOIDDCbgPtr; + double *B3SOIDDqbPtr; + double *B3SOIDDQbfPtr; + double *B3SOIDDQjsPtr; + double *B3SOIDDQjdPtr; + + /* clean up last */ + double *B3SOIDDGmPtr; + double *B3SOIDDGmbsPtr; + double *B3SOIDDGdsPtr; + double *B3SOIDDGmePtr; + double *B3SOIDDVbs0teffPtr; + double *B3SOIDDVthPtr; + double *B3SOIDDVgsteffPtr; + double *B3SOIDDXcsatPtr; + double *B3SOIDDQaccPtr; + double *B3SOIDDQsub0Ptr; + double *B3SOIDDQsubs1Ptr; + double *B3SOIDDQsubs2Ptr; + double *B3SOIDDVdscvPtr; + double *B3SOIDDVcscvPtr; + double *B3SOIDDCbePtr; + double *B3SOIDDqgPtr; + double *B3SOIDDqdPtr; + double *B3SOIDDqePtr; + double *B3SOIDDDum1Ptr; + double *B3SOIDDDum2Ptr; + double *B3SOIDDDum3Ptr; + double *B3SOIDDDum4Ptr; + double *B3SOIDDDum5Ptr; + /* End clean up last */ + +#define B3SOIDDvbd B3SOIDDstates+ 0 +#define B3SOIDDvbs B3SOIDDstates+ 1 +#define B3SOIDDvgs B3SOIDDstates+ 2 +#define B3SOIDDvds B3SOIDDstates+ 3 +#define B3SOIDDves B3SOIDDstates+ 4 +#define B3SOIDDvps B3SOIDDstates+ 5 + +#define B3SOIDDvg B3SOIDDstates+ 6 +#define B3SOIDDvd B3SOIDDstates+ 7 +#define B3SOIDDvs B3SOIDDstates+ 8 +#define B3SOIDDvp B3SOIDDstates+ 9 +#define B3SOIDDve B3SOIDDstates+ 10 +#define B3SOIDDdeltemp B3SOIDDstates+ 11 + +#define B3SOIDDqb B3SOIDDstates+ 12 +#define B3SOIDDcqb B3SOIDDstates+ 13 +#define B3SOIDDqg B3SOIDDstates+ 14 +#define B3SOIDDcqg B3SOIDDstates+ 15 +#define B3SOIDDqd B3SOIDDstates+ 16 +#define B3SOIDDcqd B3SOIDDstates+ 17 +#define B3SOIDDqe B3SOIDDstates+ 18 +#define B3SOIDDcqe B3SOIDDstates+ 19 + +#define B3SOIDDqbs B3SOIDDstates+ 20 +#define B3SOIDDqbd B3SOIDDstates+ 21 +#define B3SOIDDqbe B3SOIDDstates+ 22 + +#define B3SOIDDqth B3SOIDDstates+ 23 +#define B3SOIDDcqth B3SOIDDstates+ 24 + +#define B3SOIDDnumStates 25 + + +/* indices to the array of B3SOIDD NOISE SOURCES */ + +#define B3SOIDDRDNOIZ 0 +#define B3SOIDDRSNOIZ 1 +#define B3SOIDDIDNOIZ 2 +#define B3SOIDDFLNOIZ 3 +#define B3SOIDDFBNOIZ 4 +#define B3SOIDDTOTNOIZ 5 + +#define B3SOIDDNSRCS 6 /* the number of MOSFET(3) noise sources */ + +#ifndef NONOISE + double B3SOIDDnVar[NSTATVARS][B3SOIDDNSRCS]; +#else /* NONOISE */ + double **B3SOIDDnVar; +#endif /* NONOISE */ + +} B3SOIDDinstance ; + +struct b3soiddSizeDependParam +{ + double Width; + double Length; + double Rth0; + double Cth0; + + double B3SOIDDcdsc; + double B3SOIDDcdscb; + double B3SOIDDcdscd; + double B3SOIDDcit; + double B3SOIDDnfactor; + double B3SOIDDvsat; + double B3SOIDDat; + double B3SOIDDa0; + double B3SOIDDags; + double B3SOIDDa1; + double B3SOIDDa2; + double B3SOIDDketa; + double B3SOIDDnpeak; + double B3SOIDDnsub; + double B3SOIDDngate; + double B3SOIDDgamma1; + double B3SOIDDgamma2; + double B3SOIDDvbx; + double B3SOIDDvbi; + double B3SOIDDvbm; + double B3SOIDDvbsc; + double B3SOIDDxt; + double B3SOIDDphi; + double B3SOIDDlitl; + double B3SOIDDk1; + double B3SOIDDkt1; + double B3SOIDDkt1l; + double B3SOIDDkt2; + double B3SOIDDk2; + double B3SOIDDk3; + double B3SOIDDk3b; + double B3SOIDDw0; + double B3SOIDDnlx; + double B3SOIDDdvt0; + double B3SOIDDdvt1; + double B3SOIDDdvt2; + double B3SOIDDdvt0w; + double B3SOIDDdvt1w; + double B3SOIDDdvt2w; + double B3SOIDDdrout; + double B3SOIDDdsub; + double B3SOIDDvth0; + double B3SOIDDua; + double B3SOIDDua1; + double B3SOIDDub; + double B3SOIDDub1; + double B3SOIDDuc; + double B3SOIDDuc1; + double B3SOIDDu0; + double B3SOIDDute; + double B3SOIDDvoff; + double B3SOIDDvfb; + double B3SOIDDuatemp; + double B3SOIDDubtemp; + double B3SOIDDuctemp; + double B3SOIDDrbody; + double B3SOIDDrth; + double B3SOIDDcth; + double B3SOIDDrds0denom; + double B3SOIDDvfbb; + double B3SOIDDjbjt; + double B3SOIDDjdif; + double B3SOIDDjrec; + double B3SOIDDjtun; + double B3SOIDDcsesw; + double B3SOIDDcdesw; + + /* Added */ + double B3SOIDDsdt1; + double B3SOIDDst2; + double B3SOIDDst3; + double B3SOIDDdt2; + double B3SOIDDdt3; + /* Added */ + + double B3SOIDDdelta; + double B3SOIDDrdsw; + double B3SOIDDrds0; + double B3SOIDDprwg; + double B3SOIDDprwb; + double B3SOIDDprt; + double B3SOIDDeta0; + double B3SOIDDetab; + double B3SOIDDpclm; + double B3SOIDDpdibl1; + double B3SOIDDpdibl2; + double B3SOIDDpdiblb; + double B3SOIDDpvag; + double B3SOIDDwr; + double B3SOIDDdwg; + double B3SOIDDdwb; + double B3SOIDDb0; + double B3SOIDDb1; + double B3SOIDDalpha0; + double B3SOIDDalpha1; + double B3SOIDDbeta0; + + + /* CV model */ + double B3SOIDDcgsl; + double B3SOIDDcgdl; + double B3SOIDDckappa; + double B3SOIDDcf; + double B3SOIDDclc; + double B3SOIDDcle; + +/* Added for binning - START0 */ + double B3SOIDDvbsa; + double B3SOIDDdelp; + double B3SOIDDkb1; + double B3SOIDDkb3; + double B3SOIDDdvbd0; + double B3SOIDDdvbd1; + double B3SOIDDabp; + double B3SOIDDmxc; + double B3SOIDDadice0; + double B3SOIDDaii; + double B3SOIDDbii; + double B3SOIDDcii; + double B3SOIDDdii; + double B3SOIDDagidl; + double B3SOIDDbgidl; + double B3SOIDDngidl; + double B3SOIDDntun; + double B3SOIDDndiode; + double B3SOIDDisbjt; + double B3SOIDDisdif; + double B3SOIDDisrec; + double B3SOIDDistun; + double B3SOIDDedl; + double B3SOIDDkbjt1; + double B3SOIDDvsdfb; + double B3SOIDDvsdth; +/* Added for binning - END0 */ + +/* Pre-calculated constants */ + + double B3SOIDDdw; + double B3SOIDDdl; + double B3SOIDDleff; + double B3SOIDDweff; + + double B3SOIDDdwc; + double B3SOIDDdlc; + double B3SOIDDleffCV; + double B3SOIDDweffCV; + double B3SOIDDabulkCVfactor; + double B3SOIDDcgso; + double B3SOIDDcgdo; + double B3SOIDDcgeo; + + double B3SOIDDu0temp; + double B3SOIDDvsattemp; + double B3SOIDDsqrtPhi; + double B3SOIDDphis3; + double B3SOIDDXdep0; + double B3SOIDDsqrtXdep0; + double B3SOIDDtheta0vb0; + double B3SOIDDthetaRout; + + double B3SOIDDcof1; + double B3SOIDDcof2; + double B3SOIDDcof3; + double B3SOIDDcof4; + double B3SOIDDcdep0; + struct b3soiddSizeDependParam *pNext; +}; + + +typedef struct sB3SOIDDmodel +{ + int B3SOIDDmodType; + struct sB3SOIDDmodel *B3SOIDDnextModel; + B3SOIDDinstance *B3SOIDDinstances; + IFuid B3SOIDDmodName; + int B3SOIDDtype; + + int B3SOIDDmobMod; + int B3SOIDDcapMod; + int B3SOIDDnoiMod; + int B3SOIDDshMod; + int B3SOIDDbinUnit; + int B3SOIDDparamChk; + double B3SOIDDversion; + double B3SOIDDtox; + double B3SOIDDcdsc; + double B3SOIDDcdscb; + double B3SOIDDcdscd; + double B3SOIDDcit; + double B3SOIDDnfactor; + double B3SOIDDvsat; + double B3SOIDDat; + double B3SOIDDa0; + double B3SOIDDags; + double B3SOIDDa1; + double B3SOIDDa2; + double B3SOIDDketa; + double B3SOIDDnsub; + double B3SOIDDnpeak; + double B3SOIDDngate; + double B3SOIDDgamma1; + double B3SOIDDgamma2; + double B3SOIDDvbx; + double B3SOIDDvbm; + double B3SOIDDxt; + double B3SOIDDk1; + double B3SOIDDkt1; + double B3SOIDDkt1l; + double B3SOIDDkt2; + double B3SOIDDk2; + double B3SOIDDk3; + double B3SOIDDk3b; + double B3SOIDDw0; + double B3SOIDDnlx; + double B3SOIDDdvt0; + double B3SOIDDdvt1; + double B3SOIDDdvt2; + double B3SOIDDdvt0w; + double B3SOIDDdvt1w; + double B3SOIDDdvt2w; + double B3SOIDDdrout; + double B3SOIDDdsub; + double B3SOIDDvth0; + double B3SOIDDua; + double B3SOIDDua1; + double B3SOIDDub; + double B3SOIDDub1; + double B3SOIDDuc; + double B3SOIDDuc1; + double B3SOIDDu0; + double B3SOIDDute; + double B3SOIDDvoff; + double B3SOIDDdelta; + double B3SOIDDrdsw; + double B3SOIDDprwg; + double B3SOIDDprwb; + double B3SOIDDprt; + double B3SOIDDeta0; + double B3SOIDDetab; + double B3SOIDDpclm; + double B3SOIDDpdibl1; + double B3SOIDDpdibl2; + double B3SOIDDpdiblb; + double B3SOIDDpvag; + double B3SOIDDwr; + double B3SOIDDdwg; + double B3SOIDDdwb; + double B3SOIDDb0; + double B3SOIDDb1; + double B3SOIDDalpha0; + double B3SOIDDalpha1; + double B3SOIDDbeta0; + double B3SOIDDtbox; + double B3SOIDDtsi; + double B3SOIDDxj; + double B3SOIDDkb1; + double B3SOIDDkb3; + double B3SOIDDdvbd0; + double B3SOIDDdvbd1; + double B3SOIDDvbsa; + double B3SOIDDdelp; + double B3SOIDDrbody; + double B3SOIDDrbsh; + double B3SOIDDadice0; + double B3SOIDDabp; + double B3SOIDDmxc; + double B3SOIDDrth0; + double B3SOIDDcth0; + double B3SOIDDaii; + double B3SOIDDbii; + double B3SOIDDcii; + double B3SOIDDdii; + double B3SOIDDngidl; + double B3SOIDDagidl; + double B3SOIDDbgidl; + double B3SOIDDndiode; + double B3SOIDDntun; + double B3SOIDDisbjt; + double B3SOIDDisdif; + double B3SOIDDisrec; + double B3SOIDDistun; + double B3SOIDDxbjt; + double B3SOIDDxdif; + double B3SOIDDxrec; + double B3SOIDDxtun; + double B3SOIDDedl; + double B3SOIDDkbjt1; + double B3SOIDDtt; + double B3SOIDDvsdfb; + double B3SOIDDvsdth; + double B3SOIDDcsdmin; + double B3SOIDDasd; + + /* CV model */ + double B3SOIDDcgsl; + double B3SOIDDcgdl; + double B3SOIDDckappa; + double B3SOIDDcf; + double B3SOIDDclc; + double B3SOIDDcle; + double B3SOIDDdwc; + double B3SOIDDdlc; + + double B3SOIDDtnom; + double B3SOIDDcgso; + double B3SOIDDcgdo; + double B3SOIDDcgeo; + + double B3SOIDDxpart; + double B3SOIDDcFringOut; + double B3SOIDDcFringMax; + + double B3SOIDDsheetResistance; + double B3SOIDDbodyJctGateSideGradingCoeff; + double B3SOIDDGatesidewallJctPotential; + double B3SOIDDunitLengthGateSidewallJctCap; + double B3SOIDDcsdesw; + + double B3SOIDDLint; + double B3SOIDDLl; + double B3SOIDDLln; + double B3SOIDDLw; + double B3SOIDDLwn; + double B3SOIDDLwl; + double B3SOIDDLmin; + double B3SOIDDLmax; + + double B3SOIDDWint; + double B3SOIDDWl; + double B3SOIDDWln; + double B3SOIDDWw; + double B3SOIDDWwn; + double B3SOIDDWwl; + double B3SOIDDWmin; + double B3SOIDDWmax; + +/* Added for binning - START1 */ + /* Length Dependence */ + double B3SOIDDlnpeak; + double B3SOIDDlnsub; + double B3SOIDDlngate; + double B3SOIDDlvth0; + double B3SOIDDlk1; + double B3SOIDDlk2; + double B3SOIDDlk3; + double B3SOIDDlk3b; + double B3SOIDDlvbsa; + double B3SOIDDldelp; + double B3SOIDDlkb1; + double B3SOIDDlkb3; + double B3SOIDDldvbd0; + double B3SOIDDldvbd1; + double B3SOIDDlw0; + double B3SOIDDlnlx; + double B3SOIDDldvt0; + double B3SOIDDldvt1; + double B3SOIDDldvt2; + double B3SOIDDldvt0w; + double B3SOIDDldvt1w; + double B3SOIDDldvt2w; + double B3SOIDDlu0; + double B3SOIDDlua; + double B3SOIDDlub; + double B3SOIDDluc; + double B3SOIDDlvsat; + double B3SOIDDla0; + double B3SOIDDlags; + double B3SOIDDlb0; + double B3SOIDDlb1; + double B3SOIDDlketa; + double B3SOIDDlabp; + double B3SOIDDlmxc; + double B3SOIDDladice0; + double B3SOIDDla1; + double B3SOIDDla2; + double B3SOIDDlrdsw; + double B3SOIDDlprwb; + double B3SOIDDlprwg; + double B3SOIDDlwr; + double B3SOIDDlnfactor; + double B3SOIDDldwg; + double B3SOIDDldwb; + double B3SOIDDlvoff; + double B3SOIDDleta0; + double B3SOIDDletab; + double B3SOIDDldsub; + double B3SOIDDlcit; + double B3SOIDDlcdsc; + double B3SOIDDlcdscb; + double B3SOIDDlcdscd; + double B3SOIDDlpclm; + double B3SOIDDlpdibl1; + double B3SOIDDlpdibl2; + double B3SOIDDlpdiblb; + double B3SOIDDldrout; + double B3SOIDDlpvag; + double B3SOIDDldelta; + double B3SOIDDlaii; + double B3SOIDDlbii; + double B3SOIDDlcii; + double B3SOIDDldii; + double B3SOIDDlalpha0; + double B3SOIDDlalpha1; + double B3SOIDDlbeta0; + double B3SOIDDlagidl; + double B3SOIDDlbgidl; + double B3SOIDDlngidl; + double B3SOIDDlntun; + double B3SOIDDlndiode; + double B3SOIDDlisbjt; + double B3SOIDDlisdif; + double B3SOIDDlisrec; + double B3SOIDDlistun; + double B3SOIDDledl; + double B3SOIDDlkbjt1; + /* CV model */ + double B3SOIDDlvsdfb; + double B3SOIDDlvsdth; + + /* Width Dependence */ + double B3SOIDDwnpeak; + double B3SOIDDwnsub; + double B3SOIDDwngate; + double B3SOIDDwvth0; + double B3SOIDDwk1; + double B3SOIDDwk2; + double B3SOIDDwk3; + double B3SOIDDwk3b; + double B3SOIDDwvbsa; + double B3SOIDDwdelp; + double B3SOIDDwkb1; + double B3SOIDDwkb3; + double B3SOIDDwdvbd0; + double B3SOIDDwdvbd1; + double B3SOIDDww0; + double B3SOIDDwnlx; + double B3SOIDDwdvt0; + double B3SOIDDwdvt1; + double B3SOIDDwdvt2; + double B3SOIDDwdvt0w; + double B3SOIDDwdvt1w; + double B3SOIDDwdvt2w; + double B3SOIDDwu0; + double B3SOIDDwua; + double B3SOIDDwub; + double B3SOIDDwuc; + double B3SOIDDwvsat; + double B3SOIDDwa0; + double B3SOIDDwags; + double B3SOIDDwb0; + double B3SOIDDwb1; + double B3SOIDDwketa; + double B3SOIDDwabp; + double B3SOIDDwmxc; + double B3SOIDDwadice0; + double B3SOIDDwa1; + double B3SOIDDwa2; + double B3SOIDDwrdsw; + double B3SOIDDwprwb; + double B3SOIDDwprwg; + double B3SOIDDwwr; + double B3SOIDDwnfactor; + double B3SOIDDwdwg; + double B3SOIDDwdwb; + double B3SOIDDwvoff; + double B3SOIDDweta0; + double B3SOIDDwetab; + double B3SOIDDwdsub; + double B3SOIDDwcit; + double B3SOIDDwcdsc; + double B3SOIDDwcdscb; + double B3SOIDDwcdscd; + double B3SOIDDwpclm; + double B3SOIDDwpdibl1; + double B3SOIDDwpdibl2; + double B3SOIDDwpdiblb; + double B3SOIDDwdrout; + double B3SOIDDwpvag; + double B3SOIDDwdelta; + double B3SOIDDwaii; + double B3SOIDDwbii; + double B3SOIDDwcii; + double B3SOIDDwdii; + double B3SOIDDwalpha0; + double B3SOIDDwalpha1; + double B3SOIDDwbeta0; + double B3SOIDDwagidl; + double B3SOIDDwbgidl; + double B3SOIDDwngidl; + double B3SOIDDwntun; + double B3SOIDDwndiode; + double B3SOIDDwisbjt; + double B3SOIDDwisdif; + double B3SOIDDwisrec; + double B3SOIDDwistun; + double B3SOIDDwedl; + double B3SOIDDwkbjt1; + /* CV model */ + double B3SOIDDwvsdfb; + double B3SOIDDwvsdth; + + /* Cross-term Dependence */ + double B3SOIDDpnpeak; + double B3SOIDDpnsub; + double B3SOIDDpngate; + double B3SOIDDpvth0; + double B3SOIDDpk1; + double B3SOIDDpk2; + double B3SOIDDpk3; + double B3SOIDDpk3b; + double B3SOIDDpvbsa; + double B3SOIDDpdelp; + double B3SOIDDpkb1; + double B3SOIDDpkb3; + double B3SOIDDpdvbd0; + double B3SOIDDpdvbd1; + double B3SOIDDpw0; + double B3SOIDDpnlx; + double B3SOIDDpdvt0; + double B3SOIDDpdvt1; + double B3SOIDDpdvt2; + double B3SOIDDpdvt0w; + double B3SOIDDpdvt1w; + double B3SOIDDpdvt2w; + double B3SOIDDpu0; + double B3SOIDDpua; + double B3SOIDDpub; + double B3SOIDDpuc; + double B3SOIDDpvsat; + double B3SOIDDpa0; + double B3SOIDDpags; + double B3SOIDDpb0; + double B3SOIDDpb1; + double B3SOIDDpketa; + double B3SOIDDpabp; + double B3SOIDDpmxc; + double B3SOIDDpadice0; + double B3SOIDDpa1; + double B3SOIDDpa2; + double B3SOIDDprdsw; + double B3SOIDDpprwb; + double B3SOIDDpprwg; + double B3SOIDDpwr; + double B3SOIDDpnfactor; + double B3SOIDDpdwg; + double B3SOIDDpdwb; + double B3SOIDDpvoff; + double B3SOIDDpeta0; + double B3SOIDDpetab; + double B3SOIDDpdsub; + double B3SOIDDpcit; + double B3SOIDDpcdsc; + double B3SOIDDpcdscb; + double B3SOIDDpcdscd; + double B3SOIDDppclm; + double B3SOIDDppdibl1; + double B3SOIDDppdibl2; + double B3SOIDDppdiblb; + double B3SOIDDpdrout; + double B3SOIDDppvag; + double B3SOIDDpdelta; + double B3SOIDDpaii; + double B3SOIDDpbii; + double B3SOIDDpcii; + double B3SOIDDpdii; + double B3SOIDDpalpha0; + double B3SOIDDpalpha1; + double B3SOIDDpbeta0; + double B3SOIDDpagidl; + double B3SOIDDpbgidl; + double B3SOIDDpngidl; + double B3SOIDDpntun; + double B3SOIDDpndiode; + double B3SOIDDpisbjt; + double B3SOIDDpisdif; + double B3SOIDDpisrec; + double B3SOIDDpistun; + double B3SOIDDpedl; + double B3SOIDDpkbjt1; + /* CV model */ + double B3SOIDDpvsdfb; + double B3SOIDDpvsdth; +/* Added for binning - END1 */ + +/* Pre-calculated constants */ + double B3SOIDDcbox; + double B3SOIDDcsi; + double B3SOIDDcsieff; + double B3SOIDDcoxt; + double B3SOIDDcboxt; + double B3SOIDDcsit; + double B3SOIDDnfb; + double B3SOIDDadice; + double B3SOIDDqsi; + double B3SOIDDqsieff; + double B3SOIDDeg0; + + /* MCJ: move to size-dependent param. */ + double B3SOIDDvtm; + double B3SOIDDcox; + double B3SOIDDcof1; + double B3SOIDDcof2; + double B3SOIDDcof3; + double B3SOIDDcof4; + double B3SOIDDvcrit; + double B3SOIDDfactor1; + + double B3SOIDDoxideTrapDensityA; + double B3SOIDDoxideTrapDensityB; + double B3SOIDDoxideTrapDensityC; + double B3SOIDDem; + double B3SOIDDef; + double B3SOIDDaf; + double B3SOIDDkf; + double B3SOIDDnoif; + + struct b3soiddSizeDependParam *pSizeDependParamKnot; + + /* Flags */ + + unsigned B3SOIDDtboxGiven:1; + unsigned B3SOIDDtsiGiven :1; + unsigned B3SOIDDxjGiven :1; + unsigned B3SOIDDkb1Given :1; + unsigned B3SOIDDkb3Given :1; + unsigned B3SOIDDdvbd0Given :1; + unsigned B3SOIDDdvbd1Given :1; + unsigned B3SOIDDvbsaGiven :1; + unsigned B3SOIDDdelpGiven :1; + unsigned B3SOIDDrbodyGiven :1; + unsigned B3SOIDDrbshGiven :1; + unsigned B3SOIDDadice0Given :1; + unsigned B3SOIDDabpGiven :1; + unsigned B3SOIDDmxcGiven :1; + unsigned B3SOIDDrth0Given :1; + unsigned B3SOIDDcth0Given :1; + unsigned B3SOIDDaiiGiven :1; + unsigned B3SOIDDbiiGiven :1; + unsigned B3SOIDDciiGiven :1; + unsigned B3SOIDDdiiGiven :1; + unsigned B3SOIDDngidlGiven :1; + unsigned B3SOIDDagidlGiven :1; + unsigned B3SOIDDbgidlGiven :1; + unsigned B3SOIDDndiodeGiven :1; + unsigned B3SOIDDntunGiven :1; + unsigned B3SOIDDisbjtGiven :1; + unsigned B3SOIDDisdifGiven :1; + unsigned B3SOIDDisrecGiven :1; + unsigned B3SOIDDistunGiven :1; + unsigned B3SOIDDxbjtGiven :1; + unsigned B3SOIDDxdifGiven :1; + unsigned B3SOIDDxrecGiven :1; + unsigned B3SOIDDxtunGiven :1; + unsigned B3SOIDDedlGiven :1; + unsigned B3SOIDDkbjt1Given :1; + unsigned B3SOIDDttGiven :1; + unsigned B3SOIDDvsdfbGiven :1; + unsigned B3SOIDDvsdthGiven :1; + unsigned B3SOIDDasdGiven :1; + unsigned B3SOIDDcsdminGiven :1; + + unsigned B3SOIDDmobModGiven :1; + unsigned B3SOIDDbinUnitGiven :1; + unsigned B3SOIDDcapModGiven :1; + unsigned B3SOIDDparamChkGiven :1; + unsigned B3SOIDDnoiModGiven :1; + unsigned B3SOIDDshModGiven :1; + unsigned B3SOIDDtypeGiven :1; + unsigned B3SOIDDtoxGiven :1; + unsigned B3SOIDDversionGiven :1; + + unsigned B3SOIDDcdscGiven :1; + unsigned B3SOIDDcdscbGiven :1; + unsigned B3SOIDDcdscdGiven :1; + unsigned B3SOIDDcitGiven :1; + unsigned B3SOIDDnfactorGiven :1; + unsigned B3SOIDDvsatGiven :1; + unsigned B3SOIDDatGiven :1; + unsigned B3SOIDDa0Given :1; + unsigned B3SOIDDagsGiven :1; + unsigned B3SOIDDa1Given :1; + unsigned B3SOIDDa2Given :1; + unsigned B3SOIDDketaGiven :1; + unsigned B3SOIDDnsubGiven :1; + unsigned B3SOIDDnpeakGiven :1; + unsigned B3SOIDDngateGiven :1; + unsigned B3SOIDDgamma1Given :1; + unsigned B3SOIDDgamma2Given :1; + unsigned B3SOIDDvbxGiven :1; + unsigned B3SOIDDvbmGiven :1; + unsigned B3SOIDDxtGiven :1; + unsigned B3SOIDDk1Given :1; + unsigned B3SOIDDkt1Given :1; + unsigned B3SOIDDkt1lGiven :1; + unsigned B3SOIDDkt2Given :1; + unsigned B3SOIDDk2Given :1; + unsigned B3SOIDDk3Given :1; + unsigned B3SOIDDk3bGiven :1; + unsigned B3SOIDDw0Given :1; + unsigned B3SOIDDnlxGiven :1; + unsigned B3SOIDDdvt0Given :1; + unsigned B3SOIDDdvt1Given :1; + unsigned B3SOIDDdvt2Given :1; + unsigned B3SOIDDdvt0wGiven :1; + unsigned B3SOIDDdvt1wGiven :1; + unsigned B3SOIDDdvt2wGiven :1; + unsigned B3SOIDDdroutGiven :1; + unsigned B3SOIDDdsubGiven :1; + unsigned B3SOIDDvth0Given :1; + unsigned B3SOIDDuaGiven :1; + unsigned B3SOIDDua1Given :1; + unsigned B3SOIDDubGiven :1; + unsigned B3SOIDDub1Given :1; + unsigned B3SOIDDucGiven :1; + unsigned B3SOIDDuc1Given :1; + unsigned B3SOIDDu0Given :1; + unsigned B3SOIDDuteGiven :1; + unsigned B3SOIDDvoffGiven :1; + unsigned B3SOIDDrdswGiven :1; + unsigned B3SOIDDprwgGiven :1; + unsigned B3SOIDDprwbGiven :1; + unsigned B3SOIDDprtGiven :1; + unsigned B3SOIDDeta0Given :1; + unsigned B3SOIDDetabGiven :1; + unsigned B3SOIDDpclmGiven :1; + unsigned B3SOIDDpdibl1Given :1; + unsigned B3SOIDDpdibl2Given :1; + unsigned B3SOIDDpdiblbGiven :1; + unsigned B3SOIDDpvagGiven :1; + unsigned B3SOIDDdeltaGiven :1; + unsigned B3SOIDDwrGiven :1; + unsigned B3SOIDDdwgGiven :1; + unsigned B3SOIDDdwbGiven :1; + unsigned B3SOIDDb0Given :1; + unsigned B3SOIDDb1Given :1; + unsigned B3SOIDDalpha0Given :1; + unsigned B3SOIDDalpha1Given :1; + unsigned B3SOIDDbeta0Given :1; + + /* CV model */ + unsigned B3SOIDDcgslGiven :1; + unsigned B3SOIDDcgdlGiven :1; + unsigned B3SOIDDckappaGiven :1; + unsigned B3SOIDDcfGiven :1; + unsigned B3SOIDDclcGiven :1; + unsigned B3SOIDDcleGiven :1; + unsigned B3SOIDDdwcGiven :1; + unsigned B3SOIDDdlcGiven :1; + +/* Added for binning - START2 */ + /* Length Dependence */ + unsigned B3SOIDDlnpeakGiven :1; + unsigned B3SOIDDlnsubGiven :1; + unsigned B3SOIDDlngateGiven :1; + unsigned B3SOIDDlvth0Given :1; + unsigned B3SOIDDlk1Given :1; + unsigned B3SOIDDlk2Given :1; + unsigned B3SOIDDlk3Given :1; + unsigned B3SOIDDlk3bGiven :1; + unsigned B3SOIDDlvbsaGiven :1; + unsigned B3SOIDDldelpGiven :1; + unsigned B3SOIDDlkb1Given :1; + unsigned B3SOIDDlkb3Given :1; + unsigned B3SOIDDldvbd0Given :1; + unsigned B3SOIDDldvbd1Given :1; + unsigned B3SOIDDlw0Given :1; + unsigned B3SOIDDlnlxGiven :1; + unsigned B3SOIDDldvt0Given :1; + unsigned B3SOIDDldvt1Given :1; + unsigned B3SOIDDldvt2Given :1; + unsigned B3SOIDDldvt0wGiven :1; + unsigned B3SOIDDldvt1wGiven :1; + unsigned B3SOIDDldvt2wGiven :1; + unsigned B3SOIDDlu0Given :1; + unsigned B3SOIDDluaGiven :1; + unsigned B3SOIDDlubGiven :1; + unsigned B3SOIDDlucGiven :1; + unsigned B3SOIDDlvsatGiven :1; + unsigned B3SOIDDla0Given :1; + unsigned B3SOIDDlagsGiven :1; + unsigned B3SOIDDlb0Given :1; + unsigned B3SOIDDlb1Given :1; + unsigned B3SOIDDlketaGiven :1; + unsigned B3SOIDDlabpGiven :1; + unsigned B3SOIDDlmxcGiven :1; + unsigned B3SOIDDladice0Given :1; + unsigned B3SOIDDla1Given :1; + unsigned B3SOIDDla2Given :1; + unsigned B3SOIDDlrdswGiven :1; + unsigned B3SOIDDlprwbGiven :1; + unsigned B3SOIDDlprwgGiven :1; + unsigned B3SOIDDlwrGiven :1; + unsigned B3SOIDDlnfactorGiven :1; + unsigned B3SOIDDldwgGiven :1; + unsigned B3SOIDDldwbGiven :1; + unsigned B3SOIDDlvoffGiven :1; + unsigned B3SOIDDleta0Given :1; + unsigned B3SOIDDletabGiven :1; + unsigned B3SOIDDldsubGiven :1; + unsigned B3SOIDDlcitGiven :1; + unsigned B3SOIDDlcdscGiven :1; + unsigned B3SOIDDlcdscbGiven :1; + unsigned B3SOIDDlcdscdGiven :1; + unsigned B3SOIDDlpclmGiven :1; + unsigned B3SOIDDlpdibl1Given :1; + unsigned B3SOIDDlpdibl2Given :1; + unsigned B3SOIDDlpdiblbGiven :1; + unsigned B3SOIDDldroutGiven :1; + unsigned B3SOIDDlpvagGiven :1; + unsigned B3SOIDDldeltaGiven :1; + unsigned B3SOIDDlaiiGiven :1; + unsigned B3SOIDDlbiiGiven :1; + unsigned B3SOIDDlciiGiven :1; + unsigned B3SOIDDldiiGiven :1; + unsigned B3SOIDDlalpha0Given :1; + unsigned B3SOIDDlalpha1Given :1; + unsigned B3SOIDDlbeta0Given :1; + unsigned B3SOIDDlagidlGiven :1; + unsigned B3SOIDDlbgidlGiven :1; + unsigned B3SOIDDlngidlGiven :1; + unsigned B3SOIDDlntunGiven :1; + unsigned B3SOIDDlndiodeGiven :1; + unsigned B3SOIDDlisbjtGiven :1; + unsigned B3SOIDDlisdifGiven :1; + unsigned B3SOIDDlisrecGiven :1; + unsigned B3SOIDDlistunGiven :1; + unsigned B3SOIDDledlGiven :1; + unsigned B3SOIDDlkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDlvsdfbGiven :1; + unsigned B3SOIDDlvsdthGiven :1; + + /* Width Dependence */ + unsigned B3SOIDDwnpeakGiven :1; + unsigned B3SOIDDwnsubGiven :1; + unsigned B3SOIDDwngateGiven :1; + unsigned B3SOIDDwvth0Given :1; + unsigned B3SOIDDwk1Given :1; + unsigned B3SOIDDwk2Given :1; + unsigned B3SOIDDwk3Given :1; + unsigned B3SOIDDwk3bGiven :1; + unsigned B3SOIDDwvbsaGiven :1; + unsigned B3SOIDDwdelpGiven :1; + unsigned B3SOIDDwkb1Given :1; + unsigned B3SOIDDwkb3Given :1; + unsigned B3SOIDDwdvbd0Given :1; + unsigned B3SOIDDwdvbd1Given :1; + unsigned B3SOIDDww0Given :1; + unsigned B3SOIDDwnlxGiven :1; + unsigned B3SOIDDwdvt0Given :1; + unsigned B3SOIDDwdvt1Given :1; + unsigned B3SOIDDwdvt2Given :1; + unsigned B3SOIDDwdvt0wGiven :1; + unsigned B3SOIDDwdvt1wGiven :1; + unsigned B3SOIDDwdvt2wGiven :1; + unsigned B3SOIDDwu0Given :1; + unsigned B3SOIDDwuaGiven :1; + unsigned B3SOIDDwubGiven :1; + unsigned B3SOIDDwucGiven :1; + unsigned B3SOIDDwvsatGiven :1; + unsigned B3SOIDDwa0Given :1; + unsigned B3SOIDDwagsGiven :1; + unsigned B3SOIDDwb0Given :1; + unsigned B3SOIDDwb1Given :1; + unsigned B3SOIDDwketaGiven :1; + unsigned B3SOIDDwabpGiven :1; + unsigned B3SOIDDwmxcGiven :1; + unsigned B3SOIDDwadice0Given :1; + unsigned B3SOIDDwa1Given :1; + unsigned B3SOIDDwa2Given :1; + unsigned B3SOIDDwrdswGiven :1; + unsigned B3SOIDDwprwbGiven :1; + unsigned B3SOIDDwprwgGiven :1; + unsigned B3SOIDDwwrGiven :1; + unsigned B3SOIDDwnfactorGiven :1; + unsigned B3SOIDDwdwgGiven :1; + unsigned B3SOIDDwdwbGiven :1; + unsigned B3SOIDDwvoffGiven :1; + unsigned B3SOIDDweta0Given :1; + unsigned B3SOIDDwetabGiven :1; + unsigned B3SOIDDwdsubGiven :1; + unsigned B3SOIDDwcitGiven :1; + unsigned B3SOIDDwcdscGiven :1; + unsigned B3SOIDDwcdscbGiven :1; + unsigned B3SOIDDwcdscdGiven :1; + unsigned B3SOIDDwpclmGiven :1; + unsigned B3SOIDDwpdibl1Given :1; + unsigned B3SOIDDwpdibl2Given :1; + unsigned B3SOIDDwpdiblbGiven :1; + unsigned B3SOIDDwdroutGiven :1; + unsigned B3SOIDDwpvagGiven :1; + unsigned B3SOIDDwdeltaGiven :1; + unsigned B3SOIDDwaiiGiven :1; + unsigned B3SOIDDwbiiGiven :1; + unsigned B3SOIDDwciiGiven :1; + unsigned B3SOIDDwdiiGiven :1; + unsigned B3SOIDDwalpha0Given :1; + unsigned B3SOIDDwalpha1Given :1; + unsigned B3SOIDDwbeta0Given :1; + unsigned B3SOIDDwagidlGiven :1; + unsigned B3SOIDDwbgidlGiven :1; + unsigned B3SOIDDwngidlGiven :1; + unsigned B3SOIDDwntunGiven :1; + unsigned B3SOIDDwndiodeGiven :1; + unsigned B3SOIDDwisbjtGiven :1; + unsigned B3SOIDDwisdifGiven :1; + unsigned B3SOIDDwisrecGiven :1; + unsigned B3SOIDDwistunGiven :1; + unsigned B3SOIDDwedlGiven :1; + unsigned B3SOIDDwkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDwvsdfbGiven :1; + unsigned B3SOIDDwvsdthGiven :1; + + /* Cross-term Dependence */ + unsigned B3SOIDDpnpeakGiven :1; + unsigned B3SOIDDpnsubGiven :1; + unsigned B3SOIDDpngateGiven :1; + unsigned B3SOIDDpvth0Given :1; + unsigned B3SOIDDpk1Given :1; + unsigned B3SOIDDpk2Given :1; + unsigned B3SOIDDpk3Given :1; + unsigned B3SOIDDpk3bGiven :1; + unsigned B3SOIDDpvbsaGiven :1; + unsigned B3SOIDDpdelpGiven :1; + unsigned B3SOIDDpkb1Given :1; + unsigned B3SOIDDpkb3Given :1; + unsigned B3SOIDDpdvbd0Given :1; + unsigned B3SOIDDpdvbd1Given :1; + unsigned B3SOIDDpw0Given :1; + unsigned B3SOIDDpnlxGiven :1; + unsigned B3SOIDDpdvt0Given :1; + unsigned B3SOIDDpdvt1Given :1; + unsigned B3SOIDDpdvt2Given :1; + unsigned B3SOIDDpdvt0wGiven :1; + unsigned B3SOIDDpdvt1wGiven :1; + unsigned B3SOIDDpdvt2wGiven :1; + unsigned B3SOIDDpu0Given :1; + unsigned B3SOIDDpuaGiven :1; + unsigned B3SOIDDpubGiven :1; + unsigned B3SOIDDpucGiven :1; + unsigned B3SOIDDpvsatGiven :1; + unsigned B3SOIDDpa0Given :1; + unsigned B3SOIDDpagsGiven :1; + unsigned B3SOIDDpb0Given :1; + unsigned B3SOIDDpb1Given :1; + unsigned B3SOIDDpketaGiven :1; + unsigned B3SOIDDpabpGiven :1; + unsigned B3SOIDDpmxcGiven :1; + unsigned B3SOIDDpadice0Given :1; + unsigned B3SOIDDpa1Given :1; + unsigned B3SOIDDpa2Given :1; + unsigned B3SOIDDprdswGiven :1; + unsigned B3SOIDDpprwbGiven :1; + unsigned B3SOIDDpprwgGiven :1; + unsigned B3SOIDDpwrGiven :1; + unsigned B3SOIDDpnfactorGiven :1; + unsigned B3SOIDDpdwgGiven :1; + unsigned B3SOIDDpdwbGiven :1; + unsigned B3SOIDDpvoffGiven :1; + unsigned B3SOIDDpeta0Given :1; + unsigned B3SOIDDpetabGiven :1; + unsigned B3SOIDDpdsubGiven :1; + unsigned B3SOIDDpcitGiven :1; + unsigned B3SOIDDpcdscGiven :1; + unsigned B3SOIDDpcdscbGiven :1; + unsigned B3SOIDDpcdscdGiven :1; + unsigned B3SOIDDppclmGiven :1; + unsigned B3SOIDDppdibl1Given :1; + unsigned B3SOIDDppdibl2Given :1; + unsigned B3SOIDDppdiblbGiven :1; + unsigned B3SOIDDpdroutGiven :1; + unsigned B3SOIDDppvagGiven :1; + unsigned B3SOIDDpdeltaGiven :1; + unsigned B3SOIDDpaiiGiven :1; + unsigned B3SOIDDpbiiGiven :1; + unsigned B3SOIDDpciiGiven :1; + unsigned B3SOIDDpdiiGiven :1; + unsigned B3SOIDDpalpha0Given :1; + unsigned B3SOIDDpalpha1Given :1; + unsigned B3SOIDDpbeta0Given :1; + unsigned B3SOIDDpagidlGiven :1; + unsigned B3SOIDDpbgidlGiven :1; + unsigned B3SOIDDpngidlGiven :1; + unsigned B3SOIDDpntunGiven :1; + unsigned B3SOIDDpndiodeGiven :1; + unsigned B3SOIDDpisbjtGiven :1; + unsigned B3SOIDDpisdifGiven :1; + unsigned B3SOIDDpisrecGiven :1; + unsigned B3SOIDDpistunGiven :1; + unsigned B3SOIDDpedlGiven :1; + unsigned B3SOIDDpkbjt1Given :1; + /* CV model */ + unsigned B3SOIDDpvsdfbGiven :1; + unsigned B3SOIDDpvsdthGiven :1; +/* Added for binning - END2 */ + + unsigned B3SOIDDuseFringeGiven :1; + + unsigned B3SOIDDtnomGiven :1; + unsigned B3SOIDDcgsoGiven :1; + unsigned B3SOIDDcgdoGiven :1; + unsigned B3SOIDDcgeoGiven :1; + unsigned B3SOIDDxpartGiven :1; + unsigned B3SOIDDsheetResistanceGiven :1; + unsigned B3SOIDDGatesidewallJctPotentialGiven :1; + unsigned B3SOIDDbodyJctGateSideGradingCoeffGiven :1; + unsigned B3SOIDDunitLengthGateSidewallJctCapGiven :1; + unsigned B3SOIDDcsdeswGiven :1; + + unsigned B3SOIDDoxideTrapDensityAGiven :1; + unsigned B3SOIDDoxideTrapDensityBGiven :1; + unsigned B3SOIDDoxideTrapDensityCGiven :1; + unsigned B3SOIDDemGiven :1; + unsigned B3SOIDDefGiven :1; + unsigned B3SOIDDafGiven :1; + unsigned B3SOIDDkfGiven :1; + unsigned B3SOIDDnoifGiven :1; + + unsigned B3SOIDDLintGiven :1; + unsigned B3SOIDDLlGiven :1; + unsigned B3SOIDDLlnGiven :1; + unsigned B3SOIDDLwGiven :1; + unsigned B3SOIDDLwnGiven :1; + unsigned B3SOIDDLwlGiven :1; + unsigned B3SOIDDLminGiven :1; + unsigned B3SOIDDLmaxGiven :1; + + unsigned B3SOIDDWintGiven :1; + unsigned B3SOIDDWlGiven :1; + unsigned B3SOIDDWlnGiven :1; + unsigned B3SOIDDWwGiven :1; + unsigned B3SOIDDWwnGiven :1; + unsigned B3SOIDDWwlGiven :1; + unsigned B3SOIDDWminGiven :1; + unsigned B3SOIDDWmaxGiven :1; + +} B3SOIDDmodel; + + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ + + +/* device parameters */ +#define B3SOIDD_W 1 +#define B3SOIDD_L 2 +#define B3SOIDD_AS 3 +#define B3SOIDD_AD 4 +#define B3SOIDD_PS 5 +#define B3SOIDD_PD 6 +#define B3SOIDD_NRS 7 +#define B3SOIDD_NRD 8 +#define B3SOIDD_OFF 9 +#define B3SOIDD_IC_VBS 10 +#define B3SOIDD_IC_VDS 11 +#define B3SOIDD_IC_VGS 12 +#define B3SOIDD_IC_VES 13 +#define B3SOIDD_IC_VPS 14 +#define B3SOIDD_BJTOFF 15 +#define B3SOIDD_RTH0 16 +#define B3SOIDD_CTH0 17 +#define B3SOIDD_NRB 18 +#define B3SOIDD_IC 19 +#define B3SOIDD_NQSMOD 20 +#define B3SOIDD_DEBUG 21 + +/* model parameters */ +#define B3SOIDD_MOD_CAPMOD 101 +#define B3SOIDD_MOD_NQSMOD 102 +#define B3SOIDD_MOD_MOBMOD 103 +#define B3SOIDD_MOD_NOIMOD 104 +#define B3SOIDD_MOD_SHMOD 105 +#define B3SOIDD_MOD_DDMOD 106 + +#define B3SOIDD_MOD_TOX 107 + + + +#define B3SOIDD_MOD_CDSC 108 +#define B3SOIDD_MOD_CDSCB 109 +#define B3SOIDD_MOD_CIT 110 +#define B3SOIDD_MOD_NFACTOR 111 +#define B3SOIDD_MOD_XJ 112 +#define B3SOIDD_MOD_VSAT 113 +#define B3SOIDD_MOD_AT 114 +#define B3SOIDD_MOD_A0 115 +#define B3SOIDD_MOD_A1 116 +#define B3SOIDD_MOD_A2 117 +#define B3SOIDD_MOD_KETA 118 +#define B3SOIDD_MOD_NSUB 119 +#define B3SOIDD_MOD_NPEAK 120 +#define B3SOIDD_MOD_NGATE 121 +#define B3SOIDD_MOD_GAMMA1 122 +#define B3SOIDD_MOD_GAMMA2 123 +#define B3SOIDD_MOD_VBX 124 +#define B3SOIDD_MOD_BINUNIT 125 + +#define B3SOIDD_MOD_VBM 126 + +#define B3SOIDD_MOD_XT 127 +#define B3SOIDD_MOD_K1 129 +#define B3SOIDD_MOD_KT1 130 +#define B3SOIDD_MOD_KT1L 131 +#define B3SOIDD_MOD_K2 132 +#define B3SOIDD_MOD_KT2 133 +#define B3SOIDD_MOD_K3 134 +#define B3SOIDD_MOD_K3B 135 +#define B3SOIDD_MOD_W0 136 +#define B3SOIDD_MOD_NLX 137 + +#define B3SOIDD_MOD_DVT0 138 +#define B3SOIDD_MOD_DVT1 139 +#define B3SOIDD_MOD_DVT2 140 + +#define B3SOIDD_MOD_DVT0W 141 +#define B3SOIDD_MOD_DVT1W 142 +#define B3SOIDD_MOD_DVT2W 143 + +#define B3SOIDD_MOD_DROUT 144 +#define B3SOIDD_MOD_DSUB 145 +#define B3SOIDD_MOD_VTH0 146 +#define B3SOIDD_MOD_UA 147 +#define B3SOIDD_MOD_UA1 148 +#define B3SOIDD_MOD_UB 149 +#define B3SOIDD_MOD_UB1 150 +#define B3SOIDD_MOD_UC 151 +#define B3SOIDD_MOD_UC1 152 +#define B3SOIDD_MOD_U0 153 +#define B3SOIDD_MOD_UTE 154 +#define B3SOIDD_MOD_VOFF 155 +#define B3SOIDD_MOD_DELTA 156 +#define B3SOIDD_MOD_RDSW 157 +#define B3SOIDD_MOD_PRT 158 +#define B3SOIDD_MOD_LDD 159 +#define B3SOIDD_MOD_ETA 160 +#define B3SOIDD_MOD_ETA0 161 +#define B3SOIDD_MOD_ETAB 162 +#define B3SOIDD_MOD_PCLM 163 +#define B3SOIDD_MOD_PDIBL1 164 +#define B3SOIDD_MOD_PDIBL2 165 +#define B3SOIDD_MOD_PSCBE1 166 +#define B3SOIDD_MOD_PSCBE2 167 +#define B3SOIDD_MOD_PVAG 168 +#define B3SOIDD_MOD_WR 169 +#define B3SOIDD_MOD_DWG 170 +#define B3SOIDD_MOD_DWB 171 +#define B3SOIDD_MOD_B0 172 +#define B3SOIDD_MOD_B1 173 +#define B3SOIDD_MOD_ALPHA0 174 +#define B3SOIDD_MOD_BETA0 175 +#define B3SOIDD_MOD_PDIBLB 178 + +#define B3SOIDD_MOD_PRWG 179 +#define B3SOIDD_MOD_PRWB 180 + +#define B3SOIDD_MOD_CDSCD 181 +#define B3SOIDD_MOD_AGS 182 + +#define B3SOIDD_MOD_FRINGE 184 +#define B3SOIDD_MOD_CGSL 186 +#define B3SOIDD_MOD_CGDL 187 +#define B3SOIDD_MOD_CKAPPA 188 +#define B3SOIDD_MOD_CF 189 +#define B3SOIDD_MOD_CLC 190 +#define B3SOIDD_MOD_CLE 191 +#define B3SOIDD_MOD_PARAMCHK 192 +#define B3SOIDD_MOD_VERSION 193 + +#define B3SOIDD_MOD_TBOX 195 +#define B3SOIDD_MOD_TSI 196 +#define B3SOIDD_MOD_KB1 197 +#define B3SOIDD_MOD_KB3 198 +#define B3SOIDD_MOD_DVBD0 199 +#define B3SOIDD_MOD_DVBD1 200 +#define B3SOIDD_MOD_DELP 201 +#define B3SOIDD_MOD_VBSA 202 +#define B3SOIDD_MOD_RBODY 204 +#define B3SOIDD_MOD_ADICE0 205 +#define B3SOIDD_MOD_ABP 206 +#define B3SOIDD_MOD_MXC 207 +#define B3SOIDD_MOD_RTH0 208 +#define B3SOIDD_MOD_CTH0 209 +#define B3SOIDD_MOD_AII 210 +#define B3SOIDD_MOD_BII 211 +#define B3SOIDD_MOD_CII 212 +#define B3SOIDD_MOD_DII 213 +#define B3SOIDD_MOD_ALPHA1 214 +#define B3SOIDD_MOD_NGIDL 215 +#define B3SOIDD_MOD_AGIDL 216 +#define B3SOIDD_MOD_BGIDL 217 +#define B3SOIDD_MOD_NDIODE 218 +#define B3SOIDD_MOD_LDIOF 219 +#define B3SOIDD_MOD_LDIOR 220 +#define B3SOIDD_MOD_NTUN 221 +#define B3SOIDD_MOD_ISBJT 222 +#define B3SOIDD_MOD_ISDIF 223 +#define B3SOIDD_MOD_ISREC 224 +#define B3SOIDD_MOD_ISTUN 225 +#define B3SOIDD_MOD_XBJT 226 +#define B3SOIDD_MOD_XDIF 227 +#define B3SOIDD_MOD_XREC 228 +#define B3SOIDD_MOD_XTUN 229 +#define B3SOIDD_MOD_EDL 230 +#define B3SOIDD_MOD_KBJT1 231 +#define B3SOIDD_MOD_TT 232 +#define B3SOIDD_MOD_VSDTH 233 +#define B3SOIDD_MOD_VSDFB 234 +#define B3SOIDD_MOD_ASD 235 +#define B3SOIDD_MOD_CSDMIN 236 +#define B3SOIDD_MOD_RBSH 237 + +/* Added for binning - START3 */ +/* Length dependence */ +#define B3SOIDD_MOD_LNPEAK 301 +#define B3SOIDD_MOD_LNSUB 302 +#define B3SOIDD_MOD_LNGATE 303 +#define B3SOIDD_MOD_LVTH0 304 +#define B3SOIDD_MOD_LK1 305 +#define B3SOIDD_MOD_LK2 306 +#define B3SOIDD_MOD_LK3 307 +#define B3SOIDD_MOD_LK3B 308 +#define B3SOIDD_MOD_LVBSA 309 +#define B3SOIDD_MOD_LDELP 310 +#define B3SOIDD_MOD_LKB1 311 +#define B3SOIDD_MOD_LKB3 312 +#define B3SOIDD_MOD_LDVBD0 313 +#define B3SOIDD_MOD_LDVBD1 314 +#define B3SOIDD_MOD_LW0 315 +#define B3SOIDD_MOD_LNLX 316 +#define B3SOIDD_MOD_LDVT0 317 +#define B3SOIDD_MOD_LDVT1 318 +#define B3SOIDD_MOD_LDVT2 319 +#define B3SOIDD_MOD_LDVT0W 320 +#define B3SOIDD_MOD_LDVT1W 321 +#define B3SOIDD_MOD_LDVT2W 322 +#define B3SOIDD_MOD_LU0 323 +#define B3SOIDD_MOD_LUA 324 +#define B3SOIDD_MOD_LUB 325 +#define B3SOIDD_MOD_LUC 326 +#define B3SOIDD_MOD_LVSAT 327 +#define B3SOIDD_MOD_LA0 328 +#define B3SOIDD_MOD_LAGS 329 +#define B3SOIDD_MOD_LB0 330 +#define B3SOIDD_MOD_LB1 331 +#define B3SOIDD_MOD_LKETA 332 +#define B3SOIDD_MOD_LABP 333 +#define B3SOIDD_MOD_LMXC 334 +#define B3SOIDD_MOD_LADICE0 335 +#define B3SOIDD_MOD_LA1 336 +#define B3SOIDD_MOD_LA2 337 +#define B3SOIDD_MOD_LRDSW 338 +#define B3SOIDD_MOD_LPRWB 339 +#define B3SOIDD_MOD_LPRWG 340 +#define B3SOIDD_MOD_LWR 341 +#define B3SOIDD_MOD_LNFACTOR 342 +#define B3SOIDD_MOD_LDWG 343 +#define B3SOIDD_MOD_LDWB 344 +#define B3SOIDD_MOD_LVOFF 345 +#define B3SOIDD_MOD_LETA0 346 +#define B3SOIDD_MOD_LETAB 347 +#define B3SOIDD_MOD_LDSUB 348 +#define B3SOIDD_MOD_LCIT 349 +#define B3SOIDD_MOD_LCDSC 350 +#define B3SOIDD_MOD_LCDSCB 351 +#define B3SOIDD_MOD_LCDSCD 352 +#define B3SOIDD_MOD_LPCLM 353 +#define B3SOIDD_MOD_LPDIBL1 354 +#define B3SOIDD_MOD_LPDIBL2 355 +#define B3SOIDD_MOD_LPDIBLB 356 +#define B3SOIDD_MOD_LDROUT 357 +#define B3SOIDD_MOD_LPVAG 358 +#define B3SOIDD_MOD_LDELTA 359 +#define B3SOIDD_MOD_LAII 360 +#define B3SOIDD_MOD_LBII 361 +#define B3SOIDD_MOD_LCII 362 +#define B3SOIDD_MOD_LDII 363 +#define B3SOIDD_MOD_LALPHA0 364 +#define B3SOIDD_MOD_LALPHA1 365 +#define B3SOIDD_MOD_LBETA0 366 +#define B3SOIDD_MOD_LAGIDL 367 +#define B3SOIDD_MOD_LBGIDL 368 +#define B3SOIDD_MOD_LNGIDL 369 +#define B3SOIDD_MOD_LNTUN 370 +#define B3SOIDD_MOD_LNDIODE 371 +#define B3SOIDD_MOD_LISBJT 372 +#define B3SOIDD_MOD_LISDIF 373 +#define B3SOIDD_MOD_LISREC 374 +#define B3SOIDD_MOD_LISTUN 375 +#define B3SOIDD_MOD_LEDL 376 +#define B3SOIDD_MOD_LKBJT1 377 +#define B3SOIDD_MOD_LVSDFB 378 +#define B3SOIDD_MOD_LVSDTH 379 + +/* Width dependence */ +#define B3SOIDD_MOD_WNPEAK 401 +#define B3SOIDD_MOD_WNSUB 402 +#define B3SOIDD_MOD_WNGATE 403 +#define B3SOIDD_MOD_WVTH0 404 +#define B3SOIDD_MOD_WK1 405 +#define B3SOIDD_MOD_WK2 406 +#define B3SOIDD_MOD_WK3 407 +#define B3SOIDD_MOD_WK3B 408 +#define B3SOIDD_MOD_WVBSA 409 +#define B3SOIDD_MOD_WDELP 410 +#define B3SOIDD_MOD_WKB1 411 +#define B3SOIDD_MOD_WKB3 412 +#define B3SOIDD_MOD_WDVBD0 413 +#define B3SOIDD_MOD_WDVBD1 414 +#define B3SOIDD_MOD_WW0 415 +#define B3SOIDD_MOD_WNLX 416 +#define B3SOIDD_MOD_WDVT0 417 +#define B3SOIDD_MOD_WDVT1 418 +#define B3SOIDD_MOD_WDVT2 419 +#define B3SOIDD_MOD_WDVT0W 420 +#define B3SOIDD_MOD_WDVT1W 421 +#define B3SOIDD_MOD_WDVT2W 422 +#define B3SOIDD_MOD_WU0 423 +#define B3SOIDD_MOD_WUA 424 +#define B3SOIDD_MOD_WUB 425 +#define B3SOIDD_MOD_WUC 426 +#define B3SOIDD_MOD_WVSAT 427 +#define B3SOIDD_MOD_WA0 428 +#define B3SOIDD_MOD_WAGS 429 +#define B3SOIDD_MOD_WB0 430 +#define B3SOIDD_MOD_WB1 431 +#define B3SOIDD_MOD_WKETA 432 +#define B3SOIDD_MOD_WABP 433 +#define B3SOIDD_MOD_WMXC 434 +#define B3SOIDD_MOD_WADICE0 435 +#define B3SOIDD_MOD_WA1 436 +#define B3SOIDD_MOD_WA2 437 +#define B3SOIDD_MOD_WRDSW 438 +#define B3SOIDD_MOD_WPRWB 439 +#define B3SOIDD_MOD_WPRWG 440 +#define B3SOIDD_MOD_WWR 441 +#define B3SOIDD_MOD_WNFACTOR 442 +#define B3SOIDD_MOD_WDWG 443 +#define B3SOIDD_MOD_WDWB 444 +#define B3SOIDD_MOD_WVOFF 445 +#define B3SOIDD_MOD_WETA0 446 +#define B3SOIDD_MOD_WETAB 447 +#define B3SOIDD_MOD_WDSUB 448 +#define B3SOIDD_MOD_WCIT 449 +#define B3SOIDD_MOD_WCDSC 450 +#define B3SOIDD_MOD_WCDSCB 451 +#define B3SOIDD_MOD_WCDSCD 452 +#define B3SOIDD_MOD_WPCLM 453 +#define B3SOIDD_MOD_WPDIBL1 454 +#define B3SOIDD_MOD_WPDIBL2 455 +#define B3SOIDD_MOD_WPDIBLB 456 +#define B3SOIDD_MOD_WDROUT 457 +#define B3SOIDD_MOD_WPVAG 458 +#define B3SOIDD_MOD_WDELTA 459 +#define B3SOIDD_MOD_WAII 460 +#define B3SOIDD_MOD_WBII 461 +#define B3SOIDD_MOD_WCII 462 +#define B3SOIDD_MOD_WDII 463 +#define B3SOIDD_MOD_WALPHA0 464 +#define B3SOIDD_MOD_WALPHA1 465 +#define B3SOIDD_MOD_WBETA0 466 +#define B3SOIDD_MOD_WAGIDL 467 +#define B3SOIDD_MOD_WBGIDL 468 +#define B3SOIDD_MOD_WNGIDL 469 +#define B3SOIDD_MOD_WNTUN 470 +#define B3SOIDD_MOD_WNDIODE 471 +#define B3SOIDD_MOD_WISBJT 472 +#define B3SOIDD_MOD_WISDIF 473 +#define B3SOIDD_MOD_WISREC 474 +#define B3SOIDD_MOD_WISTUN 475 +#define B3SOIDD_MOD_WEDL 476 +#define B3SOIDD_MOD_WKBJT1 477 +#define B3SOIDD_MOD_WVSDFB 478 +#define B3SOIDD_MOD_WVSDTH 479 + +/* Cross-term dependence */ +#define B3SOIDD_MOD_PNPEAK 501 +#define B3SOIDD_MOD_PNSUB 502 +#define B3SOIDD_MOD_PNGATE 503 +#define B3SOIDD_MOD_PVTH0 504 +#define B3SOIDD_MOD_PK1 505 +#define B3SOIDD_MOD_PK2 506 +#define B3SOIDD_MOD_PK3 507 +#define B3SOIDD_MOD_PK3B 508 +#define B3SOIDD_MOD_PVBSA 509 +#define B3SOIDD_MOD_PDELP 510 +#define B3SOIDD_MOD_PKB1 511 +#define B3SOIDD_MOD_PKB3 512 +#define B3SOIDD_MOD_PDVBD0 513 +#define B3SOIDD_MOD_PDVBD1 514 +#define B3SOIDD_MOD_PW0 515 +#define B3SOIDD_MOD_PNLX 516 +#define B3SOIDD_MOD_PDVT0 517 +#define B3SOIDD_MOD_PDVT1 518 +#define B3SOIDD_MOD_PDVT2 519 +#define B3SOIDD_MOD_PDVT0W 520 +#define B3SOIDD_MOD_PDVT1W 521 +#define B3SOIDD_MOD_PDVT2W 522 +#define B3SOIDD_MOD_PU0 523 +#define B3SOIDD_MOD_PUA 524 +#define B3SOIDD_MOD_PUB 525 +#define B3SOIDD_MOD_PUC 526 +#define B3SOIDD_MOD_PVSAT 527 +#define B3SOIDD_MOD_PA0 528 +#define B3SOIDD_MOD_PAGS 529 +#define B3SOIDD_MOD_PB0 530 +#define B3SOIDD_MOD_PB1 531 +#define B3SOIDD_MOD_PKETA 532 +#define B3SOIDD_MOD_PABP 533 +#define B3SOIDD_MOD_PMXC 534 +#define B3SOIDD_MOD_PADICE0 535 +#define B3SOIDD_MOD_PA1 536 +#define B3SOIDD_MOD_PA2 537 +#define B3SOIDD_MOD_PRDSW 538 +#define B3SOIDD_MOD_PPRWB 539 +#define B3SOIDD_MOD_PPRWG 540 +#define B3SOIDD_MOD_PWR 541 +#define B3SOIDD_MOD_PNFACTOR 542 +#define B3SOIDD_MOD_PDWG 543 +#define B3SOIDD_MOD_PDWB 544 +#define B3SOIDD_MOD_PVOFF 545 +#define B3SOIDD_MOD_PETA0 546 +#define B3SOIDD_MOD_PETAB 547 +#define B3SOIDD_MOD_PDSUB 548 +#define B3SOIDD_MOD_PCIT 549 +#define B3SOIDD_MOD_PCDSC 550 +#define B3SOIDD_MOD_PCDSCB 551 +#define B3SOIDD_MOD_PCDSCD 552 +#define B3SOIDD_MOD_PPCLM 553 +#define B3SOIDD_MOD_PPDIBL1 554 +#define B3SOIDD_MOD_PPDIBL2 555 +#define B3SOIDD_MOD_PPDIBLB 556 +#define B3SOIDD_MOD_PDROUT 557 +#define B3SOIDD_MOD_PPVAG 558 +#define B3SOIDD_MOD_PDELTA 559 +#define B3SOIDD_MOD_PAII 560 +#define B3SOIDD_MOD_PBII 561 +#define B3SOIDD_MOD_PCII 562 +#define B3SOIDD_MOD_PDII 563 +#define B3SOIDD_MOD_PALPHA0 564 +#define B3SOIDD_MOD_PALPHA1 565 +#define B3SOIDD_MOD_PBETA0 566 +#define B3SOIDD_MOD_PAGIDL 567 +#define B3SOIDD_MOD_PBGIDL 568 +#define B3SOIDD_MOD_PNGIDL 569 +#define B3SOIDD_MOD_PNTUN 570 +#define B3SOIDD_MOD_PNDIODE 571 +#define B3SOIDD_MOD_PISBJT 572 +#define B3SOIDD_MOD_PISDIF 573 +#define B3SOIDD_MOD_PISREC 574 +#define B3SOIDD_MOD_PISTUN 575 +#define B3SOIDD_MOD_PEDL 576 +#define B3SOIDD_MOD_PKBJT1 577 +#define B3SOIDD_MOD_PVSDFB 578 +#define B3SOIDD_MOD_PVSDTH 579 +/* Added for binning - END3 */ + +#define B3SOIDD_MOD_TNOM 701 +#define B3SOIDD_MOD_CGSO 702 +#define B3SOIDD_MOD_CGDO 703 +#define B3SOIDD_MOD_CGEO 704 +#define B3SOIDD_MOD_XPART 705 + +#define B3SOIDD_MOD_RSH 706 +#define B3SOIDD_MOD_NMOS 814 +#define B3SOIDD_MOD_PMOS 815 + +#define B3SOIDD_MOD_NOIA 816 +#define B3SOIDD_MOD_NOIB 817 +#define B3SOIDD_MOD_NOIC 818 + +#define B3SOIDD_MOD_LINT 819 +#define B3SOIDD_MOD_LL 820 +#define B3SOIDD_MOD_LLN 821 +#define B3SOIDD_MOD_LW 822 +#define B3SOIDD_MOD_LWN 823 +#define B3SOIDD_MOD_LWL 824 + +#define B3SOIDD_MOD_WINT 827 +#define B3SOIDD_MOD_WL 828 +#define B3SOIDD_MOD_WLN 829 +#define B3SOIDD_MOD_WW 830 +#define B3SOIDD_MOD_WWN 831 +#define B3SOIDD_MOD_WWL 832 + +#define B3SOIDD_MOD_DWC 835 +#define B3SOIDD_MOD_DLC 836 + +#define B3SOIDD_MOD_EM 837 +#define B3SOIDD_MOD_EF 838 +#define B3SOIDD_MOD_AF 839 +#define B3SOIDD_MOD_KF 840 +#define B3SOIDD_MOD_NOIF 841 + + +#define B3SOIDD_MOD_PBSWG 843 +#define B3SOIDD_MOD_MJSWG 844 +#define B3SOIDD_MOD_CJSWG 845 +#define B3SOIDD_MOD_CSDESW 846 + +/* device questions */ +#define B3SOIDD_DNODE 901 +#define B3SOIDD_GNODE 902 +#define B3SOIDD_SNODE 903 +#define B3SOIDD_BNODE 904 +#define B3SOIDD_ENODE 905 +#define B3SOIDD_DNODEPRIME 906 +#define B3SOIDD_SNODEPRIME 907 +#define B3SOIDD_VBD 908 +#define B3SOIDD_VBS 909 +#define B3SOIDD_VGS 910 +#define B3SOIDD_VES 911 +#define B3SOIDD_VDS 912 +#define B3SOIDD_CD 913 +#define B3SOIDD_CBS 914 +#define B3SOIDD_CBD 915 +#define B3SOIDD_GM 916 +#define B3SOIDD_GDS 917 +#define B3SOIDD_GMBS 918 +#define B3SOIDD_GBD 919 +#define B3SOIDD_GBS 920 +#define B3SOIDD_QB 921 +#define B3SOIDD_CQB 922 +#define B3SOIDD_QG 923 +#define B3SOIDD_CQG 924 +#define B3SOIDD_QD 925 +#define B3SOIDD_CQD 926 +#define B3SOIDD_CGG 927 +#define B3SOIDD_CGD 928 +#define B3SOIDD_CGS 929 +#define B3SOIDD_CBG 930 +#define B3SOIDD_CAPBD 931 +#define B3SOIDD_CQBD 932 +#define B3SOIDD_CAPBS 933 +#define B3SOIDD_CQBS 934 +#define B3SOIDD_CDG 935 +#define B3SOIDD_CDD 936 +#define B3SOIDD_CDS 937 +#define B3SOIDD_VON 938 +#define B3SOIDD_VDSAT 939 +#define B3SOIDD_QBS 940 +#define B3SOIDD_QBD 941 +#define B3SOIDD_SOURCECONDUCT 942 +#define B3SOIDD_DRAINCONDUCT 943 +#define B3SOIDD_CBDB 944 +#define B3SOIDD_CBSB 945 +#define B3SOIDD_GMID 946 + + +#include "b3soiddext.h" + +#ifdef __STDC__ +extern void B3SOIDDevaluate(double,double,double,B3SOIDDinstance*,B3SOIDDmodel*, + double*,double*,double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, + double*, double*, double*, double*, CKTcircuit*); +extern int B3SOIDDdebug(B3SOIDDmodel*, B3SOIDDinstance*, CKTcircuit*, int); +extern int B3SOIDDcheckModel(B3SOIDDmodel*, B3SOIDDinstance*, CKTcircuit*); +#else /* stdc */ +extern void B3SOIDDevaluate(); +extern int B3SOIDDdebug(); +extern int B3SOIDDcheckModel(); +#endif /* stdc */ + +#endif /*B3SOIDD*/ + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddel.c b/src/spicelib/devices/bsim3soi_dd/b3soidddel.c new file mode 100644 index 000000000..d002acaf8 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddel.c @@ -0,0 +1,41 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidddel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "sperror.h" +#include "gendefs.h" +#include "suffix.h" + + +int +B3SOIDDdelete(inModel,name,inInst) +GENmodel *inModel; +IFuid name; +GENinstance **inInst; +{ +B3SOIDDinstance **fast = (B3SOIDDinstance**)inInst; +B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +B3SOIDDinstance **prev = NULL; +B3SOIDDinstance *here; + + for (; model ; model = model->B3SOIDDnextModel) + { prev = &(model->B3SOIDDinstances); + for (here = *prev; here ; here = *prev) + { if (here->B3SOIDDname == name || (fast && here==*fast)) + { *prev= here->B3SOIDDnextInstance; + FREE(here); + return(OK); + } + prev = &(here->B3SOIDDnextInstance); + } + } + return(E_NODEV); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddest.c b/src/spicelib/devices/bsim3soi_dd/b3soidddest.c new file mode 100644 index 000000000..107d9107d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddest.c @@ -0,0 +1,39 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soidddest.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "suffix.h" + +void +B3SOIDDdestroy(inModel) +GENmodel **inModel; +{ +B3SOIDDmodel **model = (B3SOIDDmodel**)inModel; +B3SOIDDinstance *here; +B3SOIDDinstance *prev = NULL; +B3SOIDDmodel *mod = *model; +B3SOIDDmodel *oldmod = NULL; + + for (; mod ; mod = mod->B3SOIDDnextModel) + { if(oldmod) FREE(oldmod); + oldmod = mod; + prev = (B3SOIDDinstance *)NULL; + for (here = mod->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + } + if(oldmod) FREE(oldmod); + *model = NULL; + return; +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddext.h b/src/spicelib/devices/bsim3soi_dd/b3soiddext.h new file mode 100644 index 000000000..915515f73 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddext.h @@ -0,0 +1,54 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soiddext.h +**********/ + + +#ifdef __STDC__ +extern int B3SOIDDacLoad(GENmodel *,CKTcircuit*); +extern int B3SOIDDask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int B3SOIDDconvTest(GENmodel *,CKTcircuit*); +extern int B3SOIDDdelete(GENmodel*,IFuid,GENinstance**); +extern void B3SOIDDdestroy(GENmodel**); +extern int B3SOIDDgetic(GENmodel*,CKTcircuit*); +extern int B3SOIDDload(GENmodel*,CKTcircuit*); +extern int B3SOIDDmAsk(CKTcircuit*,GENmodel *,int, IFvalue*); +extern int B3SOIDDmDelete(GENmodel**,IFuid,GENmodel*); +extern int B3SOIDDmParam(int,IFvalue*,GENmodel*); +extern void B3SOIDDmosCap(CKTcircuit*, double, double, double, double, + double, double, double, double, double, double, double, + double, double, double, double, double, double, double*, + double*, double*, double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, + double*); +extern int B3SOIDDparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int B3SOIDDpzLoad(GENmodel*,CKTcircuit*,SPcomplex*); +extern int B3SOIDDsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int B3SOIDDtemp(GENmodel*,CKTcircuit*); +extern int B3SOIDDtrunc(GENmodel*,CKTcircuit*,double*); +extern int B3SOIDDnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int B3SOIDDunsetup(GENmodel*,CKTcircuit*); + +#else /* stdc */ +extern int B3SOIDDacLoad(); +extern int B3SOIDDdelete(); +extern void B3SOIDDdestroy(); +extern int B3SOIDDgetic(); +extern int B3SOIDDload(); +extern int B3SOIDDmDelete(); +extern int B3SOIDDask(); +extern int B3SOIDDmAsk(); +extern int B3SOIDDconvTest(); +extern int B3SOIDDtemp(); +extern int B3SOIDDmParam(); +extern void B3SOIDDmosCap(); +extern int B3SOIDDparam(); +extern int B3SOIDDpzLoad(); +extern int B3SOIDDsetup(); +extern int B3SOIDDtrunc(); +extern int B3SOIDDnoise(); +extern int B3SOIDDunsetup(); + +#endif /* stdc */ + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c b/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c new file mode 100644 index 000000000..d3b549910 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddgetic.c @@ -0,0 +1,51 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddgetic.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDgetic(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ +B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +B3SOIDDinstance *here; + + for (; model ; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(!here->B3SOIDDicVBSGiven) + { here->B3SOIDDicVBS = *(ckt->CKTrhs + here->B3SOIDDbNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVDSGiven) + { here->B3SOIDDicVDS = *(ckt->CKTrhs + here->B3SOIDDdNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVGSGiven) + { here->B3SOIDDicVGS = *(ckt->CKTrhs + here->B3SOIDDgNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVESGiven) + { here->B3SOIDDicVES = *(ckt->CKTrhs + here->B3SOIDDeNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + if (!here->B3SOIDDicVPSGiven) + { here->B3SOIDDicVPS = *(ckt->CKTrhs + here->B3SOIDDpNode) + - *(ckt->CKTrhs + here->B3SOIDDsNode); + } + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c new file mode 100644 index 000000000..3d96f0879 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c @@ -0,0 +1,62 @@ +#include + +#include + +#include "b3soidditf.h" +#include "b3soiddext.h" +#include "b3soiddinit.h" + +SPICEdev B3SOIDDinfo = { + { "B3SOIDD", + "Berkeley SOI MOSFET (DD) model version 1.0", + + &B3SOIDDnSize, + &B3SOIDDnSize, + B3SOIDDnames, + + &B3SOIDDpTSize, + B3SOIDDpTable, + + &B3SOIDDmPTSize, + B3SOIDDmPTable, + DEV_DEFAULT} + , + +DEVparam: B3SOIDDparam, +DEVmodParam: B3SOIDDmParam, +DEVload: B3SOIDDload, +DEVsetup: B3SOIDDsetup, +DEVunsetup: B3SOIDDunsetup, +DEVpzSetup: B3SOIDDsetup, +DEVtemperature:B3SOIDDtemp, +DEVtrunc: B3SOIDDtrunc, +DEVfindBranch: NULL, +DEVacLoad: B3SOIDDacLoad, +DEVaccept: NULL, +DEVdestroy: B3SOIDDdestroy, +DEVmodDelete: B3SOIDDmDelete, +DEVdelete: B3SOIDDdelete, +DEVsetic: B3SOIDDgetic, +DEVask: B3SOIDDask, +DEVmodAsk: B3SOIDDmAsk, +DEVpzLoad: B3SOIDDpzLoad, +DEVconvTest: B3SOIDDconvTest, +DEVsenSetup: NULL, +DEVsenLoad: NULL, +DEVsenUpdate: NULL, +DEVsenAcLoad: NULL, +DEVsenPrint: NULL, +DEVsenTrunc: NULL, +DEVdisto: NULL, +DEVnoise: B3SOIDDnoise, +DEVinstSize: &B3SOIDDiSize, +DEVmodSize: &B3SOIDDmSize +}; + +SPICEdev * +get_b3soidd_info (void) +{ + return &B3SOIDDinfo; +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h new file mode 100644 index 000000000..c6644262f --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.h @@ -0,0 +1,13 @@ +#ifndef _B3SOIDDINIT_H +#define _B3SOIDDINIT_H + +extern IFparm B3SOIDDpTable[]; +extern IFparm B3SOIDDmPTable[]; +extern char *B3SOIDDnames[]; +extern int B3SOIDDpTSize; +extern int B3SOIDDmPTSize; +extern int B3SOIDDnSize; +extern int B3SOIDDiSize; +extern int B3SOIDDmSize; + +#endif diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidditf.h b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h new file mode 100644 index 000000000..f2adf8593 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soidditf.h @@ -0,0 +1,14 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung +File: b3soidditf.h +**********/ + +#ifndef DEV_B3SOIDD +#define DEV_B3SOIDD + +#include "b3soiddext.h" + +SPICEdev *get_b3soidd_info (void); + +#endif diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddld.c new file mode 100644 index 000000000..3e84207e6 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddld.c @@ -0,0 +1,4475 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define Charge_q 1.60219e-19 +#define KboQ 8.617087e-5 /* Kb / q */ +#define Eg300 1.115 /* energy gap at 300K */ +#define DELTA_1 0.02 +#define DELTA_2 0.02 +#define DELTA_3 0.02 +#define DELTA_4 0.02 +#define DELT_Vbs0eff 0.02 +#define DELT_Vbsmos 0.005 +#define DELT_Vbseff 0.005 +#define DELT_Xcsat 0.2 +#define DELT_Vbs0dio 1e-7 +#define DELTA_VFB 0.02 +#define DELTA_Vcscv 0.0004 +#define DELT_Vbsdio 0.01 +#define CONST_2OV3 0.6666666666 +#define OFF_Vbsdio 2e-2 +#define OFF_Vbs0_dio 2.02e-2 +#define QEX_FACT 20 + + + /* B3SOIDDSmartVbs(Vbs, Old, here, check) + * Smart Vbs guess. + */ + +double +B3SOIDDSmartVbs(New, Old, here, ckt, check) + double New, Old; + B3SOIDDinstance *here; + CKTcircuit *ckt; + int *check; +{ + double T0, T1, del; + + /* only do it for floating body and DC */ + if (here->B3SOIDDfloat && (ckt->CKTmode & (MODEDC | MODEDCOP))) + { + /* Vbs cannot be negative in DC */ + if (New < 0.0) New = 0.0; + } + return(New); +} + + + /* B3SOIDDlimit(vnew,vold) + * limits the per-iteration change of any absolute voltage value + */ + +double +B3SOIDDlimit(vnew, vold, limit, check) + double vnew; + double vold; + double limit; + int *check; +{ + double T0, T1; + + if (isnan (vnew) || isnan (vold)) + { + fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); + fprintf(stderr, "New prediction returns to 0.0!\n"); + vnew = 0.0; + *check = 1; + } + T0 = vnew - vold; + T1 = fabs(T0); + if (T1 > limit) { + if (T0 > 0.0) + vnew = vold + limit; + else + vnew = vold - limit; + *check = 1; + } + return vnew; +} + + + +int +B3SOIDDload(inModel,ckt) +GENmodel *inModel; +register CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +register int selfheat; + +double SourceSatCurrent, DrainSatCurrent, Gmin; +double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst; +double cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq; +double evbd, evbs, arg, sarg; +double delvbd, delvbs, delvds, delvgd, delvgs; +double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4; +double tol, PhiB, PhiBSW, MJ, MJSW, PhiBSWG, MJSWG; +double gcgdb, gcggb, gcgsb, gcgeb, gcgT; +double gcsdb, gcsgb, gcssb, gcseb, gcsT; +double gcddb, gcdgb, gcdsb, gcdeb, gcdT; +double gcbdb, gcbgb, gcbsb, gcbeb, gcbT; +double gcedb, gcegb, gcesb, gceeb, gceT; +double gcTt, gTtg, gTtb, gTte, gTtdp, gTtt, gTtsp; +double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact; +double vg, vd, vs, vp, ve, vb; +double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; +double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVfb_dT; +double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd, dVth_dT; +double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm; +double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, n, dn_dVb, Vtm; +double ExpArg, V0; +double ueff, dueff_dVg, dueff_dVd, dueff_dVb, dueff_dT; +double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0; +double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb, dEsatL_dT; +double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, dVdsat_dT, Vasat, dAlphaz_dVg, dAlphaz_dVb; +double dVasat_dVg, dVasat_dVb, dVasat_dVd, dVasat_dT; +double Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb, dVa_dT; +double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; +double One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; +double dVgdt_dVg, dVgdt_dVd, dVgdt_dVb; +double T0, dT0_dVg, dT0_dVd, dT0_dVb, dT0_dVc, dT0_dVe, dT0_dVrg, dT0_dT; +double T1, dT1_dVg, dT1_dVd, dT1_dVb, dT1_dVc, dT1_dVe, dT1_dT; +double T2, dT2_dVg, dT2_dVd, dT2_dVb, dT2_dVc, dT2_dVe, dT2_dT; +double T3, dT3_dVg, dT3_dVd, dT3_dVb, dT3_dVc, dT3_dVe, dT3_dT; +double T4, dT4_dVg, dT4_dVd, dT4_dVb, dT4_dVc, dT4_dVe, dT4_dT; +double T5, dT5_dVg, dT5_dVd, dT5_dVb, dT5_dVc, dT5_dVe, dT5_dT; +double T6, dT6_dVg, dT6_dVd, dT6_dVb, dT6_dVc, dT6_dVe, dT6_dT; +double T7, dT7_dVg, dT7_dVd, dT7_dVb; +double T8, dT8_dVg, dT8_dVd, dT8_dVb, dT8_dVc, dT8_dVe, dT8_dVrg; +double T9, dT9_dVg, dT9_dVd, dT9_dVb, dT9_dVc, dT9_dVe, dT9_dVrg; +double T10, dT10_dVg, dT10_dVb, dT10_dVd; +double T11, T12; +double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; +double T100, T101; +double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb, dVACLM_dT; +double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb, dVADIBL_dT; +double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb; +double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb; +double Delt_vth, dDelt_vth_dVb, dDelt_vth_dT; +double Theta0, dTheta0_dVb, Theta1, dTheta1_dVb; +double Thetarout, dThetarout_dVb, TempRatio, tmp1, tmp2, tmp3, tmp4; +double DIBL_Sft, dDIBL_Sft_dVd, DIBL_fact, Lambda, dLambda_dVg; +double Rout_Vgs_factor, dRout_Vgs_factor_dVg, dRout_Vgs_factor_dVb; +double dRout_Vgs_factor_dVd; +double tempv, a1; + +double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb, dVgsteff_dVe, dVgsteff_dT; +double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb, dVdseff_dT; +double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; +double diffVds, diffVdsCV; +double dAbulk_dVg, dn_dVd ; +double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb, dbeta_dT; +double gche, dgche_dVg, dgche_dVd, dgche_dVb, dgche_dT; +double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb, dfgche1_dT; +double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb, dfgche2_dT; +double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb, dIdl_dT; +double Ids, Gm, Gds, Gmb; +double CoxWovL; +double Rds, dRds_dVg, dRds_dVb, dRds_dT, WVCox, WVCoxRds; +double Vgst2Vtm, dVgst2Vtm_dT, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, dVdsatCV_dVb; +double Leff, Weff, dWeff_dVg, dWeff_dVb; +double AbulkCV, dAbulkCV_dVb; +double qgdo, qgso, cgdo, cgso; + +double dxpart, sxpart; + +struct b3soiddSizeDependParam *pParam; +int ByPass, Check, ChargeComputationNeeded, J, error, I; +double junk[50]; + +double gbbsp, gbbdp, gbbg, gbbb, gbbe, gbbp, gbbT; +double gddpsp, gddpdp, gddpg, gddpb, gddpe, gddpT; +double gsspsp, gsspdp, gsspg, gsspb, gsspe, gsspT; +double Gbpbs, Gbpgs, Gbpds, Gbpes, Gbpps, GbpT; +double vse, vde, ves, ved, veb, vge, delves, vedo, delved; +double vps, vpd, Vps, delvps; +double Vbd, Ves, Vesfb, sqrtXdep, DeltVthtemp, dDeltVthtemp_dT; +double Vbp, dVbp_dVp, dVbp_dVb, dVbp_dVg, dVbp_dVd, dVbp_dVe, dVbp_dT; +double Vpsdio, dVpsdio_dVg, dVpsdio_dVd, dVpsdio_dVe, dVpsdio_dVp, dVpsdio_dT; +double DeltVthw, dDeltVthw_dVb, dDeltVthw_dT; +double dVbseff_dVd, dVbseff_dVe, dVbseff_dT; +double dVdsat_dVc, dVasat_dVc, dVACLM_dVc, dVADIBL_dVc, dVa_dVc; +double dfgche1_dVc, dfgche2_dVc, dgche_dVc, dVdseff_dVc, dIdl_dVc; +double Gm0, Gds0, Gmb0, GmT0, Gmc, Gme, GmT, dVbseff_dVg; +double dDIBL_Sft_dVb, BjtA, dBjtA_dVd; +double diffVdsii ; +double Idgidl, Gdgidld, Gdgidlg, Isgidl, Gsgidlg; +double Gjsd, Gjss, Gjsb, GjsT, Gjdd, Gjdb, GjdT; +double Ibp, Iii, Giid, Giig, Giib, Giie, GiiT, Gcd, Gcb, GcT, ceqbody, ceqbodcon; +double gppg, gppdp, gppb, gppe, gppp, gppsp, gppT; +double delTemp, deldelTemp, Temp; +double ceqth, ceqqth; +double K1, WL; +double qjs, gcjsbs, gcjsT; +double qjd, gcjdbs, gcjdds, gcjdT; +double qge; +double ceqqe; +double ni, Eg, Cbox, Nfb, CboxWL; +double cjsbs; +double Qbf0, Qsicv, dVfbeff_dVrg, Cbe ; +double qinv, qgate, qbody, qdrn, qsrc, qsub, cqgate, cqbody, cqdrn, cqsub, cqtemp; +double Cgg, Cgd, Cgs, Cgb, Cge, Cdg, Cdd, Cds, Cdb, Qg, Qd; +double Csg, Csd, Css, Csb, Cse, Cbg, Cbd, Cbs, Cbb, Qs, Qb; +double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1; +double Vbs0t, dVbs0t_dT ; +double Vbs0 ,dVbs0_dVe, dVbs0_dT; +double Vbs0eff ,dVbs0eff_dVg ,dVbs0eff_dVd ,dVbs0eff_dVe, dVbs0eff_dT; +double Vbs0teff,dVbs0teff_dVg ,dVbs0teff_dVd, dVbs0teff_dVe, dVbs0teff_dT; +double Vbsdio, dVbsdio_dVg, dVbsdio_dVd, dVbsdio_dVe, dVbsdio_dVb, dVbsdio_dT; +double Vbseff0; +double Vthfd ,dVthfd_dVd ,dVthfd_dVe, dVthfd_dT; +double Vbs0mos ,dVbs0mos_dVe, dVbs0mos_dT; +double Vbsmos ,dVbsmos_dVg ,dVbsmos_dVb ,dVbsmos_dVd, dVbsmos_dVe, dVbsmos_dT; +double Abeff ,dAbeff_dVg ,dAbeff_dVb, dAbeff_dVc; +double Vcs ,dVcs_dVg ,dVcs_dVb ,dVcs_dVd ,dVcs_dVe, dVcs_dT; +double Xcsat ,dXcsat_dVg ,dXcsat_dVb, dXcsat_dVc; +double Vdsatii ,dVdsatii_dVg ,dVdsatii_dVd, dVdsatii_dVb, dVdsatii_dT; +double Vdseffii ,dVdseffii_dVg ,dVdseffii_dVd, dVdseffii_dVb, dVdseffii_dT; +double VcsCV ,dVcsCV_dVg ,dVcsCV_dVb ,dVcsCV_dVd ,dVcsCV_dVc ,dVcsCV_dVe; +double VdsCV ,dVdsCV_dVg ,dVdsCV_dVb ,dVdsCV_dVd ,dVdsCV_dVc; +double Phisc ,dPhisc_dVg ,dPhisc_dVb ,dPhisc_dVd, dPhisc_dVc; +double Phisd ,dPhisd_dVg ,dPhisd_dVb ,dPhisd_dVd, dPhisd_dVc; +double sqrtPhisc ,dsqrtPhisc_dVg ,dsqrtPhisc_dVb; +double sqrtPhisd ,dsqrtPhisd_dVg ,dsqrtPhisd_dVb; +double Xc ,dXc_dVg ,dXc_dVb ,dXc_dVd ,dXc_dVc; +double Ibjt ,dIbjt_dVb ,dIbjt_dVd ,dIbjt_dT; +double Ibs1 ,dIbs1_dVb ,dIbs1_dT; +double Ibs2 ,dIbs2_dVb ,dIbs2_dT; +double Ibs3 ,dIbs3_dVb ,dIbs3_dVd, dIbs3_dT; +double Ibs4 ,dIbs4_dVb ,dIbs4_dT; +double Ibd1 ,dIbd1_dVb ,dIbd1_dVd ,dIbd1_dT; +double Ibd2 ,dIbd2_dVb ,dIbd2_dVd ,dIbd2_dT; +double Ibd3 ,dIbd3_dVb ,dIbd3_dVd ,dIbd3_dT; +double Ibd4 ,dIbd4_dVb ,dIbd4_dVd ,dIbd4_dT; +double ExpVbs1, dExpVbs1_dVb, dExpVbs1_dT; +double ExpVbs2, dExpVbs2_dVb, dExpVbs2_dT; +double ExpVbs4, dExpVbs4_dVb, dExpVbs4_dT; +double ExpVbd1, dExpVbd1_dVb, dExpVbd1_dT; +double ExpVbd2, dExpVbd2_dVb, dExpVbd2_dT; +double ExpVbd4, dExpVbd4_dVb, dExpVbd4_dT; +double WTsi, NVtm1, NVtm2; +double Ic ,dIc_dVb ,dIc_dVd; +double Ibs ,dIbs_dVb ,dIbs_dVd ,dIbs_dVe; +double Ibd ,dIbd_dVb; +double Nomi ,dNomi_dVg ,dNomi_dVb ,dNomi_dVd ,dNomi_dVc; +double Denomi ,dDenomi_dVg ,dDenomi_dVd ,dDenomi_dVb ,dDenomi_dVc, dDenomi_dT; +double Qbf ,dQbf_dVg ,dQbf_dVb ,dQbf_dVd ,dQbf_dVc ,dQbf_dVe; +double Qsubs1 ,dQsubs1_dVg ,dQsubs1_dVb ,dQsubs1_dVd ,dQsubs1_dVc ,dQsubs1_dVe; +double Qsubs2 ,dQsubs2_dVg ,dQsubs2_dVb ,dQsubs2_dVd ,dQsubs2_dVc ,dQsubs2_dVe; +double Qsub0 ,dQsub0_dVg ,dQsub0_dVb ,dQsub0_dVd ; +double Qac0 ,dQac0_dVb ,dQac0_dVd; +double Qdep0 ,dQdep0_dVb; +double Qe1 , dQe1_dVg ,dQe1_dVb, dQe1_dVd, dQe1_dVe, dQe1_dT; +double Ce1g ,Ce1b ,Ce1d ,Ce1e, Ce1T; +double Ce2g ,Ce2b ,Ce2d ,Ce2e, Ce2T; +double Qe2 , dQe2_dVg ,dQe2_dVb, dQe2_dVd, dQe2_dVe, dQe2_dT; +double dQbf_dVrg, dQac0_dVrg, dQsub0_dVrg; +double dQsubs1_dVrg, dQsubs2_dVrg, dQbf0_dVe, dQbf0_dT; + +/* for self-heating */ +double vbi, vfbb, phi, sqrtPhi, Xdep0, jbjt, jdif, jrec, jtun, u0temp, vsattemp; +double rds0, ua, ub, uc; +double dvbi_dT, dvfbb_dT, djbjt_dT, djdif_dT, djrec_dT, djtun_dT, du0temp_dT; +double dvsattemp_dT, drds0_dT, dua_dT, dub_dT, duc_dT, dni_dT, dVtm_dT; +double dVfbeff_dT, dQac0_dT, dQsub0_dT, dQbf_dT, dVdsCV_dT, dPhisd_dT; +double dNomi_dT,dXc_dT,dQsubs1_dT,dQsubs2_dT, dVcsCV_dT, dPhisc_dT, dQsicv_dT; +double CbT, CsT, CgT, CeT; + +double Qex, dQex_dVg, dQex_dVb, dQex_dVd, dQex_dVe, dQex_dT; + +/* clean up last */ +FILE *fpdebug; +/* end clean up */ +int nandetect; +static int nanfound = 0; +char nanmessage [12]; + + + +for (; model != NULL; model = model->B3SOIDDnextModel) +{ for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { Check = 0; + ByPass = 0; + selfheat = (model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0 != 0.0); + pParam = here->pParam; + + if (here->B3SOIDDdebugMod > 3) + { + if (model->B3SOIDDtype > 0) + fpdebug = fopen("b3soiddn.log", "a"); + else + fpdebug = fopen("b3soiddp.log", "a"); + + fprintf(fpdebug, "******* Time : %.5e ******* Device: %s Iteration: %d\n", + ckt->CKTtime, here->B3SOIDDname, here->B3SOIDDiterations); + } + + if ((ckt->CKTmode & MODEINITSMSIG)) + { vbs = *(ckt->CKTstate0 + here->B3SOIDDvbs); + vgs = *(ckt->CKTstate0 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIDDves); + vps = *(ckt->CKTstate0 + here->B3SOIDDvps); + vds = *(ckt->CKTstate0 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIDDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIDDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIDDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIDDbNode); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... INIT SMSIG ...\n"); + } + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr,"DC op. point converge with %d iterations\n"); + } + } + else if ((ckt->CKTmode & MODEINITTRAN)) + { vbs = *(ckt->CKTstate1 + here->B3SOIDDvbs); + vgs = *(ckt->CKTstate1 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate1 + here->B3SOIDDves); + vps = *(ckt->CKTstate1 + here->B3SOIDDvps); + vds = *(ckt->CKTstate1 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate1 + here->B3SOIDDdeltemp); + + vg = *(ckt->CKTrhsOld + here->B3SOIDDgNode); + vd = *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime); + vs = *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime); + vp = *(ckt->CKTrhsOld + here->B3SOIDDpNode); + ve = *(ckt->CKTrhsOld + here->B3SOIDDeNode); + vb = *(ckt->CKTrhsOld + here->B3SOIDDbNode); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... Init Transient ....\n"); + } + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr, "Transient operation point converge with %d iterations\n", +here->B3SOIDDiterations); + } + here->B3SOIDDiterations = 0; + } + else if ((ckt->CKTmode & MODEINITJCT) && !here->B3SOIDDoff) + { vds = model->B3SOIDDtype * here->B3SOIDDicVDS; + vgs = model->B3SOIDDtype * here->B3SOIDDicVGS; + ves = model->B3SOIDDtype * here->B3SOIDDicVES; + vbs = model->B3SOIDDtype * here->B3SOIDDicVBS; + vps = model->B3SOIDDtype * here->B3SOIDDicVPS; + + vg = vd = vs = vp = ve = 0.0; + + here->B3SOIDDiterations = 0; /* initialize iteration number */ + + delTemp = 0.0; + here->B3SOIDDphi = pParam->B3SOIDDphi; + + + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "... INIT JCT ...\n"); + + if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && + ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | + MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) + { vbs = 0.0; + vgs = model->B3SOIDDtype*0.1 + pParam->B3SOIDDvth0; + vds = 0.0; + ves = 0.0; + vps = 0.0; + } + } + else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && + (here->B3SOIDDoff)) + { delTemp = vps = vbs = vgs = vds = ves = 0.0; + vg = vd = vs = vp = ve = 0.0; + here->B3SOIDDiterations = 0; /* initialize iteration number */ + } + else + { +#ifndef PREDICTOR + if ((ckt->CKTmode & MODEINITPRED)) + { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->B3SOIDDvbs) = + *(ckt->CKTstate1 + here->B3SOIDDvbs); + vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvbs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvbs))); + *(ckt->CKTstate0 + here->B3SOIDDvgs) = + *(ckt->CKTstate1 + here->B3SOIDDvgs); + vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvgs)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvgs))); + *(ckt->CKTstate0 + here->B3SOIDDves) = + *(ckt->CKTstate1 + here->B3SOIDDves); + ves = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDves)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDves))); + *(ckt->CKTstate0 + here->B3SOIDDvps) = + *(ckt->CKTstate1 + here->B3SOIDDvps); + vps = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvps)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvps))); + *(ckt->CKTstate0 + here->B3SOIDDvds) = + *(ckt->CKTstate1 + here->B3SOIDDvds); + vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDvds)) + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDvds))); + *(ckt->CKTstate0 + here->B3SOIDDvbd) = + *(ckt->CKTstate0 + here->B3SOIDDvbs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + + *(ckt->CKTstate0 + here->B3SOIDDvg) = *(ckt->CKTstate1 + here->B3SOIDDvg); + *(ckt->CKTstate0 + here->B3SOIDDvd) = *(ckt->CKTstate1 + here->B3SOIDDvd); + *(ckt->CKTstate0 + here->B3SOIDDvs) = *(ckt->CKTstate1 + here->B3SOIDDvs); + *(ckt->CKTstate0 + here->B3SOIDDvp) = *(ckt->CKTstate1 + here->B3SOIDDvp); + *(ckt->CKTstate0 + here->B3SOIDDve) = *(ckt->CKTstate1 + here->B3SOIDDve); + + /* Only predict ve */ + ve = (1.0 + xfact)* (*(ckt->CKTstate1 + here->B3SOIDDve)) + + - (xfact * (*(ckt->CKTstate2 + here->B3SOIDDve))); + /* Then update vg, vs, vb, vd, vp base on ve */ + vs = ve - model->B3SOIDDtype * ves; + vg = model->B3SOIDDtype * vgs + vs; + vd = model->B3SOIDDtype * vds + vs; + vb = model->B3SOIDDtype * vbs + vs; + vp = model->B3SOIDDtype * vps + vs; + + delTemp = (1.0 + xfact)* (*(ckt->CKTstate1 + + here->B3SOIDDdeltemp))-(xfact * (*(ckt->CKTstate2 + + here->B3SOIDDdeltemp))); + + if (selfheat) + { + here->B3SOIDDphi = 2.0 * here->B3SOIDDvtm + * log (pParam->B3SOIDDnpeak / + here->B3SOIDDni); + } + + if (here->B3SOIDDdebugMod > 0) + { + fprintf(stderr, "Time = %.6e converge with %d iterations\n", ckt->CKTtime, here->B3SOIDDiterations); + } + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... PREDICTOR calculation ....\n"); + } + here->B3SOIDDiterations = 0; + } + else + { +#endif /* PREDICTOR */ + + vg = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDgNode), + *(ckt->CKTstate0 + here->B3SOIDDvg), 3.0, &Check); + vd = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDdNodePrime), + *(ckt->CKTstate0 + here->B3SOIDDvd), 3.0, &Check); + vs = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), + *(ckt->CKTstate0 + here->B3SOIDDvs), 3.0, &Check); + vp = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDpNode), + *(ckt->CKTstate0 + here->B3SOIDDvp), 3.0, &Check); + ve = B3SOIDDlimit(*(ckt->CKTrhsOld + here->B3SOIDDeNode), + *(ckt->CKTstate0 + here->B3SOIDDve), 3.0, &Check); + delTemp = *(ckt->CKTrhsOld + here->B3SOIDDtempNode); + + vbs = model->B3SOIDDtype * (*(ckt->CKTrhsOld+here->B3SOIDDbNode) + - *(ckt->CKTrhsOld+here->B3SOIDDsNodePrime)); + + vps = model->B3SOIDDtype * (vp - vs); + vgs = model->B3SOIDDtype * (vg - vs); + ves = model->B3SOIDDtype * (ve - vs); + vds = model->B3SOIDDtype * (vd - vs); + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "... DC calculation ....\n"); +fprintf(fpdebug, "Vg = %.10f; Vb = %.10f; Vs = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDgNode), + *(ckt->CKTrhsOld + here->B3SOIDDbNode), + *(ckt->CKTrhsOld + here->B3SOIDDsNode)); +fprintf(fpdebug, "Vd = %.10f; Vsp = %.10f; Vdp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDdNode), + *(ckt->CKTrhsOld + here->B3SOIDDsNodePrime), + *(ckt->CKTrhsOld + here->B3SOIDDdNodePrime)); +fprintf(fpdebug, "Ve = %.10f; Vp = %.10f; delTemp = %.10f\n", + *(ckt->CKTrhsOld + here->B3SOIDDeNode), + *(ckt->CKTrhsOld + here->B3SOIDDpNode), + *(ckt->CKTrhsOld + here->B3SOIDDtempNode)); + + } + +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + vbd = vbs - vds; + vgd = vgs - vds; + ved = ves - vds; + vgdo = *(ckt->CKTstate0 + here->B3SOIDDvgs) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + vedo = *(ckt->CKTstate0 + here->B3SOIDDves) + - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvbs = vbs - *(ckt->CKTstate0 + here->B3SOIDDvbs); + delvbd = vbd - *(ckt->CKTstate0 + here->B3SOIDDvbd); + delvgs = vgs - *(ckt->CKTstate0 + here->B3SOIDDvgs); + delves = ves - *(ckt->CKTstate0 + here->B3SOIDDves); + delvps = vps - *(ckt->CKTstate0 + here->B3SOIDDvps); + deldelTemp = delTemp - *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + delvds = vds - *(ckt->CKTstate0 + here->B3SOIDDvds); + delvgd = vgd - vgdo; + delved = ved - vedo; + + if (here->B3SOIDDmode >= 0) + { + cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgs + + (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbs + + (here->B3SOIDDgme - here->B3SOIDDgjde) * delves + + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; + } + else + { + cdhat = here->B3SOIDDcd + (here->B3SOIDDgm-here->B3SOIDDgjdg) * delvgd + - (here->B3SOIDDgds - here->B3SOIDDgjdd) * delvds + + (here->B3SOIDDgmbs - here->B3SOIDDgjdb) * delvbd + + (here->B3SOIDDgme - here->B3SOIDDgjde) * delved + + (here->B3SOIDDgmT - here->B3SOIDDgjdT) * deldelTemp; + + } + cbhat = here->B3SOIDDcb + here->B3SOIDDgbgs * delvgs + + here->B3SOIDDgbbs * delvbs + here->B3SOIDDgbds * delvds + + here->B3SOIDDgbes * delves + here->B3SOIDDgbps * delvps + + here->B3SOIDDgbT * deldelTemp; + +#ifndef NOBYPASS + /* following should be one big if connected by && all over + * the place, but some C compilers can't handle that, so + * we split it up here to let them digest it in stages + */ + + if (here->B3SOIDDdebugMod > 3) + { +fprintf(fpdebug, "Convergent Criteria : vbs %d vds %d vgs %d ves %d vps %d temp %d\n", + ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol))) ? 1 : 0, + ((fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + ckt->CKTvoltTol*1e4))) ? 1 : 0); +fprintf(fpdebug, "delCd %.4e, delCb %.4e\n", fabs(cdhat - here->B3SOIDDcd) , + fabs(cbhat - here->B3SOIDDcb)); + + } + if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) && Check == 0) + if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbs))) + ckt->CKTvoltTol)) ) + if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), + fabs(*(ckt->CKTstate0+here->B3SOIDDvbd))) + ckt->CKTvoltTol)) ) + if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs), + fabs(*(ckt->CKTstate0+here->B3SOIDDvgs))) + ckt->CKTvoltTol))) + if ((fabs(delves) < (ckt->CKTreltol * MAX(fabs(ves), + fabs(*(ckt->CKTstate0+here->B3SOIDDves))) + ckt->CKTvoltTol))) + if ( (here->B3SOIDDbodyMod == 0) || (here->B3SOIDDbodyMod == 2) || + (fabs(delvps) < (ckt->CKTreltol * MAX(fabs(vps), + fabs(*(ckt->CKTstate0+here->B3SOIDDvps))) + ckt->CKTvoltTol)) ) + if ( (here->B3SOIDDtempNode == 0) || + (fabs(deldelTemp) < (ckt->CKTreltol * MAX(fabs(delTemp), + fabs(*(ckt->CKTstate0+here->B3SOIDDdeltemp))) + + ckt->CKTvoltTol*1e4))) + if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds), + fabs(*(ckt->CKTstate0+here->B3SOIDDvds))) + ckt->CKTvoltTol))) + if ((fabs(cdhat - here->B3SOIDDcd) < ckt->CKTreltol + * MAX(fabs(cdhat),fabs(here->B3SOIDDcd)) + ckt->CKTabstol)) + if ((fabs(cbhat - here->B3SOIDDcb) < ckt->CKTreltol + * MAX(fabs(cbhat),fabs(here->B3SOIDDcb)) + ckt->CKTabstol) ) + { /* bypass code */ + vbs = *(ckt->CKTstate0 + here->B3SOIDDvbs); + vbd = *(ckt->CKTstate0 + here->B3SOIDDvbd); + vgs = *(ckt->CKTstate0 + here->B3SOIDDvgs); + ves = *(ckt->CKTstate0 + here->B3SOIDDves); + vps = *(ckt->CKTstate0 + here->B3SOIDDvps); + vds = *(ckt->CKTstate0 + here->B3SOIDDvds); + delTemp = *(ckt->CKTstate0 + here->B3SOIDDdeltemp); + + /* calculate Vds for temperature conductance calculation + in bypass (used later when filling Temp node matrix) */ + Vds = here->B3SOIDDmode > 0 ? vds : -vds; + + vgd = vgs - vds; + vgb = vgs - vbs; + veb = ves - vbs; + + if (here->B3SOIDDdebugMod > 2) + { +fprintf(stderr, "Bypass for %s...\n", here->B3SOIDDname); + fprintf(fpdebug, "... By pass ....\n"); + fprintf(fpdebug, "vgs=%.4f, vds=%.4f, vbs=%.4f, ", + vgs, vds, vbs); + fprintf(fpdebug, "ves=%.4f, vps=%.4f\n", ves, vps); + } + if ((ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + { ByPass = 1; + goto line755; + } + else + { goto line850; + } + } + + +#endif /*NOBYPASS*/ + von = here->B3SOIDDvon; + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + here->B3SOIDDdum1 = here->B3SOIDDdum2 = here->B3SOIDDdum3 = 0.0; + here->B3SOIDDdum4 = here->B3SOIDDdum5 = 0.0; + Qac0 = Qsub0 = Qsubs1 = Qsubs2 = Qbf = Qe1 = Qe2 = 0.0; + qjs = qjd = Cbg = Cbb = Cbd = Cbe = Xc = qdrn = qgate = 0.0; + qbody = qsub = 0.0; + } + + if (here->B3SOIDDdebugMod > 2) { + fprintf(fpdebug, "Limited : vgs = %.8f\n", vgs); + fprintf(fpdebug, "Limited : vds = %.8f\n", vds); + } + + if (*(ckt->CKTstate0 + here->B3SOIDDvds) >= 0.0) + T0 = *(ckt->CKTstate0 + here->B3SOIDDvbs); + else + T0 = *(ckt->CKTstate0 + here->B3SOIDDvbd); + + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "Before lim : vbs = %.8f, after = ", T0); + + if (vds >= 0.0) + { + vbs = B3SOIDDlimit(vbs, T0, 0.2, &Check); + vbs = B3SOIDDSmartVbs(vbs, T0, here, ckt, &Check); + vbd = vbs - vds; + vb = model->B3SOIDDtype * vbs + vs; + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbs); + } else + { + vbd = B3SOIDDlimit(vbd, T0, 0.2, &Check); + vbd = B3SOIDDSmartVbs(vbd, T0, here, ckt, &Check); + vbs = vbd + vds; + vb = model->B3SOIDDtype * vbs + vd; + if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "%.8f\n", vbd); + } + + delTemp =B3SOIDDlimit(delTemp, *(ckt->CKTstate0 + here->B3SOIDDdeltemp),5.0,&Check); + + } + +/* Calculate temperature dependent values for self-heating effect */ + Temp = delTemp + ckt->CKTtemp; +/* for debugging + Temp = ckt->CKTtemp; + selfheat = 1; + if (here->B3SOIDDname[1] == '2') + { + Temp += 0.01; + } */ + TempRatio = Temp / model->B3SOIDDtnom; + + if (selfheat) { + Vtm = KboQ * Temp; + + T0 = 1108.0 + Temp; + T5 = Temp * Temp; + Eg = 1.16 - 7.02e-4 * T5 / T0; + T1 = ((7.02e-4 * T5) - T0 * (14.04e-4 * Temp)) / T0 / T0; + /* T1 = dEg / dT */ + + T2 = 1.9230584e-4; /* T2 = 1 / 300.15^(3/2) */ + T5 = sqrt(Temp); + T3 = 1.45e10 * Temp * T5 * T2; + T4 = exp(21.5565981 - Eg / (2.0 * Vtm)); + ni = T3 * T4; + dni_dT = 2.175e10 * T2 * T5 * T4 + T3 * T4 * + (-Vtm * T1 + Eg * KboQ) / (2.0 * Vtm * Vtm); + + T0 = log(1.0e20 * pParam->B3SOIDDnpeak / (ni * ni)); + vbi = Vtm * T0; + dvbi_dT = KboQ * T0 + Vtm * (-2.0 * dni_dT / ni); + + if (pParam->B3SOIDDnsub > 0) { + T0 = log(pParam->B3SOIDDnpeak / pParam->B3SOIDDnsub); + vfbb = -model->B3SOIDDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIDDtype * KboQ*T0; + } + else { + T0 = log(-pParam->B3SOIDDnpeak*pParam->B3SOIDDnsub/ni/ni); + vfbb = -model->B3SOIDDtype * Vtm*T0; + dvfbb_dT = -model->B3SOIDDtype * + (KboQ * T0 + Vtm * 2.0 * dni_dT / ni); + } + +/* phi = 2.0 * Vtm * log(pParam->B3SOIDDnpeak / ni); */ + phi = here->B3SOIDDphi; + sqrtPhi = sqrt(phi); + Xdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIDDnpeak * 1.0e6)) + * sqrtPhi; + /* Save the values below for phi calculation in B3SOIDDaccept() */ + here->B3SOIDDvtm = Vtm; + here->B3SOIDDni = ni; + + /* Use dTx_dVe variables to act as dTx_dT variables */ + + T8 = 1 / model->B3SOIDDtnom; + T7 = model->B3SOIDDxbjt / pParam->B3SOIDDndiode; + T0 = pow(TempRatio, T7); + dT0_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIDDxdif / pParam->B3SOIDDndiode; + T1 = pow(TempRatio, T7); + dT1_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T7 = model->B3SOIDDxrec / pParam->B3SOIDDndiode / 2.0; + T2 = pow(TempRatio, T7); + dT2_dVe = T7 * pow(TempRatio, T7 - 1.0) * T8; + + T3 = TempRatio - 1.0; + T4 = Eg300 / pParam->B3SOIDDndiode / Vtm * T3; + dT4_dVe = Eg300 / pParam->B3SOIDDndiode / Vtm / Vtm * + (Vtm * T8 - T3 * KboQ); + T5 = exp(T4); + dT5_dVe = dT4_dVe * T5; + T6 = sqrt(T5); + dT6_dVe = 0.5 / T6 * dT5_dVe; + + jbjt = pParam->B3SOIDDisbjt * T0 * T5; + jdif = pParam->B3SOIDDisdif * T1 * T5; + jrec = pParam->B3SOIDDisrec * T2 * T6; + djbjt_dT = pParam->B3SOIDDisbjt * (T0 * dT5_dVe + T5 * dT0_dVe); + djdif_dT = pParam->B3SOIDDisdif * (T1 * dT5_dVe + T5 * dT1_dVe); + djrec_dT = pParam->B3SOIDDisrec * (T2 * dT6_dVe + T6 * dT2_dVe); + + T7 = model->B3SOIDDxtun / pParam->B3SOIDDntun; + T0 = pow(TempRatio, T7); + jtun = model->B3SOIDDistun * T0; + djtun_dT = model->B3SOIDDistun * T7 * pow(TempRatio, T7 - 1.0) * T8; + + u0temp = pParam->B3SOIDDu0 * pow(TempRatio, pParam->B3SOIDDute); + du0temp_dT = pParam->B3SOIDDu0 * pParam->B3SOIDDute * + pow(TempRatio, pParam->B3SOIDDute - 1.0) * T8; + + vsattemp = pParam->B3SOIDDvsat - pParam->B3SOIDDat * T3; + dvsattemp_dT = -pParam->B3SOIDDat * T8; + + rds0 = (pParam->B3SOIDDrdsw + pParam->B3SOIDDprt + * T3) / pParam->B3SOIDDrds0denom; + drds0_dT = pParam->B3SOIDDprt / pParam->B3SOIDDrds0denom * T8; + + ua = pParam->B3SOIDDuatemp + pParam->B3SOIDDua1 * T3; + ub = pParam->B3SOIDDubtemp + pParam->B3SOIDDub1 * T3; + uc = pParam->B3SOIDDuctemp + pParam->B3SOIDDuc1 * T3; + dua_dT = pParam->B3SOIDDua1 * T8; + dub_dT = pParam->B3SOIDDub1 * T8; + duc_dT = pParam->B3SOIDDuc1 * T8; + } + else { + vbi = pParam->B3SOIDDvbi; + vfbb = pParam->B3SOIDDvfbb; + phi = pParam->B3SOIDDphi; + sqrtPhi = pParam->B3SOIDDsqrtPhi; + Xdep0 = pParam->B3SOIDDXdep0; + jbjt = pParam->B3SOIDDjbjt; + jdif = pParam->B3SOIDDjdif; + jrec = pParam->B3SOIDDjrec; + jtun = pParam->B3SOIDDjtun; + u0temp = pParam->B3SOIDDu0temp; + vsattemp = pParam->B3SOIDDvsattemp; + rds0 = pParam->B3SOIDDrds0; + ua = pParam->B3SOIDDua; + ub = pParam->B3SOIDDub; + uc = pParam->B3SOIDDuc; + dni_dT = dvbi_dT = dvfbb_dT = djbjt_dT = djdif_dT = 0.0; + djrec_dT = djtun_dT = du0temp_dT = dvsattemp_dT = 0.0; + drds0_dT = dua_dT = dub_dT = duc_dT = 0.0; + } + + /* TempRatio used for Vth and mobility */ + if (selfheat) { + TempRatio = Temp / model->B3SOIDDtnom - 1.0; + } + else { + TempRatio = ckt->CKTtemp / model->B3SOIDDtnom - 1.0; + } + + /* determine DC current and derivatives */ + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + ved = ves - vds; + veb = ves - vbs; + vge = vgs - ves; + vpd = vps - vds; + + + if (vds >= 0.0) + { /* normal mode */ + here->B3SOIDDmode = 1; + Vds = vds; + Vgs = vgs; + Vbs = vbs; + Vbd = vbd; + Ves = ves; + Vps = vps; + } + else + { /* inverse mode */ + here->B3SOIDDmode = -1; + Vds = -vds; + Vgs = vgd; + Vbs = vbd; + Vbd = vbs; + Ves = ved; + Vps = vpd; + } + + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "Vgs=%.4f, Vds=%.4f, Vbs=%.4f, ", + Vgs, Vds, Vbs); + fprintf(fpdebug, "Ves=%.4f, Vps=%.4f, Temp=%.1f\n", + Ves, Vps, Temp); + } + + Vesfb = Ves - vfbb; + Cbox = model->B3SOIDDcbox; + K1 = pParam->B3SOIDDk1; + + ChargeComputationNeeded = + ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + ? 1 : 0; + + if (here->B3SOIDDdebugMod == -1) + ChargeComputationNeeded = 1; + + + + +/* Poly Gate Si Depletion Effect */ + T0 = pParam->B3SOIDDvfb + phi; + if ((pParam->B3SOIDDngate > 1.e18) && (pParam->B3SOIDDngate < 1.e25) + && (Vgs > T0)) + /* added to avoid the problem caused by ngate */ + { T1 = 1.0e6 * Charge_q * EPSSI * pParam->B3SOIDDngate + / (model->B3SOIDDcox * model->B3SOIDDcox); + T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1); + T2 = T1 * (T4 - 1.0); + T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */ + T7 = 1.12 - T3 - 0.05; + T6 = sqrt(T7 * T7 + 0.224); + T5 = 1.12 - 0.5 * (T7 + T6); + Vgs_eff = Vgs - T5; + dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); + } + else + { Vgs_eff = Vgs; + dVgs_eff_dVg = 1.0; + } + + + Leff = pParam->B3SOIDDleff; + + if (selfheat) { + Vtm = KboQ * Temp; + dVtm_dT = KboQ; + } + else { + Vtm = model->B3SOIDDvtm; + dVtm_dT = 0.0; + } + + V0 = vbi - phi; + +/* Prepare Vbs0t */ + T0 = -pParam->B3SOIDDdvbd1 * pParam->B3SOIDDleff / pParam->B3SOIDDlitl; + T1 = pParam->B3SOIDDdvbd0 * (exp(0.5*T0) + 2*exp(T0)); + T2 = T1 * (vbi - phi); + T3 = 0.5 * model->B3SOIDDqsi / model->B3SOIDDcsi; + Vbs0t = phi - T3 + pParam->B3SOIDDvbsa + T2; + if (selfheat) + dVbs0t_dT = T1 * dvbi_dT; + else + dVbs0t_dT = 0.0; + +/* Prepare Vbs0 */ + T0 = 1 + model->B3SOIDDcsieff / Cbox; + T1 = pParam->B3SOIDDkb1 / T0; + T2 = T1 * (Vbs0t - Vesfb); + + /* T6 is Vbs0 before limiting */ + T6 = Vbs0t - T2; + dT6_dVe = T1; + if (selfheat) + dT6_dT = dVbs0t_dT - T1 * (dVbs0t_dT + dvfbb_dT); + else + dT6_dT = 0.0; + + /* limit Vbs0 to below phi */ + T1 = phi - pParam->B3SOIDDdelp; + T2 = T1 - T6 - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff); + Vbs0 = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbs0_dVe = T4 * dT6_dVe; + if (selfheat) dVbs0_dT = T4 * dT6_dT; + else dVbs0_dT = 0.0; + + T1 = Vbs0t - Vbs0 - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T4 = T3 * model->B3SOIDDcsieff / model->B3SOIDDqsieff; + Vbs0mos = Vbs0 - 0.5 * T3 * T4; + T5 = 0.5 * T4 * (1 + T1 / T2); + dVbs0mos_dVe = dVbs0_dVe * (1 + T5); + if (selfheat) + dVbs0mos_dT = dVbs0_dT - (dVbs0t_dT - dVbs0_dT) * T5; + else + dVbs0mos_dT = 0.0; + +/* Prepare Vthfd - treat Vbs0mos as if it were independent variable Vb */ + Phis = phi - Vbs0mos; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + sqrtXdep = sqrt(Xdep); + + T0 = pParam->B3SOIDDdvt2 * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2; + } + else /* Added to avoid any discontinuity problems caused by dvt2*/ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2 * T4 * T4; + } + lt1 = model->B3SOIDDfactor1 * sqrtXdep * T1; + dlt1_dVb = model->B3SOIDDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = pParam->B3SOIDDdvt2w * Vbs0mos; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2w; + } + else /* Added to avoid any discontinuity problems caused by + dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2w * T4 * T4; + } + ltw= model->B3SOIDDfactor1 * sqrtXdep * T1; + dltw_dVb = model->B3SOIDDfactor1 * (0.5 / sqrtXdep * T1 * dXdep_dVb + + sqrtXdep * T2); + + T0 = -0.5 * pParam->B3SOIDDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + here->B3SOIDDthetavth = pParam->B3SOIDDdvt0 * Theta0; + Delt_vth = here->B3SOIDDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIDDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIDDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5*pParam->B3SOIDDdvt1w * pParam->B3SOIDDweff*Leff/ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + T0 = pParam->B3SOIDDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIDDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIDDnlx / Leff); + T1 = (pParam->B3SOIDDkt1 + pParam->B3SOIDDkt1l / Leff + + pParam->B3SOIDDkt2 * Vbs0mos); + DeltVthtemp = pParam->B3SOIDDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) dDeltVthtemp_dT = T1 / model->B3SOIDDtnom; + else dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIDDtox * phi + / (pParam->B3SOIDDweff + pParam->B3SOIDDw0); + + T3 = pParam->B3SOIDDeta0 + pParam->B3SOIDDetab * Vbs0mos; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIDDetab; + dT3_dVb = T4; + } + else + { + dT3_dVb = pParam->B3SOIDDetab; + } + DIBL_Sft = T3 * pParam->B3SOIDDtheta0vb0 * Vds; + dDIBL_Sft_dVd = T3 * pParam->B3SOIDDtheta0vb0; + dDIBL_Sft_dVb = pParam->B3SOIDDtheta0vb0 * Vds * dT3_dVb; + + Vthfd = model->B3SOIDDtype * pParam->B3SOIDDvth0 + pParam->B3SOIDDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIDDk2 + * Vbs0mos-Delt_vth-DeltVthw +(pParam->B3SOIDDk3 +pParam->B3SOIDDk3b + * Vbs0mos) * tmp2 + DeltVthtemp - DIBL_Sft; + + T6 = pParam->B3SOIDDk3b * tmp2 - pParam->B3SOIDDk2 + + pParam->B3SOIDDkt2 * TempRatio; + dVthfd_dVd = -dDIBL_Sft_dVd; + T7 = pParam->B3SOIDDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; + dVthfd_dVe = T7 * dVbs0mos_dVe; + if (selfheat) + dVthfd_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT + + T7 * dVbs0mos_dT; + else + dVthfd_dT = 0.0; + +/* Effective Vbs0 and Vbs0t for all Vgs */ + T1 = Vthfd - Vgs_eff - DELT_Vbs0eff; + T2 = sqrt(T1 * T1 + DELT_Vbs0eff * DELT_Vbs0eff ); + + Vbs0teff = Vbs0t - 0.5 * (T1 + T2); + dVbs0teff_dVg = 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0teff_dVd = - 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0teff_dVe = - 0.5 * (1 + T1 / T2) * dVthfd_dVe; + if (selfheat) + dVbs0teff_dT = dVbs0t_dT - 0.5 * (1 + T1 / T2) * dVthfd_dT; + else + dVbs0teff_dT = 0.0; + + /* Calculate nfb */ + T3 = 1 / (K1 * K1); + T4 = pParam->B3SOIDDkb3 * Cbox / model->B3SOIDDcox; + T8 = sqrt(phi - Vbs0mos); + T5 = sqrt(1 + 4 * T3 * (phi + K1 * T8 - Vbs0mos)); + T6 = 1 + T4 * T5; + Nfb = model->B3SOIDDnfb = 1 / T6; + T7 = 2 * T3 * T4 * Nfb * Nfb / T5 * (0.5 * K1 / T8 + 1); + Vbs0eff = Vbs0 - Nfb * 0.5 * (T1 + T2); + dVbs0eff_dVg = Nfb * 0.5 * (1 + T1/T2) * dVgs_eff_dVg; + dVbs0eff_dVd = - Nfb * 0.5 * (1 + T1 / T2) * dVthfd_dVd; + dVbs0eff_dVe = dVbs0_dVe - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dVe - T7 * 0.5 * (T1 + T2) * dVbs0mos_dVe; + if (selfheat) + dVbs0eff_dT = dVbs0_dT - Nfb * 0.5 * (1 + T1 / T2) + * dVthfd_dT - T7 * 0.5 * (T1 + T2) * dVbs0mos_dT; + else + dVbs0eff_dT = 0.0; + +/* Simple check of Vbs */ +/* Prepare Vbsdio */ + T1 = Vbs - (Vbs0eff + OFF_Vbsdio) - DELT_Vbsdio; + T2 = sqrt(T1*T1 + DELT_Vbsdio * DELT_Vbsdio); + T3 = 0.5 * (1 + T1/T2); + + Vbsdio = Vbs0eff + OFF_Vbsdio + 0.5 * (T1 + T2); + dVbsdio_dVg = (1 - T3) * dVbs0eff_dVg; + dVbsdio_dVd = (1 - T3) * dVbs0eff_dVd; + dVbsdio_dVe = (1 - T3) * dVbs0eff_dVe; + if (selfheat) dVbsdio_dT = (1 - T3) * dVbs0eff_dT; + else dVbsdio_dT = 0.0; + dVbsdio_dVb = T3; + +/* Prepare Vbseff */ + T1 = Vbs0teff - Vbsdio - DELT_Vbsmos; + T2 = sqrt(T1 * T1 + DELT_Vbsmos * DELT_Vbsmos); + T3 = 0.5 * (T1 + T2); + T5 = 0.5 * (1 + T1/T2); + dT3_dVg = T5 * (dVbs0teff_dVg - dVbsdio_dVg); + dT3_dVd = T5 * (dVbs0teff_dVd - dVbsdio_dVd); + dT3_dVb = - T5 * dVbsdio_dVb; + dT3_dVe = T5 * (dVbs0teff_dVe - dVbsdio_dVe); + if (selfheat) dT3_dT = T5 * (dVbs0teff_dT - dVbsdio_dT); + else dT3_dT = 0.0; + T4 = T3 * model->B3SOIDDcsieff / model->B3SOIDDqsieff; + + Vbsmos = Vbsdio - 0.5 * T3 * T4; + dVbsmos_dVg = dVbsdio_dVg - T4 * dT3_dVg; + dVbsmos_dVd = dVbsdio_dVd - T4 * dT3_dVd; + dVbsmos_dVb = dVbsdio_dVb - T4 * dT3_dVb; + dVbsmos_dVe = dVbsdio_dVe - T4 * dT3_dVe; + if (selfheat) dVbsmos_dT = dVbsdio_dT - T4 * dT3_dT; + else dVbsmos_dT = 0.0; + +/* Prepare Vcs */ + Vcs = Vbsdio - Vbs0eff; + dVcs_dVb = dVbsdio_dVb; + dVcs_dVg = dVbsdio_dVg - dVbs0eff_dVg; + dVcs_dVd = dVbsdio_dVd - dVbs0eff_dVd; + dVcs_dVe = dVbsdio_dVe - dVbs0eff_dVe; + dVcs_dT = dVbsdio_dT - dVbs0eff_dT; + +/* Check Vps */ + /* Note : if Vps is less Vbs0eff => non-physical */ + T1 = Vps - Vbs0eff + DELT_Vbs0dio; + T2 = sqrt(T1 * T1 + DELT_Vbs0dio * DELT_Vbs0dio); + T3 = 0.5 * (1 + T1/T2); + Vpsdio = Vbs0eff + 0.5 * (T1 + T2); + dVpsdio_dVg = (1 - T3) * dVbs0eff_dVg; + dVpsdio_dVd = (1 - T3) * dVbs0eff_dVd; + dVpsdio_dVe = (1 - T3) * dVbs0eff_dVe; + if (selfheat) dVpsdio_dT = (1 - T3) * dVbs0eff_dT; + else dVpsdio_dT = 0.0; + dVpsdio_dVp = T3; + Vbp = Vbsdio - Vpsdio; + dVbp_dVb = dVbsdio_dVb; + dVbp_dVg = dVbsdio_dVg - dVpsdio_dVg; + dVbp_dVd = dVbsdio_dVd - dVpsdio_dVd; + dVbp_dVe = dVbsdio_dVe - dVpsdio_dVe; + dVbp_dT = dVbsdio_dT - dVpsdio_dT; + dVbp_dVp = - dVpsdio_dVp; + + here->B3SOIDDvbsdio = Vbsdio; + here->B3SOIDDvbs0eff = Vbs0eff; + + T1 = phi - pParam->B3SOIDDdelp; + T2 = T1 - Vbsmos - DELT_Vbseff; + T3 = sqrt(T2 * T2 + 4.0 * DELT_Vbseff * T1); + Vbseff = T1 - 0.5 * (T2 + T3); + T4 = 0.5 * (1 + T2/T3); + dVbseff_dVg = T4 * dVbsmos_dVg; + dVbseff_dVd = T4 * dVbsmos_dVd; + dVbseff_dVb = T4 * dVbsmos_dVb; + dVbseff_dVe = T4 * dVbsmos_dVe; + if (selfheat) dVbseff_dT = T4 * dVbsmos_dT; + else dVbseff_dT = 0.0; + + here->B3SOIDDvbseff = Vbseff; + + Phis = phi - Vbseff; + dPhis_dVb = -1; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis ; + + Xdep = Xdep0 * sqrtPhis / sqrtPhi; + dXdep_dVb = (Xdep0 / sqrtPhi) + * dsqrtPhis_dVb; + +/* Vth Calculation */ + T3 = sqrt(Xdep); + + T0 = pParam->B3SOIDDdvt2 * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2 ; + } + else /* Added to avoid any discontinuity problems caused by dvt2 */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2 * T4 * T4 ; + } + lt1 = model->B3SOIDDfactor1 * T3 * T1; + dlt1_dVb =model->B3SOIDDfactor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = pParam->B3SOIDDdvt2w * Vbseff; + if (T0 >= - 0.5) + { T1 = 1.0 + T0; + T2 = pParam->B3SOIDDdvt2w ; + } + else /* Added to avoid any discontinuity problems caused by dvt2w */ + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->B3SOIDDdvt2w * T4 * T4 ; + } + ltw= model->B3SOIDDfactor1 * T3 * T1; + dltw_dVb=model->B3SOIDDfactor1*(0.5 / T3 * T1 * dXdep_dVb + T3 * T2); + + T0 = -0.5 * pParam->B3SOIDDdvt1 * Leff / lt1; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + Theta0 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb; + dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + Theta0 = T1 * (1.0 + 2.0 * T1); + dTheta0_dVb = 0.0; + } + + here->B3SOIDDthetavth = pParam->B3SOIDDdvt0 * Theta0; + Delt_vth = here->B3SOIDDthetavth * V0; + dDelt_vth_dVb = pParam->B3SOIDDdvt0 * dTheta0_dVb * V0; + if (selfheat) dDelt_vth_dT = here->B3SOIDDthetavth * dvbi_dT; + else dDelt_vth_dT = 0.0; + + T0 = -0.5 * pParam->B3SOIDDdvt1w * pParam->B3SOIDDweff * Leff / ltw; + if (T0 > -EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 * (1.0 + 2.0 * T1); + dT1_dVb = -T0 / ltw * T1 * dltw_dVb; + dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb; + } + else + { T1 = MIN_EXP; + T2 = T1 * (1.0 + 2.0 * T1); + dT2_dVb = 0.0; + } + + T0 = pParam->B3SOIDDdvt0w * T2; + DeltVthw = T0 * V0; + dDeltVthw_dVb = pParam->B3SOIDDdvt0w * dT2_dVb * V0; + if (selfheat) dDeltVthw_dT = T0 * dvbi_dT; + else dDeltVthw_dT = 0.0; + + T0 = sqrt(1.0 + pParam->B3SOIDDnlx / Leff); + T1 = (pParam->B3SOIDDkt1 + pParam->B3SOIDDkt1l / Leff + + pParam->B3SOIDDkt2 * Vbseff); + DeltVthtemp = pParam->B3SOIDDk1 * (T0 - 1.0) * sqrtPhi + T1 * TempRatio; + if (selfheat) + dDeltVthtemp_dT = T1 / model->B3SOIDDtnom; + else + dDeltVthtemp_dT = 0.0; + + tmp2 = model->B3SOIDDtox * phi + / (pParam->B3SOIDDweff + pParam->B3SOIDDw0); + + T3 = pParam->B3SOIDDeta0 + pParam->B3SOIDDetab * Vbseff; + if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */ + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9 * pParam->B3SOIDDetab; + dT3_dVb = T4 ; + } + else + { + dT3_dVb = pParam->B3SOIDDetab ; + } + DIBL_Sft = T3 * pParam->B3SOIDDtheta0vb0 * Vds; + dDIBL_Sft_dVd = pParam->B3SOIDDtheta0vb0 * T3; + dDIBL_Sft_dVb = pParam->B3SOIDDtheta0vb0 * Vds * dT3_dVb; + + Vth = model->B3SOIDDtype * pParam->B3SOIDDvth0 + pParam->B3SOIDDk1 + * (sqrtPhis - sqrtPhi) - pParam->B3SOIDDk2 + * Vbseff- Delt_vth - DeltVthw +(pParam->B3SOIDDk3 + pParam->B3SOIDDk3b + * Vbseff) * tmp2 + DeltVthtemp - DIBL_Sft; + + here->B3SOIDDvon = Vth; + + T6 = pParam->B3SOIDDk3b * tmp2 - pParam->B3SOIDDk2 + + pParam->B3SOIDDkt2 * TempRatio; + dVth_dVb = pParam->B3SOIDDk1 * dsqrtPhis_dVb + - dDelt_vth_dVb - dDeltVthw_dVb + + T6 - dDIBL_Sft_dVb; /* this is actually dVth_dVbseff */ + dVth_dVd = -dDIBL_Sft_dVd; + if (selfheat) dVth_dT = dDeltVthtemp_dT - dDelt_vth_dT - dDeltVthw_dT; + else dVth_dT = 0.0; + +/* Calculate n */ + T2 = pParam->B3SOIDDnfactor * EPSSI / Xdep; + dT2_dVb = - T2 / Xdep * dXdep_dVb; + + T3 = pParam->B3SOIDDcdsc + pParam->B3SOIDDcdscb * Vbseff + + pParam->B3SOIDDcdscd * Vds; + dT3_dVb = pParam->B3SOIDDcdscb; + dT3_dVd = pParam->B3SOIDDcdscd; + + T4 = (T2 + T3 * Theta0 + pParam->B3SOIDDcit) / model->B3SOIDDcox; + dT4_dVb = (dT2_dVb + Theta0 * dT3_dVb + dTheta0_dVb * T3) + / model->B3SOIDDcox; + dT4_dVd = Theta0 * dT3_dVd / model->B3SOIDDcox; + + if (T4 >= -0.5) + { n = 1.0 + T4; + dn_dVb = dT4_dVb; + dn_dVd = dT4_dVd; + } + else + /* avoid discontinuity problems caused by T4 */ + { T0 = 1.0 / (3.0 + 8.0 * T4); + n = (1.0 + 3.0 * T4) * T0; + T0 *= T0; + dn_dVb = T0 * dT4_dVb; + dn_dVd = T0 * dT4_dVd; + } + +/* Effective Vgst (Vgsteff) Calculation */ + + Vgst = Vgs_eff - Vth; + + T10 = 2.0 * n * Vtm; + VgstNVt = Vgst / T10; + ExpArg = (2.0 * pParam->B3SOIDDvoff - Vgst) / T10; + + /* MCJ: Very small Vgst */ + if (VgstNVt > EXP_THRESHOLD) + { Vgsteff = Vgst; + /* T0 is dVgsteff_dVbseff */ + T0 = -dVth_dVb; + dVgsteff_dVg = dVgs_eff_dVg + T0 * dVbseff_dVg; + dVgsteff_dVd = -dVth_dVd + T0 * dVbseff_dVd; + dVgsteff_dVb = T0 * dVbseff_dVb; + dVgsteff_dVe = T0 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -dVth_dT + T0 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else if (ExpArg > EXP_THRESHOLD) + { T0 = (Vgst - pParam->B3SOIDDvoff) / (n * Vtm); + ExpVgst = exp(T0); + Vgsteff = Vtm * pParam->B3SOIDDcdep0 / model->B3SOIDDcox * ExpVgst; + T3 = Vgsteff / (n * Vtm) ; + /* T1 is dVgsteff_dVbseff */ + T1 = -T3 * (dVth_dVb + T0 * Vtm * dn_dVb); + dVgsteff_dVg = T3 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVd = -T3 * (dVth_dVd + T0 * Vtm * dn_dVd) + T1 * dVbseff_dVd; + dVgsteff_dVe = T1 * dVbseff_dVe; + dVgsteff_dVb = T1 * dVbseff_dVb; + if (selfheat) + dVgsteff_dT = -T3 * (dVth_dT + T0 * dVtm_dT * n) + + Vgsteff / Temp + T1 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + else + { ExpVgst = exp(VgstNVt); + T1 = T10 * log(1.0 + ExpVgst); + dT1_dVg = ExpVgst / (1.0 + ExpVgst); + dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + + T1 / n * dn_dVb; + dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + + T1 / n * dn_dVd; + T3 = (1.0 / Temp); + if (selfheat) + dT1_dT = -dT1_dVg * (dVth_dT + Vgst * T3) + T1 * T3; + else + dT1_dT = 0.0; + + dT2_dVg = -model->B3SOIDDcox / (Vtm * pParam->B3SOIDDcdep0) + * exp(ExpArg); + T2 = 1.0 - T10 * dT2_dVg; + dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + + (T2 - 1.0) / n * dn_dVd; + dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + + (T2 - 1.0) / n * dn_dVb; + if (selfheat) + dT2_dT = -dT2_dVg * (dVth_dT - ExpArg * T10 * T3); + else + dT2_dT = 0.0; + + Vgsteff = T1 / T2; + T3 = T2 * T2; + /* T4 is dVgsteff_dVbseff */ + T4 = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; + dVgsteff_dVb = T4 * dVbseff_dVb; + dVgsteff_dVe = T4 * dVbseff_dVe; + dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg + + T4 * dVbseff_dVg; + dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3 + T4 * dVbseff_dVd; + if (selfheat) + dVgsteff_dT = (T2 * dT1_dT - T1 * dT2_dT) / T3 + T4 * dVbseff_dT; + else + dVgsteff_dT = 0.0; + } + Vgst2Vtm = Vgsteff + 2.0 * Vtm; + if (selfheat) dVgst2Vtm_dT = 2.0 * dVtm_dT; + else dVgst2Vtm_dT = 0.0; + +/* Calculate Effective Channel Geometry */ + T9 = sqrtPhis - sqrtPhi; + Weff = pParam->B3SOIDDweff - 2.0 * (pParam->B3SOIDDdwg * Vgsteff + + pParam->B3SOIDDdwb * T9); + dWeff_dVg = -2.0 * pParam->B3SOIDDdwg; + dWeff_dVb = -2.0 * pParam->B3SOIDDdwb * dsqrtPhis_dVb; + + if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff*/ + { T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; + dWeff_dVg *= T0; + dWeff_dVb *= T0; + } + + T0 = pParam->B3SOIDDprwg * Vgsteff + pParam->B3SOIDDprwb * T9; + if (T0 >= -0.9) + { Rds = rds0 * (1.0 + T0); + dRds_dVg = rds0 * pParam->B3SOIDDprwg; + dRds_dVb = rds0 * pParam->B3SOIDDprwb * dsqrtPhis_dVb; + if (selfheat) dRds_dT = (1.0 + T0) * drds0_dT; + else dRds_dT = 0.0; + } + else + /* to avoid the discontinuity problem due to prwg and prwb*/ + { T1 = 1.0 / (17.0 + 20.0 * T0); + Rds = rds0 * (0.8 + T0) * T1; + T1 *= T1; + dRds_dVg = rds0 * pParam->B3SOIDDprwg * T1; + dRds_dVb = rds0 * pParam->B3SOIDDprwb * dsqrtPhis_dVb + * T1; + if (selfheat) dRds_dT = (0.8 + T0) * T1 * drds0_dT; + else dRds_dT = 0.0; + } + +/* Calculate Abulk */ + if (pParam->B3SOIDDa0 == 0.0) + { + Abulk0 = Abulk = dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; + } + else + { + T1 = 0.5 * pParam->B3SOIDDk1 / sqrtPhi; + T9 = sqrt(model->B3SOIDDxj * Xdep); + tmp1 = Leff + 2.0 * T9; + T5 = Leff / tmp1; + tmp2 = pParam->B3SOIDDa0 * T5; + tmp3 = pParam->B3SOIDDweff + pParam->B3SOIDDb1; + tmp4 = pParam->B3SOIDDb0 / tmp3; + T2 = tmp2 + tmp4; + dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; + T6 = T5 * T5; + T7 = T5 * T6; + + Abulk0 = T1 * T2; + dAbulk0_dVb = T1 * dT2_dVb; + + T8 = pParam->B3SOIDDags * pParam->B3SOIDDa0 * T7; + dAbulk_dVg = -T1 * T8; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + + dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * 3.0 * T1 * dT2_dVb + / tmp2; + } + + if (Abulk0 < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk0); + Abulk0 = (0.02 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } + + if (Abulk < 0.01) + { + T9 = 1.0 / (3.0 - 200.0 * Abulk); + Abulk = (0.02 - Abulk) * T9; + dAbulk_dVb *= T9 * T9; + } + + T2 = pParam->B3SOIDDketa * Vbseff; + if (T2 >= -0.9) + { T0 = 1.0 / (1.0 + T2); + dT0_dVb = -pParam->B3SOIDDketa * T0 * T0 ; + } + else + /* added to avoid the problems caused by Keta */ + { T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; + dT0_dVb = -pParam->B3SOIDDketa * T1 * T1 ; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; + + Abulk += 1; + Abulk0 += 1; + +/* Prepare Abeff */ + T0 = pParam->B3SOIDDabp * Vgst2Vtm; + T1 = 1 - Vcs / T0 - DELT_Xcsat; + T2 = sqrt(T1 * T1 + DELT_Xcsat * DELT_Xcsat); + T3 = 1 - 0.5 * (T1 + T2); + T5 = -0.5 * (1 + T1 / T2); + dT1_dVg = Vcs / Vgst2Vtm / T0; + dT3_dVg = T5 * dT1_dVg; + dT1_dVc = - 1 / T0; + dT3_dVc = T5 * dT1_dVc; + + Xcsat = pParam->B3SOIDDmxc * T3 * T3 + (1 - pParam->B3SOIDDmxc)*T3; + T4 = 2 * pParam->B3SOIDDmxc * T3 + (1 - pParam->B3SOIDDmxc); + dXcsat_dVg = T4 * dT3_dVg; + dXcsat_dVc = T4 * dT3_dVc; + + Abeff = Xcsat * Abulk + (1 - Xcsat) * model->B3SOIDDadice; + T0 = Xcsat * dAbulk_dVg + Abulk * dXcsat_dVg; + dAbeff_dVg = T0 - model->B3SOIDDadice * dXcsat_dVg; + dAbeff_dVb = Xcsat * dAbulk_dVb; + dAbeff_dVc = (Abulk - model->B3SOIDDadice) * dXcsat_dVc; + here->B3SOIDDabeff = Abeff; + +/* Mobility calculation */ + if (model->B3SOIDDmobMod == 1) + { T0 = Vgsteff + Vth + Vth; + T2 = ua + uc * Vbseff; + T3 = T0 / model->B3SOIDDtox; + T5 = T3 * (T2 + ub * T3); + dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIDDtox; + dDenomi_dVd = dDenomi_dVg * 2 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2 * dVth_dVb + uc * T3 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2 * dVth_dT + + (dua_dT + Vbseff * duc_dT + + dub_dT * T3 ) * T3; + else + dDenomi_dT = 0.0; + } + else if (model->B3SOIDDmobMod == 2) + { T5 = Vgsteff / model->B3SOIDDtox * (ua + + uc * Vbseff + ub * Vgsteff + / model->B3SOIDDtox); + dDenomi_dVg = (ua + uc * Vbseff + + 2.0 * ub * Vgsteff / model->B3SOIDDtox) + / model->B3SOIDDtox; + dDenomi_dVd = 0.0; + dDenomi_dVb = Vgsteff * uc / model->B3SOIDDtox ; + if (selfheat) + dDenomi_dT = Vgsteff / model->B3SOIDDtox + * (dua_dT + Vbseff * duc_dT + dub_dT + * Vgsteff / model->B3SOIDDtox); + else + dDenomi_dT = 0.0; + } + else /* mobMod == 3 */ + { T0 = Vgsteff + Vth + Vth; + T2 = 1.0 + uc * Vbseff; + T3 = T0 / model->B3SOIDDtox; + T4 = T3 * (ua + ub * T3); + T5 = T4 * T2; + dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 + / model->B3SOIDDtox; + dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; + dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + + uc * T4 ; + if (selfheat) + dDenomi_dT = dDenomi_dVg * 2.0 * dVth_dT + + (dua_dT + dub_dT * T3) * T3 * T2 + + T4 * Vbseff * duc_dT; + else + dDenomi_dT = 0.0; + } + + if (T5 >= -0.8) + { Denomi = 1.0 + T5; + } + else /* Added to avoid the discontinuity problem caused by ua and ub*/ + { T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; + dDenomi_dVg *= T9; + dDenomi_dVd *= T9; + dDenomi_dVb *= T9; + if (selfheat) dDenomi_dT *= T9; + else dDenomi_dT = 0.0; + } + + here->B3SOIDDueff = ueff = u0temp / Denomi; + T9 = -ueff / Denomi; + dueff_dVg = T9 * dDenomi_dVg; + dueff_dVd = T9 * dDenomi_dVd; + dueff_dVb = T9 * dDenomi_dVb; + if (selfheat) dueff_dT = T9 * dDenomi_dT + du0temp_dT / Denomi; + else dueff_dT = 0.0; + +/* Saturation Drain Voltage Vdsat */ + WVCox = Weff * vsattemp * model->B3SOIDDcox; + WVCoxRds = WVCox * Rds; + +/* dWVCoxRds_dT = WVCox * dRds_dT + + Weff * model->B3SOIDDcox * Rds * dvsattemp_dT; */ + + Esat = 2.0 * vsattemp / ueff; + EsatL = Esat * Leff; + T0 = -EsatL /ueff; + dEsatL_dVg = T0 * dueff_dVg; + dEsatL_dVd = T0 * dueff_dVd; + dEsatL_dVb = T0 * dueff_dVb; + if (selfheat) + dEsatL_dT = T0 * dueff_dT + EsatL / vsattemp * dvsattemp_dT; + else + dEsatL_dT = 0.0; + + /* Sqrt() */ + a1 = pParam->B3SOIDDa1; + if (a1 == 0.0) + { Lambda = pParam->B3SOIDDa2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) +/* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ + { T0 = 1.0 - pParam->B3SOIDDa2; + T1 = T0 - pParam->B3SOIDDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * T0); + Lambda = pParam->B3SOIDDa2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIDDa1 * (1.0 + T1 / T2); + } + else + { T1 = pParam->B3SOIDDa2 + pParam->B3SOIDDa1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * pParam->B3SOIDDa2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->B3SOIDDa1 * (1.0 + T1 / T2); + } + + if (Rds > 0) + { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; + tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; + } + else + { tmp2 = dWeff_dVg / Weff; + tmp3 = dWeff_dVb / Weff; + } + if ((Rds == 0.0) && (Lambda == 1.0)) + { T0 = 1.0 / (Abeff * EsatL + Vgst2Vtm); + tmp1 = 0.0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; + T3 = EsatL * Vgst2Vtm; + Vdsat = T3 * T0; + + dT0_dVg = -(Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 1.0) * T1; + dT0_dVd = -(Abeff * dEsatL_dVd) * T1; + dT0_dVb = -(Abeff * dEsatL_dVb + EsatL * dAbeff_dVb) * T1; + dT0_dVc = -(EsatL * dAbeff_dVc) * T1; + if (selfheat) + dT0_dT = -(Abeff * dEsatL_dT + dVgst2Vtm_dT) * T1; + else dT0_dT = 0.0; + + dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; + dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + dVdsat_dVc = T3 * dT0_dVc; + if (selfheat) + dVdsat_dT = T3 * dT0_dT + T2 * dEsatL_dT + + EsatL * T0 * dVgst2Vtm_dT; + else dVdsat_dT = 0.0; + } + else + { tmp1 = dLambda_dVg / (Lambda * Lambda); + T9 = Abeff * WVCoxRds; + T8 = Abeff * T9; + T7 = Vgst2Vtm * T9; + T6 = Vgst2Vtm * WVCoxRds; + T0 = 2.0 * Abeff * (T9 - 1.0 + 1.0 / Lambda); + dT0_dVg = 2.0 * (T8 * tmp2 - Abeff * tmp1 + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); +/* dT0_dVb = 2.0 * (T8 * tmp3 this is equivalent to one below, but simpler + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); */ + dT0_dVb = 2.0 * (T8 * (2.0 / Abeff * dAbeff_dVb + tmp3) + + (1.0 / Lambda - 1.0) * dAbeff_dVb); + dT0_dVd = 0.0; + dT0_dVc = 4.0 * T9 * dAbeff_dVc; + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = 2.0 * T8 * tmp4; + } else tmp4 = dT0_dT = 0.0; + + T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abeff * EsatL + 3.0 * T7; + + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + + Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 3.0 * (T9 + + T7 * tmp2 + T6 * dAbeff_dVg); + dT1_dVb = Abeff * dEsatL_dVb + EsatL * dAbeff_dVb + + 3.0 * (T6 * dAbeff_dVb + T7 * tmp3); + dT1_dVd = Abeff * dEsatL_dVd; + dT1_dVc = EsatL * dAbeff_dVc + 3.0 * T6 * dAbeff_dVc; + + if (selfheat) + { + tmp4 += dVgst2Vtm_dT / Vgst2Vtm; + dT1_dT = (2.0 / Lambda - 1.0) * dVgst2Vtm_dT + + Abeff * dEsatL_dT + 3.0 * T7 * tmp4; + } else dT1_dT = 0.0; + + T2 = Vgst2Vtm * (EsatL + 2.0 * T6); + dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); + dT2_dVd = Vgst2Vtm * dEsatL_dVd; + if (selfheat) + dT2_dT = Vgst2Vtm * dEsatL_dT + EsatL * dVgst2Vtm_dT + + 2.0 * T6 * (dVgst2Vtm_dT + Vgst2Vtm * tmp4); + else + dT2_dT = 0.0; + + T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); + Vdsat = (T1 - T3) / T0; + + dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; + dVdsat_dVc = (dT1_dVc - (T1 * dT1_dVc - dT0_dVc * T2) / T3 + - Vdsat * dT0_dVc) / T0; + if (selfheat) + dVdsat_dT = (dT1_dT - (T1 * dT1_dT - dT0_dT * T2 + - T0 * dT2_dT) / T3 - Vdsat * dT0_dT) / T0; + else dVdsat_dT = 0.0; + } + here->B3SOIDDvdsat = Vdsat; + +/* Vdsatii for impact ionization */ + if (pParam->B3SOIDDaii > 0.0) + { + if (pParam->B3SOIDDcii != 0.0) + { + T0 = pParam->B3SOIDDcii / sqrt(3.0) + pParam->B3SOIDDdii; + /* Hard limit Vds to T0 => T4 i.e. limit T0 to 3.0 */ + T1 = Vds - T0 - 0.1; + T2 = sqrt(T1 * T1 + 0.4); + T3 = T0 + 0.5 * (T1 + T2); + dT3_dVd = 0.5 * (1.0 + T1/T2); + + T4 = T3 - pParam->B3SOIDDdii; + T5 = pParam->B3SOIDDcii / T4; + T0 = T5 * T5; + dT0_dVd = - 2 * T0 / T4 * dT3_dVd; + } else + { + T0 = dT0_dVd = 0.0; + } + T0 += 1.0; + + T3 = pParam->B3SOIDDaii + pParam->B3SOIDDbii / Leff; + T4 = 1.0 / (T0 * Vgsteff + T3 * EsatL); + T5 = -T4 * T4; + T6 = Vgsteff * T4; + T7 = EsatL * Vgsteff; + Vdsatii = T7 * T4; + + dT4_dVg = T5 * (T0 + T3 * dEsatL_dVg); + dT4_dVb = T5 * T3 * dEsatL_dVb; + dT4_dVd = T5 * (Vgsteff * dT0_dVd + T3 * dEsatL_dVd); + + if (selfheat) dT4_dT = T5 * (T3 * dEsatL_dT); + else dT4_dT = 0.0; + + T8 = T4 * Vgsteff; + dVdsatii_dVg = T7 * dT4_dVg + T4 * (EsatL + Vgsteff * dEsatL_dVg); + dVdsatii_dVb = T7 * dT4_dVb + T8 * dEsatL_dVb; + dVdsatii_dVd = T7 * dT4_dVd + T8 * dEsatL_dVd; + if (selfheat) dVdsatii_dT = T7 * dT4_dT + T8 * dEsatL_dT; + else dVdsatii_dT = 0.0; + } else + { + Vdsatii = Vdsat; + dVdsatii_dVg = dVdsat_dVg; + dVdsatii_dVb = dVdsat_dVb; + dVdsatii_dVd = dVdsat_dVd; + dVdsatii_dT = dVdsat_dT; + } + +/* Effective Vds (Vdseff) Calculation */ + T1 = Vdsat - Vds - pParam->B3SOIDDdelta; + dT1_dVg = dVdsat_dVg; + dT1_dVd = dVdsat_dVd - 1.0; + dT1_dVb = dVdsat_dVb; + dT1_dVc = dVdsat_dVc; + dT1_dT = dVdsat_dT; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIDDdelta * Vdsat); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIDDdelta / T2; + dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; + dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; + dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; + dT2_dVc = T0 * dT1_dVc + T3 * dVdsat_dVc; + if (selfheat) + dT2_dT = T0 * dT1_dT + T3 * dVdsat_dT; + else dT2_dT = 0.0; + + Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); + dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); + dVdseff_dVc = dVdsat_dVc - 0.5 * (dT1_dVc + dT2_dVc); + if (selfheat) + dVdseff_dT = dVdsat_dT - 0.5 * (dT1_dT + dT2_dT); + else dVdseff_dT = 0.0; + + if (Vdseff > Vds) + Vdseff = Vds; /* This code is added to fixed the problem + caused by computer precision when + Vds is very close to Vdseff. */ + diffVds = Vds - Vdseff; + +/* Effective Vdsii for Iii calculation */ + T1 = Vdsatii - Vds - pParam->B3SOIDDdelta; + + T2 = sqrt(T1 * T1 + 4.0 * pParam->B3SOIDDdelta * Vdsatii); + T0 = T1 / T2; + T3 = 2.0 * pParam->B3SOIDDdelta / T2; + T4 = T0 + T3; + dT2_dVg = T4 * dVdsatii_dVg; + dT2_dVd = T4 * dVdsatii_dVd - T0; + dT2_dVb = T4 * dVdsatii_dVb; + if (selfheat) dT2_dT = T4*dVdsatii_dT; + else dT2_dT = 0.0; + + Vdseffii = Vdsatii - 0.5 * (T1 + T2); + dVdseffii_dVg = 0.5 * (dVdsatii_dVg - dT2_dVg); + dVdseffii_dVd = 0.5 * (dVdsatii_dVd - dT2_dVd + 1.0); + dVdseffii_dVb = 0.5 * (dVdsatii_dVb - dT2_dVb); + if (selfheat) + dVdseffii_dT = 0.5 * (dVdsatii_dT - dT2_dT); + else dVdseffii_dT = 0.0; + diffVdsii = Vds - Vdseffii; + +/* Calculate VAsat */ + tmp4 = 1.0 - 0.5 * Abeff * Vdsat / Vgst2Vtm; + T9 = WVCoxRds * Vgsteff; + T8 = T9 / Vgst2Vtm; + T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; + + T7 = 2.0 * WVCoxRds * tmp4; + dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) + - T8 * (Abeff * dVdsat_dVg - Abeff * Vdsat / Vgst2Vtm + + Vdsat * dAbeff_dVg); + + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff + - T8 * (dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb); + dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abeff * dVdsat_dVd; + dT0_dVc = dVdsat_dVc - T8 * (Abeff * dVdsat_dVc + Vdsat * dAbeff_dVc); + + if (selfheat) + { + tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; + dT0_dT = dEsatL_dT + dVdsat_dT + T7 * tmp4 * Vgsteff + - T8 * (Abeff * dVdsat_dT - Abeff * Vdsat * dVgst2Vtm_dT + / Vgst2Vtm); + } else + dT0_dT = 0.0; + + T9 = WVCoxRds * Abeff; + T1 = 2.0 / Lambda - 1.0 + T9; + dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abeff * tmp2 + dAbeff_dVg); + dT1_dVb = dAbeff_dVb * WVCoxRds + T9 * tmp3; + dT1_dVc = dAbeff_dVc * WVCoxRds; + if (selfheat) + dT1_dT = T9 * tmp4; + else + dT1_dT = 0.0; + + Vasat = T0 / T1; + dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; + dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; + dVasat_dVd = dT0_dVd / T1; + dVasat_dVc = (dT0_dVc - Vasat * dT1_dVc) / T1; + if (selfheat) dVasat_dT = (dT0_dT - Vasat * dT1_dT) / T1; + else dVasat_dT = 0.0; + +/* Calculate VACLM */ + if ((pParam->B3SOIDDpclm > 0.0) && (diffVds > 1.0e-10)) + { T0 = 1.0 / (pParam->B3SOIDDpclm * Abeff * pParam->B3SOIDDlitl); + dT0_dVb = -T0 / Abeff * dAbeff_dVb; + dT0_dVg = -T0 / Abeff * dAbeff_dVg; + dT0_dVc = -T0 / Abeff * dAbeff_dVc; + + T2 = Vgsteff / EsatL; + T1 = Leff * (Abeff + T2); + dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbeff_dVg); + dT1_dVb = Leff * (dAbeff_dVb - T2 * dEsatL_dVb / EsatL); + dT1_dVd = -T2 * dEsatL_dVd / Esat; + dT1_dVc = Leff * dAbeff_dVc; + if (selfheat) dT1_dT = -T2 * dEsatL_dT / Esat; + else dT1_dT = 0.0; + + T9 = T0 * T1; + VACLM = T9 * diffVds; + dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + + T1 * diffVds * dT0_dVg; + dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds + - T9 * dVdseff_dVb; + dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); + dVACLM_dVc = (T1 * dT0_dVc + T0 * dT1_dVc) * diffVds + - T9 * dVdseff_dVc; + if (selfheat) + dVACLM_dT = T0 * dT1_dT * diffVds - T9 * dVdseff_dT; + else dVACLM_dT = 0.0; + + } + else + { VACLM = MAX_EXP; + dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = dVACLM_dVc = dVACLM_dT = 0.0; + } + + +/* Calculate VADIBL */ + if (pParam->B3SOIDDthetaRout > 0.0) + { T8 = Abeff * Vdsat; + T0 = Vgst2Vtm * T8; + T1 = Vgst2Vtm + T8; + dT0_dVg = Vgst2Vtm * Abeff * dVdsat_dVg + T8 + + Vgst2Vtm * Vdsat * dAbeff_dVg; + dT1_dVg = 1.0 + Abeff * dVdsat_dVg + Vdsat * dAbeff_dVg; + dT1_dVb = dAbeff_dVb * Vdsat + Abeff * dVdsat_dVb; + dT0_dVb = Vgst2Vtm * dT1_dVb; + dT1_dVd = Abeff * dVdsat_dVd; + dT0_dVd = Vgst2Vtm * dT1_dVd; + dT1_dVc = (Abeff * dVdsat_dVc + Vdsat * dAbeff_dVc); + dT0_dVc = Vgst2Vtm * dT1_dVc; + if (selfheat) + { + dT0_dT = dVgst2Vtm_dT * T8 + Abeff * Vgst2Vtm * dVdsat_dT; + dT1_dT = dVgst2Vtm_dT + Abeff * dVdsat_dT; + } else + dT0_dT = dT1_dT = 0.0; + + T9 = T1 * T1; + T2 = pParam->B3SOIDDthetaRout; + VADIBL = (Vgst2Vtm - T0 / T1) / T2; + dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; + dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; + dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; + dVADIBL_dVc = (-dT0_dVc / T1 + T0 * dT1_dVc / T9) / T2; + if (selfheat) + dVADIBL_dT = (dVgst2Vtm_dT - dT0_dT/T1 + T0*dT1_dT/T9) / T2; + else dVADIBL_dT = 0.0; + + T7 = pParam->B3SOIDDpdiblb * Vbseff; + if (T7 >= -0.9) + { T3 = 1.0 / (1.0 + T7); + VADIBL *= T3; + dVADIBL_dVg *= T3; + dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->B3SOIDDpdiblb) + * T3; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + } + else +/* Added to avoid the discontinuity problem caused by pdiblcb */ + { T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; + dVADIBL_dVg *= T3; + dVADIBL_dVb = dVADIBL_dVb * T3 + - VADIBL * pParam->B3SOIDDpdiblb * T4 * T4; + dVADIBL_dVd *= T3; + dVADIBL_dVc *= T3; + if (selfheat) dVADIBL_dT *= T3; + else dVADIBL_dT = 0.0; + VADIBL *= T3; + } + } + else + { VADIBL = MAX_EXP; + dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = dVADIBL_dVc + = dVADIBL_dT = 0.0; + } + +/* Calculate VA */ + + T8 = pParam->B3SOIDDpvag / EsatL; + T9 = T8 * Vgsteff; + if (T9 > -0.9) + { T0 = 1.0 + T9; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); + dT0_dVb = -T9 * dEsatL_dVb / EsatL; + dT0_dVd = -T9 * dEsatL_dVd / EsatL; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT / EsatL; + else + dT0_dT = 0.0; + } + else /* Added to avoid the discontinuity problems caused by pvag */ + { T1 = 1.0 / (17.0 + 20.0 * T9); + T0 = (0.8 + T9) * T1; + T1 *= T1; + dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; + + T9 *= T1 / EsatL; + dT0_dVb = -T9 * dEsatL_dVb; + dT0_dVd = -T9 * dEsatL_dVd; + if (selfheat) + dT0_dT = -T9 * dEsatL_dT; + else + dT0_dT = 0.0; + } + + tmp1 = VACLM * VACLM; + tmp2 = VADIBL * VADIBL; + tmp3 = VACLM + VADIBL; + + T1 = VACLM * VADIBL / tmp3; + tmp3 *= tmp3; + dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; + dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; + dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; + dT1_dVc = (tmp1 * dVADIBL_dVc + tmp2 * dVACLM_dVc) / tmp3; + if (selfheat) + dT1_dT = (tmp1 * dVADIBL_dT + tmp2 * dVACLM_dT ) / tmp3; + else dT1_dT = 0.0; + + Va = Vasat + T0 * T1; + dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; + dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; + dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb; + dVa_dVc = dVasat_dVc + T0 * dT1_dVc; + if (selfheat) + dVa_dT = dVasat_dT + T1 * dT0_dT + T0 * dT1_dT; + else dVa_dT = 0.0; + +/* Calculate Ids */ + CoxWovL = model->B3SOIDDcox * Weff / Leff; + beta = ueff * CoxWovL; + dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; + dbeta_dVd = CoxWovL * dueff_dVd; + dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; + if (selfheat) dbeta_dT = CoxWovL * dueff_dT; + else dbeta_dT = 0.0; + + T0 = 1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm; + dT0_dVg = -0.5 * (Abeff * dVdseff_dVg + - Abeff * Vdseff / Vgst2Vtm + Vdseff * dAbeff_dVg) / Vgst2Vtm; + dT0_dVd = -0.5 * Abeff * dVdseff_dVd / Vgst2Vtm; + dT0_dVb = -0.5 * (Abeff * dVdseff_dVb + dAbeff_dVb * Vdseff) + / Vgst2Vtm; + dT0_dVc = -0.5 * (Abeff * dVdseff_dVc + dAbeff_dVc * Vdseff) + / Vgst2Vtm; + if (selfheat) + dT0_dT = -0.5 * (Abeff * dVdseff_dT + - Abeff * Vdseff / Vgst2Vtm * dVgst2Vtm_dT) + / Vgst2Vtm; + else dT0_dT = 0.0; + + fgche1 = Vgsteff * T0; + dfgche1_dVg = Vgsteff * dT0_dVg + T0; + dfgche1_dVd = Vgsteff * dT0_dVd; + dfgche1_dVb = Vgsteff * dT0_dVb; + dfgche1_dVc = Vgsteff * dT0_dVc; + if (selfheat) dfgche1_dT = Vgsteff * dT0_dT; + else dfgche1_dT = 0.0; + + T9 = Vdseff / EsatL; + fgche2 = 1.0 + T9; + dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL; + dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL; + dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL; + dfgche2_dVc = (dVdseff_dVc) / EsatL; + if (selfheat) dfgche2_dT = (dVdseff_dT - T9 * dEsatL_dT) / EsatL; + else dfgche2_dT = 0.0; + + gche = beta * fgche1 / fgche2; + dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg + - gche * dfgche2_dVg) / fgche2; + dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd + - gche * dfgche2_dVd) / fgche2; + dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb + - gche * dfgche2_dVb) / fgche2; + dgche_dVc = (beta * dfgche1_dVc - gche * dfgche2_dVc) / fgche2; + if (selfheat) + dgche_dT = (beta * dfgche1_dT + fgche1 * dbeta_dT + - gche * dfgche2_dT) / fgche2; + else dgche_dT = 0.0; + + T0 = 1.0 + gche * Rds; + T9 = Vdseff / T0; + Idl = gche * T9; + +/* Whoa, these formulas for the derivatives of Idl are convoluted, but I + verified them to be correct */ + + dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0 + - Idl * gche / T0 * dRds_dVg ; + dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0; + dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb + - Idl * dRds_dVb * gche) / T0; + dIdl_dVc = (gche * dVdseff_dVc + T9 * dgche_dVc) / T0; + if (selfheat) + dIdl_dT = (gche * dVdseff_dT + T9 * dgche_dT + - Idl * dRds_dT * gche) / T0; + else dIdl_dT = 0.0; + + T9 = diffVds / Va; + T0 = 1.0 + T9; + here->B3SOIDDids = Ids = Idl * T0; + + Gm0 = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va; + Gds0 = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd + - T9 * dVa_dVd) / Va; + Gmb0 = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va; + Gmc = T0 * dIdl_dVc - Idl * (dVdseff_dVc + T9 * dVa_dVc) / Va; + if (selfheat) + GmT0 = T0 * dIdl_dT - Idl * (dVdseff_dT + T9 * dVa_dT) / Va; + else GmT0 = 0.0; + +/* This includes all dependencies from Vgsteff, Vbseff, Vcs */ + Gm = Gm0 * dVgsteff_dVg + Gmb0 * dVbseff_dVg + Gmc * dVcs_dVg; + Gmb = Gm0 * dVgsteff_dVb + Gmb0 * dVbseff_dVb + Gmc * dVcs_dVb; + Gds = Gm0 * dVgsteff_dVd + Gmb0 * dVbseff_dVd + Gmc * dVcs_dVd + Gds0; + Gme = Gm0 * dVgsteff_dVe + Gmb0 * dVbseff_dVe + Gmc * dVcs_dVe; + if (selfheat) + GmT = Gm0 * dVgsteff_dT + Gmb0 * dVbseff_dT + Gmc * dVcs_dT + GmT0; + else GmT = 0.0; + +/* calculate substrate current Iii */ + T2 = pParam->B3SOIDDalpha1 + pParam->B3SOIDDalpha0 / Leff; + if ((T2 <= 0.0) || (pParam->B3SOIDDbeta0 <= 0.0)) + { Giig = Giib = Giid = Giie = GiiT = 0.0; + here->B3SOIDDiii = Iii = 0.0; + } + else + { + T5 = pParam->B3SOIDDbeta0; + if (diffVdsii > T5 / EXP_THRESHOLD) + { + T0 = -T5 / diffVdsii; + T10 = T0 / diffVdsii; + dT0_dVg = T10 * dVdseffii_dVg; + T1 = T2 * diffVdsii * exp(T0); + + T3 = T1 / diffVdsii * (T0 - 1.0); + dT1_dVg = T1 * (dT0_dVg - dVdseffii_dVg / diffVdsii); + dT1_dVd = -T3 * (1.0 - dVdseffii_dVd); + dT1_dVb = T3 * dVdseffii_dVb; + if (selfheat) dT1_dT = T3 * dVdseffii_dT; + else dT1_dT = 0.0; + } + else + { T3 = T2 * MIN_EXP; + T1 = T3 * diffVdsii; + dT1_dVg = -T3 * dVdseffii_dVg; + dT1_dVd = T3 * (1.0 - dVdseffii_dVd); + dT1_dVb = -T3 * dVdseffii_dVb; + if (selfheat) dT1_dT = -T3 * dVdseffii_dT; + else dT1_dT = 0.0; + } + + here->B3SOIDDiii = Iii = T1 * Ids; + + T2 = T1 * Gm0 + Ids * dT1_dVg; + T3 = T1 * Gds0 + Ids * dT1_dVd; + T4 = T1 * Gmb0 + Ids * dT1_dVb; + T5 = T1 * Gmc; + if (selfheat) T6 = T1 * GmT0 + Ids * dT1_dT; + else T6 = 0.0; + + Giig = T2 * dVgsteff_dVg + T4 * dVbseff_dVg + T5 * dVcs_dVg; + Giib = T2 * dVgsteff_dVb + T4 * dVbseff_dVb + T5 * dVcs_dVb; + Giid = T2 * dVgsteff_dVd + T4 * dVbseff_dVd + T5 * dVcs_dVd + T3; + Giie = T2 * dVgsteff_dVe + T4 * dVbseff_dVe + T5 * dVcs_dVe; + if (selfheat) + GiiT = T2 * dVgsteff_dT + T4 * dVbseff_dT + T5 * dVcs_dT + T6; + else + GiiT = 0.0; + } + +/* calculate GIDL current */ + T0 = 3 * model->B3SOIDDtox; + /* For drain side */ + T1 = (Vds - Vgs_eff - pParam->B3SOIDDngidl) / T0; + if ((pParam->B3SOIDDagidl <= 0.0) || (pParam->B3SOIDDbgidl <= 0.0) || + (T1 <= 0.0)) + { Idgidl = Gdgidld = Gdgidlg = 0.0; + } + else { + dT1_dVd = 1 / T0; + dT1_dVg = - dT1_dVd * dVgs_eff_dVg; + T2 = pParam->B3SOIDDbgidl / T1; + if (T2 < EXP_THRESHOLD) + { + Idgidl = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * T1 * exp(-T2); + T3 = Idgidl / T1 * (T2 + 1); + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } else + { + T3 = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * MIN_EXP; + Idgidl = T3 * T1 ; + Gdgidld = T3 * dT1_dVd; + Gdgidlg = T3 * dT1_dVg; + } + } + here->B3SOIDDigidl = Idgidl; + + /* For source side */ + T1 = (- Vgs_eff - pParam->B3SOIDDngidl) / T0; + if ((pParam->B3SOIDDagidl <= 0.0) || (pParam->B3SOIDDbgidl <= 0.0) + || (T1 <= 0.0)) + { Isgidl = Gsgidlg = 0; + } + else + { + dT1_dVg = - dVgs_eff_dVg / T0; + T2 = pParam->B3SOIDDbgidl / T1; + if (T2 < EXP_THRESHOLD) + { + Isgidl = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * T1 * exp(-T2); + T3 = Isgidl / T1 * (T2 + 1); + Gsgidlg = T3 * dT1_dVg; + } else + { + T3 = pParam->B3SOIDDweff * pParam->B3SOIDDagidl * MIN_EXP; + Isgidl = T3 * T1 ; + Gsgidlg = T3 * dT1_dVg; + } + } + +/* calculate diode and BJT current */ + + WTsi = pParam->B3SOIDDweff * model->B3SOIDDtsi; + NVtm1 = Vtm * pParam->B3SOIDDndiode; + NVtm2 = Vtm * pParam->B3SOIDDntun; + + /* Create exponents first */ + T0 = Vbs / NVtm1; + if (T0 < 30) + { + ExpVbs1 = exp(T0); + dExpVbs1_dVb = ExpVbs1 / NVtm1; + if (selfheat) dExpVbs1_dT = - T0 * ExpVbs1 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbs1_dVb = T1 / NVtm1; + ExpVbs1 = dExpVbs1_dVb * Vbs - 29.0 * T1; + if (selfheat) dExpVbs1_dT = - dExpVbs1_dVb * Vbs / Temp; + } + + T0 = Vbd / NVtm1; + if (T0 < 30) + { + ExpVbd1 = exp(T0); + dExpVbd1_dVb = ExpVbd1 / NVtm1; + if (selfheat) dExpVbd1_dT = - T0 * ExpVbd1 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbd1_dVb = T1 / NVtm1; + ExpVbd1 = dExpVbd1_dVb * Vbd - 29.0 * T1; + if (selfheat) dExpVbd1_dT = - dExpVbd1_dVb * Vbd / Temp; + } + + if (jtun > 0.0) + { + T0 = -Vbs / NVtm2; + if (T0 < 30) + { + ExpVbs4 = exp(T0); + dExpVbs4_dVb = - ExpVbs4 / NVtm2; + if (selfheat) dExpVbs4_dT = - T0 * ExpVbs4 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbs4_dVb = - T1 / NVtm2; + ExpVbs4 = dExpVbs4_dVb * Vbs - 29.0 * T1; + if (selfheat) dExpVbs4_dT = - dExpVbs4_dVb * Vbs / Temp; + } + + T0 = -Vbd / NVtm2; + if (T0 < 30) + { + ExpVbd4 = exp(T0); + dExpVbd4_dVb = - ExpVbd4 / NVtm2; + if (selfheat) dExpVbd4_dT = - T0 * ExpVbd4 / Temp; + } else + { + T1 = 1.0686e13; /* exp(30) */ + dExpVbd4_dVb = - T1 / NVtm2; + ExpVbd4 = dExpVbd4_dVb * Vbd - 29.0 * T1; + if (selfheat) dExpVbd4_dT = - dExpVbd4_dVb * Vbd / Temp; + } + } + + /* Ibs1 / Ibd1 */ + if (jdif == 0.0) + { + Ibs1 = dIbs1_dVb = dIbs1_dT = 0.0; + Ibd1 = dIbd1_dVd = dIbd1_dVb = dIbd1_dT = 0.0; + } + else + { + T5 = WTsi * jdif; + Ibs1 = T5 * (ExpVbs1 - 1.0); + dIbs1_dVb = T5 * dExpVbs1_dVb; + if (selfheat) + dIbs1_dT = Ibs1 / jdif * djdif_dT + T5 * dExpVbs1_dT; + + Ibd1 = T5 * (ExpVbd1 - 1.0); + dIbd1_dVb = T5 * dExpVbd1_dVb; + dIbd1_dVd = -dIbd1_dVb; + if (selfheat) + dIbd1_dT = Ibd1 / jdif * djdif_dT + T5 * dExpVbd1_dT; + } + + /* Ibs2 */ + if (jrec == 0.0) + { + Ibs2 = dIbs2_dVb = dIbs2_dT = 0.0; + Ibd2 = dIbd2_dVb = dIbd2_dVd = dIbd2_dT = 0.0; + } + else + { + ExpVbs2 = sqrt(ExpVbs1); + if (ExpVbs2 > 1e-20) + { + dExpVbs2_dVb = 0.5 / ExpVbs2 * dExpVbs1_dVb; + if (selfheat) dExpVbs2_dT = 0.5 / ExpVbs2 * dExpVbs1_dT; + } + else + { + dExpVbs2_dVb = dExpVbs2_dT = 0.0; + } + + ExpVbd2 = sqrt(ExpVbd1); + if (ExpVbd2 > 1e-20) + { + dExpVbd2_dVb = 0.5 / ExpVbd2 * dExpVbd1_dVb; + if (selfheat) dExpVbd2_dT = 0.5 / ExpVbd2 * dExpVbd1_dT; + } + else + { + dExpVbd2_dVb = dExpVbd2_dT = 0.0; + } + + T8 = WTsi * jrec; + T9 = 0.5 * T8 / NVtm1; + Ibs2 = T8 * (ExpVbs2 - 1.0); + dIbs2_dVb = T8 * dExpVbs2_dVb; + if (selfheat) + dIbs2_dT = Ibs2 / jrec * djrec_dT + T8 * dExpVbs2_dT; + + T8 = WTsi * jrec; + T9 = 0.5 * T8 / NVtm1; + Ibd2 = T8 * (ExpVbd2 - 1.0); + dIbd2_dVb = T8 * dExpVbd2_dVb; + dIbd2_dVd = -dIbd2_dVb; + if (selfheat) + dIbd2_dT = Ibd2 / jrec * djrec_dT + T8 * dExpVbd2_dT; + } + + /* Ibjt */ + if ((here->B3SOIDDbjtoff == 1) || (Vds == 0.0) || + (jbjt == 0.0)) + { + Ibs3 = dIbs3_dVb = dIbs3_dVd = dIbs3_dT = 0.0; + Ibd3 = dIbd3_dVb = dIbd3_dVd = dIbd3_dT = 0.0; + here->B3SOIDDic = Ic = Gcd = Gcb = GcT = 0.0; + } + else { + T0 = Leff - pParam->B3SOIDDkbjt1 * Vds; + T1 = T0 / pParam->B3SOIDDedl; + dT1_dVd = - pParam->B3SOIDDkbjt1 / pParam->B3SOIDDedl; + if (T1 < 1e-3) /* Limit to 1/2e4 */ + { T2 = 1.0 / (3.0 - 2.0e3 * T1); + T1 = (2.0e-3 - T1) * T2; + dT1_dVd *= T2 * T2; + } else if (T1 > 1.0) + { T1 = 1.0; + dT1_dVd = 0.0; + } + BjtA = 1 - 0.5 * T1 * T1; + dBjtA_dVd = - T1 * dT1_dVd; + + T5 = WTsi * jbjt; + Ibjt = T5 * (ExpVbs1 - ExpVbd1); + dIbjt_dVb = T5 * (dExpVbs1_dVb - dExpVbd1_dVb); + dIbjt_dVd = T5 * dExpVbd1_dVb; + if (selfheat) + dIbjt_dT = T5 * (dExpVbs1_dT - dExpVbd1_dT) + + Ibjt / jbjt * djbjt_dT; + + T3 = (1.0 - BjtA) * T5; + T4 = - T5 * dBjtA_dVd; + Ibs3 = T3 * ExpVbs1; + dIbs3_dVb = T3 * dExpVbs1_dVb; + dIbs3_dVd = T4 * ExpVbs1; + if (selfheat) dIbs3_dT = Ibs3 / jbjt * djbjt_dT + T3 * dExpVbs1_dT; + + Ibd3 = T3 * ExpVbd1; + dIbd3_dVb = T3 * dExpVbd1_dVb; + dIbd3_dVd = T4 * ExpVbd1 - dIbd3_dVb; + if (selfheat) dIbd3_dT = Ibd3 / jbjt * djbjt_dT + T3 * dExpVbd1_dT; + + here->B3SOIDDic = Ic = Ibjt - Ibs3 + Ibd3; + Gcd = dIbjt_dVd - dIbs3_dVd + dIbd3_dVd; + Gcb = dIbjt_dVb - dIbs3_dVb + dIbd3_dVb; + if (selfheat) GcT = dIbjt_dT - dIbs3_dT + dIbd3_dT; + else GcT = 0.0; + } + + if (jtun == 0.0) + { + Ibs4 = dIbs4_dVb = dIbs4_dT = 0.0; + Ibd4 = dIbd4_dVb = dIbd4_dVd = dIbd4_dT = 0.0; + } + else + { + T5 = WTsi * jtun; + Ibs4 = T5 * (1.0 - ExpVbs4); + dIbs4_dVb = - T5 * dExpVbs4_dVb; + if (selfheat) + dIbs4_dT = Ibs4 / jtun * djtun_dT - T5 * dExpVbs4_dT; + + Ibd4 = T5 * (1.0 - ExpVbd4); + dIbd4_dVb = - T5 * dExpVbd4_dVb; + dIbd4_dVd = -dIbd4_dVb; + if (selfheat) + dIbd4_dT = Ibd4 / jtun * djtun_dT - T5 * dExpVbd4_dT; + } + +here->B3SOIDDdum1 = Ibs3 + Ibd4; +here->B3SOIDDdum2 = Ibs1; +here->B3SOIDDdum3 = Ibjt; +here->B3SOIDDdum4 = Ic; + + here->B3SOIDDitun = - Ibd3 - Ibd4; + here->B3SOIDDibs = Ibs = Ibs1 + Ibs2 + Ibs3 + Ibs4; + here->B3SOIDDibd = Ibd = Ibd1 + Ibd2 + Ibd3 + Ibd4; + + Gjsb = dIbs1_dVb + dIbs2_dVb + dIbs3_dVb + dIbs4_dVb; + Gjsd = dIbs3_dVd; + if (selfheat) GjsT = dIbs1_dT + dIbs2_dT + dIbs3_dT + dIbs4_dT; + else GjsT = 0.0; + + Gjdb = dIbd1_dVb + dIbd2_dVb + dIbd3_dVb + dIbd4_dVb; + Gjdd = dIbd1_dVd + dIbd2_dVd + dIbd3_dVd + dIbd4_dVd; + if (selfheat) GjdT = dIbd1_dT + dIbd2_dT + dIbd3_dT + dIbd4_dT; + else GjdT = 0.0; + + + /* Current through body resistor */ + /* Current going out is +ve */ + if ((here->B3SOIDDbodyMod == 0) || (here->B3SOIDDbodyMod == 2)) + { + Ibp = Gbpbs = Gbpgs = Gbpds = Gbpes = Gbpps = GbpT = 0.0; + } + else { /* here->B3SOIDDbodyMod == 1 */ + if (pParam->B3SOIDDrbody < 1e-30) + { + if (here->B3SOIDDrbodyext <= 1e-30) + T0 = 1.0 / 1e-30; + else + T0 = 1.0 / here->B3SOIDDrbodyext; + Ibp = Vbp * T0; + Gbpbs = T0 * dVbp_dVb; + Gbpps = T0 * dVbp_dVp; + Gbpgs = T0 * dVbp_dVg; + Gbpds = T0 * dVbp_dVd; + Gbpes = 0.0; + if (selfheat) GbpT = T0 * dVbp_dT; + else GbpT = 0.0; + } else + { T0 = 1.0 / pParam->B3SOIDDrbody; + if (Vbp >= 0.0) + { + T1 = sqrt(Vcs); + T3 = T1 * T0; + T5 = 1.0 + here->B3SOIDDrbodyext * T3; + T6 = T3 / T5; + T2 = 0.5 * T0 / T1; + T7 = T2 / (T5 * T5); + Ibp = Vbp * T6; + + /* Whoa, again these derivatives are convoluted, but correct */ + + Gbpbs = T6 * dVbp_dVb + Vbp * T7 * dVcs_dVb; + Gbpps = T6 * dVbp_dVp; + Gbpgs = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVg; + Gbpds = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVd; + Gbpes = T6 * dVbp_dVg + Vbp * T7 * dVcs_dVe; + if (selfheat) + GbpT = T6 * dVbp_dT + Vbp * T7 * dVcs_dT; + else GbpT = 0.0; + + } else + { + T1 = sqrt(Vpsdio - Vbs0eff); + T3 = T1 * T0; + T5 = 1.0 + here->B3SOIDDrbodyext * T3; + T6 = T3 / T5; + T2 = 0.5 * T0 / T1; + Ibp = Vbp * T6; + T7 = T2 / (T5 * T5); + Gbpbs = T6 * dVbp_dVb; + Gbpps = T6 * dVbp_dVp + Vbp * T7 * dVpsdio_dVp; + Gbpgs = Vbp * T7 * (dVpsdio_dVg - dVbs0eff_dVg); + Gbpds = Vbp * T7 * (dVpsdio_dVd - dVbs0eff_dVd); + Gbpes = Vbp * T7 * (dVpsdio_dVe - dVbs0eff_dVe); + if (selfheat) + GbpT = Vbp * T7 * (dVpsdio_dT - dVbs0eff_dT); + else GbpT = 0.0; + } + } + } + + here->B3SOIDDibp = Ibp; + here->B3SOIDDgbpbs = Gbpbs; + here->B3SOIDDgbpgs = Gbpgs; + here->B3SOIDDgbpds = Gbpds; + here->B3SOIDDgbpes = Gbpes; + here->B3SOIDDgbpps = Gbpps; + if (selfheat) + here->B3SOIDDgbpT = GbpT; + else { + GbpT = 0.0; + here->B3SOIDDgbpT = 0.0; + } + here->B3SOIDDcbodcon = Ibp - (Gbpbs * Vbs + Gbpgs * Vgs + + Gbpds * Vds + Gbpes * Ves + Gbpps * Vps + + GbpT * delTemp); + + /* Current going out of drainprime node into the drain of device */ + /* "node" means the SPICE circuit node */ + + here->B3SOIDDcdrain = Ids + Ic; + here->B3SOIDDcd = Ids + Ic - Ibd + Iii + Idgidl; + here->B3SOIDDcb = Ibs + Ibd + Ibp - Iii - Idgidl - Isgidl; + + here->B3SOIDDgds = Gds + Gcd; + here->B3SOIDDgm = Gm; + here->B3SOIDDgmbs = Gmb + Gcb; + here->B3SOIDDgme = Gme; + if (selfheat) + here->B3SOIDDgmT = GmT + GcT; + else + here->B3SOIDDgmT = 0.0; + + /* note that sign is switched because power flows out + of device into the temperature node. + Currently ommit self-heating due to bipolar current + because it can cause convergence problem*/ + + here->B3SOIDDgtempg = -Gm * Vds; + here->B3SOIDDgtempb = -Gmb * Vds; + here->B3SOIDDgtempe = -Gme * Vds; + here->B3SOIDDgtempT = -GmT * Vds; + here->B3SOIDDgtempd = -Gds * Vds - Ids; + here->B3SOIDDcth = - Ids * Vds - model->B3SOIDDtype * + (here->B3SOIDDgtempg * Vgs + here->B3SOIDDgtempb * Vbs + + here->B3SOIDDgtempe * Ves + here->B3SOIDDgtempd * Vds) + - here->B3SOIDDgtempT * delTemp; + + /* Body current which flows into drainprime node from the drain of device */ + + here->B3SOIDDgjdb = Gjdb - Giib; + here->B3SOIDDgjdd = Gjdd - (Giid + Gdgidld); + here->B3SOIDDgjdg = - (Giig + Gdgidlg); + here->B3SOIDDgjde = - Giie; + if (selfheat) here->B3SOIDDgjdT = GjdT - GiiT; + else here->B3SOIDDgjdT = 0.0; + here->B3SOIDDcjd = Ibd - Iii - Idgidl - here->B3SOIDDminIsub/2 + - (here->B3SOIDDgjdb * Vbs + here->B3SOIDDgjdd * Vds + + here->B3SOIDDgjdg * Vgs + here->B3SOIDDgjde * Ves + + here->B3SOIDDgjdT * delTemp); + + /* Body current which flows into sourceprime node from the source of device */ + + here->B3SOIDDgjsb = Gjsb; + here->B3SOIDDgjsd = Gjsd; + here->B3SOIDDgjsg = - Gsgidlg; + if (selfheat) here->B3SOIDDgjsT = GjsT; + else here->B3SOIDDgjsT = 0.0; + here->B3SOIDDcjs = Ibs - Isgidl - here->B3SOIDDminIsub/2 + - (here->B3SOIDDgjsb * Vbs + here->B3SOIDDgjsd * Vds + + here->B3SOIDDgjsg * Vgs + here->B3SOIDDgjsT * delTemp); + + /* Current flowing into body node */ + + here->B3SOIDDgbbs = Giib - Gjsb - Gjdb - Gbpbs; + here->B3SOIDDgbgs = Giig + Gdgidlg + Gsgidlg - Gbpgs; + here->B3SOIDDgbds = Giid + Gdgidld - Gjsd - Gjdd - Gbpds; + here->B3SOIDDgbes = Giie - Gbpes; + here->B3SOIDDgbps = - Gbpps; + if (selfheat) here->B3SOIDDgbT = GiiT - GjsT - GjdT - GbpT; + else here->B3SOIDDgbT = 0.0; + here->B3SOIDDcbody = Iii + Idgidl + Isgidl - Ibs - Ibd - Ibp + here->B3SOIDDminIsub + - (here->B3SOIDDgbbs * Vbs + here->B3SOIDDgbgs * Vgs + + here->B3SOIDDgbds * Vds + here->B3SOIDDgbps * Vps + + here->B3SOIDDgbes * Ves + here->B3SOIDDgbT * delTemp); + + /* Calculate Qinv for Noise analysis */ + + T1 = Vgsteff * (1.0 - 0.5 * Abeff * Vdseff / Vgst2Vtm); + here->B3SOIDDqinv = -model->B3SOIDDcox * pParam->B3SOIDDweff * Leff * T1; + + /* Begin CV (charge) model */ + + if ((model->B3SOIDDxpart < 0) || (!ChargeComputationNeeded)) + { qgate = qdrn = qsrc = qbody = 0.0; + here->B3SOIDDcggb = here->B3SOIDDcgsb = here->B3SOIDDcgdb = 0.0; + here->B3SOIDDcdgb = here->B3SOIDDcdsb = here->B3SOIDDcddb = 0.0; + here->B3SOIDDcbgb = here->B3SOIDDcbsb = here->B3SOIDDcbdb = 0.0; + goto finished; + } + else + { + CoxWL = model->B3SOIDDcox * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + + /* By using this Vgsteff,cv, discontinuity in moderate + inversion charges can be avoid. However, in capMod=3, + Vdsat from IV is used. The dVdsat_dVg is referred to + the IV Vgsteff and therefore induces error in the charges + derivatives. Fortunately, Vgsteff,iv and Vgsteff,cv are + different only in subthreshold where Qsubs is neglectible. + So the errors in derivatives is not a serious problem */ + + if ((VgstNVt > -EXP_THRESHOLD) && (VgstNVt < EXP_THRESHOLD)) + { ExpVgst *= ExpVgst; + Vgsteff = n * Vtm * log(1.0 + ExpVgst); + T0 = ExpVgst / (1.0 + ExpVgst); + T1 = -T0 * (dVth_dVb + Vgst / n * dn_dVb) + Vgsteff / n * dn_dVb; + dVgsteff_dVd = -T0 * (dVth_dVd + Vgst / n * dn_dVd) + + Vgsteff / n * dn_dVd + T1 * dVbseff_dVd; + dVgsteff_dVg = T0 * dVgs_eff_dVg + T1 * dVbseff_dVg; + dVgsteff_dVb = T1 * dVbseff_dVb; + dVgsteff_dVe = T1 * dVbseff_dVe; + if (selfheat) + dVgsteff_dT = -T0 * (dVth_dT + Vgst / Temp) + Vgsteff / Temp + + T1 * dVbseff_dT; + else dVgsteff_dT = 0.0; + } + + Vfb = Vth - phi - pParam->B3SOIDDk1 * sqrtPhis; + + dVfb_dVb = dVth_dVb - pParam->B3SOIDDk1 * dsqrtPhis_dVb; + dVfb_dVd = dVth_dVd; + dVfb_dT = dVth_dT; + + if ((model->B3SOIDDcapMod == 2) || (model->B3SOIDDcapMod == 3)) + { + /* Necessary because charge behaviour very strange at + Vgsteff = 0 */ + Vgsteff += 1e-4; + + /* Something common in capMod 2 and 3 */ + V3 = Vfb - Vgs_eff + Vbseff - DELTA_3; + if (Vfb <= 0.0) + { T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); + T2 = -DELTA_3 / T0; + } + else + { T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); + T2 = DELTA_3 / T0; + } + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd; + dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb - T1; + dVfbeff_dVrg = T1 * dVgs_eff_dVg; + if (selfheat) dVfbeff_dT = (1.0 - T1 - T2) * dVfb_dT; + else dVfbeff_dT = 0.0; + + Qac0 = -CoxWL * (Vfbeff - Vfb); + dQac0_dVrg = -CoxWL * dVfbeff_dVrg; + dQac0_dVd = -CoxWL * (dVfbeff_dVd - dVfb_dVd); + dQac0_dVb = -CoxWL * (dVfbeff_dVb - dVfb_dVb); + if (selfheat) dQac0_dT = -CoxWL * (dVfbeff_dT - dVfb_dT); + else dQac0_dT = 0.0; + + T0 = 0.5 * K1; + T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; + if (pParam->B3SOIDDk1 == 0.0) + { T1 = 0.0; + T2 = 0.0; + } + else if (T3 < 0.0) + { T1 = T0 + T3 / pParam->B3SOIDDk1; + T2 = CoxWL; + } + else + { T1 = sqrt(T0 * T0 + T3); + T2 = CoxWL * T0 / T1; + } + + Qsub0 = CoxWL * K1 * (T0 - T1); + + dQsub0_dVrg = T2 * (dVfbeff_dVrg - dVgs_eff_dVg); + dQsub0_dVg = T2; + dQsub0_dVd = T2 * dVfbeff_dVd; + dQsub0_dVb = T2 * (dVfbeff_dVb + 1); + if (selfheat) dQsub0_dT = T2 * dVfbeff_dT; + else dQsub0_dT = 0.0; + + One_Third_CoxWL = CoxWL / 3.0; + Two_Third_CoxWL = 2.0 * One_Third_CoxWL; + AbulkCV = Abulk0 * pParam->B3SOIDDabulkCVfactor; + dAbulkCV_dVb = pParam->B3SOIDDabulkCVfactor * dAbulk0_dVb; + + /* This is actually capMod=2 calculation */ + VdsatCV = Vgsteff / AbulkCV; + dVdsatCV_dVg = 1.0 / AbulkCV; + dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + VdsatCV += 1e-5; + + V4 = VdsatCV - Vds - DELTA_4; + T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV); + VdseffCV = VdsatCV - 0.5 * (V4 + T0); + T1 = 0.5 * (1.0 + V4 / T0); + T2 = DELTA_4 / T0; + T3 = (1.0 - T1 - T2) / AbulkCV; + dVdseffCV_dVg = T3; + dVdseffCV_dVd = T1; + dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb; + + if (model->B3SOIDDcapMod == 2) + { + /* VdsCV Make it compatible with capMod 3 */ + VdsCV = VdseffCV; + dVdsCV_dVg = dVdseffCV_dVg; + dVdsCV_dVd = dVdseffCV_dVd; + dVdsCV_dVb = dVdseffCV_dVb; + dVdsCV_dVc = 0.0; + + /* This is good for Xc calculation */ + VdsCV += 1e-5; + if (VdsCV > (VdsatCV-1e-7)) VdsCV=VdsatCV-1e-7; + + /* VcsCV calculation */ + T1 = VdsCV - Vcs - VdsCV * VdsCV * DELTA_Vcscv; + T5 = 2 * DELTA_Vcscv; + T2 = sqrt(T1 * T1 + T5 * VdsCV * VdsCV); + + dT1_dVb = dVdsCV_dVb * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVb = (T1 * dT1_dVb + T5 * VdsCV * dVdsCV_dVb)/T2; + + dT1_dVd = dVdsCV_dVd * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVd = (T1 * dT1_dVd + T5 * VdsCV * dVdsCV_dVd)/ T2; + + dT1_dVg = dVdsCV_dVg * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) ; + dT2_dVg = (T1 * dT1_dVg + T5 * VdsCV * dVdsCV_dVg)/T2; + + dT1_dVc = -1; + dT2_dVc = T1 * dT1_dVc / T2; + + VcsCV = Vcs + 0.5 * (T1 - T2); + + dVcsCV_dVb = 0.5 * (dT1_dVb - dT2_dVb); + dVcsCV_dVg = 0.5 * (dT1_dVg - dT2_dVg); + dVcsCV_dVd = 0.5 * (dT1_dVd - dT2_dVd); + dVcsCV_dVc = 1.0 + 0.5 * (dT1_dVc - dT2_dVc); + + if (VcsCV < 0.0) VcsCV = 0.0; + else if (VcsCV > VdsCV) VcsCV = VdsCV; + + /* Xc calculation */ + T3 = 2 * VdsatCV - VcsCV; + T4 = 2 * VdsatCV - VdsCV; + dT4_dVg = 2 * dVdsatCV_dVg - dVdsCV_dVg; + dT4_dVd = - dVdsCV_dVd; + dT4_dVb = 2 * dVdsatCV_dVb - dVdsCV_dVb; + T0 = T3 * VcsCV; + T1 = T4 * VdsCV; + Xc = T0 / T1; + + dT0_dVb = VcsCV * (2 * dVdsatCV_dVb - dVcsCV_dVb) + + T3 * dVcsCV_dVb; + dT0_dVg = VcsCV * (2 * dVdsatCV_dVg - dVcsCV_dVg) + + T3 * dVcsCV_dVg; + dT0_dVd = 2 * dVcsCV_dVd * (VdsatCV - VcsCV); + dT0_dVc = 2 * dVcsCV_dVc * (VdsatCV - VcsCV); + + dT1_dVb = VdsCV * dT4_dVb + T4 * dVdsCV_dVb; + dT1_dVg = VdsCV * dT4_dVg + T4 * dVdsCV_dVg; + dT1_dVd = dVdsCV_dVd * T4 + VdsCV * dT4_dVd; + T3 = T1 * T1; + + dXc_dVb = (dT0_dVb - dT1_dVb * Xc) / T1; + dXc_dVg = (dT0_dVg - dT1_dVg * Xc) / T1; + dXc_dVd = (dT0_dVd - dT1_dVd * Xc) / T1; + dXc_dVc = dT0_dVc / T1; + + T0 = AbulkCV * VcsCV; + dT0_dVb = dAbulkCV_dVb * VcsCV + dVcsCV_dVb * AbulkCV; + dT0_dVg = dVcsCV_dVg * AbulkCV; + dT0_dVd = AbulkCV * dVcsCV_dVd; + dT0_dVc = AbulkCV * dVcsCV_dVc; + + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + dT1_dVb = -6.0 * dT0_dVb; + dT1_dVg = 12.0 * (1.0 - 0.5 * dT0_dVg); + dT1_dVd = -6.0 * dT0_dVd; + dT1_dVc = -6.0 * dT0_dVc; + + T2 = VcsCV / T1; + T4 = T1 * T1; + dT2_dVb = ( dVcsCV_dVb * T1 - dT1_dVb * VcsCV ) / T4; + dT2_dVg = ( dVcsCV_dVg * T1 - dT1_dVg * VcsCV ) / T4; + dT2_dVd = ( dVcsCV_dVd * T1 - dT1_dVd * VcsCV ) / T4; + dT2_dVc = ( dVcsCV_dVc * T1 - dT1_dVc * VcsCV ) / T4; + + T3 = T0 * T2; + dT3_dVb = dT0_dVb * T2 + dT2_dVb * T0; + dT3_dVg = dT0_dVg * T2 + dT2_dVg * T0; + dT3_dVd = dT0_dVd * T2 + dT2_dVd * T0; + dT3_dVc = dT0_dVc * T2 + dT2_dVc * T0; + + T4 = 1.0 - AbulkCV; + dT4_dVb = - dAbulkCV_dVb; + + T5 = 0.5 * VcsCV - T3; + dT5_dVb = 0.5 * dVcsCV_dVb - dT3_dVb; + dT5_dVg = 0.5 * dVcsCV_dVg - dT3_dVg; + dT5_dVd = 0.5 * dVcsCV_dVd - dT3_dVd; + dT5_dVc = 0.5 * dVcsCV_dVc - dT3_dVc; + + T6 = T4 * T5 * CoxWL; + T7 = CoxWL * Xc; + + Qsubs1 = CoxWL * Xc * T4 * T5; + dQsubs1_dVb = T6 * dXc_dVb + T7 * ( T4*dT5_dVb + dT4_dVb*T5 ); + dQsubs1_dVg = T6 * dXc_dVg + T7 * T4 * dT5_dVg; + dQsubs1_dVd = T6 * dXc_dVd + T7 * T4 * dT5_dVd; + dQsubs1_dVc = T6 * dXc_dVc + T7 * T4 * dT5_dVc; + + Qsubs2 = -CoxWL * (1-Xc) * (AbulkCV - 1.0) * Vcs; + + T2 = CoxWL * (AbulkCV - 1.0) * Vcs; + dQsubs2_dVb = T2 * dXc_dVb - CoxWL * (1-Xc) * Vcs * dAbulkCV_dVb; + dQsubs2_dVg = T2 * dXc_dVg; + dQsubs2_dVd = T2 * dXc_dVd; + dQsubs2_dVc = T2 * dXc_dVc - CoxWL * (1-Xc) * (AbulkCV - 1.0); + + Qbf = Qac0 + Qsub0 + Qsubs1 + Qsubs2; + dQbf_dVrg = dQac0_dVrg + dQsub0_dVrg; + dQbf_dVg = dQsub0_dVg + dQsubs1_dVg + dQsubs2_dVg; + dQbf_dVd = dQac0_dVd + dQsub0_dVd + dQsubs1_dVd + + dQsubs2_dVd; + dQbf_dVb = dQac0_dVb + dQsub0_dVb + dQsubs1_dVb + + dQsubs2_dVb; + dQbf_dVc = dQsubs1_dVc + dQsubs2_dVc; + dQbf_dVe = 0.0; + if (selfheat) dQbf_dT = dQac0_dT + dQsub0_dT; + else dQbf_dT = 0.0; + } /* End of if (capMod == 2) */ + else if (model->B3SOIDDcapMod == 3) + { + /* Front gate strong inversion depletion charge */ + /* VdssatCV calculation */ + + T1 = Vgsteff + K1*sqrtPhis + 0.5*K1*K1; + T2 = Vgsteff + K1*sqrtPhis + Phis + 0.25*K1*K1; + + dT1_dVb = K1*dsqrtPhis_dVb; + dT2_dVb = dT1_dVb + dPhis_dVb; + dT1_dVg = dT2_dVg = 1; + + /* Note VdsatCV is redefined in capMod = 3 */ + VdsatCV = T1 - K1*sqrt(T2); + + dVdsatCV_dVb = dT1_dVb - K1/2/sqrt(T2)*dT2_dVb; + dVdsatCV_dVg = dT1_dVg - K1/2/sqrt(T2)*dT2_dVg; + + T1 = VdsatCV - Vdsat; + dT1_dVg = dVdsatCV_dVg - dVdsat_dVg; + dT1_dVb = dVdsatCV_dVb - dVdsat_dVb; + dT1_dVd = - dVdsat_dVd; + dT1_dVc = - dVdsat_dVc; + dT1_dT = - dVdsat_dT; + + if (!(T1 == 0.0)) + { T3 = -0.5 * Vdsat / T1; /* Vdsmax */ + T2 = T3 * Vdsat; + T4 = T2 + T1 * T3 * T3; /* fmax */ + if ((Vdseff > T2) && (T1 < 0)) + { + VdsCV = T4; + T5 = -0.5 / (T1 * T1); + dT3_dVg = T5 * (T1 * dVdsat_dVg - Vdsat * dT1_dVg); + dT3_dVb = T5 * (T1 * dVdsat_dVb - Vdsat * dT1_dVb); + dT3_dVd = T5 * (T1 * dVdsat_dVd - Vdsat * dT1_dVd); + dT3_dVc = T5 * (T1 * dVdsat_dVc - Vdsat * dT1_dVc); + if (selfheat) + dT3_dT=T5 * (T1 * dVdsat_dT - Vdsat * dT1_dT); + else dT3_dT=0.0; + + dVdsCV_dVd = T3 * dVdsat_dVd + Vdsat * dT3_dVd + + T3 * (2 * T1 * dT3_dVd + T3 * dT1_dVd); + dVdsCV_dVg = T3 * dVdsat_dVg + Vdsat * dT3_dVg + + T3 * (2 * T1 * dT3_dVg + T3 * dT1_dVg); + dVdsCV_dVb = T3 * dVdsat_dVb + Vdsat * dT3_dVb + + T3 * (2 * T1 * dT3_dVb + T3 * dT1_dVb); + dVdsCV_dVc = T3 * dVdsat_dVc + Vdsat * dT3_dVc + + T3 * (2 * T1 * dT3_dVc + T3 * dT1_dVc); + if (selfheat) + dVdsCV_dT = T3 * dVdsat_dT + Vdsat * dT3_dT + + T3 * (2 * T1 * dT3_dT + T3 * dT1_dT ); + else dVdsCV_dT = 0.0; + } else + { T5 = Vdseff / Vdsat; + T6 = T5 * T5; + T7 = 2 * T1 * T5 / Vdsat; + T8 = T7 / Vdsat; + VdsCV = Vdseff + T1 * T6; + dVdsCV_dVd = dVdseff_dVd + T8 * + ( Vdsat * dVdseff_dVd + - Vdseff * dVdsat_dVd) + + T6 * dT1_dVd; + dVdsCV_dVb = dVdseff_dVb + T8 * ( Vdsat * + dVdseff_dVb - Vdseff * dVdsat_dVb) + + T6 * dT1_dVb; + dVdsCV_dVg = dVdseff_dVg + T8 * + ( Vdsat * dVdseff_dVg + - Vdseff * dVdsat_dVg) + + T6 * dT1_dVg; + dVdsCV_dVc = dVdseff_dVc + T8 * + ( Vdsat * dVdseff_dVc + - Vdseff * dVdsat_dVc) + + T6 * dT1_dVc; + if (selfheat) + dVdsCV_dT = dVdseff_dT + T8 * + ( Vdsat * dVdseff_dT + - Vdseff * dVdsat_dT ) + + T6 * dT1_dT ; + else dVdsCV_dT = 0.0; + } + } else + { VdsCV = Vdseff; + dVdsCV_dVb = dVdseff_dVb; + dVdsCV_dVd = dVdseff_dVd; + dVdsCV_dVg = dVdseff_dVg; + dVdsCV_dVc = dVdseff_dVc; + dVdsCV_dT = dVdseff_dT; + } + if (VdsCV < 0.0) VdsCV = 0.0; + VdsCV += 1e-4; + + if (VdsCV > (VdsatCV - 1e-7)) + { + VdsCV = VdsatCV - 1e-7; + } + Phisd = Phis + VdsCV; + dPhisd_dVb = dPhis_dVb + dVdsCV_dVb; + dPhisd_dVd = dVdsCV_dVd; + dPhisd_dVg = dVdsCV_dVg; + dPhisd_dVc = dVdsCV_dVc; + dPhisd_dT = dVdsCV_dT; + sqrtPhisd = sqrt(Phisd); + + /* Qdep0 - Depletion charge at Vgs=Vth */ + T10 = CoxWL * K1; + Qdep0 = T10 * sqrtPhis; + dQdep0_dVb = T10 * dsqrtPhis_dVb; + + /* VcsCV calculation */ + T1 = VdsCV - Vcs - VdsCV * VdsCV * DELTA_Vcscv; + T5 = 2 * DELTA_Vcscv; + T2 = sqrt(T1 * T1 + T5 * VdsCV * VdsCV); + + dT1_dVb = dVdsCV_dVb * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVb = (T1 * dT1_dVb + T5 * VdsCV * dVdsCV_dVb)/T2; + + dT1_dVd = dVdsCV_dVd * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dVd = (T1 * dT1_dVd + T5 * VdsCV * dVdsCV_dVd)/ T2; + + dT1_dVg = dVdsCV_dVg * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) ; + dT2_dVg = (T1 * dT1_dVg + T5 * VdsCV * dVdsCV_dVg)/T2; + + dT1_dVc = dVdsCV_dVc * (1.0 - 2.0 * VdsCV * DELTA_Vcscv) - 1; + dT2_dVc = (T1 * dT1_dVc + T5 * VdsCV * dVdsCV_dVc)/T2; + + if (selfheat) + { + dT1_dT = dVdsCV_dT * (1.0 - 2.0 * VdsCV * DELTA_Vcscv); + dT2_dT = (T1 * dT1_dT + T5 * VdsCV * dVdsCV_dT )/ T2; + } else dT1_dT = dT2_dT = 0.0; + + VcsCV = Vcs + 0.5*(T1 - T2); + + dVcsCV_dVb = 0.5 * (dT1_dVb - dT2_dVb); + dVcsCV_dVg = 0.5 * (dT1_dVg - dT2_dVg); + dVcsCV_dVd = 0.5 * (dT1_dVd - dT2_dVd); + dVcsCV_dVc = 1 + 0.5 * (dT1_dVc - dT2_dVc); + if (selfheat) + dVcsCV_dT = 0.5 * (dT1_dT - dT2_dT); + else dVcsCV_dT = 0.0; + + Phisc = Phis + VcsCV; + dPhisc_dVb = dPhis_dVb + dVcsCV_dVb; + dPhisc_dVd = dVcsCV_dVd; + dPhisc_dVg = dVcsCV_dVg; + dPhisc_dVc = dVcsCV_dVc; + dPhisc_dT = dVcsCV_dT; + sqrtPhisc = sqrt(Phisc); + + /* Xc calculation */ + T1 = Vgsteff + K1*sqrtPhis - 0.5*VdsCV; + T2 = CONST_2OV3*K1*(Phisd*sqrtPhisd - Phis*sqrtPhis); + T3 = Vgsteff + K1*sqrtPhis - 0.5*VcsCV; + T4 = CONST_2OV3*K1*(Phisc*sqrtPhisc - Phis*sqrtPhis); + T5 = T1*VdsCV - T2; + T6 = T3*VcsCV - T4; + Xc = T6/T5; + + dT1_dVb = K1*dsqrtPhis_dVb - 0.5*dVdsCV_dVb; + dT2_dVb = K1*(sqrtPhisd*dPhisd_dVb - sqrtPhis*dPhis_dVb); + dT3_dVb = K1*dsqrtPhis_dVb - 0.5*dVcsCV_dVb; + dT4_dVb = K1*(sqrtPhisc*dPhisc_dVb - sqrtPhis*dPhis_dVb); + + dT1_dVd = - 0.5*dVdsCV_dVd; + dT2_dVd = K1 * (sqrtPhisd*dPhisd_dVd); + dT3_dVd = - 0.5*dVcsCV_dVd; + dT4_dVd = K1 * (sqrtPhisc*dPhisc_dVd); + + dT1_dVg = 1 - 0.5*dVdsCV_dVg; + dT2_dVg = K1 * (sqrtPhisd*dPhisd_dVg); + dT3_dVg = 1 - 0.5*dVcsCV_dVg; + dT4_dVg = K1 * (sqrtPhisc*dPhisc_dVg); + + dT1_dVc = - 0.5*dVdsCV_dVc; + dT2_dVc = K1 * (sqrtPhisd*dPhisd_dVc); + dT3_dVc = - 0.5*dVcsCV_dVc; + dT4_dVc = K1 * (sqrtPhisc*dPhisc_dVc); + + if (selfheat) + { + dT1_dT = - 0.5*dVdsCV_dT; + dT2_dT = K1 * (sqrtPhisd*dPhisd_dT); + dT3_dT = - 0.5*dVcsCV_dT; + dT4_dT = K1 * (sqrtPhisc*dPhisc_dT); + } else dT1_dT = dT2_dT = dT3_dT = dT4_dT = 0.0; + + dT5_dVb = T1 * dVdsCV_dVb + VdsCV * dT1_dVb - dT2_dVb; + dT6_dVb = T3 * dVcsCV_dVb + VcsCV * dT3_dVb - dT4_dVb; + + dT5_dVd = T1 * dVdsCV_dVd + VdsCV * dT1_dVd - dT2_dVd; + dT6_dVd = T3 * dVcsCV_dVd + VcsCV * dT3_dVd - dT4_dVd; + + dT5_dVg = T1 * dVdsCV_dVg + VdsCV * dT1_dVg - dT2_dVg; + dT6_dVg = T3 * dVcsCV_dVg + VcsCV * dT3_dVg - dT4_dVg; + + dT5_dVc = T1 * dVdsCV_dVc + VdsCV * dT1_dVc - dT2_dVc; + dT6_dVc = T3 * dVcsCV_dVc + VcsCV * dT3_dVc - dT4_dVc; + + if (selfheat) + { + dT5_dT = T1 * dVdsCV_dT + VdsCV * dT1_dT - dT2_dT; + dT6_dT = T3 * dVcsCV_dT + VcsCV * dT3_dT - dT4_dT; + } else dT5_dT = dT6_dT = 0.0; + + dXc_dVb = (dT6_dVb - T6/T5 * dT5_dVb) / T5; + dXc_dVd = (dT6_dVd - T6/T5 * dT5_dVd) / T5; + dXc_dVg = (dT6_dVg - T6/T5 * dT5_dVg) / T5; + dXc_dVc = (dT6_dVc - T6/T5 * dT5_dVc) / T5; + if (selfheat) + dXc_dT = (dT6_dT - T6/T5 * dT5_dT ) / T5; + else dXc_dT = 0.0; + + T10 = Phis * sqrtPhis ; + T5 = Phisc * sqrtPhisc; + T0 = T5 - T10; + T1 = Vgsteff + K1*sqrtPhis + Phis; + T2 = Phisc*T5 - Phis*T10; + T3 = K1*VcsCV*(Phis + 0.5*VcsCV); + + dT0_dVb = 1.5 *(sqrtPhisc*dPhisc_dVb-sqrtPhis*dPhis_dVb); + dT1_dVb = (0.5*K1/sqrtPhis + 1) * dPhis_dVb; + dT2_dVb = 2.5 * (T5 * dPhisc_dVb - T10 * dPhis_dVb); + dT3_dVb = K1 * ( VcsCV * (dPhis_dVb + 0.5 * dVcsCV_dVb) + + dVcsCV_dVb * (Phis + 0.5*VcsCV)); + + dT0_dVd = 1.5 * sqrtPhisc * dPhisc_dVd; + dT1_dVd = 0; + dT2_dVd = 2.5 * T5 * dPhisc_dVd; + dT3_dVd = K1 * (Phis + VcsCV) * dVcsCV_dVd; + + dT0_dVg = 1.5 * sqrtPhisc * dPhisc_dVg; + dT1_dVg = 1; + dT2_dVg = 2.5 * T5 * dPhisc_dVg; + dT3_dVg = K1 * (VcsCV * 0.5 * dVcsCV_dVg + + dVcsCV_dVg * (Phis + 0.5*VcsCV)); + + dT0_dVc = 1.5 * sqrtPhisc * dPhisc_dVc; + dT1_dVc = 0.0; + dT2_dVc = 2.5 * T5 * dPhisc_dVc; + dT3_dVc = K1 * (VcsCV * 0.5 * dVcsCV_dVc + + dVcsCV_dVc * (Phis + 0.5*VcsCV)); + + if (selfheat) + { + dT0_dT = 1.5 * sqrtPhisc * dPhisc_dT; + dT1_dT = 0; + dT2_dT = 2.5 * T5 * dPhisc_dT; + dT3_dT = K1 * (Phis + VcsCV) * dVcsCV_dT; + } else dT0_dT = dT1_dT = dT2_dT = dT3_dT = 0.0; + + Nomi = K1*(CONST_2OV3*T1*T0 - 0.4*T2 - T3); + + dNomi_dVb = K1*(CONST_2OV3 * (T1 * dT0_dVb + T0*dT1_dVb) + - 0.4 * dT2_dVb - dT3_dVb); + dNomi_dVd = K1*(CONST_2OV3 * (T1 * dT0_dVd + T0*dT1_dVd) + - 0.4 * dT2_dVd - dT3_dVd); + dNomi_dVg = K1*(CONST_2OV3 * (T1 * dT0_dVg + T0*dT1_dVg) + - 0.4 * dT2_dVg - dT3_dVg); + dNomi_dVc = K1*(CONST_2OV3 * (T1 * dT0_dVc + T0*dT1_dVc) + - 0.4 * dT2_dVc - dT3_dVc); + if (selfheat) + dNomi_dT = K1*(CONST_2OV3 * (T1 * dT0_dT + T0*dT1_dT ) + - 0.4 * dT2_dT - dT3_dT ); + else + dNomi_dT = 0.0; + + T4 = Vgsteff + K1*sqrtPhis - 0.5*VdsCV; + T5 = CONST_2OV3*K1*(Phisd*sqrtPhisd - T10); + + dT4_dVb = K1 * dsqrtPhis_dVb - 0.5*dVdsCV_dVb; + dT5_dVb = K1*(sqrtPhisd*dPhisd_dVb - sqrtPhis*dPhis_dVb); + + dT4_dVd = - 0.5*dVdsCV_dVd; + dT5_dVd = K1*( sqrtPhisd * dPhisd_dVd); + + dT4_dVg = 1 - 0.5 * dVdsCV_dVg; + dT5_dVg = K1* sqrtPhisd * dPhisd_dVg; + + dT4_dVc = - 0.5 * dVdsCV_dVc; + dT5_dVc = K1* sqrtPhisd * dPhisd_dVc; + + if (selfheat) + { + dT4_dT = - 0.5 * dVdsCV_dT; + dT5_dT = K1* sqrtPhisd * dPhisd_dT; + } else dT4_dT = dT5_dT = 0.0; + + Denomi = T4*VdsCV - T5; + + dDenomi_dVb = VdsCV*dT4_dVb + T4*dVdsCV_dVb - dT5_dVb; + dDenomi_dVd = VdsCV*dT4_dVd + T4*dVdsCV_dVd - dT5_dVd; + dDenomi_dVg = VdsCV*dT4_dVg + T4*dVdsCV_dVg - dT5_dVg; + dDenomi_dVc = VdsCV*dT4_dVc + T4*dVdsCV_dVc - dT5_dVc; + if (selfheat) + dDenomi_dT = VdsCV*dT4_dT + T4*dVdsCV_dT - dT5_dT; + else dDenomi_dT = 0.0; + + T6 = -CoxWL / Denomi; + Qsubs1 = T6 * Nomi; + dQsubs1_dVb = T6*(dNomi_dVb - Nomi / Denomi*dDenomi_dVb); + dQsubs1_dVg = T6*(dNomi_dVg - Nomi / Denomi*dDenomi_dVg); + dQsubs1_dVd = T6*(dNomi_dVd - Nomi / Denomi*dDenomi_dVd); + dQsubs1_dVc = T6*(dNomi_dVc - Nomi / Denomi*dDenomi_dVc); + if (selfheat) + dQsubs1_dT = T6*(dNomi_dT - Nomi / Denomi*dDenomi_dT ); + else dQsubs1_dT = 0.0; + + T6 = sqrt(1e-4 + phi - Vbs0eff); + T7 = K1 * CoxWL; + T8 = 1 - Xc; + T10 = T7 * T6; + T11 = T7 * T8 * 0.5 / T6; + Qsubs2 = -T10 * T8 ; + dQsubs2_dVg = T10 * dXc_dVg; + dQsubs2_dVb = T10 * dXc_dVb; + dQsubs2_dVd = T10 * dXc_dVd + T11 * dVbs0eff_dVd; + dQsubs2_dVc = T10 * dXc_dVc; + dQsubs2_dVe = T11 * dVbs0eff_dVe; + dQsubs2_dVrg = T11 * dVbs0eff_dVg; + if (selfheat) + dQsubs2_dT = T10 * dXc_dT + T11 * dVbs0eff_dT; + else dQsubs2_dT = 0.0; + + Qbf = Qac0 + Qsub0 + Qsubs1 + Qsubs2 + Qdep0; + dQbf_dVrg = dQac0_dVrg + dQsub0_dVrg + dQsubs2_dVrg; + dQbf_dVg = dQsub0_dVg + dQsubs1_dVg + dQsubs2_dVg ; + dQbf_dVd = dQac0_dVd + dQsub0_dVd + dQsubs1_dVd + + dQsubs2_dVd; + dQbf_dVb = dQac0_dVb + dQsub0_dVb + dQsubs1_dVb + + dQsubs2_dVb + dQdep0_dVb; + dQbf_dVc = dQsubs1_dVc + dQsubs2_dVc; + dQbf_dVe = dQsubs2_dVe; + if (selfheat) + dQbf_dT = dQac0_dT + dQsub0_dT + dQsubs1_dT + dQsubs2_dT; + else dQbf_dT = 0.0; + } /* End of if capMod == 3 */ + + /* Something common in both capMod 2 or 3 */ + + /* Backgate charge */ + CboxWL = pParam->B3SOIDDkb3 * Cbox * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + T0 = 0.5 * K1; + T2 = sqrt(phi - Vbs0t); + T3 = phi + K1 * T2 - Vbs0t; + T4 = sqrt(T0 * T0 + T3); + Qsicv = K1 * CoxWL * ( T0 - T4); + T6 = CoxWL * T0 / T4 * (1 + T0 / T2); + if (selfheat) dQsicv_dT = T6 * dVbs0t_dT; + else dQsicv_dT = 0.0; + + T2 = sqrt(phi - Vbs0mos); + T3 = phi + K1 * T2 - Vbs0mos; + T4 = sqrt(T0 * T0 + T3); + Qbf0 = K1 * CoxWL * ( T0 - T4); + T6 = CoxWL * T0 / T4 * (1 + T0 / T2); + dQbf0_dVe = T6 * dVbs0mos_dVe; + if (selfheat) dQbf0_dT = T6 * dVbs0mos_dT; + else dQbf0_dT = 0.0; + + T5 = -CboxWL * (Vbsdio - Vbs0); + T6 = CboxWL * Xc; + Qe1 = -Qsicv + Qbf0 + T5 * Xc; + dQe1_dVg = T5 * (dXc_dVg * dVgsteff_dVg + dXc_dVb * dVbseff_dVg + + dXc_dVc * dVcs_dVg) - T6 * dVbsdio_dVg; + dQe1_dVb = T5 * (dXc_dVg * dVgsteff_dVb + dXc_dVb * dVbseff_dVb + + dXc_dVc * dVcs_dVb) - T6 * dVbsdio_dVb; + dQe1_dVd = T5 * (dXc_dVg * dVgsteff_dVd + dXc_dVb * dVbseff_dVd + + dXc_dVc * dVcs_dVd + dXc_dVd) - T6 * dVbsdio_dVd; + dQe1_dVe = dQbf0_dVe + T6 * (dVbs0_dVe - dVbsdio_dVe); + if (selfheat) + dQe1_dT = -dQsicv_dT + dQbf0_dT + + T5 * (dXc_dVg * dVgsteff_dT + dXc_dVb * dVbseff_dT + + dXc_dVc * dVcs_dT + dXc_dT ) + + T6 * (dVbs0_dT - dVbsdio_dT); + else dQe1_dT = 0.0; + + T2 = -model->B3SOIDDcboxt * pParam->B3SOIDDweffCV + * pParam->B3SOIDDleffCV; + T3 = T2 * 0.5 * (1 - Xc); + T4 = T2 * 0.5 * (VdsCV - VcsCV); + Qe2 = T2 * 0.5 * (1 - Xc) * (VdsCV - VcsCV); + + /* T10 - dVgsteff, T11 - dVbseff, T12 - dVcs */ + T10 = T3 * (dVdsCV_dVg - dVcsCV_dVg) - T4 * dXc_dVg; + T11 = T3 * (dVdsCV_dVb - dVcsCV_dVb) - T4 * dXc_dVb; + T12 = T3 * (dVdsCV_dVc - dVcsCV_dVc) - T4 * dXc_dVc; + dQe2_dVg = T10 * dVgsteff_dVg + T11 * dVbseff_dVg + T12 * dVcs_dVg; + dQe2_dVb = T10 * dVgsteff_dVb + T11 * dVbseff_dVb + T12 * dVcs_dVb; + dQe2_dVd = T10 * dVgsteff_dVd + T11 * dVbseff_dVd + T12 * dVcs_dVd + + T3 * (dVdsCV_dVd - dVcsCV_dVd) - T4 * dXc_dVd; + dQe2_dVe = T10 * dVgsteff_dVe + T11 * dVbseff_dVe + T12 * dVcs_dVe; + if (selfheat) + dQe2_dT = T10 * dVgsteff_dT + T11 * dVbseff_dT + T12 * dVcs_dT + + T3 * (dVdsCV_dT - dVcsCV_dT ) - T4 * dXc_dT; + else dQe2_dT = 0.0; + + /* This transform all the dependency on Vgsteff, Vbseff, + Vcs into real ones */ + Cbg = dQbf_dVrg + dQbf_dVg * dVgsteff_dVg + + dQbf_dVb * dVbseff_dVg + dQbf_dVc * dVcs_dVg; + Cbb = dQbf_dVg * dVgsteff_dVb + dQbf_dVb * dVbseff_dVb + + dQbf_dVc * dVcs_dVb; + Cbd = dQbf_dVg * dVgsteff_dVd + dQbf_dVb * dVbseff_dVd + + dQbf_dVc * dVcs_dVd + dQbf_dVd; + Cbe = dQbf_dVg * dVgsteff_dVe + dQbf_dVb * dVbseff_dVe + + dQbf_dVc * dVcs_dVe + dQbf_dVe; + if (selfheat) + CbT = dQbf_dVg * dVgsteff_dT + dQbf_dVb * dVbseff_dT + + dQbf_dVc * dVcs_dT + dQbf_dT; + else CbT = 0.0; + + Ce1g = dQe1_dVg; + Ce1b = dQe1_dVb; + Ce1d = dQe1_dVd; + Ce1e = dQe1_dVe; + Ce1T = dQe1_dT; + + Ce2g = dQe2_dVg; + Ce2b = dQe2_dVb; + Ce2d = dQe2_dVd; + Ce2e = dQe2_dVe; + Ce2T = dQe2_dT; + + /* Total inversion charge */ + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qinv = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Cgd1 = CoxWL * T5 * dVdseffCV_dVd; + Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + /* Inversion charge partitioning into S / D */ + if (model->B3SOIDDxpart > 0.5) + { /* 0/100 Charge partition model */ + T1 = T1 + T1; + qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 + - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); + Csg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); + Csd1 = CoxWL * T5 * dVdseffCV_dVd; + Csb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb); + + } + else if (model->B3SOIDDxpart < 0.5) + { /* 40/60 Charge partition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff + * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 + * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + Csg1 = T4 + T5 * dVdseffCV_dVg; + Csd1 = T5 * dVdseffCV_dVd; + Csb1 = T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb; + } + else + { /* 50/50 Charge partition model */ + qsrc = - 0.5 * qinv; + Csg1 = - 0.5 * Cgg1; + Csb1 = - 0.5 * Cgb1; + Csd1 = - 0.5 * Cgd1; + } + + Csg = Csg1 * dVgsteff_dVg + Csb1 * dVbseff_dVg; + Csd = Csd1 + Csg1 * dVgsteff_dVd + Csb1 * dVbseff_dVd; + Csb = Csg1 * dVgsteff_dVb + Csb1 * dVbseff_dVb; + Cse = Csg1 * dVgsteff_dVe + Csb1 * dVbseff_dVe; + if (selfheat) + CsT = Csg1 * dVgsteff_dT + Csb1 * dVbseff_dT; + else CsT = 0.0; + + T0 = QEX_FACT * K1 * CoxWL; + Qex = T0 * (Vbs - Vbsdio); + dQex_dVg = - T0 * dVbsdio_dVg; + dQex_dVb = T0 * (1 - dVbsdio_dVb); + dQex_dVd = - T0 * dVbsdio_dVd; + dQex_dVe = - T0 * dVbsdio_dVe; + if (selfheat) dQex_dT = - T0 * dVbsdio_dT; + else dQex_dT = 0.0; + + qgate = qinv - (Qbf + Qe2); + qbody = (Qbf - Qe1 + Qex); + qsub = Qe1 + Qe2 - Qex; + qdrn = -(qinv + qsrc); + + Cgg = (Cgg1 * dVgsteff_dVg + Cgb1 * dVbseff_dVg) - Cbg ; + Cgd = (Cgd1 + Cgg1 * dVgsteff_dVd + Cgb1 * dVbseff_dVd)-Cbd; + Cgb = (Cgb1 * dVbseff_dVb + Cgg1 * dVgsteff_dVb) - Cbb; + Cge = (Cgg1 * dVgsteff_dVe + Cgb1 * dVbseff_dVe) - Cbe; + if (selfheat) + CgT = (Cgg1 * dVgsteff_dT + Cgb1 * dVbseff_dT ) - CbT; + else CgT = 0.0; + + here->B3SOIDDcggb = Cgg - Ce2g; + here->B3SOIDDcgsb = - (Cgg + Cgd + Cgb + Cge) + + (Ce2g + Ce2d + Ce2b + Ce2e); + here->B3SOIDDcgdb = Cgd - Ce2d; + here->B3SOIDDcgeb = Cge - Ce2e; + here->B3SOIDDcgT = CgT - Ce2T; + + here->B3SOIDDcbgb = Cbg - Ce1g + dQex_dVg; + here->B3SOIDDcbsb = -(Cbg + Cbd + Cbb + Cbe) + + (Ce1g + Ce1d + Ce1b + Ce1e) + - (dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIDDcbdb = Cbd - Ce1d + dQex_dVd; + here->B3SOIDDcbeb = Cbe - Ce1e + dQex_dVe; + here->B3SOIDDcbT = CbT - Ce1T + dQex_dT; + + here->B3SOIDDcegb = Ce1g + Ce2g - dQex_dVg; + here->B3SOIDDcesb = -(Ce1g + Ce1d + Ce1b + Ce1e) + -(Ce2g + Ce2d + Ce2b + Ce2e) + +(dQex_dVg + dQex_dVd + dQex_dVb + dQex_dVe); + here->B3SOIDDcedb = Ce1d + Ce2d - dQex_dVd; + here->B3SOIDDceeb = Ce1e + Ce2e - dQex_dVe; + here->B3SOIDDceT = Ce1T + Ce2T - dQex_dT; + + here->B3SOIDDcdgb = -(Cgg + Cbg + Csg); + here->B3SOIDDcddb = -(Cgd + Cbd + Csd); + here->B3SOIDDcdeb = -(Cge + Cbe + Cse); + here->B3SOIDDcdT = -(CgT + CbT + CsT); + here->B3SOIDDcdsb = (Cgg + Cgd + Cgb + Cge + + Cbg + Cbd + Cbb + Cbe + + Csg + Csd + Csb + Cse); + + } /* End of if capMod == 2 or capMod ==3 */ + } + + finished: /* returning Values to Calling Routine */ + /* + * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE + */ + if (ChargeComputationNeeded) + { + /* Intrinsic S/D junction charge */ + PhiBSWG = model->B3SOIDDGatesidewallJctPotential; + MJSWG = model->B3SOIDDbodyJctGateSideGradingCoeff; + cjsbs = model->B3SOIDDunitLengthGateSidewallJctCap + * pParam->B3SOIDDweff * model->B3SOIDDtsi / 1e-7; + if (Vbs < 0.0) + { arg = 1.0 - Vbs / PhiBSWG; + if (MJSWG == 0.5) + dT3_dVb = 1.0 / sqrt(arg); + else + dT3_dVb = exp(-MJSWG * log(arg)); + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + } + else + { T3 = Vbs * ( 1 + 0.5 * MJSWG * Vbs / PhiBSWG); + dT3_dVb = 1 + MJSWG * Vbs / PhiBSWG; + } + + qjs = cjsbs * T3 + model->B3SOIDDtt * Ibs1; + gcjsbs = cjsbs * dT3_dVb + model->B3SOIDDtt * dIbs1_dVb; + if (selfheat) gcjsT = model->B3SOIDDtt * dIbs1_dT; + else gcjsT = 0.0; + + if (Vbd < 0.0) + { arg = 1.0 - Vbd / PhiBSWG; + if (MJSWG == 0.5) + dT3_dVb = 1.0 / sqrt(arg); + else + dT3_dVb = exp(-MJSWG * log(arg)); + T3 = (1.0 - arg * dT3_dVb) * PhiBSWG / (1.0 - MJSWG); + } + else + { T3 = Vbd * ( 1 + 0.5 * MJSWG * Vbd / PhiBSWG); + dT3_dVb = 1 + MJSWG * Vbd / PhiBSWG; + } + dT3_dVd = - dT3_dVb; + + qjd = cjsbs * T3 + model->B3SOIDDtt * Ibd1; + gcjdbs = cjsbs * dT3_dVb + model->B3SOIDDtt * dIbd1_dVb; + gcjdds = cjsbs * dT3_dVd + model->B3SOIDDtt * dIbd1_dVd; + if (selfheat) gcjdT = model->B3SOIDDtt * dIbd1_dT; + else gcjdT = 0.0; + + qdrn -= qjd; + qbody += (qjs + qjd); + qsrc = -(qgate + qbody + qdrn + qsub); + + /* Update the conductance */ + here->B3SOIDDcddb -= gcjdds; + here->B3SOIDDcdT -= gcjdT; + here->B3SOIDDcdsb += gcjdds + gcjdbs; + + here->B3SOIDDcbdb += (gcjdds); + here->B3SOIDDcbT += (gcjdT + gcjsT); + here->B3SOIDDcbsb -= (gcjdds + gcjdbs + gcjsbs); + + /* Extrinsic Bottom S/D to substrate charge */ + T10 = -model->B3SOIDDtype * ves; + /* T10 is vse without type conversion */ + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + if (T10 < pParam->B3SOIDDvsdfb) + { here->B3SOIDDqse = here->B3SOIDDcsbox * (T10 - pParam->B3SOIDDvsdfb); + here->B3SOIDDgcse = here->B3SOIDDcsbox; + } + else if (T10 < pParam->B3SOIDDsdt1) + { T0 = T10 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqse = T0 * (here->B3SOIDDcsbox - + pParam->B3SOIDDst2 / 3 * T1) ; + here->B3SOIDDgcse = here->B3SOIDDcsbox - pParam->B3SOIDDst2 * T1; + } + else if (T10 < pParam->B3SOIDDvsdth) + { T0 = T10 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqse = here->B3SOIDDcsmin * T10 + here->B3SOIDDst4 + + pParam->B3SOIDDst3 / 3 * T0 * T1; + here->B3SOIDDgcse = here->B3SOIDDcsmin + pParam->B3SOIDDst3 * T1; + } + else + { here->B3SOIDDqse = here->B3SOIDDcsmin * T10 + here->B3SOIDDst4; + here->B3SOIDDgcse = here->B3SOIDDcsmin; + } + } else + { + if (T10 < pParam->B3SOIDDvsdth) + { here->B3SOIDDqse = here->B3SOIDDcsmin * (T10 - pParam->B3SOIDDvsdth); + here->B3SOIDDgcse = here->B3SOIDDcsmin; + } + else if (T10 < pParam->B3SOIDDsdt1) + { T0 = T10 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqse = T0 * (here->B3SOIDDcsmin - pParam->B3SOIDDst2 / 3 * T1) ; + here->B3SOIDDgcse = here->B3SOIDDcsmin - pParam->B3SOIDDst2 * T1; + } + else if (T10 < pParam->B3SOIDDvsdfb) + { T0 = T10 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqse = here->B3SOIDDcsbox * T10 + here->B3SOIDDst4 + + pParam->B3SOIDDst3 / 3 * T0 * T1; + here->B3SOIDDgcse = here->B3SOIDDcsbox + pParam->B3SOIDDst3 * T1; + } + else + { here->B3SOIDDqse = here->B3SOIDDcsbox * T10 + here->B3SOIDDst4; + here->B3SOIDDgcse = here->B3SOIDDcsbox; + } + } + + /* T11 is vde without type conversion */ + T11 = model->B3SOIDDtype * (vds - ves); + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + if (T11 < pParam->B3SOIDDvsdfb) + { here->B3SOIDDqde = here->B3SOIDDcdbox * (T11 - pParam->B3SOIDDvsdfb); + here->B3SOIDDgcde = here->B3SOIDDcdbox; + } + else if (T11 < pParam->B3SOIDDsdt1) + { T0 = T11 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqde = T0 * (here->B3SOIDDcdbox - pParam->B3SOIDDdt2 / 3 * T1) ; + here->B3SOIDDgcde = here->B3SOIDDcdbox - pParam->B3SOIDDdt2 * T1; + } + else if (T11 < pParam->B3SOIDDvsdth) + { T0 = T11 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqde = here->B3SOIDDcdmin * T11 + here->B3SOIDDdt4 + + pParam->B3SOIDDdt3 / 3 * T0 * T1; + here->B3SOIDDgcde = here->B3SOIDDcdmin + pParam->B3SOIDDdt3 * T1; + } + else + { here->B3SOIDDqde = here->B3SOIDDcdmin * T11 + here->B3SOIDDdt4; + here->B3SOIDDgcde = here->B3SOIDDcdmin; + } + } else + { + if (T11 < pParam->B3SOIDDvsdth) + { here->B3SOIDDqde = here->B3SOIDDcdmin * (T11 - pParam->B3SOIDDvsdth); + here->B3SOIDDgcde = here->B3SOIDDcdmin; + } + else if (T11 < pParam->B3SOIDDsdt1) + { T0 = T11 - pParam->B3SOIDDvsdth; + T1 = T0 * T0; + here->B3SOIDDqde = T0 * (here->B3SOIDDcdmin - pParam->B3SOIDDdt2 / 3 * T1) ; + here->B3SOIDDgcde = here->B3SOIDDcdmin - pParam->B3SOIDDdt2 * T1; + } + else if (T11 < pParam->B3SOIDDvsdfb) + { T0 = T11 - pParam->B3SOIDDvsdfb; + T1 = T0 * T0; + here->B3SOIDDqde = here->B3SOIDDcdbox * T11 + here->B3SOIDDdt4 + + pParam->B3SOIDDdt3 / 3 * T0 * T1; + here->B3SOIDDgcde = here->B3SOIDDcdbox + pParam->B3SOIDDdt3 * T1; + } + else + { here->B3SOIDDqde = here->B3SOIDDcdbox * T11 + here->B3SOIDDdt4; + here->B3SOIDDgcde = here->B3SOIDDcdbox; + } + } + + /* Extrinsic : Sidewall fringing S/D charge */ + here->B3SOIDDqse += pParam->B3SOIDDcsesw * T10; + here->B3SOIDDgcse += pParam->B3SOIDDcsesw; + here->B3SOIDDqde += pParam->B3SOIDDcdesw * T11; + here->B3SOIDDgcde += pParam->B3SOIDDcdesw; + + /* All charge are mutliplied with type at the end, but qse and qde + have true polarity => so pre-mutliplied with type */ + here->B3SOIDDqse *= model->B3SOIDDtype; + here->B3SOIDDqde *= model->B3SOIDDtype; + } + + here->B3SOIDDxc = Xc; + here->B3SOIDDcbb = Cbb; + here->B3SOIDDcbd = Cbd; + here->B3SOIDDcbg = Cbg; + here->B3SOIDDqbf = Qbf; + here->B3SOIDDqjs = qjs; + here->B3SOIDDqjd = qjd; + + if (here->B3SOIDDdebugMod == -1) + ChargeComputationNeeded = 0; + + /* + * check convergence + */ + if ((here->B3SOIDDoff == 0) || (!(ckt->CKTmode & MODEINITFIX))) + { if (Check == 1) + { ckt->CKTnoncon++; +if (here->B3SOIDDdebugMod > 2) + fprintf(fpdebug, "Check is on, noncon=%d\n", ckt->CKTnoncon++); +#ifndef NEWCONV + } + else + { tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(here->B3SOIDDcd)) + + ckt->CKTabstol; + if (fabs(cdhat - here->B3SOIDDcd) >= tol) + { ckt->CKTnoncon++; + } + else + { tol = ckt->CKTreltol * MAX(fabs(cbhat), + fabs(here->B3SOIDDcbs + here->B3SOIDDcbd)) + + ckt->CKTabstol; + if (fabs(cbhat - (here->B3SOIDDcbs + here->B3SOIDDcbd)) + > tol) + { ckt->CKTnoncon++; + } + } +#endif /* NEWCONV */ + } + } + + *(ckt->CKTstate0 + here->B3SOIDDvg) = vg; + *(ckt->CKTstate0 + here->B3SOIDDvd) = vd; + *(ckt->CKTstate0 + here->B3SOIDDvs) = vs; + *(ckt->CKTstate0 + here->B3SOIDDvp) = vp; + *(ckt->CKTstate0 + here->B3SOIDDve) = ve; + + *(ckt->CKTstate0 + here->B3SOIDDvbs) = vbs; + *(ckt->CKTstate0 + here->B3SOIDDvbd) = vbd; + *(ckt->CKTstate0 + here->B3SOIDDvgs) = vgs; + *(ckt->CKTstate0 + here->B3SOIDDvds) = vds; + *(ckt->CKTstate0 + here->B3SOIDDves) = ves; + *(ckt->CKTstate0 + here->B3SOIDDvps) = vps; + *(ckt->CKTstate0 + here->B3SOIDDdeltemp) = delTemp; + + /* bulk and channel charge plus overlaps */ + + if (!ChargeComputationNeeded) + goto line850; + + line755: + ag0 = ckt->CKTag[0]; + + T0 = vgd + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = pParam->B3SOIDDweffCV * pParam->B3SOIDDcgdl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIDDckappa); + cgdo = pParam->B3SOIDDcgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->B3SOIDDcgdo + T3) * vgd - T3 * (T2 + + 0.5 * pParam->B3SOIDDckappa * (T4 - 1.0)); + + T0 = vgs + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = pParam->B3SOIDDweffCV * pParam->B3SOIDDcgsl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->B3SOIDDckappa); + cgso = pParam->B3SOIDDcgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->B3SOIDDcgso + T3) * vgs - T3 * (T2 + + 0.5 * pParam->B3SOIDDckappa * (T4 - 1.0)); + + + if (here->B3SOIDDmode > 0) + { gcdgb = (here->B3SOIDDcdgb - cgdo) * ag0; + gcddb = (here->B3SOIDDcddb + cgdo + here->B3SOIDDgcde) * ag0; + gcdsb = here->B3SOIDDcdsb * ag0; + gcdeb = (here->B3SOIDDcdeb - here->B3SOIDDgcde) * ag0; + gcdT = model->B3SOIDDtype * here->B3SOIDDcdT * ag0; + + gcsgb = -(here->B3SOIDDcggb + here->B3SOIDDcbgb + here->B3SOIDDcdgb + + here->B3SOIDDcegb + cgso) * ag0; + gcsdb = -(here->B3SOIDDcgdb + here->B3SOIDDcbdb + here->B3SOIDDcddb + + here->B3SOIDDcedb) * ag0; + gcssb = (cgso + here->B3SOIDDgcse - (here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcdsb + here->B3SOIDDcesb)) * ag0; + gcseb = -(here->B3SOIDDgcse + here->B3SOIDDcgeb + here->B3SOIDDcbeb + here->B3SOIDDcdeb + + here->B3SOIDDceeb) * ag0; + gcsT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + here->B3SOIDDcdT + + here->B3SOIDDceT) * ag0; + + gcggb = (here->B3SOIDDcggb + cgdo + cgso + pParam->B3SOIDDcgeo) * ag0; + gcgdb = (here->B3SOIDDcgdb - cgdo) * ag0; + gcgsb = (here->B3SOIDDcgsb - cgso) * ag0; + gcgeb = (here->B3SOIDDcgeb - pParam->B3SOIDDcgeo) * ag0; + gcgT = model->B3SOIDDtype * here->B3SOIDDcgT * ag0; + + gcbgb = here->B3SOIDDcbgb * ag0; + gcbdb = here->B3SOIDDcbdb * ag0; + gcbsb = here->B3SOIDDcbsb * ag0; + gcbeb = here->B3SOIDDcbeb * ag0; + gcbT = model->B3SOIDDtype * here->B3SOIDDcbT * ag0; + + gcegb = (here->B3SOIDDcegb - pParam->B3SOIDDcgeo) * ag0; + gcedb = (here->B3SOIDDcedb - here->B3SOIDDgcde) * ag0; + gcesb = (here->B3SOIDDcesb - here->B3SOIDDgcse) * ag0; + gceeb = (here->B3SOIDDgcse + here->B3SOIDDgcde + + here->B3SOIDDceeb + pParam->B3SOIDDcgeo) * ag0; + + gceT = model->B3SOIDDtype * here->B3SOIDDceT * ag0; + + gcTt = pParam->B3SOIDDcth * ag0; + + sxpart = 0.6; + dxpart = 0.4; + + /* Lump the overlap capacitance and S/D parasitics */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIDDcgeo * vge; + qgate += qgd + qgs + qge; + qdrn += here->B3SOIDDqde - qgd; + qsub -= qge + here->B3SOIDDqse + here->B3SOIDDqde; + qsrc = -(qgate + qbody + qdrn + qsub); + } + else + { gcsgb = (here->B3SOIDDcdgb - cgso) * ag0; + gcssb = (here->B3SOIDDcddb + cgso + here->B3SOIDDgcse) * ag0; + gcsdb = here->B3SOIDDcdsb * ag0; + gcseb = (here->B3SOIDDcdeb - here->B3SOIDDgcse) * ag0; + gcsT = model->B3SOIDDtype * here->B3SOIDDcdT * ag0; + + gcdgb = -(here->B3SOIDDcggb + here->B3SOIDDcbgb + here->B3SOIDDcdgb + + here->B3SOIDDcegb + cgdo) * ag0; + gcdsb = -(here->B3SOIDDcgdb + here->B3SOIDDcbdb + here->B3SOIDDcddb + + here->B3SOIDDcedb) * ag0; + gcddb = (cgdo + here->B3SOIDDgcde - (here->B3SOIDDcgsb + here->B3SOIDDcbsb + + here->B3SOIDDcdsb + here->B3SOIDDcesb)) * ag0; + gcdeb = -(here->B3SOIDDgcde + here->B3SOIDDcgeb + here->B3SOIDDcbeb + here->B3SOIDDcdeb + + here->B3SOIDDceeb) * ag0; + gcdT = - model->B3SOIDDtype * (here->B3SOIDDcgT + here->B3SOIDDcbT + + here->B3SOIDDcdT + here->B3SOIDDceT) * ag0; + + gcggb = (here->B3SOIDDcggb + cgdo + cgso + pParam->B3SOIDDcgeo) * ag0; + gcgsb = (here->B3SOIDDcgdb - cgso) * ag0; + gcgdb = (here->B3SOIDDcgsb - cgdo) * ag0; + gcgeb = (here->B3SOIDDcgeb - pParam->B3SOIDDcgeo) * ag0; + gcgT = model->B3SOIDDtype * here->B3SOIDDcgT * ag0; + + gcbgb = here->B3SOIDDcbgb * ag0; + gcbsb = here->B3SOIDDcbdb * ag0; + gcbdb = here->B3SOIDDcbsb * ag0; + gcbeb = here->B3SOIDDcbeb * ag0; + gcbT = model->B3SOIDDtype * here->B3SOIDDcbT * ag0; + + gcegb = (here->B3SOIDDcegb - pParam->B3SOIDDcgeo) * ag0; + gcesb = (here->B3SOIDDcedb - here->B3SOIDDgcse) * ag0; + gcedb = (here->B3SOIDDcesb - here->B3SOIDDgcde) * ag0; + gceeb = (here->B3SOIDDceeb + pParam->B3SOIDDcgeo + + here->B3SOIDDgcse + here->B3SOIDDgcde) * ag0; + gceT = model->B3SOIDDtype * here->B3SOIDDceT * ag0; + + gcTt = pParam->B3SOIDDcth * ag0; + + dxpart = 0.6; + sxpart = 0.4; + + /* Lump the overlap capacitance */ + qgd = qgdo; + qgs = qgso; + qge = pParam->B3SOIDDcgeo * vge; + qgate += qgd + qgs + qge; + qsrc = qdrn - qgs + here->B3SOIDDqse; + qsub -= qge + here->B3SOIDDqse + here->B3SOIDDqde; + qdrn = -(qgate + qbody + qsrc + qsub); + } + + here->B3SOIDDcgdo = cgdo; + here->B3SOIDDcgso = cgso; + + if (ByPass) goto line860; + + *(ckt->CKTstate0 + here->B3SOIDDqe) = qsub; + *(ckt->CKTstate0 + here->B3SOIDDqg) = qgate; + *(ckt->CKTstate0 + here->B3SOIDDqd) = qdrn; + *(ckt->CKTstate0 + here->B3SOIDDqb) = qbody; + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) + *(ckt->CKTstate0 + here->B3SOIDDqth) = pParam->B3SOIDDcth * delTemp; + + + /* store small signal parameters */ + if (ckt->CKTmode & MODEINITSMSIG) + { goto line1000; + } + if (!ChargeComputationNeeded) + goto line850; + + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIDDqb) = + *(ckt->CKTstate0 + here->B3SOIDDqb); + *(ckt->CKTstate1 + here->B3SOIDDqg) = + *(ckt->CKTstate0 + here->B3SOIDDqg); + *(ckt->CKTstate1 + here->B3SOIDDqd) = + *(ckt->CKTstate0 + here->B3SOIDDqd); + *(ckt->CKTstate1 + here->B3SOIDDqe) = + *(ckt->CKTstate0 + here->B3SOIDDqe); + *(ckt->CKTstate1 + here->B3SOIDDqth) = + *(ckt->CKTstate0 + here->B3SOIDDqth); + } + + error = NIintegrate(ckt, &geq, &ceq,0.0,here->B3SOIDDqb); + if (error) return(error); + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIDDqg); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIDDqd); + if (error) return(error); + error = NIintegrate(ckt,&geq, &ceq, 0.0, here->B3SOIDDqe); + if (error) return(error); + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) + { + error = NIintegrate(ckt, &geq, &ceq, 0.0, here->B3SOIDDqth); + if (error) return (error); + } + + goto line860; + + line850: + /* initialize to zero charge conductance and current */ + ceqqe = ceqqg = ceqqb = ceqqd = ceqqth= 0.0; + + gcdgb = gcddb = gcdsb = gcdeb = gcdT = 0.0; + gcsgb = gcsdb = gcssb = gcseb = gcsT = 0.0; + gcggb = gcgdb = gcgsb = gcgeb = gcgT = 0.0; + gcbgb = gcbdb = gcbsb = gcbeb = gcbT = 0.0; + gcegb = gcedb = gceeb = gcesb = gceT = 0.0; + gcTt = 0.0; + + sxpart = (1.0 - (dxpart = (here->B3SOIDDmode > 0) ? 0.4 : 0.6)); + + goto line900; + + line860: + /* evaluate equivalent charge current */ + + cqgate = *(ckt->CKTstate0 + here->B3SOIDDcqg); + cqbody = *(ckt->CKTstate0 + here->B3SOIDDcqb); + cqdrn = *(ckt->CKTstate0 + here->B3SOIDDcqd); + cqsub = *(ckt->CKTstate0 + here->B3SOIDDcqe); + cqtemp = *(ckt->CKTstate0 + here->B3SOIDDcqth); + + here->B3SOIDDcb += cqbody; + here->B3SOIDDcd += cqdrn; + + ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs + - gcgeb * veb - gcgT * delTemp; + ceqqb = cqbody - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs + - gcbeb * veb - gcbT * delTemp; + ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs + - gcdeb * veb - gcdT * delTemp; + ceqqe = cqsub - gcegb * vgb + gcedb * vbd + gcesb * vbs + - gceeb * veb - gceT * delTemp;; + ceqqth = cqtemp - gcTt * delTemp; + + if (ckt->CKTmode & MODEINITTRAN) + { *(ckt->CKTstate1 + here->B3SOIDDcqe) = + *(ckt->CKTstate0 + here->B3SOIDDcqe); + *(ckt->CKTstate1 + here->B3SOIDDcqb) = + *(ckt->CKTstate0 + here->B3SOIDDcqb); + *(ckt->CKTstate1 + here->B3SOIDDcqg) = + *(ckt->CKTstate0 + here->B3SOIDDcqg); + *(ckt->CKTstate1 + here->B3SOIDDcqd) = + *(ckt->CKTstate0 + here->B3SOIDDcqd); + *(ckt->CKTstate1 + here->B3SOIDDcqth) = + *(ckt->CKTstate0 + here->B3SOIDDcqth); + } + + /* + * load current vector + */ + line900: + + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + Gme = here->B3SOIDDgme; + GmT = model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = Gm + Gmbs + Gme; + RevSum = 0.0; + cdreq = model->B3SOIDDtype * (here->B3SOIDDcdrain - here->B3SOIDDgds * vds + - Gm * vgs - Gmbs * vbs - Gme * ves - GmT * delTemp); + /* ceqbs now is compatible with cdreq, ie. going in is +ve */ + /* Equivalent current source from the diode */ + ceqbs = here->B3SOIDDcjs; + ceqbd = here->B3SOIDDcjd; + /* Current going in is +ve */ + ceqbody = -here->B3SOIDDcbody; + ceqth = here->B3SOIDDcth; + ceqbodcon = here->B3SOIDDcbodcon; + + gbbg = -here->B3SOIDDgbgs; + gbbdp = -here->B3SOIDDgbds; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbsp = - ( gbbg + gbbdp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjdg; + gddpdp = -here->B3SOIDDgjdd; + gddpb = -here->B3SOIDDgjdb; + gddpe = -here->B3SOIDDgjde; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gddpsp = - ( gddpg + gddpdp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjsg; + gsspdp = -here->B3SOIDDgjsd; + gsspb = -here->B3SOIDDgjsb; + gsspe = 0.0; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gsspsp = - (gsspg + gsspdp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppdp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppsp = - (gppg + gppdp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtdp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtsp = - (gTtg + gTtb + gTte + gTtdp); + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + Gme = -here->B3SOIDDgme; + GmT = -model->B3SOIDDtype * here->B3SOIDDgmT; + FwdSum = 0.0; + RevSum = -(Gm + Gmbs + Gme); + cdreq = -model->B3SOIDDtype * (here->B3SOIDDcdrain + here->B3SOIDDgds*vds + + Gm * vgd + Gmbs * vbd + Gme * (ves - vds) + GmT * delTemp); + ceqbs = here->B3SOIDDcjd; + ceqbd = here->B3SOIDDcjs; + /* Current going in is +ve */ + ceqbody = -here->B3SOIDDcbody; + ceqth = here->B3SOIDDcth; + ceqbodcon = here->B3SOIDDcbodcon; + + gbbg = -here->B3SOIDDgbgs; + gbbb = -here->B3SOIDDgbbs; + gbbe = -here->B3SOIDDgbes; + gbbp = -here->B3SOIDDgbps; + gbbsp = -here->B3SOIDDgbds; + gbbT = -model->B3SOIDDtype * here->B3SOIDDgbT; + gbbdp = - ( gbbg + gbbsp + gbbb + gbbe + gbbp); + + gddpg = -here->B3SOIDDgjsg; + gddpsp = -here->B3SOIDDgjsd; + gddpb = -here->B3SOIDDgjsb; + gddpe = 0.0; + gddpT = -model->B3SOIDDtype * here->B3SOIDDgjsT; + gddpdp = - (gddpg + gddpsp + gddpb + gddpe); + + gsspg = -here->B3SOIDDgjdg; + gsspsp = -here->B3SOIDDgjdd; + gsspb = -here->B3SOIDDgjdb; + gsspe = -here->B3SOIDDgjde; + gsspT = -model->B3SOIDDtype * here->B3SOIDDgjdT; + gsspdp = - ( gsspg + gsspsp + gsspb + gsspe); + + gppg = -here->B3SOIDDgbpgs; + gppsp = -here->B3SOIDDgbpds; + gppb = -here->B3SOIDDgbpbs; + gppe = -here->B3SOIDDgbpes; + gppp = -here->B3SOIDDgbpps; + gppT = -model->B3SOIDDtype * here->B3SOIDDgbpT; + gppdp = - (gppg + gppsp + gppb + gppe + gppp); + + gTtg = here->B3SOIDDgtempg; + gTtb = here->B3SOIDDgtempb; + gTte = here->B3SOIDDgtempe; + gTtsp = here->B3SOIDDgtempd; + gTtt = here->B3SOIDDgtempT; + gTtdp = - (gTtg + gTtb + gTte + gTtsp); + } + + if (model->B3SOIDDtype > 0) + { + ceqqg = ceqqg; + ceqqb = ceqqb; + ceqqe = ceqqe; + ceqqd = ceqqd; + } + else + { + ceqbodcon = -ceqbodcon; + ceqbody = -ceqbody; + ceqbs = -ceqbs; + ceqbd = -ceqbd; + ceqqg = -ceqqg; + ceqqb = -ceqqb; + ceqqd = -ceqqd; + ceqqe = -ceqqe; + } + + (*(ckt->CKTrhs + here->B3SOIDDbNode) -=(ceqbody+ceqqb)); + + (*(ckt->CKTrhs + here->B3SOIDDgNode) -= ceqqg); + (*(ckt->CKTrhs + here->B3SOIDDdNodePrime) += (ceqbd - cdreq - ceqqd)); + (*(ckt->CKTrhs + here->B3SOIDDsNodePrime) += (cdreq + ceqbs + ceqqg + + ceqqb + ceqqd + ceqqe)); + (*(ckt->CKTrhs + here->B3SOIDDeNode) -= ceqqe); + + if (here->B3SOIDDbodyMod == 1) { + (*(ckt->CKTrhs + here->B3SOIDDpNode) += ceqbodcon); + } + + if (selfheat) { + (*(ckt->CKTrhs + here->B3SOIDDtempNode) -= ceqth + ceqqth); + } + + + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + *(ckt->CKTrhs + here->B3SOIDDvbsNode) = here->B3SOIDDvbsdio; + *(ckt->CKTrhs + here->B3SOIDDidsNode) = here->B3SOIDDids; + *(ckt->CKTrhs + here->B3SOIDDicNode) = here->B3SOIDDic; + *(ckt->CKTrhs + here->B3SOIDDibsNode) = here->B3SOIDDibs; + *(ckt->CKTrhs + here->B3SOIDDibdNode) = here->B3SOIDDibd; + *(ckt->CKTrhs + here->B3SOIDDiiiNode) = here->B3SOIDDiii; + *(ckt->CKTrhs + here->B3SOIDDigidlNode) = here->B3SOIDDigidl; + *(ckt->CKTrhs + here->B3SOIDDitunNode) = here->B3SOIDDitun; + *(ckt->CKTrhs + here->B3SOIDDibpNode) = here->B3SOIDDibp; + *(ckt->CKTrhs + here->B3SOIDDabeffNode) = here->B3SOIDDabeff; + *(ckt->CKTrhs + here->B3SOIDDvbs0effNode) = here->B3SOIDDvbs0eff; + *(ckt->CKTrhs + here->B3SOIDDvbseffNode) = here->B3SOIDDvbseff; + *(ckt->CKTrhs + here->B3SOIDDxcNode) = here->B3SOIDDxc; + *(ckt->CKTrhs + here->B3SOIDDcbbNode) = here->B3SOIDDcbb; + *(ckt->CKTrhs + here->B3SOIDDcbdNode) = here->B3SOIDDcbd; + *(ckt->CKTrhs + here->B3SOIDDcbgNode) = here->B3SOIDDcbg; + *(ckt->CKTrhs + here->B3SOIDDqbfNode) = here->B3SOIDDqbf; + *(ckt->CKTrhs + here->B3SOIDDqjsNode) = here->B3SOIDDqjs; + *(ckt->CKTrhs + here->B3SOIDDqjdNode) = here->B3SOIDDqjd; + + /* clean up last */ + *(ckt->CKTrhs + here->B3SOIDDgmNode) = Gm; + *(ckt->CKTrhs + here->B3SOIDDgmbsNode) = Gmbs; + *(ckt->CKTrhs + here->B3SOIDDgdsNode) = Gds; + *(ckt->CKTrhs + here->B3SOIDDgmeNode) = Gme; + *(ckt->CKTrhs + here->B3SOIDDqdNode) = qdrn; + *(ckt->CKTrhs + here->B3SOIDDcbeNode) = Cbe; + *(ckt->CKTrhs + here->B3SOIDDvbs0teffNode) = Vbs0teff; + *(ckt->CKTrhs + here->B3SOIDDvthNode) = here->B3SOIDDvon; + *(ckt->CKTrhs + here->B3SOIDDvgsteffNode) = Vgsteff; + *(ckt->CKTrhs + here->B3SOIDDxcsatNode) = Xcsat; + *(ckt->CKTrhs + here->B3SOIDDqaccNode) = -Qac0; + *(ckt->CKTrhs + here->B3SOIDDqsub0Node) = Qsub0; + *(ckt->CKTrhs + here->B3SOIDDqsubs1Node) = Qsubs1; + *(ckt->CKTrhs + here->B3SOIDDqsubs2Node) = Qsubs2; + *(ckt->CKTrhs + here->B3SOIDDvdscvNode) = VdsCV; + *(ckt->CKTrhs + here->B3SOIDDvcscvNode) = VcsCV; + *(ckt->CKTrhs + here->B3SOIDDqgNode) = qgate; + *(ckt->CKTrhs + here->B3SOIDDqbNode) = qbody; + *(ckt->CKTrhs + here->B3SOIDDqeNode) = qsub; + *(ckt->CKTrhs + here->B3SOIDDdum1Node) = here->B3SOIDDdum1; + *(ckt->CKTrhs + here->B3SOIDDdum2Node) = here->B3SOIDDdum2; + *(ckt->CKTrhs + here->B3SOIDDdum3Node) = here->B3SOIDDdum3; + *(ckt->CKTrhs + here->B3SOIDDdum4Node) = here->B3SOIDDdum4; + *(ckt->CKTrhs + here->B3SOIDDdum5Node) = here->B3SOIDDdum5; + /* end clean up last */ + } + + + /* + * load y matrix + */ + (*(here->B3SOIDDEgPtr) += gcegb); + (*(here->B3SOIDDEdpPtr) += gcedb); + (*(here->B3SOIDDEspPtr) += gcesb); + (*(here->B3SOIDDGePtr) += gcgeb); + (*(here->B3SOIDDDPePtr) += Gme + gddpe + gcdeb); + (*(here->B3SOIDDSPePtr) += gsspe - Gme + gcseb); + + Gmin = ckt->CKTgmin * 1e-6; + (*(here->B3SOIDDEbPtr) -= gcegb + gcedb + gcesb + gceeb); + (*(here->B3SOIDDGbPtr) -= gcggb + gcgdb + gcgsb + gcgeb); + (*(here->B3SOIDDDPbPtr) -= (-gddpb - Gmbs + gcdgb + gcddb + gcdeb + gcdsb)); + (*(here->B3SOIDDSPbPtr) -= (-gsspb + Gmbs + gcsgb + gcsdb + gcseb + gcssb)); + (*(here->B3SOIDDBePtr) += gbbe + gcbeb); + (*(here->B3SOIDDBgPtr) += gcbgb + gbbg); + (*(here->B3SOIDDBdpPtr) += gcbdb + gbbdp ); + (*(here->B3SOIDDBspPtr) += gcbsb + gbbsp - Gmin); + (*(here->B3SOIDDBbPtr) += gbbb - gcbgb - gcbdb - gcbsb - gcbeb + Gmin) ; + + (*(here->B3SOIDDEePtr) += gceeb); + + (*(here->B3SOIDDGgPtr) += gcggb + ckt->CKTgmin); + (*(here->B3SOIDDGdpPtr) += gcgdb - ckt->CKTgmin); + (*(here->B3SOIDDGspPtr) += gcgsb ); + + (*(here->B3SOIDDDPgPtr) += (Gm + gcdgb) + gddpg - ckt->CKTgmin); + (*(here->B3SOIDDDPdpPtr) += (here->B3SOIDDdrainConductance + + here->B3SOIDDgds + gddpdp + + RevSum + gcddb) + ckt->CKTgmin); + (*(here->B3SOIDDDPspPtr) -= (-gddpsp + here->B3SOIDDgds + FwdSum - gcdsb)); + + (*(here->B3SOIDDDPdPtr) -= here->B3SOIDDdrainConductance); + + (*(here->B3SOIDDSPgPtr) += gcsgb - Gm + gsspg ); + (*(here->B3SOIDDSPdpPtr) -= (here->B3SOIDDgds - gsspdp + RevSum - gcsdb)); + (*(here->B3SOIDDSPspPtr) += (here->B3SOIDDsourceConductance + + here->B3SOIDDgds + gsspsp + + FwdSum + gcssb)); + (*(here->B3SOIDDSPsPtr) -= here->B3SOIDDsourceConductance); + + + (*(here->B3SOIDDDdPtr) += here->B3SOIDDdrainConductance); + (*(here->B3SOIDDDdpPtr) -= here->B3SOIDDdrainConductance); + + + (*(here->B3SOIDDSsPtr) += here->B3SOIDDsourceConductance); + (*(here->B3SOIDDSspPtr) -= here->B3SOIDDsourceConductance); + + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDBpPtr) -= gppp); + (*(here->B3SOIDDPbPtr) += gppb); + (*(here->B3SOIDDPpPtr) += gppp); + (*(here->B3SOIDDPgPtr) += gppg); + (*(here->B3SOIDDPdpPtr) += gppdp); + (*(here->B3SOIDDPspPtr) += gppsp); + (*(here->B3SOIDDPePtr) += gppe); + } + + if (selfheat) + { + (*(here->B3SOIDDDPtempPtr) += GmT + gddpT + gcdT); + (*(here->B3SOIDDSPtempPtr) += -GmT + gsspT + gcsT); + (*(here->B3SOIDDBtempPtr) += gbbT + gcbT); + (*(here->B3SOIDDEtempPtr) += gceT); + (*(here->B3SOIDDGtempPtr) += gcgT); + if (here->B3SOIDDbodyMod == 1) { + (*(here->B3SOIDDPtempPtr) += gppT); + } + (*(here->B3SOIDDTemptempPtr) += gTtt + 1/pParam->B3SOIDDrth + gcTt); + (*(here->B3SOIDDTempgPtr) += gTtg); + (*(here->B3SOIDDTempbPtr) += gTtb); + (*(here->B3SOIDDTempePtr) += gTte); + (*(here->B3SOIDDTempdpPtr) += gTtdp); + (*(here->B3SOIDDTempspPtr) += gTtsp); + } + + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + *(here->B3SOIDDVbsPtr) += 1; + *(here->B3SOIDDIdsPtr) += 1; + *(here->B3SOIDDIcPtr) += 1; + *(here->B3SOIDDIbsPtr) += 1; + *(here->B3SOIDDIbdPtr) += 1; + *(here->B3SOIDDIiiPtr) += 1; + *(here->B3SOIDDIgidlPtr) += 1; + *(here->B3SOIDDItunPtr) += 1; + *(here->B3SOIDDIbpPtr) += 1; + *(here->B3SOIDDAbeffPtr) += 1; + *(here->B3SOIDDVbs0effPtr) += 1; + *(here->B3SOIDDVbseffPtr) += 1; + *(here->B3SOIDDXcPtr) += 1; + *(here->B3SOIDDCbgPtr) += 1; + *(here->B3SOIDDCbbPtr) += 1; + *(here->B3SOIDDCbdPtr) += 1; + *(here->B3SOIDDqbPtr) += 1; + *(here->B3SOIDDQbfPtr) += 1; + *(here->B3SOIDDQjsPtr) += 1; + *(here->B3SOIDDQjdPtr) += 1; + + /* clean up last */ + *(here->B3SOIDDGmPtr) += 1; + *(here->B3SOIDDGmbsPtr) += 1; + *(here->B3SOIDDGdsPtr) += 1; + *(here->B3SOIDDGmePtr) += 1; + *(here->B3SOIDDVbs0teffPtr) += 1; + *(here->B3SOIDDVgsteffPtr) += 1; + *(here->B3SOIDDCbePtr) += 1; + *(here->B3SOIDDVthPtr) += 1; + *(here->B3SOIDDXcsatPtr) += 1; + *(here->B3SOIDDVdscvPtr) += 1; + *(here->B3SOIDDVcscvPtr) += 1; + *(here->B3SOIDDQaccPtr) += 1; + *(here->B3SOIDDQsub0Ptr) += 1; + *(here->B3SOIDDQsubs1Ptr) += 1; + *(here->B3SOIDDQsubs2Ptr) += 1; + *(here->B3SOIDDqgPtr) += 1; + *(here->B3SOIDDqdPtr) += 1; + *(here->B3SOIDDqePtr) += 1; + *(here->B3SOIDDDum1Ptr) += 1; + *(here->B3SOIDDDum2Ptr) += 1; + *(here->B3SOIDDDum3Ptr) += 1; + *(here->B3SOIDDDum4Ptr) += 1; + *(here->B3SOIDDDum5Ptr) += 1; + /* end clean up last */ + } + + line1000: ; + +/* Here NaN will be detected in any conductance or equivalent current. Note + that nandetect is initialized within the "if" statements */ + + if (nandetect = isnan (*(here->B3SOIDDGbPtr))) + { strcpy (nanmessage, "GbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEbPtr))) + { strcpy (nanmessage, "EbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPbPtr))) + { strcpy (nanmessage, "DPbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPbPtr))) + { strcpy (nanmessage, "SPbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBbPtr))) + { strcpy (nanmessage, "BbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBgPtr))) + { strcpy (nanmessage, "BgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBePtr))) + { strcpy (nanmessage, "BePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBdpPtr))) + { strcpy (nanmessage, "BdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBspPtr))) + { strcpy (nanmessage, "BspPtr"); } + + if (nandetect = isnan (*(here->B3SOIDDGgPtr))) + { strcpy (nanmessage, "GgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGdpPtr))) + { strcpy (nanmessage, "GdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGspPtr))) + { strcpy (nanmessage, "GspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPgPtr))) + { strcpy (nanmessage, "DPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPdpPtr))) + { strcpy (nanmessage, "DPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPspPtr))) + { strcpy (nanmessage, "DPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPgPtr))) + { strcpy (nanmessage, "SPgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPdpPtr))) + { strcpy (nanmessage, "SPdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPspPtr))) + { strcpy (nanmessage, "SPspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEePtr))) + { strcpy (nanmessage, "EePtr"); } + + /* At this point, nandetect = 0 if none of the + conductances checked so far are NaN */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIDDEgPtr))) + { strcpy (nanmessage, "EgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEdpPtr))) + { strcpy (nanmessage, "EdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEspPtr))) + { strcpy (nanmessage, "EspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGePtr))) + { strcpy (nanmessage, "GePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPePtr))) + { strcpy (nanmessage, "DPePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPePtr))) + { strcpy (nanmessage, "SPePtr"); } } + + /* Now check if self-heating caused NaN if nothing else + has so far (check tempnode current also) */ + + if (selfheat && nandetect == 0) + { + if (nandetect = isnan (*(here->B3SOIDDTemptempPtr))) + { strcpy (nanmessage, "TemptempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempgPtr))) + { strcpy (nanmessage, "TempgPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempbPtr))) + { strcpy (nanmessage, "TempbPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempePtr))) + { strcpy (nanmessage, "TempePtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempdpPtr))) + { strcpy (nanmessage, "TempdpPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDTempspPtr))) + { strcpy (nanmessage, "TempspPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDGtempPtr))) + { strcpy (nanmessage, "GtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDDPtempPtr))) + { strcpy (nanmessage, "DPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDSPtempPtr))) + { strcpy (nanmessage, "SPtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDEtempPtr))) + { strcpy (nanmessage, "EtempPtr"); } + else if (nandetect = isnan (*(here->B3SOIDDBtempPtr))) + { strcpy (nanmessage, "BtempPtr"); } + else if (nandetect = isnan (*(ckt->CKTrhs + here->B3SOIDDtempNode))) + { strcpy (nanmessage, "tempNode"); } + } + + /* Lastly, check all equivalent currents (tempnode is + checked above */ + + if (nandetect == 0) + { + if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDgNode))) + { strcpy (nanmessage, "gNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDbNode))) + { strcpy (nanmessage, "bNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDdNodePrime))) + { strcpy (nanmessage, "dpNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDsNodePrime))) + { strcpy (nanmessage, "spNode"); } + else if (nandetect = isnan (*(ckt->CKTrhs + + here->B3SOIDDeNode))) + { strcpy (nanmessage, "eNode"); } + } + + /* Now print error message if NaN detected. Note that + error will only be printed once (the first time it is + encountered) each time SPICE is run since nanfound is + static variable */ + + if (nanfound == 0 && nandetect) + { + fprintf(stderr, "Alberto says: YOU TURKEY! %s is NaN for instance %s at time %g!\n", nanmessage, here->B3SOIDDname, ckt->CKTtime); + nanfound = nandetect; + fprintf(stderr, " The program exit!\n"); + exit(-1); + } + + if (here->B3SOIDDdebugMod > 2) + { + fprintf(fpdebug, "Ids = %.4e, Ic = %.4e, cqdrn = %.4e, gmin=%.3e\n", + Ids, Ic, cqdrn, ckt->CKTgmin); + fprintf(fpdebug, "Iii = %.4e, Idgidl = %.4e, Ibs = %.14e\n", + Iii, Idgidl, Ibs); + fprintf(fpdebug, "Ibd = %.4e, Ibp = %.4e\n", Ibd, Ibp); + fprintf(fpdebug, "qbody = %.5e, qbf = %.5e, qbe = %.5e\n", + qbody, Qbf, -(Qe1+Qe2)); + fprintf(fpdebug, "qbs = %.5e, qbd = %.5e\n", qjs, qjd); + fprintf(fpdebug, "qdrn = %.5e, qinv = %.5e\n", qdrn, qinv); + + + + +/* I am trying to debug the convergence problems here by printing out + the entire Jacobian and equivalent current matrix */ + + + if (here->B3SOIDDdebugMod > 4) { + fprintf(fpdebug, "Ibtot = %.6e;\t Cbtot = %.6e;\n", Ibs+Ibp+Ibd-Iii-Idgidl-Isgidl, cqbody); + fprintf(fpdebug, "ceqg = %.6e;\t ceqb = %.6e;\t ceqdp = %.6e;\t ceqsp = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIDDgNode), + *(ckt->CKTrhs + here->B3SOIDDbNode), + *(ckt->CKTrhs + here->B3SOIDDdNodePrime), + *(ckt->CKTrhs + here->B3SOIDDsNodePrime)); + fprintf(fpdebug, "ceqe = %.6e;\t ceqp = %.6e;\t ceqth = %.6e;\n", + *(ckt->CKTrhs + here->B3SOIDDeNode), + *(ckt->CKTrhs + here->B3SOIDDpNode), + *(ckt->CKTrhs + here->B3SOIDDtempNode)); + + fprintf(fpdebug, "Eg = %.5e;\t Edp = %.5e;\t Esp = %.5e;\t Eb = %.5e;\n", + *(here->B3SOIDDEgPtr), *(here->B3SOIDDEdpPtr), *(here->B3SOIDDEspPtr), + *(here->B3SOIDDEbPtr)); + fprintf(fpdebug, "Ee = %.5e;\t Gg = %.5e;\t Gdp = %.5e;\t Gsp = %.5e;\n", + *(here->B3SOIDDEePtr), + *(here->B3SOIDDGgPtr), + *(here->B3SOIDDGdpPtr), + *(here->B3SOIDDGspPtr)); + fprintf(fpdebug, "Gb = %.5e;\t Ge = %.5e;\t DPg = %.5e;\t DPdp = %.5e;\n", + *(here->B3SOIDDGbPtr), + *(here->B3SOIDDGePtr), + *(here->B3SOIDDDPgPtr), + *(here->B3SOIDDDPdpPtr)); + fprintf(fpdebug, "DPsp = %.5e;\t DPb = %.5e;\t DPe = %.5e;\t\n", + *(here->B3SOIDDDPspPtr), + *(here->B3SOIDDDPbPtr), + *(here->B3SOIDDDPePtr)); + fprintf(fpdebug, "DPd = %.5e;\t SPg = %.5e;\t SPdp = %.5e;\t SPsp = %.5e;\n", + *(here->B3SOIDDDPdPtr), + *(here->B3SOIDDSPgPtr), + *(here->B3SOIDDSPdpPtr), + *(here->B3SOIDDSPspPtr)); + fprintf(fpdebug, "SPb = %.5e;\t SPe = %.5e;\t SPs = %.5e;\n", + *(here->B3SOIDDSPbPtr), + *(here->B3SOIDDSPePtr), + *(here->B3SOIDDSPsPtr)); + fprintf(fpdebug, "Dd = %.5e;\t Ddp = %.5e;\t Ss = %.5e;\t Ssp = %.5e;\n", + *(here->B3SOIDDDdPtr), + *(here->B3SOIDDDdpPtr), + *(here->B3SOIDDSsPtr), + *(here->B3SOIDDSspPtr)); + fprintf(fpdebug, "Bg = %.5e;\t Bdp = %.5e;\t Bsp = %.5e;\t Bb = %.5e;\n", + *(here->B3SOIDDBgPtr), + *(here->B3SOIDDBdpPtr), + *(here->B3SOIDDBspPtr), + *(here->B3SOIDDBbPtr)); + fprintf(fpdebug, "Be = %.5e;\t Btot = %.5e;\t DPtot = %.5e;\n", + *(here->B3SOIDDBePtr), + *(here->B3SOIDDBgPtr) + *(here->B3SOIDDBdpPtr) + + *(here->B3SOIDDBspPtr) + *(here->B3SOIDDBbPtr) + + *(here->B3SOIDDBePtr), + *(here->B3SOIDDDPePtr) + + *(here->B3SOIDDDPgPtr) + *(here->B3SOIDDDPdpPtr) + + *(here->B3SOIDDDPspPtr) + *(here->B3SOIDDDPbPtr)); + if (selfheat) { + fprintf (fpdebug, "DPtemp = %.5e;\t SPtemp = %.5e;\t Btemp = %.5e;\n", + *(here->B3SOIDDDPtempPtr), *(here->B3SOIDDSPtempPtr), + *(here->B3SOIDDBtempPtr)); + fprintf (fpdebug, "Gtemp = %.5e;\t Etemp = %.5e;\n", + *(here->B3SOIDDGtempPtr), *(here->B3SOIDDEtempPtr)); + fprintf (fpdebug, "Tempg = %.5e;\t Tempdp = %.5e;\t Tempsp = %.5e;\t Tempb = %.5e;\n", + *(here->B3SOIDDTempgPtr), *(here->B3SOIDDTempdpPtr), + *(here->B3SOIDDTempspPtr), *(here->B3SOIDDTempbPtr)); + fprintf (fpdebug, "Tempe = %.5e;\t TempT = %.5e;\t Temptot = %.5e;\n", + *(here->B3SOIDDTempePtr), *(here->B3SOIDDTemptempPtr), + *(here->B3SOIDDTempgPtr) + *(here->B3SOIDDTempdpPtr) + + *(here->B3SOIDDTempspPtr)+ *(here->B3SOIDDTempbPtr) + + *(here->B3SOIDDTempePtr)); + } + + if (here->B3SOIDDbodyMod == 1) + { + fprintf(fpdebug, "ceqbodcon=%.5e;\t", ceqbodcon); + fprintf(fpdebug, "Bp = %.5e;\t Pb = %.5e;\t Pp = %.5e;\n", -gppp, gppb, gppp); + fprintf(fpdebug, "Pg=%.5e;\t Pdp=%.5e;\t Psp=%.5e;\t Pe=%.5e;\n", + gppg, gppdp, gppsp, gppe); + } +} + + if (here->B3SOIDDdebugMod > 3) + { + fprintf(fpdebug, "Vth = %.4f, Vbs0eff = %.8f, Vdsat = %.4f\n", + Vth, Vbs0eff, Vdsat); + fprintf(fpdebug, "ueff = %g, Vgsteff = %.4f, Vdseff = %.4f\n", + ueff, Vgsteff, Vdseff); + fprintf(fpdebug, "Vthfd = %.4f, Vbs0mos = %.4f, Vbs0 = %.4f\n", + Vthfd, Vbs0mos, Vbs0); + fprintf(fpdebug, "Vbs0t = %.4f, Vbsdio = %.8f\n", + Vbs0t, Vbsdio); + } + + fclose(fpdebug); + } + + here->B3SOIDDiterations++; /* increment the iteration counter */ + + } /* End of Mosfet Instance */ +} /* End of Model Instance */ + + +return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c new file mode 100644 index 000000000..840895396 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmask.c @@ -0,0 +1,1207 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Wei Jin 99/9/27 +File: b3soiddmask.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDmAsk(ckt,inst,which,value) +CKTcircuit *ckt; +GENmodel *inst; +int which; +IFvalue *value; +{ + B3SOIDDmodel *model = (B3SOIDDmodel *)inst; + switch(which) + { case B3SOIDD_MOD_MOBMOD: + value->iValue = model->B3SOIDDmobMod; + return(OK); + case B3SOIDD_MOD_PARAMCHK: + value->iValue = model->B3SOIDDparamChk; + return(OK); + case B3SOIDD_MOD_BINUNIT: + value->iValue = model->B3SOIDDbinUnit; + return(OK); + case B3SOIDD_MOD_CAPMOD: + value->iValue = model->B3SOIDDcapMod; + return(OK); + case B3SOIDD_MOD_SHMOD: + value->iValue = model->B3SOIDDshMod; + return(OK); + case B3SOIDD_MOD_NOIMOD: + value->iValue = model->B3SOIDDnoiMod; + return(OK); + case B3SOIDD_MOD_VERSION : + value->rValue = model->B3SOIDDversion; + return(OK); + case B3SOIDD_MOD_TOX : + value->rValue = model->B3SOIDDtox; + return(OK); + case B3SOIDD_MOD_CDSC : + value->rValue = model->B3SOIDDcdsc; + return(OK); + case B3SOIDD_MOD_CDSCB : + value->rValue = model->B3SOIDDcdscb; + return(OK); + + case B3SOIDD_MOD_CDSCD : + value->rValue = model->B3SOIDDcdscd; + return(OK); + + case B3SOIDD_MOD_CIT : + value->rValue = model->B3SOIDDcit; + return(OK); + case B3SOIDD_MOD_NFACTOR : + value->rValue = model->B3SOIDDnfactor; + return(OK); + case B3SOIDD_MOD_VSAT: + value->rValue = model->B3SOIDDvsat; + return(OK); + case B3SOIDD_MOD_AT: + value->rValue = model->B3SOIDDat; + return(OK); + case B3SOIDD_MOD_A0: + value->rValue = model->B3SOIDDa0; + return(OK); + + case B3SOIDD_MOD_AGS: + value->rValue = model->B3SOIDDags; + return(OK); + + case B3SOIDD_MOD_A1: + value->rValue = model->B3SOIDDa1; + return(OK); + case B3SOIDD_MOD_A2: + value->rValue = model->B3SOIDDa2; + return(OK); + case B3SOIDD_MOD_KETA: + value->rValue = model->B3SOIDDketa; + return(OK); + case B3SOIDD_MOD_NSUB: + value->rValue = model->B3SOIDDnsub; + return(OK); + case B3SOIDD_MOD_NPEAK: + value->rValue = model->B3SOIDDnpeak; + return(OK); + case B3SOIDD_MOD_NGATE: + value->rValue = model->B3SOIDDngate; + return(OK); + case B3SOIDD_MOD_GAMMA1: + value->rValue = model->B3SOIDDgamma1; + return(OK); + case B3SOIDD_MOD_GAMMA2: + value->rValue = model->B3SOIDDgamma2; + return(OK); + case B3SOIDD_MOD_VBX: + value->rValue = model->B3SOIDDvbx; + return(OK); + case B3SOIDD_MOD_VBM: + value->rValue = model->B3SOIDDvbm; + return(OK); + case B3SOIDD_MOD_XT: + value->rValue = model->B3SOIDDxt; + return(OK); + case B3SOIDD_MOD_K1: + value->rValue = model->B3SOIDDk1; + return(OK); + case B3SOIDD_MOD_KT1: + value->rValue = model->B3SOIDDkt1; + return(OK); + case B3SOIDD_MOD_KT1L: + value->rValue = model->B3SOIDDkt1l; + return(OK); + case B3SOIDD_MOD_KT2 : + value->rValue = model->B3SOIDDkt2; + return(OK); + case B3SOIDD_MOD_K2 : + value->rValue = model->B3SOIDDk2; + return(OK); + case B3SOIDD_MOD_K3: + value->rValue = model->B3SOIDDk3; + return(OK); + case B3SOIDD_MOD_K3B: + value->rValue = model->B3SOIDDk3b; + return(OK); + case B3SOIDD_MOD_W0: + value->rValue = model->B3SOIDDw0; + return(OK); + case B3SOIDD_MOD_NLX: + value->rValue = model->B3SOIDDnlx; + return(OK); + case B3SOIDD_MOD_DVT0 : + value->rValue = model->B3SOIDDdvt0; + return(OK); + case B3SOIDD_MOD_DVT1 : + value->rValue = model->B3SOIDDdvt1; + return(OK); + case B3SOIDD_MOD_DVT2 : + value->rValue = model->B3SOIDDdvt2; + return(OK); + case B3SOIDD_MOD_DVT0W : + value->rValue = model->B3SOIDDdvt0w; + return(OK); + case B3SOIDD_MOD_DVT1W : + value->rValue = model->B3SOIDDdvt1w; + return(OK); + case B3SOIDD_MOD_DVT2W : + value->rValue = model->B3SOIDDdvt2w; + return(OK); + case B3SOIDD_MOD_DROUT : + value->rValue = model->B3SOIDDdrout; + return(OK); + case B3SOIDD_MOD_DSUB : + value->rValue = model->B3SOIDDdsub; + return(OK); + case B3SOIDD_MOD_VTH0: + value->rValue = model->B3SOIDDvth0; + return(OK); + case B3SOIDD_MOD_UA: + value->rValue = model->B3SOIDDua; + return(OK); + case B3SOIDD_MOD_UA1: + value->rValue = model->B3SOIDDua1; + return(OK); + case B3SOIDD_MOD_UB: + value->rValue = model->B3SOIDDub; + return(OK); + case B3SOIDD_MOD_UB1: + value->rValue = model->B3SOIDDub1; + return(OK); + case B3SOIDD_MOD_UC: + value->rValue = model->B3SOIDDuc; + return(OK); + case B3SOIDD_MOD_UC1: + value->rValue = model->B3SOIDDuc1; + return(OK); + case B3SOIDD_MOD_U0: + value->rValue = model->B3SOIDDu0; + return(OK); + case B3SOIDD_MOD_UTE: + value->rValue = model->B3SOIDDute; + return(OK); + case B3SOIDD_MOD_VOFF: + value->rValue = model->B3SOIDDvoff; + return(OK); + case B3SOIDD_MOD_DELTA: + value->rValue = model->B3SOIDDdelta; + return(OK); + case B3SOIDD_MOD_RDSW: + value->rValue = model->B3SOIDDrdsw; + return(OK); + case B3SOIDD_MOD_PRWG: + value->rValue = model->B3SOIDDprwg; + return(OK); + case B3SOIDD_MOD_PRWB: + value->rValue = model->B3SOIDDprwb; + return(OK); + case B3SOIDD_MOD_PRT: + value->rValue = model->B3SOIDDprt; + return(OK); + case B3SOIDD_MOD_ETA0: + value->rValue = model->B3SOIDDeta0; + return(OK); + case B3SOIDD_MOD_ETAB: + value->rValue = model->B3SOIDDetab; + return(OK); + case B3SOIDD_MOD_PCLM: + value->rValue = model->B3SOIDDpclm; + return(OK); + case B3SOIDD_MOD_PDIBL1: + value->rValue = model->B3SOIDDpdibl1; + return(OK); + case B3SOIDD_MOD_PDIBL2: + value->rValue = model->B3SOIDDpdibl2; + return(OK); + case B3SOIDD_MOD_PDIBLB: + value->rValue = model->B3SOIDDpdiblb; + return(OK); + case B3SOIDD_MOD_PVAG: + value->rValue = model->B3SOIDDpvag; + return(OK); + case B3SOIDD_MOD_WR: + value->rValue = model->B3SOIDDwr; + return(OK); + case B3SOIDD_MOD_DWG: + value->rValue = model->B3SOIDDdwg; + return(OK); + case B3SOIDD_MOD_DWB: + value->rValue = model->B3SOIDDdwb; + return(OK); + case B3SOIDD_MOD_B0: + value->rValue = model->B3SOIDDb0; + return(OK); + case B3SOIDD_MOD_B1: + value->rValue = model->B3SOIDDb1; + return(OK); + case B3SOIDD_MOD_ALPHA0: + value->rValue = model->B3SOIDDalpha0; + return(OK); + case B3SOIDD_MOD_ALPHA1: + value->rValue = model->B3SOIDDalpha1; + return(OK); + case B3SOIDD_MOD_BETA0: + value->rValue = model->B3SOIDDbeta0; + return(OK); + + case B3SOIDD_MOD_CGSL: + value->rValue = model->B3SOIDDcgsl; + return(OK); + case B3SOIDD_MOD_CGDL: + value->rValue = model->B3SOIDDcgdl; + return(OK); + case B3SOIDD_MOD_CKAPPA: + value->rValue = model->B3SOIDDckappa; + return(OK); + case B3SOIDD_MOD_CF: + value->rValue = model->B3SOIDDcf; + return(OK); + case B3SOIDD_MOD_CLC: + value->rValue = model->B3SOIDDclc; + return(OK); + case B3SOIDD_MOD_CLE: + value->rValue = model->B3SOIDDcle; + return(OK); + case B3SOIDD_MOD_DWC: + value->rValue = model->B3SOIDDdwc; + return(OK); + case B3SOIDD_MOD_DLC: + value->rValue = model->B3SOIDDdlc; + return(OK); + + case B3SOIDD_MOD_TBOX: + value->rValue = model->B3SOIDDtbox; + return(OK); + case B3SOIDD_MOD_TSI: + value->rValue = model->B3SOIDDtsi; + return(OK); + case B3SOIDD_MOD_KB1: + value->rValue = model->B3SOIDDkb1; + return(OK); + case B3SOIDD_MOD_KB3: + value->rValue = model->B3SOIDDkb3; + return(OK); + case B3SOIDD_MOD_DVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_DVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_DELP: + value->rValue = model->B3SOIDDdelp; + return(OK); + case B3SOIDD_MOD_VBSA: + value->rValue = model->B3SOIDDvbsa; + return(OK); + case B3SOIDD_MOD_RBODY: + value->rValue = model->B3SOIDDrbody; + return(OK); + case B3SOIDD_MOD_RBSH: + value->rValue = model->B3SOIDDrbsh; + return(OK); + case B3SOIDD_MOD_ADICE0: + value->rValue = model->B3SOIDDadice0; + return(OK); + case B3SOIDD_MOD_ABP: + value->rValue = model->B3SOIDDabp; + return(OK); + case B3SOIDD_MOD_MXC: + value->rValue = model->B3SOIDDmxc; + return(OK); + case B3SOIDD_MOD_RTH0: + value->rValue = model->B3SOIDDrth0; + return(OK); + case B3SOIDD_MOD_CTH0: + value->rValue = model->B3SOIDDcth0; + return(OK); + case B3SOIDD_MOD_AII: + value->rValue = model->B3SOIDDaii; + return(OK); + case B3SOIDD_MOD_BII: + value->rValue = model->B3SOIDDbii; + return(OK); + case B3SOIDD_MOD_CII: + value->rValue = model->B3SOIDDcii; + return(OK); + case B3SOIDD_MOD_DII: + value->rValue = model->B3SOIDDdii; + return(OK); + case B3SOIDD_MOD_NDIODE: + value->rValue = model->B3SOIDDndiode; + return(OK); + case B3SOIDD_MOD_NTUN: + value->rValue = model->B3SOIDDntun; + return(OK); + case B3SOIDD_MOD_ISBJT: + value->rValue = model->B3SOIDDisbjt; + return(OK); + case B3SOIDD_MOD_ISDIF: + value->rValue = model->B3SOIDDisdif; + return(OK); + case B3SOIDD_MOD_ISREC: + value->rValue = model->B3SOIDDisrec; + return(OK); + case B3SOIDD_MOD_ISTUN: + value->rValue = model->B3SOIDDistun; + return(OK); + case B3SOIDD_MOD_XBJT: + value->rValue = model->B3SOIDDxbjt; + return(OK); + case B3SOIDD_MOD_XREC: + value->rValue = model->B3SOIDDxrec; + return(OK); + case B3SOIDD_MOD_XTUN: + value->rValue = model->B3SOIDDxtun; + return(OK); + case B3SOIDD_MOD_EDL: + value->rValue = model->B3SOIDDedl; + return(OK); + case B3SOIDD_MOD_KBJT1: + value->rValue = model->B3SOIDDkbjt1; + return(OK); + case B3SOIDD_MOD_TT: + value->rValue = model->B3SOIDDtt; + return(OK); + case B3SOIDD_MOD_VSDTH: + value->rValue = model->B3SOIDDvsdth; + return(OK); + case B3SOIDD_MOD_VSDFB: + value->rValue = model->B3SOIDDvsdfb; + return(OK); + case B3SOIDD_MOD_CSDMIN: + value->rValue = model->B3SOIDDcsdmin; + return(OK); + case B3SOIDD_MOD_ASD: + value->rValue = model->B3SOIDDasd; + return(OK); + + case B3SOIDD_MOD_TNOM : + value->rValue = model->B3SOIDDtnom; + return(OK); + case B3SOIDD_MOD_CGSO: + value->rValue = model->B3SOIDDcgso; + return(OK); + case B3SOIDD_MOD_CGDO: + value->rValue = model->B3SOIDDcgdo; + return(OK); + case B3SOIDD_MOD_CGEO: + value->rValue = model->B3SOIDDcgeo; + return(OK); + case B3SOIDD_MOD_XPART: + value->rValue = model->B3SOIDDxpart; + return(OK); + case B3SOIDD_MOD_RSH: + value->rValue = model->B3SOIDDsheetResistance; + return(OK); + case B3SOIDD_MOD_PBSWG: + value->rValue = model->B3SOIDDGatesidewallJctPotential; + return(OK); + case B3SOIDD_MOD_MJSWG: + value->rValue = model->B3SOIDDbodyJctGateSideGradingCoeff; + return(OK); + case B3SOIDD_MOD_CJSWG: + value->rValue = model->B3SOIDDunitLengthGateSidewallJctCap; + return(OK); + case B3SOIDD_MOD_CSDESW: + value->rValue = model->B3SOIDDcsdesw; + return(OK); + case B3SOIDD_MOD_LINT: + value->rValue = model->B3SOIDDLint; + return(OK); + case B3SOIDD_MOD_LL: + value->rValue = model->B3SOIDDLl; + return(OK); + case B3SOIDD_MOD_LLN: + value->rValue = model->B3SOIDDLln; + return(OK); + case B3SOIDD_MOD_LW: + value->rValue = model->B3SOIDDLw; + return(OK); + case B3SOIDD_MOD_LWN: + value->rValue = model->B3SOIDDLwn; + return(OK); + case B3SOIDD_MOD_LWL: + value->rValue = model->B3SOIDDLwl; + return(OK); + case B3SOIDD_MOD_WINT: + value->rValue = model->B3SOIDDWint; + return(OK); + case B3SOIDD_MOD_WL: + value->rValue = model->B3SOIDDWl; + return(OK); + case B3SOIDD_MOD_WLN: + value->rValue = model->B3SOIDDWln; + return(OK); + case B3SOIDD_MOD_WW: + value->rValue = model->B3SOIDDWw; + return(OK); + case B3SOIDD_MOD_WWN: + value->rValue = model->B3SOIDDWwn; + return(OK); + case B3SOIDD_MOD_WWL: + value->rValue = model->B3SOIDDWwl; + return(OK); + case B3SOIDD_MOD_NOIA: + value->rValue = model->B3SOIDDoxideTrapDensityA; + return(OK); + case B3SOIDD_MOD_NOIB: + value->rValue = model->B3SOIDDoxideTrapDensityB; + return(OK); + case B3SOIDD_MOD_NOIC: + value->rValue = model->B3SOIDDoxideTrapDensityC; + return(OK); + case B3SOIDD_MOD_NOIF: + value->rValue = model->B3SOIDDnoif; + return(OK); + case B3SOIDD_MOD_EM: + value->rValue = model->B3SOIDDem; + return(OK); + case B3SOIDD_MOD_EF: + value->rValue = model->B3SOIDDef; + return(OK); + case B3SOIDD_MOD_AF: + value->rValue = model->B3SOIDDaf; + return(OK); + case B3SOIDD_MOD_KF: + value->rValue = model->B3SOIDDkf; + return(OK); + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIDD_MOD_LNPEAK: + value->rValue = model->B3SOIDDlnpeak; + return(OK); + case B3SOIDD_MOD_LNSUB: + value->rValue = model->B3SOIDDlnsub; + return(OK); + case B3SOIDD_MOD_LNGATE: + value->rValue = model->B3SOIDDlngate; + return(OK); + case B3SOIDD_MOD_LVTH0: + value->rValue = model->B3SOIDDlvth0; + return(OK); + case B3SOIDD_MOD_LK1: + value->rValue = model->B3SOIDDlk1; + return(OK); + case B3SOIDD_MOD_LK2: + value->rValue = model->B3SOIDDlk2; + return(OK); + case B3SOIDD_MOD_LK3: + value->rValue = model->B3SOIDDlk3; + return(OK); + case B3SOIDD_MOD_LK3B: + value->rValue = model->B3SOIDDlk3b; + return(OK); + case B3SOIDD_MOD_LVBSA: + value->rValue = model->B3SOIDDlvbsa; + return(OK); + case B3SOIDD_MOD_LDELP: + value->rValue = model->B3SOIDDldelp; + return(OK); + case B3SOIDD_MOD_LKB1: + value->rValue = model->B3SOIDDlkb1; + return(OK); + case B3SOIDD_MOD_LKB3: + value->rValue = model->B3SOIDDlkb3; + return(OK); + case B3SOIDD_MOD_LDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_LDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_LW0: + value->rValue = model->B3SOIDDlw0; + return(OK); + case B3SOIDD_MOD_LNLX: + value->rValue = model->B3SOIDDlnlx; + return(OK); + case B3SOIDD_MOD_LDVT0 : + value->rValue = model->B3SOIDDldvt0; + return(OK); + case B3SOIDD_MOD_LDVT1 : + value->rValue = model->B3SOIDDldvt1; + return(OK); + case B3SOIDD_MOD_LDVT2 : + value->rValue = model->B3SOIDDldvt2; + return(OK); + case B3SOIDD_MOD_LDVT0W : + value->rValue = model->B3SOIDDldvt0w; + return(OK); + case B3SOIDD_MOD_LDVT1W : + value->rValue = model->B3SOIDDldvt1w; + return(OK); + case B3SOIDD_MOD_LDVT2W : + value->rValue = model->B3SOIDDldvt2w; + return(OK); + case B3SOIDD_MOD_LU0: + value->rValue = model->B3SOIDDlu0; + return(OK); + case B3SOIDD_MOD_LUA: + value->rValue = model->B3SOIDDlua; + return(OK); + case B3SOIDD_MOD_LUB: + value->rValue = model->B3SOIDDlub; + return(OK); + case B3SOIDD_MOD_LUC: + value->rValue = model->B3SOIDDluc; + return(OK); + case B3SOIDD_MOD_LVSAT: + value->rValue = model->B3SOIDDlvsat; + return(OK); + case B3SOIDD_MOD_LA0: + value->rValue = model->B3SOIDDla0; + return(OK); + case B3SOIDD_MOD_LAGS: + value->rValue = model->B3SOIDDlags; + return(OK); + case B3SOIDD_MOD_LB0: + value->rValue = model->B3SOIDDlb0; + return(OK); + case B3SOIDD_MOD_LB1: + value->rValue = model->B3SOIDDlb1; + return(OK); + case B3SOIDD_MOD_LKETA: + value->rValue = model->B3SOIDDlketa; + return(OK); + case B3SOIDD_MOD_LABP: + value->rValue = model->B3SOIDDlabp; + return(OK); + case B3SOIDD_MOD_LMXC: + value->rValue = model->B3SOIDDlmxc; + return(OK); + case B3SOIDD_MOD_LADICE0: + value->rValue = model->B3SOIDDladice0; + return(OK); + case B3SOIDD_MOD_LA1: + value->rValue = model->B3SOIDDla1; + return(OK); + case B3SOIDD_MOD_LA2: + value->rValue = model->B3SOIDDla2; + return(OK); + case B3SOIDD_MOD_LRDSW: + value->rValue = model->B3SOIDDlrdsw; + return(OK); + case B3SOIDD_MOD_LPRWB: + value->rValue = model->B3SOIDDlprwb; + return(OK); + case B3SOIDD_MOD_LPRWG: + value->rValue = model->B3SOIDDlprwg; + return(OK); + case B3SOIDD_MOD_LWR: + value->rValue = model->B3SOIDDlwr; + return(OK); + case B3SOIDD_MOD_LNFACTOR : + value->rValue = model->B3SOIDDlnfactor; + return(OK); + case B3SOIDD_MOD_LDWG: + value->rValue = model->B3SOIDDldwg; + return(OK); + case B3SOIDD_MOD_LDWB: + value->rValue = model->B3SOIDDldwb; + return(OK); + case B3SOIDD_MOD_LVOFF: + value->rValue = model->B3SOIDDlvoff; + return(OK); + case B3SOIDD_MOD_LETA0: + value->rValue = model->B3SOIDDleta0; + return(OK); + case B3SOIDD_MOD_LETAB: + value->rValue = model->B3SOIDDletab; + return(OK); + case B3SOIDD_MOD_LDSUB : + value->rValue = model->B3SOIDDldsub; + return(OK); + case B3SOIDD_MOD_LCIT : + value->rValue = model->B3SOIDDlcit; + return(OK); + case B3SOIDD_MOD_LCDSC : + value->rValue = model->B3SOIDDlcdsc; + return(OK); + case B3SOIDD_MOD_LCDSCB : + value->rValue = model->B3SOIDDlcdscb; + return(OK); + case B3SOIDD_MOD_LCDSCD : + value->rValue = model->B3SOIDDlcdscd; + return(OK); + case B3SOIDD_MOD_LPCLM: + value->rValue = model->B3SOIDDlpclm; + return(OK); + case B3SOIDD_MOD_LPDIBL1: + value->rValue = model->B3SOIDDlpdibl1; + return(OK); + case B3SOIDD_MOD_LPDIBL2: + value->rValue = model->B3SOIDDlpdibl2; + return(OK); + case B3SOIDD_MOD_LPDIBLB: + value->rValue = model->B3SOIDDlpdiblb; + return(OK); + case B3SOIDD_MOD_LDROUT : + value->rValue = model->B3SOIDDldrout; + return(OK); + case B3SOIDD_MOD_LPVAG: + value->rValue = model->B3SOIDDlpvag; + return(OK); + case B3SOIDD_MOD_LDELTA: + value->rValue = model->B3SOIDDldelta; + return(OK); + case B3SOIDD_MOD_LAII: + value->rValue = model->B3SOIDDlaii; + return(OK); + case B3SOIDD_MOD_LBII: + value->rValue = model->B3SOIDDlbii; + return(OK); + case B3SOIDD_MOD_LCII: + value->rValue = model->B3SOIDDlcii; + return(OK); + case B3SOIDD_MOD_LDII: + value->rValue = model->B3SOIDDldii; + return(OK); + case B3SOIDD_MOD_LALPHA0: + value->rValue = model->B3SOIDDlalpha0; + return(OK); + case B3SOIDD_MOD_LALPHA1: + value->rValue = model->B3SOIDDlalpha1; + return(OK); + case B3SOIDD_MOD_LBETA0: + value->rValue = model->B3SOIDDlbeta0; + return(OK); + case B3SOIDD_MOD_LAGIDL: + value->rValue = model->B3SOIDDlagidl; + return(OK); + case B3SOIDD_MOD_LBGIDL: + value->rValue = model->B3SOIDDlbgidl; + return(OK); + case B3SOIDD_MOD_LNGIDL: + value->rValue = model->B3SOIDDlngidl; + return(OK); + case B3SOIDD_MOD_LNTUN: + value->rValue = model->B3SOIDDlntun; + return(OK); + case B3SOIDD_MOD_LNDIODE: + value->rValue = model->B3SOIDDlndiode; + return(OK); + case B3SOIDD_MOD_LISBJT: + value->rValue = model->B3SOIDDlisbjt; + return(OK); + case B3SOIDD_MOD_LISDIF: + value->rValue = model->B3SOIDDlisdif; + return(OK); + case B3SOIDD_MOD_LISREC: + value->rValue = model->B3SOIDDlisrec; + return(OK); + case B3SOIDD_MOD_LISTUN: + value->rValue = model->B3SOIDDlistun; + return(OK); + case B3SOIDD_MOD_LEDL: + value->rValue = model->B3SOIDDledl; + return(OK); + case B3SOIDD_MOD_LKBJT1: + value->rValue = model->B3SOIDDlkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_LVSDFB: + value->rValue = model->B3SOIDDlvsdfb; + return(OK); + case B3SOIDD_MOD_LVSDTH: + value->rValue = model->B3SOIDDlvsdth; + return(OK); + /* Width Dependence */ + case B3SOIDD_MOD_WNPEAK: + value->rValue = model->B3SOIDDwnpeak; + return(OK); + case B3SOIDD_MOD_WNSUB: + value->rValue = model->B3SOIDDwnsub; + return(OK); + case B3SOIDD_MOD_WNGATE: + value->rValue = model->B3SOIDDwngate; + return(OK); + case B3SOIDD_MOD_WVTH0: + value->rValue = model->B3SOIDDwvth0; + return(OK); + case B3SOIDD_MOD_WK1: + value->rValue = model->B3SOIDDwk1; + return(OK); + case B3SOIDD_MOD_WK2: + value->rValue = model->B3SOIDDwk2; + return(OK); + case B3SOIDD_MOD_WK3: + value->rValue = model->B3SOIDDwk3; + return(OK); + case B3SOIDD_MOD_WK3B: + value->rValue = model->B3SOIDDwk3b; + return(OK); + case B3SOIDD_MOD_WVBSA: + value->rValue = model->B3SOIDDwvbsa; + return(OK); + case B3SOIDD_MOD_WDELP: + value->rValue = model->B3SOIDDwdelp; + return(OK); + case B3SOIDD_MOD_WKB1: + value->rValue = model->B3SOIDDwkb1; + return(OK); + case B3SOIDD_MOD_WKB3: + value->rValue = model->B3SOIDDwkb3; + return(OK); + case B3SOIDD_MOD_WDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_WDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_WW0: + value->rValue = model->B3SOIDDww0; + return(OK); + case B3SOIDD_MOD_WNLX: + value->rValue = model->B3SOIDDwnlx; + return(OK); + case B3SOIDD_MOD_WDVT0 : + value->rValue = model->B3SOIDDwdvt0; + return(OK); + case B3SOIDD_MOD_WDVT1 : + value->rValue = model->B3SOIDDwdvt1; + return(OK); + case B3SOIDD_MOD_WDVT2 : + value->rValue = model->B3SOIDDwdvt2; + return(OK); + case B3SOIDD_MOD_WDVT0W : + value->rValue = model->B3SOIDDwdvt0w; + return(OK); + case B3SOIDD_MOD_WDVT1W : + value->rValue = model->B3SOIDDwdvt1w; + return(OK); + case B3SOIDD_MOD_WDVT2W : + value->rValue = model->B3SOIDDwdvt2w; + return(OK); + case B3SOIDD_MOD_WU0: + value->rValue = model->B3SOIDDwu0; + return(OK); + case B3SOIDD_MOD_WUA: + value->rValue = model->B3SOIDDwua; + return(OK); + case B3SOIDD_MOD_WUB: + value->rValue = model->B3SOIDDwub; + return(OK); + case B3SOIDD_MOD_WUC: + value->rValue = model->B3SOIDDwuc; + return(OK); + case B3SOIDD_MOD_WVSAT: + value->rValue = model->B3SOIDDwvsat; + return(OK); + case B3SOIDD_MOD_WA0: + value->rValue = model->B3SOIDDwa0; + return(OK); + case B3SOIDD_MOD_WAGS: + value->rValue = model->B3SOIDDwags; + return(OK); + case B3SOIDD_MOD_WB0: + value->rValue = model->B3SOIDDwb0; + return(OK); + case B3SOIDD_MOD_WB1: + value->rValue = model->B3SOIDDwb1; + return(OK); + case B3SOIDD_MOD_WKETA: + value->rValue = model->B3SOIDDwketa; + return(OK); + case B3SOIDD_MOD_WABP: + value->rValue = model->B3SOIDDwabp; + return(OK); + case B3SOIDD_MOD_WMXC: + value->rValue = model->B3SOIDDwmxc; + return(OK); + case B3SOIDD_MOD_WADICE0: + value->rValue = model->B3SOIDDwadice0; + return(OK); + case B3SOIDD_MOD_WA1: + value->rValue = model->B3SOIDDwa1; + return(OK); + case B3SOIDD_MOD_WA2: + value->rValue = model->B3SOIDDwa2; + return(OK); + case B3SOIDD_MOD_WRDSW: + value->rValue = model->B3SOIDDwrdsw; + return(OK); + case B3SOIDD_MOD_WPRWB: + value->rValue = model->B3SOIDDwprwb; + return(OK); + case B3SOIDD_MOD_WPRWG: + value->rValue = model->B3SOIDDwprwg; + return(OK); + case B3SOIDD_MOD_WWR: + value->rValue = model->B3SOIDDwwr; + return(OK); + case B3SOIDD_MOD_WNFACTOR : + value->rValue = model->B3SOIDDwnfactor; + return(OK); + case B3SOIDD_MOD_WDWG: + value->rValue = model->B3SOIDDwdwg; + return(OK); + case B3SOIDD_MOD_WDWB: + value->rValue = model->B3SOIDDwdwb; + return(OK); + case B3SOIDD_MOD_WVOFF: + value->rValue = model->B3SOIDDwvoff; + return(OK); + case B3SOIDD_MOD_WETA0: + value->rValue = model->B3SOIDDweta0; + return(OK); + case B3SOIDD_MOD_WETAB: + value->rValue = model->B3SOIDDwetab; + return(OK); + case B3SOIDD_MOD_WDSUB : + value->rValue = model->B3SOIDDwdsub; + return(OK); + case B3SOIDD_MOD_WCIT : + value->rValue = model->B3SOIDDwcit; + return(OK); + case B3SOIDD_MOD_WCDSC : + value->rValue = model->B3SOIDDwcdsc; + return(OK); + case B3SOIDD_MOD_WCDSCB : + value->rValue = model->B3SOIDDwcdscb; + return(OK); + case B3SOIDD_MOD_WCDSCD : + value->rValue = model->B3SOIDDwcdscd; + return(OK); + case B3SOIDD_MOD_WPCLM: + value->rValue = model->B3SOIDDwpclm; + return(OK); + case B3SOIDD_MOD_WPDIBL1: + value->rValue = model->B3SOIDDwpdibl1; + return(OK); + case B3SOIDD_MOD_WPDIBL2: + value->rValue = model->B3SOIDDwpdibl2; + return(OK); + case B3SOIDD_MOD_WPDIBLB: + value->rValue = model->B3SOIDDwpdiblb; + return(OK); + case B3SOIDD_MOD_WDROUT : + value->rValue = model->B3SOIDDwdrout; + return(OK); + case B3SOIDD_MOD_WPVAG: + value->rValue = model->B3SOIDDwpvag; + return(OK); + case B3SOIDD_MOD_WDELTA: + value->rValue = model->B3SOIDDwdelta; + return(OK); + case B3SOIDD_MOD_WAII: + value->rValue = model->B3SOIDDwaii; + return(OK); + case B3SOIDD_MOD_WBII: + value->rValue = model->B3SOIDDwbii; + return(OK); + case B3SOIDD_MOD_WCII: + value->rValue = model->B3SOIDDwcii; + return(OK); + case B3SOIDD_MOD_WDII: + value->rValue = model->B3SOIDDwdii; + return(OK); + case B3SOIDD_MOD_WALPHA0: + value->rValue = model->B3SOIDDwalpha0; + return(OK); + case B3SOIDD_MOD_WALPHA1: + value->rValue = model->B3SOIDDwalpha1; + return(OK); + case B3SOIDD_MOD_WBETA0: + value->rValue = model->B3SOIDDwbeta0; + return(OK); + case B3SOIDD_MOD_WAGIDL: + value->rValue = model->B3SOIDDwagidl; + return(OK); + case B3SOIDD_MOD_WBGIDL: + value->rValue = model->B3SOIDDwbgidl; + return(OK); + case B3SOIDD_MOD_WNGIDL: + value->rValue = model->B3SOIDDwngidl; + return(OK); + case B3SOIDD_MOD_WNTUN: + value->rValue = model->B3SOIDDwntun; + return(OK); + case B3SOIDD_MOD_WNDIODE: + value->rValue = model->B3SOIDDwndiode; + return(OK); + case B3SOIDD_MOD_WISBJT: + value->rValue = model->B3SOIDDwisbjt; + return(OK); + case B3SOIDD_MOD_WISDIF: + value->rValue = model->B3SOIDDwisdif; + return(OK); + case B3SOIDD_MOD_WISREC: + value->rValue = model->B3SOIDDwisrec; + return(OK); + case B3SOIDD_MOD_WISTUN: + value->rValue = model->B3SOIDDwistun; + return(OK); + case B3SOIDD_MOD_WEDL: + value->rValue = model->B3SOIDDwedl; + return(OK); + case B3SOIDD_MOD_WKBJT1: + value->rValue = model->B3SOIDDwkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_WVSDFB: + value->rValue = model->B3SOIDDwvsdfb; + return(OK); + case B3SOIDD_MOD_WVSDTH: + value->rValue = model->B3SOIDDwvsdth; + return(OK); + /* Cross-term Dependence */ + case B3SOIDD_MOD_PNPEAK: + value->rValue = model->B3SOIDDpnpeak; + return(OK); + case B3SOIDD_MOD_PNSUB: + value->rValue = model->B3SOIDDpnsub; + return(OK); + case B3SOIDD_MOD_PNGATE: + value->rValue = model->B3SOIDDpngate; + return(OK); + case B3SOIDD_MOD_PVTH0: + value->rValue = model->B3SOIDDpvth0; + return(OK); + case B3SOIDD_MOD_PK1: + value->rValue = model->B3SOIDDpk1; + return(OK); + case B3SOIDD_MOD_PK2: + value->rValue = model->B3SOIDDpk2; + return(OK); + case B3SOIDD_MOD_PK3: + value->rValue = model->B3SOIDDpk3; + return(OK); + case B3SOIDD_MOD_PK3B: + value->rValue = model->B3SOIDDpk3b; + return(OK); + case B3SOIDD_MOD_PVBSA: + value->rValue = model->B3SOIDDpvbsa; + return(OK); + case B3SOIDD_MOD_PDELP: + value->rValue = model->B3SOIDDpdelp; + return(OK); + case B3SOIDD_MOD_PKB1: + value->rValue = model->B3SOIDDpkb1; + return(OK); + case B3SOIDD_MOD_PKB3: + value->rValue = model->B3SOIDDpkb3; + return(OK); + case B3SOIDD_MOD_PDVBD0: + value->rValue = model->B3SOIDDdvbd0; + return(OK); + case B3SOIDD_MOD_PDVBD1: + value->rValue = model->B3SOIDDdvbd1; + return(OK); + case B3SOIDD_MOD_PW0: + value->rValue = model->B3SOIDDpw0; + return(OK); + case B3SOIDD_MOD_PNLX: + value->rValue = model->B3SOIDDpnlx; + return(OK); + case B3SOIDD_MOD_PDVT0 : + value->rValue = model->B3SOIDDpdvt0; + return(OK); + case B3SOIDD_MOD_PDVT1 : + value->rValue = model->B3SOIDDpdvt1; + return(OK); + case B3SOIDD_MOD_PDVT2 : + value->rValue = model->B3SOIDDpdvt2; + return(OK); + case B3SOIDD_MOD_PDVT0W : + value->rValue = model->B3SOIDDpdvt0w; + return(OK); + case B3SOIDD_MOD_PDVT1W : + value->rValue = model->B3SOIDDpdvt1w; + return(OK); + case B3SOIDD_MOD_PDVT2W : + value->rValue = model->B3SOIDDpdvt2w; + return(OK); + case B3SOIDD_MOD_PU0: + value->rValue = model->B3SOIDDpu0; + return(OK); + case B3SOIDD_MOD_PUA: + value->rValue = model->B3SOIDDpua; + return(OK); + case B3SOIDD_MOD_PUB: + value->rValue = model->B3SOIDDpub; + return(OK); + case B3SOIDD_MOD_PUC: + value->rValue = model->B3SOIDDpuc; + return(OK); + case B3SOIDD_MOD_PVSAT: + value->rValue = model->B3SOIDDpvsat; + return(OK); + case B3SOIDD_MOD_PA0: + value->rValue = model->B3SOIDDpa0; + return(OK); + case B3SOIDD_MOD_PAGS: + value->rValue = model->B3SOIDDpags; + return(OK); + case B3SOIDD_MOD_PB0: + value->rValue = model->B3SOIDDpb0; + return(OK); + case B3SOIDD_MOD_PB1: + value->rValue = model->B3SOIDDpb1; + return(OK); + case B3SOIDD_MOD_PKETA: + value->rValue = model->B3SOIDDpketa; + return(OK); + case B3SOIDD_MOD_PABP: + value->rValue = model->B3SOIDDpabp; + return(OK); + case B3SOIDD_MOD_PMXC: + value->rValue = model->B3SOIDDpmxc; + return(OK); + case B3SOIDD_MOD_PADICE0: + value->rValue = model->B3SOIDDpadice0; + return(OK); + case B3SOIDD_MOD_PA1: + value->rValue = model->B3SOIDDpa1; + return(OK); + case B3SOIDD_MOD_PA2: + value->rValue = model->B3SOIDDpa2; + return(OK); + case B3SOIDD_MOD_PRDSW: + value->rValue = model->B3SOIDDprdsw; + return(OK); + case B3SOIDD_MOD_PPRWB: + value->rValue = model->B3SOIDDpprwb; + return(OK); + case B3SOIDD_MOD_PPRWG: + value->rValue = model->B3SOIDDpprwg; + return(OK); + case B3SOIDD_MOD_PWR: + value->rValue = model->B3SOIDDpwr; + return(OK); + case B3SOIDD_MOD_PNFACTOR : + value->rValue = model->B3SOIDDpnfactor; + return(OK); + case B3SOIDD_MOD_PDWG: + value->rValue = model->B3SOIDDpdwg; + return(OK); + case B3SOIDD_MOD_PDWB: + value->rValue = model->B3SOIDDpdwb; + return(OK); + case B3SOIDD_MOD_PVOFF: + value->rValue = model->B3SOIDDpvoff; + return(OK); + case B3SOIDD_MOD_PETA0: + value->rValue = model->B3SOIDDpeta0; + return(OK); + case B3SOIDD_MOD_PETAB: + value->rValue = model->B3SOIDDpetab; + return(OK); + case B3SOIDD_MOD_PDSUB : + value->rValue = model->B3SOIDDpdsub; + return(OK); + case B3SOIDD_MOD_PCIT : + value->rValue = model->B3SOIDDpcit; + return(OK); + case B3SOIDD_MOD_PCDSC : + value->rValue = model->B3SOIDDpcdsc; + return(OK); + case B3SOIDD_MOD_PCDSCB : + value->rValue = model->B3SOIDDpcdscb; + return(OK); + case B3SOIDD_MOD_PCDSCD : + value->rValue = model->B3SOIDDpcdscd; + return(OK); + case B3SOIDD_MOD_PPCLM: + value->rValue = model->B3SOIDDppclm; + return(OK); + case B3SOIDD_MOD_PPDIBL1: + value->rValue = model->B3SOIDDppdibl1; + return(OK); + case B3SOIDD_MOD_PPDIBL2: + value->rValue = model->B3SOIDDppdibl2; + return(OK); + case B3SOIDD_MOD_PPDIBLB: + value->rValue = model->B3SOIDDppdiblb; + return(OK); + case B3SOIDD_MOD_PDROUT : + value->rValue = model->B3SOIDDpdrout; + return(OK); + case B3SOIDD_MOD_PPVAG: + value->rValue = model->B3SOIDDppvag; + return(OK); + case B3SOIDD_MOD_PDELTA: + value->rValue = model->B3SOIDDpdelta; + return(OK); + case B3SOIDD_MOD_PAII: + value->rValue = model->B3SOIDDpaii; + return(OK); + case B3SOIDD_MOD_PBII: + value->rValue = model->B3SOIDDpbii; + return(OK); + case B3SOIDD_MOD_PCII: + value->rValue = model->B3SOIDDpcii; + return(OK); + case B3SOIDD_MOD_PDII: + value->rValue = model->B3SOIDDpdii; + return(OK); + case B3SOIDD_MOD_PALPHA0: + value->rValue = model->B3SOIDDpalpha0; + return(OK); + case B3SOIDD_MOD_PALPHA1: + value->rValue = model->B3SOIDDpalpha1; + return(OK); + case B3SOIDD_MOD_PBETA0: + value->rValue = model->B3SOIDDpbeta0; + return(OK); + case B3SOIDD_MOD_PAGIDL: + value->rValue = model->B3SOIDDpagidl; + return(OK); + case B3SOIDD_MOD_PBGIDL: + value->rValue = model->B3SOIDDpbgidl; + return(OK); + case B3SOIDD_MOD_PNGIDL: + value->rValue = model->B3SOIDDpngidl; + return(OK); + case B3SOIDD_MOD_PNTUN: + value->rValue = model->B3SOIDDpntun; + return(OK); + case B3SOIDD_MOD_PNDIODE: + value->rValue = model->B3SOIDDpndiode; + return(OK); + case B3SOIDD_MOD_PISBJT: + value->rValue = model->B3SOIDDpisbjt; + return(OK); + case B3SOIDD_MOD_PISDIF: + value->rValue = model->B3SOIDDpisdif; + return(OK); + case B3SOIDD_MOD_PISREC: + value->rValue = model->B3SOIDDpisrec; + return(OK); + case B3SOIDD_MOD_PISTUN: + value->rValue = model->B3SOIDDpistun; + return(OK); + case B3SOIDD_MOD_PEDL: + value->rValue = model->B3SOIDDpedl; + return(OK); + case B3SOIDD_MOD_PKBJT1: + value->rValue = model->B3SOIDDpkbjt1; + return(OK); + /* CV Model */ + case B3SOIDD_MOD_PVSDFB: + value->rValue = model->B3SOIDDpvsdfb; + return(OK); + case B3SOIDD_MOD_PVSDTH: + value->rValue = model->B3SOIDDpvsdth; + return(OK); +/* Added for binning - END */ + + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c new file mode 100644 index 000000000..7cd06dbe6 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmdel.c @@ -0,0 +1,48 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddmdel.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDmDelete(inModel,modname,kill) +GENmodel **inModel; +IFuid modname; +GENmodel *kill; +{ +B3SOIDDmodel **model = (B3SOIDDmodel**)inModel; +B3SOIDDmodel *modfast = (B3SOIDDmodel*)kill; +B3SOIDDinstance *here; +B3SOIDDinstance *prev = NULL; +B3SOIDDmodel **oldmod; + + oldmod = model; + for (; *model ; model = &((*model)->B3SOIDDnextModel)) + { if ((*model)->B3SOIDDmodName == modname || + (modfast && *model == modfast)) + goto delgot; + oldmod = model; + } + return(E_NOMOD); + +delgot: + *oldmod = (*model)->B3SOIDDnextModel; /* cut deleted device out of list */ + for (here = (*model)->B3SOIDDinstances; here; here = here->B3SOIDDnextInstance) + { if(prev) FREE(prev); + prev = here; + } + if(prev) FREE(prev); + FREE(*model); + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c b/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c new file mode 100644 index 000000000..85f4b6797 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddmpar.c @@ -0,0 +1,1625 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Wei Jin 99/9/27 +File: b3soiddmpar.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "b3soidddef.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDmParam(param,value,inMod) +int param; +IFvalue *value; +GENmodel *inMod; +{ + B3SOIDDmodel *mod = (B3SOIDDmodel*)inMod; + switch(param) + { + + case B3SOIDD_MOD_MOBMOD : + mod->B3SOIDDmobMod = value->iValue; + mod->B3SOIDDmobModGiven = TRUE; + break; + case B3SOIDD_MOD_BINUNIT : + mod->B3SOIDDbinUnit = value->iValue; + mod->B3SOIDDbinUnitGiven = TRUE; + break; + case B3SOIDD_MOD_PARAMCHK : + mod->B3SOIDDparamChk = value->iValue; + mod->B3SOIDDparamChkGiven = TRUE; + break; + case B3SOIDD_MOD_CAPMOD : + mod->B3SOIDDcapMod = value->iValue; + mod->B3SOIDDcapModGiven = TRUE; + break; + case B3SOIDD_MOD_SHMOD : + mod->B3SOIDDshMod = value->iValue; + mod->B3SOIDDshModGiven = TRUE; + break; + case B3SOIDD_MOD_NOIMOD : + mod->B3SOIDDnoiMod = value->iValue; + mod->B3SOIDDnoiModGiven = TRUE; + break; + case B3SOIDD_MOD_VERSION : + mod->B3SOIDDversion = value->rValue; + mod->B3SOIDDversionGiven = TRUE; + break; + case B3SOIDD_MOD_TOX : + mod->B3SOIDDtox = value->rValue; + mod->B3SOIDDtoxGiven = TRUE; + break; + + case B3SOIDD_MOD_CDSC : + mod->B3SOIDDcdsc = value->rValue; + mod->B3SOIDDcdscGiven = TRUE; + break; + case B3SOIDD_MOD_CDSCB : + mod->B3SOIDDcdscb = value->rValue; + mod->B3SOIDDcdscbGiven = TRUE; + break; + + case B3SOIDD_MOD_CDSCD : + mod->B3SOIDDcdscd = value->rValue; + mod->B3SOIDDcdscdGiven = TRUE; + break; + + case B3SOIDD_MOD_CIT : + mod->B3SOIDDcit = value->rValue; + mod->B3SOIDDcitGiven = TRUE; + break; + case B3SOIDD_MOD_NFACTOR : + mod->B3SOIDDnfactor = value->rValue; + mod->B3SOIDDnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_VSAT: + mod->B3SOIDDvsat = value->rValue; + mod->B3SOIDDvsatGiven = TRUE; + break; + case B3SOIDD_MOD_A0: + mod->B3SOIDDa0 = value->rValue; + mod->B3SOIDDa0Given = TRUE; + break; + + case B3SOIDD_MOD_AGS: + mod->B3SOIDDags= value->rValue; + mod->B3SOIDDagsGiven = TRUE; + break; + + case B3SOIDD_MOD_A1: + mod->B3SOIDDa1 = value->rValue; + mod->B3SOIDDa1Given = TRUE; + break; + case B3SOIDD_MOD_A2: + mod->B3SOIDDa2 = value->rValue; + mod->B3SOIDDa2Given = TRUE; + break; + case B3SOIDD_MOD_AT: + mod->B3SOIDDat = value->rValue; + mod->B3SOIDDatGiven = TRUE; + break; + case B3SOIDD_MOD_KETA: + mod->B3SOIDDketa = value->rValue; + mod->B3SOIDDketaGiven = TRUE; + break; + case B3SOIDD_MOD_NSUB: + mod->B3SOIDDnsub = value->rValue; + mod->B3SOIDDnsubGiven = TRUE; + break; + case B3SOIDD_MOD_NPEAK: + mod->B3SOIDDnpeak = value->rValue; + mod->B3SOIDDnpeakGiven = TRUE; + if (mod->B3SOIDDnpeak > 1.0e20) + mod->B3SOIDDnpeak *= 1.0e-6; + break; + case B3SOIDD_MOD_NGATE: + mod->B3SOIDDngate = value->rValue; + mod->B3SOIDDngateGiven = TRUE; + if (mod->B3SOIDDngate > 1.0e23) + mod->B3SOIDDngate *= 1.0e-6; + break; + case B3SOIDD_MOD_GAMMA1: + mod->B3SOIDDgamma1 = value->rValue; + mod->B3SOIDDgamma1Given = TRUE; + break; + case B3SOIDD_MOD_GAMMA2: + mod->B3SOIDDgamma2 = value->rValue; + mod->B3SOIDDgamma2Given = TRUE; + break; + case B3SOIDD_MOD_VBX: + mod->B3SOIDDvbx = value->rValue; + mod->B3SOIDDvbxGiven = TRUE; + break; + case B3SOIDD_MOD_VBM: + mod->B3SOIDDvbm = value->rValue; + mod->B3SOIDDvbmGiven = TRUE; + break; + case B3SOIDD_MOD_XT: + mod->B3SOIDDxt = value->rValue; + mod->B3SOIDDxtGiven = TRUE; + break; + case B3SOIDD_MOD_K1: + mod->B3SOIDDk1 = value->rValue; + mod->B3SOIDDk1Given = TRUE; + break; + case B3SOIDD_MOD_KT1: + mod->B3SOIDDkt1 = value->rValue; + mod->B3SOIDDkt1Given = TRUE; + break; + case B3SOIDD_MOD_KT1L: + mod->B3SOIDDkt1l = value->rValue; + mod->B3SOIDDkt1lGiven = TRUE; + break; + case B3SOIDD_MOD_KT2: + mod->B3SOIDDkt2 = value->rValue; + mod->B3SOIDDkt2Given = TRUE; + break; + case B3SOIDD_MOD_K2: + mod->B3SOIDDk2 = value->rValue; + mod->B3SOIDDk2Given = TRUE; + break; + case B3SOIDD_MOD_K3: + mod->B3SOIDDk3 = value->rValue; + mod->B3SOIDDk3Given = TRUE; + break; + case B3SOIDD_MOD_K3B: + mod->B3SOIDDk3b = value->rValue; + mod->B3SOIDDk3bGiven = TRUE; + break; + case B3SOIDD_MOD_NLX: + mod->B3SOIDDnlx = value->rValue; + mod->B3SOIDDnlxGiven = TRUE; + break; + case B3SOIDD_MOD_W0: + mod->B3SOIDDw0 = value->rValue; + mod->B3SOIDDw0Given = TRUE; + break; + case B3SOIDD_MOD_DVT0: + mod->B3SOIDDdvt0 = value->rValue; + mod->B3SOIDDdvt0Given = TRUE; + break; + case B3SOIDD_MOD_DVT1: + mod->B3SOIDDdvt1 = value->rValue; + mod->B3SOIDDdvt1Given = TRUE; + break; + case B3SOIDD_MOD_DVT2: + mod->B3SOIDDdvt2 = value->rValue; + mod->B3SOIDDdvt2Given = TRUE; + break; + case B3SOIDD_MOD_DVT0W: + mod->B3SOIDDdvt0w = value->rValue; + mod->B3SOIDDdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_DVT1W: + mod->B3SOIDDdvt1w = value->rValue; + mod->B3SOIDDdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_DVT2W: + mod->B3SOIDDdvt2w = value->rValue; + mod->B3SOIDDdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_DROUT: + mod->B3SOIDDdrout = value->rValue; + mod->B3SOIDDdroutGiven = TRUE; + break; + case B3SOIDD_MOD_DSUB: + mod->B3SOIDDdsub = value->rValue; + mod->B3SOIDDdsubGiven = TRUE; + break; + case B3SOIDD_MOD_VTH0: + mod->B3SOIDDvth0 = value->rValue; + mod->B3SOIDDvth0Given = TRUE; + break; + case B3SOIDD_MOD_UA: + mod->B3SOIDDua = value->rValue; + mod->B3SOIDDuaGiven = TRUE; + break; + case B3SOIDD_MOD_UA1: + mod->B3SOIDDua1 = value->rValue; + mod->B3SOIDDua1Given = TRUE; + break; + case B3SOIDD_MOD_UB: + mod->B3SOIDDub = value->rValue; + mod->B3SOIDDubGiven = TRUE; + break; + case B3SOIDD_MOD_UB1: + mod->B3SOIDDub1 = value->rValue; + mod->B3SOIDDub1Given = TRUE; + break; + case B3SOIDD_MOD_UC: + mod->B3SOIDDuc = value->rValue; + mod->B3SOIDDucGiven = TRUE; + break; + case B3SOIDD_MOD_UC1: + mod->B3SOIDDuc1 = value->rValue; + mod->B3SOIDDuc1Given = TRUE; + break; + case B3SOIDD_MOD_U0 : + mod->B3SOIDDu0 = value->rValue; + mod->B3SOIDDu0Given = TRUE; + break; + case B3SOIDD_MOD_UTE : + mod->B3SOIDDute = value->rValue; + mod->B3SOIDDuteGiven = TRUE; + break; + case B3SOIDD_MOD_VOFF: + mod->B3SOIDDvoff = value->rValue; + mod->B3SOIDDvoffGiven = TRUE; + break; + case B3SOIDD_MOD_DELTA : + mod->B3SOIDDdelta = value->rValue; + mod->B3SOIDDdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_RDSW: + mod->B3SOIDDrdsw = value->rValue; + mod->B3SOIDDrdswGiven = TRUE; + break; + case B3SOIDD_MOD_PRWG: + mod->B3SOIDDprwg = value->rValue; + mod->B3SOIDDprwgGiven = TRUE; + break; + case B3SOIDD_MOD_PRWB: + mod->B3SOIDDprwb = value->rValue; + mod->B3SOIDDprwbGiven = TRUE; + break; + case B3SOIDD_MOD_PRT: + mod->B3SOIDDprt = value->rValue; + mod->B3SOIDDprtGiven = TRUE; + break; + case B3SOIDD_MOD_ETA0: + mod->B3SOIDDeta0 = value->rValue; + mod->B3SOIDDeta0Given = TRUE; + break; + case B3SOIDD_MOD_ETAB: + mod->B3SOIDDetab = value->rValue; + mod->B3SOIDDetabGiven = TRUE; + break; + case B3SOIDD_MOD_PCLM: + mod->B3SOIDDpclm = value->rValue; + mod->B3SOIDDpclmGiven = TRUE; + break; + case B3SOIDD_MOD_PDIBL1: + mod->B3SOIDDpdibl1 = value->rValue; + mod->B3SOIDDpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_PDIBL2: + mod->B3SOIDDpdibl2 = value->rValue; + mod->B3SOIDDpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_PDIBLB: + mod->B3SOIDDpdiblb = value->rValue; + mod->B3SOIDDpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_PVAG: + mod->B3SOIDDpvag = value->rValue; + mod->B3SOIDDpvagGiven = TRUE; + break; + case B3SOIDD_MOD_WR : + mod->B3SOIDDwr = value->rValue; + mod->B3SOIDDwrGiven = TRUE; + break; + case B3SOIDD_MOD_DWG : + mod->B3SOIDDdwg = value->rValue; + mod->B3SOIDDdwgGiven = TRUE; + break; + case B3SOIDD_MOD_DWB : + mod->B3SOIDDdwb = value->rValue; + mod->B3SOIDDdwbGiven = TRUE; + break; + case B3SOIDD_MOD_B0 : + mod->B3SOIDDb0 = value->rValue; + mod->B3SOIDDb0Given = TRUE; + break; + case B3SOIDD_MOD_B1 : + mod->B3SOIDDb1 = value->rValue; + mod->B3SOIDDb1Given = TRUE; + break; + case B3SOIDD_MOD_ALPHA0 : + mod->B3SOIDDalpha0 = value->rValue; + mod->B3SOIDDalpha0Given = TRUE; + break; + case B3SOIDD_MOD_ALPHA1 : + mod->B3SOIDDalpha1 = value->rValue; + mod->B3SOIDDalpha1Given = TRUE; + break; + case B3SOIDD_MOD_BETA0 : + mod->B3SOIDDbeta0 = value->rValue; + mod->B3SOIDDbeta0Given = TRUE; + break; + + case B3SOIDD_MOD_CGSL : + mod->B3SOIDDcgsl = value->rValue; + mod->B3SOIDDcgslGiven = TRUE; + break; + case B3SOIDD_MOD_CGDL : + mod->B3SOIDDcgdl = value->rValue; + mod->B3SOIDDcgdlGiven = TRUE; + break; + case B3SOIDD_MOD_CKAPPA : + mod->B3SOIDDckappa = value->rValue; + mod->B3SOIDDckappaGiven = TRUE; + break; + case B3SOIDD_MOD_CF : + mod->B3SOIDDcf = value->rValue; + mod->B3SOIDDcfGiven = TRUE; + break; + case B3SOIDD_MOD_CLC : + mod->B3SOIDDclc = value->rValue; + mod->B3SOIDDclcGiven = TRUE; + break; + case B3SOIDD_MOD_CLE : + mod->B3SOIDDcle = value->rValue; + mod->B3SOIDDcleGiven = TRUE; + break; + case B3SOIDD_MOD_DWC : + mod->B3SOIDDdwc = value->rValue; + mod->B3SOIDDdwcGiven = TRUE; + break; + case B3SOIDD_MOD_DLC : + mod->B3SOIDDdlc = value->rValue; + mod->B3SOIDDdlcGiven = TRUE; + break; + case B3SOIDD_MOD_TBOX : + mod->B3SOIDDtbox = value->rValue; + mod->B3SOIDDtboxGiven = TRUE; + break; + case B3SOIDD_MOD_TSI : + mod->B3SOIDDtsi = value->rValue; + mod->B3SOIDDtsiGiven = TRUE; + break; + case B3SOIDD_MOD_XJ : + mod->B3SOIDDxj = value->rValue; + mod->B3SOIDDxjGiven = TRUE; + break; + case B3SOIDD_MOD_KB1 : + mod->B3SOIDDkb1 = value->rValue; + mod->B3SOIDDkb1Given = TRUE; + break; + case B3SOIDD_MOD_KB3 : + mod->B3SOIDDkb3 = value->rValue; + mod->B3SOIDDkb3Given = TRUE; + break; + case B3SOIDD_MOD_DVBD0 : + mod->B3SOIDDdvbd0 = value->rValue; + mod->B3SOIDDdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_DVBD1 : + mod->B3SOIDDdvbd1 = value->rValue; + mod->B3SOIDDdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_DELP : + mod->B3SOIDDdelp = value->rValue; + mod->B3SOIDDdelpGiven = TRUE; + break; + case B3SOIDD_MOD_VBSA : + mod->B3SOIDDvbsa = value->rValue; + mod->B3SOIDDvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_RBODY : + mod->B3SOIDDrbody = value->rValue; + mod->B3SOIDDrbodyGiven = TRUE; + break; + case B3SOIDD_MOD_RBSH : + mod->B3SOIDDrbsh = value->rValue; + mod->B3SOIDDrbshGiven = TRUE; + break; + case B3SOIDD_MOD_ADICE0 : + mod->B3SOIDDadice0 = value->rValue; + mod->B3SOIDDadice0Given = TRUE; + break; + case B3SOIDD_MOD_ABP : + mod->B3SOIDDabp = value->rValue; + mod->B3SOIDDabpGiven = TRUE; + break; + case B3SOIDD_MOD_MXC : + mod->B3SOIDDmxc = value->rValue; + mod->B3SOIDDmxcGiven = TRUE; + break; + case B3SOIDD_MOD_RTH0 : + mod->B3SOIDDrth0 = value->rValue; + mod->B3SOIDDrth0Given = TRUE; + break; + case B3SOIDD_MOD_CTH0 : + mod->B3SOIDDcth0 = value->rValue; + mod->B3SOIDDcth0Given = TRUE; + break; + case B3SOIDD_MOD_AII : + mod->B3SOIDDaii = value->rValue; + mod->B3SOIDDaiiGiven = TRUE; + break; + case B3SOIDD_MOD_BII : + mod->B3SOIDDbii = value->rValue; + mod->B3SOIDDbiiGiven = TRUE; + break; + case B3SOIDD_MOD_CII : + mod->B3SOIDDcii = value->rValue; + mod->B3SOIDDciiGiven = TRUE; + break; + case B3SOIDD_MOD_DII : + mod->B3SOIDDdii = value->rValue; + mod->B3SOIDDdiiGiven = TRUE; + break; + case B3SOIDD_MOD_NGIDL : + mod->B3SOIDDngidl = value->rValue; + mod->B3SOIDDngidlGiven = TRUE; + break; + case B3SOIDD_MOD_AGIDL : + mod->B3SOIDDagidl = value->rValue; + mod->B3SOIDDagidlGiven = TRUE; + break; + case B3SOIDD_MOD_BGIDL : + mod->B3SOIDDbgidl = value->rValue; + mod->B3SOIDDbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_NDIODE : + mod->B3SOIDDndiode = value->rValue; + mod->B3SOIDDndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_NTUN : + mod->B3SOIDDntun = value->rValue; + mod->B3SOIDDntunGiven = TRUE; + break; + case B3SOIDD_MOD_ISBJT : + mod->B3SOIDDisbjt = value->rValue; + mod->B3SOIDDisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_ISDIF : + mod->B3SOIDDisdif = value->rValue; + mod->B3SOIDDisdifGiven = TRUE; + break; + case B3SOIDD_MOD_ISREC : + mod->B3SOIDDisrec = value->rValue; + mod->B3SOIDDisrecGiven = TRUE; + break; + case B3SOIDD_MOD_ISTUN : + mod->B3SOIDDistun = value->rValue; + mod->B3SOIDDistunGiven = TRUE; + break; + case B3SOIDD_MOD_XBJT : + mod->B3SOIDDxbjt = value->rValue; + mod->B3SOIDDxbjtGiven = TRUE; + break; + case B3SOIDD_MOD_XREC : + mod->B3SOIDDxrec = value->rValue; + mod->B3SOIDDxrecGiven = TRUE; + break; + case B3SOIDD_MOD_XTUN : + mod->B3SOIDDxtun = value->rValue; + mod->B3SOIDDxtunGiven = TRUE; + break; + case B3SOIDD_MOD_EDL : + mod->B3SOIDDedl = value->rValue; + mod->B3SOIDDedlGiven = TRUE; + break; + case B3SOIDD_MOD_KBJT1 : + mod->B3SOIDDkbjt1 = value->rValue; + mod->B3SOIDDkbjt1Given = TRUE; + break; + case B3SOIDD_MOD_TT : + mod->B3SOIDDtt = value->rValue; + mod->B3SOIDDttGiven = TRUE; + break; + case B3SOIDD_MOD_VSDTH : + mod->B3SOIDDvsdth = value->rValue; + mod->B3SOIDDvsdthGiven = TRUE; + break; + case B3SOIDD_MOD_VSDFB : + mod->B3SOIDDvsdfb = value->rValue; + mod->B3SOIDDvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_CSDMIN : + mod->B3SOIDDcsdmin = value->rValue; + mod->B3SOIDDcsdminGiven = TRUE; + break; + case B3SOIDD_MOD_ASD : + mod->B3SOIDDasd = value->rValue; + mod->B3SOIDDasdGiven = TRUE; + break; + + + case B3SOIDD_MOD_TNOM : + mod->B3SOIDDtnom = value->rValue + 273.15; + mod->B3SOIDDtnomGiven = TRUE; + break; + case B3SOIDD_MOD_CGSO : + mod->B3SOIDDcgso = value->rValue; + mod->B3SOIDDcgsoGiven = TRUE; + break; + case B3SOIDD_MOD_CGDO : + mod->B3SOIDDcgdo = value->rValue; + mod->B3SOIDDcgdoGiven = TRUE; + break; + case B3SOIDD_MOD_CGEO : + mod->B3SOIDDcgeo = value->rValue; + mod->B3SOIDDcgeoGiven = TRUE; + break; + case B3SOIDD_MOD_XPART : + mod->B3SOIDDxpart = value->rValue; + mod->B3SOIDDxpartGiven = TRUE; + break; + case B3SOIDD_MOD_RSH : + mod->B3SOIDDsheetResistance = value->rValue; + mod->B3SOIDDsheetResistanceGiven = TRUE; + break; + case B3SOIDD_MOD_PBSWG : + mod->B3SOIDDGatesidewallJctPotential = value->rValue; + mod->B3SOIDDGatesidewallJctPotentialGiven = TRUE; + break; + case B3SOIDD_MOD_MJSWG : + mod->B3SOIDDbodyJctGateSideGradingCoeff = value->rValue; + mod->B3SOIDDbodyJctGateSideGradingCoeffGiven = TRUE; + break; + case B3SOIDD_MOD_CJSWG : + mod->B3SOIDDunitLengthGateSidewallJctCap = value->rValue; + mod->B3SOIDDunitLengthGateSidewallJctCapGiven = TRUE; + break; + case B3SOIDD_MOD_CSDESW : + mod->B3SOIDDcsdesw = value->rValue; + mod->B3SOIDDcsdeswGiven = TRUE; + break; + case B3SOIDD_MOD_LINT : + mod->B3SOIDDLint = value->rValue; + mod->B3SOIDDLintGiven = TRUE; + break; + case B3SOIDD_MOD_LL : + mod->B3SOIDDLl = value->rValue; + mod->B3SOIDDLlGiven = TRUE; + break; + case B3SOIDD_MOD_LLN : + mod->B3SOIDDLln = value->rValue; + mod->B3SOIDDLlnGiven = TRUE; + break; + case B3SOIDD_MOD_LW : + mod->B3SOIDDLw = value->rValue; + mod->B3SOIDDLwGiven = TRUE; + break; + case B3SOIDD_MOD_LWN : + mod->B3SOIDDLwn = value->rValue; + mod->B3SOIDDLwnGiven = TRUE; + break; + case B3SOIDD_MOD_LWL : + mod->B3SOIDDLwl = value->rValue; + mod->B3SOIDDLwlGiven = TRUE; + break; + case B3SOIDD_MOD_WINT : + mod->B3SOIDDWint = value->rValue; + mod->B3SOIDDWintGiven = TRUE; + break; + case B3SOIDD_MOD_WL : + mod->B3SOIDDWl = value->rValue; + mod->B3SOIDDWlGiven = TRUE; + break; + case B3SOIDD_MOD_WLN : + mod->B3SOIDDWln = value->rValue; + mod->B3SOIDDWlnGiven = TRUE; + break; + case B3SOIDD_MOD_WW : + mod->B3SOIDDWw = value->rValue; + mod->B3SOIDDWwGiven = TRUE; + break; + case B3SOIDD_MOD_WWN : + mod->B3SOIDDWwn = value->rValue; + mod->B3SOIDDWwnGiven = TRUE; + break; + case B3SOIDD_MOD_WWL : + mod->B3SOIDDWwl = value->rValue; + mod->B3SOIDDWwlGiven = TRUE; + break; + + case B3SOIDD_MOD_NOIA : + mod->B3SOIDDoxideTrapDensityA = value->rValue; + mod->B3SOIDDoxideTrapDensityAGiven = TRUE; + break; + case B3SOIDD_MOD_NOIB : + mod->B3SOIDDoxideTrapDensityB = value->rValue; + mod->B3SOIDDoxideTrapDensityBGiven = TRUE; + break; + case B3SOIDD_MOD_NOIC : + mod->B3SOIDDoxideTrapDensityC = value->rValue; + mod->B3SOIDDoxideTrapDensityCGiven = TRUE; + break; + case B3SOIDD_MOD_NOIF : + mod->B3SOIDDnoif = value->rValue; + mod->B3SOIDDnoifGiven = TRUE; + break; + case B3SOIDD_MOD_EM : + mod->B3SOIDDem = value->rValue; + mod->B3SOIDDemGiven = TRUE; + break; + case B3SOIDD_MOD_EF : + mod->B3SOIDDef = value->rValue; + mod->B3SOIDDefGiven = TRUE; + break; + case B3SOIDD_MOD_AF : + mod->B3SOIDDaf = value->rValue; + mod->B3SOIDDafGiven = TRUE; + break; + case B3SOIDD_MOD_KF : + mod->B3SOIDDkf = value->rValue; + mod->B3SOIDDkfGiven = TRUE; + break; + +/* Added for binning - START */ + /* Length Dependence */ + case B3SOIDD_MOD_LNPEAK: + mod->B3SOIDDlnpeak = value->rValue; + mod->B3SOIDDlnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_LNSUB: + mod->B3SOIDDlnsub = value->rValue; + mod->B3SOIDDlnsubGiven = TRUE; + break; + case B3SOIDD_MOD_LNGATE: + mod->B3SOIDDlngate = value->rValue; + mod->B3SOIDDlngateGiven = TRUE; + break; + case B3SOIDD_MOD_LVTH0: + mod->B3SOIDDlvth0 = value->rValue; + mod->B3SOIDDlvth0Given = TRUE; + break; + case B3SOIDD_MOD_LK1: + mod->B3SOIDDlk1 = value->rValue; + mod->B3SOIDDlk1Given = TRUE; + break; + case B3SOIDD_MOD_LK2: + mod->B3SOIDDlk2 = value->rValue; + mod->B3SOIDDlk2Given = TRUE; + break; + case B3SOIDD_MOD_LK3: + mod->B3SOIDDlk3 = value->rValue; + mod->B3SOIDDlk3Given = TRUE; + break; + case B3SOIDD_MOD_LK3B: + mod->B3SOIDDlk3b = value->rValue; + mod->B3SOIDDlk3bGiven = TRUE; + break; + case B3SOIDD_MOD_LVBSA: + mod->B3SOIDDlvbsa = value->rValue; + mod->B3SOIDDlvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_LDELP: + mod->B3SOIDDldelp = value->rValue; + mod->B3SOIDDldelpGiven = TRUE; + break; + case B3SOIDD_MOD_LKB1 : + mod->B3SOIDDlkb1 = value->rValue; + mod->B3SOIDDlkb1Given = TRUE; + break; + case B3SOIDD_MOD_LKB3 : + mod->B3SOIDDlkb3 = value->rValue; + mod->B3SOIDDlkb3Given = TRUE; + break; + case B3SOIDD_MOD_LDVBD0 : + mod->B3SOIDDldvbd0 = value->rValue; + mod->B3SOIDDldvbd0Given = TRUE; + break; + case B3SOIDD_MOD_LDVBD1 : + mod->B3SOIDDldvbd1 = value->rValue; + mod->B3SOIDDldvbd1Given = TRUE; + break; + case B3SOIDD_MOD_LW0: + mod->B3SOIDDlw0 = value->rValue; + mod->B3SOIDDlw0Given = TRUE; + break; + case B3SOIDD_MOD_LNLX: + mod->B3SOIDDlnlx = value->rValue; + mod->B3SOIDDlnlxGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT0: + mod->B3SOIDDldvt0 = value->rValue; + mod->B3SOIDDldvt0Given = TRUE; + break; + case B3SOIDD_MOD_LDVT1: + mod->B3SOIDDldvt1 = value->rValue; + mod->B3SOIDDldvt1Given = TRUE; + break; + case B3SOIDD_MOD_LDVT2: + mod->B3SOIDDldvt2 = value->rValue; + mod->B3SOIDDldvt2Given = TRUE; + break; + case B3SOIDD_MOD_LDVT0W: + mod->B3SOIDDldvt0w = value->rValue; + mod->B3SOIDDldvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT1W: + mod->B3SOIDDldvt1w = value->rValue; + mod->B3SOIDDldvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_LDVT2W: + mod->B3SOIDDldvt2w = value->rValue; + mod->B3SOIDDldvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_LU0 : + mod->B3SOIDDlu0 = value->rValue; + mod->B3SOIDDlu0Given = TRUE; + break; + case B3SOIDD_MOD_LUA: + mod->B3SOIDDlua = value->rValue; + mod->B3SOIDDluaGiven = TRUE; + break; + case B3SOIDD_MOD_LUB: + mod->B3SOIDDlub = value->rValue; + mod->B3SOIDDlubGiven = TRUE; + break; + case B3SOIDD_MOD_LUC: + mod->B3SOIDDluc = value->rValue; + mod->B3SOIDDlucGiven = TRUE; + break; + case B3SOIDD_MOD_LVSAT: + mod->B3SOIDDlvsat = value->rValue; + mod->B3SOIDDlvsatGiven = TRUE; + break; + case B3SOIDD_MOD_LA0: + mod->B3SOIDDla0 = value->rValue; + mod->B3SOIDDla0Given = TRUE; + break; + case B3SOIDD_MOD_LAGS: + mod->B3SOIDDlags= value->rValue; + mod->B3SOIDDlagsGiven = TRUE; + break; + case B3SOIDD_MOD_LB0 : + mod->B3SOIDDlb0 = value->rValue; + mod->B3SOIDDlb0Given = TRUE; + break; + case B3SOIDD_MOD_LB1 : + mod->B3SOIDDlb1 = value->rValue; + mod->B3SOIDDlb1Given = TRUE; + break; + case B3SOIDD_MOD_LKETA: + mod->B3SOIDDlketa = value->rValue; + mod->B3SOIDDlketaGiven = TRUE; + break; + case B3SOIDD_MOD_LABP: + mod->B3SOIDDlabp = value->rValue; + mod->B3SOIDDlabpGiven = TRUE; + break; + case B3SOIDD_MOD_LMXC: + mod->B3SOIDDlmxc = value->rValue; + mod->B3SOIDDlmxcGiven = TRUE; + break; + case B3SOIDD_MOD_LADICE0: + mod->B3SOIDDladice0 = value->rValue; + mod->B3SOIDDladice0Given = TRUE; + break; + case B3SOIDD_MOD_LA1: + mod->B3SOIDDla1 = value->rValue; + mod->B3SOIDDla1Given = TRUE; + break; + case B3SOIDD_MOD_LA2: + mod->B3SOIDDla2 = value->rValue; + mod->B3SOIDDla2Given = TRUE; + break; + case B3SOIDD_MOD_LRDSW: + mod->B3SOIDDlrdsw = value->rValue; + mod->B3SOIDDlrdswGiven = TRUE; + break; + case B3SOIDD_MOD_LPRWB: + mod->B3SOIDDlprwb = value->rValue; + mod->B3SOIDDlprwbGiven = TRUE; + break; + case B3SOIDD_MOD_LPRWG: + mod->B3SOIDDlprwg = value->rValue; + mod->B3SOIDDlprwgGiven = TRUE; + break; + case B3SOIDD_MOD_LWR : + mod->B3SOIDDlwr = value->rValue; + mod->B3SOIDDlwrGiven = TRUE; + break; + case B3SOIDD_MOD_LNFACTOR : + mod->B3SOIDDlnfactor = value->rValue; + mod->B3SOIDDlnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_LDWG : + mod->B3SOIDDldwg = value->rValue; + mod->B3SOIDDldwgGiven = TRUE; + break; + case B3SOIDD_MOD_LDWB : + mod->B3SOIDDldwb = value->rValue; + mod->B3SOIDDldwbGiven = TRUE; + break; + case B3SOIDD_MOD_LVOFF: + mod->B3SOIDDlvoff = value->rValue; + mod->B3SOIDDlvoffGiven = TRUE; + break; + case B3SOIDD_MOD_LETA0: + mod->B3SOIDDleta0 = value->rValue; + mod->B3SOIDDleta0Given = TRUE; + break; + case B3SOIDD_MOD_LETAB: + mod->B3SOIDDletab = value->rValue; + mod->B3SOIDDletabGiven = TRUE; + break; + case B3SOIDD_MOD_LDSUB: + mod->B3SOIDDldsub = value->rValue; + mod->B3SOIDDldsubGiven = TRUE; + break; + case B3SOIDD_MOD_LCIT : + mod->B3SOIDDlcit = value->rValue; + mod->B3SOIDDlcitGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSC : + mod->B3SOIDDlcdsc = value->rValue; + mod->B3SOIDDlcdscGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSCB : + mod->B3SOIDDlcdscb = value->rValue; + mod->B3SOIDDlcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_LCDSCD : + mod->B3SOIDDlcdscd = value->rValue; + mod->B3SOIDDlcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_LPCLM: + mod->B3SOIDDlpclm = value->rValue; + mod->B3SOIDDlpclmGiven = TRUE; + break; + case B3SOIDD_MOD_LPDIBL1: + mod->B3SOIDDlpdibl1 = value->rValue; + mod->B3SOIDDlpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_LPDIBL2: + mod->B3SOIDDlpdibl2 = value->rValue; + mod->B3SOIDDlpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_LPDIBLB: + mod->B3SOIDDlpdiblb = value->rValue; + mod->B3SOIDDlpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_LDROUT: + mod->B3SOIDDldrout = value->rValue; + mod->B3SOIDDldroutGiven = TRUE; + break; + case B3SOIDD_MOD_LPVAG: + mod->B3SOIDDlpvag = value->rValue; + mod->B3SOIDDlpvagGiven = TRUE; + break; + case B3SOIDD_MOD_LDELTA : + mod->B3SOIDDldelta = value->rValue; + mod->B3SOIDDldeltaGiven = TRUE; + break; + case B3SOIDD_MOD_LAII : + mod->B3SOIDDlaii = value->rValue; + mod->B3SOIDDlaiiGiven = TRUE; + break; + case B3SOIDD_MOD_LBII : + mod->B3SOIDDlbii = value->rValue; + mod->B3SOIDDlbiiGiven = TRUE; + break; + case B3SOIDD_MOD_LCII : + mod->B3SOIDDlcii = value->rValue; + mod->B3SOIDDlciiGiven = TRUE; + break; + case B3SOIDD_MOD_LDII : + mod->B3SOIDDldii = value->rValue; + mod->B3SOIDDldiiGiven = TRUE; + break; + case B3SOIDD_MOD_LALPHA0 : + mod->B3SOIDDlalpha0 = value->rValue; + mod->B3SOIDDlalpha0Given = TRUE; + break; + case B3SOIDD_MOD_LALPHA1 : + mod->B3SOIDDlalpha1 = value->rValue; + mod->B3SOIDDlalpha1Given = TRUE; + break; + case B3SOIDD_MOD_LBETA0 : + mod->B3SOIDDlbeta0 = value->rValue; + mod->B3SOIDDlbeta0Given = TRUE; + break; + case B3SOIDD_MOD_LAGIDL : + mod->B3SOIDDlagidl = value->rValue; + mod->B3SOIDDlagidlGiven = TRUE; + break; + case B3SOIDD_MOD_LBGIDL : + mod->B3SOIDDlbgidl = value->rValue; + mod->B3SOIDDlbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_LNGIDL : + mod->B3SOIDDlngidl = value->rValue; + mod->B3SOIDDlngidlGiven = TRUE; + break; + case B3SOIDD_MOD_LNTUN : + mod->B3SOIDDlntun = value->rValue; + mod->B3SOIDDlntunGiven = TRUE; + break; + case B3SOIDD_MOD_LNDIODE : + mod->B3SOIDDlndiode = value->rValue; + mod->B3SOIDDlndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_LISBJT : + mod->B3SOIDDlisbjt = value->rValue; + mod->B3SOIDDlisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_LISDIF : + mod->B3SOIDDlisdif = value->rValue; + mod->B3SOIDDlisdifGiven = TRUE; + break; + case B3SOIDD_MOD_LISREC : + mod->B3SOIDDlisrec = value->rValue; + mod->B3SOIDDlisrecGiven = TRUE; + break; + case B3SOIDD_MOD_LISTUN : + mod->B3SOIDDlistun = value->rValue; + mod->B3SOIDDlistunGiven = TRUE; + break; + case B3SOIDD_MOD_LEDL : + mod->B3SOIDDledl = value->rValue; + mod->B3SOIDDledlGiven = TRUE; + break; + case B3SOIDD_MOD_LKBJT1 : + mod->B3SOIDDlkbjt1 = value->rValue; + mod->B3SOIDDlkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_LVSDFB : + mod->B3SOIDDlvsdfb = value->rValue; + mod->B3SOIDDlvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_LVSDTH : + mod->B3SOIDDlvsdth = value->rValue; + mod->B3SOIDDlvsdthGiven = TRUE; + break; + /* Width Dependence */ + case B3SOIDD_MOD_WNPEAK: + mod->B3SOIDDwnpeak = value->rValue; + mod->B3SOIDDwnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_WNSUB: + mod->B3SOIDDwnsub = value->rValue; + mod->B3SOIDDwnsubGiven = TRUE; + break; + case B3SOIDD_MOD_WNGATE: + mod->B3SOIDDwngate = value->rValue; + mod->B3SOIDDwngateGiven = TRUE; + break; + case B3SOIDD_MOD_WVTH0: + mod->B3SOIDDwvth0 = value->rValue; + mod->B3SOIDDwvth0Given = TRUE; + break; + case B3SOIDD_MOD_WK1: + mod->B3SOIDDwk1 = value->rValue; + mod->B3SOIDDwk1Given = TRUE; + break; + case B3SOIDD_MOD_WK2: + mod->B3SOIDDwk2 = value->rValue; + mod->B3SOIDDwk2Given = TRUE; + break; + case B3SOIDD_MOD_WK3: + mod->B3SOIDDwk3 = value->rValue; + mod->B3SOIDDwk3Given = TRUE; + break; + case B3SOIDD_MOD_WK3B: + mod->B3SOIDDwk3b = value->rValue; + mod->B3SOIDDwk3bGiven = TRUE; + break; + case B3SOIDD_MOD_WVBSA: + mod->B3SOIDDwvbsa = value->rValue; + mod->B3SOIDDwvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_WDELP: + mod->B3SOIDDwdelp = value->rValue; + mod->B3SOIDDwdelpGiven = TRUE; + break; + case B3SOIDD_MOD_WKB1 : + mod->B3SOIDDwkb1 = value->rValue; + mod->B3SOIDDwkb1Given = TRUE; + break; + case B3SOIDD_MOD_WKB3 : + mod->B3SOIDDwkb3 = value->rValue; + mod->B3SOIDDwkb3Given = TRUE; + break; + case B3SOIDD_MOD_WDVBD0 : + mod->B3SOIDDwdvbd0 = value->rValue; + mod->B3SOIDDwdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_WDVBD1 : + mod->B3SOIDDwdvbd1 = value->rValue; + mod->B3SOIDDwdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_WW0: + mod->B3SOIDDww0 = value->rValue; + mod->B3SOIDDww0Given = TRUE; + break; + case B3SOIDD_MOD_WNLX: + mod->B3SOIDDwnlx = value->rValue; + mod->B3SOIDDwnlxGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT0: + mod->B3SOIDDwdvt0 = value->rValue; + mod->B3SOIDDwdvt0Given = TRUE; + break; + case B3SOIDD_MOD_WDVT1: + mod->B3SOIDDwdvt1 = value->rValue; + mod->B3SOIDDwdvt1Given = TRUE; + break; + case B3SOIDD_MOD_WDVT2: + mod->B3SOIDDwdvt2 = value->rValue; + mod->B3SOIDDwdvt2Given = TRUE; + break; + case B3SOIDD_MOD_WDVT0W: + mod->B3SOIDDwdvt0w = value->rValue; + mod->B3SOIDDwdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT1W: + mod->B3SOIDDwdvt1w = value->rValue; + mod->B3SOIDDwdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_WDVT2W: + mod->B3SOIDDwdvt2w = value->rValue; + mod->B3SOIDDwdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_WU0 : + mod->B3SOIDDwu0 = value->rValue; + mod->B3SOIDDwu0Given = TRUE; + break; + case B3SOIDD_MOD_WUA: + mod->B3SOIDDwua = value->rValue; + mod->B3SOIDDwuaGiven = TRUE; + break; + case B3SOIDD_MOD_WUB: + mod->B3SOIDDwub = value->rValue; + mod->B3SOIDDwubGiven = TRUE; + break; + case B3SOIDD_MOD_WUC: + mod->B3SOIDDwuc = value->rValue; + mod->B3SOIDDwucGiven = TRUE; + break; + case B3SOIDD_MOD_WVSAT: + mod->B3SOIDDwvsat = value->rValue; + mod->B3SOIDDwvsatGiven = TRUE; + break; + case B3SOIDD_MOD_WA0: + mod->B3SOIDDwa0 = value->rValue; + mod->B3SOIDDwa0Given = TRUE; + break; + case B3SOIDD_MOD_WAGS: + mod->B3SOIDDwags= value->rValue; + mod->B3SOIDDwagsGiven = TRUE; + break; + case B3SOIDD_MOD_WB0 : + mod->B3SOIDDwb0 = value->rValue; + mod->B3SOIDDwb0Given = TRUE; + break; + case B3SOIDD_MOD_WB1 : + mod->B3SOIDDwb1 = value->rValue; + mod->B3SOIDDwb1Given = TRUE; + break; + case B3SOIDD_MOD_WKETA: + mod->B3SOIDDwketa = value->rValue; + mod->B3SOIDDwketaGiven = TRUE; + break; + case B3SOIDD_MOD_WABP: + mod->B3SOIDDwabp = value->rValue; + mod->B3SOIDDwabpGiven = TRUE; + break; + case B3SOIDD_MOD_WMXC: + mod->B3SOIDDwmxc = value->rValue; + mod->B3SOIDDwmxcGiven = TRUE; + break; + case B3SOIDD_MOD_WADICE0: + mod->B3SOIDDwadice0 = value->rValue; + mod->B3SOIDDwadice0Given = TRUE; + break; + case B3SOIDD_MOD_WA1: + mod->B3SOIDDwa1 = value->rValue; + mod->B3SOIDDwa1Given = TRUE; + break; + case B3SOIDD_MOD_WA2: + mod->B3SOIDDwa2 = value->rValue; + mod->B3SOIDDwa2Given = TRUE; + break; + case B3SOIDD_MOD_WRDSW: + mod->B3SOIDDwrdsw = value->rValue; + mod->B3SOIDDwrdswGiven = TRUE; + break; + case B3SOIDD_MOD_WPRWB: + mod->B3SOIDDwprwb = value->rValue; + mod->B3SOIDDwprwbGiven = TRUE; + break; + case B3SOIDD_MOD_WPRWG: + mod->B3SOIDDwprwg = value->rValue; + mod->B3SOIDDwprwgGiven = TRUE; + break; + case B3SOIDD_MOD_WWR : + mod->B3SOIDDwwr = value->rValue; + mod->B3SOIDDwwrGiven = TRUE; + break; + case B3SOIDD_MOD_WNFACTOR : + mod->B3SOIDDwnfactor = value->rValue; + mod->B3SOIDDwnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_WDWG : + mod->B3SOIDDwdwg = value->rValue; + mod->B3SOIDDwdwgGiven = TRUE; + break; + case B3SOIDD_MOD_WDWB : + mod->B3SOIDDwdwb = value->rValue; + mod->B3SOIDDwdwbGiven = TRUE; + break; + case B3SOIDD_MOD_WVOFF: + mod->B3SOIDDwvoff = value->rValue; + mod->B3SOIDDwvoffGiven = TRUE; + break; + case B3SOIDD_MOD_WETA0: + mod->B3SOIDDweta0 = value->rValue; + mod->B3SOIDDweta0Given = TRUE; + break; + case B3SOIDD_MOD_WETAB: + mod->B3SOIDDwetab = value->rValue; + mod->B3SOIDDwetabGiven = TRUE; + break; + case B3SOIDD_MOD_WDSUB: + mod->B3SOIDDwdsub = value->rValue; + mod->B3SOIDDwdsubGiven = TRUE; + break; + case B3SOIDD_MOD_WCIT : + mod->B3SOIDDwcit = value->rValue; + mod->B3SOIDDwcitGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSC : + mod->B3SOIDDwcdsc = value->rValue; + mod->B3SOIDDwcdscGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSCB : + mod->B3SOIDDwcdscb = value->rValue; + mod->B3SOIDDwcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_WCDSCD : + mod->B3SOIDDwcdscd = value->rValue; + mod->B3SOIDDwcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_WPCLM: + mod->B3SOIDDwpclm = value->rValue; + mod->B3SOIDDwpclmGiven = TRUE; + break; + case B3SOIDD_MOD_WPDIBL1: + mod->B3SOIDDwpdibl1 = value->rValue; + mod->B3SOIDDwpdibl1Given = TRUE; + break; + case B3SOIDD_MOD_WPDIBL2: + mod->B3SOIDDwpdibl2 = value->rValue; + mod->B3SOIDDwpdibl2Given = TRUE; + break; + case B3SOIDD_MOD_WPDIBLB: + mod->B3SOIDDwpdiblb = value->rValue; + mod->B3SOIDDwpdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_WDROUT: + mod->B3SOIDDwdrout = value->rValue; + mod->B3SOIDDwdroutGiven = TRUE; + break; + case B3SOIDD_MOD_WPVAG: + mod->B3SOIDDwpvag = value->rValue; + mod->B3SOIDDwpvagGiven = TRUE; + break; + case B3SOIDD_MOD_WDELTA : + mod->B3SOIDDwdelta = value->rValue; + mod->B3SOIDDwdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_WAII : + mod->B3SOIDDwaii = value->rValue; + mod->B3SOIDDwaiiGiven = TRUE; + break; + case B3SOIDD_MOD_WBII : + mod->B3SOIDDwbii = value->rValue; + mod->B3SOIDDwbiiGiven = TRUE; + break; + case B3SOIDD_MOD_WCII : + mod->B3SOIDDwcii = value->rValue; + mod->B3SOIDDwciiGiven = TRUE; + break; + case B3SOIDD_MOD_WDII : + mod->B3SOIDDwdii = value->rValue; + mod->B3SOIDDwdiiGiven = TRUE; + break; + case B3SOIDD_MOD_WALPHA0 : + mod->B3SOIDDwalpha0 = value->rValue; + mod->B3SOIDDwalpha0Given = TRUE; + break; + case B3SOIDD_MOD_WALPHA1 : + mod->B3SOIDDwalpha1 = value->rValue; + mod->B3SOIDDwalpha1Given = TRUE; + break; + case B3SOIDD_MOD_WBETA0 : + mod->B3SOIDDwbeta0 = value->rValue; + mod->B3SOIDDwbeta0Given = TRUE; + break; + case B3SOIDD_MOD_WAGIDL : + mod->B3SOIDDwagidl = value->rValue; + mod->B3SOIDDwagidlGiven = TRUE; + break; + case B3SOIDD_MOD_WBGIDL : + mod->B3SOIDDwbgidl = value->rValue; + mod->B3SOIDDwbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_WNGIDL : + mod->B3SOIDDwngidl = value->rValue; + mod->B3SOIDDwngidlGiven = TRUE; + break; + case B3SOIDD_MOD_WNTUN : + mod->B3SOIDDwntun = value->rValue; + mod->B3SOIDDwntunGiven = TRUE; + break; + case B3SOIDD_MOD_WNDIODE : + mod->B3SOIDDwndiode = value->rValue; + mod->B3SOIDDwndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_WISBJT : + mod->B3SOIDDwisbjt = value->rValue; + mod->B3SOIDDwisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_WISDIF : + mod->B3SOIDDwisdif = value->rValue; + mod->B3SOIDDwisdifGiven = TRUE; + break; + case B3SOIDD_MOD_WISREC : + mod->B3SOIDDwisrec = value->rValue; + mod->B3SOIDDwisrecGiven = TRUE; + break; + case B3SOIDD_MOD_WISTUN : + mod->B3SOIDDwistun = value->rValue; + mod->B3SOIDDwistunGiven = TRUE; + break; + case B3SOIDD_MOD_WEDL : + mod->B3SOIDDwedl = value->rValue; + mod->B3SOIDDwedlGiven = TRUE; + break; + case B3SOIDD_MOD_WKBJT1 : + mod->B3SOIDDwkbjt1 = value->rValue; + mod->B3SOIDDwkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_WVSDFB : + mod->B3SOIDDwvsdfb = value->rValue; + mod->B3SOIDDwvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_WVSDTH : + mod->B3SOIDDwvsdth = value->rValue; + mod->B3SOIDDwvsdthGiven = TRUE; + break; + /* Cross-term Dependence */ + case B3SOIDD_MOD_PNPEAK: + mod->B3SOIDDpnpeak = value->rValue; + mod->B3SOIDDpnpeakGiven = TRUE; + break; + case B3SOIDD_MOD_PNSUB: + mod->B3SOIDDpnsub = value->rValue; + mod->B3SOIDDpnsubGiven = TRUE; + break; + case B3SOIDD_MOD_PNGATE: + mod->B3SOIDDpngate = value->rValue; + mod->B3SOIDDpngateGiven = TRUE; + break; + case B3SOIDD_MOD_PVTH0: + mod->B3SOIDDpvth0 = value->rValue; + mod->B3SOIDDpvth0Given = TRUE; + break; + case B3SOIDD_MOD_PK1: + mod->B3SOIDDpk1 = value->rValue; + mod->B3SOIDDpk1Given = TRUE; + break; + case B3SOIDD_MOD_PK2: + mod->B3SOIDDpk2 = value->rValue; + mod->B3SOIDDpk2Given = TRUE; + break; + case B3SOIDD_MOD_PK3: + mod->B3SOIDDpk3 = value->rValue; + mod->B3SOIDDpk3Given = TRUE; + break; + case B3SOIDD_MOD_PK3B: + mod->B3SOIDDpk3b = value->rValue; + mod->B3SOIDDpk3bGiven = TRUE; + break; + case B3SOIDD_MOD_PVBSA: + mod->B3SOIDDpvbsa = value->rValue; + mod->B3SOIDDpvbsaGiven = TRUE; + break; + case B3SOIDD_MOD_PDELP: + mod->B3SOIDDpdelp = value->rValue; + mod->B3SOIDDpdelpGiven = TRUE; + break; + case B3SOIDD_MOD_PKB1 : + mod->B3SOIDDpkb1 = value->rValue; + mod->B3SOIDDpkb1Given = TRUE; + break; + case B3SOIDD_MOD_PKB3 : + mod->B3SOIDDpkb3 = value->rValue; + mod->B3SOIDDpkb3Given = TRUE; + break; + case B3SOIDD_MOD_PDVBD0 : + mod->B3SOIDDpdvbd0 = value->rValue; + mod->B3SOIDDpdvbd0Given = TRUE; + break; + case B3SOIDD_MOD_PDVBD1 : + mod->B3SOIDDpdvbd1 = value->rValue; + mod->B3SOIDDpdvbd1Given = TRUE; + break; + case B3SOIDD_MOD_PW0: + mod->B3SOIDDpw0 = value->rValue; + mod->B3SOIDDpw0Given = TRUE; + break; + case B3SOIDD_MOD_PNLX: + mod->B3SOIDDpnlx = value->rValue; + mod->B3SOIDDpnlxGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT0: + mod->B3SOIDDpdvt0 = value->rValue; + mod->B3SOIDDpdvt0Given = TRUE; + break; + case B3SOIDD_MOD_PDVT1: + mod->B3SOIDDpdvt1 = value->rValue; + mod->B3SOIDDpdvt1Given = TRUE; + break; + case B3SOIDD_MOD_PDVT2: + mod->B3SOIDDpdvt2 = value->rValue; + mod->B3SOIDDpdvt2Given = TRUE; + break; + case B3SOIDD_MOD_PDVT0W: + mod->B3SOIDDpdvt0w = value->rValue; + mod->B3SOIDDpdvt0wGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT1W: + mod->B3SOIDDpdvt1w = value->rValue; + mod->B3SOIDDpdvt1wGiven = TRUE; + break; + case B3SOIDD_MOD_PDVT2W: + mod->B3SOIDDpdvt2w = value->rValue; + mod->B3SOIDDpdvt2wGiven = TRUE; + break; + case B3SOIDD_MOD_PU0 : + mod->B3SOIDDpu0 = value->rValue; + mod->B3SOIDDpu0Given = TRUE; + break; + case B3SOIDD_MOD_PUA: + mod->B3SOIDDpua = value->rValue; + mod->B3SOIDDpuaGiven = TRUE; + break; + case B3SOIDD_MOD_PUB: + mod->B3SOIDDpub = value->rValue; + mod->B3SOIDDpubGiven = TRUE; + break; + case B3SOIDD_MOD_PUC: + mod->B3SOIDDpuc = value->rValue; + mod->B3SOIDDpucGiven = TRUE; + break; + case B3SOIDD_MOD_PVSAT: + mod->B3SOIDDpvsat = value->rValue; + mod->B3SOIDDpvsatGiven = TRUE; + break; + case B3SOIDD_MOD_PA0: + mod->B3SOIDDpa0 = value->rValue; + mod->B3SOIDDpa0Given = TRUE; + break; + case B3SOIDD_MOD_PAGS: + mod->B3SOIDDpags= value->rValue; + mod->B3SOIDDpagsGiven = TRUE; + break; + case B3SOIDD_MOD_PB0 : + mod->B3SOIDDpb0 = value->rValue; + mod->B3SOIDDpb0Given = TRUE; + break; + case B3SOIDD_MOD_PB1 : + mod->B3SOIDDpb1 = value->rValue; + mod->B3SOIDDpb1Given = TRUE; + break; + case B3SOIDD_MOD_PKETA: + mod->B3SOIDDpketa = value->rValue; + mod->B3SOIDDpketaGiven = TRUE; + break; + case B3SOIDD_MOD_PABP: + mod->B3SOIDDpabp = value->rValue; + mod->B3SOIDDpabpGiven = TRUE; + break; + case B3SOIDD_MOD_PMXC: + mod->B3SOIDDpmxc = value->rValue; + mod->B3SOIDDpmxcGiven = TRUE; + break; + case B3SOIDD_MOD_PADICE0: + mod->B3SOIDDpadice0 = value->rValue; + mod->B3SOIDDpadice0Given = TRUE; + break; + case B3SOIDD_MOD_PA1: + mod->B3SOIDDpa1 = value->rValue; + mod->B3SOIDDpa1Given = TRUE; + break; + case B3SOIDD_MOD_PA2: + mod->B3SOIDDpa2 = value->rValue; + mod->B3SOIDDpa2Given = TRUE; + break; + case B3SOIDD_MOD_PRDSW: + mod->B3SOIDDprdsw = value->rValue; + mod->B3SOIDDprdswGiven = TRUE; + break; + case B3SOIDD_MOD_PPRWB: + mod->B3SOIDDpprwb = value->rValue; + mod->B3SOIDDpprwbGiven = TRUE; + break; + case B3SOIDD_MOD_PPRWG: + mod->B3SOIDDpprwg = value->rValue; + mod->B3SOIDDpprwgGiven = TRUE; + break; + case B3SOIDD_MOD_PWR : + mod->B3SOIDDpwr = value->rValue; + mod->B3SOIDDpwrGiven = TRUE; + break; + case B3SOIDD_MOD_PNFACTOR : + mod->B3SOIDDpnfactor = value->rValue; + mod->B3SOIDDpnfactorGiven = TRUE; + break; + case B3SOIDD_MOD_PDWG : + mod->B3SOIDDpdwg = value->rValue; + mod->B3SOIDDpdwgGiven = TRUE; + break; + case B3SOIDD_MOD_PDWB : + mod->B3SOIDDpdwb = value->rValue; + mod->B3SOIDDpdwbGiven = TRUE; + break; + case B3SOIDD_MOD_PVOFF: + mod->B3SOIDDpvoff = value->rValue; + mod->B3SOIDDpvoffGiven = TRUE; + break; + case B3SOIDD_MOD_PETA0: + mod->B3SOIDDpeta0 = value->rValue; + mod->B3SOIDDpeta0Given = TRUE; + break; + case B3SOIDD_MOD_PETAB: + mod->B3SOIDDpetab = value->rValue; + mod->B3SOIDDpetabGiven = TRUE; + break; + case B3SOIDD_MOD_PDSUB: + mod->B3SOIDDpdsub = value->rValue; + mod->B3SOIDDpdsubGiven = TRUE; + break; + case B3SOIDD_MOD_PCIT : + mod->B3SOIDDpcit = value->rValue; + mod->B3SOIDDpcitGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSC : + mod->B3SOIDDpcdsc = value->rValue; + mod->B3SOIDDpcdscGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSCB : + mod->B3SOIDDpcdscb = value->rValue; + mod->B3SOIDDpcdscbGiven = TRUE; + break; + case B3SOIDD_MOD_PCDSCD : + mod->B3SOIDDpcdscd = value->rValue; + mod->B3SOIDDpcdscdGiven = TRUE; + break; + case B3SOIDD_MOD_PPCLM: + mod->B3SOIDDppclm = value->rValue; + mod->B3SOIDDppclmGiven = TRUE; + break; + case B3SOIDD_MOD_PPDIBL1: + mod->B3SOIDDppdibl1 = value->rValue; + mod->B3SOIDDppdibl1Given = TRUE; + break; + case B3SOIDD_MOD_PPDIBL2: + mod->B3SOIDDppdibl2 = value->rValue; + mod->B3SOIDDppdibl2Given = TRUE; + break; + case B3SOIDD_MOD_PPDIBLB: + mod->B3SOIDDppdiblb = value->rValue; + mod->B3SOIDDppdiblbGiven = TRUE; + break; + case B3SOIDD_MOD_PDROUT: + mod->B3SOIDDpdrout = value->rValue; + mod->B3SOIDDpdroutGiven = TRUE; + break; + case B3SOIDD_MOD_PPVAG: + mod->B3SOIDDppvag = value->rValue; + mod->B3SOIDDppvagGiven = TRUE; + break; + case B3SOIDD_MOD_PDELTA : + mod->B3SOIDDpdelta = value->rValue; + mod->B3SOIDDpdeltaGiven = TRUE; + break; + case B3SOIDD_MOD_PAII : + mod->B3SOIDDpaii = value->rValue; + mod->B3SOIDDpaiiGiven = TRUE; + break; + case B3SOIDD_MOD_PBII : + mod->B3SOIDDpbii = value->rValue; + mod->B3SOIDDpbiiGiven = TRUE; + break; + case B3SOIDD_MOD_PCII : + mod->B3SOIDDpcii = value->rValue; + mod->B3SOIDDpciiGiven = TRUE; + break; + case B3SOIDD_MOD_PDII : + mod->B3SOIDDpdii = value->rValue; + mod->B3SOIDDpdiiGiven = TRUE; + break; + case B3SOIDD_MOD_PALPHA0 : + mod->B3SOIDDpalpha0 = value->rValue; + mod->B3SOIDDpalpha0Given = TRUE; + break; + case B3SOIDD_MOD_PALPHA1 : + mod->B3SOIDDpalpha1 = value->rValue; + mod->B3SOIDDpalpha1Given = TRUE; + break; + case B3SOIDD_MOD_PBETA0 : + mod->B3SOIDDpbeta0 = value->rValue; + mod->B3SOIDDpbeta0Given = TRUE; + break; + case B3SOIDD_MOD_PAGIDL : + mod->B3SOIDDpagidl = value->rValue; + mod->B3SOIDDpagidlGiven = TRUE; + break; + case B3SOIDD_MOD_PBGIDL : + mod->B3SOIDDpbgidl = value->rValue; + mod->B3SOIDDpbgidlGiven = TRUE; + break; + case B3SOIDD_MOD_PNGIDL : + mod->B3SOIDDpngidl = value->rValue; + mod->B3SOIDDpngidlGiven = TRUE; + break; + case B3SOIDD_MOD_PNTUN : + mod->B3SOIDDpntun = value->rValue; + mod->B3SOIDDpntunGiven = TRUE; + break; + case B3SOIDD_MOD_PNDIODE : + mod->B3SOIDDpndiode = value->rValue; + mod->B3SOIDDpndiodeGiven = TRUE; + break; + case B3SOIDD_MOD_PISBJT : + mod->B3SOIDDpisbjt = value->rValue; + mod->B3SOIDDpisbjtGiven = TRUE; + break; + case B3SOIDD_MOD_PISDIF : + mod->B3SOIDDpisdif = value->rValue; + mod->B3SOIDDpisdifGiven = TRUE; + break; + case B3SOIDD_MOD_PISREC : + mod->B3SOIDDpisrec = value->rValue; + mod->B3SOIDDpisrecGiven = TRUE; + break; + case B3SOIDD_MOD_PISTUN : + mod->B3SOIDDpistun = value->rValue; + mod->B3SOIDDpistunGiven = TRUE; + break; + case B3SOIDD_MOD_PEDL : + mod->B3SOIDDpedl = value->rValue; + mod->B3SOIDDpedlGiven = TRUE; + break; + case B3SOIDD_MOD_PKBJT1 : + mod->B3SOIDDpkbjt1 = value->rValue; + mod->B3SOIDDpkbjt1Given = TRUE; + break; + /* CV Model */ + case B3SOIDD_MOD_PVSDFB : + mod->B3SOIDDpvsdfb = value->rValue; + mod->B3SOIDDpvsdfbGiven = TRUE; + break; + case B3SOIDD_MOD_PVSDTH : + mod->B3SOIDDpvsdth = value->rValue; + mod->B3SOIDDpvsdthGiven = TRUE; + break; +/* Added for binning - END */ + + case B3SOIDD_MOD_NMOS : + if(value->iValue) { + mod->B3SOIDDtype = 1; + mod->B3SOIDDtypeGiven = TRUE; + } + break; + case B3SOIDD_MOD_PMOS : + if(value->iValue) { + mod->B3SOIDDtype = - 1; + mod->B3SOIDDtypeGiven = TRUE; + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c b/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c new file mode 100644 index 000000000..6e4826bb1 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddnoi.c @@ -0,0 +1,395 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddnoi.c 98/5/01 +**********/ + +#include "ngspice.h" +#include +#include +#include "b3soidddef.h" +#include "cktdefs.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "suffix.h" +#include "const.h" /* jwan */ + +/* + * B3SOIDDnoise (mode, operation, firstModel, ckt, data, OnDens) + * This routine names and evaluates all of the noise sources + * associated with MOSFET's. It starts with the model *firstModel and + * traverses all of its insts. It then proceeds to any other models + * on the linked list. The total output noise density generated by + * all of the MOSFET's is summed with the variable "OnDens". + */ + +/* + Channel thermal and flicker noises are calculated based on the value + of model->B3SOIDDnoiMod. + If model->B3SOIDDnoiMod = 1, + Channel thermal noise = SPICE2 model + Flicker noise = SPICE2 model + If model->B3SOIDDnoiMod = 2, + Channel thermal noise = B3SOIDD model + Flicker noise = B3SOIDD model + If model->B3SOIDDnoiMod = 3, + Channel thermal noise = SPICE2 model + Flicker noise = B3SOIDD model + If model->B3SOIDDnoiMod = 4, + Channel thermal noise = B3SOIDD model + Flicker noise = SPICE2 model + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +double +B3SOIDDStrongInversionNoiseEval(vgs, vds, model, here, freq, temp) +double vgs, vds, freq, temp; +B3SOIDDmodel *model; +B3SOIDDinstance *here; +{ +struct b3soiddSizeDependParam *pParam; +double cd, esat, DelClm, EffFreq, N0, Nl, Vgst; +double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, Ssi; +double req, ceq; + + pParam = here->pParam; + cd = fabs(here->B3SOIDDcd); + if (vds > here->B3SOIDDvdsat) + { esat = 2.0 * pParam->B3SOIDDvsattemp / here->B3SOIDDueff; + T0 = ((((vds - here->B3SOIDDvdsat) / pParam->B3SOIDDlitl) + model->B3SOIDDem) + / esat); + DelClm = pParam->B3SOIDDlitl * log (MAX(T0, N_MINLOG)); + } + else + DelClm = 0.0; + EffFreq = pow(freq, model->B3SOIDDef); + T1 = CHARGE * CHARGE * 8.62e-5 * cd * temp * here->B3SOIDDueff; + T2 = 1.0e8 * EffFreq * model->B3SOIDDcox + * pParam->B3SOIDDleff * pParam->B3SOIDDleff; + Vgst = vgs - here->B3SOIDDvon; + N0 = model->B3SOIDDcox * Vgst / CHARGE; + if (N0 < 0.0) + N0 = 0.0; + Nl = model->B3SOIDDcox * (Vgst - MIN(vds, here->B3SOIDDvdsat)) / CHARGE; + if (Nl < 0.0) + Nl = 0.0; + + T3 = model->B3SOIDDoxideTrapDensityA + * log(MAX(((N0 + 2.0e14) / (Nl + 2.0e14)), N_MINLOG)); + T4 = model->B3SOIDDoxideTrapDensityB * (N0 - Nl); + T5 = model->B3SOIDDoxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); + + T6 = 8.62e-5 * temp * cd * cd; + T7 = 1.0e8 * EffFreq * pParam->B3SOIDDleff + * pParam->B3SOIDDleff * pParam->B3SOIDDweff; + T8 = model->B3SOIDDoxideTrapDensityA + model->B3SOIDDoxideTrapDensityB * Nl + + model->B3SOIDDoxideTrapDensityC * Nl * Nl; + T9 = (Nl + 2.0e14) * (Nl + 2.0e14); + + Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; + + return Ssi; +} + +int +B3SOIDDnoise (mode, operation, inModel, ckt, data, OnDens) +int mode, operation; +GENmodel *inModel; +CKTcircuit *ckt; +register Ndata *data; +double *OnDens; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel *)inModel; +register B3SOIDDinstance *here; +struct b3soiddSizeDependParam *pParam; +char name[N_MXVLNTH]; +double tempOnoise; +double tempInoise; +double noizDens[B3SOIDDNSRCS]; +double lnNdens[B3SOIDDNSRCS]; + +double vgs, vds, Slimit; +double N0, Nl; +double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13; +double n, ExpArg, Ssi, Swi; + +int error, i; + + /* define the names of the noise sources */ + static char *B3SOIDDnNames[B3SOIDDNSRCS] = + { /* Note that we have to keep the order */ + ".rd", /* noise due to rd */ + /* consistent with the index definitions */ + ".rs", /* noise due to rs */ + /* in B3SOIDDdefs.h */ + ".id", /* noise due to id */ + ".1overf", /* flicker (1/f) noise */ + ".fb", /* noise due to floating body */ + "" /* total transistor noise */ + }; + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { pParam = here->pParam; + switch (operation) + { case N_OPEN: + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { switch (mode) + { case N_DENS: + for (i = 0; i < B3SOIDDNSRCS; i++) + { (void) sprintf(name, "onoise.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + } + break; + case INT_NOIZ: + for (i = 0; i < B3SOIDDNSRCS; i++) + { (void) sprintf(name, "onoise_total.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **) NULL); + /* we've added one more plot */ + + (void) sprintf(name, "inoise_total.%s%s", + here->B3SOIDDname, + B3SOIDDnNames[i]); + data->namelist = (IFuid *) trealloc( + (char *) data->namelist, + (data->numPlots + 1) + * sizeof(IFuid)); + if (!data->namelist) + return(E_NOMEM); + (*(SPfrontEnd->IFnewUid)) (ckt, + &(data->namelist[data->numPlots++]), + (IFuid) NULL, name, UID_OTHER, + (void **)NULL); + /* we've added one more plot */ + } + break; + } + } + break; + case N_CALC: + switch (mode) + { case N_DENS: + NevalSrc(&noizDens[B3SOIDDRDNOIZ], + &lnNdens[B3SOIDDRDNOIZ], ckt, THERMNOISE, + here->B3SOIDDdNodePrime, here->B3SOIDDdNode, + here->B3SOIDDdrainConductance); + + NevalSrc(&noizDens[B3SOIDDRSNOIZ], + &lnNdens[B3SOIDDRSNOIZ], ckt, THERMNOISE, + here->B3SOIDDsNodePrime, here->B3SOIDDsNode, + here->B3SOIDDsourceConductance); + + switch( model->B3SOIDDnoiMod ) + { case 1: + case 3: + NevalSrc(&noizDens[B3SOIDDIDNOIZ], + &lnNdens[B3SOIDDIDNOIZ], ckt, + THERMNOISE, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, + (2.0 / 3.0 * fabs(here->B3SOIDDgm + + here->B3SOIDDgds + + here->B3SOIDDgmbs))); + break; + case 2: + case 4: + NevalSrc(&noizDens[B3SOIDDIDNOIZ], + &lnNdens[B3SOIDDIDNOIZ], ckt, + THERMNOISE, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, + (here->B3SOIDDueff + * fabs(here->B3SOIDDqinv + / (pParam->B3SOIDDleff + * pParam->B3SOIDDleff)))); + break; + } + NevalSrc(&noizDens[B3SOIDDFLNOIZ], (double*) NULL, + ckt, N_GAIN, here->B3SOIDDdNodePrime, + here->B3SOIDDsNodePrime, (double) 0.0); + + switch( model->B3SOIDDnoiMod ) + { case 1: + case 4: + noizDens[B3SOIDDFLNOIZ] *= model->B3SOIDDkf + * exp(model->B3SOIDDaf + * log(MAX(fabs(here->B3SOIDDcd), + N_MINLOG))) + / (pow(data->freq, model->B3SOIDDef) + * pParam->B3SOIDDleff + * pParam->B3SOIDDleff + * model->B3SOIDDcox); + break; + case 2: + case 3: + vgs = *(ckt->CKTstates[0] + here->B3SOIDDvgs); + vds = *(ckt->CKTstates[0] + here->B3SOIDDvds); + if (vds < 0.0) + { vds = -vds; + vgs = vgs + vds; + } + if (vgs >= here->B3SOIDDvon + 0.1) + { Ssi = B3SOIDDStrongInversionNoiseEval(vgs, + vds, model, here, data->freq, + ckt->CKTtemp); + noizDens[B3SOIDDFLNOIZ] *= Ssi; + } + else + { pParam = here->pParam; + T10 = model->B3SOIDDoxideTrapDensityA + * 8.62e-5 * ckt->CKTtemp; + T11 = pParam->B3SOIDDweff + * pParam->B3SOIDDleff + * pow(data->freq, model->B3SOIDDef) + * 4.0e36; + Swi = T10 / T11 * here->B3SOIDDcd + * here->B3SOIDDcd; + Slimit = B3SOIDDStrongInversionNoiseEval( + here->B3SOIDDvon + 0.1, vds, model, + here, data->freq, ckt->CKTtemp); + T1 = Swi + Slimit; + if (T1 > 0.0) + noizDens[B3SOIDDFLNOIZ] *= (Slimit + * Swi) / T1; + else + noizDens[B3SOIDDFLNOIZ] *= 0.0; + } + break; + } + + lnNdens[B3SOIDDFLNOIZ] = + log(MAX(noizDens[B3SOIDDFLNOIZ], N_MINLOG)); + + /* Low frequency excess noise due to FBE */ + NevalSrc(&noizDens[B3SOIDDFBNOIZ], &lnNdens[B3SOIDDFBNOIZ], + ckt, SHOTNOISE, here->B3SOIDDsNodePrime, + here->B3SOIDDbNode, + 2.0 * model->B3SOIDDnoif * here->B3SOIDDibs); + + noizDens[B3SOIDDTOTNOIZ] = noizDens[B3SOIDDRDNOIZ] + + noizDens[B3SOIDDRSNOIZ] + + noizDens[B3SOIDDIDNOIZ] + + noizDens[B3SOIDDFLNOIZ] + + noizDens[B3SOIDDFBNOIZ]; + lnNdens[B3SOIDDTOTNOIZ] = + log(MAX(noizDens[B3SOIDDTOTNOIZ], N_MINLOG)); + + *OnDens += noizDens[B3SOIDDTOTNOIZ]; + + if (data->delFreq == 0.0) + { /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ + + for (i = 0; i < B3SOIDDNSRCS; i++) + { here->B3SOIDDnVar[LNLSTDENS][i] = + lnNdens[i]; + } + + /* clear out our integration variables + if it's the first pass + */ + if (data->freq == + ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { here->B3SOIDDnVar[OUTNOIZ][i] = 0.0; + here->B3SOIDDnVar[INNOIZ][i] = 0.0; + } + } + } + else + { /* data->delFreq != 0.0, + we have to integrate. + */ + for (i = 0; i < B3SOIDDNSRCS; i++) + { if (i != B3SOIDDTOTNOIZ) + { tempOnoise = Nintegrate(noizDens[i], + lnNdens[i], + here->B3SOIDDnVar[LNLSTDENS][i], + data); + tempInoise = Nintegrate(noizDens[i] + * data->GainSqInv, lnNdens[i] + + data->lnGainInv, + here->B3SOIDDnVar[LNLSTDENS][i] + + data->lnGainInv, data); + here->B3SOIDDnVar[LNLSTDENS][i] = + lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*) + ckt->CKTcurJob)->NStpsSm != 0) + { here->B3SOIDDnVar[OUTNOIZ][i] + += tempOnoise; + here->B3SOIDDnVar[OUTNOIZ][B3SOIDDTOTNOIZ] + += tempOnoise; + here->B3SOIDDnVar[INNOIZ][i] + += tempInoise; + here->B3SOIDDnVar[INNOIZ][B3SOIDDTOTNOIZ] + += tempInoise; + } + } + } + } + if (data->prtSummary) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { /* print a summary report */ + data->outpVector[data->outNumber++] + = noizDens[i]; + } + } + break; + case INT_NOIZ: + /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { for (i = 0; i < B3SOIDDNSRCS; i++) + { data->outpVector[data->outNumber++] + = here->B3SOIDDnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] + = here->B3SOIDDnVar[INNOIZ][i]; + } + } + break; + } + break; + case N_CLOSE: + /* do nothing, the main calling routine will close */ + return (OK); + break; /* the plots */ + } /* switch (operation) */ + } /* for here */ + } /* for model */ + + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c new file mode 100644 index 000000000..cf514fca5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddpar.c @@ -0,0 +1,128 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddpar.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "ifsim.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + +int +B3SOIDDparam(param,value,inst,select) +int param; +IFvalue *value; +GENinstance *inst; +IFvalue *select; +{ + B3SOIDDinstance *here = (B3SOIDDinstance*)inst; + switch(param) + { case B3SOIDD_W: + here->B3SOIDDw = value->rValue; + here->B3SOIDDwGiven = TRUE; + break; + case B3SOIDD_L: + here->B3SOIDDl = value->rValue; + here->B3SOIDDlGiven = TRUE; + break; + case B3SOIDD_AS: + here->B3SOIDDsourceArea = value->rValue; + here->B3SOIDDsourceAreaGiven = TRUE; + break; + case B3SOIDD_AD: + here->B3SOIDDdrainArea = value->rValue; + here->B3SOIDDdrainAreaGiven = TRUE; + break; + case B3SOIDD_PS: + here->B3SOIDDsourcePerimeter = value->rValue; + here->B3SOIDDsourcePerimeterGiven = TRUE; + break; + case B3SOIDD_PD: + here->B3SOIDDdrainPerimeter = value->rValue; + here->B3SOIDDdrainPerimeterGiven = TRUE; + break; + case B3SOIDD_NRS: + here->B3SOIDDsourceSquares = value->rValue; + here->B3SOIDDsourceSquaresGiven = TRUE; + break; + case B3SOIDD_NRD: + here->B3SOIDDdrainSquares = value->rValue; + here->B3SOIDDdrainSquaresGiven = TRUE; + break; + case B3SOIDD_OFF: + here->B3SOIDDoff = value->iValue; + break; + case B3SOIDD_IC_VBS: + here->B3SOIDDicVBS = value->rValue; + here->B3SOIDDicVBSGiven = TRUE; + break; + case B3SOIDD_IC_VDS: + here->B3SOIDDicVDS = value->rValue; + here->B3SOIDDicVDSGiven = TRUE; + break; + case B3SOIDD_IC_VGS: + here->B3SOIDDicVGS = value->rValue; + here->B3SOIDDicVGSGiven = TRUE; + break; + case B3SOIDD_IC_VES: + here->B3SOIDDicVES = value->rValue; + here->B3SOIDDicVESGiven = TRUE; + break; + case B3SOIDD_IC_VPS: + here->B3SOIDDicVPS = value->rValue; + here->B3SOIDDicVPSGiven = TRUE; + break; + case B3SOIDD_BJTOFF: + here->B3SOIDDbjtoff = value->iValue; + here->B3SOIDDbjtoffGiven= TRUE; + break; + case B3SOIDD_DEBUG: + here->B3SOIDDdebugMod = value->iValue; + here->B3SOIDDdebugModGiven= TRUE; + break; + case B3SOIDD_RTH0: + here->B3SOIDDrth0= value->rValue; + here->B3SOIDDrth0Given = TRUE; + break; + case B3SOIDD_CTH0: + here->B3SOIDDcth0= value->rValue; + here->B3SOIDDcth0Given = TRUE; + break; + case B3SOIDD_NRB: + here->B3SOIDDbodySquares = value->rValue; + here->B3SOIDDbodySquaresGiven = TRUE; + break; + case B3SOIDD_IC: + switch(value->v.numValue){ + case 5: + here->B3SOIDDicVPS = *(value->v.vec.rVec+4); + here->B3SOIDDicVPSGiven = TRUE; + case 4: + here->B3SOIDDicVES = *(value->v.vec.rVec+3); + here->B3SOIDDicVESGiven = TRUE; + case 3: + here->B3SOIDDicVBS = *(value->v.vec.rVec+2); + here->B3SOIDDicVBSGiven = TRUE; + case 2: + here->B3SOIDDicVGS = *(value->v.vec.rVec+1); + here->B3SOIDDicVGSGiven = TRUE; + case 1: + here->B3SOIDDicVDS = *(value->v.vec.rVec); + here->B3SOIDDicVDSGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + default: + return(E_BADPARM); + } + return(OK); +} + + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c b/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c new file mode 100644 index 000000000..a545828ed --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddpzld.c @@ -0,0 +1,153 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddpzld.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "sperror.h" +#include "b3soidddef.h" +#include "suffix.h" + +int +B3SOIDDpzLoad(inModel,ckt,s) +GENmodel *inModel; +register CKTcircuit *ckt; +register SPcomplex *s; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; +double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; +double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb; +double GSoverlapCap, GDoverlapCap, GBoverlapCap; +double FwdSum, RevSum, Gm, Gmbs; + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here!= NULL; + here = here->B3SOIDDnextInstance) + { + if (here->B3SOIDDmode >= 0) + { Gm = here->B3SOIDDgm; + Gmbs = here->B3SOIDDgmbs; + FwdSum = Gm + Gmbs; + RevSum = 0.0; + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgsb; + cgdb = here->B3SOIDDcgdb; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbsb; + cbdb = here->B3SOIDDcbdb; + + cdgb = here->B3SOIDDcdgb; + cdsb = here->B3SOIDDcdsb; + cddb = here->B3SOIDDcddb; + } + else + { Gm = -here->B3SOIDDgm; + Gmbs = -here->B3SOIDDgmbs; + FwdSum = 0.0; + RevSum = -Gm - Gmbs; + cggb = here->B3SOIDDcggb; + cgsb = here->B3SOIDDcgdb; + cgdb = here->B3SOIDDcgsb; + + cbgb = here->B3SOIDDcbgb; + cbsb = here->B3SOIDDcbdb; + cbdb = here->B3SOIDDcbsb; + + cdgb = -(here->B3SOIDDcdgb + cggb + cbgb); + cdsb = -(here->B3SOIDDcddb + cgsb + cbsb); + cddb = -(here->B3SOIDDcdsb + cgdb + cbdb); + } + gdpr=here->B3SOIDDdrainConductance; + gspr=here->B3SOIDDsourceConductance; + gds= here->B3SOIDDgds; + gbd= here->B3SOIDDgjdb; + gbs= here->B3SOIDDgjsb; +#ifdef BULKCODE + capbd= here->B3SOIDDcapbd; + capbs= here->B3SOIDDcapbs; +#endif + GSoverlapCap = here->B3SOIDDcgso; + GDoverlapCap = here->B3SOIDDcgdo; +#ifdef BULKCODE + GBoverlapCap = here->pParam->B3SOIDDcgbo; +#endif + + xcdgb = (cdgb - GDoverlapCap); + xcddb = (cddb + capbd + GDoverlapCap); + xcdsb = cdsb; + xcsgb = -(cggb + cbgb + cdgb + GSoverlapCap); + xcsdb = -(cgdb + cbdb + cddb); + xcssb = (capbs + GSoverlapCap - (cgsb+cbsb+cdsb)); + xcggb = (cggb + GDoverlapCap + GSoverlapCap + GBoverlapCap); + xcgdb = (cgdb - GDoverlapCap); + xcgsb = (cgsb - GSoverlapCap); + xcbgb = (cbgb - GBoverlapCap); + xcbdb = (cbdb - capbd); + xcbsb = (cbsb - capbs); + + + *(here->B3SOIDDGgPtr ) += xcggb * s->real; + *(here->B3SOIDDGgPtr +1) += xcggb * s->imag; + *(here->B3SOIDDBbPtr ) += (-xcbgb-xcbdb-xcbsb) * s->real; + *(here->B3SOIDDBbPtr +1) += (-xcbgb-xcbdb-xcbsb) * s->imag; + *(here->B3SOIDDDPdpPtr ) += xcddb * s->real; + *(here->B3SOIDDDPdpPtr +1) += xcddb * s->imag; + *(here->B3SOIDDSPspPtr ) += xcssb * s->real; + *(here->B3SOIDDSPspPtr +1) += xcssb * s->imag; + *(here->B3SOIDDGbPtr ) += (-xcggb-xcgdb-xcgsb) * s->real; + *(here->B3SOIDDGbPtr +1) += (-xcggb-xcgdb-xcgsb) * s->imag; + *(here->B3SOIDDGdpPtr ) += xcgdb * s->real; + *(here->B3SOIDDGdpPtr +1) += xcgdb * s->imag; + *(here->B3SOIDDGspPtr ) += xcgsb * s->real; + *(here->B3SOIDDGspPtr +1) += xcgsb * s->imag; + *(here->B3SOIDDBgPtr ) += xcbgb * s->real; + *(here->B3SOIDDBgPtr +1) += xcbgb * s->imag; + *(here->B3SOIDDBdpPtr ) += xcbdb * s->real; + *(here->B3SOIDDBdpPtr +1) += xcbdb * s->imag; + *(here->B3SOIDDBspPtr ) += xcbsb * s->real; + *(here->B3SOIDDBspPtr +1) += xcbsb * s->imag; + *(here->B3SOIDDDPgPtr ) += xcdgb * s->real; + *(here->B3SOIDDDPgPtr +1) += xcdgb * s->imag; + *(here->B3SOIDDDPbPtr ) += (-xcdgb-xcddb-xcdsb) * s->real; + *(here->B3SOIDDDPbPtr +1) += (-xcdgb-xcddb-xcdsb) * s->imag; + *(here->B3SOIDDDPspPtr ) += xcdsb * s->real; + *(here->B3SOIDDDPspPtr +1) += xcdsb * s->imag; + *(here->B3SOIDDSPgPtr ) += xcsgb * s->real; + *(here->B3SOIDDSPgPtr +1) += xcsgb * s->imag; + *(here->B3SOIDDSPbPtr ) += (-xcsgb-xcsdb-xcssb) * s->real; + *(here->B3SOIDDSPbPtr +1) += (-xcsgb-xcsdb-xcssb) * s->imag; + *(here->B3SOIDDSPdpPtr ) += xcsdb * s->real; + *(here->B3SOIDDSPdpPtr +1) += xcsdb * s->imag; + *(here->B3SOIDDDdPtr) += gdpr; + *(here->B3SOIDDSsPtr) += gspr; + *(here->B3SOIDDBbPtr) += gbd+gbs; + *(here->B3SOIDDDPdpPtr) += gdpr+gds+gbd+RevSum; + *(here->B3SOIDDSPspPtr) += gspr+gds+gbs+FwdSum; + *(here->B3SOIDDDdpPtr) -= gdpr; + *(here->B3SOIDDSspPtr) -= gspr; + *(here->B3SOIDDBdpPtr) -= gbd; + *(here->B3SOIDDBspPtr) -= gbs; + *(here->B3SOIDDDPdPtr) -= gdpr; + *(here->B3SOIDDDPgPtr) += Gm; + *(here->B3SOIDDDPbPtr) -= gbd - Gmbs; + *(here->B3SOIDDDPspPtr) -= gds + FwdSum; + *(here->B3SOIDDSPgPtr) -= Gm; + *(here->B3SOIDDSPsPtr) -= gspr; + *(here->B3SOIDDSPbPtr) -= gbs + Gmbs; + *(here->B3SOIDDSPdpPtr) -= gds + RevSum; + + } + } + return(OK); +} + + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddset.c b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c new file mode 100644 index 000000000..5e032490d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c @@ -0,0 +1,1353 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddset.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soidddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define SMOOTHFACTOR 0.1 +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define Charge_q 1.60219e-19 +#define Meter2Micron 1.0e6 + +int +B3SOIDDsetup(matrix,inModel,ckt,states) +register SMPmatrix *matrix; +register GENmodel *inModel; +register CKTcircuit *ckt; +int *states; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; +int error; +CKTnode *tmp; + +double tmp1, tmp2; +double nfb0, Cboxt; +int itmp1; + + /* loop through all the B3SOIDD device models */ + for( ; model != NULL; model = model->B3SOIDDnextModel ) + { +/* Default value Processing for B3SOIDD MOSFET Models */ + + if (!model->B3SOIDDtypeGiven) + model->B3SOIDDtype = NMOS; + if (!model->B3SOIDDmobModGiven) + model->B3SOIDDmobMod = 1; + if (!model->B3SOIDDbinUnitGiven) + model->B3SOIDDbinUnit = 1; + if (!model->B3SOIDDparamChkGiven) + model->B3SOIDDparamChk = 0; + if (!model->B3SOIDDcapModGiven) + model->B3SOIDDcapMod = 2; + if (!model->B3SOIDDnoiModGiven) + model->B3SOIDDnoiMod = 1; + if (!model->B3SOIDDshModGiven) + model->B3SOIDDshMod = 0; + if (!model->B3SOIDDversionGiven) + model->B3SOIDDversion = 2.0; + if (!model->B3SOIDDtoxGiven) + model->B3SOIDDtox = 100.0e-10; + model->B3SOIDDcox = 3.453133e-11 / model->B3SOIDDtox; + + if (!model->B3SOIDDcdscGiven) + model->B3SOIDDcdsc = 2.4e-4; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcdscbGiven) + model->B3SOIDDcdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcdscdGiven) + model->B3SOIDDcdscd = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDcitGiven) + model->B3SOIDDcit = 0.0; /* unit Q/V/m^2 */ + if (!model->B3SOIDDnfactorGiven) + model->B3SOIDDnfactor = 1; + if (!model->B3SOIDDvsatGiven) + model->B3SOIDDvsat = 8.0e4; /* unit m/s */ + if (!model->B3SOIDDatGiven) + model->B3SOIDDat = 3.3e4; /* unit m/s */ + if (!model->B3SOIDDa0Given) + model->B3SOIDDa0 = 1.0; + if (!model->B3SOIDDagsGiven) + model->B3SOIDDags = 0.0; + if (!model->B3SOIDDa1Given) + model->B3SOIDDa1 = 0.0; + if (!model->B3SOIDDa2Given) + model->B3SOIDDa2 = 1.0; + if (!model->B3SOIDDketaGiven) + model->B3SOIDDketa = -0.6; /* unit / V */ + if (!model->B3SOIDDnsubGiven) + model->B3SOIDDnsub = 6.0e16; /* unit 1/cm3 */ + if (!model->B3SOIDDnpeakGiven) + model->B3SOIDDnpeak = 1.7e17; /* unit 1/cm3 */ + if (!model->B3SOIDDngateGiven) + model->B3SOIDDngate = 0; /* unit 1/cm3 */ + if (!model->B3SOIDDvbmGiven) + model->B3SOIDDvbm = -3.0; + if (!model->B3SOIDDxtGiven) + model->B3SOIDDxt = 1.55e-7; + if (!model->B3SOIDDkt1Given) + model->B3SOIDDkt1 = -0.11; /* unit V */ + if (!model->B3SOIDDkt1lGiven) + model->B3SOIDDkt1l = 0.0; /* unit V*m */ + if (!model->B3SOIDDkt2Given) + model->B3SOIDDkt2 = 0.022; /* No unit */ + if (!model->B3SOIDDk3Given) + model->B3SOIDDk3 = 0.0; + if (!model->B3SOIDDk3bGiven) + model->B3SOIDDk3b = 0.0; + if (!model->B3SOIDDw0Given) + model->B3SOIDDw0 = 2.5e-6; + if (!model->B3SOIDDnlxGiven) + model->B3SOIDDnlx = 1.74e-7; + if (!model->B3SOIDDdvt0Given) + model->B3SOIDDdvt0 = 2.2; + if (!model->B3SOIDDdvt1Given) + model->B3SOIDDdvt1 = 0.53; + if (!model->B3SOIDDdvt2Given) + model->B3SOIDDdvt2 = -0.032; /* unit 1 / V */ + + if (!model->B3SOIDDdvt0wGiven) + model->B3SOIDDdvt0w = 0.0; + if (!model->B3SOIDDdvt1wGiven) + model->B3SOIDDdvt1w = 5.3e6; + if (!model->B3SOIDDdvt2wGiven) + model->B3SOIDDdvt2w = -0.032; + + if (!model->B3SOIDDdroutGiven) + model->B3SOIDDdrout = 0.56; + if (!model->B3SOIDDdsubGiven) + model->B3SOIDDdsub = model->B3SOIDDdrout; + if (!model->B3SOIDDvth0Given) + model->B3SOIDDvth0 = (model->B3SOIDDtype == NMOS) ? 0.7 : -0.7; + if (!model->B3SOIDDuaGiven) + model->B3SOIDDua = 2.25e-9; /* unit m/V */ + if (!model->B3SOIDDua1Given) + model->B3SOIDDua1 = 4.31e-9; /* unit m/V */ + if (!model->B3SOIDDubGiven) + model->B3SOIDDub = 5.87e-19; /* unit (m/V)**2 */ + if (!model->B3SOIDDub1Given) + model->B3SOIDDub1 = -7.61e-18; /* unit (m/V)**2 */ + if (!model->B3SOIDDucGiven) + model->B3SOIDDuc = (model->B3SOIDDmobMod == 3) ? -0.0465 : -0.0465e-9; + if (!model->B3SOIDDuc1Given) + model->B3SOIDDuc1 = (model->B3SOIDDmobMod == 3) ? -0.056 : -0.056e-9; + if (!model->B3SOIDDu0Given) + model->B3SOIDDu0 = (model->B3SOIDDtype == NMOS) ? 0.067 : 0.025; + if (!model->B3SOIDDuteGiven) + model->B3SOIDDute = -1.5; + if (!model->B3SOIDDvoffGiven) + model->B3SOIDDvoff = -0.08; + if (!model->B3SOIDDdeltaGiven) + model->B3SOIDDdelta = 0.01; + if (!model->B3SOIDDrdswGiven) + model->B3SOIDDrdsw = 100; + if (!model->B3SOIDDprwgGiven) + model->B3SOIDDprwg = 0.0; /* unit 1/V */ + if (!model->B3SOIDDprwbGiven) + model->B3SOIDDprwb = 0.0; + if (!model->B3SOIDDprtGiven) + if (!model->B3SOIDDprtGiven) + model->B3SOIDDprt = 0.0; + if (!model->B3SOIDDeta0Given) + model->B3SOIDDeta0 = 0.08; /* no unit */ + if (!model->B3SOIDDetabGiven) + model->B3SOIDDetab = -0.07; /* unit 1/V */ + if (!model->B3SOIDDpclmGiven) + model->B3SOIDDpclm = 1.3; /* no unit */ + if (!model->B3SOIDDpdibl1Given) + model->B3SOIDDpdibl1 = .39; /* no unit */ + if (!model->B3SOIDDpdibl2Given) + model->B3SOIDDpdibl2 = 0.0086; /* no unit */ + if (!model->B3SOIDDpdiblbGiven) + model->B3SOIDDpdiblb = 0.0; /* 1/V */ + if (!model->B3SOIDDpvagGiven) + model->B3SOIDDpvag = 0.0; + if (!model->B3SOIDDwrGiven) + model->B3SOIDDwr = 1.0; + if (!model->B3SOIDDdwgGiven) + model->B3SOIDDdwg = 0.0; + if (!model->B3SOIDDdwbGiven) + model->B3SOIDDdwb = 0.0; + if (!model->B3SOIDDb0Given) + model->B3SOIDDb0 = 0.0; + if (!model->B3SOIDDb1Given) + model->B3SOIDDb1 = 0.0; + if (!model->B3SOIDDalpha0Given) + model->B3SOIDDalpha0 = 0.0; + if (!model->B3SOIDDalpha1Given) + model->B3SOIDDalpha1 = 1.0; + if (!model->B3SOIDDbeta0Given) + model->B3SOIDDbeta0 = 30.0; + + if (!model->B3SOIDDcgslGiven) + model->B3SOIDDcgsl = 0.0; + if (!model->B3SOIDDcgdlGiven) + model->B3SOIDDcgdl = 0.0; + if (!model->B3SOIDDckappaGiven) + model->B3SOIDDckappa = 0.6; + if (!model->B3SOIDDclcGiven) + model->B3SOIDDclc = 0.1e-7; + if (!model->B3SOIDDcleGiven) + model->B3SOIDDcle = 0.0; + if (!model->B3SOIDDtboxGiven) + model->B3SOIDDtbox = 3e-7; + if (!model->B3SOIDDtsiGiven) + model->B3SOIDDtsi = 1e-7; + if (!model->B3SOIDDxjGiven) + model->B3SOIDDxj = model->B3SOIDDtsi; + if (!model->B3SOIDDkb1Given) + model->B3SOIDDkb1 = 1; + if (!model->B3SOIDDkb3Given) + model->B3SOIDDkb3 = 1; + if (!model->B3SOIDDdvbd0Given) + model->B3SOIDDdvbd0 = 0.0; + if (!model->B3SOIDDdvbd1Given) + model->B3SOIDDdvbd1 = 0.0; + if (!model->B3SOIDDvbsaGiven) + model->B3SOIDDvbsa = 0.0; + if (!model->B3SOIDDdelpGiven) + model->B3SOIDDdelp = 0.02; + if (!model->B3SOIDDrbodyGiven) + model->B3SOIDDrbody = 0.0; + if (!model->B3SOIDDrbshGiven) + model->B3SOIDDrbsh = 0.0; + if (!model->B3SOIDDadice0Given) + model->B3SOIDDadice0 = 1; + if (!model->B3SOIDDabpGiven) + model->B3SOIDDabp = 1; + if (!model->B3SOIDDmxcGiven) + model->B3SOIDDmxc = -0.9; + if (!model->B3SOIDDrth0Given) + model->B3SOIDDrth0 = 0; + if (!model->B3SOIDDcth0Given) + model->B3SOIDDcth0 = 0; + + if (!model->B3SOIDDaiiGiven) + model->B3SOIDDaii = 0.0; + if (!model->B3SOIDDbiiGiven) + model->B3SOIDDbii = 0.0; + if (!model->B3SOIDDciiGiven) + model->B3SOIDDcii = 0.0; + if (!model->B3SOIDDdiiGiven) + model->B3SOIDDdii = -1.0; + if (!model->B3SOIDDagidlGiven) + model->B3SOIDDagidl = 0.0; + if (!model->B3SOIDDbgidlGiven) + model->B3SOIDDbgidl = 0.0; + if (!model->B3SOIDDngidlGiven) + model->B3SOIDDngidl = 1.2; + if (!model->B3SOIDDndiodeGiven) + model->B3SOIDDndiode = 1.0; + if (!model->B3SOIDDntunGiven) + model->B3SOIDDntun = 10.0; + if (!model->B3SOIDDisbjtGiven) + model->B3SOIDDisbjt = 1e-6; + if (!model->B3SOIDDisdifGiven) + model->B3SOIDDisdif = 0.0; + if (!model->B3SOIDDisrecGiven) + model->B3SOIDDisrec = 1e-5; + if (!model->B3SOIDDistunGiven) + model->B3SOIDDistun = 0.0; + if (!model->B3SOIDDxbjtGiven) + model->B3SOIDDxbjt = 2; + if (!model->B3SOIDDxdifGiven) + model->B3SOIDDxdif = 2; + if (!model->B3SOIDDxrecGiven) + model->B3SOIDDxrec = 20; + if (!model->B3SOIDDxtunGiven) + model->B3SOIDDxtun = 0; + if (!model->B3SOIDDedlGiven) + model->B3SOIDDedl = 2e-6; + if (!model->B3SOIDDkbjt1Given) + model->B3SOIDDkbjt1 = 0; + if (!model->B3SOIDDttGiven) + model->B3SOIDDtt = 1e-12; + if (!model->B3SOIDDasdGiven) + model->B3SOIDDasd = 0.3; + + /* unit degree celcius */ + if (!model->B3SOIDDtnomGiven) + model->B3SOIDDtnom = ckt->CKTnomTemp; + if (!model->B3SOIDDLintGiven) + model->B3SOIDDLint = 0.0; + if (!model->B3SOIDDLlGiven) + model->B3SOIDDLl = 0.0; + if (!model->B3SOIDDLlnGiven) + model->B3SOIDDLln = 1.0; + if (!model->B3SOIDDLwGiven) + model->B3SOIDDLw = 0.0; + if (!model->B3SOIDDLwnGiven) + model->B3SOIDDLwn = 1.0; + if (!model->B3SOIDDLwlGiven) + model->B3SOIDDLwl = 0.0; + if (!model->B3SOIDDLminGiven) + model->B3SOIDDLmin = 0.0; + if (!model->B3SOIDDLmaxGiven) + model->B3SOIDDLmax = 1.0; + if (!model->B3SOIDDWintGiven) + model->B3SOIDDWint = 0.0; + if (!model->B3SOIDDWlGiven) + model->B3SOIDDWl = 0.0; + if (!model->B3SOIDDWlnGiven) + model->B3SOIDDWln = 1.0; + if (!model->B3SOIDDWwGiven) + model->B3SOIDDWw = 0.0; + if (!model->B3SOIDDWwnGiven) + model->B3SOIDDWwn = 1.0; + if (!model->B3SOIDDWwlGiven) + model->B3SOIDDWwl = 0.0; + if (!model->B3SOIDDWminGiven) + model->B3SOIDDWmin = 0.0; + if (!model->B3SOIDDWmaxGiven) + model->B3SOIDDWmax = 1.0; + if (!model->B3SOIDDdwcGiven) + model->B3SOIDDdwc = model->B3SOIDDWint; + if (!model->B3SOIDDdlcGiven) + model->B3SOIDDdlc = model->B3SOIDDLint; + +/* Added for binning - START */ + /* Length dependence */ + if (!model->B3SOIDDlnpeakGiven) + model->B3SOIDDlnpeak = 0.0; + if (!model->B3SOIDDlnsubGiven) + model->B3SOIDDlnsub = 0.0; + if (!model->B3SOIDDlngateGiven) + model->B3SOIDDlngate = 0.0; + if (!model->B3SOIDDlvth0Given) + model->B3SOIDDlvth0 = 0.0; + if (!model->B3SOIDDlk1Given) + model->B3SOIDDlk1 = 0.0; + if (!model->B3SOIDDlk2Given) + model->B3SOIDDlk2 = 0.0; + if (!model->B3SOIDDlk3Given) + model->B3SOIDDlk3 = 0.0; + if (!model->B3SOIDDlk3bGiven) + model->B3SOIDDlk3b = 0.0; + if (!model->B3SOIDDlvbsaGiven) + model->B3SOIDDlvbsa = 0.0; + if (!model->B3SOIDDldelpGiven) + model->B3SOIDDldelp = 0.0; + if (!model->B3SOIDDlkb1Given) + model->B3SOIDDlkb1 = 0.0; + if (!model->B3SOIDDlkb3Given) + model->B3SOIDDlkb3 = 1.0; + if (!model->B3SOIDDldvbd0Given) + model->B3SOIDDldvbd0 = 1.0; + if (!model->B3SOIDDldvbd1Given) + model->B3SOIDDldvbd1 = 1.0; + if (!model->B3SOIDDlw0Given) + model->B3SOIDDlw0 = 0.0; + if (!model->B3SOIDDlnlxGiven) + model->B3SOIDDlnlx = 0.0; + if (!model->B3SOIDDldvt0Given) + model->B3SOIDDldvt0 = 0.0; + if (!model->B3SOIDDldvt1Given) + model->B3SOIDDldvt1 = 0.0; + if (!model->B3SOIDDldvt2Given) + model->B3SOIDDldvt2 = 0.0; + if (!model->B3SOIDDldvt0wGiven) + model->B3SOIDDldvt0w = 0.0; + if (!model->B3SOIDDldvt1wGiven) + model->B3SOIDDldvt1w = 0.0; + if (!model->B3SOIDDldvt2wGiven) + model->B3SOIDDldvt2w = 0.0; + if (!model->B3SOIDDlu0Given) + model->B3SOIDDlu0 = 0.0; + if (!model->B3SOIDDluaGiven) + model->B3SOIDDlua = 0.0; + if (!model->B3SOIDDlubGiven) + model->B3SOIDDlub = 0.0; + if (!model->B3SOIDDlucGiven) + model->B3SOIDDluc = 0.0; + if (!model->B3SOIDDlvsatGiven) + model->B3SOIDDlvsat = 0.0; + if (!model->B3SOIDDla0Given) + model->B3SOIDDla0 = 0.0; + if (!model->B3SOIDDlagsGiven) + model->B3SOIDDlags = 0.0; + if (!model->B3SOIDDlb0Given) + model->B3SOIDDlb0 = 0.0; + if (!model->B3SOIDDlb1Given) + model->B3SOIDDlb1 = 0.0; + if (!model->B3SOIDDlketaGiven) + model->B3SOIDDlketa = 0.0; + if (!model->B3SOIDDlabpGiven) + model->B3SOIDDlabp = 0.0; + if (!model->B3SOIDDlmxcGiven) + model->B3SOIDDlmxc = 0.0; + if (!model->B3SOIDDladice0Given) + model->B3SOIDDladice0 = 0.0; + if (!model->B3SOIDDla1Given) + model->B3SOIDDla1 = 0.0; + if (!model->B3SOIDDla2Given) + model->B3SOIDDla2 = 0.0; + if (!model->B3SOIDDlrdswGiven) + model->B3SOIDDlrdsw = 0.0; + if (!model->B3SOIDDlprwbGiven) + model->B3SOIDDlprwb = 0.0; + if (!model->B3SOIDDlprwgGiven) + model->B3SOIDDlprwg = 0.0; + if (!model->B3SOIDDlwrGiven) + model->B3SOIDDlwr = 0.0; + if (!model->B3SOIDDlnfactorGiven) + model->B3SOIDDlnfactor = 0.0; + if (!model->B3SOIDDldwgGiven) + model->B3SOIDDldwg = 0.0; + if (!model->B3SOIDDldwbGiven) + model->B3SOIDDldwb = 0.0; + if (!model->B3SOIDDlvoffGiven) + model->B3SOIDDlvoff = 0.0; + if (!model->B3SOIDDleta0Given) + model->B3SOIDDleta0 = 0.0; + if (!model->B3SOIDDletabGiven) + model->B3SOIDDletab = 0.0; + if (!model->B3SOIDDldsubGiven) + model->B3SOIDDldsub = 0.0; + if (!model->B3SOIDDlcitGiven) + model->B3SOIDDlcit = 0.0; + if (!model->B3SOIDDlcdscGiven) + model->B3SOIDDlcdsc = 0.0; + if (!model->B3SOIDDlcdscbGiven) + model->B3SOIDDlcdscb = 0.0; + if (!model->B3SOIDDlcdscdGiven) + model->B3SOIDDlcdscd = 0.0; + if (!model->B3SOIDDlpclmGiven) + model->B3SOIDDlpclm = 0.0; + if (!model->B3SOIDDlpdibl1Given) + model->B3SOIDDlpdibl1 = 0.0; + if (!model->B3SOIDDlpdibl2Given) + model->B3SOIDDlpdibl2 = 0.0; + if (!model->B3SOIDDlpdiblbGiven) + model->B3SOIDDlpdiblb = 0.0; + if (!model->B3SOIDDldroutGiven) + model->B3SOIDDldrout = 0.0; + if (!model->B3SOIDDlpvagGiven) + model->B3SOIDDlpvag = 0.0; + if (!model->B3SOIDDldeltaGiven) + model->B3SOIDDldelta = 0.0; + if (!model->B3SOIDDlaiiGiven) + model->B3SOIDDlaii = 0.0; + if (!model->B3SOIDDlbiiGiven) + model->B3SOIDDlbii = 0.0; + if (!model->B3SOIDDlciiGiven) + model->B3SOIDDlcii = 0.0; + if (!model->B3SOIDDldiiGiven) + model->B3SOIDDldii = 0.0; + if (!model->B3SOIDDlalpha0Given) + model->B3SOIDDlalpha0 = 0.0; + if (!model->B3SOIDDlalpha1Given) + model->B3SOIDDlalpha1 = 0.0; + if (!model->B3SOIDDlbeta0Given) + model->B3SOIDDlbeta0 = 0.0; + if (!model->B3SOIDDlagidlGiven) + model->B3SOIDDlagidl = 0.0; + if (!model->B3SOIDDlbgidlGiven) + model->B3SOIDDlbgidl = 0.0; + if (!model->B3SOIDDlngidlGiven) + model->B3SOIDDlngidl = 0.0; + if (!model->B3SOIDDlntunGiven) + model->B3SOIDDlntun = 0.0; + if (!model->B3SOIDDlndiodeGiven) + model->B3SOIDDlndiode = 0.0; + if (!model->B3SOIDDlisbjtGiven) + model->B3SOIDDlisbjt = 0.0; + if (!model->B3SOIDDlisdifGiven) + model->B3SOIDDlisdif = 0.0; + if (!model->B3SOIDDlisrecGiven) + model->B3SOIDDlisrec = 0.0; + if (!model->B3SOIDDlistunGiven) + model->B3SOIDDlistun = 0.0; + if (!model->B3SOIDDledlGiven) + model->B3SOIDDledl = 0.0; + if (!model->B3SOIDDlkbjt1Given) + model->B3SOIDDlkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDlvsdfbGiven) + model->B3SOIDDlvsdfb = 0.0; + if (!model->B3SOIDDlvsdthGiven) + model->B3SOIDDlvsdth = 0.0; + /* Width dependence */ + if (!model->B3SOIDDwnpeakGiven) + model->B3SOIDDwnpeak = 0.0; + if (!model->B3SOIDDwnsubGiven) + model->B3SOIDDwnsub = 0.0; + if (!model->B3SOIDDwngateGiven) + model->B3SOIDDwngate = 0.0; + if (!model->B3SOIDDwvth0Given) + model->B3SOIDDwvth0 = 0.0; + if (!model->B3SOIDDwk1Given) + model->B3SOIDDwk1 = 0.0; + if (!model->B3SOIDDwk2Given) + model->B3SOIDDwk2 = 0.0; + if (!model->B3SOIDDwk3Given) + model->B3SOIDDwk3 = 0.0; + if (!model->B3SOIDDwk3bGiven) + model->B3SOIDDwk3b = 0.0; + if (!model->B3SOIDDwvbsaGiven) + model->B3SOIDDwvbsa = 0.0; + if (!model->B3SOIDDwdelpGiven) + model->B3SOIDDwdelp = 0.0; + if (!model->B3SOIDDwkb1Given) + model->B3SOIDDwkb1 = 0.0; + if (!model->B3SOIDDwkb3Given) + model->B3SOIDDwkb3 = 1.0; + if (!model->B3SOIDDwdvbd0Given) + model->B3SOIDDwdvbd0 = 1.0; + if (!model->B3SOIDDwdvbd1Given) + model->B3SOIDDwdvbd1 = 1.0; + if (!model->B3SOIDDww0Given) + model->B3SOIDDww0 = 0.0; + if (!model->B3SOIDDwnlxGiven) + model->B3SOIDDwnlx = 0.0; + if (!model->B3SOIDDwdvt0Given) + model->B3SOIDDwdvt0 = 0.0; + if (!model->B3SOIDDwdvt1Given) + model->B3SOIDDwdvt1 = 0.0; + if (!model->B3SOIDDwdvt2Given) + model->B3SOIDDwdvt2 = 0.0; + if (!model->B3SOIDDwdvt0wGiven) + model->B3SOIDDwdvt0w = 0.0; + if (!model->B3SOIDDwdvt1wGiven) + model->B3SOIDDwdvt1w = 0.0; + if (!model->B3SOIDDwdvt2wGiven) + model->B3SOIDDwdvt2w = 0.0; + if (!model->B3SOIDDwu0Given) + model->B3SOIDDwu0 = 0.0; + if (!model->B3SOIDDwuaGiven) + model->B3SOIDDwua = 0.0; + if (!model->B3SOIDDwubGiven) + model->B3SOIDDwub = 0.0; + if (!model->B3SOIDDwucGiven) + model->B3SOIDDwuc = 0.0; + if (!model->B3SOIDDwvsatGiven) + model->B3SOIDDwvsat = 0.0; + if (!model->B3SOIDDwa0Given) + model->B3SOIDDwa0 = 0.0; + if (!model->B3SOIDDwagsGiven) + model->B3SOIDDwags = 0.0; + if (!model->B3SOIDDwb0Given) + model->B3SOIDDwb0 = 0.0; + if (!model->B3SOIDDwb1Given) + model->B3SOIDDwb1 = 0.0; + if (!model->B3SOIDDwketaGiven) + model->B3SOIDDwketa = 0.0; + if (!model->B3SOIDDwabpGiven) + model->B3SOIDDwabp = 0.0; + if (!model->B3SOIDDwmxcGiven) + model->B3SOIDDwmxc = 0.0; + if (!model->B3SOIDDwadice0Given) + model->B3SOIDDwadice0 = 0.0; + if (!model->B3SOIDDwa1Given) + model->B3SOIDDwa1 = 0.0; + if (!model->B3SOIDDwa2Given) + model->B3SOIDDwa2 = 0.0; + if (!model->B3SOIDDwrdswGiven) + model->B3SOIDDwrdsw = 0.0; + if (!model->B3SOIDDwprwbGiven) + model->B3SOIDDwprwb = 0.0; + if (!model->B3SOIDDwprwgGiven) + model->B3SOIDDwprwg = 0.0; + if (!model->B3SOIDDwwrGiven) + model->B3SOIDDwwr = 0.0; + if (!model->B3SOIDDwnfactorGiven) + model->B3SOIDDwnfactor = 0.0; + if (!model->B3SOIDDwdwgGiven) + model->B3SOIDDwdwg = 0.0; + if (!model->B3SOIDDwdwbGiven) + model->B3SOIDDwdwb = 0.0; + if (!model->B3SOIDDwvoffGiven) + model->B3SOIDDwvoff = 0.0; + if (!model->B3SOIDDweta0Given) + model->B3SOIDDweta0 = 0.0; + if (!model->B3SOIDDwetabGiven) + model->B3SOIDDwetab = 0.0; + if (!model->B3SOIDDwdsubGiven) + model->B3SOIDDwdsub = 0.0; + if (!model->B3SOIDDwcitGiven) + model->B3SOIDDwcit = 0.0; + if (!model->B3SOIDDwcdscGiven) + model->B3SOIDDwcdsc = 0.0; + if (!model->B3SOIDDwcdscbGiven) + model->B3SOIDDwcdscb = 0.0; + if (!model->B3SOIDDwcdscdGiven) + model->B3SOIDDwcdscd = 0.0; + if (!model->B3SOIDDwpclmGiven) + model->B3SOIDDwpclm = 0.0; + if (!model->B3SOIDDwpdibl1Given) + model->B3SOIDDwpdibl1 = 0.0; + if (!model->B3SOIDDwpdibl2Given) + model->B3SOIDDwpdibl2 = 0.0; + if (!model->B3SOIDDwpdiblbGiven) + model->B3SOIDDwpdiblb = 0.0; + if (!model->B3SOIDDwdroutGiven) + model->B3SOIDDwdrout = 0.0; + if (!model->B3SOIDDwpvagGiven) + model->B3SOIDDwpvag = 0.0; + if (!model->B3SOIDDwdeltaGiven) + model->B3SOIDDwdelta = 0.0; + if (!model->B3SOIDDwaiiGiven) + model->B3SOIDDwaii = 0.0; + if (!model->B3SOIDDwbiiGiven) + model->B3SOIDDwbii = 0.0; + if (!model->B3SOIDDwciiGiven) + model->B3SOIDDwcii = 0.0; + if (!model->B3SOIDDwdiiGiven) + model->B3SOIDDwdii = 0.0; + if (!model->B3SOIDDwalpha0Given) + model->B3SOIDDwalpha0 = 0.0; + if (!model->B3SOIDDwalpha1Given) + model->B3SOIDDwalpha1 = 0.0; + if (!model->B3SOIDDwbeta0Given) + model->B3SOIDDwbeta0 = 0.0; + if (!model->B3SOIDDwagidlGiven) + model->B3SOIDDwagidl = 0.0; + if (!model->B3SOIDDwbgidlGiven) + model->B3SOIDDwbgidl = 0.0; + if (!model->B3SOIDDwngidlGiven) + model->B3SOIDDwngidl = 0.0; + if (!model->B3SOIDDwntunGiven) + model->B3SOIDDwntun = 0.0; + if (!model->B3SOIDDwndiodeGiven) + model->B3SOIDDwndiode = 0.0; + if (!model->B3SOIDDwisbjtGiven) + model->B3SOIDDwisbjt = 0.0; + if (!model->B3SOIDDwisdifGiven) + model->B3SOIDDwisdif = 0.0; + if (!model->B3SOIDDwisrecGiven) + model->B3SOIDDwisrec = 0.0; + if (!model->B3SOIDDwistunGiven) + model->B3SOIDDwistun = 0.0; + if (!model->B3SOIDDwedlGiven) + model->B3SOIDDwedl = 0.0; + if (!model->B3SOIDDwkbjt1Given) + model->B3SOIDDwkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDwvsdfbGiven) + model->B3SOIDDwvsdfb = 0.0; + if (!model->B3SOIDDwvsdthGiven) + model->B3SOIDDwvsdth = 0.0; + /* Cross-term dependence */ + if (!model->B3SOIDDpnpeakGiven) + model->B3SOIDDpnpeak = 0.0; + if (!model->B3SOIDDpnsubGiven) + model->B3SOIDDpnsub = 0.0; + if (!model->B3SOIDDpngateGiven) + model->B3SOIDDpngate = 0.0; + if (!model->B3SOIDDpvth0Given) + model->B3SOIDDpvth0 = 0.0; + if (!model->B3SOIDDpk1Given) + model->B3SOIDDpk1 = 0.0; + if (!model->B3SOIDDpk2Given) + model->B3SOIDDpk2 = 0.0; + if (!model->B3SOIDDpk3Given) + model->B3SOIDDpk3 = 0.0; + if (!model->B3SOIDDpk3bGiven) + model->B3SOIDDpk3b = 0.0; + if (!model->B3SOIDDpvbsaGiven) + model->B3SOIDDpvbsa = 0.0; + if (!model->B3SOIDDpdelpGiven) + model->B3SOIDDpdelp = 0.0; + if (!model->B3SOIDDpkb1Given) + model->B3SOIDDpkb1 = 0.0; + if (!model->B3SOIDDpkb3Given) + model->B3SOIDDpkb3 = 1.0; + if (!model->B3SOIDDpdvbd0Given) + model->B3SOIDDpdvbd0 = 1.0; + if (!model->B3SOIDDpdvbd1Given) + model->B3SOIDDpdvbd1 = 1.0; + if (!model->B3SOIDDpw0Given) + model->B3SOIDDpw0 = 0.0; + if (!model->B3SOIDDpnlxGiven) + model->B3SOIDDpnlx = 0.0; + if (!model->B3SOIDDpdvt0Given) + model->B3SOIDDpdvt0 = 0.0; + if (!model->B3SOIDDpdvt1Given) + model->B3SOIDDpdvt1 = 0.0; + if (!model->B3SOIDDpdvt2Given) + model->B3SOIDDpdvt2 = 0.0; + if (!model->B3SOIDDpdvt0wGiven) + model->B3SOIDDpdvt0w = 0.0; + if (!model->B3SOIDDpdvt1wGiven) + model->B3SOIDDpdvt1w = 0.0; + if (!model->B3SOIDDpdvt2wGiven) + model->B3SOIDDpdvt2w = 0.0; + if (!model->B3SOIDDpu0Given) + model->B3SOIDDpu0 = 0.0; + if (!model->B3SOIDDpuaGiven) + model->B3SOIDDpua = 0.0; + if (!model->B3SOIDDpubGiven) + model->B3SOIDDpub = 0.0; + if (!model->B3SOIDDpucGiven) + model->B3SOIDDpuc = 0.0; + if (!model->B3SOIDDpvsatGiven) + model->B3SOIDDpvsat = 0.0; + if (!model->B3SOIDDpa0Given) + model->B3SOIDDpa0 = 0.0; + if (!model->B3SOIDDpagsGiven) + model->B3SOIDDpags = 0.0; + if (!model->B3SOIDDpb0Given) + model->B3SOIDDpb0 = 0.0; + if (!model->B3SOIDDpb1Given) + model->B3SOIDDpb1 = 0.0; + if (!model->B3SOIDDpketaGiven) + model->B3SOIDDpketa = 0.0; + if (!model->B3SOIDDpabpGiven) + model->B3SOIDDpabp = 0.0; + if (!model->B3SOIDDpmxcGiven) + model->B3SOIDDpmxc = 0.0; + if (!model->B3SOIDDpadice0Given) + model->B3SOIDDpadice0 = 0.0; + if (!model->B3SOIDDpa1Given) + model->B3SOIDDpa1 = 0.0; + if (!model->B3SOIDDpa2Given) + model->B3SOIDDpa2 = 0.0; + if (!model->B3SOIDDprdswGiven) + model->B3SOIDDprdsw = 0.0; + if (!model->B3SOIDDpprwbGiven) + model->B3SOIDDpprwb = 0.0; + if (!model->B3SOIDDpprwgGiven) + model->B3SOIDDpprwg = 0.0; + if (!model->B3SOIDDpwrGiven) + model->B3SOIDDpwr = 0.0; + if (!model->B3SOIDDpnfactorGiven) + model->B3SOIDDpnfactor = 0.0; + if (!model->B3SOIDDpdwgGiven) + model->B3SOIDDpdwg = 0.0; + if (!model->B3SOIDDpdwbGiven) + model->B3SOIDDpdwb = 0.0; + if (!model->B3SOIDDpvoffGiven) + model->B3SOIDDpvoff = 0.0; + if (!model->B3SOIDDpeta0Given) + model->B3SOIDDpeta0 = 0.0; + if (!model->B3SOIDDpetabGiven) + model->B3SOIDDpetab = 0.0; + if (!model->B3SOIDDpdsubGiven) + model->B3SOIDDpdsub = 0.0; + if (!model->B3SOIDDpcitGiven) + model->B3SOIDDpcit = 0.0; + if (!model->B3SOIDDpcdscGiven) + model->B3SOIDDpcdsc = 0.0; + if (!model->B3SOIDDpcdscbGiven) + model->B3SOIDDpcdscb = 0.0; + if (!model->B3SOIDDpcdscdGiven) + model->B3SOIDDpcdscd = 0.0; + if (!model->B3SOIDDppclmGiven) + model->B3SOIDDppclm = 0.0; + if (!model->B3SOIDDppdibl1Given) + model->B3SOIDDppdibl1 = 0.0; + if (!model->B3SOIDDppdibl2Given) + model->B3SOIDDppdibl2 = 0.0; + if (!model->B3SOIDDppdiblbGiven) + model->B3SOIDDppdiblb = 0.0; + if (!model->B3SOIDDpdroutGiven) + model->B3SOIDDpdrout = 0.0; + if (!model->B3SOIDDppvagGiven) + model->B3SOIDDppvag = 0.0; + if (!model->B3SOIDDpdeltaGiven) + model->B3SOIDDpdelta = 0.0; + if (!model->B3SOIDDpaiiGiven) + model->B3SOIDDpaii = 0.0; + if (!model->B3SOIDDpbiiGiven) + model->B3SOIDDpbii = 0.0; + if (!model->B3SOIDDpciiGiven) + model->B3SOIDDpcii = 0.0; + if (!model->B3SOIDDpdiiGiven) + model->B3SOIDDpdii = 0.0; + if (!model->B3SOIDDpalpha0Given) + model->B3SOIDDpalpha0 = 0.0; + if (!model->B3SOIDDpalpha1Given) + model->B3SOIDDpalpha1 = 0.0; + if (!model->B3SOIDDpbeta0Given) + model->B3SOIDDpbeta0 = 0.0; + if (!model->B3SOIDDpagidlGiven) + model->B3SOIDDpagidl = 0.0; + if (!model->B3SOIDDpbgidlGiven) + model->B3SOIDDpbgidl = 0.0; + if (!model->B3SOIDDpngidlGiven) + model->B3SOIDDpngidl = 0.0; + if (!model->B3SOIDDpntunGiven) + model->B3SOIDDpntun = 0.0; + if (!model->B3SOIDDpndiodeGiven) + model->B3SOIDDpndiode = 0.0; + if (!model->B3SOIDDpisbjtGiven) + model->B3SOIDDpisbjt = 0.0; + if (!model->B3SOIDDpisdifGiven) + model->B3SOIDDpisdif = 0.0; + if (!model->B3SOIDDpisrecGiven) + model->B3SOIDDpisrec = 0.0; + if (!model->B3SOIDDpistunGiven) + model->B3SOIDDpistun = 0.0; + if (!model->B3SOIDDpedlGiven) + model->B3SOIDDpedl = 0.0; + if (!model->B3SOIDDpkbjt1Given) + model->B3SOIDDpkbjt1 = 0.0; + /* CV Model */ + if (!model->B3SOIDDpvsdfbGiven) + model->B3SOIDDpvsdfb = 0.0; + if (!model->B3SOIDDpvsdthGiven) + model->B3SOIDDpvsdth = 0.0; +/* Added for binning - END */ + + if (!model->B3SOIDDcfGiven) + model->B3SOIDDcf = 2.0 * EPSOX / PI + * log(1.0 + 0.4e-6 / model->B3SOIDDtox); + if (!model->B3SOIDDcgdoGiven) + { if (model->B3SOIDDdlcGiven && (model->B3SOIDDdlc > 0.0)) + { model->B3SOIDDcgdo = model->B3SOIDDdlc * model->B3SOIDDcox + - model->B3SOIDDcgdl ; + } + else + model->B3SOIDDcgdo = 0.6 * model->B3SOIDDxj * model->B3SOIDDcox; + } + if (!model->B3SOIDDcgsoGiven) + { if (model->B3SOIDDdlcGiven && (model->B3SOIDDdlc > 0.0)) + { model->B3SOIDDcgso = model->B3SOIDDdlc * model->B3SOIDDcox + - model->B3SOIDDcgsl ; + } + else + model->B3SOIDDcgso = 0.6 * model->B3SOIDDxj * model->B3SOIDDcox; + } + + if (!model->B3SOIDDcgeoGiven) + { model->B3SOIDDcgeo = 0.0; + } + if (!model->B3SOIDDxpartGiven) + model->B3SOIDDxpart = 0.0; + if (!model->B3SOIDDsheetResistanceGiven) + model->B3SOIDDsheetResistance = 0.0; + if (!model->B3SOIDDcsdeswGiven) + model->B3SOIDDcsdesw = 0.0; + if (!model->B3SOIDDunitLengthGateSidewallJctCapGiven) + model->B3SOIDDunitLengthGateSidewallJctCap = 1e-10; + if (!model->B3SOIDDGatesidewallJctPotentialGiven) + model->B3SOIDDGatesidewallJctPotential = 0.7; + if (!model->B3SOIDDbodyJctGateSideGradingCoeffGiven) + model->B3SOIDDbodyJctGateSideGradingCoeff = 0.5; + if (!model->B3SOIDDoxideTrapDensityAGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityA = 1e20; + else + model->B3SOIDDoxideTrapDensityA=9.9e18; + } + if (!model->B3SOIDDoxideTrapDensityBGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityB = 5e4; + else + model->B3SOIDDoxideTrapDensityB = 2.4e3; + } + if (!model->B3SOIDDoxideTrapDensityCGiven) + { if (model->B3SOIDDtype == NMOS) + model->B3SOIDDoxideTrapDensityC = -1.4e-12; + else + model->B3SOIDDoxideTrapDensityC = 1.4e-12; + + } + if (!model->B3SOIDDemGiven) + model->B3SOIDDem = 4.1e7; /* V/m */ + if (!model->B3SOIDDefGiven) + model->B3SOIDDef = 1.0; + if (!model->B3SOIDDafGiven) + model->B3SOIDDaf = 1.0; + if (!model->B3SOIDDkfGiven) + model->B3SOIDDkf = 0.0; + if (!model->B3SOIDDnoifGiven) + model->B3SOIDDnoif = 1.0; + + /* loop through all the instances of the model */ + for (here = model->B3SOIDDinstances; here != NULL ; + here=here->B3SOIDDnextInstance) + { /* allocate a chunk of the state vector */ + here->B3SOIDDstates = *states; + *states += B3SOIDDnumStates; + /* perform the parameter defaulting */ + if (!here->B3SOIDDdrainAreaGiven) + here->B3SOIDDdrainArea = 0.0; + if (!here->B3SOIDDdrainPerimeterGiven) + here->B3SOIDDdrainPerimeter = 0.0; + if (!here->B3SOIDDdrainSquaresGiven) + here->B3SOIDDdrainSquares = 1.0; + if (!here->B3SOIDDicVBSGiven) + here->B3SOIDDicVBS = 0; + if (!here->B3SOIDDicVDSGiven) + here->B3SOIDDicVDS = 0; + if (!here->B3SOIDDicVGSGiven) + here->B3SOIDDicVGS = 0; + if (!here->B3SOIDDicVESGiven) + here->B3SOIDDicVES = 0; + if (!here->B3SOIDDicVPSGiven) + here->B3SOIDDicVPS = 0; + if (!here->B3SOIDDbjtoffGiven) + here->B3SOIDDbjtoff = 0; + if (!here->B3SOIDDdebugModGiven) + here->B3SOIDDdebugMod = 0; + if (!here->B3SOIDDrth0Given) + here->B3SOIDDrth0 = model->B3SOIDDrth0; + if (!here->B3SOIDDcth0Given) + here->B3SOIDDcth0 = model->B3SOIDDcth0; + if (!here->B3SOIDDbodySquaresGiven) + here->B3SOIDDbodySquares = 1.0; + if (!here->B3SOIDDlGiven) + here->B3SOIDDl = 5e-6; + if (!here->B3SOIDDsourceAreaGiven) + here->B3SOIDDsourceArea = 0; + if (!here->B3SOIDDsourcePerimeterGiven) + here->B3SOIDDsourcePerimeter = 0; + if (!here->B3SOIDDsourceSquaresGiven) + here->B3SOIDDsourceSquares = 1; + if (!here->B3SOIDDwGiven) + here->B3SOIDDw = 5e-6; + if (!here->B3SOIDDoffGiven) + here->B3SOIDDoff = 0; + + /* process drain series resistance */ + if ((model->B3SOIDDsheetResistance > 0.0) && + (here->B3SOIDDdrainSquares > 0.0 ) && + (here->B3SOIDDdNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"drain"); + if(error) return(error); + here->B3SOIDDdNodePrime = tmp->number; + } + else + { here->B3SOIDDdNodePrime = here->B3SOIDDdNode; + } + + /* process source series resistance */ + if ((model->B3SOIDDsheetResistance > 0.0) && + (here->B3SOIDDsourceSquares > 0.0 ) && + (here->B3SOIDDsNodePrime == 0)) + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"source"); + if(error) return(error); + here->B3SOIDDsNodePrime = tmp->number; + } + else + { here->B3SOIDDsNodePrime = here->B3SOIDDsNode; + } + + /* process effective silicon film thickness */ + model->B3SOIDDcbox = 3.453133e-11 / model->B3SOIDDtbox; + model->B3SOIDDcsi = 1.03594e-10 / model->B3SOIDDtsi; + Cboxt = model->B3SOIDDcbox * model->B3SOIDDcsi / (model->B3SOIDDcbox + model->B3SOIDDcsi); + model->B3SOIDDqsi = Charge_q*model->B3SOIDDnpeak*1e6*model->B3SOIDDtsi; + /* Tsieff */ + tmp1 = 2.0 * EPSSI * model->B3SOIDDvbsa / Charge_q + / (1e6*model->B3SOIDDnpeak); + tmp2 = model->B3SOIDDtsi * model->B3SOIDDtsi; + if (tmp2 < tmp1) + { + fprintf(stderr, "vbsa = %.3f is too large for this tsi = %.3e and is automatically set to zero\n", model->B3SOIDDvbsa, model->B3SOIDDtsi); + model->B3SOIDDcsieff = model->B3SOIDDcsi; + model->B3SOIDDqsieff = model->B3SOIDDqsi; + } + else + { + tmp1 = sqrt(model->B3SOIDDtsi * model->B3SOIDDtsi - + 2.0 * EPSSI * model->B3SOIDDvbsa / Charge_q / + (1e6*model->B3SOIDDnpeak)); + model->B3SOIDDcsieff = 1.03594e-10 / tmp1; + model->B3SOIDDqsieff = Charge_q*model->B3SOIDDnpeak*1e6*tmp1; + } + model->B3SOIDDcsit = 1/(1/model->B3SOIDDcox + 1/model->B3SOIDDcsieff); + model->B3SOIDDcboxt = 1/(1/model->B3SOIDDcbox + 1/model->B3SOIDDcsieff); + nfb0 = 1/(1 + model->B3SOIDDcbox / model->B3SOIDDcsit); + model->B3SOIDDnfb = model->B3SOIDDkb3 * nfb0; + model->B3SOIDDadice = model->B3SOIDDadice0 / ( 1 + Cboxt / model->B3SOIDDcox); + + here->B3SOIDDfloat = 0; + if (here->B3SOIDDbNode == -1) + /* no body contact but bNode to be created for SPICE iteration */ + { error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"Body"); + if(error) return(error); + here->B3SOIDDbNode = tmp->number; + here->B3SOIDDpNode = 0; + here->B3SOIDDfloat = 1; + here->B3SOIDDbodyMod = 0; + } + else /* if body tied */ + { /* ideal body tie */ + if ((model->B3SOIDDrbody == 0.0) && (model->B3SOIDDrbsh == 0.0)) + { + here->B3SOIDDbodyMod = 2; + /* pNode is not used in this case */ + } + else { + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Body"); + if(error) return(error); + here->B3SOIDDbodyMod = 1; + here->B3SOIDDpNode = here->B3SOIDDbNode; + here->B3SOIDDbNode = tmp->number; + } + } + + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0)) + { + error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"Temp"); + if(error) return(error); + here->B3SOIDDtempNode = tmp->number; + + } else { + here->B3SOIDDtempNode = 0; + } + +/* here for debugging purpose only */ + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + /* The real Vbs value */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs"); + if(error) return(error); + here->B3SOIDDvbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ids"); + if(error) return(error); + here->B3SOIDDidsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ic"); + if(error) return(error); + here->B3SOIDDicNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibs"); + if(error) return(error); + here->B3SOIDDibsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibd"); + if(error) return(error); + here->B3SOIDDibdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Iii"); + if(error) return(error); + here->B3SOIDDiiiNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Igidl"); + if(error) return(error); + here->B3SOIDDigidlNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Itun"); + if(error) return(error); + here->B3SOIDDitunNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Ibp"); + if(error) return(error); + here->B3SOIDDibpNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Abeff"); + if(error) return(error); + here->B3SOIDDabeffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs0eff"); + if(error) return(error); + here->B3SOIDDvbs0effNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbseff"); + if(error) return(error); + here->B3SOIDDvbseffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Xc"); + if(error) return(error); + here->B3SOIDDxcNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbb"); + if(error) return(error); + here->B3SOIDDcbbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbd"); + if(error) return(error); + here->B3SOIDDcbdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbg"); + if(error) return(error); + here->B3SOIDDcbgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qbody"); + if(error) return(error); + here->B3SOIDDqbNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qbf"); + if(error) return(error); + here->B3SOIDDqbfNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qjs"); + if(error) return(error); + here->B3SOIDDqjsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qjd"); + if(error) return(error); + here->B3SOIDDqjdNode = tmp->number; + + /* clean up last */ + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gm"); + if(error) return(error); + here->B3SOIDDgmNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gmbs"); + if(error) return(error); + here->B3SOIDDgmbsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gds"); + if(error) return(error); + here->B3SOIDDgdsNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Gme"); + if(error) return(error); + here->B3SOIDDgmeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vbs0teff"); + if(error) return(error); + here->B3SOIDDvbs0teffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vth"); + if(error) return(error); + here->B3SOIDDvthNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vgsteff"); + if(error) return(error); + here->B3SOIDDvgsteffNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Xcsat"); + if(error) return(error); + here->B3SOIDDxcsatNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qac0"); + if(error) return(error); + here->B3SOIDDqaccNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsub0"); + if(error) return(error); + here->B3SOIDDqsub0Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsubs1"); + if(error) return(error); + here->B3SOIDDqsubs1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsubs2"); + if(error) return(error); + here->B3SOIDDqsubs2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qsub"); + if(error) return(error); + here->B3SOIDDqeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qdrn"); + if(error) return(error); + here->B3SOIDDqdNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Qgate"); + if(error) return(error); + here->B3SOIDDqgNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vdscv"); + if(error) return(error); + here->B3SOIDDvdscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Vcscv"); + if(error) return(error); + here->B3SOIDDvcscvNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Cbe"); + if(error) return(error); + here->B3SOIDDcbeNode = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum1"); + if(error) return(error); + here->B3SOIDDdum1Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum2"); + if(error) return(error); + here->B3SOIDDdum2Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum3"); + if(error) return(error); + here->B3SOIDDdum3Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum4"); + if(error) return(error); + here->B3SOIDDdum4Node = tmp->number; + + error = CKTmkVolt(ckt, &tmp, here->B3SOIDDname, "Dum5"); + if(error) return(error); + here->B3SOIDDdum5Node = tmp->number; + } + + /* set Sparse Matrix Pointers */ + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ + return(E_NOMEM);\ +} + + + if ((model->B3SOIDDshMod == 1) && (here->B3SOIDDrth0!=0.0)) { + TSTALLOC(B3SOIDDTemptempPtr, B3SOIDDtempNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDTempdpPtr, B3SOIDDtempNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDTempspPtr, B3SOIDDtempNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDTempgPtr, B3SOIDDtempNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDTempbPtr, B3SOIDDtempNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDTempePtr, B3SOIDDtempNode, B3SOIDDeNode) + + TSTALLOC(B3SOIDDGtempPtr, B3SOIDDgNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDDPtempPtr, B3SOIDDdNodePrime, B3SOIDDtempNode) + TSTALLOC(B3SOIDDSPtempPtr, B3SOIDDsNodePrime, B3SOIDDtempNode) + TSTALLOC(B3SOIDDEtempPtr, B3SOIDDeNode, B3SOIDDtempNode) + TSTALLOC(B3SOIDDBtempPtr, B3SOIDDbNode, B3SOIDDtempNode) + + if (here->B3SOIDDbodyMod == 1) { + TSTALLOC(B3SOIDDPtempPtr, B3SOIDDpNode, B3SOIDDtempNode) + } + } + if (here->B3SOIDDbodyMod == 2) { + /* Don't create any Jacobian entry for pNode */ + } + else if (here->B3SOIDDbodyMod == 1) { + TSTALLOC(B3SOIDDBpPtr, B3SOIDDbNode, B3SOIDDpNode) + TSTALLOC(B3SOIDDPbPtr, B3SOIDDpNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDPpPtr, B3SOIDDpNode, B3SOIDDpNode) + TSTALLOC(B3SOIDDPgPtr, B3SOIDDpNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDPdpPtr, B3SOIDDpNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDPspPtr, B3SOIDDpNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDPePtr, B3SOIDDpNode, B3SOIDDeNode) + } + + TSTALLOC(B3SOIDDEgPtr, B3SOIDDeNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDEdpPtr, B3SOIDDeNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDEspPtr, B3SOIDDeNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDGePtr, B3SOIDDgNode, B3SOIDDeNode) + TSTALLOC(B3SOIDDDPePtr, B3SOIDDdNodePrime, B3SOIDDeNode) + TSTALLOC(B3SOIDDSPePtr, B3SOIDDsNodePrime, B3SOIDDeNode) + + TSTALLOC(B3SOIDDEbPtr, B3SOIDDeNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDGbPtr, B3SOIDDgNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDDPbPtr, B3SOIDDdNodePrime, B3SOIDDbNode) + TSTALLOC(B3SOIDDSPbPtr, B3SOIDDsNodePrime, B3SOIDDbNode) + TSTALLOC(B3SOIDDBePtr, B3SOIDDbNode, B3SOIDDeNode) + TSTALLOC(B3SOIDDBgPtr, B3SOIDDbNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDBdpPtr, B3SOIDDbNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDBspPtr, B3SOIDDbNode, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDBbPtr, B3SOIDDbNode, B3SOIDDbNode) + + TSTALLOC(B3SOIDDEbPtr, B3SOIDDeNode, B3SOIDDbNode) + TSTALLOC(B3SOIDDEePtr, B3SOIDDeNode, B3SOIDDeNode) + + TSTALLOC(B3SOIDDGgPtr, B3SOIDDgNode, B3SOIDDgNode) + TSTALLOC(B3SOIDDGdpPtr, B3SOIDDgNode, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDGspPtr, B3SOIDDgNode, B3SOIDDsNodePrime) + + TSTALLOC(B3SOIDDDPgPtr, B3SOIDDdNodePrime, B3SOIDDgNode) + TSTALLOC(B3SOIDDDPdpPtr, B3SOIDDdNodePrime, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDDPspPtr, B3SOIDDdNodePrime, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDDPdPtr, B3SOIDDdNodePrime, B3SOIDDdNode) + + TSTALLOC(B3SOIDDSPgPtr, B3SOIDDsNodePrime, B3SOIDDgNode) + TSTALLOC(B3SOIDDSPdpPtr, B3SOIDDsNodePrime, B3SOIDDdNodePrime) + TSTALLOC(B3SOIDDSPspPtr, B3SOIDDsNodePrime, B3SOIDDsNodePrime) + TSTALLOC(B3SOIDDSPsPtr, B3SOIDDsNodePrime, B3SOIDDsNode) + + TSTALLOC(B3SOIDDDdPtr, B3SOIDDdNode, B3SOIDDdNode) + TSTALLOC(B3SOIDDDdpPtr, B3SOIDDdNode, B3SOIDDdNodePrime) + + TSTALLOC(B3SOIDDSsPtr, B3SOIDDsNode, B3SOIDDsNode) + TSTALLOC(B3SOIDDSspPtr, B3SOIDDsNode, B3SOIDDsNodePrime) + +/* here for debugging purpose only */ + if ((here->B3SOIDDdebugMod > 1) || (here->B3SOIDDdebugMod == -1)) + { + TSTALLOC(B3SOIDDVbsPtr, B3SOIDDvbsNode, B3SOIDDvbsNode) + TSTALLOC(B3SOIDDIdsPtr, B3SOIDDidsNode, B3SOIDDidsNode) + TSTALLOC(B3SOIDDIcPtr, B3SOIDDicNode, B3SOIDDicNode) + TSTALLOC(B3SOIDDIbsPtr, B3SOIDDibsNode, B3SOIDDibsNode) + TSTALLOC(B3SOIDDIbdPtr, B3SOIDDibdNode, B3SOIDDibdNode) + TSTALLOC(B3SOIDDIiiPtr, B3SOIDDiiiNode, B3SOIDDiiiNode) + TSTALLOC(B3SOIDDIgidlPtr, B3SOIDDigidlNode, B3SOIDDigidlNode) + TSTALLOC(B3SOIDDItunPtr, B3SOIDDitunNode, B3SOIDDitunNode) + TSTALLOC(B3SOIDDIbpPtr, B3SOIDDibpNode, B3SOIDDibpNode) + TSTALLOC(B3SOIDDAbeffPtr, B3SOIDDabeffNode, B3SOIDDabeffNode) + TSTALLOC(B3SOIDDVbs0effPtr, B3SOIDDvbs0effNode, B3SOIDDvbs0effNode) + TSTALLOC(B3SOIDDVbseffPtr, B3SOIDDvbseffNode, B3SOIDDvbseffNode) + TSTALLOC(B3SOIDDXcPtr, B3SOIDDxcNode, B3SOIDDxcNode) + TSTALLOC(B3SOIDDCbbPtr, B3SOIDDcbbNode, B3SOIDDcbbNode) + TSTALLOC(B3SOIDDCbdPtr, B3SOIDDcbdNode, B3SOIDDcbdNode) + TSTALLOC(B3SOIDDCbgPtr, B3SOIDDcbgNode, B3SOIDDcbgNode) + TSTALLOC(B3SOIDDqbPtr, B3SOIDDqbNode, B3SOIDDqbNode) + TSTALLOC(B3SOIDDQbfPtr, B3SOIDDqbfNode, B3SOIDDqbfNode) + TSTALLOC(B3SOIDDQjsPtr, B3SOIDDqjsNode, B3SOIDDqjsNode) + TSTALLOC(B3SOIDDQjdPtr, B3SOIDDqjdNode, B3SOIDDqjdNode) + + /* clean up last */ + TSTALLOC(B3SOIDDGmPtr, B3SOIDDgmNode, B3SOIDDgmNode) + TSTALLOC(B3SOIDDGmbsPtr, B3SOIDDgmbsNode, B3SOIDDgmbsNode) + TSTALLOC(B3SOIDDGdsPtr, B3SOIDDgdsNode, B3SOIDDgdsNode) + TSTALLOC(B3SOIDDGmePtr, B3SOIDDgmeNode, B3SOIDDgmeNode) + TSTALLOC(B3SOIDDVbs0teffPtr, B3SOIDDvbs0teffNode, B3SOIDDvbs0teffNode) + TSTALLOC(B3SOIDDVthPtr, B3SOIDDvthNode, B3SOIDDvthNode) + TSTALLOC(B3SOIDDVgsteffPtr, B3SOIDDvgsteffNode, B3SOIDDvgsteffNode) + TSTALLOC(B3SOIDDXcsatPtr, B3SOIDDxcsatNode, B3SOIDDxcsatNode) + TSTALLOC(B3SOIDDVcscvPtr, B3SOIDDvcscvNode, B3SOIDDvcscvNode) + TSTALLOC(B3SOIDDVdscvPtr, B3SOIDDvdscvNode, B3SOIDDvdscvNode) + TSTALLOC(B3SOIDDCbePtr, B3SOIDDcbeNode, B3SOIDDcbeNode) + TSTALLOC(B3SOIDDDum1Ptr, B3SOIDDdum1Node, B3SOIDDdum1Node) + TSTALLOC(B3SOIDDDum2Ptr, B3SOIDDdum2Node, B3SOIDDdum2Node) + TSTALLOC(B3SOIDDDum3Ptr, B3SOIDDdum3Node, B3SOIDDdum3Node) + TSTALLOC(B3SOIDDDum4Ptr, B3SOIDDdum4Node, B3SOIDDdum4Node) + TSTALLOC(B3SOIDDDum5Ptr, B3SOIDDdum5Node, B3SOIDDdum5Node) + TSTALLOC(B3SOIDDQaccPtr, B3SOIDDqaccNode, B3SOIDDqaccNode) + TSTALLOC(B3SOIDDQsub0Ptr, B3SOIDDqsub0Node, B3SOIDDqsub0Node) + TSTALLOC(B3SOIDDQsubs1Ptr, B3SOIDDqsubs1Node, B3SOIDDqsubs1Node) + TSTALLOC(B3SOIDDQsubs2Ptr, B3SOIDDqsubs2Node, B3SOIDDqsubs2Node) + TSTALLOC(B3SOIDDqePtr, B3SOIDDqeNode, B3SOIDDqeNode) + TSTALLOC(B3SOIDDqdPtr, B3SOIDDqdNode, B3SOIDDqdNode) + TSTALLOC(B3SOIDDqgPtr, B3SOIDDqgNode, B3SOIDDqgNode) + } + + } + } + return(OK); +} + +int +B3SOIDDunsetup(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ +#ifndef HAS_BATCHSIM + B3SOIDDmodel *model; + B3SOIDDinstance *here; + + for (model = (B3SOIDDmodel *)inModel; model != NULL; + model = model->B3SOIDDnextModel) + { + for (here = model->B3SOIDDinstances; here != NULL; + here=here->B3SOIDDnextInstance) + { + if (here->B3SOIDDdNodePrime + && here->B3SOIDDdNodePrime != here->B3SOIDDdNode) + { + CKTdltNNum(ckt, here->B3SOIDDdNodePrime); + here->B3SOIDDdNodePrime = 0; + } + if (here->B3SOIDDsNodePrime + && here->B3SOIDDsNodePrime != here->B3SOIDDsNode) + { + CKTdltNNum(ckt, here->B3SOIDDsNodePrime); + here->B3SOIDDsNodePrime = 0; + } + } + } +#endif + return OK; +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c b/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c new file mode 100644 index 000000000..c197af59d --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddtemp.c @@ -0,0 +1,816 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: Weidong Liu and Pin Su Feb 1999 +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +Modified by Pin Su, Wei Jin 99/9/27 +File: b3soiddtemp.c 98/5/01 +**********/ + +/* Lmin, Lmax, Wmin, Wmax */ + +#include "ngspice.h" +#include +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "b3soidddef.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#define Kb 1.3806226e-23 +#define KboQ 8.617087e-5 /* Kb / q where q = 1.60219e-19 */ +#define EPSOX 3.453133e-11 +#define EPSSI 1.03594e-10 +#define PI 3.141592654 +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THRESHOLD 34.0 +#define Charge_q 1.60219e-19 + + +/* ARGSUSED */ +int +B3SOIDDtemp(inModel,ckt) +GENmodel *inModel; +CKTcircuit *ckt; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*) inModel; +register B3SOIDDinstance *here; +struct b3soiddSizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam; +double tmp, tmp1, tmp2, Eg, Eg0, ni, T0, T1, T2, T3, T4, T5, T6, Ldrn, Wdrn; +double Temp, TRatio, Inv_L, Inv_W, Inv_LW, Dw, Dl, Vtm0, Tnom; +double SDphi, SDgamma; +int Size_Not_Found; + + /* loop through all the B3SOIDD device models */ + for (; model != NULL; model = model->B3SOIDDnextModel) + { Temp = ckt->CKTtemp; + if (model->B3SOIDDGatesidewallJctPotential < 0.1) + model->B3SOIDDGatesidewallJctPotential = 0.1; + model->pSizeDependParamKnot = NULL; + pLastKnot = NULL; + + Tnom = model->B3SOIDDtnom; + TRatio = Temp / Tnom; + + model->B3SOIDDvcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + model->B3SOIDDfactor1 = sqrt(EPSSI / EPSOX * model->B3SOIDDtox); + + Vtm0 = KboQ * Tnom; + Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); + model->B3SOIDDeg0 = Eg0; + model->B3SOIDDvtm = KboQ * Temp; + + Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); + /* ni is in cm^-3 */ + ni = 1.45e10 * (Temp / 300.15) * sqrt(Temp / 300.15) + * exp(21.5565981 - Eg / (2.0 * model->B3SOIDDvtm)); + + + /* loop through all the instances of the model */ + /* MCJ: Length and Width not initialized */ + for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { + here->B3SOIDDrbodyext = here->B3SOIDDbodySquares * + model->B3SOIDDrbsh; + pSizeDependParamKnot = model->pSizeDependParamKnot; + Size_Not_Found = 1; + while ((pSizeDependParamKnot != NULL) && Size_Not_Found) + { if ((here->B3SOIDDl == pSizeDependParamKnot->Length) + && (here->B3SOIDDw == pSizeDependParamKnot->Width) + && (here->B3SOIDDrth0 == pSizeDependParamKnot->Rth0) + && (here->B3SOIDDcth0 == pSizeDependParamKnot->Cth0)) + { Size_Not_Found = 0; + here->pParam = pSizeDependParamKnot; + } + else + { pLastKnot = pSizeDependParamKnot; + pSizeDependParamKnot = pSizeDependParamKnot->pNext; + } + } + + if (Size_Not_Found) + { pParam = (struct b3soiddSizeDependParam *)malloc( + sizeof(struct b3soiddSizeDependParam)); + if (pLastKnot == NULL) + model->pSizeDependParamKnot = pParam; + else + pLastKnot->pNext = pParam; + pParam->pNext = NULL; + here->pParam = pParam; + + Ldrn = here->B3SOIDDl; + Wdrn = here->B3SOIDDw; + pParam->Length = Ldrn; + pParam->Width = Wdrn; + pParam->Rth0 = here->B3SOIDDrth0; + pParam->Cth0 = here->B3SOIDDcth0; + + T0 = pow(Ldrn, model->B3SOIDDLln); + T1 = pow(Wdrn, model->B3SOIDDLwn); + tmp1 = model->B3SOIDDLl / T0 + model->B3SOIDDLw / T1 + + model->B3SOIDDLwl / (T0 * T1); + pParam->B3SOIDDdl = model->B3SOIDDLint + tmp1; + pParam->B3SOIDDdlc = model->B3SOIDDdlc + tmp1; + + T2 = pow(Ldrn, model->B3SOIDDWln); + T3 = pow(Wdrn, model->B3SOIDDWwn); + tmp2 = model->B3SOIDDWl / T2 + model->B3SOIDDWw / T3 + + model->B3SOIDDWwl / (T2 * T3); + pParam->B3SOIDDdw = model->B3SOIDDWint + tmp2; + pParam->B3SOIDDdwc = model->B3SOIDDdwc + tmp2; + + pParam->B3SOIDDleff = here->B3SOIDDl - 2.0 * pParam->B3SOIDDdl; + if (pParam->B3SOIDDleff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel length <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDweff = here->B3SOIDDw - 2.0 * pParam->B3SOIDDdw; + if (pParam->B3SOIDDweff <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel width <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDleffCV = here->B3SOIDDl - 2.0 * pParam->B3SOIDDdlc; + if (pParam->B3SOIDDleffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel length for C-V <= 0", + namarray); + return(E_BADPARM); + } + + pParam->B3SOIDDweffCV = here->B3SOIDDw - 2.0 * pParam->B3SOIDDdwc; + if (pParam->B3SOIDDweffCV <= 0.0) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror))(ERR_FATAL, + "B3SOIDD: mosfet %s, model %s: Effective channel width for C-V <= 0", + namarray); + return(E_BADPARM); + } + + /* Not binned - START */ + pParam->B3SOIDDat = model->B3SOIDDat; + pParam->B3SOIDDgamma1 = model->B3SOIDDgamma1; + pParam->B3SOIDDgamma2 = model->B3SOIDDgamma2; + pParam->B3SOIDDvbx = model->B3SOIDDvbx; + pParam->B3SOIDDvbm = model->B3SOIDDvbm; + pParam->B3SOIDDxt = model->B3SOIDDxt; + pParam->B3SOIDDkt1 = model->B3SOIDDkt1; + pParam->B3SOIDDkt1l = model->B3SOIDDkt1l; + pParam->B3SOIDDkt2 = model->B3SOIDDkt2; + pParam->B3SOIDDua1 = model->B3SOIDDua1; + pParam->B3SOIDDub1 = model->B3SOIDDub1; + pParam->B3SOIDDuc1 = model->B3SOIDDuc1; + pParam->B3SOIDDute = model->B3SOIDDute; + pParam->B3SOIDDprt = model->B3SOIDDprt; + /* Not binned - END */ + + /* CV model */ + pParam->B3SOIDDcgsl = model->B3SOIDDcgsl; + pParam->B3SOIDDcgdl = model->B3SOIDDcgdl; + pParam->B3SOIDDckappa = model->B3SOIDDckappa; + pParam->B3SOIDDcf = model->B3SOIDDcf; + pParam->B3SOIDDclc = model->B3SOIDDclc; + pParam->B3SOIDDcle = model->B3SOIDDcle; + + pParam->B3SOIDDabulkCVfactor = pow(1.0+(pParam->B3SOIDDclc + / pParam->B3SOIDDleff), + pParam->B3SOIDDcle); + +/* Added for binning - START */ + if (model->B3SOIDDbinUnit == 1) + { Inv_L = 1.0e-6 / pParam->B3SOIDDleff; + Inv_W = 1.0e-6 / pParam->B3SOIDDweff; + Inv_LW = 1.0e-12 / (pParam->B3SOIDDleff + * pParam->B3SOIDDweff); + } + else + { Inv_L = 1.0 / pParam->B3SOIDDleff; + Inv_W = 1.0 / pParam->B3SOIDDweff; + Inv_LW = 1.0 / (pParam->B3SOIDDleff + * pParam->B3SOIDDweff); + } + pParam->B3SOIDDnpeak = model->B3SOIDDnpeak + + model->B3SOIDDlnpeak * Inv_L + + model->B3SOIDDwnpeak * Inv_W + + model->B3SOIDDpnpeak * Inv_LW; + pParam->B3SOIDDnsub = model->B3SOIDDnsub + + model->B3SOIDDlnsub * Inv_L + + model->B3SOIDDwnsub * Inv_W + + model->B3SOIDDpnsub * Inv_LW; + pParam->B3SOIDDngate = model->B3SOIDDngate + + model->B3SOIDDlngate * Inv_L + + model->B3SOIDDwngate * Inv_W + + model->B3SOIDDpngate * Inv_LW; + pParam->B3SOIDDvth0 = model->B3SOIDDvth0 + + model->B3SOIDDlvth0 * Inv_L + + model->B3SOIDDwvth0 * Inv_W + + model->B3SOIDDpvth0 * Inv_LW; + pParam->B3SOIDDk1 = model->B3SOIDDk1 + + model->B3SOIDDlk1 * Inv_L + + model->B3SOIDDwk1 * Inv_W + + model->B3SOIDDpk1 * Inv_LW; + pParam->B3SOIDDk2 = model->B3SOIDDk2 + + model->B3SOIDDlk2 * Inv_L + + model->B3SOIDDwk2 * Inv_W + + model->B3SOIDDpk2 * Inv_LW; + pParam->B3SOIDDk3 = model->B3SOIDDk3 + + model->B3SOIDDlk3 * Inv_L + + model->B3SOIDDwk3 * Inv_W + + model->B3SOIDDpk3 * Inv_LW; + pParam->B3SOIDDk3b = model->B3SOIDDk3b + + model->B3SOIDDlk3b * Inv_L + + model->B3SOIDDwk3b * Inv_W + + model->B3SOIDDpk3b * Inv_LW; + pParam->B3SOIDDvbsa = model->B3SOIDDvbsa + + model->B3SOIDDlvbsa * Inv_L + + model->B3SOIDDwvbsa * Inv_W + + model->B3SOIDDpvbsa * Inv_LW; + pParam->B3SOIDDdelp = model->B3SOIDDdelp + + model->B3SOIDDldelp * Inv_L + + model->B3SOIDDwdelp * Inv_W + + model->B3SOIDDpdelp * Inv_LW; + pParam->B3SOIDDkb1 = model->B3SOIDDkb1 + + model->B3SOIDDlkb1 * Inv_L + + model->B3SOIDDwkb1 * Inv_W + + model->B3SOIDDpkb1 * Inv_LW; + pParam->B3SOIDDkb3 = model->B3SOIDDkb3 + + model->B3SOIDDlkb3 * Inv_L + + model->B3SOIDDwkb3 * Inv_W + + model->B3SOIDDpkb3 * Inv_LW; + pParam->B3SOIDDdvbd0 = model->B3SOIDDdvbd0 + + model->B3SOIDDldvbd0 * Inv_L + + model->B3SOIDDwdvbd0 * Inv_W + + model->B3SOIDDpdvbd0 * Inv_LW; + pParam->B3SOIDDdvbd1 = model->B3SOIDDdvbd1 + + model->B3SOIDDldvbd1 * Inv_L + + model->B3SOIDDwdvbd1 * Inv_W + + model->B3SOIDDpdvbd1 * Inv_LW; + pParam->B3SOIDDw0 = model->B3SOIDDw0 + + model->B3SOIDDlw0 * Inv_L + + model->B3SOIDDww0 * Inv_W + + model->B3SOIDDpw0 * Inv_LW; + pParam->B3SOIDDnlx = model->B3SOIDDnlx + + model->B3SOIDDlnlx * Inv_L + + model->B3SOIDDwnlx * Inv_W + + model->B3SOIDDpnlx * Inv_LW; + pParam->B3SOIDDdvt0 = model->B3SOIDDdvt0 + + model->B3SOIDDldvt0 * Inv_L + + model->B3SOIDDwdvt0 * Inv_W + + model->B3SOIDDpdvt0 * Inv_LW; + pParam->B3SOIDDdvt1 = model->B3SOIDDdvt1 + + model->B3SOIDDldvt1 * Inv_L + + model->B3SOIDDwdvt1 * Inv_W + + model->B3SOIDDpdvt1 * Inv_LW; + pParam->B3SOIDDdvt2 = model->B3SOIDDdvt2 + + model->B3SOIDDldvt2 * Inv_L + + model->B3SOIDDwdvt2 * Inv_W + + model->B3SOIDDpdvt2 * Inv_LW; + pParam->B3SOIDDdvt0w = model->B3SOIDDdvt0w + + model->B3SOIDDldvt0w * Inv_L + + model->B3SOIDDwdvt0w * Inv_W + + model->B3SOIDDpdvt0w * Inv_LW; + pParam->B3SOIDDdvt1w = model->B3SOIDDdvt1w + + model->B3SOIDDldvt1w * Inv_L + + model->B3SOIDDwdvt1w * Inv_W + + model->B3SOIDDpdvt1w * Inv_LW; + pParam->B3SOIDDdvt2w = model->B3SOIDDdvt2w + + model->B3SOIDDldvt2w * Inv_L + + model->B3SOIDDwdvt2w * Inv_W + + model->B3SOIDDpdvt2w * Inv_LW; + pParam->B3SOIDDu0 = model->B3SOIDDu0 + + model->B3SOIDDlu0 * Inv_L + + model->B3SOIDDwu0 * Inv_W + + model->B3SOIDDpu0 * Inv_LW; + pParam->B3SOIDDua = model->B3SOIDDua + + model->B3SOIDDlua * Inv_L + + model->B3SOIDDwua * Inv_W + + model->B3SOIDDpua * Inv_LW; + pParam->B3SOIDDub = model->B3SOIDDub + + model->B3SOIDDlub * Inv_L + + model->B3SOIDDwub * Inv_W + + model->B3SOIDDpub * Inv_LW; + pParam->B3SOIDDuc = model->B3SOIDDuc + + model->B3SOIDDluc * Inv_L + + model->B3SOIDDwuc * Inv_W + + model->B3SOIDDpuc * Inv_LW; + pParam->B3SOIDDvsat = model->B3SOIDDvsat + + model->B3SOIDDlvsat * Inv_L + + model->B3SOIDDwvsat * Inv_W + + model->B3SOIDDpvsat * Inv_LW; + pParam->B3SOIDDa0 = model->B3SOIDDa0 + + model->B3SOIDDla0 * Inv_L + + model->B3SOIDDwa0 * Inv_W + + model->B3SOIDDpa0 * Inv_LW; + pParam->B3SOIDDags = model->B3SOIDDags + + model->B3SOIDDlags * Inv_L + + model->B3SOIDDwags * Inv_W + + model->B3SOIDDpags * Inv_LW; + pParam->B3SOIDDb0 = model->B3SOIDDb0 + + model->B3SOIDDlb0 * Inv_L + + model->B3SOIDDwb0 * Inv_W + + model->B3SOIDDpb0 * Inv_LW; + pParam->B3SOIDDb1 = model->B3SOIDDb1 + + model->B3SOIDDlb1 * Inv_L + + model->B3SOIDDwb1 * Inv_W + + model->B3SOIDDpb1 * Inv_LW; + pParam->B3SOIDDketa = model->B3SOIDDketa + + model->B3SOIDDlketa * Inv_L + + model->B3SOIDDwketa * Inv_W + + model->B3SOIDDpketa * Inv_LW; + pParam->B3SOIDDabp = model->B3SOIDDabp + + model->B3SOIDDlabp * Inv_L + + model->B3SOIDDwabp * Inv_W + + model->B3SOIDDpabp * Inv_LW; + pParam->B3SOIDDmxc = model->B3SOIDDmxc + + model->B3SOIDDlmxc * Inv_L + + model->B3SOIDDwmxc * Inv_W + + model->B3SOIDDpmxc * Inv_LW; + pParam->B3SOIDDadice0 = model->B3SOIDDadice0 + + model->B3SOIDDladice0 * Inv_L + + model->B3SOIDDwadice0 * Inv_W + + model->B3SOIDDpadice0 * Inv_LW; + pParam->B3SOIDDa1 = model->B3SOIDDa1 + + model->B3SOIDDla1 * Inv_L + + model->B3SOIDDwa1 * Inv_W + + model->B3SOIDDpa1 * Inv_LW; + pParam->B3SOIDDa2 = model->B3SOIDDa2 + + model->B3SOIDDla2 * Inv_L + + model->B3SOIDDwa2 * Inv_W + + model->B3SOIDDpa2 * Inv_LW; + pParam->B3SOIDDrdsw = model->B3SOIDDrdsw + + model->B3SOIDDlrdsw * Inv_L + + model->B3SOIDDwrdsw * Inv_W + + model->B3SOIDDprdsw * Inv_LW; + pParam->B3SOIDDprwb = model->B3SOIDDprwb + + model->B3SOIDDlprwb * Inv_L + + model->B3SOIDDwprwb * Inv_W + + model->B3SOIDDpprwb * Inv_LW; + pParam->B3SOIDDprwg = model->B3SOIDDprwg + + model->B3SOIDDlprwg * Inv_L + + model->B3SOIDDwprwg * Inv_W + + model->B3SOIDDpprwg * Inv_LW; + pParam->B3SOIDDwr = model->B3SOIDDwr + + model->B3SOIDDlwr * Inv_L + + model->B3SOIDDwwr * Inv_W + + model->B3SOIDDpwr * Inv_LW; + pParam->B3SOIDDnfactor = model->B3SOIDDnfactor + + model->B3SOIDDlnfactor * Inv_L + + model->B3SOIDDwnfactor * Inv_W + + model->B3SOIDDpnfactor * Inv_LW; + pParam->B3SOIDDdwg = model->B3SOIDDdwg + + model->B3SOIDDldwg * Inv_L + + model->B3SOIDDwdwg * Inv_W + + model->B3SOIDDpdwg * Inv_LW; + pParam->B3SOIDDdwb = model->B3SOIDDdwb + + model->B3SOIDDldwb * Inv_L + + model->B3SOIDDwdwb * Inv_W + + model->B3SOIDDpdwb * Inv_LW; + pParam->B3SOIDDvoff = model->B3SOIDDvoff + + model->B3SOIDDlvoff * Inv_L + + model->B3SOIDDwvoff * Inv_W + + model->B3SOIDDpvoff * Inv_LW; + pParam->B3SOIDDeta0 = model->B3SOIDDeta0 + + model->B3SOIDDleta0 * Inv_L + + model->B3SOIDDweta0 * Inv_W + + model->B3SOIDDpeta0 * Inv_LW; + pParam->B3SOIDDetab = model->B3SOIDDetab + + model->B3SOIDDletab * Inv_L + + model->B3SOIDDwetab * Inv_W + + model->B3SOIDDpetab * Inv_LW; + pParam->B3SOIDDdsub = model->B3SOIDDdsub + + model->B3SOIDDldsub * Inv_L + + model->B3SOIDDwdsub * Inv_W + + model->B3SOIDDpdsub * Inv_LW; + pParam->B3SOIDDcit = model->B3SOIDDcit + + model->B3SOIDDlcit * Inv_L + + model->B3SOIDDwcit * Inv_W + + model->B3SOIDDpcit * Inv_LW; + pParam->B3SOIDDcdsc = model->B3SOIDDcdsc + + model->B3SOIDDlcdsc * Inv_L + + model->B3SOIDDwcdsc * Inv_W + + model->B3SOIDDpcdsc * Inv_LW; + pParam->B3SOIDDcdscb = model->B3SOIDDcdscb + + model->B3SOIDDlcdscb * Inv_L + + model->B3SOIDDwcdscb * Inv_W + + model->B3SOIDDpcdscb * Inv_LW; + pParam->B3SOIDDcdscd = model->B3SOIDDcdscd + + model->B3SOIDDlcdscd * Inv_L + + model->B3SOIDDwcdscd * Inv_W + + model->B3SOIDDpcdscd * Inv_LW; + pParam->B3SOIDDpclm = model->B3SOIDDpclm + + model->B3SOIDDlpclm * Inv_L + + model->B3SOIDDwpclm * Inv_W + + model->B3SOIDDppclm * Inv_LW; + pParam->B3SOIDDpdibl1 = model->B3SOIDDpdibl1 + + model->B3SOIDDlpdibl1 * Inv_L + + model->B3SOIDDwpdibl1 * Inv_W + + model->B3SOIDDppdibl1 * Inv_LW; + pParam->B3SOIDDpdibl2 = model->B3SOIDDpdibl2 + + model->B3SOIDDlpdibl2 * Inv_L + + model->B3SOIDDwpdibl2 * Inv_W + + model->B3SOIDDppdibl2 * Inv_LW; + pParam->B3SOIDDpdiblb = model->B3SOIDDpdiblb + + model->B3SOIDDlpdiblb * Inv_L + + model->B3SOIDDwpdiblb * Inv_W + + model->B3SOIDDppdiblb * Inv_LW; + pParam->B3SOIDDdrout = model->B3SOIDDdrout + + model->B3SOIDDldrout * Inv_L + + model->B3SOIDDwdrout * Inv_W + + model->B3SOIDDpdrout * Inv_LW; + pParam->B3SOIDDpvag = model->B3SOIDDpvag + + model->B3SOIDDlpvag * Inv_L + + model->B3SOIDDwpvag * Inv_W + + model->B3SOIDDppvag * Inv_LW; + pParam->B3SOIDDdelta = model->B3SOIDDdelta + + model->B3SOIDDldelta * Inv_L + + model->B3SOIDDwdelta * Inv_W + + model->B3SOIDDpdelta * Inv_LW; + pParam->B3SOIDDaii = model->B3SOIDDaii + + model->B3SOIDDlaii * Inv_L + + model->B3SOIDDwaii * Inv_W + + model->B3SOIDDpaii * Inv_LW; + pParam->B3SOIDDbii = model->B3SOIDDbii + + model->B3SOIDDlbii * Inv_L + + model->B3SOIDDwbii * Inv_W + + model->B3SOIDDpbii * Inv_LW; + pParam->B3SOIDDcii = model->B3SOIDDcii + + model->B3SOIDDlcii * Inv_L + + model->B3SOIDDwcii * Inv_W + + model->B3SOIDDpcii * Inv_LW; + pParam->B3SOIDDdii = model->B3SOIDDdii + + model->B3SOIDDldii * Inv_L + + model->B3SOIDDwdii * Inv_W + + model->B3SOIDDpdii * Inv_LW; + pParam->B3SOIDDalpha0 = model->B3SOIDDalpha0 + + model->B3SOIDDlalpha0 * Inv_L + + model->B3SOIDDwalpha0 * Inv_W + + model->B3SOIDDpalpha0 * Inv_LW; + pParam->B3SOIDDalpha1 = model->B3SOIDDalpha1 + + model->B3SOIDDlalpha1 * Inv_L + + model->B3SOIDDwalpha1 * Inv_W + + model->B3SOIDDpalpha1 * Inv_LW; + pParam->B3SOIDDbeta0 = model->B3SOIDDbeta0 + + model->B3SOIDDlbeta0 * Inv_L + + model->B3SOIDDwbeta0 * Inv_W + + model->B3SOIDDpbeta0 * Inv_LW; + pParam->B3SOIDDagidl = model->B3SOIDDagidl + + model->B3SOIDDlagidl * Inv_L + + model->B3SOIDDwagidl * Inv_W + + model->B3SOIDDpagidl * Inv_LW; + pParam->B3SOIDDbgidl = model->B3SOIDDbgidl + + model->B3SOIDDlbgidl * Inv_L + + model->B3SOIDDwbgidl * Inv_W + + model->B3SOIDDpbgidl * Inv_LW; + pParam->B3SOIDDngidl = model->B3SOIDDngidl + + model->B3SOIDDlngidl * Inv_L + + model->B3SOIDDwngidl * Inv_W + + model->B3SOIDDpngidl * Inv_LW; + pParam->B3SOIDDntun = model->B3SOIDDntun + + model->B3SOIDDlntun * Inv_L + + model->B3SOIDDwntun * Inv_W + + model->B3SOIDDpntun * Inv_LW; + pParam->B3SOIDDndiode = model->B3SOIDDndiode + + model->B3SOIDDlndiode * Inv_L + + model->B3SOIDDwndiode * Inv_W + + model->B3SOIDDpndiode * Inv_LW; + pParam->B3SOIDDisbjt = model->B3SOIDDisbjt + + model->B3SOIDDlisbjt * Inv_L + + model->B3SOIDDwisbjt * Inv_W + + model->B3SOIDDpisbjt * Inv_LW; + pParam->B3SOIDDisdif = model->B3SOIDDisdif + + model->B3SOIDDlisdif * Inv_L + + model->B3SOIDDwisdif * Inv_W + + model->B3SOIDDpisdif * Inv_LW; + pParam->B3SOIDDisrec = model->B3SOIDDisrec + + model->B3SOIDDlisrec * Inv_L + + model->B3SOIDDwisrec * Inv_W + + model->B3SOIDDpisrec * Inv_LW; + pParam->B3SOIDDistun = model->B3SOIDDistun + + model->B3SOIDDlistun * Inv_L + + model->B3SOIDDwistun * Inv_W + + model->B3SOIDDpistun * Inv_LW; + pParam->B3SOIDDedl = model->B3SOIDDedl + + model->B3SOIDDledl * Inv_L + + model->B3SOIDDwedl * Inv_W + + model->B3SOIDDpedl * Inv_LW; + pParam->B3SOIDDkbjt1 = model->B3SOIDDkbjt1 + + model->B3SOIDDlkbjt1 * Inv_L + + model->B3SOIDDwkbjt1 * Inv_W + + model->B3SOIDDpkbjt1 * Inv_LW; + /* CV model */ + pParam->B3SOIDDvsdfb = model->B3SOIDDvsdfb + + model->B3SOIDDlvsdfb * Inv_L + + model->B3SOIDDwvsdfb * Inv_W + + model->B3SOIDDpvsdfb * Inv_LW; + pParam->B3SOIDDvsdth = model->B3SOIDDvsdth + + model->B3SOIDDlvsdth * Inv_L + + model->B3SOIDDwvsdth * Inv_W + + model->B3SOIDDpvsdth * Inv_LW; +/* Added for binning - END */ + + T0 = (TRatio - 1.0); + + pParam->B3SOIDDuatemp = pParam->B3SOIDDua; /* save ua, ub, and uc for b3soild.c */ + pParam->B3SOIDDubtemp = pParam->B3SOIDDub; + pParam->B3SOIDDuctemp = pParam->B3SOIDDuc; + pParam->B3SOIDDrds0denom = pow(pParam->B3SOIDDweff * 1E6, pParam->B3SOIDDwr); + pParam->B3SOIDDrth = here->B3SOIDDrth0 * sqrt(model->B3SOIDDtbox + / model->B3SOIDDtsi) / pParam->B3SOIDDweff; + pParam->B3SOIDDcth = here->B3SOIDDcth0 * model->B3SOIDDtsi; + pParam->B3SOIDDrbody = model->B3SOIDDrbody * + pParam->B3SOIDDweff / pParam->B3SOIDDleff; + pParam->B3SOIDDua = pParam->B3SOIDDua + pParam->B3SOIDDua1 * T0; + pParam->B3SOIDDub = pParam->B3SOIDDub + pParam->B3SOIDDub1 * T0; + pParam->B3SOIDDuc = pParam->B3SOIDDuc + pParam->B3SOIDDuc1 * T0; + if (pParam->B3SOIDDu0 > 1.0) + pParam->B3SOIDDu0 = pParam->B3SOIDDu0 / 1.0e4; + + pParam->B3SOIDDu0temp = pParam->B3SOIDDu0 + * pow(TRatio, pParam->B3SOIDDute); + pParam->B3SOIDDvsattemp = pParam->B3SOIDDvsat - pParam->B3SOIDDat + * T0; + pParam->B3SOIDDrds0 = (pParam->B3SOIDDrdsw + pParam->B3SOIDDprt * T0) + / pow(pParam->B3SOIDDweff * 1E6, pParam->B3SOIDDwr); + + if (B3SOIDDcheckModel(model, here, ckt)) + { IFuid namarray[2]; + namarray[0] = model->B3SOIDDmodName; + namarray[1] = here->B3SOIDDname; + (*(SPfrontEnd->IFerror)) (ERR_FATAL, "Fatal error(s) detected during B3SOIDDV3 parameter checking for %s in model %s", namarray); + return(E_BADPARM); + } + + + pParam->B3SOIDDcgdo = (model->B3SOIDDcgdo + pParam->B3SOIDDcf) + * pParam->B3SOIDDweffCV; + pParam->B3SOIDDcgso = (model->B3SOIDDcgso + pParam->B3SOIDDcf) + * pParam->B3SOIDDweffCV; + pParam->B3SOIDDcgeo = model->B3SOIDDcgeo + * pParam->B3SOIDDleffCV; + + + if (!model->B3SOIDDnpeakGiven && model->B3SOIDDgamma1Given) + { T0 = pParam->B3SOIDDgamma1 * model->B3SOIDDcox; + pParam->B3SOIDDnpeak = 3.021E22 * T0 * T0; + } + + T0 = pow(TRatio, model->B3SOIDDxbjt / pParam->B3SOIDDndiode); + T1 = pow(TRatio, model->B3SOIDDxdif / pParam->B3SOIDDndiode); + T2 = pow(TRatio, model->B3SOIDDxrec / pParam->B3SOIDDndiode / 2); + T4 = -Eg0 / pParam->B3SOIDDndiode / model->B3SOIDDvtm * (1 - TRatio); + T5 = exp(T4); + T6 = sqrt(T5); + pParam->B3SOIDDjbjt = pParam->B3SOIDDisbjt * T0 * T5; + pParam->B3SOIDDjdif = pParam->B3SOIDDisdif * T1 * T5; + pParam->B3SOIDDjrec = pParam->B3SOIDDisrec * T2 * T6; + T0 = pow(TRatio, model->B3SOIDDxtun / pParam->B3SOIDDntun); + pParam->B3SOIDDjtun = pParam->B3SOIDDistun * T0 ; + + if (pParam->B3SOIDDnsub > 0) + pParam->B3SOIDDvfbb = -model->B3SOIDDtype * model->B3SOIDDvtm * + log(pParam->B3SOIDDnpeak/ pParam->B3SOIDDnsub); + else + pParam->B3SOIDDvfbb = -model->B3SOIDDtype * model->B3SOIDDvtm * + log(-pParam->B3SOIDDnpeak* pParam->B3SOIDDnsub/ni/ni); + + if (!model->B3SOIDDvsdfbGiven) + { + if (pParam->B3SOIDDnsub > 0) + pParam->B3SOIDDvsdfb = -model->B3SOIDDtype * (model->B3SOIDDvtm*log(1e20 * + pParam->B3SOIDDnsub / ni /ni) - 0.3); + else if (pParam->B3SOIDDnsub < 0) + pParam->B3SOIDDvsdfb = -model->B3SOIDDtype * (model->B3SOIDDvtm*log(-1e20 / + pParam->B3SOIDDnsub) + 0.3); + } + + /* Phi & Gamma */ + SDphi = 2.0*model->B3SOIDDvtm*log(fabs(pParam->B3SOIDDnsub) / ni); + SDgamma = 5.753e-12 * sqrt(fabs(pParam->B3SOIDDnsub)) / model->B3SOIDDcbox; + + if (!model->B3SOIDDvsdthGiven) + { + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + pParam->B3SOIDDvsdth = pParam->B3SOIDDvsdfb + SDphi + + SDgamma * sqrt(SDphi); + else + pParam->B3SOIDDvsdth = pParam->B3SOIDDvsdfb - SDphi - + SDgamma * sqrt(SDphi); + } + if (!model->B3SOIDDcsdminGiven) + { + /* Cdmin */ + tmp = sqrt(2.0 * EPSSI * SDphi / (Charge_q * + fabs(pParam->B3SOIDDnsub) * 1.0e6)); + tmp1 = EPSSI / tmp; + model->B3SOIDDcsdmin = tmp1 * model->B3SOIDDcbox / + (tmp1 + model->B3SOIDDcbox); + } + + + T0 = model->B3SOIDDcsdesw * log(1 + model->B3SOIDDtsi / + model->B3SOIDDtbox); + T1 = here->B3SOIDDsourcePerimeter - pParam->B3SOIDDweff; + if (T1 > 0.0) + pParam->B3SOIDDcsesw = T0 * T1; + else + pParam->B3SOIDDcsesw = 0.0; + T1 = here->B3SOIDDdrainPerimeter - pParam->B3SOIDDweff; + if (T1 > 0.0) + pParam->B3SOIDDcdesw = T0 * T1; + else + pParam->B3SOIDDcdesw = 0.0; + + pParam->B3SOIDDphi = 2.0 * model->B3SOIDDvtm + * log(pParam->B3SOIDDnpeak / ni); + + pParam->B3SOIDDsqrtPhi = sqrt(pParam->B3SOIDDphi); + pParam->B3SOIDDphis3 = pParam->B3SOIDDsqrtPhi * pParam->B3SOIDDphi; + + pParam->B3SOIDDXdep0 = sqrt(2.0 * EPSSI / (Charge_q + * pParam->B3SOIDDnpeak * 1.0e6)) + * pParam->B3SOIDDsqrtPhi; + pParam->B3SOIDDsqrtXdep0 = sqrt(pParam->B3SOIDDXdep0); + pParam->B3SOIDDlitl = sqrt(3.0 * model->B3SOIDDxj + * model->B3SOIDDtox); + pParam->B3SOIDDvbi = model->B3SOIDDvtm * log(1.0e20 + * pParam->B3SOIDDnpeak / (ni * ni)); + pParam->B3SOIDDcdep0 = sqrt(Charge_q * EPSSI + * pParam->B3SOIDDnpeak * 1.0e6 / 2.0 + / pParam->B3SOIDDphi); + + if (model->B3SOIDDk1Given || model->B3SOIDDk2Given) + { if (!model->B3SOIDDk1Given) + { fprintf(stdout, "Warning: k1 should be specified with k2.\n"); + pParam->B3SOIDDk1 = 0.53; + } + if (!model->B3SOIDDk2Given) + { fprintf(stdout, "Warning: k2 should be specified with k1.\n"); + pParam->B3SOIDDk2 = -0.0186; + } + if (model->B3SOIDDxtGiven) + fprintf(stdout, "Warning: xt is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDvbxGiven) + fprintf(stdout, "Warning: vbx is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDvbmGiven) + fprintf(stdout, "Warning: vbm is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDgamma1Given) + fprintf(stdout, "Warning: gamma1 is ignored because k1 or k2 is given.\n"); + if (model->B3SOIDDgamma2Given) + fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); + } + else + { if (!model->B3SOIDDvbxGiven) + pParam->B3SOIDDvbx = pParam->B3SOIDDphi - 7.7348e-4 + * pParam->B3SOIDDnpeak + * pParam->B3SOIDDxt * pParam->B3SOIDDxt; + if (pParam->B3SOIDDvbx > 0.0) + pParam->B3SOIDDvbx = -pParam->B3SOIDDvbx; + if (pParam->B3SOIDDvbm > 0.0) + pParam->B3SOIDDvbm = -pParam->B3SOIDDvbm; + + if (!model->B3SOIDDgamma1Given) + pParam->B3SOIDDgamma1 = 5.753e-12 + * sqrt(pParam->B3SOIDDnpeak) + / model->B3SOIDDcox; + if (!model->B3SOIDDgamma2Given) + pParam->B3SOIDDgamma2 = 5.753e-12 + * sqrt(pParam->B3SOIDDnsub) + / model->B3SOIDDcox; + + T0 = pParam->B3SOIDDgamma1 - pParam->B3SOIDDgamma2; + T1 = sqrt(pParam->B3SOIDDphi - pParam->B3SOIDDvbx) + - pParam->B3SOIDDsqrtPhi; + T2 = sqrt(pParam->B3SOIDDphi * (pParam->B3SOIDDphi + - pParam->B3SOIDDvbm)) - pParam->B3SOIDDphi; + pParam->B3SOIDDk2 = T0 * T1 / (2.0 * T2 + pParam->B3SOIDDvbm); + pParam->B3SOIDDk1 = pParam->B3SOIDDgamma2 - 2.0 + * pParam->B3SOIDDk2 * sqrt(pParam->B3SOIDDphi + - pParam->B3SOIDDvbm); + } + + if (pParam->B3SOIDDk2 < 0.0) + { T0 = 0.5 * pParam->B3SOIDDk1 / pParam->B3SOIDDk2; + pParam->B3SOIDDvbsc = 0.9 * (pParam->B3SOIDDphi - T0 * T0); + if (pParam->B3SOIDDvbsc > -3.0) + pParam->B3SOIDDvbsc = -3.0; + else if (pParam->B3SOIDDvbsc < -30.0) + pParam->B3SOIDDvbsc = -30.0; + } + else + { pParam->B3SOIDDvbsc = -30.0; + } + if (pParam->B3SOIDDvbsc > pParam->B3SOIDDvbm) + pParam->B3SOIDDvbsc = pParam->B3SOIDDvbm; + + if (model->B3SOIDDvth0Given) + { pParam->B3SOIDDvfb = model->B3SOIDDtype * pParam->B3SOIDDvth0 + - pParam->B3SOIDDphi - pParam->B3SOIDDk1 + * pParam->B3SOIDDsqrtPhi; + } + else + { pParam->B3SOIDDvfb = -1.0; + pParam->B3SOIDDvth0 = model->B3SOIDDtype * (pParam->B3SOIDDvfb + + pParam->B3SOIDDphi + pParam->B3SOIDDk1 + * pParam->B3SOIDDsqrtPhi); + } + T1 = sqrt(EPSSI / EPSOX * model->B3SOIDDtox + * pParam->B3SOIDDXdep0); + T0 = exp(-0.5 * pParam->B3SOIDDdsub * pParam->B3SOIDDleff / T1); + pParam->B3SOIDDtheta0vb0 = (T0 + 2.0 * T0 * T0); + + T0 = exp(-0.5 * pParam->B3SOIDDdrout * pParam->B3SOIDDleff / T1); + T2 = (T0 + 2.0 * T0 * T0); + pParam->B3SOIDDthetaRout = pParam->B3SOIDDpdibl1 * T2 + + pParam->B3SOIDDpdibl2; + + here->B3SOIDDminIsub = 5.0e-2 * pParam->B3SOIDDweff * model->B3SOIDDtsi + * MAX(pParam->B3SOIDDisdif, pParam->B3SOIDDisrec); + } + + here->B3SOIDDcsbox = model->B3SOIDDcbox*here->B3SOIDDsourceArea; + here->B3SOIDDcsmin = model->B3SOIDDcsdmin*here->B3SOIDDsourceArea; + here->B3SOIDDcdbox = model->B3SOIDDcbox*here->B3SOIDDdrainArea; + here->B3SOIDDcdmin = model->B3SOIDDcsdmin*here->B3SOIDDdrainArea; + + if ( ((pParam->B3SOIDDnsub > 0) && (model->B3SOIDDtype > 0)) || + ((pParam->B3SOIDDnsub < 0) && (model->B3SOIDDtype < 0)) ) + { + T0 = pParam->B3SOIDDvsdth - pParam->B3SOIDDvsdfb; + pParam->B3SOIDDsdt1 = pParam->B3SOIDDvsdfb + model->B3SOIDDasd * T0; + T1 = here->B3SOIDDcsbox - here->B3SOIDDcsmin; + T2 = T1 / T0 / T0; + pParam->B3SOIDDst2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDst3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDst4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcsmin * pParam->B3SOIDDvsdfb; + + T1 = here->B3SOIDDcdbox - here->B3SOIDDcdmin; + T2 = T1 / T0 / T0; + pParam->B3SOIDDdt2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDdt3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDdt4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcdmin * pParam->B3SOIDDvsdfb; + } else + { + T0 = pParam->B3SOIDDvsdfb - pParam->B3SOIDDvsdth; + pParam->B3SOIDDsdt1 = pParam->B3SOIDDvsdth + model->B3SOIDDasd * T0; + T1 = here->B3SOIDDcsmin - here->B3SOIDDcsbox; + T2 = T1 / T0 / T0; + pParam->B3SOIDDst2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDst3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDst4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcsbox * pParam->B3SOIDDvsdth; + + T1 = here->B3SOIDDcdmin - here->B3SOIDDcdbox; + T2 = T1 / T0 / T0; + pParam->B3SOIDDdt2 = T2 / model->B3SOIDDasd; + pParam->B3SOIDDdt3 = T2 /( 1 - model->B3SOIDDasd); + here->B3SOIDDdt4 = T0 * T1 * (1 + model->B3SOIDDasd) / 3 + - here->B3SOIDDcdbox * pParam->B3SOIDDvsdth; + } + + here->B3SOIDDphi = pParam->B3SOIDDphi; + /* process source/drain series resistance */ + here->B3SOIDDdrainConductance = model->B3SOIDDsheetResistance + * here->B3SOIDDdrainSquares; + if (here->B3SOIDDdrainConductance > 0.0) + here->B3SOIDDdrainConductance = 1.0 + / here->B3SOIDDdrainConductance; + else + here->B3SOIDDdrainConductance = 0.0; + + here->B3SOIDDsourceConductance = model->B3SOIDDsheetResistance + * here->B3SOIDDsourceSquares; + if (here->B3SOIDDsourceConductance > 0.0) + here->B3SOIDDsourceConductance = 1.0 + / here->B3SOIDDsourceConductance; + else + here->B3SOIDDsourceConductance = 0.0; + here->B3SOIDDcgso = pParam->B3SOIDDcgso; + here->B3SOIDDcgdo = pParam->B3SOIDDcgdo; + + } + } + return(OK); +} + diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c b/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c new file mode 100644 index 000000000..916cdedf5 --- /dev/null +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddtrunc.c @@ -0,0 +1,52 @@ +/********** +Copyright 1999 Regents of the University of California. All rights reserved. +Author: 1998 Samuel Fung, Dennis Sinitsky and Stephen Tang +File: b3soiddtrunc.c 98/5/01 +**********/ + + +#include "ngspice.h" +#include +#include +#include "cktdefs.h" +#include "b3soidddef.h" +#include "sperror.h" +#include "suffix.h" + + +int +B3SOIDDtrunc(inModel,ckt,timeStep) +GENmodel *inModel; +register CKTcircuit *ckt; +double *timeStep; +{ +register B3SOIDDmodel *model = (B3SOIDDmodel*)inModel; +register B3SOIDDinstance *here; + +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + + for (; model != NULL; model = model->B3SOIDDnextModel) + { for (here = model->B3SOIDDinstances; here != NULL; + here = here->B3SOIDDnextInstance) + { +#ifdef STEPDEBUG + debugtemp = *timeStep; +#endif /* STEPDEBUG */ + CKTterr(here->B3SOIDDqb,ckt,timeStep); + CKTterr(here->B3SOIDDqg,ckt,timeStep); + CKTterr(here->B3SOIDDqd,ckt,timeStep); +#ifdef STEPDEBUG + if(debugtemp != *timeStep) + { printf("device %s reduces step from %g to %g\n", + here->B3SOIDDname,debugtemp,*timeStep); + } +#endif /* STEPDEBUG */ + } + } + return(OK); +} + + +