diff --git a/ChangeLog b/ChangeLog index 06767943b..1f582cfcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-05-22 Robert Larice + * src/spicelib/devices/hisim2/* : + hisim2, populate this new directory + with files from HiSIM_2.5.1_Release_20110407.zip + unchanged, from + HiSIM_2.5.1_Release_20110407/HiSIM_2.5.1_C-Code/hisim2/ + 2011-05-21 Robert Larice * src/spicelib/devices/hisimhv/hsmhvset.c : extend HSMHVunsetup() to process some more CKTmkVolt() generated nodes @@ -5,7 +12,7 @@ 2011-05-21 Holger Vogt * windisp.c, winprint.c, windisp.h, winprint.h, display.c xdisplay.c, - winmain.c: reduce compiler warnings + winmain.c: reduce compiler warnings 2011-05-20 Robert Larice * src/spicelib/devices/adms/admst/ngspiceMakefile.am.xml: diff --git a/src/spicelib/devices/hisim2/hisim2.h b/src/spicelib/devices/hisim2/hisim2.h new file mode 100644 index 000000000..39f10ce8e --- /dev/null +++ b/src/spicelib/devices/hisim2/hisim2.h @@ -0,0 +1,70 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hisim2.h + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "hsm2def.h" +#include "cktdefs.h" + +#ifndef _HiSIM2_H +#define _HiSIM2_H + +/* return value */ +#ifndef OK +#define HiSIM_OK 0 +#define HiSIM_ERROR 1 +#else +#define HiSIM_OK OK +#define HiSIM_ERROR E_PANIC +#endif + +/* MOS type */ +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif + +/* device working mode */ +#ifndef CMI_NORMAL_MODE +#define HiSIM_NORMAL_MODE 1 +#define HiSIM_REVERSE_MODE -1 +#else +#define HiSIM_NORMAL_MODE CMI_NORMAL_MODE +#define HiSIM_REVERSE_MODE CMI_REVERSE_MODE +#endif + +/* others */ +#ifndef NULL +#define NULL 0 +#endif + +#define HiSIM_FALSE 0 +#define HiSIM_TRUE 1 + +#ifdef __STDC__ +extern int HSM2evaluate +( + double ivds, + double ivgs, + double ivbs, + double vbs_jct, + double vbd_jct, + HSM2instance *here, + HSM2model *model, + CKTcircuit *ckt + ) ; +#else +extern int HSM2evaluate() ; +#endif + +#endif /* _HiSIM2_H */ diff --git a/src/spicelib/devices/hisim2/hsm2.c b/src/spicelib/devices/hisim2/hsm2.c new file mode 100644 index 000000000..686cae54c --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2.c @@ -0,0 +1,608 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "devdefs.h" +#include "hsm2def.h" +#include "suffix.h" + +IFparm HSM2pTable[] = { /* parameters */ + IOP( "l", HSM2_L, IF_REAL , "Length"), + IOP( "w", HSM2_W, IF_REAL , "Width"), + IOP( "ad", HSM2_AD, IF_REAL , "Drain area"), + IOP( "as", HSM2_AS, IF_REAL , "Source area"), + IOP( "pd", HSM2_PD, IF_REAL , "Drain perimeter"), + IOP( "ps", HSM2_PS, IF_REAL , "Source perimeter"), + IOP( "nrd", HSM2_NRD, IF_REAL , "Number of squares in drain"), + IOP( "nrs", HSM2_NRS, IF_REAL , "Number of squares in source"), + IOP( "temp", HSM2_TEMP, IF_REAL , "Lattice temperature [K]"), + IOP( "dtemp", HSM2_DTEMP,IF_REAL , ""), + IOP( "off", HSM2_OFF, IF_FLAG , "Device is initially off"), + IP ( "ic", HSM2_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), + IOP("corbnet", HSM2_CORBNET, IF_INTEGER, "activate body resistance (1) or not (0)"), + IOP("rbpb", HSM2_RBPB, IF_REAL, ""), + IOP("rbpd", HSM2_RBPD, IF_REAL, ""), + IOP("rbps", HSM2_RBPS, IF_REAL, ""), + IOP("rbdb", HSM2_RBDB, IF_REAL, ""), + IOP("rbsb", HSM2_RBSB, IF_REAL, ""), + IOP("corg", HSM2_CORG, IF_INTEGER, "activate gate resistance (1) or not (0)"), +/* IOP("rshg", HSM2_RSHG, IF_REAL, "gate-elecrode sheet resistance"), */ + IOP("ngcon", HSM2_NGCON, IF_REAL, "number of gate contacts"), + IOP("xgw", HSM2_XGW, IF_REAL, "distance from gate contact to channel edge"), + IOP("xgl", HSM2_XGL, IF_REAL, "offset of gate length due to variation in patterning"), + IOP("nf", HSM2_NF, IF_REAL, "number of fingers"), + IOP("sa", HSM2_SA, IF_REAL, "distance from STI edge to Gate edge [m]"), + IOP("sb", HSM2_SB, IF_REAL, "distance from STI edge to Gate edge [m]"), + IOP("sd", HSM2_SD, IF_REAL, "distance from Gate edge to Gate edge [m]"), + IOP("nsubcdfm", HSM2_NSUBCDFM, IF_REAL, "constant part of Nsub for DFM [1/cm^3]"), + IOP("mphdfm", HSM2_MPHDFM, IF_REAL, "NSUBCDFM dependence of phonon scattering for DFM"), + IOP("m", HSM2_M, IF_REAL, "Multiplication factor [-]"), + /* Output Physical Values: */ + OP ( "ids", HSM2_CD, IF_REAL , "Ids"), /* Drain-Source current */ + OP ( "isub", HSM2_ISUB, IF_REAL , "Isub"), /* Substrate current */ + OP ( "igidl", HSM2_IGIDL, IF_REAL , "Igidl"), /* Gate-Induced Drain Leakage current */ + OP ( "igisl", HSM2_IGISL, IF_REAL , "Igisl"), /* Gate-Induced Source Leakage current */ + OP ( "igd", HSM2_IGD, IF_REAL , "Igd"), /* Gate-Drain current */ + OP ( "igs", HSM2_IGS, IF_REAL , "Igs"), /* Gate-Source current */ + OP ( "igb", HSM2_IGB, IF_REAL , "Igb"), /* Gate-Substrate current */ + OP ( "gm", HSM2_GM, IF_REAL , "Gm"), /* Transconductance */ + OP ( "gds", HSM2_GDS, IF_REAL , "Gds"), /* Channel conductance */ + OP ( "gmbs", HSM2_GMBS, IF_REAL , "Gmbs"), /* Body effect (Back gate) transconductance */ + OP ( "von", HSM2_VON, IF_REAL , "Von"), /* Threshold voltage */ + OP ( "vdsat", HSM2_VDSAT, IF_REAL , "Vdsat"), /* Saturation voltage */ + OP ( "qb", HSM2_QB, IF_REAL , "Qb"), /* Bulk charge */ + OP ( "qg", HSM2_QG, IF_REAL , "Qg"), /* Gate charge */ + OP ( "qd", HSM2_QD, IF_REAL , "Qd"), /* Drain charge */ + OP ( "cgg", HSM2_CGG, IF_REAL , "Cgg"), /* MOSFET capacitance */ + OP ( "cgd", HSM2_CGD, IF_REAL , "Cgd"), /* MOSFET capacitance */ + OP ( "cgs", HSM2_CGS, IF_REAL , "Cgs"), /* MOSFET capacitance */ + OP ( "cbg", HSM2_CBG, IF_REAL , "Cbg"), /* MOSFET capacitance */ + OP ( "cbs", HSM2_CBSB, IF_REAL , "Cbs"), /* MOSFET capacitance */ + OP ( "cbd", HSM2_CBDB, IF_REAL , "Cbd"), /* MOSFET capacitance */ + OP ( "cdg", HSM2_CDG, IF_REAL , "Cdg"), /* MOSFET capacitance */ + OP ( "cdd", HSM2_CDD, IF_REAL , "Cdd"), /* MOSFET capacitance */ + OP ( "cds", HSM2_CDS, IF_REAL , "Cds"), /* MOSFET capacitance */ + OP ( "cgdo", HSM2_CGDO, IF_REAL , "Cgdo"), /* MOSFET overlap capacitance */ + OP ( "cgso", HSM2_CGSO, IF_REAL , "Cgso"), /* MOSFET overlap capacitance */ + OP ( "cgbo", HSM2_CGBO, IF_REAL , "Cgbo"), /* MOSFET overlap capacitance */ + OP ( "ibd", HSM2_CBD, IF_REAL , "Ibd"), /* Diode current */ + OP ( "ibs", HSM2_CBS, IF_REAL , "Ibs"), /* Diode current */ + OP ( "gbd", HSM2_GBD, IF_REAL , "Gbd"), /* Diode conductance */ + OP ( "gbs", HSM2_GBS, IF_REAL , "Gbs"), /* Diode conductance */ + OP ( "capbd", HSM2_CAPBD, IF_REAL , "Capbd"), /* Diode capacitance */ + OP ( "capbs", HSM2_CAPBS, IF_REAL , "Capbs") /* Diode capacitance */ +}; + +IFparm HSM2mPTable[] = { /* model parameters */ + IP("nmos", HSM2_MOD_NMOS, IF_FLAG, ""), + IP("pmos", HSM2_MOD_PMOS, IF_FLAG, ""), + IOP("level", HSM2_MOD_LEVEL, IF_INTEGER, ""), + IOP("info", HSM2_MOD_INFO, IF_INTEGER, "information level (for debug, etc.)"), + IOP("noise", HSM2_MOD_NOISE, IF_INTEGER, "noise model selector"), + IOP("version", HSM2_MOD_VERSION, IF_INTEGER, "model version 220"), + IOP("show", HSM2_MOD_SHOW, IF_INTEGER, "show physical value"), + IOP("corsrd", HSM2_MOD_CORSRD, IF_INTEGER, "solve equations accounting Rs and Rd."), + IOP("corg", HSM2_MOD_CORG, IF_INTEGER, "solve equations accounting Rg."), + IOP("coiprv", HSM2_MOD_COIPRV, IF_INTEGER, "use ids_prv as initial guess of Ids (internal flag)"), + IOP("copprv", HSM2_MOD_COPPRV, IF_INTEGER, "use ps{0/l}_prv as initial guess of Ps{0/l} (internal flag)"), + IOP("coadov", HSM2_MOD_COADOV, IF_INTEGER, "add overlap to intrisic"), + IOP("coisub", HSM2_MOD_COISUB, IF_INTEGER, "calculate isub"), + IOP("coiigs", HSM2_MOD_COIIGS, IF_INTEGER, "calculate igate"), + IOP("cogidl", HSM2_MOD_COGIDL, IF_INTEGER, "calculate igidl"), + IOP("coovlp", HSM2_MOD_COOVLP, IF_INTEGER, "calculate overlap charge"), + IOP("coflick", HSM2_MOD_COFLICK, IF_INTEGER, "calculate 1/f noise"), + IOP("coisti", HSM2_MOD_COISTI, IF_INTEGER, "calculate STI"), + IOP("conqs", HSM2_MOD_CONQS, IF_INTEGER, "calculate in nqs mode or qs mode"), + IOP("corbnet", HSM2_MOD_CORBNET, IF_INTEGER, ""), + IOP("cothrml", HSM2_MOD_COTHRML, IF_INTEGER, "calculate thermal noise"), + IOP("coign", HSM2_MOD_COIGN, IF_INTEGER, "calculate induced gate noise"), + IOP("codfm", HSM2_MOD_CODFM, IF_INTEGER, "calculation of model for DFM"), + IOP("corecip", HSM2_MOD_CORECIP, IF_INTEGER, "capacitance reciprocity takes first priority"), + IOP("coqy", HSM2_MOD_COQY, IF_INTEGER, "calculate lateral-field-induced charge/capacitance"), + IOP("coqovsm", HSM2_MOD_COQOVSM, IF_INTEGER, "select smoothing method of Qover"), + IOP("vmax", HSM2_MOD_VMAX, IF_REAL, "saturation velocity [cm/s"), + IOP("bgtmp1", HSM2_MOD_BGTMP1, IF_REAL, "first order temp. coeff. for band gap [V/K]"), + IOP("bgtmp2", HSM2_MOD_BGTMP2, IF_REAL, "second order temp. coeff. for band gap [V/K^2]"), + IOP("eg0", HSM2_MOD_EG0, IF_REAL, ""), + IOP("tox", HSM2_MOD_TOX, IF_REAL, "oxide thickness [m]"), + IOP("xld", HSM2_MOD_XLD, IF_REAL, "lateral diffusion of S/D under the gate [m]"), + IOP("lover", HSM2_MOD_LOVER, IF_REAL, "overlap length"), + IOP("ddltmax", HSM2_MOD_DDLTMAX, IF_REAL, ""), /* Vdseff */ + IOP("ddltslp", HSM2_MOD_DDLTSLP, IF_REAL, ""), /* Vdseff */ + IOP("ddltict", HSM2_MOD_DDLTICT, IF_REAL, ""), /* Vdseff */ + IOP("vfbover", HSM2_MOD_VFBOVER, IF_REAL, ""), + IOP("nover", HSM2_MOD_NOVER, IF_REAL, ""), + IOP("xwd", HSM2_MOD_XWD, IF_REAL, "lateral diffusion along the width dir. [m]"), + IOP("xl", HSM2_MOD_XL, IF_REAL, "gate length offset due to mask/etch effect [m]"), + IOP("xw", HSM2_MOD_XW, IF_REAL, "gate width offset due to mask/etch effect [m]"), + IOP("saref", HSM2_MOD_SAREF, IF_REAL, "reference distance from STI edge to Gate edge [m]"), + IOP("sbref", HSM2_MOD_SBREF, IF_REAL, "reference distance from STI edge to Gate edge [m]"), + IOP("ll", HSM2_MOD_LL, IF_REAL, "gate length parameter"), + IOP("lld", HSM2_MOD_LLD, IF_REAL, "gate length parameter"), + IOP("lln", HSM2_MOD_LLN, IF_REAL, "gate length parameter"), + IOP("wl", HSM2_MOD_WL, IF_REAL, "gate width parameter"), + IOP("wl1", HSM2_MOD_WL1, IF_REAL, "gate width parameter"), + IOP("wl1p", HSM2_MOD_WL1P, IF_REAL, "gate width parameter"), + IOP("wl2", HSM2_MOD_WL2, IF_REAL, "gate width parameter"), + IOP("wl2p", HSM2_MOD_WL2P, IF_REAL, "gate width parameter"), + IOP("wld", HSM2_MOD_WLD, IF_REAL, "gate width parameter"), + IOP("wln", HSM2_MOD_WLN, IF_REAL, "gate width parameter"), + IOP("xqy", HSM2_MOD_XQY, IF_REAL, "[m]"), + IOP("xqy1", HSM2_MOD_XQY1, IF_REAL, "[F m^{XQY2}]"), + IOP("xqy2", HSM2_MOD_XQY2, IF_REAL, "[-]"), + IOP("qyrat", HSM2_MOD_QYRAT, IF_REAL, ""), + IOP("rs", HSM2_MOD_RS, IF_REAL, "source contact resistance [ohm m]"), + IOP("rd", HSM2_MOD_RD, IF_REAL, "drain contact resistance [ohm m]"), + IOP("rsh", HSM2_MOD_RSH, IF_REAL, "source/drain diffusion sheet resistance [ohm]"), + IOP("rshg", HSM2_MOD_RSHG, IF_REAL, "gate-elecrode sheet resistance"), +/* IOP("ngcon", HSM2_MOD_NGCON, IF_REAL, "number of gate contacts"), */ +/* IOP("xgw", HSM2_MOD_XGW, IF_REAL, "distance from gate contact to channel edge"), */ +/* IOP("xgl", HSM2_MOD_XGL, IF_REAL, "offset of gate length due to variation in patterning"), */ +/* IOP("nf", HSM2_MOD_NF, IF_REAL, "number of fingers"), */ + IOP("vfbc", HSM2_MOD_VFBC, IF_REAL, "constant part of Vfb [V]"), + IOP("vbi", HSM2_MOD_VBI, IF_REAL, "built-in potential [V]"), + IOP("nsubc", HSM2_MOD_NSUBC, IF_REAL, "constant part of Nsub [1/cm^3]"), + IOP("parl2", HSM2_MOD_PARL2, IF_REAL, "under diffusion [m]"), + IOP("lp", HSM2_MOD_LP, IF_REAL, "length of pocket potential [m]"), + IOP("nsubp", HSM2_MOD_NSUBP, IF_REAL, "[1/cm^3]"), + IOP("nsubpl", HSM2_MOD_NSUBPL, IF_REAL, "gate-length dependence of NSUBP"), + IOP("nsubpfac", HSM2_MOD_NSUBPFAC, IF_REAL, "gate-length dependence of NSUBP"), + IOP("nsubpw", HSM2_MOD_NSUBPW, IF_REAL, "pocket implant parameter"), + IOP("nsubpwp", HSM2_MOD_NSUBPWP, IF_REAL, "pocket implant parameter"), + IOP("scp1", HSM2_MOD_SCP1, IF_REAL, "parameter for pocket [-]"), + IOP("scp2", HSM2_MOD_SCP2, IF_REAL, "parameter for pocket [1/V]"), + IOP("scp3", HSM2_MOD_SCP3, IF_REAL, "parameter for pocket [m/V]"), + IOP("sc1", HSM2_MOD_SC1, IF_REAL, "parameter for SCE [-]"), + IOP("sc2", HSM2_MOD_SC2, IF_REAL, "parameter for SCE [1/V]"), + IOP("sc3", HSM2_MOD_SC3, IF_REAL, "parameter for SCE [m/V]"), + IOP("sc4", HSM2_MOD_SC4, IF_REAL, "parameter for SCE []"), + IOP("pgd1", HSM2_MOD_PGD1, IF_REAL, "parameter for gate-poly depletion [V]"), + IOP("pgd2", HSM2_MOD_PGD2, IF_REAL, "parameter for gate-poly depletion [V]"), +//IOP("pgd3", HSM2_MOD_PGD3, IF_REAL, "parameter for gate-poly depletion [-]"), + IOP("pgd4", HSM2_MOD_PGD4, IF_REAL, "parameter for gate-poly depletion [-]"), + IOP("ndep", HSM2_MOD_NDEP, IF_REAL, "coeff. of Qbm for Eeff [-]"), + IOP("ndepl", HSM2_MOD_NDEPL, IF_REAL, "coeff. of Qbm for Eeff [-]"), + IOP("ndeplp", HSM2_MOD_NDEPLP, IF_REAL, "coeff. of Qbm for Eeff [-]"), + IOP("ndepw", HSM2_MOD_NDEPW, IF_REAL, "coeff. of Qbm for Eeff [-]"), + IOP("ndepwp", HSM2_MOD_NDEPWP, IF_REAL, "coeff. of Qbm for Eeff [-]"), + IOP("ninv", HSM2_MOD_NINV, IF_REAL, "coeff. of Qnm for Eeff [-]"), + IOP("ninvd", HSM2_MOD_NINVD, IF_REAL, "modification of Vdse dependence on Eeff [1/V]"), + IOP("muecb0", HSM2_MOD_MUECB0, IF_REAL, "const. part of coulomb scattering [cm^2/Vs]"), + IOP("muecb1", HSM2_MOD_MUECB1, IF_REAL, "coeff. for coulomb scattering [cm^2/Vs]"), + IOP("mueph0", HSM2_MOD_MUEPH0, IF_REAL, "power of Eeff for phonon scattering [-]"), + IOP("mueph1", HSM2_MOD_MUEPH1, IF_REAL, ""), + IOP("muephw", HSM2_MOD_MUEPHW, IF_REAL, ""), + IOP("muepwp", HSM2_MOD_MUEPWP, IF_REAL, "phonon scattering parameter"), + IOP("muepwd", HSM2_MOD_MUEPWD, IF_REAL, "phonon scattering parameter"), + IOP("muephl", HSM2_MOD_MUEPHL, IF_REAL, "phonon scattering parameter"), + IOP("mueplp", HSM2_MOD_MUEPLP, IF_REAL, "phonon scattering parameter"), + IOP("muepld", HSM2_MOD_MUEPLD, IF_REAL, "phonon scattering parameter"), + IOP("muephs", HSM2_MOD_MUEPHS, IF_REAL, ""), + IOP("muepsp", HSM2_MOD_MUEPSP, IF_REAL, ""), + IOP("vtmp", HSM2_MOD_VTMP, IF_REAL, ""), + IOP("wvth0", HSM2_MOD_WVTH0, IF_REAL, ""), + IOP("muesr0", HSM2_MOD_MUESR0, IF_REAL, "power of Eeff for S.R. scattering [-]"), + IOP("muesr1", HSM2_MOD_MUESR1, IF_REAL, "coeff. for S.R. scattering [-]"), + IOP("muesrl", HSM2_MOD_MUESRL, IF_REAL, "surface roughness parameter"), + IOP("muesrw", HSM2_MOD_MUESRW, IF_REAL, "change of surface roughness related mobility"), + IOP("mueswp", HSM2_MOD_MUESWP, IF_REAL, "change of surface roughness related mobility"), + IOP("mueslp", HSM2_MOD_MUESLP, IF_REAL, "surface roughness parameter"), + IOP("muetmp", HSM2_MOD_MUETMP, IF_REAL, "parameter for mobility [-]"), + IOP("bb", HSM2_MOD_BB, IF_REAL, "empirical mobility model coefficient [-]"), + IOP("sub1", HSM2_MOD_SUB1, IF_REAL, "parameter for Isub [1/V]"), + IOP("sub2", HSM2_MOD_SUB2, IF_REAL, "parameter for Isub [V]"), + IOP("svgs", HSM2_MOD_SVGS, IF_REAL, "coefficient for Vg of Psislsat"), + IOP("svbs", HSM2_MOD_SVBS, IF_REAL, "coefficient for Vbs of Psislsat"), + IOP("svbsl", HSM2_MOD_SVBSL, IF_REAL, " "), + IOP("svds", HSM2_MOD_SVDS, IF_REAL, " "), + IOP("slg", HSM2_MOD_SLG, IF_REAL, " "), + IOP("sub1l", HSM2_MOD_SUB1L, IF_REAL, " "), + IOP("sub2l", HSM2_MOD_SUB2L, IF_REAL, " "), + IOP("svgsl", HSM2_MOD_SVGSL, IF_REAL, " "), + IOP("svgslp", HSM2_MOD_SVGSLP, IF_REAL, " "), + IOP("svgswp", HSM2_MOD_SVGSWP, IF_REAL, " "), + IOP("svgsw", HSM2_MOD_SVGSW, IF_REAL, " "), + IOP("svbslp", HSM2_MOD_SVBSLP, IF_REAL, " "), + IOP("slgl", HSM2_MOD_SLGL, IF_REAL, " "), + IOP("slglp", HSM2_MOD_SLGLP, IF_REAL, " "), + IOP("sub1lp", HSM2_MOD_SUB1LP, IF_REAL, " "), + IOP("nsti", HSM2_MOD_NSTI, IF_REAL, "parameter for STI [1/cm^3]"), + IOP("wsti", HSM2_MOD_WSTI, IF_REAL, "parameter for STI [m]"), + IOP("wstil", HSM2_MOD_WSTIL, IF_REAL, "parameter for STI [?]"), + IOP("wstilp", HSM2_MOD_WSTILP, IF_REAL, "parameter for STI [?]"), + IOP("wstiw", HSM2_MOD_WSTIW, IF_REAL, "parameter for STI [?]"), + IOP("wstiwp", HSM2_MOD_WSTIWP, IF_REAL, "parameter for STI [?]"), + IOP("scsti1", HSM2_MOD_SCSTI1, IF_REAL, "parameter for STI [-]"), + IOP("scsti2", HSM2_MOD_SCSTI2, IF_REAL, "parameter for STI [1/V]"), + IOP("vthsti", HSM2_MOD_VTHSTI, IF_REAL, "parameter for STI"), + IOP("vdsti", HSM2_MOD_VDSTI, IF_REAL, "parameter for STI [-]"), + IOP("muesti1", HSM2_MOD_MUESTI1, IF_REAL, "STI Stress mobility parameter"), + IOP("muesti2", HSM2_MOD_MUESTI2, IF_REAL, "STI Stress mobility parameter"), + IOP("muesti3", HSM2_MOD_MUESTI3, IF_REAL, "STI Stress mobility parameter"), + IOP("nsubpsti1", HSM2_MOD_NSUBPSTI1, IF_REAL, "STI Stress pocket impla parameter"), + IOP("nsubpsti2", HSM2_MOD_NSUBPSTI2, IF_REAL, "STI Stress pocket impla parameter"), + IOP("nsubpsti3", HSM2_MOD_NSUBPSTI3, IF_REAL, "STI Stress pocket impla parameter"), + IOP("lpext", HSM2_MOD_LPEXT, IF_REAL, "Pocket extension"), + IOP("npext", HSM2_MOD_NPEXT, IF_REAL, "Pocket extension"), + IOP("npextw", HSM2_MOD_NPEXTW, IF_REAL, "new model parameter NPEXTW"), + IOP("npextwp", HSM2_MOD_NPEXTWP, IF_REAL, "new model parameter NPEXTWP"), + IOP("scp22", HSM2_MOD_SCP22, IF_REAL, ""), + IOP("scp21", HSM2_MOD_SCP21, IF_REAL, ""), + IOP("bs1", HSM2_MOD_BS1, IF_REAL, ""), + IOP("bs2", HSM2_MOD_BS2, IF_REAL, ""), + IOP("cgso", HSM2_MOD_CGSO, IF_REAL, "G-S overlap capacitance per unit W [F/m]"), + IOP("cgdo", HSM2_MOD_CGDO, IF_REAL, "G-D overlap capacitance per unit W [F/m]"), + IOP("cgbo", HSM2_MOD_CGBO, IF_REAL, "G-B overlap capacitance per unit L [F/m]"), + IOP("tpoly", HSM2_MOD_TPOLY, IF_REAL, "hight of poly gate [m]"), + IOP("js0", HSM2_MOD_JS0, IF_REAL, "Saturation current density [A/m^2]"), + IOP("js0sw", HSM2_MOD_JS0SW, IF_REAL, "Side wall saturation current density [A/m]"), + IOP("nj", HSM2_MOD_NJ, IF_REAL, "Emission coefficient [-]"), + IOP("njsw", HSM2_MOD_NJSW, IF_REAL, "Sidewall emission coefficient"), + IOP("xti", HSM2_MOD_XTI, IF_REAL, "Junction current temparature exponent coefficient [-]"), + IOP("cj", HSM2_MOD_CJ, IF_REAL, "Bottom junction capacitance per unit area at zero bias [F/m^2]"), + IOP("cjsw", HSM2_MOD_CJSW, IF_REAL, "Source/drain sidewall junction capacitance grading coefficient per unit length at zero bias [F/m]"), + IOP("cjswg", HSM2_MOD_CJSWG, IF_REAL, "Source/drain gate sidewall junction capacitance per unit length at zero bias [F/m]"), + IOP("mj", HSM2_MOD_MJ, IF_REAL, "Bottom junction capacitance grading coefficient"), + IOP("mjsw", HSM2_MOD_MJSW, IF_REAL, "Source/drain sidewall junction capacitance grading coefficient"), + IOP("mjswg", HSM2_MOD_MJSWG, IF_REAL, "Source/drain gate sidewall junction capacitance grading coefficient"), + IOP("pb", HSM2_MOD_PB, IF_REAL, "Bottom junction build-in potential [V]"), + IOP("pbsw", HSM2_MOD_PBSW, IF_REAL, "Source/drain sidewall junction build-in potential [V]"), + IOP("pbswg", HSM2_MOD_PBSWG, IF_REAL, "Source/drain gate sidewall junction build-in potential [V]"), + + IOP("tcjbd", HSM2_MOD_TCJBD, IF_REAL, "Temperature dependence of czbd"), + IOP("tcjbs", HSM2_MOD_TCJBS, IF_REAL, "Temperature dependence of czbs"), + IOP("tcjbdsw", HSM2_MOD_TCJBDSW, IF_REAL, "Temperature dependence of czbdsw"), + IOP("tcjbssw", HSM2_MOD_TCJBSSW, IF_REAL, "Temperature dependence of czbssw"), + IOP("tcjbdswg", HSM2_MOD_TCJBDSWG, IF_REAL, "Temperature dependence of czbdswg"), + IOP("tcjbsswg", HSM2_MOD_TCJBSSWG, IF_REAL, "Temperature dependence of czbsswg"), + + IOP("xti2", HSM2_MOD_XTI2, IF_REAL, " temperature coefficient [-]"), + IOP("cisb", HSM2_MOD_CISB, IF_REAL, " reverse bias saturation current [-]"), + IOP("cvb", HSM2_MOD_CVB, IF_REAL, " bias dependence coefficient of cisb [-]"), + IOP("ctemp", HSM2_MOD_CTEMP, IF_REAL, " temperature coefficient [-]"), + IOP("cisbk", HSM2_MOD_CISBK, IF_REAL, " reverse bias saturation current [A]"), + IOP("cvbk", HSM2_MOD_CVBK, IF_REAL, " bias dependence coefficient of cisb [-]"), + IOP("divx", HSM2_MOD_DIVX, IF_REAL, " [1/V]"), + + IOP("clm1", HSM2_MOD_CLM1, IF_REAL, "parameter for CLM [-]"), + IOP("clm2", HSM2_MOD_CLM2, IF_REAL, "parameter for CLM [1/m]"), + IOP("clm3", HSM2_MOD_CLM3, IF_REAL, "parameter for CLM [-]"), + IOP("clm5", HSM2_MOD_CLM5, IF_REAL, "parameter for CLM [-]"), + IOP("clm6", HSM2_MOD_CLM6, IF_REAL, "parameter for CLM [um^{-clm5}]"), + IOP("vover", HSM2_MOD_VOVER, IF_REAL, "parameter for overshoot [m^{voverp}]"), + IOP("voverp", HSM2_MOD_VOVERP, IF_REAL, "parameter for overshoot [-]"), + IOP("vovers", HSM2_MOD_VOVERS, IF_REAL, "parameter for overshoot [-]"), + IOP("voversp", HSM2_MOD_VOVERSP, IF_REAL, "parameter for overshoot [-]"), + + IOP("wfc", HSM2_MOD_WFC, IF_REAL, "parameter for narrow channel effect [m*F/(cm^2)]"), + IOP("nsubcw", HSM2_MOD_NSUBCW, IF_REAL, "Parameter for narrow channel effect "), + IOP("nsubcwp", HSM2_MOD_NSUBCWP, IF_REAL, "Parameter for narrow channel effect "), + IOP("nsubcmax", HSM2_MOD_NSUBCMAX, IF_REAL, "Parameter for narrow channel effect "), + IOP("qme1", HSM2_MOD_QME1, IF_REAL, "parameter for quantum effect [mV]"), + IOP("qme2", HSM2_MOD_QME2, IF_REAL, "parameter for quantum effect [V]"), + IOP("qme3", HSM2_MOD_QME3, IF_REAL, "parameter for quantum effect [m]"), + IOP("gidl1", HSM2_MOD_GIDL1, IF_REAL, "parameter for GIDL [?]"), + IOP("gidl2", HSM2_MOD_GIDL2, IF_REAL, "parameter for GIDL [?]"), + IOP("gidl3", HSM2_MOD_GIDL3, IF_REAL, "parameter for GIDL [?]"), + IOP("gidl4", HSM2_MOD_GIDL4, IF_REAL, "parameter for GIDL [?]"), + IOP("gidl5", HSM2_MOD_GIDL5, IF_REAL, "parameter for GIDL [?]"), + IOP("gleak1", HSM2_MOD_GLEAK1, IF_REAL, "parameter for gate current [A*V^(-3/2)/C]"), + IOP("gleak2", HSM2_MOD_GLEAK2, IF_REAL, "parameter for gate current [V^(-1/2)/m ]"), + IOP("gleak3", HSM2_MOD_GLEAK3, IF_REAL, "parameter for gate current [-]"), + IOP("gleak4", HSM2_MOD_GLEAK4, IF_REAL, "parameter for gate current [1/m]"), + IOP("gleak5", HSM2_MOD_GLEAK5, IF_REAL, "parameter for gate current [V/m]"), + IOP("gleak6", HSM2_MOD_GLEAK6, IF_REAL, "parameter for gate current [V]"), + IOP("gleak7", HSM2_MOD_GLEAK7, IF_REAL, "parameter for gate current [m^2]"), + IOP("glksd1", HSM2_MOD_GLKSD1, IF_REAL, "parameter for gate current [A*m/V^2]"), + IOP("glksd2", HSM2_MOD_GLKSD2, IF_REAL, "parameter for gate current [1/(V*m)]"), + IOP("glksd3", HSM2_MOD_GLKSD3, IF_REAL, "parameter for gate current [1/m]"), + IOP("glkb1", HSM2_MOD_GLKB1, IF_REAL, "parameter for gate current [A/V^2]"), + IOP("glkb2", HSM2_MOD_GLKB2, IF_REAL, "parameter for gate current [m/V]"), + IOP("glkb3", HSM2_MOD_GLKB3, IF_REAL, "parameter for gate current [V]"), + IOP("egig", HSM2_MOD_EGIG, IF_REAL, "parameter for gate current [V]"), + IOP("igtemp2", HSM2_MOD_IGTEMP2, IF_REAL, "parameter for gate current [V*k]"), + IOP("igtemp3", HSM2_MOD_IGTEMP3, IF_REAL, "parameter for gate current [V*k^2]"), + IOP("vzadd0", HSM2_MOD_VZADD0, IF_REAL, "Vzadd at Vds=0 [V]"), + IOP("pzadd0", HSM2_MOD_PZADD0, IF_REAL, "Pzadd at Vds=0 [V]"), + IOP("nftrp", HSM2_MOD_NFTRP, IF_REAL, ""), + IOP("nfalp", HSM2_MOD_NFALP, IF_REAL, ""), + IOP("falph", HSM2_MOD_FALPH, IF_REAL, "parameter for 1/f noise"), + IOP("cit", HSM2_MOD_CIT, IF_REAL, ""), + IOP("kappa", HSM2_MOD_KAPPA, IF_REAL, "dielectric constant for high-k stacked gate"), + IOP("vdiffj", HSM2_MOD_VDIFFJ, IF_REAL, "threshold voltage for S/D junction diode [V]"), + IOP("dly1", HSM2_MOD_DLY1, IF_REAL, "parameter for transit time [-]"), + IOP("dly2", HSM2_MOD_DLY2, IF_REAL, "parameter for transit time [-]"), + IOP("dly3", HSM2_MOD_DLY3, IF_REAL, "parameter for trandforming bulk charge [s/F]"), + IOP("tnom", HSM2_MOD_TNOM, IF_REAL, "nominal temperature [K]"), + IOP("ovslp", HSM2_MOD_OVSLP, IF_REAL, ""), + IOP("ovmag", HSM2_MOD_OVMAG, IF_REAL, ""), + + IOP("gbmin", HSM2_MOD_GBMIN, IF_REAL, ""), + IOP("rbpb", HSM2_MOD_RBPB, IF_REAL, ""), + IOP("rbpd", HSM2_MOD_RBPD, IF_REAL, ""), + IOP("rbps", HSM2_MOD_RBPS, IF_REAL, ""), + IOP("rbdb", HSM2_MOD_RBDB, IF_REAL, ""), + IOP("rbsb", HSM2_MOD_RBSB, IF_REAL, ""), + + IOP("ibpc1", HSM2_MOD_IBPC1, IF_REAL, "parameter for Impact-Ionization Induced Bulk Potential Change"), + IOP("ibpc2", HSM2_MOD_IBPC2, IF_REAL, "parameter for Impact-Ionization Induced Bulk Potential Change"), + + IOP("mphdfm", HSM2_MOD_MPHDFM, IF_REAL, "NSUBCDFM dependence of phonon scattering for DFM"), + + + IOP("ptl", HSM2_MOD_PTL, IF_REAL, ""), + IOP("ptp", HSM2_MOD_PTP, IF_REAL, ""), + IOP("pt2", HSM2_MOD_PT2, IF_REAL, ""), + IOP("ptlp", HSM2_MOD_PTLP, IF_REAL, ""), + IOP("gdl", HSM2_MOD_GDL, IF_REAL, ""), + IOP("gdlp", HSM2_MOD_GDLP, IF_REAL, ""), + + IOP("gdld", HSM2_MOD_GDLD, IF_REAL, ""), + IOP("pt4", HSM2_MOD_PT4, IF_REAL, ""), + IOP("pt4p", HSM2_MOD_PT4P, IF_REAL, ""), + IOP("muephl2", HSM2_MOD_MUEPHL2, IF_REAL, ""), + IOP("mueplp2", HSM2_MOD_MUEPLP2, IF_REAL, ""), + IOP("nsubcw2", HSM2_MOD_NSUBCW2, IF_REAL, ""), + IOP("nsubcwp2", HSM2_MOD_NSUBCWP2, IF_REAL, ""), + IOP("muephw2", HSM2_MOD_MUEPHW2, IF_REAL, ""), + IOP("muepwp2", HSM2_MOD_MUEPWP2, IF_REAL, ""), + + IOP("vgsmin", HSM2_MOD_VGSMIN, IF_REAL, "minimal/maximal expected Vgs (NMOS/PMOS) [V]"), + IOP("sc3vbs", HSM2_MOD_SC3VBS, IF_REAL, "Vbs value for clamping sc3 [V]"), + IOP("byptol", HSM2_MOD_BYPTOL, IF_REAL, "BYP_TOL_FACTOR for bypass control"), + IOP("muecb0lp", HSM2_MOD_MUECB0LP, IF_REAL, "L dependence of MUECB0"), + IOP("muecb1lp", HSM2_MOD_MUECB1LP, IF_REAL, "L dependence of MUECB1"), + + + /* binning parameters */ + IOP("lmin", HSM2_MOD_LMIN, IF_REAL, "Minimum length for the model"), + IOP("lmax", HSM2_MOD_LMAX, IF_REAL, "Maximum length for the model"), + IOP("wmin", HSM2_MOD_WMIN, IF_REAL, "Minimum width for the model"), + IOP("wmax", HSM2_MOD_WMAX, IF_REAL, "Maximum width for the model"), + IOP("lbinn", HSM2_MOD_LBINN, IF_REAL, "L modulation coefficient for binning"), + IOP("wbinn", HSM2_MOD_WBINN, IF_REAL, "W modulation coefficient for binning"), + + /* Length dependence */ + IOP("lvmax", HSM2_MOD_LVMAX, IF_REAL, "Length dependence of vmax"), + IOP("lbgtmp1", HSM2_MOD_LBGTMP1, IF_REAL, "Length dependence of bgtmp1"), + IOP("lbgtmp2", HSM2_MOD_LBGTMP2, IF_REAL, "Length dependence of bgtmp2"), + IOP("leg0", HSM2_MOD_LEG0, IF_REAL, "Length dependence of eg0"), + IOP("llover", HSM2_MOD_LLOVER, IF_REAL, "Length dependence of lover"), + IOP("lvfbover", HSM2_MOD_LVFBOVER, IF_REAL, "Length dependence of vfbover"), + IOP("lnover", HSM2_MOD_LNOVER, IF_REAL, "Length dependence of nover"), + IOP("lwl2", HSM2_MOD_LWL2, IF_REAL, "Length dependence of wl2"), + IOP("lvfbc", HSM2_MOD_LVFBC, IF_REAL, "Length dependence of vfbc"), + IOP("lnsubc", HSM2_MOD_LNSUBC, IF_REAL, "Length dependence of nsubc"), + IOP("lnsubp", HSM2_MOD_LNSUBP, IF_REAL, "Length dependence of nsubp"), + IOP("lscp1", HSM2_MOD_LSCP1, IF_REAL, "Length dependence of scp1"), + IOP("lscp2", HSM2_MOD_LSCP2, IF_REAL, "Length dependence of scp2"), + IOP("lscp3", HSM2_MOD_LSCP3, IF_REAL, "Length dependence of scp3"), + IOP("lsc1", HSM2_MOD_LSC1, IF_REAL, "Length dependence of sc1"), + IOP("lsc2", HSM2_MOD_LSC2, IF_REAL, "Length dependence of sc2"), + IOP("lsc3", HSM2_MOD_LSC3, IF_REAL, "Length dependence of sc3"), + IOP("lsc4", HSM2_MOD_LSC4, IF_REAL, "Length dependence of sc4"), + IOP("lpgd1", HSM2_MOD_LPGD1, IF_REAL, "Length dependence of pgd1"), +//IOP("lpgd3", HSM2_MOD_LPGD3, IF_REAL, "Length dependence of pgd3"), + IOP("lndep", HSM2_MOD_LNDEP, IF_REAL, "Length dependence of ndep"), + IOP("lninv", HSM2_MOD_LNINV, IF_REAL, "Length dependence of ninv"), + IOP("lmuecb0", HSM2_MOD_LMUECB0, IF_REAL, "Length dependence of muecb0"), + IOP("lmuecb1", HSM2_MOD_LMUECB1, IF_REAL, "Length dependence of muecb1"), + IOP("lmueph1", HSM2_MOD_LMUEPH1, IF_REAL, "Length dependence of mueph1"), + IOP("lvtmp", HSM2_MOD_LVTMP, IF_REAL, "Length dependence of vtmp"), + IOP("lwvth0", HSM2_MOD_LWVTH0, IF_REAL, "Length dependence of wvth0"), + IOP("lmuesr1", HSM2_MOD_LMUESR1, IF_REAL, "Length dependence of muesr1"), + IOP("lmuetmp", HSM2_MOD_LMUETMP, IF_REAL, "Length dependence of muetmp"), + IOP("lsub1", HSM2_MOD_LSUB1, IF_REAL, "Length dependence of sub1"), + IOP("lsub2", HSM2_MOD_LSUB2, IF_REAL, "Length dependence of sub2"), + IOP("lsvds", HSM2_MOD_LSVDS, IF_REAL, "Length dependence of svds"), + IOP("lsvbs", HSM2_MOD_LSVBS, IF_REAL, "Length dependence of svbs"), + IOP("lsvgs", HSM2_MOD_LSVGS, IF_REAL, "Length dependence of svgs"), + IOP("lnsti", HSM2_MOD_LNSTI, IF_REAL, "Length dependence of nsti"), + IOP("lwsti", HSM2_MOD_LWSTI, IF_REAL, "Length dependence of wsti"), + IOP("lscsti1", HSM2_MOD_LSCSTI1, IF_REAL, "Length dependence of scsti1"), + IOP("lscsti2", HSM2_MOD_LSCSTI2, IF_REAL, "Length dependence of scsti2"), + IOP("lvthsti", HSM2_MOD_LVTHSTI, IF_REAL, "Length dependence of vthsti"), + IOP("lmuesti1", HSM2_MOD_LMUESTI1, IF_REAL, "Length dependence of muesti1"), + IOP("lmuesti2", HSM2_MOD_LMUESTI2, IF_REAL, "Length dependence of muesti2"), + IOP("lmuesti3", HSM2_MOD_LMUESTI3, IF_REAL, "Length dependence of muesti3"), + IOP("lnsubpsti1", HSM2_MOD_LNSUBPSTI1, IF_REAL, "Length dependence of nsubpsti1"), + IOP("lnsubpsti2", HSM2_MOD_LNSUBPSTI2, IF_REAL, "Length dependence of nsubpsti2"), + IOP("lnsubpsti3", HSM2_MOD_LNSUBPSTI3, IF_REAL, "Length dependence of nsubpsti3"), + IOP("lcgso", HSM2_MOD_LCGSO, IF_REAL, "Length dependence of cgso"), + IOP("lcgdo", HSM2_MOD_LCGDO, IF_REAL, "Length dependence of cgdo"), + IOP("ljs0", HSM2_MOD_LJS0, IF_REAL, "Length dependence of js0"), + IOP("ljs0sw", HSM2_MOD_LJS0SW, IF_REAL, "Length dependence of js0sw"), + IOP("lnj", HSM2_MOD_LNJ, IF_REAL, "Length dependence of nj"), + IOP("lcisbk", HSM2_MOD_LCISBK, IF_REAL, "Length dependence of cisbk"), + IOP("lclm1", HSM2_MOD_LCLM1, IF_REAL, "Length dependence of clm1"), + IOP("lclm2", HSM2_MOD_LCLM2, IF_REAL, "Length dependence of clm2"), + IOP("lclm3", HSM2_MOD_LCLM3, IF_REAL, "Length dependence of clm3"), + IOP("lwfc", HSM2_MOD_LWFC, IF_REAL, "Length dependence of wfc"), + IOP("lgidl1", HSM2_MOD_LGIDL1, IF_REAL, "Length dependence of gidl1"), + IOP("lgidl2", HSM2_MOD_LGIDL2, IF_REAL, "Length dependence of gidl2"), + IOP("lgleak1", HSM2_MOD_LGLEAK1, IF_REAL, "Length dependence of gleak1"), + IOP("lgleak2", HSM2_MOD_LGLEAK2, IF_REAL, "Length dependence of gleak2"), + IOP("lgleak3", HSM2_MOD_LGLEAK3, IF_REAL, "Length dependence of gleak3"), + IOP("lgleak6", HSM2_MOD_LGLEAK6, IF_REAL, "Length dependence of gleak6"), + IOP("lglksd1", HSM2_MOD_LGLKSD1, IF_REAL, "Length dependence of glksd1"), + IOP("lglksd2", HSM2_MOD_LGLKSD2, IF_REAL, "Length dependence of glksd2"), + IOP("lglkb1", HSM2_MOD_LGLKB1, IF_REAL, "Length dependence of glkb1"), + IOP("lglkb2", HSM2_MOD_LGLKB2, IF_REAL, "Length dependence of glkb2"), + IOP("lnftrp", HSM2_MOD_LNFTRP, IF_REAL, "Length dependence of nftrp"), + IOP("lnfalp", HSM2_MOD_LNFALP, IF_REAL, "Length dependence of nfalp"), + IOP("lvdiffj", HSM2_MOD_LVDIFFJ, IF_REAL, "Length dependence of vdiffj"), + IOP("libpc1", HSM2_MOD_LIBPC1, IF_REAL, "Length dependence of ibpc1"), + IOP("libpc2", HSM2_MOD_LIBPC2, IF_REAL, "Length dependence of ibpc2"), + + /* Width dependence */ + IOP("wvmax", HSM2_MOD_WVMAX, IF_REAL, "Width dependence of vmax"), + IOP("wbgtmp1", HSM2_MOD_WBGTMP1, IF_REAL, "Width dependence of bgtmp1"), + IOP("wbgtmp2", HSM2_MOD_WBGTMP2, IF_REAL, "Width dependence of bgtmp2"), + IOP("weg0", HSM2_MOD_WEG0, IF_REAL, "Width dependence of eg0"), + IOP("wlover", HSM2_MOD_WLOVER, IF_REAL, "Width dependence of lover"), + IOP("wvfbover", HSM2_MOD_WVFBOVER, IF_REAL, "Width dependence of vfbover"), + IOP("wnover", HSM2_MOD_WNOVER, IF_REAL, "Width dependence of nover"), + IOP("wwl2", HSM2_MOD_WWL2, IF_REAL, "Width dependence of wl2"), + IOP("wvfbc", HSM2_MOD_WVFBC, IF_REAL, "Width dependence of vfbc"), + IOP("wnsubc", HSM2_MOD_WNSUBC, IF_REAL, "Width dependence of nsubc"), + IOP("wnsubp", HSM2_MOD_WNSUBP, IF_REAL, "Width dependence of nsubp"), + IOP("wscp1", HSM2_MOD_WSCP1, IF_REAL, "Width dependence of scp1"), + IOP("wscp2", HSM2_MOD_WSCP2, IF_REAL, "Width dependence of scp2"), + IOP("wscp3", HSM2_MOD_WSCP3, IF_REAL, "Width dependence of scp3"), + IOP("wsc1", HSM2_MOD_WSC1, IF_REAL, "Width dependence of sc1"), + IOP("wsc2", HSM2_MOD_WSC2, IF_REAL, "Width dependence of sc2"), + IOP("wsc3", HSM2_MOD_WSC3, IF_REAL, "Width dependence of sc3"), + IOP("wsc4", HSM2_MOD_WSC4, IF_REAL, "Width dependence of sc4"), + IOP("wpgd1", HSM2_MOD_WPGD1, IF_REAL, "Width dependence of pgd1"), +//IOP("wpgd3", HSM2_MOD_WPGD3, IF_REAL, "Width dependence of pgd3"), + IOP("wndep", HSM2_MOD_WNDEP, IF_REAL, "Width dependence of ndep"), + IOP("wninv", HSM2_MOD_WNINV, IF_REAL, "Width dependence of ninv"), + IOP("wmuecb0", HSM2_MOD_WMUECB0, IF_REAL, "Width dependence of muecb0"), + IOP("wmuecb1", HSM2_MOD_WMUECB1, IF_REAL, "Width dependence of muecb1"), + IOP("wmueph1", HSM2_MOD_WMUEPH1, IF_REAL, "Width dependence of mueph1"), + IOP("wvtmp", HSM2_MOD_WVTMP, IF_REAL, "Width dependence of vtmp"), + IOP("wwvth0", HSM2_MOD_WWVTH0, IF_REAL, "Width dependence of wvth0"), + IOP("wmuesr1", HSM2_MOD_WMUESR1, IF_REAL, "Width dependence of muesr1"), + IOP("wmuetmp", HSM2_MOD_WMUETMP, IF_REAL, "Width dependence of muetmp"), + IOP("wsub1", HSM2_MOD_WSUB1, IF_REAL, "Width dependence of sub1"), + IOP("wsub2", HSM2_MOD_WSUB2, IF_REAL, "Width dependence of sub2"), + IOP("wsvds", HSM2_MOD_WSVDS, IF_REAL, "Width dependence of svds"), + IOP("wsvbs", HSM2_MOD_WSVBS, IF_REAL, "Width dependence of svbs"), + IOP("wsvgs", HSM2_MOD_WSVGS, IF_REAL, "Width dependence of svgs"), + IOP("wnsti", HSM2_MOD_WNSTI, IF_REAL, "Width dependence of nsti"), + IOP("wwsti", HSM2_MOD_WWSTI, IF_REAL, "Width dependence of wsti"), + IOP("wscsti1", HSM2_MOD_WSCSTI1, IF_REAL, "Width dependence of scsti1"), + IOP("wscsti2", HSM2_MOD_WSCSTI2, IF_REAL, "Width dependence of scsti2"), + IOP("wvthsti", HSM2_MOD_WVTHSTI, IF_REAL, "Width dependence of vthsti"), + IOP("wmuesti1", HSM2_MOD_WMUESTI1, IF_REAL, "Width dependence of muesti1"), + IOP("wmuesti2", HSM2_MOD_WMUESTI2, IF_REAL, "Width dependence of muesti2"), + IOP("wmuesti3", HSM2_MOD_WMUESTI3, IF_REAL, "Width dependence of muesti3"), + IOP("wnsubpsti1", HSM2_MOD_WNSUBPSTI1, IF_REAL, "Width dependence of nsubpsti1"), + IOP("wnsubpsti2", HSM2_MOD_WNSUBPSTI2, IF_REAL, "Width dependence of nsubpsti2"), + IOP("wnsubpsti3", HSM2_MOD_WNSUBPSTI3, IF_REAL, "Width dependence of nsubpsti3"), + IOP("wcgso", HSM2_MOD_WCGSO, IF_REAL, "Width dependence of cgso"), + IOP("wcgdo", HSM2_MOD_WCGDO, IF_REAL, "Width dependence of cgdo"), + IOP("wjs0", HSM2_MOD_WJS0, IF_REAL, "Width dependence of js0"), + IOP("wjs0sw", HSM2_MOD_WJS0SW, IF_REAL, "Width dependence of js0sw"), + IOP("wnj", HSM2_MOD_WNJ, IF_REAL, "Width dependence of nj"), + IOP("wcisbk", HSM2_MOD_WCISBK, IF_REAL, "Width dependence of cisbk"), + IOP("wclm1", HSM2_MOD_WCLM1, IF_REAL, "Width dependence of clm1"), + IOP("wclm2", HSM2_MOD_WCLM2, IF_REAL, "Width dependence of clm2"), + IOP("wclm3", HSM2_MOD_WCLM3, IF_REAL, "Width dependence of clm3"), + IOP("wwfc", HSM2_MOD_WWFC, IF_REAL, "Width dependence of wfc"), + IOP("wgidl1", HSM2_MOD_WGIDL1, IF_REAL, "Width dependence of gidl1"), + IOP("wgidl2", HSM2_MOD_WGIDL2, IF_REAL, "Width dependence of gidl2"), + IOP("wgleak1", HSM2_MOD_WGLEAK1, IF_REAL, "Width dependence of gleak1"), + IOP("wgleak2", HSM2_MOD_WGLEAK2, IF_REAL, "Width dependence of gleak2"), + IOP("wgleak3", HSM2_MOD_WGLEAK3, IF_REAL, "Width dependence of gleak3"), + IOP("wgleak6", HSM2_MOD_WGLEAK6, IF_REAL, "Width dependence of gleak6"), + IOP("wglksd1", HSM2_MOD_WGLKSD1, IF_REAL, "Width dependence of glksd1"), + IOP("wglksd2", HSM2_MOD_WGLKSD2, IF_REAL, "Width dependence of glksd2"), + IOP("wglkb1", HSM2_MOD_WGLKB1, IF_REAL, "Width dependence of glkb1"), + IOP("wglkb2", HSM2_MOD_WGLKB2, IF_REAL, "Width dependence of glkb2"), + IOP("wnftrp", HSM2_MOD_WNFTRP, IF_REAL, "Width dependence of nftrp"), + IOP("wnfalp", HSM2_MOD_WNFALP, IF_REAL, "Width dependence of nfalp"), + IOP("wvdiffj", HSM2_MOD_WVDIFFJ, IF_REAL, "Width dependence of vdiffj"), + IOP("wibpc1", HSM2_MOD_WIBPC1, IF_REAL, "Width dependence of ibpc1"), + IOP("wibpc2", HSM2_MOD_WIBPC2, IF_REAL, "Width dependence of ibpc2"), + + /* Cross-term dependence */ + IOP("pvmax", HSM2_MOD_PVMAX, IF_REAL, "Cross-term dependence of vmax"), + IOP("pbgtmp1", HSM2_MOD_PBGTMP1, IF_REAL, "Cross-term dependence of bgtmp1"), + IOP("pbgtmp2", HSM2_MOD_PBGTMP2, IF_REAL, "Cross-term dependence of bgtmp2"), + IOP("peg0", HSM2_MOD_PEG0, IF_REAL, "Cross-term dependence of eg0"), + IOP("plover", HSM2_MOD_PLOVER, IF_REAL, "Cross-term dependence of lover"), + IOP("pvfbover", HSM2_MOD_PVFBOVER, IF_REAL, "Cross-term dependence of vfbover"), + IOP("pnover", HSM2_MOD_PNOVER, IF_REAL, "Cross-term dependence of nover"), + IOP("pwl2", HSM2_MOD_PWL2, IF_REAL, "Cross-term dependence of wl2"), + IOP("pvfbc", HSM2_MOD_PVFBC, IF_REAL, "Cross-term dependence of vfbc"), + IOP("pnsubc", HSM2_MOD_PNSUBC, IF_REAL, "Cross-term dependence of nsubc"), + IOP("pnsubp", HSM2_MOD_PNSUBP, IF_REAL, "Cross-term dependence of nsubp"), + IOP("pscp1", HSM2_MOD_PSCP1, IF_REAL, "Cross-term dependence of scp1"), + IOP("pscp2", HSM2_MOD_PSCP2, IF_REAL, "Cross-term dependence of scp2"), + IOP("pscp3", HSM2_MOD_PSCP3, IF_REAL, "Cross-term dependence of scp3"), + IOP("psc1", HSM2_MOD_PSC1, IF_REAL, "Cross-term dependence of sc1"), + IOP("psc2", HSM2_MOD_PSC2, IF_REAL, "Cross-term dependence of sc2"), + IOP("psc3", HSM2_MOD_PSC3, IF_REAL, "Cross-term dependence of sc3"), + IOP("psc4", HSM2_MOD_PSC4, IF_REAL, "Cross-term dependence of sc4"), + IOP("ppgd1", HSM2_MOD_PPGD1, IF_REAL, "Cross-term dependence of pgd1"), +//IOP("ppgd3", HSM2_MOD_PPGD3, IF_REAL, "Cross-term dependence of pgd3"), + IOP("pndep", HSM2_MOD_PNDEP, IF_REAL, "Cross-term dependence of ndep"), + IOP("pninv", HSM2_MOD_PNINV, IF_REAL, "Cross-term dependence of ninv"), + IOP("pmuecb0", HSM2_MOD_PMUECB0, IF_REAL, "Cross-term dependence of muecb0"), + IOP("pmuecb1", HSM2_MOD_PMUECB1, IF_REAL, "Cross-term dependence of muecb1"), + IOP("pmueph1", HSM2_MOD_PMUEPH1, IF_REAL, "Cross-term dependence of mueph1"), + IOP("pvtmp", HSM2_MOD_PVTMP, IF_REAL, "Cross-term dependence of vtmp"), + IOP("pwvth0", HSM2_MOD_PWVTH0, IF_REAL, "Cross-term dependence of wvth0"), + IOP("pmuesr1", HSM2_MOD_PMUESR1, IF_REAL, "Cross-term dependence of muesr1"), + IOP("pmuetmp", HSM2_MOD_PMUETMP, IF_REAL, "Cross-term dependence of muetmp"), + IOP("psub1", HSM2_MOD_PSUB1, IF_REAL, "Cross-term dependence of sub1"), + IOP("psub2", HSM2_MOD_PSUB2, IF_REAL, "Cross-term dependence of sub2"), + IOP("psvds", HSM2_MOD_PSVDS, IF_REAL, "Cross-term dependence of svds"), + IOP("psvbs", HSM2_MOD_PSVBS, IF_REAL, "Cross-term dependence of svbs"), + IOP("psvgs", HSM2_MOD_PSVGS, IF_REAL, "Cross-term dependence of svgs"), + IOP("pnsti", HSM2_MOD_PNSTI, IF_REAL, "Cross-term dependence of nsti"), + IOP("pwsti", HSM2_MOD_PWSTI, IF_REAL, "Cross-term dependence of wsti"), + IOP("pscsti1", HSM2_MOD_PSCSTI1, IF_REAL, "Cross-term dependence of scsti1"), + IOP("pscsti2", HSM2_MOD_PSCSTI2, IF_REAL, "Cross-term dependence of scsti2"), + IOP("pvthsti", HSM2_MOD_PVTHSTI, IF_REAL, "Cross-term dependence of vthsti"), + IOP("pmuesti1", HSM2_MOD_PMUESTI1, IF_REAL, "Cross-term dependence of muesti1"), + IOP("pmuesti2", HSM2_MOD_PMUESTI2, IF_REAL, "Cross-term dependence of muesti2"), + IOP("pmuesti3", HSM2_MOD_PMUESTI3, IF_REAL, "Cross-term dependence of muesti3"), + IOP("pnsubpsti1", HSM2_MOD_PNSUBPSTI1, IF_REAL, "Cross-term dependence of nsubpsti1"), + IOP("pnsubpsti2", HSM2_MOD_PNSUBPSTI2, IF_REAL, "Cross-term dependence of nsubpsti2"), + IOP("pnsubpsti3", HSM2_MOD_PNSUBPSTI3, IF_REAL, "Cross-term dependence of nsubpsti3"), + IOP("pcgso", HSM2_MOD_PCGSO, IF_REAL, "Cross-term dependence of cgso"), + IOP("pcgdo", HSM2_MOD_PCGDO, IF_REAL, "Cross-term dependence of cgdo"), + IOP("pjs0", HSM2_MOD_PJS0, IF_REAL, "Cross-term dependence of js0"), + IOP("pjs0sw", HSM2_MOD_PJS0SW, IF_REAL, "Cross-term dependence of js0sw"), + IOP("pnj", HSM2_MOD_PNJ, IF_REAL, "Cross-term dependence of nj"), + IOP("pcisbk", HSM2_MOD_PCISBK, IF_REAL, "Cross-term dependence of cisbk"), + IOP("pclm1", HSM2_MOD_PCLM1, IF_REAL, "Cross-term dependence of clm1"), + IOP("pclm2", HSM2_MOD_PCLM2, IF_REAL, "Cross-term dependence of clm2"), + IOP("pclm3", HSM2_MOD_PCLM3, IF_REAL, "Cross-term dependence of clm3"), + IOP("pwfc", HSM2_MOD_PWFC, IF_REAL, "Cross-term dependence of wfc"), + IOP("pgidl1", HSM2_MOD_PGIDL1, IF_REAL, "Cross-term dependence of gidl1"), + IOP("pgidl2", HSM2_MOD_PGIDL2, IF_REAL, "Cross-term dependence of gidl2"), + IOP("pgleak1", HSM2_MOD_PGLEAK1, IF_REAL, "Cross-term dependence of gleak1"), + IOP("pgleak2", HSM2_MOD_PGLEAK2, IF_REAL, "Cross-term dependence of gleak2"), + IOP("pgleak3", HSM2_MOD_PGLEAK3, IF_REAL, "Cross-term dependence of gleak3"), + IOP("pgleak6", HSM2_MOD_PGLEAK6, IF_REAL, "Cross-term dependence of gleak6"), + IOP("pglksd1", HSM2_MOD_PGLKSD1, IF_REAL, "Cross-term dependence of glksd1"), + IOP("pglksd2", HSM2_MOD_PGLKSD2, IF_REAL, "Cross-term dependence of glksd2"), + IOP("pglkb1", HSM2_MOD_PGLKB1, IF_REAL, "Cross-term dependence of glkb1"), + IOP("pglkb2", HSM2_MOD_PGLKB2, IF_REAL, "Cross-term dependence of glkb2"), + IOP("pnftrp", HSM2_MOD_PNFTRP, IF_REAL, "Cross-term dependence of nftrp"), + IOP("pnfalp", HSM2_MOD_PNFALP, IF_REAL, "Cross-term dependence of nfalp"), + IOP("pvdiffj", HSM2_MOD_PVDIFFJ, IF_REAL, "Cross-term dependence of vdiffj"), + IOP("pibpc1", HSM2_MOD_PIBPC1, IF_REAL, "Cross-term dependence of ibpc1"), + IOP("pibpc2", HSM2_MOD_PIBPC2, IF_REAL, "Cross-term dependence of ibpc2") + +}; + +char *HSM2names[] = { + "Drain", + "Gate", + "Source", + "Bulk" +}; + +int HSM2nSize = NUMELEMS(HSM2names); +int HSM2pTSize = NUMELEMS(HSM2pTable); +int HSM2mPTSize = NUMELEMS(HSM2mPTable); +int HSM2iSize = sizeof(HSM2instance); +int HSM2mSize = sizeof(HSM2model); + diff --git a/src/spicelib/devices/hisim2/hsm2acld.c b/src/spicelib/devices/hisim2/hsm2acld.c new file mode 100644 index 000000000..ca80e5e1c --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2acld.c @@ -0,0 +1,638 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2acld.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include +#include "spice.h" +#include "cktdefs.h" +#include "sperror.h" +#include "suffix.h" +#include "hsm2def.h" + + +int HSM2acLoad(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; + double xcggb_r, xcgdb_r, xcgsb_r, xcgbb_r, xcggb_i, xcgdb_i, xcgsb_i, xcgbb_i; + double xcbgb_r, xcbdb_r, xcbsb_r, xcbbb_r, xcbgb_i, xcbdb_i, xcbsb_i, xcbbb_i; + double xcdgb_r, xcddb_r, xcdsb_r, xcdbb_r, xcdgb_i, xcddb_i, xcdsb_i, xcdbb_i; + double xcsgb_r, xcsdb_r, xcssb_r, xcsbb_r, xcsgb_i, xcsdb_i, xcssb_i, xcsbb_i; + double gdpr, gspr, gds, gbd, gbs, capbd, capbs, omega; + double FwdSum, RevSum, gm, gmbs; + double gbspsp, gbbdp, gbbsp, gbspg, gbspb; + double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; + double gIbtotg, gIbtotd, gIbtots, gIbtotb; + double gIgtotg, gIgtotd, gIgtots, gIgtotb; + double gIdtotg, gIdtotd, gIdtots, gIdtotb; + double gIstotg, gIstotd, gIstots, gIstotb; + double cggb_real, cgsb_real, cgdb_real, cggb_imag, cgsb_imag, cgdb_imag; + double cdgb_real, cdsb_real, cddb_real, cdgb_imag, cdsb_imag, cddb_imag; + double csgb_real, cssb_real, csdb_real, csgb_imag, cssb_imag, csdb_imag; + double cbgb_real, cbsb_real, cbdb_real, cbgb_imag, cbsb_imag, cbdb_imag; + double pyggb_r = 0.0, pygdb_r = 0.0, pygsb_r = 0.0, pygbb_r = 0.0; + double pybgb_r = 0.0, pybdb_r = 0.0, pybsb_r = 0.0, pybbb_r = 0.0; + double pydgb_r = 0.0, pyddb_r = 0.0, pydsb_r = 0.0, pydbb_r = 0.0; + double pysgb_r = 0.0, pysdb_r = 0.0, pyssb_r = 0.0, pysbb_r = 0.0; + double pyggb_i = 0.0, pygdb_i = 0.0, pygsb_i = 0.0, pygbb_i = 0.0; + double pybgb_i = 0.0, pybdb_i = 0.0, pybsb_i = 0.0, pybbb_i = 0.0; + double pydgb_i = 0.0, pyddb_i = 0.0, pydsb_i = 0.0, pydbb_i = 0.0; + double pysgb_i = 0.0, pysdb_i = 0.0, pyssb_i = 0.0, pysbb_i = 0.0; + double yggb_r, ygdb_r, ygsb_r, ygbb_r, yggb_i, ygdb_i, ygsb_i, ygbb_i; + double ybgb_r, ybdb_r, ybsb_r, ybbb_r, ybgb_i, ybdb_i, ybsb_i, ybbb_i; + double ydgb_r, yddb_r, ydsb_r, ydbb_r, ydgb_i, yddb_i, ydsb_i, ydbb_i; + double ysgb_r, ysdb_r, yssb_r, ysbb_r, ysgb_i, ysdb_i, yssb_i, ysbb_i; + double grg, pxcbdb_i, pxcbsb_i; + + double Qi, Qi_dVgs, Qi_dVbs, Qi_dVds ; + double Qb, Qb_dVgs, Qb_dVbs, Qb_dVds ; + double tau ; + double taub ; + double Xd, Xd_dVgs, Xd_dVbs, Xd_dVds ; + double T1, T2, T3, T4 ; + double cdbs_real, cgbs_real, csbs_real, cbbs_real; + double cdbs_imag, cgbs_imag, csbs_imag, cbbs_imag; + + omega = ckt->CKTomega; + for ( ; model != NULL; model = model->HSM2nextModel ) { + for ( here = model->HSM2instances; here!= NULL; here = here->HSM2nextInstance ) { + + gdpr = here->HSM2drainConductance; + gspr = here->HSM2sourceConductance; + gds = here->HSM2_gds; + gbd = here->HSM2_gbd; + gbs = here->HSM2_gbs; + capbd = here->HSM2_capbd; + capbs = here->HSM2_capbs; + + if (model->HSM2_conqs) { /* for nqs mode */ + + tau = here->HSM2_tau ; + + taub = here->HSM2_taub ; + + Xd = here->HSM2_Xd; + Xd_dVgs = here->HSM2_Xd_dVgs ; + Xd_dVds = here->HSM2_Xd_dVds ; + Xd_dVbs = here->HSM2_Xd_dVbs ; + + Qi = here->HSM2_Qi ; + Qi_dVgs = here->HSM2_Qi_dVgs ; + Qi_dVds = here->HSM2_Qi_dVds ; + Qi_dVbs = here->HSM2_Qi_dVbs ; + + Qb = here->HSM2_Qb ; + Qb_dVgs = here->HSM2_Qb_dVgs ; + Qb_dVds = here->HSM2_Qb_dVds ; + Qb_dVbs = here->HSM2_Qb_dVbs ; + + T1 = 1.0 + (tau * omega) * (tau * omega); + T2 = tau * omega / T1; + T3 = 1.0 + (taub * omega) * (taub * omega); + T4 = taub * omega / T3; + + cddb_real = Xd_dVds*Qi + Xd/T1*Qi_dVds; + cdgb_real = Xd_dVgs*Qi + Xd/T1*Qi_dVgs; + cdbs_real = Xd_dVbs*Qi + Xd/T1*Qi_dVbs; + cdsb_real = - (cddb_real + cdgb_real + cdbs_real); + + cddb_imag = - T2*Xd*Qi_dVds; + cdgb_imag = - T2*Xd*Qi_dVgs; + cdbs_imag = - T2*Xd*Qi_dVbs; + cdsb_imag = - (cddb_imag + cdgb_imag + cdbs_imag); + + csdb_real = - Xd_dVds*Qi + (1.0-Xd)/T1*Qi_dVds; + csgb_real = - Xd_dVgs*Qi + (1.0-Xd)/T1*Qi_dVgs; + csbs_real = - Xd_dVbs*Qi + (1.0-Xd)/T1*Qi_dVbs; + cssb_real = - (csdb_real + csgb_real + csbs_real); + + csdb_imag = - T2*(1.0-Xd)*Qi_dVds; + csgb_imag = - T2*(1.0-Xd)*Qi_dVgs; + csbs_imag = - T2*(1.0-Xd)*Qi_dVbs; + cssb_imag = - (csdb_imag + csgb_imag + csbs_imag); + + cbdb_real = Qb_dVds/T3; + cbgb_real = Qb_dVgs/T3; + cbbs_real = Qb_dVbs/T3; + cbsb_real = - (cbdb_real + cbgb_real + cbbs_real); + + cbdb_imag = - T4*Qb_dVds; + cbgb_imag = - T4*Qb_dVgs; + cbbs_imag = - T4*Qb_dVbs; + cbsb_imag = - (cbdb_imag + cbgb_imag + cbbs_imag); + + cgdb_real = - Qi_dVds/T1 - Qb_dVds/T3; + cggb_real = - Qi_dVgs/T1 - Qb_dVgs/T3; + cgbs_real = - Qi_dVbs/T1 - Qb_dVbs/T3; + cgsb_real = - (cgdb_real + cggb_real + cgbs_real); + + cgdb_imag = T2*Qi_dVds + T4*Qb_dVds; + cggb_imag = T2*Qi_dVgs + T4*Qb_dVgs; + cgbs_imag = T2*Qi_dVbs + T4*Qb_dVbs; + cgsb_imag = - (cgdb_imag + cggb_imag + cgbs_imag); + + + +#ifdef DEBUG_HISIM2CGG + printf("Freq. %e ", omega/(2*3.14159265358979) ) ; + printf("mag[Cgg] %e ", sqrt( cggb_real * cggb_real + cggb_imag * cggb_imag ) ) ; + printf("qi %e ", ( sqrt(T1) / T1 ) * Qi ) ; + printf("qb %e ", ( sqrt(T3) / T3 ) * Qb ) ; + printf("\n") ; +#endif + +#ifdef DEBUG_HISIM2AC + printf ("#1 cssb, cggb, cgdb, cgsb, cdgb, cddb, cdsb, csgb, csdb %e %e %e %e %e %e %e %e %e %e %e %e\n", cggb_real, cgdb_real, cgsb_real, cdgb_real, cddb_real, cdsb_real, csgb_real, csdb_real, cssb_real); +#endif + } + + if ( here->HSM2_mode >= 0 ) { + gm = here->HSM2_gm; + gmbs = here->HSM2_gmbs; + FwdSum = gm + gmbs; + RevSum = 0.0; + + gbbdp = -here->HSM2_gbds; + gbbsp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = here->HSM2_gbgs; + gbdpb = here->HSM2_gbbs; + gbdpdp = here->HSM2_gbds; + gbdpsp = -(gbdpg + gbdpb + gbdpdp); + + gbspdp = 0.0; + gbspg = 0.0; + gbspb = 0.0; + gbspsp = 0.0; + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + } else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + } else { + gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; + } + + if (model->HSM2_conqs) { /* for nqs mode */ + /* + cggb_real, cgsb_real, cgdb_real + cggb_imag, cgsb_imag, cgdb_imag + cdgb_real, cdsb_real, cddb_real + cdgb_imag, cdsb_imag, cddb_imag + csgb_real, cssb_real, csdb_real + csgb_imag, cssb_imag, csdb_imag + cbgb_real, cbsb_real, cbdb_real + cbgb_imag, cbsb_imag, cbdb_imag + have already obtained. + */ + if (model->HSM2_coadov == 1) { /* add overlap caps to intrinsic caps */ + pydgb_i = (here->HSM2_cdgo - here->HSM2_cqyg) * omega ; + pyddb_i = (here->HSM2_cddo - here->HSM2_cqyd) * omega ; + pydsb_i = (here->HSM2_cdso + here->HSM2_cqyg + here->HSM2_cqyd + here->HSM2_cqyb) * omega ; + pydbb_i = -(pydgb_i + pyddb_i + pydsb_i) ; + + pysgb_i = here->HSM2_csgo * omega ; + pysdb_i = here->HSM2_csdo * omega ; + pyssb_i = here->HSM2_csso * omega ; + pysbb_i = -(pysgb_i + pysdb_i + pyssb_i) ; + + pyggb_i = (-(here->HSM2_cgdo + here->HSM2_cgbo + here->HSM2_cgso) + here->HSM2_cqyg) * omega ; + pygdb_i = (here->HSM2_cgdo + here->HSM2_cqyd) * omega ; + pygsb_i = (here->HSM2_cgso - here->HSM2_cqyg - here->HSM2_cqyd - here->HSM2_cqyb) * omega ; + pygbb_i = -(pyggb_i + pygdb_i + pygsb_i) ; + } + + } else { /* for qs mode */ + /* if coadov = 1, coverlap caps have been arleady added to intrinsic caps (QS mode)*/ + cggb_real = here->HSM2_cggb; + cgsb_real = here->HSM2_cgsb; + cgdb_real = here->HSM2_cgdb; + cggb_imag = cgsb_imag = cgdb_imag = 0.0; + + cbgb_real = here->HSM2_cbgb; + cbsb_real = here->HSM2_cbsb; + cbdb_real = here->HSM2_cbdb; + cbgb_imag = cbsb_imag = cbdb_imag = 0.0; + + cdgb_real = here->HSM2_cdgb; + cdsb_real = here->HSM2_cdsb; + cddb_real = here->HSM2_cddb; + cdgb_imag = cdsb_imag = cddb_imag = 0.0; + + csgb_real = -(cdgb_real + cggb_real + cbgb_real); + cssb_real = -(cdsb_real + cgsb_real + cbsb_real); + csdb_real = -(cddb_real + cgdb_real + cbdb_real); + csgb_imag = cssb_imag = csdb_imag = 0.0; + + pyggb_i = 0.0; pygdb_i = 0.0; pygsb_i = 0.0; pygbb_i = 0.0; + pybgb_i = 0.0; pybdb_i = 0.0; pybsb_i = 0.0; pybbb_i = 0.0; + pydgb_i = 0.0; pyddb_i = 0.0; pydsb_i = 0.0; pydbb_i = 0.0; + pysgb_i = 0.0; pysdb_i = 0.0; pyssb_i = 0.0; pysbb_i = 0.0; + } + + } else { /* reverse mode */ + gm = -here->HSM2_gm; + gmbs = -here->HSM2_gmbs; + FwdSum = 0.0; + RevSum = -(gm + gmbs); + + gbbsp = -here->HSM2_gbds; + gbbdp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = 0.0; + gbdpsp = 0.0; + gbdpb = 0.0; + gbdpdp = 0.0; + + gbspg = here->HSM2_gbgs; + gbspsp = here->HSM2_gbds; + gbspb = here->HSM2_gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + } else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + } else { + gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; + } + + if (model->HSM2_conqs) { /* for nqs mode */ + /* swap d with s, s with d */ + /* cggb_real has already obtained. */ + T1 = cgsb_real; + cgsb_real = cgdb_real; + cgdb_real = T1; + /* cggb_imag has already obtained. */ + T1 = cgsb_imag; + cgsb_imag = cgdb_imag; + cgdb_imag = T1; + + T1 = cdgb_real; + cdgb_real = csgb_real; + csgb_real = T1; + T1 = cdsb_real; + cdsb_real = csdb_real; + csdb_real = T1; + T1 = cddb_real; + cddb_real = cssb_real; + cssb_real = T1; + T1 = cdgb_imag; + cdgb_imag = csgb_imag; + csgb_imag = T1; + T1 = cdsb_imag; + cdsb_imag = csdb_imag; + csdb_imag = T1; + T1 = cddb_imag; + cddb_imag = cssb_imag; + cssb_imag = T1; + + /* cbgb_real has already obtained. */ + T1 = cbsb_real; + cbsb_real = cbdb_real; + cbdb_real = T1; + /* cbgb_imag has already obtained. */ + T1 = cbsb_imag; + cbsb_imag = cbdb_imag; + cbdb_imag = T1; + + if (model->HSM2_coadov == 1) { /* add overlap caps to intrinsic caps */ + pydgb_i = here->HSM2_csgo * omega ; + pyddb_i = here->HSM2_csso * omega ; + pydsb_i = here->HSM2_csdo * omega ; + pydbb_i = -(pydgb_i + pyddb_i + pydsb_i) ; + + pysgb_i = (here->HSM2_cdgo - here->HSM2_cqyg) * omega ; + pysdb_i = (here->HSM2_cdso + here->HSM2_cqyg + here->HSM2_cqyd + here->HSM2_cqyb) * omega ; + pyssb_i = (here->HSM2_cddo - here->HSM2_cqyd) * omega ; + pysbb_i = -(pysgb_i + pysdb_i + pyssb_i) ; + + pyggb_i = (-(here->HSM2_cgdo + here->HSM2_cgbo + here->HSM2_cgso) + here->HSM2_cqyg) * omega ; + pygdb_i = (here->HSM2_cgso - here->HSM2_cqyg - here->HSM2_cqyd - here->HSM2_cqyb) * omega ; + pygsb_i = (here->HSM2_cgdo + here->HSM2_cqyd) * omega ; + pygbb_i = -(pyggb_i + pygdb_i + pygsb_i) ; + } + + } else { /* for qs mode */ + /* if coadov = 1, coverlap caps have already been added to intrinsic caps (QS mode)*/ + cggb_real = here->HSM2_cggb; + cgsb_real = here->HSM2_cgdb; + cgdb_real = here->HSM2_cgsb; + cggb_imag = cgsb_imag = cgdb_imag = 0.0; + + cbgb_real = here->HSM2_cbgb; + cbsb_real = here->HSM2_cbdb; + cbdb_real = here->HSM2_cbsb; + cbgb_imag = cbsb_imag = cbdb_imag = 0.0; + + csgb_real = here->HSM2_cdgb ; + cssb_real = here->HSM2_cddb ; + csdb_real = here->HSM2_cdsb ; + csgb_imag = cssb_imag = csdb_imag = 0.0; + + cdgb_real = -(csgb_real + cggb_real + cbgb_real); + cdsb_real = -(cssb_real + cgsb_real + cbsb_real); + cddb_real = -(csdb_real + cgdb_real + cbdb_real); + cdgb_imag = cdsb_imag = cddb_imag = 0.0; + + pyggb_i = 0.0; pygdb_i = 0.0; pygsb_i = 0.0; pygbb_i = 0.0; + pybgb_i = 0.0; pybdb_i = 0.0; pybsb_i = 0.0; pybbb_i = 0.0; + pydgb_i = 0.0; pyddb_i = 0.0; pydsb_i = 0.0; pydbb_i = 0.0; + pysgb_i = 0.0; pysdb_i = 0.0; pyssb_i = 0.0; pysbb_i = 0.0; + } + + } +#ifdef DEBUG_HISIM2AC + printf ("#2 cssb, cggb, cgdb, cgsb, cdgb, cddb, cdsb, csgb, csdb %e %e %e %e %e %e %e %e %e %e %e %e\n", cggb_real, cgdb_real, cgsb_real, cdgb_real, cddb_real, cdsb_real, csgb_real, csdb_real, cssb_real); +#endif + + /* matrix elements for ac analysis (including real and imaginary parts) */ + xcdgb_r = cdgb_real * omega; + xcddb_r = cddb_real * omega; + xcdsb_r = cdsb_real * omega; + xcdbb_r = -(xcdgb_r + xcddb_r + xcdsb_r); + + xcsgb_r = csgb_real * omega; + xcsdb_r = csdb_real * omega; + xcssb_r = cssb_real * omega; + xcsbb_r = -(xcsgb_r + xcsdb_r + xcssb_r); + + xcggb_r = cggb_real * omega; + xcgdb_r = cgdb_real * omega; + xcgsb_r = cgsb_real * omega; + xcgbb_r = -(xcggb_r + xcgdb_r + xcgsb_r); + + xcbgb_r = cbgb_real * omega; + xcbdb_r = cbdb_real * omega; + xcbsb_r = cbsb_real * omega; + xcbbb_r = -(xcbgb_r + xcbdb_r + xcbsb_r); + + xcdgb_i = cdgb_imag * omega; + xcddb_i = cddb_imag * omega; + xcdsb_i = cdsb_imag * omega; + xcdbb_i = -(xcddb_i + xcdgb_i + xcdsb_i); + + xcsgb_i = csgb_imag * omega; + xcsdb_i = csdb_imag * omega; + xcssb_i = cssb_imag * omega; + xcsbb_i = -(xcsdb_i + xcsgb_i + xcssb_i); + + xcggb_i = cggb_imag * omega; + xcgdb_i = cgdb_imag * omega; + xcgsb_i = cgsb_imag * omega; + xcgbb_i = -(xcggb_i + xcgdb_i + xcgsb_i); + + xcbgb_i = cbgb_imag * omega; + xcbdb_i = cbdb_imag * omega; + xcbsb_i = cbsb_imag * omega; + xcbbb_i = -(xcbgb_i + xcbdb_i + xcbsb_i); + + /* stamp intrinsic y-parameters */ + yggb_r = - xcggb_i; yggb_i = xcggb_r; + ygdb_r = - xcgdb_i; ygdb_i = xcgdb_r; + ygsb_r = - xcgsb_i; ygsb_i = xcgsb_r; + ygbb_r = - xcgbb_i; ygbb_i = xcgbb_r; + + ydgb_r = - xcdgb_i; ydgb_i = xcdgb_r; + yddb_r = - xcddb_i; yddb_i = xcddb_r; + ydsb_r = - xcdsb_i; ydsb_i = xcdsb_r; + ydbb_r = - xcdbb_i; ydbb_i = xcdbb_r; + ydgb_r += gm; + yddb_r += gds + RevSum; + ydsb_r += - gds - FwdSum; + ydbb_r += gmbs; + + ysgb_r = - xcsgb_i; ysgb_i = xcsgb_r; + ysdb_r = - xcsdb_i; ysdb_i = xcsdb_r; + yssb_r = - xcssb_i; yssb_i = xcssb_r; + ysbb_r = - xcsbb_i; ysbb_i = xcsbb_r; + ysgb_r += - gm; + ysdb_r += - gds - RevSum; + yssb_r += gds + FwdSum; + ysbb_r += - gmbs; + + ybgb_r = - xcbgb_i; ybgb_i = xcbgb_r; + ybdb_r = - xcbdb_i; ybdb_i = xcbdb_r; + ybsb_r = - xcbsb_i; ybsb_i = xcbsb_r; + ybbb_r = - xcbbb_i; ybbb_i = xcbbb_r; + + /* Ibd, Ibs, Igate, Igd, Igs, Igb, Igidl, Igisl, Isub */ + pydgb_r = gbdpg - gIdtotg + here->HSM2_gigidlgs ; + pyddb_r = gbd + gbdpdp - gIdtotd + here->HSM2_gigidlds ; + pydsb_r = gbdpsp - gIdtots - (here->HSM2_gigidlgs + here->HSM2_gigidlds + here->HSM2_gigidlbs); + pydbb_r = gbdpb - gIdtotb + here->HSM2_gigidlbs ; + if (!here->HSM2_corbnet) pydbb_r += - gbd; + + pysgb_r = gbspg - gIstotg + here->HSM2_gigislgd ; + pysdb_r = gbspdp - gIstotd - (here->HSM2_gigislsd + here->HSM2_gigislgd + here->HSM2_gigislbd); + pyssb_r = gbs + gbspsp - gIstots + here->HSM2_gigislsd ; + pysbb_r =gbspb - gIstotb + here->HSM2_gigislbd ; + if (!here->HSM2_corbnet) pysbb_r += - gbs; + + pyggb_r = gIgtotg ; + if (here->HSM2_corg == 1) { + grg = here->HSM2_grg; + pyggb_r += grg; + } + pygdb_r = gIgtotd ; + pygsb_r = gIgtots ; + pygbb_r = gIgtotb ; + + pybgb_r = - here->HSM2_gbgs - gIbtotg - here->HSM2_gigidlgs - here->HSM2_gigislgd ; + pybdb_r = gbbdp - gIbtotd + - here->HSM2_gigidlds + (here->HSM2_gigislgd + here->HSM2_gigislsd + here->HSM2_gigislbd) ; + if (!here->HSM2_corbnet) pybdb_r += - gbd ; + pybsb_r = gbbsp - gIbtots + + (here->HSM2_gigidlgs + here->HSM2_gigidlds + here->HSM2_gigidlbs) - here->HSM2_gigislsd ; + if (!here->HSM2_corbnet) pybsb_r += - gbs ; + pybbb_r = - here->HSM2_gbbs - gIbtotb - here->HSM2_gigidlbs - here->HSM2_gigislbd ; + if (!here->HSM2_corbnet) pybbb_r += gbd + gbs ; + + pybdb_i = -(pyddb_i + pygdb_i + pysdb_i); + pybgb_i = -(pydgb_i + pyggb_i + pysgb_i); + pybsb_i = -(pydsb_i + pygsb_i + pyssb_i); + pybbb_i = -(pydbb_i + pygbb_i + pysbb_i); + + /* Cbd, Cbs */ + pyddb_i += capbd * omega ; + pyssb_i += capbs * omega ; + if (!here->HSM2_corbnet) { + pydbb_i -= capbd * omega ; + pysbb_i -= capbs * omega ; + + pybdb_i -= capbd * omega ; + pybsb_i -= capbs * omega ; + pybbb_i += (capbd + capbs) * omega ; + } else { + pxcbdb_i = - capbd * omega ; + pxcbsb_i = - capbs * omega ; + } + +#ifdef DEBUG_HISIM2AC + /* for representing y-parameters */ + printf("f ygg_r ygg_i %e %e %e\n",omega/(2.0*3.141592653589793),yggb_r+pyggb_r,yggb_i+pyggb_i); + printf("f ygd_r ygd_i %e %e %e\n",omega/(2.0*3.141592653589793),ygdb_r+pygdb_r,ygdb_i+pygdb_i); + printf("f ygs_r ygs_i %e %e %e\n",omega/(2.0*3.141592653589793),ygsb_r+pygsb_r,ygsb_i+pygsb_i); + printf("f ygb_r ygb_i %e %e %e\n",omega/(2.0*3.141592653589793),ygbb_r+pygbb_r,ygbb_i+pygbb_i); + + printf("f ydg_r ydg_i %e %e %e\n",omega/(2.0*3.141592653589793),ydgb_r+pydgb_r,ydgb_i+pydgb_i); + printf("f ydd_r ydd_i %e %e %e\n",omega/(2.0*3.141592653589793),yddb_r+pyddb_r,yddb_i+pyddb_i); + printf("f yds_r yds_i %e %e %e\n",omega/(2.0*3.141592653589793),ydsb_r+pydsb_r,ydsb_i+pydsb_i); + printf("f ydb_r ydb_i %e %e %e\n",omega/(2.0*3.141592653589793),ydbb_r+pydbb_r,ydbb_i+pydbb_i); + + printf("f ybg_r ybg_i %e %e %e\n",omega/(2.0*3.141592653589793),ybgb_r+pybgb_r,ybgb_i+pybgb_i); + printf("f ybd_r ybd_i %e %e %e\n",omega/(2.0*3.141592653589793),ybdb_r+pybdb_r,ybdb_i+pybdb_i); + printf("f ybs_r ybs_i %e %e %e\n",omega/(2.0*3.141592653589793),ybsb_r+pybsb_r,ybsb_i+pybsb_i); + printf("f ybb_r ybb_i %e %e %e\n",omega/(2.0*3.141592653589793),ybbb_r+pybbb_r,ybbb_i+pybbb_i); + + printf("f ysg_r ysg_i %e %e %e\n",omega/(2.0*3.141592653589793),ysgb_r+pysgb_r,ysgb_i+pysgb_i); + printf("f ysd_r ysd_i %e %e %e\n",omega/(2.0*3.141592653589793),ysdb_r+pysdb_r,ysdb_i+pysdb_i); + printf("f yss_r yss_i %e %e %e\n",omega/(2.0*3.141592653589793),yssb_r+pyssb_r,yssb_i+pyssb_i); + printf("f ysb_r ysb_i %e %e %e\n",omega/(2.0*3.141592653589793),ysbb_r+pysbb_r,ysbb_i+pysbb_i); + + printf("f y11r y11i y12r y12i y21r y21i y22r y22i %e %e %e %e %e %e %e %e %e\n",omega/(2.0*3.141592653589793),yggb_r+pyggb_r,yggb_i+pyggb_i, ygdb_r+pygdb_r,ygdb_i+pygdb_i, ydgb_r+pydgb_r,ydgb_i+pydgb_i, yddb_r+pyddb_r,yddb_i+pyddb_i); +#endif + + if (here->HSM2_corg == 1) { + *(here->HSM2GgPtr) += grg; + *(here->HSM2GPgPtr) -= grg; + *(here->HSM2GgpPtr) -= grg; + } + + *(here->HSM2GPgpPtr +1) += yggb_i + pyggb_i; + *(here->HSM2GPgpPtr) += yggb_r + pyggb_r; + *(here->HSM2GPdpPtr +1) += ygdb_i + pygdb_i; + *(here->HSM2GPdpPtr) += ygdb_r + pygdb_r; + *(here->HSM2GPspPtr +1) += ygsb_i + pygsb_i; + *(here->HSM2GPspPtr) += ygsb_r + pygsb_r; + *(here->HSM2GPbpPtr +1) += ygbb_i + pygbb_i; + *(here->HSM2GPbpPtr) += ygbb_r + pygbb_r; + + *(here->HSM2DPdpPtr +1) += yddb_i + pyddb_i; + *(here->HSM2DPdpPtr) += yddb_r + pyddb_r + gdpr; + *(here->HSM2DPdPtr) -= gdpr; + *(here->HSM2DPgpPtr +1) += ydgb_i + pydgb_i; + *(here->HSM2DPgpPtr) += ydgb_r + pydgb_r; + *(here->HSM2DPspPtr +1) += ydsb_i + pydsb_i; + *(here->HSM2DPspPtr) += ydsb_r + pydsb_r; + *(here->HSM2DPbpPtr +1) += ydbb_i + pydbb_i; + *(here->HSM2DPbpPtr) += ydbb_r + pydbb_r; + + *(here->HSM2DdpPtr) -= gdpr; + *(here->HSM2DdPtr) += gdpr; + + *(here->HSM2SPdpPtr +1) += ysdb_i + pysdb_i; + *(here->HSM2SPdpPtr) += ysdb_r + pysdb_r; + *(here->HSM2SPgpPtr +1) += ysgb_i + pysgb_i; + *(here->HSM2SPgpPtr) += ysgb_r + pysgb_r; + *(here->HSM2SPspPtr +1) += yssb_i + pyssb_i; + *(here->HSM2SPspPtr) += yssb_r + pyssb_r + gspr; + *(here->HSM2SPsPtr) -= gspr ; + *(here->HSM2SPbpPtr +1) += ysbb_i + pysbb_i; + *(here->HSM2SPbpPtr) += ysbb_r + pysbb_r; + + *(here->HSM2SspPtr) -= gspr; + *(here->HSM2SsPtr) += gspr; + + *(here->HSM2BPdpPtr +1) += ybdb_i + pybdb_i; + *(here->HSM2BPdpPtr) += ybdb_r + pybdb_r; + *(here->HSM2BPgpPtr +1) += ybgb_i + pybgb_i; + *(here->HSM2BPgpPtr) += ybgb_r + pybgb_r; + *(here->HSM2BPspPtr +1) += ybsb_i + pybsb_i; + *(here->HSM2BPspPtr) += ybsb_r + pybsb_r; + *(here->HSM2BPbpPtr +1) += ybbb_i + pybbb_i; + *(here->HSM2BPbpPtr) += ybbb_r + pybbb_r; + + if (here->HSM2_corbnet == 1) { + *(here->HSM2DPdbPtr +1) += pxcbdb_i; + *(here->HSM2DPdbPtr) -= gbd; + *(here->HSM2SPsbPtr +1) += pxcbsb_i; + *(here->HSM2SPsbPtr) -= gbs; + + *(here->HSM2DBdpPtr +1) += pxcbdb_i; + *(here->HSM2DBdpPtr) -= gbd; + *(here->HSM2DBdbPtr +1) -= pxcbdb_i; + *(here->HSM2DBdbPtr) += gbd + here->HSM2_grbpd + here->HSM2_grbdb; + *(here->HSM2DBbpPtr) -= here->HSM2_grbpd; + *(here->HSM2DBbPtr) -= here->HSM2_grbdb; + + *(here->HSM2BPdbPtr) -= here->HSM2_grbpd; + *(here->HSM2BPbPtr) -= here->HSM2_grbpb; + *(here->HSM2BPsbPtr) -= here->HSM2_grbps; + *(here->HSM2BPbpPtr) += here->HSM2_grbpd + here->HSM2_grbps + here->HSM2_grbpb; + + *(here->HSM2SBspPtr +1) += pxcbsb_i; + *(here->HSM2SBspPtr) -= gbs; + *(here->HSM2SBbpPtr) -= here->HSM2_grbps; + *(here->HSM2SBbPtr) -= here->HSM2_grbsb; + *(here->HSM2SBsbPtr +1) -= pxcbsb_i; + *(here->HSM2SBsbPtr) += gbs + here->HSM2_grbps + here->HSM2_grbsb; + + *(here->HSM2BdbPtr) -= here->HSM2_grbdb; + *(here->HSM2BbpPtr) -= here->HSM2_grbpb; + *(here->HSM2BsbPtr) -= here->HSM2_grbsb; + *(here->HSM2BbPtr) += here->HSM2_grbsb + here->HSM2_grbdb + here->HSM2_grbpb; + } + + } + } + + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2ask.c b/src/spicelib/devices/hisim2/hsm2ask.c new file mode 100644 index 000000000..c94f30d50 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2ask.c @@ -0,0 +1,286 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2ask.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "hsm2def.h" +#include "sperror.h" +#include "util.h" +#include "suffix.h" + +int HSM2ask(ckt,inst,which,value,select) + CKTcircuit *ckt; + GENinstance *inst; + int which; + IFvalue *value; + IFvalue *select; +{ + HSM2instance *here = (HSM2instance*)inst; + + switch (which) { + case HSM2_L: + value->rValue = here->HSM2_l; + return(OK); + case HSM2_W: + value->rValue = here->HSM2_w; + return(OK); + case HSM2_AS: + value->rValue = here->HSM2_as; + return(OK); + case HSM2_AD: + value->rValue = here->HSM2_ad; + return(OK); + case HSM2_PS: + value->rValue = here->HSM2_ps; + return(OK); + case HSM2_PD: + value->rValue = here->HSM2_pd; + return(OK); + case HSM2_NRS: + value->rValue = here->HSM2_nrs; + return(OK); + case HSM2_NRD: + value->rValue = here->HSM2_nrd; + return(OK); + case HSM2_TEMP: + value->rValue = here->HSM2_temp; + return(OK); + case HSM2_DTEMP: + value->rValue = here->HSM2_dtemp; + return(OK); + case HSM2_OFF: + value->iValue = here->HSM2_off; + return(OK); + case HSM2_IC_VBS: + value->rValue = here->HSM2_icVBS; + return(OK); + case HSM2_IC_VDS: + value->rValue = here->HSM2_icVDS; + return(OK); + case HSM2_IC_VGS: + value->rValue = here->HSM2_icVGS; + return(OK); + case HSM2_DNODE: + value->iValue = here->HSM2dNode; + return(OK); + case HSM2_GNODE: + value->iValue = here->HSM2gNode; + return(OK); + case HSM2_SNODE: + value->iValue = here->HSM2sNode; + return(OK); + case HSM2_BNODE: + value->iValue = here->HSM2bNode; + return(OK); + case HSM2_DNODEPRIME: + value->iValue = here->HSM2dNodePrime; + return(OK); + case HSM2_SNODEPRIME: + value->iValue = here->HSM2sNodePrime; + return(OK); + case HSM2_SOURCECONDUCT: + value->rValue = here->HSM2sourceConductance; + return(OK); + case HSM2_DRAINCONDUCT: + value->rValue = here->HSM2drainConductance; + return(OK); + case HSM2_VBD: + value->rValue = *(ckt->CKTstate0 + here->HSM2vbd); + return(OK); + case HSM2_VBS: + value->rValue = *(ckt->CKTstate0 + here->HSM2vbs); + return(OK); + case HSM2_VGS: + value->rValue = *(ckt->CKTstate0 + here->HSM2vgs); + return(OK); + case HSM2_VDS: + value->rValue = *(ckt->CKTstate0 + here->HSM2vds); + return(OK); + case HSM2_CD: + value->rValue = here->HSM2_ids; + return(OK); + case HSM2_ISUB: + value->rValue = here->HSM2_isub; + return(OK); + case HSM2_IGIDL: + value->rValue = here->HSM2_igidl; + return(OK); + case HSM2_IGISL: + value->rValue = here->HSM2_igisl; + return(OK); + case HSM2_IGD: + value->rValue = here->HSM2_igd; + return(OK); + case HSM2_IGS: + value->rValue = here->HSM2_igs; + return(OK); + case HSM2_IGB: + value->rValue = here->HSM2_igb; + return(OK); + case HSM2_CBS: + value->rValue = here->HSM2_ibs; + return(OK); + case HSM2_CBD: + value->rValue = here->HSM2_ibd; + return(OK); + case HSM2_GM: + value->rValue = here->HSM2_gm; + return(OK); + case HSM2_GDS: + value->rValue = here->HSM2_gds; + return(OK); + case HSM2_GMBS: + value->rValue = here->HSM2_gmbs; + return(OK); + case HSM2_GBD: + value->rValue = here->HSM2_gbd; + return(OK); + case HSM2_GBS: + value->rValue = here->HSM2_gbs; + return(OK); + case HSM2_QB: + value->rValue = *(ckt->CKTstate0 + here->HSM2qb); + return(OK); + case HSM2_CQB: + value->rValue = *(ckt->CKTstate0 + here->HSM2cqb); + return(OK); + case HSM2_QG: + value->rValue = *(ckt->CKTstate0 + here->HSM2qg); + return(OK); + case HSM2_CQG: + value->rValue = *(ckt->CKTstate0 + here->HSM2cqg); + return(OK); + case HSM2_QD: + value->rValue = *(ckt->CKTstate0 + here->HSM2qd); + return(OK); + case HSM2_CQD: + value->rValue = *(ckt->CKTstate0 + here->HSM2cqd); + return(OK); + case HSM2_CGG: + value->rValue = here->HSM2_cggb; + return(OK); + case HSM2_CGD: + value->rValue = here->HSM2_cgdb; + return(OK); + case HSM2_CGS: + value->rValue = here->HSM2_cgsb; + return(OK); + case HSM2_CDG: + value->rValue = here->HSM2_cdgb; + return(OK); + case HSM2_CDD: + value->rValue = here->HSM2_cddb; + return(OK); + case HSM2_CDS: + value->rValue = here->HSM2_cdsb; + return(OK); + case HSM2_CBG: + value->rValue = here->HSM2_cbgb; + return(OK); + case HSM2_CBDB: + value->rValue = here->HSM2_cbdb; + return(OK); + case HSM2_CBSB: + value->rValue = here->HSM2_cbsb; + return(OK); + case HSM2_CGDO: + value->rValue = here->HSM2_cgdo; + return(OK); + case HSM2_CGSO: + value->rValue = here->HSM2_cgso; + return(OK); + case HSM2_CGBO: + value->rValue = here->HSM2_cgbo; + return(OK); + case HSM2_CAPBD: + value->rValue = here->HSM2_capbd; + return(OK); + case HSM2_CAPBS: + value->rValue = here->HSM2_capbs; + return(OK); + case HSM2_VON: + value->rValue = here->HSM2_von; + return(OK); + case HSM2_VDSAT: + value->rValue = here->HSM2_vdsat; + return(OK); + case HSM2_QBS: + value->rValue = *(ckt->CKTstate0 + here->HSM2qbs); + return(OK); + case HSM2_QBD: + value->rValue = *(ckt->CKTstate0 + here->HSM2qbd); + return(OK); + case HSM2_CORBNET: + value->iValue = here->HSM2_corbnet; + return(OK); + case HSM2_RBPB: + value->rValue = here->HSM2_rbpb; + return (OK); + case HSM2_RBPD: + value->rValue = here->HSM2_rbpd; + return(OK); + case HSM2_RBPS: + value->rValue = here->HSM2_rbps; + return(OK); + case HSM2_RBDB: + value->rValue = here->HSM2_rbdb; + return(OK); + case HSM2_RBSB: + value->rValue = here->HSM2_rbsb; + return(OK); + case HSM2_CORG: + value->iValue = here->HSM2_corg; + return(OK); +/* case HSM2_RSHG: */ +/* value->rValue = here->HSM2_rshg; */ +/* return(OK); */ + case HSM2_NGCON: + value->rValue = here->HSM2_ngcon; + return(OK); + case HSM2_XGW: + value->rValue = here->HSM2_xgw; + return(OK); + case HSM2_XGL: + value->rValue = here->HSM2_xgl; + return(OK); + case HSM2_NF: + value->rValue = here->HSM2_nf; + return(OK); + case HSM2_SA: + value->rValue = here->HSM2_sa; + return(OK); + case HSM2_SB: + value->rValue = here->HSM2_sb; + return(OK); + case HSM2_SD: + value->rValue = here->HSM2_sd; + return(OK); + case HSM2_NSUBCDFM: + value->rValue = here->HSM2_nsubcdfm; + return(OK); + case HSM2_MPHDFM: + value->rValue = here->HSM2_mphdfm; + return(OK); + case HSM2_M: + value->rValue = here->HSM2_m; + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} diff --git a/src/spicelib/devices/hisim2/hsm2cvtest.c b/src/spicelib/devices/hisim2/hsm2cvtest.c new file mode 100644 index 000000000..7ffc9f62e --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2cvtest.c @@ -0,0 +1,133 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2cvtest.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "util.h" +#include "cktdefs.h" +#include "hsm2def.h" +#include "trandefs.h" +#include "const.h" +#include "devdefs.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2convTest(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; + double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; + double cd, cdhat, tol0, tol1, tol2, tol3, tol4, vgd, vgdo, vgs; + double Ibtot, cbhat, Igstot, cgshat, Igdtot, cgdhat, Igbtot, cgbhat; + + /* loop through all the HSM2 device models */ + for ( ; model != NULL; model = model->HSM2nextModel ) { + /* loop through all the instances of the model */ + for ( here = model->HSM2instances; here != NULL ; + here = here->HSM2nextInstance ) { + vbs = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2bNode) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vgs = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2gNode) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vds = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2dNodePrime) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vbd = vbs - vds; + vgd = vgs - vds; + vgdo = *(ckt->CKTstate0 + here->HSM2vgs) - + *(ckt->CKTstate0 + here->HSM2vds); + delvbs = vbs - *(ckt->CKTstate0 + here->HSM2vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->HSM2vbd); + delvgs = vgs - *(ckt->CKTstate0 + here->HSM2vgs); + delvds = vds - *(ckt->CKTstate0 + here->HSM2vds); + delvgd = vgd - vgdo; + + cd = here->HSM2_ids - here->HSM2_ibd; + if ( here->HSM2_mode >= 0 ) { + cd += here->HSM2_isub + here->HSM2_igidl; + cdhat = cd - here->HSM2_gbd * delvbd + + (here->HSM2_gmbs + here->HSM2_gbbs + here->HSM2_gigidlbs) * delvbs + + (here->HSM2_gm + here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgs + + (here->HSM2_gds + here->HSM2_gbds + here->HSM2_gigidlds) * delvds; + Ibtot = here->HSM2_ibs + here->HSM2_ibd - here->HSM2_isub + - here->HSM2_igidl - here->HSM2_igisl; + cbhat = Ibtot + here->HSM2_gbd * delvbd + + (here->HSM2_gbs - here->HSM2_gbbs - here->HSM2_gigidlbs) * delvbs + - (here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgs + - (here->HSM2_gbds + here->HSM2_gigidlds) * delvds + - here->HSM2_gigislgd * delvgd - here->HSM2_gigislbd * delvbd + + here->HSM2_gigislsd * delvds; + Igstot = here->HSM2_igs; + cgshat = Igstot + here->HSM2_gigsg * delvgs + + here->HSM2_gigsd * delvds + here->HSM2_gigsb * delvbs; + Igdtot = here->HSM2_igd; + cgdhat = Igdtot + here->HSM2_gigdg * delvgs + + here->HSM2_gigdd * delvds + here->HSM2_gigdb * delvbs; + Igbtot = here->HSM2_igb; + cgbhat = Igbtot + here->HSM2_gigbg * delvgs + + here->HSM2_gigbd * delvds + here->HSM2_gigbb * delvbs; + } + else { + cd -= here->HSM2_igidl; + cdhat = cd + + (here->HSM2_gmbs + here->HSM2_gbd - here->HSM2_gigidlbs) * delvbd + + (here->HSM2_gm - here->HSM2_gigidlgs) * delvgd + + (- here->HSM2_gds + here->HSM2_gigidlds) * delvds; + Ibtot = here->HSM2_ibs + here->HSM2_ibd - here->HSM2_isub + - here->HSM2_igidl - here->HSM2_igisl; + cbhat = Ibtot + here->HSM2_gbs * delvbs + + (here->HSM2_gbd - here->HSM2_gbbs - here->HSM2_gigidlbs) * delvbd + - (here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgd + + (here->HSM2_gbds + here->HSM2_gigidlds) * delvds + - here->HSM2_gigislgd * delvgd - here->HSM2_gigislbd * delvbd + + here->HSM2_gigislsd * delvds; + Igbtot = here->HSM2_igb; + cgbhat = Igbtot + here->HSM2_gigbg * delvgd + - here->HSM2_gigbs * delvds + here->HSM2_gigbb * delvbd; + Igstot = here->HSM2_igs; + cgshat = Igstot + here->HSM2_gigsg * delvgd + - here->HSM2_gigss * delvds + here->HSM2_gigsb * delvbd; + Igdtot = here->HSM2_igd; + cgdhat = Igdtot + here->HSM2_gigdg * delvgd + - here->HSM2_gigds * delvds + here->HSM2_gigdb * delvbd; + } + + /* + * check convergence + */ + if ( here->HSM2_off == 0 || !(ckt->CKTmode & MODEINITFIX) ) { + tol0 = ckt->CKTreltol * MAX(FABS(cdhat), FABS(cd)) + ckt->CKTabstol; + tol1 = ckt->CKTreltol * MAX(FABS(cgshat), FABS(Igstot)) + ckt->CKTabstol; + tol2 = ckt->CKTreltol * MAX(FABS(cgdhat), FABS(Igdtot)) + ckt->CKTabstol; + tol3 = ckt->CKTreltol * MAX(FABS(cgbhat), FABS(Igbtot)) + ckt->CKTabstol; + tol4 = ckt->CKTreltol * MAX(FABS(cbhat), FABS(Ibtot)) + ckt->CKTabstol; + + if ( (FABS(cdhat - cd) >= tol0) + || (FABS(cgshat - Igstot) >= tol1) + || (FABS(cgdhat - Igdtot) >= tol2) + || (FABS(cgbhat - Igbtot) >= tol3) + || (FABS(cbhat - Ibtot) >= tol4) ) { + ckt->CKTnoncon++; + return(OK); + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2def.h b/src/spicelib/devices/hisim2/hsm2def.h new file mode 100644 index 000000000..ad151483b --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2def.h @@ -0,0 +1,2168 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2def.h + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#ifndef HSM2 +#define HSM2 + +#include "ifsim.h" +#include "gendefs.h" +#include "cktdefs.h" +#include "complex.h" +#include "noisedef.h" + +/* declarations for HiSIM2 MOSFETs */ + +/* binning parameters */ +typedef struct sHSM2binningParam { + double HSM2_vmax ; + double HSM2_bgtmp1 ; + double HSM2_bgtmp2 ; + double HSM2_eg0 ; + double HSM2_lover ; + double HSM2_vfbover ; + double HSM2_nover ; + double HSM2_wl2 ; + double HSM2_vfbc ; + double HSM2_nsubc ; + double HSM2_nsubp ; + double HSM2_scp1 ; + double HSM2_scp2 ; + double HSM2_scp3 ; + double HSM2_sc1 ; + double HSM2_sc2 ; + double HSM2_sc3 ; + double HSM2_sc4 ; + double HSM2_pgd1 ; +//double HSM2_pgd3 ; + double HSM2_ndep ; + double HSM2_ninv ; + double HSM2_muecb0 ; + double HSM2_muecb1 ; + double HSM2_mueph1 ; + double HSM2_vtmp ; + double HSM2_wvth0 ; + double HSM2_muesr1 ; + double HSM2_muetmp ; + double HSM2_sub1 ; + double HSM2_sub2 ; + double HSM2_svds ; + double HSM2_svbs ; + double HSM2_svgs ; + double HSM2_nsti ; + double HSM2_wsti ; + double HSM2_scsti1 ; + double HSM2_scsti2 ; + double HSM2_vthsti ; + double HSM2_muesti1 ; + double HSM2_muesti2 ; + double HSM2_muesti3 ; + double HSM2_nsubpsti1 ; + double HSM2_nsubpsti2 ; + double HSM2_nsubpsti3 ; + double HSM2_cgso ; + double HSM2_cgdo ; + double HSM2_js0 ; + double HSM2_js0sw ; + double HSM2_nj ; + double HSM2_cisbk ; + double HSM2_clm1 ; + double HSM2_clm2 ; + double HSM2_clm3 ; + double HSM2_wfc ; + double HSM2_gidl1 ; + double HSM2_gidl2 ; + double HSM2_gleak1 ; + double HSM2_gleak2 ; + double HSM2_gleak3 ; + double HSM2_gleak6 ; + double HSM2_glksd1 ; + double HSM2_glksd2 ; + double HSM2_glkb1 ; + double HSM2_glkb2 ; + double HSM2_nftrp ; + double HSM2_nfalp ; + double HSM2_vdiffj ; + double HSM2_ibpc1 ; + double HSM2_ibpc2 ; +} HSM2binningParam ; + +/* information needed for each instance */ +typedef struct sHSM2instance { + struct sHSM2model *HSM2modPtr; /* pointer to model */ + struct sHSM2instance *HSM2nextInstance; /* pointer to next instance of + current model*/ + IFuid HSM2name; /* pointer to character string naming this instance */ + int HSM2states; /* index into state table for this device */ + + int HSM2dNode; /* number of the drain node of the mosfet */ + int HSM2gNode; /* number of the gate node of the mosfet */ + int HSM2sNode; /* number of the source node of the mosfet */ + int HSM2bNode; /* number of the bulk node of the mosfet */ + int HSM2dNodePrime; /* number od the inner drain node */ + int HSM2gNodePrime; /* number of the inner gate node */ + int HSM2sNodePrime; /* number od the inner source node */ + int HSM2bNodePrime; + int HSM2dbNode; + int HSM2sbNode; + + double HSM2_noiflick; /* for 1/f noise calc. */ + double HSM2_noithrml; /* for thrmal noise calc. */ + double HSM2_noiigate; /* for induced gate noise */ + double HSM2_noicross; /* for induced gate noise */ + + /* instance */ + double HSM2_l; /* the length of the channel region */ + double HSM2_w; /* the width of the channel region */ + double HSM2_ad; /* the area of the drain diffusion */ + double HSM2_as; /* the area of the source diffusion */ + double HSM2_pd; /* perimeter of drain junction [m] */ + double HSM2_ps; /* perimeter of source junction [m] */ + double HSM2_nrd; /* equivalent num of squares of drain [-] (unused) */ + double HSM2_nrs; /* equivalent num of squares of source [-] (unused) */ + double HSM2_temp; /* lattice temperature [K] */ + double HSM2_dtemp; + + double HSM2_weff; /* the effective width of the channel region */ + double HSM2_weff_nf; /* Weff * NF */ + double HSM2_leff; /* the effective length of the channel region */ + + int HSM2_corbnet ; + double HSM2_rbpb ; + double HSM2_rbpd ; + double HSM2_rbps ; + double HSM2_rbdb ; + double HSM2_rbsb ; + + int HSM2_corg ; +/* double HSM2_rshg; */ + double HSM2_ngcon; + double HSM2_xgw; + double HSM2_xgl; + double HSM2_nf; + + double HSM2_sa; + double HSM2_sb; + double HSM2_sd; + double HSM2_nsubcdfm; /* DFM */ + double HSM2_mphdfm; /* DFM */ + double HSM2_m; + + int HSM2_called; /* flag to check the first call */ + /* previous values to evaluate initial guess */ + double HSM2_mode_prv; + double HSM2_vbsc_prv; + double HSM2_vdsc_prv; + double HSM2_vgsc_prv; + double HSM2_ps0_prv; + double HSM2_ps0_dvbs_prv; + double HSM2_ps0_dvds_prv; + double HSM2_ps0_dvgs_prv; + double HSM2_pds_prv; + double HSM2_pds_dvbs_prv; + double HSM2_pds_dvds_prv; + double HSM2_pds_dvgs_prv; + double HSM2_ids_prv; + double HSM2_ids_dvbs_prv; + double HSM2_ids_dvds_prv; + double HSM2_ids_dvgs_prv; + double HSM2_mode_prv2; + double HSM2_vbsc_prv2; + double HSM2_vdsc_prv2; + double HSM2_vgsc_prv2; + double HSM2_ps0_prv2; + double HSM2_ps0_dvbs_prv2; + double HSM2_ps0_dvds_prv2; + double HSM2_ps0_dvgs_prv2; + double HSM2_pds_prv2; + double HSM2_pds_dvbs_prv2; + double HSM2_pds_dvds_prv2; + double HSM2_pds_dvgs_prv2; + double HSM2_PS0Z_SCE_prv ; + double HSM2_PS0Z_SCE_dvds_prv ; + double HSM2_PS0Z_SCE_dvgs_prv ; + double HSM2_PS0Z_SCE_dvbs_prv ; + + /* output */ + int HSM2_capop; + double HSM2_gd; + double HSM2_gs; + double HSM2_cgso; + double HSM2_cgdo; + double HSM2_cgbo; + double HSM2_cdso; + double HSM2_cddo; + double HSM2_cdgo; + double HSM2_csso; + double HSM2_csdo; + double HSM2_csgo; + double HSM2_cqyd; + double HSM2_cqyg; + double HSM2_cqyb; + double HSM2_von; /* vth */ + double HSM2_vdsat; + double HSM2_ids; /* cdrain, HSM2_cd */ + double HSM2_gds; + double HSM2_gm; + double HSM2_gmbs; + double HSM2_ibs; /* HSM2_cbs */ + double HSM2_ibd; /* HSM2_cbd */ + double HSM2_gbs; + double HSM2_gbd; + double HSM2_capbs; + double HSM2_capbd; + double HSM2_capgs; + double HSM2_capgd; + double HSM2_capgb; + double HSM2_isub; /* HSM2_csub */ + double HSM2_gbgs; + double HSM2_gbds; + double HSM2_gbbs; + double HSM2_qg; + double HSM2_qd; + double HSM2_qs; + double HSM2_qb; /* bulk charge qb = -(qg + qd + qs) */ + double HSM2_cggb; + double HSM2_cgdb; + double HSM2_cgsb; + double HSM2_cbgb; + double HSM2_cbdb; + double HSM2_cbsb; + double HSM2_cdgb; + double HSM2_cddb; + double HSM2_cdsb; + + double HSM2_mu; /* mobility */ + double HSM2_igidl; /* gate induced drain leakage */ + double HSM2_gigidlgs; + double HSM2_gigidlds; + double HSM2_gigidlbs; + double HSM2_igisl; /* gate induced source leakage */ + double HSM2_gigislgd; + double HSM2_gigislsd; + double HSM2_gigislbd; + double HSM2_igb; /* gate tunneling current (gate to bulk) */ + double HSM2_gigbg; + double HSM2_gigbd; + double HSM2_gigbb; + double HSM2_gigbs; + double HSM2_igs; /* gate tunneling current (gate to source) */ + double HSM2_gigsg; + double HSM2_gigsd; + double HSM2_gigsb; + double HSM2_gigss; + double HSM2_igd; /* gate tunneling current (gate to drain) */ + double HSM2_gigdg; + double HSM2_gigdd; + double HSM2_gigdb; + double HSM2_gigds; + + /* NQS */ + double HSM2_tau ; + double HSM2_tau_dVgs ; + double HSM2_tau_dVds ; + double HSM2_tau_dVbs ; + double HSM2_Xd ; + double HSM2_Xd_dVgs ; + double HSM2_Xd_dVds ; + double HSM2_Xd_dVbs ; + double HSM2_Qi ; + double HSM2_Qi_dVgs ; + double HSM2_Qi_dVds ; + double HSM2_Qi_dVbs ; + double HSM2_taub ; + double HSM2_taub_dVgs ; + double HSM2_taub_dVds ; + double HSM2_taub_dVbs ; + double HSM2_Qb ; + double HSM2_Qb_dVgs ; + double HSM2_Qb_dVds ; + double HSM2_Qb_dVbs ; + double HSM2_alpha; + + /* internal variables */ + double HSM2_eg ; + double HSM2_beta ; + double HSM2_beta_inv ; + double HSM2_beta2 ; + double HSM2_betatnom ; + double HSM2_nin ; + double HSM2_egp12 ; + double HSM2_egp32 ; + double HSM2_lgate ; + double HSM2_wg ; + double HSM2_mueph ; + double HSM2_mphn0 ; + double HSM2_mphn1 ; + double HSM2_muesr ; + double HSM2_nsub ; + double HSM2_qnsub ; + double HSM2_qnsub_esi ; + double HSM2_2qnsub_esi ; + double HSM2_ptovr0 ; + double HSM2_ptovr ; + double HSM2_vmax0 ; + double HSM2_vmax ; + double HSM2_pb2 ; + double HSM2_pb20 ; + double HSM2_pb2c ; + double HSM2_cnst0 ; + double HSM2_cnst1 ; + double HSM2_isbd ; + double HSM2_isbd2 ; + double HSM2_isbs ; + double HSM2_isbs2 ; + double HSM2_vbdt ; + double HSM2_vbst ; + double HSM2_exptemp ; + double HSM2_wsti ; + double HSM2_cnstpgd ; + double HSM2_ninvp0 ; + double HSM2_ninv0 ; + double HSM2_grbpb ; + double HSM2_grbpd ; + double HSM2_grbps ; + double HSM2_grbdb ; + double HSM2_grbsb ; + double HSM2_grg ; + double HSM2_rs ; + double HSM2_rd ; + double HSM2_clmmod ; + double HSM2_lgatesm ; + double HSM2_dVthsm ; + double HSM2_ddlt ; + /* 2007.02.20--03.15 */ + double HSM2_xsub1 ; + double HSM2_xsub2 ; + double HSM2_xgate ; + double HSM2_xvbs ; + double HSM2_vg2const ; + double HSM2_wdpl ; + double HSM2_wdplp ; + double HSM2_cfrng ; + double HSM2_jd_nvtm_inv ; + double HSM2_jd_expcd ; + double HSM2_jd_expcs ; + double HSM2_sqrt_eg ; + + double HSM2_egtnom ; + double HSM2_cecox ; + double HSM2_msc ; + int HSM2_flg_pgd ; + double HSM2_ndep_o_esi ; + double HSM2_ninv_o_esi ; + double HSM2_cqyb0 ; + double HSM2_cnst0over ; + double HSM2_costi00 ; + double HSM2_nsti_p2 ; + double HSM2_costi0 ; + double HSM2_costi0_p2 ; + double HSM2_costi1 ; + double HSM2_pb2over ; /* for Qover model */ + double HSM2_ps0ldinib ; + double HSM2_ptl0; + double HSM2_pt40; + double HSM2_gdl0; + double HSM2_muecb0; + double HSM2_muecb1; + + HSM2binningParam pParam ; /* binning parameters */ + + /* no use in SPICE3f5 + double HSM2drainSquares; the length of the drain in squares + double HSM2sourceSquares; the length of the source in squares */ + double HSM2sourceConductance; /* cond. of source (or 0): set in setup */ + double HSM2drainConductance; /* cond. of drain (or 0): set in setup */ + double HSM2internalGs; /* internal cond. of source for thermal noise calc. */ + double HSM2internalGd; /* internal cond. of drain for thermal noise calc. */ + + double HSM2_icVBS; /* initial condition B-S voltage */ + double HSM2_icVDS; /* initial condition D-S voltage */ + double HSM2_icVGS; /* initial condition G-S voltage */ + int HSM2_off; /* non-zero to indicate device is off for dc analysis */ + int HSM2_mode; /* device mode : 1 = normal, -1 = inverse */ + + unsigned HSM2_l_Given :1; + unsigned HSM2_w_Given :1; + unsigned HSM2_ad_Given :1; + unsigned HSM2_as_Given :1; + /* unsigned HSM2drainSquaresGiven :1; + unsigned HSM2sourceSquaresGiven :1;*/ + unsigned HSM2_pd_Given :1; + unsigned HSM2_ps_Given :1; + unsigned HSM2_nrd_Given :1; + unsigned HSM2_nrs_Given :1; + unsigned HSM2_temp_Given :1; + unsigned HSM2_dtemp_Given :1; + unsigned HSM2_icVBS_Given :1; + unsigned HSM2_icVDS_Given :1; + unsigned HSM2_icVGS_Given :1; + unsigned HSM2_corbnet_Given :1; + unsigned HSM2_rbpb_Given :1; + unsigned HSM2_rbpd_Given :1; + unsigned HSM2_rbps_Given :1; + unsigned HSM2_rbdb_Given :1; + unsigned HSM2_rbsb_Given :1; + unsigned HSM2_corg_Given :1; +/* unsigned HSM2_rshg_Given :1; */ + unsigned HSM2_ngcon_Given :1; + unsigned HSM2_xgw_Given :1; + unsigned HSM2_xgl_Given :1; + unsigned HSM2_nf_Given :1; + unsigned HSM2_sa_Given :1; + unsigned HSM2_sb_Given :1; + unsigned HSM2_sd_Given :1; + unsigned HSM2_nsubcdfm_Given :1; /* DFM */ + unsigned HSM2_mphdfm_Given :1; /* DFM */ + unsigned HSM2_m_Given :1; + + /* pointer to sparse matrix */ + + double *HSM2GgPtr; /* pointer to sparse matrix element at (gate node,gate node) */ + double *HSM2GgpPtr; /* pointer to sparse matrix element at (gate node,gate prime node) */ + double *HSM2GdpPtr; /* pointer to sparse matrix element at (gate node,drain prime node) */ + double *HSM2GspPtr; /* pointer to sparse matrix element at (gate node,source prime node) */ + double *HSM2GbpPtr; /* pointer to sparse matrix element at (gate node,bulk prime node) */ + + double *HSM2GPgPtr; /* pointer to sparse matrix element at (gate prime node,gate node) */ + double *HSM2GPgpPtr; /* pointer to sparse matrix element at (gate prime node,gate prime node) */ + double *HSM2GPdpPtr; /* pointer to sparse matrix element at (gate prime node,drain prime node) */ + double *HSM2GPspPtr; /* pointer to sparse matrix element at (gate prime node,source prime node) */ + double *HSM2GPbpPtr; /* pointer to sparse matrix element at (gate prime node,bulk prime node) */ + + double *HSM2DPdPtr; /* pointer to sparse matrix element at (drain prime node,drain node) */ + double *HSM2DPdpPtr; /* pointer to sparse matrix element at (drain prime node,drain prime node) */ + double *HSM2DPgpPtr; /* pointer to sparse matrix element at (drain prime node,gate prime node) */ + double *HSM2DPspPtr; /* pointer to sparse matrix element at (drain prime node,source prime node) */ + double *HSM2DPbpPtr; /* pointer to sparse matrix element at (drain prime node,bulk prime node) */ + double *HSM2DPdbPtr; /* pointer to sparse matrix element at (drain prime node,drain body node) */ + + double *HSM2DdPtr; /* pointer to sparse matrix element at (Drain node,drain node) */ + double *HSM2DdpPtr; /* pointer to sparse matrix element at (drain node,drain prime node) */ + + double *HSM2SPsPtr; /* pointer to sparse matrix element at (source prime node,source node) */ + double *HSM2SPspPtr; /* pointer to sparse matrix element at (source prime node,source prime node) */ + double *HSM2SPgpPtr; /* pointer to sparse matrix element at (source prime node,gate prime node) */ + double *HSM2SPdpPtr; /* pointer to sparse matrix element at (source prime node,drain prime node) */ + double *HSM2SPbpPtr; /* pointer to sparse matrix element at (source prime node,bulk prime node) */ + double *HSM2SPsbPtr; /* pointer to sparse matrix element at (source prime node,source body node) */ + + double *HSM2SsPtr; /* pointer to sparse matrix element at (source node,source node) */ + double *HSM2SspPtr; /* pointer to sparse matrix element at (source node,source prime node) */ + + double *HSM2BPgpPtr; /* pointer to sparse matrix element at (bulk prime node,gate prime node) */ + double *HSM2BPbpPtr; /* pointer to sparse matrix element at (bulk prime node,bulk prime node) */ + double *HSM2BPdpPtr; /* pointer to sparse matrix element at (bulk prime node,drain prime node) */ + double *HSM2BPspPtr; /* pointer to sparse matrix element at (bulk prime node,source prime node) */ + double *HSM2BPbPtr; /* pointer to sparse matrix element at (bulk prime node,bulk node) */ + double *HSM2BPdbPtr; /* pointer to sparse matrix element at (bulk prime node,source body node) */ + double *HSM2BPsbPtr; /* pointer to sparse matrix element at (bulk prime node,source body node) */ + + double *HSM2DBdpPtr; /* pointer to sparse matrix element at (drain body node,drain prime node) */ + double *HSM2DBdbPtr; /* pointer to sparse matrix element at (drain body node,drain body node) */ + double *HSM2DBbpPtr; /* pointer to sparse matrix element at (drain body node,bulk prime node) */ + double *HSM2DBbPtr; /* pointer to sparse matrix element at (drain body node,bulk node) */ + + double *HSM2SBspPtr; /* pointer to sparse matrix element at (source body node,drain prime node) */ + double *HSM2SBbpPtr; /* pointer to sparse matrix element at (source body node,drain body node) */ + double *HSM2SBbPtr; /* pointer to sparse matrix element at (source body node,bulk prime node) */ + double *HSM2SBsbPtr; /* pointer to sparse matrix element at (source body node,bulk node) */ + + double *HSM2BsbPtr; /* pointer to sparse matrix element at (bulk node,source body node) */ + double *HSM2BbpPtr; /* pointer to sparse matrix element at (bulk node,bulk prime node) */ + double *HSM2BdbPtr; /* pointer to sparse matrix element at (bulk node,drain body node) */ + double *HSM2BbPtr; /* pointer to sparse matrix element at (bulk node,bulk node) */ + + /* common state values in hisim module */ +#define HSM2vbd HSM2states+ 0 +#define HSM2vbs HSM2states+ 1 +#define HSM2vgs HSM2states+ 2 +#define HSM2vds HSM2states+ 3 +#define HSM2vdbs HSM2states+ 4 +#define HSM2vdbd HSM2states+ 5 +#define HSM2vsbs HSM2states+ 6 +#define HSM2vges HSM2states+ 7 + +#define HSM2qb HSM2states+ 8 +#define HSM2cqb HSM2states+ 9 +#define HSM2qg HSM2states+ 10 +#define HSM2cqg HSM2states+ 11 +#define HSM2qd HSM2states+ 12 +#define HSM2cqd HSM2states+ 13 + +#define HSM2qbs HSM2states+ 14 +#define HSM2cqbs HSM2states+ 15 +#define HSM2qbd HSM2states+ 16 +#define HSM2cqbd HSM2states+ 17 + +#define HSM2numStates 18 + +/* nqs charges */ +#define HSM2qi_nqs HSM2states+ 19 +#define HSM2qb_nqs HSM2states+ 20 + +#define HSM2numStatesNqs 21 + + /* indices to the array of HiSIM2 NOISE SOURCES (the same as BSIM3) */ +#define HSM2RDNOIZ 0 +#define HSM2RSNOIZ 1 +#define HSM2IDNOIZ 2 +#define HSM2FLNOIZ 3 +#define HSM2IGSNOIZ 4 /* shot noise */ +#define HSM2IGDNOIZ 5 /* shot noise */ +#define HSM2IGBNOIZ 6 /* shot noise */ +#define HSM2IGNOIZ 7 /* induced gate noise */ +#define HSM2TOTNOIZ 8 + +#define HSM2NSRCS 9 /* the number of HiSIM2 MOSFET noise sources */ + +#ifndef NONOISE + double HSM2nVar[NSTATVARS][HSM2NSRCS]; +#else /* NONOISE */ + double **HSM2nVar; +#endif /* NONOISE */ + +} HSM2instance ; + + +/* per model data */ + +typedef struct sHSM2model { /* model structure for a resistor */ + int HSM2modType; /* type index of this device type */ + struct sHSM2model *HSM2nextModel; /* pointer to next possible model + in linked list */ + HSM2instance * HSM2instances; /* pointer to list of instances + that have this model */ + IFuid HSM2modName; /* pointer to the name of this model */ + int HSM2_type; /* device type: 1 = nmos, -1 = pmos */ + int HSM2_level; /* level */ + int HSM2_info; /* information */ + int HSM2_noise; /* noise model selecter see hsm2noi.c */ + int HSM2_version; /* model version 200 */ + int HSM2_show; /* show physical value 1, 2, ... , 11 */ + + /* flags for initial guess */ + int HSM2_corsrd ; + int HSM2_corg ; + int HSM2_coiprv ; + int HSM2_copprv ; + int HSM2_coadov ; + int HSM2_coisub ; + int HSM2_coiigs ; + int HSM2_cogidl ; + int HSM2_coovlp ; + int HSM2_coflick ; + int HSM2_coisti ; + int HSM2_conqs ; /* HiSIM2 */ + int HSM2_corbnet ; + int HSM2_cothrml; + int HSM2_coign; /* induced gate noise */ + int HSM2_codfm; /* DFM */ + int HSM2_corecip; + int HSM2_coqy; + int HSM2_coqovsm ; + + /* HiSIM original */ + double HSM2_vmax ; + double HSM2_bgtmp1 ; + double HSM2_bgtmp2 ; + double HSM2_eg0 ; + double HSM2_tox ; + double HSM2_xld ; + double HSM2_lover ; + double HSM2_ddltmax ; /* Vdseff */ + double HSM2_ddltslp ; /* Vdseff */ + double HSM2_ddltict ; /* Vdseff */ + double HSM2_vfbover ; + double HSM2_nover ; + double HSM2_xwd ; + double HSM2_xl ; + double HSM2_xw ; + double HSM2_saref ; + double HSM2_sbref ; + double HSM2_ll ; + double HSM2_lld ; + double HSM2_lln ; + double HSM2_wl ; + double HSM2_wl1 ; + double HSM2_wl1p ; + double HSM2_wl2 ; + double HSM2_wl2p ; + double HSM2_wld ; + double HSM2_wln ; + double HSM2_xqy ; + double HSM2_xqy1 ; + double HSM2_xqy2 ; + double HSM2_qyrat ; + double HSM2_rs; /* source contact resistance */ + double HSM2_rd; /* drain contact resistance */ + double HSM2_rsh; /* source/drain diffusion sheet resistance */ + double HSM2_rshg; +/* double HSM2_ngcon; */ +/* double HSM2_xgw; */ +/* double HSM2_xgl; */ +/* double HSM2_nf; */ + double HSM2_vfbc ; + double HSM2_vbi ; + double HSM2_nsubc ; + double HSM2_parl2 ; + double HSM2_lp ; + double HSM2_nsubp ; + double HSM2_nsubpl ; + double HSM2_nsubpfac ; + double HSM2_nsubpw ; + double HSM2_nsubpwp ; + double HSM2_scp1 ; + double HSM2_scp2 ; + double HSM2_scp3 ; + double HSM2_sc1 ; + double HSM2_sc2 ; + double HSM2_sc3 ; + double HSM2_sc4 ; + double HSM2_pgd1 ; + double HSM2_pgd2 ; +//double HSM2_pgd3 ; + double HSM2_pgd4 ; + double HSM2_ndep ; + double HSM2_ndepl ; + double HSM2_ndeplp ; + double HSM2_ndepw ; + double HSM2_ndepwp ; + double HSM2_ninv ; + double HSM2_ninvd ; + double HSM2_muecb0 ; + double HSM2_muecb1 ; + double HSM2_mueph1 ; + double HSM2_mueph0 ; + double HSM2_muephw ; + double HSM2_muepwp ; + double HSM2_muepwd ; + double HSM2_muephl ; + double HSM2_mueplp ; + double HSM2_muepld ; + double HSM2_muephs ; + double HSM2_muepsp ; + double HSM2_vtmp ; + double HSM2_wvth0 ; + double HSM2_muesr1 ; + double HSM2_muesr0 ; + double HSM2_muesrw ; + double HSM2_mueswp ; + double HSM2_muesrl ; + double HSM2_mueslp ; + double HSM2_bb ; + double HSM2_sub1 ; + double HSM2_sub2 ; + double HSM2_svgs ; + double HSM2_svbs ; + double HSM2_svbsl ; + double HSM2_svds ; + double HSM2_slg ; + double HSM2_sub1l ; + double HSM2_sub2l ; + double HSM2_svgsl ; + double HSM2_svgslp ; + double HSM2_svgswp ; + double HSM2_svgsw ; + double HSM2_svbslp ; + double HSM2_slgl ; + double HSM2_slglp ; + double HSM2_sub1lp ; + double HSM2_nsti ; + double HSM2_wsti ; + double HSM2_wstil ; + double HSM2_wstilp ; + double HSM2_wstiw ; + double HSM2_wstiwp ; + double HSM2_scsti1 ; + double HSM2_scsti2 ; + double HSM2_vthsti ; + double HSM2_vdsti ; + double HSM2_muesti1 ; + double HSM2_muesti2 ; + double HSM2_muesti3 ; + double HSM2_nsubpsti1 ; + double HSM2_nsubpsti2 ; + double HSM2_nsubpsti3 ; + double HSM2_lpext ; + double HSM2_npext ; + double HSM2_npextw ; + double HSM2_npextwp ; + double HSM2_scp22 ; + double HSM2_scp21 ; + double HSM2_bs1 ; + double HSM2_bs2 ; + double HSM2_cgso ; + double HSM2_cgdo ; + double HSM2_cgbo ; + double HSM2_tpoly ; + double HSM2_js0 ; + double HSM2_js0sw ; + double HSM2_nj ; + double HSM2_njsw ; + double HSM2_xti ; + double HSM2_cj ; + double HSM2_cjsw ; + double HSM2_cjswg ; + double HSM2_mj ; + double HSM2_mjsw ; + double HSM2_mjswg ; + double HSM2_xti2 ; + double HSM2_cisb ; + double HSM2_cvb ; + double HSM2_ctemp ; + double HSM2_cisbk ; + double HSM2_cvbk ; + double HSM2_divx ; + double HSM2_pb ; + double HSM2_pbsw ; + double HSM2_pbswg ; + double HSM2_tcjbd ; + double HSM2_tcjbs ; + double HSM2_tcjbdsw ; + double HSM2_tcjbssw ; + double HSM2_tcjbdswg ; + double HSM2_tcjbsswg ; + + double HSM2_clm1 ; + double HSM2_clm2 ; + double HSM2_clm3 ; + double HSM2_clm5 ; + double HSM2_clm6 ; + double HSM2_muetmp ; + double HSM2_vover ; + double HSM2_voverp ; + double HSM2_vovers ; + double HSM2_voversp ; + double HSM2_wfc ; + double HSM2_nsubcw ; + double HSM2_nsubcwp ; + double HSM2_nsubcmax ; + double HSM2_qme1 ; + double HSM2_qme2 ; + double HSM2_qme3 ; + double HSM2_gidl1 ; + double HSM2_gidl2 ; + double HSM2_gidl3 ; + double HSM2_gidl4 ; + double HSM2_gidl5 ; + double HSM2_gleak1 ; + double HSM2_gleak2 ; + double HSM2_gleak3 ; + double HSM2_gleak4 ; + double HSM2_gleak5 ; + double HSM2_gleak6 ; + double HSM2_gleak7 ; + double HSM2_glksd1 ; + double HSM2_glksd2 ; + double HSM2_glksd3 ; + double HSM2_glkb1 ; + double HSM2_glkb2 ; + double HSM2_glkb3 ; + double HSM2_egig; + double HSM2_igtemp2; + double HSM2_igtemp3; + double HSM2_vzadd0 ; + double HSM2_pzadd0 ; + double HSM2_nftrp ; + double HSM2_nfalp ; + double HSM2_falph ; + double HSM2_cit ; + double HSM2_kappa ; + double HSM2_vdiffj ; + double HSM2_dly1 ; + double HSM2_dly2 ; + double HSM2_dly3; + double HSM2_tnom ; + double HSM2_ovslp ; + double HSM2_ovmag ; + /* substrate resistances */ + double HSM2_gbmin; + double HSM2_rbpb ; + double HSM2_rbpd ; + double HSM2_rbps ; + double HSM2_rbdb ; + double HSM2_rbsb ; + /* IBPC */ + double HSM2_ibpc1 ; + double HSM2_ibpc2 ; + /* DFM */ + double HSM2_mphdfm ; + + double HSM2_ptl, HSM2_ptp, HSM2_pt2, HSM2_ptlp, HSM2_gdl, HSM2_gdlp ; + + double HSM2_gdld ; + double HSM2_pt4 ; + double HSM2_pt4p ; + double HSM2_muephl2 ; + double HSM2_mueplp2 ; + double HSM2_nsubcw2 ; + double HSM2_nsubcwp2 ; + double HSM2_muephw2 ; + double HSM2_muepwp2 ; + + /* for Ps0_min */ + double HSM2_Vgsmin ; + double HSM2_sc3Vbs ; /* SC3 clamping */ + double HSM2_byptol ; /* bypass control */ + double HSM2_muecb0lp; + double HSM2_muecb1lp; + + + /* binning parameters */ + double HSM2_lmin ; + double HSM2_lmax ; + double HSM2_wmin ; + double HSM2_wmax ; + double HSM2_lbinn ; + double HSM2_wbinn ; + + /* Length dependence */ + double HSM2_lvmax ; + double HSM2_lbgtmp1 ; + double HSM2_lbgtmp2 ; + double HSM2_leg0 ; + double HSM2_llover ; + double HSM2_lvfbover ; + double HSM2_lnover ; + double HSM2_lwl2 ; + double HSM2_lvfbc ; + double HSM2_lnsubc ; + double HSM2_lnsubp ; + double HSM2_lscp1 ; + double HSM2_lscp2 ; + double HSM2_lscp3 ; + double HSM2_lsc1 ; + double HSM2_lsc2 ; + double HSM2_lsc3 ; + double HSM2_lsc4 ; + double HSM2_lpgd1 ; +//double HSM2_lpgd3 ; + double HSM2_lndep ; + double HSM2_lninv ; + double HSM2_lmuecb0 ; + double HSM2_lmuecb1 ; + double HSM2_lmueph1 ; + double HSM2_lvtmp ; + double HSM2_lwvth0 ; + double HSM2_lmuesr1 ; + double HSM2_lmuetmp ; + double HSM2_lsub1 ; + double HSM2_lsub2 ; + double HSM2_lsvds ; + double HSM2_lsvbs ; + double HSM2_lsvgs ; + double HSM2_lnsti ; + double HSM2_lwsti ; + double HSM2_lscsti1 ; + double HSM2_lscsti2 ; + double HSM2_lvthsti ; + double HSM2_lmuesti1 ; + double HSM2_lmuesti2 ; + double HSM2_lmuesti3 ; + double HSM2_lnsubpsti1 ; + double HSM2_lnsubpsti2 ; + double HSM2_lnsubpsti3 ; + double HSM2_lcgso ; + double HSM2_lcgdo ; + double HSM2_ljs0 ; + double HSM2_ljs0sw ; + double HSM2_lnj ; + double HSM2_lcisbk ; + double HSM2_lclm1 ; + double HSM2_lclm2 ; + double HSM2_lclm3 ; + double HSM2_lwfc ; + double HSM2_lgidl1 ; + double HSM2_lgidl2 ; + double HSM2_lgleak1 ; + double HSM2_lgleak2 ; + double HSM2_lgleak3 ; + double HSM2_lgleak6 ; + double HSM2_lglksd1 ; + double HSM2_lglksd2 ; + double HSM2_lglkb1 ; + double HSM2_lglkb2 ; + double HSM2_lnftrp ; + double HSM2_lnfalp ; + double HSM2_lvdiffj ; + double HSM2_libpc1 ; + double HSM2_libpc2 ; + + /* Width dependence */ + double HSM2_wvmax ; + double HSM2_wbgtmp1 ; + double HSM2_wbgtmp2 ; + double HSM2_weg0 ; + double HSM2_wlover ; + double HSM2_wvfbover ; + double HSM2_wnover ; + double HSM2_wwl2 ; + double HSM2_wvfbc ; + double HSM2_wnsubc ; + double HSM2_wnsubp ; + double HSM2_wscp1 ; + double HSM2_wscp2 ; + double HSM2_wscp3 ; + double HSM2_wsc1 ; + double HSM2_wsc2 ; + double HSM2_wsc3 ; + double HSM2_wsc4 ; + double HSM2_wpgd1 ; +//double HSM2_wpgd3 ; + double HSM2_wndep ; + double HSM2_wninv ; + double HSM2_wmuecb0 ; + double HSM2_wmuecb1 ; + double HSM2_wmueph1 ; + double HSM2_wvtmp ; + double HSM2_wwvth0 ; + double HSM2_wmuesr1 ; + double HSM2_wmuetmp ; + double HSM2_wsub1 ; + double HSM2_wsub2 ; + double HSM2_wsvds ; + double HSM2_wsvbs ; + double HSM2_wsvgs ; + double HSM2_wnsti ; + double HSM2_wwsti ; + double HSM2_wscsti1 ; + double HSM2_wscsti2 ; + double HSM2_wvthsti ; + double HSM2_wmuesti1 ; + double HSM2_wmuesti2 ; + double HSM2_wmuesti3 ; + double HSM2_wnsubpsti1 ; + double HSM2_wnsubpsti2 ; + double HSM2_wnsubpsti3 ; + double HSM2_wcgso ; + double HSM2_wcgdo ; + double HSM2_wjs0 ; + double HSM2_wjs0sw ; + double HSM2_wnj ; + double HSM2_wcisbk ; + double HSM2_wclm1 ; + double HSM2_wclm2 ; + double HSM2_wclm3 ; + double HSM2_wwfc ; + double HSM2_wgidl1 ; + double HSM2_wgidl2 ; + double HSM2_wgleak1 ; + double HSM2_wgleak2 ; + double HSM2_wgleak3 ; + double HSM2_wgleak6 ; + double HSM2_wglksd1 ; + double HSM2_wglksd2 ; + double HSM2_wglkb1 ; + double HSM2_wglkb2 ; + double HSM2_wnftrp ; + double HSM2_wnfalp ; + double HSM2_wvdiffj ; + double HSM2_wibpc1 ; + double HSM2_wibpc2 ; + + /* Cross-term dependence */ + double HSM2_pvmax ; + double HSM2_pbgtmp1 ; + double HSM2_pbgtmp2 ; + double HSM2_peg0 ; + double HSM2_plover ; + double HSM2_pvfbover ; + double HSM2_pnover ; + double HSM2_pwl2 ; + double HSM2_pvfbc ; + double HSM2_pnsubc ; + double HSM2_pnsubp ; + double HSM2_pscp1 ; + double HSM2_pscp2 ; + double HSM2_pscp3 ; + double HSM2_psc1 ; + double HSM2_psc2 ; + double HSM2_psc3 ; + double HSM2_psc4 ; + double HSM2_ppgd1 ; +//double HSM2_ppgd3 ; + double HSM2_pndep ; + double HSM2_pninv ; + double HSM2_pmuecb0 ; + double HSM2_pmuecb1 ; + double HSM2_pmueph1 ; + double HSM2_pvtmp ; + double HSM2_pwvth0 ; + double HSM2_pmuesr1 ; + double HSM2_pmuetmp ; + double HSM2_psub1 ; + double HSM2_psub2 ; + double HSM2_psvds ; + double HSM2_psvbs ; + double HSM2_psvgs ; + double HSM2_pnsti ; + double HSM2_pwsti ; + double HSM2_pscsti1 ; + double HSM2_pscsti2 ; + double HSM2_pvthsti ; + double HSM2_pmuesti1 ; + double HSM2_pmuesti2 ; + double HSM2_pmuesti3 ; + double HSM2_pnsubpsti1 ; + double HSM2_pnsubpsti2 ; + double HSM2_pnsubpsti3 ; + double HSM2_pcgso ; + double HSM2_pcgdo ; + double HSM2_pjs0 ; + double HSM2_pjs0sw ; + double HSM2_pnj ; + double HSM2_pcisbk ; + double HSM2_pclm1 ; + double HSM2_pclm2 ; + double HSM2_pclm3 ; + double HSM2_pwfc ; + double HSM2_pgidl1 ; + double HSM2_pgidl2 ; + double HSM2_pgleak1 ; + double HSM2_pgleak2 ; + double HSM2_pgleak3 ; + double HSM2_pgleak6 ; + double HSM2_pglksd1 ; + double HSM2_pglksd2 ; + double HSM2_pglkb1 ; + double HSM2_pglkb2 ; + double HSM2_pnftrp ; + double HSM2_pnfalp ; + double HSM2_pvdiffj ; + double HSM2_pibpc1 ; + double HSM2_pibpc2 ; + + /* internal variables */ + double HSM2_vcrit ; + int HSM2_flg_qme ; + double HSM2_qme12 ; + int HSM2_bypass_enable ; + + /* flag for model */ + unsigned HSM2_type_Given :1; + unsigned HSM2_level_Given :1; + unsigned HSM2_info_Given :1; + unsigned HSM2_noise_Given :1; + unsigned HSM2_version_Given :1; + unsigned HSM2_show_Given :1; + unsigned HSM2_corsrd_Given :1; + unsigned HSM2_corg_Given :1; + unsigned HSM2_coiprv_Given :1; + unsigned HSM2_copprv_Given :1; + unsigned HSM2_coadov_Given :1; + unsigned HSM2_coisub_Given :1; + unsigned HSM2_coiigs_Given :1; + unsigned HSM2_cogidl_Given :1; + unsigned HSM2_coovlp_Given :1; + unsigned HSM2_coflick_Given :1; + unsigned HSM2_coisti_Given :1; + unsigned HSM2_conqs_Given :1; + unsigned HSM2_corbnet_Given :1; + unsigned HSM2_cothrml_Given :1; + unsigned HSM2_coign_Given :1; /* induced gate noise */ + unsigned HSM2_codfm_Given :1; /* DFM */ + unsigned HSM2_corecip_Given :1; + unsigned HSM2_coqy_Given :1; + unsigned HSM2_coqovsm_Given :1; + unsigned HSM2_kappa_Given :1; + unsigned HSM2_vdiffj_Given :1; + unsigned HSM2_vmax_Given :1; + unsigned HSM2_bgtmp1_Given :1; + unsigned HSM2_bgtmp2_Given :1; + unsigned HSM2_eg0_Given :1; + unsigned HSM2_tox_Given :1; + unsigned HSM2_xld_Given :1; + unsigned HSM2_lover_Given :1; + unsigned HSM2_ddltmax_Given :1; /* Vdseff */ + unsigned HSM2_ddltslp_Given :1; /* Vdseff */ + unsigned HSM2_ddltict_Given :1; /* Vdseff */ + unsigned HSM2_vfbover_Given :1; + unsigned HSM2_nover_Given :1; + unsigned HSM2_xwd_Given :1; + unsigned HSM2_xl_Given :1; + unsigned HSM2_xw_Given :1; + unsigned HSM2_saref_Given :1; + unsigned HSM2_sbref_Given :1; + unsigned HSM2_ll_Given :1; + unsigned HSM2_lld_Given :1; + unsigned HSM2_lln_Given :1; + unsigned HSM2_wl_Given :1; + unsigned HSM2_wl1_Given :1; + unsigned HSM2_wl1p_Given :1; + unsigned HSM2_wl2_Given :1; + unsigned HSM2_wl2p_Given :1; + unsigned HSM2_wld_Given :1; + unsigned HSM2_wln_Given :1; + unsigned HSM2_xqy_Given :1; + unsigned HSM2_xqy1_Given :1; + unsigned HSM2_xqy2_Given :1; + unsigned HSM2_qyrat_Given :1; + unsigned HSM2_rs_Given :1; + unsigned HSM2_rd_Given :1; + unsigned HSM2_rsh_Given :1; + unsigned HSM2_rshg_Given :1; +/* unsigned HSM2_ngcon_Given :1; */ +/* unsigned HSM2_xgw_Given :1; */ +/* unsigned HSM2_xgl_Given :1; */ +/* unsigned HSM2_nf_Given :1; */ + unsigned HSM2_vfbc_Given :1; + unsigned HSM2_vbi_Given :1; + unsigned HSM2_nsubc_Given :1; + unsigned HSM2_parl2_Given :1; + unsigned HSM2_lp_Given :1; + unsigned HSM2_nsubp_Given :1; + unsigned HSM2_nsubpl_Given :1; + unsigned HSM2_nsubpfac_Given :1; + unsigned HSM2_nsubpw_Given :1; + unsigned HSM2_nsubpwp_Given :1; + unsigned HSM2_scp1_Given :1; + unsigned HSM2_scp2_Given :1; + unsigned HSM2_scp3_Given :1; + unsigned HSM2_sc1_Given :1; + unsigned HSM2_sc2_Given :1; + unsigned HSM2_sc3_Given :1; + unsigned HSM2_sc4_Given :1; + unsigned HSM2_pgd1_Given :1; + unsigned HSM2_pgd2_Given :1; +//unsigned HSM2_pgd3_Given :1; + unsigned HSM2_pgd4_Given :1; + unsigned HSM2_ndep_Given :1; + unsigned HSM2_ndepl_Given :1; + unsigned HSM2_ndeplp_Given :1; + unsigned HSM2_ndepw_Given :1; + unsigned HSM2_ndepwp_Given :1; + unsigned HSM2_ninv_Given :1; + unsigned HSM2_ninvd_Given :1; + unsigned HSM2_muecb0_Given :1; + unsigned HSM2_muecb1_Given :1; + unsigned HSM2_mueph1_Given :1; + unsigned HSM2_mueph0_Given :1; + unsigned HSM2_muephw_Given :1; + unsigned HSM2_muepwp_Given :1; + unsigned HSM2_muepwd_Given :1; + unsigned HSM2_muephl_Given :1; + unsigned HSM2_mueplp_Given :1; + unsigned HSM2_muepld_Given :1; + unsigned HSM2_muephs_Given :1; + unsigned HSM2_muepsp_Given :1; + unsigned HSM2_vtmp_Given :1; + unsigned HSM2_wvth0_Given :1; + unsigned HSM2_muesr1_Given :1; + unsigned HSM2_muesr0_Given :1; + unsigned HSM2_muesrl_Given :1; + unsigned HSM2_mueslp_Given :1; + unsigned HSM2_muesrw_Given :1; + unsigned HSM2_mueswp_Given :1; + unsigned HSM2_bb_Given :1; + unsigned HSM2_sub1_Given :1; + unsigned HSM2_sub2_Given :1; + unsigned HSM2_svgs_Given :1; + unsigned HSM2_svbs_Given :1; + unsigned HSM2_svbsl_Given :1; + unsigned HSM2_svds_Given :1; + unsigned HSM2_slg_Given :1; + unsigned HSM2_sub1l_Given :1; + unsigned HSM2_sub2l_Given :1; + unsigned HSM2_svgsl_Given :1; + unsigned HSM2_svgslp_Given :1; + unsigned HSM2_svgswp_Given :1; + unsigned HSM2_svgsw_Given :1; + unsigned HSM2_svbslp_Given :1; + unsigned HSM2_slgl_Given :1; + unsigned HSM2_slglp_Given :1; + unsigned HSM2_sub1lp_Given :1; + unsigned HSM2_nsti_Given :1; + unsigned HSM2_wsti_Given :1; + unsigned HSM2_wstil_Given :1; + unsigned HSM2_wstilp_Given :1; + unsigned HSM2_wstiw_Given :1; + unsigned HSM2_wstiwp_Given :1; + unsigned HSM2_scsti1_Given :1; + unsigned HSM2_scsti2_Given :1; + unsigned HSM2_vthsti_Given :1; + unsigned HSM2_vdsti_Given :1; + unsigned HSM2_muesti1_Given :1; + unsigned HSM2_muesti2_Given :1; + unsigned HSM2_muesti3_Given :1; + unsigned HSM2_nsubpsti1_Given :1; + unsigned HSM2_nsubpsti2_Given :1; + unsigned HSM2_nsubpsti3_Given :1; + unsigned HSM2_lpext_Given :1; + unsigned HSM2_npext_Given :1; + unsigned HSM2_npextw_Given :1; + unsigned HSM2_npextwp_Given :1; + unsigned HSM2_scp22_Given :1; + unsigned HSM2_scp21_Given :1; + unsigned HSM2_bs1_Given :1; + unsigned HSM2_bs2_Given :1; + unsigned HSM2_cgso_Given :1; + unsigned HSM2_cgdo_Given :1; + unsigned HSM2_cgbo_Given :1; + unsigned HSM2_tpoly_Given :1; + unsigned HSM2_js0_Given :1; + unsigned HSM2_js0sw_Given :1; + unsigned HSM2_nj_Given :1; + unsigned HSM2_njsw_Given :1; + unsigned HSM2_xti_Given :1; + unsigned HSM2_cj_Given :1; + unsigned HSM2_cjsw_Given :1; + unsigned HSM2_cjswg_Given :1; + unsigned HSM2_mj_Given :1; + unsigned HSM2_mjsw_Given :1; + unsigned HSM2_mjswg_Given :1; + unsigned HSM2_xti2_Given :1; + unsigned HSM2_cisb_Given :1; + unsigned HSM2_cvb_Given :1; + unsigned HSM2_ctemp_Given :1; + unsigned HSM2_cisbk_Given :1; + unsigned HSM2_cvbk_Given :1; + unsigned HSM2_divx_Given :1; + unsigned HSM2_pb_Given :1; + unsigned HSM2_pbsw_Given :1; + unsigned HSM2_pbswg_Given :1; + unsigned HSM2_tcjbd_Given :1; + unsigned HSM2_tcjbs_Given :1; + unsigned HSM2_tcjbdsw_Given :1; + unsigned HSM2_tcjbssw_Given :1; + unsigned HSM2_tcjbdswg_Given :1; + unsigned HSM2_tcjbsswg_Given :1; + + unsigned HSM2_clm1_Given :1; + unsigned HSM2_clm2_Given :1; + unsigned HSM2_clm3_Given :1; + unsigned HSM2_clm5_Given :1; + unsigned HSM2_clm6_Given :1; + unsigned HSM2_muetmp_Given :1; + unsigned HSM2_vover_Given :1; + unsigned HSM2_voverp_Given :1; + unsigned HSM2_vovers_Given :1; + unsigned HSM2_voversp_Given :1; + unsigned HSM2_wfc_Given :1; + unsigned HSM2_nsubcw_Given :1; + unsigned HSM2_nsubcwp_Given :1; + unsigned HSM2_nsubcmax_Given :1; + unsigned HSM2_qme1_Given :1; + unsigned HSM2_qme2_Given :1; + unsigned HSM2_qme3_Given :1; + unsigned HSM2_gidl1_Given :1; + unsigned HSM2_gidl2_Given :1; + unsigned HSM2_gidl3_Given :1; + unsigned HSM2_gidl4_Given :1; + unsigned HSM2_gidl5_Given :1; + unsigned HSM2_gleak1_Given :1; + unsigned HSM2_gleak2_Given :1; + unsigned HSM2_gleak3_Given :1; + unsigned HSM2_gleak4_Given :1; + unsigned HSM2_gleak5_Given :1; + unsigned HSM2_gleak6_Given :1; + unsigned HSM2_gleak7_Given :1; + unsigned HSM2_glksd1_Given :1; + unsigned HSM2_glksd2_Given :1; + unsigned HSM2_glksd3_Given :1; + unsigned HSM2_glkb1_Given :1; + unsigned HSM2_glkb2_Given :1; + unsigned HSM2_glkb3_Given :1; + unsigned HSM2_egig_Given :1; + unsigned HSM2_igtemp2_Given :1; + unsigned HSM2_igtemp3_Given :1; + unsigned HSM2_vzadd0_Given :1; + unsigned HSM2_pzadd0_Given :1; + unsigned HSM2_nftrp_Given :1; + unsigned HSM2_nfalp_Given :1; + unsigned HSM2_cit_Given :1; + unsigned HSM2_falph_Given :1; + unsigned HSM2_dly1_Given :1; + unsigned HSM2_dly2_Given :1; + unsigned HSM2_dly3_Given :1; + unsigned HSM2_tnom_Given :1; + unsigned HSM2_ovslp_Given :1; + unsigned HSM2_ovmag_Given :1; + unsigned HSM2_gbmin_Given :1; + unsigned HSM2_rbpb_Given :1; + unsigned HSM2_rbpd_Given :1; + unsigned HSM2_rbps_Given :1; + unsigned HSM2_rbdb_Given :1; + unsigned HSM2_rbsb_Given :1; + unsigned HSM2_ibpc1_Given :1; + unsigned HSM2_ibpc2_Given :1; + unsigned HSM2_mphdfm_Given :1; + + unsigned HSM2_ptl_Given :1; + unsigned HSM2_ptp_Given :1; + unsigned HSM2_pt2_Given :1; + unsigned HSM2_ptlp_Given :1; + unsigned HSM2_gdl_Given :1; + unsigned HSM2_gdlp_Given :1; + + unsigned HSM2_gdld_Given :1; + unsigned HSM2_pt4_Given :1; + unsigned HSM2_pt4p_Given :1; + unsigned HSM2_muephl2_Given :1; + unsigned HSM2_mueplp2_Given :1; + unsigned HSM2_nsubcw2_Given :1; + unsigned HSM2_nsubcwp2_Given :1; + unsigned HSM2_muephw2_Given :1; + unsigned HSM2_muepwp2_Given :1; + + unsigned HSM2_Vgsmin_Given :1; + unsigned HSM2_sc3Vbs_Given :1; + unsigned HSM2_byptol_Given :1; + unsigned HSM2_muecb0lp_Given :1; + unsigned HSM2_muecb1lp_Given :1; + + /* binning parameters */ + unsigned HSM2_lmin_Given :1; + unsigned HSM2_lmax_Given :1; + unsigned HSM2_wmin_Given :1; + unsigned HSM2_wmax_Given :1; + unsigned HSM2_lbinn_Given :1; + unsigned HSM2_wbinn_Given :1; + + /* Length dependence */ + unsigned HSM2_lvmax_Given :1; + unsigned HSM2_lbgtmp1_Given :1; + unsigned HSM2_lbgtmp2_Given :1; + unsigned HSM2_leg0_Given :1; + unsigned HSM2_llover_Given :1; + unsigned HSM2_lvfbover_Given :1; + unsigned HSM2_lnover_Given :1; + unsigned HSM2_lwl2_Given :1; + unsigned HSM2_lvfbc_Given :1; + unsigned HSM2_lnsubc_Given :1; + unsigned HSM2_lnsubp_Given :1; + unsigned HSM2_lscp1_Given :1; + unsigned HSM2_lscp2_Given :1; + unsigned HSM2_lscp3_Given :1; + unsigned HSM2_lsc1_Given :1; + unsigned HSM2_lsc2_Given :1; + unsigned HSM2_lsc3_Given :1; + unsigned HSM2_lsc4_Given :1; + unsigned HSM2_lpgd1_Given :1; +//unsigned HSM2_lpgd3_Given :1; + unsigned HSM2_lndep_Given :1; + unsigned HSM2_lninv_Given :1; + unsigned HSM2_lmuecb0_Given :1; + unsigned HSM2_lmuecb1_Given :1; + unsigned HSM2_lmueph1_Given :1; + unsigned HSM2_lvtmp_Given :1; + unsigned HSM2_lwvth0_Given :1; + unsigned HSM2_lmuesr1_Given :1; + unsigned HSM2_lmuetmp_Given :1; + unsigned HSM2_lsub1_Given :1; + unsigned HSM2_lsub2_Given :1; + unsigned HSM2_lsvds_Given :1; + unsigned HSM2_lsvbs_Given :1; + unsigned HSM2_lsvgs_Given :1; + unsigned HSM2_lnsti_Given :1; + unsigned HSM2_lwsti_Given :1; + unsigned HSM2_lscsti1_Given :1; + unsigned HSM2_lscsti2_Given :1; + unsigned HSM2_lvthsti_Given :1; + unsigned HSM2_lmuesti1_Given :1; + unsigned HSM2_lmuesti2_Given :1; + unsigned HSM2_lmuesti3_Given :1; + unsigned HSM2_lnsubpsti1_Given :1; + unsigned HSM2_lnsubpsti2_Given :1; + unsigned HSM2_lnsubpsti3_Given :1; + unsigned HSM2_lcgso_Given :1; + unsigned HSM2_lcgdo_Given :1; + unsigned HSM2_ljs0_Given :1; + unsigned HSM2_ljs0sw_Given :1; + unsigned HSM2_lnj_Given :1; + unsigned HSM2_lcisbk_Given :1; + unsigned HSM2_lclm1_Given :1; + unsigned HSM2_lclm2_Given :1; + unsigned HSM2_lclm3_Given :1; + unsigned HSM2_lwfc_Given :1; + unsigned HSM2_lgidl1_Given :1; + unsigned HSM2_lgidl2_Given :1; + unsigned HSM2_lgleak1_Given :1; + unsigned HSM2_lgleak2_Given :1; + unsigned HSM2_lgleak3_Given :1; + unsigned HSM2_lgleak6_Given :1; + unsigned HSM2_lglksd1_Given :1; + unsigned HSM2_lglksd2_Given :1; + unsigned HSM2_lglkb1_Given :1; + unsigned HSM2_lglkb2_Given :1; + unsigned HSM2_lnftrp_Given :1; + unsigned HSM2_lnfalp_Given :1; + unsigned HSM2_lvdiffj_Given :1; + unsigned HSM2_libpc1_Given :1; + unsigned HSM2_libpc2_Given :1; + + /* Width dependence */ + unsigned HSM2_wvmax_Given :1; + unsigned HSM2_wbgtmp1_Given :1; + unsigned HSM2_wbgtmp2_Given :1; + unsigned HSM2_weg0_Given :1; + unsigned HSM2_wlover_Given :1; + unsigned HSM2_wvfbover_Given :1; + unsigned HSM2_wnover_Given :1; + unsigned HSM2_wwl2_Given :1; + unsigned HSM2_wvfbc_Given :1; + unsigned HSM2_wnsubc_Given :1; + unsigned HSM2_wnsubp_Given :1; + unsigned HSM2_wscp1_Given :1; + unsigned HSM2_wscp2_Given :1; + unsigned HSM2_wscp3_Given :1; + unsigned HSM2_wsc1_Given :1; + unsigned HSM2_wsc2_Given :1; + unsigned HSM2_wsc3_Given :1; + unsigned HSM2_wsc4_Given :1; + unsigned HSM2_wpgd1_Given :1; +//unsigned HSM2_wpgd3_Given :1; + unsigned HSM2_wndep_Given :1; + unsigned HSM2_wninv_Given :1; + unsigned HSM2_wmuecb0_Given :1; + unsigned HSM2_wmuecb1_Given :1; + unsigned HSM2_wmueph1_Given :1; + unsigned HSM2_wvtmp_Given :1; + unsigned HSM2_wwvth0_Given :1; + unsigned HSM2_wmuesr1_Given :1; + unsigned HSM2_wmuetmp_Given :1; + unsigned HSM2_wsub1_Given :1; + unsigned HSM2_wsub2_Given :1; + unsigned HSM2_wsvds_Given :1; + unsigned HSM2_wsvbs_Given :1; + unsigned HSM2_wsvgs_Given :1; + unsigned HSM2_wnsti_Given :1; + unsigned HSM2_wwsti_Given :1; + unsigned HSM2_wscsti1_Given :1; + unsigned HSM2_wscsti2_Given :1; + unsigned HSM2_wvthsti_Given :1; + unsigned HSM2_wmuesti1_Given :1; + unsigned HSM2_wmuesti2_Given :1; + unsigned HSM2_wmuesti3_Given :1; + unsigned HSM2_wnsubpsti1_Given :1; + unsigned HSM2_wnsubpsti2_Given :1; + unsigned HSM2_wnsubpsti3_Given :1; + unsigned HSM2_wcgso_Given :1; + unsigned HSM2_wcgdo_Given :1; + unsigned HSM2_wjs0_Given :1; + unsigned HSM2_wjs0sw_Given :1; + unsigned HSM2_wnj_Given :1; + unsigned HSM2_wcisbk_Given :1; + unsigned HSM2_wclm1_Given :1; + unsigned HSM2_wclm2_Given :1; + unsigned HSM2_wclm3_Given :1; + unsigned HSM2_wwfc_Given :1; + unsigned HSM2_wgidl1_Given :1; + unsigned HSM2_wgidl2_Given :1; + unsigned HSM2_wgleak1_Given :1; + unsigned HSM2_wgleak2_Given :1; + unsigned HSM2_wgleak3_Given :1; + unsigned HSM2_wgleak6_Given :1; + unsigned HSM2_wglksd1_Given :1; + unsigned HSM2_wglksd2_Given :1; + unsigned HSM2_wglkb1_Given :1; + unsigned HSM2_wglkb2_Given :1; + unsigned HSM2_wnftrp_Given :1; + unsigned HSM2_wnfalp_Given :1; + unsigned HSM2_wvdiffj_Given :1; + unsigned HSM2_wibpc1_Given :1; + unsigned HSM2_wibpc2_Given :1; + + /* Cross-term dependence */ + unsigned HSM2_pvmax_Given :1; + unsigned HSM2_pbgtmp1_Given :1; + unsigned HSM2_pbgtmp2_Given :1; + unsigned HSM2_peg0_Given :1; + unsigned HSM2_plover_Given :1; + unsigned HSM2_pvfbover_Given :1; + unsigned HSM2_pnover_Given :1; + unsigned HSM2_pwl2_Given :1; + unsigned HSM2_pvfbc_Given :1; + unsigned HSM2_pnsubc_Given :1; + unsigned HSM2_pnsubp_Given :1; + unsigned HSM2_pscp1_Given :1; + unsigned HSM2_pscp2_Given :1; + unsigned HSM2_pscp3_Given :1; + unsigned HSM2_psc1_Given :1; + unsigned HSM2_psc2_Given :1; + unsigned HSM2_psc3_Given :1; + unsigned HSM2_psc4_Given :1; + unsigned HSM2_ppgd1_Given :1; +//unsigned HSM2_ppgd3_Given :1; + unsigned HSM2_pndep_Given :1; + unsigned HSM2_pninv_Given :1; + unsigned HSM2_pmuecb0_Given :1; + unsigned HSM2_pmuecb1_Given :1; + unsigned HSM2_pmueph1_Given :1; + unsigned HSM2_pvtmp_Given :1; + unsigned HSM2_pwvth0_Given :1; + unsigned HSM2_pmuesr1_Given :1; + unsigned HSM2_pmuetmp_Given :1; + unsigned HSM2_psub1_Given :1; + unsigned HSM2_psub2_Given :1; + unsigned HSM2_psvds_Given :1; + unsigned HSM2_psvbs_Given :1; + unsigned HSM2_psvgs_Given :1; + unsigned HSM2_pnsti_Given :1; + unsigned HSM2_pwsti_Given :1; + unsigned HSM2_pscsti1_Given :1; + unsigned HSM2_pscsti2_Given :1; + unsigned HSM2_pvthsti_Given :1; + unsigned HSM2_pmuesti1_Given :1; + unsigned HSM2_pmuesti2_Given :1; + unsigned HSM2_pmuesti3_Given :1; + unsigned HSM2_pnsubpsti1_Given :1; + unsigned HSM2_pnsubpsti2_Given :1; + unsigned HSM2_pnsubpsti3_Given :1; + unsigned HSM2_pcgso_Given :1; + unsigned HSM2_pcgdo_Given :1; + unsigned HSM2_pjs0_Given :1; + unsigned HSM2_pjs0sw_Given :1; + unsigned HSM2_pnj_Given :1; + unsigned HSM2_pcisbk_Given :1; + unsigned HSM2_pclm1_Given :1; + unsigned HSM2_pclm2_Given :1; + unsigned HSM2_pclm3_Given :1; + unsigned HSM2_pwfc_Given :1; + unsigned HSM2_pgidl1_Given :1; + unsigned HSM2_pgidl2_Given :1; + unsigned HSM2_pgleak1_Given :1; + unsigned HSM2_pgleak2_Given :1; + unsigned HSM2_pgleak3_Given :1; + unsigned HSM2_pgleak6_Given :1; + unsigned HSM2_pglksd1_Given :1; + unsigned HSM2_pglksd2_Given :1; + unsigned HSM2_pglkb1_Given :1; + unsigned HSM2_pglkb2_Given :1; + unsigned HSM2_pnftrp_Given :1; + unsigned HSM2_pnfalp_Given :1; + unsigned HSM2_pvdiffj_Given :1; + unsigned HSM2_pibpc1_Given :1; + unsigned HSM2_pibpc2_Given :1; + +} HSM2model; + +#ifndef NMOS +#define NMOS 1 +#define PMOS -1 +#endif /*NMOS*/ + +#define HSM2_BAD_PARAM -1 + +/* flags */ +#define HSM2_MOD_NMOS 1 +#define HSM2_MOD_PMOS 2 +#define HSM2_MOD_LEVEL 3 +#define HSM2_MOD_INFO 4 +#define HSM2_MOD_NOISE 5 +#define HSM2_MOD_VERSION 6 +#define HSM2_MOD_SHOW 7 +#define HSM2_MOD_CORSRD 11 +#define HSM2_MOD_COIPRV 12 +#define HSM2_MOD_COPPRV 13 +#define HSM2_MOD_COADOV 17 +#define HSM2_MOD_COISUB 21 +#define HSM2_MOD_COIIGS 22 +#define HSM2_MOD_COGIDL 23 +#define HSM2_MOD_COOVLP 24 +#define HSM2_MOD_COFLICK 25 +#define HSM2_MOD_COISTI 26 +#define HSM2_MOD_CONQS 29 /* HiSIM2 */ +#define HSM2_MOD_COTHRML 30 +#define HSM2_MOD_COIGN 31 /* induced gate noise */ +#define HSM2_MOD_CORG 32 +#define HSM2_MOD_CORBNET 33 +#define HSM2_MOD_CODFM 36 /* DFM */ +#define HSM2_MOD_CORECIP 37 +#define HSM2_MOD_COQY 38 +#define HSM2_MOD_COQOVSM 39 +/* device parameters */ +#define HSM2_L 51 +#define HSM2_W 52 +#define HSM2_AD 53 +#define HSM2_AS 54 +#define HSM2_PD 55 +#define HSM2_PS 56 +#define HSM2_NRD 57 +#define HSM2_NRS 58 +#define HSM2_TEMP 59 +#define HSM2_DTEMP 60 +#define HSM2_OFF 61 +#define HSM2_IC_VBS 62 +#define HSM2_IC_VDS 63 +#define HSM2_IC_VGS 64 +#define HSM2_IC 65 +#define HSM2_CORBNET 66 +#define HSM2_RBPB 67 +#define HSM2_RBPD 68 +#define HSM2_RBPS 69 +#define HSM2_RBDB 70 +#define HSM2_RBSB 71 +#define HSM2_CORG 72 +/* #define HSM2_RSHG 73 */ +#define HSM2_NGCON 74 +#define HSM2_XGW 75 +#define HSM2_XGL 76 +#define HSM2_NF 77 +#define HSM2_SA 78 +#define HSM2_SB 79 +#define HSM2_SD 80 +#define HSM2_NSUBCDFM 82 +#define HSM2_MPHDFM 84 +#define HSM2_M 83 + +/* model parameters */ +#define HSM2_MOD_VMAX 100 +#define HSM2_MOD_BGTMP1 101 +#define HSM2_MOD_BGTMP2 102 +#define HSM2_MOD_EG0 103 +#define HSM2_MOD_TOX 104 +#define HSM2_MOD_XLD 105 +#define HSM2_MOD_LOVER 106 +#define HSM2_MOD_DDLTMAX 421 /* Vdseff */ +#define HSM2_MOD_DDLTSLP 422 /* Vdseff */ +#define HSM2_MOD_DDLTICT 423 /* Vdseff */ +#define HSM2_MOD_VFBOVER 428 +#define HSM2_MOD_NOVER 430 +#define HSM2_MOD_XWD 107 +#define HSM2_MOD_XL 112 +#define HSM2_MOD_XW 117 +#define HSM2_MOD_SAREF 433 +#define HSM2_MOD_SBREF 434 +#define HSM2_MOD_LL 108 +#define HSM2_MOD_LLD 109 +#define HSM2_MOD_LLN 110 +#define HSM2_MOD_WL 111 +#define HSM2_MOD_WL1 113 +#define HSM2_MOD_WL1P 114 +#define HSM2_MOD_WL2 407 +#define HSM2_MOD_WL2P 408 +#define HSM2_MOD_WLD 115 +#define HSM2_MOD_WLN 116 + +#define HSM2_MOD_XQY 178 +#define HSM2_MOD_XQY1 118 +#define HSM2_MOD_XQY2 120 +#define HSM2_MOD_QYRAT 991 + +#define HSM2_MOD_RSH 119 +#define HSM2_MOD_RSHG 384 +/* #define HSM2_MOD_NGCON 385 */ +/* #define HSM2_MOD_XGW 386 */ +/* #define HSM2_MOD_XGL 387 */ +/* #define HSM2_MOD_NF 388 */ +#define HSM2_MOD_RS 398 +#define HSM2_MOD_RD 399 + +#define HSM2_MOD_VFBC 121 +#define HSM2_MOD_VBI 122 +#define HSM2_MOD_NSUBC 123 +#define HSM2_MOD_TNOM 124 +#define HSM2_MOD_PARL2 125 +#define HSM2_MOD_SC1 126 +#define HSM2_MOD_SC2 127 +#define HSM2_MOD_SC3 128 +#define HSM2_MOD_SC4 460 +#define HSM2_MOD_NDEP 129 +#define HSM2_MOD_NDEPL 419 +#define HSM2_MOD_NDEPLP 420 +#define HSM2_MOD_NDEPW 469 +#define HSM2_MOD_NDEPWP 470 +#define HSM2_MOD_NINV 130 +#define HSM2_MOD_NINVD 300 +#define HSM2_MOD_MUECB0 131 +#define HSM2_MOD_MUECB1 132 +#define HSM2_MOD_MUEPH1 133 +#define HSM2_MOD_MUEPH0 134 +#define HSM2_MOD_MUEPHW 135 +#define HSM2_MOD_MUEPWP 136 +#define HSM2_MOD_MUEPWD 333 +#define HSM2_MOD_MUEPHL 137 +#define HSM2_MOD_MUEPLP 138 +#define HSM2_MOD_MUEPLD 150 +#define HSM2_MOD_MUEPHS 139 +#define HSM2_MOD_MUEPSP 140 +#define HSM2_MOD_VTMP 141 +#define HSM2_MOD_WVTH0 142 +#define HSM2_MOD_MUESR1 143 +#define HSM2_MOD_MUESR0 144 +#define HSM2_MOD_MUESRL 145 +#define HSM2_MOD_MUESLP 146 +#define HSM2_MOD_MUESRW 147 +#define HSM2_MOD_MUESWP 148 +#define HSM2_MOD_BB 149 + +#define HSM2_MOD_SUB1 151 +#define HSM2_MOD_SUB2 152 +#define HSM2_MOD_CGSO 154 +#define HSM2_MOD_CGDO 155 +#define HSM2_MOD_CGBO 156 +#define HSM2_MOD_JS0 157 +#define HSM2_MOD_JS0SW 158 +#define HSM2_MOD_NJ 159 +#define HSM2_MOD_NJSW 160 +#define HSM2_MOD_XTI 161 +#define HSM2_MOD_CJ 162 +#define HSM2_MOD_CJSW 163 +#define HSM2_MOD_CJSWG 164 +#define HSM2_MOD_MJ 165 +#define HSM2_MOD_MJSW 166 +#define HSM2_MOD_MJSWG 167 +#define HSM2_MOD_XTI2 168 +#define HSM2_MOD_CISB 169 +#define HSM2_MOD_CVB 170 +#define HSM2_MOD_CTEMP 171 +#define HSM2_MOD_CISBK 172 +#define HSM2_MOD_CVBK 173 +#define HSM2_MOD_DIVX 174 +#define HSM2_MOD_PB 175 +#define HSM2_MOD_PBSW 176 +#define HSM2_MOD_PBSWG 177 +#define HSM2_MOD_TPOLY 179 +#define HSM2_MOD_LP 180 +#define HSM2_MOD_NSUBP 181 +#define HSM2_MOD_NSUBPL 196 +#define HSM2_MOD_NSUBPFAC 197 +#define HSM2_MOD_NSUBPW 182 +#define HSM2_MOD_NSUBPWP 183 +#define HSM2_MOD_SCP1 184 +#define HSM2_MOD_SCP2 185 +#define HSM2_MOD_SCP3 186 +#define HSM2_MOD_PGD1 187 +#define HSM2_MOD_PGD2 188 +//#define HSM2_MOD_PGD3 189 +#define HSM2_MOD_PGD4 190 +#define HSM2_MOD_CLM1 191 +#define HSM2_MOD_CLM2 192 +#define HSM2_MOD_CLM3 193 +#define HSM2_MOD_CLM5 402 +#define HSM2_MOD_CLM6 403 +#define HSM2_MOD_MUETMP 195 + +#define HSM2_MOD_VOVER 199 +#define HSM2_MOD_VOVERP 200 +#define HSM2_MOD_WFC 201 +#define HSM2_MOD_NSUBCW 249 +#define HSM2_MOD_NSUBCWP 250 +#define HSM2_MOD_NSUBCMAX 248 +#define HSM2_MOD_QME1 202 +#define HSM2_MOD_QME2 203 +#define HSM2_MOD_QME3 204 +#define HSM2_MOD_GIDL1 205 +#define HSM2_MOD_GIDL2 206 +#define HSM2_MOD_GIDL3 207 +#define HSM2_MOD_GLEAK1 208 +#define HSM2_MOD_GLEAK2 209 +#define HSM2_MOD_GLEAK3 210 +#define HSM2_MOD_GLEAK4 211 +#define HSM2_MOD_GLEAK5 212 +#define HSM2_MOD_GLEAK6 213 +#define HSM2_MOD_GLEAK7 214 +#define HSM2_MOD_GLKSD1 215 +#define HSM2_MOD_GLKSD2 216 +#define HSM2_MOD_GLKSD3 217 +#define HSM2_MOD_GLKB1 218 +#define HSM2_MOD_GLKB2 219 +#define HSM2_MOD_GLKB3 429 +#define HSM2_MOD_EGIG 220 +#define HSM2_MOD_IGTEMP2 221 +#define HSM2_MOD_IGTEMP3 222 +#define HSM2_MOD_VZADD0 223 +#define HSM2_MOD_PZADD0 224 +#define HSM2_MOD_NSTI 225 +#define HSM2_MOD_WSTI 226 +#define HSM2_MOD_WSTIL 227 +#define HSM2_MOD_WSTILP 231 +#define HSM2_MOD_WSTIW 234 +#define HSM2_MOD_WSTIWP 228 +#define HSM2_MOD_SCSTI1 229 +#define HSM2_MOD_SCSTI2 230 +#define HSM2_MOD_VTHSTI 232 +#define HSM2_MOD_VDSTI 233 +#define HSM2_MOD_MUESTI1 235 +#define HSM2_MOD_MUESTI2 236 +#define HSM2_MOD_MUESTI3 237 +#define HSM2_MOD_NSUBPSTI1 238 +#define HSM2_MOD_NSUBPSTI2 239 +#define HSM2_MOD_NSUBPSTI3 240 +#define HSM2_MOD_LPEXT 241 +#define HSM2_MOD_NPEXT 242 +#define HSM2_MOD_NPEXTW 471 +#define HSM2_MOD_NPEXTWP 472 +#define HSM2_MOD_SCP22 243 +#define HSM2_MOD_SCP21 244 +#define HSM2_MOD_BS1 245 +#define HSM2_MOD_BS2 246 +#define HSM2_MOD_KAPPA 251 +#define HSM2_MOD_VDIFFJ 254 +#define HSM2_MOD_DLY1 255 +#define HSM2_MOD_DLY2 256 +#define HSM2_MOD_DLY3 257 +#define HSM2_MOD_NFTRP 258 +#define HSM2_MOD_NFALP 259 +#define HSM2_MOD_FALPH 263 +#define HSM2_MOD_CIT 260 +#define HSM2_MOD_OVSLP 261 +#define HSM2_MOD_OVMAG 262 +#define HSM2_MOD_GIDL4 281 +#define HSM2_MOD_GIDL5 282 +#define HSM2_MOD_SVGS 283 +#define HSM2_MOD_SVBS 284 +#define HSM2_MOD_SVBSL 285 +#define HSM2_MOD_SVDS 286 +#define HSM2_MOD_SLG 287 +#define HSM2_MOD_SUB1L 290 +#define HSM2_MOD_SUB2L 292 +#define HSM2_MOD_VOVERS 303 +#define HSM2_MOD_VOVERSP 304 +#define HSM2_MOD_SVGSL 305 +#define HSM2_MOD_SVGSLP 306 +#define HSM2_MOD_SVGSWP 307 +#define HSM2_MOD_SVGSW 308 +#define HSM2_MOD_SVBSLP 309 +#define HSM2_MOD_SLGL 310 +#define HSM2_MOD_SLGLP 311 +#define HSM2_MOD_SUB1LP 312 +#define HSM2_MOD_IBPC1 404 +#define HSM2_MOD_IBPC2 405 +#define HSM2_MOD_MPHDFM 409 + +#define HSM2_MOD_PTL 450 +#define HSM2_MOD_PTP 451 +#define HSM2_MOD_PT2 452 +#define HSM2_MOD_PTLP 455 +#define HSM2_MOD_GDL 453 +#define HSM2_MOD_GDLP 454 + +#define HSM2_MOD_GDLD 456 +#define HSM2_MOD_PT4 457 +#define HSM2_MOD_PT4P 465 +#define HSM2_MOD_MUEPHL2 458 +#define HSM2_MOD_MUEPLP2 459 +#define HSM2_MOD_NSUBCW2 461 +#define HSM2_MOD_NSUBCWP2 462 +#define HSM2_MOD_MUEPHW2 463 +#define HSM2_MOD_MUEPWP2 464 + +#define HSM2_MOD_VGSMIN 466 +#define HSM2_MOD_SC3VBS 467 +#define HSM2_MOD_BYPTOL 468 +#define HSM2_MOD_MUECB0LP 473 +#define HSM2_MOD_MUECB1LP 474 + +/* binning parameters */ +#define HSM2_MOD_LMIN 1000 +#define HSM2_MOD_LMAX 1001 +#define HSM2_MOD_WMIN 1002 +#define HSM2_MOD_WMAX 1003 +#define HSM2_MOD_LBINN 1004 +#define HSM2_MOD_WBINN 1005 + +/* Length dependence */ +#define HSM2_MOD_LVMAX 1100 +#define HSM2_MOD_LBGTMP1 1101 +#define HSM2_MOD_LBGTMP2 1102 +#define HSM2_MOD_LEG0 1103 +#define HSM2_MOD_LLOVER 1106 +#define HSM2_MOD_LVFBOVER 1428 +#define HSM2_MOD_LNOVER 1430 +#define HSM2_MOD_LWL2 1407 +#define HSM2_MOD_LVFBC 1121 +#define HSM2_MOD_LNSUBC 1123 +#define HSM2_MOD_LNSUBP 1181 +#define HSM2_MOD_LSCP1 1184 +#define HSM2_MOD_LSCP2 1185 +#define HSM2_MOD_LSCP3 1186 +#define HSM2_MOD_LSC1 1126 +#define HSM2_MOD_LSC2 1127 +#define HSM2_MOD_LSC3 1128 +#define HSM2_MOD_LSC4 1270 +#define HSM2_MOD_LPGD1 1187 +//#define HSM2_MOD_LPGD3 1189 +#define HSM2_MOD_LNDEP 1129 +#define HSM2_MOD_LNINV 1130 +#define HSM2_MOD_LMUECB0 1131 +#define HSM2_MOD_LMUECB1 1132 +#define HSM2_MOD_LMUEPH1 1133 +#define HSM2_MOD_LVTMP 1141 +#define HSM2_MOD_LWVTH0 1142 +#define HSM2_MOD_LMUESR1 1143 +#define HSM2_MOD_LMUETMP 1195 +#define HSM2_MOD_LSUB1 1151 +#define HSM2_MOD_LSUB2 1152 +#define HSM2_MOD_LSVDS 1286 +#define HSM2_MOD_LSVBS 1284 +#define HSM2_MOD_LSVGS 1283 +#define HSM2_MOD_LNSTI 1225 +#define HSM2_MOD_LWSTI 1226 +#define HSM2_MOD_LSCSTI1 1229 +#define HSM2_MOD_LSCSTI2 1230 +#define HSM2_MOD_LVTHSTI 1232 +#define HSM2_MOD_LMUESTI1 1235 +#define HSM2_MOD_LMUESTI2 1236 +#define HSM2_MOD_LMUESTI3 1237 +#define HSM2_MOD_LNSUBPSTI1 1238 +#define HSM2_MOD_LNSUBPSTI2 1239 +#define HSM2_MOD_LNSUBPSTI3 1240 +#define HSM2_MOD_LCGSO 1154 +#define HSM2_MOD_LCGDO 1155 +#define HSM2_MOD_LJS0 1157 +#define HSM2_MOD_LJS0SW 1158 +#define HSM2_MOD_LNJ 1159 +#define HSM2_MOD_LCISBK 1172 +#define HSM2_MOD_LCLM1 1191 +#define HSM2_MOD_LCLM2 1192 +#define HSM2_MOD_LCLM3 1193 +#define HSM2_MOD_LWFC 1201 +#define HSM2_MOD_LGIDL1 1205 +#define HSM2_MOD_LGIDL2 1206 +#define HSM2_MOD_LGLEAK1 1208 +#define HSM2_MOD_LGLEAK2 1209 +#define HSM2_MOD_LGLEAK3 1210 +#define HSM2_MOD_LGLEAK6 1213 +#define HSM2_MOD_LGLKSD1 1215 +#define HSM2_MOD_LGLKSD2 1216 +#define HSM2_MOD_LGLKB1 1218 +#define HSM2_MOD_LGLKB2 1219 +#define HSM2_MOD_LNFTRP 1258 +#define HSM2_MOD_LNFALP 1259 +#define HSM2_MOD_LVDIFFJ 1254 +#define HSM2_MOD_LIBPC1 1404 +#define HSM2_MOD_LIBPC2 1405 + +/* Width dependence */ +#define HSM2_MOD_WVMAX 2100 +#define HSM2_MOD_WBGTMP1 2101 +#define HSM2_MOD_WBGTMP2 2102 +#define HSM2_MOD_WEG0 2103 +#define HSM2_MOD_WLOVER 2106 +#define HSM2_MOD_WVFBOVER 2428 +#define HSM2_MOD_WNOVER 2430 +#define HSM2_MOD_WWL2 2407 +#define HSM2_MOD_WVFBC 2121 +#define HSM2_MOD_WNSUBC 2123 +#define HSM2_MOD_WNSUBP 2181 +#define HSM2_MOD_WSCP1 2184 +#define HSM2_MOD_WSCP2 2185 +#define HSM2_MOD_WSCP3 2186 +#define HSM2_MOD_WSC1 2126 +#define HSM2_MOD_WSC2 2127 +#define HSM2_MOD_WSC3 2128 +#define HSM2_MOD_WSC4 2270 +#define HSM2_MOD_WPGD1 2187 +//#define HSM2_MOD_WPGD3 2189 +#define HSM2_MOD_WNDEP 2129 +#define HSM2_MOD_WNINV 2130 +#define HSM2_MOD_WMUECB0 2131 +#define HSM2_MOD_WMUECB1 2132 +#define HSM2_MOD_WMUEPH1 2133 +#define HSM2_MOD_WVTMP 2141 +#define HSM2_MOD_WWVTH0 2142 +#define HSM2_MOD_WMUESR1 2143 +#define HSM2_MOD_WMUETMP 2195 +#define HSM2_MOD_WSUB1 2151 +#define HSM2_MOD_WSUB2 2152 +#define HSM2_MOD_WSVDS 2286 +#define HSM2_MOD_WSVBS 2284 +#define HSM2_MOD_WSVGS 2283 +#define HSM2_MOD_WNSTI 2225 +#define HSM2_MOD_WWSTI 2226 +#define HSM2_MOD_WSCSTI1 2229 +#define HSM2_MOD_WSCSTI2 2230 +#define HSM2_MOD_WVTHSTI 2232 +#define HSM2_MOD_WMUESTI1 2235 +#define HSM2_MOD_WMUESTI2 2236 +#define HSM2_MOD_WMUESTI3 2237 +#define HSM2_MOD_WNSUBPSTI1 2238 +#define HSM2_MOD_WNSUBPSTI2 2239 +#define HSM2_MOD_WNSUBPSTI3 2240 +#define HSM2_MOD_WCGSO 2154 +#define HSM2_MOD_WCGDO 2155 +#define HSM2_MOD_WJS0 2157 +#define HSM2_MOD_WJS0SW 2158 +#define HSM2_MOD_WNJ 2159 +#define HSM2_MOD_WCISBK 2172 +#define HSM2_MOD_WCLM1 2191 +#define HSM2_MOD_WCLM2 2192 +#define HSM2_MOD_WCLM3 2193 +#define HSM2_MOD_WWFC 2201 +#define HSM2_MOD_WGIDL1 2205 +#define HSM2_MOD_WGIDL2 2206 +#define HSM2_MOD_WGLEAK1 2208 +#define HSM2_MOD_WGLEAK2 2209 +#define HSM2_MOD_WGLEAK3 2210 +#define HSM2_MOD_WGLEAK6 2213 +#define HSM2_MOD_WGLKSD1 2215 +#define HSM2_MOD_WGLKSD2 2216 +#define HSM2_MOD_WGLKB1 2218 +#define HSM2_MOD_WGLKB2 2219 +#define HSM2_MOD_WNFTRP 2258 +#define HSM2_MOD_WNFALP 2259 +#define HSM2_MOD_WVDIFFJ 2254 +#define HSM2_MOD_WIBPC1 2404 +#define HSM2_MOD_WIBPC2 2405 + +/* Cross-term dependence */ +#define HSM2_MOD_PVMAX 3100 +#define HSM2_MOD_PBGTMP1 3101 +#define HSM2_MOD_PBGTMP2 3102 +#define HSM2_MOD_PEG0 3103 +#define HSM2_MOD_PLOVER 3106 +#define HSM2_MOD_PVFBOVER 3428 +#define HSM2_MOD_PNOVER 3430 +#define HSM2_MOD_PWL2 3407 +#define HSM2_MOD_PVFBC 3121 +#define HSM2_MOD_PNSUBC 3123 +#define HSM2_MOD_PNSUBP 3181 +#define HSM2_MOD_PSCP1 3184 +#define HSM2_MOD_PSCP2 3185 +#define HSM2_MOD_PSCP3 3186 +#define HSM2_MOD_PSC1 3126 +#define HSM2_MOD_PSC2 3127 +#define HSM2_MOD_PSC3 3128 +#define HSM2_MOD_PSC4 3270 +#define HSM2_MOD_PPGD1 3187 +//#define HSM2_MOD_PPGD3 3189 +#define HSM2_MOD_PNDEP 3129 +#define HSM2_MOD_PNINV 3130 +#define HSM2_MOD_PMUECB0 3131 +#define HSM2_MOD_PMUECB1 3132 +#define HSM2_MOD_PMUEPH1 3133 +#define HSM2_MOD_PVTMP 3141 +#define HSM2_MOD_PWVTH0 3142 +#define HSM2_MOD_PMUESR1 3143 +#define HSM2_MOD_PMUETMP 3195 +#define HSM2_MOD_PSUB1 3151 +#define HSM2_MOD_PSUB2 3152 +#define HSM2_MOD_PSVDS 3286 +#define HSM2_MOD_PSVBS 3284 +#define HSM2_MOD_PSVGS 3283 +#define HSM2_MOD_PNSTI 3225 +#define HSM2_MOD_PWSTI 3226 +#define HSM2_MOD_PSCSTI1 3229 +#define HSM2_MOD_PSCSTI2 3230 +#define HSM2_MOD_PVTHSTI 3232 +#define HSM2_MOD_PMUESTI1 3235 +#define HSM2_MOD_PMUESTI2 3236 +#define HSM2_MOD_PMUESTI3 3237 +#define HSM2_MOD_PNSUBPSTI1 3238 +#define HSM2_MOD_PNSUBPSTI2 3239 +#define HSM2_MOD_PNSUBPSTI3 3240 +#define HSM2_MOD_PCGSO 3154 +#define HSM2_MOD_PCGDO 3155 +#define HSM2_MOD_PJS0 3157 +#define HSM2_MOD_PJS0SW 3158 +#define HSM2_MOD_PNJ 3159 +#define HSM2_MOD_PCISBK 3172 +#define HSM2_MOD_PCLM1 3191 +#define HSM2_MOD_PCLM2 3192 +#define HSM2_MOD_PCLM3 3193 +#define HSM2_MOD_PWFC 3201 +#define HSM2_MOD_PGIDL1 3205 +#define HSM2_MOD_PGIDL2 3206 +#define HSM2_MOD_PGLEAK1 3208 +#define HSM2_MOD_PGLEAK2 3209 +#define HSM2_MOD_PGLEAK3 3210 +#define HSM2_MOD_PGLEAK6 3213 +#define HSM2_MOD_PGLKSD1 3215 +#define HSM2_MOD_PGLKSD2 3216 +#define HSM2_MOD_PGLKB1 3218 +#define HSM2_MOD_PGLKB2 3219 +#define HSM2_MOD_PNFTRP 3258 +#define HSM2_MOD_PNFALP 3259 +#define HSM2_MOD_PVDIFFJ 3254 +#define HSM2_MOD_PIBPC1 3404 +#define HSM2_MOD_PIBPC2 3405 + +/* device questions */ +#define HSM2_DNODE 341 +#define HSM2_GNODE 342 +#define HSM2_SNODE 343 +#define HSM2_BNODE 344 +#define HSM2_DNODEPRIME 345 +#define HSM2_SNODEPRIME 346 +#define HSM2_BNODEPRIME 395 +#define HSM2_DBNODE 396 +#define HSM2_SBNODE 397 +#define HSM2_VBD 347 +#define HSM2_VBS 348 +#define HSM2_VGS 349 +#define HSM2_VDS 350 +#define HSM2_CD 351 +#define HSM2_CBS 352 +#define HSM2_CBD 353 +#define HSM2_GM 354 +#define HSM2_GDS 355 +#define HSM2_GMBS 356 +#define HSM2_GBD 357 +#define HSM2_GBS 358 +#define HSM2_QB 359 +#define HSM2_CQB 360 +#define HSM2_QG 361 +#define HSM2_CQG 362 +#define HSM2_QD 363 +#define HSM2_CQD 364 +#define HSM2_CGG 365 +#define HSM2_CGD 366 +#define HSM2_CGS 367 +#define HSM2_CBG 368 +#define HSM2_CAPBD 369 +#define HSM2_CQBD 370 +#define HSM2_CAPBS 371 +#define HSM2_CQBS 372 +#define HSM2_CDG 373 +#define HSM2_CDD 374 +#define HSM2_CDS 375 +#define HSM2_VON 376 +#define HSM2_VDSAT 377 +#define HSM2_QBS 378 +#define HSM2_QBD 379 +#define HSM2_SOURCECONDUCT 380 +#define HSM2_DRAINCONDUCT 381 +#define HSM2_CBDB 382 +#define HSM2_CBSB 383 +#define HSM2_MOD_RBPB 389 +#define HSM2_MOD_RBPD 390 +#define HSM2_MOD_RBPS 391 +#define HSM2_MOD_RBDB 392 +#define HSM2_MOD_RBSB 393 +#define HSM2_MOD_GBMIN 394 + +#define HSM2_ISUB 410 +#define HSM2_IGIDL 411 +#define HSM2_IGISL 412 +#define HSM2_IGD 413 +#define HSM2_IGS 414 +#define HSM2_IGB 415 +#define HSM2_CGSO 416 +#define HSM2_CGBO 417 +#define HSM2_CGDO 418 + +#define HSM2_MOD_TCJBD 92 +#define HSM2_MOD_TCJBS 93 +#define HSM2_MOD_TCJBDSW 94 +#define HSM2_MOD_TCJBSSW 95 +#define HSM2_MOD_TCJBDSWG 96 +#define HSM2_MOD_TCJBSSWG 97 + +#include "hsm2ext.h" + +/* +#ifdef __STDC__ +extern void HSM2evaluate(double,double,double,HSM2instance*,HSM2model*, + double*,double*,double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, + double*, double*, double*, double*, CKTcircuit*); +#else +extern void HSM2evaluate(); +#endif +*/ + +#endif /*HSM2*/ + diff --git a/src/spicelib/devices/hisim2/hsm2del.c b/src/spicelib/devices/hisim2/hsm2del.c new file mode 100644 index 000000000..c18f5ea69 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2del.c @@ -0,0 +1,46 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2del.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "util.h" +#include "hsm2def.h" +#include "sperror.h" +#include "gendefs.h" +#include "suffix.h" + +int HSM2delete(inModel,name,inInst) + GENmodel *inModel; + IFuid name; + GENinstance **inInst; +{ + HSM2instance **fast = (HSM2instance**)inInst; + HSM2model *model = (HSM2model*)inModel; + HSM2instance **prev = NULL; + HSM2instance *here; + + for( ;model ;model = model->HSM2nextModel ) { + prev = &(model->HSM2instances); + for ( here = *prev ;here ;here = *prev ) { + if ( here->HSM2name == name || (fast && here==*fast) ) { + *prev= here->HSM2nextInstance; + FREE(here); + return(OK); + } + prev = &(here->HSM2nextInstance); + } + } + return(E_NODEV); +} diff --git a/src/spicelib/devices/hisim2/hsm2dest.c b/src/spicelib/devices/hisim2/hsm2dest.c new file mode 100644 index 000000000..a495c2e41 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2dest.c @@ -0,0 +1,44 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2dest.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "util.h" +#include "hsm2def.h" +#include "suffix.h" + +void HSM2destroy(inModel) + GENmodel **inModel; +{ + HSM2model **model = (HSM2model**)inModel; + HSM2instance *here; + HSM2instance *prev = NULL; + HSM2model *mod = *model; + HSM2model *oldmod = NULL; + + for ( ;mod ;mod = mod->HSM2nextModel ) { + if (oldmod) FREE(oldmod); + oldmod = mod; + prev = (HSM2instance *)NULL; + for ( here = mod->HSM2instances ;here ;here = here->HSM2nextInstance ) { + if (prev) FREE(prev); + prev = here; + } + if (prev) FREE(prev); + } + if (oldmod) FREE(oldmod); + *model = NULL; +} + diff --git a/src/spicelib/devices/hisim2/hsm2eval.c b/src/spicelib/devices/hisim2/hsm2eval.c new file mode 100644 index 000000000..457d3b023 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2eval.c @@ -0,0 +1,7653 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2eval.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +/********************************************************************** + +The following source code, and all copyrights, trade secrets or other +intellectual property rights in and to the source code in its entirety, +is owned by the Hiroshima University and the STARC organization. + +All users need to follow the "HiSIM2 Distribution Statement and +Copyright Notice" attached to HiSIM2 model. + +-----HiSIM2 Distribution Statement and Copyright Notice-------------- + Hiroshima University and/or Semiconductor Technology Academic Research +Center ("STARC") grants to Licensee a worldwide, royalty-free, +sub-licensable, retroactive, perpetual, irrevocable license to make, +have made, offer to sell, sell, import, export, use, copy, redistribute, +perform, display and incorporate HiSIM2 intellectual property (the +"License") subject to the conditions set forth below. + This License includes rights to use and modify copyrighted material +for any purpose if the copyright is acknowledged as well as the use of +related patents which STARC owns, has applied for or will apply for +in connection with HiSIM2 intellectual property for the purpose of +implementing and using the HiSIM2 intellectual property in connection +with the standard. This license applies to all past and future versions +of HiSIM2. + +1. HiSIM2 intellectual property is offered "as is" without any warranty, +explicit or implied, or service support. Hiroshima University, STARC, +its University staff and employees assume no liability for the quality +and performance of HiSIM2 intellectual property. + +2. As the owner of the HiSIM2 intellectual property, and all other +related rights, Hiroshima University and/or STARC grant the License +as set forth above. + +3. A Licensee may not charge an end user a fee for the HiSIM2 source +code, which Hiroshima University and STARC own, by itself, however, +a Licensee may charge an end user a fee for alterations or additions +to the HiSIM2 source code or for maintenance service. + +4. A Licensee of HiSIM2 intellectual property agrees that Hiroshima +University and STARC are the developers of HiSIM2 in all products +containing HiSIM2 and the alteration thereof (subject to Licensee's +ownership of the alterations). +If future versions of HiSIM2 incorporate elements of other CMC models +the copyrights of those elements remains with the original developers. +For this purpose the copyright notice as shown below shall be used. + +"The HiSIM2 source code, and all copyrights, trade secrets or other +intellectual property rights in and to the source code, is owned +by Hiroshima University and/or STARC." + +5. A Licensee of HiSIM2 intellectual property will comply with the +export obligations pertaining to the export of the HiSIM2 intellectual +property. + +6. By using HiSIM2 intellectual property owned by Hiroshima University +and/or STARC, Licensee agrees not to prosecute any patents or patent +held by Licensee that are required for implementation of HiSIM2 against +any party who is infringing those patents solely by implementing and/or +using the HiSIM2 standard. + +*************************************************************************/ + +/********************************************************************* +* Memorandum on programming +* +* (1) Bias (x: b|d|g) +* . vxs : Input argument. +* . Vxse: External bias taking account device type (pMOS->nMOS). +* . Vxsc: Confined bias within a specified region. +* . Vxs : Internal bias. +* . Y_dVxs denotes the partial derivative of Y w.r.t. Vxs. +* +* (2) Device Mode +* . Normal mode (Vds>0 for nMOS) is assumed. +* . In case of reverse mode, parent routines have to properly +* transform or interchange inputs and outputs except ones +* related to junction diodes, which are regarded as being +* fixed to the nodal S/D. +* +* (3) Modification for symmetry at Vds=0 +* . Vxsz: Modified bias. (x: b|d|g) +* . Ps0z: Modified Ps0. +* . The following variables are calculated as a function of +* modified biases or potential. +* Tox, Cox, (-- with quantum effect) +* Vth*, dVth*, dPpg, Igate, Igidl, Igisl. +* . The following variables are calculated using a transform +* function. +* Lred +* +* (4) Zones and Cases (terminology) +* +* Chi:=beta*(Ps0-Vbs)= 0 3 5 +* +* Zone: A | D1 | D2 | D3 +* | +* (accumulation)|(depletion) +* | +* Vgs = Vgs_fb Vth +* / / +* Case: Nonconductive / Conductive +* / +* VgVt:=Qn0/Cox= VgVt_small +* +* . Ids is regarded as zero in zone-A. +* . Procedure to calculate Psl and dependent variables is +* omitted in the nonconductive case. Ids and Qi are regarded +* as zero in this case. +* +*********************************************************************/ + +/*===========================================================* +* Preamble. +*=================*/ +/*---------------------------------------------------* +* Header files. +*-----------------*/ +#include +#include +#include +#include +#ifdef __STDC__ +/* #include */ +#endif +#include "cktdefs.h" + +/*-----------------------------------* +* HiSIM macros +*-----------------*/ +#include "hisim2.h" +#include "hsm2evalenv.h" + +/*-----------------------------------* +* HiSIM constants +*-----------------*/ +#define C_sce_dlt (1.0e-2) +#define C_gidl_delta 0.5 +#define C_PSLK_DELTA 1e-3 /* delta for Pslk smoothing */ +#define C_PSLK_SHIFT 1.0 /* constant value for temporary shift */ +#define C_IDD_MIN 1.0e-15 + +/* local variables used in macro functions */ +double TMF1 , TMF2 , TMF3 , TMF4 ; +/*===========================================================* +* pow +*=================*/ +#ifdef POW_TO_EXP_AND_LOG +#define Fn_Pow( x , y ) exp( y * log( x ) ) +#else +#define Fn_Pow( x , y ) pow( x , y ) +#endif + +/*===========================================================* +* Exp() for PGD. +* - ExpLim(-3)=0 +*=================*/ + +#define Fn_ExpLim( y , x , dx ) { \ + if ( (x) < -3.0 ) { \ + dx = 0.0 ; \ + y = 0.0 ; \ + } else if ( (x) < 0.0 ) { \ + dx = 1.0 + (x) * ( 2 * (1.0/3.0) + (x) * 3 * (1.0/27.0) ) ; \ + y = 1.0 + (x) * ( 1.0 + (x) * ( (1.0/3.0) + (x) * (1.0/27.0) ) ) ; \ + } else { \ + dx = 1.0 + (x) * ( 2 * (1.0/3.0) + (x) * ( 3 * 0.0402052934513951 \ + + (x) * 4 * 0.148148111111111 ) ) ; \ + y = 1.0 + (x) * ( 1.0 + (x) * ( (1.0/3.0) + (x) * ( 0.0402052934513951 \ + + (x) * 0.148148111111111 ) ) ) ; \ + } \ +} + +/*===========================================================* +* Ceiling, smoothing functions. +*=================*/ +/*---------------------------------------------------* +* smoothUpper: ceiling. +* y = xmax - 0.5 ( arg + sqrt( arg^2 + 4 xmax delta ) ) +* arg = xmax - x - delta +*-----------------*/ + +#define Fn_SU( y , x , xmax , delta , dx ) { \ + TMF1 = ( xmax ) - ( x ) - ( delta ) ; \ + TMF2 = sqrt ( TMF1 * TMF1 + 4.0 * ( xmax ) * ( delta) ) ; \ + dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \ + y = ( xmax ) - 0.5 * ( TMF1 + TMF2 ) ; \ + } + +#define Fn_SU2( y , x , xmax , delta , dy_dx , dy_dxmax ) { \ + TMF1 = ( xmax ) - ( x ) - ( delta ) ; \ + TMF2 = sqrt ( TMF1 * TMF1 + 4.0 * ( xmax ) * ( delta) ) ; \ + dy_dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \ + dy_dxmax = 0.5 * ( 1.0 - ( TMF1 + 2.0 * delta ) / TMF2 ) ; \ + y = ( xmax ) - 0.5 * ( TMF1 + TMF2 ) ; \ + } + +/*---------------------------------------------------* +* smoothLower: flooring. +* y = xmin + 0.5 ( arg + sqrt( arg^2 + 4 xmin delta ) ) +* arg = x - xmin - delta +*-----------------*/ + +#define Fn_SL( y , x , xmin , delta , dx ) { \ + TMF1 = ( x ) - ( xmin ) - ( delta ) ; \ + TMF2 = sqrt ( TMF1 * TMF1 + 4.0 * ( xmin ) * ( delta ) ) ; \ + dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \ + y = ( xmin ) + 0.5 * ( TMF1 + TMF2 ) ; \ + } + +/*---------------------------------------------------* +* smoothZero: flooring to zero. +* y = 0.5 ( x + sqrt( x^2 + 4 delta^2 ) ) +*-----------------*/ + +#define Fn_SZ( y , x , delta , dx ) { \ + TMF2 = sqrt ( ( x ) * ( x ) + 4.0 * ( delta ) * ( delta) ) ; \ + dx = 0.5 * ( 1.0 + ( x ) / TMF2 ) ; \ + y = 0.5 * ( ( x ) + TMF2 ) ; \ + } + +/*---------------------------------------------------* +* smoothZero: flooring to zero. +* y = 0.5 ( x + sqrt( x^2 + 4 delta^2 ) ) +*-----------------*/ +static double smoothZero +( + double x, + double delta, + double *dx + ) +{ + double sqr = sqrt ( x * x + 4.0 * delta * delta) ; + if (dx) *dx = 0.5 * ( 1.0 + x / sqr ) ; + return 0.5 * ( x + sqr ) ; +} +/*---------------------------------------------------* +* CeilingPow: ceiling for positive x, flooring for negative x. +* y = x * xmax / ( x^{2m} + xmax^{2m} )^{1/(2m)} +* note: +* - xmax has to be positive. +* - -xmax < y < xmax. +* - dy/dx|_{x=0} = 1. +*-----------------*/ +static double CeilingPow +( + double x, + double xmax, + int pw, + double *dx + ) +{ + double x2 = x * x ; + double xmax2 = xmax * xmax ; + double xp = 1.0 , xmp = 1.0 ; + int m , mm ; + double arg , dnm ; + double result ; + + for ( m = 0 ; m < pw ; m ++ ) { + xp *= x2 ; + xmp *= xmax2 ; + } + arg = xp + xmp ; + dnm = arg ; + if ( pw == 1 || pw == 2 || pw == 4 || pw == 8 ) { + if ( pw == 1 ) { + mm = 1 ; + } else if ( pw == 2 ) { + mm = 2 ; + } else if ( pw == 4 ) { + mm = 3 ; + } else if ( pw == 8 ) { + mm = 4 ; + } + for ( m = 0 ; m < mm ; m ++ ) { + dnm = sqrt( dnm ) ; + } + } else { + dnm = pow( dnm , 1.0 / ( 2.0 * pw ) ) ; + } + dnm = 1.0 / dnm ; + result = x * xmax * dnm ; + (*dx) = xmax * xmp * dnm / arg ; + return result ; +} + +/*---------------------------------------------------* +* CeilingPow: ceiling for positive x, flooring for negative x. +* y = x * xmax / ( x^{2m} + xmax^{2m} )^{1/(2m)} +* note: +* - xmax has to be positive. +* - -xmax < y < xmax. +* - dy/dx|_{x=0} = 1. +*-----------------*/ + +#define Fn_CP( y , x , xmax , pw , dx ) { \ + double x2 = (x) * (x) ; \ + double xmax2 = (xmax) * (xmax) ; \ + double xp = 1.0 , xmp = 1.0 ; \ + int m , mm ; \ + double arg , dnm ; \ + for ( m = 0 ; m < pw ; m ++ ) { xp *= x2 ; xmp *= xmax2 ; } \ + arg = xp + xmp ; \ + dnm = arg ; \ + if ( pw == 1 || pw == 2 || pw == 4 || pw == 8 ) { \ + if ( pw == 1 ) { mm = 1 ; \ + } else if ( pw == 2 ) { mm = 2 ; \ + } else if ( pw == 4 ) { mm = 3 ; \ + } else if ( pw == 8 ) { mm = 4 ; } \ + for ( m = 0 ; m < mm ; m ++ ) { dnm = sqrt( dnm ) ; } \ + } else { dnm = Fn_Pow( dnm , 1.0 / ( 2.0 * pw ) ) ; } \ + dnm = 1.0 / dnm ; \ + y = (x) * (xmax) * dnm ; \ + dx = (xmax) * xmp * dnm / arg ; \ +} + + +/*===========================================================* +* Functions for symmetry. +*=================*/ + +/*---------------------------------------------------* +* Declining function using a polynomial. +*-----------------*/ + +#define Fn_DclPoly4( y , x , dx ) { \ + TMF2 = (x) * (x) ; \ + TMF3 = TMF2 * (x) ; \ + TMF4 = TMF2 * TMF2 ; \ + y = 1.0 / ( 1.0 + (x) + TMF2 + TMF3 + TMF4 ) ; \ + dx = - ( 1.0 + 2.0 * (x) + 3.0 * TMF2 + 4.0 * TMF3 ) * y * y ; \ +} + +/*---------------------------------------------------* +* "smoothUpper" uasing a polynomial +*-----------------*/ + +#define Fn_SUPoly4( y , x , xmax , dx ) { \ + TMF1 = (x) / xmax ; \ + Fn_DclPoly4( y , TMF1 , dx ) ; \ + y = xmax * ( 1.0 - y ) ; \ + dx = - dx ; \ +} + +/*---------------------------------------------------* +* SymAdd: evaluate additional term for symmetry. +*-----------------*/ + +#define Fn_SymAdd( y , x , add0 , dx ) \ +{ \ + TMF1 = 2.0 * ( x ) / ( add0 ) ; \ + TMF2 = 1.0 + TMF1 * ( (1.0/2) + TMF1 * ( (1.0/6) \ + + TMF1 * ( (1.0/24) + TMF1 * ( (1.0/120) \ + + TMF1 * ( (1.0/720) + TMF1 * (1.0/5040) ) ) ) ) ) ; \ + TMF3 = (1.0/2) + TMF1 * ( (1.0/3) \ + + TMF1 * ( (1.0/8) + TMF1 * ( (1.0/30) \ + + TMF1 * ( (1.0/144) + TMF1 * (1.0/840) ) ) ) ) ; \ + y = add0 / TMF2 ; \ + dx = - 2.0 * TMF3 / ( TMF2 * TMF2 ) ; \ +} + +/*===========================================================* +* Function hsm2evaluate. +*=================*/ +#ifdef __STDC__ +int HSM2evaluate +( + double vds, + double vgs, + double vbs, + double vbs_jct, + double vbd_jct, + HSM2instance *here, + HSM2model *model, + CKTcircuit *ckt + ) +#else +int HSM2evaluate( vds , vgs , vbs , vbs_jct, vbd_jct, here , model , ckt) + double vds ; + double vgs ; + double vbs ; + double vbs_jct ; + double vbd_jct ; + HSM2instance *here ; + HSM2model *model ; + CKTcircuit *ckt ; +#endif +{ + HSM2binningParam *pParam = &here->pParam ; + /*-----------------------------------* + * Constants for Smoothing functions + *---------------*/ + const double vth_dlt = 1.0e-3 ; + /* const double cclmmdf = 1.0e-2 ;*/ + const double cclmmdf = 1.0e-1 ; + const double qme_dlt = 1.0e-4 ; + const double eef_dlt = 1.0e-2 ; + const double sti2_dlt = 2.0e-3 ; + const double pol_dlt = 5.0e-2 ; + const double psia_dlt = 1.0e-3 ; + const double psia2_dlt = 5.0e-3 ; + const double psisti_dlt = 5.0e-3 ; + const double jct_dlt = 1.0e-2 ; + + /*---------------------------------------------------* + * Local variables. + *-----------------*/ + /* Constants ----------------------- */ + const int lp_s0_max = 20 ; + const int lp_sl_max = 20 ; + int lp_bs_max = 10 ; + const double Ids_tol = 1.0e-10 ; + const double Ids_maxvar = 1.0e-1 ; + const double dP_max = 0.1e0 ; + const double ps_conv = 5.0e-13 ; + /* double ps_conv = 1.0e-13 ;*/ + const double gs_conv = 1.0e-8 ; + const double mini_current = 1.0e-15 ; + /** depletion **/ + const double znbd3 = 3.0e0 ; + const double znbd5 = 5.0e0 ; + const double cn_nc3 = C_SQRT_2 / 108e0 ; + /* 5-degree, contact:Chi=5 */ + const double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ + const double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ + const double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ + const double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ + const double cn_nc55 = 6.36964918866352e-5 ; /* (1509-1040*sqrt(2))/600000 */ + /** inversion **/ + /* 3-degree polynomial approx for ( exp[Chi]-1 )^{1/2} */ + const double cn_im53 = 2.9693154855770998e-1 ; + const double cn_im54 = -7.0536542840097616e-2 ; + const double cn_im55 = 6.1152888951331797e-3 ; + /** initial guess **/ + const double c_ps0ini_2 = 8.0e-4 ; + const double c_pslini_1 = 0.3e0 ; + const double c_pslini_2 = 3.0e-2 ; + + const double VgVt_small = 1.0e-12 ; + const double Vbs_min = -10.5e0 ; + const double Vds_max = 10.5e0 ; + const double Vgs_max = 10.5e0 ; + const double epsm10 = 10.0e0 * C_EPS_M ; + const double small = 1.0e-50 ; + + double Vbs_max = 0.8e0 ; + double Vbs_bnd = 0.4e0 ; /* start point of positive Vbs bending */ + double Gdsmin = 0.0 ; + double Gjmin = ckt->CKTgmin ; + + /* Internal flags --------------------*/ + int flg_err = 0 ; /* error level */ + int flg_rsrd = 0 ; /* Flag for bias loop accounting Rs and Rd */ + int flg_iprv = 0 ; /* Flag for initial guess of Ids */ + int flg_pprv = 0 ; /* Flag for initial guesses of Ps0 and Pds */ + int flg_noqi ; /* Flag for the cases regarding Qi=Qd=0 */ + int flg_vbsc = 0 ; /* Flag for Vbs confining */ + int flg_info = 0 ; + int flg_clamp = 0 ; /* Flag for clamping biases */ + int flg_conv = 0 ; /* Flag for Poisson loop convergence */ + int flg_qme = 0 ; /* Flag for QME */ + + /* flag for NQS calculation */ + int flg_nqs; + + /* Important Variables in HiSIM -------*/ + /* external bias */ + double Vbse , Vdse , Vgse ; + /* confine bias */ + double Vbsc , Vdsc , Vgsc ; + double Vbsc_dVbse = 1.0 ; + /* internal bias */ + double Vbs , Vds , Vgs , Vdb , Vsb ; + double Vbs_dVbse = 1.0 , Vbs_dVdse = 0.0 , Vbs_dVgse = 0.0 ; + double Vds_dVbse = 0.0 , Vds_dVdse = 1.0 , Vds_dVgse = 0.0 ; + double Vgs_dVbse = 0.0 , Vgs_dVdse = 0.0 , Vgs_dVgse = 1.0 ; + double Vgp ; + double Vgp_dVbs , Vgp_dVds , Vgp_dVgs ; + double Vgs_fb ; + /* Ps0 : surface potential at the source side */ + double Ps0 ; + double Ps0_dVbs , Ps0_dVds , Ps0_dVgs ; + double Ps0_ini , Ps0_iniA , Ps0_iniB ; + /* Psl : surface potential at the drain side */ + double Psl ; + double Psl_dVbs , Psl_dVds , Psl_dVgs ; + double Psl_lim , dPlim ; + /* Pds := Psl - Ps0 */ + double Pds = 0.0 ; + double Pds_dVbs = 0.0, Pds_dVds = 0.0 , Pds_dVgs = 0.0 ; + double Pds_ini ; + double Pds_max ; + /* iteration numbers of Ps0 and Psl equations. */ + int lp_s0 = 0 , lp_sl = 0 ; + /* Xi0 := beta * ( Ps0 - Vbs ) - 1. */ + double Xi0 ; + double Xi0_dVbs , Xi0_dVds , Xi0_dVgs ; + double Xi0p12 ; + double Xi0p12_dVbs , Xi0p12_dVds , Xi0p12_dVgs ; + double Xi0p32 ; + /* Xil := beta * ( Psl - Vbs ) - 1. */ + double Xilp12 ; + double Xilp32 ; + double Xil ; + /* modified bias and potential for sym.*/ + double Vbsz , Vdsz , Vgsz ; + double Vbsz_dVbs , Vbsz_dVds ; + double Vdsz_dVds ; + double Vgsz_dVgs , Vgsz_dVds ; + double Vzadd , Vzadd_dVds ; + double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; + double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; + double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; /* (tmp) */ + + /* IBPC */ + double dVbsIBPC , dVbsIBPC_dVbs , dVbsIBPC_dVds , dVbsIBPC_dVgs ; + double betaWL , betaWL_dVbs , betaWL_dVds , betaWL_dVgs ; + double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; + double Xil_dVbs , Xil_dVds , Xil_dVgs ; + double Xilp12_dVbs , Xilp12_dVds , Xilp12_dVgs ; + double Xilp32_dVbs , Xilp32_dVds , Xilp32_dVgs ; + double dG3 , dG3_dVbs , dG3_dVds , dG3_dVgs ; + double dG4 , dG4_dVbs , dG4_dVds , dG4_dVgs ; + double dIdd , dIdd_dVbs , dIdd_dVds , dIdd_dVgs ; + + /* Chi := beta * ( Ps{0/l} - Vbs ) */ + double Chi ; + double Chi_dVbs , Chi_dVds , Chi_dVgs ; + /* Rho := beta * ( Psl - Vds ) */ + double Rho ; + /* threshold voltage */ + double Vth ; + double Vth0 ; + double Vth0_dVb , Vth0_dVd , Vth0_dVg ; + /* variation of threshold voltage */ + double dVth ; + double dVth_dVb , dVth_dVd , dVth_dVg ; + double dVth0 ; + double dVth0_dVb , dVth0_dVd , dVth0_dVg ; + double dVthSC ; + double dVthSC_dVb , dVthSC_dVd , dVthSC_dVg ; + double delta0 = 5.0e-3 ; + double Pb20b ; + double Pb20b_dVg , Pb20b_dVb , Pb20b_dVd ; + double dVthW ; + double dVthW_dVb , dVthW_dVd , dVthW_dVg ; + /* Alpha and related parameters */ + double Alpha ; + double Alpha_dVbs , Alpha_dVds , Alpha_dVgs ; + double Achi ; + double Achi_dVbs , Achi_dVds , Achi_dVgs ; + double VgVt = 0.0 ; + double VgVt_dVbs = 0.0, VgVt_dVds = 0.0, VgVt_dVgs = 0.0 ; + double Pslsat = 0.0 ; + double Vdsat = 0.0 ; + double VdsatE = 0.0 ; + double VdsatS = 0.0 ; + double VdsatS_dVbs = 0.0, VdsatS_dVds = 0.0, VdsatS_dVgs = 0.0 ; + double Delta ; + /* Q_B and capacitances */ + double Qb , Qb_dVbs , Qb_dVds , Qb_dVgs ; + double Qb_dVbse , Qb_dVdse , Qb_dVgse ; + double Qbu = 0.0 , Qbu_dVbs = 0.0 , Qbu_dVds = 0.0 , Qbu_dVgs = 0.0 ; + /* Q_I and capacitances */ + double Qi , Qi_dVbs , Qi_dVds , Qi_dVgs ; + double Qi_dVbse , Qi_dVdse , Qi_dVgse ; + double Qiu = 0.0 , Qiu_dVbs = 0.0 , Qiu_dVds = 0.0 , Qiu_dVgs = 0.0 ; + /* Q_D and capacitances */ + double Qd , Qd_dVbs , Qd_dVds , Qd_dVgs ; + double Qd_dVbse , Qd_dVdse , Qd_dVgse ; + double qd_dVgse, qd_dVdse, qd_dVbse, qd_dVsse ; + /* channel current */ + double Ids ; + double Ids_dVbs , Ids_dVds , Ids_dVgs ; + double Ids_dVbse , Ids_dVdse , Ids_dVgse ; + double Ids0 ; + double Ids0_dVbs , Ids0_dVds , Ids0_dVgs ; + /* STI */ + double dVthSCSTI ; + double dVthSCSTI_dVg , dVthSCSTI_dVd , dVthSCSTI_dVb ; + double Vgssti ; + double Vgssti_dVbs , Vgssti_dVds , Vgssti_dVgs ; + double costi0 , costi1 , costi3 ; + double costi4 , costi5 , costi6 , costi7 ; + double costi3_dVb , costi3_dVd, costi3_dVg ; + double costi3_dVb_c3 , costi3_dVd_c3, costi3_dVg_c3 ; + double Psasti ; + double Psasti_dVbs , Psasti_dVds , Psasti_dVgs ; + double Psbsti ; + double Psbsti_dVbs , Psbsti_dVds , Psbsti_dVgs ; + double Psab ; + double Psab_dVbs , Psab_dVds , Psab_dVgs ; + double Psti ; + double Psti_dVbs , Psti_dVds , Psti_dVgs ; + double sq1sti ; + double sq1sti_dVbs , sq1sti_dVds , sq1sti_dVgs ; + double sq2sti ; + double sq2sti_dVbs , sq2sti_dVds , sq2sti_dVgs ; + double Qn0sti ; + double Qn0sti_dVbs , Qn0sti_dVds , Qn0sti_dVgs ; + double Idssti ; + double Idssti_dVbs , Idssti_dVds , Idssti_dVgs ; + /* constants */ + double beta , beta_inv ; + double beta2 ; + double Pb2 ; + double Pb20 ; + double Pb2c ; + double Vfb ; + double c_eox ; + double Leff, Weff ; + double q_Nsub ; + /* PART-1 */ + /* Accumulation zone */ + double Psa ; + double Psa_dVbs , Psa_dVds , Psa_dVgs ; + /* CLM*/ + double Psdl , Psdl_dVbs , Psdl_dVds , Psdl_dVgs ; + double Lred , Lred_dVbs , Lred_dVds , Lred_dVgs ; + double Lch , Lch_dVbs , Lch_dVds , Lch_dVgs ; + double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; + double Aclm ; + /* Pocket Implant */ + double Vthp, Vthp_dVb, Vthp_dVd, Vthp_dVg ; + double dVthLP, dVthLP_dVb, dVthLP_dVd, dVthLP_dVg ; + double bs12, bs12_dVb, bs12_dVd , bs12_dVg ; + double Qbmm, Qbmm_dVb, Qbmm_dVd , Qbmm_dVg ; + double dqb, dqb_dVb, dqb_dVg, dqb_dVd ; + double Vdx, Vdx2 ; + double Pbsum, sqrt_Pbsum ; + double Pbsum_dVb, Pbsum_dVd, Pbsum_dVg ; + /* Poly-Depletion Effect */ + const double pol_b = 1.0 ; + double dPpg , dPpg_dVb , dPpg_dVd , dPpg_dVg ; + /* Quantum Effect */ + double Tox , Tox_dVb , Tox_dVd , Tox_dVg ; + double dTox , dTox_dVb , dTox_dVd , dTox_dVg ; + double Cox , Cox_dVb , Cox_dVd , Cox_dVg ; + double Cox_inv , Cox_inv_dVb , Cox_inv_dVd , Cox_inv_dVg ; + double Tox0 , Cox0 , Cox0_inv ; + double Vthq, Vthq_dVb , Vthq_dVd ; + /* Igate , Igidl , Igisl */ + const double igate_dlt = 1.0e-2 ; + const double gidlvds_dlt = 1.0e-5 ; + const double gidla = 100.0 ; + double Psdlz , Psdlz_dVbs , Psdlz_dVds , Psdlz_dVgs ; + double Egp12 , Egp32 ; + double E1 , E1_dVb , E1_dVd , E1_dVg ; + double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; + double Egidl , Egidl_dVb , Egidl_dVd , Egidl_dVg ; + double Egisl , Egisl_dVb , Egisl_dVd , Egisl_dVg ; + double Igate , Igate_dVbs , Igate_dVds , Igate_dVgs ; + double Igate_dVbse , Igate_dVdse , Igate_dVgse ; + double Igs , Igd , Igb ; + double Igs_dVbs , Igs_dVds , Igs_dVgs ; + double Igs_dVbse , Igs_dVdse , Igs_dVgse ; + double Igd_dVbs , Igd_dVds , Igd_dVgs ; + double Igd_dVbse , Igd_dVdse , Igd_dVgse ; + double Igb_dVbs , Igb_dVds , Igb_dVgs ; + double Igb_dVbse , Igb_dVdse , Igb_dVgse ; + double Igidl , Igidl_dVbs , Igidl_dVds , Igidl_dVgs ; + double Igidl_dVbse , Igidl_dVdse , Igidl_dVgse ; + double Igisl , Igisl_dVbs , Igisl_dVds , Igisl_dVgs ; + double Igisl_dVbse , Igisl_dVdse , Igisl_dVgse ; + /* connecting function */ + double FD2 , FD2_dVbs , FD2_dVds , FD2_dVgs ; + double FMDVDS , FMDVDS_dVbs , FMDVDS_dVds , FMDVDS_dVgs ; + double FMDVGS , FMDVGS_dVgs ; + double FMDPG , FMDPG_dVbs , FMDPG_dVds , FMDPG_dVgs ; + + double cnst0 , cnst1 ; + double cnstCoxi =0.0 , cnstCoxi_dVg =0.0 , cnstCoxi_dVd =0.0 , cnstCoxi_dVb =0.0 ; + double fac1 ; + double fac1_dVbs , fac1_dVds , fac1_dVgs ; + double fac1p2 ; + double fs01 ; + double fs01_dPs0 ; + double fs01_dVbs , fs01_dVds , fs01_dVgs ; + double fs02 ; + double fs02_dPs0 ; + double fs02_dVbs , fs02_dVds , fs02_dVgs ; + double fsl1 ; + double fsl1_dPsl ; + double fsl1_dVbs , fsl1_dVds , fsl1_dVgs ; /* Vdseff */ + double fsl2 ; + double fsl2_dPsl ; + double fsl2_dVbs , fsl2_dVds , fsl2_dVgs ; /* Vdseff */ + double cfs1 ; + double fb , fb_dChi ; + double fi , fi_dChi ; + double exp_Chi , exp_Rho , exp_bVbs , exp_bVbsVds ; + double Fs0, Fsl ; + double Fs0_dPs0 , Fsl_dPsl ; + double dPs0 , dPsl ; + double Qn0 = 0.0e0 ; + double Qn0_dVbs , Qn0_dVds , Qn0_dVgs ; + double Qb0 ; + double Qb0_dVb , Qb0_dVd , Qb0_dVg ; + double Qn00 ; + double Qn00_dVbs , Qn00_dVds , Qn00_dVgs ; + double Qbnm ; + double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; + double DtPds ; + double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; + double Qinm ; + double Qinm_dVbs , Qinm_dVds , Qinm_dVgs ; + double Qidn ; + double Qidn_dVbs , Qidn_dVds , Qidn_dVgs ; + double Qdnm ; + double Qdnm_dVbs , Qdnm_dVds , Qdnm_dVgs ; + double Qddn ; + double Qddn_dVbs , Qddn_dVds , Qddn_dVgs ; + double Quot ; + double Qdrat = 0.5; + double Qdrat_dVbs = 0.0 , Qdrat_dVds = 0.0, Qdrat_dVgs = 0.0; + double Qdrat_dVbse , Qdrat_dVdse , Qdrat_dVgse ; + double Idd ; + double Idd_dVbs , Idd_dVds , Idd_dVgs ; + double Fdd ; + double Fdd_dVbs , Fdd_dVds , Fdd_dVgs ; + double Eeff ; + double Eeff_dVbs , Eeff_dVds , Eeff_dVgs ; + double Rns ; + double Mu = 0.0 ; + double Mu_dVbs , Mu_dVds , Mu_dVgs ; + double Muun , Muun_dVbs , Muun_dVds , Muun_dVgs ; + double Ey = 0e0 ; + double Ey_dVbs , Ey_dVds , Ey_dVgs ; + double Em ; + double Em_dVbs , Em_dVds , Em_dVgs ; + double Vmax ; + double Eta ; + double Eta_dVbs , Eta_dVds , Eta_dVgs ; + double Eta1 , Eta1p12 , Eta1p32 , Eta1p52 ; + double Zeta12 , Zeta32 , Zeta52 ; + double F00 ; + double F00_dVbs , F00_dVds , F00_dVgs ; + double F10 ; + double F10_dVbs , F10_dVds , F10_dVgs ; + double F30 ; + double F30_dVbs , F30_dVds , F30_dVgs ; + double F11 ; + double F11_dVbs , F11_dVds , F11_dVgs ; + double Ps0_min ; + double Ps0_min_dVbs , Ps0_min_dVds , Ps0_min_dVgs ; + double Acn , Acd , Ac1 , Ac2 , Ac3 , Ac4 , Ac31 , Ac41 ; + double Acn_dVbs , Acn_dVds , Acn_dVgs ; + double Acd_dVbs , Acd_dVds , Acd_dVgs ; + double Ac1_dVbs , Ac1_dVds , Ac1_dVgs ; + double Ac2_dVbs , Ac2_dVds , Ac2_dVgs ; + double Ac3_dVbs , Ac3_dVds , Ac3_dVgs ; + double Ac4_dVbs , Ac4_dVds , Ac4_dVgs ; + double Ac31_dVbs , Ac31_dVds , Ac31_dVgs ; + /* PART-2 (Isub) */ + double Isub ; + double Isub_dVbs , Isub_dVds , Isub_dVgs ; + double Isub_dVbse , Isub_dVdse , Isub_dVgse ; + double Psislsat, Psisubsat ; + double Psislsat_dVd, Psislsat_dVg, Psislsat_dVb ; + double Psisubsat_dVd, Psisubsat_dVg, Psisubsat_dVb ; + /* PART-3 (overlap) */ + double cov_slp , cov_mag , covvg , covvg_dVgs ; + double Lov ; + double Qgos = 0.0, Qgos_dVbs = 0.0, Qgos_dVds = 0.0, Qgos_dVgs = 0.0 ; + double Qgos_dVbse , Qgos_dVdse , Qgos_dVgse ; + double Qgod = 0.0, Qgod_dVbs = 0.0, Qgod_dVds = 0.0, Qgod_dVgs = 0.0 ; + double Qgod_dVbse , Qgod_dVdse , Qgod_dVgse ; + + int flg_overgiven =0 ; + + double Qgbo , Qgbo_dVbs , Qgbo_dVds , Qgbo_dVgs ; + double Qgbo_dVbse , Qgbo_dVdse , Qgbo_dVgse ; + double Cggo = 0.0 , Cgdo = 0.0 , Cgso = 0.0 , Cgbo = 0.0 , Cgbo_loc; + /* fringing capacitance */ + double Cf ; + double Qfd , Qfs ; + /* Cqy */ + double Ec , Ec_dVbs , Ec_dVds , Ec_dVgs ; + double Pslk , Pslk_dVbs , Pslk_dVds , Pslk_dVgs ; + double Qy ; + double Cqyd, Cqyg, Cqys, Cqyb ; + double Qy_dVbs , Qy_dVds , Qy_dVgs; + double Qy_dVbse , Qy_dVdse, Qy_dVgse; + double Qys, Qys_dVbse , Qys_dVdse, Qys_dVgse; + /* PART-4 (junction diode) */ + double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; + double Nvtm ; + /* junction capacitance */ + double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; + double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; + double arg , sarg ; + /* PART-5 (NQS) */ + double tau, Qi_prev ; + double tau_dVgs, tau_dVds, tau_dVbs ; + double tau_dVgse, tau_dVdse, tau_dVbse ; + double Qi_nqs ; + double Qi_dVbs_nqs, Qi_dVds_nqs, Qi_dVgs_nqs ; + double Qi_dVbse_nqs, Qi_dVdse_nqs, Qi_dVgse_nqs ; + double taub, Qb_prev ; + double taub_dVgs, taub_dVds, taub_dVbs ; + double taub_dVgse, taub_dVdse, taub_dVbse ; + double Qb_nqs ; + double Qb_dVbs_nqs, Qb_dVds_nqs, Qb_dVgs_nqs ; + double Qb_dVbse_nqs, Qb_dVdse_nqs, Qb_dVgse_nqs ; + /* PART-6 (noise) */ + /* 1/f */ + double NFalp , NFtrp , Cit , Nflic ; + /* thermal */ + double Eyd, Mu_Ave, Nthrml, Mud_hoso ; + /* induced gate noise ( Part 0/3 ) */ + double kusai00 , kusaidd , kusaiL , kusai00L ; + int flg_ign = 0 ; + double sqrtkusaiL , kusai_ig , gds0_ign , gds0_h2 , GAMMA , crl_f ; + const double c_sqrt_15 = 3.872983346207417e0 ; /* sqrt(15) */ + const double Cox_small = 1.0e-6 ; + const double c_16o135 = 1.185185185185185e-1 ; /* 16/135 */ + double Nign0 , MuModA , MuModB , correct_w1 ; + + /* Bias iteration accounting Rs/Rd */ + int lp_bs ; + double Ids_last ; + double vtol_iprv = 2.0e-1 ; + double vtol_pprv = 1.01e-1 ; + double Vbsc_dif , Vdsc_dif , Vgsc_dif , sum_vdif ; + double Vbsc_dif2 , Vdsc_dif2 , Vgsc_dif2 , sum_vdif2 ; + double Rs , Rd ; + double Fbs , Fds , Fgs ; + double DJ , DJI ; + double JI11 , JI12 , JI13 , JI21 , JI22 , JI23 , JI31 , JI32 , JI33 ; + double dVbs , dVds , dVgs ; + double dV_sum ; + /* temporary vars. */ + double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 ; + double TX , TX_dVbs , TX_dVds , TX_dVgs ; + double TY , TY_dVbs , TY_dVds , TY_dVgs ; + double T1_dVb , T1_dVd , T1_dVg ; + double T2_dVb , T2_dVd , T2_dVg ; + double T3_dVb , T3_dVd , T3_dVg ; + double T4_dVb , T4_dVd , T4_dVg ; + double T5_dVb , T5_dVd , T5_dVg ; + double T6_dVb , T6_dVd , T6_dVg ; + double T7_dVb , T7_dVd , T7_dVg ; + double T8_dVb , T8_dVd , T8_dVg ; + double T9_dVb , T9_dVd , T9_dVg ; + double T10_dVb , T10_dVd , T10_dVg ; + double T11_dVb , T11_dVd , T11_dVg ; + double T12_dVb , T12_dVd , T12_dVg ; + + int flg_zone = 0 ; + double Vfbsft = 0.0 , Vfbsft_dVbs , Vfbsft_dVds , Vfbsft_dVgs ; + + /* Vdseff */ + double Vdseff , Vdsorg ; + double Vdseff_dVbs , Vdseff_dVds , Vdseff_dVgs ; + + /* G/S and G/D Overlap Charges: Qovs/Qovd */ + double Qovd = 0.0, Qovd_dVbse = 0.0, Qovd_dVdse = 0.0, Qovd_dVgse = 0.0 ; + double Qovd_dVbs = 0.0, Qovd_dVds = 0.0, Qovd_dVgs = 0.0 ; + double Qovs = 0.0, Qovs_dVbse = 0.0, Qovs_dVdse = 0.0, Qovs_dVgse = 0.0 ; + double Qovs_dVbs = 0.0, Qovs_dVds = 0.0, Qovs_dVgs = 0.0 ; + int lcover = 0, flg_ovloops = 0, flg_ovloopd = 0 ; + int flg_overs = 0, flg_overd = 0 ; + double VgpLD , VgpLD_dVgs ; + double Vgp_fb_LD ; + double QbdLD = 0.0 , QbdLD_dVbs = 0.0 , QbdLD_dVds = 0.0 , QbdLD_dVgs = 0.0 ; + double QidLD = 0.0 , QidLD_dVbs = 0.0 , QidLD_dVds = 0.0 , QidLD_dVgs = 0.0 ; + double QbsLD = 0.0 , QbsLD_dVbs = 0.0 , QbsLD_dVds = 0.0 , QbsLD_dVgs = 0.0 ; + double QisLD = 0.0 , QisLD_dVbs = 0.0 , QisLD_dVds = 0.0 , QisLD_dVgs = 0.0 ; + double QbdLD_dVbse = 0.0 , QbdLD_dVdse = 0.0 , QbdLD_dVgse = 0.0 ; + double QidLD_dVbse = 0.0 , QidLD_dVdse = 0.0 , QidLD_dVgse = 0.0 ; + double QbsLD_dVbse = 0.0 , QbsLD_dVdse = 0.0 , QbsLD_dVgse = 0.0 ; + double QisLD_dVbse = 0.0 , QisLD_dVdse = 0.0 , QisLD_dVgse = 0.0 ; + double QbuLD = 0.0 , QbuLD_dVbs = 0.0 , QbuLD_dVds = 0.0 , QbuLD_dVgs = 0.0 ; + double QsuLD = 0.0 , QsuLD_dVbs = 0.0 , QsuLD_dVds = 0.0 , QsuLD_dVgs = 0.0 ; + double QiuLD = 0.0 , QiuLD_dVbs = 0.0 , QiuLD_dVds = 0.0 , QiuLD_dVgs = 0.0 ; + double Ps0LD = 0.0 , Ps0LD_dVbs = 0.0 , Ps0LD_dVds = 0.0 , Ps0LD_dVgs = 0.0 ; + double QbuLD_dVxb = 0.0 , QbuLD_dVgb = 0.0 ; + double QsuLD_dVxb = 0.0 , QsuLD_dVgb = 0.0 ; + double VthLD = 0.0; + int flg_ovzone = 0 ; + + /* Vgsz for SCE and PGD */ + double Vbsz2 , Vbsz2_dVbs , Vbsz2_dVds , Vbsz2_dVgs ; + + /* Multiplication factor of a MOSFET instance */ + double M = 1.0 ; + + /* Mode flag ( = 0 | 1 ) */ + double ModeNML , ModeRVS ; + + /* For Gate Leak Current Partitioning */ + double A2, Alpha0, Alpha1, Alpha2, GLPART1 ; + double Alpha0_dVgs, Alpha1_dVgs, Alpha2_dVgs ; + double Alpha0_dVds, Alpha1_dVds, Alpha2_dVds ; + double Alpha0_dVbs, Alpha1_dVbs, Alpha2_dVbs ; + double GLPART1_dVgs, GLPART1_dVds, GLPART1_dVbs ; + double GLPART1_dVgse, GLPART1_dVdse, GLPART1_dVbse ; + + /* IBPC */ + double IdsIBPC = 0.0 ; + double IdsIBPC_dVbs = 0.0 , IdsIBPC_dVds = 0.0 , IdsIBPC_dVgs = 0.0 ; + double IdsIBPC_dVbse = 0.0 , IdsIBPC_dVdse = 0.0 , IdsIBPC_dVgse = 0.0 ; + + /* Overlap Charge: Qover */ + double Vbsgmt , Vdsgmt , Vgsgmt , Vdbgmt , Vgbgmt , Vsbgmt , Vxbgmt ; + double Vxbgmtcl = 0.0, Vxbgmtcl_dVxbgmt = 0.0; + + double Pb2over ; + + /* SCE LOOP */ + double A , A_dVgs, A_dVds, A_dVbs ; + int NNN ; + double PS0_SCE=0 , PS0_SCE_dVgs = 0 , PS0_SCE_dVds = 0 , PS0_SCE_dVbs = 0 ; + double PS0Z_SCE=0 , PS0Z_SCE_dVgs = 0 , PS0Z_SCE_dVds = 0 , PS0Z_SCE_dVbs = 0 ; + /* double arg0 = 0.01 , arg1 = 0.04 ; */ + double arg0 = 0.01 ; + double arg2 = here->HSM2_2qnsub_esi * 1.0e-4; + int MAX_LOOP_SCE ; + + int codqb = 0 ; + int corecip = model->HSM2_corecip ; + + + /* modify Qy in accumulation region */ + double eps_qy = 5.0e-3 ; + double Aclm_eff, Aclm_eff_dVds, Aclm_eff_dVgs, Aclm_eff_dVbs ; + + double Idd1 , Idd1_dVbs , Idd1_dVgs , Idd1_dVds ; + double Fdd1 , Fdd1_dVbs , Fdd1_dVgs , Fdd1_dVds ; + + double tcjbs=0.0, tcjbssw=0.0, tcjbsswg=0.0, + tcjbd=0.0, tcjbdsw=0.0, tcjbdswg=0.0 ; + double TTEMP ; + + double PS0_SCE_tol = 4.0e-7 ; + double PS0_SCE_deriv_tol = 1.0e-8; + double Ps0_ini_dVds =0.0, Ps0_ini_dVgs =0.0, Ps0_ini_dVbs =0.0 ; + double Ps0_iniA_dVds =0.0, Ps0_iniA_dVgs =0.0, Ps0_iniA_dVbs =0.0 ; + double Ps0_iniB_dVds =0.0, Ps0_iniB_dVgs =0.0, Ps0_iniB_dVbs =0.0 ; + + double A_dPS0Z = 0.0, dqb_dPS0Z = 0.0, dVth_dPS0Z = 0.0, dVth0_dPS0Z = 0.0, + dVthLP_dPS0Z = 0.0, dVthSC_dPS0Z = 0.0, Qbmm_dPS0Z = 0.0, Vfbsft_dPS0Z = 0.0, + Vgp_dPS0Z = 0.0, Vgpz_dPS0Z = 0.0, Vthp_dPS0Z = 0.0, + Vth0_dPS0Z = 0.0 ; + double T1_dPS0Z, T3_dPS0Z, T4_dPS0Z, T5_dPS0Z, + T6_dPS0Z, T7_dPS0Z, T8_dPS0Z, T9_dPS0Z, + T10_dPS0Z, TX_dPS0Z ; + double Ac1_dPS0Z, Ac2_dPS0Z, Ac3_dPS0Z, Ac31_dPS0Z, + Acd_dPS0Z, Acn_dPS0Z, Chi_dPS0Z, Psa_dPS0Z ; + double Fs0_dPS0Z, Fsl_dPS0Z, Ps0_dPS0Z, Psl_dPS0Z, + Pds_dPS0Z, Pzadd_dPS0Z, Ps0z_dPS0Z ; + double G, delta_PS0Z_SCE, delta_PS0Z_SCE_dVds, + delta_PS0Z_SCE_dVgs,delta_PS0Z_SCE_dVbs ; + + + double Vgs_min ; + + /*================ Start of executable code.=================*/ + + if (here->HSM2_mode == HiSIM_NORMAL_MODE) { + ModeNML = 1.0 ; + ModeRVS = 0.0 ; + } else { + ModeNML = 0.0 ; + ModeRVS = 1.0 ; + } + + T1 = vbs + vds + vgs + vbd_jct + vbs_jct ; + if ( ! finite (T1) ) { + fprintf (stderr , + "*** warning(HiSIM): Unacceptable Bias(es).\n" ) ; + fprintf (stderr , "----- bias information (HiSIM)\n" ) ; + fprintf (stderr , "name: %s\n" , here->HSM2name ) ; + fprintf (stderr , "states: %d\n" , here->HSM2states ) ; + fprintf (stderr , "vds= %12.5e vgs=%12.5e vbs=%12.5e\n" + , vds , vgs , vbs ) ; + fprintf (stderr , "vbs_jct= %12.5e vbd_jct= %12.5e\n" + , vbs_jct , vbd_jct ) ; + fprintf (stderr , "vd= %12.5e vg= %12.5e vb= %12.5e vs= %12.5e\n" + , *( ckt->CKTrhsOld + here->HSM2dNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2gNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2bNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2sNodePrime ) ) ; + if ( here->HSM2_called >= 1 ) { + fprintf (stderr , "vdsc_prv= %12.5e vgsc_prv=%12.5e vbsc_prv=%12.5e\n" + , here->HSM2_vdsc_prv , here->HSM2_vgsc_prv + , here->HSM2_vbsc_prv ) ; + } + fprintf (stderr , "----- bias information (end)\n" ) ; + return ( HiSIM_ERROR ) ; + } + + flg_info = model->HSM2_info ; + flg_nqs = model->HSM2_conqs ; + + /*-----------------------------------------------------------* + * Start of the routine. (label) + *-----------------*/ +start_of_routine: + + TTEMP = ckt->CKTtemp ; + if ( here->HSM2_dtemp_Given ) { TTEMP = TTEMP + here->HSM2_dtemp ; } + + beta = here->HSM2_beta ; + + /* Inverse of the thermal voltage */ + beta_inv = here->HSM2_beta_inv ; + beta2 = here->HSM2_beta2 ; + + /* Bandgap */ + Egp12 = here->HSM2_egp12 ; + Egp32 = here->HSM2_egp32 ; + + /* Metallurgical channel geometry */ + Leff = here->HSM2_leff ; + Weff = here->HSM2_weff ; + + /* Flat band voltage */ + Vfb = pParam->HSM2_vfbc ; + + /* Surface impurity profile */ + q_Nsub = here->HSM2_qnsub ; + + /* Velocity Temperature Dependence */ + Vmax = here->HSM2_vmax ; + + /* 2 phi_B */ + Pb2 = here->HSM2_pb2 ; + Pb20 = here->HSM2_pb20 ; + Pb2c = here->HSM2_pb2c ; + + /* Coefficient of the F function for bulk charge */ + cnst0 = here->HSM2_cnst0 ; + + /* cnst1: n_{p0} / p_{p0} */ + cnst1 = here->HSM2_cnst1 ; + + /* c_eox: Permitivity in ox */ + c_eox = here->HSM2_cecox ; + + /* Tox and Cox without QME */ + Tox0 = model->HSM2_tox ; + Cox0 = c_eox / Tox0 ; + Cox0_inv = 1.0 / Cox0 ; + + /* for calculation of Ps0_min */ + Vgs_min = model->HSM2_type * model->HSM2_Vgsmin ; + + /*-----------------------------------------------------------* + * Exchange bias conditions according to MOS type. + * - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 + * are assumed.) + *-----------------*/ + Vbse = vbs ; + Vdse = vds ; + Vgse = vgs ; + + /*---------------------------------------------------* + * Clamp too large biases. + * -note: Quantities are extrapolated in PART-5. + *-----------------*/ + + if ( Pb2 - model->HSM2_vzadd0 < Vbs_max ) { + Vbs_max = Pb2 - model->HSM2_vzadd0 ; + } + if ( Pb20 - model->HSM2_vzadd0 < Vbs_max ) { + Vbs_max = Pb20 - model->HSM2_vzadd0 ; + } + if ( Pb2c - model->HSM2_vzadd0 < Vbs_max ) { + Vbs_max = Pb2c - model->HSM2_vzadd0 ; + } + + if ( Vbs_bnd > Vbs_max * 0.5 ) { + Vbs_bnd = 0.5 * Vbs_max ; + } + + if ( Vbse > Vbs_bnd ) { + flg_vbsc = 1 ; + T1 = Vbse - Vbs_bnd ; + T2 = Vbs_max - Vbs_bnd ; + Fn_SUPoly4( TY , T1 , T2 , Vbsc_dVbse ) ; + Vbsc = Vbs_bnd + TY ; + } else if ( Vbse < Vbs_min ) { + flg_vbsc = -1 ; + Vbsc = Vbs_min ; + Vbsc_dVbse = 1.0 ; + } else { + flg_vbsc = 0 ; + Vbsc = Vbse ; + Vbsc_dVbse = 1.0 ; + } + + Vdsc = Vdse ; + Vgsc = Vgse ; + + if (here->HSM2_rs > 0.0 || here->HSM2_rd > 0.0) { + if ( model->HSM2_corsrd == 1 ) flg_rsrd = 1 ; + if ( model->HSM2_corsrd == 2 ) flg_rsrd = 2 ; + } + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-1: Basic device characteristics. + *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* + * Prepare for potential initial guesses using previous values + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + flg_pprv = 0 ; + + if ( here->HSM2_called >= 1 ) { + + Vbsc_dif = Vbsc - here->HSM2_vbsc_prv ; + Vdsc_dif = Vdsc - here->HSM2_vdsc_prv ; + Vgsc_dif = Vgsc - here->HSM2_vgsc_prv ; + + sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) + + fabs( Vgsc_dif ) ; + + if ( model->HSM2_copprv >= 1 && sum_vdif <= vtol_pprv && + here->HSM2_mode * here->HSM2_mode_prv > 0 ) { flg_pprv = 1 ;} + + if ( here->HSM2_called >= 2 && flg_pprv == 1 ) { + Vbsc_dif2 = here->HSM2_vbsc_prv - here->HSM2_vbsc_prv2 ; + Vdsc_dif2 = here->HSM2_vdsc_prv - here->HSM2_vdsc_prv2 ; + Vgsc_dif2 = here->HSM2_vgsc_prv - here->HSM2_vgsc_prv2 ; + sum_vdif2 = fabs( Vbsc_dif2 ) + fabs( Vdsc_dif2 ) + + fabs( Vgsc_dif2 ) ; + if ( epsm10 < sum_vdif2 && sum_vdif2 <= vtol_pprv && + here->HSM2_mode_prv * here->HSM2_mode_prv2 > 0 ) { flg_pprv = 2 ; } + } + } else { + Vbsc_dif = 0.0 ; + Vdsc_dif = 0.0 ; + Vgsc_dif = 0.0 ; + sum_vdif = 0.0 ; + Vbsc_dif2 = 0.0 ; + Vdsc_dif2 = 0.0 ; + Vgsc_dif2 = 0.0 ; + sum_vdif2 = 0.0 ; + flg_iprv = 0 ; + flg_pprv = 0 ; + } + + dVbs = Vbsc_dif ; + dVds = Vdsc_dif ; + dVgs = Vgsc_dif ; + + if ( flg_pprv >= 1 ) { + Ps0 = here->HSM2_ps0_prv ; + Ps0_dVbs = here->HSM2_ps0_dvbs_prv ; + Ps0_dVds = here->HSM2_ps0_dvds_prv ; + Ps0_dVgs = here->HSM2_ps0_dvgs_prv ; + + Pds = here->HSM2_pds_prv ; + Pds_dVbs = here->HSM2_pds_dvbs_prv ; + Pds_dVds = here->HSM2_pds_dvds_prv ; + Pds_dVgs = here->HSM2_pds_dvgs_prv ; + } + + + /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* + * Bias loop: iteration to solve the system of equations of + * the small circuit taking into account Rs and Rd. + * - Vxs are internal (or effective) biases. + * - Equations: + * Vbs = Vbsc - Rs * Ids + * Vds = Vdsc - ( Rs + Rd ) * Ids + * Vgs = Vgsc - Rs * Ids + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + if ( flg_rsrd == 1 ) { + + if (here->HSM2_mode == HiSIM_NORMAL_MODE) { + Rs = here->HSM2_rs ; + Rd = here->HSM2_rd ; + } else { + Rs = here->HSM2_rd ; + Rd = here->HSM2_rs ; + } + + if ( here->HSM2_called >= 1 ) { + + if ( model->HSM2_coiprv >= 1 && + 0.0 < sum_vdif && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} + } + + /*-----------------------------------------------------------* + * Initial guesses using the previous values. + *-----------------*/ + if ( flg_iprv == 1 ) { + here->HSM2_ids_dvbs_prv = Fn_Max( 0.0 , here->HSM2_ids_dvbs_prv ) ; + here->HSM2_ids_dvds_prv = Fn_Max( 0.0 , here->HSM2_ids_dvds_prv ) ; + here->HSM2_ids_dvgs_prv = Fn_Max( 0.0 , here->HSM2_ids_dvgs_prv ) ; + + dVbs = Vbsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * here->HSM2_ids_dvbs_prv ) ) ; + dVds = Vdsc_dif * ( 1.0 - 1.0 / ( 1.0 + ( Rs + Rd ) * here->HSM2_ids_dvds_prv ) ) ; + dVgs = Vgsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * here->HSM2_ids_dvgs_prv ) ) ; + + Ids = here->HSM2_ids_prv + + here->HSM2_ids_dvbs_prv * dVbs + + here->HSM2_ids_dvds_prv * dVds + + here->HSM2_ids_dvgs_prv * dVgs ; + + T1 = ( Ids - here->HSM2_ids_prv ) ; + T2 = fabs( T1 ) ; + if ( Ids_maxvar * here->HSM2_ids_prv < T2 ) { + Ids = here->HSM2_ids_prv * ( 1.0 + Fn_Sgn( T1 ) * Ids_maxvar ) ; + } + if ( Ids < 0 ) Ids = 0.0 ; + + } else { + Ids = 0.0 ; + if ( flg_pprv >= 1 ) { + dVbs = Vbsc_dif ; + dVds = Vdsc_dif ; + dVgs = Vgsc_dif ; + } + } /* end of flg_iprv if-blocks */ + + Vbs = Vbsc - Ids * Rs ; + Vds = Vdsc - Ids * ( Rs + Rd ) ; + if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } + + Vgs = Vgsc - Ids * Rs ; + + } else { + lp_bs_max = 1 ; + Ids = 0.0 ; + Vbs = Vbsc ; + Vds = Vdsc ; + Vgs = Vgsc ; + } /* end of flg_rsrd if-blocks */ + + /*-----------------------------------------------------------* + * start of the loop. + *-----------------*/ + for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { + + Ids_last = Ids ; + /* Initialization of counters is needed for restart. */ + lp_s0 = 0 ; + lp_sl = 0 ; + + /*-----------------------------------------------------------* + * Vxsz: Modified bias introduced to realize symmetry at Vds=0. + *-----------------*/ + + T1 = Vbsc_dVbse * Vds / 2 ; + Fn_SymAdd( Vzadd , T1 , model->HSM2_vzadd0 , T2 ) ; + T2 *= Vbsc_dVbse / 2 ; + Vzadd_dVds = T2 ; + + if ( Vzadd < ps_conv ) { + Vzadd = ps_conv ; + Vzadd_dVds = 0.0 ; + } + + Vbsz = Vbs + Vzadd ; + Vbsz_dVbs = 1.0 ; + Vbsz_dVds = Vzadd_dVds ; + + Vdsz = Vds + 2.0 * Vzadd ; + Vdsz_dVds = 1.0 + 2.0 * Vzadd_dVds ; + + Vgsz = Vgs + Vzadd ; + Vgsz_dVgs = 1.0 ; + Vgsz_dVds = Vzadd_dVds ; + + /*---------------------------------------------------* + * Factor of modification for symmetry. + *-----------------*/ + + T1 = here->HSM2_qnsub_esi * Cox0_inv * Cox0_inv ; + T2 = Vgs - Vfb ; + T3 = 1 + 2.0 / T1 * ( T2 - beta_inv - Vbs ) ; + Fn_SZ( T4 , T3 , 1e-3 , T5 ) ; + TX = sqrt( T4 ) ; + Pslsat = T2 + T1 * ( 1.0 - TX ) ; + VdsatS = Pslsat - Pb2 ; + Fn_SL( VdsatS , VdsatS , 0.1 , 5e-2 , T6 ) ; + + VdsatS_dVbs = T6 * T5 / TX ; + VdsatS_dVds = 0.0 ; + VdsatS_dVgs = T6 * ( 1.0 - T5 / TX ) ; + + + T1 = Vds / VdsatS ; + Fn_SUPoly4( TX , T1 , 1.0 , T0 ) ; + FMDVDS = TX * TX ; + T2 = 2 * TX * T0 ; + T3 = T2 / ( VdsatS * VdsatS ) ; + FMDVDS_dVbs = T3 * ( - Vds * VdsatS_dVbs ) ; + FMDVDS_dVds = T3 * ( 1.0 * VdsatS - Vds * VdsatS_dVds ) ; + FMDVDS_dVgs = T3 * ( - Vds * VdsatS_dVgs ) ; + + /*-----------------------------------------------------------* + * Quantum effect + *-----------------*/ + if ( model->HSM2_flg_qme == 0 ) { + flg_qme = 0 ; + } else { + flg_qme = 1 ; + } + + + T1 = here->HSM2_2qnsub_esi ; + T2 = sqrt( T1 * Pb20 ) ; + Vthq = Pb20 + Vfb + T2 * Cox0_inv ; + Vthq_dVb = 0.0 ; + Vthq_dVd = 0.0 ; + + if ( flg_qme == 0 ) { + Tox = Tox0 ; + Tox_dVb = 0.0 ; + Tox_dVd = 0.0 ; + Tox_dVg = 0.0 ; + + Cox = Cox0 ; + Cox_dVb = 0.0 ; + Cox_dVd = 0.0 ; + Cox_dVg = 0.0 ; + + Cox_inv = Cox0_inv ; + Cox_inv_dVb = 0.0 ; + Cox_inv_dVd = 0.0 ; + Cox_inv_dVg = 0.0 ; + + T0 = cnst0 * cnst0 * Cox_inv ; + cnstCoxi = T0 * Cox_inv ; + cnstCoxi_dVb = 0.0 ; + cnstCoxi_dVd = 0.0 ; + cnstCoxi_dVg = 0.0 ; + } else { + + T5 = Vgs - Vbs - Vthq + model->HSM2_qme2 ; + T5_dVb = -1.0 - Vthq_dVb ; + T5_dVd = - Vthq_dVd ; + T5_dVg = 1.0 ; + Fn_SZ( T2 , T5 , qme_dlt, T3) ; + T2_dVb = T3 * T5_dVb ; + T2_dVd = T3 * T5_dVd ; + T2_dVg = T3 * T5_dVg ; + + T3 = 1.0 / T2 ; + T7 = -1.0 / ( T2 * T2 ) ; + T3_dVb = T7 * T2_dVb ; + T3_dVd = T7 * T2_dVd ; + T3_dVg = T7 * T2_dVg ; + + T4 = 2.0 * fabs(Vthq) ; + T6 = Vfb - Vthq + model->HSM2_qme2 ; + if(T6 > T4) { T4 = T6; } + + Fn_SU( T2 , T3 , 1.0 / T4 , qme_dlt, T6 ) ; + T2_dVb = T6 * T3_dVb ; + T2_dVd = T6 * T3_dVd ; + T2_dVg = T6 * T3_dVg ; + + dTox = model->HSM2_qme1 * T2 + model->HSM2_qme3 ; + T7 = model->HSM2_qme1 ; + dTox_dVb = T7 * T2_dVb ; + dTox_dVd = T7 * T2_dVd ; + dTox_dVg = T7 * T2_dVg ; + + if ( dTox * 1.0e12 < Tox0 ) { + dTox = 0.0 ; + dTox_dVb = 0.0 ; + dTox_dVd = 0.0 ; + dTox_dVg = 0.0 ; + flg_qme = 0 ; + } + + Tox = Tox0 + dTox ; + Tox_dVb = dTox_dVb ; + Tox_dVd = dTox_dVd ; + Tox_dVg = dTox_dVg ; + + Cox = c_eox / Tox ; + T1 = - c_eox / ( Tox * Tox ) ; + Cox_dVb = T1 * Tox_dVb ; + Cox_dVd = T1 * Tox_dVd ; + Cox_dVg = T1 * Tox_dVg ; + + Cox_inv = Tox / c_eox ; + T1 = 1.0 / c_eox ; + Cox_inv_dVb = T1 * Tox_dVb ; + Cox_inv_dVd = T1 * Tox_dVd ; + Cox_inv_dVg = T1 * Tox_dVg ; + + T0 = cnst0 * cnst0 * Cox_inv ; + cnstCoxi = T0 * Cox_inv ; + T1 = 2.0 * T0 ; + cnstCoxi_dVb = T1 * Cox_inv_dVb ; + cnstCoxi_dVd = T1 * Cox_inv_dVd ; + cnstCoxi_dVg = T1 * Cox_inv_dVg ; + } + + + fac1 = cnst0 * Cox_inv ; + fac1_dVds = cnst0 * Cox_inv_dVd ; + fac1_dVgs = cnst0 * Cox_inv_dVg ; + fac1_dVbs = cnst0 * Cox_inv_dVb ; + fac1p2 = fac1 * fac1 ; + + /* Ps0_min: approx. solution of Poisson equation at Vgs_min */ + /* ( easy to improve, if necessary ) */ + Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ; + Ps0_min_dVds = -2.0 * beta_inv * fac1_dVds / fac1 ; + Ps0_min_dVgs = -2.0 * beta_inv * fac1_dVgs / fac1 ; + Ps0_min_dVbs = -2.0 * beta_inv * fac1_dVbs / fac1 ; + + + /*---------------------------------------------------* + * Vbsz2 : Vbs for dVth + *-----------------*/ + Vbsz2 = Vbsz ; + Vbsz2_dVbs = Vbsz_dVbs ; + Vbsz2_dVds = Vbsz_dVds ; + Vbsz2_dVgs = 0.0 ; + + if ( corecip ) { + + /* ************************** */ + /* Initial value for PS0Z_SCE */ + /* ************************** */ + + T1 = dP_max + dP_max ; + + if ( flg_pprv >= 1 ) { + /* -------------------------- * + * Extrapolate previous value * + * -------------------------- */ + + T1 = here->HSM2_PS0Z_SCE_dvbs_prv * dVbs + + here->HSM2_PS0Z_SCE_dvds_prv * dVds + + here->HSM2_PS0Z_SCE_dvgs_prv * dVgs ; + + if ( fabs(T1) <= dP_max ) { + Ps0_ini = here->HSM2_PS0Z_SCE_prv + T1 ; /* take extrapolated value */ + Ps0_ini_dVds = here->HSM2_PS0Z_SCE_dvds_prv ; + Ps0_ini_dVgs = here->HSM2_PS0Z_SCE_dvgs_prv ; + Ps0_ini_dVbs = here->HSM2_PS0Z_SCE_dvbs_prv ; + } + } /* end of (flg_pprv >=1) if-block */ + + if ( fabs(T1) > dP_max) { + /* ------------------------------------- * + * Analytical initial value for PS0Z_SCE * + * ------------------------------------- */ + + + T1 = here->HSM2_2qnsub_esi ; + T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; + Vthq = Pb20 + Vfb + T2 * Cox0_inv ; + Vth = Vthq ; + + TX = 4.0e0 * ( beta * ( Vgs - Vbs ) - 1.0e0 ) / ( fac1p2 * beta2 ) ; + TX_dVds = - 2.0 * TX / fac1 * fac1_dVds ; + TX_dVgs = - 2.0 * TX / fac1 * fac1_dVgs + 4.0 * beta / ( fac1p2 * beta2 ) ; + TX_dVbs = - 2.0 * TX / fac1 * fac1_dVbs - 4.0 * beta / ( fac1p2 * beta2 ) ; + TX += 1.0 ; + if ( TX > epsm10 ) { + T3 = sqrt( TX ) ; + T3_dVd = 0.5 * TX_dVds / T3 ; + T3_dVg = 0.5 * TX_dVgs / T3 ; + T3_dVb = 0.5 * TX_dVbs / T3 ; + } else { + T3 = sqrt( epsm10 ) ; + T3_dVd = T3_dVg = T3_dVb = 0.0 ; + } + Ps0_iniA = Vgs + fac1p2 * beta * 0.5 * ( 1.0e0 - T3 ) ; + Ps0_iniA_dVds = fac1 * beta * ( 1.0 - T3 ) * fac1_dVds - fac1p2 * beta * 0.5 * T3_dVd ; + Ps0_iniA_dVgs = 1.0 + fac1 * beta * ( 1.0 - T3 ) * fac1_dVgs - fac1p2 * beta * 0.5 * T3_dVg ; + Ps0_iniA_dVbs = fac1 * beta * ( 1.0 - T3 ) * fac1_dVbs - fac1p2 * beta * 0.5 * T3_dVb ; + + Chi = beta * ( Ps0_iniA - Vbs ) ; + + if ( Chi < znbd3 ) { + /*-----------------------------------* + * zone-D1/D2 + * - Ps0_ini is the analytical solution of Qs=Qb0 with + * Qb0 being approximated to 3-degree polynomial. + *-----------------*/ + TY = beta * ( Vgs - Vbs ) ; + TY_dVds = 0.0 ; + TY_dVgs = beta ; + TY_dVbs = - beta ; + T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; + T1_dVd = - T1 / fac1 * fac1_dVds ; + T1_dVg = - T1 / fac1 * fac1_dVgs ; + T1_dVb = - T1 / fac1 * fac1_dVbs ; + T2 = 81.0 + 3.0 * T1 ; + T2_dVd = 3.0 * T1_dVd ; + T2_dVg = 3.0 * T1_dVg ; + T2_dVb = 3.0 * T1_dVb ; + T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ; + T3_dVd = ( - 81.0 + 27.0 * TY ) * T1_dVd + 27.0 * T1 * TY_dVds ; + T3_dVg = ( - 81.0 + 27.0 * TY ) * T1_dVg + 27.0 * T1 * TY_dVgs ; + T3_dVb = ( - 81.0 + 27.0 * TY ) * T1_dVb + 27.0 * T1 * TY_dVbs ; + T4 = T3 ; + T4_dVd = T3_dVd ; + T4_dVg = T3_dVg ; + T4_dVb = T3_dVb ; + T6 = sqrt( 4 * T2 * T2 * T2 + T4 * T4 ) ; + T6_dVd = ( 6.0 * T2 * T2 * T2_dVd + T4 * T4_dVd ) / T6 ; + T6_dVg = ( 6.0 * T2 * T2 * T2_dVg + T4 * T4_dVg ) / T6 ; + T6_dVb = ( 6.0 * T2 * T2 * T2_dVb + T4 * T4_dVb ) / T6 ; + T5 = Fn_Pow( T3 + T6 , C_1o3 ) ; + T5_dVd = ( T3_dVd + T6_dVd ) / ( 3.0 * T5 * T5 ) ; + T5_dVg = ( T3_dVg + T6_dVg ) / ( 3.0 * T5 * T5 ) ; + T5_dVb = ( T3_dVb + T6_dVb ) / ( 3.0 * T5 * T5 ) ; + + TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 ) + + 1 / ( 3.0 * C_2p_1o3 ) * T5 ; + TX_dVds = - C_2p_1o3 / (3.0 * T5) * T2_dVd + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVd ; + TX_dVgs = - C_2p_1o3 / (3.0 * T5) * T2_dVg + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVg ; + TX_dVbs = - C_2p_1o3 / (3.0 * T5) * T2_dVb + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVb ; + + Ps0_iniA = TX * beta_inv + Vbs ; + Ps0_iniA_dVds = TX_dVds * beta_inv ; + Ps0_iniA_dVgs = TX_dVgs * beta_inv ; + Ps0_iniA_dVbs = TX_dVbs * beta_inv + 1.0 ; + Ps0_ini = Ps0_iniA ; + Ps0_ini_dVds = Ps0_iniA_dVds ; + Ps0_ini_dVgs = Ps0_iniA_dVgs ; + Ps0_ini_dVbs = Ps0_iniA_dVbs ; + + } else if ( Vgs <= Vth ) { + /*-----------------------------------* + * Weak inversion zone. + *-----------------*/ + Ps0_ini = Ps0_iniA ; + Ps0_ini_dVds = Ps0_iniA_dVds ; + Ps0_ini_dVgs = Ps0_iniA_dVgs ; + Ps0_ini_dVbs = Ps0_iniA_dVbs ; + + } else { + /*-----------------------------------* + * Strong inversion zone. + * - Ps0_iniB : upper bound. + *-----------------*/ + T1 = 1.0 / cnst1 / cnstCoxi ; + T1_dVd = - T1 / cnstCoxi * cnstCoxi_dVd ; + T1_dVg = - T1 / cnstCoxi * cnstCoxi_dVg ; + T1_dVb = - T1 / cnstCoxi * cnstCoxi_dVb ; + T0 = Vgs - Vfb ; + T2 = T1 * T0 * T0 ; + T2_dVd = T1_dVd * T0 * T0 ; + T2_dVg = T1_dVg * T0 * T0 + 2.0 * T1 * T0 ; + T2_dVb = T1_dVb * T0 * T0 ; + T3 = beta + 2.0 / T0 ; + T3_dVg = -2.0 / (T0 * T0) ; + + Ps0_iniB = log( T2 + small ) / T3 ; + Ps0_iniB_dVds = T2_dVd / (T2 * T3) ; + Ps0_iniB_dVgs = T2_dVg / (T2 * T3) - T3_dVg * Ps0_iniB / T3 ; + Ps0_iniB_dVbs = T2_dVb / (T2 * T3) ; + + Fn_SU2( Ps0_ini , Ps0_iniA, Ps0_iniB, c_ps0ini_2, T1,T2) ; + Ps0_ini_dVds = Ps0_iniA_dVds * T1 + Ps0_iniB_dVds * T2 ; + Ps0_ini_dVgs = Ps0_iniA_dVgs * T1 + Ps0_iniB_dVgs * T2 ; + Ps0_ini_dVbs = Ps0_iniA_dVbs * T1 + Ps0_iniB_dVbs * T2 ; + } + } /* end of initial value calulation */ + + /**************************/ + + /* initial value for SCE LOOP */ + PS0_SCE = Ps0_ini ; + PS0_SCE_dVds = Ps0_ini_dVds ; + PS0_SCE_dVgs = Ps0_ini_dVgs ; + PS0_SCE_dVbs = Ps0_ini_dVbs ; + + PS0Z_SCE = Ps0_ini ; + PS0Z_SCE_dVds = Ps0_ini_dVds ; + PS0Z_SCE_dVgs = Ps0_ini_dVgs ; + PS0Z_SCE_dVbs = Ps0_ini_dVbs ; + } /* end of corecip=1 case (initial value calculation) */ + + MAX_LOOP_SCE = 5 ; + NNN = 0 ; + + /* ************************************************************************* */ + + START_OF_SCE_LOOP : /* outer loop of multi level Newton framework */ + + /* ************************************************************************* */ + + /* for multi level Newton method we need the derivatives */ + /* with respect to PS0Z_SCE */ + /* naming convention: ..._dPS0Z means d.../dPS0Z_SCE */ + + + if ( flg_qme == 1 ) { + /*---------------------------------------------------* + * Vthp : Vth with pocket. + *-----------------*/ + + if( corecip ){ + + T1 = here->HSM2_2qnsub_esi ; + Qb0 = sqrt ( T1 ) ; + Qb0_dVb = 0.0 ; + Qb0_dVd = 0.0 ; + Qb0_dVg = 0.0 ; + + Vthp = PS0Z_SCE + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr ; + Vthp_dVb = PS0Z_SCE_dVbs + Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ; + Vthp_dVd = PS0Z_SCE_dVds + Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ; + Vthp_dVg = PS0Z_SCE_dVgs + Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ; + Vthp_dPS0Z = 1.0 ; + + }else{ /* original */ + T1 = here->HSM2_2qnsub_esi ; + Qb0 = sqrt (T1 * (Pb20 - Vbsz2)) ; + T2 = 0.5 * T1 / Qb0 ; + Qb0_dVb = T2 * (- Vbsz2_dVbs) ; + Qb0_dVd = T2 * (- Vbsz2_dVds) ; + Qb0_dVg = T2 * (- Vbsz2_dVgs) ; + + Vthp = Pb20 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr; + Vthp_dVb = Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ; + Vthp_dVd = Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ; + Vthp_dVg = Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ; + } + + + Pb20b = Pb20 ; + Pb20b_dVb = 0.0 ; + Pb20b_dVd = 0.0 ; + Pb20b_dVg = 0.0 ; + + T0 = 0.95 ; + T1 = T0 * Pb20b - Vbsz2 - 1.0e-3 ; + T1_dVb = T0 * Pb20b_dVb - Vbsz2_dVbs ; + T1_dVd = T0 * Pb20b_dVd - Vbsz2_dVds ; + T1_dVg = T0 * Pb20b_dVg - Vbsz2_dVgs ; + T2 = sqrt (T1 * T1 + 4.0 * T0 * Pb20b * 1.0e-3) ; + T3 = T0 * Pb20b - 0.5 * (T1 + T2) ; + T4 = 2.0 * T0 * 1.0e-3 ; + T5 = T1 / T2 ; + T6 = T4 / T2 ; + T3_dVb = T0 * Pb20b_dVb + - 0.5 * (T1_dVb + (T1_dVb * T5 + T6 * Pb20b_dVb ) ) ; + T3_dVd = T0 * Pb20b_dVd + - 0.5 * (T1_dVd + (T1_dVd * T5 + T6 * Pb20b_dVd ) ) ; + T3_dVg = T0 * Pb20b_dVg + - 0.5 * (T1_dVg + (T1_dVg * T5 + T6 * Pb20b_dVg ) ) ; + Pbsum = Pb20b - T3 ; + Pbsum_dVb = Pb20b_dVb - T3_dVb ; + Pbsum_dVd = Pb20b_dVd - T3_dVd ; + Pbsum_dVg = Pb20b_dVg - T3_dVg ; + + sqrt_Pbsum = sqrt( Pbsum ) ; + + /*-------------------------------------------* + * dVthLP : Short-channel effect induced by pocket. + * - Vth0 : Vth without pocket. + *-----------------*/ + if ( model->HSM2_lp != 0.0 ) { + + if( corecip ){ + + T1 = here->HSM2_2qnsub_esi ; + T2 = model->HSM2_bs2 - Vbsz2 ; + T3 = T2 + small ; + T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ; + T5 = 0.5 * (T3 + T4) ; + T6 = 0.5 * (1.0 + T3 / T4) ; + T5_dVb = - Vbsz2_dVbs * T6 ; + T5_dVd = - Vbsz2_dVds * T6 ; + T5_dVg = - Vbsz2_dVgs * T6 ; + T7 = 1.0 / T5 ; + bs12 = model->HSM2_bs1 * T7 ; + T8 = - bs12 * T7 ; + bs12_dVb = T8 * T5_dVb ; + bs12_dVd = T8 * T5_dVd ; + bs12_dVg = T8 * T5_dVg ; + + T1 = 0.93 * ( PS0Z_SCE + Ps0_min - Vbsz2 ); + T1_dVb = 0.93 * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs ); + T1_dVd = 0.93 * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds ); + T1_dVg = 0.93 * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs ); + T1_dPS0Z = 0.93 ; + + T2 = bs12 ; + T2_dVb = bs12_dVb ; + T2_dVd = bs12_dVd ; + T2_dVg = bs12_dVg ; + + Fn_SU2( T10 , T2 , T1 , vth_dlt, T0, T3 ) ; + T10_dVb = T2_dVb * T0 + T1_dVb * T3 ; + T10_dVd = T2_dVd * T0 + T1_dVd * T3 ; + T10_dVg = T2_dVg * T0 + T1_dVg * T3 ; + T10_dPS0Z = T1_dPS0Z * T3 ; + + T4 = here->HSM2_2qnsub_esi * ( PS0Z_SCE + Ps0_min - Vbsz2 - T10 ) ; + T4_dVb = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs - T10_dVb ) ; + T4_dVd = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds - T10_dVd ) ; + T4_dVg = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs - T10_dVg ) ; + T4_dPS0Z = here->HSM2_2qnsub_esi * ( 1.0 - T10_dPS0Z ) ; + + if (T4 > arg2){ + Qbmm = sqrt ( T4 ) ; + Qbmm_dVb = 0.5 / Qbmm * T4_dVb ; + Qbmm_dVd = 0.5 / Qbmm * T4_dVd ; + Qbmm_dVg = 0.5 / Qbmm * T4_dVg ; + Qbmm_dPS0Z = 0.5 / Qbmm * T4_dPS0Z ; + } else { + Qbmm = sqrt(arg2) + 0.5 / sqrt(arg2) * ( T4 - arg2) ; + Qbmm_dVb = 0.5 / sqrt(arg2) * T4_dVb ; + Qbmm_dVd = 0.5 / sqrt(arg2) * T4_dVd ; + Qbmm_dVg = 0.5 / sqrt(arg2) * T4_dVg ; + Qbmm_dPS0Z = 0.5 / sqrt(arg2) * T4_dPS0Z ; + } + + dqb = ( Qb0 - Qbmm ) * Cox_inv ; + dqb_dVb = ( Qb0_dVb - Qbmm_dVb ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVb ; + dqb_dVd = ( Qb0_dVd - Qbmm_dVd ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVd ; + dqb_dVg = ( Qb0_dVg - Qbmm_dVg ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVg ; + dqb_dPS0Z = - Qbmm_dPS0Z * Cox_inv ; + + if( codqb == 0 ){ + dqb = 0.0 ; + dqb_dVb = 0.0 ; + dqb_dVd = 0.0 ; + dqb_dVg = 0.0 ; + dqb_dPS0Z = 0.0 ; + } + + T1 = 2.0 * C_QE * pParam->HSM2_nsubc * C_ESI ; + T2 = sqrt( T1 ) ; + T2_dVb = 0.0 ; + T2_dVd = 0.0 ; + T2_dVg = 0.0 ; + + Vth0 = PS0Z_SCE + Vfb + T2 * Cox_inv ; + Vth0_dVb = PS0Z_SCE_dVbs + T2_dVb * Cox_inv + T2 * Cox_inv_dVb ; + Vth0_dVd = PS0Z_SCE_dVds + T2_dVd * Cox_inv + T2 * Cox_inv_dVd ; + Vth0_dVg = PS0Z_SCE_dVgs + T2_dVg * Cox_inv + T2 * Cox_inv_dVg ; + Vth0_dPS0Z = 1.0 ; + + T1 = C_ESI * Cox_inv ; + T1_dVb = C_ESI * Cox_inv_dVb ; + T1_dVd = C_ESI * Cox_inv_dVd ; + T1_dVg = C_ESI * Cox_inv_dVg ; + T2 = here->HSM2_wdplp ; + + T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ; + T3 = 2.0 * ( model->HSM2_vbi - Pb20 ) * T2 * T4 ; + + T5 = T1 * T3 ; + T5_dVb = T1_dVb * T3 ; + T5_dVd = T1_dVd * T3 ; + T5_dVg = T1_dVg * T3 ; + + T6 = PS0Z_SCE - Vbsz ; + T6_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs ; + T6_dVd = PS0Z_SCE_dVds - Vbsz_dVds ; + T6_dVg = PS0Z_SCE_dVgs ; + T6_dPS0Z = 1.0 ; + + Fn_SZ( T6, T6, C_sce_dlt, T0 ); + T6_dVb *= T0 ; + T6_dVd *= T0 ; + T6_dVg *= T0 ; + T6_dPS0Z *= T0 ; + + dVth0 = T5 * sqrt( T6 ) ; + dVth0_dVb = T5 * 0.5 / sqrt( T6 ) * T6_dVb + T5_dVb * sqrt( T6 ); + dVth0_dVd = T5 * 0.5 / sqrt( T6 ) * T6_dVd + T5_dVd * sqrt( T6 ) ; + dVth0_dVg = T5 * 0.5 / sqrt( T6 ) * T6_dVg + T5_dVg * sqrt( T6 ) ; + dVth0_dPS0Z = T5 * 0.5 / sqrt( T6 ) * T6_dPS0Z ; + + T1 = Vthp - Vth0 ; + T1_dVb = Vthp_dVb - Vth0_dVb ; + T1_dVd = Vthp_dVd - Vth0_dVd ; + T1_dVg = Vthp_dVg - Vth0_dVg ; + T1_dPS0Z = Vthp_dPS0Z - Vth0_dPS0Z ; + + T9 = PS0Z_SCE - Vbsz2 ; + T9_dVb = PS0Z_SCE_dVbs - Vbsz2_dVbs ; + T9_dVd = PS0Z_SCE_dVds - Vbsz2_dVds ; + T9_dVg = PS0Z_SCE_dVgs - Vbsz2_dVgs ; + T9_dPS0Z = 1.0 ; + + T3 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * T9 / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz ; + T3_dVb = pParam->HSM2_scp3 * T9_dVb / model->HSM2_lp ; + T3_dVd = pParam->HSM2_scp3 * T9_dVd / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz_dVds ; + T3_dVg = pParam->HSM2_scp3 * T9_dVg / model->HSM2_lp ; + T3_dPS0Z = pParam->HSM2_scp3 * T9_dPS0Z / model->HSM2_lp ; + + Vdx = model->HSM2_scp21 + Vdsz ; + Vdx2 = Vdx * Vdx + small ; + T4 = Vdx * Vdx + small ; + T4_dVb = 0.0 ; + T4_dVd = 2.0 * Vdx * Vdsz_dVds ; + T4_dVg = 0.0 ; + + T5 = 1.0 / T4 ; + T5_dVb = - T4_dVb / T4 / T4 ; + T5_dVd = - T4_dVd / T4 / T4 ; + T5_dVg = - T4_dVg / T4 / T4 ; + + dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc * T5 ; + dVthLP_dVb = T1_dVb * dVth0 * T3 + T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb + dqb_dVb - here->HSM2_msc * T5_dVb ; + dVthLP_dVd = T1_dVd * dVth0 * T3 + T1 * dVth0_dVd * T3 + T1 * dVth0 * T3_dVd + dqb_dVd - here->HSM2_msc * T5_dVd ; + dVthLP_dVg = T1_dVg * dVth0 * T3 + T1 * dVth0_dVg * T3 + T1 * dVth0 * T3_dVg + dqb_dVg - here->HSM2_msc * T5_dVg ; + dVthLP_dPS0Z = T1_dPS0Z * dVth0 * T3 + T1 * dVth0_dPS0Z * T3 + T1 * dVth0 * T3_dPS0Z + dqb_dPS0Z ; + + }else{ /* original */ + + T1 = here->HSM2_2qnsub_esi ; + T2 = model->HSM2_bs2 - Vbsz2 ; + T3 = T2 + small ; + T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ; + T5 = 0.5 * (T3 + T4) ; + T6 = 0.5 * (1.0 + T3 / T4) ; + T5_dVb = - Vbsz2_dVbs * T6 ; + T5_dVd = - Vbsz2_dVds * T6 ; + T5_dVg = - Vbsz2_dVgs * T6 ; + T7 = 1.0 / T5 ; + bs12 = model->HSM2_bs1 * T7 ; + T8 = - bs12 * T7 ; + bs12_dVb = T8 * T5_dVb ; + bs12_dVd = T8 * T5_dVd ; + bs12_dVg = T8 * T5_dVg ; + Fn_SU( T10 , Vbsz2 + bs12, 0.93 * Pb20, vth_dlt, T0) ; + Qbmm = sqrt (T1 * (Pb20 - T10 )) ; + T9 = T0 / Qbmm ; + Qbmm_dVb = 0.5 * T1 * - (Vbsz2_dVbs + bs12_dVb) * T9 ; + Qbmm_dVd = 0.5 * T1 * - (Vbsz2_dVds + bs12_dVd) * T9 ; + Qbmm_dVg = 0.5 * T1 * - (Vbsz2_dVgs + bs12_dVg) * T9 ; + + dqb = (Qb0 - Qbmm) * Cox_inv ; + dqb_dVb = Vthp_dVb - Qbmm_dVb * Cox_inv - Qbmm * Cox_inv_dVb ; + dqb_dVd = Vthp_dVd - Qbmm_dVd * Cox_inv - Qbmm * Cox_inv_dVd ; + dqb_dVg = Vthp_dVg - Qbmm_dVg * Cox_inv - Qbmm * Cox_inv_dVg ; + + T1 = 2.0 * C_QE * pParam->HSM2_nsubc * C_ESI ; + T2 = sqrt( T1 * ( Pb2c - Vbsz2 ) ) ; + Vth0 = Pb2c + Vfb + T2 * Cox_inv ; + T3 = 0.5 * T1 / T2 * Cox_inv ; + Vth0_dVb = T3 * ( - Vbsz2_dVbs ) + T2 * Cox_inv_dVb ; + Vth0_dVd = T3 * ( - Vbsz2_dVds ) + T2 * Cox_inv_dVd ; + Vth0_dVg = T3 * ( - Vbsz2_dVgs ) + T2 * Cox_inv_dVg ; + + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdplp ; + T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ; + T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ; + dVth0 = T5 * sqrt_Pbsum ; + T6 = 0.5 * T5 / sqrt_Pbsum ; + T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ; + T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ; + dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ; + dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ; + dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ; + + T1 = Vthp - Vth0 ; + T2 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * Pbsum / model->HSM2_lp ; + T3 = T2 + pParam->HSM2_scp2 * Vdsz ; + + Vdx = model->HSM2_scp21 + Vdsz ; + Vdx2 = Vdx * Vdx + small ; + + dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc / Vdx2 ; + T4 = T1 * dVth0 * pParam->HSM2_scp3 / model->HSM2_lp ; + dVthLP_dVb = (Vthp_dVb - Vth0_dVb) * dVth0 * T3 + T1 * dVth0_dVb * T3 + + T4 * Pbsum_dVb + dqb_dVb ; + dVthLP_dVd = (Vthp_dVd - Vth0_dVd) * dVth0 * T3 + T1 * dVth0_dVd * T3 + + T4 * Pbsum_dVd + + T1 * dVth0 * pParam->HSM2_scp2 * Vdsz_dVds + + dqb_dVd + + 2.0e0 * here->HSM2_msc * Vdx * Vdsz_dVds / ( Vdx2 * Vdx2 ) ; + dVthLP_dVg = (Vthp_dVg - Vth0_dVg) * dVth0 * T3 + T1 * dVth0_dVg * T3 + + T4 * Pbsum_dVg + dqb_dVg ; + } + + } else { + dVthLP = 0.0e0 ; + dVthLP_dVb = 0.0e0 ; + dVthLP_dVd = 0.0e0 ; + dVthLP_dVg = 0.0e0 ; + } + + /*---------------------------------------------------* + * dVthSC : Short-channel effect induced by Vds. + *-----------------*/ + + if( corecip ){ + + T3 = here->HSM2_lgate - model->HSM2_parl2 ; + T4 = 1.0e0 / ( T3 * T3 ) ; + T5 = pParam->HSM2_sc3 / here->HSM2_lgate ; + + T6 = pParam->HSM2_sc1 + T5 * ( PS0Z_SCE - Vbsz ) ; + T6_dVb = T5 * ( PS0Z_SCE_dVbs - Vbsz_dVbs ); + T6_dVd = T5 * ( PS0Z_SCE_dVds - Vbsz_dVds ); + T6_dVg = T5 * PS0Z_SCE_dVgs ; + T6_dPS0Z = T5 ; + + /* QME:1 CORECIP:1 */ + if( pParam->HSM2_sc4 != 0 ){ + T8 = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE - Vbsz ) ; + T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * ( PS0Z_SCE - Vbsz ) + Vdsz * ( PS0Z_SCE_dVds - Vbsz_dVds ) ) ; + T8_dVb = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE_dVbs - Vbsz_dVbs ) ; + T8_dVg = pParam->HSM2_sc4 * Vdsz * PS0Z_SCE_dVgs ; + T8_dPS0Z = pParam->HSM2_sc4 * Vdsz ; + + T1 = T6 + pParam->HSM2_sc2 * Vdsz + T8 ; + T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ; + T1_dVb = T6_dVb + T8_dVb ; + T1_dVg = T6_dVg + T8_dVg ; + T1_dPS0Z = T6_dPS0Z + T8_dPS0Z ; + }else{ + T1 = T6 + pParam->HSM2_sc2 * Vdsz ; + T1_dVb = T6_dVb ; + T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds ; + T1_dVg = T6_dVg ; + T1_dPS0Z = T6_dPS0Z ; + } + + T0 = C_ESI * here->HSM2_wdpl * 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T4 ; + + T2 = T0 * Cox_inv ; + T2_dVb = T0 * Cox_inv_dVb ; + T2_dVd = T0 * Cox_inv_dVd ; + T2_dVg = T0 * Cox_inv_dVg ; + + A = T2 * T1 ; + A_dVbs = T2 * T1_dVb + T1 * T2_dVb ; + A_dVds = T2 * T1_dVd + T1 * T2_dVd ; + A_dVgs = T2 * T1_dVg + T1 * T2_dVg ; + A_dPS0Z = T2 * T1_dPS0Z ; + + T9 = PS0Z_SCE - Vbsz + Ps0_min ; + T9_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs + Ps0_min_dVbs ; + T9_dVd = PS0Z_SCE_dVds - Vbsz_dVds + Ps0_min_dVds ; + T9_dVg = PS0Z_SCE_dVgs + Ps0_min_dVgs ; + T9_dPS0Z = 1.0 ; + + if ( T9 > arg0 ) { + T8 = sqrt( T9 ) ; + T8_dVb = 0.5 * T9_dVb / T8 ; + T8_dVd = 0.5 * T9_dVd / T8 ; + T8_dVg = 0.5 * T9_dVg / T8 ; + T8_dPS0Z = 0.5 * T9_dPS0Z / T8 ; + } else { + T8 = sqrt(arg0) + 0.5 / sqrt(arg0) * ( T9 - arg0) ; + T8_dVb = 0.5 / sqrt(arg0) * T9_dVb ; + T8_dVd = 0.5 / sqrt(arg0) * T9_dVd ; + T8_dVg = 0.5 / sqrt(arg0) * T9_dVg ; + T8_dPS0Z = 0.5 / sqrt(arg0) * T9_dPS0Z ; + } + + dVthSC = A * T8 ; + dVthSC_dVb = A * T8_dVb + A_dVbs * T8; + dVthSC_dVd = A * T8_dVd + A_dVds * T8; + dVthSC_dVg = A * T8_dVg + A_dVgs * T8; + dVthSC_dPS0Z = A * T8_dPS0Z + A_dPS0Z * T8; + + + }else{ /* original */ + + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdpl ; + T3 = here->HSM2_lgate - model->HSM2_parl2 ; + T4 = 1.0e0 / ( T3 * T3 ) ; + T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ; + + dVth0 = T5 * sqrt_Pbsum ; + T6 = T5 / 2.0 / sqrt_Pbsum ; + T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ; + T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ; + dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ; + dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ; + dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ; + + T1 = pParam->HSM2_sc3 / here->HSM2_lgate ; + T4 = pParam->HSM2_sc1 + T1 * Pbsum ; + T4_dVb = T1 * Pbsum_dVb ; + T4_dVd = T1 * Pbsum_dVd ; + T4_dVg = T1 * Pbsum_dVg ; + + /* QME:1 CORECIP:0 */ + if( pParam->HSM2_sc4 != 0 ){ + T8 = pParam->HSM2_sc4 * Vdsz * Pbsum ; + T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * Pbsum + Vdsz * Pbsum_dVd ) ; + T8_dVb = pParam->HSM2_sc4 * Vdsz * Pbsum_dVb ; + T8_dVg = pParam->HSM2_sc4 * Vdsz * Pbsum_dVg ; + + T5 = T4 + pParam->HSM2_sc2 * Vdsz + T8 ; + T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ; + T5_dVb = T4_dVb + T8_dVb ; + T5_dVg = T4_dVg + T8_dVg ; + }else{ + T5 = T4 + pParam->HSM2_sc2 * Vdsz ; + T5_dVb = T4_dVb ; + T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds ; + T5_dVg = T4_dVg ; + } + + dVthSC = dVth0 * T5 ; + dVthSC_dVb = dVth0_dVb * T5 + dVth0 * T5_dVb ; + dVthSC_dVd = dVth0_dVd * T5 + dVth0 * T5_dVd ; + dVthSC_dVg = dVth0_dVg * T5 + dVth0 * T5_dVg ; + + } + + + /*---------------------------------------------------* + * dVthW : narrow-channel effect. + *-----------------*/ + T1 = 1.0 / Cox ; + T2 = T1 * T1 ; + T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ; + T4 = T3 * T3 ; + T5 = T1 - T3 ; + T6 = Qb0 * ( T2 - T4 ) ; + + if( corecip ){ + dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ; + dVthW_dVb = Qb0_dVb * T5 - Cox_dVb * T6 ; + dVthW_dVd = Qb0_dVd * T5 - Cox_dVd * T6 ; + dVthW_dVg = Qb0_dVg * T5 - Cox_dVg * T6 ; + }else{ /* original */ + dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ; + dVthW_dVb = Qb0_dVb * T5 - Cox_dVb * T6 ; + dVthW_dVd = Qb0_dVd * T5 - Cox_dVd * T6 ; + dVthW_dVg = - Cox_dVg * T6 ; + } + + /* end of case flg_qme = 1 */ + + } else { + + /* now case flg_qme = 0 */ + + /*---------------------------------------------------* + * Vthp : Vth with pocket. + *-----------------*/ + + if( corecip ){ + T1 = here->HSM2_2qnsub_esi ; + Qb0 = sqrt ( T1 ) ; + Qb0_dVb = 0.0 ; + Qb0_dVd = 0.0 ; + Qb0_dVg = 0.0 ; + + Vthp = PS0Z_SCE + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr; + Vthp_dVb = PS0Z_SCE_dVbs + Qb0_dVb * Cox_inv ; + Vthp_dVd = PS0Z_SCE_dVds + Qb0_dVd * Cox_inv ; + Vthp_dVg = PS0Z_SCE_dVgs + Qb0_dVg * Cox_inv ; + Vthp_dPS0Z = 1.0 ; + }else{ /* original */ + T1 = here->HSM2_2qnsub_esi ; + Qb0 = sqrt (T1 * (Pb20 - Vbsz2)) ; + T2 = 0.5 * T1 / Qb0 ; + Qb0_dVb = T2 * (- Vbsz2_dVbs) ; + Qb0_dVd = T2 * (- Vbsz2_dVds) ; + Qb0_dVg = T2 * (- Vbsz2_dVgs) ; + + Vthp = Pb20 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr; + Vthp_dVb = Qb0_dVb * Cox_inv ; + Vthp_dVd = Qb0_dVd * Cox_inv ; + Vthp_dVg = Qb0_dVg * Cox_inv ; + } + + Pb20b = Pb20 ; + Pb20b_dVb = 0.0 ; + Pb20b_dVd = 0.0 ; + Pb20b_dVg = 0.0 ; + + T0 = 0.95 ; + T1 = T0 * Pb20b - Vbsz2 - 1.0e-3 ; + T1_dVb = T0 * Pb20b_dVb - Vbsz2_dVbs ; + T1_dVd = T0 * Pb20b_dVd - Vbsz2_dVds ; + T1_dVg = T0 * Pb20b_dVg - Vbsz2_dVgs ; + T2 = sqrt (T1 * T1 + 4.0 * T0 * Pb20b * 1.0e-3) ; + T3 = T0 * Pb20b - 0.5 * (T1 + T2) ; + T4 = 2.0 * T0 * 1.0e-3 ; + T5 = T1 / T2 ; + T6 = T4 / T2 ; + T3_dVb = T0 * Pb20b_dVb + - 0.5 * (T1_dVb + (T1_dVb * T5 + T6 * Pb20b_dVb ) ) ; + T3_dVd = T0 * Pb20b_dVd + - 0.5 * (T1_dVd + (T1_dVd * T5 + T6 * Pb20b_dVd ) ) ; + T3_dVg = T0 * Pb20b_dVg + - 0.5 * (T1_dVg + (T1_dVg * T5 + T6 * Pb20b_dVg ) ) ; + Pbsum = Pb20b - T3 ; + Pbsum_dVb = Pb20b_dVb - T3_dVb ; + Pbsum_dVd = Pb20b_dVd - T3_dVd ; + Pbsum_dVg = Pb20b_dVg - T3_dVg ; + + sqrt_Pbsum = sqrt( Pbsum ) ; + + /*-------------------------------------------* + * dVthLP : Short-channel effect induced by pocket. + * - Vth0 : Vth without pocket. + *-----------------*/ + if ( model->HSM2_lp != 0.0 ) { + + if( corecip ){ + T1 = here->HSM2_2qnsub_esi ; + T2 = model->HSM2_bs2 - Vbsz2 ; + T3 = T2 + small ; + T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ; + T5 = 0.5 * (T3 + T4) ; + T6 = 0.5 * (1.0 + T3 / T4) ; + T5_dVb = - Vbsz2_dVbs * T6 ; + T5_dVd = - Vbsz2_dVds * T6 ; + T5_dVg = - Vbsz2_dVgs * T6 ; + T7 = 1.0 / T5 ; + bs12 = model->HSM2_bs1 * T7 ; + T8 = - bs12 * T7 ; + bs12_dVb = T8 * T5_dVb ; + bs12_dVd = T8 * T5_dVd ; + bs12_dVg = T8 * T5_dVg ; + + T1 = 0.93 * ( PS0Z_SCE + Ps0_min - Vbsz2 ); + T1_dVb = 0.93 * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs ); + T1_dVd = 0.93 * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds ); + T1_dVg = 0.93 * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs ); + T1_dPS0Z = 0.93 ; + + T2 = bs12 ; + T2_dVb = bs12_dVb ; + T2_dVd = bs12_dVd ; + T2_dVg = bs12_dVg ; + + Fn_SU2( T10 , T2 , T1 , vth_dlt, T0, T3 ) ; + T10_dVb = T2_dVb * T0 + T1_dVb * T3 ; + T10_dVd = T2_dVd * T0 + T1_dVd * T3 ; + T10_dVg = T2_dVg * T0 + T1_dVg * T3 ; + T10_dPS0Z = T1_dPS0Z * T3 ; + + T4 = here->HSM2_2qnsub_esi * ( PS0Z_SCE + Ps0_min - Vbsz2 - T10 ) ; + T4_dVb = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs - T10_dVb ) ; + T4_dVd = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds - T10_dVd ) ; + T4_dVg = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs - T10_dVg ) ; + T4_dPS0Z = here->HSM2_2qnsub_esi * ( 1.0 - T10_dPS0Z ) ; + + if (T4 > arg2){ + Qbmm = sqrt ( T4 ) ; + Qbmm_dVb = 0.5 / Qbmm * T4_dVb ; + Qbmm_dVd = 0.5 / Qbmm * T4_dVd ; + Qbmm_dVg = 0.5 / Qbmm * T4_dVg ; + Qbmm_dPS0Z = 0.5 / Qbmm * T4_dPS0Z ; + } else { + Qbmm = sqrt(arg2) + 0.5 / sqrt(arg2) * ( T4 - arg2) ; + Qbmm_dVb = 0.5 / sqrt(arg2) * T4_dVb ; + Qbmm_dVd = 0.5 / sqrt(arg2) * T4_dVd ; + Qbmm_dVg = 0.5 / sqrt(arg2) * T4_dVg ; + Qbmm_dPS0Z = 0.5 / sqrt(arg2) * T4_dPS0Z ; + } + + dqb = ( Qb0 - Qbmm ) * Cox_inv ; + dqb_dVb = ( Qb0_dVb - Qbmm_dVb ) * Cox_inv ; + dqb_dVd = ( Qb0_dVd - Qbmm_dVd ) * Cox_inv ; + dqb_dVg = ( Qb0_dVg - Qbmm_dVg ) * Cox_inv ; + dqb_dPS0Z = ( - Qbmm_dPS0Z ) * Cox_inv ; + + /* W/O QME PART */ + if( codqb == 0 ){ + dqb = 0 ; + dqb_dVb = 0 ; + dqb_dVd = 0 ; + dqb_dVg = 0 ; + dqb_dPS0Z = 0.0 ; + } + + T1 = 2.0 * C_QE * pParam->HSM2_nsubc * C_ESI ; + T2 = sqrt( T1 ) ; + T2_dVb = 0.0 ; + T2_dVd = 0.0 ; + T2_dVg = 0.0 ; + + Vth0 = PS0Z_SCE + Vfb + T2 * Cox_inv ; + Vth0_dVb = PS0Z_SCE_dVbs + T2_dVb * Cox_inv ; + Vth0_dVd = PS0Z_SCE_dVds + T2_dVd * Cox_inv ; + Vth0_dVg = PS0Z_SCE_dVgs + T2_dVg * Cox_inv ; + Vth0_dPS0Z = 1.0 ; + + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdplp ; + + T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ; + T5 = 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T1 * T2 * T4 ; + T5_dVb = 0.0 ; + T5_dVd = 0.0 ; + T5_dVg = 0.0 ; + + T6 = PS0Z_SCE - Vbsz ; + T6_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs ; + T6_dVd = PS0Z_SCE_dVds - Vbsz_dVds ; + T6_dVg = PS0Z_SCE_dVgs ; + T6_dPS0Z = 1.0 ; + + Fn_SZ(T6, T6, C_sce_dlt, T0 ); + T6_dVb *= T0 ; + T6_dVd *= T0 ; + T6_dVg *= T0 ; + T6_dPS0Z *= T0 ; + + dVth0 = T5 * sqrt( T6 ) ; + dVth0_dVb = T5 * 0.5 / sqrt( T6 ) * T6_dVb + T5_dVb * sqrt( T6 ); + dVth0_dVd = T5 * 0.5 / sqrt( T6 ) * T6_dVd + T5_dVd * sqrt( T6 ) ; + dVth0_dVg = T5 * 0.5 / sqrt( T6 ) * T6_dVg + T5_dVg * sqrt( T6 ) ; + dVth0_dPS0Z = T5 * 0.5 / sqrt( T6 ) * T6_dPS0Z ; + + T1 = Vthp - Vth0 ; + T1_dVb = Vthp_dVb - Vth0_dVb ; + T1_dVd = Vthp_dVd - Vth0_dVd ; + T1_dVg = Vthp_dVg - Vth0_dVg ; + T1_dPS0Z = Vthp_dPS0Z - Vth0_dPS0Z ; + + T9 = PS0Z_SCE - Vbsz2 ; + T9_dVb = PS0Z_SCE_dVbs - Vbsz2_dVbs ; + T9_dVd = PS0Z_SCE_dVds - Vbsz2_dVds ; + T9_dVg = PS0Z_SCE_dVgs - Vbsz2_dVgs ; + T9_dPS0Z = 1.0 ; + + T3 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * T9 / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz ; + T3_dVb = pParam->HSM2_scp3 * T9_dVb / model->HSM2_lp ; + T3_dVd = pParam->HSM2_scp3 * T9_dVd / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz_dVds ; + T3_dVg = pParam->HSM2_scp3 * T9_dVg / model->HSM2_lp ; + T3_dPS0Z = pParam->HSM2_scp3 * T9_dPS0Z / model->HSM2_lp ; + + Vdx = model->HSM2_scp21 + Vdsz ; + Vdx2 = Vdx * Vdx + small ; + T4 = Vdx * Vdx + small ; + T4_dVb = 0.0 ; + T4_dVd = 2.0 * Vdx * Vdsz_dVds ; + T4_dVg = 0.0 ; + + T5 = 1.0 / T4 ; + T5_dVb = - T4_dVb / T4 / T4 ; + T5_dVd = - T4_dVd / T4 / T4 ; + T5_dVg = - T4_dVg / T4 / T4 ; + + dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc * T5 ; + dVthLP_dVb = T1_dVb * dVth0 * T3 + T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb + dqb_dVb - here->HSM2_msc * T5_dVb ; + dVthLP_dVd = T1_dVd * dVth0 * T3 + T1 * dVth0_dVd * T3 + T1 * dVth0 * T3_dVd + dqb_dVd - here->HSM2_msc * T5_dVd ; + dVthLP_dVg = T1_dVg * dVth0 * T3 + T1 * dVth0_dVg * T3 + T1 * dVth0 * T3_dVg + dqb_dVg - here->HSM2_msc * T5_dVg ; + dVthLP_dPS0Z = T1_dPS0Z * dVth0 * T3 + T1 * dVth0_dPS0Z * T3 + T1 * dVth0 * T3_dPS0Z + dqb_dPS0Z ; + + }else{ /* Original */ + + T1 = here->HSM2_2qnsub_esi ; + T2 = model->HSM2_bs2 - Vbsz2 ; + T3 = T2 + small ; + T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ; + T5 = 0.5 * (T3 + T4) ; + T6 = 0.5 * (1.0 + T3 / T4) ; + T5_dVb = - Vbsz2_dVbs * T6 ; + T5_dVd = - Vbsz2_dVds * T6 ; + T5_dVg = - Vbsz2_dVgs * T6 ; + T7 = 1.0 / T5 ; + bs12 = model->HSM2_bs1 * T7 ; + T8 = - bs12 * T7 ; + bs12_dVb = T8 * T5_dVb ; + bs12_dVd = T8 * T5_dVd ; + bs12_dVg = T8 * T5_dVg ; + Fn_SU( T10 , Vbsz2 + bs12, 0.93 * Pb20, vth_dlt, T0) ; + Qbmm = sqrt (T1 * (Pb20 - T10 )) ; + + T9 = T0 / Qbmm ; + Qbmm_dVb = 0.5 * T1 * - (Vbsz2_dVbs + bs12_dVb) * T9 ; + Qbmm_dVd = 0.5 * T1 * - (Vbsz2_dVds + bs12_dVd) * T9 ; + Qbmm_dVg = 0.5 * T1 * - (Vbsz2_dVgs + bs12_dVg) * T9 ; + + dqb = (Qb0 - Qbmm) * Cox_inv ; + dqb_dVb = Vthp_dVb - Qbmm_dVb * Cox_inv ; + dqb_dVd = Vthp_dVd - Qbmm_dVd * Cox_inv ; + dqb_dVg = Vthp_dVg - Qbmm_dVg * Cox_inv ; + + T1 = 2.0 * C_QE * pParam->HSM2_nsubc * C_ESI ; + T2 = sqrt( T1 * ( Pb2c - Vbsz2 ) ) ; + Vth0 = Pb2c + Vfb + T2 * Cox_inv ; + T3 = 0.5 * T1 / T2 * Cox_inv ; + Vth0_dVb = T3 * ( - Vbsz2_dVbs ) ; + Vth0_dVd = T3 * ( - Vbsz2_dVds ) ; + Vth0_dVg = T3 * ( - Vbsz2_dVgs ) ; + + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdplp ; + + T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ; + T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ; + dVth0 = T5 * sqrt_Pbsum ; + T6 = 0.5 * T5 / sqrt_Pbsum ; + T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ; + T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ; + dVth0_dVb = T6 * Pbsum_dVb + T8 * Pb20b_dVb ; + dVth0_dVd = T6 * Pbsum_dVd + T8 * Pb20b_dVd ; + dVth0_dVg = T6 * Pbsum_dVg + T8 * Pb20b_dVg ; + + T1 = Vthp - Vth0 ; + T2 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * Pbsum / model->HSM2_lp ; + T3 = T2 + pParam->HSM2_scp2 * Vdsz ; + + Vdx = model->HSM2_scp21 + Vdsz ; + Vdx2 = Vdx * Vdx + small ; + + dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc / Vdx2 ; + T4 = T1 * dVth0 * pParam->HSM2_scp3 / model->HSM2_lp ; + dVthLP_dVb = (Vthp_dVb - Vth0_dVb) * dVth0 * T3 + T1 * dVth0_dVb * T3 + + T4 * Pbsum_dVb + dqb_dVb ; + dVthLP_dVd = (Vthp_dVd - Vth0_dVd) * dVth0 * T3 + T1 * dVth0_dVd * T3 + + T4 * Pbsum_dVd + + T1 * dVth0 * pParam->HSM2_scp2 * Vdsz_dVds + + dqb_dVd + + 2.0e0 * here->HSM2_msc * Vdx * Vdsz_dVds / ( Vdx2 * Vdx2 ) ; + dVthLP_dVg = (Vthp_dVg - Vth0_dVg) * dVth0 * T3 + T1 * dVth0_dVg * T3 + + T4 * Pbsum_dVg + dqb_dVg ; + + } + + } else { + dVthLP = 0.0e0 ; + dVthLP_dVb = 0.0e0 ; + dVthLP_dVd = 0.0e0 ; + dVthLP_dVg = 0.0e0 ; + } + + /*---------------------------------------------------* + * dVthSC : Short-channel effect induced by Vds. + *-----------------*/ + + if( corecip ){ + T3 = here->HSM2_lgate - model->HSM2_parl2 ; + T4 = 1.0e0 / ( T3 * T3 ) ; + T5 = pParam->HSM2_sc3 / here->HSM2_lgate ; + + T6 = pParam->HSM2_sc1 + T5 * ( PS0Z_SCE - Vbsz ) ; + T6_dVb = T5 * ( PS0Z_SCE_dVbs - Vbsz_dVbs ); + T6_dVd = T5 * ( PS0Z_SCE_dVds - Vbsz_dVds ); + T6_dVg = T5 * PS0Z_SCE_dVgs ; + T6_dPS0Z = T5 ; + + /* QME:0 CORECIP:1 */ + if( pParam->HSM2_sc4 != 0 ){ + T8 = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE - Vbsz ) ; + T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * ( PS0Z_SCE - Vbsz ) + Vdsz * ( PS0Z_SCE_dVds - Vbsz_dVds ) ) ; + T8_dVb = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE_dVbs - Vbsz_dVbs ) ; + T8_dVg = pParam->HSM2_sc4 * Vdsz * PS0Z_SCE_dVgs ; + T8_dPS0Z = pParam->HSM2_sc4 * Vdsz ; + + T1 = T6 + pParam->HSM2_sc2 * Vdsz + T8 ; + T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ; + T1_dVb = T6_dVb + T8_dVb ; + T1_dVg = T6_dVg + T8_dVg ; + T1_dPS0Z = T6_dPS0Z + T8_dPS0Z ; + }else{ + T1 = T6 + pParam->HSM2_sc2 * Vdsz ; + T1_dVb = T6_dVb ; + T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds ; + T1_dVg = T6_dVg ; + T1_dPS0Z = T6_dPS0Z ; + } + + T2 = C_ESI * Cox_inv * here->HSM2_wdpl * 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T4 ; + + A = T2 * T1 ; + A_dVbs = T2 * T1_dVb ; + A_dVds = T2 * T1_dVd ; + A_dVgs = T2 * T1_dVg ; + A_dPS0Z = T2 * T1_dPS0Z ; + + T7 = PS0Z_SCE - Vbsz + Ps0_min ; + T7_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs + Ps0_min_dVbs; + T7_dVd = PS0Z_SCE_dVds - Vbsz_dVds + Ps0_min_dVds ; + T7_dVg = PS0Z_SCE_dVgs + Ps0_min_dVgs ; + T7_dPS0Z = 1.0 ; + + if ( T7 > arg0 ) { + T8 = sqrt( T7 ) ; + T8_dVb = 0.5 * T7_dVb / T8 ; + T8_dVd = 0.5 * T7_dVd / T8 ; + T8_dVg = 0.5 * T7_dVg / T8 ; + T8_dPS0Z = 0.5 * T7_dPS0Z / T8 ; + } else { + T8 = sqrt(arg0) + 0.5 / sqrt(arg0) * ( T7 - arg0) ; + T8_dVb = 0.5 / sqrt(arg0) * T7_dVb ; + T8_dVd = 0.5 / sqrt(arg0) * T7_dVd ; + T8_dVg = 0.5 / sqrt(arg0) * T7_dVg ; + T8_dPS0Z = 0.5 / sqrt(arg0) * T7_dPS0Z ; + } + + dVthSC = A * T8 ; + dVthSC_dVb = A * T8_dVb + A_dVbs * T8; + dVthSC_dVd = A * T8_dVd + A_dVds * T8; + dVthSC_dVg = A * T8_dVg + A_dVgs * T8; + dVthSC_dPS0Z = A * T8_dPS0Z + A_dPS0Z * T8; + + }else{ /* original */ + + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdpl ; + T3 = here->HSM2_lgate - model->HSM2_parl2 ; + T4 = 1.0e0 / ( T3 * T3 ) ; + T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ; + + dVth0 = T5 * sqrt_Pbsum ; + T6 = T5 / 2.0 / sqrt_Pbsum ; + T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ; + T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ; + dVth0_dVb = T6 * Pbsum_dVb + T8 * Pb20b_dVb ; + dVth0_dVd = T6 * Pbsum_dVd + T8 * Pb20b_dVd ; + dVth0_dVg = T6 * Pbsum_dVg + T8 * Pb20b_dVg ; + + T1 = pParam->HSM2_sc3 / here->HSM2_lgate ; + T4 = pParam->HSM2_sc1 + T1 * Pbsum ; + T4_dVb = T1 * Pbsum_dVb ; + T4_dVd = T1 * Pbsum_dVd ; + T4_dVg = T1 * Pbsum_dVg ; + + /* QME:0 CORECIP:0 */ + if( pParam->HSM2_sc4 != 0 ){ + T8 = pParam->HSM2_sc4 * Vdsz * Pbsum ; + T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * Pbsum + Vdsz * Pbsum_dVd ) ; + T8_dVb = pParam->HSM2_sc4 * Vdsz * Pbsum_dVb ; + T8_dVg = pParam->HSM2_sc4 * Vdsz * Pbsum_dVg ; + + T5 = T4 + pParam->HSM2_sc2 * Vdsz + T8 ; + T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ; + T5_dVb = T4_dVb + T8_dVb ; + T5_dVg = T4_dVg + T8_dVg ; + }else{ + T5 = T4 + pParam->HSM2_sc2 * Vdsz ; + T5_dVb = T4_dVb ; + T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds ; + T5_dVg = T4_dVg ; + } + + dVthSC = dVth0 * T5 ; + dVthSC_dVb = dVth0_dVb * T5 + dVth0 * T5_dVb ; + dVthSC_dVd = dVth0_dVd * T5 + dVth0 * T5_dVd ; + dVthSC_dVg = dVth0_dVg * T5 + dVth0 * T5_dVg ; + + } + + /*---------------------------------------------------* + * dVthW : narrow-channel effect. + *-----------------*/ + T1 = 1.0 / Cox ; + T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ; + T5 = T1 - T3 ; + + if( corecip ){ + dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ; + dVthW_dVb = Qb0_dVb * T5 ; + dVthW_dVd = Qb0_dVd * T5 ; + dVthW_dVg = Qb0_dVg * T5 ; + }else{ /* original */ + dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ; + dVthW_dVb = Qb0_dVb * T5 ; + dVthW_dVd = Qb0_dVd * T5 ; + dVthW_dVg = 0.0 ; + } + + + + } /* end of flg_qme if-blocks */ + + /*---------------------------------------------------* + * dVth : Total variation. + * - Positive dVth means the decrease in Vth. + *-----------------*/ + dVth = dVthSC + dVthLP + dVthW + here->HSM2_dVthsm ; + dVth_dVb = dVthSC_dVb + dVthLP_dVb + dVthW_dVb ; + dVth_dVd = dVthSC_dVd + dVthLP_dVd + dVthW_dVd ; + dVth_dVg = dVthSC_dVg + dVthLP_dVg + dVthW_dVg ; + dVth_dPS0Z = dVthSC_dPS0Z + dVthLP_dPS0Z ; + + /*---------------------------------------------------* + * Vth : Threshold voltage. + *-----------------*/ + Vth = Vthq - dVth ; + + /*-----------------------------------------------------------* + * Constants in the equation of Ps0 . + *-----------------*/ + + fac1 = cnst0 * Cox_inv ; + fac1_dVbs = cnst0 * Cox_inv_dVb ; + fac1_dVds = cnst0 * Cox_inv_dVd ; + fac1_dVgs = cnst0 * Cox_inv_dVg ; + + fac1p2 = fac1 * fac1 ; + /*---------------------------------------------------* + * Poly-Depletion Effect + *-----------------*/ + + if ( here->HSM2_flg_pgd == 0 ) { + dPpg = 0.0 ; + dPpg_dVb = 0.0 ; + dPpg_dVd = 0.0 ; + dPpg_dVg = 0.0 ; + } else { + + T7 = Vgsz ; + T7_dVb = 0.0 ; + T7_dVd = Vgsz_dVds ; + T7_dVg = Vgsz_dVgs ; + + T0 = here->HSM2_cnstpgd ; + + T3 = T7 - model->HSM2_pgd2 ; + T3_dVb = T7_dVb ; + T3_dVd = T7_dVd ; + T3_dVg = T7_dVg ; + + Fn_ExpLim( dPpg , T3 , T6 ) ; + dPpg_dVb = T6 * T3_dVb ; + dPpg_dVd = T6 * T3_dVd ; + dPpg_dVg = T6 * T3_dVg ; + + Fn_SZ( dPpg , dPpg - 1.0 , 0.1 , T6 ) ; + dPpg_dVb *= T6 ; + dPpg_dVd *= T6 ; + dPpg_dVg *= T6 ; + + dPpg *= T0 ; + dPpg_dVb *= T0 ; + dPpg_dVd *= T0 ; + dPpg_dVg *= T0 ; + + Fn_SU( dPpg , dPpg , pol_b , pol_dlt , T9 ) ; + dPpg_dVb *= T9 ; + dPpg_dVd *= T9 ; + dPpg_dVg *= T9 ; + + } + + /*---------------------------------------------------* + * Vgp : Effective gate bias with SCE & RSCE & flatband. + *-----------------*/ + Vgp = Vgs - Vfb + dVth - dPpg ; + Vgp_dVbs = dVth_dVb - dPpg_dVb ; + Vgp_dVds = dVth_dVd - dPpg_dVd ; + Vgp_dVgs = 1.0e0 + dVth_dVg - dPpg_dVg ; + Vgp_dPS0Z = dVth_dPS0Z ; + + Vgpz = Vgsz - Vfb + dVth - dPpg ; /* (tmp) */ + Vgpz_dVbs = dVth_dVb ; + Vgpz_dVds = Vgsz_dVds + dVth_dVd - dPpg_dVd ; + Vgpz_dVgs = Vgsz_dVgs + dVth_dVg - dPpg_dVg ; + Vgpz_dPS0Z = dVth_dPS0Z ; + + /*---------------------------------------------------* + * Vgs_fb : Actual flatband voltage taking account Vbs. + * - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . + *------------------*/ + Vgs_fb = Vfb - dVth + dPpg + Vbs ; + + + /*---------------------------------------------------* + * Vfbsft : Vfb shift + *-----------------*/ + Vfbsft = 0.0 ; + Vfbsft_dVbs = 0.0 ; + Vfbsft_dVds = 0.0 ; + Vfbsft_dVgs = 0.0 ; + Vfbsft_dPS0Z = 0.0 ; + + if ( Vbs > 0.0 ) { + /* values at D2/D3 boundary + beta */ + /* Ps0 */ + T1 = Vbs + ( znbd5 + 1 ) * beta_inv ; + /* Qb0 */ + /* T2 = cnst0 * sqrt( znbd5 ) */ + T2 = cnst0 * 2.23606797749979 ; + + /* Vgp assuming Qn0=0 */ + T3 = T2 * Cox_inv + T1 ; + + /* Vgp difference */ + TX = T3 - Vgp ; + TX_dVbs = 1.0 - Vgp_dVbs ; + TX_dVds = - Vgp_dVds ; + TX_dVgs = - Vgp_dVgs ; + TX_dPS0Z = - Vgp_dPS0Z ; + + /* set lower limit to 0 */ + Fn_SZ( TX , TX , 0.1 , T4 ) ; + TX_dVbs *= T4 ; + TX_dVds *= T4 ; + TX_dVgs *= T4 ; + TX_dPS0Z *= T4 ; + + /* TY: damping factor */ + T1 = 0.5 ; + T5 = Vbs / T1 ; + T5_dVb = 1.0 / T1 ; + T6 = T5 * T5 ; + T6 *= T6 ; + T6_dVb = 4 * T5 * T5 * T5 * T5_dVb ; + T7 = 1.0 / ( 1.0 + T6 ) ; + T8 = T7 * T7 ; + TY = 1.0 - T7 ; + TY_dVbs = T8 * T6_dVb ; + + TX = TY = 0.0 ; + TX_dVbs = TX_dVds = TX_dVgs = TX_dPS0Z = TY_dVbs = 0.0 ; + + Vfbsft = TX * TY ; + Vfbsft_dVbs = TX_dVbs * TY + TX * TY_dVbs ; + Vfbsft_dVds = TX_dVds * TY ; + Vfbsft_dVgs = TX_dVgs * TY ; + Vfbsft_dPS0Z = TX_dPS0Z * TY ; + Vgs_fb -= Vfbsft ; + + Vgp += Vfbsft ; + Vgp_dVbs += Vfbsft_dVbs ; + Vgp_dVds += Vfbsft_dVds ; + Vgp_dVgs += Vfbsft_dVgs ; + Vgp_dPS0Z += Vfbsft_dPS0Z ; + + Vgpz += Vfbsft ; + Vgpz_dVbs += Vfbsft_dVbs ; + Vgpz_dVds += Vfbsft_dVds ; + Vgpz_dVgs += Vfbsft_dVgs ; + Vgpz_dPS0Z += Vfbsft_dPS0Z ; + } + + /*-----------------------------------------------------------* + * Accumulation zone. (zone-A) + * - evaluate basic characteristics and exit from this part. + *-----------------*/ + if ( Vgs < Vgs_fb ) { + + flg_zone = -1 ; + + /*---------------------------------------------------* + * Evaluation of Ps0. + * - Psa : Analytical solution of + * Cox( Vgp - Psa ) = cnst0 * Qacc + * where Qacc is the 3-degree series of (fdep)^{1/2}. + * The unkown is transformed to Chi=beta(Ps0-Vbs). + * - Ps0_min : |Ps0_min| when Vbs=0. + *-----------------*/ + + /* Ps0_min = here->HSM2_eg - Pb2 ; */ + /* -> replaced by approx. solving Poisson equation at Vgs=Vgs_min */ + /* Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ; already done above */ + + TX = beta * ( Vgp - Vbs ) ; + TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; + TX_dVds = beta * Vgp_dVds ; + TX_dVgs = beta * Vgp_dVgs ; + TX_dPS0Z = beta * Vgp_dPS0Z ; + + T1 = 1.0 / ( beta * cnst0 ) ; + TY = T1 * Cox ; + TY_dVbs = T1 * Cox_dVb ; + TY_dVds = T1 * Cox_dVd ; + TY_dVgs = T1 * Cox_dVg ; + + Ac41 = 2.0 + 3.0 * C_SQRT_2 * TY ; + + Ac4 = 8.0 * Ac41 * Ac41 * Ac41 ; + T1 = 72.0 * Ac41 * Ac41 * C_SQRT_2 ; + Ac4_dVbs = T1 * TY_dVbs ; + Ac4_dVds = T1 * TY_dVds ; + Ac4_dVgs = T1 * TY_dVgs ; + + T4 = ( TX - 2.0 ) ; + T5 = 9.0 * TY * T4 ; + T5_dVb = 9.0 * ( TY_dVbs * T4 + TY * TX_dVbs ) ; + T5_dVd = 9.0 * ( TY_dVds * T4 + TY * TX_dVds ) ; + T5_dVg = 9.0 * ( TY_dVgs * T4 + TY * TX_dVgs ) ; + T5_dPS0Z = 9.0 * ( TY * TX_dPS0Z ) ; + + Ac31 = 7.0 * C_SQRT_2 - T5 ; + Ac31_dVbs = -T5_dVb ; + Ac31_dVds = -T5_dVd ; + Ac31_dVgs = -T5_dVg ; + Ac31_dPS0Z = -T5_dPS0Z ; + + Ac3 = Ac31 * Ac31 ; + T1 = 2.0 * Ac31 ; + Ac3_dVbs = T1 * Ac31_dVbs ; + Ac3_dVds = T1 * Ac31_dVds ; + Ac3_dVgs = T1 * Ac31_dVgs ; + Ac3_dPS0Z = T1 * Ac31_dPS0Z ; + + Ac2 = sqrt( Ac4 + Ac3 ) ; + T1 = 0.5 / Ac2 ; + Ac2_dVbs = T1 * ( Ac4_dVbs + Ac3_dVbs ) ; + Ac2_dVds = T1 * ( Ac4_dVds + Ac3_dVds ) ; + Ac2_dVgs = T1 * ( Ac4_dVgs + Ac3_dVgs ) ; + Ac2_dPS0Z = T1 * ( Ac3_dPS0Z ) ; + + Ac1 = -7.0 * C_SQRT_2 + Ac2 + T5 ; + Ac1_dVbs = Ac2_dVbs + T5_dVb ; + Ac1_dVds = Ac2_dVds + T5_dVd ; + Ac1_dVgs = Ac2_dVgs + T5_dVg ; + Ac1_dPS0Z = Ac2_dPS0Z + T5_dPS0Z ; + + Acd = Fn_Pow( Ac1 , C_1o3 ) ; + T1 = C_1o3 / ( Acd * Acd ) ; + Acd_dVbs = Ac1_dVbs * T1 ; + Acd_dVds = Ac1_dVds * T1 ; + Acd_dVgs = Ac1_dVgs * T1 ; + Acd_dPS0Z = Ac1_dPS0Z * T1 ; + + Acn = -4.0 * C_SQRT_2 - 12.0 * TY + 2.0 * Acd + C_SQRT_2 * Acd * Acd ; + T1 = 2.0 + 2.0 * C_SQRT_2 * Acd ; + Acn_dVbs = - 12.0 * TY_dVbs + T1 * Acd_dVbs ; + Acn_dVds = - 12.0 * TY_dVds + T1 * Acd_dVds ; + Acn_dVgs = - 12.0 * TY_dVgs + T1 * Acd_dVgs ; + Acn_dPS0Z = T1 * Acd_dPS0Z ; + + T1 = 1.0 / Acd ; + Chi = Acn * T1 ; + Chi_dVbs = ( Acn_dVbs - Chi * Acd_dVbs ) * T1 ; + Chi_dVds = ( Acn_dVds - Chi * Acd_dVds ) * T1 ; + Chi_dVgs = ( Acn_dVgs - Chi * Acd_dVgs ) * T1 ; + Chi_dPS0Z = ( Acn_dPS0Z - Chi * Acd_dPS0Z ) * T1 ; + + Psa = Chi * beta_inv + Vbs ; + Psa_dVbs = Chi_dVbs * beta_inv + 1.0 ; + Psa_dVds = Chi_dVds * beta_inv ; + Psa_dVgs = Chi_dVgs * beta_inv ; + Psa_dPS0Z = Chi_dPS0Z * beta_inv ; + + T1 = Psa - Vbs ; + T2 = T1 / Ps0_min ; + T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; + + T9 = T2 / T3 / Ps0_min ; + T3_dVb = T9 * ( Psa_dVbs - 1.0 ) ; + T3_dVd = T9 * ( Psa_dVds ) ; + T3_dVg = T9 * ( Psa_dVgs ) ; + T3_dPS0Z = T9 * ( Psa_dPS0Z ) ; + + Ps0 = T1 / T3 + Vbs ; + T9 = 1.0 / ( T3 * T3 ) ; + Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVb ) + 1.0 ; + Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVd ) ; + Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVg ) ; + Ps0_dPS0Z = T9 * ( Psa_dPS0Z * T3 - T1 * T3_dPS0Z ) ; + + /*---------------------------------------------------* + * Characteristics. + *-----------------*/ + Psl = Ps0 ; + Psl_dVbs = Ps0_dVbs ; + Psl_dVds = Ps0_dVds ; + Psl_dVgs = Ps0_dVgs ; + + T2 = ( Vgp - Ps0 ) ; + Qbu = Cox * T2 ; + Qbu_dVbs = Cox * ( Vgp_dVbs - Ps0_dVbs ) + Cox_dVb * T2 ; + Qbu_dVds = Cox * ( Vgp_dVds - Ps0_dVds ) + Cox_dVd * T2 ; + Qbu_dVgs = Cox * ( Vgp_dVgs - Ps0_dVgs ) + Cox_dVg * T2 ; + + Qiu = 0.0e0 ; + Qiu_dVbs = 0.0e0 ; + Qiu_dVds = 0.0e0 ; + Qiu_dVgs = 0.0e0 ; + + Qdrat = 0.5e0 ; + Qdrat_dVbs = 0.0e0 ; + Qdrat_dVds = 0.0e0 ; + Qdrat_dVgs = 0.0e0 ; + + Lred = 0.0e0 ; + Lred_dVbs = 0.0e0 ; + Lred_dVds = 0.0e0 ; + Lred_dVgs = 0.0e0 ; + + Ids = 0.0e0 ; + Ids_dVbs = 0.0e0 ; + Ids_dVds = 0.0e0 ; + Ids_dVgs = 0.0e0 ; + + VgVt = 0.0 ; + + flg_noqi = 1 ; + + DJI = 1.0 ; + + if( corecip ){ + /*!! This is for Accumulation Region !!*/ + + T1 = Vds * 0.5 ; + Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ; + T2 /= 2 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = T2 * ( 1.0 ) ; + Pzadd_dVgs = 0.0 ; + Pzadd_dPS0Z = 0.0 ; + + if ( Pzadd < epsm10 ) { + Pzadd = epsm10 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = 0.0 ; + Pzadd_dVgs = 0.0 ; + Pzadd_dPS0Z = 0.0 ; + } + + Ps0z = Ps0 + Pzadd ; + Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ; + Ps0z_dVds = Ps0_dVds + Pzadd_dVds ; + Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ; + Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ; + + /* calculate Newton correction: */ + G = PS0Z_SCE - Ps0z ; + delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ; + + delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs; + delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds; + delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs; + PS0Z_SCE += delta_PS0Z_SCE ; + PS0Z_SCE_dVbs = Ps0z_dVbs ; + PS0Z_SCE_dVds = Ps0z_dVds ; + PS0Z_SCE_dVgs = Ps0z_dVgs ; + + PS0_SCE = PS0Z_SCE - Pzadd ; + PS0_SCE_dVbs = Ps0_dVbs ; + PS0_SCE_dVds = Ps0_dVds ; + PS0_SCE_dVgs = Ps0_dVgs ; + + NNN += 1 ; + + if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol + || fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol + ) && (NNN < MAX_LOOP_SCE) ){ + goto START_OF_SCE_LOOP; + } + } + + goto end_of_part_1 ; + } + + + /*-----------------------------------------------------------* + * Initial guess for Ps0. + *-----------------*/ + + /*---------------------------------------------------* + * Ps0_iniA: solution of subthreshold equation assuming zone-D1/D2. + *-----------------*/ + TX = 1.0e0 + 4.0e0 + * ( beta * ( Vgp - Vbs ) - 1.0e0 ) / ( fac1p2 * beta2 ) ; + TX = Fn_Max( TX , epsm10 ) ; + Ps0_iniA = Vgp + fac1p2 * beta * 0.5 * ( 1.0e0 - sqrt( TX ) ) ; + + /* use analitical value in subthreshold region. */ + if ( Vgs < ( Vfb + Vth ) * 0.5 ) { + flg_pprv = 0 ; + } + + if ( flg_pprv >= 1 ) { + /*---------------------------------------------------* + * Use previous value. + *-----------------*/ + + T1 = Ps0_dVbs * dVbs + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; + Ps0_ini = Ps0 + T1 ; + + if ( flg_pprv == 2 ) { + /* TX_dVxs = d^2 Ps0 / d Vxs^2 here */ + if ( Vbsc_dif2 > epsm10 ) { + TX_dVbs = ( here->HSM2_ps0_dvbs_prv - here->HSM2_ps0_dvbs_prv2 ) + / Vbsc_dif2 ; + } else { + TX_dVbs = 0.0 ; + } + if ( Vdsc_dif2 > epsm10 ) { + TX_dVds = ( here->HSM2_ps0_dvds_prv - here->HSM2_ps0_dvds_prv2 ) + / Vdsc_dif2 ; + } else { + TX_dVds = 0.0 ; + } + if ( Vgsc_dif2 > epsm10 ) { + TX_dVgs = ( here->HSM2_ps0_dvgs_prv - here->HSM2_ps0_dvgs_prv2 ) + / Vgsc_dif2 ; + } else { + TX_dVgs = 0.0 ; + } + T2 = ( dVbs * dVbs ) / 2 * TX_dVbs + + ( dVds * dVds ) / 2 * TX_dVds + + ( dVgs * dVgs ) / 2 * TX_dVgs ; + + if ( fabs( T2 ) < fabs( 0.5 * T1 ) ) { + Ps0_ini += T2 ; + } else { + flg_pprv = 1 ; + } + } + + T1 = Ps0_ini - Ps0 ; + if ( T1 < - dP_max || T1 > dP_max ) { + flg_pprv = 0 ; /* flag changes to analitical */ + } else { + Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; + } + } /* end of (flg_pprv >=1) if-block */ + + if ( flg_pprv == 0 ) { + + /*---------------------------------------------------* + * Analytical initial guess. + *-----------------*/ + /*-------------------------------------------* + * Common part. + *-----------------*/ + Chi = beta * ( Ps0_iniA - Vbs ) ; + + if ( Chi < znbd3 ) { + /*-----------------------------------* + * zone-D1/D2 + * - Ps0_ini is the analytical solution of Qs=Qb0 with + * Qb0 being approximated to 3-degree polynomial. + *-----------------*/ + TY = beta * ( Vgp - Vbs ) ; + T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; + T2 = 81.0 + 3.0 * T1 ; + T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ; + T4 = 1458.0 - 81.0 * ( 54.0 + T1 ) + 27.0 * T1 * TY ; + T4 = T4 * T4 ; + T5 = Fn_Pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; + TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 ) + + 1 / ( 3.0 * C_2p_1o3 ) * T5 ; + + Ps0_iniA = TX * beta_inv + Vbs ; + Ps0_ini = Ps0_iniA ; + + } else if ( Vgs <= Vth ) { + /*-----------------------------------* + * Weak inversion zone. + *-----------------*/ + Ps0_ini = Ps0_iniA ; + + } else { + /*-----------------------------------* + * Strong inversion zone. + * - Ps0_iniB : upper bound. + *-----------------*/ + T1 = 1.0 / cnst1 / cnstCoxi ; + T2 = T1 * Vgp * Vgp ; + T3 = beta + 2.0 / Vgp ; + + Ps0_iniB = log( T2 + small ) / T3 ; + + Fn_SU( Ps0_ini , Ps0_iniA, Ps0_iniB, c_ps0ini_2, T1) ; + } + } + + TX = Vbs + ps_conv / 2 ; + if ( Ps0_ini < TX ) Ps0_ini = TX ; + + + /*---------------------------------------------------* + * Assign initial guess. + *-----------------*/ + if ( NNN == 0 ) { + Ps0 = Ps0_ini ; + } + Psl_lim = Ps0_iniA ; + + /*---------------------------------------------------* + * Calculation of Ps0. (beginning of Newton loop) + * - Fs0 : Fs0 = 0 is the equation to be solved. + * - dPs0 : correction value. + *-----------------*/ + exp_bVbs = exp( beta * Vbs ) ; + cfs1 = cnst1 * exp_bVbs ; + + flg_conv = 0 ; + for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max + 1 ; lp_s0 ++ ) { + + Chi = beta * ( Ps0 - Vbs ) ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D1/D2. (Ps0) + * - Qb0 is approximated to 5-degree polynomial. + *-----------------*/ + fi = Chi * Chi * Chi + * ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ; + fi_dChi = Chi * Chi + * ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ; + + fs01 = cfs1 * fi * fi ; + fs01_dPs0 = cfs1 * beta * 2 * fi * fi_dChi ; + + fb = Chi * ( cn_nc51 + + Chi * ( cn_nc52 + + Chi * ( cn_nc53 + + Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ; + fb_dChi = cn_nc51 + + Chi * ( 2 * cn_nc52 + + Chi * ( 3 * cn_nc53 + + Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ; + + fs02 = sqrt( fb * fb + fs01 ) ; + fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) / ( fs02 + fs02 ) ; + + } else { + /*-------------------------------------------* + * zone-D3. (Ps0) + *-----------------*/ + exp_Chi = exp( Chi ) ; + fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; + fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; + fs02 = sqrt( Chi - 1.0 + fs01 ) ; + fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; + } /* end of if ( Chi ... ) else block */ + + Fs0 = Vgp - Ps0 - fac1 * fs02 ; + Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; + + if ( flg_conv == 1 ) break ; + + dPs0 = - Fs0 / Fs0_dPs0 ; + + /*-------------------------------------------* + * Update Ps0 . + * - clamped to Vbs if Ps0 < Vbs . + *-----------------*/ + dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Ps0))) ; + if ( fabs( dPs0 ) > dPlim ) dPs0 = dPlim * Fn_Sgn( dPs0 ) ; + + Ps0 = Ps0 + dPs0 ; + + TX = Vbs + ps_conv / 2 ; + if ( Ps0 < TX ) Ps0 = TX ; + + /*-------------------------------------------* + * Check convergence. + * NOTE: This condition may be too rigid. + *-----------------*/ + if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { + flg_conv = 1 ; + } + + } /* end of Ps0 Newton loop */ + + /* Eliminate loop count to take account of the derivative loop */ + lp_s0 -- ; + + /*-------------------------------------------* + * Procedure for diverged case. + *-----------------*/ + if ( flg_conv == 0 ) { + fprintf( stderr , + "*** warning(HiSIM): Went Over Iteration Maximum (Ps0)\n" ) ; + fprintf( stderr , + " Vbse = %7.3f Vdse = %7.3f Vgse = %7.3f\n" , + Vbse , Vdse , Vgse ) ; + if ( flg_info >= 2 ) { + printf( "*** warning(HiSIM): Went Over Iteration Maximum (Ps0)\n" ) ; + } + } + + /*---------------------------------------------------* + * Evaluate derivatives of Ps0. + * - note: Here, fs01_dVbs and fs02_dVbs are derivatives + * w.r.t. explicit Vbs. So, Ps0 in the fs01 and fs02 + * expressions is regarded as a constant. + *-----------------*/ + + /* derivatives of fs0* w.r.t. explicit Vbs */ + if ( Chi < znbd5 ) { + fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; + T2 = 1.0e0 / ( fs02 + fs02 ) ; + fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) * T2 ; + } else { + fs01_dVbs = - cfs1 * beta ; + T2 = 0.5e0 / fs02 ; + fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; + } + + T1 = 1.0 / Fs0_dPs0 ; + Ps0_dVbs = - ( Vgp_dVbs - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) ) * T1 ; + Ps0_dVds = - ( Vgp_dVds - fac1_dVds * fs02 ) * T1 ; + Ps0_dVgs = - ( Vgp_dVgs - fac1_dVgs * fs02 ) * T1 ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D1/D2. (Ps0) + * Xi0 := fdep0^2 = fb * fb [D1,D2] + *-----------------*/ + Xi0 = fb * fb + epsm10 ; + T1 = 2 * fb * fb_dChi * beta ; + Xi0_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ; + Xi0_dVds = T1 * Ps0_dVds ; + Xi0_dVgs = T1 * Ps0_dVgs ; + + Xi0p12 = fb + epsm10 ; + T1 = fb_dChi * beta ; + Xi0p12_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ; + Xi0p12_dVds = T1 * Ps0_dVds ; + Xi0p12_dVgs = T1 * Ps0_dVgs ; + + Xi0p32 = fb * fb * fb + epsm10 ; + T1 = 3 * fb * fb * fb_dChi * beta ; + Xi0p32_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ; + Xi0p32_dVds = T1 * Ps0_dVds ; + Xi0p32_dVgs = T1 * Ps0_dVgs ; + + } else { + /*-------------------------------------------* + * zone-D3. (Ps0) + *-----------------*/ + flg_zone = 3 ; + flg_noqi = 0 ; + + /*-----------------------------------* + * Xi0 := fdep0^2 = Chi - 1 = beta * ( Ps0 - Vbs ) - 1 [D3] + *-----------------*/ + Xi0 = Chi - 1.0e0 ; + Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; + Xi0_dVds = beta * Ps0_dVds ; + Xi0_dVgs = beta * Ps0_dVgs ; + + Xi0p12 = sqrt( Xi0 ) ; + T1 = 0.5e0 / Xi0p12 ; + Xi0p12_dVbs = T1 * Xi0_dVbs ; + Xi0p12_dVds = T1 * Xi0_dVds ; + Xi0p12_dVgs = T1 * Xi0_dVgs ; + + Xi0p32 = Xi0 * Xi0p12 ; + T1 = 1.5e0 * Xi0p12 ; + Xi0p32_dVbs = T1 * Xi0_dVbs ; + Xi0p32_dVds = T1 * Xi0_dVds ; + Xi0p32_dVgs = T1 * Xi0_dVgs ; + + } /* end of if ( Chi ... ) block */ + + /*-----------------------------------------------------------* + * - Recalculate the derivatives of fs01 and fs02. + * note: fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; + * fs02 = sqrt( Xi0 + fs01 ) ; + *-----------------*/ + fs01_dVbs = Ps0_dVbs * fs01_dPs0 + fs01_dVbs ; + fs01_dVds = Ps0_dVds * fs01_dPs0 ; + fs01_dVgs = Ps0_dVgs * fs01_dPs0 ; + fs02_dVbs = Ps0_dVbs * fs02_dPs0 + fs02_dVbs ; + fs02_dVds = Ps0_dVds * fs02_dPs0 ; + fs02_dVgs = Ps0_dVgs * fs02_dPs0 ; + + /*-----------------------------------------------------------* + * Qb0 : Qb at source side. + * Qn0 : Qi at source side. + *-----------------*/ + + Qb0 = cnst0 * Xi0p12 ; + Qb0_dVb = cnst0 * Xi0p12_dVbs ; + Qb0_dVd = cnst0 * Xi0p12_dVds ; + Qb0_dVg = cnst0 * Xi0p12_dVgs ; + + T1 = 1.0 / ( fs02 + Xi0p12 ) ; + Qn0 = cnst0 * fs01 * T1 ; + + T2 = 1.0 / ( fs01 + epsm10 ) ; + + Qn0_dVbs = Qn0 * ( fs01_dVbs * T2 - ( fs02_dVbs + Xi0p12_dVbs ) * T1 ) ; + Qn0_dVds = Qn0 * ( fs01_dVds * T2 - ( fs02_dVds + Xi0p12_dVds ) * T1 ) ; + Qn0_dVgs = Qn0 * ( fs01_dVgs * T2 - ( fs02_dVgs + Xi0p12_dVgs ) * T1 ) ; + + + /*-----------------------------------------------------------* + * zone-D1 and D2 + *-----------------*/ + if ( Chi < znbd5 ) { + if ( Chi < znbd3 ) { + /*-------------------------------------------* + * zone-D1. (Ps0) + *-----------------*/ + flg_zone = 1 ; + flg_noqi = 1 ; /** !! to be revisited !! **/ + + Qiu = Qn0 ; + Qiu_dVbs = Qn0_dVbs ; + Qiu_dVds = Qn0_dVds ; + Qiu_dVgs = Qn0_dVgs ; + + Qbu = Qb0 ; + Qbu_dVbs = Qb0_dVb ; + Qbu_dVds = Qb0_dVd ; + Qbu_dVgs = Qb0_dVg ; + + Qdrat = 0.5 ; + Qdrat_dVbs = 0.0 ; + Qdrat_dVds = 0.0 ; + Qdrat_dVgs = 0.0 ; + + Lred = 0.0e0 ; + Lred_dVbs = 0.0e0 ; + Lred_dVds = 0.0e0 ; + Lred_dVgs = 0.0e0 ; + + } else { + /*-------------------------------------------* + * zone-D2 (Ps0) + *-----------------*/ + flg_zone = 2 ; + flg_noqi = 0 ; + /*-----------------------------------------------------------* + * FD2 : connecting function for zone-D2. + * - Qiu, Qbu, Qdrat and Lred should be interpolated later. + *-----------------*/ + T1 = 1.0 / ( znbd5 - znbd3 ) ; + TX = T1 * ( Chi - znbd3 ) ; + TX_dVbs = beta * T1 * ( Ps0_dVbs - 1.0 ) ; + TX_dVds = beta * T1 * Ps0_dVds ; + TX_dVgs = beta * T1 * Ps0_dVgs ; + + FD2 = TX * TX * TX * ( 10.0 + TX * ( -15.0 + TX * 6.0 ) ) ; + T4 = TX * TX * ( 30.0 + TX * ( -60.0 + TX * 30.0 ) ) ; + + FD2_dVbs = T4 * TX_dVbs ; + FD2_dVds = T4 * TX_dVds ; + FD2_dVgs = T4 * TX_dVgs ; + } /* end of zone-D2 */ + } + + + /*---------------------------------------------------* + * VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) + *-----------------*/ + VgVt = Qn0 * Cox_inv ; + VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVb ; + VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVd ; + VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVg ; + + /*-----------------------------------------------------------* + * make Qi=Qd=Ids=0 if VgVt <= VgVt_small + *-----------------*/ + if ( VgVt <= VgVt_small && model->HSM2_bypass_enable ) { + flg_zone = 4 ; + flg_noqi = 1 ; + + Psl = Ps0 ; + Psl_dVbs = Ps0_dVbs ; + Psl_dVds = Ps0_dVds ; + Psl_dVgs = Ps0_dVgs ; + + + Pds = 0.0 ; + Pds_dVbs = 0.0 ; + Pds_dVds = 0.0 ; + Pds_dVgs = 0.0 ; + + Qbu = Qb0 ; + Qbu_dVbs = Qb0_dVb ; + Qbu_dVds = Qb0_dVd ; + Qbu_dVgs = Qb0_dVg ; + + Qiu = 0.0 ; + Qiu_dVbs = 0.0 ; + Qiu_dVds = 0.0 ; + Qiu_dVgs = 0.0 ; + + Qdrat = 0.5 ; + Qdrat_dVbs = 0.0 ; + Qdrat_dVds = 0.0 ; + Qdrat_dVgs = 0.0 ; + + Lred = 0.0 ; + Lred_dVbs = 0.0 ; + Lred_dVds = 0.0 ; + Lred_dVgs = 0.0 ; + + Ids = 0.0e0 ; + Ids_dVbs = 0.0e0 ; + Ids_dVds = 0.0e0 ; + Ids_dVgs = 0.0e0 ; + + DJI = 1.0 ; + + + if( corecip ){ + + Fs0_dPS0Z = Vgp_dPS0Z ; + Ps0_dPS0Z = - Fs0_dPS0Z / Fs0_dPs0 ; + + T1 = Vds * 0.5 ; + Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ; + T2 /= 2 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = T2 * ( 1.0 ) ; + Pzadd_dVgs = 0.0 ; + Pzadd_dPS0Z = 0.0 ; + if ( Pzadd < epsm10 ) { + Pzadd = epsm10 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = 0.0 ; + Pzadd_dVgs = 0.0 ; + Pzadd_dPS0Z = 0.0 ; + } + + Ps0z = Ps0 + Pzadd ; + Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ; + Ps0z_dVds = Ps0_dVds + Pzadd_dVds ; + Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ; + Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ; + + /* calculate Newton correction: */ + G = PS0Z_SCE - Ps0z ; + delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ; + + delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs; + delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds; + delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs; + PS0Z_SCE += delta_PS0Z_SCE ; + PS0Z_SCE_dVbs = Ps0z_dVbs ; + PS0Z_SCE_dVds = Ps0z_dVds ; + PS0Z_SCE_dVgs = Ps0z_dVgs ; + + PS0_SCE = PS0Z_SCE - Pzadd ; + PS0_SCE_dVbs = Ps0_dVbs ; + PS0_SCE_dVds = Ps0_dVds ; + PS0_SCE_dVgs = Ps0_dVgs ; + + + NNN += 1 ; + + if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol + || fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol + ) && (NNN < MAX_LOOP_SCE) ){ + goto START_OF_SCE_LOOP; + } + + + } + + goto end_of_part_1 ; + } + + + /*-----------------------------------------------------------* + * Start point of Psl (= Ps0 + Pds) calculation. (label) + *-----------------*/ + start_of_Psl: + + + /* Vdseff (begin) */ + Vdsorg = Vds ; + + T2 = here->HSM2_qnsub_esi / ( Cox * Cox ) ; + T4 = - 2.0e0 * T2 / Cox ; + T2_dVb = T4 * Cox_dVb ; + T2_dVd = T4 * Cox_dVd ; + T2_dVg = T4 * Cox_dVg ; + + T5 = Vgpz - beta_inv - Vbsz ; + T5_dVb = Vgpz_dVbs - Vbsz_dVbs ; + T5_dVd = Vgpz_dVds - Vbsz_dVds ; + T5_dVg = Vgpz_dVgs ; + + T0 = 2.0 / T2 ; + T1 = 1.0e0 + T0 * T5 ; + T1_dVb = ( T5_dVb * T2 - T5 * T2_dVb ) * T0 / T2 ; + T1_dVd = ( T5_dVd * T2 - T5 * T2_dVd ) * T0 / T2 ; + T1_dVg = ( T5_dVg * T2 - T5 * T2_dVg ) * T0 / T2 ; + + Fn_SZ( T1 , T1 , 0.05 , T9 ) ; + T1_dVb *= T9 ; + T1_dVd *= T9 ; + T1_dVg *= T9 ; + + T3 = sqrt( T1 ) ; + T3_dVb = 0.5 / T3 * T1_dVb ; + T3_dVd = 0.5 / T3 * T1_dVd ; + T3_dVg = 0.5 / T3 * T1_dVg ; + + T10 = Vgpz + T2 * ( 1.0e0 - T3 ) ; + T10_dVb = Vgpz_dVbs + T2_dVb * ( 1.0e0 - T3 ) - T2 * T3_dVb ; + T10_dVd = Vgpz_dVds + T2_dVd * ( 1.0e0 - T3 ) - T2 * T3_dVd ; + T10_dVg = Vgpz_dVgs + T2_dVg * ( 1.0e0 - T3 ) - T2 * T3_dVg ; + Fn_SZ( T10 , T10 , 0.01 , T0 ) ; + T10_dVb *= T0 ; + T10_dVd *= T0 ; + T10_dVg *= T0 ; + + + T1 = Vds / T10 ; + T2 = Fn_Pow( T1 , here->HSM2_ddlt - 1.0e0 ) ; + T7 = T2 * T1 ; + T0 = here->HSM2_ddlt * T2 / ( T10 * T10 ) ; + T7_dVb = T0 * ( - Vds * T10_dVb ) ; + T7_dVd = T0 * ( T10 - Vds * T10_dVd ) ; + T7_dVg = T0 * ( - Vds * T10_dVg ) ; + + T3 = 1.0 + T7 ; + T4 = Fn_Pow( T3 , 1.0 / here->HSM2_ddlt - 1.0 ) ; + T6 = T4 * T3 ; + T0 = T4 / here->HSM2_ddlt ; + T6_dVb = T0 * T7_dVb ; + T6_dVd = T0 * T7_dVd ; + T6_dVg = T0 * T7_dVg ; + + Vdseff = Vds / T6 ; + T0 = 1.0 / ( T6 * T6 ) ; + Vdseff_dVbs = - Vds * T6_dVb * T0 ; + Vdseff_dVds = ( T6 - Vds * T6_dVd ) * T0 ; + Vdseff_dVgs = - Vds * T6_dVg * T0 ; + + Vds = Vdseff ; + /* Vdseff (end) */ + + + exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; + + + /*---------------------------------------------------* + * Skip Psl calculation when Vds is very small. + *-----------------*/ + if ( Vds <= 0.0 ) { + Pds = 0.0 ; + Psl = Ps0 ; + flg_conv = 1 ; + goto start_of_loopl ; + } + + /*-----------------------------------------------------------* + * Initial guess for Pds ( = Psl - Ps0 ). + *-----------------*/ + if ( flg_pprv >= 1 ) { + /*---------------------------------------------------* + * Use previous value. + *-----------------*/ + + T1 = Pds_dVbs * dVbs + Pds_dVds * dVds + Pds_dVgs * dVgs ; + Pds_ini = Pds + T1 ; + + if ( flg_pprv == 2 ) { + /* TX_dVxs = d^2 Pds / d Vxs^2 here */ + if ( Vbsc_dif2 > epsm10 ) { + TX_dVbs = ( here->HSM2_pds_dvbs_prv - here->HSM2_pds_dvbs_prv2 ) + / Vbsc_dif2 ; + } else { + TX_dVbs = 0.0 ; + } + if ( Vdsc_dif2 > epsm10 ) { + TX_dVds = ( here->HSM2_pds_dvds_prv - here->HSM2_pds_dvds_prv2 ) + / Vdsc_dif2 ; + } else { + TX_dVds = 0.0 ; + } + if ( Vgsc_dif2 > epsm10 ) { + TX_dVgs = ( here->HSM2_pds_dvgs_prv - here->HSM2_pds_dvgs_prv2 ) + / Vgsc_dif2 ; + } else { + TX_dVgs = 0.0 ; + } + T2 = ( dVbs * dVbs ) / 2 * TX_dVbs + + ( dVds * dVds ) / 2 * TX_dVds + + ( dVgs * dVgs ) / 2 * TX_dVgs ; + + if ( fabs( T2 ) < fabs( 0.5 * T1 ) ) { + Pds_ini += T2 ; + } else { + flg_pprv = 1 ; + } + } + + T1 = Pds_ini - Pds ; + if ( T1 < - dP_max || T1 > dP_max ) flg_pprv = 0 ; /* flag changes */ + + } /* end of (flg_pprv>=1) if-block */ + + if ( flg_pprv == 0 ) { + /*---------------------------------------------------* + * Analytical initial guess. + *-----------------*/ + Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ) ; + + Fn_SU( Pds_ini , Vds, (1.0e0 + c_pslini_1) * Pds_max, c_pslini_2, T1 ) ; + Pds_ini = Fn_Min( Pds_ini , Pds_max ) ; + } + + if ( Pds_ini < 0.0 ) Pds_ini = 0.0 ; + else if ( Pds_ini > Vds ) Pds_ini = Vds ; + + + /*---------------------------------------------------* + * Assign initial guess. + *-----------------*/ + if ( NNN == 0 ) { + Pds = Pds_ini ; + Psl = Ps0 + Pds ; + } else { + /* take solution from previous PS0_SCE_loop as initial value */ + Pds = Psl - Ps0 ; + } + TX = Vbs + ps_conv / 2 ; + if ( Psl < TX ) Psl = TX ; + + /*---------------------------------------------------* + * Calculation of Psl by solving Poisson eqn. + * (beginning of Newton loop) + * - Fsl : Fsl = 0 is the equation to be solved. + * - dPsl : correction value. + *-----------------*/ + flg_conv = 0 ; + + /*---------------------------------------------------* + * start of Psl calculation. (label) + *-----------------*/ +start_of_loopl: + + for ( lp_sl = 1 ; lp_sl <= lp_sl_max + 1 ; lp_sl ++ ) { + + Chi = beta * ( Psl - Vbs ) ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D2. (Psl) + * - Qb0 is approximated to 5-degree polynomial. + *-----------------*/ + + fi = Chi * Chi * Chi + * ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ; + fi_dChi = Chi * Chi + * ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ; + + cfs1 = cnst1 * exp_bVbsVds ; + fsl1 = cfs1 * fi * fi ; + fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; + + fb = Chi * ( cn_nc51 + + Chi * ( cn_nc52 + + Chi * ( cn_nc53 + + Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ; + fb_dChi = cn_nc51 + + Chi * ( 2 * cn_nc52 + + Chi * ( 3 * cn_nc53 + + Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ; + + fsl2 = sqrt( fb * fb + fsl1 ) ; + fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; + + } else { + /*-------------------------------------------* + * zone-D3. (Psl) + *-----------------*/ + Rho = beta * ( Psl - Vds ) ; + exp_Rho = exp( Rho ) ; + + fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; + fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; + Xil = Chi - 1.0e0 ; + fsl2 = sqrt( Xil + fsl1 ) ; + fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; + } + + Fsl = Vgp - Psl - fac1 * fsl2 ; + Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; + + if ( flg_conv == 1 ) break ; + + dPsl = - Fsl / Fsl_dPsl ; + + /*-------------------------------------------* + * Update Psl . + * - clamped to Vbs if Psl < Vbs . + *-----------------*/ + dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Psl))) ; + if ( fabs( dPsl ) > dPlim ) dPsl = dPlim * Fn_Sgn( dPsl ) ; + + Psl = Psl + dPsl ; + + TX = Vbs + ps_conv / 2 ; + if ( Psl < TX ) Psl = TX ; + + /*-------------------------------------------* + * Check convergence. + * NOTE: This condition may be too rigid. + *-----------------*/ + if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { + flg_conv = 1 ; + } + } /* end of Psl Newton loop */ + + /* Eliminate loop count to take account of the derivative loop */ + lp_sl -- ; + + /*-------------------------------------------* + * Procedure for diverged case. + *-----------------*/ + if ( flg_conv == 0 ) { + fprintf( stderr , + "*** warning(HiSIM): Went Over Iteration Maximum (Psl)\n" ) ; + fprintf( stderr , + " Vbse = %7.3f Vdse = %7.3f Vgse = %7.3f\n" , + Vbse , Vdse , Vgse ) ; + if ( flg_info >= 2 ) { + printf("*** warning(HiSIM): Went Over Iteration Maximum (Psl)\n" ) ; + } + } + + + /*---------------------------------------------------* + * Evaluate derivatives of Psl. + * - note: Here, fsl1_dVbs and fsl2_dVbs are derivatives + * w.r.t. explicit Vbs. So, Psl in the fsl1 and fsl2 + * expressions is regarded as a constant. + *-----------------*/ + if ( Chi < znbd5 ) { + T1 = cfs1 * beta * fi ; + fsl1_dVbs = T1 * ( ( 1.0 - Vdseff_dVbs ) * fi - 2.0 * fi_dChi ) ; + fsl1_dVds = - T1 * fi * Vdseff_dVds ; + fsl1_dVgs = - T1 * fi * Vdseff_dVgs ; + T2 = 0.5 / fsl2 ; + fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; + fsl2_dVds = fsl1_dVds * T2 ; + fsl2_dVgs = fsl1_dVgs * T2 ; + } else { + T1 = cnst1 * beta ; + fsl1_dVbs = - T1 * ( exp_Rho * Vdseff_dVbs + + ( 1.0 - Vdseff_dVbs ) * exp_bVbsVds ); + fsl1_dVds = - T1 * Vdseff_dVds * ( exp_Rho - exp_bVbsVds ); + fsl1_dVgs = T1 * Vdseff_dVgs * ( - exp_Rho + exp_bVbsVds ); + T2 = 0.5e0 / fsl2 ; + fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; + fsl2_dVds = ( fsl1_dVds ) * T2 ; + fsl2_dVgs = ( fsl1_dVgs ) * T2 ; + } + + T1 = 1.0 / Fsl_dPsl ; + Psl_dVbs = - ( Vgp_dVbs - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) ) * T1 ; + Psl_dVds = - ( Vgp_dVds - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) ) * T1 ; + Psl_dVgs = - ( Vgp_dVgs - ( fac1 * fsl2_dVgs + fac1_dVgs * fsl2 ) ) * T1 ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D1/D2. (Psl) + *-----------------*/ + Xil = fb * fb + epsm10 ; + T1 = 2 * fb * fb_dChi * beta ; + Xil_dVbs = T1 * ( Psl_dVbs - 1.0 ) ; + Xil_dVds = T1 * Psl_dVds ; + Xil_dVgs = T1 * Psl_dVgs ; + + Xilp12 = fb + epsm10 ; + T1 = fb_dChi * beta ; + Xilp12_dVbs = T1 * ( Psl_dVbs - 1.0 ) ; + Xilp12_dVds = T1 * Psl_dVds ; + Xilp12_dVgs = T1 * Psl_dVgs ; + + Xilp32 = fb * fb * fb + epsm10 ; + T1 = 3 * fb * fb * fb_dChi * beta ; + Xilp32_dVbs = T1 * ( Psl_dVbs - 1.0 ) ; + Xilp32_dVds = T1 * Psl_dVds ; + Xilp32_dVgs = T1 * Psl_dVgs ; + + } else { + /*-------------------------------------------* + * zone-D3. (Psl) + *-----------------*/ + + Xil = Chi - 1.0e0 ; + Xil_dVbs = beta * ( Psl_dVbs - 1.0e0 ) ; + Xil_dVds = beta * Psl_dVds ; + Xil_dVgs = beta * Psl_dVgs ; + + Xilp12 = sqrt( Xil ) ; + T1 = 0.5e0 / Xilp12 ; + Xilp12_dVbs = T1 * Xil_dVbs ; + Xilp12_dVds = T1 * Xil_dVds ; + Xilp12_dVgs = T1 * Xil_dVgs ; + + Xilp32 = Xil * Xilp12 ; + T1 = 1.5e0 * Xilp12 ; + Xilp32_dVbs = T1 * Xil_dVbs ; + Xilp32_dVds = T1 * Xil_dVds ; + Xilp32_dVgs = T1 * Xil_dVgs ; + + } + + /*---------------------------------------------------* + * Assign Pds. + *-----------------*/ + Pds = Psl - Ps0 ; + + if ( Pds < 0.0 ) { + Pds = 0.0 ; + Psl = Ps0 ; + } + + Pds_dVbs = Psl_dVbs - Ps0_dVbs ; + Pds_dVds = Psl_dVds - Ps0_dVds ; + Pds_dVgs = Psl_dVgs - Ps0_dVgs ; + + if ( Pds < ps_conv ) { + Pds_dVbs = 0.0 ; + Pds_dVgs = 0.0 ; + Psl_dVbs = Ps0_dVbs ; + Psl_dVgs = Ps0_dVgs ; + } + + /* Vdseff */ + Vds = Vdsorg; + + + if( corecip ){ + + /* For multi level Newton method to calculate PS0Z_SCE */ + /* remember that for the inner Newton: */ + /* Fs0(PS0Z_SCE,Ps0) = Vgp(PSOZ_SCE) - Ps0 - fac1 * fs02(Ps0) */ + /* -> dPs0/dPS0Z_SCE = - (dFs0/dPS0Z_SCE) / (dFs0/dPs0) */ + /* and */ + /* Fsl(PS0Z_SCE,Psl) = Vgp(PS0Z_SCE) - Psl - fac1 * fsl1(Psl) */ + /* -> dPsl/dPS0Z_SCE = - (dFsl/dPS0Z_SCE) / (dFsl/dPsl) */ + + /* Outer Newton: */ + /* PS0Z_SCE = Ps0 + Pzadd(Ps0,Psl) */ + /* -> G(PS0Z_SCE) := PS0Z_SCE - Ps0(PS0Z_SCE) - Pzadd(Ps0(PS0Z_SCE),Psl(Ps0Z_SCE)) = 0 */ + /* -> Newton correction delta_PS0Z_SCE from: */ + /* (1.0 - dPs0/dPS0Z_SCE - dPzadd/dPS0Z_SCE) * delta_PS0Z_SCE = - G */ + + Fs0_dPS0Z = Vgp_dPS0Z ; + Ps0_dPS0Z = - Fs0_dPS0Z / Fs0_dPs0 ; + + Fsl_dPS0Z = Vgp_dPS0Z ; + Psl_dPS0Z = - Fsl_dPS0Z / Fsl_dPsl ; + + if ( Pds < ps_conv ) { + Pds_dPS0Z = 0.0 ; + } else { + Pds_dPS0Z = Psl_dPS0Z - Ps0_dPS0Z ; + } + + T1 = ( Vds - Pds ) / 2 ; + Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ; + T2 /= 2 ; + Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; + Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; + Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; + Pzadd_dPS0Z = T2 * ( - Pds_dPS0Z) ; + + if ( Pzadd < epsm10 ) { + Pzadd = epsm10 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = 0.0 ; + Pzadd_dVgs = 0.0 ; + Pzadd_dPS0Z = 0.0 ; + } + + Ps0z = Ps0 + Pzadd ; + Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ; + Ps0z_dVds = Ps0_dVds + Pzadd_dVds ; + Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ; + Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ; + + + /* calculate Newton correction: */ + G = PS0Z_SCE - Ps0z ; + delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ; + + delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs; + delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds; + delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs; + PS0Z_SCE += delta_PS0Z_SCE ; + PS0Z_SCE_dVbs = Ps0z_dVbs ; + PS0Z_SCE_dVds = Ps0z_dVds ; + PS0Z_SCE_dVgs = Ps0z_dVgs ; + + PS0_SCE = PS0Z_SCE - Pzadd ; + PS0_SCE_dVbs = Ps0_dVbs ; + PS0_SCE_dVds = Ps0_dVds ; + PS0_SCE_dVgs = Ps0_dVgs ; + + NNN += 1 ; + + if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol + || fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol + || fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol + ) && (NNN < MAX_LOOP_SCE) ){ + goto START_OF_SCE_LOOP; + } + + + } + + + /*-----------------------------------------------------------* + * Evaluate Idd. + * - Eta : substantial variable of QB'/Pds and Idd/Pds. + * - note: Eta = 4 * GAMMA_{hisim_0} + *-----------------*/ + T1 = beta / Xi0 ; + Eta = T1 * Pds ; + T2 = Eta * beta_inv ; + Eta_dVbs = T1 * ( Pds_dVbs - Xi0_dVbs * T2 ) ; + Eta_dVds = T1 * ( Pds_dVds - Xi0_dVds * T2 ) ; + Eta_dVgs = T1 * ( Pds_dVgs - Xi0_dVgs * T2 ) ; + + /* ( Eta + 1 )^n */ + Eta1 = Eta + 1.0e0 ; + Eta1p12 = sqrt( Eta1 ) ; + Eta1p32 = Eta1p12 * Eta1 ; + Eta1p52 = Eta1p32 * Eta1 ; + + /* 1 / ( ( Eta + 1 )^n + 1 ) */ + Zeta12 = 1.0e0 / ( Eta1p12 + 1.0e0 ) ; + Zeta32 = 1.0e0 / ( Eta1p32 + 1.0e0 ) ; + Zeta52 = 1.0e0 / ( Eta1p52 + 1.0e0 ) ; + + /*---------------------------------------------------* + * F00 := PS00/Pds (n=1/2) + *-----------------*/ + F00 = Zeta12 / Xi0p12 ; + T3 = - 1 / Xi0 ; + T4 = - 0.5e0 / Eta1p12 * F00 ; + T5 = Zeta12 * T3 ; + T6 = Zeta12 * T4 ; + F00_dVbs = ( Xi0p12_dVbs * T5 + Eta_dVbs * T6 ) ; + F00_dVds = ( Xi0p12_dVds * T5 + Eta_dVds * T6 ) ; + F00_dVgs = ( Xi0p12_dVgs * T5 + Eta_dVgs * T6 ) ; + + /*---------------------------------------------------* + * F10 := PS10/Pds (n=3/2) + *-----------------*/ + T1 = 3.0e0 + Eta * ( 3.0e0 + Eta ) ; + F10 = C_2o3 * Xi0p12 * Zeta32 * T1 ; + T2 = 3.0e0 + Eta * 2.0e0 ; + T3 = C_2o3 * T1 ; + T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; + T5 = Zeta32 * T3 ; + T6 = Zeta32 * T4 ; + F10_dVbs = ( Xi0p12_dVbs * T5 + Eta_dVbs * T6 ) ; + F10_dVds = ( Xi0p12_dVds * T5 + Eta_dVds * T6 ) ; + F10_dVgs = ( Xi0p12_dVgs * T5 + Eta_dVgs * T6 ) ; + + /*---------------------------------------------------* + * F30 := PS30/Pds (n=5/2) + *-----------------*/ + T1 = 5e0 + Eta * ( 10e0 + Eta * ( 10e0 + Eta * ( 5e0 + Eta ) ) ) ; + F30 = 4e0 / ( 15e0 * beta ) * Xi0p32 * Zeta52 * T1 ; + T2 = 10e0 + Eta * ( 20e0 + Eta * ( 15e0 + Eta * 4e0 ) ) ; + T3 = 4e0 / ( 15e0 * beta ) * T1 ; + T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; + T5 = Zeta52 * T3 ; + T6 = Zeta52 * T4 ; + F30_dVbs = ( Xi0p32_dVbs * T5 + Eta_dVbs * T6 ) ; + F30_dVds = ( Xi0p32_dVds * T5 + Eta_dVds * T6 ) ; + F30_dVgs = ( Xi0p32_dVgs * T5 + Eta_dVgs * T6 ) ; + + /*---------------------------------------------------* + * F11 := PS11/Pds. + *-----------------*/ + F11 = Ps0 * F10 + C_2o3 * beta_inv * Xilp32 - F30 ; + T1 = C_2o3 * beta_inv ; + F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs + + T1 * Xilp32_dVbs - F30_dVbs ; + F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds + + T1 * Xilp32_dVds - F30_dVds ; + F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs + + T1 * Xilp32_dVgs - F30_dVgs ; + + /*---------------------------------------------------* + * Fdd := Idd/Pds. + *-----------------*/ + T1 = Vgp + beta_inv - 0.5e0 * ( 2.0e0 * Ps0 + Pds ) ; + T2 = - F10 + F00 ; + T3 = beta * Cox ; + T4 = beta * cnst0 ; + Fdd = T3 * T1 + T4 * T2 ; + Fdd_dVbs = T3 * ( Vgp_dVbs - Ps0_dVbs - 0.5e0 * Pds_dVbs ) + + beta * Cox_dVb * T1 + T4 * ( - F10_dVbs + F00_dVbs ) ; + Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds ) + + beta * Cox_dVd * T1 + T4 * ( - F10_dVds + F00_dVds ) ; + Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs ) + + beta * Cox_dVg * T1 + T4 * ( - F10_dVgs + F00_dVgs ) ; + + + /*---------------------------------------------------* + * Idd: + *-----------------*/ + Idd = Pds * Fdd ; + Idd_dVbs = Pds_dVbs * Fdd + Pds * Fdd_dVbs ; + Idd_dVds = Pds_dVds * Fdd + Pds * Fdd_dVds ; + Idd_dVgs = Pds_dVgs * Fdd + Pds * Fdd_dVgs ; + + /*-----------------------------------------------------------* + * Skip CLM and integrated charges if zone==D1 + *-----------------*/ + if( flg_zone == 1 ) { + goto start_of_mobility ; + } + + /*-----------------------------------------------------------* + * Channel Length Modulation. Lred: \Delta L + *-----------------*/ + if( pParam->HSM2_clm2 < epsm10 && pParam->HSM2_clm3 < epsm10 ) { + Lred = 0.0e0 ; + Lred_dVbs = 0.0e0 ; + Lred_dVds = 0.0e0 ; + Lred_dVgs = 0.0e0 ; + + Psdl = Psl ; + Psdl_dVbs = Psl_dVbs ; + Psdl_dVds = Psl_dVds ; + Psdl_dVgs = Psl_dVgs ; + if ( Psdl > Ps0 + Vds - epsm10 ) { + Psdl = Ps0 + Vds - epsm10 ; + Psdl_dVbs = Ps0_dVbs ; + Psdl_dVds = Ps0_dVds + 1.0 ; + Psdl_dVgs = Ps0_dVgs ; + } + + } else { + T1 = here->HSM2_wdpl ; + T8 = sqrt (Psl - Vbs) ; + Wd = T1 * T8 ; + T9 = 0.5 * T1 / T8 ; + Wd_dVbs = T9 * (Psl_dVbs - 1.0) ; + Wd_dVds = T9 * Psl_dVds ; + Wd_dVgs = T9 * Psl_dVgs ; + + T0 = 1.0 / Wd ; + T1 = Qn0 * T0 ; + T2 = pParam->HSM2_clm3 * T1 ; + T3 = pParam->HSM2_clm3 * T0 ; + T2_dVb = T3 * (Qn0_dVbs - T1 * Wd_dVbs) ; + T2_dVd = T3 * (Qn0_dVds - T1 * Wd_dVds) ; + T2_dVg = T3 * (Qn0_dVgs - T1 * Wd_dVgs) ; + + T5 = pParam->HSM2_clm2 * q_Nsub + T2 ; + T1 = 1.0 / T5 ; + T4 = C_ESI * T1 ; + T4_dVb = - T4 * T2_dVb * T1 ; + T4_dVd = - T4 * T2_dVd * T1 ; + T4_dVg = - T4 * T2_dVg * T1 ; + + T1 = (1.0e0 - pParam->HSM2_clm1) ; + Psdl = pParam->HSM2_clm1 * (Vds + Ps0) + T1 * Psl ; + Psdl_dVbs = pParam->HSM2_clm1 * Ps0_dVbs + T1 * Psl_dVbs ; + Psdl_dVds = pParam->HSM2_clm1 * (1.0 + Ps0_dVds) + T1 * Psl_dVds ; + Psdl_dVgs = pParam->HSM2_clm1 * Ps0_dVgs + T1 * Psl_dVgs ; + if ( Psdl > Ps0 + Vds - epsm10 ) { + Psdl = Ps0 + Vds - epsm10 ; + Psdl_dVbs = Ps0_dVbs ; + Psdl_dVds = Ps0_dVds + 1.0 ; + Psdl_dVgs = Ps0_dVgs ; + } + T6 = Psdl - Psl ; + T6_dVb = Psdl_dVbs - Psl_dVbs ; + T6_dVd = Psdl_dVds - Psl_dVds ; + T6_dVg = Psdl_dVgs - Psl_dVgs ; + + T3 = beta * Qn0 ; + T1 = 1.0 / T3 ; + T5 = Idd * T1 ; + T2 = T5 * beta ; + T5_dVb = (Idd_dVbs - T2 * Qn0_dVbs) * T1 ; + T5_dVd = (Idd_dVds - T2 * Qn0_dVds) * T1 ; + T5_dVg = (Idd_dVgs - T2 * Qn0_dVgs) * T1 ; + + T10 = q_Nsub / C_ESI ; + T1 = 1.0e5 ; + T2 = 1.0 / Leff ; + T11 = (2.0 * T5 + 2.0 * T10 * T6 * T4 + T1 * T4) * T2 ; + T3 = T2 * T4 ; + T7 = T11 * T4 ; + T7_dVb = (2.0 * T5_dVb + 2.0 * T10 * (T6_dVb * T4 + T6 * T4_dVb) + T1 * T4_dVb) * T3 + T11 * T4_dVb ; + T7_dVd = (2.0 * T5_dVd + 2.0 * T10 * (T6_dVd * T4 + T6 * T4_dVd) + T1 * T4_dVd) * T3 + T11 * T4_dVd ; + T7_dVg = (2.0 * T5_dVg + 2.0 * T10 * (T6_dVg * T4 + T6 * T4_dVg) + T1 * T4_dVg) * T3 + T11 * T4_dVg ; + + T11 = 4.0 * (2.0 * T10 * T6 + T1) ; + T1 = 8.0 * T10 * T4 * T4 ; + T2 = 2.0 * T11 * T4 ; + T8 = T11 * T4 * T4 ; + T8_dVb = ( T1 * T6_dVb + T2 * T4_dVb) ; + T8_dVd = ( T1 * T6_dVd + T2 * T4_dVd) ; + T8_dVg = ( T1 * T6_dVg + T2 * T4_dVg) ; + + T9 = sqrt (T7 * T7 + T8); + T1 = 1.0 / T9 ; + T2 = T7 * T1 ; + T3 = 0.5 * T1 ; + T9_dVb = (T2 * T7_dVb + T3 * T8_dVb) ; + T9_dVd = (T2 * T7_dVd + T3 * T8_dVd) ; + T9_dVg = (T2 * T7_dVg + T3 * T8_dVg) ; + + Lred = 0.5 * (- T7 + T9) ; + Lred_dVbs = 0.5 * (- T7_dVb + T9_dVb) ; + Lred_dVds = 0.5 * (- T7_dVd + T9_dVd) ; + Lred_dVgs = 0.5 * (- T7_dVg + T9_dVg) ; + + /*---------------------------------------------------* + * Modify Lred for symmetry. + *-----------------*/ + T1 = Lred ; + Lred = FMDVDS * T1 ; + Lred_dVbs = FMDVDS_dVbs * T1 + FMDVDS * Lred_dVbs ; + Lred_dVds = FMDVDS_dVds * T1 + FMDVDS * Lred_dVds ; + Lred_dVgs = FMDVDS_dVgs * T1 + FMDVDS * Lred_dVgs ; + } + + /* CLM5 & CLM6 */ + Lred *= here->HSM2_clmmod ; + Lred_dVbs *= here->HSM2_clmmod ; + Lred_dVds *= here->HSM2_clmmod ; + Lred_dVgs *= here->HSM2_clmmod ; + + + /*---------------------------------------------------* + * Qbu : -Qb in unit area. + *-----------------*/ + T1 = Vgp + beta_inv ; + T2 = T1 * F10 - F11 ; + + Qbnm = cnst0 * ( cnst0 * ( 1.5e0 - ( Xi0 + 1.0e0 ) - 0.5e0 * beta * Pds ) + + Cox * T2 ) ; + Qbnm_dVbs = cnst0 * ( cnst0 * ( - Xi0_dVbs - 0.5e0 * beta * Pds_dVbs ) + + Cox * ( Vgp_dVbs * F10 + T1 * F10_dVbs - F11_dVbs ) + + Cox_dVb * T2 ) ; + Qbnm_dVds = cnst0 * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds ) + + Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds ) + + Cox_dVd * T2 ) ; + Qbnm_dVgs = cnst0 * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs ) + + Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs ) + + Cox_dVg * T2 ) ; + + T1 = beta ; + Qbu = T1 * Qbnm / Fdd ; + T2 = T1 / ( Fdd * Fdd ) ; + Qbu_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; + Qbu_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; + Qbu_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; + + /*---------------------------------------------------* + * preparation for Qi and Qd. + * - DtPds: Delta * Pds ; + * - Achi: (1+Delta) * Pds ; + *-----------------*/ + T1 = 2.0e0 * fac1 ; + DtPds = T1 * ( F10 - Xi0p12 ) ; + T2 = 2.0 * ( F10 - Xi0p12 ) ; + DtPds_dVbs = T1 * ( F10_dVbs - Xi0p12_dVbs ) + + T2 * fac1_dVbs ; + DtPds_dVds = T1 * ( F10_dVds - Xi0p12_dVds ) + + T2 * fac1_dVds ; + DtPds_dVgs = T1 * ( F10_dVgs - Xi0p12_dVgs ) + + T2 * fac1_dVgs ; + + Achi = Pds + DtPds ; + Achi_dVbs = Pds_dVbs + DtPds_dVbs ; + Achi_dVds = Pds_dVds + DtPds_dVds ; + Achi_dVgs = Pds_dVgs + DtPds_dVgs ; + + /*-----------------------------------------------------------* + * Alpha : parameter to evaluate charges. + * - Achi: (1+Delta) * Pds ; + * - clamped to 0 if Alpha < 0. + *-----------------*/ + T1 = 1.0 / VgVt ; + T2 = Achi * T1 ; + T3 = 1.0e0 - T2 ; + TX = 1.0 - T3 ; + Fn_CP( TY , TX , 1.0 , 4 , T4 ) ; + Alpha = 1.0 - TY ; + T5 = T1 * T4 ; + Alpha_dVbs = - ( Achi_dVbs - T2 * VgVt_dVbs ) * T5 ; + Alpha_dVds = - ( Achi_dVds - T2 * VgVt_dVds ) * T5 ; + Alpha_dVgs = - ( Achi_dVgs - T2 * VgVt_dVgs ) * T5 ; + + + /*-----------------------------------------------------------* + * Qiu : -Qi in unit area. + *-----------------*/ + + Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; + T1 = 1.0e0 + Alpha + Alpha ; + Qinm_dVbs = Alpha_dVbs * T1 ; + Qinm_dVds = Alpha_dVds * T1 ; + Qinm_dVgs = Alpha_dVgs * T1 ; + + Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; + Qidn_dVbs = Alpha_dVbs ; + Qidn_dVds = Alpha_dVds ; + Qidn_dVgs = Alpha_dVgs ; + + T1 = C_2o3 * VgVt * Qinm / Qidn ; + Qiu = T1 * Cox ; + T2 = 1.0 / VgVt ; + T3 = 1.0 / Qinm ; + T4 = 1.0 / Qidn ; + Qiu_dVbs = Qiu * ( VgVt_dVbs * T2 + Qinm_dVbs * T3 - Qidn_dVbs * T4 ) + + T1 * Cox_dVb ; + Qiu_dVds = Qiu * ( VgVt_dVds * T2 + Qinm_dVds * T3 - Qidn_dVds * T4) + + T1 * Cox_dVd ; + Qiu_dVgs = Qiu * ( VgVt_dVgs * T2 + Qinm_dVgs * T3 - Qidn_dVgs * T4) + + T1 * Cox_dVg ; + + /*-----------------------------------------------------------* + * Qdrat : Qd/Qi + *-----------------*/ + Qdnm = 0.5e0 + Alpha ; + Qdnm_dVbs = Alpha_dVbs ; + Qdnm_dVds = Alpha_dVds ; + Qdnm_dVgs = Alpha_dVgs ; + + Qddn = Qidn * Qinm ; + Qddn_dVbs = Qidn_dVbs * Qinm + Qidn * Qinm_dVbs ; + Qddn_dVds = Qidn_dVds * Qinm + Qidn * Qinm_dVds ; + Qddn_dVgs = Qidn_dVgs * Qinm + Qidn * Qinm_dVgs ; + + Quot = 0.4e0 * Qdnm / Qddn ; + Qdrat = 0.6e0 - Quot ; + + if ( Qdrat <= 0.5e0 ) { + T1 = 1.0 / Qddn ; + T2 = 1.0 / Qdnm ; + Qdrat_dVbs = Quot * ( Qddn_dVbs * T1 - Qdnm_dVbs * T2 ) ; + Qdrat_dVds = Quot * ( Qddn_dVds * T1 - Qdnm_dVds * T2 ) ; + Qdrat_dVgs = Quot * ( Qddn_dVgs * T1 - Qdnm_dVgs * T2 ) ; + } else { + Qdrat = 0.5e0 ; + Qdrat_dVbs = 0.0e0 ; + Qdrat_dVds = 0.0e0 ; + Qdrat_dVgs = 0.0e0 ; + } + + + /*-----------------------------------------------------------* + * Interpolate charges and CLM for zone-D2. + *-----------------*/ + + if ( flg_zone == 2 ) { + T1 = Qbu ; + Qbu = FD2 * Qbu + ( 1.0 - FD2 ) * Qb0 ; + Qbu_dVbs = FD2 * Qbu_dVbs + FD2_dVbs * T1 + + ( 1.0 - FD2 ) * Qb0_dVb - FD2_dVbs * Qb0 ; + Qbu_dVds = FD2 * Qbu_dVds + FD2_dVds * T1 + + ( 1.0 - FD2 ) * Qb0_dVd - FD2_dVds * Qb0 ; + Qbu_dVgs = FD2 * Qbu_dVgs + FD2_dVgs * T1 + + ( 1.0 - FD2 ) * Qb0_dVg - FD2_dVgs * Qb0 ; + + if ( Qbu < 0.0 ) { + Qbu = 0.0 ; + Qbu_dVbs = 0.0 ; + Qbu_dVds = 0.0 ; + Qbu_dVgs = 0.0 ; + } + T1 = Qiu ; + Qiu = FD2 * Qiu + ( 1.0 - FD2 ) * Qn0 ; + Qiu_dVbs = FD2 * Qiu_dVbs + FD2_dVbs * T1 + + ( 1.0 - FD2 ) * Qn0_dVbs - FD2_dVbs * Qn0 ; + Qiu_dVds = FD2 * Qiu_dVds + FD2_dVds * T1 + + ( 1.0 - FD2 ) * Qn0_dVds - FD2_dVds * Qn0 ; + Qiu_dVgs = FD2 * Qiu_dVgs + FD2_dVgs * T1 + + ( 1.0 - FD2 ) * Qn0_dVgs - FD2_dVgs * Qn0 ; + if ( Qiu < 0.0 ) { + Qiu = 0.0 ; + Qiu_dVbs = 0.0 ; + Qiu_dVds = 0.0 ; + Qiu_dVgs = 0.0 ; + } + + T1 = Qdrat ; + Qdrat = FD2 * Qdrat + ( 1.0 - FD2 ) * 0.5e0 ; + Qdrat_dVbs = FD2 * Qdrat_dVbs + FD2_dVbs * T1 - FD2_dVbs * 0.5e0 ; + Qdrat_dVds = FD2 * Qdrat_dVds + FD2_dVds * T1 - FD2_dVds * 0.5e0 ; + Qdrat_dVgs = FD2 * Qdrat_dVgs + FD2_dVgs * T1 - FD2_dVgs * 0.5e0 ; + + /* note: Lred=0 in zone-D1 */ + T1 = Lred ; + Lred = FD2 * Lred ; + Lred_dVbs = FD2 * Lred_dVbs + FD2_dVbs * T1 ; + Lred_dVds = FD2 * Lred_dVds + FD2_dVds * T1 ; + Lred_dVgs = FD2 * Lred_dVgs + FD2_dVgs * T1 ; + } /* end of flg_zone==2 if-block */ + + +start_of_mobility: + + Lch = Leff - Lred ; + if ( Lch < 1.0e-7 ) { + Lch = 1.0e-7 ; Lch_dVbs = Lch_dVds = Lch_dVgs = 0.0 ; + } else { Lch_dVbs = - Lred_dVbs ; Lch_dVds = - Lred_dVds ; Lch_dVgs = - Lred_dVgs ; } + + + /*-----------------------------------------------------------* + * Modified potential for symmetry. + *-----------------*/ + T1 = ( Vds - Pds ) / 2 ; + Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ; + T2 /= 2 ; + Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; + Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; + Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; + + if ( Pzadd < epsm10 ) { + Pzadd = epsm10 ; + Pzadd_dVbs = 0.0 ; + Pzadd_dVds = 0.0 ; + Pzadd_dVgs = 0.0 ; + } + + Ps0z = Ps0 + Pzadd ; + Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ; + Ps0z_dVds = Ps0_dVds + Pzadd_dVds ; + Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ; + + + /*-----------------------------------------------------------* + * Muun : universal mobility. + *-----------------*/ + + T1 = here->HSM2_ndep_o_esi ; + T2 = here->HSM2_ninv_o_esi ; + + T0 = model->HSM2_ninvd ; + T4 = 1.0 + ( Psl - Ps0 ) * T0 ; + T4_dVb = ( Psl_dVbs - Ps0_dVbs ) * T0 ; + T4_dVd = ( Psl_dVds - Ps0_dVds ) * T0 ; + T4_dVg = ( Psl_dVgs - Ps0_dVgs ) * T0 ; + + T5 = T1 * Qbu + T2 * Qiu ; + T5_dVb = T1 * Qbu_dVbs + T2 * Qiu_dVbs ; + T5_dVd = T1 * Qbu_dVds + T2 * Qiu_dVds ; + T5_dVg = T1 * Qbu_dVgs + T2 * Qiu_dVgs ; + + T3 = T5 / T4 ; + T3_dVb = ( - T4_dVb * T5 + T4 * T5_dVb ) / T4 / T4 ; + T3_dVd = ( - T4_dVd * T5 + T4 * T5_dVd ) / T4 / T4 ; + T3_dVg = ( - T4_dVg * T5 + T4 * T5_dVg ) / T4 / T4 ; + + Eeff = T3 ; + Eeff_dVbs = T3_dVb ; + Eeff_dVds = T3_dVd ; + Eeff_dVgs = T3_dVg ; + + T5 = Fn_Pow( Eeff , model->HSM2_mueph0 - 1.0e0 ) ; + T8 = T5 * Eeff ; + T7 = Fn_Pow( Eeff , here->HSM2_muesr - 1.0e0 ) ; + T6 = T7 * Eeff ; + + + Rns = Qiu / C_QE ; + T1 = 1.0e0 / ( here->HSM2_muecb0 + here->HSM2_muecb1 * Rns / 1.0e11 ) + + here->HSM2_mphn0 * T8 + T6 / pParam->HSM2_muesr1 ; + Muun = 1.0e0 / T1 ; + + T1 = 1.0e0 / ( T1 * T1 ) ; + T2 = here->HSM2_muecb0 + here->HSM2_muecb1 * Rns / 1.0e11 ; + T2 = 1.0e0 / ( T2 * T2 ) ; + T3 = here->HSM2_mphn1 * T5 ; + T4 = here->HSM2_muesr * T7 / pParam->HSM2_muesr1 ; + T5 = - 1.0e-11 * here->HSM2_muecb1 / C_QE * T2 ; + Muun_dVbs = - ( T5 * Qiu_dVbs + + Eeff_dVbs * T3 + Eeff_dVbs * T4 ) * T1 ; + Muun_dVds = - ( T5 * Qiu_dVds + + Eeff_dVds * T3 + Eeff_dVds * T4 ) * T1 ; + Muun_dVgs = - ( T5 * Qiu_dVgs + + Eeff_dVgs * T3 + Eeff_dVgs * T4 ) * T1 ; + + /*-----------------------------------------------------------* + * Mu : mobility + *-----------------*/ + T2 = beta * (Qn0 + small) * Lch ; + + + T1 = 1.0e0 / T2 ; + T3 = T1 * T1 ; + T4 = - beta * T3 ; + T5 = T4 * Lch ; + T6 = T4 * (Qn0 + small) ; + T1_dVb = ( T5 * Qn0_dVbs + T6 * Lch_dVbs) ; + T1_dVd = ( T5 * Qn0_dVds + T6 * Lch_dVds) ; + T1_dVg = ( T5 * Qn0_dVgs + T6 * Lch_dVgs) ; + + TY = Idd * T1 ; + TY_dVbs = Idd_dVbs * T1 + Idd * T1_dVb ; + TY_dVds = Idd_dVds * T1 + Idd * T1_dVd ; + TY_dVgs = Idd_dVgs * T1 + Idd * T1_dVg ; + + T2 = 0.2 * Vmax / Muun ; + T3 = - T2 / Muun ; + T2_dVb = T3 * Muun_dVbs ; + T2_dVd = T3 * Muun_dVds ; + T2_dVg = T3 * Muun_dVgs ; + + Ey = sqrt( TY * TY + T2 * T2 ) ; + T4 = 1.0 / Ey ; + Ey_dVbs = T4 * ( TY * TY_dVbs + T2 * T2_dVb ) ; + Ey_dVds = T4 * ( TY * TY_dVds + T2 * T2_dVd ) ; + Ey_dVgs = T4 * ( TY * TY_dVgs + T2 * T2_dVg ) ; + + Em = Muun * Ey ; + Em_dVbs = Muun_dVbs * Ey + Muun * Ey_dVbs ; + Em_dVds = Muun_dVds * Ey + Muun * Ey_dVds ; + Em_dVgs = Muun_dVgs * Ey + Muun * Ey_dVgs ; + + T1 = Em / Vmax ; + + /* note: model->HSM2_bb = 2 (electron) ;1 (hole) */ + if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) { + T3 = 1.0e0 ; + } else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) { + T3 = T1 ; + } else { + T3 = Fn_Pow( T1 , model->HSM2_bb - 1.0e0 ) ; + } + T2 = T1 * T3 ; + T4 = 1.0e0 + T2 ; + + if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) { + T5 = 1.0 / T4 ; + T6 = T5 / T4 ; + } else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) { + T5 = 1.0 / sqrt( T4 ) ; + T6 = T5 / T4 ; + } else { + T6 = Fn_Pow( T4 , ( - 1.0e0 / model->HSM2_bb - 1.0e0 ) ) ; + T5 = T4 * T6 ; + } + + T7 = Muun / Vmax * T6 * T3 ; + + Mu = Muun * T5 ; + Mu_dVbs = Muun_dVbs * T5 - T7 * Em_dVbs ; + Mu_dVds = Muun_dVds * T5 - T7 * Em_dVds ; + Mu_dVgs = Muun_dVgs * T5 - T7 * Em_dVgs ; + + end_of_mobility : + + /*-----------------------------------------------------------* + * Ids: channel current. + *-----------------*/ + betaWL = here->HSM2_weff_nf * beta_inv / Lch ; + T1 = - betaWL / Lch ; + betaWL_dVbs = T1 * Lch_dVbs ; + betaWL_dVds = T1 * Lch_dVds ; + betaWL_dVgs = T1 * Lch_dVgs ; + + Ids0 = betaWL * Idd * Mu ; + T1 = betaWL * Idd ; + T2 = Idd * Mu ; + T3 = Mu * betaWL ; + Ids0_dVbs = T3 * Idd_dVbs + T1 * Mu_dVbs + T2 * betaWL_dVbs ; + Ids0_dVds = T3 * Idd_dVds + T1 * Mu_dVds + T2 * betaWL_dVds ; + Ids0_dVgs = T3 * Idd_dVgs + T1 * Mu_dVgs + T2 * betaWL_dVgs ; + + /*-----------------------------------------------------------* + * Adding parasitic components to the channel current. + *-----------------*/ + if( model->HSM2_ptl != 0 ){ + T1 = 0.5 * ( Vds - Pds ) ; + Fn_SymAdd( T6 , T1 , 0.01 , T2 ) ; + T2 *= 0.5 ; + T6_dVb = T2 * ( - Pds_dVbs ) ; + T6_dVd = T2 * ( 1.0 - Pds_dVds ) ; + T6_dVg = T2 * ( - Pds_dVgs ) ; + + T1 = 1.1 - ( Ps0 + T6 ); + T1_dVb = - ( Ps0_dVbs + T6_dVb ); + T1_dVd = - ( Ps0_dVds + T6_dVd ); + T1_dVg = - ( Ps0_dVgs + T6_dVg ); + + Fn_SZ( T2 , T1 , 0.05 , T0 ) ; + T2_dVb = T1_dVb * T0 ; + T2_dVd = T1_dVd * T0 ; + T2_dVg = T1_dVg * T0 ; + + T0 = beta * here->HSM2_ptl0 ; + T3 = Cox * T0 ; + T3_dVb = Cox_dVb * T0 ; + T3_dVd = Cox_dVd * T0 ; + T3_dVg = Cox_dVg * T0 ; + T0 = pow( T2 , model->HSM2_ptp ) ; + T9 = T3 * T0 ; + T9_dVb = T3 * model->HSM2_ptp * T0 / T2 * T2_dVb + T3_dVb * T0 ; + T9_dVd = T3 * model->HSM2_ptp * T0 / T2 * T2_dVd + T3_dVd * T0 ; + T9_dVg = T3 * model->HSM2_ptp * T0 / T2 * T2_dVg + T3_dVg * T0 ; + + + T4 = 1.0 + Vdsz * model->HSM2_pt2 ; + T4_dVb = 0.0 ; + T4_dVd = Vdsz_dVds * model->HSM2_pt2 ; + T4_dVg = 0.0 ; + + T0 = here->HSM2_pt40 ; + T5 = Ps0 + T6 - Vbsz ; + T5_dVb = Ps0_dVbs + T6_dVb - Vbsz_dVbs ; + T5_dVd = Ps0_dVds + T6_dVd - Vbsz_dVds ; + T5_dVg = Ps0_dVgs + T6_dVg ; + T4 += Vdsz * T0 * T5 ; + T4_dVb += Vdsz * T0 * T5_dVb ; + T4_dVd += Vdsz * T0 * T5_dVd + Vdsz_dVds * T0 * T5 ; + T4_dVg += Vdsz * T0 * T5_dVg ; + + T6 = T9 * T4 ; + T9_dVb = T9_dVb * T4 + T9 * T4_dVb ; + T9_dVd = T9_dVd * T4 + T9 * T4_dVd ; + T9_dVg = T9_dVg * T4 + T9 * T4_dVg ; + T9 = T6 ; + + }else{ + T9 = 0.0 ; + T9_dVb = 0.0 ; + T9_dVd = 0.0 ; + T9_dVg = 0.0 ; + } + + + if( model->HSM2_gdl != 0 ){ + T1 = beta * here->HSM2_gdl0 ; + T2 = Cox * T1 ; + T2_dVb = Cox_dVb * T1 ; + T2_dVd = Cox_dVd * T1 ; + T2_dVg = Cox_dVg * T1 ; + T8 = T2 * Vdsz ; + T8_dVb = T2_dVb * Vdsz ; + T8_dVd = T2_dVd * Vdsz + T2 * Vdsz_dVds ; + T8_dVg = T2_dVg * Vdsz ; + }else{ + T8 = 0.0 ; + T8_dVb = 0.0 ; + T8_dVd = 0.0 ; + T8_dVg = 0.0 ; + } + + + if ( ( T9 + T8 ) > 0.0 ) { + Idd1 = Pds * ( T9 + T8 ) ; + Idd1_dVbs = Pds_dVbs * ( T9 + T8 ) + Pds * ( T9_dVb + T8_dVb ) ; + Idd1_dVds = Pds_dVds * ( T9 + T8 ) + Pds * ( T9_dVd + T8_dVd ) ; + Idd1_dVgs = Pds_dVgs * ( T9 + T8 ) + Pds * ( T9_dVg + T8_dVg ) ; + + Ids0 += betaWL * Idd1 * Mu ; + T1 = betaWL * Idd1 ; + T2 = Idd1 * Mu ; + T3 = Mu * betaWL ; + Ids0_dVbs += T3 * Idd1_dVbs + T1 * Mu_dVbs + T2 * betaWL_dVbs ; + Ids0_dVds += T3 * Idd1_dVds + T1 * Mu_dVds + T2 * betaWL_dVds ; + Ids0_dVgs += T3 * Idd1_dVgs + T1 * Mu_dVgs + T2 * betaWL_dVgs ; + } + + + /* (note: rpock procedure was removed. (2006.04.20) */ + if ( flg_rsrd == 2 ) { + Rd = here->HSM2_rd ; + T0 = Rd * Ids0 ; + T1 = Vds + small ; + T2 = 1.0 / T1 ; + T3 = 1.0 + T0 * T2 ; + T3_dVb = Rd * Ids0_dVbs * T2 ; + T3_dVd = ( Rd * Ids0_dVds * T1 - T0 ) * T2 * T2 ; + T3_dVg = Rd * Ids0_dVgs * T2 ; + T4 = 1.0 / T3 ; + Ids = Ids0 * T4 ; + T5 = T4 * T4 ; + Ids_dVbs = ( Ids0_dVbs * T3 - Ids0 * T3_dVb ) * T5 ; + Ids_dVds = ( Ids0_dVds * T3 - Ids0 * T3_dVd ) * T5 ; + Ids_dVgs = ( Ids0_dVgs * T3 - Ids0 * T3_dVg ) * T5 ; + } else { + Ids = Ids0 ; + Ids_dVbs = Ids0_dVbs ; + Ids_dVds = Ids0_dVds ; + Ids_dVgs = Ids0_dVgs ; + } + + if ( Pds < ps_conv ) { + Ids_dVbs = 0.0 ; + Ids_dVgs = 0.0 ; + } + + Ids += Gdsmin * Vds ; + Ids_dVds += Gdsmin ; + + + /*-----------------------------------------------------------* + * STI + *-----------------*/ + if ( model->HSM2_coisti != 0 ) { + /*---------------------------------------------------* + * dVthSCSTI : Short-channel effect induced by Vds (STI). + *-----------------*/ + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdpl ; + T3 = here->HSM2_lgatesm - model->HSM2_parl2 ; + T4 = 1.0 / (T3 * T3) ; + T5 = 2.0 * (model->HSM2_vbi - Pb20b) * T1 * T2 * T4 ; + + dVth0 = T5 * sqrt_Pbsum ; + T6 = T5 * 0.5 / sqrt_Pbsum ; + T7 = 2.0 * (model->HSM2_vbi - Pb20b) * C_ESI * T2 * T4 * sqrt_Pbsum ; + T8 = - 2.0 * T1 * T2 * T4 * sqrt_Pbsum ; + dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ; + dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ; + dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ; + + T4 = pParam->HSM2_scsti1 ; + T6 = pParam->HSM2_scsti2 ; + T1 = T4 + T6 * Vdsz ; + dVthSCSTI = dVth0 * T1 ; + dVthSCSTI_dVb = dVth0_dVb * T1 ; + dVthSCSTI_dVd = dVth0_dVd * T1 + dVth0 * T6 * Vdsz_dVds ; + dVthSCSTI_dVg = dVth0_dVg * T1 ; + + T1 = pParam->HSM2_vthsti - model->HSM2_vdsti * Vds ; + T1_dVd = - model->HSM2_vdsti ; + + Vgssti = Vgsz - Vfb + T1 + dVthSCSTI ; + Vgssti_dVbs = dVthSCSTI_dVb ; + Vgssti_dVds = Vgsz_dVds + T1_dVd + dVthSCSTI_dVd ; + Vgssti_dVgs = Vgsz_dVgs + dVthSCSTI_dVg ; + + costi0 = here->HSM2_costi0 ; + costi1 = here->HSM2_costi1 ; + + costi3 = here->HSM2_costi0_p2 * Cox_inv * Cox_inv ; + T1 = 2.0 * here->HSM2_costi0_p2 * Cox_inv ; + costi3_dVb = T1 * Cox_inv_dVb ; + costi3_dVd = T1 * Cox_inv_dVd ; + costi3_dVg = T1 * Cox_inv_dVg ; + T2 = 1.0 / costi3 ; + costi3_dVb_c3 = costi3_dVb * T2 ; + costi3_dVd_c3 = costi3_dVd * T2 ; + costi3_dVg_c3 = costi3_dVg * T2 ; + + costi4 = costi3 * beta * 0.5 ; + costi5 = costi4 * beta * 2.0 ; + + T11 = beta * 0.25 ; + T10 = beta_inv - costi3 * T11 + Vfb - pParam->HSM2_vthsti - dVthSCSTI + small ; + T10_dVb = - T11 * costi3_dVb - dVthSCSTI_dVb ; + T10_dVd = - T11 * costi3_dVd - dVthSCSTI_dVd ; + T10_dVg = - T11 * costi3_dVg - dVthSCSTI_dVg ; + T1 = Vgsz - T10 - psisti_dlt ; + T1_dVb = - T10_dVb ; + T1_dVd = Vgsz_dVds - T10_dVd ; + T1_dVg = Vgsz_dVgs - T10_dVg ; + T0 = Fn_Sgn(T10) ; + T2 = sqrt (T1 * T1 + T0 * 4.0 * T10 * psisti_dlt) ; + T3 = T10 + 0.5 * (T1 + T2) - Vfb + pParam->HSM2_vthsti + dVthSCSTI - Vbsz ; + T3_dVb = T10_dVb + 0.5 * (T1_dVb + (T1 * T1_dVb + T0 * 2.0 * T10_dVb * psisti_dlt) / T2) + + dVthSCSTI_dVb - Vbsz_dVbs ; + T3_dVd = T10_dVd + 0.5 * (T1_dVd + (T1 * T1_dVd + T0 * 2.0 * T10_dVd * psisti_dlt) / T2) + + dVthSCSTI_dVd - Vbsz_dVds ; + T3_dVg = T10_dVg + 0.5 * (T1_dVg + (T1 * T1_dVg + T0 * 2.0 * T10_dVg * psisti_dlt) / T2) + + dVthSCSTI_dVg ; + T4 = beta * T3 - 1.0 ; + T5 = 4.0 / costi5 ; + T1 = 1.0 + T4 * T5 ; + T6 = beta * T5 ; + T7 = T4 * T5 ; + T1_dVb = (T6 * T3_dVb - T7 * costi3_dVb_c3) ; + T1_dVd = (T6 * T3_dVd - T7 * costi3_dVd_c3) ; + T1_dVg = (T6 * T3_dVg - T7 * costi3_dVg_c3) ; + Fn_SZ( T1 , T1, 1.0e-2, T2) ; + T1_dVb *= T2 ; + T1_dVd *= T2 ; + T1_dVg *= T2 ; + costi6 = sqrt (T1) ; + T0 = costi4 * (1.0 - costi6) ; + Psasti = Vgssti + T0 ; + T2 = 0.5 * costi4 / costi6 ; + Psasti_dVbs = Vgssti_dVbs + costi3_dVb_c3 * T0 - T2 * T1_dVb ; + Psasti_dVds = Vgssti_dVds + costi3_dVd_c3 * T0 - T2 * T1_dVd ; + Psasti_dVgs = Vgssti_dVgs + costi3_dVg_c3 * T0 - T2 * T1_dVg ; + + T0 = 1.0 / (beta + 2.0 / (Vgssti + small)) ; + Psbsti = log (1.0 / costi1 / costi3 * (Vgssti * Vgssti)) * T0 ; + T2 = 2.0 * T0 / (Vgssti + small) ; + T3 = Psbsti / (Vgssti + small) ; + Psbsti_dVbs = T2 * (Vgssti_dVbs - 0.5 * costi3_dVb_c3 * Vgssti + + T3 * Vgssti_dVbs ) ; + Psbsti_dVds = T2 * (Vgssti_dVds - 0.5 * costi3_dVd_c3 * Vgssti + + T3 * Vgssti_dVds ) ; + Psbsti_dVgs = T2 * (Vgssti_dVgs - 0.5 * costi3_dVg_c3 * Vgssti + + T3 * Vgssti_dVgs ) ; + + Psab = Psbsti - Psasti - sti2_dlt ; + Psab_dVbs = Psbsti_dVbs - Psasti_dVbs ; + Psab_dVds = Psbsti_dVds - Psasti_dVds ; + Psab_dVgs = Psbsti_dVgs - Psasti_dVgs ; + T0 = sqrt (Psab * Psab + 4.0 * sti2_dlt * Psbsti) ; + Psti = Psbsti - 0.5 * (Psab + T0) ; + T1 = 1.0 / T0 ; + Psti_dVbs = Psbsti_dVbs + - 0.5 * ( Psab_dVbs + + ( Psab * Psab_dVbs + 2.0 * sti2_dlt * Psbsti_dVbs ) * T1 ) ; + Psti_dVds = Psbsti_dVds + - 0.5 * ( Psab_dVds + + ( Psab * Psab_dVds + 2.0 * sti2_dlt * Psbsti_dVds ) * T1 ) ; + Psti_dVgs = Psbsti_dVgs + - 0.5 * ( Psab_dVgs + + ( Psab * Psab_dVgs + 2.0 * sti2_dlt * Psbsti_dVgs ) * T1 ) ; + + T0 = costi1 * exp (beta * Psti) ; + T1 = beta * (Psti - Vbsz) - 1.0 + T0 ; + T1_dVb = beta * ((Psti_dVbs - Vbsz_dVbs) + T0 * Psti_dVbs) ; + T1_dVd = beta * ((Psti_dVds - Vbsz_dVds) + T0 * Psti_dVds) ; + T1_dVg = beta * (Psti_dVgs + T0 * Psti_dVgs) ; + Fn_SZ ( T1 , T1, 1.0e-2, T0) ; + T1 += epsm10 ; + T1_dVb *= T0 ; + T1_dVd *= T0 ; + T1_dVg *= T0 ; + sq1sti = sqrt (T1); + T2 = 0.5 / sq1sti ; + sq1sti_dVbs = T2 * T1_dVb ; + sq1sti_dVds = T2 * T1_dVd ; + sq1sti_dVgs = T2 * T1_dVg ; + + T1 = beta * (Psti - Vbsz) - 1.0; + T1_dVb = beta * (Psti_dVbs - Vbsz_dVbs) ; + T1_dVd = beta * (Psti_dVds - Vbsz_dVds) ; + T1_dVg = beta * Psti_dVgs ; + Fn_SZ( T1 , T1, 1.0e-2, T0) ; + T1 += epsm10 ; + T1_dVb *= T0 ; + T1_dVd *= T0 ; + T1_dVg *= T0 ; + sq2sti = sqrt (T1); + T2 = 0.5 / sq2sti ; + sq2sti_dVbs = T2 * T1_dVb ; + sq2sti_dVds = T2 * T1_dVd ; + sq2sti_dVgs = T2 * T1_dVg ; + + Qn0sti = costi0 * (sq1sti - sq2sti) ; + Qn0sti_dVbs = costi0 * (sq1sti_dVbs - sq2sti_dVbs) ; + Qn0sti_dVds = costi0 * (sq1sti_dVds - sq2sti_dVds) ; + Qn0sti_dVgs = costi0 * (sq1sti_dVgs - sq2sti_dVgs) ; + + /* T1: Vdsatsti */ + T1 = Psasti - Psti ; + T1_dVb = Psasti_dVbs - Psti_dVbs ; + T1_dVd = Psasti_dVds - Psti_dVds ; + T1_dVg = Psasti_dVgs - Psti_dVgs ; + + Fn_SZ( T1 , T1 , 1.0e-1 , T2 ) ; + T1_dVb *= T2 ; + T1_dVd *= T2 ; + T1_dVg *= T2 ; + + + TX = Vds / T1 ; + T2 = 1.0 / ( T1 * T1 ) ; + TX_dVbs = T2 * ( - Vds * T1_dVb ) ; + TX_dVds = T2 * ( T1 - Vds * T1_dVd ) ; + TX_dVgs = T2 * ( - Vds * T1_dVg ) ; + + Fn_CP( TY , TX , 1.0 , 4 , T2 ) ; + TY_dVbs = T2 * TX_dVbs ; + TY_dVds = T2 * TX_dVds ; + TY_dVgs = T2 * TX_dVgs ; + + costi7 = 2.0 * here->HSM2_wsti * here->HSM2_nf * beta_inv ; + T1 = Lch ; + Idssti = costi7 * Mu * Qn0sti * TY / T1; + T3 = 1.0 / T1 ; + T4 = Mu * Qn0sti * TY / T1 / T1 ; + T5 = Mu * Qn0sti ; + Idssti_dVbs = costi7 * (((Mu_dVbs * Qn0sti + Mu * Qn0sti_dVbs) * TY + + T5 * TY_dVbs ) * T3 + - Lch_dVbs * T4 ) ; + Idssti_dVds = costi7 * (((Mu_dVds * Qn0sti + Mu * Qn0sti_dVds) * TY + + T5 * TY_dVds ) * T3 + - Lch_dVds * T4 ) ; + Idssti_dVgs = costi7 * (((Mu_dVgs * Qn0sti + Mu * Qn0sti_dVgs) * TY + + T5 * TY_dVgs ) * T3 + - Lch_dVgs * T4 ) ; + + Ids = Ids + Idssti ; + Ids_dVbs = Ids_dVbs + Idssti_dVbs ; + Ids_dVds = Ids_dVds + Idssti_dVds ; + Ids_dVgs = Ids_dVgs + Idssti_dVgs ; + + } + + /*-----------------------------------------------------------* + * Break point for the case of Rs=Rd=0. + *-----------------*/ + if ( flg_rsrd == 0 ) { + DJI = 1.0 ; + break ; + } + + /*-----------------------------------------------------------* + * calculate corrections of biases. + * - Fbs = 0, etc. are the small ciucuit equations. + * - DJ, Jacobian of the small circuit matrix, is g.t. 1 + * provided Rs, Rd and conductances are positive. + *-----------------*/ + Fbs = Vbs - Vbsc + Ids * Rs ; + Fds = Vds - Vdsc + Ids * ( Rs + Rd ) ; + Fgs = Vgs - Vgsc + Ids * Rs ; + + DJ = 1.0 + Rs * Ids_dVbs + ( Rs + Rd ) * Ids_dVds + Rs * Ids_dVgs ; + DJI = 1.0 / DJ ; + + JI11 = 1 + ( Rs + Rd ) * Ids_dVds + Rs * Ids_dVgs ; + JI12 = - Rs * Ids_dVds ; + JI13 = - Rs * Ids_dVgs ; + JI21 = - ( Rs + Rd ) * Ids_dVbs ; + JI22 = 1 + Rs * Ids_dVbs + Rs * Ids_dVgs ; + JI23 = - ( Rs + Rd ) * Ids_dVgs ; + JI31 = - Rs * Ids_dVbs ; + JI32 = - Rs * Ids_dVds ; + JI33 = 1 + Rs * Ids_dVbs + ( Rs + Rd ) * Ids_dVds ; + + dVbs = - DJI * ( JI11 * Fbs + JI12 * Fds + JI13 * Fgs ) ; + dVds = - DJI * ( JI21 * Fbs + JI22 * Fds + JI23 * Fgs ) ; + dVgs = - DJI * ( JI31 * Fbs + JI32 * Fds + JI33 * Fgs ) ; + + dV_sum = fabs( dVbs ) + fabs( dVds ) + fabs( dVgs ) ; + + + /*-----------------------------------------------------------* + * Break point for converged case. + * - Exit from the bias loop. + * - NOTE: Update of internal biases is avoided. + *-----------------*/ + if ( Ids_last * Ids_tol >= fabs( Ids_last - Ids ) || mini_current >= fabs( Ids_last - Ids ) + || dV_sum < ps_conv ) break ; + + /*-----------------------------------------------------------* + * Update the internal biases. + *-----------------*/ + Vbs = Vbs + dVbs ; + Vds = Vds + dVds ; + Vgs = Vgs + dVgs ; + if ( Vds < 0.0 ) { + Vds = 0.0 ; + dVds = 0.0 ; + } + + /*-----------------------------------------------------------* + * Bottom of bias loop. (label) + *-----------------*/ + bottom_of_bias_loop : + + /*-----------------------------------------------------------* + * Make initial guess flag of potential ON. + * - This effects for the 2nd and later iterations of bias loop. + *-----------------*/ + flg_pprv = 1 ; + + } /*++ End of the bias loop +++++++++++++++++++++++++++++*/ + + if ( lp_bs > lp_bs_max ) { lp_bs -- ; } + + + + /*----------------------------------------------------------* + * induced gate noise. ( Part 1/3 ) + *----------------------*/ + if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 ) { + kusai00 = VgVt * VgVt ; + kusaidd = 2.0e0 * beta_inv * Cox_inv * Idd ; + kusaiL = kusai00 - kusaidd ; + Fn_SZ( kusai00 , kusai00 , 1.0e-3 , T0 ) ; + Fn_SZ( kusaiL , kusaiL , 1.0e-3 , T0 ) ; + kusai00L = kusai00 - kusaiL ; + if ( Qn0 < epsm10 || kusai00L < epsm10 ) flg_ign = 0 ; + else flg_ign = 1 ; + } + + + + /*-----------------------------------------------------------* + * End of PART-1. (label) + *-----------------*/ + end_of_part_1: + + /*----------------------------------------------------------* + * Evaluate integrated chages in unit [C]. + *----------------------*/ + + T1 = - here->HSM2_weff_nf * Leff ; + + Qb = T1 * Qbu ; + Qb_dVbs = T1 * Qbu_dVbs ; + Qb_dVds = T1 * Qbu_dVds ; + Qb_dVgs = T1 * Qbu_dVgs ; + + Qi = T1 * Qiu ; + Qi_dVbs = T1 * Qiu_dVbs ; + Qi_dVds = T1 * Qiu_dVds ; + Qi_dVgs = T1 * Qiu_dVgs ; + + Qd = Qi * Qdrat ; + Qd_dVbs = Qi_dVbs * Qdrat + Qi * Qdrat_dVbs ; + Qd_dVds = Qi_dVds * Qdrat + Qi * Qdrat_dVds ; + Qd_dVgs = Qi_dVgs * Qdrat + Qi * Qdrat_dVgs ; + + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-2: Substrate / gate / leak currents + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + /*-----------------------------------------------------------* + * Isub : substrate current induced by impact ionization. + *-----------------*/ + + if ( flg_noqi == 1 || model->HSM2_coisub == 0 ) { + /* Accumulation zone or nonconductive case, in which Ids==0. */ + Isub = 0.0e0 ; + Isub_dVbs = Isub_dVds = Isub_dVgs = 0.0e0 ; + } else { + /*-------------------------------------------* + * Conductive case. + *-----------------*/ + if ( pParam->HSM2_sub1 > 0.0e0 && pParam->HSM2_vmax > 0.0e0 ) { + T0 = here->HSM2_vg2const ; + T1 = T0 * Vgp ; + T1_dVd = T0 * Vgp_dVds ; + T1_dVg = T0 * Vgp_dVgs ; + T1_dVb = T0 * Vgp_dVbs ; + + T7 = Cox0 * Cox0 ; + T8 = here->HSM2_qnsub_esi ; + T3 = T8 / T7 ; + + T9 = 2.0 / T8 ; + T4 = 1.0e0 + T9 * T7 ; + + T2 = here->HSM2_xvbs ; + T5 = T1 - beta_inv - T2 * Vbsz ; + T5_dVd = T1_dVd - T2 * Vbsz_dVds; + T5_dVg = T1_dVg ; + T5_dVb = T1_dVb - T2 * Vbsz_dVbs; + + T6 = T4 * T5 ; + T6_dVd = T4 * T5_dVd ; + T6_dVg = T4 * T5_dVg ; + T6_dVb = T4 * T5_dVb ; + Fn_SZ( T6 , T6, 1.0e-3, T9) ; + T6 += small ; + T6_dVd *= T9 ; + T6_dVg *= T9 ; + T6_dVb *= T9 ; + T6 = sqrt( T6 ) ; + T9 = 0.5 / T6 ; + T6_dVd = T9 * T6_dVd ; + T6_dVg = T9 * T6_dVg ; + T6_dVb = T9 * T6_dVb ; + + Psislsat = T1 + T3 * ( 1.0 - T6 ) ; + Psislsat_dVd = T1_dVd - T3 * T6_dVd ; + Psislsat_dVg = T1_dVg - T3 * T6_dVg ; + Psislsat_dVb = T1_dVb - T3 * T6_dVb ; + + T2 = here->HSM2_lgate / (here->HSM2_xgate + here->HSM2_lgate) ; + + Psisubsat = pParam->HSM2_svds * Vdsz + Ps0z - T2 * Psislsat ; + Psisubsat_dVd = pParam->HSM2_svds * Vdsz_dVds + Ps0z_dVds - T2 * Psislsat_dVd ; + Psisubsat_dVg = Ps0z_dVgs - T2 * Psislsat_dVg ; + Psisubsat_dVb = Ps0z_dVbs - T2 * Psislsat_dVb ; + Fn_SZ( Psisubsat , Psisubsat, 1.0e-3, T9 ) ; + Psisubsat += small ; + Psisubsat_dVd *= T9 ; + Psisubsat_dVg *= T9 ; + Psisubsat_dVb *= T9 ; + + T5 = here->HSM2_xsub1 ; + T6 = here->HSM2_xsub2 ; + T2 = exp( - T6 / Psisubsat ) ; + T3 = T2 * T6 / ( Psisubsat * Psisubsat ) ; + T2_dVd = T3 * Psisubsat_dVd ; + T2_dVg = T3 * Psisubsat_dVg ; + T2_dVb = T3 * Psisubsat_dVb ; + + Isub = T5 * Psisubsat * Ids * T2 ; + Isub_dVds = T5 * ( Psisubsat_dVd * Ids * T2 + + Psisubsat * Ids_dVds * T2 + + Psisubsat * Ids * T2_dVd ) ; + Isub_dVgs = T5 * ( Psisubsat_dVg * Ids * T2 + + Psisubsat * Ids_dVgs * T2 + + Psisubsat * Ids * T2_dVg ) ; + Isub_dVbs = T5 * ( Psisubsat_dVb * Ids * T2 + + Psisubsat * Ids_dVbs * T2 + + Psisubsat * Ids * T2_dVb ) ; + } else { + Isub = 0.0e0 ; + Isub_dVbs = Isub_dVds = Isub_dVgs = 0.0e0 ; + } /* end of if ( pParam->HSM2_sub1 ... ) else block. */ + } + + + /*---------------------------------------------------* + * Impact-Ionization Induced Bulk Potential Change (IBPC) + *-----------------*/ + if ( flg_noqi == 0 && Isub > 0e0 && pParam->HSM2_ibpc1 != 0e0 ) { + + /* delta Vbs */ + T0 = 1e0 + pParam->HSM2_ibpc2 * dVth ; + dVbsIBPC = pParam->HSM2_ibpc1 * T0 * Isub ; + dVbsIBPC_dVbs = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVb * Isub + T0 * Isub_dVbs ) ; + dVbsIBPC_dVds = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVd * Isub + T0 * Isub_dVds ) ; + dVbsIBPC_dVgs = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVg * Isub + T0 * Isub_dVgs ) ; + + /* dG3 & dG4 */ + T10 = 1e0 / Xi0 ; + T1 = beta * dVbsIBPC * T10 ; + T10 *= T10 ; + T1_dVb = beta * ( dVbsIBPC_dVbs * Xi0 - dVbsIBPC * Xi0_dVbs ) * T10 ; + T1_dVd = beta * ( dVbsIBPC_dVds * Xi0 - dVbsIBPC * Xi0_dVds ) * T10 ; + T1_dVg = beta * ( dVbsIBPC_dVgs * Xi0 - dVbsIBPC * Xi0_dVgs ) * T10 ; + + T10 = 1e0 / Xil ; + T2 = beta * dVbsIBPC * T10 ; + T10 *= T10 ; + T2_dVb = beta * ( dVbsIBPC_dVbs * Xil - dVbsIBPC * Xil_dVbs ) * T10 ; + T2_dVd = beta * ( dVbsIBPC_dVds * Xil - dVbsIBPC * Xil_dVds ) * T10 ; + T2_dVg = beta * ( dVbsIBPC_dVgs * Xil - dVbsIBPC * Xil_dVgs ) * T10 ; + + dG3 = cnst0 * ( Xilp32 * T2 - Xi0p32 * T1 ) ; + dG3_dVbs = cnst0 * ( Xilp32_dVbs * T2 + Xilp32 * T2_dVb - Xi0p32_dVbs * T1 - Xi0p32 * T1_dVb ) ; + dG3_dVds = cnst0 * ( Xilp32_dVds * T2 + Xilp32 * T2_dVd - Xi0p32_dVds * T1 - Xi0p32 * T1_dVd ) ; + dG3_dVgs = cnst0 * ( Xilp32_dVgs * T2 + Xilp32 * T2_dVg - Xi0p32_dVgs * T1 - Xi0p32 * T1_dVg ) ; + dG4 = cnst0 * 0.5 * ( - Xilp12 * T2 + Xi0p12 * T1 ) ; + dG4_dVbs = cnst0 * 0.5 * ( - Xilp12_dVbs * T2 - Xilp12 * T2_dVb + Xi0p12_dVbs * T1 + Xi0p12 * T1_dVb ) ; + dG4_dVds = cnst0 * 0.5 * ( - Xilp12_dVds * T2 - Xilp12 * T2_dVd + Xi0p12_dVds * T1 + Xi0p12 * T1_dVd ) ; + dG4_dVgs = cnst0 * 0.5 * ( - Xilp12_dVgs * T2 - Xilp12 * T2_dVg + Xi0p12_dVgs * T1 + Xi0p12 * T1_dVg ) ; + + /* Add IBPC current into Ids */ + dIdd = dG3 + dG4 ; + dIdd_dVbs = dG3_dVbs + dG4_dVbs ; + dIdd_dVds = dG3_dVds + dG4_dVds ; + dIdd_dVgs = dG3_dVgs + dG4_dVgs ; + IdsIBPC = betaWL * dIdd * Mu ; + IdsIBPC_dVbs = betaWL * ( Mu * dIdd_dVbs + dIdd * Mu_dVbs ) + betaWL_dVbs * Mu * dIdd ; + IdsIBPC_dVds = betaWL * ( Mu * dIdd_dVds + dIdd * Mu_dVds ) + betaWL_dVds * Mu * dIdd ; + IdsIBPC_dVgs = betaWL * ( Mu * dIdd_dVgs + dIdd * Mu_dVgs ) + betaWL_dVgs * Mu * dIdd ; + + } /* End if (IBPC) */ + + /*-----------------------------------------------------------* + * Igate : Gate current induced by tunneling. + *-----------------*/ + if ( model->HSM2_coiigs == 0 ) { + Igate = 0.0 ; + Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ; + Igs = 0.0 ; + Igs_dVbs = Igs_dVds = Igs_dVgs = 0.0 ; + Igd = 0.0 ; + Igd_dVbs = Igd_dVds = Igd_dVgs = 0.0 ; + Igb = 0.0 ; + Igb_dVbs = Igb_dVds = Igb_dVgs = 0.0 ; + GLPART1 = 0.0 ; + GLPART1_dVgs = GLPART1_dVds = GLPART1_dVbs = 0.0 ; + } else { + + + /* Igate */ + if ( flg_noqi == 0 ) { + Psdlz = Ps0z + Vdsz - epsm10 ; + Psdlz_dVbs = Ps0z_dVbs ; + Psdlz_dVds = Ps0z_dVds + Vdsz_dVds ; + Psdlz_dVgs = Ps0z_dVgs ; + + T1 = Vgsz - Vfb + model->HSM2_gleak4 * (dVth - dPpg) * Leff - Psdlz * pParam->HSM2_gleak3 ; + T1_dVg = Vgsz_dVgs + model->HSM2_gleak4 * (dVth_dVg - dPpg_dVg) * Leff - Psdlz_dVgs * pParam->HSM2_gleak3 ; + T1_dVd = Vgsz_dVds + model->HSM2_gleak4 * (dVth_dVd - dPpg_dVd) * Leff - Psdlz_dVds * pParam->HSM2_gleak3 ; + T1_dVb = model->HSM2_gleak4 * ( dVth_dVb - dPpg_dVb ) * Leff - Psdlz_dVbs * pParam->HSM2_gleak3 ; + + T3 = 1.0 / Tox0 ; + T2 = T1 * T3 ; + T2_dVg = (T1_dVg ) * T3 ; + T2_dVd = (T1_dVd ) * T3 ; + T2_dVb = (T1_dVb ) * T3 ; + + T3 = 1.0 / model->HSM2_gleak5 ; + + if ( VgVt <= VgVt_small ) { + Ey = 0.0 ; + Ey_dVgs = 0.0 ; + Ey_dVds = 0.0 ; + Ey_dVbs = 0.0 ; + } + T7 = 1.0 + Ey * T3 ; + T7_dVg = Ey_dVgs * T3 ; + T7_dVd = Ey_dVds * T3 ; + T7_dVb = Ey_dVbs * T3 ; + + Etun = T2 * T7 ; + Etun_dVgs = T2_dVg * T7 + T7_dVg * T2 ; + Etun_dVds = T2_dVd * T7 + T7_dVd * T2 ; + Etun_dVbs = T2_dVb * T7 + T7_dVb * T2 ; + + Fn_SZ( Etun , Etun , igate_dlt , T5 ) ; + Etun_dVgs *= T5 ; + Etun_dVds *= T5 ; + Etun_dVbs *= T5 ; + + Fn_SZ( T3 , Vgsz , 1.0e-3 , T4 ) ; + T3 -= model->HSM2_vzadd0 ; + TX = T3 / cclmmdf ; + T2 = 1.0 + TX * TX ; + T1 = 1.0 - 1.0 / T2 ; + T1_dVg = 2.0 * TX * T4 / ( T2 * T2 * cclmmdf ) ; + T1_dVd = T1_dVg * Vgsz_dVds ; + Etun_dVgs = T1 * Etun_dVgs + Etun * T1_dVg ; + Etun_dVds = T1 * Etun_dVds + Etun * T1_dVd ; + Etun_dVbs *= T1 ; + Etun *= T1 ; + + T0 = Leff * here->HSM2_weff_nf ; + T7 = model->HSM2_gleak7 / (model->HSM2_gleak7 + T0) ; + + T6 = pParam->HSM2_gleak6 ; + T9 = T6 / (T6 + Vdsz) ; + T9_dVd = - T9 / (T6 + Vdsz) * Vdsz_dVds ; + + T1 = - pParam->HSM2_gleak2 * Egp32 / (Etun + small) ; + + if ( T1 < - EXP_THR ) { + Igate = 0.0 ; + Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ; + } else { + T2 = exp ( T1 ) ; + T3 = pParam->HSM2_gleak1 / Egp12 * C_QE * T0 ; + + T4 = T2 * T3 * sqrt ((Qiu + Cox0 * VgVt_small ) / cnst0) ; + T5 = T4 * Etun ; + T6 = 0.5 * Etun / (Qiu + Cox0 * VgVt_small ) ; + T10 = T5 * Etun ; + T10_dVb = T5 * (2.0 * Etun_dVbs - T1 * Etun_dVbs + T6 * Qiu_dVbs) ; + T10_dVd = T5 * (2.0 * Etun_dVds - T1 * Etun_dVds + T6 * Qiu_dVds) ; + T10_dVg = T5 * (2.0 * Etun_dVgs - T1 * Etun_dVgs + T6 * Qiu_dVgs) ; + + Igate = T7 * T9 * T10 ; + Igate_dVbs = T7 * T9 * T10_dVb ; + Igate_dVds = T7 * (T9_dVd * T10 + T9 * T10_dVd) ; + Igate_dVgs = T7 * T9 * T10_dVg ; + } + } else { + Igate = 0.0 ; + Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ; + } + + /* Igs */ + T0 = - pParam->HSM2_glksd2 * Vgs + model->HSM2_glksd3 ; + T2 = exp (Tox0 * T0); + T2_dVg = (- Tox0 * pParam->HSM2_glksd2) * T2; + + T0 = Vgs / Tox0 / Tox0 ; + T3 = Vgs * T0 ; + T3_dVg = 2.0 * T0 * (1.0 ) ; + T4 = pParam->HSM2_glksd1 / 1.0e6 * here->HSM2_weff_nf ; + Igs = T4 * T2 * T3 ; + Igs_dVgs = T4 * (T2_dVg * T3 + T2 * T3_dVg) ; + Igs_dVds = 0.0 ; + Igs_dVbs = 0.0 ; + + if ( Vgs >= 0.0e0 ){ + Igs *= -1.0 ; + Igs_dVgs *= -1.0 ; + Igs_dVds *= -1.0 ; + Igs_dVbs *= -1.0 ; + } + + + /* Igd */ + T1 = Vgs - Vds ; + T0 = - pParam->HSM2_glksd2 * T1 + model->HSM2_glksd3 ; + T2 = exp (Tox0 * T0); + T2_dVg = (- Tox0 * pParam->HSM2_glksd2) * T2; + T2_dVd = (+ Tox0 * pParam->HSM2_glksd2) * T2; + T2_dVb = 0.0 ; + + T0 = T1 / Tox0 / Tox0 ; + T3 = T1 * T0 ; + T3_dVg = 2.0 * T0 ; + T3_dVd = - 2.0 * T0 ; + T3_dVb = 0.0 ; + T4 = pParam->HSM2_glksd1 / 1.0e6 * here->HSM2_weff_nf ; + Igd = T4 * T2 * T3 ; + Igd_dVgs = T4 * (T2_dVg * T3 + T2 * T3_dVg) ; + Igd_dVds = T4 * (T2_dVd * T3 + T2 * T3_dVd) ; + Igd_dVbs = 0.0 ; + + if( T1 >= 0.0e0 ){ + Igd *= -1.0 ; + Igd_dVgs *= -1.0 ; + Igd_dVds *= -1.0 ; + Igd_dVbs *= -1.0 ; + } + + + /* Igb */ + Etun = (- Vgs + Vbs + Vfb + model->HSM2_glkb3 ) / Tox0 ; + + Etun_dVgs = - 1.0 / Tox0 ; + Etun_dVds = 0.0 ; + Etun_dVbs = 1.0 / Tox0 ; + + Fn_SZ( Etun , Etun, igate_dlt, T5) ; + Etun += small ; + Etun_dVgs *= T5 ; + Etun_dVbs *= T5 ; + + T1 = - pParam->HSM2_glkb2 / Etun ; + if ( T1 < - EXP_THR ) { + Igb = 0.0 ; + Igb_dVgs = Igb_dVds = Igb_dVbs = 0.0 ; + } else { + T2 = exp ( T1 ); + T3 = pParam->HSM2_glkb2 / ( Etun * Etun ) * T2 ; + T2_dVg = T3 * Etun_dVgs ; + T2_dVb = T3 * Etun_dVbs ; + + T3 = pParam->HSM2_glkb1 * here->HSM2_weff_nf * Leff ; + Igb = T3 * Etun * Etun * T2 ; + Igb_dVgs = T3 * (2.0 * Etun * Etun_dVgs * T2 + Etun * Etun * T2_dVg); + Igb_dVds = 0.0 ; + Igb_dVbs = T3 * (2.0 * Etun * Etun_dVbs * T2 + Etun * Etun * T2_dVb); + } + + GLPART1 = 0.5 ; + GLPART1_dVgs = 0.0 ; + GLPART1_dVds = 0.0 ; + GLPART1_dVbs = 0.0 ; + + } /* if ( model->HSM2_coiigs == 0 ) */ + + + + + /*-----------------------------------------------------------* + * Igidl : GIDL + *-----------------*/ + if( model->HSM2_cogidl == 0 ){ + Igidl = 0.0e0 ; + Igidl_dVbs = 0.0e0 ; + Igidl_dVds = 0.0e0 ; + Igidl_dVgs = 0.0e0 ; + } else { + T1 = model->HSM2_gidl3 * (Vds + model->HSM2_gidl4) - Vgs + (dVthSC + dVthLP) * model->HSM2_gidl5 ; + + T2 = 1.0 / Tox0 ; + E1 = T1 * T2 ; + + E1_dVb = model->HSM2_gidl5 * (dVthSC_dVb + dVthLP_dVb) * T2 ; + E1_dVd = ( model->HSM2_gidl3 + model->HSM2_gidl5 * (dVthSC_dVd + dVthLP_dVd) ) * T2 ; + E1_dVg = ( -1.0 + model->HSM2_gidl5 * (dVthSC_dVg + dVthLP_dVg) ) * T2 ; + + Fn_SZ( Egidl , E1, eef_dlt, T5) ; + Egidl_dVb = T5 * E1_dVb ; + Egidl_dVd = T5 * E1_dVd ; + Egidl_dVg = T5 * E1_dVg ; + + T0 = - pParam->HSM2_gidl2 * Egp32 / (Egidl + small) ; + if ( T0 < - EXP_THR ) { + Igidl = 0.0 ; + Igidl_dVbs = Igidl_dVds = Igidl_dVgs = 0.0 ; + } else { + T1 = exp ( T0 ) ; + T2 = pParam->HSM2_gidl1 / Egp12 * C_QE * here->HSM2_weff_nf ; + Igidl = T2 * Egidl * Egidl * T1 ; + T3 = T2 * T1 * Egidl * (2.0 + pParam->HSM2_gidl2 * Egp32 * Egidl / (Egidl + small) / (Egidl + small)) ; + Igidl_dVbs = T3 * Egidl_dVb ; + Igidl_dVds = T3 * Egidl_dVd ; + Igidl_dVgs = T3 * Egidl_dVg ; + } + + Vdb = Vds - Vbs ; + if ( Vdb > 0.0 ) { + T2 = Vdb * Vdb ; + T4 = T2 * Vdb ; + T0 = T4 + C_gidl_delta ; + T5 = T4 / T0 ; + T7 = ( 3.0 * T2 * T0 - T4 * 3.0 * T2 ) / ( T0 * T0 ) ; /* == T5_dVdb */ + Igidl_dVbs = Igidl_dVbs * T5 + Igidl * T7 * ( - 1.0 ) ; /* Vdb_dVbs = -1 */ + Igidl_dVds = Igidl_dVds * T5 + Igidl * T7 * ( + 1.0 ) ; /* Vdb_dVds = +1 */ + Igidl_dVgs = Igidl_dVgs * T5 ; /* Vdb_dVgs = 0 */ + Igidl *= T5 ; + } else { + Igidl = 0.0 ; + Igidl_dVbs = Igidl_dVds = Igidl_dVgs = 0.0 ; + } + + } + + + /*-----------------------------------------------------------* + * Igisl : GISL + *-----------------*/ + if( model->HSM2_cogidl == 0){ + Igisl = 0.0e0 ; + Igisl_dVbs = 0.0e0 ; + Igisl_dVds = 0.0e0 ; + Igisl_dVgs = 0.0e0 ; + } else { + T1 = model->HSM2_gidl3 * ( - Vds + model->HSM2_gidl4 ) + - ( Vgs - Vds ) + ( dVthSC + dVthLP ) * model->HSM2_gidl5 ; + T2 = 1.0 / Tox0 ; + E1 = T1 * T2 ; + E1_dVb = model->HSM2_gidl5 * (dVthSC_dVb + dVthLP_dVb) * T2 ; + E1_dVd = ( -1.0 * model->HSM2_gidl3 + 1.0 + model->HSM2_gidl5 * (dVthSC_dVd + dVthLP_dVd) ) * T2 ; + E1_dVg = ( -1.0 + model->HSM2_gidl5 * (dVthSC_dVg + dVthLP_dVg) ) * T2 ; + + Fn_SZ( Egisl , E1, eef_dlt, T5) ; + Egisl_dVb = T5 * E1_dVb ; + Egisl_dVd = T5 * E1_dVd ; + Egisl_dVg = T5 * E1_dVg ; + + T0 = - pParam->HSM2_gidl2 * Egp32 / (Egisl + small) ; + if ( T0 < - EXP_THR ) { + Igisl = 0.0 ; + Igisl_dVbs = Igisl_dVds = Igisl_dVgs = 0.0 ; + } else { + T1 = exp ( T0 ) ; + T2 = pParam->HSM2_gidl1 / Egp12 * C_QE * here->HSM2_weff_nf ; + Igisl = T2 * Egisl * Egisl * T1 ; + T3 = T2 * T1 * Egisl * (2.0 + pParam->HSM2_gidl2 * Egp32 * Egisl / (Egisl + small) / (Egisl + small)) ; + Igisl_dVbs = T3 * Egisl_dVb ; + Igisl_dVds = T3 * Egisl_dVd ; + Igisl_dVgs = T3 * Egisl_dVg ; + } + + Vsb = - Vbs ; + if ( Vsb > 0.0 ) { + T2 = Vsb * Vsb ; + T4 = T2 * Vsb ; + T0 = T4 + C_gidl_delta ; + T5 = T4 / T0 ; + T7 = ( 3.0 * T2 * T0 - T4 * 3.0 * T2 ) / ( T0 * T0 ) ; /* == T5_dVsb */ + Igisl_dVbs = Igisl_dVbs * T5 + Igisl * T7 * ( - 1.0 ) ; /* Vsb_dVbs = -1 */ + Igisl_dVds = Igisl_dVds * T5 ; /* Vsb_dVds = 0 */ + Igisl_dVgs = Igisl_dVgs * T5 ; /* Vsb_dVgs = 0 */ + Igisl *= T5 ; + } else { + Igisl = 0.0 ; + Igisl_dVbs = Igisl_dVds = Igisl_dVgs = 0.0 ; + } + + } + + + /*-----------------------------------------------------------* + * End of PART-2. (label) + *-----------------*/ + end_of_part_2: + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-3: Overlap charge + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + Aclm = pParam->HSM2_clm1 ; + if ( flg_noqi != 0 ) { + /*-------------------------------------------* + * Calculation of Psdl for cases of flg_noqi==1. + *-----------------*/ + Psdl = Aclm * (Vds + Ps0) + (1.0e0 - Aclm) * Psl ; + Psdl_dVbs = Aclm * Ps0_dVbs + (1.0e0 - Aclm) * Psl_dVbs ; + Psdl_dVds = Aclm * (1.0e0 + Ps0_dVds) + (1.0e0 - Aclm) * Psl_dVds ; + Psdl_dVgs = Aclm * Ps0_dVgs + (1.0e0 - Aclm) * Psl_dVgs ; + if ( Psdl > Ps0 + Vds - epsm10 ) { + Psdl = Ps0 + Vds - epsm10 ; + Psdl_dVbs = Ps0_dVbs ; + Psdl_dVds = Ps0_dVds + 1.0 ; + Psdl_dVgs = Ps0_dVgs ; + } + + if (model->HSM2_xqy !=0) { + Ec = 0.0e0 ; + Ec_dVbs =0.0e0 ; + Ec_dVds =0.0e0 ; + Ec_dVgs =0.0e0 ; + } + } else { + /* Ec is removed from Lred calc. part */ + if (model->HSM2_xqy !=0) { + if ( Idd < C_IDD_MIN ) { + Ec = 0.0e0 ; + Ec_dVbs =0.0e0 ; + Ec_dVds =0.0e0 ; + Ec_dVgs =0.0e0 ; + } else { + T1 = beta_inv / Leff ; + T2 = 1.0 / Qn0 ; + T3 = T2 * T2 ; + Ec = Idd * T1 * T2 ; + Ec_dVbs = T1 * (Idd_dVbs * T2 - Idd * Qn0_dVbs * T3 ) ; + Ec_dVds = T1 * (Idd_dVds * T2 - Idd * Qn0_dVds * T3 ) ; + Ec_dVgs = T1 * (Idd_dVgs * T2 - Idd * Qn0_dVgs * T3 ) ; + } + } + } + + + /*-------------------------------------------* + * Overlap charges: Qgod, Qgos, and Qover + *-----------------*/ + if ( model->HSM2_coovlp >= 1 && pParam->HSM2_lover > 0.0 ){ + cov_slp = model->HSM2_ovslp ; + cov_mag = model->HSM2_ovmag ; + + covvg = Vgs ; + covvg_dVgs = 1.0 ; + + T1 = Cox0 * here->HSM2_weff_nf ; + Lov = pParam->HSM2_lover ; + + if ( pParam->HSM2_nover == 0.0 ){ + T4 = cov_slp * T1 * ( cov_mag + covvg ) ; + T4_dVg = cov_slp * T1 * covvg_dVgs ; + T4_dVd = 0.0 ; + T5 = Lov * T1 ; + + TX = Ps0 ; + TX_dVbs = Ps0_dVbs ; + TX_dVds = Ps0_dVds ; + TX_dVgs = Ps0_dVgs ; + + T9 = 1.2e0 - TX ; + Qgos = Vgs * T5 - T9 * T4 ; + Qgos_dVbs = T4 * TX_dVbs ; + Qgos_dVds = T4 * TX_dVds - T9 * T4_dVd ; + Qgos_dVgs = T5 + T4 * TX_dVgs - T9 * T4_dVg ; + + T4 = cov_slp * T1 * ( cov_mag + covvg - Vds ) ; + T4_dVg = cov_slp * T1 * covvg_dVgs ; + T4_dVd = - cov_slp * T1 ; + TX = Psl - Vds ; + TX_dVbs = Psl_dVbs ; + TX_dVds = Psl_dVds - 1.0 ; + TX_dVgs = Psl_dVgs ; + T9 = 1.2e0 - TX ; + Qgod = (Vgs - Vds) * T5 - T4 * T9 ; + Qgod_dVbs = T4 * TX_dVbs ; + Qgod_dVds = - T5 + T4 * TX_dVds - T9 * T4_dVd ; + Qgod_dVgs = T5 + T4 * TX_dVgs - T9 * T4_dVg ; + } else { + for ( lcover = -1 ; lcover <= +1 ; lcover += 2 ) { + flg_ovloops = ( 1 - lcover ) / 2 ; /* 1 in Source overlap calc. */ + flg_ovloopd = ( 1 + lcover ) / 2 ; /* 1 in Drain overlap calc. */ + /*-------------------------------------------* + * Qover (G/D overlap charge) | note: _dVxs means _dVxse + *------------------------*/ + Vbsgmt = ModeNML * Vbse + ModeRVS * ( Vbse - Vdse ) ; + Vdsgmt = ModeNML * Vdse + ModeRVS * ( - Vdse ) ; + Vgsgmt = ModeNML * Vgse + ModeRVS * ( Vgse - Vdse ) ; + Vdbgmt = Vdsgmt - Vbsgmt ; + Vgbgmt = Vgsgmt - Vbsgmt ; + Vsbgmt = - Vbsgmt ; + flg_overs = flg_ovloops * ModeNML + flg_ovloopd * ModeRVS ; /* geometrical source */ + flg_overd = flg_ovloops * ModeRVS + flg_ovloopd * ModeNML ; /* geometrical drain */ + Vxbgmt = flg_overs * Vsbgmt + flg_overd * Vdbgmt ; + + /*---------------------------------------------------* + * Clamp -Vxbgmt. + *-----------------*/ + T0 = - Vxbgmt; + if ( T0 > Vbs_bnd ) { + Fn_SUPoly4( TY, (T0 - Vbs_bnd), (Vbs_max - Vbs_bnd), T10_dVb ) ; + T10 = Vbs_bnd + TY ; + } else if ( T0 < Vbs_min ) { + T10 = Vbs_min ; + T10_dVb = 0.0; + } else { + T10 = T0 ; + T10_dVb = 1.0; + } + Vxbgmtcl = - T10; + Vxbgmtcl_dVxbgmt = T10_dVb; + fac1 = here->HSM2_cnst0over * Cox0_inv ; + fac1_dVbs = 0.0; fac1_dVds = 0.0; fac1_dVgs = 0.0; + fac1p2 = fac1 * fac1 ; + + VgpLD = - Vgbgmt + 2.0 * pParam->HSM2_vfbover; + VgpLD_dVgs = - 1.0e0 ; + + Vgp_fb_LD = pParam->HSM2_vfbover - Vxbgmtcl ; + + /*-----------------------------------* + * QsuLD: total charge = Accumulation | Depletion+inversion + *-----------------*/ + if ( VgpLD < Vgp_fb_LD ){ + /*---------------------------* + * Accumulation + *-----------------*/ + flg_ovzone = -1 ; + T1 = 1.0 / ( beta * here->HSM2_cnst0over ) ; + TY = T1 * Cox0 ; + Ac41 = 2.0 + 3.0 * C_SQRT_2 * TY ; + Ac4 = 8.0 * Ac41 * Ac41 * Ac41 ; + + Pb2over = here->HSM2_pb2over ; + Ps0_min = here->HSM2_eg - Pb2over ; + + TX = beta * ( VgpLD + Vxbgmtcl ) ; + TX_dVds = beta * Vxbgmtcl_dVxbgmt ; + TX_dVgs = beta * VgpLD_dVgs ; + + Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; + Ac31_dVds = - 9.0 * TY * TX_dVds ; + Ac31_dVgs = - 9.0 * TY * TX_dVgs ; + + Ac3 = Ac31 * Ac31 ; + T1 = 2.0 * Ac31 ; + Ac3_dVds = T1 * Ac31_dVds ; + Ac3_dVgs = T1 * Ac31_dVgs ; + + Ac2 = sqrt( Ac4 + Ac3 ) ; + T1 = 0.5 / Ac2 ; + Ac2_dVds = T1 * Ac3_dVds ; + Ac2_dVgs = T1 * Ac3_dVgs ; + + Ac1 = -7.0 * C_SQRT_2 + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; + Ac1_dVds = Ac2_dVds + 9.0 * TY * TX_dVds ; + Ac1_dVgs = Ac2_dVgs + 9.0 * TY * TX_dVgs ; + + Acd = pow( Ac1 , C_1o3 ) ; + T1 = C_1o3 / ( Acd * Acd ) ; + Acd_dVds = Ac1_dVds * T1 ; + Acd_dVgs = Ac1_dVgs * T1 ; + + Acn = -4.0 * C_SQRT_2 - 12.0 * TY + 2.0 * Acd + C_SQRT_2 * Acd * Acd ; + T1 = 2.0 + 2.0 * C_SQRT_2 * Acd ; + Acn_dVds = T1 * Acd_dVds ; + Acn_dVgs = T1 * Acd_dVgs ; + + Chi = Acn / Acd ; + T1 = 1.0 / ( Acd * Acd ) ; + Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; + Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; + + Psa = Chi * beta_inv - Vxbgmtcl ; + Psa_dVds = Chi_dVds * beta_inv - Vxbgmtcl_dVxbgmt ; + Psa_dVgs = Chi_dVgs * beta_inv ; + + T1 = Psa + Vxbgmtcl ; + T2 = T1 / Ps0_min ; + T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; + + T9 = T2 / T3 / Ps0_min ; + T3_dVd = T9 * ( Psa_dVds + Vxbgmtcl_dVxbgmt ) ; + T3_dVg = T9 * Psa_dVgs ; + + Ps0LD = T1 / T3 - Vxbgmtcl ; + T9 = 1.0 / ( T3 * T3 ) ; + Ps0LD_dVds = T9 * ( ( Psa_dVds + Vxbgmtcl_dVxbgmt ) * T3 - T1 * T3_dVd ) - Vxbgmtcl_dVxbgmt ; + Ps0LD_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVg ); + + T2 = ( VgpLD - Ps0LD ) ; + QbuLD = Cox0 * T2 ; + QbuLD_dVxb = - Cox0 * Ps0LD_dVds ; + QbuLD_dVgb = Cox0 * ( VgpLD_dVgs - Ps0LD_dVgs ) ; + + QsuLD = QbuLD ; + QsuLD_dVxb = QbuLD_dVxb ; + QsuLD_dVgb = QbuLD_dVgb ; + + } else { + + if ( model->HSM2_coqovsm != 1 ) { /*-- COQOVSM != 1: Analytical solution --(Original)--*/ + + Ps0_iniA = - Vxbgmtcl ; + Ps0_iniA_dVds = - Vxbgmtcl_dVxbgmt; + Ps0_iniA_dVgs = 0.0; + + /*-----------------------------------* + * Depletion + *-----------------*/ + TX = 1.0e0 + 4.0e0 + * ( beta * ( VgpLD + Vxbgmtcl ) - 1.0e0 ) / ( fac1p2 * beta2 ) ; + TX_dVds = 4.0e0 * ( beta * ( Vxbgmtcl_dVxbgmt ) ) / ( fac1p2 * beta2 ); + TX_dVgs = 4.0e0 * ( beta * ( VgpLD_dVgs ) ) / ( fac1p2 * beta2 ); + + TX = Fn_Max( TX , epsm10 ) ; + Ps0_iniA = VgpLD + fac1p2 * beta / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; + Ps0_iniA_dVds = - fac1p2 * beta / 2.0e0 * TX_dVds * 0.5 / sqrt( TX ); + Ps0_iniA_dVgs = VgpLD_dVgs - fac1p2 * beta / 2.0e0 * TX_dVgs * 0.5 / sqrt( TX ); + + Chi = beta * ( Ps0_iniA + Vxbgmtcl ) ; + Chi_dVds = beta * ( Ps0_iniA_dVds + Vxbgmtcl_dVxbgmt ) ; + Chi_dVgs = beta * ( Ps0_iniA_dVgs ) ; + + if ( Chi < znbd3 ) { + flg_ovzone = 1 ; + /*-----------------------------------* + * zone-D1/D2 + * - Ps0LD is the analytical solution of Qs=Qb0 with + * Qb0 being approximated to 3-degree polynomial. + *-----------------*/ + TY = beta * ( VgpLD + Vxbgmtcl ) ; + TY_dVds = beta * ( Vxbgmtcl_dVxbgmt ) ; + TY_dVgs = beta * ( VgpLD_dVgs ) ; + + T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; + T2 = 81.0 + 3.0 * T1 ; + T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ; + T3_dVd = 27.0 * T1 * TY_dVds ; + T3_dVg = 27.0 * T1 * TY_dVgs ; + + T4 = 1458.0 - 81.0 * ( 54.0 + T1 ) + 27.0 * T1 * TY ; + T4_dVd = 27.0 * T1 * TY_dVds ; + T4_dVg = 27.0 * T1 * TY_dVgs ; + T0 = 2.0 * T4; + T4 = T4 * T4 ; + T4_dVd = T0 * T4_dVd ; + T4_dVg = T0 * T4_dVg ; + + T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; + T0 = C_1o3 / ( T5 * T5 ); + T1 = sqrt( 4 * T2 * T2 * T2 + T4 ); + T5_dVd = ( T3_dVd + T4_dVd * 0.5 / T1 ) * T0 ; + T5_dVg = ( T3_dVg + T4_dVg * 0.5 / T1 ) * T0 ; + + TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 ) + + 1 / ( 3.0 * C_2p_1o3 ) * T5 ; + T0 = 1 / ( 3.0 * C_2p_1o3 ); + T1 = ( 9.0 * T5 * T5 ); + TX_dVds = - ( - C_2p_1o3 * T2 * 3.0 * T5_dVd ) / T1 + T0 * T5_dVd; + TX_dVgs = - ( - C_2p_1o3 * T2 * 3.0 * T5_dVg ) / T1 + T0 * T5_dVg; + + Ps0_iniA = TX * beta_inv - Vxbgmtcl ; + Ps0_iniA_dVds = TX_dVds * beta_inv - Vxbgmtcl_dVxbgmt; + Ps0_iniA_dVgs = TX_dVgs * beta_inv; + + } else { + flg_ovzone = 3 ; + } + + /*---------------------------------------------------* + * Assign initial guess. + *-----------------*/ + Ps0LD = Ps0_iniA ; + Ps0LD_dVds = Ps0_iniA_dVds; + Ps0LD_dVgs = Ps0_iniA_dVgs; + + Chi = beta * ( Ps0LD + Vxbgmtcl ) ; + Chi_dVds = beta * ( Ps0LD_dVds + Vxbgmtcl_dVxbgmt ) ; + Chi_dVgs = beta * ( Ps0LD_dVgs ) ; + + if ( Chi < znbd5 ) { + if ( flg_ovzone == 3 ) { flg_ovzone = 2 ;} + /*-------------------------------------------* + * zone-D1/D2. (Ps0LD) + *-----------------*/ + + fb = Chi * ( cn_nc51 + + Chi * ( cn_nc52 + + Chi * ( cn_nc53 + + Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ; + fb_dChi = cn_nc51 + + Chi * ( 2 * cn_nc52 + + Chi * ( 3 * cn_nc53 + + Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ; + + fs02 = fb ; + fs02_dVds = fb_dChi * Chi_dVds; + fs02_dVgs = fb_dChi * Chi_dVgs; + + /* memo: Fs0 = VgpLD - Ps0LD - fac1 * fs02 */ + + QbuLD = here->HSM2_cnst0over * fs02 ; + QbuLD_dVxb = here->HSM2_cnst0over * fs02_dVds; + QbuLD_dVgb = here->HSM2_cnst0over * fs02_dVgs; + + } else { + /*-------------------------------------------* + * zone-D3. (Ps0LD) + *-----------------*/ + + if ( model->HSM2_coqovsm > 0 && VgpLD > 0.0 ) { + /*-----------------------------------* + * Strong inversion zone. + * - Ps0_iniB : upper bound. + *-----------------*/ + flg_ovzone = 5 ; + T1 = here->HSM2_ps0ldinib; /* (1 / cnst1 / cnstCoxi) */ + T2 = T1 * VgpLD * VgpLD ; + T2_dVg = T1 * 2.0 * VgpLD * VgpLD_dVgs ; + T3 = beta + 2.0 / VgpLD ; + T3_dVg = - 2.0 * VgpLD_dVgs / ( VgpLD * VgpLD ); + + Ps0_iniB = log( T2 + small ) / T3 ; + Ps0_iniB_dVgs = ( T2_dVg / T2 * T3 - log( T2 ) * T3_dVg ) / ( T3 * T3 ); + + Fn_SU2( Ps0LD, Ps0LD, Ps0_iniB, c_ps0ini_2, T1, T2 ); + Ps0LD_dVds *= T1; + Ps0LD_dVgs = Ps0LD_dVgs * T1 + Ps0_iniB_dVgs * T2; + } + + /* T1: Xi */ + T1 = beta * ( Ps0LD + Vxbgmtcl ) - 1.0 ; + T1_dVd = beta * ( Ps0LD_dVds + Vxbgmtcl_dVxbgmt ) ; + T1_dVg = beta * ( Ps0LD_dVgs ) ; + + if ( T1 > 0.0 ){ T2 = sqrt( T1 ); } else{ T2 = small; } + QbuLD = here->HSM2_cnst0over * T2 ; + T3 = here->HSM2_cnst0over * 0.5 / T2 ; + QbuLD_dVxb = T3 * T1_dVd ; + QbuLD_dVgb = T3 * T1_dVg ; + } /* end of if ( Chi ... ) block */ + /*-----------------------------------------------------------* + * QsuLD : Qovs or Qovd in unit area. + * note: QsuLD = Qdep+Qinv. + *-----------------*/ + QsuLD = Cox0 * ( VgpLD - Ps0LD ) ; + QsuLD_dVxb = Cox0 * ( - Ps0LD_dVds ) ; + QsuLD_dVgb = Cox0 * ( VgpLD_dVgs - Ps0LD_dVgs ) ; + + } else { /*-- COQOVSM == 1: Iterative solution ---------------*/ + + VthLD = here->HSM2_pb2over + 2.0 * pParam->HSM2_vfbover + + sqrt( 2 * C_QE * pParam->HSM2_nover * C_ESI * here->HSM2_pb2over ) * Cox0_inv ; + /*-----------------------------------* + * Depletion + *-----------------*/ + TX = 1.0e0 + 4.0e0 + * ( beta * ( VgpLD + Vxbgmtcl ) - 1.0e0 ) / ( fac1p2 * beta2 ) ; + + TX = Fn_Max( TX , epsm10 ) ; + Ps0_iniA = VgpLD + fac1p2 * beta / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; + + Chi = beta * ( Ps0_iniA + Vxbgmtcl ) ; + + if ( Chi < znbd3 ) { + /*-----------------------------------* + * zone-D1/D2 + * - Ps0LD is the analytical solution of Qs=Qb0 with + * Qb0 being approximated to 3-degree polynomial. + *-----------------*/ + TY = beta * ( VgpLD + Vxbgmtcl ) ; + T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; + T2 = 81.0 + 3.0 * T1 ; + T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ; + T4 = 1458.0 - 81.0 * ( 54.0 + T1 ) + 27.0 * T1 * TY ; + T4 = T4 * T4 ; + T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; + TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 ) + + 1 / ( 3.0 * C_2p_1o3 ) * T5 ; + + Ps0_iniA = TX * beta_inv - Vxbgmtcl ; + Ps0_ini = Ps0_iniA ; + + } else if ( - Vgbgmt <= VthLD ) { + Ps0_ini = Ps0_iniA ; + + } else { + /*-----------------------------------* + * Strong inversion zone. + * - Ps0_iniB : upper bound. + *-----------------*/ + T1 = here->HSM2_ps0ldinib; /* (1 / cnst1 / cnstCoxi) */ + T2 = T1 * VgpLD * VgpLD ; + T3 = beta + 2.0 / VgpLD ; + + Ps0_iniB = log( T2 + small ) / T3 ; + + Fn_SU( Ps0_ini , Ps0_iniA, Ps0_iniB, c_ps0ini_2, T1) ; + } + + TX = - Vxbgmtcl + 0.5 * ps_conv ; + if ( Ps0_ini < TX ) Ps0_ini = TX ; + + /*---------------------------------------------------* + * Assign initial guess. + *-----------------*/ + Ps0LD = Ps0_ini ; + + /*---------------------------------------------------* + * Calculation of Ps0LD. (beginning of Newton loop) + * - Fs0 : Fs0 = 0 is the equation to be solved. + * - dPs0 : correction value. + *-----------------*/ + exp_bVbs = exp( beta * - Vxbgmtcl ) ; + T0 = here->HSM2_nin / pParam->HSM2_nover; + T1 = T0 * T0; /* cnst1_over */ + cfs1 = T1 * exp_bVbs ; + + flg_conv = 0 ; + for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max + 1 ; lp_s0 ++ ) { + + Chi = beta * ( Ps0LD + Vxbgmtcl ) ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D1/D2. (Ps0LD) + *-----------------*/ + fi = Chi * Chi * Chi + * ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ; + fi_dChi = Chi * Chi + * ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ; + + fs01 = cfs1 * fi * fi ; + fs01_dPs0 = cfs1 * beta * 2 * fi * fi_dChi ; + + fb = Chi * ( cn_nc51 + + Chi * ( cn_nc52 + + Chi * ( cn_nc53 + + Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ; + fb_dChi = cn_nc51 + + Chi * ( 2 * cn_nc52 + + Chi * ( 3 * cn_nc53 + + Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ; + + fs02 = sqrt( fb * fb + fs01 ) ; + fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) / ( fs02 + fs02 ) ; + + } else { + /*-------------------------------------------* + * zone-D3. (Ps0LD) + *-----------------*/ + exp_Chi = exp( Chi ) ; + fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; + fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; + fs02 = sqrt( Chi - 1.0 + fs01 ) ; + fs02_dPs0 = ( beta + fs01_dPs0 ) / fs02 * 0.5 ; + + } /* end of if ( Chi ... ) block */ + /*-----------------------------------------------------------* + * Fs0 + *-----------------*/ + Fs0 = VgpLD - Ps0LD - fac1 * fs02 ; + Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; + + if ( flg_conv == 1 ) break ; + + dPs0 = - Fs0 / Fs0_dPs0 ; + + /*-------------------------------------------* + * Update Ps0LD . + *-----------------*/ + dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Ps0LD))) ; + if ( fabs( dPs0 ) > dPlim ) dPs0 = dPlim * Fn_Sgn( dPs0 ) ; + + Ps0LD = Ps0LD + dPs0 ; + + TX = -Vxbgmtcl + ps_conv / 2 ; + if ( Ps0LD < TX ) Ps0LD = TX ; + + /*-------------------------------------------* + * Check convergence. + *-----------------*/ + if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { + flg_conv = 1 ; + } + + } /* end of Ps0LD Newton loop */ + + /*-------------------------------------------* + * Procedure for diverged case. + *-----------------*/ + if ( flg_conv == 0 ) { + fprintf( stderr , + "*** warning(HiSIM): Went Over Iteration Maximum (Ps0LD)\n" ) ; + fprintf( stderr , + " -Vxbgmtcl = %e Vgbgmt = %e\n" , + -Vxbgmtcl , Vgbgmt ) ; + if ( flg_info >= 2 ) { + printf( "*** warning(HiSIM): Went Over Iteration Maximum (Ps0LD)\n" ) ; + } + } + + /*---------------------------------------------------* + * Evaluate derivatives of Ps0LD. + *-----------------*/ + if ( Chi < znbd5 ) { + fs01_dVbs = cfs1 * beta * fi * ( - fi + 2 * fi_dChi ) ; /* fs01_dVxbgmtcl */ + T2 = 1.0e0 / ( fs02 + fs02 ) ; + fs02_dVbs = ( + beta * fb_dChi * 2 * fb + fs01_dVbs ) * T2 ; /* fs02_dVxbgmtcl */ + } else { + fs01_dVbs = + cfs1 * beta ; /* fs01_dVxbgmtcl */ + T2 = 0.5e0 / fs02 ; + fs02_dVbs = ( + beta + fs01_dVbs ) * T2 ; /* fs02_dVxbgmtcl */ + } + + T1 = 1.0 / Fs0_dPs0 ; + Ps0LD_dVbs = - ( - fac1 * fs02_dVbs ) * T1 ; + Ps0LD_dVds = 0.0 ; + Ps0LD_dVgs = - ( VgpLD_dVgs - fac1_dVgs * fs02 ) * T1 ; + + if ( Chi < znbd5 ) { + /*-------------------------------------------* + * zone-D1/D2. (Ps0LD) + *-----------------*/ + if ( Chi < znbd3 ) { flg_ovzone = 1; } + else { flg_ovzone = 2 ; } + + Xi0 = fb * fb + epsm10 ; + T1 = 2 * fb * fb_dChi * beta ; + Xi0_dVbs = T1 * ( Ps0LD_dVbs + 1.0 ) ; /* Xi0_dVxbgmtcl */ + Xi0_dVds = T1 * Ps0LD_dVds ; + Xi0_dVgs = T1 * Ps0LD_dVgs ; + + Xi0p12 = fb + epsm10 ; + T1 = fb_dChi * beta ; + Xi0p12_dVbs = T1 * ( Ps0LD_dVbs + 1.0 ) ; /* Xi0p12_dVxbgmtcl */ + Xi0p12_dVds = T1 * Ps0LD_dVds ; + Xi0p12_dVgs = T1 * Ps0LD_dVgs ; + + Xi0p32 = fb * fb * fb + epsm10 ; + T1 = 3 * fb * fb * fb_dChi * beta ; + Xi0p32_dVbs = T1 * ( Ps0LD_dVbs + 1.0 ) ; /* Xi0p32_dVxbgmtcl */ + Xi0p32_dVds = T1 * Ps0LD_dVds ; + Xi0p32_dVgs = T1 * Ps0LD_dVgs ; + + } else { + /*-------------------------------------------* + * zone-D3. (Ps0LD) + *-----------------*/ + flg_ovzone = 3 ; + + Xi0 = Chi - 1.0e0 ; + Xi0_dVbs = beta * ( Ps0LD_dVbs + 1.0e0 ) ; /* Xi0_dVxbgmtcl */ + Xi0_dVds = beta * Ps0LD_dVds ; + Xi0_dVgs = beta * Ps0LD_dVgs ; + + Xi0p12 = sqrt( Xi0 ) ; + T1 = 0.5e0 / Xi0p12 ; + Xi0p12_dVbs = T1 * Xi0_dVbs ; + Xi0p12_dVds = T1 * Xi0_dVds ; + Xi0p12_dVgs = T1 * Xi0_dVgs ; + + Xi0p32 = Xi0 * Xi0p12 ; + T1 = 1.5e0 * Xi0p12 ; + Xi0p32_dVbs = T1 * Xi0_dVbs ; + Xi0p32_dVds = T1 * Xi0_dVds ; + Xi0p32_dVgs = T1 * Xi0_dVgs ; + + } /* end of if ( Chi ... ) block */ + + /*-----------------------------------------------------------* + * - Recalculate the derivatives of fs01 and fs02. + *-----------------*/ + fs01_dVbs = Ps0LD_dVbs * fs01_dPs0 + fs01_dVbs ; + fs01_dVds = Ps0LD_dVds * fs01_dPs0 ; + fs01_dVgs = Ps0LD_dVgs * fs01_dPs0 ; + fs02_dVbs = Ps0LD_dVbs * fs02_dPs0 + fs02_dVbs ; + fs02_dVds = Ps0LD_dVds * fs02_dPs0 ; + fs02_dVgs = Ps0LD_dVgs * fs02_dPs0 ; + + /*-----------------------------------------------------------* + * QbuLD and QiuLD + *-----------------*/ + QbuLD = here->HSM2_cnst0over * Xi0p12 ; + QbuLD_dVxb = here->HSM2_cnst0over * Xi0p12_dVbs ; + QbuLD_dVgb = here->HSM2_cnst0over * Xi0p12_dVgs ; + + T1 = 1.0 / ( fs02 + Xi0p12 ) ; + QiuLD = here->HSM2_cnst0over * fs01 * T1 ; + T2 = 1.0 / ( fs01 + epsm10 ) ; + QiuLD_dVbs = QiuLD * ( fs01_dVbs * T2 - ( fs02_dVbs + Xi0p12_dVbs ) * T1 ) ; + QiuLD_dVgs = QiuLD * ( fs01_dVgs * T2 - ( fs02_dVgs + Xi0p12_dVgs ) * T1 ) ; + + /*-----------------------------------------------------------* + * make QiuLD=0 if VgVt <= VgVt_small + *-----------------*/ + if ( QiuLD * Cox_inv <= VgVt_small ) { + flg_ovzone = 4 ; + QiuLD = 0.0 ; + QiuLD_dVbs = 0.0 ; + QiuLD_dVgs = 0.0 ; + } + + /*-----------------------------------------------------------* + * Extrapolation: X_dVxbgmt = X_dVxbgmtcl * Vxbgmtcl_dVxbgmt + *-----------------*/ + QbuLD_dVxb *= Vxbgmtcl_dVxbgmt; + QiuLD_dVbs *= Vxbgmtcl_dVxbgmt; + + /*-----------------------------------------------------------* + * Total overlap charge + *-----------------*/ + QsuLD = QbuLD + QiuLD; + QsuLD_dVxb = QbuLD_dVxb + QiuLD_dVbs; + QsuLD_dVgb = QbuLD_dVgb + QiuLD_dVgs; + + } /* end of COQOVSM branches */ + + } /* end of Vgbgmt region blocks */ + + /* convert to source ref. */ + QsuLD_dVbs = - (QsuLD_dVxb + QsuLD_dVgb) ; + QsuLD_dVds = QsuLD_dVxb * flg_overd ; + QsuLD_dVgs = QsuLD_dVgb ; + + QbuLD_dVbs = - (QbuLD_dVxb + QbuLD_dVgb) ; + QbuLD_dVds = QbuLD_dVxb * flg_overd ; + QbuLD_dVgs = QbuLD_dVgb ; + + /* inversion charge = total - depletion */ + QiuLD = QsuLD - QbuLD ; + QiuLD_dVbs = QsuLD_dVbs - QbuLD_dVbs ; + QiuLD_dVds = QsuLD_dVds - QbuLD_dVds ; + QiuLD_dVgs = QsuLD_dVgs - QbuLD_dVgs ; + + /* assign final outputs of Qover model */ + /* note: Qovs and Qovd are exchanged in reverse mode */ + T4 = here->HSM2_weff_nf * Lov ; + + if(flg_ovloops) { + Qovs = T4 * QsuLD ; + Qovs_dVbs = T4 * QsuLD_dVbs ; + Qovs_dVds = T4 * QsuLD_dVds ; + Qovs_dVgs = T4 * QsuLD_dVgs ; + QisLD = T4 * QiuLD ; + QisLD_dVbs = T4 * QiuLD_dVbs ; + QisLD_dVds = T4 * QiuLD_dVds ; + QisLD_dVgs = T4 * QiuLD_dVgs ; + QbsLD = T4 * QbuLD ; + QbsLD_dVbs = T4 * QbuLD_dVbs ; + QbsLD_dVds = T4 * QbuLD_dVds ; + QbsLD_dVgs = T4 * QbuLD_dVgs ; + } + + if(flg_ovloopd) { + Qovd = T4 * QsuLD ; + Qovd_dVbs = T4 * QsuLD_dVbs ; + Qovd_dVds = T4 * QsuLD_dVds ; + Qovd_dVgs = T4 * QsuLD_dVgs ; + QidLD = T4 * QiuLD ; + QidLD_dVbs = T4 * QiuLD_dVbs ; + QidLD_dVds = T4 * QiuLD_dVds ; + QidLD_dVgs = T4 * QiuLD_dVgs ; + QbdLD = T4 * QbuLD ; + QbdLD_dVbs = T4 * QbuLD_dVbs ; + QbdLD_dVds = T4 * QbuLD_dVds ; + QbdLD_dVgs = T4 * QbuLD_dVgs ; + } + + } /* end of lcover loop */ + + /* convert to the derivatives w.r.t. mode-dependent biases */ + Qovs_dVds = ModeNML * Qovs_dVds + - ModeRVS * ( Qovs_dVds + Qovs_dVgs + Qovs_dVbs ) ; + QisLD_dVds = ModeNML * QisLD_dVds + - ModeRVS * ( QisLD_dVds + QisLD_dVgs + QisLD_dVbs ) ; + QbsLD_dVds = ModeNML * QbsLD_dVds + - ModeRVS * ( QbsLD_dVds + QbsLD_dVgs + QbsLD_dVbs ) ; + Qovd_dVds = ModeNML * Qovd_dVds + - ModeRVS * ( Qovd_dVds + Qovd_dVgs + Qovd_dVbs ); + QidLD_dVds = ModeNML * QidLD_dVds + - ModeRVS * ( QidLD_dVds + QidLD_dVgs + QidLD_dVbs ) ; + QbdLD_dVds = ModeNML * QbdLD_dVds + - ModeRVS * ( QbdLD_dVds + QbdLD_dVgs + QbdLD_dVbs ) ; + + } /* end of if ( pParam->HSM2_nover == 0.0 ) */ + + /*-----------------------------------* + * Additional constant capacitance model + *-----------------*/ + flg_overgiven = ( ModeRVS * model->HSM2_cgso_Given + + ModeNML * model->HSM2_cgdo_Given ) ; + if ( flg_overgiven ) { + Cgdo = ModeRVS * pParam->HSM2_cgso + ModeNML * pParam->HSM2_cgdo ; + Cgdo *= - here->HSM2_weff_nf ; + + Qgod += - Cgdo * (Vgs - Vds) ; + Qgod_dVds += Cgdo ; + Qgod_dVgs += -Cgdo ; + } + + flg_overgiven = ( ModeNML * model->HSM2_cgso_Given + + ModeRVS * model->HSM2_cgdo_Given ) ; + if(flg_overgiven) { + Cgso = ModeNML * pParam->HSM2_cgso + ModeRVS * pParam->HSM2_cgdo ; + Cgso *= - here->HSM2_weff_nf ; + + Qgos += - Cgso * Vgs ; + Qgos_dVgs += -Cgso ; + } + + } else { /* else case of if ( model->HSM2_coovlp >= 1 ) */ + if ( (here->HSM2_mode == HiSIM_NORMAL_MODE && !model->HSM2_cgdo_Given) || + (here->HSM2_mode != HiSIM_NORMAL_MODE && !model->HSM2_cgso_Given) ) { + Cgdo = - Cox0 * pParam->HSM2_lover * here->HSM2_weff_nf ; + } else { + Cgdo = ModeRVS * pParam->HSM2_cgso + ModeNML * pParam->HSM2_cgdo ; + Cgdo *= - here->HSM2_weff_nf ; + } + Qgod = - Cgdo * (Vgs - Vds) ; + Qgod_dVbs = 0.0 ; + Qgod_dVds = Cgdo ; + Qgod_dVgs = - Cgdo ; + + if ( (here->HSM2_mode == HiSIM_NORMAL_MODE && !model->HSM2_cgso_Given) || + (here->HSM2_mode != HiSIM_NORMAL_MODE && !model->HSM2_cgdo_Given) ) { + Cgso = - Cox0 * pParam->HSM2_lover * here->HSM2_weff_nf ; + } else { + Cgso = ModeNML * pParam->HSM2_cgso + ModeRVS * pParam->HSM2_cgdo ; + Cgso *= - here->HSM2_weff_nf ; + } + Qgos = - Cgso * Vgs ; + Qgos_dVbs = 0.0 ; + Qgos_dVds = 0.0 ; + Qgos_dVgs = - Cgso ; + } /* end of if ( model->HSM2_coovlp >= 1 ) */ + + /*-------------------------------------------* + * Gate/Bulk overlap charge: Qgbo + *-----------------*/ + Cgbo_loc = - model->HSM2_cgbo * here->HSM2_lgate ; + Qgbo = - Cgbo_loc * (Vgs -Vbs) ; + Qgbo_dVgs = - Cgbo_loc ; + Qgbo_dVbs = Cgbo_loc ; + Qgbo_dVds = 0.0 ; + + /*---------------------------------------------------* + * Lateral-field-induced capacitance. + *-----------------*/ + if ( model->HSM2_coqy == 0 || model->HSM2_xqy == 0 ){ + Qy = 0.0e0 ; + Qy_dVds = 0.0e0 ; + Qy_dVgs = 0.0e0 ; + Qy_dVbs = 0.0e0 ; + } else { + Pslk = Ec * Leff + Ps0 ; + Pslk_dVbs = Ec_dVbs * Leff + Ps0_dVbs; + Pslk_dVds = Ec_dVds * Leff + Ps0_dVds; + Pslk_dVgs = Ec_dVgs * Leff + Ps0_dVgs; + Fn_SU2( T10, (Pslk + C_PSLK_SHIFT), (Psdl + C_PSLK_SHIFT), C_PSLK_DELTA, T1, T2 ); + Pslk_dVbs = Pslk_dVbs * T1 + Psdl_dVbs * T2; + Pslk_dVds = Pslk_dVds * T1 + Psdl_dVds * T2; + Pslk_dVgs = Pslk_dVgs * T1 + Psdl_dVgs * T2; + Pslk = T10 - C_PSLK_SHIFT; + + /* suppress Qy in accumulation region */ + /* + Aclm_eff = 1.0 - Pds / (eps_qy + Pds) * (1.0 - Aclm) ; + Aclm_eff_dVds = eps_qy * Pds_dVds / ((eps_qy + Pds)*(eps_qy + Pds)) ; + Aclm_eff_dVgs = eps_qy * Pds_dVgs / ((eps_qy + Pds)*(eps_qy + Pds)) ; + Aclm_eff_dVbs = eps_qy * Pds_dVbs / ((eps_qy + Pds)*(eps_qy + Pds)) ; + */ + + Aclm_eff = Aclm ; Aclm_eff_dVds = Aclm_eff_dVgs = Aclm_eff_dVbs = 0.0 ; + + T1 = Aclm_eff * ( Vds + Ps0 ) + ( 1.0e0 - Aclm_eff ) * Pslk ; + T1_dVb = Aclm_eff * ( Ps0_dVbs ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVbs + + Aclm_eff_dVbs * ( Vds + Ps0 - Pslk ) ; + T1_dVd = Aclm_eff * ( 1.0 + Ps0_dVds ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVds + + Aclm_eff_dVds * ( Vds + Ps0 - Pslk ) ; + T1_dVg = Aclm_eff * ( Ps0_dVgs ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVgs + + Aclm_eff_dVgs * ( Vds + Ps0 - Pslk ) ; + T10 = here->HSM2_wdpl ; + T3 = T10 * 1.3 ; + T2 = C_ESI * here->HSM2_weff_nf * T3 ; + T7 = 1.0e-7 ; /* 1nm */ + T0 = Fn_Max( model->HSM2_xqy , T7 ) ; + T4 = T2 / T0 ; + Qy = - ( Ps0 + Vds - T1 ) * T4 ; + Qy_dVds = - ( Ps0_dVds + 1.0e0 - T1_dVd ) * T4 ; + Qy_dVgs = - ( Ps0_dVgs - T1_dVg ) * T4 ; + Qy_dVbs = - ( Ps0_dVbs - T1_dVb ) * T4 ; + + + } + + if ( model->HSM2_xqy1 != 0.0 ){ + Qy += here->HSM2_cqyb0 * Vbs ; + Qy_dVbs += here->HSM2_cqyb0 ; + } + + Qy = Qy * FMDVDS ; + Qy_dVbs = Qy_dVbs * FMDVDS + Qy * FMDVDS_dVbs ; + Qy_dVds = Qy_dVds * FMDVDS + Qy * FMDVDS_dVds ; + Qy_dVgs = Qy_dVgs * FMDVDS + Qy * FMDVDS_dVgs ; + + /*---------------------------------------------------* + * Fringing capacitance. + *-----------------*/ + Cf = here->HSM2_cfrng ; + Qfd = Cf * ( Vgs - Vds ) ; + Qfs = Cf * Vgs ; + + /*-----------------------------------------------------------* + * End of PART-3. (label) + *-----------------*/ + + end_of_part_3: + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-4: Substrate-source/drain junction diode. + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + /*-----------------------------------------------------------* + * Cbsj, Cbdj: node-base S/D biases. + *-----------------*/ + + T10 = model->HSM2_cvb * here->HSM2_jd_nvtm_inv ; + T11 = model->HSM2_cvbk * here->HSM2_jd_nvtm_inv ; + + T9 = model->HSM2_cisb * here->HSM2_exptemp ; + T0 = here->HSM2_isbd2 * T9 ; + + T2 = exp (- vbd_jct * T10 ); + T2_dVb = - T2 * T10 ; + + T3 = exp (- vbd_jct * T11 ); + T3_dVb = - T3 * T11 ; + + + /* ibd */ + if ( vbd_jct < here->HSM2_vbdt ) { + TX = vbd_jct * here->HSM2_jd_nvtm_inv ; + if ( TX < - EXP_THR ) { + T1 = 0.0 ; + T1_dVb = 0.0 ; + } else { + T1 = exp ( TX ) ; + T1_dVb = T1 * here->HSM2_jd_nvtm_inv ; + } + + Ibd = here->HSM2_isbd * (T1 - 1.0) + + T0 * (T2 - 1.0) + + pParam->HSM2_cisbk * (T3 - 1.0); + Gbd = here->HSM2_isbd * T1_dVb + + T0 * T2_dVb + + pParam->HSM2_cisbk * T3_dVb ; + + } else { + T1 = here->HSM2_jd_expcd ; + + T4 = here->HSM2_isbd * here->HSM2_jd_nvtm_inv * T1 ; + + Ibd = here->HSM2_isbd * (T1 - 1.0) + + T4 * (vbd_jct - here->HSM2_vbdt) + + T0 * (T2 - 1.0) + + pParam->HSM2_cisbk * (T3 - 1.0) ; + Gbd = T4 + + T0 * T2_dVb + + pParam->HSM2_cisbk * T3_dVb ; + } + T12 = model->HSM2_divx * here->HSM2_isbd2 ; + Ibd += T12 * vbd_jct ; + Gbd += T12 ; + + /* ibs */ + T0 = here->HSM2_isbs2 * T9 ; + + TX = - vbs_jct * T10 ; + if ( TX < - EXP_THR ) { + T2 = 0.0 ; + T2_dVb = 0.0 ; + } else { + T2 = exp ( TX ); + T2_dVb = - T2 * T10 ; + } + + TX = - vbs_jct * T11 ; + if ( TX < - EXP_THR ) { + T3 = 0.0 ; + T3_dVb = 0.0 ; + } else { + T3 = exp ( TX ); + T3_dVb = - T3 * T11 ; + } + + if ( vbs_jct < here->HSM2_vbst ) { + TX = vbs_jct * here->HSM2_jd_nvtm_inv ; + if ( TX < - EXP_THR ) { + T1 = 0.0 ; + T1_dVb = 0.0 ; + } else { + T1 = exp ( TX ) ; + T1_dVb = T1 * here->HSM2_jd_nvtm_inv ; + } + Ibs = here->HSM2_isbs * (T1 - 1.0) + + T0 * (T2 - 1.0) + + pParam->HSM2_cisbk * (T3 - 1.0); + Gbs = here->HSM2_isbs * T1_dVb + + T0 * T2_dVb + + pParam->HSM2_cisbk * T3_dVb ; + } else { + T1 = here->HSM2_jd_expcs ; + + T4 = here->HSM2_isbs * here->HSM2_jd_nvtm_inv * T1 ; + + Ibs = here->HSM2_isbs * (T1 - 1.0) + + T4 * (vbs_jct - here->HSM2_vbst) + + T0 * (T2 - 1.0) + + pParam->HSM2_cisbk * (T3 - 1.0) ; + Gbs = T4 + + T0 * T2_dVb + + pParam->HSM2_cisbk * T3_dVb ; + } + T12 = model->HSM2_divx * here->HSM2_isbs2 ; + Ibs += T12 * vbs_jct ; + Gbs += T12 ; + + /*---------------------------------------------------* + * Add Gjmin. + *-----------------*/ + Ibd += Gjmin * vbd_jct ; + Ibs += Gjmin * vbs_jct ; + + Gbd += Gjmin ; + Gbs += Gjmin ; + + /*-----------------------------------------------------------* + * Charges and Capacitances. + *-----------------*/ + /* charge storage elements + * bulk-drain and bulk-source depletion capacitances + * czbd : zero bias drain junction capacitance + * czbs : zero bias source junction capacitance + * czbdsw:zero bias drain junction sidewall capacitance + * czbssw:zero bias source junction sidewall capacitance + */ + /* add new parameters + tcjbs : temperature dependence of czbs + tcjbd : temperature dependence of czbd + tcjbssw : temperature dependence of czbssw + tcjbdsw : temperature dependence of czbdsw + tcjbsswg : temperature dependence of czbsswg + tcjbdswg : temperature dependence of czbdswg + */ + tcjbd=model->HSM2_tcjbd; + tcjbs=model->HSM2_tcjbs; + tcjbdsw=model->HSM2_tcjbdsw; + tcjbssw=model->HSM2_tcjbssw; + tcjbdswg=model->HSM2_tcjbdswg; + tcjbsswg=model->HSM2_tcjbsswg; + + czbs = model->HSM2_cj * here->HSM2_as ; + czbs = czbs * ( 1.0 + tcjbs * ( TTEMP - model->HSM2_tnom )) ; + + czbd = model->HSM2_cj * here->HSM2_ad ; + czbd = czbd * ( 1.0 + tcjbd * ( TTEMP - model->HSM2_tnom )) ; + + /* Source Bulk Junction */ + if (here->HSM2_ps > here->HSM2_weff_nf) { + czbssw = model->HSM2_cjsw * ( here->HSM2_ps - here->HSM2_weff_nf ) ; + czbssw = czbssw * ( 1.0 + tcjbssw * ( TTEMP - model->HSM2_tnom )) ; + + czbsswg = model->HSM2_cjswg * here->HSM2_weff_nf ; + czbsswg = czbsswg * ( 1.0 + tcjbsswg * ( TTEMP - model->HSM2_tnom )) ; + + if (vbs_jct == 0.0) { + Qbs = 0.0 ; + Capbs = czbs + czbssw + czbsswg ; + } else if (vbs_jct < 0.0) { + if (czbs > 0.0) { + arg = 1.0 - vbs_jct / model->HSM2_pb ; + if (model->HSM2_mj == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mj ) ; + Qbs = model->HSM2_pb * czbs * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ; + Capbs = czbs * sarg ; + } else { + Qbs = 0.0 ; + Capbs = 0.0 ; + } + if (czbssw > 0.0) { + arg = 1.0 - vbs_jct / model->HSM2_pbsw ; + if (model->HSM2_mjsw == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjsw ) ; + Qbs += model->HSM2_pbsw * czbssw * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjsw) ; + Capbs += czbssw * sarg ; + } + if (czbsswg > 0.0) { + arg = 1.0 - vbs_jct / model->HSM2_pbswg ; + if (model->HSM2_mjswg == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ; + Qbs += model->HSM2_pbswg * czbsswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ; + Capbs += czbsswg * sarg ; + } + } else { + T1 = czbs + czbssw + czbsswg ; + T2 = czbs * model->HSM2_mj / model->HSM2_pb + + czbssw * model->HSM2_mjsw / model->HSM2_pbsw + + czbsswg * model->HSM2_mjswg / model->HSM2_pbswg ; + Qbs = vbs_jct * (T1 + vbs_jct * 0.5 * T2) ; + Capbs = T1 + vbs_jct * T2 ; + } + } else { + czbsswg = model->HSM2_cjswg * here->HSM2_ps ; + czbsswg = czbsswg * ( 1.0 + tcjbsswg * ( TTEMP - model->HSM2_tnom )) ; + if (vbs_jct == 0.0) { + Qbs = 0.0 ; + Capbs = czbs + czbsswg ; + } else if (vbs_jct < 0.0) { + if (czbs > 0.0) { + arg = 1.0 - vbs_jct / model->HSM2_pb ; + if (model->HSM2_mj == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mj ) ; + Qbs = model->HSM2_pb * czbs * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ; + Capbs = czbs * sarg ; + } else { + Qbs = 0.0 ; + Capbs = 0.0 ; + } + if (czbsswg > 0.0) { + arg = 1.0 - vbs_jct / model->HSM2_pbswg ; + if (model->HSM2_mjswg == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ; + Qbs += model->HSM2_pbswg * czbsswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ; + Capbs += czbsswg * sarg ; + } + } else { + T1 = czbs + czbsswg ; + T2 = czbs * model->HSM2_mj / model->HSM2_pb + + czbsswg * model->HSM2_mjswg / model->HSM2_pbswg ; + Qbs = vbs_jct * (T1 + vbs_jct * 0.5 * T2) ; + Capbs = T1 + vbs_jct * T2 ; + } + } + + /* Drain Bulk Junction */ + if (here->HSM2_pd > here->HSM2_weff_nf) { + czbdsw = model->HSM2_cjsw * ( here->HSM2_pd - here->HSM2_weff_nf ) ; + czbdsw = czbdsw * ( 1.0 + tcjbdsw * ( TTEMP - model->HSM2_tnom )) ; + czbdswg = model->HSM2_cjswg * here->HSM2_weff_nf ; + czbdswg = czbdswg * ( 1.0 + tcjbdswg * ( TTEMP - model->HSM2_tnom )) ; + if (vbd_jct == 0.0) { + Qbd = 0.0 ; + Capbd = czbd + czbdsw + czbdswg ; + } else if (vbd_jct < 0.0) { + if (czbd > 0.0) { + arg = 1.0 - vbd_jct / model->HSM2_pb ; + if (model->HSM2_mj == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mj ) ; + Qbd = model->HSM2_pb * czbd * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ; + Capbd = czbd * sarg ; + } else { + Qbd = 0.0 ; + Capbd = 0.0 ; + } + if (czbdsw > 0.0) { + arg = 1.0 - vbd_jct / model->HSM2_pbsw ; + if (model->HSM2_mjsw == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjsw ) ; + Qbd += model->HSM2_pbsw * czbdsw * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjsw) ; + Capbd += czbdsw * sarg ; + } + if (czbdswg > 0.0) { + arg = 1.0 - vbd_jct / model->HSM2_pbswg ; + if (model->HSM2_mjswg == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ; + Qbd += model->HSM2_pbswg * czbdswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ; + Capbd += czbdswg * sarg ; + } + } else { + T1 = czbd + czbdsw + czbdswg ; + T2 = czbd * model->HSM2_mj / model->HSM2_pb + + czbdsw * model->HSM2_mjsw / model->HSM2_pbsw + + czbdswg * model->HSM2_mjswg / model->HSM2_pbswg ; + Qbd = vbd_jct * (T1 + vbd_jct * 0.5 * T2) ; + Capbd = T1 + vbd_jct * T2 ; + } + + } else { + czbdswg = model->HSM2_cjswg * here->HSM2_pd ; + czbdswg = czbdswg * ( 1.0 + tcjbdswg * ( TTEMP - model->HSM2_tnom )) ; + if (vbd_jct == 0.0) { + Qbd = 0.0 ; + Capbd = czbd + czbdswg ; + } else if (vbd_jct < 0.0) { + if (czbd > 0.0) { + arg = 1.0 - vbd_jct / model->HSM2_pb ; + if (model->HSM2_mj == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mj ) ; + Qbd = model->HSM2_pb * czbd * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ; + Capbd = czbd * sarg ; + } else { + Qbd = 0.0 ; + Capbd = 0.0 ; + } + if (czbdswg > 0.0) { + arg = 1.0 - vbd_jct / model->HSM2_pbswg ; + if (model->HSM2_mjswg == 0.5) + sarg = 1.0 / sqrt(arg) ; + else + sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ; + Qbd += model->HSM2_pbswg * czbdswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ; + Capbd += czbdswg * sarg ; + } + } else { + T1 = czbd + czbdswg ; + T2 = czbd * model->HSM2_mj / model->HSM2_pb + + czbdswg * model->HSM2_mjswg / model->HSM2_pbswg ; + Qbd = vbd_jct * (T1 + vbd_jct * 0.5 * T2) ; + Capbd = T1 + vbd_jct * T2 ; + } + } + + /*-----------------------------------------------------------* + * End of PART-4. (label) + *-----------------*/ + + end_of_part_4: + + + + /*-----------------------------------------------------------* + * PART-5: NQS. (label) + *-----------------*/ + if (flg_nqs) { + + if(ckt->CKTmode & MODETRAN){ + if( ckt->CKTmode & MODEINITTRAN ){ + Qi_nqs = Qi ; + Qi_dVgs_nqs = Qi_dVgs ; + Qi_dVds_nqs = Qi_dVds ; + Qi_dVbs_nqs = Qi_dVbs ; + + Qb_nqs = Qb ; + Qb_dVgs_nqs = Qb_dVgs ; + Qb_dVds_nqs = Qb_dVds ; + Qb_dVbs_nqs = Qb_dVbs ; + } else { + /* tau for inversion charge */ + if (flg_noqi == 0) { + T12 = model->HSM2_dly1; + T10 = model->HSM2_dly2; + + T3 = Lch ; + T1 = T10 * T12 * T3 * T3 ; + T2 = Mu * VgVt * T12 + T10 * T3 * T3 + small ; + tau = T1 / T2 ; + + T1_dVg = T10 * T12 * 2.0 * T3 * Lch_dVgs ; + T1_dVd = T10 * T12 * 2.0 * T3 * Lch_dVds ; + T1_dVb = T10 * T12 * 2.0 * T3 * Lch_dVbs ; + + T2_dVg = T12 * Mu_dVgs * VgVt + + T12 * Mu * VgVt_dVgs + T10 * 2.0 * T3 * Lch_dVgs ; + T2_dVd = T12 * Mu_dVds * VgVt + + T12 * Mu * VgVt_dVds + T10 * 2.0 * T3 * Lch_dVds ; + T2_dVb = T12 * Mu_dVbs * VgVt + + T12 * Mu * VgVt_dVbs + T10 * 2.0 * T3 * Lch_dVbs ; + + T4 = 1.0 / ( T2 * T2 ) ; + tau_dVgs = ( T2 * T1_dVg - T1 * T2_dVg ) * T4 ; + tau_dVds = ( T2 * T1_dVd - T1 * T2_dVd ) * T4 ; + tau_dVbs = ( T2 * T1_dVb - T1 * T2_dVb ) * T4 ; + } else { + tau = model->HSM2_dly1 + small ; + tau_dVgs = tau_dVds = tau_dVbs = 0.0 ; + } + + T1 = ckt->CKTdelta ; + + /* Calculation of Qi */ + Qi_prev = *(ckt->CKTstate1 + here->HSM2qi_nqs) ; + T2 = T1 + tau ; + T0 = Qi - Qi_prev ; + Qi_nqs = Qi_prev + T1 / T2 * T0; + T3 = T1 / T2 ; + T4 = T0 / T2 ; + Qi_dVgs_nqs = T3 * (Qi_dVgs - T4 * tau_dVgs); + Qi_dVds_nqs = T3 * (Qi_dVds - T4 * tau_dVds); + Qi_dVbs_nqs = T3 * (Qi_dVbs - T4 * tau_dVbs); + + /* tau for bulk charge */ + T2 = model->HSM2_dly3 ; + taub = T2 * Cox ; + taub_dVgs = T2 * Cox_dVg ; + taub_dVds = T2 * Cox_dVd ; + taub_dVbs = T2 * Cox_dVb ; + /* Calculation of Qb */ + Qb_prev = *(ckt->CKTstate1 + here->HSM2qb_nqs) ; + T2 = T1 + taub ; + T0 = Qb - Qb_prev ; + Qb_nqs = Qb_prev + T1 / T2 * T0 ; + T3 = T1 / T2 ; + T4 = T0 / T2 ; + Qb_dVgs_nqs = T3 * (Qb_dVgs - T4 * taub_dVgs) ; + Qb_dVds_nqs = T3 * (Qb_dVds - T4 * taub_dVds) ; + Qb_dVbs_nqs = T3 * (Qb_dVbs - T4 * taub_dVbs) ; + } + } else { /* !(CKT_mode & MODETRAN) */ + Qi_nqs = Qi ; + Qi_dVgs_nqs = Qi_dVgs ; + Qi_dVds_nqs = Qi_dVds ; + Qi_dVbs_nqs = Qi_dVbs ; + + Qb_nqs = Qb ; + Qb_dVgs_nqs = Qb_dVgs ; + Qb_dVds_nqs = Qb_dVds ; + Qb_dVbs_nqs = Qb_dVbs ; + } + } + + if ( flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG)) ) { /* ACNQS */ + + if (flg_noqi == 0) { + T10 = model->HSM2_dly1 ; + T11 = model->HSM2_dly2 ; + T12 = Lch ; + + T1 = T10 * T11 * T12 * T12 ; + T2 = Mu * VgVt * T10 + T11 * T12 * T12 + small ; + tau = T1 / T2 ; + + T1_dVg = T10 * T11 * 2.0 * T12 * Lch_dVgs ; + T1_dVd = T10 * T11 * 2.0 * T12 * Lch_dVds ; + T1_dVb = T10 * T11 * 2.0 * T12 * Lch_dVbs ; + T2_dVg = T10 * Mu_dVgs * VgVt + T10 * Mu * VgVt_dVgs + + T11 * 2.0 * T12 * Lch_dVgs ; + T2_dVd = T10 * Mu_dVds * VgVt + T10 * Mu * VgVt_dVds + + T11 * 2.0 * T12 * Lch_dVds ; + T2_dVb = T10 * Mu_dVbs * VgVt + T10 * Mu * VgVt_dVbs + + T11 * 2.0 * T12 * Lch_dVbs ; + + T3 = 1.0 / T2 ; + tau_dVgs = (T1_dVg - tau * T2_dVg) * T3 ; + tau_dVds = (T1_dVd - tau * T2_dVd) * T3 ; + tau_dVbs = (T1_dVb - tau * T2_dVb) * T3 ; + } else { + tau = model->HSM2_dly1 + small ; + tau_dVgs = tau_dVds = tau_dVbs = 0.0 ; + } + + T1 = model->HSM2_dly3 ; + taub = T1 * Cox ; + taub_dVgs = T1 * Cox_dVg ; + taub_dVds = T1 * Cox_dVd ; + taub_dVbs = T1 * Cox_dVb ; + } + + /*-----------------------------------------------------------* + * End of PART-5. (label) + *-----------------*/ + end_of_part_5: + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-6: Noise Calculation. + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + /*-----------------------------------------------------------* + * 1/f noise. + *-----------------*/ + if ( model->HSM2_coflick != 0 && !flg_noqi ) { + + NFalp = pParam->HSM2_nfalp ; + NFtrp = pParam->HSM2_nftrp ; + Cit = model->HSM2_cit ; + + T1 = Qn0 / C_QE ; + T2 = ( Cox + Qn0 / ( Ps0 - Vbs ) + Cit ) * beta_inv / C_QE ; + T3 = -2.0E0 * Qi / C_QE / Lch / here->HSM2_weff_nf - T1 ; + if ( T3 != T1 ) { + T4 = 1.0E0 / ( T1 + T2 ) / ( T3 + T2 ) + 2.0E0 * NFalp * Ey * Mu / ( T3 - T1 ) + * log( ( T3 + T2 ) / ( T1 + T2 ) ) + NFalp * Ey * Mu * NFalp * Ey * Mu ; + } else { + T4 = 1.0 / ( T1 + T2 ) / ( T3 + T2 ) + 2.0 * NFalp * Ey * Mu / ( T1 + T2 ) + + NFalp * Ey * Mu * NFalp * Ey * Mu; + } + Nflic = Ids * Ids * NFtrp / ( Lch * beta * here->HSM2_weff_nf ) * T4 ; + } else { + Nflic = 0.0 ; + } + + /*-----------------------------------------------------------* + * thermal noise. + *-----------------*/ + if ( model->HSM2_cothrml != 0 && !flg_noqi ) { + + Eyd = ( Psdl - Ps0 ) / Lch ; + T12 = Muun * Eyd / 1.0e7 ; + /* note: model->HSM2_bb = 2 (electron) ;1 (hole) */ + if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) { + T7 = 1.0e0 ; + } else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) { + T7 = T12 ; + } else { + T7 = Fn_Pow( Eyd, model->HSM2_bb - 1.0e0 ) ; + } + T8 = T12 * T7 ; + T9 = 1.0e0 + T8 ; + T10 = Fn_Pow( T9, ( - 1.0e0 / model->HSM2_bb - 1.0e0 ) ) ; + T11 = T9 * T10 ; + Mud_hoso = Muun * T11 ; + Mu_Ave = ( Mu + Mud_hoso ) / 2.0 ; + + /* Sid_h = GAMMA * 4.0 * C_KB * model->HSM2_temp * gds0_h2; */ + T0 = Alpha * Alpha ; + Nthrml = here->HSM2_weff_nf * Cox * VgVt * Mu + * ( ( 1e0 + 3e0 * Alpha + 6e0 * T0 ) * Mud_hoso * Mud_hoso + + ( 3e0 + 4e0 * Alpha + 3e0 * T0 ) * Mud_hoso * Mu + + ( 6e0 + 3e0 * Alpha + T0 ) * Mu * Mu ) + / ( 15e0 * Lch * ( 1e0 + Alpha ) * Mu_Ave * Mu_Ave ) ; + } else { + Nthrml = 0e0 ; + } + + + /*----------------------------------------------------------* + * induced gate noise. ( Part 2/3 ) + *----------------------*/ + if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 && flg_ign == 1 && !flg_noqi ) { + sqrtkusaiL = sqrt( kusaiL ) ; + T2 = VgVt + sqrtkusaiL ; + T3 = kusai00 * kusai00 ; + T4 = kusaiL * kusaiL ; + T5 = 42.0e0 * kusai00 * kusaiL ; + T5 += 4.0e0 * ( T3 + T4 ) ; + T5 += 20.0e0 * sqrtkusaiL * VgVt * ( kusai00 + kusaiL ) ; + T10 = T2 * T2 ; + T10 *= T10 ; + kusai_ig = T5 / ( T10 * T2 ) ; /* Induced Gate Noise parameter */ + gds0_ign = here->HSM2_weff_nf / Lch * Mu * Cox ; + gds0_h2 = gds0_ign * VgVt ; + GAMMA = Nthrml / gds0_h2 ; + T7 = kusai00 + 4.0e0 * VgVt * sqrtkusaiL + kusaiL ; + /* cross-correlation coefficient (= Sigid/sqrt(Sig*Sid) ) */ + crl_f = c_sqrt_15 * kusai00L * T7 + / ( 6.0e0 * T2 * sqrt( GAMMA * T2 * VgVt * T5 ) ) ; + } + + + /*-----------------------------------------------------------* + * End of PART-6. (label) + *-----------------*/ + end_of_part_6: + + + /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + * PART-7: Evaluation of outputs. + *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ + + /*-----------------------------------------------------------* + * Implicit quantities related to Alpha. + *-----------------*/ + /* note: T1 = 1 + Delta */ + if ( flg_noqi == 0 && VgVt > VgVt_small ) { + Delta = fac1 * beta / ( 2 * Xi0p12 ) ; + Pslsat = VgVt / ( 1.0 + Delta ) + Ps0 ; + } else { + Pslsat = 0.0 ; + } + Vdsat = Pslsat - Pb2 ; + if ( Vdsat < 0.0 ) { + Vdsat = 0.0 ; + } + + /*-----------------------------------------------------------* + * Evaluate the derivatives w.r.t. external biases. + * - All derivatives that influence outputs must be modified here. + *-----------------*/ + + /*---------------------------------------------------* + * Case ignoring Rs/Rd. + *-----------------*/ + if ( flg_rsrd != 1 || Ids < 0.0 ) { + Ids_dVbse = Ids_dVbs ; Ids_dVdse = Ids_dVds ; Ids_dVgse = Ids_dVgs ; + Qb_dVbse = Qb_dVbs ; Qb_dVdse = Qb_dVds ; Qb_dVgse = Qb_dVgs ; + Qi_dVbse = Qi_dVbs ; Qi_dVdse = Qi_dVds ; Qi_dVgse = Qi_dVgs ; + Qd_dVbse = Qd_dVbs ; Qd_dVdse = Qd_dVds ; Qd_dVgse = Qd_dVgs ; + Isub_dVbse = Isub_dVbs ; Isub_dVdse = Isub_dVds ; Isub_dVgse = Isub_dVgs ; + IdsIBPC_dVbse = IdsIBPC_dVbs ; IdsIBPC_dVdse = IdsIBPC_dVds ; IdsIBPC_dVgse = IdsIBPC_dVgs ; + Igate_dVbse = Igate_dVbs ; Igate_dVdse = Igate_dVds ; Igate_dVgse = Igate_dVgs ; + Igd_dVbse = Igd_dVbs ; Igd_dVdse = Igd_dVds ; Igd_dVgse = Igd_dVgs ; + Igs_dVbse = Igs_dVbs ; Igs_dVdse = Igs_dVds ; Igs_dVgse = Igs_dVgs ; + Igb_dVbse = Igb_dVbs ; Igb_dVdse = Igb_dVds ; Igb_dVgse = Igb_dVgs ; + Igidl_dVbse = Igidl_dVbs ; Igidl_dVdse = Igidl_dVds ; Igidl_dVgse = Igidl_dVgs ; + Igisl_dVbse = Igisl_dVbs ; Igisl_dVdse = Igisl_dVds ; Igisl_dVgse = Igisl_dVgs ; + Qgos_dVbse = Qgos_dVbs ; Qgos_dVdse = Qgos_dVds ; Qgos_dVgse = Qgos_dVgs ; + Qgod_dVbse = Qgod_dVbs ; Qgod_dVdse = Qgod_dVds ; Qgod_dVgse = Qgod_dVgs ; + Qgbo_dVbse = Qgbo_dVbs ; Qgbo_dVdse = Qgbo_dVds ; Qgbo_dVgse = Qgbo_dVgs ; + Qovd_dVbse = Qovd_dVbs ; Qovd_dVdse = Qovd_dVds ; Qovd_dVgse = Qovd_dVgs ; + QidLD_dVbse = QidLD_dVbs ; QidLD_dVdse = QidLD_dVds ; QidLD_dVgse = QidLD_dVgs ; + QbdLD_dVbse = QbdLD_dVbs ; QbdLD_dVdse = QbdLD_dVds ; QbdLD_dVgse = QbdLD_dVgs ; + Qovs_dVbse = Qovs_dVbs ; Qovs_dVdse = Qovs_dVds ; Qovs_dVgse = Qovs_dVgs ; + QisLD_dVbse = QisLD_dVbs ; QisLD_dVdse = QisLD_dVds ; QisLD_dVgse = QisLD_dVgs ; + QbsLD_dVbse = QbsLD_dVbs ; QbsLD_dVdse = QbsLD_dVds ; QbsLD_dVgse = QbsLD_dVgs ; + Qy_dVbse = Qy_dVbs ; Qy_dVdse = Qy_dVds ; Qy_dVgse = Qy_dVgs ; + Qdrat_dVbse = Qdrat_dVbs; Qdrat_dVdse = Qdrat_dVds; Qdrat_dVgse = Qdrat_dVgs; + GLPART1_dVbse = GLPART1_dVbs ;GLPART1_dVdse = GLPART1_dVds ;GLPART1_dVgse = GLPART1_dVgs ; + + if (flg_nqs) { /* NQS */ + Qi_dVgse_nqs = Qi_dVgs_nqs; Qi_dVdse_nqs = Qi_dVds_nqs; Qi_dVbse_nqs = Qi_dVbs_nqs; + Qb_dVgse_nqs = Qb_dVgs_nqs; Qb_dVdse_nqs = Qb_dVds_nqs; Qb_dVbse_nqs = Qb_dVbs_nqs; + } + if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */ + tau_dVgse = tau_dVgs ; tau_dVdse = tau_dVds ; tau_dVbse = tau_dVbs ; + taub_dVgse = taub_dVgs ; taub_dVdse = taub_dVds ; taub_dVbse = taub_dVbs ; + } + + } else { + /*---------------------------------------------------* + * Case Rs>0 or Rd>0 + *-----------------*/ + + /*-------------------------------------------* + * Conductances w.r.t. confined biases. + *-----------------*/ + Ids_dVbse = Ids_dVbs * DJI ; + Ids_dVdse = Ids_dVds * DJI ; + Ids_dVgse = Ids_dVgs * DJI ; + + /*-------------------------------------------* + * Derivatives of internal biases w.r.t. external biases. + *-----------------*/ + Vbs_dVbse = ( 1.0 - Rs * Ids_dVbse ) ; + Vbs_dVdse = - Rs * Ids_dVdse ; + Vbs_dVgse = - Rs * Ids_dVgse ; + + Vds_dVbse = - ( Rs + Rd ) * Ids_dVbse ; + Vds_dVdse = ( 1.0 - ( Rs + Rd ) * Ids_dVdse ) ; + Vds_dVgse = - ( Rs + Rd ) * Ids_dVgse ; + + Vgs_dVbse = - Rs * Ids_dVbse ; + Vgs_dVdse = - Rs * Ids_dVdse ; + Vgs_dVgse = ( 1.0 - Rs * Ids_dVgse ) ; + + /*-------------------------------------------* + * Derivatives of charges. + *-----------------*/ + Qb_dVbse = Qb_dVbs * Vbs_dVbse + Qb_dVds * Vds_dVbse + Qb_dVgs * Vgs_dVbse ; + Qb_dVdse = Qb_dVbs * Vbs_dVdse + Qb_dVds * Vds_dVdse + Qb_dVgs * Vgs_dVdse ; + Qb_dVgse = Qb_dVbs * Vbs_dVgse + Qb_dVds * Vds_dVgse + Qb_dVgs * Vgs_dVgse ; + Qi_dVbse = Qi_dVbs * Vbs_dVbse + Qi_dVds * Vds_dVbse + Qi_dVgs * Vgs_dVbse ; + Qi_dVdse = Qi_dVbs * Vbs_dVdse + Qi_dVds * Vds_dVdse + Qi_dVgs * Vgs_dVdse ; + Qi_dVgse = Qi_dVbs * Vbs_dVgse + Qi_dVds * Vds_dVgse + Qi_dVgs * Vgs_dVgse ; + Qd_dVbse = Qd_dVbs * Vbs_dVbse + Qd_dVds * Vds_dVbse + Qd_dVgs * Vgs_dVbse ; + Qd_dVdse = Qd_dVbs * Vbs_dVdse + Qd_dVds * Vds_dVdse + Qd_dVgs * Vgs_dVdse ; + Qd_dVgse = Qd_dVbs * Vbs_dVgse + Qd_dVds * Vds_dVgse + Qd_dVgs * Vgs_dVgse ; + + /*-------------------------------------------* + * Substrate/gate/leak conductances. + *-----------------*/ + Isub_dVbse = Isub_dVbs * Vbs_dVbse + Isub_dVds * Vds_dVbse + Isub_dVgs * Vgs_dVbse ; + Isub_dVdse = Isub_dVbs * Vbs_dVdse + Isub_dVds * Vds_dVdse + Isub_dVgs * Vgs_dVdse ; + Isub_dVgse = Isub_dVbs * Vbs_dVgse + Isub_dVds * Vds_dVgse + Isub_dVgs * Vgs_dVgse ; + IdsIBPC_dVbse = IdsIBPC_dVbs * Vbs_dVbse + IdsIBPC_dVds * Vds_dVbse + IdsIBPC_dVgs * Vgs_dVbse ; + IdsIBPC_dVdse = IdsIBPC_dVbs * Vbs_dVdse + IdsIBPC_dVds * Vds_dVdse + IdsIBPC_dVgs * Vgs_dVdse ; + IdsIBPC_dVgse = IdsIBPC_dVbs * Vbs_dVgse + IdsIBPC_dVds * Vds_dVgse + IdsIBPC_dVgs * Vgs_dVgse ; + Igate_dVbse = Igate_dVbs * Vbs_dVbse + Igate_dVds * Vds_dVbse + Igate_dVgs * Vgs_dVbse ; + Igate_dVdse = Igate_dVbs * Vbs_dVdse + Igate_dVds * Vds_dVdse + Igate_dVgs * Vgs_dVdse ; + Igate_dVgse = Igate_dVbs * Vbs_dVgse + Igate_dVds * Vds_dVgse + Igate_dVgs * Vgs_dVgse ; + Igb_dVbse = Igb_dVbs * Vbs_dVbse + Igb_dVds * Vds_dVbse + Igb_dVgs * Vgs_dVbse ; + Igb_dVdse = Igb_dVbs * Vbs_dVdse + Igb_dVds * Vds_dVdse + Igb_dVgs * Vgs_dVdse ; + Igb_dVgse = Igb_dVbs * Vbs_dVgse + Igb_dVds * Vds_dVgse + Igb_dVgs * Vgs_dVgse ; + Igd_dVbse = Igd_dVbs * Vbs_dVbse + Igd_dVds * Vds_dVbse + Igd_dVgs * Vgs_dVbse ; + Igd_dVdse = Igd_dVbs * Vbs_dVdse + Igd_dVds * Vds_dVdse + Igd_dVgs * Vgs_dVdse ; + Igd_dVgse = Igd_dVbs * Vbs_dVgse + Igd_dVds * Vds_dVgse + Igd_dVgs * Vgs_dVgse ; + Igs_dVbse = Igs_dVbs * Vbs_dVbse + Igs_dVds * Vds_dVbse + Igs_dVgs * Vgs_dVbse ; + Igs_dVdse = Igs_dVbs * Vbs_dVdse + Igs_dVds * Vds_dVdse + Igs_dVgs * Vgs_dVdse ; + Igs_dVgse = Igs_dVbs * Vbs_dVgse + Igs_dVds * Vds_dVgse + Igs_dVgs * Vgs_dVgse ; + Igidl_dVbse = Igidl_dVbs * Vbs_dVbse + Igidl_dVds * Vds_dVbse + Igidl_dVgs * Vgs_dVbse ; + Igidl_dVdse = Igidl_dVbs * Vbs_dVdse + Igidl_dVds * Vds_dVdse + Igidl_dVgs * Vgs_dVdse ; + Igidl_dVgse = Igidl_dVbs * Vbs_dVgse + Igidl_dVds * Vds_dVgse + Igidl_dVgs * Vgs_dVgse ; + Igisl_dVbse = Igisl_dVbs * Vbs_dVbse + Igisl_dVds * Vds_dVbse + Igisl_dVgs * Vgs_dVbse ; + Igisl_dVdse = Igisl_dVbs * Vbs_dVdse + Igisl_dVds * Vds_dVdse + Igisl_dVgs * Vgs_dVdse ; + Igisl_dVgse = Igisl_dVbs * Vbs_dVgse + Igisl_dVds * Vds_dVgse + Igisl_dVgs * Vgs_dVgse ; + + GLPART1_dVbse = GLPART1_dVbs * Vbs_dVbse + GLPART1_dVds * Vds_dVbse + GLPART1_dVgs * Vgs_dVbse ; + GLPART1_dVdse = GLPART1_dVbs * Vbs_dVdse + GLPART1_dVds * Vds_dVdse + GLPART1_dVgs * Vgs_dVdse ; + GLPART1_dVgse = GLPART1_dVbs * Vbs_dVgse + GLPART1_dVds * Vds_dVgse + GLPART1_dVgs * Vgs_dVgse ; + + /*---------------------------------------------------* + * Derivatives of overlap charges. + *-----------------*/ + Qgos_dVbse = Qgos_dVbs * Vbs_dVbse + Qgos_dVds * Vds_dVbse + Qgos_dVgs * Vgs_dVbse ; + Qgos_dVdse = Qgos_dVbs * Vbs_dVdse + Qgos_dVds * Vds_dVdse + Qgos_dVgs * Vgs_dVdse ; + Qgos_dVgse = Qgos_dVbs * Vbs_dVgse + Qgos_dVds * Vds_dVgse + Qgos_dVgs * Vgs_dVgse ; + Qgod_dVbse = Qgod_dVbs * Vbs_dVbse + Qgod_dVds * Vds_dVbse + Qgod_dVgs * Vgs_dVbse ; + Qgod_dVdse = Qgod_dVbs * Vbs_dVdse + Qgod_dVds * Vds_dVdse + Qgod_dVgs * Vgs_dVdse ; + Qgod_dVgse = Qgod_dVbs * Vbs_dVgse + Qgod_dVds * Vds_dVgse + Qgod_dVgs * Vgs_dVgse ; + Qgbo_dVbse = Qgbo_dVbs * Vbs_dVbse + Qgbo_dVds * Vds_dVbse + Qgbo_dVgs * Vgs_dVbse ; + Qgbo_dVdse = Qgbo_dVbs * Vbs_dVdse + Qgbo_dVds * Vds_dVdse + Qgbo_dVgs * Vgs_dVdse ; + Qgbo_dVgse = Qgbo_dVbs * Vbs_dVgse + Qgbo_dVds * Vds_dVgse + Qgbo_dVgs * Vgs_dVgse ; + Qovd_dVbse = Qovd_dVbs * Vbs_dVbse + Qovd_dVds * Vds_dVbse + Qovd_dVgs * Vgs_dVbse ; + Qovd_dVdse = Qovd_dVbs * Vbs_dVdse + Qovd_dVds * Vds_dVdse + Qovd_dVgs * Vgs_dVdse ; + Qovd_dVgse = Qovd_dVbs * Vbs_dVgse + Qovd_dVds * Vds_dVgse + Qovd_dVgs * Vgs_dVgse ; + QidLD_dVbse = QidLD_dVbs * Vbs_dVbse + QidLD_dVds * Vds_dVbse + QidLD_dVgs * Vgs_dVbse ; + QidLD_dVdse = QidLD_dVbs * Vbs_dVdse + QidLD_dVds * Vds_dVdse + QidLD_dVgs * Vgs_dVdse ; + QidLD_dVgse = QidLD_dVbs * Vbs_dVgse + QidLD_dVds * Vds_dVgse + QidLD_dVgs * Vgs_dVgse ; + QbdLD_dVbse = QbdLD_dVbs * Vbs_dVbse + QbdLD_dVds * Vds_dVbse + QbdLD_dVgs * Vgs_dVbse ; + QbdLD_dVdse = QbdLD_dVbs * Vbs_dVdse + QbdLD_dVds * Vds_dVdse + QbdLD_dVgs * Vgs_dVdse ; + QbdLD_dVgse = QbdLD_dVbs * Vbs_dVgse + QbdLD_dVds * Vds_dVgse + QbdLD_dVgs * Vgs_dVgse ; + Qovs_dVbse = Qovs_dVbs * Vbs_dVbse + Qovs_dVds * Vds_dVbse + Qovs_dVgs * Vgs_dVbse ; + Qovs_dVdse = Qovs_dVbs * Vbs_dVdse + Qovs_dVds * Vds_dVdse + Qovs_dVgs * Vgs_dVdse ; + Qovs_dVgse = Qovs_dVbs * Vbs_dVgse + Qovs_dVds * Vds_dVgse + Qovs_dVgs * Vgs_dVgse ; + QisLD_dVbse = QisLD_dVbs * Vbs_dVbse + QisLD_dVds * Vds_dVbse + QisLD_dVgs * Vgs_dVbse ; + QisLD_dVdse = QisLD_dVbs * Vbs_dVdse + QisLD_dVds * Vds_dVdse + QisLD_dVgs * Vgs_dVdse ; + QisLD_dVgse = QisLD_dVbs * Vbs_dVgse + QisLD_dVds * Vds_dVgse + QisLD_dVgs * Vgs_dVgse ; + QbsLD_dVbse = QbsLD_dVbs * Vbs_dVbse + QbsLD_dVds * Vds_dVbse + QbsLD_dVgs * Vgs_dVbse ; + QbsLD_dVdse = QbsLD_dVbs * Vbs_dVdse + QbsLD_dVds * Vds_dVdse + QbsLD_dVgs * Vgs_dVdse ; + QbsLD_dVgse = QbsLD_dVbs * Vbs_dVgse + QbsLD_dVds * Vds_dVgse + QbsLD_dVgs * Vgs_dVgse ; + Qy_dVbse = Qy_dVbs * Vbs_dVbse + Qy_dVds * Vds_dVbse + Qy_dVgs * Vgs_dVbse ; + Qy_dVdse = Qy_dVbs * Vbs_dVdse + Qy_dVds * Vds_dVdse + Qy_dVgs * Vgs_dVdse ; + Qy_dVgse = Qy_dVbs * Vbs_dVgse + Qy_dVds * Vds_dVgse + Qy_dVgs * Vgs_dVgse ; + Qdrat_dVbse = Qdrat_dVbs * Vbs_dVbse + Qdrat_dVds * Vds_dVbse + Qdrat_dVgs * Vgs_dVbse ; + Qdrat_dVdse = Qdrat_dVbs * Vbs_dVdse + Qdrat_dVds * Vds_dVdse + Qdrat_dVgs * Vgs_dVdse ; + Qdrat_dVgse = Qdrat_dVbs * Vbs_dVgse + Qdrat_dVds * Vds_dVgse + Qdrat_dVgs * Vgs_dVgse ; + + if (flg_nqs) { /* NQS */ + Qi_dVgse_nqs = Qi_dVgs_nqs * Vgs_dVgse + Qi_dVds_nqs * Vds_dVgse + Qi_dVbs_nqs * Vbs_dVgse; + Qi_dVdse_nqs = Qi_dVgs_nqs * Vgs_dVdse + Qi_dVds_nqs * Vds_dVdse + Qi_dVbs_nqs * Vbs_dVdse; + Qi_dVbse_nqs = Qi_dVgs_nqs * Vgs_dVbse + Qi_dVds_nqs * Vds_dVbse + Qi_dVbs_nqs * Vbs_dVbse; + Qb_dVgse_nqs = Qb_dVgs_nqs * Vgs_dVgse + Qb_dVds_nqs * Vds_dVgse + Qb_dVbs_nqs * Vbs_dVgse; + Qb_dVdse_nqs = Qb_dVgs_nqs * Vgs_dVdse + Qb_dVds_nqs * Vds_dVdse + Qb_dVbs_nqs * Vbs_dVdse; + Qb_dVbse_nqs = Qb_dVgs_nqs * Vgs_dVbse + Qb_dVds_nqs * Vds_dVbse + Qb_dVbs_nqs * Vbs_dVbse; + } + if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */ + tau_dVgse = tau_dVgs * Vgs_dVgse + tau_dVds * Vds_dVgse + tau_dVbs * Vbs_dVgse; + tau_dVdse = tau_dVgs * Vgs_dVdse + tau_dVds * Vds_dVdse + tau_dVbs * Vbs_dVdse; + tau_dVbse = tau_dVgs * Vgs_dVbse + tau_dVds * Vds_dVbse + tau_dVbs * Vbs_dVbse; + taub_dVgse = taub_dVgs * Vgs_dVgse + taub_dVds * Vds_dVgse + taub_dVbs * Vbs_dVgse; + taub_dVdse = taub_dVgs * Vgs_dVdse + taub_dVds * Vds_dVdse + taub_dVbs * Vbs_dVdse; + taub_dVbse = taub_dVgs * Vgs_dVbse + taub_dVds * Vds_dVbse + taub_dVbs * Vbs_dVbse; + } + } /* end of if ( flg_rsrd == 0 ) blocks */ + + /*-------------------------------------------* + * Add IdsIBPC to Ids. + *-----------------*/ + Ids += IdsIBPC ; + Ids_dVbse += IdsIBPC_dVbse ; + Ids_dVdse += IdsIBPC_dVdse ; + Ids_dVgse += IdsIBPC_dVgse ; + + /*---------------------------------------------------* + * Derivatives of junction diode currents and charges. + * - NOTE: These quantities are regarded as functions of + * external biases. + * - NOTE: node-base S/D + *-----------------*/ + Gbse = Gbs ; + Gbde = Gbd ; + Capbse = Capbs ; + Capbde = Capbd ; + + /*---------------------------------------------------* + * Extrapolate quantities if external biases are out of bounds. + *-----------------*/ + if ( flg_vbsc == 1 ) { + Ids_dVbse *= Vbsc_dVbse ; + Qb_dVbse *= Vbsc_dVbse ; + Qi_dVbse *= Vbsc_dVbse ; + Qd_dVbse *= Vbsc_dVbse ; + Isub_dVbse *= Vbsc_dVbse ; + Igate_dVbse *= Vbsc_dVbse ; + Igs_dVbse *= Vbsc_dVbse ; + Igd_dVbse *= Vbsc_dVbse ; + Igb_dVbse *= Vbsc_dVbse ; + Igidl_dVbse *= Vbsc_dVbse ; + Igisl_dVbse *= Vbsc_dVbse ; + Qgos_dVbse *= Vbsc_dVbse ; + Qgod_dVbse *= Vbsc_dVbse ; + Qgbo_dVbse *= Vbsc_dVbse ; + Qy_dVbse *= Vbsc_dVbse ; + if (flg_nqs) { + Qi_dVbse_nqs *= Vbsc_dVbse ; + Qb_dVbse_nqs *= Vbsc_dVbse ; + } + if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */ + tau_dVbse *= Vbsc_dVbse ; + taub_dVbse *= Vbsc_dVbse ; + } + } else if ( flg_vbsc == -1 ) { + T1 = Vbse - Vbsc ; + + TX = Ids + T1 * Ids_dVbse ; + if ( TX * Ids >= 0.0 ) { + Ids = TX ; + } else { + Ids_dVbse = 0.0 ; + Ids_dVdse = 0.0 ; + Ids_dVgse = 0.0 ; + Ids = 0.0 ; + } + + TX = Qb + T1 * Qb_dVbse ; + /*note: The sign of Qb can be changed.*/ + Qb = TX ; + + TX = Qd + T1 * Qd_dVbse ; + if ( TX * Qd >= 0.0 ) { + Qd = TX ; + } else { + Qd_dVbse = 0.0 ; + Qd_dVdse = 0.0 ; + Qd_dVgse = 0.0 ; + Qd = 0.0 ; + } + + TX = Qi + T1 * Qi_dVbse ; + if ( TX * Qi >= 0.0 ) { + Qi = TX ; + } else { + Qi_dVbse = 0.0 ; + Qi_dVdse = 0.0 ; + Qi_dVgse = 0.0 ; + Qi = 0.0 ; + } + + TX = Isub + T1 * Isub_dVbse ; + if ( TX * Isub >= 0.0 ) { + Isub = TX ; + } else { + Isub_dVbse = 0.0 ; + Isub_dVdse = 0.0 ; + Isub_dVgse = 0.0 ; + Isub = 0.0 ; + } + + TX = Igate + T1 * Igate_dVbse ; + if ( TX * Igate >= 0.0 ) { + Igate = TX ; + } else { + Igate_dVbse = 0.0 ; + Igate_dVdse = 0.0 ; + Igate_dVgse = 0.0 ; + Igate = 0.0 ; + } + + TX = Igs + T1 * Igs_dVbse ; + if ( TX * Igs >= 0.0 ) { + Igs = TX ; + } else { + Igs_dVbse = 0.0 ; + Igs_dVdse = 0.0 ; + Igs_dVgse = 0.0 ; + Igs = 0.0 ; + } + + TX = Igd + T1 * Igd_dVbse ; + if ( TX * Igd >= 0.0 ) { + Igd = TX ; + } else { + Igd_dVbse = 0.0 ; + Igd_dVdse = 0.0 ; + Igd_dVgse = 0.0 ; + Igd = 0.0 ; + } + + TX = Igb + T1 * Igb_dVbse ; + if ( TX * Igb >= 0.0 ) { + Igb = TX ; + } else { + Igb_dVbse = 0.0 ; + Igb_dVdse = 0.0 ; + Igb_dVgse = 0.0 ; + Igb = 0.0 ; + } + + TX = Igidl + T1 * Igidl_dVbse ; + if ( TX * Igidl >= 0.0 ) { + Igidl = TX ; + } else { + Igidl_dVbse = 0.0 ; + Igidl_dVdse = 0.0 ; + Igidl_dVgse = 0.0 ; + Igidl = 0.0 ; + } + + TX = Igisl + T1 * Igisl_dVbse ; + if ( TX * Igisl >= 0.0 ) { + Igisl = TX ; + } else { + Igisl_dVbse = 0.0 ; + Igisl_dVdse = 0.0 ; + Igisl_dVgse = 0.0 ; + Igisl = 0.0 ; + } + + TX = GLPART1 + T1 * GLPART1_dVbse ; + if ( TX * GLPART1 >= 0.0 ) { + GLPART1 = TX ; + } else{ + GLPART1_dVbse = 0.0 ; + GLPART1_dVdse = 0.0 ; + GLPART1_dVgse = 0.0 ; + GLPART1 = 0.0 ; + } + + TX = Qgod + T1 * Qgod_dVbse ; + if ( TX * Qgod >= 0.0 ) { + Qgod = TX ; + } else { + Qgod_dVbse = 0.0 ; + Qgod_dVdse = 0.0 ; + Qgod_dVgse = 0.0 ; + Qgod = 0.0 ; + } + + TX = Qgos + T1 * Qgos_dVbse ; + if ( TX * Qgos >= 0.0 ) { + Qgos = TX ; + } else { + Qgos_dVbse = 0.0 ; + Qgos_dVdse = 0.0 ; + Qgos_dVgse = 0.0 ; + Qgos = 0.0 ; + } + + TX = Qgbo + T1 * Qgbo_dVbse ; + if ( TX * Qgbo >= 0.0 ) { + Qgbo = TX ; + } else { + Qgbo_dVbse = 0.0 ; + Qgbo_dVdse = 0.0 ; + Qgbo_dVgse = 0.0 ; + Qgbo = 0.0 ; + } + + TX = Qy + T1 * Qy_dVbse ; + if ( TX * Qy >= 0.0 ) { + Qy = TX ; + } else { + Qy_dVbse = 0.0 ; + Qy_dVdse = 0.0 ; + Qy_dVgse = 0.0 ; + Qy = 0.0 ; + } + + TX = Qdrat + T1 * Qdrat_dVbse ; + if ( TX * Qdrat >= 0.0 ) { + Qdrat = TX ; + } else{ + Qdrat_dVbse = 0.0 ; + Qdrat_dVdse = 0.0 ; + Qdrat_dVgse = 0.0 ; + Qdrat = 0.0 ; + } + + TX = Qovd + T1 * Qovd_dVbse ; + if ( TX * Qovd >= 0.0 ) { + Qovd = TX ; + } else{ + Qovd_dVbse = 0.0 ; + Qovd_dVdse = 0.0 ; + Qovd_dVgse = 0.0 ; + Qovd = 0.0 ; + } + + TX = QidLD + T1 * QidLD_dVbse ; + if ( TX * QidLD >= 0.0 ) { + QidLD = TX ; + } else{ + QidLD_dVbse = 0.0 ; + QidLD_dVdse = 0.0 ; + QidLD_dVgse = 0.0 ; + QidLD = 0.0 ; + } + + TX = QbdLD + T1 * QbdLD_dVbse ; + if ( TX * QbdLD >= 0.0 ) { + QbdLD = TX ; + } else{ + QbdLD_dVbse = 0.0 ; + QbdLD_dVdse = 0.0 ; + QbdLD_dVgse = 0.0 ; + QbdLD = 0.0 ; + } + + TX = Qovs + T1 * Qovs_dVbse ; + if ( TX * Qovs >= 0.0 ) { + Qovs = TX ; + } else{ + T7 = Qovs / ( Qovs - TX ) ; + Qovs_dVbse *= T7 ; + Qovs_dVdse *= T7 ; + Qovs_dVgse *= T7 ; + Qovs = 0.0 ; + } + + TX = QisLD + T1 * QisLD_dVbse ; + if ( TX * QisLD >= 0.0 ) { + QisLD = TX ; + } else{ + QisLD_dVbse = 0.0 ; + QisLD_dVdse = 0.0 ; + QisLD_dVgse = 0.0 ; + QisLD = 0.0 ; + } + + TX = QbsLD + T1 * QbsLD_dVbse ; + if ( TX * QbsLD >= 0.0 ) { + QbsLD = TX ; + } else{ + QbsLD_dVbse = 0.0 ; + QbsLD_dVdse = 0.0 ; + QbsLD_dVgse = 0.0 ; + QbsLD = 0.0 ; + } + + if (flg_nqs) { /* for NQS charge */ + TX = Qi_nqs + T1 * Qi_dVbse_nqs ; + if ( TX * Qi_nqs >= 0.0 ) { + Qi_nqs = TX ; + } else { + Qi_dVbse_nqs = 0.0 ; + Qi_dVdse_nqs = 0.0 ; + Qi_dVgse_nqs = 0.0 ; + Qi_nqs = 0.0 ; + } + + TX = Qb_nqs + T1 * Qb_dVbse_nqs ; + Qb_nqs = TX ; + } + + if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */ + TX = tau + T1 * tau_dVbse ; + if ( TX * tau >= 0.0 ) { + tau = TX ; + } else { + tau_dVbse = 0.0 ; + tau_dVdse = 0.0 ; + tau_dVgse = 0.0 ; + tau = 0.0 ; + } + + TX = taub + T1 * taub_dVbse ; + if ( TX * taub >= 0.0 ) { + taub = TX ; + } else { + taub_dVbse = 0.0 ; + taub_dVdse = 0.0 ; + taub_dVgse = 0.0 ; + taub = 0.0 ; + } + } + } + + /*-----------------------------------------------------------* + * Warn negative conductance. + * - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. + *-----------------*/ + if ( here->HSM2_mode == HiSIM_NORMAL_MODE ) { + T1 = Ids_dVdse ; + } else { + T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; /* Ids_dVss * -1 */ + } + + if ( flg_info >= 1 && + (Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0) ) { + printf( "*** warning(HiSIM): Negative Conductance\n" ) ; + printf( " type = %d mode = %d\n" , model->HSM2_type , here->HSM2_mode ) ; + printf( " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" , + Vbse , Vdse , Vgse ) ; + printf( " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; + printf( " Ids_dVdse = %12.5e\n" , T1 ) ; + printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; + } + + /*-----------------------------------------------------------* + * Redefine overlap charges/capacitances. + *-----------------*/ + /*---------------------------------------------------* + * Overlap capacitance. + *-----------------*/ + Cggo = Qgos_dVgse + Qgod_dVgse + Qgbo_dVgse ; + Cgdo = Qgos_dVdse + Qgod_dVdse ; + Cgso = - (Qgos_dVbse + Qgod_dVbse + Qgos_dVdse + Qgod_dVdse + + Qgos_dVgse + Qgod_dVgse) ; + Cgbo = Qgos_dVbse + Qgod_dVbse + Qgbo_dVbse ; + + /*---------------------------------------------------* + * Add fringing charge/capacitance to overlap. + *-----------------*/ + Qgod += Qfd ; + Qgos += Qfs ; + + Cggo += 2.0 * Cf ; + Cgdo += - Cf ; + Cgso += - Cf ; + /*-----------------------------------------------------------* + * Assign outputs. + *-----------------*/ + + /*---------------------------------------------------* + * Multiplication factor of a MOSFET instance. + *-----------------*/ + M = here->HSM2_m ; + + /*---------------------------------------------------* + * Channel current and conductances. + *-----------------*/ + here->HSM2_ids = M * Ids ; + here->HSM2_gmbs = M * Ids_dVbse ; + here->HSM2_gds = M * Ids_dVdse ; + here->HSM2_gm = M * Ids_dVgse ; + + /*---------------------------------------------------* + * Overlap capacitances. + *-----------------*/ + /* Q_dVsx */ + T2 = - ( Qovd_dVbse + Qovd_dVdse + Qovd_dVgse ) ; + T6 = - ( Qovs_dVbse + Qovs_dVdse + Qovs_dVgse ) ; + T5 = - ( QbdLD_dVbse + QbdLD_dVdse + QbdLD_dVgse ) ; + T7 = - ( QbsLD_dVbse + QbsLD_dVdse + QbsLD_dVgse ) ; + + here->HSM2_cgdo = M * ( Cgdo - Qovd_dVdse - Qovs_dVdse ) ; + here->HSM2_cgso = M * ( Cgso - T2 - T6 ) ; + here->HSM2_cgbo = M * ( Cgbo - Qovd_dVbse - Qovs_dVbse ) ; + + here->HSM2_cdgo = M * ( - Qgod_dVgse - Cf + QbdLD_dVgse ) ; + here->HSM2_cddo = M * ( - Qgod_dVdse + Cf + QbdLD_dVdse ) ; + here->HSM2_cdso = M * ( Qgod_dVbse + Qgod_dVdse + Qgod_dVgse + T5 ) ; + + here->HSM2_csgo = M * ( - Qgos_dVgse - Cf + QbsLD_dVgse ) ; + here->HSM2_csdo = M * ( - Qgos_dVdse + QbsLD_dVdse ) ; + here->HSM2_csso = M * ( Qgos_dVbse + Qgos_dVdse + Qgos_dVgse + Cf + T7 ) ; + + /*---------------------------------------------------* + * Lateral-field-induced capacitance. + *-----------------*/ + T0 = model->HSM2_qyrat ; + T1 = 1.0 - T0 ; + Qys = Qy * T1 ; + Qys_dVdse = Qy_dVdse * T1 ; + Qys_dVgse = Qy_dVgse * T1 ; + Qys_dVbse = Qy_dVbse * T1 ; + Qy = Qy * T0 ; + Qy_dVdse = Qy_dVdse * T0 ; + Qy_dVgse = Qy_dVgse * T0 ; + Qy_dVbse = Qy_dVbse * T0 ; + + Cqyd = Qy_dVdse ; + Cqyg = Qy_dVgse ; + Cqyb = Qy_dVbse ; + Cqys = - ( Cqyb + Cqyd + Cqyg ) ; + here->HSM2_cqyd = M * Cqyd ; + here->HSM2_cqyg = M * Cqyg ; + here->HSM2_cqyb = M * Cqyb ; + + /* -------------------------------------* + * Intrinsic charges / capacitances. + *-----------------*/ + if ( flg_nqs && ((ckt->CKTmode & MODETRAN) || + (ckt->CKTmode & MODEINITFIX)) ) { /* NQS (tran. analysis) */ + + *(ckt->CKTstate0 + here->HSM2qi_nqs) = Qi_nqs ; + *(ckt->CKTstate0 + here->HSM2qb_nqs) = Qb_nqs ; + + here->HSM2_qg = M * - (Qb_nqs + Qi_nqs) ; + here->HSM2_qd = M * Qi_nqs * Qdrat ; + here->HSM2_qs = M * Qi_nqs * (1.0 - Qdrat) ; + + here->HSM2_cbgb = M * Qb_dVgse_nqs ; + here->HSM2_cbdb = M * Qb_dVdse_nqs ; + here->HSM2_cbsb = M * - (Qb_dVbse_nqs + Qb_dVdse_nqs + Qb_dVgse_nqs) ; + + here->HSM2_cggb = M * ( - Qb_dVgse_nqs - Qi_dVgse_nqs ) ; + here->HSM2_cgdb = M * ( - Qb_dVdse_nqs - Qi_dVdse_nqs ) ; + here->HSM2_cgsb = M * ( Qb_dVbse_nqs + Qb_dVdse_nqs + Qb_dVgse_nqs + + Qi_dVbse_nqs + Qi_dVdse_nqs + Qi_dVgse_nqs ) ; + + qd_dVgse = Qi_dVgse_nqs * Qdrat + Qdrat_dVgse * Qi_nqs ; + qd_dVdse = Qi_dVdse_nqs * Qdrat + Qdrat_dVdse * Qi_nqs ; + qd_dVbse = Qi_dVbse_nqs * Qdrat + Qdrat_dVbse * Qi_nqs ; + qd_dVsse = - ( qd_dVgse + qd_dVdse + qd_dVbse ) ; + here->HSM2_cdgb = M * qd_dVgse ; + here->HSM2_cddb = M * qd_dVdse ; + here->HSM2_cdsb = M * qd_dVsse ; + } else { /* QS or NQS (ac dc analysis) */ + + here->HSM2_qg = M * - (Qb + Qi) ; + here->HSM2_qd = M * Qd ; + here->HSM2_qs = M * ( Qi - Qd ) ; + + here->HSM2_cbgb = M * Qb_dVgse ; + here->HSM2_cbdb = M * Qb_dVdse ; + here->HSM2_cbsb = M * - (Qb_dVbse + Qb_dVdse + Qb_dVgse) ; + + here->HSM2_cggb = M * ( - Qb_dVgse - Qi_dVgse ) ; + here->HSM2_cgdb = M * ( - Qb_dVdse - Qi_dVdse ) ; + here->HSM2_cgsb = M * ( Qb_dVbse + Qb_dVdse + Qb_dVgse + + Qi_dVbse + Qi_dVdse + Qi_dVgse ) ; + + here->HSM2_cdgb = M * Qd_dVgse ; + here->HSM2_cddb = M * Qd_dVdse ; + here->HSM2_cdsb = M * - (Qd_dVgse + Qd_dVdse + Qd_dVbse) ; + } + + + /*---------------------------------------------------* + * Add lateral-field-induced charges/capacitances to intrinsic ones. + * - NOTE: This function depends on coqy, a control option. + *-----------------*/ + if ( model->HSM2_coqy == 1 ) { + here->HSM2_qg += M * ( Qy + Qys ) ; + here->HSM2_qd += M * ( - Qy ) ; + here->HSM2_qs += M * ( - Qys ) ; + + T8 = - ( Qys_dVbse + Qys_dVdse + Qys_dVgse ) ; + here->HSM2_cggb += M * ( Cqyg + Qys_dVgse ) ; + here->HSM2_cgdb += M * ( Cqyd + Qys_dVdse ) ; + here->HSM2_cgsb += M * ( Cqys + T8 ) ; + + here->HSM2_cdgb += M * ( - Cqyg ) ; + here->HSM2_cddb += M * ( - Cqyd ) ; + here->HSM2_cdsb += M * ( - Cqys ) ; + } + + /*---------------------------------------------------* + * Add S/D overlap charges/capacitances to intrinsic ones. + * - NOTE: This function depends on coadov, a control option. + *-----------------*/ + if ( model->HSM2_coadov == 1 ) { + /* Q_dVsb */ + T0 = - ( Qgbo_dVbse + Qgbo_dVdse + Qgbo_dVgse ) ; + T1 = - ( Qovd_dVbse + Qovd_dVdse + Qovd_dVgse ) ; + T3 = - ( Qovs_dVbse + Qovs_dVdse + Qovs_dVgse ) ; + T4 = - ( QidLD_dVbse + QidLD_dVdse + QidLD_dVgse + QisLD_dVbse + QisLD_dVdse + QisLD_dVgse ) ; + T5 = - ( QbdLD_dVbse + QbdLD_dVdse + QbdLD_dVgse ) ; + T7 = - ( Qgod_dVbse + Qgod_dVdse + Qgod_dVgse ) ; + + here->HSM2_qg += M * ( Qgod + Qgos + Qgbo - Qovd - Qovs ) ; + here->HSM2_qd += M * ( - Qgod + QbdLD ) ; + here->HSM2_qs += M * ( - Qgos + QbsLD ) ; + + here->HSM2_cbgb += M * ( - Qgbo_dVgse + QidLD_dVgse + QisLD_dVgse ) ; + here->HSM2_cbdb += M * ( - Qgbo_dVdse + QidLD_dVdse + QisLD_dVdse ) ; + here->HSM2_cbsb += M * ( - T0 + T4 ) ; + + here->HSM2_cggb += M * ( Cggo - Qovd_dVgse - Qovs_dVgse ) ; + here->HSM2_cgdb += M * ( Cgdo - Qovd_dVdse - Qovs_dVdse ) ; + here->HSM2_cgsb += M * ( Cgso - T1 - T3 ) ; + + here->HSM2_cdgb += M * ( - Qgod_dVgse - Cf + QbdLD_dVgse ) ; + here->HSM2_cddb += M * ( - Qgod_dVdse + Cf + QbdLD_dVdse ) ; + here->HSM2_cdsb += M * ( - T7 + T5 ) ; + } + + + + /*---------------------------------------------------* + * tau (channel/bulk charge) for ACNQS. + *-----------------*/ + if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { + here->HSM2_tau = tau ; + here->HSM2_tau_dVgs = tau_dVgse ; + here->HSM2_tau_dVds = tau_dVdse ; + here->HSM2_tau_dVbs = tau_dVbse ; + + here->HSM2_taub = taub ; + here->HSM2_taub_dVgs = taub_dVgse ; + here->HSM2_taub_dVds = taub_dVdse ; + here->HSM2_taub_dVbs = taub_dVbse ; + + here->HSM2_Xd = Qdrat; + here->HSM2_Xd_dVgs = Qdrat_dVgse ; + here->HSM2_Xd_dVds = Qdrat_dVdse ; + here->HSM2_Xd_dVbs = Qdrat_dVbse ; + + here->HSM2_Qb = M * Qb ; + here->HSM2_Qb_dVgs = M * Qb_dVgse ; + here->HSM2_Qb_dVds = M * Qb_dVdse ; + here->HSM2_Qb_dVbs = M * Qb_dVbse ; + + here->HSM2_Qi = M * Qi ; + here->HSM2_Qi_dVgs = M * Qi_dVgse ; + here->HSM2_Qi_dVds = M * Qi_dVdse ; + here->HSM2_Qi_dVbs = M * Qi_dVbse ; + + here->HSM2_alpha = Alpha ; + } + + /*---------------------------------------------------* + * Substrate/gate/leak currents. + *-----------------*/ + + here->HSM2_isub = M * Isub ; + here->HSM2_gbbs = M * Isub_dVbse ; + here->HSM2_gbds = M * Isub_dVdse ; + here->HSM2_gbgs = M * Isub_dVgse ; + + here->HSM2_igb = M * -Igb ; + here->HSM2_gigbb = M * -Igb_dVbse ; + here->HSM2_gigbg = M * -Igb_dVgse ; + if (here->HSM2_mode == HiSIM_NORMAL_MODE) { + here->HSM2_gigbd = M * -Igb_dVdse ; + here->HSM2_gigbs = M * ( Igb_dVbse + Igb_dVdse + Igb_dVgse ) ; + } else { + here->HSM2_gigbd = M * ( Igb_dVbse + Igb_dVdse + Igb_dVgse ) ; + here->HSM2_gigbs = M * -Igb_dVdse ; + } + + if (here->HSM2_mode == HiSIM_NORMAL_MODE) { + + here->HSM2_igd = M * ( GLPART1 * Igate - Igd ) ; + here->HSM2_gigdb = M * ( GLPART1 * Igate_dVbse + GLPART1_dVbse * Igate - Igd_dVbse ) ; + here->HSM2_gigdd = M * ( GLPART1 * Igate_dVdse + GLPART1_dVdse * Igate - Igd_dVdse ) ; + here->HSM2_gigdg = M * ( GLPART1 * Igate_dVgse + GLPART1_dVgse * Igate - Igd_dVgse ) ; + + } else { + + T1 = 1.0 - GLPART1 ; + T1_dVb = - GLPART1_dVbse ; + T1_dVd = - GLPART1_dVdse ; + T1_dVg = - GLPART1_dVgse ; + here->HSM2_igd = M * ( T1 * Igate - Igs ) ; + here->HSM2_gigdb = M * ( T1 * Igate_dVbse + T1_dVb * Igate - Igs_dVbse ) ; + here->HSM2_gigdd = M * ( T1 * - ( Igate_dVgse + Igate_dVbse + Igate_dVdse ) + + ( - T1_dVb - T1_dVg - T1_dVd ) * Igate + ( Igs_dVgse + Igs_dVbse + Igs_dVdse ) ) ; + here->HSM2_gigdg = M * ( T1 * Igate_dVgse + T1_dVg * Igate - Igs_dVgse ) ; + } + here->HSM2_gigds = -(here->HSM2_gigdb + here->HSM2_gigdd + here->HSM2_gigdg) ; + + if (here->HSM2_mode == HiSIM_NORMAL_MODE) { + + T1 = 1.0 - GLPART1 ; + T1_dVb = - GLPART1_dVbse ; + T1_dVd = - GLPART1_dVdse ; + T1_dVg = - GLPART1_dVgse ; + here->HSM2_igs = M * ( T1 * Igate - Igs ) ; + here->HSM2_gigsb = M * ( T1 * Igate_dVbse + T1_dVb * Igate - Igs_dVbse ) ; + here->HSM2_gigsd = M * ( T1 * Igate_dVdse + T1_dVd * Igate - Igs_dVdse ) ; + here->HSM2_gigsg = M * ( T1 * Igate_dVgse + T1_dVg * Igate - Igs_dVgse ) ; + + } else { + + here->HSM2_igs = M * ( GLPART1 * Igate - Igd ) ; + here->HSM2_gigsb = M * ( GLPART1 * Igate_dVbse + GLPART1_dVbse * Igate - Igd_dVbse ) ; + here->HSM2_gigsd = M * ( GLPART1 * -(Igate_dVgse + Igate_dVbse + Igate_dVdse) + - Igate * ( GLPART1_dVbse + GLPART1_dVdse + GLPART1_dVgse ) + (Igs_dVgse + Igs_dVbse + Igs_dVdse) ) ; + here->HSM2_gigsg = M * ( GLPART1 * Igate_dVgse + GLPART1_dVgse * Igate - Igd_dVgse ) ; + + } + here->HSM2_gigss = -(here->HSM2_gigsb + here->HSM2_gigsd + here->HSM2_gigsg) ; + + here->HSM2_igidl = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl : M * Igisl ; + here->HSM2_gigidlbs = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVbse : M * Igisl_dVbse ; + here->HSM2_gigidlds = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVdse : M * ( - Igisl_dVbse - Igisl_dVdse - Igisl_dVgse ) ; + here->HSM2_gigidlgs = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVgse : M * Igisl_dVgse ; + + here->HSM2_igisl = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl : M * Igidl ; + here->HSM2_gigislbd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVbse : M * Igidl_dVbse ; + here->HSM2_gigislsd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVdse : M * ( - Igidl_dVbse - Igidl_dVdse - Igidl_dVgse ) ; + here->HSM2_gigislgd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVgse : M * Igidl_dVgse ; + + /*---------------------------------------------------* + * Von, Vdsat. + *-----------------*/ + here->HSM2_von = Vth ; + here->HSM2_vdsat = Vdsat ; + + /*---------------------------------------------------* + * Junction diode. + *-----------------*/ + here->HSM2_ibs = M * Ibs ; + here->HSM2_ibd = M * Ibd ; + here->HSM2_gbs = M * Gbse ; + here->HSM2_gbd = M * Gbde ; + *(ckt->CKTstate0 + here->HSM2qbs) = M * Qbs ; + *(ckt->CKTstate0 + here->HSM2qbd) = M * Qbd ; + here->HSM2_capbs = M * Capbse ; + here->HSM2_capbd = M * Capbde ; + + /*-----------------------------------------------------------* + * Warn floating-point exceptions. + * - Function finite() in libm is called. + * - Go to start with info==5. + *-----------------*/ + T1 = here->HSM2_ids + here->HSM2_gmbs + here->HSM2_gds + here->HSM2_gm ; + T1 = T1 + here->HSM2_qd + here->HSM2_cdsb ; + if ( ! finite (T1) ) { + flg_err = 1 ; + fprintf (stderr , + "*** warning(HiSIM): FP-exception (PART-1)\n" ) ; + if ( flg_info >= 1 ) { + printf ( "*** warning(HiSIM): FP-exception\n") ; + printf ( "here->HSM2_ids = %12.5e\n" , here->HSM2_ids ) ; + printf ( "here->HSM2_gmbs = %12.5e\n" , here->HSM2_gmbs) ; + printf ( "here->HSM2_gds = %12.5e\n" , here->HSM2_gds ) ; + printf ( "here->HSM2_gm = %12.5e\n" , here->HSM2_gm ) ; + printf ( "here->HSM2_qd = %12.5e\n" , here->HSM2_qd ) ; + printf ( "here->HSM2_cdsb = %12.5e\n" , here->HSM2_cdsb) ; + } + } + + T1 = here->HSM2_isub + here->HSM2_gbbs + here->HSM2_gbds + here->HSM2_gbgs ; + if ( ! finite (T1) ) { + flg_err = 1 ; + fprintf (stderr , + "*** warning(HiSIM): FP-exception (PART-2)\n") ; + if ( flg_info >= 1 ) { + printf ("*** warning(HiSIM): FP-exception\n") ; + } + } + + T1 = here->HSM2_cgbo + Cgdo + Cgso + Cggo ; + if ( ! finite (T1) ) { + flg_err = 1 ; + fprintf(stderr , + "*** warning(HiSIM): FP-exception (PART-3)\n") ; + if ( flg_info >= 1 ) { + printf ("*** warning(HiSIM): FP-exception\n") ; + } + } + + T1 = here->HSM2_ibs + here->HSM2_ibd + here->HSM2_gbs + here->HSM2_gbd ; + T1 = T1 + *(ckt->CKTstate0 + here->HSM2qbs) + *(ckt->CKTstate0 + here->HSM2qbd) + + here->HSM2_capbs + here->HSM2_capbd ; + if ( ! finite (T1) ) { + flg_err = 1 ; + fprintf(stderr , + "*** warning(HiSIM): FP-exception (PART-4)\n") ; + if ( flg_info >= 1 ) { + printf ("*** warning(HiSIM): FP-exception\n") ; + } + } + + /*-----------------------------------------------------------* + * Exit for error case. + *-----------------*/ + if ( flg_err != 0 ) { + fprintf (stderr , "----- bias information (HiSIM)\n" ) ; + fprintf (stderr , "name: %s\n" , here->HSM2name ) ; + fprintf (stderr , "stetes: %d\n" , here->HSM2states ) ; + fprintf (stderr , "vds= %12.5e vgs=%12.5e vbs=%12.5e\n" + , vds , vgs , vbs ) ; + fprintf (stderr , "vbs_jct= %12.5e vbd_jct= %12.5e\n" + , vbs_jct , vbd_jct ) ; + fprintf (stderr , "vd= %12.5e vg= %12.5e vb= %12.5e vs= %12.5e\n" + , *( ckt->CKTrhsOld + here->HSM2dNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2gNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2bNodePrime ) + , *( ckt->CKTrhsOld + here->HSM2sNodePrime ) ) ; + if ( here->HSM2_called >= 1 ) { + fprintf (stderr , "vdsc_prv= %12.5e vgsc_prv=%12.5e vbsc_prv=%12.5e\n" + , here->HSM2_vdsc_prv , here->HSM2_vgsc_prv + , here->HSM2_vbsc_prv ) ; + } + fprintf (stderr , "----- bias information (end)\n" ) ; + } + + if ( flg_err != 0 ) return ( HiSIM_ERROR ) ; + + /*-----------------------------------------------------------* + * Noise. + *-----------------*/ + here->HSM2_noiflick = M * Nflic ; + here->HSM2_noithrml = M * Nthrml ; + + /*----------------------------------------------------------* + * induced gate noise. ( Part 3/3 ) + *----------------------*/ + if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 && flg_ign == 1 && !flg_noqi ) { + T0 = Cox_small * Cox * here->HSM2_weff_nf * Leff ; + T1 = here->HSM2_cgsb / M ; + if( - T1 > T0 ){ + Nign0 = c_16o135 * C_QE * beta_inv * T1 * T1 / gds0_ign ; + if ( kusai00L > epsm10 && Vds > epsm10 ) { + MuModA = Muun / Mu ; + MuModB = ( Muun / Mud_hoso - MuModA ) / Vds ; + correct_w1 = MuModA + C_2o3 * MuModB + * ( kusai00 + VgVt * sqrtkusaiL + kusaiL ) + / ( VgVt + sqrtkusaiL ) ; + } else { + correct_w1 = Muun / Mud_hoso ; + } + here->HSM2_noiigate = M * Nign0 * kusai_ig * correct_w1 ; + here->HSM2_noicross = crl_f ; + if ( here->HSM2_noiigate < 0.0 ) here->HSM2_noiigate = 0.0e0 ; + }else{ + here->HSM2_noiigate = 0.0e0 ; + here->HSM2_noicross = 0.0e0 ; + } + }else{ + here->HSM2_noiigate = 0.0e0 ; + here->HSM2_noicross = 0.0e0 ; + } + + /*-----------------------------------------------------------* + * Restore values for next calculation. + *-----------------*/ + + /* Confined biases */ + if ( here->HSM2_called >= 1 ) { + here->HSM2_vbsc_prv2 = here->HSM2_vbsc_prv ; + here->HSM2_vdsc_prv2 = here->HSM2_vdsc_prv ; + here->HSM2_vgsc_prv2 = here->HSM2_vgsc_prv ; + here->HSM2_mode_prv2 = here->HSM2_mode_prv ; + } + here->HSM2_vbsc_prv = Vbsc ; + here->HSM2_vdsc_prv = Vdsc ; + here->HSM2_vgsc_prv = Vgsc ; + here->HSM2_mode_prv = here->HSM2_mode ; + + /* Surface potentials and derivatives w.r.t. internal biases */ + if ( here->HSM2_called >= 1 ) { + here->HSM2_ps0_prv2 = here->HSM2_ps0_prv ; + here->HSM2_ps0_dvbs_prv2 = here->HSM2_ps0_dvbs_prv ; + here->HSM2_ps0_dvds_prv2 = here->HSM2_ps0_dvds_prv ; + here->HSM2_ps0_dvgs_prv2 = here->HSM2_ps0_dvgs_prv ; + here->HSM2_pds_prv2 = here->HSM2_pds_prv ; + here->HSM2_pds_dvbs_prv2 = here->HSM2_pds_dvbs_prv ; + here->HSM2_pds_dvds_prv2 = here->HSM2_pds_dvds_prv ; + here->HSM2_pds_dvgs_prv2 = here->HSM2_pds_dvgs_prv ; + } + + here->HSM2_ps0_prv = Ps0 ; + here->HSM2_ps0_dvbs_prv = Ps0_dVbs ; + here->HSM2_ps0_dvds_prv = Ps0_dVds ; + here->HSM2_ps0_dvgs_prv = Ps0_dVgs ; + here->HSM2_pds_prv = Pds ; + here->HSM2_pds_dvbs_prv = Pds_dVbs ; + here->HSM2_pds_dvds_prv = Pds_dVds ; + here->HSM2_pds_dvgs_prv = Pds_dVgs ; + + /* Derivatives of channel current w.r.t. internal biases */ + here->HSM2_ids_prv = Ids ; + here->HSM2_ids_dvbs_prv = Ids_dVbs ; + here->HSM2_ids_dvds_prv = Ids_dVds ; + here->HSM2_ids_dvgs_prv = Ids_dVgs ; + + /* For CORECIP = 1 */ + if ( corecip ) { + here->HSM2_PS0Z_SCE_prv = PS0Z_SCE ; + here->HSM2_PS0Z_SCE_dvds_prv = PS0Z_SCE_dVds ; + here->HSM2_PS0Z_SCE_dvgs_prv = PS0Z_SCE_dVgs ; + here->HSM2_PS0Z_SCE_dvbs_prv = PS0Z_SCE_dVbs ; + /* here->HSM2_nnn = NNN ; */ + } + + /*-----------------------------------------------------------* + * End of PART-7. (label) + *-----------------*/ + end_of_part_7: + + /*-----------------------------------------------------------* + * Bottom of hsm2eval. + *-----------------*/ + + + return ( HiSIM_OK ) ; + +} /* end of hsm2eval */ + diff --git a/src/spicelib/devices/hisim2/hsm2evalenv.h b/src/spicelib/devices/hisim2/hsm2evalenv.h new file mode 100644 index 000000000..192ab8a6a --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2evalenv.h @@ -0,0 +1,91 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2evalenv.h + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#ifndef HSM2_EVAL_ENV_H +#define HSM2_EVAL_ENV_H + +/* macros and constants used in hsm2eval2yz.c */ + +/*---------------------------------------------------* +* Numerical constants. (macro) +*-----------------*/ + +/* machine epsilon */ +#if defined(_FLOAT_H) && defined(DBL_EPSILON) +#define C_EPS_M (DBL_EPSILON) +#else +#define C_EPS_M (2.2204460492503131e-16) +#endif + +#define MAX_EXP 5.834617425e14 +#define MIN_EXP 1.713908431e-15 +#define EXP_THR 34.0 + +/* sqrt(2) */ +#define C_SQRT_2 (1.414213562373095e+00) + +/* 1/3 */ +#define C_1o3 (3.333333333333333e-01) +/* 2/3 */ +#define C_2o3 (6.666666666666667e-01) +/* 2^(1/3) */ +#define C_2p_1o3 (1.259921049894873e+00) + +/* Pi */ +#define C_Pi (3.141592653589793) +#define C_Pio2 (1.570796326794897) + +/* Unit change */ +#define C_m2cm (1.0e2) +#define C_m2cm_p2 (1.0e4) +#define C_m2cm_p1o2 (1.0e1) +#define C_m2um (1.0e6) + +/*---------------------------------------------------* +* Physical constants/properties. (macro) +*-----------------*/ +/* Elemental charge */ +#define C_QE (1.6021918e-19) + +/* Boltzmann constant */ +#define C_KB (1.3806226e-23) + +/* Permitivity of Si, SiO2 and vacuum */ +#define C_ESI (1.034943e-12) +#define C_EOX (3.453133e-13) +#define C_VAC (8.8541878e-14) + +/* Room temperature constants */ +#define C_T300 (300e+00) +#define C_b300 (3.868283e+01) +/* #define C_Eg0 (1.1785e0) */ /*changed to parameter sIN.eg0*/ + +/* Build-in potential */ +/*#define C_Vbi (1.0e0)*/ /* changed to parameter sIN.vbi */ + + +/* Intrinsic carrier density at 300K */ +#define C_Nin0 (1.04e+10) + + +/*---------------------------------------------------* +* Functions. (macro) Take care of the arguments. +*-----------------*/ +#define Fn_Sqr(x) ( (x)*(x) ) /* x^2 */ +#define Fn_Max(x,y) ( (x) >= (y) ? (x) : (y) ) /* max[x,y] */ +#define Fn_Min(x,y) ( (x) <= (y) ? (x) : (y) ) /* min[x,y] */ +#define Fn_Sgn(x) ( (x) >= 0 ? (1) : (-1) ) /* sign[x] */ + +#endif /* HSM2_EVAL_ENV_H */ diff --git a/src/spicelib/devices/hisim2/hsm2ext.h b/src/spicelib/devices/hisim2/hsm2ext.h new file mode 100644 index 000000000..d162e119e --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2ext.h @@ -0,0 +1,59 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2ext.h + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#ifdef __STDC__ +extern int HSM2acLoad(GENmodel *,CKTcircuit*); +extern int HSM2ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int HSM2convTest(GENmodel *,CKTcircuit*); +extern int HSM2delete(GENmodel*,IFuid,GENinstance**); +extern void HSM2destroy(GENmodel**); +extern int HSM2getic(GENmodel*,CKTcircuit*); +extern int HSM2load(GENmodel*,CKTcircuit*); +extern int HSM2mAsk(CKTcircuit*,GENmodel *,int, IFvalue*); +extern int HSM2mDelete(GENmodel**,IFuid,GENmodel*); +extern int HSM2mParam(int,IFvalue*,GENmodel*); +extern void HSM2mosCap(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*); +extern int HSM2param(int,IFvalue*,GENinstance*,IFvalue*); +extern int HSM2pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); +extern int HSM2setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int HSM2unsetup(GENmodel*,CKTcircuit*); +extern int HSM2temp(GENmodel*,CKTcircuit*); +extern int HSM2trunc(GENmodel*,CKTcircuit*,double*); +extern int HSM2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +#else /* stdc */ +extern int HSM2acLoad(); +extern int HSM2delete(); +extern void HSM2destroy(); +extern int HSM2getic(); +extern int HSM2load(); +extern int HSM2mDelete(); +extern int HSM2ask(); +extern int HSM2mAsk(); +extern int HSM2convTest(); +extern int HSM2temp(); +extern int HSM2mParam(); +extern void HSM2mosCap(); +extern int HSM2param(); +extern int HSM2pzLoad(); +extern int HSM2setup(); +extern int HSM2unsetup(); +extern int HSM2trunc(); +extern int HSM2noise(); + +#endif /* stdc */ diff --git a/src/spicelib/devices/hisim2/hsm2getic.c b/src/spicelib/devices/hisim2/hsm2getic.c new file mode 100644 index 000000000..ca95cd3fb --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2getic.c @@ -0,0 +1,55 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2getic.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "cktdefs.h" +#include "hsm2def.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2getic(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + HSM2model *model = (HSM2model*)inModel; + HSM2instance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for ( ;model ;model = model->HSM2nextModel ) { + for ( here = model->HSM2instances; here ;here = here->HSM2nextInstance ) { + if (!here->HSM2_icVBS_Given) { + here->HSM2_icVBS = + *(ckt->CKTrhs + here->HSM2bNode) - + *(ckt->CKTrhs + here->HSM2sNode); + } + if (!here->HSM2_icVDS_Given) { + here->HSM2_icVDS = + *(ckt->CKTrhs + here->HSM2dNode) - + *(ckt->CKTrhs + here->HSM2sNode); + } + if (!here->HSM2_icVGS_Given) { + here->HSM2_icVGS = + *(ckt->CKTrhs + here->HSM2gNode) - + *(ckt->CKTrhs + here->HSM2sNode); + } + } + } + return(OK); +} + diff --git a/src/spicelib/devices/hisim2/hsm2itf.h b/src/spicelib/devices/hisim2/hsm2itf.h new file mode 100644 index 000000000..83475f674 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2itf.h @@ -0,0 +1,100 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2itf.h + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#ifdef DEV_hisim2 + +#ifndef DEV_HISIM2 +#define DEV_HISIM2 + +#include "hsm2ext.h" + +extern IFparm HSM2pTable[ ]; +extern IFparm HSM2mPTable[ ]; +extern char *HSM2names[ ]; +extern int HSM2pTSize; +extern int HSM2mPTSize; +extern int HSM2nSize; +extern int HSM2iSize; +extern int HSM2mSize; + +SPICEdev HSM2info = { + { "HiSIM2", + "Hiroshima University STARC IGFET Model 2.5.1", + + &HSM2nSize, + &HSM2nSize, + HSM2names, + + &HSM2pTSize, + HSM2pTable, + + &HSM2mPTSize, + HSM2mPTable, + + }, + + HSM2param, + HSM2mParam, + HSM2load, + HSM2setup, + NULL, + HSM2setup, + HSM2temp, + HSM2trunc, + NULL, + HSM2acLoad, + NULL, + HSM2destroy, +#ifdef DELETES + HSM2mDelete, + HSM2delete, +#else /* DELETES */ + NULL, + NULL, +#endif /* DELETES */ + HSM2getic, + HSM2ask, + HSM2mAsk, +#ifdef AN_pz + HSM2pzLoad, +#else /* AN_pz */ + NULL, +#endif /* AN_pz */ +#ifdef NEWCONV + HSM2convTest, +#else /* NEWCONV */ + NULL, +#endif /* NEWCONV */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + +#ifdef AN_noise + HSM2noise, +#else /* AN_noise */ + NULL, +#endif /* AN_noise */ + + &HSM2iSize, + &HSM2mSize + +}; + +#endif +#endif diff --git a/src/spicelib/devices/hisim2/hsm2ld.c b/src/spicelib/devices/hisim2/hsm2ld.c new file mode 100644 index 000000000..9478dcbfa --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2ld.c @@ -0,0 +1,1307 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2ld.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include +#include "spice.h" +#include "util.h" +#include "cktdefs.h" +#include "hsm2def.h" +#include "hisim2.h" +#include "trandefs.h" +#include "const.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +#define SHOW_EPS_QUANT 1.0e-15 +#define BYP_TOL_FACTOR model->HSM2_byptol + +#ifdef MOS_MODEL_TIME +/** MOS Model Time **/ +#include +extern char *mos_model_name ; +extern double mos_model_time ; +double gtodsecld(void) { + struct timeval tv; + const double sec2000 = 9.46e8 ; + gettimeofday(&tv, NULL); + return ( tv.tv_sec - sec2000 ) + (double)tv.tv_usec*1e-6; +} +double tm0 , tm1 ; +#ifdef PARAMOS_TIME +#include +double vsum ; +static double vsum0 = 1.0e5 ; +#endif +#endif + + +#ifdef __STDC__ +static void ShowPhysVals +( + HSM2instance *here, + HSM2model *model, + int isFirst, + double vds, + double vgs, + double vbs, + double vgd, + double vbd, + double vgb +) +#else +static void ShowPhysVals(here,model,isFirst,vds,vgs,vbs,vgd,vbd,vgb) + HSM2instance *here; + HSM2model *model; + int isFirst; + double vds; + double vgs; + double vbs; + double vgd; + double vbd; + double vgb; +#endif +{ + /* regard the epsilon-quantity as 0.0 */ + vds = (fabs(vds) < SHOW_EPS_QUANT) ? 0.0 : vds; + vgs = (fabs(vgs) < SHOW_EPS_QUANT) ? 0.0 : vgs; + vbs = (fabs(vbs) < SHOW_EPS_QUANT) ? 0.0 : vbs; + vgb = (fabs(vgb) < SHOW_EPS_QUANT) ? 0.0 : vgb; + switch (model->HSM2_show) { + case 1: + if (isFirst) printf("Vds Ids\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_mode*here->HSM2_ids); + break; + case 2: + if (isFirst) printf("Vgs Ids\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_mode*here->HSM2_ids); + break; + case 3: + if (isFirst) printf("Vgs log10(|Ids|)\n"); + printf("%e %e\n", model->HSM2_type*vgs, log10(here->HSM2_ids)); + break; + case 4: + if (isFirst) printf("log10(|Ids|) gm/|Ids|\n"); + if (here->HSM2_ids == 0.0) + printf("I can't show gm/Ids - log10(Ids), because Ids = 0.\n"); + else + printf("%e %e\n", log10(here->HSM2_ids), here->HSM2_gm/here->HSM2_ids); + break; + case 5: + if (isFirst) printf("Vds gds\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_gds); + break; + case 6: + if (isFirst) printf("Vgs gm\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_gm); + break; + case 7: + if (isFirst) printf("Vbs gbs\n"); + printf("%e %e\n", model->HSM2_type*vbs, here->HSM2_gmbs); + break; + case 8: + if (isFirst) printf("Vgs Cgg\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_cggb); + break; + case 9: + if (isFirst) printf("Vgs Cgs\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_cgsb); + break; + case 10: + if (isFirst) printf("Vgs Cgd\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_cgdb); + break; + case 11: + if (isFirst) printf("Vgs Cgb\n"); + printf("%e %e\n", model->HSM2_type*vgs, -(here->HSM2_cggb+here->HSM2_cgsb+here->HSM2_cgdb)); + break; + case 12: + if (isFirst) printf("Vds Csg\n"); + printf("%e %e\n", model->HSM2_type*vds, -(here->HSM2_cggb+here->HSM2_cbgb+here->HSM2_cdgb)); + break; + case 13: + if (isFirst) printf("Vds Cdg\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_cdgb); + break; + case 14: + if (isFirst) printf("Vds Cbg\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_cbgb); + break; + case 15: + if (isFirst) printf("Vds Cgg\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_cggb); + break; + case 16: + if (isFirst) printf("Vds Cgs\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_cgsb); + break; + case 17: + if (isFirst) printf("Vds Cgd\n"); + printf("%e %e\n", model->HSM2_type*vds, here->HSM2_cgdb); + break; + case 18: + if (isFirst) printf("Vds Cgb\n"); + printf("%e %e\n", model->HSM2_type*vds, -(here->HSM2_cggb+here->HSM2_cgsb+here->HSM2_cgdb)); + break; + case 19: + if (isFirst) printf("Vgs Csg\n"); + printf("%e %e\n", model->HSM2_type*vgs, -(here->HSM2_cggb+here->HSM2_cbgb+here->HSM2_cdgb)); + break; + case 20: + if (isFirst) printf("Vgs Cdg\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_cdgb); + break; + case 21: + if (isFirst) printf("Vgs Cbg\n"); + printf("%e %e\n", model->HSM2_type*vgs, here->HSM2_cbgb); + break; + case 22: + if (isFirst) printf("Vgb Cgb\n"); + printf("%e %e\n", model->HSM2_type*vgb, -(here->HSM2_cggb+here->HSM2_cgsb+here->HSM2_cgdb)); + break; + case 50: + if (isFirst) printf("Vgs Vds Vbs Vgb Ids log10(|Ids|) gm/|Ids| gm gds gbs Cgg Cgs Cgb Cgd Csg Cbg Cdg\n"); + printf("%e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e %e\n", model->HSM2_type*vgs, model->HSM2_type*vds, model->HSM2_type*vbs, model->HSM2_type*vgb, here->HSM2_mode*here->HSM2_ids, log10(here->HSM2_ids), here->HSM2_gm/here->HSM2_ids, here->HSM2_gm, here->HSM2_gds, here->HSM2_gmbs, here->HSM2_cggb, here->HSM2_cgsb, -(here->HSM2_cggb+here->HSM2_cgsb+here->HSM2_cgdb), here->HSM2_cgdb, -(here->HSM2_cggb+here->HSM2_cbgb+here->HSM2_cdgb), here->HSM2_cbgb, here->HSM2_cdgb); + break; + default: + /* + printf("There is no physical value corrsponding to %d\n", flag); + */ + break; + } +} + +int HSM2load(inModel,ckt) + GENmodel *inModel; + register CKTcircuit *ckt; + /* actually load the current value into the + * sparse matrix previously provided + */ +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; + HSM2binningParam *pParam; + double cbhat, cdrain, cdhat, cdreq, cgbhat, cgshat, cgdhat; + double Ibtot, Idtot, Igbtot, Igstot, Igdtot; + double ceq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg; + double ceqjs, ceqjd, ceqqjs, ceqqjd; + double delvbd, delvbs, delvds, delvgd, delvgs; + double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb; + double gcgdb, gcggb, gcgsb, gcgbb, gcsdb, gcsgb, gcssb; + double geq, xfact; + double vbd, vbs, vds, vgb, vgd, vgdo, vgs, von; + double gbbdp, gbbsp, gbspg, gbspdp, gbspb, gbspsp; + double qgate, qbulk, qdrn; + double cqgate, cqbulk, cqdrn; + double gbdpdp, gbdpg, gbdpb, gbdpsp; + double gm, gmbs, FwdSum, RevSum; + double ag0; + double Ibtoteq, gIbtotg, gIbtotd, gIbtots, gIbtotb; + double Igtoteq, gIgtotg, gIgtotd, gIgtots, gIgtotb; + double Idtoteq, gIdtotg, gIdtotd, gIdtots, gIdtotb; + double Istoteq, gIstotg, gIstotd, gIstots, gIstotb; + double ivds, ivgs, ivbs; + double gjbs, gjbd, gcdbdb, gcsbsb, gcbbb, gcdbb, gcsbb, grg; + double vdbs, vsbs, vdbd, delvdbs, delvsbs, delvdbd; + double vges, vged, delvges, delvged, vgedo; + double vsbdo, vsbd; + double vbs_jct, vbd_jct, delvbs_jct, delvbd_jct; + int ByPass, Check, Check1, Check2, error; + int BYPASS_enable ; +#ifndef NOBYPASS + double tempv; +#endif /*NOBYPASS*/ +#ifndef NEWCONV + double tol, tol2, tol3, tol4; +#endif + int ChargeComputationNeeded = + ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) + ? 1 : 0; + int showPhysVal; + int isConv; + double vds_pre; + double reltol, abstol , voltTol ; + +#ifdef MOS_MODEL_TIME +tm0 = gtodsecld() ; +#endif + + + /* loop through all the HSM2 device models */ + for ( ; model != NULL; model = model->HSM2nextModel ) { + /* loop through all the instances of the model */ + + reltol = ckt->CKTreltol * BYP_TOL_FACTOR ; + abstol = ckt->CKTabstol * BYP_TOL_FACTOR ; + voltTol= ckt->CKTvoltTol* BYP_TOL_FACTOR ; + BYPASS_enable = (BYP_TOL_FACTOR > 0.0 && ckt->CKTbypass) ; + model->HSM2_bypass_enable = BYPASS_enable ; + + for (here = model->HSM2instances; here != NULL ; + here = here->HSM2nextInstance) { + pParam = &here->pParam ; + showPhysVal = 0; + Check=1; + ByPass = 0; + +#ifdef DEBUG_HISIM2LD_VX + printf("mode = %x\n", ckt->CKTmode); + printf("Vd Vg Vs Vb %e %e %e %e\n", *(ckt->CKTrhsOld+here->HSM2dNodePrime), + *(ckt->CKTrhsOld+here->HSM2gNodePrime), + *(ckt->CKTrhsOld+here->HSM2sNodePrime), + *(ckt->CKTrhsOld+here->HSM2bNodePrime)); +#endif + + if ( ckt->CKTmode & MODEINITSMSIG ) { + vbs = *(ckt->CKTstate0 + here->HSM2vbs); + vgs = *(ckt->CKTstate0 + here->HSM2vgs); + vds = *(ckt->CKTstate0 + here->HSM2vds); + + vges = *(ckt->CKTstate0 + here->HSM2vges); + vdbs = *(ckt->CKTstate0 + here->HSM2vdbs); + vsbs = *(ckt->CKTstate0 + here->HSM2vsbs); + } + else if ( ckt->CKTmode & MODEINITTRAN ) { + vbs = *(ckt->CKTstate1 + here->HSM2vbs); + vgs = *(ckt->CKTstate1 + here->HSM2vgs); + vds = *(ckt->CKTstate1 + here->HSM2vds); + + vges = *(ckt->CKTstate1 + here->HSM2vges); + vdbs = *(ckt->CKTstate1 + here->HSM2vdbs); + vsbs = *(ckt->CKTstate1 + here->HSM2vsbs); + } + else if ( (ckt->CKTmode & MODEINITJCT) && !here->HSM2_off ) { + vds = model->HSM2_type * here->HSM2_icVDS; + vgs = vges = model->HSM2_type * here->HSM2_icVGS; + vbs = vdbs = vsbs = model->HSM2_type * here->HSM2_icVBS; + if ( (vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && + ( (ckt->CKTmode & (MODETRAN|MODEAC|MODEDCOP|MODEDCTRANCURVE)) || + !(ckt->CKTmode & MODEUIC) ) ) { + /* set biases for starting analysis */ + vbs = vdbs = vsbs = 0.0; + /* + vgs = vges = model->HSM2_type * pParam->HSM2_vfbc + 0.1; + */ + vgs = vges = 0.1; + vds = 0.1; + } + } + else if ( ( ckt->CKTmode & (MODEINITJCT | MODEINITFIX) ) && + here->HSM2_off ) { + vbs = vgs = vds = 0.0; vges = 0.0; vdbs = vsbs = 0.0; + } + else { +#ifndef PREDICTOR /* BSIM3 style */ + if (ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->HSM2vbs) = + *(ckt->CKTstate1 + here->HSM2vbs); + vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vbs)) + -(xfact * (*(ckt->CKTstate2 + here->HSM2vbs))); + *(ckt->CKTstate0 + here->HSM2vgs) = + *(ckt->CKTstate1 + here->HSM2vgs); + vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vgs)) + -(xfact * (*(ckt->CKTstate2 + here->HSM2vgs))); + *(ckt->CKTstate0 + here->HSM2vds) = + *(ckt->CKTstate1 + here->HSM2vds); + vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vds)) + -(xfact * (*(ckt->CKTstate2 + here->HSM2vds))); + *(ckt->CKTstate0 + here->HSM2vbd) = + *(ckt->CKTstate0 + here->HSM2vbs)- + *(ckt->CKTstate0 + here->HSM2vds); + + *(ckt->CKTstate0 + here->HSM2vges) = + *(ckt->CKTstate1 + here->HSM2vges); + vges = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vges)) + -(xfact * (*(ckt->CKTstate2 + here->HSM2vges))); + *(ckt->CKTstate0 + here->HSM2vdbs) = + *(ckt->CKTstate1 + here->HSM2vdbs); + vdbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vdbs)) + - (xfact * (*(ckt->CKTstate2 + here->HSM2vdbs))); + *(ckt->CKTstate0 + here->HSM2vdbd) = + *(ckt->CKTstate0 + here->HSM2vdbs) + - *(ckt->CKTstate0 + here->HSM2vds); + *(ckt->CKTstate0 + here->HSM2vsbs) = + *(ckt->CKTstate1 + here->HSM2vsbs); + vsbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM2vsbs)) + - (xfact * (*(ckt->CKTstate2 + here->HSM2vsbs))); + } + else { +#endif /* PREDICTOR */ + /* get biases from CKT */ + vbs = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2bNodePrime) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vgs = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2gNodePrime) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vds = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2dNodePrime) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + + vges = model->HSM2_type * + (*(ckt->CKTrhsOld+here->HSM2gNode) - + *(ckt->CKTrhsOld+here->HSM2sNodePrime)); + vdbs = model->HSM2_type + * (*(ckt->CKTrhsOld + here->HSM2dbNode) + - *(ckt->CKTrhsOld + here->HSM2sNodePrime)); + vsbs = model->HSM2_type + * (*(ckt->CKTrhsOld + here->HSM2sbNode) + - *(ckt->CKTrhsOld + here->HSM2sNodePrime)); +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + + vbd = vbs - vds; + vgd = vgs - vds; + vged = vges - vds; + vdbd = vdbs - vds; + vgdo = *(ckt->CKTstate0 + here->HSM2vgs) - *(ckt->CKTstate0 + here->HSM2vds); + vgedo = *(ckt->CKTstate0 + here->HSM2vges) - *(ckt->CKTstate0 + here->HSM2vds); + delvbs = vbs - *(ckt->CKTstate0 + here->HSM2vbs); + delvbd = vbd - *(ckt->CKTstate0 + here->HSM2vbd); + delvgs = vgs - *(ckt->CKTstate0 + here->HSM2vgs); + delvges = vges - *(ckt->CKTstate0 + here->HSM2vges); + delvds = vds - *(ckt->CKTstate0 + here->HSM2vds); + delvdbs = vdbs - *(ckt->CKTstate0 + here->HSM2vdbs); + delvsbs = vsbs - *(ckt->CKTstate0 + here->HSM2vsbs); + delvdbd = vdbd - *(ckt->CKTstate0 + here->HSM2vdbd); + delvgd = vgd - vgdo; + delvged = vged - vgedo; + + delvbd_jct = (!here->HSM2_corbnet) ? delvbd : delvdbd; + delvbs_jct = (!here->HSM2_corbnet) ? delvbs : delvsbs; + if (here->HSM2_mode >= 0) { + Idtot = here->HSM2_ids + here->HSM2_isub - here->HSM2_ibd + + here->HSM2_igidl; + cdhat = Idtot - here->HSM2_gbd * delvbd_jct + + (here->HSM2_gmbs + here->HSM2_gbbs + here->HSM2_gigidlbs) * delvbs + + (here->HSM2_gm + here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgs + + (here->HSM2_gds + here->HSM2_gbds + here->HSM2_gigidlds) * delvds; + Ibtot = here->HSM2_ibs + here->HSM2_ibd - here->HSM2_isub + - here->HSM2_igidl - here->HSM2_igisl; + cbhat = Ibtot + here->HSM2_gbd * delvbd_jct + + here->HSM2_gbs * delvbs_jct - (here->HSM2_gbbs + here->HSM2_gigidlbs) * delvbs + - (here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgs + - (here->HSM2_gbds + here->HSM2_gigidlds) * delvds + - here->HSM2_gigislgd * delvgd - here->HSM2_gigislbd * delvbd + + here->HSM2_gigislsd * delvds; + Igstot = here->HSM2_igs; + cgshat = Igstot + here->HSM2_gigsg * delvgs + + here->HSM2_gigsd * delvds + here->HSM2_gigsb * delvbs; + Igdtot = here->HSM2_igd; + cgdhat = Igdtot + here->HSM2_gigdg * delvgs + + here->HSM2_gigdd * delvds + here->HSM2_gigdb * delvbs; + Igbtot = here->HSM2_igb; + cgbhat = Igbtot + here->HSM2_gigbg * delvgs + + here->HSM2_gigbd * delvds + here->HSM2_gigbb * delvbs; + } + else { + Idtot = here->HSM2_ids + here->HSM2_ibd - here->HSM2_igidl; + cdhat = Idtot + here->HSM2_gbd * delvbd_jct + here->HSM2_gmbs * delvbd + + here->HSM2_gm * delvgd - here->HSM2_gds * delvds + - here->HSM2_gigidlgs * delvgd - here->HSM2_gigidlbs * delvbd + + here->HSM2_gigidlds * delvds ; + Ibtot = here->HSM2_ibs + here->HSM2_ibd - here->HSM2_isub + - here->HSM2_igidl - here->HSM2_igisl; + cbhat = Ibtot + here->HSM2_gbs * delvbs_jct + + here->HSM2_gbd * delvbd_jct - (here->HSM2_gbbs + here->HSM2_gigidlbs) * delvbd + - (here->HSM2_gbgs + here->HSM2_gigidlgs) * delvgd + + (here->HSM2_gbds + here->HSM2_gigidlds) * delvds + - here->HSM2_gigislgd * delvgd - here->HSM2_gigislbd * delvbd + + here->HSM2_gigislsd * delvds; + Igbtot = here->HSM2_igb; + cgbhat = Igbtot + here->HSM2_gigbg * delvgd + - here->HSM2_gigbs * delvds + here->HSM2_gigbb * delvbd; + Igstot = here->HSM2_igs; + cgshat = Igstot + here->HSM2_gigsg * delvgd + - here->HSM2_gigss * delvds + here->HSM2_gigsb * delvbd; + Igdtot = here->HSM2_igd; + cgdhat = Igdtot + here->HSM2_gigdg * delvgd + - here->HSM2_gigds * delvds + here->HSM2_gigdb * delvbd; + } + + vds_pre = vds; + +#ifndef NOBYPASS /* BSIM3 style */ + /* now lets see if we can bypass (ugh) */ + + /* 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 ( !(ckt->CKTmode & MODEINITPRED) && BYPASS_enable ) + if ((!here->HSM2_corbnet) || + (FABS(delvdbs) < + (reltol + * MAX(FABS(vdbs), FABS(*(ckt->CKTstate0 + here->HSM2vdbs))) + + voltTol))) + if ((!here->HSM2_corbnet) || + (FABS(delvdbd) < + (reltol + * MAX(FABS(vdbd), FABS(*(ckt->CKTstate0 + here->HSM2vdbd))) + + voltTol))) + if ((!here->HSM2_corbnet) || + (FABS(delvsbs) < + (reltol + * MAX(FABS(vsbs), FABS(*(ckt->CKTstate0 + here->HSM2vsbs))) + + voltTol))) + if ((here->HSM2_corg == 0) || (here->HSM2_corg == 1) || + (FABS(delvges) < + (reltol + * MAX(FABS(vges), FABS(*(ckt->CKTstate0 + here->HSM2vges))) + + voltTol))) + if ( FABS(delvbs) < + ( reltol * + MAX(FABS(vbs), FABS(*(ckt->CKTstate0+here->HSM2vbs))) + + voltTol ) ) + if ( FABS(delvbd) < + ( reltol * + MAX(FABS(vbd), FABS(*(ckt->CKTstate0+here->HSM2vbd))) + + voltTol ) ) + if ( FABS(delvgs) < + ( reltol * + MAX(FABS(vgs), FABS(*(ckt->CKTstate0+here->HSM2vgs))) + + voltTol ) ) + if ( FABS(delvds) < + ( reltol * + MAX(FABS(vds), FABS(*(ckt->CKTstate0+here->HSM2vds))) + + voltTol ) ) + if ( FABS(cdhat - Idtot) < + ( reltol * + MAX(FABS(cdhat),FABS(Idtot)) + abstol ) ) + if (!model->HSM2_coiigs || + (FABS(cgbhat - Igbtot) < reltol + * MAX(FABS(cgbhat), FABS(Igbtot)) + abstol)) + if (!model->HSM2_coiigs || + (FABS(cgshat - Igstot) < reltol + * MAX(FABS(cgshat), FABS(Igstot)) + abstol)) + if (!model->HSM2_coiigs || + (FABS(cgdhat - Igdtot) < reltol + * MAX(FABS(cgdhat), FABS(Igdtot)) + abstol)){ + tempv = MAX(FABS(cbhat),FABS(Ibtot)) + abstol; + if ((FABS(cbhat - Ibtot)) < reltol * tempv) { + /* bypass code */ + vbs = *(ckt->CKTstate0 + here->HSM2vbs); + vbd = *(ckt->CKTstate0 + here->HSM2vbd); + vgs = *(ckt->CKTstate0 + here->HSM2vgs); + vds = *(ckt->CKTstate0 + here->HSM2vds); + + vges = *(ckt->CKTstate0 + here->HSM2vges); + vdbs = *(ckt->CKTstate0 + here->HSM2vdbs); + vdbd = *(ckt->CKTstate0 + here->HSM2vdbd); + vsbs = *(ckt->CKTstate0 + here->HSM2vsbs); + + vgd = vgs - vds; + vgb = vgs - vbs; + vged = vges - vds; + + vbs_jct = (!here->HSM2_corbnet) ? vbs : vsbs; + vbd_jct = (!here->HSM2_corbnet) ? vbd : vdbd; + + cdrain = here->HSM2_ids; + if ((ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && + (ckt->CKTmode & MODEUIC))) { + ByPass = 1; + qgate = here->HSM2_qg; + qbulk = here->HSM2_qb; + qdrn = here->HSM2_qd; + goto line755; + } + else + goto line850; + } + } +#endif /*NOBYPASS*/ + +#ifdef DEBUG_HISIM2LD_VX + printf( "vbd_p = %12.5e\n" , vbd ); + printf( "vbs_p = %12.5e\n" , vbs ); + printf( "vgs_p = %12.5e\n" , vgs ); + printf( "vds_p = %12.5e\n" , vds ); +#endif + + von = here->HSM2_von; + if(*(ckt->CKTstate0 + here->HSM2vds) >= 0.0) { + vgs = DEVfetlim(vgs, *(ckt->CKTstate0 + here->HSM2vgs), von); + vds = vgs - vgd; + vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->HSM2vds)); + vgd = vgs - vds; + + if (here->HSM2_corg == 1) { + vges = DEVfetlim(vges, *(ckt->CKTstate0 + here->HSM2vges), von); + vged = vges - vds; + } + } + else { + vgd = DEVfetlim(vgd, vgdo, von); + vds = vgs - vgd; + vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0 + here->HSM2vds))); + vgs = vgd + vds; + + if (here->HSM2_corg == 1) { + vged = DEVfetlim(vged, vgedo, von); + vges = vged + vds; + } + } + if (vds >= 0.0) { + vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->HSM2vbs), + CONSTvt0, model->HSM2_vcrit, &Check); + vbd = vbs - vds; + if (here->HSM2_corbnet) { + vdbs = DEVpnjlim(vdbs, *(ckt->CKTstate0 + here->HSM2vdbs), + CONSTvt0, model->HSM2_vcrit, &Check1); + vdbd = vdbs - vds; + vsbs = DEVpnjlim(vsbs, *(ckt->CKTstate0 + here->HSM2vsbs), + CONSTvt0, model->HSM2_vcrit, &Check2); + if ((Check1 == 0) && (Check2 == 0)) Check = 0; + else Check = 1; + } + } + else { + vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->HSM2vbd), + CONSTvt0, model->HSM2_vcrit, &Check); + vbs = vbd + vds; + if (here->HSM2_corbnet) { + vdbd = DEVpnjlim(vdbd, *(ckt->CKTstate0 + here->HSM2vdbd), + CONSTvt0, model->HSM2_vcrit, &Check1); + vdbs = vdbd + vds; + vsbdo = *(ckt->CKTstate0 + here->HSM2vsbs) + - *(ckt->CKTstate0 + here->HSM2vds); + vsbd = vsbs - vds; + vsbd = DEVpnjlim(vsbd, vsbdo, CONSTvt0, model->HSM2_vcrit, &Check2); + vsbs = vsbd + vds; + if ((Check1 == 0) && (Check2 == 0)) Check = 0; + else Check = 1; + } + } + } + + vbd = vbs - vds; + vgd = vgs - vds; + vgb = vgs - vbs; + vged = vges - vds; + vdbd = vdbs - vds; + + vbs_jct = (!here->HSM2_corbnet) ? vbs : vsbs; + vbd_jct = (!here->HSM2_corbnet) ? vbd : vdbd; + +#ifdef DEBUG_HISIM2LD_VX + printf( "vbd = %12.5e\n" , vbd ); + printf( "vbs = %12.5e\n" , vbs ); + printf( "vgs = %12.5e\n" , vgs ); + printf( "vds = %12.5e\n" , vds ); +#endif + + if (vds >= 0) { /* normal mode */ + here->HSM2_mode = 1; + ivds = vds; + ivgs = vgs; + ivbs = vbs; + } else { /* reverse mode */ + here->HSM2_mode = -1; + ivds = -vds; + ivgs = vgd; + ivbs = vbd; + } + + if ( model->HSM2_info >= 5 ) { /* mode, bias conditions ... */ + printf( "--- variables given to HSM2evaluate() ----\n" ); + printf( "type = %s\n" , (model->HSM2_type>0) ? "NMOS" : "PMOS" ); + printf( "mode = %s\n" , (here->HSM2_mode>0) ? "NORMAL" : "REVERSE" ); + + printf( "vbs = %12.5e\n" , ivbs ); + printf( "vds = %12.5e\n" , ivds ); + printf( "vgs = %12.5e\n" , ivgs ); + } + if ( model->HSM2_info >= 6 ) { /* input flags */ + printf( "corsrd = %s\n" , (model->HSM2_corsrd) ? "true" : "false" ) ; + printf( "coadov = %s\n" , (model->HSM2_coadov) ? "true" : "false" ) ; + printf( "coisub = %s\n" , (model->HSM2_coisub) ? "true" : "false" ) ; + printf( "coiigs = %s\n" , (model->HSM2_coiigs) ? "true" : "false" ) ; + printf( "cogidl = %s\n" , (model->HSM2_cogidl) ? "true" : "false" ) ; + printf( "coovlp = %s\n" , (model->HSM2_coovlp) ? "true" : "false" ) ; + printf( "coflick = %s\n" , (model->HSM2_coflick) ? "true" : "false" ) ; + printf( "coisti = %s\n" , (model->HSM2_coisti) ? "true" : "false" ) ; + printf( "conqs = %s\n" , (model->HSM2_conqs) ? "true" : "false" ) ; + printf( "cothrml = %s\n" , (model->HSM2_cothrml) ? "true" : "false" ) ; + printf( "coign = %s\n" , (model->HSM2_coign) ? "true" : "false" ) ; + } + /* print inputs ------------AA */ + +#ifdef DEBUG_HISIM2CGG + /* Print convergence flag */ + printf("isConv %d ", isConv ); + printf("CKTtime %e ", ckt->CKTtime ); + printf("Vb %1.3e ", (model->HSM2_type>0) ? vbs:-vbs ); + printf("Vd %1.3e ", (model->HSM2_type>0) ? vds:-vds ); + printf("Vg %1.3e ", (model->HSM2_type>0) ? vgs:-vgs ); +#endif + + /* call model evaluation */ + if ( HSM2evaluate(ivds, ivgs, ivbs, vbs_jct, vbd_jct, here, model, ckt) == HiSIM_ERROR ) + return (HiSIM_ERROR); + + +#ifdef DEBUG_HISIM2CGG + printf("HSM2_ids %e ", here->HSM2_ids ) ; + printf("HSM2_cggb %e ", here->HSM2_cggb ) ; + printf("\n") ; +#endif + + /* modified by T.Y. 2006.05.31 + * if ( !here->HSM2_called ) here->HSM2_called = 1; + */ + here->HSM2_called += 1; + + cdrain = here->HSM2_ids ; /* cdrain */ + qgate = here->HSM2_qg ; /* gate */ + qdrn = here->HSM2_qd ; /* drain */ + qbulk = here->HSM2_qb = -1.0 * (here->HSM2_qg + here->HSM2_qd + here->HSM2_qs); /* bulk */ + + /* print all outputs ------------VV */ + if ( model->HSM2_info >= 4 ) { + printf( "--- variables returned from HSM2evaluate() ----\n" ) ; + + printf( "von = %12.5e\n" , here->HSM2_von ) ; + printf( "vdsat = %12.5e\n" , here->HSM2_vdsat ) ; + printf( "ids = %12.5e\n" , here->HSM2_ids ) ; + + printf( "gds = %12.5e\n" , here->HSM2_gds ) ; + printf( "gm = %12.5e\n" , here->HSM2_gm ) ; + printf( "gmbs = %12.5e\n" , here->HSM2_gmbs ) ; + + printf( "cggo = %12.5e\n" , -(here->HSM2_cgdo + here->HSM2_cgso +here->HSM2_cgbo) ) ; + printf( "cgdo = %12.5e\n" , here->HSM2_cgdo ) ; + printf( "cgso = %12.5e\n" , here->HSM2_cgso ) ; + printf( "cdgo = %12.5e\n" , here->HSM2_cdgo ) ; + printf( "cddo = %12.5e\n" , here->HSM2_cddo ) ; + printf( "cdso = %12.5e\n" , here->HSM2_cdso ) ; + printf( "csgo = %12.5e\n" , here->HSM2_csgo ) ; + printf( "csdo = %12.5e\n" , here->HSM2_csdo ) ; + printf( "csso = %12.5e\n" , here->HSM2_csso ) ; + + printf( "qg = %12.5e\n" , here->HSM2_qg ) ; + printf( "qd = %12.5e\n" , here->HSM2_qd ) ; + printf( "qs = %12.5e\n" , here->HSM2_qs ) ; + + printf( "cggb = %12.5e\n" , here->HSM2_cggb ) ; + printf( "cgsb = %12.5e\n" , here->HSM2_cgsb ) ; + printf( "cgdb = %12.5e\n" , here->HSM2_cgdb ) ; + printf( "cbgb = %12.5e\n" , here->HSM2_cbgb ) ; + printf( "cbsb = %12.5e\n" , here->HSM2_cbsb ) ; + printf( "cbdb = %12.5e\n" , here->HSM2_cbdb ) ; + printf( "cdgb = %12.5e\n" , here->HSM2_cdgb ) ; + printf( "cdsb = %12.5e\n" , here->HSM2_cdsb ) ; + printf( "cddb = %12.5e\n" , here->HSM2_cddb ) ; + + printf( "ibd = %12.5e\n" , here->HSM2_ibd ) ; + printf( "ibs = %12.5e\n" , here->HSM2_ibs ) ; + printf( "gbd = %12.5e\n" , here->HSM2_gbd ) ; + printf( "gbs = %12.5e\n" , here->HSM2_gbs ) ; + printf( "capbd = %12.5e\n" , here->HSM2_capbd ) ; + printf( "capbs = %12.5e\n" , here->HSM2_capbs ) ; + printf( "qbd = %12.5e\n" , *(ckt->CKTstate0 + here->HSM2qbd) ) ; + printf( "qbs = %12.5e\n" , *(ckt->CKTstate0 + here->HSM2qbs) ) ; + + printf( "isub = %12.5e\n" , here->HSM2_isub ) ; + printf( "gbgs = %12.5e\n" , here->HSM2_gbgs ) ; + printf( "gbds = %12.5e\n" , here->HSM2_gbds ) ; + printf( "gbbs = %12.5e\n" , here->HSM2_gbbs ) ; + + printf( "S_flicker_noise * ( freq / gain ) = %.16e\n" , here->HSM2_noiflick ) ; + printf( "S_thermal_noise / ( gain * 4kT ) = %.16e\n" , here->HSM2_noithrml ) ; + printf( "S_induced_gate_noise / ( gain * freq^2 ) = %.16e\n" , here->HSM2_noiigate ) ; + printf( "cross-correlation coefficient (= Sigid/sqrt(Sig*Sid) ) = %.16e\n" , here->HSM2_noicross ) ; + /* print Surface Potentials */ + printf( "ivds %e ivgs %e ivbs %e Ps0 %.16e Pds %.16e\n" , + ivds, ivgs, ivbs, here->HSM2_ps0_prv, here->HSM2_pds_prv ) ; + } + /* print all outputs ------------AA */ + + if ( model->HSM2_info >= 3 ) { /* physical valiables vs bias */ + static int isFirst = 1; + if (isFirst) { + printf("# vbs vds vgs cggb cgdb cgsb cbgb cbdb cbsb cdgb cddb cdsb\n"); + isFirst = 0; + } + printf("%12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n", + vbs, vds, vgs , + here->HSM2_cggb, here->HSM2_cgdb, here->HSM2_cgsb, + here->HSM2_cbgb, here->HSM2_cbdb, here->HSM2_cbsb, + here->HSM2_cdgb, here->HSM2_cddb, here->HSM2_cdsb); + + } + /* + * check convergence + */ + isConv = 1; + if ( (here->HSM2_off == 0) || !(ckt->CKTmode & MODEINITFIX) ) { + if (Check == 1) { + ckt->CKTnoncon++; + isConv = 0; +#ifndef NEWCONV + } + else { + if (here->HSM2_mode >= 0) + Idtot = here->HSM2_ids + here->HSM2_isub - here->HSM2_ibd + here->HSM2_igidl; + else + Idtot = here->HSM2_ids + here->HSM2_ibd - here->HSM2_igidl; + tol = ckt->CKTreltol * MAX(FABS(cdhat), FABS(Idtot)) + ckt->CKTabstol; + tol2 = ckt->CKTreltol * MAX(FABS(cgbhat), FABS(Igbtot)) + ckt->CKTabstol; + tol3 = ckt->CKTreltol * MAX(FABS(cgshat), FABS(Igstot)) + ckt->CKTabstol; + tol4 = ckt->CKTreltol * MAX(FABS(cgdhat), FABS(Igdtot)) + ckt->CKTabstol; + if (FABS(cdhat - Idtot) >= tol) { + ckt->CKTnoncon++; + isConv = 0; + } + else if (FABS(cgbhat - Igbtot) >= tol2 || + FABS(cgshat - Igstot) >= tol3 || + FABS(cgdhat - Igdtot) >= tol4) { + ckt->CKTnoncon++; + isConv = 0; + } + else { + Ibtot = here->HSM2_ibs + here->HSM2_ibd + - here->HSM2_isub - here->HSM2_igidl - here->HSM2_igisl; + tol = ckt->CKTreltol * MAX(FABS(cbhat), FABS(Ibtot)) + ckt->CKTabstol; + if (FABS(cbhat - Ibtot) > tol) { + ckt->CKTnoncon++; + isConv = 0; + } + } + } +#endif /* NEWCONV */ + } + } + *(ckt->CKTstate0 + here->HSM2vbs) = vbs; + *(ckt->CKTstate0 + here->HSM2vbd) = vbd; + *(ckt->CKTstate0 + here->HSM2vgs) = vgs; + *(ckt->CKTstate0 + here->HSM2vds) = vds; + *(ckt->CKTstate0 + here->HSM2vsbs) = vsbs; + *(ckt->CKTstate0 + here->HSM2vdbs) = vdbs; + *(ckt->CKTstate0 + here->HSM2vdbd) = vdbd; + *(ckt->CKTstate0 + here->HSM2vges) = vges; + + if ((ckt->CKTmode & MODEDC) && + !(ckt->CKTmode & MODEINITFIX) && !(ckt->CKTmode & MODEINITJCT)) + showPhysVal = 1; + if (model->HSM2_show_Given && showPhysVal && isConv) { + static int isFirst = 1; + if (vds != vds_pre) + ShowPhysVals(here, model, isFirst, vds_pre, vgs, vbs, vgd, vbd, vgb); + else + ShowPhysVals(here, model, isFirst, vds, vgs, vbs, vgd, vbd, vgb); + if (isFirst) isFirst = 0; + } + + /* bulk and channel charge plus overlaps */ + + if (!ChargeComputationNeeded) goto line850; + + line755: + + ag0 = ckt->CKTag[0]; + if (here->HSM2_mode > 0) { /* NORMAL mode */ + gcggb = here->HSM2_cggb * ag0; + gcgdb = here->HSM2_cgdb * ag0; + gcgsb = here->HSM2_cgsb * ag0; + gcgbb = -(gcggb + gcgdb + gcgsb); + + gcdgb = here->HSM2_cdgb * ag0; + gcddb = (here->HSM2_cddb + here->HSM2_capbd) * ag0; + gcdsb = here->HSM2_cdsb * ag0; + + gcsgb = -(here->HSM2_cggb + here->HSM2_cbgb + here->HSM2_cdgb) * ag0; + gcsdb = -(here->HSM2_cgdb + here->HSM2_cbdb + here->HSM2_cddb) * ag0; + gcssb = (here->HSM2_capbs + - (here->HSM2_cgsb + here->HSM2_cbsb + here->HSM2_cdsb)) * ag0; + + gcbgb = here->HSM2_cbgb * ag0; + + if ( !here->HSM2_corbnet ) { + gcdbb = -(gcdgb + gcddb + gcdsb); + gcsbb = -(gcsgb + gcsdb + gcssb); + gcbdb = (here->HSM2_cbdb - here->HSM2_capbd) * ag0; + gcbsb = (here->HSM2_cbsb - here->HSM2_capbs) * ag0; + gcdbdb = 0.0; gcsbsb = 0.0; + } else { + gcdbb = -(gcdgb + gcddb + gcdsb) + here->HSM2_capbd * ag0; + gcsbb = -(gcsgb + gcsdb + gcssb) + here->HSM2_capbs * ag0; + gcbdb = here->HSM2_cbdb * ag0; + gcbsb = here->HSM2_cbsb * ag0; + gcdbdb = - here->HSM2_capbd * ag0; + gcsbsb = - here->HSM2_capbs * ag0; + } + gcbbb = -(gcbdb + gcbgb + gcbsb); + + } + else { /* REVERSE mode */ + gcggb = here->HSM2_cggb * ag0; + gcgdb = here->HSM2_cgsb * ag0; + gcgsb = here->HSM2_cgdb * ag0; + gcgbb = -(gcggb + gcgdb + gcgsb); + + gcdgb = -(here->HSM2_cggb + here->HSM2_cbgb + here->HSM2_cdgb) * ag0; + gcddb = (here->HSM2_capbd + - (here->HSM2_cgsb + here->HSM2_cbsb + here->HSM2_cdsb)) * ag0; + gcdsb = -(here->HSM2_cgdb + here->HSM2_cbdb + here->HSM2_cddb) * ag0; + + gcsgb = here->HSM2_cdgb * ag0; + gcsdb = here->HSM2_cdsb * ag0; + gcssb = (here->HSM2_cddb + here->HSM2_capbs) * ag0; + + gcbgb = here->HSM2_cbgb * ag0; + + if ( !here->HSM2_corbnet ){ + gcdbb = -(gcdgb + gcddb + gcdsb); + gcsbb = -(gcsgb + gcsdb + gcssb); + gcbdb = (here->HSM2_cbsb - here->HSM2_capbd) * ag0; + gcbsb = (here->HSM2_cbdb - here->HSM2_capbs) * ag0; + gcdbdb = 0.0; gcsbsb = 0.0; + } else { + gcdbb = -(gcdgb + gcddb + gcdsb) + here->HSM2_capbd * ag0; + gcsbb = -(gcsgb + gcsdb + gcssb) + here->HSM2_capbs * ag0; + gcbdb = here->HSM2_cbsb * ag0; + gcbsb = here->HSM2_cbdb * ag0; + gcdbdb = - here->HSM2_capbd * ag0; + gcsbsb = - here->HSM2_capbs * ag0; + } + gcbbb = -(gcbgb + gcbdb + gcbsb); + + qdrn = -(qgate + qbulk + qdrn); + } + + if (ByPass) goto line860; + + *(ckt->CKTstate0 + here->HSM2qg) = qgate; + *(ckt->CKTstate0 + here->HSM2qd) = qdrn - *(ckt->CKTstate0 + here->HSM2qbd); + if ( !here->HSM2_corbnet ) { + *(ckt->CKTstate0 + here->HSM2qb) = qbulk + + *(ckt->CKTstate0 + here->HSM2qbd) + *(ckt->CKTstate0 + here->HSM2qbs); + } else { + *(ckt->CKTstate0 + here->HSM2qb) = qbulk; + } + +#ifdef DEBUG_HISIM2LD + printf( "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\n" ) ; + printf( "HSM2qg = %12.5e\n" , *(ckt->CKTstate0 + here->HSM2qg) ) ; + printf( "HSM2qd = %12.5e\n" , *(ckt->CKTstate0 + here->HSM2qd) ) ; + printf( "HSM2qb = %12.5e\n" , *(ckt->CKTstate0 + here->HSM2qb) ) ; + printf( "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\n" ) ; +#endif + + /* store small signal parameters */ + if (ckt->CKTmode & MODEINITSMSIG) goto line1000; + if (!ChargeComputationNeeded) goto line850; + + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HSM2qb) = *(ckt->CKTstate0 + here->HSM2qb); + *(ckt->CKTstate1 + here->HSM2qg) = *(ckt->CKTstate0 + here->HSM2qg); + *(ckt->CKTstate1 + here->HSM2qd) = *(ckt->CKTstate0 + here->HSM2qd); + if ( here->HSM2_corbnet ) { + *(ckt->CKTstate1 + here->HSM2qbs) = *(ckt->CKTstate0 + here->HSM2qbs); + *(ckt->CKTstate1 + here->HSM2qbd) = *(ckt->CKTstate0 + here->HSM2qbd); + } + } + + if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM2qb))) return(error); + if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM2qg))) return(error); + if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM2qd))) return(error); + if ( here->HSM2_corbnet ) { + if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM2qbs))) return(error); + if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM2qbd))) return(error); + } + + goto line860; + + line850: + /* initialize to zero charge conductance and current */ + ceqqg = ceqqb = ceqqd = 0.0; + ceqqjd = ceqqjs = 0.0; + + gcdgb = gcddb = gcdsb = gcdbb = 0.0; + gcsgb = gcsdb = gcssb = gcsbb = 0.0; + gcggb = gcgdb = gcgsb = gcgbb = 0.0; + gcbgb = gcbdb = gcbsb = gcbbb = 0.0; + + gcdbdb = gcsbsb = 0.0; + + goto line900; + + line860: + /* evaluate equivalent charge current */ + + cqgate = *(ckt->CKTstate0 + here->HSM2cqg); + cqbulk = *(ckt->CKTstate0 + here->HSM2cqb); + cqdrn = *(ckt->CKTstate0 + here->HSM2cqd); + +#ifdef DEBUG_HISIM2LD + printf( "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n" ) ; + printf( "cqgate = %12.5e\n" , cqgate ) ; + printf( "cqbulk = %12.5e\n" , cqbulk ) ; + printf( "cqdrn = %12.5e\n" , cqdrn ) ; + printf( "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n" ) ; +#endif + + ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs; + ceqqd = cqdrn - gcdgb * vgb + (gcddb + gcdbdb) * vbd - gcdbdb * vbd_jct + gcdsb * vbs; + ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs; + + if (here->HSM2_corbnet) { + ceqqjs = *(ckt->CKTstate0 + here->HSM2cqbs) + gcsbsb * vbs_jct; + ceqqjd = *(ckt->CKTstate0 + here->HSM2cqbd) + gcdbdb * vbd_jct; + } + + if (ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HSM2cqb) = *(ckt->CKTstate0 + here->HSM2cqb); + *(ckt->CKTstate1 + here->HSM2cqg) = *(ckt->CKTstate0 + here->HSM2cqg); + *(ckt->CKTstate1 + here->HSM2cqd) = *(ckt->CKTstate0 + here->HSM2cqd); + if (here->HSM2_corbnet) { + *(ckt->CKTstate1 + here->HSM2cqbs) = *(ckt->CKTstate0 + here->HSM2cqbs); + *(ckt->CKTstate1 + here->HSM2cqbd) = *(ckt->CKTstate0 + here->HSM2cqbd); + } + } + + /* + * load current vector + */ + line900: + + if (here->HSM2_mode >= 0) { /* NORMAL mode */ + gm = here->HSM2_gm; + gmbs = here->HSM2_gmbs; + FwdSum = gm + gmbs; + RevSum = 0.0; + + cdreq = model->HSM2_type * + (cdrain - here->HSM2_gds * vds - gm * vgs - gmbs * vbs); + ceqbd = model->HSM2_type * (here->HSM2_isub + here->HSM2_igidl + - (here->HSM2_gbds + here->HSM2_gigidlds) * vds + - (here->HSM2_gbgs + here->HSM2_gigidlgs) * vgs + - (here->HSM2_gbbs + here->HSM2_gigidlbs) * vbs); + ceqbs = model->HSM2_type * (here->HSM2_igisl + + here->HSM2_gigislsd * vds + - here->HSM2_gigislgd * vgd + - here->HSM2_gigislbd * vbd); + + gbbdp = -here->HSM2_gbds; + gbbsp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = here->HSM2_gbgs; + gbdpdp = here->HSM2_gbds; + gbdpb = here->HSM2_gbbs; + gbdpsp = -(gbdpg + gbdpdp + gbdpb); + + gbspg = 0.0; + gbspdp = 0.0; + gbspb = 0.0; + gbspsp = 0.0; + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + Ibtoteq = model->HSM2_type * + (here->HSM2_igb - here->HSM2_gigbg * vgs + - here->HSM2_gigbd * vds - here->HSM2_gigbb * vbs); + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + Istoteq = model->HSM2_type * + (here->HSM2_igs - here->HSM2_gigsg * vgs + - here->HSM2_gigsd * vds - here->HSM2_gigsb * vbs); + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + Idtoteq = model->HSM2_type * + (here->HSM2_igd - here->HSM2_gigdg * vgs + - here->HSM2_gigdd * vds - here->HSM2_gigdb * vbs); + } + else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = Ibtoteq = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = Istoteq = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = Idtoteq = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + Igtoteq = Ibtoteq + Istoteq + Idtoteq; + } + else + gIgtotg = gIgtotd = gIgtots = gIgtotb = Igtoteq = 0.0; + + } + else { /* REVERSE mode */ + gm = - here->HSM2_gm; + gmbs = - here->HSM2_gmbs; + FwdSum = 0.0; + RevSum = -(gm + gmbs); + cdreq = -model->HSM2_type * (cdrain + here->HSM2_gds * vds + gm * vgd + gmbs * vbd); + + ceqbs = model->HSM2_type * (here->HSM2_isub + here->HSM2_igisl + + (here->HSM2_gbds + here->HSM2_gigislsd) * vds + - (here->HSM2_gbgs + here->HSM2_gigislgd) * vgd + - (here->HSM2_gbbs + here->HSM2_gigislbd) * vbd); + ceqbd = model->HSM2_type * (here->HSM2_igidl + - here->HSM2_gigidlds * vds + - here->HSM2_gigidlgs * vgs + - here->HSM2_gigidlbs * vbs); + + gbbsp = - here->HSM2_gbds; + gbbdp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = 0.0; + gbdpsp = 0.0; + gbdpb = 0.0; + gbdpdp = 0.0; + + gbspg = here->HSM2_gbgs; + gbspsp = here->HSM2_gbds; + gbspb = here->HSM2_gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + Ibtoteq = model->HSM2_type * + (here->HSM2_igb - here->HSM2_gigbg * vgd + + here->HSM2_gigbs * vds - here->HSM2_gigbb * vbd); + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + Istoteq = model->HSM2_type * + (here->HSM2_igs - here->HSM2_gigsg * vgd + + here->HSM2_gigss * vds - here->HSM2_gigsb * vbd); + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + Idtoteq = model->HSM2_type * + (here->HSM2_igd - here->HSM2_gigdg * vgd + + here->HSM2_gigds * vds - here->HSM2_gigdb * vbd); + } + else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = Ibtoteq = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = Istoteq = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = Idtoteq = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + Igtoteq = Ibtoteq + Istoteq + Idtoteq; + } + else + gIgtotg = gIgtotd = gIgtots = gIgtotb = Igtoteq = 0.0; + + } + + if (model->HSM2_type > 0) { + ceqjs = here->HSM2_ibs - here->HSM2_gbs * vbs_jct; + ceqjd = here->HSM2_ibd - here->HSM2_gbd * vbd_jct; + } + else { + ceqjs = -(here->HSM2_ibs - here->HSM2_gbs * vbs_jct); + ceqjd = -(here->HSM2_ibd - here->HSM2_gbd * vbd_jct); + ceqqg = -ceqqg; + ceqqb = -ceqqb; + ceqqd = -ceqqd; + + if (here->HSM2_corbnet) { + ceqqjs = -ceqqjs; + ceqqjd = -ceqqjd; + } + } + +#ifdef DEBUG_HISIM2LD + printf( "----------------------------------------------------\n" ) ; + printf( "ceqqg = %12.5e\n" , ceqqg ) ; + printf( "....................................................\n" ) ; + printf( "ceqbs = %12.5e\n" , ceqbs ) ; + printf( "ceqbd = %12.5e\n" , ceqbd ) ; + printf( "ceqqb = %12.5e\n" , ceqqb ) ; + printf( "....................................................\n" ) ; + printf( "ceqbd = %12.5e\n" , ceqbd ) ; + printf( "cdreq = %12.5e\n" , cdreq ) ; + printf( "ceqqd = %12.5e\n" , ceqqd ) ; + printf( "----------------------------------------------------\n" ) ; +#endif + + *(ckt->CKTrhs + here->HSM2dNodePrime) += ceqjd - ceqbd - cdreq - ceqqd + Idtoteq; + *(ckt->CKTrhs + here->HSM2gNodePrime) -= ceqqg + Igtoteq; + + if ( !here->HSM2_corbnet ) { + *(ckt->CKTrhs + here->HSM2bNodePrime) += ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq; + *(ckt->CKTrhs + here->HSM2sNodePrime) += cdreq - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + Istoteq; + } else { + *(ckt->CKTrhs + here->HSM2dbNode) -= ceqjd + ceqqjd; + *(ckt->CKTrhs + here->HSM2bNodePrime) += ceqbd + ceqbs - ceqqb + Ibtoteq; + *(ckt->CKTrhs + here->HSM2sbNode) -= ceqjs + ceqqjs; + *(ckt->CKTrhs + here->HSM2sNodePrime) += cdreq - ceqbs + ceqjs + ceqqd + + ceqqg + ceqqb + ceqqjd + ceqqjs + Istoteq; + } + +#ifdef DEBUG_HISIM2LD + printf ("id ig ib is %12.5e %12.5e %12.5e %12.5e\n", ceqjd - ceqbd - cdreq - ceqqd + Idtoteq, + -(ceqqg + Igtoteq), ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq, + cdreq - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + Istoteq); +#endif + + /* + * load y matrix + */ + + if ( !here->HSM2_corbnet ){ + gjbd = here->HSM2_gbd; + gjbs = here->HSM2_gbs; + } else + gjbd = gjbs = 0.0; + + + if (here->HSM2_corg == 1) { + grg = here->HSM2_grg; + *(here->HSM2GgPtr) += grg; + *(here->HSM2GPgPtr) -= grg; + *(here->HSM2GgpPtr) -= grg; + *(here->HSM2GPgpPtr) += gcggb + grg + gIgtotg; + *(here->HSM2GPdpPtr) += gcgdb + gIgtotd; + *(here->HSM2GPspPtr) += gcgsb + gIgtots; + *(here->HSM2GPbpPtr) += gcgbb + gIgtotb; + } else { + *(here->HSM2GPgpPtr) += gcggb + gIgtotg; + *(here->HSM2GPdpPtr) += gcgdb + gIgtotd; + *(here->HSM2GPspPtr) += gcgsb + gIgtots; + *(here->HSM2GPbpPtr) += gcgbb + gIgtotb; + } + + *(here->HSM2DPdpPtr) += here->HSM2drainConductance + + here->HSM2_gds + here->HSM2_gbd + RevSum + gcddb + gbdpdp - gIdtotd; + *(here->HSM2DPdPtr) -= here->HSM2drainConductance; + *(here->HSM2DPgpPtr) += gm + gcdgb + gbdpg - gIdtotg; + *(here->HSM2DPspPtr) -= here->HSM2_gds + FwdSum - gcdsb - gbdpsp + gIdtots; + *(here->HSM2DPbpPtr) -= gjbd - gmbs - gcdbb - gbdpb + gIdtotb; + + *(here->HSM2DdpPtr) -= here->HSM2drainConductance; + *(here->HSM2DdPtr) += here->HSM2drainConductance; + + *(here->HSM2SPdpPtr) -= here->HSM2_gds + RevSum - gcsdb - gbspdp + gIstotd; + *(here->HSM2SPgpPtr) += gcsgb - gm + gbspg - gIstotg; + *(here->HSM2SPspPtr) += here->HSM2sourceConductance + + here->HSM2_gds + here->HSM2_gbs + FwdSum + gcssb + gbspsp - gIstots; + *(here->HSM2SPsPtr) -= here->HSM2sourceConductance; + *(here->HSM2SPbpPtr) -= gjbs + gmbs - gcsbb - gbspb + gIstotb; + + *(here->HSM2SspPtr) -= here->HSM2sourceConductance; + *(here->HSM2SsPtr) += here->HSM2sourceConductance; + + *(here->HSM2BPdpPtr) += gcbdb - gjbd + gbbdp - gIbtotd; + *(here->HSM2BPgpPtr) += gcbgb - here->HSM2_gbgs - gIbtotg; + *(here->HSM2BPspPtr) += gcbsb - gjbs + gbbsp - gIbtots; + *(here->HSM2BPbpPtr) += gjbd + gjbs + gcbbb - here->HSM2_gbbs - gIbtotb; + + if (model->HSM2_cogidl) { + /* stamp GIDL */ + *(here->HSM2DPdpPtr) += here->HSM2_gigidlds; + *(here->HSM2DPgpPtr) += here->HSM2_gigidlgs; + *(here->HSM2DPspPtr) -= (here->HSM2_gigidlgs + + here->HSM2_gigidlds + here->HSM2_gigidlbs); + *(here->HSM2DPbpPtr) += here->HSM2_gigidlbs; + *(here->HSM2BPdpPtr) -= here->HSM2_gigidlds; + *(here->HSM2BPgpPtr) -= here->HSM2_gigidlgs; + *(here->HSM2BPspPtr) += (here->HSM2_gigidlgs + + here->HSM2_gigidlds + here->HSM2_gigidlbs); + *(here->HSM2BPbpPtr) -= here->HSM2_gigidlbs; + /* stamp GISL */ + *(here->HSM2SPdpPtr) -= (here->HSM2_gigislsd + + here->HSM2_gigislgd + here->HSM2_gigislbd); + *(here->HSM2SPgpPtr) += here->HSM2_gigislgd; + *(here->HSM2SPspPtr) += here->HSM2_gigislsd; + *(here->HSM2SPbpPtr) += here->HSM2_gigislbd; + *(here->HSM2BPdpPtr) += (here->HSM2_gigislgd + + here->HSM2_gigislsd + here->HSM2_gigislbd); + *(here->HSM2BPgpPtr) -= here->HSM2_gigislgd; + *(here->HSM2BPspPtr) -= here->HSM2_gigislsd; + *(here->HSM2BPbpPtr) -= here->HSM2_gigislbd; + } + + if (here->HSM2_corbnet) { /* body resistance network */ + *(here->HSM2DPdbPtr) += gcdbdb - here->HSM2_gbd; + *(here->HSM2SPsbPtr) -= here->HSM2_gbs - gcsbsb; + + *(here->HSM2DBdpPtr) += gcdbdb - here->HSM2_gbd; + *(here->HSM2DBdbPtr) += here->HSM2_gbd - gcdbdb + + here->HSM2_grbpd + here->HSM2_grbdb; + *(here->HSM2DBbpPtr) -= here->HSM2_grbpd; + *(here->HSM2DBbPtr) -= here->HSM2_grbdb; + + *(here->HSM2BPdbPtr) -= here->HSM2_grbpd; + *(here->HSM2BPbPtr) -= here->HSM2_grbpb; + *(here->HSM2BPsbPtr) -= here->HSM2_grbps; + *(here->HSM2BPbpPtr) += here->HSM2_grbpd + here->HSM2_grbps + here->HSM2_grbpb; + + *(here->HSM2SBspPtr) += gcsbsb - here->HSM2_gbs; + *(here->HSM2SBbpPtr) -= here->HSM2_grbps; + *(here->HSM2SBbPtr) -= here->HSM2_grbsb; + *(here->HSM2SBsbPtr) += here->HSM2_gbs - gcsbsb + + here->HSM2_grbps + here->HSM2_grbsb; + + *(here->HSM2BdbPtr) -= here->HSM2_grbdb; + *(here->HSM2BbpPtr) -= here->HSM2_grbpb; + *(here->HSM2BsbPtr) -= here->HSM2_grbsb; + *(here->HSM2BbPtr) += here->HSM2_grbsb + here->HSM2_grbdb + here->HSM2_grbpb; + } + + line1000: + ; + + } /* End of MOSFET Instance */ + } /* End of Model Instance */ + +#ifdef MOS_MODEL_TIME +tm1 = gtodsecld() ; +mos_model_time += ( tm1 - tm0 ) ; +sprintf( mos_model_name , "HiSIM 240BSC1" ) ; +#ifdef PARAMOS_TIME +vsum = vbs + vds + vgs ; +if ( vsum < vsum0 - 1e-6 || vsum > vsum0 + 1e-6 ) { +printf( "PMVbs= %12.5e\n" , vbs ) ; +printf( "PMVds= %12.5e\n" , vds ) ; +printf( "PMVgs= %12.5e\n" , vgs ) ; +printf( "PMTime= %12.5e\n" , tm1 - tm0 ) ; +} +vsum0 = vsum ; +#endif +#endif + + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2mask.c b/src/spicelib/devices/hisim2/hsm2mask.c new file mode 100644 index 000000000..a897b6865 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2mask.c @@ -0,0 +1,1502 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2mask.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "cktdefs.h" +#include "devdefs.h" +#include "hsm2def.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2mAsk(ckt,inst,which,value) + CKTcircuit *ckt; + GENmodel *inst; + int which; + IFvalue *value; +{ + HSM2model *model = (HSM2model *)inst; + switch (which) { + case HSM2_MOD_NMOS: + value->iValue = model->HSM2_type; + return(OK); + case HSM2_MOD_PMOS: + value->iValue = model->HSM2_type; + return(OK); + case HSM2_MOD_LEVEL: + value->iValue = model->HSM2_level; + return(OK); + case HSM2_MOD_INFO: + value->iValue = model->HSM2_info; + return(OK); + case HSM2_MOD_NOISE: + value->iValue = model->HSM2_noise; + return(OK); + case HSM2_MOD_VERSION: + value->iValue = model->HSM2_version; + return(OK); + case HSM2_MOD_SHOW: + value->iValue = model->HSM2_show; + return(OK); + case HSM2_MOD_CORSRD: + value->iValue = model->HSM2_corsrd; + return(OK); + case HSM2_MOD_CORG: + value->iValue = model->HSM2_corg; + return(OK); + case HSM2_MOD_COIPRV: + value->iValue = model->HSM2_coiprv; + return(OK); + case HSM2_MOD_COPPRV: + value->iValue = model->HSM2_copprv; + return(OK); + case HSM2_MOD_COADOV: + value->iValue = model->HSM2_coadov; + return(OK); + case HSM2_MOD_COISUB: + value->iValue = model->HSM2_coisub; + return(OK); + case HSM2_MOD_COIIGS: + value->iValue = model->HSM2_coiigs; + return(OK); + case HSM2_MOD_COGIDL: + value->iValue = model->HSM2_cogidl; + return(OK); + case HSM2_MOD_COOVLP: + value->iValue = model->HSM2_coovlp; + return(OK); + case HSM2_MOD_COFLICK: + value->iValue = model->HSM2_coflick; + return(OK); + case HSM2_MOD_COISTI: + value->iValue = model->HSM2_coisti; + return(OK); + case HSM2_MOD_CONQS: + value->iValue = model->HSM2_conqs; + return(OK); + case HSM2_MOD_CORBNET: + value->iValue = model->HSM2_corbnet; + return(OK); + case HSM2_MOD_COTHRML: + value->iValue = model->HSM2_cothrml; + return(OK); + case HSM2_MOD_COIGN: + value->iValue = model->HSM2_coign; + return(OK); + case HSM2_MOD_CODFM: + value->iValue = model->HSM2_codfm; + return(OK); + case HSM2_MOD_CORECIP: + value->iValue = model->HSM2_corecip; + return(OK); + case HSM2_MOD_COQY: + value->iValue = model->HSM2_coqy; + return(OK); + case HSM2_MOD_COQOVSM: + value->iValue = model->HSM2_coqovsm; + return(OK); + case HSM2_MOD_VMAX: + value->rValue = model->HSM2_vmax; + return(OK); + case HSM2_MOD_BGTMP1: + value->rValue = model->HSM2_bgtmp1; + return(OK); + case HSM2_MOD_BGTMP2: + value->rValue = model->HSM2_bgtmp2; + return(OK); + case HSM2_MOD_EG0: + value->rValue = model->HSM2_eg0; + return(OK); + case HSM2_MOD_TOX: + value->rValue = model->HSM2_tox; + return(OK); + case HSM2_MOD_XLD: + value->rValue = model->HSM2_xld; + return(OK); + case HSM2_MOD_LOVER: + value->rValue = model->HSM2_lover; + return(OK); + case HSM2_MOD_DDLTMAX: /* Vdseff */ + value->rValue = model->HSM2_ddltmax; + return(OK); + case HSM2_MOD_DDLTSLP: /* Vdseff */ + value->rValue = model->HSM2_ddltslp; + return(OK); + case HSM2_MOD_DDLTICT: /* Vdseff */ + value->rValue = model->HSM2_ddltict; + return(OK); + case HSM2_MOD_VFBOVER: + value->rValue = model->HSM2_vfbover; + return(OK); + case HSM2_MOD_NOVER: + value->rValue = model->HSM2_nover; + return(OK); + case HSM2_MOD_XWD: + value->rValue = model->HSM2_xwd; + return(OK); + case HSM2_MOD_XL: + value->rValue = model->HSM2_xl; + return(OK); + case HSM2_MOD_XW: + value->rValue = model->HSM2_xw; + return(OK); + case HSM2_MOD_SAREF: + value->rValue = model->HSM2_saref; + return(OK); + case HSM2_MOD_SBREF: + value->rValue = model->HSM2_sbref; + return(OK); + case HSM2_MOD_LL: + value->rValue = model->HSM2_ll; + return(OK); + case HSM2_MOD_LLD: + value->rValue = model->HSM2_lld; + return(OK); + case HSM2_MOD_LLN: + value->rValue = model->HSM2_lln; + return(OK); + case HSM2_MOD_WL: + value->rValue = model->HSM2_wl; + return(OK); + case HSM2_MOD_WL1: + value->rValue = model->HSM2_wl1; + return(OK); + case HSM2_MOD_WL1P: + value->rValue = model->HSM2_wl1p; + return(OK); + case HSM2_MOD_WL2: + value->rValue = model->HSM2_wl2; + return(OK); + case HSM2_MOD_WL2P: + value->rValue = model->HSM2_wl2p; + return(OK); + case HSM2_MOD_WLD: + value->rValue = model->HSM2_wld; + return(OK); + case HSM2_MOD_WLN: + value->rValue = model->HSM2_wln; + return(OK); + case HSM2_MOD_XQY: + value->rValue = model->HSM2_xqy; + return(OK); + case HSM2_MOD_XQY1: + value->rValue = model->HSM2_xqy1; + return(OK); + case HSM2_MOD_XQY2: + value->rValue = model->HSM2_xqy2; + return(OK); + case HSM2_MOD_QYRAT: + value->rValue = model->HSM2_qyrat; + return(OK); + case HSM2_MOD_RS: + value->rValue = model->HSM2_rs; + return(OK); + case HSM2_MOD_RD: + value->rValue = model->HSM2_rd; + return(OK); + case HSM2_MOD_RSH: + value->rValue = model->HSM2_rsh; + return(OK); + case HSM2_MOD_RSHG: + value->rValue = model->HSM2_rshg; + return(OK); +/* case HSM2_MOD_NGCON: */ +/* value->rValue = model->HSM2_ngcon; */ +/* return(OK); */ +/* case HSM2_MOD_XGW: */ +/* value->rValue = model->HSM2_xgw; */ +/* return(OK); */ +/* case HSM2_MOD_XGL: */ +/* value->rValue = model->HSM2_xgl; */ +/* return(OK); */ +/* case HSM2_MOD_NF: */ +/* value->rValue = model->HSM2_nf; */ +/* return(OK); */ + case HSM2_MOD_VFBC: + value->rValue = model->HSM2_vfbc; + return(OK); + case HSM2_MOD_VBI: + value->rValue = model->HSM2_vbi; + return(OK); + case HSM2_MOD_NSUBC: + value->rValue = model->HSM2_nsubc; + return(OK); + case HSM2_MOD_PARL2: + value->rValue = model->HSM2_parl2; + return(OK); + case HSM2_MOD_LP: + value->rValue = model->HSM2_lp; + return(OK); + case HSM2_MOD_NSUBP: + value->rValue = model->HSM2_nsubp; + return(OK); + case HSM2_MOD_NSUBPL: + value->rValue = model->HSM2_nsubpl; + return(OK); + case HSM2_MOD_NSUBPFAC: + value->rValue = model->HSM2_nsubpfac; + return(OK); + case HSM2_MOD_NSUBPW: + value->rValue = model->HSM2_nsubpw; + return(OK); + case HSM2_MOD_NSUBPWP: + value->rValue = model->HSM2_nsubpwp; + return(OK); + case HSM2_MOD_SCP1: + value->rValue = model->HSM2_scp1; + return(OK); + case HSM2_MOD_SCP2: + value->rValue = model->HSM2_scp2; + return(OK); + case HSM2_MOD_SCP3: + value->rValue = model->HSM2_scp3; + return(OK); + case HSM2_MOD_SC1: + value->rValue = model->HSM2_sc1; + return(OK); + case HSM2_MOD_SC2: + value->rValue = model->HSM2_sc2; + return(OK); + case HSM2_MOD_SC3: + value->rValue = model->HSM2_sc3; + return(OK); + case HSM2_MOD_SC4: + value->rValue = model->HSM2_sc4; + return(OK); + case HSM2_MOD_PGD1: + value->rValue = model->HSM2_pgd1; + return(OK); + case HSM2_MOD_PGD2: + value->rValue = model->HSM2_pgd2; + return(OK); +//case HSM2_MOD_PGD3: +// value->rValue = model->HSM2_pgd3; +// return(OK); + case HSM2_MOD_PGD4: + value->rValue = model->HSM2_pgd4; + return(OK); + case HSM2_MOD_NDEP: + value->rValue = model->HSM2_ndep; + return(OK); + case HSM2_MOD_NDEPL: + value->rValue = model->HSM2_ndepl; + return(OK); + case HSM2_MOD_NDEPLP: + value->rValue = model->HSM2_ndeplp; + return(OK); + case HSM2_MOD_NDEPW: + value->rValue = model->HSM2_ndepw; + return(OK); + case HSM2_MOD_NDEPWP: + value->rValue = model->HSM2_ndepwp; + return(OK); + case HSM2_MOD_NINV: + value->rValue = model->HSM2_ninv; + return(OK); + case HSM2_MOD_NINVD: + value->rValue = model->HSM2_ninvd; + return(OK); + case HSM2_MOD_MUECB0: + value->rValue = model->HSM2_muecb0; + return(OK); + case HSM2_MOD_MUECB1: + value->rValue = model->HSM2_muecb1; + return(OK); + case HSM2_MOD_MUEPH1: + value->rValue = model->HSM2_mueph1; + return(OK); + case HSM2_MOD_MUEPH0: + value->rValue = model->HSM2_mueph0; + return(OK); + case HSM2_MOD_MUEPHW: + value->rValue = model->HSM2_muephw; + return(OK); + case HSM2_MOD_MUEPWP: + value->rValue = model->HSM2_muepwp; + return(OK); + case HSM2_MOD_MUEPWD: + value->rValue = model->HSM2_muepwd; + return(OK); + case HSM2_MOD_MUEPHL: + value->rValue = model->HSM2_muephl; + return(OK); + case HSM2_MOD_MUEPLP: + value->rValue = model->HSM2_mueplp; + return(OK); + case HSM2_MOD_MUEPLD: + value->rValue = model->HSM2_muepld; + return(OK); + case HSM2_MOD_MUEPHS: + value->rValue = model->HSM2_muephs; + return(OK); + case HSM2_MOD_MUEPSP: + value->rValue = model->HSM2_muepsp; + return(OK); + case HSM2_MOD_VTMP: + value->rValue = model->HSM2_vtmp; + return(OK); + case HSM2_MOD_WVTH0: + value->rValue = model->HSM2_wvth0; + return(OK); + case HSM2_MOD_MUESR1: + value->rValue = model->HSM2_muesr1; + return(OK); + case HSM2_MOD_MUESR0: + value->rValue = model->HSM2_muesr0; + return(OK); + case HSM2_MOD_MUESRL: + value->rValue = model->HSM2_muesrl; + return(OK); + case HSM2_MOD_MUESLP: + value->rValue = model->HSM2_mueslp; + return(OK); + case HSM2_MOD_MUESRW: + value->rValue = model->HSM2_muesrw; + return(OK); + case HSM2_MOD_MUESWP: + value->rValue = model->HSM2_mueswp; + return(OK); + case HSM2_MOD_BB: + value->rValue = model->HSM2_bb; + return(OK); + case HSM2_MOD_SUB1: + value->rValue = model->HSM2_sub1; + return(OK); + case HSM2_MOD_SUB2: + value->rValue = model->HSM2_sub2; + return(OK); + case HSM2_MOD_SVGS: + value->rValue = model->HSM2_svgs; + return(OK); + case HSM2_MOD_SVGSL: + value->rValue = model->HSM2_svgsl; + return(OK); + case HSM2_MOD_SVGSLP: + value->rValue = model->HSM2_svgslp; + return(OK); + case HSM2_MOD_SVGSW: + value->rValue = model->HSM2_svgsw; + return(OK); + case HSM2_MOD_SVGSWP: + value->rValue = model->HSM2_svgswp; + return(OK); + case HSM2_MOD_SVBS: + value->rValue = model->HSM2_svbs; + return(OK); + case HSM2_MOD_SVBSL: + value->rValue = model->HSM2_svbsl; + return(OK); + case HSM2_MOD_SVBSLP: + value->rValue = model->HSM2_svbslp; + return(OK); + case HSM2_MOD_SVDS: + value->rValue = model->HSM2_svds; + return(OK); + case HSM2_MOD_SLG: + value->rValue = model->HSM2_slg; + return(OK); + case HSM2_MOD_SLGL: + value->rValue = model->HSM2_slgl; + return(OK); + case HSM2_MOD_SLGLP: + value->rValue = model->HSM2_slglp; + return(OK); + case HSM2_MOD_SUB1L: + value->rValue = model->HSM2_sub1l; + return(OK); + case HSM2_MOD_SUB1LP: + value->rValue = model->HSM2_sub1lp; + return(OK); + case HSM2_MOD_SUB2L: + value->rValue = model->HSM2_sub2l; + return(OK); + case HSM2_MOD_NSTI: + value->rValue = model->HSM2_nsti; + return(OK); + case HSM2_MOD_WSTI: + value->rValue = model->HSM2_wsti; + return(OK); + case HSM2_MOD_WSTIL: + value->rValue = model->HSM2_wstil; + return(OK); + case HSM2_MOD_WSTILP: + value->rValue = model->HSM2_wstilp; + return(OK); + case HSM2_MOD_WSTIW: + value->rValue = model->HSM2_wstiw; + return(OK); + case HSM2_MOD_WSTIWP: + value->rValue = model->HSM2_wstiwp; + return(OK); + case HSM2_MOD_SCSTI1: + value->rValue = model->HSM2_scsti1; + return(OK); + case HSM2_MOD_SCSTI2: + value->rValue = model->HSM2_scsti2; + return(OK); + case HSM2_MOD_VTHSTI: + value->rValue = model->HSM2_vthsti; + return(OK); + case HSM2_MOD_VDSTI: + value->rValue = model->HSM2_vdsti; + return(OK); + case HSM2_MOD_MUESTI1: + value->rValue = model->HSM2_muesti1; + return(OK); + case HSM2_MOD_MUESTI2: + value->rValue = model->HSM2_muesti2; + return(OK); + case HSM2_MOD_MUESTI3: + value->rValue = model->HSM2_muesti3; + return(OK); + case HSM2_MOD_NSUBPSTI1: + value->rValue = model->HSM2_nsubpsti1; + return(OK); + case HSM2_MOD_NSUBPSTI2: + value->rValue = model->HSM2_nsubpsti2; + return(OK); + case HSM2_MOD_NSUBPSTI3: + value->rValue = model->HSM2_nsubpsti3; + return(OK); + case HSM2_MOD_LPEXT: + value->rValue = model->HSM2_lpext; + return(OK); + case HSM2_MOD_NPEXT: + value->rValue = model->HSM2_npext; + return(OK); + case HSM2_MOD_NPEXTW: + value->rValue = model->HSM2_npextw; + return(OK); + case HSM2_MOD_NPEXTWP: + value->rValue = model->HSM2_npextwp; + return(OK); + case HSM2_MOD_SCP22: + value->rValue = model->HSM2_scp22; + return(OK); + case HSM2_MOD_SCP21: + value->rValue = model->HSM2_scp21; + return(OK); + case HSM2_MOD_BS1: + value->rValue = model->HSM2_bs1; + return(OK); + case HSM2_MOD_BS2: + value->rValue = model->HSM2_bs2; + return(OK); + case HSM2_MOD_CGSO: + value->rValue = model->HSM2_cgso; + return(OK); + case HSM2_MOD_CGDO: + value->rValue = model->HSM2_cgdo; + return(OK); + case HSM2_MOD_CGBO: + value->rValue = model->HSM2_cgbo; + return(OK); + case HSM2_MOD_TPOLY: + value->rValue = model->HSM2_tpoly; + return(OK); + case HSM2_MOD_JS0: + value->rValue = model->HSM2_js0; + return(OK); + case HSM2_MOD_JS0SW: + value->rValue = model->HSM2_js0sw; + return(OK); + case HSM2_MOD_NJ: + value->rValue = model->HSM2_nj; + return(OK); + case HSM2_MOD_NJSW: + value->rValue = model->HSM2_njsw; + return(OK); + case HSM2_MOD_XTI: + value->rValue = model->HSM2_xti; + return(OK); + case HSM2_MOD_CJ: + value->rValue = model->HSM2_cj; + return(OK); + case HSM2_MOD_CJSW: + value->rValue = model->HSM2_cjsw; + return(OK); + case HSM2_MOD_CJSWG: + value->rValue = model->HSM2_cjswg; + return(OK); + case HSM2_MOD_MJ: + value->rValue = model->HSM2_mj; + return(OK); + case HSM2_MOD_MJSW: + value->rValue = model->HSM2_mjsw; + return(OK); + case HSM2_MOD_MJSWG: + value->rValue = model->HSM2_mjswg; + return(OK); + case HSM2_MOD_PB: + value->rValue = model->HSM2_pb; + return(OK); + case HSM2_MOD_PBSW: + value->rValue = model->HSM2_pbsw; + return(OK); + case HSM2_MOD_PBSWG: + value->rValue = model->HSM2_pbswg; + return(OK); + + case HSM2_MOD_TCJBD: + value->rValue = model->HSM2_tcjbd; + return(OK); + case HSM2_MOD_TCJBS: + value->rValue = model->HSM2_tcjbs; + return(OK); + case HSM2_MOD_TCJBDSW: + value->rValue = model->HSM2_tcjbdsw; + return(OK); + case HSM2_MOD_TCJBSSW: + value->rValue = model->HSM2_tcjbssw; + return(OK); + case HSM2_MOD_TCJBDSWG: + value->rValue = model->HSM2_tcjbdswg; + return(OK); + case HSM2_MOD_TCJBSSWG: + value->rValue = model->HSM2_tcjbsswg; + return(OK); + case HSM2_MOD_XTI2: + value->rValue = model->HSM2_xti2; + return(OK); + case HSM2_MOD_CISB: + value->rValue = model->HSM2_cisb; + return(OK); + case HSM2_MOD_CVB: + value->rValue = model->HSM2_cvb; + return(OK); + case HSM2_MOD_CTEMP: + value->rValue = model->HSM2_ctemp; + return(OK); + case HSM2_MOD_CISBK: + value->rValue = model->HSM2_cisbk; + return(OK); + case HSM2_MOD_CVBK: + value->rValue = model->HSM2_cvbk; + return(OK); + case HSM2_MOD_DIVX: + value->rValue = model->HSM2_divx; + return(OK); + case HSM2_MOD_CLM1: + value->rValue = model->HSM2_clm1; + return(OK); + case HSM2_MOD_CLM2: + value->rValue = model->HSM2_clm2; + return(OK); + case HSM2_MOD_CLM3: + value->rValue = model->HSM2_clm3; + return(OK); + case HSM2_MOD_CLM5: + value->rValue = model->HSM2_clm5; + return(OK); + case HSM2_MOD_CLM6: + value->rValue = model->HSM2_clm6; + return(OK); + case HSM2_MOD_MUETMP: + value->rValue = model->HSM2_muetmp; + return(OK); + case HSM2_MOD_VOVER: + value->rValue = model->HSM2_vover; + return(OK); + case HSM2_MOD_VOVERP: + value->rValue = model->HSM2_voverp; + return(OK); + case HSM2_MOD_VOVERS: + value->rValue = model->HSM2_vovers; + return(OK); + case HSM2_MOD_VOVERSP: + value->rValue = model->HSM2_voversp; + return(OK); + case HSM2_MOD_WFC: + value->rValue = model->HSM2_wfc; + return(OK); + case HSM2_MOD_NSUBCW: + value->rValue = model->HSM2_nsubcw; + return(OK); + case HSM2_MOD_NSUBCWP: + value->rValue = model->HSM2_nsubcwp; + return(OK); + case HSM2_MOD_NSUBCMAX: + value->rValue = model->HSM2_nsubcmax; + return(OK); + case HSM2_MOD_QME1: + value->rValue = model->HSM2_qme1; + return(OK); + case HSM2_MOD_QME2: + value->rValue = model->HSM2_qme2; + return(OK); + case HSM2_MOD_QME3: + value->rValue = model->HSM2_qme3; + return(OK); + case HSM2_MOD_GIDL1: + value->rValue = model->HSM2_gidl1; + return(OK); + case HSM2_MOD_GIDL2: + value->rValue = model->HSM2_gidl2; + return(OK); + case HSM2_MOD_GIDL3: + value->rValue = model->HSM2_gidl3; + return(OK); + case HSM2_MOD_GIDL4: + value->rValue = model->HSM2_gidl4; + return(OK); + case HSM2_MOD_GIDL5: + value->rValue = model->HSM2_gidl5; + return(OK); + case HSM2_MOD_GLEAK1: + value->rValue = model->HSM2_gleak1; + return(OK); + case HSM2_MOD_GLEAK2: + value->rValue = model->HSM2_gleak2; + return(OK); + case HSM2_MOD_GLEAK3: + value->rValue = model->HSM2_gleak3; + return(OK); + case HSM2_MOD_GLEAK4: + value->rValue = model->HSM2_gleak4; + return(OK); + case HSM2_MOD_GLEAK5: + value->rValue = model->HSM2_gleak5; + return(OK); + case HSM2_MOD_GLEAK6: + value->rValue = model->HSM2_gleak6; + return(OK); + case HSM2_MOD_GLEAK7: + value->rValue = model->HSM2_gleak7; + return(OK); + case HSM2_MOD_GLKSD1: + value->rValue = model->HSM2_glksd1; + return(OK); + case HSM2_MOD_GLKSD2: + value->rValue = model->HSM2_glksd2; + return(OK); + case HSM2_MOD_GLKSD3: + value->rValue = model->HSM2_glksd3; + return(OK); + case HSM2_MOD_GLKB1: + value->rValue = model->HSM2_glkb1; + return(OK); + case HSM2_MOD_GLKB2: + value->rValue = model->HSM2_glkb2; + return(OK); + case HSM2_MOD_GLKB3: + value->rValue = model->HSM2_glkb3; + return(OK); + case HSM2_MOD_EGIG: + value->rValue = model->HSM2_egig; + return(OK); + case HSM2_MOD_IGTEMP2: + value->rValue = model->HSM2_igtemp2; + return(OK); + case HSM2_MOD_IGTEMP3: + value->rValue = model->HSM2_igtemp3; + return(OK); + case HSM2_MOD_VZADD0: + value->rValue = model->HSM2_vzadd0; + return(OK); + case HSM2_MOD_PZADD0: + value->rValue = model->HSM2_pzadd0; + return(OK); + case HSM2_MOD_NFTRP: + value->rValue = model->HSM2_nftrp; + return(OK); + case HSM2_MOD_NFALP: + value->rValue = model->HSM2_nfalp; + return(OK); + case HSM2_MOD_CIT: + value->rValue = model->HSM2_cit; + return(OK); + case HSM2_MOD_FALPH: + value->rValue = model->HSM2_falph; + return(OK); + case HSM2_MOD_KAPPA: + value->rValue = model->HSM2_kappa; + return(OK); + case HSM2_MOD_VDIFFJ: + value->rValue = model->HSM2_vdiffj; + return(OK); + case HSM2_MOD_DLY1: + value->rValue = model->HSM2_dly1; + return(OK); + case HSM2_MOD_DLY2: + value->rValue = model->HSM2_dly2; + return(OK); + case HSM2_MOD_DLY3: + value->rValue = model->HSM2_dly3; + return(OK); + case HSM2_MOD_TNOM: + value->rValue = model->HSM2_tnom; + return(OK); + case HSM2_MOD_OVSLP: + value->rValue = model->HSM2_ovslp; + return(OK); + case HSM2_MOD_OVMAG: + value->rValue = model->HSM2_ovmag; + return(OK); + case HSM2_MOD_GBMIN: + value->rValue = model->HSM2_gbmin; + return(OK); + case HSM2_MOD_RBPB: + value->rValue = model->HSM2_rbpb; + return(OK); + case HSM2_MOD_RBPD: + value->rValue = model->HSM2_rbpd; + return(OK); + case HSM2_MOD_RBPS: + value->rValue = model->HSM2_rbps; + return(OK); + case HSM2_MOD_RBDB: + value->rValue = model->HSM2_rbdb; + return(OK); + case HSM2_MOD_RBSB: + value->rValue = model->HSM2_rbsb; + return(OK); + case HSM2_MOD_IBPC1: + value->rValue = model->HSM2_ibpc1; + return(OK); + case HSM2_MOD_IBPC2: + value->rValue = model->HSM2_ibpc2; + return(OK); + case HSM2_MOD_MPHDFM: + value->rValue = model->HSM2_mphdfm; + return(OK); + + + case HSM2_MOD_PTL: + value->rValue = model->HSM2_ptl; + return(OK); + case HSM2_MOD_PTP: + value->rValue = model->HSM2_ptp; + return(OK); + case HSM2_MOD_PT2: + value->rValue = model->HSM2_pt2; + return(OK); + case HSM2_MOD_PTLP: + value->rValue = model->HSM2_ptlp; + return(OK); + case HSM2_MOD_GDL: + value->rValue = model->HSM2_gdl; + return(OK); + case HSM2_MOD_GDLP: + value->rValue = model->HSM2_gdlp; + return(OK); + + case HSM2_MOD_GDLD: + value->rValue = model->HSM2_gdld; + return(OK); + case HSM2_MOD_PT4: + value->rValue = model->HSM2_pt4; + return(OK); + case HSM2_MOD_PT4P: + value->rValue = model->HSM2_pt4p; + return(OK); + case HSM2_MOD_MUEPHL2: + value->rValue = model->HSM2_muephl2; + return(OK); + case HSM2_MOD_MUEPLP2: + value->rValue = model->HSM2_mueplp2; + return(OK); + case HSM2_MOD_NSUBCW2: + value->rValue = model->HSM2_nsubcw2; + return(OK); + case HSM2_MOD_NSUBCWP2: + value->rValue = model->HSM2_nsubcwp2; + return(OK); + case HSM2_MOD_MUEPHW2: + value->rValue = model->HSM2_muephw2; + return(OK); + case HSM2_MOD_MUEPWP2: + value->rValue = model->HSM2_muepwp2; + return(OK); + case HSM2_MOD_VGSMIN: + value->rValue = model->HSM2_Vgsmin; + return(OK); + case HSM2_MOD_SC3VBS: + value->rValue = model->HSM2_sc3Vbs; + return(OK); + case HSM2_MOD_BYPTOL: + value->rValue = model->HSM2_byptol; + return(OK); + case HSM2_MOD_MUECB0LP: + value->rValue = model->HSM2_muecb0lp; + return(OK); + case HSM2_MOD_MUECB1LP: + value->rValue = model->HSM2_muecb1lp; + return(OK); + + + /* binning parameters */ + case HSM2_MOD_LMIN: + value->rValue = model->HSM2_lmin; + return(OK); + case HSM2_MOD_LMAX: + value->rValue = model->HSM2_lmax; + return(OK); + case HSM2_MOD_WMIN: + value->rValue = model->HSM2_wmin; + return(OK); + case HSM2_MOD_WMAX: + value->rValue = model->HSM2_wmax; + return(OK); + case HSM2_MOD_LBINN: + value->rValue = model->HSM2_lbinn; + return(OK); + case HSM2_MOD_WBINN: + value->rValue = model->HSM2_wbinn; + return(OK); + + /* Length dependence */ + case HSM2_MOD_LVMAX: + value->rValue = model->HSM2_lvmax; + return(OK); + case HSM2_MOD_LBGTMP1: + value->rValue = model->HSM2_lbgtmp1; + return(OK); + case HSM2_MOD_LBGTMP2: + value->rValue = model->HSM2_lbgtmp2; + return(OK); + case HSM2_MOD_LEG0: + value->rValue = model->HSM2_leg0; + return(OK); + case HSM2_MOD_LLOVER: + value->rValue = model->HSM2_llover; + return(OK); + case HSM2_MOD_LVFBOVER: + value->rValue = model->HSM2_lvfbover; + return(OK); + case HSM2_MOD_LNOVER: + value->rValue = model->HSM2_lnover; + return(OK); + case HSM2_MOD_LWL2: + value->rValue = model->HSM2_lwl2; + return(OK); + case HSM2_MOD_LVFBC: + value->rValue = model->HSM2_lvfbc; + return(OK); + case HSM2_MOD_LNSUBC: + value->rValue = model->HSM2_lnsubc; + return(OK); + case HSM2_MOD_LNSUBP: + value->rValue = model->HSM2_lnsubp; + return(OK); + case HSM2_MOD_LSCP1: + value->rValue = model->HSM2_lscp1; + return(OK); + case HSM2_MOD_LSCP2: + value->rValue = model->HSM2_lscp2; + return(OK); + case HSM2_MOD_LSCP3: + value->rValue = model->HSM2_lscp3; + return(OK); + case HSM2_MOD_LSC1: + value->rValue = model->HSM2_lsc1; + return(OK); + case HSM2_MOD_LSC2: + value->rValue = model->HSM2_lsc2; + return(OK); + case HSM2_MOD_LSC3: + value->rValue = model->HSM2_lsc3; + return(OK); + case HSM2_MOD_LSC4: + value->rValue = model->HSM2_lsc4; + return(OK); + case HSM2_MOD_LPGD1: + value->rValue = model->HSM2_lpgd1; + return(OK); +//case HSM2_MOD_LPGD3: +// value->rValue = model->HSM2_lpgd3; +// return(OK); + case HSM2_MOD_LNDEP: + value->rValue = model->HSM2_lndep; + return(OK); + case HSM2_MOD_LNINV: + value->rValue = model->HSM2_lninv; + return(OK); + case HSM2_MOD_LMUECB0: + value->rValue = model->HSM2_lmuecb0; + return(OK); + case HSM2_MOD_LMUECB1: + value->rValue = model->HSM2_lmuecb1; + return(OK); + case HSM2_MOD_LMUEPH1: + value->rValue = model->HSM2_lmueph1; + return(OK); + case HSM2_MOD_LVTMP: + value->rValue = model->HSM2_lvtmp; + return(OK); + case HSM2_MOD_LWVTH0: + value->rValue = model->HSM2_lwvth0; + return(OK); + case HSM2_MOD_LMUESR1: + value->rValue = model->HSM2_lmuesr1; + return(OK); + case HSM2_MOD_LMUETMP: + value->rValue = model->HSM2_lmuetmp; + return(OK); + case HSM2_MOD_LSUB1: + value->rValue = model->HSM2_lsub1; + return(OK); + case HSM2_MOD_LSUB2: + value->rValue = model->HSM2_lsub2; + return(OK); + case HSM2_MOD_LSVDS: + value->rValue = model->HSM2_lsvds; + return(OK); + case HSM2_MOD_LSVBS: + value->rValue = model->HSM2_lsvbs; + return(OK); + case HSM2_MOD_LSVGS: + value->rValue = model->HSM2_lsvgs; + return(OK); + case HSM2_MOD_LNSTI: + value->rValue = model->HSM2_lnsti; + return(OK); + case HSM2_MOD_LWSTI: + value->rValue = model->HSM2_lwsti; + return(OK); + case HSM2_MOD_LSCSTI1: + value->rValue = model->HSM2_lscsti1; + return(OK); + case HSM2_MOD_LSCSTI2: + value->rValue = model->HSM2_lscsti2; + return(OK); + case HSM2_MOD_LVTHSTI: + value->rValue = model->HSM2_lvthsti; + return(OK); + case HSM2_MOD_LMUESTI1: + value->rValue = model->HSM2_lmuesti1; + return(OK); + case HSM2_MOD_LMUESTI2: + value->rValue = model->HSM2_lmuesti2; + return(OK); + case HSM2_MOD_LMUESTI3: + value->rValue = model->HSM2_lmuesti3; + return(OK); + case HSM2_MOD_LNSUBPSTI1: + value->rValue = model->HSM2_lnsubpsti1; + return(OK); + case HSM2_MOD_LNSUBPSTI2: + value->rValue = model->HSM2_lnsubpsti2; + return(OK); + case HSM2_MOD_LNSUBPSTI3: + value->rValue = model->HSM2_lnsubpsti3; + return(OK); + case HSM2_MOD_LCGSO: + value->rValue = model->HSM2_lcgso; + return(OK); + case HSM2_MOD_LCGDO: + value->rValue = model->HSM2_lcgdo; + return(OK); + case HSM2_MOD_LJS0: + value->rValue = model->HSM2_ljs0; + return(OK); + case HSM2_MOD_LJS0SW: + value->rValue = model->HSM2_ljs0sw; + return(OK); + case HSM2_MOD_LNJ: + value->rValue = model->HSM2_lnj; + return(OK); + case HSM2_MOD_LCISBK: + value->rValue = model->HSM2_lcisbk; + return(OK); + case HSM2_MOD_LCLM1: + value->rValue = model->HSM2_lclm1; + return(OK); + case HSM2_MOD_LCLM2: + value->rValue = model->HSM2_lclm2; + return(OK); + case HSM2_MOD_LCLM3: + value->rValue = model->HSM2_lclm3; + return(OK); + case HSM2_MOD_LWFC: + value->rValue = model->HSM2_lwfc; + return(OK); + case HSM2_MOD_LGIDL1: + value->rValue = model->HSM2_lgidl1; + return(OK); + case HSM2_MOD_LGIDL2: + value->rValue = model->HSM2_lgidl2; + return(OK); + case HSM2_MOD_LGLEAK1: + value->rValue = model->HSM2_lgleak1; + return(OK); + case HSM2_MOD_LGLEAK2: + value->rValue = model->HSM2_lgleak2; + return(OK); + case HSM2_MOD_LGLEAK3: + value->rValue = model->HSM2_lgleak3; + return(OK); + case HSM2_MOD_LGLEAK6: + value->rValue = model->HSM2_lgleak6; + return(OK); + case HSM2_MOD_LGLKSD1: + value->rValue = model->HSM2_lglksd1; + return(OK); + case HSM2_MOD_LGLKSD2: + value->rValue = model->HSM2_lglksd2; + return(OK); + case HSM2_MOD_LGLKB1: + value->rValue = model->HSM2_lglkb1; + return(OK); + case HSM2_MOD_LGLKB2: + value->rValue = model->HSM2_lglkb2; + return(OK); + case HSM2_MOD_LNFTRP: + value->rValue = model->HSM2_lnftrp; + return(OK); + case HSM2_MOD_LNFALP: + value->rValue = model->HSM2_lnfalp; + return(OK); + case HSM2_MOD_LVDIFFJ: + value->rValue = model->HSM2_lvdiffj; + return(OK); + case HSM2_MOD_LIBPC1: + value->rValue = model->HSM2_libpc1; + return(OK); + case HSM2_MOD_LIBPC2: + value->rValue = model->HSM2_libpc2; + return(OK); + + /* Width dependence */ + case HSM2_MOD_WVMAX: + value->rValue = model->HSM2_wvmax; + return(OK); + case HSM2_MOD_WBGTMP1: + value->rValue = model->HSM2_wbgtmp1; + return(OK); + case HSM2_MOD_WBGTMP2: + value->rValue = model->HSM2_wbgtmp2; + return(OK); + case HSM2_MOD_WEG0: + value->rValue = model->HSM2_weg0; + return(OK); + case HSM2_MOD_WLOVER: + value->rValue = model->HSM2_wlover; + return(OK); + case HSM2_MOD_WVFBOVER: + value->rValue = model->HSM2_wvfbover; + return(OK); + case HSM2_MOD_WNOVER: + value->rValue = model->HSM2_wnover; + return(OK); + case HSM2_MOD_WWL2: + value->rValue = model->HSM2_wwl2; + return(OK); + case HSM2_MOD_WVFBC: + value->rValue = model->HSM2_wvfbc; + return(OK); + case HSM2_MOD_WNSUBC: + value->rValue = model->HSM2_wnsubc; + return(OK); + case HSM2_MOD_WNSUBP: + value->rValue = model->HSM2_wnsubp; + return(OK); + case HSM2_MOD_WSCP1: + value->rValue = model->HSM2_wscp1; + return(OK); + case HSM2_MOD_WSCP2: + value->rValue = model->HSM2_wscp2; + return(OK); + case HSM2_MOD_WSCP3: + value->rValue = model->HSM2_wscp3; + return(OK); + case HSM2_MOD_WSC1: + value->rValue = model->HSM2_wsc1; + return(OK); + case HSM2_MOD_WSC2: + value->rValue = model->HSM2_wsc2; + return(OK); + case HSM2_MOD_WSC3: + value->rValue = model->HSM2_wsc3; + return(OK); + case HSM2_MOD_WSC4: + value->rValue = model->HSM2_wsc4; + return(OK); + case HSM2_MOD_WPGD1: + value->rValue = model->HSM2_wpgd1; + return(OK); +//case HSM2_MOD_WPGD3: +// value->rValue = model->HSM2_wpgd3; +// return(OK); + case HSM2_MOD_WNDEP: + value->rValue = model->HSM2_wndep; + return(OK); + case HSM2_MOD_WNINV: + value->rValue = model->HSM2_wninv; + return(OK); + case HSM2_MOD_WMUECB0: + value->rValue = model->HSM2_wmuecb0; + return(OK); + case HSM2_MOD_WMUECB1: + value->rValue = model->HSM2_wmuecb1; + return(OK); + case HSM2_MOD_WMUEPH1: + value->rValue = model->HSM2_wmueph1; + return(OK); + case HSM2_MOD_WVTMP: + value->rValue = model->HSM2_wvtmp; + return(OK); + case HSM2_MOD_WWVTH0: + value->rValue = model->HSM2_wwvth0; + return(OK); + case HSM2_MOD_WMUESR1: + value->rValue = model->HSM2_wmuesr1; + return(OK); + case HSM2_MOD_WMUETMP: + value->rValue = model->HSM2_wmuetmp; + return(OK); + case HSM2_MOD_WSUB1: + value->rValue = model->HSM2_wsub1; + return(OK); + case HSM2_MOD_WSUB2: + value->rValue = model->HSM2_wsub2; + return(OK); + case HSM2_MOD_WSVDS: + value->rValue = model->HSM2_wsvds; + return(OK); + case HSM2_MOD_WSVBS: + value->rValue = model->HSM2_wsvbs; + return(OK); + case HSM2_MOD_WSVGS: + value->rValue = model->HSM2_wsvgs; + return(OK); + case HSM2_MOD_WNSTI: + value->rValue = model->HSM2_wnsti; + return(OK); + case HSM2_MOD_WWSTI: + value->rValue = model->HSM2_wwsti; + return(OK); + case HSM2_MOD_WSCSTI1: + value->rValue = model->HSM2_wscsti1; + return(OK); + case HSM2_MOD_WSCSTI2: + value->rValue = model->HSM2_wscsti2; + return(OK); + case HSM2_MOD_WVTHSTI: + value->rValue = model->HSM2_wvthsti; + return(OK); + case HSM2_MOD_WMUESTI1: + value->rValue = model->HSM2_wmuesti1; + return(OK); + case HSM2_MOD_WMUESTI2: + value->rValue = model->HSM2_wmuesti2; + return(OK); + case HSM2_MOD_WMUESTI3: + value->rValue = model->HSM2_wmuesti3; + return(OK); + case HSM2_MOD_WNSUBPSTI1: + value->rValue = model->HSM2_wnsubpsti1; + return(OK); + case HSM2_MOD_WNSUBPSTI2: + value->rValue = model->HSM2_wnsubpsti2; + return(OK); + case HSM2_MOD_WNSUBPSTI3: + value->rValue = model->HSM2_wnsubpsti3; + return(OK); + case HSM2_MOD_WCGSO: + value->rValue = model->HSM2_wcgso; + return(OK); + case HSM2_MOD_WCGDO: + value->rValue = model->HSM2_wcgdo; + return(OK); + case HSM2_MOD_WJS0: + value->rValue = model->HSM2_wjs0; + return(OK); + case HSM2_MOD_WJS0SW: + value->rValue = model->HSM2_wjs0sw; + return(OK); + case HSM2_MOD_WNJ: + value->rValue = model->HSM2_wnj; + return(OK); + case HSM2_MOD_WCISBK: + value->rValue = model->HSM2_wcisbk; + return(OK); + case HSM2_MOD_WCLM1: + value->rValue = model->HSM2_wclm1; + return(OK); + case HSM2_MOD_WCLM2: + value->rValue = model->HSM2_wclm2; + return(OK); + case HSM2_MOD_WCLM3: + value->rValue = model->HSM2_wclm3; + return(OK); + case HSM2_MOD_WWFC: + value->rValue = model->HSM2_wwfc; + return(OK); + case HSM2_MOD_WGIDL1: + value->rValue = model->HSM2_wgidl1; + return(OK); + case HSM2_MOD_WGIDL2: + value->rValue = model->HSM2_wgidl2; + return(OK); + case HSM2_MOD_WGLEAK1: + value->rValue = model->HSM2_wgleak1; + return(OK); + case HSM2_MOD_WGLEAK2: + value->rValue = model->HSM2_wgleak2; + return(OK); + case HSM2_MOD_WGLEAK3: + value->rValue = model->HSM2_wgleak3; + return(OK); + case HSM2_MOD_WGLEAK6: + value->rValue = model->HSM2_wgleak6; + return(OK); + case HSM2_MOD_WGLKSD1: + value->rValue = model->HSM2_wglksd1; + return(OK); + case HSM2_MOD_WGLKSD2: + value->rValue = model->HSM2_wglksd2; + return(OK); + case HSM2_MOD_WGLKB1: + value->rValue = model->HSM2_wglkb1; + return(OK); + case HSM2_MOD_WGLKB2: + value->rValue = model->HSM2_wglkb2; + return(OK); + case HSM2_MOD_WNFTRP: + value->rValue = model->HSM2_wnftrp; + return(OK); + case HSM2_MOD_WNFALP: + value->rValue = model->HSM2_wnfalp; + return(OK); + case HSM2_MOD_WVDIFFJ: + value->rValue = model->HSM2_wvdiffj; + return(OK); + case HSM2_MOD_WIBPC1: + value->rValue = model->HSM2_wibpc1; + return(OK); + case HSM2_MOD_WIBPC2: + value->rValue = model->HSM2_wibpc2; + return(OK); + + /* Cross-term dependence */ + case HSM2_MOD_PVMAX: + value->rValue = model->HSM2_pvmax; + return(OK); + case HSM2_MOD_PBGTMP1: + value->rValue = model->HSM2_pbgtmp1; + return(OK); + case HSM2_MOD_PBGTMP2: + value->rValue = model->HSM2_pbgtmp2; + return(OK); + case HSM2_MOD_PEG0: + value->rValue = model->HSM2_peg0; + return(OK); + case HSM2_MOD_PLOVER: + value->rValue = model->HSM2_plover; + return(OK); + case HSM2_MOD_PVFBOVER: + value->rValue = model->HSM2_pvfbover; + return(OK); + case HSM2_MOD_PNOVER: + value->rValue = model->HSM2_pnover; + return(OK); + case HSM2_MOD_PWL2: + value->rValue = model->HSM2_pwl2; + return(OK); + case HSM2_MOD_PVFBC: + value->rValue = model->HSM2_pvfbc; + return(OK); + case HSM2_MOD_PNSUBC: + value->rValue = model->HSM2_pnsubc; + return(OK); + case HSM2_MOD_PNSUBP: + value->rValue = model->HSM2_pnsubp; + return(OK); + case HSM2_MOD_PSCP1: + value->rValue = model->HSM2_pscp1; + return(OK); + case HSM2_MOD_PSCP2: + value->rValue = model->HSM2_pscp2; + return(OK); + case HSM2_MOD_PSCP3: + value->rValue = model->HSM2_pscp3; + return(OK); + case HSM2_MOD_PSC1: + value->rValue = model->HSM2_psc1; + return(OK); + case HSM2_MOD_PSC2: + value->rValue = model->HSM2_psc2; + return(OK); + case HSM2_MOD_PSC3: + value->rValue = model->HSM2_psc3; + return(OK); + case HSM2_MOD_PSC4: + value->rValue = model->HSM2_psc4; + return(OK); + case HSM2_MOD_PPGD1: + value->rValue = model->HSM2_ppgd1; + return(OK); +//case HSM2_MOD_PPGD3: +// value->rValue = model->HSM2_ppgd3; +// return(OK); + case HSM2_MOD_PNDEP: + value->rValue = model->HSM2_pndep; + return(OK); + case HSM2_MOD_PNINV: + value->rValue = model->HSM2_pninv; + return(OK); + case HSM2_MOD_PMUECB0: + value->rValue = model->HSM2_pmuecb0; + return(OK); + case HSM2_MOD_PMUECB1: + value->rValue = model->HSM2_pmuecb1; + return(OK); + case HSM2_MOD_PMUEPH1: + value->rValue = model->HSM2_pmueph1; + return(OK); + case HSM2_MOD_PVTMP: + value->rValue = model->HSM2_pvtmp; + return(OK); + case HSM2_MOD_PWVTH0: + value->rValue = model->HSM2_pwvth0; + return(OK); + case HSM2_MOD_PMUESR1: + value->rValue = model->HSM2_pmuesr1; + return(OK); + case HSM2_MOD_PMUETMP: + value->rValue = model->HSM2_pmuetmp; + return(OK); + case HSM2_MOD_PSUB1: + value->rValue = model->HSM2_psub1; + return(OK); + case HSM2_MOD_PSUB2: + value->rValue = model->HSM2_psub2; + return(OK); + case HSM2_MOD_PSVDS: + value->rValue = model->HSM2_psvds; + return(OK); + case HSM2_MOD_PSVBS: + value->rValue = model->HSM2_psvbs; + return(OK); + case HSM2_MOD_PSVGS: + value->rValue = model->HSM2_psvgs; + return(OK); + case HSM2_MOD_PNSTI: + value->rValue = model->HSM2_pnsti; + return(OK); + case HSM2_MOD_PWSTI: + value->rValue = model->HSM2_pwsti; + return(OK); + case HSM2_MOD_PSCSTI1: + value->rValue = model->HSM2_pscsti1; + return(OK); + case HSM2_MOD_PSCSTI2: + value->rValue = model->HSM2_pscsti2; + return(OK); + case HSM2_MOD_PVTHSTI: + value->rValue = model->HSM2_pvthsti; + return(OK); + case HSM2_MOD_PMUESTI1: + value->rValue = model->HSM2_pmuesti1; + return(OK); + case HSM2_MOD_PMUESTI2: + value->rValue = model->HSM2_pmuesti2; + return(OK); + case HSM2_MOD_PMUESTI3: + value->rValue = model->HSM2_pmuesti3; + return(OK); + case HSM2_MOD_PNSUBPSTI1: + value->rValue = model->HSM2_pnsubpsti1; + return(OK); + case HSM2_MOD_PNSUBPSTI2: + value->rValue = model->HSM2_pnsubpsti2; + return(OK); + case HSM2_MOD_PNSUBPSTI3: + value->rValue = model->HSM2_pnsubpsti3; + return(OK); + case HSM2_MOD_PCGSO: + value->rValue = model->HSM2_pcgso; + return(OK); + case HSM2_MOD_PCGDO: + value->rValue = model->HSM2_pcgdo; + return(OK); + case HSM2_MOD_PJS0: + value->rValue = model->HSM2_pjs0; + return(OK); + case HSM2_MOD_PJS0SW: + value->rValue = model->HSM2_pjs0sw; + return(OK); + case HSM2_MOD_PNJ: + value->rValue = model->HSM2_pnj; + return(OK); + case HSM2_MOD_PCISBK: + value->rValue = model->HSM2_pcisbk; + return(OK); + case HSM2_MOD_PCLM1: + value->rValue = model->HSM2_pclm1; + return(OK); + case HSM2_MOD_PCLM2: + value->rValue = model->HSM2_pclm2; + return(OK); + case HSM2_MOD_PCLM3: + value->rValue = model->HSM2_pclm3; + return(OK); + case HSM2_MOD_PWFC: + value->rValue = model->HSM2_pwfc; + return(OK); + case HSM2_MOD_PGIDL1: + value->rValue = model->HSM2_pgidl1; + return(OK); + case HSM2_MOD_PGIDL2: + value->rValue = model->HSM2_pgidl2; + return(OK); + case HSM2_MOD_PGLEAK1: + value->rValue = model->HSM2_pgleak1; + return(OK); + case HSM2_MOD_PGLEAK2: + value->rValue = model->HSM2_pgleak2; + return(OK); + case HSM2_MOD_PGLEAK3: + value->rValue = model->HSM2_pgleak3; + return(OK); + case HSM2_MOD_PGLEAK6: + value->rValue = model->HSM2_pgleak6; + return(OK); + case HSM2_MOD_PGLKSD1: + value->rValue = model->HSM2_pglksd1; + return(OK); + case HSM2_MOD_PGLKSD2: + value->rValue = model->HSM2_pglksd2; + return(OK); + case HSM2_MOD_PGLKB1: + value->rValue = model->HSM2_pglkb1; + return(OK); + case HSM2_MOD_PGLKB2: + value->rValue = model->HSM2_pglkb2; + return(OK); + case HSM2_MOD_PNFTRP: + value->rValue = model->HSM2_pnftrp; + return(OK); + case HSM2_MOD_PNFALP: + value->rValue = model->HSM2_pnfalp; + return(OK); + case HSM2_MOD_PVDIFFJ: + value->rValue = model->HSM2_pvdiffj; + return(OK); + case HSM2_MOD_PIBPC1: + value->rValue = model->HSM2_pibpc1; + return(OK); + case HSM2_MOD_PIBPC2: + value->rValue = model->HSM2_pibpc2; + return(OK); + + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + + diff --git a/src/spicelib/devices/hisim2/hsm2mdel.c b/src/spicelib/devices/hisim2/hsm2mdel.c new file mode 100644 index 000000000..4333d1f21 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2mdel.c @@ -0,0 +1,53 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2mdel.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "util.h" +#include "hsm2def.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2mDelete(inModel,modname,kill) + GENmodel **inModel; + IFuid modname; + GENmodel *kill; +{ + HSM2model **model = (HSM2model**)inModel; + HSM2model *modfast = (HSM2model*)kill; + HSM2instance *here; + HSM2instance *prev = NULL; + HSM2model **oldmod; + + oldmod = model; + for ( ;*model ;model = &((*model)->HSM2nextModel) ) { + if ( (*model)->HSM2modName == modname || + (modfast && *model == modfast) ) goto delgot; + oldmod = model; + } + return(E_NOMOD); + + delgot: + *oldmod = (*model)->HSM2nextModel; /* cut deleted device out of list */ + for ( here = (*model)->HSM2instances ; + here ;here = here->HSM2nextInstance ) { + if (prev) FREE(prev); + prev = here; + } + if (prev) FREE(prev); + FREE(*model); + return(OK); +} + diff --git a/src/spicelib/devices/hisim2/hsm2mpar.c b/src/spicelib/devices/hisim2/hsm2mpar.c new file mode 100644 index 000000000..99797fc15 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2mpar.c @@ -0,0 +1,1986 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2mpar.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "util.h" +#include "hsm2def.h" +#include "ifsim.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2mParam(param,value,inMod) + int param; + IFvalue *value; + GENmodel *inMod; +{ + HSM2model *mod = (HSM2model*)inMod; + switch (param) { + case HSM2_MOD_NMOS : + if (value->iValue) { + mod->HSM2_type = 1; + mod->HSM2_type_Given = TRUE; + } + break; + case HSM2_MOD_PMOS : + if (value->iValue) { + mod->HSM2_type = - 1; + mod->HSM2_type_Given = TRUE; + } + break; + case HSM2_MOD_LEVEL: + mod->HSM2_level = value->iValue; + mod->HSM2_level_Given = TRUE; + break; + case HSM2_MOD_INFO: + mod->HSM2_info = value->iValue; + mod->HSM2_info_Given = TRUE; + break; + case HSM2_MOD_NOISE: + mod->HSM2_noise = value->iValue; + mod->HSM2_noise_Given = TRUE; + break; + case HSM2_MOD_VERSION: + mod->HSM2_version = value->iValue; + mod->HSM2_version_Given = TRUE; + break; + case HSM2_MOD_SHOW: + mod->HSM2_show = value->iValue; + mod->HSM2_show_Given = TRUE; + break; + case HSM2_MOD_CORSRD: + mod->HSM2_corsrd = value->iValue; + mod->HSM2_corsrd_Given = TRUE; + break; + case HSM2_MOD_CORG: + mod->HSM2_corg = value->iValue; + mod->HSM2_corg_Given = TRUE; + break; + case HSM2_MOD_COIPRV: + mod->HSM2_coiprv = value->iValue; + mod->HSM2_coiprv_Given = TRUE; + break; + case HSM2_MOD_COPPRV: + mod->HSM2_copprv = value->iValue; + mod->HSM2_copprv_Given = TRUE; + break; + case HSM2_MOD_COADOV: + mod->HSM2_coadov = value->iValue; + mod->HSM2_coadov_Given = TRUE; + break; + case HSM2_MOD_COISUB: + mod->HSM2_coisub = value->iValue; + mod->HSM2_coisub_Given = TRUE; + break; + case HSM2_MOD_COIIGS: + mod->HSM2_coiigs = value->iValue; + mod->HSM2_coiigs_Given = TRUE; + break; + case HSM2_MOD_COGIDL: + mod->HSM2_cogidl = value->iValue; + mod->HSM2_cogidl_Given = TRUE; + break; + case HSM2_MOD_COOVLP: + mod->HSM2_coovlp = value->iValue; + mod->HSM2_coovlp_Given = TRUE; + break; + case HSM2_MOD_COFLICK: + mod->HSM2_coflick = value->iValue; + mod->HSM2_coflick_Given = TRUE; + break; + case HSM2_MOD_COISTI: + mod->HSM2_coisti = value->iValue; + mod->HSM2_coisti_Given = TRUE; + break; + case HSM2_MOD_CONQS: /* HiSIM2 */ + mod->HSM2_conqs = value->iValue; + mod->HSM2_conqs_Given = TRUE; + break; + case HSM2_MOD_CORBNET: + mod->HSM2_corbnet = value->iValue; + mod->HSM2_corbnet_Given = TRUE; + break; + case HSM2_MOD_COTHRML: + mod->HSM2_cothrml = value->iValue; + mod->HSM2_cothrml_Given = TRUE; + break; + case HSM2_MOD_COIGN: + mod->HSM2_coign = value->iValue; + mod->HSM2_coign_Given = TRUE; + break; + case HSM2_MOD_CODFM: + mod->HSM2_codfm = value->iValue; + mod->HSM2_codfm_Given = TRUE; + break; + case HSM2_MOD_CORECIP: + mod->HSM2_corecip = value->iValue; + mod->HSM2_corecip_Given = TRUE; + break; + case HSM2_MOD_COQY: + mod->HSM2_coqy = value->iValue; + mod->HSM2_coqy_Given = TRUE; + break; + case HSM2_MOD_COQOVSM: + mod->HSM2_coqovsm = value->iValue; + mod->HSM2_coqovsm_Given = TRUE; + break; + case HSM2_MOD_VMAX: + mod->HSM2_vmax = value->rValue; + mod->HSM2_vmax_Given = TRUE; + break; + case HSM2_MOD_BGTMP1: + mod->HSM2_bgtmp1 = value->rValue; + mod->HSM2_bgtmp1_Given = TRUE; + break; + case HSM2_MOD_BGTMP2: + mod->HSM2_bgtmp2 = value->rValue; + mod->HSM2_bgtmp2_Given = TRUE; + break; + case HSM2_MOD_EG0: + mod->HSM2_eg0 = value->rValue; + mod->HSM2_eg0_Given = TRUE; + break; + case HSM2_MOD_TOX: + mod->HSM2_tox = value->rValue; + mod->HSM2_tox_Given = TRUE; + break; + case HSM2_MOD_XLD: + mod->HSM2_xld = value->rValue; + mod->HSM2_xld_Given = TRUE; + break; + case HSM2_MOD_LOVER: + mod->HSM2_lover = value->rValue; + mod->HSM2_lover_Given = TRUE; + break; + case HSM2_MOD_DDLTMAX: /* Vdseff */ + mod->HSM2_ddltmax = value->rValue; + mod->HSM2_ddltmax_Given = TRUE; + break; + case HSM2_MOD_DDLTSLP: /* Vdseff */ + mod->HSM2_ddltslp = value->rValue; + mod->HSM2_ddltslp_Given = TRUE; + break; + case HSM2_MOD_DDLTICT: /* Vdseff */ + mod->HSM2_ddltict = value->rValue; + mod->HSM2_ddltict_Given = TRUE; + break; + case HSM2_MOD_VFBOVER: + mod->HSM2_vfbover = value->rValue; + mod->HSM2_vfbover_Given = TRUE; + break; + case HSM2_MOD_NOVER: + mod->HSM2_nover = value->rValue; + mod->HSM2_nover_Given = TRUE; + break; + case HSM2_MOD_XWD: + mod->HSM2_xwd = value->rValue; + mod->HSM2_xwd_Given = TRUE; + break; + case HSM2_MOD_XL: + mod->HSM2_xl = value->rValue; + mod->HSM2_xl_Given = TRUE; + break; + case HSM2_MOD_XW: + mod->HSM2_xw = value->rValue; + mod->HSM2_xw_Given = TRUE; + break; + case HSM2_MOD_SAREF: + mod->HSM2_saref = value->rValue; + mod->HSM2_saref_Given = TRUE; + break; + case HSM2_MOD_SBREF: + mod->HSM2_sbref = value->rValue; + mod->HSM2_sbref_Given = TRUE; + break; + case HSM2_MOD_LL: + mod->HSM2_ll = value->rValue; + mod->HSM2_ll_Given = TRUE; + break; + case HSM2_MOD_LLD: + mod->HSM2_lld = value->rValue; + mod->HSM2_lld_Given = TRUE; + break; + case HSM2_MOD_LLN: + mod->HSM2_lln = value->rValue; + mod->HSM2_lln_Given = TRUE; + break; + case HSM2_MOD_WL: + mod->HSM2_wl = value->rValue; + mod->HSM2_wl_Given = TRUE; + break; + case HSM2_MOD_WL1: + mod->HSM2_wl1 = value->rValue; + mod->HSM2_wl1_Given = TRUE; + break; + case HSM2_MOD_WL1P: + mod->HSM2_wl1p = value->rValue; + mod->HSM2_wl1p_Given = TRUE; + break; + case HSM2_MOD_WL2: + mod->HSM2_wl2 = value->rValue; + mod->HSM2_wl2_Given = TRUE; + break; + case HSM2_MOD_WL2P: + mod->HSM2_wl2p = value->rValue; + mod->HSM2_wl2p_Given = TRUE; + break; + case HSM2_MOD_WLD: + mod->HSM2_wld = value->rValue; + mod->HSM2_wld_Given = TRUE; + break; + case HSM2_MOD_WLN: + mod->HSM2_wln = value->rValue; + mod->HSM2_wln_Given = TRUE; + break; + case HSM2_MOD_XQY: + mod->HSM2_xqy = value->rValue; + mod->HSM2_xqy_Given = TRUE; + break; + case HSM2_MOD_XQY1: + mod->HSM2_xqy1 = value->rValue; + mod->HSM2_xqy1_Given = TRUE; + break; + case HSM2_MOD_XQY2: + mod->HSM2_xqy2 = value->rValue; + mod->HSM2_xqy2_Given = TRUE; + break; + case HSM2_MOD_QYRAT: + mod->HSM2_qyrat = value->rValue; + mod->HSM2_qyrat_Given = TRUE; + break; + case HSM2_MOD_RS: + mod->HSM2_rs = value->rValue; + mod->HSM2_rs_Given = TRUE; + break; + case HSM2_MOD_RD: + mod->HSM2_rd = value->rValue; + mod->HSM2_rd_Given = TRUE; + break; + case HSM2_MOD_RSH: + mod->HSM2_rsh = value->rValue; + mod->HSM2_rsh_Given = TRUE; + break; + case HSM2_MOD_RSHG: + mod->HSM2_rshg = value->rValue; + mod->HSM2_rshg_Given = TRUE; + break; +/* case HSM2_MOD_NGCON: */ +/* mod->HSM2_ngcon = value->rValue; */ +/* mod->HSM2_ngcon_Given = TRUE; */ +/* break; */ +/* case HSM2_MOD_XGW: */ +/* mod->HSM2_xgw = value->rValue; */ +/* mod->HSM2_xgw_Given = TRUE; */ +/* break; */ +/* case HSM2_MOD_XGL: */ +/* mod->HSM2_xgl = value->rValue; */ +/* mod->HSM2_xgl_Given = TRUE; */ +/* break; */ +/* case HSM2_MOD_NF: */ +/* mod->HSM2_nf = value->rValue; */ +/* mod->HSM2_nf_Given = TRUE; */ +/* break; */ + case HSM2_MOD_VFBC: + mod->HSM2_vfbc = value->rValue; + mod->HSM2_vfbc_Given = TRUE; + break; + case HSM2_MOD_VBI: + mod->HSM2_vbi = value->rValue; + mod->HSM2_vbi_Given = TRUE; + break; + case HSM2_MOD_NSUBC: + mod->HSM2_nsubc = value->rValue; + mod->HSM2_nsubc_Given = TRUE; + break; + case HSM2_MOD_PARL2: + mod->HSM2_parl2 = value->rValue; + mod->HSM2_parl2_Given = TRUE; + break; + case HSM2_MOD_LP: + mod->HSM2_lp = value->rValue; + mod->HSM2_lp_Given = TRUE; + break; + case HSM2_MOD_NSUBP: + mod->HSM2_nsubp = value->rValue; + mod->HSM2_nsubp_Given = TRUE; + break; + case HSM2_MOD_NSUBPL: + mod->HSM2_nsubpl = value->rValue; + mod->HSM2_nsubpl_Given = TRUE; + break; + case HSM2_MOD_NSUBPFAC: + mod->HSM2_nsubpfac = value->rValue; + mod->HSM2_nsubpfac_Given = TRUE; + break; + case HSM2_MOD_NSUBPW: + mod->HSM2_nsubpw = value->rValue; + mod->HSM2_nsubpw_Given = TRUE; + break; + case HSM2_MOD_NSUBPWP: + mod->HSM2_nsubpwp = value->rValue; + mod->HSM2_nsubpwp_Given = TRUE; + break; + case HSM2_MOD_SCP1: + mod->HSM2_scp1 = value->rValue; + mod->HSM2_scp1_Given = TRUE; + break; + case HSM2_MOD_SCP2: + mod->HSM2_scp2 = value->rValue; + mod->HSM2_scp2_Given = TRUE; + break; + case HSM2_MOD_SCP3: + mod->HSM2_scp3 = value->rValue; + mod->HSM2_scp3_Given = TRUE; + break; + case HSM2_MOD_SC1: + mod->HSM2_sc1 = value->rValue; + mod->HSM2_sc1_Given = TRUE; + break; + case HSM2_MOD_SC2: + mod->HSM2_sc2 = value->rValue; + mod->HSM2_sc2_Given = TRUE; + break; + case HSM2_MOD_SC3: + mod->HSM2_sc3 = value->rValue; + mod->HSM2_sc3_Given = TRUE; + break; + case HSM2_MOD_SC4: + mod->HSM2_sc4 = value->rValue; + mod->HSM2_sc4_Given = TRUE; + break; + case HSM2_MOD_PGD1: + mod->HSM2_pgd1 = value->rValue; + mod->HSM2_pgd1_Given = TRUE; + break; + case HSM2_MOD_PGD2: + mod->HSM2_pgd2 = value->rValue; + mod->HSM2_pgd2_Given = TRUE; + break; +//case HSM2_MOD_PGD3: +// mod->HSM2_pgd3 = value->rValue; +// mod->HSM2_pgd3_Given = TRUE; +// break; + case HSM2_MOD_PGD4: + mod->HSM2_pgd4 = value->rValue; + mod->HSM2_pgd4_Given = TRUE; + break; + case HSM2_MOD_NDEP: + mod->HSM2_ndep = value->rValue; + mod->HSM2_ndep_Given = TRUE; + break; + case HSM2_MOD_NDEPL: + mod->HSM2_ndepl = value->rValue; + mod->HSM2_ndepl_Given = TRUE; + break; + case HSM2_MOD_NDEPLP: + mod->HSM2_ndeplp = value->rValue; + mod->HSM2_ndeplp_Given = TRUE; + break; + case HSM2_MOD_NDEPW: + mod->HSM2_ndepw = value->rValue; + mod->HSM2_ndepw_Given = TRUE; + break; + case HSM2_MOD_NDEPWP: + mod->HSM2_ndepwp = value->rValue; + mod->HSM2_ndepwp_Given = TRUE; + break; + case HSM2_MOD_NINV: + mod->HSM2_ninv = value->rValue; + mod->HSM2_ninv_Given = TRUE; + break; + case HSM2_MOD_NINVD: + mod->HSM2_ninvd = value->rValue; + mod->HSM2_ninvd_Given = TRUE; + break; + case HSM2_MOD_MUECB0: + mod->HSM2_muecb0 = value->rValue; + mod->HSM2_muecb0_Given = TRUE; + break; + case HSM2_MOD_MUECB1: + mod->HSM2_muecb1 = value->rValue; + mod->HSM2_muecb1_Given = TRUE; + break; + case HSM2_MOD_MUEPH1: + mod->HSM2_mueph1 = value->rValue; + mod->HSM2_mueph1_Given = TRUE; + break; + case HSM2_MOD_MUEPH0: + mod->HSM2_mueph0 = value->rValue; + mod->HSM2_mueph0_Given = TRUE; + break; + case HSM2_MOD_MUEPHW: + mod->HSM2_muephw = value->rValue; + mod->HSM2_muephw_Given = TRUE; + break; + case HSM2_MOD_MUEPWP: + mod->HSM2_muepwp = value->rValue; + mod->HSM2_muepwp_Given = TRUE; + break; + case HSM2_MOD_MUEPWD: + mod->HSM2_muepwd = value->rValue; + mod->HSM2_muepwd_Given = TRUE; + break; + case HSM2_MOD_MUEPHL: + mod->HSM2_muephl = value->rValue; + mod->HSM2_muephl_Given = TRUE; + break; + case HSM2_MOD_MUEPLP: + mod->HSM2_mueplp = value->rValue; + mod->HSM2_mueplp_Given = TRUE; + break; + case HSM2_MOD_MUEPLD: + mod->HSM2_muepld = value->rValue; + mod->HSM2_muepld_Given = TRUE; + break; + case HSM2_MOD_MUEPHS: + mod->HSM2_muephs = value->rValue; + mod->HSM2_muephs_Given = TRUE; + break; + case HSM2_MOD_MUEPSP: + mod->HSM2_muepsp = value->rValue; + mod->HSM2_muepsp_Given = TRUE; + break; + case HSM2_MOD_VTMP: + mod->HSM2_vtmp = value->rValue; + mod->HSM2_vtmp_Given = TRUE; + break; + case HSM2_MOD_WVTH0: + mod->HSM2_wvth0 = value->rValue; + mod->HSM2_wvth0_Given = TRUE; + break; + case HSM2_MOD_MUESR1: + mod->HSM2_muesr1 = value->rValue; + mod->HSM2_muesr1_Given = TRUE; + break; + case HSM2_MOD_MUESR0: + mod->HSM2_muesr0 = value->rValue; + mod->HSM2_muesr0_Given = TRUE; + break; + case HSM2_MOD_MUESRL: + mod->HSM2_muesrl = value->rValue; + mod->HSM2_muesrl_Given = TRUE; + break; + case HSM2_MOD_MUESLP: + mod->HSM2_mueslp = value->rValue; + mod->HSM2_mueslp_Given = TRUE; + break; + case HSM2_MOD_MUESRW: + mod->HSM2_muesrw = value->rValue; + mod->HSM2_muesrw_Given = TRUE; + break; + case HSM2_MOD_MUESWP: + mod->HSM2_mueswp = value->rValue; + mod->HSM2_mueswp_Given = TRUE; + break; + case HSM2_MOD_BB: + mod->HSM2_bb = value->rValue; + mod->HSM2_bb_Given = TRUE; + break; + case HSM2_MOD_SUB1: + mod->HSM2_sub1 = value->rValue; + mod->HSM2_sub1_Given = TRUE; + break; + case HSM2_MOD_SUB2: + mod->HSM2_sub2 = value->rValue; + mod->HSM2_sub2_Given = TRUE; + break; + case HSM2_MOD_SVGS: + mod->HSM2_svgs = value->rValue; + mod->HSM2_svgs_Given = TRUE; + break; + case HSM2_MOD_SVBS: + mod->HSM2_svbs = value->rValue; + mod->HSM2_svbs_Given = TRUE; + break; + case HSM2_MOD_SVBSL: + mod->HSM2_svbsl = value->rValue; + mod->HSM2_svbsl_Given = TRUE; + break; + case HSM2_MOD_SVDS: + mod->HSM2_svds = value->rValue; + mod->HSM2_svds_Given = TRUE; + break; + case HSM2_MOD_SLG: + mod->HSM2_slg = value->rValue; + mod->HSM2_slg_Given = TRUE; + break; + case HSM2_MOD_SUB1L: + mod->HSM2_sub1l = value->rValue; + mod->HSM2_sub1l_Given = TRUE; + break; + case HSM2_MOD_SUB2L: + mod->HSM2_sub2l = value->rValue; + mod->HSM2_sub2l_Given = TRUE; + break; + case HSM2_MOD_SVGSL: + mod->HSM2_svgsl = value->rValue; + mod->HSM2_svgsl_Given = TRUE; + break; + case HSM2_MOD_SVGSLP: + mod->HSM2_svgslp = value->rValue; + mod->HSM2_svgslp_Given = TRUE; + break; + case HSM2_MOD_SVGSWP: + mod->HSM2_svgswp = value->rValue; + mod->HSM2_svgswp_Given = TRUE; + break; + case HSM2_MOD_SVGSW: + mod->HSM2_svgsw = value->rValue; + mod->HSM2_svgsw_Given = TRUE; + break; + case HSM2_MOD_SVBSLP: + mod->HSM2_svbslp = value->rValue; + mod->HSM2_svbslp_Given = TRUE; + break; + case HSM2_MOD_SLGL: + mod->HSM2_slgl = value->rValue; + mod->HSM2_slgl_Given = TRUE; + break; + case HSM2_MOD_SLGLP: + mod->HSM2_slglp = value->rValue; + mod->HSM2_slglp_Given = TRUE; + break; + case HSM2_MOD_SUB1LP: + mod->HSM2_sub1lp = value->rValue; + mod->HSM2_sub1lp_Given = TRUE; + break; + case HSM2_MOD_NSTI: + mod->HSM2_nsti = value->rValue; + mod->HSM2_nsti_Given = TRUE; + break; + case HSM2_MOD_WSTI: + mod->HSM2_wsti = value->rValue; + mod->HSM2_wsti_Given = TRUE; + break; + case HSM2_MOD_WSTIL: + mod->HSM2_wstil = value->rValue; + mod->HSM2_wstil_Given = TRUE; + break; + case HSM2_MOD_WSTILP: + mod->HSM2_wstilp = value->rValue; + mod->HSM2_wstilp_Given = TRUE; + break; + case HSM2_MOD_WSTIW: + mod->HSM2_wstiw = value->rValue; + mod->HSM2_wstiw_Given = TRUE; + break; + case HSM2_MOD_WSTIWP: + mod->HSM2_wstiwp = value->rValue; + mod->HSM2_wstiwp_Given = TRUE; + break; + case HSM2_MOD_SCSTI1: + mod->HSM2_scsti1 = value->rValue; + mod->HSM2_scsti1_Given = TRUE; + break; + case HSM2_MOD_SCSTI2: + mod->HSM2_scsti2 = value->rValue; + mod->HSM2_scsti2_Given = TRUE; + break; + case HSM2_MOD_VTHSTI: + mod->HSM2_vthsti = value->rValue; + mod->HSM2_vthsti_Given = TRUE; + break; + case HSM2_MOD_VDSTI: + mod->HSM2_vdsti = value->rValue; + mod->HSM2_vdsti_Given = TRUE; + break; + case HSM2_MOD_MUESTI1: + mod->HSM2_muesti1 = value->rValue; + mod->HSM2_muesti1_Given = TRUE; + break; + case HSM2_MOD_MUESTI2: + mod->HSM2_muesti2 = value->rValue; + mod->HSM2_muesti2_Given = TRUE; + break; + case HSM2_MOD_MUESTI3: + mod->HSM2_muesti3 = value->rValue; + mod->HSM2_muesti3_Given = TRUE; + break; + case HSM2_MOD_NSUBPSTI1: + mod->HSM2_nsubpsti1 = value->rValue; + mod->HSM2_nsubpsti1_Given = TRUE; + break; + case HSM2_MOD_NSUBPSTI2: + mod->HSM2_nsubpsti2 = value->rValue; + mod->HSM2_nsubpsti2_Given = TRUE; + break; + case HSM2_MOD_NSUBPSTI3: + mod->HSM2_nsubpsti3 = value->rValue; + mod->HSM2_nsubpsti3_Given = TRUE; + break; + case HSM2_MOD_LPEXT: + mod->HSM2_lpext = value->rValue; + mod->HSM2_lpext_Given = TRUE; + break; + case HSM2_MOD_NPEXT: + mod->HSM2_npext = value->rValue; + mod->HSM2_npext_Given = TRUE; + break; + case HSM2_MOD_NPEXTW: + mod->HSM2_npextw = value->rValue; + mod->HSM2_npextw_Given = TRUE; + break; + case HSM2_MOD_NPEXTWP: + mod->HSM2_npextwp = value->rValue; + mod->HSM2_npextwp_Given = TRUE; + break; + case HSM2_MOD_SCP22: + mod->HSM2_scp22 = value->rValue; + mod->HSM2_scp22_Given = TRUE; + break; + case HSM2_MOD_SCP21: + mod->HSM2_scp21 = value->rValue; + mod->HSM2_scp21_Given = TRUE; + break; + case HSM2_MOD_BS1: + mod->HSM2_bs1 = value->rValue; + mod->HSM2_bs1_Given = TRUE; + break; + case HSM2_MOD_BS2: + mod->HSM2_bs2 = value->rValue; + mod->HSM2_bs2_Given = TRUE; + break; + case HSM2_MOD_CGSO: + mod->HSM2_cgso = value->rValue; + mod->HSM2_cgso_Given = TRUE; + break; + case HSM2_MOD_CGDO: + mod->HSM2_cgdo = value->rValue; + mod->HSM2_cgdo_Given = TRUE; + break; + case HSM2_MOD_CGBO: + mod->HSM2_cgbo = value->rValue; + mod->HSM2_cgbo_Given = TRUE; + break; + case HSM2_MOD_TPOLY: + mod->HSM2_tpoly = value->rValue; + mod->HSM2_tpoly_Given = TRUE; + break; + case HSM2_MOD_JS0: + mod->HSM2_js0 = value->rValue; + mod->HSM2_js0_Given = TRUE; + break; + case HSM2_MOD_JS0SW: + mod->HSM2_js0sw = value->rValue; + mod->HSM2_js0sw_Given = TRUE; + break; + case HSM2_MOD_NJ: + mod->HSM2_nj = value->rValue; + mod->HSM2_nj_Given = TRUE; + break; + case HSM2_MOD_NJSW: + mod->HSM2_njsw = value->rValue; + mod->HSM2_njsw_Given = TRUE; + break; + case HSM2_MOD_XTI: + mod->HSM2_xti = value->rValue; + mod->HSM2_xti_Given = TRUE; + break; + case HSM2_MOD_CJ: + mod->HSM2_cj = value->rValue; + mod->HSM2_cj_Given = TRUE; + break; + case HSM2_MOD_CJSW: + mod->HSM2_cjsw = value->rValue; + mod->HSM2_cjsw_Given = TRUE; + break; + case HSM2_MOD_CJSWG: + mod->HSM2_cjswg = value->rValue; + mod->HSM2_cjswg_Given = TRUE; + break; + case HSM2_MOD_MJ: + mod->HSM2_mj = value->rValue; + mod->HSM2_mj_Given = TRUE; + break; + case HSM2_MOD_MJSW: + mod->HSM2_mjsw = value->rValue; + mod->HSM2_mjsw_Given = TRUE; + break; + case HSM2_MOD_MJSWG: + mod->HSM2_mjswg = value->rValue; + mod->HSM2_mjswg_Given = TRUE; + break; + case HSM2_MOD_PB: + mod->HSM2_pb = value->rValue; + mod->HSM2_pb_Given = TRUE; + break; + case HSM2_MOD_PBSW: + mod->HSM2_pbsw = value->rValue; + mod->HSM2_pbsw_Given = TRUE; + break; + case HSM2_MOD_PBSWG: + mod->HSM2_pbswg = value->rValue; + mod->HSM2_pbswg_Given = TRUE; + break; + + case HSM2_MOD_TCJBD: + mod->HSM2_tcjbd = value->rValue; + mod->HSM2_tcjbd_Given = TRUE; + break; + case HSM2_MOD_TCJBS: + mod->HSM2_tcjbs = value->rValue; + mod->HSM2_tcjbs_Given = TRUE; + break; + case HSM2_MOD_TCJBDSW: + mod->HSM2_tcjbdsw = value->rValue; + mod->HSM2_tcjbdsw_Given = TRUE; + break; + case HSM2_MOD_TCJBSSW: + mod->HSM2_tcjbssw = value->rValue; + mod->HSM2_tcjbssw_Given = TRUE; + break; + case HSM2_MOD_TCJBDSWG: + mod->HSM2_tcjbdswg = value->rValue; + mod->HSM2_tcjbdswg_Given = TRUE; + break; + case HSM2_MOD_TCJBSSWG: + mod->HSM2_tcjbsswg = value->rValue; + mod->HSM2_tcjbsswg_Given = TRUE; + break; + + case HSM2_MOD_XTI2: + mod->HSM2_xti2 = value->rValue; + mod->HSM2_xti2_Given = TRUE; + break; + case HSM2_MOD_CISB: + mod->HSM2_cisb = value->rValue; + mod->HSM2_cisb_Given = TRUE; + break; + case HSM2_MOD_CVB: + mod->HSM2_cvb = value->rValue; + mod->HSM2_cvb_Given = TRUE; + break; + case HSM2_MOD_CTEMP: + mod->HSM2_ctemp = value->rValue; + mod->HSM2_ctemp_Given = TRUE; + break; + case HSM2_MOD_CISBK: + mod->HSM2_cisbk = value->rValue; + mod->HSM2_cisbk_Given = TRUE; + break; + case HSM2_MOD_CVBK: + mod->HSM2_cvbk = value->rValue; + mod->HSM2_cvbk_Given = TRUE; + break; + case HSM2_MOD_DIVX: + mod->HSM2_divx = value->rValue; + mod->HSM2_divx_Given = TRUE; + break; + case HSM2_MOD_CLM1: + mod->HSM2_clm1 = value->rValue; + mod->HSM2_clm1_Given = TRUE; + break; + case HSM2_MOD_CLM2: + mod->HSM2_clm2 = value->rValue; + mod->HSM2_clm2_Given = TRUE; + break; + case HSM2_MOD_CLM3: + mod->HSM2_clm3 = value->rValue; + mod->HSM2_clm3_Given = TRUE; + break; + case HSM2_MOD_CLM5: + mod->HSM2_clm5 = value->rValue; + mod->HSM2_clm5_Given = TRUE; + break; + case HSM2_MOD_CLM6: + mod->HSM2_clm6 = value->rValue; + mod->HSM2_clm6_Given = TRUE; + break; + case HSM2_MOD_MUETMP: + mod->HSM2_muetmp = value->rValue; + mod->HSM2_muetmp_Given = TRUE; + break; + case HSM2_MOD_VOVER: + mod->HSM2_vover = value->rValue; + mod->HSM2_vover_Given = TRUE; + break; + case HSM2_MOD_VOVERP: + mod->HSM2_voverp = value->rValue; + mod->HSM2_voverp_Given = TRUE; + break; + case HSM2_MOD_VOVERS: + mod->HSM2_vovers = value->rValue; + mod->HSM2_vovers_Given = TRUE; + break; + case HSM2_MOD_VOVERSP: + mod->HSM2_voversp = value->rValue; + mod->HSM2_voversp_Given = TRUE; + break; + case HSM2_MOD_WFC: + mod->HSM2_wfc = value->rValue; + mod->HSM2_wfc_Given = TRUE; + break; + case HSM2_MOD_NSUBCW: + mod->HSM2_nsubcw = value->rValue; + mod->HSM2_nsubcw_Given = TRUE; + break; + case HSM2_MOD_NSUBCWP: + mod->HSM2_nsubcwp = value->rValue; + mod->HSM2_nsubcwp_Given = TRUE; + break; + case HSM2_MOD_NSUBCMAX: + mod->HSM2_nsubcmax = value->rValue; + mod->HSM2_nsubcmax_Given = TRUE; + break; + case HSM2_MOD_QME1: + mod->HSM2_qme1 = value->rValue; + mod->HSM2_qme1_Given = TRUE; + break; + case HSM2_MOD_QME2: + mod->HSM2_qme2 = value->rValue; + mod->HSM2_qme2_Given = TRUE; + break; + case HSM2_MOD_QME3: + mod->HSM2_qme3 = value->rValue; + mod->HSM2_qme3_Given = TRUE; + break; + case HSM2_MOD_GIDL1: + mod->HSM2_gidl1 = value->rValue; + mod->HSM2_gidl1_Given = TRUE; + break; + case HSM2_MOD_GIDL2: + mod->HSM2_gidl2 = value->rValue; + mod->HSM2_gidl2_Given = TRUE; + break; + case HSM2_MOD_GIDL3: + mod->HSM2_gidl3 = value->rValue; + mod->HSM2_gidl3_Given = TRUE; + break; + case HSM2_MOD_GIDL4: + mod->HSM2_gidl4 = value->rValue; + mod->HSM2_gidl4_Given = TRUE; + break; + case HSM2_MOD_GIDL5: + mod->HSM2_gidl5 = value->rValue; + mod->HSM2_gidl5_Given = TRUE; + break; + case HSM2_MOD_GLEAK1: + mod->HSM2_gleak1 = value->rValue; + mod->HSM2_gleak1_Given = TRUE; + break; + case HSM2_MOD_GLEAK2: + mod->HSM2_gleak2 = value->rValue; + mod->HSM2_gleak2_Given = TRUE; + break; + case HSM2_MOD_GLEAK3: + mod->HSM2_gleak3 = value->rValue; + mod->HSM2_gleak3_Given = TRUE; + break; + case HSM2_MOD_GLEAK4: + mod->HSM2_gleak4 = value->rValue; + mod->HSM2_gleak4_Given = TRUE; + break; + case HSM2_MOD_GLEAK5: + mod->HSM2_gleak5 = value->rValue; + mod->HSM2_gleak5_Given = TRUE; + break; + case HSM2_MOD_GLEAK6: + mod->HSM2_gleak6 = value->rValue; + mod->HSM2_gleak6_Given = TRUE; + break; + case HSM2_MOD_GLEAK7: + mod->HSM2_gleak7 = value->rValue; + mod->HSM2_gleak7_Given = TRUE; + break; + case HSM2_MOD_GLKSD1: + mod->HSM2_glksd1 = value->rValue; + mod->HSM2_glksd1_Given = TRUE; + break; + case HSM2_MOD_GLKSD2: + mod->HSM2_glksd2 = value->rValue; + mod->HSM2_glksd2_Given = TRUE; + break; + case HSM2_MOD_GLKSD3: + mod->HSM2_glksd3 = value->rValue; + mod->HSM2_glksd3_Given = TRUE; + break; + case HSM2_MOD_GLKB1: + mod->HSM2_glkb1 = value->rValue; + mod->HSM2_glkb1_Given = TRUE; + break; + case HSM2_MOD_GLKB2: + mod->HSM2_glkb2 = value->rValue; + mod->HSM2_glkb2_Given = TRUE; + break; + case HSM2_MOD_GLKB3: + mod->HSM2_glkb3 = value->rValue; + mod->HSM2_glkb3_Given = TRUE; + break; + case HSM2_MOD_EGIG: + mod->HSM2_egig = value->rValue; + mod->HSM2_egig_Given = TRUE; + break; + case HSM2_MOD_IGTEMP2: + mod->HSM2_igtemp2 = value->rValue; + mod->HSM2_igtemp2_Given = TRUE; + break; + case HSM2_MOD_IGTEMP3: + mod->HSM2_igtemp3 = value->rValue; + mod->HSM2_igtemp3_Given = TRUE; + break; + case HSM2_MOD_VZADD0: + mod->HSM2_vzadd0 = value->rValue; + mod->HSM2_vzadd0_Given = TRUE; + break; + case HSM2_MOD_PZADD0: + mod->HSM2_pzadd0 = value->rValue; + mod->HSM2_pzadd0_Given = TRUE; + break; + case HSM2_MOD_NFTRP: + mod->HSM2_nftrp = value->rValue; + mod->HSM2_nftrp_Given = TRUE; + break; + case HSM2_MOD_NFALP: + mod->HSM2_nfalp = value->rValue; + mod->HSM2_nfalp_Given = TRUE; + break; + case HSM2_MOD_CIT: + mod->HSM2_cit = value->rValue; + mod->HSM2_cit_Given = TRUE; + break; + case HSM2_MOD_FALPH: + mod->HSM2_falph = value->rValue; + mod->HSM2_falph_Given = TRUE; + break; + case HSM2_MOD_KAPPA: + mod->HSM2_kappa = value->rValue; + mod->HSM2_kappa_Given = TRUE; + break; + case HSM2_MOD_VDIFFJ: + mod->HSM2_vdiffj = value->rValue; + mod->HSM2_vdiffj_Given = TRUE; + break; + case HSM2_MOD_DLY1: + mod->HSM2_dly1 = value->rValue; + mod->HSM2_dly1_Given = TRUE; + break; + case HSM2_MOD_DLY2: + mod->HSM2_dly2 = value->rValue; + mod->HSM2_dly2_Given = TRUE; + break; + case HSM2_MOD_DLY3: + mod->HSM2_dly3 = value->rValue; + mod->HSM2_dly3_Given = TRUE; + break; + case HSM2_MOD_TNOM: + mod->HSM2_tnom = value->rValue; + mod->HSM2_tnom_Given = TRUE; + break; + case HSM2_MOD_OVSLP: + mod->HSM2_ovslp = value->rValue; + mod->HSM2_ovslp_Given = TRUE; + break; + case HSM2_MOD_OVMAG: + mod->HSM2_ovmag = value->rValue; + mod->HSM2_ovmag_Given = TRUE; + break; + case HSM2_MOD_GBMIN: + mod->HSM2_gbmin = value->rValue; + mod->HSM2_gbmin_Given = TRUE; + break; + case HSM2_MOD_RBPB: + mod->HSM2_rbpb = value->rValue; + mod->HSM2_rbpb_Given = TRUE; + break; + case HSM2_MOD_RBPD: + mod->HSM2_rbpd = value->rValue; + mod->HSM2_rbpd_Given = TRUE; + break; + case HSM2_MOD_RBPS: + mod->HSM2_rbps = value->rValue; + mod->HSM2_rbps_Given = TRUE; + break; + case HSM2_MOD_RBDB: + mod->HSM2_rbdb = value->rValue; + mod->HSM2_rbdb_Given = TRUE; + break; + case HSM2_MOD_RBSB: + mod->HSM2_rbsb = value->rValue; + mod->HSM2_rbsb_Given = TRUE; + break; + case HSM2_MOD_IBPC1: + mod->HSM2_ibpc1 = value->rValue; + mod->HSM2_ibpc1_Given = TRUE; + break; + case HSM2_MOD_IBPC2: + mod->HSM2_ibpc2 = value->rValue; + mod->HSM2_ibpc2_Given = TRUE; + break; + case HSM2_MOD_MPHDFM: + mod->HSM2_mphdfm = value->rValue; + mod->HSM2_mphdfm_Given = TRUE; + break; + + case HSM2_MOD_PTL: + mod->HSM2_ptl = value->rValue; + mod->HSM2_ptl_Given = TRUE; + break; + case HSM2_MOD_PTP: + mod->HSM2_ptp = value->rValue; + mod->HSM2_ptp_Given = TRUE; + break; + case HSM2_MOD_PT2: + mod->HSM2_pt2 = value->rValue; + mod->HSM2_pt2_Given = TRUE; + break; + case HSM2_MOD_PTLP: + mod->HSM2_ptlp = value->rValue; + mod->HSM2_ptlp_Given = TRUE; + break; + case HSM2_MOD_GDL: + mod->HSM2_gdl = value->rValue; + mod->HSM2_gdl_Given = TRUE; + break; + case HSM2_MOD_GDLP: + mod->HSM2_gdlp = value->rValue; + mod->HSM2_gdlp_Given = TRUE; + break; + + case HSM2_MOD_GDLD: + mod->HSM2_gdld = value->rValue; + mod->HSM2_gdld_Given = TRUE; + break; + case HSM2_MOD_PT4: + mod->HSM2_pt4 = value->rValue; + mod->HSM2_pt4_Given = TRUE; + break; + case HSM2_MOD_PT4P: + mod->HSM2_pt4p = value->rValue; + mod->HSM2_pt4p_Given = TRUE; + break; + case HSM2_MOD_MUEPHL2: + mod->HSM2_muephl2 = value->rValue; + mod->HSM2_muephl2_Given = TRUE; + break; + case HSM2_MOD_MUEPLP2: + mod->HSM2_mueplp2 = value->rValue; + mod->HSM2_mueplp2_Given = TRUE; + break; + case HSM2_MOD_NSUBCW2: + mod->HSM2_nsubcw2 = value->rValue; + mod->HSM2_nsubcw2_Given = TRUE; + break; + case HSM2_MOD_NSUBCWP2: + mod->HSM2_nsubcwp2 = value->rValue; + mod->HSM2_nsubcwp2_Given = TRUE; + break; + case HSM2_MOD_MUEPHW2: + mod->HSM2_muephw2 = value->rValue; + mod->HSM2_muephw2_Given = TRUE; + break; + case HSM2_MOD_MUEPWP2: + mod->HSM2_muepwp2 = value->rValue; + mod->HSM2_muepwp2_Given = TRUE; + break; + case HSM2_MOD_VGSMIN: + mod->HSM2_Vgsmin = value->rValue; + mod->HSM2_Vgsmin_Given = TRUE; + break; + case HSM2_MOD_SC3VBS: + mod->HSM2_sc3Vbs = value->rValue; + mod->HSM2_sc3Vbs_Given = TRUE; + break; + case HSM2_MOD_BYPTOL: + mod->HSM2_byptol = value->rValue; + mod->HSM2_byptol_Given = TRUE; + break; + case HSM2_MOD_MUECB0LP: + mod->HSM2_muecb0lp = value->rValue; + mod->HSM2_muecb0lp_Given = TRUE; + break; + case HSM2_MOD_MUECB1LP: + mod->HSM2_muecb1lp = value->rValue; + mod->HSM2_muecb1lp_Given = TRUE; + break; + + + /* binning parameters */ + case HSM2_MOD_LMIN: + mod->HSM2_lmin = value->rValue; + mod->HSM2_lmin_Given = TRUE; + break; + case HSM2_MOD_LMAX: + mod->HSM2_lmax = value->rValue; + mod->HSM2_lmax_Given = TRUE; + break; + case HSM2_MOD_WMIN: + mod->HSM2_wmin = value->rValue; + mod->HSM2_wmin_Given = TRUE; + break; + case HSM2_MOD_WMAX: + mod->HSM2_wmax = value->rValue; + mod->HSM2_wmax_Given = TRUE; + break; + case HSM2_MOD_LBINN: + mod->HSM2_lbinn = value->rValue; + mod->HSM2_lbinn_Given = TRUE; + break; + case HSM2_MOD_WBINN: + mod->HSM2_wbinn = value->rValue; + mod->HSM2_wbinn_Given = TRUE; + break; + + /* Length dependence */ + case HSM2_MOD_LVMAX: + mod->HSM2_lvmax = value->rValue; + mod->HSM2_lvmax_Given = TRUE; + break; + case HSM2_MOD_LBGTMP1: + mod->HSM2_lbgtmp1 = value->rValue; + mod->HSM2_lbgtmp1_Given = TRUE; + break; + case HSM2_MOD_LBGTMP2: + mod->HSM2_lbgtmp2 = value->rValue; + mod->HSM2_lbgtmp2_Given = TRUE; + break; + case HSM2_MOD_LEG0: + mod->HSM2_leg0 = value->rValue; + mod->HSM2_leg0_Given = TRUE; + break; + case HSM2_MOD_LLOVER: + mod->HSM2_llover = value->rValue; + mod->HSM2_llover_Given = TRUE; + break; + case HSM2_MOD_LVFBOVER: + mod->HSM2_lvfbover = value->rValue; + mod->HSM2_lvfbover_Given = TRUE; + break; + case HSM2_MOD_LNOVER: + mod->HSM2_lnover = value->rValue; + mod->HSM2_lnover_Given = TRUE; + break; + case HSM2_MOD_LWL2: + mod->HSM2_lwl2 = value->rValue; + mod->HSM2_lwl2_Given = TRUE; + break; + case HSM2_MOD_LVFBC: + mod->HSM2_lvfbc = value->rValue; + mod->HSM2_lvfbc_Given = TRUE; + break; + case HSM2_MOD_LNSUBC: + mod->HSM2_lnsubc = value->rValue; + mod->HSM2_lnsubc_Given = TRUE; + break; + case HSM2_MOD_LNSUBP: + mod->HSM2_lnsubp = value->rValue; + mod->HSM2_lnsubp_Given = TRUE; + break; + case HSM2_MOD_LSCP1: + mod->HSM2_lscp1 = value->rValue; + mod->HSM2_lscp1_Given = TRUE; + break; + case HSM2_MOD_LSCP2: + mod->HSM2_lscp2 = value->rValue; + mod->HSM2_lscp2_Given = TRUE; + break; + case HSM2_MOD_LSCP3: + mod->HSM2_lscp3 = value->rValue; + mod->HSM2_lscp3_Given = TRUE; + break; + case HSM2_MOD_LSC1: + mod->HSM2_lsc1 = value->rValue; + mod->HSM2_lsc1_Given = TRUE; + break; + case HSM2_MOD_LSC2: + mod->HSM2_lsc2 = value->rValue; + mod->HSM2_lsc2_Given = TRUE; + break; + case HSM2_MOD_LSC3: + mod->HSM2_lsc3 = value->rValue; + mod->HSM2_lsc3_Given = TRUE; + break; + case HSM2_MOD_LSC4: + mod->HSM2_lsc4 = value->rValue; + mod->HSM2_lsc4_Given = TRUE; + break; + case HSM2_MOD_LPGD1: + mod->HSM2_lpgd1 = value->rValue; + mod->HSM2_lpgd1_Given = TRUE; + break; +//case HSM2_MOD_LPGD3: +// mod->HSM2_lpgd3 = value->rValue; +// mod->HSM2_lpgd3_Given = TRUE; +// break; + case HSM2_MOD_LNDEP: + mod->HSM2_lndep = value->rValue; + mod->HSM2_lndep_Given = TRUE; + break; + case HSM2_MOD_LNINV: + mod->HSM2_lninv = value->rValue; + mod->HSM2_lninv_Given = TRUE; + break; + case HSM2_MOD_LMUECB0: + mod->HSM2_lmuecb0 = value->rValue; + mod->HSM2_lmuecb0_Given = TRUE; + break; + case HSM2_MOD_LMUECB1: + mod->HSM2_lmuecb1 = value->rValue; + mod->HSM2_lmuecb1_Given = TRUE; + break; + case HSM2_MOD_LMUEPH1: + mod->HSM2_lmueph1 = value->rValue; + mod->HSM2_lmueph1_Given = TRUE; + break; + case HSM2_MOD_LVTMP: + mod->HSM2_lvtmp = value->rValue; + mod->HSM2_lvtmp_Given = TRUE; + break; + case HSM2_MOD_LWVTH0: + mod->HSM2_lwvth0 = value->rValue; + mod->HSM2_lwvth0_Given = TRUE; + break; + case HSM2_MOD_LMUESR1: + mod->HSM2_lmuesr1 = value->rValue; + mod->HSM2_lmuesr1_Given = TRUE; + break; + case HSM2_MOD_LMUETMP: + mod->HSM2_lmuetmp = value->rValue; + mod->HSM2_lmuetmp_Given = TRUE; + break; + case HSM2_MOD_LSUB1: + mod->HSM2_lsub1 = value->rValue; + mod->HSM2_lsub1_Given = TRUE; + break; + case HSM2_MOD_LSUB2: + mod->HSM2_lsub2 = value->rValue; + mod->HSM2_lsub2_Given = TRUE; + break; + case HSM2_MOD_LSVDS: + mod->HSM2_lsvds = value->rValue; + mod->HSM2_lsvds_Given = TRUE; + break; + case HSM2_MOD_LSVBS: + mod->HSM2_lsvbs = value->rValue; + mod->HSM2_lsvbs_Given = TRUE; + break; + case HSM2_MOD_LSVGS: + mod->HSM2_lsvgs = value->rValue; + mod->HSM2_lsvgs_Given = TRUE; + break; + case HSM2_MOD_LNSTI: + mod->HSM2_lnsti = value->rValue; + mod->HSM2_lnsti_Given = TRUE; + break; + case HSM2_MOD_LWSTI: + mod->HSM2_lwsti = value->rValue; + mod->HSM2_lwsti_Given = TRUE; + break; + case HSM2_MOD_LSCSTI1: + mod->HSM2_lscsti1 = value->rValue; + mod->HSM2_lscsti1_Given = TRUE; + break; + case HSM2_MOD_LSCSTI2: + mod->HSM2_lscsti2 = value->rValue; + mod->HSM2_lscsti2_Given = TRUE; + break; + case HSM2_MOD_LVTHSTI: + mod->HSM2_lvthsti = value->rValue; + mod->HSM2_lvthsti_Given = TRUE; + break; + case HSM2_MOD_LMUESTI1: + mod->HSM2_lmuesti1 = value->rValue; + mod->HSM2_lmuesti1_Given = TRUE; + break; + case HSM2_MOD_LMUESTI2: + mod->HSM2_lmuesti2 = value->rValue; + mod->HSM2_lmuesti2_Given = TRUE; + break; + case HSM2_MOD_LMUESTI3: + mod->HSM2_lmuesti3 = value->rValue; + mod->HSM2_lmuesti3_Given = TRUE; + break; + case HSM2_MOD_LNSUBPSTI1: + mod->HSM2_lnsubpsti1 = value->rValue; + mod->HSM2_lnsubpsti1_Given = TRUE; + break; + case HSM2_MOD_LNSUBPSTI2: + mod->HSM2_lnsubpsti2 = value->rValue; + mod->HSM2_lnsubpsti2_Given = TRUE; + break; + case HSM2_MOD_LNSUBPSTI3: + mod->HSM2_lnsubpsti3 = value->rValue; + mod->HSM2_lnsubpsti3_Given = TRUE; + break; + case HSM2_MOD_LCGSO: + mod->HSM2_lcgso = value->rValue; + mod->HSM2_lcgso_Given = TRUE; + break; + case HSM2_MOD_LCGDO: + mod->HSM2_lcgdo = value->rValue; + mod->HSM2_lcgdo_Given = TRUE; + break; + case HSM2_MOD_LJS0: + mod->HSM2_ljs0 = value->rValue; + mod->HSM2_ljs0_Given = TRUE; + break; + case HSM2_MOD_LJS0SW: + mod->HSM2_ljs0sw = value->rValue; + mod->HSM2_ljs0sw_Given = TRUE; + break; + case HSM2_MOD_LNJ: + mod->HSM2_lnj = value->rValue; + mod->HSM2_lnj_Given = TRUE; + break; + case HSM2_MOD_LCISBK: + mod->HSM2_lcisbk = value->rValue; + mod->HSM2_lcisbk_Given = TRUE; + break; + case HSM2_MOD_LCLM1: + mod->HSM2_lclm1 = value->rValue; + mod->HSM2_lclm1_Given = TRUE; + break; + case HSM2_MOD_LCLM2: + mod->HSM2_lclm2 = value->rValue; + mod->HSM2_lclm2_Given = TRUE; + break; + case HSM2_MOD_LCLM3: + mod->HSM2_lclm3 = value->rValue; + mod->HSM2_lclm3_Given = TRUE; + break; + case HSM2_MOD_LWFC: + mod->HSM2_lwfc = value->rValue; + mod->HSM2_lwfc_Given = TRUE; + break; + case HSM2_MOD_LGIDL1: + mod->HSM2_lgidl1 = value->rValue; + mod->HSM2_lgidl1_Given = TRUE; + break; + case HSM2_MOD_LGIDL2: + mod->HSM2_lgidl2 = value->rValue; + mod->HSM2_lgidl2_Given = TRUE; + break; + case HSM2_MOD_LGLEAK1: + mod->HSM2_lgleak1 = value->rValue; + mod->HSM2_lgleak1_Given = TRUE; + break; + case HSM2_MOD_LGLEAK2: + mod->HSM2_lgleak2 = value->rValue; + mod->HSM2_lgleak2_Given = TRUE; + break; + case HSM2_MOD_LGLEAK3: + mod->HSM2_lgleak3 = value->rValue; + mod->HSM2_lgleak3_Given = TRUE; + break; + case HSM2_MOD_LGLEAK6: + mod->HSM2_lgleak6 = value->rValue; + mod->HSM2_lgleak6_Given = TRUE; + break; + case HSM2_MOD_LGLKSD1: + mod->HSM2_lglksd1 = value->rValue; + mod->HSM2_lglksd1_Given = TRUE; + break; + case HSM2_MOD_LGLKSD2: + mod->HSM2_lglksd2 = value->rValue; + mod->HSM2_lglksd2_Given = TRUE; + break; + case HSM2_MOD_LGLKB1: + mod->HSM2_lglkb1 = value->rValue; + mod->HSM2_lglkb1_Given = TRUE; + break; + case HSM2_MOD_LGLKB2: + mod->HSM2_lglkb2 = value->rValue; + mod->HSM2_lglkb2_Given = TRUE; + break; + case HSM2_MOD_LNFTRP: + mod->HSM2_lnftrp = value->rValue; + mod->HSM2_lnftrp_Given = TRUE; + break; + case HSM2_MOD_LNFALP: + mod->HSM2_lnfalp = value->rValue; + mod->HSM2_lnfalp_Given = TRUE; + break; + case HSM2_MOD_LVDIFFJ: + mod->HSM2_lvdiffj = value->rValue; + mod->HSM2_lvdiffj_Given = TRUE; + break; + case HSM2_MOD_LIBPC1: + mod->HSM2_libpc1 = value->rValue; + mod->HSM2_libpc1_Given = TRUE; + break; + case HSM2_MOD_LIBPC2: + mod->HSM2_libpc2 = value->rValue; + mod->HSM2_libpc2_Given = TRUE; + break; + + /* Width dependence */ + case HSM2_MOD_WVMAX: + mod->HSM2_wvmax = value->rValue; + mod->HSM2_wvmax_Given = TRUE; + break; + case HSM2_MOD_WBGTMP1: + mod->HSM2_wbgtmp1 = value->rValue; + mod->HSM2_wbgtmp1_Given = TRUE; + break; + case HSM2_MOD_WBGTMP2: + mod->HSM2_wbgtmp2 = value->rValue; + mod->HSM2_wbgtmp2_Given = TRUE; + break; + case HSM2_MOD_WEG0: + mod->HSM2_weg0 = value->rValue; + mod->HSM2_weg0_Given = TRUE; + break; + case HSM2_MOD_WLOVER: + mod->HSM2_wlover = value->rValue; + mod->HSM2_wlover_Given = TRUE; + break; + case HSM2_MOD_WVFBOVER: + mod->HSM2_wvfbover = value->rValue; + mod->HSM2_wvfbover_Given = TRUE; + break; + case HSM2_MOD_WNOVER: + mod->HSM2_wnover = value->rValue; + mod->HSM2_wnover_Given = TRUE; + break; + case HSM2_MOD_WWL2: + mod->HSM2_wwl2 = value->rValue; + mod->HSM2_wwl2_Given = TRUE; + break; + case HSM2_MOD_WVFBC: + mod->HSM2_wvfbc = value->rValue; + mod->HSM2_wvfbc_Given = TRUE; + break; + case HSM2_MOD_WNSUBC: + mod->HSM2_wnsubc = value->rValue; + mod->HSM2_wnsubc_Given = TRUE; + break; + case HSM2_MOD_WNSUBP: + mod->HSM2_wnsubp = value->rValue; + mod->HSM2_wnsubp_Given = TRUE; + break; + case HSM2_MOD_WSCP1: + mod->HSM2_wscp1 = value->rValue; + mod->HSM2_wscp1_Given = TRUE; + break; + case HSM2_MOD_WSCP2: + mod->HSM2_wscp2 = value->rValue; + mod->HSM2_wscp2_Given = TRUE; + break; + case HSM2_MOD_WSCP3: + mod->HSM2_wscp3 = value->rValue; + mod->HSM2_wscp3_Given = TRUE; + break; + case HSM2_MOD_WSC1: + mod->HSM2_wsc1 = value->rValue; + mod->HSM2_wsc1_Given = TRUE; + break; + case HSM2_MOD_WSC2: + mod->HSM2_wsc2 = value->rValue; + mod->HSM2_wsc2_Given = TRUE; + break; + case HSM2_MOD_WSC3: + mod->HSM2_wsc3 = value->rValue; + mod->HSM2_wsc3_Given = TRUE; + break; + case HSM2_MOD_WSC4: + mod->HSM2_wsc4 = value->rValue; + mod->HSM2_wsc4_Given = TRUE; + break; + case HSM2_MOD_WPGD1: + mod->HSM2_wpgd1 = value->rValue; + mod->HSM2_wpgd1_Given = TRUE; + break; +//case HSM2_MOD_WPGD3: +// mod->HSM2_wpgd3 = value->rValue; +// mod->HSM2_wpgd3_Given = TRUE; +// break; + case HSM2_MOD_WNDEP: + mod->HSM2_wndep = value->rValue; + mod->HSM2_wndep_Given = TRUE; + break; + case HSM2_MOD_WNINV: + mod->HSM2_wninv = value->rValue; + mod->HSM2_wninv_Given = TRUE; + break; + case HSM2_MOD_WMUECB0: + mod->HSM2_wmuecb0 = value->rValue; + mod->HSM2_wmuecb0_Given = TRUE; + break; + case HSM2_MOD_WMUECB1: + mod->HSM2_wmuecb1 = value->rValue; + mod->HSM2_wmuecb1_Given = TRUE; + break; + case HSM2_MOD_WMUEPH1: + mod->HSM2_wmueph1 = value->rValue; + mod->HSM2_wmueph1_Given = TRUE; + break; + case HSM2_MOD_WVTMP: + mod->HSM2_wvtmp = value->rValue; + mod->HSM2_wvtmp_Given = TRUE; + break; + case HSM2_MOD_WWVTH0: + mod->HSM2_wwvth0 = value->rValue; + mod->HSM2_wwvth0_Given = TRUE; + break; + case HSM2_MOD_WMUESR1: + mod->HSM2_wmuesr1 = value->rValue; + mod->HSM2_wmuesr1_Given = TRUE; + break; + case HSM2_MOD_WMUETMP: + mod->HSM2_wmuetmp = value->rValue; + mod->HSM2_wmuetmp_Given = TRUE; + break; + case HSM2_MOD_WSUB1: + mod->HSM2_wsub1 = value->rValue; + mod->HSM2_wsub1_Given = TRUE; + break; + case HSM2_MOD_WSUB2: + mod->HSM2_wsub2 = value->rValue; + mod->HSM2_wsub2_Given = TRUE; + break; + case HSM2_MOD_WSVDS: + mod->HSM2_wsvds = value->rValue; + mod->HSM2_wsvds_Given = TRUE; + break; + case HSM2_MOD_WSVBS: + mod->HSM2_wsvbs = value->rValue; + mod->HSM2_wsvbs_Given = TRUE; + break; + case HSM2_MOD_WSVGS: + mod->HSM2_wsvgs = value->rValue; + mod->HSM2_wsvgs_Given = TRUE; + break; + case HSM2_MOD_WNSTI: + mod->HSM2_wnsti = value->rValue; + mod->HSM2_wnsti_Given = TRUE; + break; + case HSM2_MOD_WWSTI: + mod->HSM2_wwsti = value->rValue; + mod->HSM2_wwsti_Given = TRUE; + break; + case HSM2_MOD_WSCSTI1: + mod->HSM2_wscsti1 = value->rValue; + mod->HSM2_wscsti1_Given = TRUE; + break; + case HSM2_MOD_WSCSTI2: + mod->HSM2_wscsti2 = value->rValue; + mod->HSM2_wscsti2_Given = TRUE; + break; + case HSM2_MOD_WVTHSTI: + mod->HSM2_wvthsti = value->rValue; + mod->HSM2_wvthsti_Given = TRUE; + break; + case HSM2_MOD_WMUESTI1: + mod->HSM2_wmuesti1 = value->rValue; + mod->HSM2_wmuesti1_Given = TRUE; + break; + case HSM2_MOD_WMUESTI2: + mod->HSM2_wmuesti2 = value->rValue; + mod->HSM2_wmuesti2_Given = TRUE; + break; + case HSM2_MOD_WMUESTI3: + mod->HSM2_wmuesti3 = value->rValue; + mod->HSM2_wmuesti3_Given = TRUE; + break; + case HSM2_MOD_WNSUBPSTI1: + mod->HSM2_wnsubpsti1 = value->rValue; + mod->HSM2_wnsubpsti1_Given = TRUE; + break; + case HSM2_MOD_WNSUBPSTI2: + mod->HSM2_wnsubpsti2 = value->rValue; + mod->HSM2_wnsubpsti2_Given = TRUE; + break; + case HSM2_MOD_WNSUBPSTI3: + mod->HSM2_wnsubpsti3 = value->rValue; + mod->HSM2_wnsubpsti3_Given = TRUE; + break; + case HSM2_MOD_WCGSO: + mod->HSM2_wcgso = value->rValue; + mod->HSM2_wcgso_Given = TRUE; + break; + case HSM2_MOD_WCGDO: + mod->HSM2_wcgdo = value->rValue; + mod->HSM2_wcgdo_Given = TRUE; + break; + case HSM2_MOD_WJS0: + mod->HSM2_wjs0 = value->rValue; + mod->HSM2_wjs0_Given = TRUE; + break; + case HSM2_MOD_WJS0SW: + mod->HSM2_wjs0sw = value->rValue; + mod->HSM2_wjs0sw_Given = TRUE; + break; + case HSM2_MOD_WNJ: + mod->HSM2_wnj = value->rValue; + mod->HSM2_wnj_Given = TRUE; + break; + case HSM2_MOD_WCISBK: + mod->HSM2_wcisbk = value->rValue; + mod->HSM2_wcisbk_Given = TRUE; + break; + case HSM2_MOD_WCLM1: + mod->HSM2_wclm1 = value->rValue; + mod->HSM2_wclm1_Given = TRUE; + break; + case HSM2_MOD_WCLM2: + mod->HSM2_wclm2 = value->rValue; + mod->HSM2_wclm2_Given = TRUE; + break; + case HSM2_MOD_WCLM3: + mod->HSM2_wclm3 = value->rValue; + mod->HSM2_wclm3_Given = TRUE; + break; + case HSM2_MOD_WWFC: + mod->HSM2_wwfc = value->rValue; + mod->HSM2_wwfc_Given = TRUE; + break; + case HSM2_MOD_WGIDL1: + mod->HSM2_wgidl1 = value->rValue; + mod->HSM2_wgidl1_Given = TRUE; + break; + case HSM2_MOD_WGIDL2: + mod->HSM2_wgidl2 = value->rValue; + mod->HSM2_wgidl2_Given = TRUE; + break; + case HSM2_MOD_WGLEAK1: + mod->HSM2_wgleak1 = value->rValue; + mod->HSM2_wgleak1_Given = TRUE; + break; + case HSM2_MOD_WGLEAK2: + mod->HSM2_wgleak2 = value->rValue; + mod->HSM2_wgleak2_Given = TRUE; + break; + case HSM2_MOD_WGLEAK3: + mod->HSM2_wgleak3 = value->rValue; + mod->HSM2_wgleak3_Given = TRUE; + break; + case HSM2_MOD_WGLEAK6: + mod->HSM2_wgleak6 = value->rValue; + mod->HSM2_wgleak6_Given = TRUE; + break; + case HSM2_MOD_WGLKSD1: + mod->HSM2_wglksd1 = value->rValue; + mod->HSM2_wglksd1_Given = TRUE; + break; + case HSM2_MOD_WGLKSD2: + mod->HSM2_wglksd2 = value->rValue; + mod->HSM2_wglksd2_Given = TRUE; + break; + case HSM2_MOD_WGLKB1: + mod->HSM2_wglkb1 = value->rValue; + mod->HSM2_wglkb1_Given = TRUE; + break; + case HSM2_MOD_WGLKB2: + mod->HSM2_wglkb2 = value->rValue; + mod->HSM2_wglkb2_Given = TRUE; + break; + case HSM2_MOD_WNFTRP: + mod->HSM2_wnftrp = value->rValue; + mod->HSM2_wnftrp_Given = TRUE; + break; + case HSM2_MOD_WNFALP: + mod->HSM2_wnfalp = value->rValue; + mod->HSM2_wnfalp_Given = TRUE; + break; + case HSM2_MOD_WVDIFFJ: + mod->HSM2_wvdiffj = value->rValue; + mod->HSM2_wvdiffj_Given = TRUE; + break; + case HSM2_MOD_WIBPC1: + mod->HSM2_wibpc1 = value->rValue; + mod->HSM2_wibpc1_Given = TRUE; + break; + case HSM2_MOD_WIBPC2: + mod->HSM2_wibpc2 = value->rValue; + mod->HSM2_wibpc2_Given = TRUE; + break; + + /* Cross-term dependence */ + case HSM2_MOD_PVMAX: + mod->HSM2_pvmax = value->rValue; + mod->HSM2_pvmax_Given = TRUE; + break; + case HSM2_MOD_PBGTMP1: + mod->HSM2_pbgtmp1 = value->rValue; + mod->HSM2_pbgtmp1_Given = TRUE; + break; + case HSM2_MOD_PBGTMP2: + mod->HSM2_pbgtmp2 = value->rValue; + mod->HSM2_pbgtmp2_Given = TRUE; + break; + case HSM2_MOD_PEG0: + mod->HSM2_peg0 = value->rValue; + mod->HSM2_peg0_Given = TRUE; + break; + case HSM2_MOD_PLOVER: + mod->HSM2_plover = value->rValue; + mod->HSM2_plover_Given = TRUE; + break; + case HSM2_MOD_PVFBOVER: + mod->HSM2_pvfbover = value->rValue; + mod->HSM2_pvfbover_Given = TRUE; + break; + case HSM2_MOD_PNOVER: + mod->HSM2_pnover = value->rValue; + mod->HSM2_pnover_Given = TRUE; + break; + case HSM2_MOD_PWL2: + mod->HSM2_pwl2 = value->rValue; + mod->HSM2_pwl2_Given = TRUE; + break; + case HSM2_MOD_PVFBC: + mod->HSM2_pvfbc = value->rValue; + mod->HSM2_pvfbc_Given = TRUE; + break; + case HSM2_MOD_PNSUBC: + mod->HSM2_pnsubc = value->rValue; + mod->HSM2_pnsubc_Given = TRUE; + break; + case HSM2_MOD_PNSUBP: + mod->HSM2_pnsubp = value->rValue; + mod->HSM2_pnsubp_Given = TRUE; + break; + case HSM2_MOD_PSCP1: + mod->HSM2_pscp1 = value->rValue; + mod->HSM2_pscp1_Given = TRUE; + break; + case HSM2_MOD_PSCP2: + mod->HSM2_pscp2 = value->rValue; + mod->HSM2_pscp2_Given = TRUE; + break; + case HSM2_MOD_PSCP3: + mod->HSM2_pscp3 = value->rValue; + mod->HSM2_pscp3_Given = TRUE; + break; + case HSM2_MOD_PSC1: + mod->HSM2_psc1 = value->rValue; + mod->HSM2_psc1_Given = TRUE; + break; + case HSM2_MOD_PSC2: + mod->HSM2_psc2 = value->rValue; + mod->HSM2_psc2_Given = TRUE; + break; + case HSM2_MOD_PSC3: + mod->HSM2_psc3 = value->rValue; + mod->HSM2_psc3_Given = TRUE; + break; + case HSM2_MOD_PSC4: + mod->HSM2_psc4 = value->rValue; + mod->HSM2_psc4_Given = TRUE; + break; + case HSM2_MOD_PPGD1: + mod->HSM2_ppgd1 = value->rValue; + mod->HSM2_ppgd1_Given = TRUE; + break; +//case HSM2_MOD_PPGD3: +// mod->HSM2_ppgd3 = value->rValue; +// mod->HSM2_ppgd3_Given = TRUE; +// break; + case HSM2_MOD_PNDEP: + mod->HSM2_pndep = value->rValue; + mod->HSM2_pndep_Given = TRUE; + break; + case HSM2_MOD_PNINV: + mod->HSM2_pninv = value->rValue; + mod->HSM2_pninv_Given = TRUE; + break; + case HSM2_MOD_PMUECB0: + mod->HSM2_pmuecb0 = value->rValue; + mod->HSM2_pmuecb0_Given = TRUE; + break; + case HSM2_MOD_PMUECB1: + mod->HSM2_pmuecb1 = value->rValue; + mod->HSM2_pmuecb1_Given = TRUE; + break; + case HSM2_MOD_PMUEPH1: + mod->HSM2_pmueph1 = value->rValue; + mod->HSM2_pmueph1_Given = TRUE; + break; + case HSM2_MOD_PVTMP: + mod->HSM2_pvtmp = value->rValue; + mod->HSM2_pvtmp_Given = TRUE; + break; + case HSM2_MOD_PWVTH0: + mod->HSM2_pwvth0 = value->rValue; + mod->HSM2_pwvth0_Given = TRUE; + break; + case HSM2_MOD_PMUESR1: + mod->HSM2_pmuesr1 = value->rValue; + mod->HSM2_pmuesr1_Given = TRUE; + break; + case HSM2_MOD_PMUETMP: + mod->HSM2_pmuetmp = value->rValue; + mod->HSM2_pmuetmp_Given = TRUE; + break; + case HSM2_MOD_PSUB1: + mod->HSM2_psub1 = value->rValue; + mod->HSM2_psub1_Given = TRUE; + break; + case HSM2_MOD_PSUB2: + mod->HSM2_psub2 = value->rValue; + mod->HSM2_psub2_Given = TRUE; + break; + case HSM2_MOD_PSVDS: + mod->HSM2_psvds = value->rValue; + mod->HSM2_psvds_Given = TRUE; + break; + case HSM2_MOD_PSVBS: + mod->HSM2_psvbs = value->rValue; + mod->HSM2_psvbs_Given = TRUE; + break; + case HSM2_MOD_PSVGS: + mod->HSM2_psvgs = value->rValue; + mod->HSM2_psvgs_Given = TRUE; + break; + case HSM2_MOD_PNSTI: + mod->HSM2_pnsti = value->rValue; + mod->HSM2_pnsti_Given = TRUE; + break; + case HSM2_MOD_PWSTI: + mod->HSM2_pwsti = value->rValue; + mod->HSM2_pwsti_Given = TRUE; + break; + case HSM2_MOD_PSCSTI1: + mod->HSM2_pscsti1 = value->rValue; + mod->HSM2_pscsti1_Given = TRUE; + break; + case HSM2_MOD_PSCSTI2: + mod->HSM2_pscsti2 = value->rValue; + mod->HSM2_pscsti2_Given = TRUE; + break; + case HSM2_MOD_PVTHSTI: + mod->HSM2_pvthsti = value->rValue; + mod->HSM2_pvthsti_Given = TRUE; + break; + case HSM2_MOD_PMUESTI1: + mod->HSM2_pmuesti1 = value->rValue; + mod->HSM2_pmuesti1_Given = TRUE; + break; + case HSM2_MOD_PMUESTI2: + mod->HSM2_pmuesti2 = value->rValue; + mod->HSM2_pmuesti2_Given = TRUE; + break; + case HSM2_MOD_PMUESTI3: + mod->HSM2_pmuesti3 = value->rValue; + mod->HSM2_pmuesti3_Given = TRUE; + break; + case HSM2_MOD_PNSUBPSTI1: + mod->HSM2_pnsubpsti1 = value->rValue; + mod->HSM2_pnsubpsti1_Given = TRUE; + break; + case HSM2_MOD_PNSUBPSTI2: + mod->HSM2_pnsubpsti2 = value->rValue; + mod->HSM2_pnsubpsti2_Given = TRUE; + break; + case HSM2_MOD_PNSUBPSTI3: + mod->HSM2_pnsubpsti3 = value->rValue; + mod->HSM2_pnsubpsti3_Given = TRUE; + break; + case HSM2_MOD_PCGSO: + mod->HSM2_pcgso = value->rValue; + mod->HSM2_pcgso_Given = TRUE; + break; + case HSM2_MOD_PCGDO: + mod->HSM2_pcgdo = value->rValue; + mod->HSM2_pcgdo_Given = TRUE; + break; + case HSM2_MOD_PJS0: + mod->HSM2_pjs0 = value->rValue; + mod->HSM2_pjs0_Given = TRUE; + break; + case HSM2_MOD_PJS0SW: + mod->HSM2_pjs0sw = value->rValue; + mod->HSM2_pjs0sw_Given = TRUE; + break; + case HSM2_MOD_PNJ: + mod->HSM2_pnj = value->rValue; + mod->HSM2_pnj_Given = TRUE; + break; + case HSM2_MOD_PCISBK: + mod->HSM2_pcisbk = value->rValue; + mod->HSM2_pcisbk_Given = TRUE; + break; + case HSM2_MOD_PCLM1: + mod->HSM2_pclm1 = value->rValue; + mod->HSM2_pclm1_Given = TRUE; + break; + case HSM2_MOD_PCLM2: + mod->HSM2_pclm2 = value->rValue; + mod->HSM2_pclm2_Given = TRUE; + break; + case HSM2_MOD_PCLM3: + mod->HSM2_pclm3 = value->rValue; + mod->HSM2_pclm3_Given = TRUE; + break; + case HSM2_MOD_PWFC: + mod->HSM2_pwfc = value->rValue; + mod->HSM2_pwfc_Given = TRUE; + break; + case HSM2_MOD_PGIDL1: + mod->HSM2_pgidl1 = value->rValue; + mod->HSM2_pgidl1_Given = TRUE; + break; + case HSM2_MOD_PGIDL2: + mod->HSM2_pgidl2 = value->rValue; + mod->HSM2_pgidl2_Given = TRUE; + break; + case HSM2_MOD_PGLEAK1: + mod->HSM2_pgleak1 = value->rValue; + mod->HSM2_pgleak1_Given = TRUE; + break; + case HSM2_MOD_PGLEAK2: + mod->HSM2_pgleak2 = value->rValue; + mod->HSM2_pgleak2_Given = TRUE; + break; + case HSM2_MOD_PGLEAK3: + mod->HSM2_pgleak3 = value->rValue; + mod->HSM2_pgleak3_Given = TRUE; + break; + case HSM2_MOD_PGLEAK6: + mod->HSM2_pgleak6 = value->rValue; + mod->HSM2_pgleak6_Given = TRUE; + break; + case HSM2_MOD_PGLKSD1: + mod->HSM2_pglksd1 = value->rValue; + mod->HSM2_pglksd1_Given = TRUE; + break; + case HSM2_MOD_PGLKSD2: + mod->HSM2_pglksd2 = value->rValue; + mod->HSM2_pglksd2_Given = TRUE; + break; + case HSM2_MOD_PGLKB1: + mod->HSM2_pglkb1 = value->rValue; + mod->HSM2_pglkb1_Given = TRUE; + break; + case HSM2_MOD_PGLKB2: + mod->HSM2_pglkb2 = value->rValue; + mod->HSM2_pglkb2_Given = TRUE; + break; + case HSM2_MOD_PNFTRP: + mod->HSM2_pnftrp = value->rValue; + mod->HSM2_pnftrp_Given = TRUE; + break; + case HSM2_MOD_PNFALP: + mod->HSM2_pnfalp = value->rValue; + mod->HSM2_pnfalp_Given = TRUE; + break; + case HSM2_MOD_PVDIFFJ: + mod->HSM2_pvdiffj = value->rValue; + mod->HSM2_pvdiffj_Given = TRUE; + break; + case HSM2_MOD_PIBPC1: + mod->HSM2_pibpc1 = value->rValue; + mod->HSM2_pibpc1_Given = TRUE; + break; + case HSM2_MOD_PIBPC2: + mod->HSM2_pibpc2 = value->rValue; + mod->HSM2_pibpc2_Given = TRUE; + break; + + default: + return(E_BADPARM); + } + return(OK); +} + diff --git a/src/spicelib/devices/hisim2/hsm2noi.c b/src/spicelib/devices/hisim2/hsm2noi.c new file mode 100644 index 000000000..c00ee9c22 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2noi.c @@ -0,0 +1,319 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2noi.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include +#include "hsm2def.h" +#include "cktdefs.h" +#include "fteconst.h" +#include "iferrmsg.h" +#include "noisedef.h" +#include "util.h" +#include "suffix.h" +#include "const.h" /* jwan */ + +/* + * HSM2noise (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". + */ + +extern void NevalSrc(); +extern double Nintegrate(); + +int HSM2noise (mode, operation, inModel, ckt, data, OnDens) + int mode, operation; + GENmodel *inModel; + CKTcircuit *ckt; + register Ndata *data; + double *OnDens; +{ + register HSM2model *model = (HSM2model *)inModel; + register HSM2instance *here; + char name[N_MXVLNTH]; + double tempOnoise; + double tempInoise; + double noizDens[HSM2NSRCS]; + double lnNdens[HSM2NSRCS]; + register int i; + double R = 0.0 , G = 0.0 ; + double TTEMP = 0.0 ; + + /* define the names of the noise sources */ + static char * HSM2nNames[HSM2NSRCS] = { + /* Note that we have to keep the order + consistent with the index definitions + in hsm2defs.h */ + ".rd", /* noise due to rd */ + ".rs", /* noise due to rs */ + ".id", /* noise due to id */ + ".1ovf", /* flicker (1/f) noise */ + ".igs", /* shot noise due to Igs */ + ".igd", /* shot noise due to Igd */ + ".igb", /* shot noise due to Igb */ + ".ign", /* induced gate noise component at the drain node */ + "" /* total transistor noise */ + }; + + for ( ;model != NULL; model = model->HSM2nextModel ) { + for ( here = model->HSM2instances; here != NULL; + here = here->HSM2nextInstance ) { + 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 < HSM2NSRCS; i++ ) { + (void) sprintf(name, "onoise.%s%s", + (char *)here->HSM2name, HSM2nNames[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, (GENERIC **) NULL); + } + break; + case INT_NOIZ: + for ( i = 0; i < HSM2NSRCS; i++ ) { + (void) sprintf(name, "onoise_total.%s%s", + (char *)here->HSM2name, HSM2nNames[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, (GENERIC **) NULL); + + (void) sprintf(name, "inoise_total.%s%s", + (char *)here->HSM2name, HSM2nNames[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, (GENERIC **)NULL); + } + break; + } + } + break; + case N_CALC: + switch (mode) { + case N_DENS: + + /* temperature */ + TTEMP = ckt->CKTtemp ; + if ( here->HSM2_temp_Given ) TTEMP = here->HSM2_temp ; + if ( here->HSM2_dtemp_Given ) { + TTEMP = TTEMP + here->HSM2_dtemp ; + } + + /* rs/rd thermal noise */ + if ( model->HSM2_corsrd < 0 ) { + NevalSrc(&noizDens[HSM2RDNOIZ], (double*) NULL, + ckt, N_GAIN, + here->HSM2dNodePrime, here->HSM2dNode, + (double) 0.0); + noizDens[HSM2RDNOIZ] *= 4 * CONSTboltz * TTEMP * here->HSM2drainConductance ; + lnNdens[HSM2RDNOIZ] = log( MAX(noizDens[HSM2RDNOIZ],N_MINLOG) ) ; + + NevalSrc(&noizDens[HSM2RSNOIZ], (double*) NULL, + ckt, N_GAIN, + here->HSM2sNodePrime, here->HSM2sNode, + (double) 0.0); + noizDens[HSM2RSNOIZ] *= 4 * CONSTboltz * TTEMP * here->HSM2sourceConductance ; + lnNdens[HSM2RSNOIZ] = log( MAX(noizDens[HSM2RSNOIZ],N_MINLOG) ) ; + + /* + NevalSrc(&noizDens[HSM2RDNOIZ], &lnNdens[HSM2RDNOIZ], + ckt, THERMNOISE, + here->HSM2dNodePrime, here->HSM2dNode, + here->HSM2_weff / model->HSM2_rsh); + + NevalSrc(&noizDens[HSM2RSNOIZ], &lnNdens[HSM2RSNOIZ], + ckt, THERMNOISE, + here->HSM2sNodePrime, here->HSM2sNode, + here->HSM2_weff / model->HSM2_rsh); + */ + } else { + noizDens[HSM2RDNOIZ] = 0e0 ; + lnNdens[HSM2RDNOIZ] = N_MINLOG ; + noizDens[HSM2RSNOIZ] = 0e0 ; + lnNdens[HSM2RSNOIZ] = N_MINLOG ; + } + + /* channel thermal noise */ + switch( model->HSM2_noise ) { + case 1: + /* HiSIM2 model */ + if ( model->HSM2_corsrd <= 0 || here->HSM2internalGd <= 0.0 ) { + G = here->HSM2_noithrml ; + } else { + R = 0.0 , G = 0.0 ; + if ( here->HSM2_noithrml > 0.0 ) R += 1.0 / here->HSM2_noithrml ; + if ( here->HSM2internalGd > 0.0 ) R += 1.0 / here->HSM2internalGd ; + if ( here->HSM2internalGs > 0.0 ) R += 1.0 / here->HSM2internalGs ; + if ( R > 0.0 ) G = 1.0 / R ; + } + NevalSrc(&noizDens[HSM2IDNOIZ], (double*) NULL, + ckt, N_GAIN, + here->HSM2dNodePrime, here->HSM2sNodePrime, + (double) 0.0); + noizDens[HSM2IDNOIZ] *= 4 * CONSTboltz * TTEMP * G ; + lnNdens[HSM2IDNOIZ] = log( MAX(noizDens[HSM2IDNOIZ],N_MINLOG) ); + break; + } + + /* flicker noise */ + NevalSrc(&noizDens[HSM2FLNOIZ], (double*) NULL, + ckt, N_GAIN, + here->HSM2dNodePrime, here->HSM2sNodePrime, + (double) 0.0); + switch ( model->HSM2_noise ) { + case 1: + /* HiSIM model */ + noizDens[HSM2FLNOIZ] *= here->HSM2_noiflick / pow(data->freq, model->HSM2_falph) ; + break; + } + lnNdens[HSM2FLNOIZ] = log(MAX(noizDens[HSM2FLNOIZ], N_MINLOG)); + + /* shot noise */ + NevalSrc(&noizDens[HSM2IGSNOIZ], + &lnNdens[HSM2IGSNOIZ], ckt, SHOTNOISE, + here->HSM2gNodePrime, here->HSM2sNodePrime, + here->HSM2_igs); + NevalSrc(&noizDens[HSM2IGDNOIZ], + &lnNdens[HSM2IGDNOIZ], ckt, SHOTNOISE, + here->HSM2gNodePrime, here->HSM2dNodePrime, + here->HSM2_igd); + NevalSrc(&noizDens[HSM2IGBNOIZ], + &lnNdens[HSM2IGBNOIZ], ckt, SHOTNOISE, + here->HSM2gNodePrime, here->HSM2bNodePrime, + here->HSM2_igb); + + /* induced gate noise */ + switch ( model->HSM2_noise ) { + case 1: + /* HiSIM model */ + NevalSrc(&noizDens[HSM2IGNOIZ], (double*) NULL, + ckt, N_GAIN, + here->HSM2dNodePrime, here->HSM2sNodePrime, + (double) 0.0); + noizDens[HSM2IGNOIZ] *= here->HSM2_noiigate * here->HSM2_noicross * here->HSM2_noicross * data->freq * data->freq; + lnNdens[HSM2IGNOIZ] = log(MAX(noizDens[HSM2IGNOIZ], N_MINLOG)); + break; + } + + /* total */ + noizDens[HSM2TOTNOIZ] = noizDens[HSM2RDNOIZ] + noizDens[HSM2RSNOIZ] + + noizDens[HSM2IDNOIZ] + noizDens[HSM2FLNOIZ] + + noizDens[HSM2IGSNOIZ] + noizDens[HSM2IGDNOIZ] + noizDens[HSM2IGBNOIZ] + + noizDens[HSM2IGNOIZ]; + lnNdens[HSM2TOTNOIZ] = log(MAX(noizDens[HSM2TOTNOIZ], N_MINLOG)); +/* printf("f %e Sid %.16e Srd %.16e Srs %.16e Sflick %.16e Stherm %.16e Sign %.16e\n", */ +/* data->freq,noizDens[HSM2TOTNOIZ],noizDens[HSM2RDNOIZ],noizDens[HSM2RSNOIZ],noizDens[HSM2FLNOIZ],noizDens[HSM2IDNOIZ],noizDens[HSM2IGNOIZ]); */ + + *OnDens += noizDens[HSM2TOTNOIZ]; + + if ( data->delFreq == 0.0 ) { + /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ + + for ( i = 0; i < HSM2NSRCS; i++ ) + here->HSM2nVar[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 < HSM2NSRCS; i++) { + here->HSM2nVar[OUTNOIZ][i] = 0.0; + here->HSM2nVar[INNOIZ][i] = 0.0; + } + } + } + else { + /* data->delFreq != 0.0, + we have to integrate. + */ + for ( i = 0; i < HSM2NSRCS; i++ ) { + if ( i != HSM2TOTNOIZ ) { + tempOnoise = + Nintegrate(noizDens[i], lnNdens[i], + here->HSM2nVar[LNLSTDENS][i], data); + tempInoise = + Nintegrate(noizDens[i] * data->GainSqInv, + lnNdens[i] + data->lnGainInv, + here->HSM2nVar[LNLSTDENS][i] + data->lnGainInv, + data); + here->HSM2nVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if ( ((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0 ) { + here->HSM2nVar[OUTNOIZ][i] += tempOnoise; + here->HSM2nVar[OUTNOIZ][HSM2TOTNOIZ] += tempOnoise; + here->HSM2nVar[INNOIZ][i] += tempInoise; + here->HSM2nVar[INNOIZ][HSM2TOTNOIZ] += tempInoise; + } + } + } + } + if ( data->prtSummary ) { + for (i = 0; i < HSM2NSRCS; 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 < HSM2NSRCS; i++ ) { + data->outpVector[data->outNumber++] = here->HSM2nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = here->HSM2nVar[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/hisim2/hsm2par.c b/src/spicelib/devices/hisim2/hsm2par.c new file mode 100644 index 000000000..d38cf5f48 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2par.c @@ -0,0 +1,179 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2par.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "ifsim.h" +#include "hsm2def.h" +#include "util.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2param(param,value,inst,select) + int param; + IFvalue *value; + GENinstance *inst; + IFvalue *select; +{ + HSM2instance *here = (HSM2instance*)inst; + switch (param) { + case HSM2_W: + here->HSM2_w = value->rValue; + here->HSM2_w_Given = TRUE; + break; + case HSM2_L: + here->HSM2_l = value->rValue; + here->HSM2_l_Given = TRUE; + break; + case HSM2_AS: + here->HSM2_as = value->rValue; + here->HSM2_as_Given = TRUE; + break; + case HSM2_AD: + here->HSM2_ad = value->rValue; + here->HSM2_ad_Given = TRUE; + break; + case HSM2_PS: + here->HSM2_ps = value->rValue; + here->HSM2_ps_Given = TRUE; + break; + case HSM2_PD: + here->HSM2_pd = value->rValue; + here->HSM2_pd_Given = TRUE; + break; + case HSM2_NRS: + here->HSM2_nrs = value->rValue; + here->HSM2_nrs_Given = TRUE; + break; + case HSM2_NRD: + here->HSM2_nrd = value->rValue; + here->HSM2_nrd_Given = TRUE; + break; + case HSM2_TEMP: + here->HSM2_temp = value->rValue; + here->HSM2_temp_Given = TRUE; + break; + case HSM2_DTEMP: + here->HSM2_dtemp = value->rValue; + here->HSM2_dtemp_Given = TRUE; + break; + case HSM2_OFF: + here->HSM2_off = value->iValue; + break; + case HSM2_IC_VBS: + here->HSM2_icVBS = value->rValue; + here->HSM2_icVBS_Given = TRUE; + break; + case HSM2_IC_VDS: + here->HSM2_icVDS = value->rValue; + here->HSM2_icVDS_Given = TRUE; + break; + case HSM2_IC_VGS: + here->HSM2_icVGS = value->rValue; + here->HSM2_icVGS_Given = TRUE; + break; + case HSM2_IC: + switch (value->v.numValue) { + case 3: + here->HSM2_icVBS = *(value->v.vec.rVec + 2); + here->HSM2_icVBS_Given = TRUE; + case 2: + here->HSM2_icVGS = *(value->v.vec.rVec + 1); + here->HSM2_icVGS_Given = TRUE; + case 1: + here->HSM2_icVDS = *(value->v.vec.rVec); + here->HSM2_icVDS_Given = TRUE; + break; + default: + return(E_BADPARM); + } + break; + case HSM2_CORBNET: + here->HSM2_corbnet = value->iValue; + here->HSM2_corbnet_Given = TRUE; + break; + case HSM2_RBPB: + here->HSM2_rbpb = value->rValue; + here->HSM2_rbpb_Given = TRUE; + break; + case HSM2_RBPD: + here->HSM2_rbpd = value->rValue; + here->HSM2_rbpd_Given = TRUE; + break; + case HSM2_RBPS: + here->HSM2_rbps = value->rValue; + here->HSM2_rbps_Given = TRUE; + break; + case HSM2_RBDB: + here->HSM2_rbdb = value->rValue; + here->HSM2_rbdb_Given = TRUE; + break; + case HSM2_RBSB: + here->HSM2_rbsb = value->rValue; + here->HSM2_rbsb_Given = TRUE; + break; + case HSM2_CORG: + here->HSM2_corg = value->iValue; + here->HSM2_corg_Given = TRUE; + break; +/* case HSM2_RSHG: */ +/* here->HSM2_rshg = value->rValue; */ +/* here->HSM2_rshg_Given = TRUE; */ +/* break; */ + case HSM2_NGCON: + here->HSM2_ngcon = value->rValue; + here->HSM2_ngcon_Given = TRUE; + break; + case HSM2_XGW: + here->HSM2_xgw = value->rValue; + here->HSM2_xgw_Given = TRUE; + break; + case HSM2_XGL: + here->HSM2_xgl = value->rValue; + here->HSM2_xgl_Given = TRUE; + break; + case HSM2_NF: + here->HSM2_nf = value->rValue; + here->HSM2_nf_Given = TRUE; + break; + case HSM2_SA: + here->HSM2_sa = value->rValue; + here->HSM2_sa_Given = TRUE; + break; + case HSM2_SB: + here->HSM2_sb = value->rValue; + here->HSM2_sb_Given = TRUE; + break; + case HSM2_SD: + here->HSM2_sd = value->rValue; + here->HSM2_sd_Given = TRUE; + break; + case HSM2_NSUBCDFM: + here->HSM2_nsubcdfm = value->rValue; + here->HSM2_nsubcdfm_Given = TRUE; + break; + case HSM2_MPHDFM: + here->HSM2_mphdfm = value->rValue; + here->HSM2_mphdfm_Given = TRUE; + break; + case HSM2_M: + here->HSM2_m = value->rValue; + here->HSM2_m_Given = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2pzld.c b/src/spicelib/devices/hisim2/hsm2pzld.c new file mode 100644 index 000000000..9c8bd7a46 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2pzld.c @@ -0,0 +1,364 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2pzld.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "cktdefs.h" +#include "complex.h" +#include "sperror.h" +#include "hsm2def.h" +#include "suffix.h" + +int HSM2pzLoad(inModel,ckt,s) + GENmodel *inModel; + register CKTcircuit *ckt; + register SPcomplex *s; +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; + double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; + double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb; + double xcdbdb, xcsbsb; + double gdpr, gspr, gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, gm, gmbs; + double gjbd, gjbs, grg; + double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb; + double gbspsp, gbbdp, gbbsp, gbspg, gbspb; + double gbspdp, gbdpdp, gbdpg, gbdpb, gbdpsp; + double gIbtotg, gIbtotd, gIbtots, gIbtotb; + double gIgtotg, gIgtotd, gIgtots, gIgtotb; + double gIdtotg, gIdtotd, gIdtots, gIdtotb; + double gIstotg, gIstotd, gIstots, gIstotb; + + for ( ;model != NULL ;model = model->HSM2nextModel ) { + for ( here = model->HSM2instances ;here!= NULL ; + here = here->HSM2nextInstance ) { + if ( here->HSM2_mode >= 0 ) { + gm = here->HSM2_gm; + gmbs = here->HSM2_gmbs; + FwdSum = gm + gmbs; + RevSum = 0.0; + + gbbdp = -here->HSM2_gbds; + gbbsp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = here->HSM2_gbgs; + gbdpdp = here->HSM2_gbds; + gbdpb = here->HSM2_gbbs; + gbdpsp = -(gbdpg + gbdpdp + gbdpb); + + gbspg = 0.0; + gbspdp = 0.0; + gbspb = 0.0; + gbspsp = 0.0; + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + + } + else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + } + else + gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; + + cggb = here->HSM2_cggb; + cgsb = here->HSM2_cgsb; + cgdb = here->HSM2_cgdb; + + cbgb = here->HSM2_cbgb; + cbsb = here->HSM2_cbsb; + cbdb = here->HSM2_cbdb; + + cdgb = here->HSM2_cdgb; + cdsb = here->HSM2_cdsb; + cddb = here->HSM2_cddb; + + } + else { + gm = -here->HSM2_gm; + gmbs = -here->HSM2_gmbs; + FwdSum = 0.0; + RevSum = -(gm + gmbs); + + gbbsp = -here->HSM2_gbds; + gbbdp = here->HSM2_gbds + here->HSM2_gbgs + here->HSM2_gbbs; + + gbdpg = 0.0; + gbdpsp = 0.0; + gbdpb = 0.0; + gbdpdp = 0.0; + + if (model->HSM2_coiigs) { + gIbtotg = here->HSM2_gigbg; + gIbtotd = here->HSM2_gigbd; + gIbtots = here->HSM2_gigbs; + gIbtotb = here->HSM2_gigbb; + + gIstotg = here->HSM2_gigsg; + gIstotd = here->HSM2_gigsd; + gIstots = here->HSM2_gigss; + gIstotb = here->HSM2_gigsb; + + gIdtotg = here->HSM2_gigdg; + gIdtotd = here->HSM2_gigdd; + gIdtots = here->HSM2_gigds; + gIdtotb = here->HSM2_gigdb; + } + else { + gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; + gIstotg = gIstotd = gIstots = gIstotb = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; + } + + if (model->HSM2_coiigs) { + gIgtotg = gIbtotg + gIstotg + gIdtotg; + gIgtotd = gIbtotd + gIstotd + gIdtotd; + gIgtots = gIbtots + gIstots + gIdtots; + gIgtotb = gIbtotb + gIstotb + gIdtotb; + } + else + gIgtotg = gIgtotd = gIgtots = gIgtotb = 0.0; + + gbspg = here->HSM2_gbgs; + gbspsp = here->HSM2_gbds; + gbspb = here->HSM2_gbbs; + gbspdp = -(gbspg + gbspsp + gbspb); + + cggb = here->HSM2_cggb; + cgsb = here->HSM2_cgdb; + cgdb = here->HSM2_cgsb; + + cbgb = here->HSM2_cbgb; + cbsb = here->HSM2_cbdb; + cbdb = here->HSM2_cbsb; + + cdgb = -(here->HSM2_cdgb + cggb + cbgb); + cdsb = -(here->HSM2_cddb + cgsb + cbsb); + cddb = -(here->HSM2_cdsb + cgdb + cbdb); + } + + gdpr = here->HSM2drainConductance; + gspr = here->HSM2sourceConductance; + gds = here->HSM2_gds; + gbd = here->HSM2_gbd; + gbs = here->HSM2_gbs; + capbd = here->HSM2_capbd; + capbs = here->HSM2_capbs; + + xcdgb = cdgb; + xcddb = cddb + capbd; + xcdsb = cdsb; + xcdbb = -(xcdgb + xcddb + xcdsb); + if (here->HSM2_corbnet == 1) xcdbb += capbd; + + xcsgb = -(cggb + cbgb + cdgb); + xcsdb = -(cgdb + cbdb + cddb); + xcssb = capbs - (cgsb + cbsb + cdsb); + xcsbb = -(xcsgb + xcsdb + xcssb); + if (here->HSM2_corbnet == 1) xcsbb += capbs; + + xcggb = cggb; + xcgdb = cgdb; + xcgsb = cgsb; + xcgbb = -(xcggb + xcgdb + xcgsb); + + xcbgb = cbgb; + if (!here->HSM2_corbnet) { + xcbdb = cbdb - capbd; + xcbsb = cbsb - capbs; + } else { + xcbdb = cbdb; + xcbsb = cbsb; + xcdbdb = - capbd; + xcsbsb = - capbs; + } + xcbbb = -(xcbgb + xcbdb + xcbsb); + + if (!here->HSM2_corbnet) { + gjbd = gbd; + gjbs = gbs; + } else + gjbd = gjbs = 0.0; + + if (here->HSM2_corg == 1) { + grg = here->HSM2_grg; + *(here->HSM2GgPtr) += grg; + *(here->HSM2GPgPtr) -= grg; + *(here->HSM2GgpPtr) -= grg; + + *(here->HSM2GPdpPtr ) += xcgdb * s->real; + *(here->HSM2GPdpPtr +1) += xcgdb * s->imag; + *(here->HSM2GPdpPtr) += grg + gIgtotd; + *(here->HSM2GPgpPtr ) += xcggb * s->real; + *(here->HSM2GPgpPtr +1) += xcggb * s->imag; + *(here->HSM2GPgpPtr) += gIgtotg; + *(here->HSM2GPspPtr ) += xcgsb * s->real; + *(here->HSM2GPspPtr +1) += xcgsb * s->imag; + *(here->HSM2GPspPtr) += gIgtots; + *(here->HSM2GPbpPtr ) += xcgbb * s->real; + *(here->HSM2GPbpPtr +1) += xcgbb * s->imag; + *(here->HSM2GPbpPtr) += gIgtotb; + + } else { + *(here->HSM2GPdpPtr ) += xcgdb * s->real; + *(here->HSM2GPdpPtr +1) += xcgdb * s->imag; + *(here->HSM2GPdpPtr) += gIgtotd; + *(here->HSM2GPgpPtr ) += xcggb * s->real; + *(here->HSM2GPgpPtr +1) += xcggb * s->imag; + *(here->HSM2GPgpPtr) += gIgtotg; + *(here->HSM2GPspPtr ) += xcgsb * s->real; + *(here->HSM2GPspPtr +1) += xcgsb * s->imag; + *(here->HSM2GPspPtr) += gIgtots; + *(here->HSM2GPbpPtr ) += xcgbb * s->real; + *(here->HSM2GPbpPtr +1) += xcgbb * s->imag; + *(here->HSM2GPbpPtr) += gIgtotb; + } + + *(here->HSM2DPdpPtr ) += xcddb * s->real; + *(here->HSM2DPdpPtr +1) += xcddb * s->imag; + *(here->HSM2DPdpPtr) += gdpr + gds + gbd + RevSum + gbdpdp - gIdtotd; + *(here->HSM2DPdPtr) -= gdpr; + *(here->HSM2DPgpPtr ) += xcdgb * s->real; + *(here->HSM2DPgpPtr +1) += xcdgb * s->imag; + *(here->HSM2DPgpPtr) += gm + gbdpg - gIdtotg; + *(here->HSM2DPspPtr ) += xcdsb * s->real; + *(here->HSM2DPspPtr +1) += xcdsb * s->imag; + *(here->HSM2DPspPtr) -= gds + FwdSum - gbdpsp + gIdtots; + *(here->HSM2DPbpPtr ) += xcdbb * s->real; + *(here->HSM2DPbpPtr +1) += xcdbb * s->imag; + *(here->HSM2DPbpPtr) -= gjbd - gmbs - gbdpb + gIdtotb; + + *(here->HSM2DdpPtr) -= gdpr; + *(here->HSM2DdPtr) += gdpr; + + *(here->HSM2SPdpPtr ) += xcsdb * s->real; + *(here->HSM2SPdpPtr +1) += xcsdb * s->imag; + *(here->HSM2SPdpPtr) -= gds + RevSum - gbspdp + gIstotd; + *(here->HSM2SPgpPtr ) += xcsgb * s->real; + *(here->HSM2SPgpPtr +1) += xcsgb * s->imag; + *(here->HSM2SPgpPtr) -= gm - gbspg + gIstotg; + *(here->HSM2SPspPtr ) += xcssb * s->real; + *(here->HSM2SPspPtr +1) += xcssb * s->imag; + *(here->HSM2SPspPtr) += gspr + gds + gbs + FwdSum + gbspsp - gIstots; + *(here->HSM2SPsPtr) -= gspr; + *(here->HSM2SPbpPtr ) += xcsbb * s->real; + *(here->HSM2SPbpPtr +1) += xcsbb * s->imag; + *(here->HSM2SPbpPtr) -= gjbs + gmbs - gbspb + gIstotb; + + *(here->HSM2SspPtr) -= gspr; + *(here->HSM2SsPtr) += gspr; + + *(here->HSM2BPdpPtr ) += xcbdb * s->real; + *(here->HSM2BPdpPtr +1) += xcbdb * s->imag; + *(here->HSM2BPdpPtr) -= gjbd - gbbdp + gIbtotd; + *(here->HSM2BPgpPtr ) += xcbgb * s->real; + *(here->HSM2BPgpPtr +1) += xcbgb * s->imag; + *(here->HSM2BPgpPtr) -= here->HSM2_gbgs + gIbtotg; + *(here->HSM2BPspPtr ) += xcbsb * s->real; + *(here->HSM2BPspPtr +1) += xcbsb * s->imag; + *(here->HSM2BPspPtr) -= gjbs - gbbsp + gIbtots; + *(here->HSM2BPbpPtr ) += xcbbb * s->real; + *(here->HSM2BPbpPtr +1) += xcbbb * s->imag; + *(here->HSM2BPbpPtr) += gjbd + gjbs - here->HSM2_gbbs - gIbtotb; + + if (model->HSM2_cogidl) { + /* stamp gidl */ + *(here->HSM2DPdpPtr) += here->HSM2_gigidlds; + *(here->HSM2DPgpPtr) += here->HSM2_gigidlgs; + *(here->HSM2DPspPtr) -= (here->HSM2_gigidlgs + + here->HSM2_gigidlds + here->HSM2_gigidlbs); + *(here->HSM2DPbpPtr) += here->HSM2_gigidlbs; + *(here->HSM2BPdpPtr) -= here->HSM2_gigidlds; + *(here->HSM2BPgpPtr) -= here->HSM2_gigidlgs; + *(here->HSM2BPspPtr) += (here->HSM2_gigidlgs + + here->HSM2_gigidlds + here->HSM2_gigidlbs); + *(here->HSM2BPbpPtr) -= here->HSM2_gigidlbs; + /* stamp gisl */ + *(here->HSM2SPdpPtr) -= (here->HSM2_gigislsd + + here->HSM2_gigislgd + here->HSM2_gigislbd); + *(here->HSM2SPgpPtr) += here->HSM2_gigislgd; + *(here->HSM2SPspPtr) += here->HSM2_gigislsd; + *(here->HSM2SPbpPtr) += here->HSM2_gigislbd; + *(here->HSM2BPdpPtr) += (here->HSM2_gigislgd + + here->HSM2_gigislsd + here->HSM2_gigislbd); + *(here->HSM2BPgpPtr) -= here->HSM2_gigislgd; + *(here->HSM2BPspPtr) -= here->HSM2_gigislsd; + *(here->HSM2BPbpPtr) -= here->HSM2_gigislbd; + } + + if (here->HSM2_corbnet) { + *(here->HSM2DPdbPtr ) += xcdbdb * s->real; + *(here->HSM2DPdbPtr +1) += xcdbdb * s->imag; + *(here->HSM2DPdbPtr) -= gbd; + *(here->HSM2SPsbPtr ) += xcsbsb * s->real; + *(here->HSM2SPsbPtr +1) += xcsbsb * s->imag; + *(here->HSM2SPsbPtr) -= gbs; + + *(here->HSM2DBdpPtr ) += xcdbdb * s->real; + *(here->HSM2DBdpPtr +1) += xcdbdb * s->imag; + *(here->HSM2DBdpPtr) -= gbd; + *(here->HSM2DBdbPtr ) -= xcdbdb * s->real; + *(here->HSM2DBdbPtr +1) -= xcdbdb * s->imag; + *(here->HSM2DBdbPtr) += gbd + here->HSM2_grbpd + here->HSM2_grbdb; + *(here->HSM2DBbpPtr) -= here->HSM2_grbpd; + *(here->HSM2DBbPtr) -= here->HSM2_grbdb; + + *(here->HSM2BPdbPtr) -= here->HSM2_grbpd; + *(here->HSM2BPbPtr) -= here->HSM2_grbpb; + *(here->HSM2BPsbPtr) -= here->HSM2_grbps; + *(here->HSM2BPbpPtr) += here->HSM2_grbpd + here->HSM2_grbps + here->HSM2_grbpb; + + *(here->HSM2SBspPtr ) += xcsbsb * s->real; + *(here->HSM2SBspPtr +1) += xcsbsb * s->imag; + *(here->HSM2SBspPtr) -= gbs; + *(here->HSM2SBbpPtr) -= here->HSM2_grbps; + *(here->HSM2SBbPtr) -= here->HSM2_grbsb; + *(here->HSM2SBsbPtr ) -= xcsbsb * s->real; + *(here->HSM2SBsbPtr +1) -= xcsbsb * s->imag; + *(here->HSM2SBsbPtr) += gbs + here->HSM2_grbps + here->HSM2_grbsb; + + *(here->HSM2BdbPtr) -= here->HSM2_grbdb; + *(here->HSM2BbpPtr) -= here->HSM2_grbpb; + *(here->HSM2BsbPtr) -= here->HSM2_grbsb; + *(here->HSM2BbPtr) += here->HSM2_grbsb + here->HSM2_grbdb + here->HSM2_grbpb; + } + + } + } + return(OK); +} + diff --git a/src/spicelib/devices/hisim2/hsm2set.c b/src/spicelib/devices/hisim2/hsm2set.c new file mode 100644 index 000000000..22bf287d3 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2set.c @@ -0,0 +1,775 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2set.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hsm2def.h" +#include "hsm2evalenv.h" +#include "util.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + + +int HSM2setup(matrix,inModel,ckt,states) + register SMPmatrix *matrix; + register GENmodel *inModel; + register CKTcircuit *ckt; + int *states; + /* load the HSM2 device structure with those pointers needed later + * for fast matrix loading + */ +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; + int error; + CKTnode *tmp; + + /* loop through all the HSM2 device models */ + for ( ;model != NULL ;model = model->HSM2nextModel ) { + /* Default value Processing for HSM2 MOSFET Models */ + if ( !model->HSM2_type_Given ) + model->HSM2_type = NMOS ; + /***/ + if ( !model->HSM2_info_Given ) model->HSM2_info = 0 ; + /* if ( !model->HSM2_noise_Given) model->HSM2_noise = 1;*/ + model->HSM2_noise = 1; /* allways noise is set to be 1 */ + + if ( !model->HSM2_version_Given) { + model->HSM2_version = 251; /* default 251 */ + printf(" 251 is selected for VERSION. (default) \n"); + } else { + if (model->HSM2_version != 251) { + model->HSM2_version = 251; /* default 251 */ + printf(" 251 is only available for VERSION. \n"); + printf(" 251 is selected for VERSION. (default) \n"); + } else { + printf(" %d is selected for VERSION \n", (int)model->HSM2_version); + } + } + + if ( !model->HSM2_corsrd_Given ) model->HSM2_corsrd = 0 ; + if ( !model->HSM2_corg_Given ) model->HSM2_corg = 0 ; + if ( !model->HSM2_coiprv_Given ) model->HSM2_coiprv = 1 ; + if ( !model->HSM2_copprv_Given ) model->HSM2_copprv = 1 ; + if ( !model->HSM2_coadov_Given ) model->HSM2_coadov = 1 ; + if ( !model->HSM2_coisub_Given ) model->HSM2_coisub = 0 ; + if ( !model->HSM2_coiigs_Given ) model->HSM2_coiigs = 0 ; + if ( !model->HSM2_cogidl_Given ) model->HSM2_cogidl = 0 ; + if ( !model->HSM2_coovlp_Given ) model->HSM2_coovlp = 1 ; + if ( !model->HSM2_coflick_Given ) model->HSM2_coflick = 0 ; + if ( !model->HSM2_coisti_Given ) model->HSM2_coisti = 0 ; + if ( !model->HSM2_conqs_Given ) model->HSM2_conqs = 0 ; /* QS (default) */ + if ( !model->HSM2_cothrml_Given ) model->HSM2_cothrml = 0 ; + if ( !model->HSM2_coign_Given ) model->HSM2_coign = 0 ; /* induced gate noise */ + if ( !model->HSM2_codfm_Given ) model->HSM2_codfm = 0 ; /* DFM */ + if ( !model->HSM2_corbnet_Given ) model->HSM2_corbnet = 0 ; + else if ( model->HSM2_corbnet != 0 && model->HSM2_corbnet != 1 ) { + model->HSM2_corbnet = 0; + printf("warning(HiSIM2): CORBNET has been set to its default value: %d.\n", model->HSM2_corbnet); + } + if ( !model->HSM2_corecip_Given ) model->HSM2_corecip = 1 ; + if ( !model->HSM2_coqy_Given ) model->HSM2_coqy = 0 ; + if ( !model->HSM2_coqovsm_Given ) model->HSM2_coqovsm = 1 ; + + + if ( !model->HSM2_vmax_Given ) model->HSM2_vmax = 1.0e7 ; + if ( !model->HSM2_bgtmp1_Given ) model->HSM2_bgtmp1 = 90.25e-6 ; + if ( !model->HSM2_bgtmp2_Given ) model->HSM2_bgtmp2 = 1.0e-7 ; + if ( !model->HSM2_eg0_Given ) model->HSM2_eg0 = 1.1785e0 ; + if ( !model->HSM2_tox_Given ) model->HSM2_tox = 3.0e-9 ; + if ( !model->HSM2_xld_Given ) model->HSM2_xld = 0.0 ; + if ( !model->HSM2_lover_Given ) model->HSM2_lover = 30e-9 ; + if ( !model->HSM2_ddltmax_Given ) model->HSM2_ddltmax = 10.0 ; /* Vdseff */ + if ( !model->HSM2_ddltslp_Given ) model->HSM2_ddltslp = 0.0 ; /* Vdseff */ + if ( !model->HSM2_ddltict_Given ) model->HSM2_ddltict = 10.0 ; /* Vdseff */ + if ( !model->HSM2_vfbover_Given ) model->HSM2_vfbover = 0.0 ; + if ( !model->HSM2_nover_Given ) model->HSM2_nover = 1E19 ; + if ( !model->HSM2_xwd_Given ) model->HSM2_xwd = 0.0 ; + + if ( !model->HSM2_xl_Given ) model->HSM2_xl = 0.0 ; + if ( !model->HSM2_xw_Given ) model->HSM2_xw = 0.0 ; + if ( !model->HSM2_saref_Given ) model->HSM2_saref = 1e-6 ; + if ( !model->HSM2_sbref_Given ) model->HSM2_sbref = 1e-6 ; + if ( !model->HSM2_ll_Given ) model->HSM2_ll = 0.0 ; + if ( !model->HSM2_lld_Given ) model->HSM2_lld = 0.0 ; + if ( !model->HSM2_lln_Given ) model->HSM2_lln = 0.0 ; + if ( !model->HSM2_wl_Given ) model->HSM2_wl = 0.0 ; + if ( !model->HSM2_wl1_Given ) model->HSM2_wl1 = 0.0 ; + if ( !model->HSM2_wl1p_Given ) model->HSM2_wl1p = 1.0 ; + if ( !model->HSM2_wl2_Given ) model->HSM2_wl2 = 0.0 ; + if ( !model->HSM2_wl2p_Given ) model->HSM2_wl2p = 1.0 ; + if ( !model->HSM2_wld_Given ) model->HSM2_wld = 0.0 ; + if ( !model->HSM2_wln_Given ) model->HSM2_wln = 0.0 ; + + if ( !model->HSM2_rsh_Given ) model->HSM2_rsh = 0.0 ; + if ( !model->HSM2_rshg_Given ) model->HSM2_rshg = 0.0 ; + + if ( !model->HSM2_xqy_Given ) model->HSM2_xqy = 10e-9 ; + if ( !model->HSM2_xqy1_Given ) model->HSM2_xqy1 = 0.0 ; + if ( !model->HSM2_xqy2_Given ) model->HSM2_xqy2 = 2.0 ; + if ( !model->HSM2_qyrat_Given ) model->HSM2_qyrat = 0.5 ; + if ( !model->HSM2_rs_Given ) model->HSM2_rs = 0.0 ; + if ( !model->HSM2_rd_Given ) model->HSM2_rd = 0.0 ; + if ( !model->HSM2_vfbc_Given ) model->HSM2_vfbc = -1.0 ; + if ( !model->HSM2_vbi_Given ) model->HSM2_vbi = 1.1 ; + if ( !model->HSM2_nsubc_Given ) model->HSM2_nsubc = 5.0e17 ; + if ( !model->HSM2_parl2_Given ) model->HSM2_parl2 = 10.0e-9 ; + if ( !model->HSM2_lp_Given ) model->HSM2_lp = 15.0e-9 ; + if ( !model->HSM2_nsubp_Given ) model->HSM2_nsubp = 1.0e18 ; + if ( !model->HSM2_nsubpl_Given ) model->HSM2_nsubpl = 0.001 ; /* um */ + if ( !model->HSM2_nsubpfac_Given ) model->HSM2_nsubpfac = 1.0 ; + + if ( !model->HSM2_nsubpw_Given ) model->HSM2_nsubpw = 0.0 ; + if ( !model->HSM2_nsubpwp_Given ) model->HSM2_nsubpwp = 1.0 ; + + if ( !model->HSM2_scp1_Given ) model->HSM2_scp1 = 1.0 ; + if ( !model->HSM2_scp2_Given ) model->HSM2_scp2 = 0.0 ; + if ( !model->HSM2_scp3_Given ) model->HSM2_scp3 = 0.0 ; + if ( !model->HSM2_sc1_Given ) model->HSM2_sc1 = 1.0 ; + if ( !model->HSM2_sc2_Given ) model->HSM2_sc2 = 0.0 ; + if ( !model->HSM2_sc3_Given ) model->HSM2_sc3 = 0.0 ; + if ( !model->HSM2_sc4_Given ) model->HSM2_sc4 = 0.0 ; + if ( !model->HSM2_pgd1_Given ) model->HSM2_pgd1 = 0.0 ; + if ( !model->HSM2_pgd2_Given ) model->HSM2_pgd2 = 0.3 ; + if ( !model->HSM2_pgd4_Given ) model->HSM2_pgd4 = 0.0 ; + + if ( !model->HSM2_ndep_Given ) model->HSM2_ndep = 1.0 ; + if ( !model->HSM2_ndepl_Given ) model->HSM2_ndepl = 0.0 ; + if ( !model->HSM2_ndeplp_Given ) model->HSM2_ndeplp = 1.0 ; + if ( !model->HSM2_ndepw_Given ) model->HSM2_ndepw = 0.0 ; + if ( !model->HSM2_ndepwp_Given ) model->HSM2_ndepwp = 1.0 ; + if ( !model->HSM2_ninv_Given ) model->HSM2_ninv = 0.5 ; + if ( !model->HSM2_ninvd_Given ) model->HSM2_ninvd = 0.0 ; + if ( !model->HSM2_muecb0_Given ) model->HSM2_muecb0 = 1.0e3 ; + if ( !model->HSM2_muecb1_Given ) model->HSM2_muecb1 = 100.0 ; + if ( !model->HSM2_mueph0_Given ) model->HSM2_mueph0 = 300.0e-3 ; + if ( !model->HSM2_mueph1_Given ) { + if (model->HSM2_type == NMOS) model->HSM2_mueph1 = 25.0e3 ; + else model->HSM2_mueph1 = 9.0e3 ; + } + if ( !model->HSM2_muephw_Given ) model->HSM2_muephw = 0.0 ; + if ( !model->HSM2_muepwp_Given ) model->HSM2_muepwp = 1.0 ; + if ( !model->HSM2_muepwd_Given ) model->HSM2_muepwd = 0.0 ; + if ( !model->HSM2_muephl_Given ) model->HSM2_muephl = 0.0 ; + if ( !model->HSM2_mueplp_Given ) model->HSM2_mueplp = 1.0 ; + if ( !model->HSM2_muepld_Given ) model->HSM2_muepld = 0.0 ; + if ( !model->HSM2_muephs_Given ) model->HSM2_muephs = 0.0 ; + if ( !model->HSM2_muepsp_Given ) model->HSM2_muepsp = 1.0 ; + + if ( !model->HSM2_vtmp_Given ) model->HSM2_vtmp = 0.0 ; + + if ( !model->HSM2_wvth0_Given ) model->HSM2_wvth0 = 0.0 ; + + if ( !model->HSM2_muesr0_Given ) model->HSM2_muesr0 = 2.0 ; + if ( !model->HSM2_muesr1_Given ) model->HSM2_muesr1 = 1.0e15 ; + if ( !model->HSM2_muesrl_Given ) model->HSM2_muesrl = 0.0 ; + if ( !model->HSM2_muesrw_Given ) model->HSM2_muesrw = 0.0 ; + if ( !model->HSM2_mueswp_Given ) model->HSM2_mueswp = 1.0 ; + if ( !model->HSM2_mueslp_Given ) model->HSM2_mueslp = 1.0 ; + + if ( !model->HSM2_muetmp_Given ) model->HSM2_muetmp = 1.5 ; + + if ( !model->HSM2_bb_Given ) { + if (model->HSM2_type == NMOS) model->HSM2_bb = 2.0 ; + else model->HSM2_bb = 1.0 ; + } + + if ( !model->HSM2_sub1_Given ) model->HSM2_sub1 = 10e0 ; + if ( !model->HSM2_sub2_Given ) model->HSM2_sub2 = 25e0 ; + if ( !model->HSM2_svgs_Given ) model->HSM2_svgs = 0.8e0 ; + if ( !model->HSM2_svbs_Given ) model->HSM2_svbs = 0.5e0 ; + if ( !model->HSM2_svbsl_Given ) model->HSM2_svbsl = 0e0 ; + if ( !model->HSM2_svds_Given ) model->HSM2_svds = 0.8e0 ; + if ( !model->HSM2_slg_Given ) model->HSM2_slg = 30e-9 ; + if ( !model->HSM2_sub1l_Given ) model->HSM2_sub1l = 2.5e-3 ; + if ( !model->HSM2_sub2l_Given ) model->HSM2_sub2l = 2e-6 ; + + if ( !model->HSM2_svgsl_Given ) model->HSM2_svgsl = 0.0 ; + if ( !model->HSM2_svgslp_Given ) model->HSM2_svgslp = 1.0 ; + if ( !model->HSM2_svgswp_Given ) model->HSM2_svgswp = 1.0 ; + if ( !model->HSM2_svgsw_Given ) model->HSM2_svgsw = 0.0 ; + if ( !model->HSM2_svbslp_Given ) model->HSM2_svbslp = 1.0 ; + if ( !model->HSM2_slgl_Given ) model->HSM2_slgl = 0.0 ; + if ( !model->HSM2_slglp_Given ) model->HSM2_slglp = 1.0 ; + if ( !model->HSM2_sub1lp_Given ) model->HSM2_sub1lp = 1.0 ; + + if ( !model->HSM2_nsti_Given ) model->HSM2_nsti = 5.0e17 ; + if ( !model->HSM2_wsti_Given ) model->HSM2_wsti = 0.0 ; + if ( !model->HSM2_wstil_Given ) model->HSM2_wstil = 0.0 ; + if ( !model->HSM2_wstilp_Given ) model->HSM2_wstilp = 1.0 ; + if ( !model->HSM2_wstiw_Given ) model->HSM2_wstiw = 0.0 ; + if ( !model->HSM2_wstiwp_Given ) model->HSM2_wstiwp = 1.0 ; + if ( !model->HSM2_scsti1_Given ) model->HSM2_scsti1 = 0.0 ; + if ( !model->HSM2_scsti2_Given ) model->HSM2_scsti2 = 0.0 ; + if ( !model->HSM2_vthsti_Given ) model->HSM2_vthsti = 0.0 ; + if ( !model->HSM2_vdsti_Given ) model->HSM2_vdsti = 0.0 ; + if ( !model->HSM2_muesti1_Given ) model->HSM2_muesti1 = 0.0 ; + if ( !model->HSM2_muesti2_Given ) model->HSM2_muesti2 = 0.0 ; + if ( !model->HSM2_muesti3_Given ) model->HSM2_muesti3 = 1.0 ; + if ( !model->HSM2_nsubpsti1_Given ) model->HSM2_nsubpsti1 = 0.0 ; + if ( !model->HSM2_nsubpsti2_Given ) model->HSM2_nsubpsti2 = 0.0 ; + if ( !model->HSM2_nsubpsti3_Given ) model->HSM2_nsubpsti3 = 1.0 ; + + if ( !model->HSM2_lpext_Given ) model->HSM2_lpext = 1.0e-50 ; + if ( !model->HSM2_npext_Given ) model->HSM2_npext = 5.0e17 ; + if ( !model->HSM2_npextw_Given ) model->HSM2_npextw = 0.0 ; + if ( !model->HSM2_npextwp_Given ) model->HSM2_npextwp = 1.0 ; + if ( !model->HSM2_scp21_Given ) model->HSM2_scp21 = 0.0 ; + if ( !model->HSM2_scp22_Given ) model->HSM2_scp22 = 0.0 ; + if ( !model->HSM2_bs1_Given ) model->HSM2_bs1 = 0.0 ; + if ( !model->HSM2_bs2_Given ) model->HSM2_bs2 = 0.9 ; + + if ( !model->HSM2_tpoly_Given ) model->HSM2_tpoly = 200e-9 ; + if ( !model->HSM2_cgbo_Given ) model->HSM2_cgbo = 0.0 ; + if ( !model->HSM2_js0_Given ) model->HSM2_js0 = 0.5e-6 ; + if ( !model->HSM2_js0sw_Given ) model->HSM2_js0sw = 0.0 ; + if ( !model->HSM2_nj_Given ) model->HSM2_nj = 1.0 ; + if ( !model->HSM2_njsw_Given ) model->HSM2_njsw = 1.0 ; + if ( !model->HSM2_xti_Given ) model->HSM2_xti = 2.0 ; + if ( !model->HSM2_cj_Given ) model->HSM2_cj = 5.0e-04 ; + if ( !model->HSM2_cjsw_Given ) model->HSM2_cjsw = 5.0e-10 ; + if ( !model->HSM2_cjswg_Given ) model->HSM2_cjswg = 5.0e-10 ; + if ( !model->HSM2_mj_Given ) model->HSM2_mj = 0.5e0 ; + if ( !model->HSM2_mjsw_Given ) model->HSM2_mjsw = 0.33e0 ; + if ( !model->HSM2_mjswg_Given ) model->HSM2_mjswg = 0.33e0 ; + if ( !model->HSM2_pb_Given ) model->HSM2_pb = 1.0e0 ; + if ( !model->HSM2_pbsw_Given ) model->HSM2_pbsw = 1.0e0 ; + if ( !model->HSM2_pbswg_Given ) model->HSM2_pbswg = 1.0e0 ; + + if ( !model->HSM2_tcjbd_Given ) model->HSM2_tcjbd = 0.0 ; + if ( !model->HSM2_tcjbs_Given ) model->HSM2_tcjbs = 0.0 ; + if ( !model->HSM2_tcjbdsw_Given ) model->HSM2_tcjbdsw = 0.0 ; + if ( !model->HSM2_tcjbssw_Given ) model->HSM2_tcjbssw = 0.0 ; + if ( !model->HSM2_tcjbdswg_Given ) model->HSM2_tcjbdswg = 0.0 ; + if ( !model->HSM2_tcjbsswg_Given ) model->HSM2_tcjbsswg = 0.0 ; + + if ( !model->HSM2_xti2_Given ) model->HSM2_xti2 = 0.0e0 ; + if ( !model->HSM2_cisb_Given ) model->HSM2_cisb = 0.0e0 ; + if ( !model->HSM2_cvb_Given ) model->HSM2_cvb = 0.0e0 ; + if ( !model->HSM2_ctemp_Given ) model->HSM2_ctemp = 0.0e0 ; + if ( !model->HSM2_cisbk_Given ) model->HSM2_cisbk = 0.0e0 ; + if ( !model->HSM2_cvbk_Given ) model->HSM2_cvbk = 0.0e0 ; + if ( !model->HSM2_divx_Given ) model->HSM2_divx = 0.0e0 ; + + if ( !model->HSM2_clm1_Given ) model->HSM2_clm1 = 700.0e-3 ; + if ( !model->HSM2_clm2_Given ) model->HSM2_clm2 = 2.0 ; + if ( !model->HSM2_clm3_Given ) model->HSM2_clm3 = 1.0 ; + if ( !model->HSM2_clm5_Given ) model->HSM2_clm5 = 1.0 ; + if ( !model->HSM2_clm6_Given ) model->HSM2_clm6 = 0.0 ; + if ( !model->HSM2_vover_Given ) model->HSM2_vover = 0.3 ; + if ( !model->HSM2_voverp_Given ) model->HSM2_voverp = 0.3 ; + if ( !model->HSM2_wfc_Given ) model->HSM2_wfc = 0.0 ; + if ( !model->HSM2_nsubcw_Given ) model->HSM2_nsubcw = 0.0 ; + if ( !model->HSM2_nsubcwp_Given ) model->HSM2_nsubcwp = 1.0 ; + if ( !model->HSM2_nsubcmax_Given ) model->HSM2_nsubcmax = 5e18 ; + + if ( !model->HSM2_qme1_Given ) model->HSM2_qme1 = 0.0 ; + if ( !model->HSM2_qme2_Given ) model->HSM2_qme2 = 0.0 ; + if ( !model->HSM2_qme3_Given ) model->HSM2_qme3 = 0.0 ; + + if ( !model->HSM2_vovers_Given ) model->HSM2_vovers = 0.0 ; + if ( !model->HSM2_voversp_Given ) model->HSM2_voversp = 0.0 ; + + if ( !model->HSM2_gidl1_Given ) model->HSM2_gidl1 = 2e0 ; + if ( !model->HSM2_gidl2_Given ) model->HSM2_gidl2 = 3e7 ; + if ( !model->HSM2_gidl3_Given ) model->HSM2_gidl3 = 0.9e0 ; + if ( !model->HSM2_gidl4_Given ) model->HSM2_gidl4 = 0.0 ; + if ( !model->HSM2_gidl5_Given ) model->HSM2_gidl5 = 0.2e0 ; + + if ( !model->HSM2_gleak1_Given ) model->HSM2_gleak1 = 50e0 ; + if ( !model->HSM2_gleak2_Given ) model->HSM2_gleak2 = 10e6 ; + if ( !model->HSM2_gleak3_Given ) model->HSM2_gleak3 = 60e-3 ; + if ( !model->HSM2_gleak4_Given ) model->HSM2_gleak4 = 4e0 ; + if ( !model->HSM2_gleak5_Given ) model->HSM2_gleak5 = 7.5e3 ; + if ( !model->HSM2_gleak6_Given ) model->HSM2_gleak6 = 250e-3 ; + if ( !model->HSM2_gleak7_Given ) model->HSM2_gleak7 = 1e-6 ; + + if ( !model->HSM2_glksd1_Given ) model->HSM2_glksd1 = 1.0e-15 ; + if ( !model->HSM2_glksd2_Given ) model->HSM2_glksd2 = 5e6 ; + if ( !model->HSM2_glksd3_Given ) model->HSM2_glksd3 = -5e6 ; + if ( !model->HSM2_glkb1_Given ) model->HSM2_glkb1 = 5e-16 ; + if ( !model->HSM2_glkb2_Given ) model->HSM2_glkb2 = 1e0 ; + if ( !model->HSM2_glkb3_Given ) model->HSM2_glkb3 = 0e0 ; + if ( !model->HSM2_egig_Given ) model->HSM2_egig = 0e0 ; + if ( !model->HSM2_igtemp2_Given ) model->HSM2_igtemp2 = 0e0 ; + if ( !model->HSM2_igtemp3_Given ) model->HSM2_igtemp3 = 0e0 ; + if ( !model->HSM2_vzadd0_Given ) model->HSM2_vzadd0 = 20.0e-3 ; + if ( !model->HSM2_pzadd0_Given ) model->HSM2_pzadd0 = 20.0e-3 ; + if ( !model->HSM2_nftrp_Given ) model->HSM2_nftrp = 10e9 ; + if ( !model->HSM2_nfalp_Given ) model->HSM2_nfalp = 1.0e-19 ; + if ( !model->HSM2_falph_Given ) model->HSM2_falph = 1.0 ; + if ( !model->HSM2_cit_Given ) model->HSM2_cit = 0e0 ; + + if ( !model->HSM2_kappa_Given ) model->HSM2_kappa = 3.90e0 ; + if ( !model->HSM2_cgso_Given ) model->HSM2_cgso = 0.0 ; + if ( !model->HSM2_cgdo_Given ) model->HSM2_cgdo = 0.0 ; + + + if ( !model->HSM2_vdiffj_Given ) model->HSM2_vdiffj = 0.6e-3 ; + if ( !model->HSM2_dly1_Given ) model->HSM2_dly1 = 100.0e-12 ; + if ( !model->HSM2_dly2_Given ) model->HSM2_dly2 = 0.7e0 ; + if ( !model->HSM2_dly3_Given ) model->HSM2_dly3 = 0.8e-6 ; + if ( !model->HSM2_tnom_Given ) model->HSM2_tnom = 27.0 ; /* [C] */ + + if ( !model->HSM2_ovslp_Given ) model->HSM2_ovslp = 2.1e-7 ; + if ( !model->HSM2_ovmag_Given ) model->HSM2_ovmag = 0.6e0 ; + + if ( !model->HSM2_gbmin_Given ) model->HSM2_gbmin = 1.0e-12; /* in mho */ + if ( !model->HSM2_rbpb_Given ) model->HSM2_rbpb = 50.0e0 ; + if ( !model->HSM2_rbpd_Given ) model->HSM2_rbpd = 50.0e0 ; + if ( !model->HSM2_rbps_Given ) model->HSM2_rbps = 50.0e0 ; + if ( !model->HSM2_rbdb_Given ) model->HSM2_rbdb = 50.0e0 ; + if ( !model->HSM2_rbsb_Given ) model->HSM2_rbsb = 50.0e0 ; + + if ( !model->HSM2_ibpc1_Given ) model->HSM2_ibpc1 = 0.0 ; + if ( !model->HSM2_ibpc2_Given ) model->HSM2_ibpc2 = 0.0 ; + + if ( !model->HSM2_mphdfm_Given ) model->HSM2_mphdfm = -0.3 ; + + + if ( !model->HSM2_ptl_Given ) model->HSM2_ptl = 0.0 ; + if ( !model->HSM2_ptp_Given ) model->HSM2_ptp = 3.5 ; + if ( !model->HSM2_pt2_Given ) model->HSM2_pt2 = 0.0 ; + if ( !model->HSM2_ptlp_Given ) model->HSM2_ptlp = 1.0 ; + if ( !model->HSM2_gdl_Given ) model->HSM2_gdl = 0.0 ; + if ( !model->HSM2_gdlp_Given ) model->HSM2_gdlp = 0.0 ; + + if ( !model->HSM2_gdld_Given ) model->HSM2_gdld = 0.0 ; + if ( !model->HSM2_pt4_Given ) model->HSM2_pt4 = 0.0 ; + if ( !model->HSM2_pt4p_Given ) model->HSM2_pt4p = 1.0 ; + if ( !model->HSM2_muephl2_Given ) model->HSM2_muephl2 = 0.0 ; + if ( !model->HSM2_mueplp2_Given ) model->HSM2_mueplp2 = 1.0 ; + if ( !model->HSM2_nsubcw2_Given ) model->HSM2_nsubcw2 = 0.0 ; + if ( !model->HSM2_nsubcwp2_Given ) model->HSM2_nsubcwp2 = 1.0 ; + if ( !model->HSM2_muephw2_Given ) model->HSM2_muephw2 = 0.0 ; + if ( !model->HSM2_muepwp2_Given ) model->HSM2_muepwp2 = 1.0 ; + if ( !model->HSM2_Vgsmin_Given ) model->HSM2_Vgsmin = -5.0 * model->HSM2_type ; + if ( !model->HSM2_sc3Vbs_Given ) model->HSM2_sc3Vbs = 0.0 ; + if ( !model->HSM2_byptol_Given ) model->HSM2_byptol = 0.0 ; + if ( !model->HSM2_muecb0lp_Given ) model->HSM2_muecb0lp = 0.0; + if ( !model->HSM2_muecb1lp_Given ) model->HSM2_muecb1lp = 0.0; + + /* binning parameters */ + if ( !model->HSM2_lmin_Given ) model->HSM2_lmin = 0.0 ; + if ( !model->HSM2_lmax_Given ) model->HSM2_lmax = 1.0 ; + if ( !model->HSM2_wmin_Given ) model->HSM2_wmin = 0.0 ; + if ( !model->HSM2_wmax_Given ) model->HSM2_wmax = 1.0 ; + if ( !model->HSM2_lbinn_Given ) model->HSM2_lbinn = 1.0 ; + if ( !model->HSM2_wbinn_Given ) model->HSM2_wbinn = 1.0 ; + + /* Length dependence */ + if ( !model->HSM2_lvmax_Given ) model->HSM2_lvmax = 0.0 ; + if ( !model->HSM2_lbgtmp1_Given ) model->HSM2_lbgtmp1 = 0.0 ; + if ( !model->HSM2_lbgtmp2_Given ) model->HSM2_lbgtmp2 = 0.0 ; + if ( !model->HSM2_leg0_Given ) model->HSM2_leg0 = 0.0 ; + if ( !model->HSM2_llover_Given ) model->HSM2_llover = 0.0 ; + if ( !model->HSM2_lvfbover_Given ) model->HSM2_lvfbover = 0.0 ; + if ( !model->HSM2_lnover_Given ) model->HSM2_lnover = 0.0 ; + if ( !model->HSM2_lwl2_Given ) model->HSM2_lwl2 = 0.0 ; + if ( !model->HSM2_lvfbc_Given ) model->HSM2_lvfbc = 0.0 ; + if ( !model->HSM2_lnsubc_Given ) model->HSM2_lnsubc = 0.0 ; + if ( !model->HSM2_lnsubp_Given ) model->HSM2_lnsubp = 0.0 ; + if ( !model->HSM2_lscp1_Given ) model->HSM2_lscp1 = 0.0 ; + if ( !model->HSM2_lscp2_Given ) model->HSM2_lscp2 = 0.0 ; + if ( !model->HSM2_lscp3_Given ) model->HSM2_lscp3 = 0.0 ; + if ( !model->HSM2_lsc1_Given ) model->HSM2_lsc1 = 0.0 ; + if ( !model->HSM2_lsc2_Given ) model->HSM2_lsc2 = 0.0 ; + if ( !model->HSM2_lsc3_Given ) model->HSM2_lsc3 = 0.0 ; + if ( !model->HSM2_lsc4_Given ) model->HSM2_lsc4 = 0.0 ; + if ( !model->HSM2_lpgd1_Given ) model->HSM2_lpgd1 = 0.0 ; + if ( !model->HSM2_lndep_Given ) model->HSM2_lndep = 0.0 ; + if ( !model->HSM2_lninv_Given ) model->HSM2_lninv = 0.0 ; + if ( !model->HSM2_lmuecb0_Given ) model->HSM2_lmuecb0 = 0.0 ; + if ( !model->HSM2_lmuecb1_Given ) model->HSM2_lmuecb1 = 0.0 ; + if ( !model->HSM2_lmueph1_Given ) model->HSM2_lmueph1 = 0.0 ; + if ( !model->HSM2_lvtmp_Given ) model->HSM2_lvtmp = 0.0 ; + if ( !model->HSM2_lwvth0_Given ) model->HSM2_lwvth0 = 0.0 ; + if ( !model->HSM2_lmuesr1_Given ) model->HSM2_lmuesr1 = 0.0 ; + if ( !model->HSM2_lmuetmp_Given ) model->HSM2_lmuetmp = 0.0 ; + if ( !model->HSM2_lsub1_Given ) model->HSM2_lsub1 = 0.0 ; + if ( !model->HSM2_lsub2_Given ) model->HSM2_lsub2 = 0.0 ; + if ( !model->HSM2_lsvds_Given ) model->HSM2_lsvds = 0.0 ; + if ( !model->HSM2_lsvbs_Given ) model->HSM2_lsvbs = 0.0 ; + if ( !model->HSM2_lsvgs_Given ) model->HSM2_lsvgs = 0.0 ; + if ( !model->HSM2_lnsti_Given ) model->HSM2_lnsti = 0.0 ; + if ( !model->HSM2_lwsti_Given ) model->HSM2_lwsti = 0.0 ; + if ( !model->HSM2_lscsti1_Given ) model->HSM2_lscsti1 = 0.0 ; + if ( !model->HSM2_lscsti2_Given ) model->HSM2_lscsti2 = 0.0 ; + if ( !model->HSM2_lvthsti_Given ) model->HSM2_lvthsti = 0.0 ; + if ( !model->HSM2_lmuesti1_Given ) model->HSM2_lmuesti1 = 0.0 ; + if ( !model->HSM2_lmuesti2_Given ) model->HSM2_lmuesti2 = 0.0 ; + if ( !model->HSM2_lmuesti3_Given ) model->HSM2_lmuesti3 = 0.0 ; + if ( !model->HSM2_lnsubpsti1_Given ) model->HSM2_lnsubpsti1 = 0.0 ; + if ( !model->HSM2_lnsubpsti2_Given ) model->HSM2_lnsubpsti2 = 0.0 ; + if ( !model->HSM2_lnsubpsti3_Given ) model->HSM2_lnsubpsti3 = 0.0 ; + if ( !model->HSM2_lcgso_Given ) model->HSM2_lcgso = 0.0 ; + if ( !model->HSM2_lcgdo_Given ) model->HSM2_lcgdo = 0.0 ; + if ( !model->HSM2_ljs0_Given ) model->HSM2_ljs0 = 0.0 ; + if ( !model->HSM2_ljs0sw_Given ) model->HSM2_ljs0sw = 0.0 ; + if ( !model->HSM2_lnj_Given ) model->HSM2_lnj = 0.0 ; + if ( !model->HSM2_lcisbk_Given ) model->HSM2_lcisbk = 0.0 ; + if ( !model->HSM2_lclm1_Given ) model->HSM2_lclm1 = 0.0 ; + if ( !model->HSM2_lclm2_Given ) model->HSM2_lclm2 = 0.0 ; + if ( !model->HSM2_lclm3_Given ) model->HSM2_lclm3 = 0.0 ; + if ( !model->HSM2_lwfc_Given ) model->HSM2_lwfc = 0.0 ; + if ( !model->HSM2_lgidl1_Given ) model->HSM2_lgidl1 = 0.0 ; + if ( !model->HSM2_lgidl2_Given ) model->HSM2_lgidl2 = 0.0 ; + if ( !model->HSM2_lgleak1_Given ) model->HSM2_lgleak1 = 0.0 ; + if ( !model->HSM2_lgleak2_Given ) model->HSM2_lgleak2 = 0.0 ; + if ( !model->HSM2_lgleak3_Given ) model->HSM2_lgleak3 = 0.0 ; + if ( !model->HSM2_lgleak6_Given ) model->HSM2_lgleak6 = 0.0 ; + if ( !model->HSM2_lglksd1_Given ) model->HSM2_lglksd1 = 0.0 ; + if ( !model->HSM2_lglksd2_Given ) model->HSM2_lglksd2 = 0.0 ; + if ( !model->HSM2_lglkb1_Given ) model->HSM2_lglkb1 = 0.0 ; + if ( !model->HSM2_lglkb2_Given ) model->HSM2_lglkb2 = 0.0 ; + if ( !model->HSM2_lnftrp_Given ) model->HSM2_lnftrp = 0.0 ; + if ( !model->HSM2_lnfalp_Given ) model->HSM2_lnfalp = 0.0 ; + if ( !model->HSM2_lvdiffj_Given ) model->HSM2_lvdiffj = 0.0 ; + if ( !model->HSM2_libpc1_Given ) model->HSM2_libpc1 = 0.0 ; + if ( !model->HSM2_libpc2_Given ) model->HSM2_libpc2 = 0.0 ; + + /* Width dependence */ + if ( !model->HSM2_wvmax_Given ) model->HSM2_wvmax = 0.0 ; + if ( !model->HSM2_wbgtmp1_Given ) model->HSM2_wbgtmp1 = 0.0 ; + if ( !model->HSM2_wbgtmp2_Given ) model->HSM2_wbgtmp2 = 0.0 ; + if ( !model->HSM2_weg0_Given ) model->HSM2_weg0 = 0.0 ; + if ( !model->HSM2_wlover_Given ) model->HSM2_wlover = 0.0 ; + if ( !model->HSM2_wvfbover_Given ) model->HSM2_wvfbover = 0.0 ; + if ( !model->HSM2_wnover_Given ) model->HSM2_wnover = 0.0 ; + if ( !model->HSM2_wwl2_Given ) model->HSM2_wwl2 = 0.0 ; + if ( !model->HSM2_wvfbc_Given ) model->HSM2_wvfbc = 0.0 ; + if ( !model->HSM2_wnsubc_Given ) model->HSM2_wnsubc = 0.0 ; + if ( !model->HSM2_wnsubp_Given ) model->HSM2_wnsubp = 0.0 ; + if ( !model->HSM2_wscp1_Given ) model->HSM2_wscp1 = 0.0 ; + if ( !model->HSM2_wscp2_Given ) model->HSM2_wscp2 = 0.0 ; + if ( !model->HSM2_wscp3_Given ) model->HSM2_wscp3 = 0.0 ; + if ( !model->HSM2_wsc1_Given ) model->HSM2_wsc1 = 0.0 ; + if ( !model->HSM2_wsc2_Given ) model->HSM2_wsc2 = 0.0 ; + if ( !model->HSM2_wsc3_Given ) model->HSM2_wsc3 = 0.0 ; + if ( !model->HSM2_wsc4_Given ) model->HSM2_wsc4 = 0.0 ; + if ( !model->HSM2_wpgd1_Given ) model->HSM2_wpgd1 = 0.0 ; + if ( !model->HSM2_wndep_Given ) model->HSM2_wndep = 0.0 ; + if ( !model->HSM2_wninv_Given ) model->HSM2_wninv = 0.0 ; + if ( !model->HSM2_wmuecb0_Given ) model->HSM2_wmuecb0 = 0.0 ; + if ( !model->HSM2_wmuecb1_Given ) model->HSM2_wmuecb1 = 0.0 ; + if ( !model->HSM2_wmueph1_Given ) model->HSM2_wmueph1 = 0.0 ; + if ( !model->HSM2_wvtmp_Given ) model->HSM2_wvtmp = 0.0 ; + if ( !model->HSM2_wwvth0_Given ) model->HSM2_wwvth0 = 0.0 ; + if ( !model->HSM2_wmuesr1_Given ) model->HSM2_wmuesr1 = 0.0 ; + if ( !model->HSM2_wmuetmp_Given ) model->HSM2_wmuetmp = 0.0 ; + if ( !model->HSM2_wsub1_Given ) model->HSM2_wsub1 = 0.0 ; + if ( !model->HSM2_wsub2_Given ) model->HSM2_wsub2 = 0.0 ; + if ( !model->HSM2_wsvds_Given ) model->HSM2_wsvds = 0.0 ; + if ( !model->HSM2_wsvbs_Given ) model->HSM2_wsvbs = 0.0 ; + if ( !model->HSM2_wsvgs_Given ) model->HSM2_wsvgs = 0.0 ; + if ( !model->HSM2_wnsti_Given ) model->HSM2_wnsti = 0.0 ; + if ( !model->HSM2_wwsti_Given ) model->HSM2_wwsti = 0.0 ; + if ( !model->HSM2_wscsti1_Given ) model->HSM2_wscsti1 = 0.0 ; + if ( !model->HSM2_wscsti2_Given ) model->HSM2_wscsti2 = 0.0 ; + if ( !model->HSM2_wvthsti_Given ) model->HSM2_wvthsti = 0.0 ; + if ( !model->HSM2_wmuesti1_Given ) model->HSM2_wmuesti1 = 0.0 ; + if ( !model->HSM2_wmuesti2_Given ) model->HSM2_wmuesti2 = 0.0 ; + if ( !model->HSM2_wmuesti3_Given ) model->HSM2_wmuesti3 = 0.0 ; + if ( !model->HSM2_wnsubpsti1_Given ) model->HSM2_wnsubpsti1 = 0.0 ; + if ( !model->HSM2_wnsubpsti2_Given ) model->HSM2_wnsubpsti2 = 0.0 ; + if ( !model->HSM2_wnsubpsti3_Given ) model->HSM2_wnsubpsti3 = 0.0 ; + if ( !model->HSM2_wcgso_Given ) model->HSM2_wcgso = 0.0 ; + if ( !model->HSM2_wcgdo_Given ) model->HSM2_wcgdo = 0.0 ; + if ( !model->HSM2_wjs0_Given ) model->HSM2_wjs0 = 0.0 ; + if ( !model->HSM2_wjs0sw_Given ) model->HSM2_wjs0sw = 0.0 ; + if ( !model->HSM2_wnj_Given ) model->HSM2_wnj = 0.0 ; + if ( !model->HSM2_wcisbk_Given ) model->HSM2_wcisbk = 0.0 ; + if ( !model->HSM2_wclm1_Given ) model->HSM2_wclm1 = 0.0 ; + if ( !model->HSM2_wclm2_Given ) model->HSM2_wclm2 = 0.0 ; + if ( !model->HSM2_wclm3_Given ) model->HSM2_wclm3 = 0.0 ; + if ( !model->HSM2_wwfc_Given ) model->HSM2_wwfc = 0.0 ; + if ( !model->HSM2_wgidl1_Given ) model->HSM2_wgidl1 = 0.0 ; + if ( !model->HSM2_wgidl2_Given ) model->HSM2_wgidl2 = 0.0 ; + if ( !model->HSM2_wgleak1_Given ) model->HSM2_wgleak1 = 0.0 ; + if ( !model->HSM2_wgleak2_Given ) model->HSM2_wgleak2 = 0.0 ; + if ( !model->HSM2_wgleak3_Given ) model->HSM2_wgleak3 = 0.0 ; + if ( !model->HSM2_wgleak6_Given ) model->HSM2_wgleak6 = 0.0 ; + if ( !model->HSM2_wglksd1_Given ) model->HSM2_wglksd1 = 0.0 ; + if ( !model->HSM2_wglksd2_Given ) model->HSM2_wglksd2 = 0.0 ; + if ( !model->HSM2_wglkb1_Given ) model->HSM2_wglkb1 = 0.0 ; + if ( !model->HSM2_wglkb2_Given ) model->HSM2_wglkb2 = 0.0 ; + if ( !model->HSM2_wnftrp_Given ) model->HSM2_wnftrp = 0.0 ; + if ( !model->HSM2_wnfalp_Given ) model->HSM2_wnfalp = 0.0 ; + if ( !model->HSM2_wvdiffj_Given ) model->HSM2_wvdiffj = 0.0 ; + if ( !model->HSM2_wibpc1_Given ) model->HSM2_wibpc1 = 0.0 ; + if ( !model->HSM2_wibpc2_Given ) model->HSM2_wibpc2 = 0.0 ; + + /* Cross-term dependence */ + if ( !model->HSM2_pvmax_Given ) model->HSM2_pvmax = 0.0 ; + if ( !model->HSM2_pbgtmp1_Given ) model->HSM2_pbgtmp1 = 0.0 ; + if ( !model->HSM2_pbgtmp2_Given ) model->HSM2_pbgtmp2 = 0.0 ; + if ( !model->HSM2_peg0_Given ) model->HSM2_peg0 = 0.0 ; + if ( !model->HSM2_plover_Given ) model->HSM2_plover = 0.0 ; + if ( !model->HSM2_pvfbover_Given ) model->HSM2_pvfbover = 0.0 ; + if ( !model->HSM2_pnover_Given ) model->HSM2_pnover = 0.0 ; + if ( !model->HSM2_pwl2_Given ) model->HSM2_pwl2 = 0.0 ; + if ( !model->HSM2_pvfbc_Given ) model->HSM2_pvfbc = 0.0 ; + if ( !model->HSM2_pnsubc_Given ) model->HSM2_pnsubc = 0.0 ; + if ( !model->HSM2_pnsubp_Given ) model->HSM2_pnsubp = 0.0 ; + if ( !model->HSM2_pscp1_Given ) model->HSM2_pscp1 = 0.0 ; + if ( !model->HSM2_pscp2_Given ) model->HSM2_pscp2 = 0.0 ; + if ( !model->HSM2_pscp3_Given ) model->HSM2_pscp3 = 0.0 ; + if ( !model->HSM2_psc1_Given ) model->HSM2_psc1 = 0.0 ; + if ( !model->HSM2_psc2_Given ) model->HSM2_psc2 = 0.0 ; + if ( !model->HSM2_psc3_Given ) model->HSM2_psc3 = 0.0 ; + if ( !model->HSM2_psc4_Given ) model->HSM2_psc4 = 0.0 ; + if ( !model->HSM2_ppgd1_Given ) model->HSM2_ppgd1 = 0.0 ; + if ( !model->HSM2_pndep_Given ) model->HSM2_pndep = 0.0 ; + if ( !model->HSM2_pninv_Given ) model->HSM2_pninv = 0.0 ; + if ( !model->HSM2_pmuecb0_Given ) model->HSM2_pmuecb0 = 0.0 ; + if ( !model->HSM2_pmuecb1_Given ) model->HSM2_pmuecb1 = 0.0 ; + if ( !model->HSM2_pmueph1_Given ) model->HSM2_pmueph1 = 0.0 ; + if ( !model->HSM2_pvtmp_Given ) model->HSM2_pvtmp = 0.0 ; + if ( !model->HSM2_pwvth0_Given ) model->HSM2_pwvth0 = 0.0 ; + if ( !model->HSM2_pmuesr1_Given ) model->HSM2_pmuesr1 = 0.0 ; + if ( !model->HSM2_pmuetmp_Given ) model->HSM2_pmuetmp = 0.0 ; + if ( !model->HSM2_psub1_Given ) model->HSM2_psub1 = 0.0 ; + if ( !model->HSM2_psub2_Given ) model->HSM2_psub2 = 0.0 ; + if ( !model->HSM2_psvds_Given ) model->HSM2_psvds = 0.0 ; + if ( !model->HSM2_psvbs_Given ) model->HSM2_psvbs = 0.0 ; + if ( !model->HSM2_psvgs_Given ) model->HSM2_psvgs = 0.0 ; + if ( !model->HSM2_pnsti_Given ) model->HSM2_pnsti = 0.0 ; + if ( !model->HSM2_pwsti_Given ) model->HSM2_pwsti = 0.0 ; + if ( !model->HSM2_pscsti1_Given ) model->HSM2_pscsti1 = 0.0 ; + if ( !model->HSM2_pscsti2_Given ) model->HSM2_pscsti2 = 0.0 ; + if ( !model->HSM2_pvthsti_Given ) model->HSM2_pvthsti = 0.0 ; + if ( !model->HSM2_pmuesti1_Given ) model->HSM2_pmuesti1 = 0.0 ; + if ( !model->HSM2_pmuesti2_Given ) model->HSM2_pmuesti2 = 0.0 ; + if ( !model->HSM2_pmuesti3_Given ) model->HSM2_pmuesti3 = 0.0 ; + if ( !model->HSM2_pnsubpsti1_Given ) model->HSM2_pnsubpsti1 = 0.0 ; + if ( !model->HSM2_pnsubpsti2_Given ) model->HSM2_pnsubpsti2 = 0.0 ; + if ( !model->HSM2_pnsubpsti3_Given ) model->HSM2_pnsubpsti3 = 0.0 ; + if ( !model->HSM2_pcgso_Given ) model->HSM2_pcgso = 0.0 ; + if ( !model->HSM2_pcgdo_Given ) model->HSM2_pcgdo = 0.0 ; + if ( !model->HSM2_pjs0_Given ) model->HSM2_pjs0 = 0.0 ; + if ( !model->HSM2_pjs0sw_Given ) model->HSM2_pjs0sw = 0.0 ; + if ( !model->HSM2_pnj_Given ) model->HSM2_pnj = 0.0 ; + if ( !model->HSM2_pcisbk_Given ) model->HSM2_pcisbk = 0.0 ; + if ( !model->HSM2_pclm1_Given ) model->HSM2_pclm1 = 0.0 ; + if ( !model->HSM2_pclm2_Given ) model->HSM2_pclm2 = 0.0 ; + if ( !model->HSM2_pclm3_Given ) model->HSM2_pclm3 = 0.0 ; + if ( !model->HSM2_pwfc_Given ) model->HSM2_pwfc = 0.0 ; + if ( !model->HSM2_pgidl1_Given ) model->HSM2_pgidl1 = 0.0 ; + if ( !model->HSM2_pgidl2_Given ) model->HSM2_pgidl2 = 0.0 ; + if ( !model->HSM2_pgleak1_Given ) model->HSM2_pgleak1 = 0.0 ; + if ( !model->HSM2_pgleak2_Given ) model->HSM2_pgleak2 = 0.0 ; + if ( !model->HSM2_pgleak3_Given ) model->HSM2_pgleak3 = 0.0 ; + if ( !model->HSM2_pgleak6_Given ) model->HSM2_pgleak6 = 0.0 ; + if ( !model->HSM2_pglksd1_Given ) model->HSM2_pglksd1 = 0.0 ; + if ( !model->HSM2_pglksd2_Given ) model->HSM2_pglksd2 = 0.0 ; + if ( !model->HSM2_pglkb1_Given ) model->HSM2_pglkb1 = 0.0 ; + if ( !model->HSM2_pglkb2_Given ) model->HSM2_pglkb2 = 0.0 ; + if ( !model->HSM2_pnftrp_Given ) model->HSM2_pnftrp = 0.0 ; + if ( !model->HSM2_pnfalp_Given ) model->HSM2_pnfalp = 0.0 ; + if ( !model->HSM2_pvdiffj_Given ) model->HSM2_pvdiffj = 0.0 ; + if ( !model->HSM2_pibpc1_Given ) model->HSM2_pibpc1 = 0.0 ; + if ( !model->HSM2_pibpc2_Given ) model->HSM2_pibpc2 = 0.0 ; + + + if ( model->HSM2_corecip == 1 ){ + model->HSM2_sc2 = 0.0 ; model->HSM2_lsc2 = 0.0 ; model->HSM2_wsc2 = 0.0 ; model->HSM2_psc2 = 0.0 ; + model->HSM2_scp2 = 0.0 ; model->HSM2_lscp2 = 0.0 ; model->HSM2_wscp2 = 0.0 ; model->HSM2_pscp2 = 0.0 ; + model->HSM2_sc4 = 0.0 ; + model->HSM2_coqy = 0 ; + } + + + + /* loop through all the instances of the model */ + for ( here = model->HSM2instances ;here != NULL ; + here = here->HSM2nextInstance ) { + /* allocate a chunk of the state vector */ + here->HSM2states = *states; + if (model->HSM2_conqs) + *states += HSM2numStatesNqs; + else + *states += HSM2numStates; + + /* perform the parameter defaulting */ + if ( !here->HSM2_l_Given ) here->HSM2_l = 5.0e-6 ; + if ( !here->HSM2_w_Given ) here->HSM2_w = 5.0e-6 ; + if ( !here->HSM2_ad_Given ) here->HSM2_ad = 0.0 ; + if ( !here->HSM2_as_Given ) here->HSM2_as = 0.0 ; + if ( !here->HSM2_pd_Given ) here->HSM2_pd = 0.0 ; + if ( !here->HSM2_ps_Given ) here->HSM2_ps = 0.0 ; + if ( !here->HSM2_nrd_Given ) here->HSM2_nrd = 1.0 ; + if ( !here->HSM2_nrs_Given ) here->HSM2_nrs = 1.0 ; + if ( !here->HSM2_ngcon_Given ) here->HSM2_ngcon = 1.0 ; + if ( !here->HSM2_xgw_Given ) here->HSM2_xgw = 0e0 ; + if ( !here->HSM2_xgl_Given ) here->HSM2_xgl = 0e0 ; + if ( !here->HSM2_nf_Given ) here->HSM2_nf = 1.0 ; + if ( !here->HSM2_sa_Given ) here->HSM2_sa = 0 ; + if ( !here->HSM2_sb_Given ) here->HSM2_sb = 0 ; + if ( !here->HSM2_sd_Given ) here->HSM2_sd = 0 ; + if ( !here->HSM2_temp_Given ) here->HSM2_temp = 27.0 ; /* [C] */ + if ( !here->HSM2_dtemp_Given ) here->HSM2_dtemp = 0.0 ; + + if ( !here->HSM2_icVBS_Given ) here->HSM2_icVBS = 0.0; + if ( !here->HSM2_icVDS_Given ) here->HSM2_icVDS = 0.0; + if ( !here->HSM2_icVGS_Given ) here->HSM2_icVGS = 0.0; + + if ( !here->HSM2_corbnet_Given ) + here->HSM2_corbnet = model->HSM2_corbnet ; + else if ( here->HSM2_corbnet != 0 && here->HSM2_corbnet != 1 ) { + here->HSM2_corbnet = model->HSM2_corbnet ; + printf("warning(HiSIM2): CORBNET has been set to its default value: %d.\n", here->HSM2_corbnet); + } + if ( !here->HSM2_rbdb_Given) here->HSM2_rbdb = model->HSM2_rbdb; /* in ohm */ + if ( !here->HSM2_rbsb_Given) here->HSM2_rbsb = model->HSM2_rbsb; + if ( !here->HSM2_rbpb_Given) here->HSM2_rbpb = model->HSM2_rbpb; + if ( !here->HSM2_rbps_Given) here->HSM2_rbps = model->HSM2_rbps; + if ( !here->HSM2_rbpd_Given) here->HSM2_rbpd = model->HSM2_rbpd; + + if ( !here->HSM2_corg_Given ) + here->HSM2_corg = model->HSM2_corg ; + else if ( here->HSM2_corg != 0 && here->HSM2_corg != 1 ) { + here->HSM2_corg = model->HSM2_corg ; + printf("warning(HiSIM2): CORG has been set to its default value: %d.\n", here->HSM2_corg); + } + + if ( !here->HSM2_mphdfm_Given ) here->HSM2_mphdfm = model->HSM2_mphdfm ; + if ( !here->HSM2_m_Given ) here->HSM2_m = 1.0 ; + + + + + /* process drain series resistance */ + if ((model->HSM2_corsrd < 0 && + (model->HSM2_rsh > 0.0 || model->HSM2_rd > 0.0)) && here->HSM2dNodePrime == 0) { + error = CKTmkVolt(ckt, &tmp, here->HSM2name, "drain"); + if (error) return(error); + here->HSM2dNodePrime = tmp->number; + } else { + here->HSM2dNodePrime = here->HSM2dNode; + } + + /* process source series resistance */ + if ((model->HSM2_corsrd < 0 && + (model->HSM2_rsh > 0.0 || model->HSM2_rs > 0.0)) && here->HSM2sNodePrime == 0) { + error = CKTmkVolt(ckt, &tmp, here->HSM2name, "source"); + if (error) return(error); + here->HSM2sNodePrime = tmp->number; + } else { + here->HSM2sNodePrime = here->HSM2sNode; + } + + /* process gate resistance */ + if ((here->HSM2_corg == 1 && model->HSM2_rshg > 0.0) && here->HSM2gNodePrime == 0) { + error = CKTmkVolt(ckt, &tmp, here->HSM2name, "gate"); + if (error) return(error); + here->HSM2gNodePrime = tmp->number; + } else { + here->HSM2gNodePrime = here->HSM2gNode; + } + + /* internal body nodes for body resistance model */ + if ( here->HSM2_corbnet == 1 ) { + if (here->HSM2dbNode == 0) { + error = CKTmkVolt(ckt, &tmp, here->HSM2name, "dbody"); + if (error) return(error); + here->HSM2dbNode = tmp->number; + } + if (here->HSM2bNodePrime == 0) { + error = CKTmkVolt(ckt, &tmp,here->HSM2name, "body"); + if (error) return(error); + here->HSM2bNodePrime = tmp->number; + } + if (here->HSM2sbNode == 0) { + error = CKTmkVolt(ckt, &tmp, here->HSM2name,"sbody"); + if (error) return(error); + here->HSM2sbNode = tmp->number; + } + } else { + here->HSM2dbNode = here->HSM2bNodePrime = here->HSM2sbNode = here->HSM2bNode; + } + + /* 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);\ +} + + TSTALLOC(HSM2DPbpPtr, HSM2dNodePrime, HSM2bNodePrime) + TSTALLOC(HSM2SPbpPtr, HSM2sNodePrime, HSM2bNodePrime) + TSTALLOC(HSM2GPbpPtr, HSM2gNodePrime, HSM2bNodePrime) + + TSTALLOC(HSM2BPdpPtr, HSM2bNodePrime, HSM2dNodePrime) + TSTALLOC(HSM2BPspPtr, HSM2bNodePrime, HSM2sNodePrime) + TSTALLOC(HSM2BPgpPtr, HSM2bNodePrime, HSM2gNodePrime) + TSTALLOC(HSM2BPbpPtr, HSM2bNodePrime, HSM2bNodePrime) + + TSTALLOC(HSM2DdPtr, HSM2dNode, HSM2dNode) + TSTALLOC(HSM2GPgpPtr, HSM2gNodePrime, HSM2gNodePrime) + TSTALLOC(HSM2SsPtr, HSM2sNode, HSM2sNode) + TSTALLOC(HSM2DPdpPtr, HSM2dNodePrime, HSM2dNodePrime) + TSTALLOC(HSM2SPspPtr, HSM2sNodePrime, HSM2sNodePrime) + TSTALLOC(HSM2DdpPtr, HSM2dNode, HSM2dNodePrime) + TSTALLOC(HSM2GPdpPtr, HSM2gNodePrime, HSM2dNodePrime) + TSTALLOC(HSM2GPspPtr, HSM2gNodePrime, HSM2sNodePrime) + TSTALLOC(HSM2SspPtr, HSM2sNode, HSM2sNodePrime) + TSTALLOC(HSM2DPspPtr, HSM2dNodePrime, HSM2sNodePrime) + TSTALLOC(HSM2DPdPtr, HSM2dNodePrime, HSM2dNode) + TSTALLOC(HSM2DPgpPtr, HSM2dNodePrime, HSM2gNodePrime) + TSTALLOC(HSM2SPgpPtr, HSM2sNodePrime, HSM2gNodePrime) + TSTALLOC(HSM2SPsPtr, HSM2sNodePrime, HSM2sNode) + TSTALLOC(HSM2SPdpPtr, HSM2sNodePrime, HSM2dNodePrime); + + if ( here->HSM2_corg == 1 ) { + TSTALLOC(HSM2GgPtr, HSM2gNode, HSM2gNode); + TSTALLOC(HSM2GgpPtr, HSM2gNode, HSM2gNodePrime); + TSTALLOC(HSM2GPgPtr, HSM2gNodePrime, HSM2gNode); + TSTALLOC(HSM2GdpPtr, HSM2gNode, HSM2dNodePrime); + TSTALLOC(HSM2GspPtr, HSM2gNode, HSM2sNodePrime); + TSTALLOC(HSM2GbpPtr, HSM2gNode, HSM2bNodePrime); + } + + if ( here->HSM2_corbnet == 1 ) { /* consider body resistance net */ + TSTALLOC(HSM2DPdbPtr, HSM2dNodePrime, HSM2dbNode); + TSTALLOC(HSM2SPsbPtr, HSM2sNodePrime, HSM2sbNode); + + TSTALLOC(HSM2DBdpPtr, HSM2dbNode, HSM2dNodePrime); + TSTALLOC(HSM2DBdbPtr, HSM2dbNode, HSM2dbNode); + TSTALLOC(HSM2DBbpPtr, HSM2dbNode, HSM2bNodePrime); + TSTALLOC(HSM2DBbPtr, HSM2dbNode, HSM2bNode); + + TSTALLOC(HSM2BPdbPtr, HSM2bNodePrime, HSM2dbNode); + TSTALLOC(HSM2BPbPtr, HSM2bNodePrime, HSM2bNode); + TSTALLOC(HSM2BPsbPtr, HSM2bNodePrime, HSM2sbNode); + + TSTALLOC(HSM2SBspPtr, HSM2sbNode, HSM2sNodePrime); + TSTALLOC(HSM2SBbpPtr, HSM2sbNode, HSM2bNodePrime); + TSTALLOC(HSM2SBbPtr, HSM2sbNode, HSM2bNode); + TSTALLOC(HSM2SBsbPtr, HSM2sbNode, HSM2sbNode); + + TSTALLOC(HSM2BdbPtr, HSM2bNode, HSM2dbNode); + TSTALLOC(HSM2BbpPtr, HSM2bNode, HSM2bNodePrime); + TSTALLOC(HSM2BsbPtr, HSM2bNode, HSM2sbNode); + TSTALLOC(HSM2BbPtr, HSM2bNode, HSM2bNode); + } + + } + } + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2temp.c b/src/spicelib/devices/hisim2/hsm2temp.c new file mode 100644 index 000000000..5e5c14f3d --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2temp.c @@ -0,0 +1,923 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2temp.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "smpdefs.h" +#include "cktdefs.h" +#include "hsm2def.h" +#include "hsm2evalenv.h" +#include "util.h" +#include "const.h" +#include "sperror.h" +#include "suffix.h" + +#ifdef __STDC__ +#define BINNING(param) pParam->HSM2_##param = model->HSM2_##param \ + + model->HSM2_l##param / Lbin + model->HSM2_w##param / Wbin \ + + model->HSM2_p##param / LWbin ; +#else +#define BINNING(param) pParam->HSM2_/**/param = model->HSM2_/**/param \ + + model->HSM2_l/**/param / Lbin + model->HSM2_w/**/param / Wbin \ + + model->HSM2_p/**/param / LWbin ; +#endif + +#define RANGECHECK(param, min, max, pname) \ + if ( (param) < (min) || (param) > (max) ) { \ + printf("warning(HiSIM2): The model/instance parameter %s (= %e) must be in the range [%e , %e].\n", \ + (pname), (param), (min), (max) ); \ + } + + +/*---------------------------------------------------* +* smoothZero: flooring to zero. +* y = 0.5 ( x + sqrt( x^2 + 4 delta^2 ) ) +*-----------------*/ + +#define Fn_SZtemp( y , x , delta ) { \ + T1 = sqrt ( ( x ) * ( x ) + 4.0 * ( delta ) * ( delta) ) ; \ + y = 0.5 * ( ( x ) + T1 ) ; \ + } + +#define Fn_SUtemp( y , x , xmax , delta ) { \ + T1 = ( xmax ) - ( x ) - ( delta ) ; \ + T2 = sqrt ( T1 * T1 + 4.0 * ( xmax ) * ( delta) ) ; \ + y = ( xmax ) - 0.5 * ( T1 + T2 ) ; \ + } + +#define Fn_SLtemp( y , x , xmin , delta ) { \ + T1 = ( x ) - ( xmin ) - ( delta ) ; \ + T2 = sqrt ( T1 * T1 + 4.0 * ( xmin ) * ( delta ) ) ; \ + y = ( xmin ) + 0.5 * ( T1 + T2 ) ; \ + } + +int HSM2temp(inModel,ckt) + GENmodel *inModel; + CKTcircuit *ckt; +{ + register HSM2model *model = (HSM2model *)inModel ; + register HSM2instance *here ; + HSM2binningParam *pParam ; + double mueph ; + double Leff, dL , LG, Weff, dW , WG , WL , Lgate , Wgate; + double Lbin, Wbin, LWbin ; /* binning */ + double Nsubpp, Nsubps, Nsub, q_Nsub, Nsubb, Npext ; + double Lod_half, Lod_half_ref ; + double MUEPWD = 0.0 ; + double MUEPLD = 0.0 ; + double GDLD = 0.0 ; + double T1, T2, T3 ; + /* temperature-dependent variables */ + double Eg ,TTEMP, beta, Nin; + double js, jssw, js2, jssw2 ; + int i; + + /* declarations for the sc3 clamping part */ + double A, beta_inv, c_eox, cnst0, cnst1, Cox, Cox_inv; + double Denom, dPpg, dVth, dVthLP, dVthLP_dVb, dVthSC, dVthW; + double dVth0, dVth0_dVb, fac1, limVgp_dVbs, Pb20, Ps0, Ps0_dVbs; + double Ps0_min, Qb0, sc3lim, sc3Vbs, sc3Vgs, term1, term2, term3, term4; + double Tox, T0, T1_dVb, T3_dVb, T4, T5, T6, T6_dVb, T8, T8_dVb; + double T9, T9_dVb, Vgp, Vgs_min, Vfb, Vthp, Vth0; + + + for ( ;model ;model = model->HSM2nextModel ) { + + /*-----------------------------------------------------------* + * Range check of model parameters + *-----------------*/ + if ( model->HSM2_tox <= 0 ) { + printf("warning(HiSIM2): TOX = %e\n ", model->HSM2_tox); + printf("warning(HiSIM2): The model parameter TOX must be positive.\n"); + } + RANGECHECK(model->HSM2_xld, 0.0, 50.0e-9, "XLD") ; + RANGECHECK(model->HSM2_xwd, -10.0e-9, 100.0e-9, "XWD") ; + RANGECHECK(model->HSM2_rsh, 0.0, 1.0e-3, "RSH") ; + RANGECHECK(model->HSM2_rshg, 0.0, 100.0, "RSHG") ; + RANGECHECK(model->HSM2_xqy, 10.0e-9, 50.0e-9, "XQY") ; + RANGECHECK(model->HSM2_rs, 0.0, 10.0e-3, "RS") ; + RANGECHECK(model->HSM2_rd, 0.0, 10.0e-3, "RD") ; + RANGECHECK(model->HSM2_vbi, 1.0, 1.2, "VBI") ; + RANGECHECK(model->HSM2_parl2, 0.0, 50.0e-9, "PARL2") ; + RANGECHECK(model->HSM2_lp, 0.0, 300.0e-9, "LP") ; + RANGECHECK(model->HSM2_pgd2, 0.0, 1.5, "PGD2") ; + RANGECHECK(model->HSM2_pgd4, 0.0, 3.0, "PGD4") ; + RANGECHECK(model->HSM2_muecb0lp, 0.0, 2.0, "MUECB0LP") ; + RANGECHECK(model->HSM2_muecb1lp, 0.0, 2.0, "MUECB1LP") ; + RANGECHECK(model->HSM2_mueph0, 0.25, 0.35, "MUEPH0") ; + RANGECHECK(model->HSM2_muesr0, 1.8, 2.2, "MUESR0") ; + RANGECHECK(model->HSM2_lpext, 1.0e-50, 10.0e-6, "LPEXT") ; + RANGECHECK(model->HSM2_npext, 1.0e16, 1.0e18, "NPEXT") ; + RANGECHECK(model->HSM2_scp21, 0.0, 5.0, "SCP21") ; + RANGECHECK(model->HSM2_scp22, 0.0, 0.0, "SCP22") ; + RANGECHECK(model->HSM2_bs1, 0.0, 50.0e-3, "BS1") ; + RANGECHECK(model->HSM2_bs2, 0.5, 1.0, "BS2") ; + if ( model->HSM2_cgbo < 0.0 ) { + printf("warning(HiSIM2): %s = %e\n", "CGBO", model->HSM2_cgbo ); + printf("warning(HiSIM2): The model parameter %s must not be less than %s.\n", "CGBO", "0.0" ); + } + RANGECHECK(model->HSM2_clm5, 0.0, 2.0, "CLM5") ; + RANGECHECK(model->HSM2_clm6, 0.0, 20.0, "CLM6") ; + RANGECHECK(model->HSM2_vover, 0.0, 50.0, "VOVER") ; + RANGECHECK(model->HSM2_voverp, 0.0, 2.0, "VOVERP") ; + RANGECHECK(model->HSM2_qme1, 0.0, 300.0e-9, "QME1") ; + RANGECHECK(model->HSM2_qme3, 0.0,800.0e-12, "QME3") ; + RANGECHECK(model->HSM2_tnom, 22.0, 32.0, "TNOM") ; + RANGECHECK(model->HSM2_ddltmax, 1.0, 20.0, "DDLTMAX") ; + RANGECHECK(model->HSM2_ddltict, -3.0, 20.0, "DDLTICT") ; + RANGECHECK(model->HSM2_ddltslp, 0.0, 20.0, "DDLTSLP") ; + RANGECHECK(model->HSM2_cvb, -0.1, 0.2, "CVB") ; + RANGECHECK(model->HSM2_cvbk, -0.1, 0.2, "CVBK") ; + RANGECHECK(model->HSM2_byptol, 0.0, 1.0, "BYPTOL") ; + RANGECHECK(model->HSM2_sc3Vbs, -3.0, 0.0, "SC3VBS") ; + + /*-----------------------------------------------------------* + * Change units into CGS. + *-----------------*/ + model->HSM2_tox *= C_m2cm ; + model->HSM2_xld *= C_m2cm ; + model->HSM2_xwd *= C_m2cm ; + model->HSM2_xqy *= C_m2cm ; + model->HSM2_xl *= C_m2cm ; + model->HSM2_xw *= C_m2cm ; + model->HSM2_saref *= C_m2cm ; + model->HSM2_sbref *= C_m2cm ; + model->HSM2_ll *= C_m2cm ; + model->HSM2_lld *= C_m2cm ; + model->HSM2_wl *= C_m2cm ; + model->HSM2_wld *= C_m2cm ; + model->HSM2_lp *= C_m2cm ; + model->HSM2_tpoly *= C_m2cm ; + model->HSM2_parl2 *= C_m2cm ; + model->HSM2_qme1 *= C_m2cm ; + model->HSM2_qme3 *= C_m2cm ; + model->HSM2_cgbo /= C_m2cm ; + model->HSM2_cj /= C_m2cm_p2 ; + model->HSM2_cjsw /= C_m2cm ; + model->HSM2_cjswg /= C_m2cm ; + model->HSM2_lpext *= C_m2cm ; + model->HSM2_wl1 *= C_m2cm ; + model->HSM2_rs *= C_m2cm ; + model->HSM2_rd *= C_m2cm ; + GDLD = model->HSM2_gdld * C_m2um ; + + /*-----------------------------------------------------------* + * Change unit into Kelvin. + *-----------------*/ + model->HSM2_tnom += 273.15 ; /* [C] -> [K] */ + + + /* SourceSatCurrent = 1.0e-14 */ + /* DrainSatCurrent = 1.0e-14 */ + model->HSM2_vcrit = CONSTvt0 * log( CONSTvt0 / (CONSTroot2 * 1.0e-14) ) ; + + /* Quantum Mechanical Effect */ + if ( ( model->HSM2_qme1 == 0.0 && model->HSM2_qme3 == 0.0 ) || model->HSM2_qme2 == 0.0 ) { + model->HSM2_flg_qme = 0 ; + } else { + model->HSM2_flg_qme = 1 ; + model->HSM2_qme12 = model->HSM2_qme1 / ( model->HSM2_qme2 * model->HSM2_qme2 ) ; + } + + for ( here = model->HSM2instances; here; here = here->HSM2nextInstance ) { + pParam = &here->pParam ; + + /*-----------------------------------------------------------* + * Range check of instance parameters + *-----------------*/ + RANGECHECK(here->HSM2_l, model->HSM2_lmin, model->HSM2_lmax, "L") ; + RANGECHECK(here->HSM2_w, model->HSM2_wmin, model->HSM2_wmax, "W") ; + RANGECHECK(here->HSM2_mphdfm, -3.0, 3.0, "MPHDFM") ; + + /*-----------------------------------------------------------* + * Change units into CGS. + *-----------------*/ + here->HSM2_l *= C_m2cm ; + here->HSM2_w *= C_m2cm ; + here->HSM2_as *= C_m2cm_p2 ; + here->HSM2_ad *= C_m2cm_p2 ; + here->HSM2_ps *= C_m2cm ; + here->HSM2_pd *= C_m2cm ; + here->HSM2_xgw *= C_m2cm ; + here->HSM2_xgl *= C_m2cm ; + here->HSM2_sa *= C_m2cm ; + here->HSM2_sb *= C_m2cm ; + here->HSM2_sd *= C_m2cm ; + /*-----------------------------------------------------------* + * Change unit into Kelvin. + *-----------------*/ + here->HSM2_temp += 273.15 ; /* [C] -> [K] */ + + + here->HSM2_lgate = Lgate = here->HSM2_l + model->HSM2_xl ; + Wgate = here->HSM2_w / here->HSM2_nf + model->HSM2_xw ; + + LG = Lgate * 1.0e4 ; + here->HSM2_wg = WG = Wgate * 1.0e4 ; + WL = WG * LG ; + MUEPWD = model->HSM2_muepwd * C_m2um ; + MUEPLD = model->HSM2_muepld * C_m2um ; + + /* binning calculation */ + Lbin = pow(LG, model->HSM2_lbinn) ; + Wbin = pow(WG, model->HSM2_wbinn) ; + LWbin = Lbin * Wbin ; + + BINNING(vmax) + BINNING(bgtmp1) + BINNING(bgtmp2) + BINNING(eg0) + BINNING(lover) + BINNING(vfbover) + BINNING(nover) + BINNING(wl2) + BINNING(vfbc) + BINNING(nsubc) + BINNING(nsubp) + BINNING(scp1) + BINNING(scp2) + BINNING(scp3) + BINNING(sc1) + BINNING(sc2) + BINNING(sc3) + BINNING(sc4) + BINNING(pgd1) + BINNING(ndep) + BINNING(ninv) + BINNING(muecb0) + BINNING(muecb1) + BINNING(mueph1) + BINNING(vtmp) + BINNING(wvth0) + BINNING(muesr1) + BINNING(muetmp) + BINNING(sub1) + BINNING(sub2) + BINNING(svds) + BINNING(svbs) + BINNING(svgs) + BINNING(nsti) + BINNING(wsti) + BINNING(scsti1) + BINNING(scsti2) + BINNING(vthsti) + BINNING(muesti1) + BINNING(muesti2) + BINNING(muesti3) + BINNING(nsubpsti1) + BINNING(nsubpsti2) + BINNING(nsubpsti3) + BINNING(cgso) + BINNING(cgdo) + BINNING(js0) + BINNING(js0sw) + BINNING(nj) + BINNING(cisbk) + BINNING(clm1) + BINNING(clm2) + BINNING(clm3) + BINNING(wfc) + BINNING(gidl1) + BINNING(gidl2) + BINNING(gleak1) + BINNING(gleak2) + BINNING(gleak3) + BINNING(gleak6) + BINNING(glksd1) + BINNING(glksd2) + BINNING(glkb1) + BINNING(glkb2) + BINNING(nftrp) + BINNING(nfalp) + BINNING(vdiffj) + BINNING(ibpc1) + BINNING(ibpc2) + + /*-----------------------------------------------------------* + * Range check of model parameters + *-----------------*/ + RANGECHECK(pParam->HSM2_vmax, 1.0e5, 20.0e6, "VMAX") ; + RANGECHECK(pParam->HSM2_bgtmp1, 50.0e-6, 1.0e-3, "BGTMP1") ; + RANGECHECK(pParam->HSM2_bgtmp2, -1.0e-6, 1.0e-6, "BGTMP2") ; + RANGECHECK(pParam->HSM2_eg0, 1.0, 1.3, "EG0") ; + RANGECHECK(pParam->HSM2_vfbc, -1.2, -0.8, "VFBC") ; + RANGECHECK(pParam->HSM2_vfbover, -0.2, 0.2, "VFBOVER") ; + RANGECHECK(pParam->HSM2_nsubc, 1.0e16, 1.0e19, "NSUBC") ; + RANGECHECK(pParam->HSM2_nsubp, 1.0e16, 1.0e19, "NSUBP") ; + RANGECHECK(pParam->HSM2_scp1, 0.0, 20.0, "SCP1") ; + RANGECHECK(pParam->HSM2_scp2, 0.0, 2.0, "SCP2") ; + RANGECHECK(pParam->HSM2_scp3, 0.0, 100.0e-9, "SCP3") ; + RANGECHECK(pParam->HSM2_sc1, 0.0, 20.0, "SC1") ; + RANGECHECK(pParam->HSM2_sc2, 0.0, 2.0, "SC2") ; + RANGECHECK(pParam->HSM2_sc3, 0.0, 200.0e-9, "SC3") ; + RANGECHECK(pParam->HSM2_pgd1, 0.0, 50.0e-3, "PGD1") ; + RANGECHECK(pParam->HSM2_ndep, 0.0, 1.0, "NDEP") ; + RANGECHECK(pParam->HSM2_ninv, 0.0, 1.0, "NINV") ; + RANGECHECK(pParam->HSM2_muecb0, 100.0, 100.0e3, "MUECB0") ; + RANGECHECK(pParam->HSM2_muecb1, 5.0, 1.0e4, "MUECB1") ; + RANGECHECK(pParam->HSM2_mueph1, 2.0e3, 35.0e3, "MUEPH1") ; + RANGECHECK(pParam->HSM2_vtmp, -5.0, 1.0, "VTMP") ; + RANGECHECK(pParam->HSM2_muesr1, 1.0e13, 1.0e16, "MUESR1") ; + RANGECHECK(pParam->HSM2_muetmp, 0.5, 2.0, "MUETMP") ; + RANGECHECK(pParam->HSM2_clm1, 0.5, 1.0, "CLM1") ; + RANGECHECK(pParam->HSM2_clm2, 1.0, 4.0, "CLM2") ; + RANGECHECK(pParam->HSM2_clm3, 0.5, 5.0, "CLM3") ; + RANGECHECK(pParam->HSM2_wfc, -5.0e-15, 1.0e-6, "WFC") ; + RANGECHECK(pParam->HSM2_cgso, 0.0, 100e-9 * 100*C_VAC*model->HSM2_kappa/model->HSM2_tox*C_m2cm, "CGSO") ; + RANGECHECK(pParam->HSM2_cgdo, 0.0, 100e-9 * 100*C_VAC*model->HSM2_kappa/model->HSM2_tox*C_m2cm, "CGDO") ; + RANGECHECK(pParam->HSM2_ibpc1, 0.0, 1.0e12, "IBPC1") ; + RANGECHECK(pParam->HSM2_ibpc2, 0.0, 1.0e12, "IBPC2") ; + RANGECHECK(pParam->HSM2_nsti, 1.0e16, 1.0e19, "NSTI") ; + + /*-----------------------------------------------------------* + * Change units into CGS. + *-----------------*/ + pParam->HSM2_lover *= C_m2cm ; + pParam->HSM2_sc3 *= C_m2cm ; + pParam->HSM2_scp3 *= C_m2cm ; + pParam->HSM2_wfc *= C_m2cm ; + pParam->HSM2_wsti *= C_m2cm ; + pParam->HSM2_gidl1 *= C_m2cm_p1o2 ; + pParam->HSM2_cgso /= C_m2cm ; + pParam->HSM2_cgdo /= C_m2cm ; + pParam->HSM2_js0 /= C_m2cm_p2 ; + pParam->HSM2_js0sw /= C_m2cm ; + + /* Band gap */ + here->HSM2_egtnom = pParam->HSM2_eg0 - model->HSM2_tnom + * ( 90.25e-6 + model->HSM2_tnom * 1.0e-7 ) ; + + /* C_EOX */ + here->HSM2_cecox = C_VAC * model->HSM2_kappa ; + + /* Vth reduction for small Vds */ + here->HSM2_msc = model->HSM2_scp22 ; + + /* Poly-Si Gate Depletion */ + if ( pParam->HSM2_pgd1 == 0.0 ) { + here->HSM2_flg_pgd = 0 ; + } else { + here->HSM2_flg_pgd = 1 ; + } + + + /* CLM5 & CLM6 */ + here->HSM2_clmmod = 1e0 + pow( LG , model->HSM2_clm5 ) * model->HSM2_clm6 ; + + /* Half length of diffusion */ + T1 = 1.0 / (model->HSM2_saref + 0.5 * here->HSM2_l) + + 1.0 / (model->HSM2_sbref + 0.5 * here->HSM2_l); + Lod_half_ref = 2.0 / T1 ; + + if (here->HSM2_sa > 0.0 && here->HSM2_sb > 0.0 && + (here->HSM2_nf == 1.0 || + (here->HSM2_nf > 1.0 && here->HSM2_sd > 0.0))) { + T1 = 0.0; + for (i = 0; i < here->HSM2_nf; i++) { + T1 += 1.0 / (here->HSM2_sa + 0.5 * here->HSM2_l + + i * (here->HSM2_sd + here->HSM2_l)) + + 1.0 / (here->HSM2_sb + 0.5 * here->HSM2_l + + i * (here->HSM2_sd + here->HSM2_l)); + } + Lod_half = 2.0 * here->HSM2_nf / T1; + } else { + Lod_half = 0.0; + } + + Npext = model->HSM2_npext * ( 1.0 + model->HSM2_npextw / pow( WG, model->HSM2_npextwp ) ); /* new */ + + /* DFM */ + if ( model->HSM2_codfm == 1 && here->HSM2_nsubcdfm_Given ) { + RANGECHECK(here->HSM2_nsubcdfm, 1.0e16, 1.0e19, "NSUBCDFM") ; + pParam->HSM2_mueph1 *= here->HSM2_mphdfm + * ( log(here->HSM2_nsubcdfm) - log(pParam->HSM2_nsubc) ) + 1.0 ; + pParam->HSM2_nsubp += here->HSM2_nsubcdfm - pParam->HSM2_nsubc ; + Npext += here->HSM2_nsubcdfm - pParam->HSM2_nsubc ; + pParam->HSM2_nsubc = here->HSM2_nsubcdfm ; + } + + /* Coulomb Scattering */ + here->HSM2_muecb0 = pParam->HSM2_muecb0 * pow( LG, model->HSM2_muecb0lp ); + here->HSM2_muecb1 = pParam->HSM2_muecb1 * pow( LG, model->HSM2_muecb1lp ); + + /* Phonon Scattering (temperature-independent part) */ + mueph = pParam->HSM2_mueph1 + * (1.0e0 + (model->HSM2_muephw / pow( WG + MUEPWD , model->HSM2_muepwp))) + * (1.0e0 + (model->HSM2_muephl / pow( LG + MUEPLD , model->HSM2_mueplp))) + * (1.0e0 + (model->HSM2_muephw2 / pow( WG, model->HSM2_muepwp2))) + * (1.0e0 + (model->HSM2_muephl2 / pow( LG, model->HSM2_mueplp2))) + * (1.0e0 + (model->HSM2_muephs / pow( WL, model->HSM2_muepsp))); + if (Lod_half > 0.0) { + T1 = 1.0e0 / (1.0e0 + pParam->HSM2_muesti2) ; + T2 = pow (pParam->HSM2_muesti1 / Lod_half, pParam->HSM2_muesti3) ; + T3 = pow (pParam->HSM2_muesti1 / Lod_half_ref, pParam->HSM2_muesti3) ; + here->HSM2_mueph = mueph * (1.0e0 + T1 * T2) / (1.0e0 + T1 * T3); + } else { + here->HSM2_mueph = mueph; + } + + /* Surface Roughness Scattering */ + here->HSM2_muesr = model->HSM2_muesr0 + * (1.0e0 + (model->HSM2_muesrl / pow (LG, model->HSM2_mueslp))) + * (1.0e0 + (model->HSM2_muesrw / pow (WG, model->HSM2_mueswp))) ; + + /* Coefficients of Qbm for Eeff */ + T1 = pow( LG, model->HSM2_ndeplp ) ; + T2 = pow( WG, model->HSM2_ndepwp ) ; /* new */ + T3 = T1 + model->HSM2_ndepl ; + T4 = T2 + model->HSM2_ndepw ; + if( T3 < 1e-8 ) { T3 = 1e-8; } + if( T4 < 1e-8 ) { T4 = 1e-8; } + here->HSM2_ndep_o_esi = ( pParam->HSM2_ndep * T1 ) / T3 * T2 / T4 + / C_ESI ; + here->HSM2_ninv_o_esi = pParam->HSM2_ninv / C_ESI ; + + /* Metallurgical channel geometry */ + dL = model->HSM2_xld + + (model->HSM2_ll / pow (Lgate + model->HSM2_lld, model->HSM2_lln)) ; + dW = model->HSM2_xwd + + (model->HSM2_wl / pow (Wgate + model->HSM2_wld, model->HSM2_wln)) ; + + Leff = Lgate - 2.0e0 * dL ; + if ( Leff <= 1.0e-7 ) { + IFuid namarr[2]; + namarr[0] = model->HSM2modName; + namarr[1] = here->HSM2name; + (*(SPfrontEnd->IFerror)) + ( + ERR_FATAL, + "HiSIM2: MOSFET(%s) MODEL(%s): effective channel length is smaller than 1nm", + namarr + ); + return (E_BADPARM); + } + here->HSM2_leff = Leff ; + + /* Wg dependence for short channel devices */ + here->HSM2_lgatesm = Lgate + model->HSM2_wl1 / pow( WL , model->HSM2_wl1p ) ; + here->HSM2_dVthsm = pParam->HSM2_wl2 / pow( WL , model->HSM2_wl2p ) ; + + /* Lg dependence of wsti */ + T1 = 1.0e0 + model->HSM2_wstil / pow( here->HSM2_lgatesm * 1e4 , model->HSM2_wstilp ) ; + T2 = 1.0e0 + model->HSM2_wstiw / pow( WG , model->HSM2_wstiwp ) ; + here->HSM2_wsti = pParam->HSM2_wsti * T1 * T2 ; + + here->HSM2_weff = Weff = Wgate - 2.0e0 * dW ; + if ( Weff <= 0.0 ) { + IFuid namarr[2]; + namarr[0] = model->HSM2modName; + namarr[1] = here->HSM2name; + (*(SPfrontEnd->IFerror)) + ( + ERR_FATAL, + "HiSIM2: MOSFET(%s) MODEL(%s): effective channel width is negative or 0", + namarr + ); + return (E_BADPARM); + } + here->HSM2_weff_nf = Weff * here->HSM2_nf ; + + /* Surface impurity profile */ + + T1 = 2.0 * ( 1.0 - model->HSM2_nsubpfac ) / model->HSM2_nsubpl * LG + 2.0 * model->HSM2_nsubpfac - 1.0 ; + Fn_SUtemp( T1 , T1 , 1 , 0.01 ) ; + Fn_SLtemp( T1 , T1 , model->HSM2_nsubpfac , 0.01 ) ; + pParam->HSM2_nsubp *= T1 ; + + /* Note: Sign Changed --> */ + Nsubpp = pParam->HSM2_nsubp + * (1.0e0 + (model->HSM2_nsubpw / pow (WG, model->HSM2_nsubpwp))) ; + /* <-- Note: Sign Changed */ + + if (Lod_half > 0.0) { + T1 = 1.0e0 / (1.0e0 + pParam->HSM2_nsubpsti2) ; + T2 = pow (pParam->HSM2_nsubpsti1 / Lod_half, pParam->HSM2_nsubpsti3) ; + T3 = pow (pParam->HSM2_nsubpsti1 / Lod_half_ref, pParam->HSM2_nsubpsti3) ; + Nsubps = Nsubpp * (1.0e0 + T1 * T2) / (1.0e0 + T1 * T3) ; + } else { + Nsubps = Nsubpp ; + } + + T2 = 1.0e0 + ( model->HSM2_nsubcw / pow ( WG, model->HSM2_nsubcwp )) ; + T2 *= 1.0e0 + ( model->HSM2_nsubcw2 / pow ( WG, model->HSM2_nsubcwp2 )) ; + T3 = model->HSM2_nsubcmax / pParam->HSM2_nsubc ; + + Fn_SUtemp( T1 , T2 , T3 , 0.01 ) ; + pParam->HSM2_nsubc *= T1 ; + + if ( pParam->HSM2_nsubc <= 0.0 ) { + fprintf ( stderr , "*** warning(HiSIM): actual NSUBC value is negative -> reset to 1E+15.\n" ) ; + fprintf ( stderr , " The model parameter NSUBCW/NSUBCWP and/or NSUBCW2/NSUBCW2P might be wrong.\n" ) ; + pParam->HSM2_nsubc = 1e15 ; + } + if(Npext < pParam->HSM2_nsubc || Npext > pParam->HSM2_nsubp) { + fprintf ( stderr , "*** warning(HiSIM): actual NPEXT value is smaller than NSUBC and/or greater than NSUBP.\n" ) ; + fprintf ( stderr , " ( Npext = %e , NSUBC = %e , NSUBP = %e ) \n",Npext,pParam->HSM2_nsubc,pParam->HSM2_nsubp); + fprintf ( stderr , " The model parameter NPEXTW and/or NPEXTWP might be wrong.\n" ) ; + } + + if( Lgate > model->HSM2_lp ){ + Nsub = (pParam->HSM2_nsubc * (Lgate - model->HSM2_lp) + + Nsubps * model->HSM2_lp) / Lgate ; + } else { + Nsub = Nsubps + + (Nsubps - pParam->HSM2_nsubc) * (model->HSM2_lp - Lgate) + / model->HSM2_lp ; + } + T3 = 0.5e0 * Lgate - model->HSM2_lp ; + Fn_SZtemp( T3 , T3 , 1e-8 ) ; + T1 = Fn_Max(0.0e0, model->HSM2_lpext ) ; + T2 = T3 * T1 / ( T3 + T1 ) ; + + here->HSM2_nsub = + Nsub = Nsub + T2 * (Npext - pParam->HSM2_nsubc) / Lgate ; + here->HSM2_qnsub = q_Nsub = C_QE * Nsub ; + here->HSM2_qnsub_esi = q_Nsub * C_ESI ; + here->HSM2_2qnsub_esi = 2.0 * here->HSM2_qnsub_esi ; + + /* Pocket Overlap (temperature-independent part) */ + if ( Lgate <= 2.0e0 * model->HSM2_lp ) { + Nsubb = 2.0e0 * Nsubps + - (Nsubps - pParam->HSM2_nsubc) * Lgate + / model->HSM2_lp - pParam->HSM2_nsubc ; + here->HSM2_ptovr0 = log (Nsubb / pParam->HSM2_nsubc) ; + } else { + here->HSM2_ptovr0 = 0.0e0 ; + } + + /* costi0 and costi1 for STI transistor model (temperature-independent part) */ + here->HSM2_costi00 = sqrt (2.0 * C_QE * pParam->HSM2_nsti * C_ESI ) ; + here->HSM2_nsti_p2 = 1.0 / ( pParam->HSM2_nsti * pParam->HSM2_nsti ) ; + + /* Velocity Temperature Dependence (Temperature-dependent part will be multiplied later.) */ + here->HSM2_vmax0 = (1.0e0 + (model->HSM2_vover / pow (LG, model->HSM2_voverp))) + * (1.0e0 + (model->HSM2_vovers / pow (WL, model->HSM2_voversp))) ; + + /* 2 phi_B (temperature-independent) */ + /* @300K, with pocket */ + here->HSM2_pb20 = 2.0e0 / C_b300 * log (Nsub / C_Nin0) ; + /* @300K, w/o pocket */ + here->HSM2_pb2c = 2.0e0 / C_b300 * log (pParam->HSM2_nsubc / C_Nin0) ; + + + /* constant for Poly depletion */ + here->HSM2_cnstpgd = pow ( 1e0 + 1e0 / LG , model->HSM2_pgd4 ) + * pParam->HSM2_pgd1 ; + + + + + /* Gate resistance */ + if ( here->HSM2_corg == 1 ) { + T1 = here->HSM2_xgw + Weff / (3.0e0 * here->HSM2_ngcon); + T2 = Lgate - here->HSM2_xgl; + here->HSM2_grg = model->HSM2_rshg * T1 / (here->HSM2_ngcon * T2 * here->HSM2_nf); + if (here->HSM2_grg > 1.0e-3) here->HSM2_grg = here->HSM2_m / here->HSM2_grg; + else { + here->HSM2_grg = here->HSM2_m * 1.0e3; + printf("warning(HiSIM2): The gate conductance reset to 1.0e3 mho.\n"); + } + } + + /* Process source/drain series resistamce */ + here->HSM2_rd = 0.0; + if ( model->HSM2_rsh > 0.0 ) { + here->HSM2_rd += model->HSM2_rsh * here->HSM2_nrd ; + } + if ( model->HSM2_rd > 0.0 ) { + here->HSM2_rd += model->HSM2_rd / here->HSM2_weff_nf ; + } + + here->HSM2_rs = 0.0; + if ( model->HSM2_rsh > 0.0 ) { + here->HSM2_rs += model->HSM2_rsh * here->HSM2_nrs ; + } + if ( model->HSM2_rs > 0.0 ) { + here->HSM2_rs += model->HSM2_rs / here->HSM2_weff_nf ; + } + + if (model->HSM2_corsrd < 0) { + if ( here->HSM2_rd > 0.0 ) { + here->HSM2drainConductance = here->HSM2_m / here->HSM2_rd ; + } else { + here->HSM2drainConductance = 0.0; + } + if ( here->HSM2_rs > 0.0 ) { + here->HSM2sourceConductance = here->HSM2_m / here->HSM2_rs ; + } else { + here->HSM2sourceConductance = 0.0; + } + } else if (model->HSM2_corsrd > 0) { + here->HSM2drainConductance = 0.0 ; + here->HSM2sourceConductance = 0.0 ; + if ( here->HSM2_rd > 0.0 && model->HSM2_cothrml != 0 ) { + here->HSM2internalGd = here->HSM2_m / here->HSM2_rd ; + } else { + here->HSM2internalGd = 0.0; + } + if ( here->HSM2_rs > 0.0 && model->HSM2_cothrml != 0 ) { + here->HSM2internalGs = here->HSM2_m / here->HSM2_rs ; + } else { + here->HSM2internalGs = 0.0; + } + } else { + here->HSM2drainConductance = 0.0 ; + here->HSM2sourceConductance = 0.0 ; + } + + + /* Body resistance */ + if ( here->HSM2_corbnet == 1 ) { + if (here->HSM2_rbdb < 1.0e-3) here->HSM2_grbdb = here->HSM2_m * 1.0e3 ; /* in mho */ + else here->HSM2_grbdb = here->HSM2_m * ( model->HSM2_gbmin + 1.0 / here->HSM2_rbdb ) ; + + if (here->HSM2_rbpb < 1.0e-3) here->HSM2_grbpb = here->HSM2_m * 1.0e3 ; + else here->HSM2_grbpb = here->HSM2_m * ( model->HSM2_gbmin + 1.0 / here->HSM2_rbpb ) ; + + if (here->HSM2_rbps < 1.0e-3) here->HSM2_grbps = here->HSM2_m * 1.0e3 ; + else here->HSM2_grbps = here->HSM2_m * ( model->HSM2_gbmin + 1.0 / here->HSM2_rbps ) ; + + if (here->HSM2_rbsb < 1.0e-3) here->HSM2_grbsb = here->HSM2_m * 1.0e3 ; + else here->HSM2_grbsb = here->HSM2_m * ( model->HSM2_gbmin + 1.0 / here->HSM2_rbsb ) ; + + if (here->HSM2_rbpd < 1.0e-3) here->HSM2_grbpd = here->HSM2_m * 1.0e3 ; + else here->HSM2_grbpd = here->HSM2_m * ( model->HSM2_gbmin + 1.0 / here->HSM2_rbpd ) ; + } + + /* Vdseff */ + T1 = model->HSM2_ddltslp * LG + model->HSM2_ddltict ; + here->HSM2_ddlt = T1 * model->HSM2_ddltmax / ( T1 + model->HSM2_ddltmax ) + 1.0 ; + + /* Isub */ + T2 = pow( Weff , model->HSM2_svgswp ) ; + here->HSM2_vg2const = pParam->HSM2_svgs + * ( 1.0e0 + + model->HSM2_svgsl / pow( here->HSM2_lgate , model->HSM2_svgslp ) ) + * ( T2 / ( T2 + model->HSM2_svgsw ) ) ; + + here->HSM2_xvbs = pParam->HSM2_svbs + * ( 1.0e0 + + model->HSM2_svbsl / pow( here->HSM2_lgate , model->HSM2_svbslp ) ) ; + here->HSM2_xgate = model->HSM2_slg + * ( 1.0 + + model->HSM2_slgl / pow( here->HSM2_lgate , model->HSM2_slglp ) ) ; + + here->HSM2_xsub1 = pParam->HSM2_sub1 + * ( 1.0 + + model->HSM2_sub1l / pow( here->HSM2_lgate , model->HSM2_sub1lp ) ) ; + + here->HSM2_xsub2 = pParam->HSM2_sub2 + * ( 1.0 + model->HSM2_sub2l / here->HSM2_lgate ) ; + + /* Fringing capacitance */ + here->HSM2_cfrng = C_EOX / ( C_Pi / 2.0e0 ) * here->HSM2_weff_nf + * log( 1.0e0 + model->HSM2_tpoly / model->HSM2_tox ) ; + + /* Additional term of lateral-field-induced capacitance */ + here->HSM2_cqyb0 = 1.0e4 * here->HSM2_weff_nf + * model->HSM2_xqy1 / pow( LG , model->HSM2_xqy2 ) ; + + /* Parasitic component of the channel current */ + here->HSM2_ptl0 = model->HSM2_ptl * pow( LG , - model->HSM2_ptlp ) ; + here->HSM2_pt40 = model->HSM2_pt4 * pow( LG , - model->HSM2_pt4p ) ; + here->HSM2_gdl0 = model->HSM2_gdl * pow( LG + GDLD , - model->HSM2_gdlp ) ; + + + /*-----------------------------------------------------------* + * Temperature dependent constants. + *-----------------*/ + TTEMP = ckt->CKTtemp ; + if ( here->HSM2_temp_Given ) TTEMP = here->HSM2_temp ; + if ( here->HSM2_dtemp_Given ) { + TTEMP = TTEMP + here->HSM2_dtemp ; + here->HSM2_temp = TTEMP ; + } + + /* Band gap */ + T1 = TTEMP - model->HSM2_tnom ; + T2 = TTEMP * TTEMP - model->HSM2_tnom * model->HSM2_tnom ; + here->HSM2_eg = Eg = here->HSM2_egtnom - pParam->HSM2_bgtmp1 * T1 + - pParam->HSM2_bgtmp2 * T2 ; + here->HSM2_sqrt_eg = sqrt( Eg ) ; + + + T1 = 1.0 / TTEMP ; + T2 = 1.0 / model->HSM2_tnom ; + T3 = here->HSM2_egtnom + model->HSM2_egig + + model->HSM2_igtemp2 * ( T1 - T2 ) + + model->HSM2_igtemp3 * ( T1 * T1 - T2 * T2 ) ; + here->HSM2_egp12 = sqrt ( T3 ) ; + here->HSM2_egp32 = T3 * here->HSM2_egp12 ; + + + /* Inverse of the thermal voltage */ + here->HSM2_beta = beta = C_QE / (C_KB * TTEMP) ; + here->HSM2_beta_inv = 1.0 / beta ; + here->HSM2_beta2 = beta * beta ; + here->HSM2_betatnom = C_QE / (C_KB * model->HSM2_tnom) ; + + /* Intrinsic carrier concentration */ + here->HSM2_nin = Nin = C_Nin0 * pow (TTEMP / model->HSM2_tnom, 1.5e0) + * exp (- Eg / 2.0e0 * beta + here->HSM2_egtnom / 2.0e0 * here->HSM2_betatnom) ; + + + /* Phonon Scattering (temperature-dependent part) */ + T1 = pow (TTEMP / model->HSM2_tnom, pParam->HSM2_muetmp) ; + here->HSM2_mphn0 = T1 / here->HSM2_mueph ; + here->HSM2_mphn1 = here->HSM2_mphn0 * model->HSM2_mueph0 ; + + + /* Pocket Overlap (temperature-dependent part) */ + here->HSM2_ptovr = here->HSM2_ptovr0 / beta ; + + + /* Velocity Temperature Dependence */ + T1 = TTEMP / model->HSM2_tnom ; + here->HSM2_vmax = here->HSM2_vmax0 * pParam->HSM2_vmax + / (1.8 + 0.4 * T1 + 0.1 * T1 * T1 - pParam->HSM2_vtmp * (1.0e0 - T1)) ; + + + /* Coefficient of the F function for bulk charge */ + here->HSM2_cnst0 = sqrt ( 2.0 * C_ESI * C_QE * here->HSM2_nsub / beta ) ; + here->HSM2_cnst0over = here->HSM2_cnst0 * sqrt( pParam->HSM2_nover / here->HSM2_nsub ) ; + + /* 2 phi_B (temperature-dependent) */ + /* @temp, with pocket */ + here->HSM2_pb2 = 2.0e0 / beta * log (here->HSM2_nsub / Nin) ; + if ( pParam->HSM2_nover != 0.0) { + here->HSM2_pb2over = 2.0 / beta * log( pParam->HSM2_nover / Nin ) ; + + /* (1 / cnst1 / cnstCoxi) for Ps0LD_iniB */ + T1 = here->HSM2_cnst0over * model->HSM2_tox / here->HSM2_cecox ; + T2 = pParam->HSM2_nover / Nin ; + T1 = T2 * T2 / ( T1 * T1 ) ; + here->HSM2_ps0ldinib = T1 ; /* (1 / cnst1 / cnstCoxi) */ + + }else { + here->HSM2_pb2over = 0.0 ; + here->HSM2_ps0ldinib = 0.0 ; + } + + + /* Depletion Width */ + T1 = 2.0e0 * C_ESI / C_QE ; + here->HSM2_wdpl = sqrt ( T1 / here->HSM2_nsub ) ; + here->HSM2_wdplp = sqrt( T1 / ( pParam->HSM2_nsubp ) ) ; + + /* cnst1: n_{p0} / p_{p0} */ + T1 = Nin / here->HSM2_nsub ; + here->HSM2_cnst1 = T1 * T1 ; + + + /* for substrate-source/drain junction diode. */ + js = pParam->HSM2_js0 + * exp ((here->HSM2_egtnom * here->HSM2_betatnom - Eg * beta + + model->HSM2_xti * log (TTEMP / model->HSM2_tnom)) / pParam->HSM2_nj) ; + jssw = pParam->HSM2_js0sw + * exp ((here->HSM2_egtnom * here->HSM2_betatnom - Eg * beta + + model->HSM2_xti * log (TTEMP / model->HSM2_tnom)) / model->HSM2_njsw) ; + + js2 = pParam->HSM2_js0 + * exp ((here->HSM2_egtnom * here->HSM2_betatnom - Eg * beta + + model->HSM2_xti2 * log (TTEMP / model->HSM2_tnom)) / pParam->HSM2_nj) ; + jssw2 = pParam->HSM2_js0sw + * exp ((here->HSM2_egtnom * here->HSM2_betatnom - Eg * beta + + model->HSM2_xti2 * log (TTEMP / model->HSM2_tnom)) / model->HSM2_njsw) ; + + here->HSM2_isbd = here->HSM2_ad * js + here->HSM2_pd * jssw ; + here->HSM2_isbd2 = here->HSM2_ad * js2 + here->HSM2_pd * jssw2 ; + here->HSM2_isbs = here->HSM2_as * js + here->HSM2_ps * jssw ; + here->HSM2_isbs2 = here->HSM2_as * js2 + here->HSM2_ps * jssw2 ; + + here->HSM2_vbdt = pParam->HSM2_nj / beta + * log (pParam->HSM2_vdiffj * (TTEMP / model->HSM2_tnom) * (TTEMP / model->HSM2_tnom) + / (here->HSM2_isbd + 1.0e-50) + 1) ; + here->HSM2_vbst = pParam->HSM2_nj / beta + * log (pParam->HSM2_vdiffj * (TTEMP / model->HSM2_tnom) * (TTEMP / model->HSM2_tnom) + / (here->HSM2_isbs + 1.0e-50) + 1) ; + + here->HSM2_exptemp = exp (((TTEMP / model->HSM2_tnom) - 1) * model->HSM2_ctemp) ; + here->HSM2_jd_nvtm_inv = 1.0 / ( pParam->HSM2_nj / beta ) ; + here->HSM2_jd_expcd = exp (here->HSM2_vbdt * here->HSM2_jd_nvtm_inv ) ; + here->HSM2_jd_expcs = exp (here->HSM2_vbst * here->HSM2_jd_nvtm_inv ) ; + + /* costi0 and costi1 for STI transistor model (temperature-dependent part) */ + here->HSM2_costi0 = here->HSM2_costi00 * sqrt(here->HSM2_beta_inv) ; + here->HSM2_costi0_p2 = here->HSM2_costi0 * here->HSM2_costi0 ; + here->HSM2_costi1 = here->HSM2_nin * here->HSM2_nin * here->HSM2_nsti_p2 ; + + /* check if SC3 is too large */ + if (pParam->HSM2_sc3 && model->HSM2_sc3Vbs < 0.0) { + + beta = here->HSM2_beta ; + beta_inv = here->HSM2_beta_inv ; + Weff = here->HSM2_weff ; + Vfb = pParam->HSM2_vfbc ; + Pb20 = here->HSM2_pb20 ; + cnst0 = here->HSM2_cnst0 ; + cnst1 = here->HSM2_cnst1 ; + c_eox = here->HSM2_cecox ; + Tox = model->HSM2_tox ; + Cox = c_eox / Tox ; + Cox_inv = 1.0 / Cox ; + fac1 = cnst0 * Cox_inv ; + Vgs_min = model->HSM2_type * model->HSM2_Vgsmin ; + sc3Vbs = model->HSM2_sc3Vbs ; + sc3Vgs = 2.0 ; + Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ; + + /* approximate solution of Poisson equation for large + Vgs and negative Vbs (3 iterations!)*/ + Vgp = sc3Vgs - Vfb; + Denom = fac1*sqrt(cnst1); + Ps0 = 2.0 * beta_inv * log(Vgp/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + Ps0_dVbs = 0.0; + + T1 = here->HSM2_2qnsub_esi ; + Qb0 = sqrt ( T1 ) ; + Vthp = Ps0 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr ; + + T1 = 2.0 * C_QE * pParam->HSM2_nsubc * C_ESI ; + T2 = sqrt( T1 ) ; + Vth0 = Ps0 + Vfb + T2 * Cox_inv ; + T1 = C_ESI * Cox_inv ; + T2 = here->HSM2_wdplp ; + T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ; + T3 = 2.0 * ( model->HSM2_vbi - Pb20 ) * T2 * T4 ; + T5 = T1 * T3 ; + T6 = Ps0 - sc3Vbs ; + T6_dVb = Ps0_dVbs - 1.0 ; + dVth0 = T5 * sqrt( T6 ) ; + dVth0_dVb = T5 * 0.5 / sqrt( T6 ) * T6_dVb; + T1 = Vthp - Vth0 ; + T9 = Ps0 - sc3Vbs ; + T9_dVb = Ps0_dVbs - 1.0 ; + T3 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * T9 / model->HSM2_lp; + T3_dVb = pParam->HSM2_scp3 * T9_dVb / model->HSM2_lp ; + dVthLP = T1 * dVth0 * T3 ; + dVthLP_dVb = T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb; + + T3 = here->HSM2_lgate - model->HSM2_parl2 ; + T4 = 1.0e0 / ( T3 * T3 ) ; + T0 = C_ESI * here->HSM2_wdpl * 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T4 ; + T2 = T0 * Cox_inv ; + T5 = pParam->HSM2_sc3 / here->HSM2_lgate ; + T6 = pParam->HSM2_sc1 + T5 * ( Ps0 - sc3Vbs ) ; + T1 = T6 ; + A = T2 * T1 ; + T9 = Ps0 - sc3Vbs + Ps0_min ; + T9_dVb = Ps0_dVbs - 1.0 ; + T8 = sqrt( T9 ) ; + T8_dVb = 0.5 * T9_dVb / T8 ; + dVthSC = A * T8 ; + + T1 = 1.0 / Cox ; + T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ; + T5 = T1 - T3 ; + dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ; + + dVth = dVthSC + dVthLP + dVthW + here->HSM2_dVthsm ; + dPpg = 0.0 ; + Vgp = sc3Vgs - Vfb + dVth - dPpg ; + + /* Recalculation of Ps0, using more accurate Vgp */ + Ps0 = 2.0 * beta_inv * log(Vgp/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + Ps0 = 2.0 * beta_inv * log((Vgp-Ps0)/Denom); + + term1 = Vgp - Ps0; + term2 = sqrt(beta*(Ps0-sc3Vbs)-1.0); + term3 = term1 + fac1 * term2; + term4 = cnst1 * exp(beta*Ps0); + limVgp_dVbs = - beta * (term3 + 0.5*fac1 * term4/term2) + / (2.0*term1/fac1/fac1*term3 - term4); + T2 = T0 * Cox_inv ; + sc3lim = here->HSM2_lgate / T2 + * (limVgp_dVbs - dVthLP_dVb - T2*pParam->HSM2_sc1*T8_dVb) + / ((Ps0-sc3Vbs)*T8_dVb +(Ps0_dVbs-1.0)*T8); + if (sc3lim < 1.0e-20) + sc3lim = 1e-20 ; + if (sc3lim < pParam->HSM2_sc3 * 0.999) { + pParam->HSM2_sc3 = sc3lim; + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hisim2/hsm2trunc.c b/src/spicelib/devices/hisim2/hsm2trunc.c new file mode 100644 index 000000000..370d673a1 --- /dev/null +++ b/src/spicelib/devices/hisim2/hsm2trunc.c @@ -0,0 +1,54 @@ +/*********************************************************************** + + HiSIM (Hiroshima University STARC IGFET Model) + Copyright (C) 2011 Hiroshima University & STARC + + VERSION : HiSIM_2.5.1 + FILE : hsm2trunc.c + + date : 2011.04.07 + + released by + Hiroshima University & + Semiconductor Technology Academic Research Center (STARC) +***********************************************************************/ + +#include "spice.h" +#include +#include "cktdefs.h" +#include "hsm2def.h" +#include "sperror.h" +#include "suffix.h" + +int HSM2trunc(inModel,ckt,timeStep) + GENmodel *inModel; + register CKTcircuit *ckt; + double *timeStep; + +{ + register HSM2model *model = (HSM2model*)inModel; + register HSM2instance *here; +#ifdef STEPDEBUG + double debugtemp; +#endif /* STEPDEBUG */ + + for ( ;model != NULL ;model = model->HSM2nextModel ) { + for ( here=model->HSM2instances ;here!=NULL ; + here = here->HSM2nextInstance ) { +#ifdef STEPDEBUG + debugtemp = *timeStep; +#endif /* STEPDEBUG */ + CKTterr(here->HSM2qb,ckt,timeStep); + CKTterr(here->HSM2qg,ckt,timeStep); + CKTterr(here->HSM2qd,ckt,timeStep); +#ifdef STEPDEBUG + if ( debugtemp != *timeStep ) + printf("device %s reduces step from %g to %g\n", + here->HSM2name, debugtemp, *timeStep); +#endif /* STEPDEBUG */ + } + } + return(OK); +} + +