From 7d1dc4224ef972a24be6381f1392542bcd28937e Mon Sep 17 00:00:00 2001 From: dwarning Date: Tue, 24 May 2011 20:08:28 +0000 Subject: [PATCH] changed to hisim2 --- src/spicelib/devices/hisim/.cvsignore | 6 - src/spicelib/devices/hisim/Makefile.am | 38 - src/spicelib/devices/hisim/hisim.h | 406 -- src/spicelib/devices/hisim/hsm1.c | 167 - src/spicelib/devices/hisim/hsm1acld.c | 273 -- src/spicelib/devices/hisim/hsm1ask.c | 229 - src/spicelib/devices/hisim/hsm1cvtest.c | 120 - src/spicelib/devices/hisim/hsm1def.h | 732 --- src/spicelib/devices/hisim/hsm1del.c | 37 - src/spicelib/devices/hisim/hsm1dest.c | 37 - src/spicelib/devices/hisim/hsm1eval102.c | 4491 ------------------ src/spicelib/devices/hisim/hsm1eval112.c | 4719 ------------------- src/spicelib/devices/hisim/hsm1eval120.c | 5501 ---------------------- src/spicelib/devices/hisim/hsm1eval1_0.c | 4572 ------------------ src/spicelib/devices/hisim/hsm1eval1_1.c | 4758 ------------------- src/spicelib/devices/hisim/hsm1evalenv.h | 80 - src/spicelib/devices/hisim/hsm1ext.h | 32 - src/spicelib/devices/hisim/hsm1getic.c | 53 - src/spicelib/devices/hisim/hsm1init.c | 82 - src/spicelib/devices/hisim/hsm1init.h | 13 - src/spicelib/devices/hisim/hsm1itf.h | 16 - src/spicelib/devices/hisim/hsm1ld.c | 1387 ------ src/spicelib/devices/hisim/hsm1mask.c | 393 -- src/spicelib/devices/hisim/hsm1mdel.c | 44 - src/spicelib/devices/hisim/hsm1mpar.c | 511 -- src/spicelib/devices/hisim/hsm1noi.c | 273 -- src/spicelib/devices/hisim/hsm1par.c | 104 - src/spicelib/devices/hisim/hsm1pzld.c | 305 -- src/spicelib/devices/hisim/hsm1set.c | 445 -- src/spicelib/devices/hisim/hsm1temp.c | 38 - src/spicelib/devices/hisim/hsm1trunc.c | 49 - 31 files changed, 29911 deletions(-) delete mode 100644 src/spicelib/devices/hisim/.cvsignore delete mode 100644 src/spicelib/devices/hisim/Makefile.am delete mode 100644 src/spicelib/devices/hisim/hisim.h delete mode 100644 src/spicelib/devices/hisim/hsm1.c delete mode 100644 src/spicelib/devices/hisim/hsm1acld.c delete mode 100644 src/spicelib/devices/hisim/hsm1ask.c delete mode 100644 src/spicelib/devices/hisim/hsm1cvtest.c delete mode 100644 src/spicelib/devices/hisim/hsm1def.h delete mode 100644 src/spicelib/devices/hisim/hsm1del.c delete mode 100644 src/spicelib/devices/hisim/hsm1dest.c delete mode 100644 src/spicelib/devices/hisim/hsm1eval102.c delete mode 100644 src/spicelib/devices/hisim/hsm1eval112.c delete mode 100644 src/spicelib/devices/hisim/hsm1eval120.c delete mode 100644 src/spicelib/devices/hisim/hsm1eval1_0.c delete mode 100644 src/spicelib/devices/hisim/hsm1eval1_1.c delete mode 100644 src/spicelib/devices/hisim/hsm1evalenv.h delete mode 100644 src/spicelib/devices/hisim/hsm1ext.h delete mode 100644 src/spicelib/devices/hisim/hsm1getic.c delete mode 100644 src/spicelib/devices/hisim/hsm1init.c delete mode 100644 src/spicelib/devices/hisim/hsm1init.h delete mode 100644 src/spicelib/devices/hisim/hsm1itf.h delete mode 100644 src/spicelib/devices/hisim/hsm1ld.c delete mode 100644 src/spicelib/devices/hisim/hsm1mask.c delete mode 100644 src/spicelib/devices/hisim/hsm1mdel.c delete mode 100644 src/spicelib/devices/hisim/hsm1mpar.c delete mode 100644 src/spicelib/devices/hisim/hsm1noi.c delete mode 100644 src/spicelib/devices/hisim/hsm1par.c delete mode 100644 src/spicelib/devices/hisim/hsm1pzld.c delete mode 100644 src/spicelib/devices/hisim/hsm1set.c delete mode 100644 src/spicelib/devices/hisim/hsm1temp.c delete mode 100644 src/spicelib/devices/hisim/hsm1trunc.c diff --git a/src/spicelib/devices/hisim/.cvsignore b/src/spicelib/devices/hisim/.cvsignore deleted file mode 100644 index dc4caac80..000000000 --- a/src/spicelib/devices/hisim/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.in -Makefile -.deps -.libs -*.lo -*.la diff --git a/src/spicelib/devices/hisim/Makefile.am b/src/spicelib/devices/hisim/Makefile.am deleted file mode 100644 index 2bd1bfdb7..000000000 --- a/src/spicelib/devices/hisim/Makefile.am +++ /dev/null @@ -1,38 +0,0 @@ -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = hsm1eval1_0.c hsm1eval1_1.c - -noinst_LTLIBRARIES = libhisim.la - -libhisim_la_SOURCES = hisim.h \ - hsm1.c \ - hsm1acld.c \ - hsm1ask.c \ - hsm1cvtest.c \ - hsm1def.h \ - hsm1del.c \ - hsm1dest.c \ - hsm1eval102.c \ - hsm1eval112.c \ - hsm1eval120.c \ - hsm1evalenv.h \ - hsm1ext.h \ - hsm1getic.c \ - hsm1init.c \ - hsm1init.h \ - hsm1itf.h \ - hsm1ld.c \ - hsm1mask.c \ - hsm1mdel.c \ - hsm1mpar.c \ - hsm1noi.c \ - hsm1par.c \ - hsm1pzld.c \ - hsm1set.c \ - hsm1temp.c \ - hsm1trunc.c - - -AM_CPPFLAGS = -I$(top_srcdir)/src/include - -MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/hisim/hisim.h b/src/spicelib/devices/hisim/hisim.h deleted file mode 100644 index 7e42f46ff..000000000 --- a/src/spicelib/devices/hisim/hisim.h +++ /dev/null @@ -1,406 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hisim.h of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - - -#ifndef _HiSIM_H -#define _HiSIM_H - -/* #define HiSIM_TIME 0*/ - -/* 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 - - -/*-------------------------------------------------------------------* -* Structure for inputs of hisim. -*----------------*/ -typedef struct sHiSIM_input { - - /* Flags that must be set in parent routines. */ - int type ; /* MOS type (1:NMOS, -1:PMOS) */ - int mode ; /* MOS mode (1:normal, -1:reverse) */ - int qflag ; /* qflag (toggle for charge calc. Unused!) */ - int has_prv ; /* 1 if previous values are held. */ - - /* Bias conditions */ - double vbs ; /* Vbs [V] */ - double vds ; /* Vds [V] */ - double vgs ; /* Vgs [V] */ - - /* frequency [Hz] */ - double freq ; - - /* version */ - double version ; - - /* Control options that can be set in a model parameter set. */ - int info ; /* information level (for debug, etc.) */ - int corsrd ; /* solve equations accounting Rs and Rd. */ - int coiprv ; /* use ids_prv as initial guess of Ids */ - int copprv ; /* use ps{0/l}_prv as initial guess of Ps{0/l} */ - int cocgso ; /* calculate cgso */ - int cocgdo ; /* calculate cgdo */ - int cocgbo ; /* calculate cgbo */ - int coadov ; /* add overlap to intrisic */ - int coxx08 ; /* spare */ - int coxx09 ; /* spare */ - int coisub ; /* calculate isub */ - int coiigs ; /* calculate igate */ - int cogidl ; /* calculate igidl */ - int cogisl ; /* calculate igisl */ - int coovlp ; /* calculate overlap charge */ - int conois ; /* calculate 1/f noise */ - int coisti ; /* calculate STI */ - int cosmbi ; /* bias smoothing in dVth */ - - /* Previous values that may be used as initial guesses */ - /* - derivatives are ones w.r.t. internal biases. */ - double vbsc_prv ; - double vdsc_prv ; - double vgsc_prv ; - double ps0_prv ; - double ps0_dvbs_prv ; - double ps0_dvds_prv ; - double ps0_dvgs_prv ; - double pds_prv ; - double pds_dvbs_prv ; - double pds_dvds_prv ; - double pds_dvgs_prv ; - double ids_prv ; - double ids_dvbs_prv ; - double ids_dvds_prv ; - double ids_dvgs_prv ; - - /* for noise calc. */ - double nfc ; - - /* Device instances */ - double xl ; /* channel length [m] (L=xl-xld) */ - double xw ; /* channel width [m] (W=xw-xwd) */ - double ad ; /* area of drain diffusion [m^2] */ - double as ; /* area of source diffusion [m^2] */ - double pd ; /* perimeter of drain junction [m] */ - double ps ; /* perimeter of source junction [m] */ - double nrd ; /* equivalent num of squares of drain [-] (unused) */ - double nrs ; /* equivalent num of squares of source [-] (unused) */ - double temp ; /* lattice temperature [K] */ - double m ; /* multiplier */ - - /* Model parameters */ - double vmax ; /* saturation velocity [cm/s] */ - double bgtmp1 ; /* first order temp. coeff. for band gap [V/K] */ - double bgtmp2 ; /* second order temp. coeff. for band gap [V/K^2] */ - double tox ; /* oxide thickness [m] */ - double xld ; /* lateral diffusion of S/D under the gate [m] */ - double xwd ; /* lateral diffusion along the width dir. [m] */ - double xj ; /* HiSIM1.0 [m] */ - double xqy ; /* HiSIM1.1 [m] */ - /*--*/ - double rd ; /* drain contact resistance [ohm m] */ - double rs ; /* source contact resistance [ohm m] */ -/**/ - double vfbc ; /* constant part of Vfb [V] */ - double nsubc ; /* constant part of Nsub [1/cm^3] */ - double parl1 ; /* factor for L dependency of dVthSC [-] */ - double parl2 ; /* under diffusion [m] */ - double lp ; /* length of pocket potential [m] */ - double nsubp ; /* [1/cm^3] */ - double scp1 ; /* parameter for pocket [1/V] */ - double scp2 ; /* parameter for pocket [1/V^2] */ - double scp3 ; /* parameter for pocket [m/V^2] */ - double sc1 ; /* parameter for SCE [1/V] */ - double sc2 ; /* parameter for SCE [1/V^2] */ - double sc3 ; /* parameter for SCE [m/V^2] */ - double pgd1 ; /* parameter for gate-poly depletion [V] */ - double pgd2 ; /* parameter for gate-poly depletion [V] */ - double pgd3 ; /* parameter for gate-poly depletion [-] */ -/**/ - double ndep ; /* coeff. of Qbm for Eeff [-] */ - double ninv ; /* coeff. of Qnm for Eeff [-] */ - double ninvd ; /* parameter for universal mobility [1/V] */ - double muecb0 ; /* const. part of coulomb scattering [cm^2/Vs] */ - double muecb1 ; /* coeff. for coulomb scattering [cm^2/Vs] */ - double mueph0 ; /* power of Eeff for phonon scattering [-] */ - double mueph1 ; - double mueph2 ; - double w0 ; - double muesr0 ; /* power of Eeff for S.R. scattering [-] */ - double muesr1 ; /* coeff. for S.R. scattering [-] */ - double muetmp ; /* parameter for mobility [-] */ - double bb ; /* empirical mobility model coefficient [-] */ -/**/ - double sub1 ; /* parameter for Isub [1/V] */ - double sub2 ; /* parameter for Isub [V] */ - double sub3 ; /* parameter for Isub [-] */ -/**/ - double wvthsc ; /* parameter for STI [-] HiSIM1.1 */ - double nsti ; /* parameter for STI [1/cm^3] HiSIM1.1 */ - double wsti ; /* parameter for STI [m] HiSIM1.1 */ -/**/ - double cgso ; /* G-S overlap capacitance per unit W [F/m] */ - double cgdo ; /* G-D overlap capacitance per unit W [F/m] */ - double cgbo ; /* G-B overlap capacitance per unit L [F/m] */ -/**/ - double tpoly ; /* hight of poly gate [m] */ -/**/ - double js0 ; /* Saturation current density [A/m^2] */ - double js0sw ; /* Side wall saturation current density [A/m] */ - double nj ; /* Emission coefficient */ - double njsw ; /* Emission coefficient (sidewall) */ - double xti ; /* Junction current temparature exponent coefficient */ - double cj ; /* Bottom junction capacitance per unit area - at zero bias [F/m^2]*/ - double cjsw ; /* Source/drain sidewall junction capacitance grading - coefficient per unit length at zero bias [F/m] */ - double cjswg ; /* Source/drain gate sidewall junction capacitance - per unit length at zero bias [F/m] */ - double mj ; /* Bottom junction capacitance grading coefficient */ - double mjsw ; /* Source/drain sidewall junction capacitance grading - coefficient */ - double mjswg ; /* Source/drain gate sidewall junction capacitance grading - coefficient */ - double pb ; /* Bottom junction build-in potential [V] */ - double pbsw ; /* Source/drain sidewall junction build-in potential [V] */ - double pbswg ; /* Source/drain gate sidewall junction build-in potential [V] */ - double xpolyd ; /* parameter for Cov [m] */ -/**/ - double clm1 ; /* parameter for CLM [-] */ - double clm2 ; /* parameter for CLM [1/m] */ - double clm3 ; /* parameter for CLM [-] */ -/**/ - double rpock1 ; /* parameter for Ids [V] */ - double rpock2 ; /* parameter for Ids [V^2 sqrt(m)/A] */ - double rpocp1 ; /* parameter for Ids [-] HiSIM1.1 */ - double rpocp2 ; /* parameter for Ids [-] HiSIM1.1 */ - -/**/ - double vover ; /* parameter for overshoot [m^{voverp}]*/ - double voverp ; /* parameter for overshoot [-] */ - double wfc ; /* parameter for narrow channel effect [m*F/(cm^2)]*/ - double qme1 ; /* parameter for quantum effect [mV]*/ - double qme2 ; /* parameter for quantum effect [V]*/ - double qme3 ; /* parameter for quantum effect [m]*/ - double gidl1 ; /* parameter for GIDL [?] */ - double gidl2 ; /* parameter for GIDL [?] */ - double gidl3 ; /* parameter for GIDL [?] */ - double gleak1 ; /* parameter for gate current [?] */ - double gleak2 ; /* parameter for gate current [?] */ - double gleak3 ; /* parameter for gate current [?] */ -/**/ - double vzadd0 ; /* Vzadd at Vds=0 [V] */ - double pzadd0 ; /* Pzadd at Vds=0 [V] */ - - double nftrp ; - double nfalp ; - double cit ; - - double gmin ; /* gmin = minimum conductance of SPICE3 */ - /**/ - double glpart1 ; /* partition of gate leackage current */ - double glpart2 ; - double kappa ; /* */ - double xdiffd ; /* */ - double pthrou ; /* */ - double vdiffj ; /* */ - -} HiSIM_input ; - -/*-------------------------------------------------------------------* -* structure for outputs of hisim. -*----------------*/ -typedef struct sHiSIM_output { - double ids ; /* channel current [A] */ - double gds ; /* channel conductance (dIds/dVds) [S] */ - double gm ; /* trans conductance (dIds/dVgs) [S] */ - double gmbs ; /* substrate trans conductance (dIds/dVbs) [S] */ -/**/ - double gd ; /* parasitic drain conductance [S] */ - double gs ; /* parasitic source conductance [S] */ -/**/ - double cgso ; /* G-S overlap capacitance [F] */ - double cgdo ; /* G-D overlap capacitance [F] */ - double cgbo ; /* G-B overlap capacitance [F] */ -/**/ - double von ; /* Vth [V] */ - double vdsat ; /* saturation voltage [V] */ -/**/ - double ibs ; /* substrate source leakage current [A] */ - double ibd ; /* substrate drain leakage current [A] */ - double gbs ; /* substrate source conductance [S] */ - double gbd ; /* substrate drain conductance [S] */ -/**/ - double capbs ; /* substrate source capacitance [F] */ - double capbd ; /* substrate drain capacitance [F] */ - double qbs ; /* substrate source charge [C] */ - double qbd ; /* substrate drain charge [C] */ -/**/ - double isub ; /* substrate impact ionization current [A] */ - double gbgs ; /* substrate trans conductance (dIsub/dVgs) [S] */ - double gbds ; /* substrate trans conductance (dIsub/dVds) [S] */ - double gbbs ; /* substrate trans conductance (dIsub/dVbs) [S] */ -/**/ - double qg ; /* intrinsic gate charge [C] */ - double qd ; /* intrinsic drain charge [C] */ - double qs ; /* intrinsic source charge [C] */ -/**/ - double cggb ; /* intrinsic gate capacitance w.r.t. gate [F] */ - double cgdb ; /* intrinsic gate capacitance w.r.t. drain [F] */ - double cgsb ; /* intrinsic gate capacitance w.r.t. source [F] */ - double cbgb ; /* intrinsic bulk capacitance w.r.t. gate [F] */ - double cbdb ; /* intrinsic bulk capacitance w.r.t. drain [F] */ - double cbsb ; /* intrinsic bulk capacitance w.r.t. source [F] */ - double cdgb ; /* intrinsic drain capacitance w.r.t. gate [F] */ - double cddb ; /* intrinsic drain capacitance w.r.t. drain [F] */ - double cdsb ; /* intrinsic drain capacitance w.r.t. source [F] */ -/**/ - double igate ; /* gate current due to tunneling [A] */ - double gggs ; /* trans conductance (dIgate/dVgs) [S] */ - double ggds ; /* trans conductance (dIgate/dVds) [S] */ - double ggbs ; /* trans conductance (dIgate/dVbs) [S] */ -/**/ - double igateb ; /* gate current due to tunneling [A] (G->B)*/ - double ggbgs ; /* trans conductance (dIgateb/dVgs) [S] */ - double ggbds ; /* trans conductance (dIgateb/dVds) [S] */ - double ggbbs ; /* trans conductance (dIgateb/dVbs) [S] */ -/**/ - double igates ; /* gate current due to tunneling [A] (G->S)*/ - double ggsgs ; /* trans conductance (dIgates/dVgs) [S] */ - double ggsds ; /* trans conductance (dIgates/dVds) [S] */ - double ggsbs ; /* trans conductance (dIgates/dVbs) [S] */ -/**/ - double igated ; /* gate current due to tunneling [A] (G->D)*/ - double ggdgs ; /* trans conductance (dIgated/dVgs) [S] */ - double ggdds ; /* trans conductance (dIgated/dVds) [S] */ - double ggdbs ; /* trans conductance (dIgated/dVbs) [S] */ -/**/ - double igidl ; /* gate induced drain leakage [A] */ - double ggidlgs ; /* trans conductance (dIgidl/dVgs) [S] */ - double ggidlds ; /* trans conductance (dIgidl/dVds) [S] */ - double ggidlbs ; /* trans conductance (dIgidl/dVbs) [S] */ -/**/ - double igisl ; /* gate induced source leakage [A] */ - double ggislgd ; /* trans conductance (dIgisl/dVgs) [S] */ - double ggislsd ; /* trans conductance (dIgisl/dVds) [S] */ - double ggislbd ; /* trans conductance (dIgisl/dVbs) [S] */ -/**/ - double nois_idsfl ; - double nois_ird ; - double nois_irs ; - double nois_idsth ; -/**/ - /* Outputs that may be used as initial guesses in the next calling */ - double vbsc ; - double vdsc ; - double vgsc ; - double ps0 ; - double ps0_dvbs ; - double ps0_dvds ; - double ps0_dvgs ; - double pds ; - double pds_dvbs ; - double pds_dvds ; - double pds_dvgs ; - double ids_dvbs ; - double ids_dvds ; - double ids_dvgs ; - - /* for noise calc. */ - double nf ; - - /* mobility added by K.M. */ - double mu ; - - /* intrinsic charges */ - double qg_int ; - double qd_int ; - double qs_int ; - double qb_int ; - -} HiSIM_output ; - -/*-------------------------------------------------------------------* -* structure for messengers to/from hisim. -*----------------*/ -typedef struct sHiSIM_messenger { - int ims[20] ; - double dms[50] ; - /* Control options for alpha versions */ - int opt_ntn ; - int opt_psl ; - int opt_rsc ; - int opt_sce ; - int opt_mbl ; - int opt_dp0 ; - int opt_inv ; - int opt_bas ; - int opt_01 ; - int opt_02 ; - int opt_03 ; - int opt_04 ; - int opt_05 ; -} HiSIM_messenger ; -/* note: ----------------------------------- -* if HiSIM_TEST is defined. -* ims[ 1 ] :(in) =1: output physical capacitances instead of ones -* referenced to bulk. -* ims[11-12] , dms[11-39] :(ot) additional outputs. -* if CMI_OK is defined. -* dms[ 1 ] :(in) timepoint. --------------------------------------------*/ - - -extern int HSM1evaluate102( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS - ) ; -extern int HSM1evaluate112 -( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS - ) ; -extern int HSM1evaluate120 -( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS - ) ; - -#endif /* _HiSIM_H */ diff --git a/src/spicelib/devices/hisim/hsm1.c b/src/spicelib/devices/hisim/hsm1.c deleted file mode 100644 index 5b06c86d5..000000000 --- a/src/spicelib/devices/hisim/hsm1.c +++ /dev/null @@ -1,167 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "devdefs.h" -#include "hsm1def.h" -#include "suffix.h" - -IFparm HSM1pTable[] = { /* parameters */ - IOP( "l", HSM1_L, IF_REAL , "Length"), - IOP( "w", HSM1_W, IF_REAL , "Width"), - IOP( "ad", HSM1_AD, IF_REAL , "Drain area"), - IOP( "as", HSM1_AS, IF_REAL , "Source area"), - IOP( "pd", HSM1_PD, IF_REAL , "Drain perimeter"), - IOP( "ps", HSM1_PS, IF_REAL , "Source perimeter"), - IOP( "nrd", HSM1_NRD, IF_REAL , "Number of squares in drain"), - IOP( "nrs", HSM1_NRS, IF_REAL , "Number of squares in source"), - IOP( "temp", HSM1_TEMP, IF_REAL , "Lattice temperature"), - IOP( "dtemp", HSM1_DTEMP,IF_REAL , ""), - IOP( "off", HSM1_OFF, IF_FLAG , "Device is initially off"), - IP ( "ic", HSM1_IC, IF_REALVEC , "Vector of DS,GS,BS initial voltages"), - IOP( "m", HSM1_M, IF_REAL , "Parallel multiplier") -}; - -IFparm HSM1mPTable[] = { /* model parameters */ - IP("nmos", HSM1_MOD_NMOS, IF_FLAG, ""), - IP("pmos", HSM1_MOD_PMOS, IF_FLAG, ""), - IOP("level", HSM1_MOD_LEVEL, IF_INTEGER, ""), - IOP("info", HSM1_MOD_INFO, IF_INTEGER, "information level (for debug, etc.)"), - IOP("noise", HSM1_MOD_NOISE, IF_INTEGER, "noise model selector"), - IOP("version", HSM1_MOD_VERSION, IF_INTEGER, "model version 102 or 112 or 120"), - IOP("show", HSM1_MOD_SHOW, IF_INTEGER, "show physical value"), - IOP("corsrd", HSM1_MOD_CORSRD, IF_INTEGER, "solve equations accounting Rs and Rd."), - IOP("coiprv", HSM1_MOD_COIPRV, IF_INTEGER, "use ids_prv as initial guess of Ids"), - IOP("copprv", HSM1_MOD_COPPRV, IF_INTEGER, "use ps{0/l}_prv as initial guess of Ps{0/l}"), - IOP("cocgso", HSM1_MOD_COCGSO, IF_INTEGER, "calculate cgso"), - IOP("cocgdo", HSM1_MOD_COCGDO, IF_INTEGER, "calculate cgdo"), - IOP("cocgbo", HSM1_MOD_COCGBO, IF_INTEGER, "calculate cgbo"), - IOP("coadov", HSM1_MOD_COADOV, IF_INTEGER, "add overlap to intrisic"), - IOP("coxx08", HSM1_MOD_COXX08, IF_INTEGER, "spare"), - IOP("coxx09", HSM1_MOD_COXX09, IF_INTEGER, "spare"), - IOP("coisub", HSM1_MOD_COISUB, IF_INTEGER, "calculate isub"), - IOP("coiigs", HSM1_MOD_COIIGS, IF_INTEGER, "calculate igate"), - IOP("cogidl", HSM1_MOD_COGIDL, IF_INTEGER, "calculate igidl"), - IOP("cogisl", HSM1_MOD_COGISL, IF_INTEGER, "calculate igisl"), - IOP("coovlp", HSM1_MOD_COOVLP, IF_INTEGER, "calculate overlap charge"), - IOP("conois", HSM1_MOD_CONOIS, IF_INTEGER, "calculate 1/f noise"), - IOP("coisti", HSM1_MOD_COISTI, IF_INTEGER, "calculate STI HiSIM1.1"), - IOP("cosmbi", HSM1_MOD_COSMBI, IF_INTEGER, "biases smoothing in dvth HiSIM1.2"), - IOP("vmax", HSM1_MOD_VMAX, IF_REAL, "saturation velocity [cm/s"), - IOP("bgtmp1", HSM1_MOD_BGTMP1, IF_REAL, "first order temp. coeff. for band gap [V/K]"), - IOP("bgtmp2", HSM1_MOD_BGTMP2, IF_REAL, "second order temp. coeff. for band gap [V/K^2]"), - IOP("tox", HSM1_MOD_TOX, IF_REAL, "oxide thickness [m]"), - IOP("xld", HSM1_MOD_XLD, IF_REAL, "lateral diffusion of S/D under the gate [m]"), - IOP("xwd", HSM1_MOD_XWD, IF_REAL, "lateral diffusion along the width dir. [m]"), - IOP("xj", HSM1_MOD_XJ, IF_REAL, "HiSIM1.0.z [m]"), - IOP("xqy", HSM1_MOD_XQY, IF_REAL, "HiSIM1.1.z or later [m]"), - IOP("rs", HSM1_MOD_RS, IF_REAL, "source contact resistance [ohm m]"), - IOP("rd", HSM1_MOD_RD, IF_REAL, "drain contact resistance [ohm m]"), - IOP("vfbc", HSM1_MOD_VFBC, IF_REAL, "constant part of Vfb [V]"), - IOP("nsubc", HSM1_MOD_NSUBC, IF_REAL, "constant part of Nsub [1/cm^3]"), - IOP("parl1", HSM1_MOD_PARL1, IF_REAL, "factor for L dependency of dVthSC [-]"), - IOP("parl2", HSM1_MOD_PARL2, IF_REAL, "under diffusion [m]"), - IOP("lp", HSM1_MOD_LP, IF_REAL, "length of pocket potential [m]"), - IOP("nsubp", HSM1_MOD_NSUBP, IF_REAL, "[1/cm^3]"), - IOP("scp1", HSM1_MOD_SCP1, IF_REAL, "parameter for pocket [-]"), - IOP("scp2", HSM1_MOD_SCP2, IF_REAL, "parameter for pocket [1/V]"), - IOP("scp3", HSM1_MOD_SCP3, IF_REAL, "parameter for pocket [m/V]"), - IOP("sc1", HSM1_MOD_SC1, IF_REAL, "parameter for SCE [-]"), - IOP("sc2", HSM1_MOD_SC2, IF_REAL, "parameter for SCE [1/V]"), - IOP("sc3", HSM1_MOD_SC3, IF_REAL, "parameter for SCE [m/V]"), - IOP("pgd1", HSM1_MOD_PGD1, IF_REAL, "parameter for gate-poly depletion [V]"), - IOP("pgd2", HSM1_MOD_PGD2, IF_REAL, "parameter for gate-poly depletion [V]"), - IOP("pgd3", HSM1_MOD_PGD3, IF_REAL, "parameter for gate-poly depletion [-]"), - IOP("ndep", HSM1_MOD_NDEP, IF_REAL, "coeff. of Qbm for Eeff [-]"), - IOP("ninv", HSM1_MOD_NINV, IF_REAL, "coeff. of Qnm for Eeff [-]"), - IOP("ninvd", HSM1_MOD_NINVD, IF_REAL, "parameter for universal mobility [1/V]"), - IOP("muecb0", HSM1_MOD_MUECB0, IF_REAL, "const. part of coulomb scattering [cm^2/Vs]"), - IOP("muecb1", HSM1_MOD_MUECB1, IF_REAL, "coeff. for coulomb scattering [cm^2/Vs]"), - IOP("mueph0", HSM1_MOD_MUEPH0, IF_REAL, "power of Eeff for phonon scattering [-]"), - IOP("mueph1", HSM1_MOD_MUEPH1, IF_REAL, ""), - IOP("mueph2", HSM1_MOD_MUEPH2, IF_REAL, ""), - IOP("w0", HSM1_MOD_W0, IF_REAL, ""), - IOP("muesr0", HSM1_MOD_MUESR0, IF_REAL, "power of Eeff for S.R. scattering [-]"), - IOP("muesr1", HSM1_MOD_MUESR1, IF_REAL, "coeff. for S.R. scattering [-]"), - IOP("muetmp", HSM1_MOD_MUETMP, IF_REAL, "parameter for mobility [-]"), - IOP("bb", HSM1_MOD_BB, IF_REAL, "empirical mobility model coefficient [-]"), - IOP("sub1", HSM1_MOD_SUB1, IF_REAL, "parameter for Isub [1/V]"), - IOP("sub2", HSM1_MOD_SUB2, IF_REAL, "parameter for Isub [V]"), - IOP("sub3", HSM1_MOD_SUB3, IF_REAL, "parameter for Isub [-]"), - IOP("wvthsc", HSM1_MOD_WVTHSC, IF_REAL, "parameter for STI [-] HiSIM1.1"), - IOP("nsti", HSM1_MOD_NSTI, IF_REAL, "parameter for STI [1/cm^3] HiSIM1.1"), - IOP("wsti", HSM1_MOD_WSTI, IF_REAL, "parameter for STI [m] HiSIM1.1"), - IOP("cgso", HSM1_MOD_CGSO, IF_REAL, "G-S overlap capacitance per unit W [F/m]"), - IOP("cgdo", HSM1_MOD_CGDO, IF_REAL, "G-D overlap capacitance per unit W [F/m]"), - IOP("cgbo", HSM1_MOD_CGBO, IF_REAL, "G-B overlap capacitance per unit L [F/m]"), - IOP("tpoly", HSM1_MOD_TPOLY, IF_REAL, "hight of poly gate [m]"), - IOP("js0", HSM1_MOD_JS0, IF_REAL, "Saturation current density [A/m^2]"), - IOP("js0sw", HSM1_MOD_JS0SW, IF_REAL, "Side wall saturation current density [A/m]"), - IOP("nj", HSM1_MOD_NJ, IF_REAL, "Emission coefficient"), - IOP("njsw", HSM1_MOD_NJSW, IF_REAL, "Sidewall emission coefficient"), - IOP("xti", HSM1_MOD_XTI, IF_REAL, "Junction current temparature exponent coefficient"), - IOP("cj", HSM1_MOD_CJ, IF_REAL, "Bottom junction capacitance per unit area at zero bias [F/m^2]"), - IOP("cjsw", HSM1_MOD_CJSW, IF_REAL, "Source/drain sidewall junction capacitance grading coefficient per unit length at zero bias [F/m]"), - IOP("cjswg", HSM1_MOD_CJSWG, IF_REAL, "Source/drain gate sidewall junction capacitance per unit length at zero bias [F/m]"), - IOP("mj", HSM1_MOD_MJ, IF_REAL, "Bottom junction capacitance grading coefficient"), - IOP("mjsw", HSM1_MOD_MJSW, IF_REAL, "Source/drain sidewall junction capacitance grading coefficient"), - IOP("mjswg", HSM1_MOD_MJSWG, IF_REAL, "Source/drain gate sidewall junction capacitance grading coefficient"), - IOP("pb", HSM1_MOD_PB, IF_REAL, "Bottom junction build-in potential [V]"), - IOP("pbsw", HSM1_MOD_PBSW, IF_REAL, "Source/drain sidewall junction build-in potential [V]"), - IOP("pbswg", HSM1_MOD_PBSWG, IF_REAL, "Source/drain gate sidewall junction build-in potential [V]"), - IOP("xpolyd", HSM1_MOD_XPOLYD, IF_REAL, "parameter for Cov [m]"), - IOP("clm1", HSM1_MOD_CLM1, IF_REAL, "parameter for CLM [-]"), - IOP("clm2", HSM1_MOD_CLM2, IF_REAL, "parameter for CLM [1/m]"), - IOP("clm3", HSM1_MOD_CLM3, IF_REAL, "parameter for CLM [-]"), - IOP("rpock1", HSM1_MOD_RPOCK1, IF_REAL, "parameter for Ids [V]"), - IOP("rpock2", HSM1_MOD_RPOCK2, IF_REAL, "parameter for Ids [V^2 sqrt(m)/A]"), - IOP("rpocp1", HSM1_MOD_RPOCP1, IF_REAL, "parameter for Ids [-] HiSIM1.1"), - IOP("rpocp2", HSM1_MOD_RPOCP2, IF_REAL, "parameter for Ids [-] HiSIM1.1"), - IOP("vover", HSM1_MOD_VOVER, IF_REAL, "parameter for overshoot [m^{voverp}]"), - IOP("voverp", HSM1_MOD_VOVERP, IF_REAL, "parameter for overshoot [-]"), - IOP("wfc", HSM1_MOD_WFC, IF_REAL, "parameter for narrow channel effect [m*F/(cm^2)]"), - IOP("qme1", HSM1_MOD_QME1, IF_REAL, "parameter for quantum effect [mV]"), - IOP("qme2", HSM1_MOD_QME2, IF_REAL, "parameter for quantum effect [V]"), - IOP("qme3", HSM1_MOD_QME3, IF_REAL, "parameter for quantum effect [m]"), - IOP("gidl1", HSM1_MOD_GIDL1, IF_REAL, "parameter for GIDL [?]"), - IOP("gidl2", HSM1_MOD_GIDL2, IF_REAL, "parameter for GIDL [?]"), - IOP("gidl3", HSM1_MOD_GIDL3, IF_REAL, "parameter for GIDL [?]"), - IOP("gleak1", HSM1_MOD_GLEAK1, IF_REAL, "parameter for gate current [?]"), - IOP("gleak2", HSM1_MOD_GLEAK2, IF_REAL, "parameter for gate current [?]"), - IOP("gleak3", HSM1_MOD_GLEAK3, IF_REAL, "parameter for gate current [?]"), - IOP("vzadd0", HSM1_MOD_VZADD0, IF_REAL, "Vzadd at Vds=0 [V]"), - IOP("pzadd0", HSM1_MOD_PZADD0, IF_REAL, "Pzadd at Vds=0 [V]"), - IOP("nftrp", HSM1_MOD_NFTRP, IF_REAL, ""), - IOP("nfalp", HSM1_MOD_NFALP, IF_REAL, ""), - IOP("cit", HSM1_MOD_CIT, IF_REAL, ""), - IOP("glpart1", HSM1_MOD_GLPART1, IF_REAL, "partitoning of gate current HiSIM1.2"), - IOP("glpart2", HSM1_MOD_GLPART2, IF_REAL, "partitoning of gate current HiSIM1.2"), - IOP("kappa", HSM1_MOD_KAPPA, IF_REAL, "HiSIM1.2 dielectric constant for high-k stacked gate"), - IOP("xdiffd", HSM1_MOD_XDIFFD, IF_REAL, "HiSIM1.2 parameter for W_design [m]"), - IOP("pthrou", HSM1_MOD_PTHROU, IF_REAL, "HiSIM1.2 modify subthreshold sloop [-]"), - IOP("vdiffj", HSM1_MOD_VDIFFJ, IF_REAL, "HiSIM1.2 threshold voltage for S/D junction diode [V]"), - IOP( "ef", HSM1_MOD_EF, IF_REAL, "flicker noise frequency exponent"), - IOP( "af", HSM1_MOD_AF, IF_REAL, "flicker noise exponent"), - IOP( "kf", HSM1_MOD_KF, IF_REAL, "flicker noise coefficient") -}; - -char *HSM1names[] = { - "Drain", - "Gate", - "Source", - "Bulk" -}; - -int HSM1nSize = NUMELEMS(HSM1names); -int HSM1pTSize = NUMELEMS(HSM1pTable); -int HSM1mPTSize = NUMELEMS(HSM1mPTable); -int HSM1iSize = sizeof(HSM1instance); -int HSM1mSize = sizeof(HSM1model); - diff --git a/src/spicelib/devices/hisim/hsm1acld.c b/src/spicelib/devices/hisim/hsm1acld.c deleted file mode 100644 index 5957f0077..000000000 --- a/src/spicelib/devices/hisim/hsm1acld.c +++ /dev/null @@ -1,273 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1acld.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - - -int -HSM1acLoad(GENmodel *inModel, register CKTcircuit *ckt) -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; - double xcggb, xcgdb, xcgsb, xcbgb, xcbdb, xcbsb, xcddb, xcssb, xcdgb; - double gdpr, gspr, gds, gbd, gbs, capbd, capbs, xcsgb, xcdsb, xcsdb; - double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb, omega; - double cgso, cgdo, cgbo, 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 m; /* Multiplier */ - - omega = ckt->CKTomega; - for ( ; model != NULL; model = model->HSM1nextModel ) { - for ( here = model->HSM1instances; here!= NULL; - here = here->HSM1nextInstance ) { - - if (here->HSM1owner != ARCHme) - continue; - - if ( here->HSM1_mode >= 0 ) { - gm = here->HSM1_gm; - gmbs = here->HSM1_gmbs; - FwdSum = gm + gmbs; - RevSum = 0.0; - - gbbdp = -here->HSM1_gbds; - gbbsp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = here->HSM1_gbgs; - gbdpb = here->HSM1_gbbs; - gbdpdp = here->HSM1_gbds; - gbdpsp = -(gbdpg + gbdpb + gbdpdp); - - gbspdp = 0.0; - gbspg = 0.0; - gbspb = 0.0; - gbspsp = 0.0; - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - } - else { - gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; - gIstotg = gIstotd = gIstots = gIstotb = 0.0; - gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; - } - - if (model->HSM1_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->HSM1_cggb; - cgsb = here->HSM1_cgsb; - cgdb = here->HSM1_cgdb; - - cbgb = here->HSM1_cbgb; - cbsb = here->HSM1_cbsb; - cbdb = here->HSM1_cbdb; - - cdgb = here->HSM1_cdgb; - cdsb = here->HSM1_cdsb; - cddb = here->HSM1_cddb; - } - else { - gm = -here->HSM1_gm; - gmbs = -here->HSM1_gmbs; - FwdSum = 0.0; - RevSum = -(gm + gmbs); - - gbbsp = -here->HSM1_gbds; - gbbdp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = 0.0; - gbdpsp = 0.0; - gbdpb = 0.0; - gbdpdp = 0.0; - - gbspg = here->HSM1_gbgs; - gbspsp = here->HSM1_gbds; - gbspb = here->HSM1_gbbs; - gbspdp = -(gbspg + gbspsp + gbspb); - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - } - else { - gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; - gIstotg = gIstotd = gIstots = gIstotb = 0.0; - gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; - } - - if (model->HSM1_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->HSM1_cggb; - cgsb = here->HSM1_cgdb; - cgdb = here->HSM1_cgsb; - - cbgb = here->HSM1_cbgb; - cbsb = here->HSM1_cbdb; - cbdb = here->HSM1_cbsb; - - cdgb = -(here->HSM1_cdgb + cggb + cbgb); - cdsb = -(here->HSM1_cddb + cgsb + cbsb); - cddb = -(here->HSM1_cdsb + cgdb + cbdb); - } - - gdpr = here->HSM1drainConductance; - gspr = here->HSM1sourceConductance; - gds = here->HSM1_gds; - gbd = here->HSM1_gbd; - gbs = here->HSM1_gbs; - capbd = here->HSM1_capbd; - capbs = here->HSM1_capbs; - - cgso = here->HSM1_cgso; - cgdo = here->HSM1_cgdo; - cgbo = here->HSM1_cgbo; - - xcdgb = (cdgb - cgdo) * omega; - xcddb = (cddb + capbd + cgdo) * omega; - xcdsb = cdsb * omega; - xcsgb = -(cggb + cbgb + cdgb + cgso) * omega; - xcsdb = -(cgdb + cbdb + cddb) * omega; - xcssb = (capbs + cgso - (cgsb + cbsb + cdsb)) * omega; - xcggb = (cggb + cgdo + cgso + cgbo) * omega; - xcgdb = (cgdb - cgdo) * omega; - xcgsb = (cgsb - cgso) * omega; - xcbgb = (cbgb - cgbo) * omega; - xcbdb = (cbdb - capbd) * omega; - xcbsb = (cbsb - capbs) * omega; - - m = here->HSM1_m; - - *(here->HSM1GgPtr +1) += m * xcggb; - *(here->HSM1GgPtr) += m * gIgtotg; - *(here->HSM1BbPtr +1) -= m * (xcbgb + xcbdb + xcbsb); - *(here->HSM1DPdpPtr +1) += m * xcddb; - *(here->HSM1SPspPtr +1) += m * xcssb; - *(here->HSM1GbPtr +1) -= m * (xcggb + xcgdb + xcgsb); - *(here->HSM1GbPtr) += m * gIgtotb; - *(here->HSM1GdpPtr +1) += m * xcgdb; - *(here->HSM1GdpPtr) += m * gIgtotd; - *(here->HSM1GspPtr +1) += m * xcgsb; - *(here->HSM1GspPtr) += m * gIgtots; - *(here->HSM1BgPtr +1) += m * xcbgb; - *(here->HSM1BdpPtr +1) += m * xcbdb; - *(here->HSM1BspPtr +1) += m * xcbsb; - *(here->HSM1DPgPtr +1) += m * xcdgb; - *(here->HSM1DPbPtr +1) -= m * (xcdgb + xcddb + xcdsb); - *(here->HSM1DPspPtr +1) += m * xcdsb; - *(here->HSM1SPgPtr +1) += m * xcsgb; - *(here->HSM1SPbPtr +1) -= m * (xcsgb + xcsdb + xcssb); - *(here->HSM1SPdpPtr +1) += m * xcsdb; - - *(here->HSM1DdPtr) += m * gdpr; - *(here->HSM1SsPtr) += m * gspr; - *(here->HSM1BbPtr) += m * (gbd + gbs - here->HSM1_gbbs - gIbtotb); - *(here->HSM1DPdpPtr) += m * (gdpr + gds + gbd + RevSum + gbdpdp); - *(here->HSM1SPspPtr) += m * (gspr + gds + gbs + FwdSum + gbspsp); - - *(here->HSM1DdpPtr) -= m * gdpr; - *(here->HSM1SspPtr) -= m * gspr; - - *(here->HSM1BgPtr) -= m * (here->HSM1_gbgs + gIbtotg); - *(here->HSM1BdpPtr) -= m * (gbd - gbbdp + gIbtotd); - *(here->HSM1BspPtr) -= m * (gbs - gbbsp + gIbtots); - - *(here->HSM1DPdPtr) += m * (gdpr - gIdtotd); - *(here->HSM1DPgPtr) += m * (gm + gbdpg - gIdtotg); - *(here->HSM1DPbPtr) -= m * (gbd - gmbs - gbdpb + gIdtotb); - *(here->HSM1DPspPtr) -= m * (gds + FwdSum - gbdpsp + gIdtots); - - *(here->HSM1SPgPtr) -= m * (gm - gbspg + gIstotg); - *(here->HSM1SPsPtr) -= m * (gspr - gIstots); - *(here->HSM1SPbPtr) -= m * (gbs + gmbs - gbspb + gIstotb); - *(here->HSM1SPdpPtr) -= m * (gds + RevSum - gbspdp + gIstotd); - - /* stamp gidl */ - *(here->HSM1DPdpPtr) += m * here->HSM1_gigidlds; - *(here->HSM1DPgPtr) += m * here->HSM1_gigidlgs; - *(here->HSM1DPspPtr) -= m * (here->HSM1_gigidlgs + - here->HSM1_gigidlds + here->HSM1_gigidlbs); - *(here->HSM1DPbPtr) += m * here->HSM1_gigidlbs; - *(here->HSM1BdpPtr) -= m * here->HSM1_gigidlds; - *(here->HSM1BgPtr) -= m * here->HSM1_gigidlgs; - *(here->HSM1BspPtr) += m * (here->HSM1_gigidlgs + - here->HSM1_gigidlds + here->HSM1_gigidlbs); - *(here->HSM1BbPtr) -= m * here->HSM1_gigidlbs; - /* stamp gisl */ - *(here->HSM1SPdpPtr) -= m * (here->HSM1_gigislsd + - here->HSM1_gigislgd + here->HSM1_gigislbd); - *(here->HSM1SPgPtr) += m * here->HSM1_gigislgd; - *(here->HSM1SPspPtr) += m * here->HSM1_gigislsd; - *(here->HSM1SPbPtr) += m * here->HSM1_gigislbd; - *(here->HSM1BdpPtr) += m * (here->HSM1_gigislgd + - here->HSM1_gigislsd + here->HSM1_gigislbd); - *(here->HSM1BgPtr) -= m * here->HSM1_gigislgd; - *(here->HSM1BspPtr) -= m * here->HSM1_gigislsd; - *(here->HSM1BbPtr) -= m * here->HSM1_gigislbd; - - /* - *(here->HSM1GgPtr) -= m * xgtg; - *(here->HSM1GbPtr) -= m * xgtb; - *(here->HSM1GdpPtr) -= m * xgtd; - *(here->HSM1GspPtr) -= m * xgts; - */ - - } - } - return(OK); -} diff --git a/src/spicelib/devices/hisim/hsm1ask.c b/src/spicelib/devices/hisim/hsm1ask.c deleted file mode 100644 index 37566f297..000000000 --- a/src/spicelib/devices/hisim/hsm1ask.c +++ /dev/null @@ -1,229 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1ask.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "ifsim.h" -#include "cktdefs.h" -#include "devdefs.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1ask(CKTcircuit *ckt, GENinstance *inst, int which, - IFvalue *value, IFvalue *select) -{ - HSM1instance *here = (HSM1instance*)inst; - - NG_IGNORE(select); - - switch (which) { - case HSM1_L: - value->rValue = here->HSM1_l; - return(OK); - case HSM1_W: - value->rValue = here->HSM1_w; - return(OK); - case HSM1_M: - value->rValue = here->HSM1_m; - return(OK); - case HSM1_AS: - value->rValue = here->HSM1_as; - return(OK); - case HSM1_AD: - value->rValue = here->HSM1_ad; - return(OK); - case HSM1_PS: - value->rValue = here->HSM1_ps; - return(OK); - case HSM1_PD: - value->rValue = here->HSM1_pd; - return(OK); - case HSM1_NRS: - value->rValue = here->HSM1_nrs; - return(OK); - case HSM1_NRD: - value->rValue = here->HSM1_nrd; - return(OK); - case HSM1_TEMP: - value->rValue = here->HSM1_temp; - return(OK); - case HSM1_DTEMP: - value->rValue = here->HSM1_dtemp; - return(OK); - case HSM1_OFF: - value->iValue = here->HSM1_off; - return(OK); - case HSM1_IC_VBS: - value->rValue = here->HSM1_icVBS; - return(OK); - case HSM1_IC_VDS: - value->rValue = here->HSM1_icVDS; - return(OK); - case HSM1_IC_VGS: - value->rValue = here->HSM1_icVGS; - return(OK); - case HSM1_DNODE: - value->iValue = here->HSM1dNode; - return(OK); - case HSM1_GNODE: - value->iValue = here->HSM1gNode; - return(OK); - case HSM1_SNODE: - value->iValue = here->HSM1sNode; - return(OK); - case HSM1_BNODE: - value->iValue = here->HSM1bNode; - return(OK); - case HSM1_DNODEPRIME: - value->iValue = here->HSM1dNodePrime; - return(OK); - case HSM1_SNODEPRIME: - value->iValue = here->HSM1sNodePrime; - return(OK); - case HSM1_SOURCECONDUCT: - value->rValue = here->HSM1sourceConductance; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_DRAINCONDUCT: - value->rValue = here->HSM1drainConductance; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_VBD: - value->rValue = *(ckt->CKTstate0 + here->HSM1vbd); - return(OK); - case HSM1_VBS: - value->rValue = *(ckt->CKTstate0 + here->HSM1vbs); - return(OK); - case HSM1_VGS: - value->rValue = *(ckt->CKTstate0 + here->HSM1vgs); - return(OK); - case HSM1_VDS: - value->rValue = *(ckt->CKTstate0 + here->HSM1vds); - return(OK); - case HSM1_CD: - value->rValue = here->HSM1_ids; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CBS: - value->rValue = here->HSM1_ibs; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CBD: - value->rValue = here->HSM1_ibs; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_GM: - value->rValue = here->HSM1_gm; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_GDS: - value->rValue = here->HSM1_gds; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_GMBS: - value->rValue = here->HSM1_gmbs; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_GBD: - value->rValue = here->HSM1_gbd; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_GBS: - value->rValue = here->HSM1_gbs; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_QB: - value->rValue = *(ckt->CKTstate0 + here->HSM1qb); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CQB: - value->rValue = *(ckt->CKTstate0 + here->HSM1cqb); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_QG: - value->rValue = *(ckt->CKTstate0 + here->HSM1qg); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CQG: - value->rValue = *(ckt->CKTstate0 + here->HSM1cqg); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_QD: - value->rValue = *(ckt->CKTstate0 + here->HSM1qd); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CQD: - value->rValue = *(ckt->CKTstate0 + here->HSM1cqd); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CGG: - value->rValue = here->HSM1_cggb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CGD: - value->rValue = here->HSM1_cgdb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CGS: - value->rValue = here->HSM1_cgsb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CDG: - value->rValue = here->HSM1_cdgb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CDD: - value->rValue = here->HSM1_cddb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CDS: - value->rValue = here->HSM1_cdsb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CBG: - value->rValue = here->HSM1_cbgb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CBDB: - value->rValue = here->HSM1_cbdb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CBSB: - value->rValue = here->HSM1_cbsb; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CAPBD: - value->rValue = here->HSM1_capbd; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_CAPBS: - value->rValue = here->HSM1_capbs; - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_VON: - value->rValue = here->HSM1_von; - return(OK); - case HSM1_VDSAT: - value->rValue = here->HSM1_vdsat; - return(OK); - case HSM1_QBS: - value->rValue = *(ckt->CKTstate0 + here->HSM1qbs); - value->rValue *= here->HSM1_m; - return(OK); - case HSM1_QBD: - value->rValue = *(ckt->CKTstate0 + here->HSM1qbd); - value->rValue *= here->HSM1_m; - return(OK); - default: - return(E_BADPARM); - } - /* NOTREACHED */ -} diff --git a/src/spicelib/devices/hisim/hsm1cvtest.c b/src/spicelib/devices/hisim/hsm1cvtest.c deleted file mode 100644 index 8d83723f3..000000000 --- a/src/spicelib/devices/hisim/hsm1cvtest.c +++ /dev/null @@ -1,120 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1cvtest.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "trandefs.h" -#include "const.h" -#include "devdefs.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1convTest(GENmodel *inModel, register CKTcircuit *ckt) -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; - double delvbd, delvbs, delvds, delvgd, delvgs, vbd, vbs, vds; - double cbd, cbhat, cbs, cd, cdhat, tol, vgd, vgdo, vgs; - - /* loop through all the HSM1 device models */ - for ( ; model != NULL; model = model->HSM1nextModel ) { - /* loop through all the instances of the model */ - for ( here = model->HSM1instances; here != NULL ; - here = here->HSM1nextInstance ) { - - - if (here->HSM1owner != ARCHme) - continue; - - vbs = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1bNode) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); - vgs = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1gNode) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); - vds = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1dNodePrime) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); - vbd = vbs - vds; - vgd = vgs - vds; - vgdo = *(ckt->CKTstate0 + here->HSM1vgs) - - *(ckt->CKTstate0 + here->HSM1vds); - delvbs = vbs - *(ckt->CKTstate0 + here->HSM1vbs); - delvbd = vbd - *(ckt->CKTstate0 + here->HSM1vbd); - delvgs = vgs - *(ckt->CKTstate0 + here->HSM1vgs); - delvds = vds - *(ckt->CKTstate0 + here->HSM1vds); - delvgd = vgd - vgdo; - - cd = here->HSM1_ids - here->HSM1_ibd; - if ( here->HSM1_mode >= 0 ) { - cd += here->HSM1_isub; - cdhat = cd - here->HSM1_gbd * delvbd - + (here->HSM1_gmbs + here->HSM1_gbbs) * delvbs - + (here->HSM1_gm + here->HSM1_gbgs) * delvgs - + (here->HSM1_gds + here->HSM1_gbds) * delvds; - } - else { - cdhat = cd + (here->HSM1_gmbs - here->HSM1_gbd) * delvbd - + here->HSM1_gm * delvgd - here->HSM1_gds * delvds; - } - - /* - * check convergence - */ - if ( here->HSM1_off == 0 || !(ckt->CKTmode & MODEINITFIX) ) { - tol = ckt->CKTreltol * MAX(fabs(cdhat), fabs(cd)) + ckt->CKTabstol; - if ( fabs(cdhat - cd) >= tol ) { -#ifdef XSPICE -/* gtri - begin - wbk - report conv prob */ - if(ckt->enh->conv_debug.report_conv_probs) { - ENHreport_conv_prob(ENH_ANALOG_INSTANCE, - (char *) here->HSM1name, - ""); - } -/* gtri - end - wbk - report conv prob */ -#endif - ckt->CKTnoncon++; - return(OK); - } - cbs = here->HSM1_ibs; - cbd = here->HSM1_ibd; - if ( here->HSM1_mode >= 0 ) { - cbhat = cbs + cbd - here->HSM1_isub + here->HSM1_gbd * delvbd - + (here->HSM1_gbs - here->HSM1_gbbs) * delvbs - - here->HSM1_gbgs * delvgs - here->HSM1_gbds * delvds; - } - else { - cbhat = cbs + cbd - here->HSM1_isub - + here->HSM1_gbs * delvbs - + (here->HSM1_gbd - here->HSM1_gbbs) * delvbd - - here->HSM1_gbgs * delvgd + here->HSM1_gbds * delvds; - } - tol = ckt->CKTreltol * - MAX(fabs(cbhat), fabs(cbs + cbd - here->HSM1_isub)) + ckt->CKTabstol; - if ( fabs(cbhat - (cbs + cbd - here->HSM1_isub)) > tol ) { -#ifdef XSPICE -/* gtri - begin - wbk - report conv prob */ - if(ckt->enh->conv_debug.report_conv_probs) { - ENHreport_conv_prob(ENH_ANALOG_INSTANCE, - (char *) here->HSM1name, - ""); - } -/* gtri - end - wbk - report conv prob */ -#endif - ckt->CKTnoncon++; - return(OK); - } - } - } - } - return(OK); -} diff --git a/src/spicelib/devices/hisim/hsm1def.h b/src/spicelib/devices/hisim/hsm1def.h deleted file mode 100644 index e11a14975..000000000 --- a/src/spicelib/devices/hisim/hsm1def.h +++ /dev/null @@ -1,732 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1def.h of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#ifndef HSM1 -#define HSM1 - -#include "ifsim.h" -#include "gendefs.h" -#include "cktdefs.h" -#include "complex.h" -#include "noisedef.h" - -/* declarations for HiSIM1 MOSFETs */ - -/* information needed for each instance */ -typedef struct sHSM1instance { - struct sHSM1model *HSM1modPtr; /* pointer to model */ - struct sHSM1instance *HSM1nextInstance; /* pointer to next instance of - current model*/ - IFuid HSM1name; /* pointer to character string naming this instance */ -/*DW next is additional in ngspice */ - int HSM1owner; /* number of owner process */ - int HSM1states; /* index into state table for this device */ - - int HSM1dNode; /* number of the drain node of the mosfet */ - int HSM1gNode; /* number of the gate node of the mosfet */ - int HSM1sNode; /* number of the source node of the mosfet */ - int HSM1bNode; /* number of the bulk node of the mosfet */ - int HSM1dNodePrime; /* number od the inner drain node */ - int HSM1sNodePrime; /* number od the inner source node */ - - char HSM1_called[4]; /* string to check the first call */ - - /* previous values to evaluate initial guess */ - double HSM1_vbsc_prv; - double HSM1_vdsc_prv; - double HSM1_vgsc_prv; - double HSM1_ps0_prv; - double HSM1_ps0_dvbs_prv; - double HSM1_ps0_dvds_prv; - double HSM1_ps0_dvgs_prv; - double HSM1_pds_prv; - double HSM1_pds_dvbs_prv; - double HSM1_pds_dvds_prv; - double HSM1_pds_dvgs_prv; - double HSM1_ids_prv; - double HSM1_ids_dvbs_prv; - double HSM1_ids_dvds_prv; - double HSM1_ids_dvgs_prv; - - double HSM1_nfc; /* for noise calc. */ - - /* instance */ - double HSM1_l; /* the length of the channel region */ - double HSM1_w; /* the width of the channel region */ - double HSM1_m; /* Parallel multiplier */ - double HSM1_ad; /* the area of the drain diffusion */ - double HSM1_as; /* the area of the source diffusion */ - double HSM1_pd; /* perimeter of drain junction [m] */ - double HSM1_ps; /* perimeter of source junction [m] */ - double HSM1_nrd; /* equivalent num of squares of drain [-] (unused) */ - double HSM1_nrs; /* equivalent num of squares of source [-] (unused) */ - double HSM1_temp; /* lattice temperature [K] */ - double HSM1_dtemp; - - /* added by K.M. */ - double HSM1_weff; /* the effective width of the channel region */ - double HSM1_leff; /* the effective length of the channel region */ - - /* output */ - int HSM1_capop; - double HSM1_gd; - double HSM1_gs; - double HSM1_cgso; - double HSM1_cgdo; - double HSM1_cgbo; - double HSM1_von; /* vth */ - double HSM1_vdsat; - double HSM1_ids; /* cdrain, HSM1_cd */ - double HSM1_gds; - double HSM1_gm; - double HSM1_gmbs; - double HSM1_ibs; /* HSM1_cbs */ - double HSM1_ibd; /* HSM1_cbd */ - double HSM1_gbs; - double HSM1_gbd; - double HSM1_capbs; - double HSM1_capbd; - /* - double HSM1_qbs; - double HSM1_qbd; - */ - double HSM1_capgs; - double HSM1_capgd; - double HSM1_capgb; - double HSM1_isub; /* HSM1_csub */ - double HSM1_gbgs; - double HSM1_gbds; - double HSM1_gbbs; - double HSM1_qg; - double HSM1_qd; - /* double HSM1_qs; */ - double HSM1_qb; /* bulk charge qb = -(qg + qd + qs) */ - double HSM1_cggb; - double HSM1_cgdb; - double HSM1_cgsb; - double HSM1_cbgb; - double HSM1_cbdb; - double HSM1_cbsb; - double HSM1_cdgb; - double HSM1_cddb; - double HSM1_cdsb; - /* no use in SPICE3f5 - double HSM1_nois_irs; - double HSM1_nois_ird; - double HSM1_nois_idsth; - double HSM1_nois_idsfl; - double HSM1_freq; - */ - - double HSM1_mu; /* mobility */ - double HSM1_igidl; /* gate induced drain leakage */ - double HSM1_gigidlgs; - double HSM1_gigidlds; - double HSM1_gigidlbs; - double HSM1_igisl; /* gate induced source leakage */ - double HSM1_gigislgd; - double HSM1_gigislsd; - double HSM1_gigislbd; - double HSM1_igb; /* gate tunneling current (gate to bulk) */ - double HSM1_gigbg; - double HSM1_gigbd; - double HSM1_gigbb; - double HSM1_gigbs; - double HSM1_igs; /* gate tunneling current (gate to source) */ - double HSM1_gigsg; - double HSM1_gigsd; - double HSM1_gigsb; - double HSM1_gigss; - double HSM1_igd; /* gate tunneling current (gate to drain) */ - double HSM1_gigdg; - double HSM1_gigdd; - double HSM1_gigdb; - double HSM1_gigds; - double HSM1_qg_int ; - double HSM1_qd_int ; - double HSM1_qs_int ; - double HSM1_qb_int ; - - /* no use in SPICE3f5 - double HSM1drainSquares; the length of the drain in squares - double HSM1sourceSquares; the length of the source in squares */ - double HSM1sourceConductance; /* cond. of source (or 0): set in setup */ - double HSM1drainConductance; /* cond. of drain (or 0): set in setup */ - - double HSM1_icVBS; /* initial condition B-S voltage */ - double HSM1_icVDS; /* initial condition D-S voltage */ - double HSM1_icVGS; /* initial condition G-S voltage */ - int HSM1_off; /* non-zero to indicate device is off for dc analysis */ - int HSM1_mode; /* device mode : 1 = normal, -1 = inverse */ - - unsigned HSM1_l_Given :1; - unsigned HSM1_w_Given :1; - unsigned HSM1_m_Given :1; - unsigned HSM1_ad_Given :1; - unsigned HSM1_as_Given :1; - /* unsigned HSM1drainSquaresGiven :1; - unsigned HSM1sourceSquaresGiven :1;*/ - unsigned HSM1_pd_Given :1; - unsigned HSM1_ps_Given :1; - unsigned HSM1_nrd_Given :1; - unsigned HSM1_nrs_Given :1; - unsigned HSM1_temp_Given :1; - unsigned HSM1_dtemp_Given :1; - unsigned HSM1dNodePrimeSet :1; - unsigned HSM1sNodePrimeSet :1; - unsigned HSM1_icVBS_Given :1; - unsigned HSM1_icVDS_Given :1; - unsigned HSM1_icVGS_Given :1; - - /* pointer to sparse matrix */ - double *HSM1DdPtr; /* pointer to sparse matrix element at - (Drain node,drain node) */ - double *HSM1GgPtr; /* pointer to sparse matrix element at - (gate node,gate node) */ - double *HSM1SsPtr; /* pointer to sparse matrix element at - (source node,source node) */ - double *HSM1BbPtr; /* pointer to sparse matrix element at - (bulk node,bulk node) */ - double *HSM1DPdpPtr; /* pointer to sparse matrix element at - (drain prime node,drain prime node) */ - double *HSM1SPspPtr; /* pointer to sparse matrix element at - (source prime node,source prime node) */ - double *HSM1DdpPtr; /* pointer to sparse matrix element at - (drain node,drain prime node) */ - double *HSM1GbPtr; /* pointer to sparse matrix element at - (gate node,bulk node) */ - double *HSM1GdpPtr; /* pointer to sparse matrix element at - (gate node,drain prime node) */ - double *HSM1GspPtr; /* pointer to sparse matrix element at - (gate node,source prime node) */ - double *HSM1SspPtr; /* pointer to sparse matrix element at - (source node,source prime node) */ - double *HSM1BdpPtr; /* pointer to sparse matrix element at - (bulk node,drain prime node) */ - double *HSM1BspPtr; /* pointer to sparse matrix element at - (bulk node,source prime node) */ - double *HSM1DPspPtr; /* pointer to sparse matrix element at - (drain prime node,source prime node) */ - double *HSM1DPdPtr; /* pointer to sparse matrix element at - (drain prime node,drain node) */ - double *HSM1BgPtr; /* pointer to sparse matrix element at - (bulk node,gate node) */ - double *HSM1DPgPtr; /* pointer to sparse matrix element at - (drain prime node,gate node) */ - double *HSM1SPgPtr; /* pointer to sparse matrix element at - (source prime node,gate node) */ - double *HSM1SPsPtr; /* pointer to sparse matrix element at - (source prime node,source node) */ - double *HSM1DPbPtr; /* pointer to sparse matrix element at - (drain prime node,bulk node) */ - double *HSM1SPbPtr; /* pointer to sparse matrix element at - (source prime node,bulk node) */ - double *HSM1SPdpPtr; /* pointer to sparse matrix element at - (source prime node,drain prime node) */ - - /* common state values in hisim1 module */ -#define HSM1vbd HSM1states+ 0 -#define HSM1vbs HSM1states+ 1 -#define HSM1vgs HSM1states+ 2 -#define HSM1vds HSM1states+ 3 - -#define HSM1qb HSM1states+ 4 -#define HSM1cqb HSM1states+ 5 -#define HSM1qg HSM1states+ 6 -#define HSM1cqg HSM1states+ 7 -#define HSM1qd HSM1states+ 8 -#define HSM1cqd HSM1states+ 9 - -#define HSM1qbs HSM1states+ 10 -#define HSM1qbd HSM1states+ 11 - -#define HSM1numStates 12 - - /* indices to the array of HiSIM1 NOISE SOURCES (the same as BSIM3) */ -#define HSM1RDNOIZ 0 -#define HSM1RSNOIZ 1 -#define HSM1IDNOIZ 2 -#define HSM1FLNOIZ 3 -#define HSM1TOTNOIZ 4 - -#define HSM1NSRCS 5 /* the number of HiSIM1 MOSFET noise sources */ - -#ifndef NONOISE - double HSM1nVar[NSTATVARS][HSM1NSRCS]; -#else /* NONOISE */ - double **HSM1nVar; -#endif /* NONOISE */ - -} HSM1instance ; - - -/* per model data */ - -typedef struct sHiSIM1model { /* model structure for a resistor */ - int HSM1modType; /* type index of this device type */ - struct sHiSIM1model *HSM1nextModel; /* pointer to next possible model - in linked list */ - HSM1instance * HSM1instances; /* pointer to list of instances - that have this model */ - IFuid HSM1modName; /* pointer to the name of this model */ - int HSM1_type; /* device type: 1 = nmos, -1 = pmos */ - int HSM1_level; /* level */ - int HSM1_info; /* information */ - int HSM1_noise; /* noise model selecter see hsm1noi.c */ - int HSM1_version; /* model version 101/111/120 */ - int HSM1_show; /* show physical value 1, 2, ... , 11 */ - - /* flags for initial guess */ - int HSM1_corsrd ; - int HSM1_coiprv ; - int HSM1_copprv ; - int HSM1_cocgso ; - int HSM1_cocgdo ; - int HSM1_cocgbo ; - int HSM1_coadov ; - int HSM1_coxx08 ; - int HSM1_coxx09 ; - int HSM1_coisub ; - int HSM1_coiigs ; - int HSM1_cogidl ; - int HSM1_cogisl ; - int HSM1_coovlp ; - int HSM1_conois ; - int HSM1_coisti ; /* HiSIM1.1 */ - int HSM1_cosmbi ; /* HiSIM1.2 */ - - /* HiSIM original */ - double HSM1_vmax ; - double HSM1_bgtmp1 ; - double HSM1_bgtmp2 ; - double HSM1_tox ; - double HSM1_xld ; - double HSM1_xwd ; - double HSM1_xj ; /* HiSIM1.0 */ - double HSM1_xqy ; /* HiSIM1.1 */ - double HSM1_rs; /* source contact resistance */ - double HSM1_rd; /* drain contact resistance */ - double HSM1_vfbc ; - double HSM1_nsubc ; - double HSM1_parl1 ; - double HSM1_parl2 ; - double HSM1_lp ; - double HSM1_nsubp ; - double HSM1_scp1 ; - double HSM1_scp2 ; - double HSM1_scp3 ; - double HSM1_sc1 ; - double HSM1_sc2 ; - double HSM1_sc3 ; - double HSM1_pgd1 ; - double HSM1_pgd2 ; - double HSM1_pgd3 ; - double HSM1_ndep ; - double HSM1_ninv ; - double HSM1_ninvd ; - double HSM1_muecb0 ; - double HSM1_muecb1 ; - double HSM1_mueph1 ; - double HSM1_mueph0 ; - double HSM1_mueph2 ; - double HSM1_w0 ; - double HSM1_muesr1 ; - double HSM1_muesr0 ; - double HSM1_bb ; - double HSM1_sub1 ; - double HSM1_sub2 ; - double HSM1_sub3 ; - double HSM1_wvthsc ; /* HiSIM1.1 */ - double HSM1_nsti ; /* HiSIM1.1 */ - double HSM1_wsti ; /* HiSIM1.1 */ - double HSM1_cgso ; - double HSM1_cgdo ; - double HSM1_cgbo ; - double HSM1_tpoly ; - double HSM1_js0 ; - double HSM1_js0sw ; - double HSM1_nj ; - double HSM1_njsw ; - double HSM1_xti ; - double HSM1_cj ; - double HSM1_cjsw ; - double HSM1_cjswg ; - double HSM1_mj ; - double HSM1_mjsw ; - double HSM1_mjswg ; - double HSM1_pb ; - double HSM1_pbsw ; - double HSM1_pbswg ; - double HSM1_xpolyd ; - double HSM1_clm1 ; - double HSM1_clm2 ; - double HSM1_clm3 ; - double HSM1_muetmp ; - double HSM1_rpock1 ; - double HSM1_rpock2 ; - double HSM1_rpocp1 ; /* HiSIM 1.1 */ - double HSM1_rpocp2 ; /* HiSIM 1.1 */ - double HSM1_vover ; - double HSM1_voverp ; - double HSM1_wfc ; - double HSM1_qme1 ; - double HSM1_qme2 ; - double HSM1_qme3 ; - double HSM1_gidl1 ; - double HSM1_gidl2 ; - double HSM1_gidl3 ; - double HSM1_gleak1 ; - double HSM1_gleak2 ; - double HSM1_gleak3 ; - double HSM1_vzadd0 ; - double HSM1_pzadd0 ; - double HSM1_nftrp ; - double HSM1_nfalp ; - double HSM1_cit ; - double HSM1_glpart1 ; /* HiSIM1.2 */ - double HSM1_glpart2 ; /* HiSIM1.2 */ - double HSM1_kappa ; /* HiSIM1.2 */ - double HSM1_xdiffd ; /* HiSIM1.2 */ - double HSM1_pthrou ; /* HiSIM1.2 */ - double HSM1_vdiffj ; /* HiSIM1.2 */ - - /* for flicker noise of SPICE3 added by K.M. */ - double HSM1_ef; - double HSM1_af; - double HSM1_kf; - - /* flag for model */ - unsigned HSM1_type_Given :1; - unsigned HSM1_level_Given :1; - unsigned HSM1_info_Given :1; - unsigned HSM1_noise_Given :1; - unsigned HSM1_version_Given :1; - unsigned HSM1_show_Given :1; - unsigned HSM1_corsrd_Given :1; - unsigned HSM1_coiprv_Given :1; - unsigned HSM1_copprv_Given :1; - unsigned HSM1_cocgso_Given :1; - unsigned HSM1_cocgdo_Given :1; - unsigned HSM1_cocgbo_Given :1; - unsigned HSM1_coadov_Given :1; - unsigned HSM1_coxx08_Given :1; - unsigned HSM1_coxx09_Given :1; - unsigned HSM1_coisub_Given :1; - unsigned HSM1_coiigs_Given :1; - unsigned HSM1_cogidl_Given :1; - unsigned HSM1_cogisl_Given :1; - unsigned HSM1_coovlp_Given :1; - unsigned HSM1_conois_Given :1; - unsigned HSM1_coisti_Given :1; /* HiSIM1.1 */ - unsigned HSM1_cosmbi_Given :1; /* HiSIM1.2 */ - unsigned HSM1_glpart1_Given :1; /* HiSIM1.2 */ - unsigned HSM1_glpart2_Given :1; /* HiSIM1.2 */ - unsigned HSM1_kappa_Given :1; /* HiSIM1.2 */ - unsigned HSM1_xdiffd_Given :1; /* HiSIM1.2 */ - unsigned HSM1_pthrou_Given :1; /* HiSIM1.2 */ - unsigned HSM1_vdiffj_Given :1; /* HiSIM1.2 */ - unsigned HSM1_vmax_Given :1; - unsigned HSM1_bgtmp1_Given :1; - unsigned HSM1_bgtmp2_Given :1; - unsigned HSM1_tox_Given :1; - unsigned HSM1_xld_Given :1; - unsigned HSM1_xwd_Given :1; - unsigned HSM1_xj_Given :1; /* HiSIM1.0 */ - unsigned HSM1_xqy_Given :1; /* HiSIM1.1 */ - unsigned HSM1_rs_Given :1; - unsigned HSM1_rd_Given :1; - unsigned HSM1_vfbc_Given :1; - unsigned HSM1_nsubc_Given :1; - unsigned HSM1_parl1_Given :1; - unsigned HSM1_parl2_Given :1; - unsigned HSM1_lp_Given :1; - unsigned HSM1_nsubp_Given :1; - unsigned HSM1_scp1_Given :1; - unsigned HSM1_scp2_Given :1; - unsigned HSM1_scp3_Given :1; - unsigned HSM1_sc1_Given :1; - unsigned HSM1_sc2_Given :1; - unsigned HSM1_sc3_Given :1; - unsigned HSM1_pgd1_Given :1; - unsigned HSM1_pgd2_Given :1; - unsigned HSM1_pgd3_Given :1; - unsigned HSM1_ndep_Given :1; - unsigned HSM1_ninv_Given :1; - unsigned HSM1_ninvd_Given :1; - unsigned HSM1_muecb0_Given :1; - unsigned HSM1_muecb1_Given :1; - unsigned HSM1_mueph1_Given :1; - unsigned HSM1_mueph0_Given :1; - unsigned HSM1_mueph2_Given :1; - unsigned HSM1_w0_Given :1; - unsigned HSM1_muesr1_Given :1; - unsigned HSM1_muesr0_Given :1; - unsigned HSM1_bb_Given :1; - unsigned HSM1_sub1_Given :1; - unsigned HSM1_sub2_Given :1; - unsigned HSM1_sub3_Given :1; - unsigned HSM1_wvthsc_Given :1; /* HiSIM1.1 */ - unsigned HSM1_nsti_Given :1; /* HiSIM1.1 */ - unsigned HSM1_wsti_Given :1; /* HiSIM1.1 */ - unsigned HSM1_cgso_Given :1; - unsigned HSM1_cgdo_Given :1; - unsigned HSM1_cgbo_Given :1; - unsigned HSM1_tpoly_Given :1; - unsigned HSM1_js0_Given :1; - unsigned HSM1_js0sw_Given :1; - unsigned HSM1_nj_Given :1; - unsigned HSM1_njsw_Given :1; - unsigned HSM1_xti_Given :1; - unsigned HSM1_cj_Given :1; - unsigned HSM1_cjsw_Given :1; - unsigned HSM1_cjswg_Given :1; - unsigned HSM1_mj_Given :1; - unsigned HSM1_mjsw_Given :1; - unsigned HSM1_mjswg_Given :1; - unsigned HSM1_pb_Given :1; - unsigned HSM1_pbsw_Given :1; - unsigned HSM1_pbswg_Given :1; - unsigned HSM1_xpolyd_Given :1; - unsigned HSM1_clm1_Given :1; - unsigned HSM1_clm2_Given :1; - unsigned HSM1_clm3_Given :1; - unsigned HSM1_muetmp_Given :1; - unsigned HSM1_rpock1_Given :1; - unsigned HSM1_rpock2_Given :1; - unsigned HSM1_rpocp1_Given :1; /* HiSIM1.1 */ - unsigned HSM1_rpocp2_Given :1; /* HiSIM1.1 */ - unsigned HSM1_vover_Given :1; - unsigned HSM1_voverp_Given :1; - unsigned HSM1_wfc_Given :1; - unsigned HSM1_qme1_Given :1; - unsigned HSM1_qme2_Given :1; - unsigned HSM1_qme3_Given :1; - unsigned HSM1_gidl1_Given :1; - unsigned HSM1_gidl2_Given :1; - unsigned HSM1_gidl3_Given :1; - unsigned HSM1_gleak1_Given :1; - unsigned HSM1_gleak2_Given :1; - unsigned HSM1_gleak3_Given :1; - unsigned HSM1_vzadd0_Given :1; - unsigned HSM1_pzadd0_Given :1; - unsigned HSM1_nftrp_Given :1; - unsigned HSM1_nfalp_Given :1; - unsigned HSM1_cit_Given :1; - - unsigned HSM1_ef_Given :1; - unsigned HSM1_af_Given :1; - unsigned HSM1_kf_Given :1; - -} HSM1model; - -#ifndef NMOS -#define NMOS 1 -#define PMOS -1 -#endif /*NMOS*/ - -#define HSM1_BAD_PARAM -1 - -/* flags */ -#define HSM1_MOD_NMOS 1 -#define HSM1_MOD_PMOS 2 -#define HSM1_MOD_LEVEL 3 -#define HSM1_MOD_INFO 4 -#define HSM1_MOD_NOISE 5 -#define HSM1_MOD_VERSION 6 -#define HSM1_MOD_SHOW 7 -#define HSM1_MOD_CORSRD 11 -#define HSM1_MOD_COIPRV 12 -#define HSM1_MOD_COPPRV 13 -#define HSM1_MOD_COCGSO 14 -#define HSM1_MOD_COCGDO 15 -#define HSM1_MOD_COCGBO 16 -#define HSM1_MOD_COADOV 17 -#define HSM1_MOD_COXX08 18 -#define HSM1_MOD_COXX09 19 -#define HSM1_MOD_COISUB 21 -#define HSM1_MOD_COIIGS 22 -#define HSM1_MOD_COGIDL 23 -#define HSM1_MOD_COOVLP 24 -#define HSM1_MOD_CONOIS 25 -#define HSM1_MOD_COISTI 26 /* HiSIM1.1 */ -#define HSM1_MOD_COSMBI 27 /* HiSIM1.2 */ -#define HSM1_MOD_COGISL 28 /* HiSIM1.2 */ -/* device parameters */ -#define HSM1_L 51 -#define HSM1_W 52 -#define HSM1_AD 53 -#define HSM1_AS 54 -#define HSM1_PD 55 -#define HSM1_PS 56 -#define HSM1_NRD 57 -#define HSM1_NRS 58 -#define HSM1_TEMP 59 -#define HSM1_DTEMP 60 -#define HSM1_OFF 61 -#define HSM1_IC_VBS 62 -#define HSM1_IC_VDS 63 -#define HSM1_IC_VGS 64 -#define HSM1_IC 65 -#define HSM1_M 66 - -/* model parameters */ -#define HSM1_MOD_VMAX 101 -#define HSM1_MOD_BGTMP1 103 -#define HSM1_MOD_BGTMP2 104 -#define HSM1_MOD_TOX 105 -#define HSM1_MOD_XLD 106 -#define HSM1_MOD_XWD 107 -#define HSM1_MOD_XJ 996 /* HiSIM1.0 */ -#define HSM1_MOD_XQY 997 /* HiSIM1.1 */ -#define HSM1_MOD_RS 108 -#define HSM1_MOD_RD 109 -#define HSM1_MOD_VFBC 110 -#define HSM1_MOD_NSUBC 113 -#define HSM1_MOD_PARL1 122 -#define HSM1_MOD_PARL2 123 -#define HSM1_MOD_SC1 124 -#define HSM1_MOD_SC2 125 -#define HSM1_MOD_SC3 126 -#define HSM1_MOD_NDEP 129 -#define HSM1_MOD_NINV 130 -#define HSM1_MOD_MUECB0 131 -#define HSM1_MOD_MUECB1 132 -#define HSM1_MOD_MUEPH1 133 -#define HSM1_MOD_MUEPH0 134 -#define HSM1_MOD_MUEPH2 999 -#define HSM1_MOD_W0 998 -#define HSM1_MOD_MUESR1 135 -#define HSM1_MOD_MUESR0 136 -#define HSM1_MOD_BB 137 -#define HSM1_MOD_SUB1 141 -#define HSM1_MOD_SUB2 142 -#define HSM1_MOD_SUB3 143 -#define HSM1_MOD_CGSO 144 -#define HSM1_MOD_CGDO 145 -#define HSM1_MOD_CGBO 146 -#define HSM1_MOD_JS0 147 -#define HSM1_MOD_JS0SW 148 -#define HSM1_MOD_NJ 149 -#define HSM1_MOD_NJSW 150 -#define HSM1_MOD_XTI 151 -#define HSM1_MOD_CJ 152 -#define HSM1_MOD_CJSW 156 -#define HSM1_MOD_CJSWG 157 -#define HSM1_MOD_MJ 160 -#define HSM1_MOD_MJSW 161 -#define HSM1_MOD_MJSWG 163 -#define HSM1_MOD_PB 166 -#define HSM1_MOD_PBSW 168 -#define HSM1_MOD_PBSWG 169 -#define HSM1_MOD_XPOLYD 170 -#define HSM1_MOD_TPOLY 171 -#define HSM1_MOD_LP 172 -#define HSM1_MOD_NSUBP 173 -#define HSM1_MOD_SCP1 174 -#define HSM1_MOD_SCP2 175 -#define HSM1_MOD_SCP3 176 -#define HSM1_MOD_PGD1 177 -#define HSM1_MOD_PGD2 178 -#define HSM1_MOD_PGD3 179 -#define HSM1_MOD_CLM1 180 -#define HSM1_MOD_CLM2 181 -#define HSM1_MOD_CLM3 182 -#define HSM1_MOD_NINVD 183 -#define HSM1_MOD_MUETMP 190 -#define HSM1_MOD_RPOCK1 191 -#define HSM1_MOD_RPOCK2 192 -#define HSM1_MOD_VOVER 193 -#define HSM1_MOD_VOVERP 194 -#define HSM1_MOD_WFC 195 -#define HSM1_MOD_QME1 196 -#define HSM1_MOD_QME2 197 -#define HSM1_MOD_QME3 198 -#define HSM1_MOD_GIDL1 199 -#define HSM1_MOD_GIDL2 200 -#define HSM1_MOD_GIDL3 201 -#define HSM1_MOD_GLEAK1 202 -#define HSM1_MOD_GLEAK2 203 -#define HSM1_MOD_GLEAK3 204 -#define HSM1_MOD_VZADD0 205 -#define HSM1_MOD_PZADD0 206 -#define HSM1_MOD_WVTHSC 207 /* HiSIM1.1 */ -#define HSM1_MOD_NSTI 208 /* HiSIM1.1 */ -#define HSM1_MOD_WSTI 209 /* HiSIM1.1 */ -#define HSM1_MOD_RPOCP1 210 /* HiSIM1.1 */ -#define HSM1_MOD_RPOCP2 211 /* HiSIM1.1 */ -#define HSM1_MOD_GLPART1 212 /* HiSIM1.2 */ -#define HSM1_MOD_GLPART2 213 /* HiSIM1.2 */ -#define HSM1_MOD_KAPPA 214 /* HiSIM1.2 */ -#define HSM1_MOD_XDIFFD 215 /* HiSIM1.2 */ -#define HSM1_MOD_PTHROU 216 /* HiSIM1.2 */ -#define HSM1_MOD_VDIFFJ 217 /* HiSIM1.2 */ -#define HSM1_MOD_NFTRP 401 -#define HSM1_MOD_NFALP 402 -#define HSM1_MOD_CIT 403 -#define HSM1_MOD_EF 500 -#define HSM1_MOD_AF 501 -#define HSM1_MOD_KF 502 - -/* device questions */ -#define HSM1_DNODE 341 -#define HSM1_GNODE 342 -#define HSM1_SNODE 343 -#define HSM1_BNODE 344 -#define HSM1_DNODEPRIME 345 -#define HSM1_SNODEPRIME 346 -#define HSM1_VBD 347 -#define HSM1_VBS 348 -#define HSM1_VGS 349 -#define HSM1_VDS 350 -#define HSM1_CD 351 -#define HSM1_CBS 352 -#define HSM1_CBD 353 -#define HSM1_GM 354 -#define HSM1_GDS 355 -#define HSM1_GMBS 356 -#define HSM1_GBD 357 -#define HSM1_GBS 358 -#define HSM1_QB 359 -#define HSM1_CQB 360 -#define HSM1_QG 361 -#define HSM1_CQG 362 -#define HSM1_QD 363 -#define HSM1_CQD 364 -#define HSM1_CGG 365 -#define HSM1_CGD 366 -#define HSM1_CGS 367 -#define HSM1_CBG 368 -#define HSM1_CAPBD 369 -#define HSM1_CQBD 370 -#define HSM1_CAPBS 371 -#define HSM1_CQBS 372 -#define HSM1_CDG 373 -#define HSM1_CDD 374 -#define HSM1_CDS 375 -#define HSM1_VON 376 -#define HSM1_VDSAT 377 -#define HSM1_QBS 378 -#define HSM1_QBD 379 -#define HSM1_SOURCECONDUCT 380 -#define HSM1_DRAINCONDUCT 381 -#define HSM1_CBDB 382 -#define HSM1_CBSB 383 - -#include "hsm1ext.h" - -/* -extern void HSM1evaluate(double,double,double,HSM1instance*,HSM1model*, - double*,double*,double*, double*, double*, double*, double*, - double*, double*, double*, double*, double*, double*, double*, - double*, double*, double*, double*, CKTcircuit*); -*/ - -#endif /*HSM1*/ - diff --git a/src/spicelib/devices/hisim/hsm1del.c b/src/spicelib/devices/hisim/hsm1del.c deleted file mode 100644 index f3b2f171f..000000000 --- a/src/spicelib/devices/hisim/hsm1del.c +++ /dev/null @@ -1,37 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1del.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "hsm1def.h" -#include "sperror.h" -#include "gendefs.h" -#include "suffix.h" - -int -HSM1delete(GENmodel *inModel, IFuid name, GENinstance **inInst) -{ - HSM1instance **fast = (HSM1instance**)inInst; - HSM1model *model = (HSM1model*)inModel; - HSM1instance **prev = NULL; - HSM1instance *here; - - for( ;model ;model = model->HSM1nextModel ) { - prev = &(model->HSM1instances); - for ( here = *prev ;here ;here = *prev ) { - if ( here->HSM1name == name || (fast && here==*fast) ) { - *prev= here->HSM1nextInstance; - FREE(here); - return(OK); - } - prev = &(here->HSM1nextInstance); - } - } - return(E_NODEV); -} diff --git a/src/spicelib/devices/hisim/hsm1dest.c b/src/spicelib/devices/hisim/hsm1dest.c deleted file mode 100644 index b3faa40f6..000000000 --- a/src/spicelib/devices/hisim/hsm1dest.c +++ /dev/null @@ -1,37 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1dest.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "hsm1def.h" -#include "suffix.h" - -void -HSM1destroy(GENmodel **inModel) -{ - HSM1model **model = (HSM1model**)inModel; - HSM1instance *here; - HSM1instance *prev = NULL; - HSM1model *mod = *model; - HSM1model *oldmod = NULL; - - for ( ;mod ;mod = mod->HSM1nextModel ) { - if (oldmod) FREE(oldmod); - oldmod = mod; - prev = NULL; - for ( here = mod->HSM1instances ;here ;here = here->HSM1nextInstance ) { - if (prev) FREE(prev); - prev = here; - } - if (prev) FREE(prev); - } - if (oldmod) FREE(oldmod); - *model = NULL; -} - diff --git a/src/spicelib/devices/hisim/hsm1eval102.c b/src/spicelib/devices/hisim/hsm1eval102.c deleted file mode 100644 index fef3d3bcb..000000000 --- a/src/spicelib/devices/hisim/hsm1eval102.c +++ /dev/null @@ -1,4491 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1eval102.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -/********************************************************************* -* Memorandum on programming -* -* (1) Bias (x: b|d|g) -* . sIN.vxs : Input argument. -* . Vxse: External bias taking account device type (pMOS->nMOS). -* . Vxsc: Confined bias within a specified region. -* . Vxs : Internal bias taking account Rs/Rd. -* . 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. -* . Ps0z: Modified Ps0. -* . The following variables are calculated as a function of -* modified biases or potential. -* Tox, Cox, (-- with quantum effect) -* Vth*, dVth*, dPpg, Qnm, Qbm, Igate, Igidl. -* . The following variables are calculated using a transform -* function. -* Lred, rp1(<-sIN.rpock1). -* -* (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 and -D1. -* . 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 "ngspice.h" - -/*-----------------------------------* -* HiSIM macros and structures. -* - All inputs and outputs are defined here. -*-----------------*/ -#include "hisim.h" -#include "hsm1evalenv.h" - -/*===========================================================* -* Function hsm1eval. (HiSIM1.0.1) -*=================*/ - -int HSM1evaluate102 -( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS -) -{ - -/*---------------------------------------------------* -* Local variables. -*-----------------*/ -/* Constans ----------------------- */ -int lp_s0_max = 20 ; -int lp_sl_max = 20 ; -int lp_bs_max = 10 ; -double Ids_tol = 1.0e-10 ; -double Ids_maxvar = 1.0e-1 ; -double dP_max = 0.1e0 ; -double ps_conv = 5.0e-13 ; -double gs_conv = 1.0e-8 ; -/** depletion **/ -double znbd3 = 3.0e0 ; -double znbd5 = 5.0e0 ; -double cn_nc3 = C_SQRT_2 / 108e0 ; -/* 5-degree, contact:Chi=5 */ -double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ -double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ -double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ -double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ -double cn_nc55 = 6.36964918866352e-5 ; /* (1509-1040*sqrt(2))/600000 */ -/** inversion **/ -/* 3-degree polynomial approx for ( exp[Chi]-1 )^{1/2} */ -double cn_im53 = 2.9693154855770998e-1 ; -double cn_im54 = -7.0536542840097616e-2 ; -double cn_im55 = 6.1152888951331797e-3 ; -/** initial guess **/ -double c_ps0ini_2 = 8.0e-4 ; -double c_pslini_1 = 0.3e0 ; -double c_pslini_2 = 3.0e-2 ; -double VgVt_small = 1.0e-12 ; -double Vbs_max = 0.5e0 ; -double Vbs_min = -10.5e0 ; -double Vds_max = 10.5e0 ; -double Vgs_max = 10.5e0 ; -double Vbd_max = 20.0e0 ; -double Vbd_min = -10.0e0 ; -double epsm10 = 10.0e0 * C_EPS_M ; -double small = 1.0e-50 ; -double Gdsmin = 0.0e0 ; -double Gjmin = sIN.gmin ; /* modified by K.M. for SPICE3f5 */ -double cclmmdf = 1.0e-1 ; -double qme_dlt = 1.0e-9 ; -double eef_dlt = 1.0e-2 ; -double sti_dlt = -3.0e-3 ; -double pol_dlt = 2.0e-1 ; - -/* Internal flags --------------------*/ -int flg_err = 0 ; /* error level */ -int flg_ncnv = 0 ; /* Flag for negative conductance */ -int flg_rsrd ; /* Flag for bias loop accounting Rs and Rd */ -int flg_iprv ; /* Flag for initial guess of Ids */ -int flg_pprv ; /* Flag for initial guesses of Ps0 and Pds */ -int flg_noqi = 0 ; /* Flag for the cases regarding Qi=Qd=0 */ -int flg_vbsc = 0 ; /* Flag for Vbs confining */ -int flg_vdsc = 0 ; /* Flag for Vds confining */ -int flg_vgsc = 0 ; /* Flag for Vgs confining */ -int flg_vbdc = 0 ; /* Flag for Vbd confining */ -int flg_vxxc = 0 ; /* Flag whether some bias was confined */ -int flg_info = 0 ; - -/* Important Variables in HiSIM -------*/ -/* external bias */ -double Vbse , Vdse , Vgse , Vbde ; -/* confine bias */ -double Vbsc , Vdsc , Vgsc , Vbdc ; -double Vbsc_dVbse = 1.0 ; -/* internal bias */ -double Vbs , Vds , Vgs ; -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 = 0.0 ; -double Vgp_dVbs = 0.0 , Vgp_dVds = 0.0 , Vgp_dVgs = 0.0 ; -double Vgs_fb ; -/* Ps0 : surface potential at the source side */ -double Ps0 = 0.0; -double Ps0_dVbs = 0.0, Ps0_dVds = 0.0, Ps0_dVgs = 0.0 ; -double Ps0_ini = 0.0 , Ps0_iniA , Ps0_iniB ; -/* Psl : surface potential at the drain side */ -double Psl = 0.0 ; -double Psl_dVbs = 0.0 , Psl_dVds = 0.0 , Psl_dVgs = 0.0 ; -double Psl_lim ; -/* Pds := Psl - Ps0 */ -double Pds = 0.0 ; -double Pds_dVbs = 0.0 , Pds_dVds = 0.0 , Pds_dVgs = 0.0 ; -double Pds_ini = 0.0; -double Pds_max ; -/* iteration numbers of Ps0 and Psl equations. */ -int lp_s0 , lp_sl ; -/* 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 ; -double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; -/* Xil := beta * ( Psl - Vbs ) - 1. */ -double Xilp12 ; -double Xilp32 ; -double Xil ; -/* modified bias and potential for sym.*/ -double Vbsz , Vdsz = 0.0, Vgsz = 0.0; -double Vbsz_dVbs , Vbsz_dVds ; -double Vdsz_dVds = 0.0 ; -double Vgsz_dVgs , Vgsz_dVds = 0.0 ; -double Vbs1 , Vbs2 , Vbsd ; -double Vbsd_dVbs , Vbsd_dVds ; -double Vzadd = 0.0 , Vzadd_dVds = 0.0; -double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; -double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; -double Ps0Vbsz , Ps0Vbsz_dVbs , Ps0Vbsz_dVds , Ps0Vbsz_dVgs ; -double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; -double Xi0z ; -double Xi0z_dVbs , Xi0z_dVds , Xi0z_dVgs ; -double Xi0zp12 ; -double Xi0zp12_dVbs , Xi0zp12_dVds , Xi0zp12_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 = 0.0; -double Vth0 ; -double Vth0_dVbs , Vth0_dVds , Vth0_dVgs ; -/* variation of threshold voltage */ -double dVth = 0.0; -double dVth_dVbs = 0.0 , dVth_dVds = 0.0 , dVth_dVgs = 0.0 ; -double dVth0 ; -double dVth0_dVbs , dVth0_dVds , dVth0_dVgs ; -double dVthSC ; -double dVthSC_dVbs , dVthSC_dVds , dVthSC_dVgs ; -double dVthW ; -double dVthW_dVbs , dVthW_dVds , dVthW_dVgs ; -/* Alpha and related parameters */ -double Alpha ; -double Alpha_dVbs , Alpha_dVds , Alpha_dVgs ; -double Achi = 0.0 ; -double Achi_dVbs , Achi_dVds , Achi_dVgs ; -double VgVt = 0.0 ; -double VgVt_dVbs , VgVt_dVds , VgVt_dVgs ; -double Delta , Vdsat ; -/* Q_B and capacitances */ -double Qb = 0.0 , Qb_dVbs = 0.0 , Qb_dVds = 0.0 , Qb_dVgs = 0.0 ; -double Qb_dVbse , Qb_dVdse , Qb_dVgse ; -/* Q_I and capacitances */ -double Qi = 0.0 , Qi_dVbs = 0.0 , Qi_dVds = 0.0 , Qi_dVgs = 0.0 ; -double Qi_dVbse , Qi_dVdse , Qi_dVgse ; -/* Q_D and capacitances */ -double Qd = 0.0 , Qd_dVbs = 0.0 , Qd_dVds = 0.0 , Qd_dVgs = 0.0 ; -double Qd_dVbse , Qd_dVdse , Qd_dVgse ; -/* channel current */ -double Ids ; -double Ids_dVbs = 0.0 , Ids_dVds = 0.0 , Ids_dVgs = 0.0 ; -double Ids_dVbse , Ids_dVdse , Ids_dVgse ; -double Ids0 ; -double Ids0_dVbs , Ids0_dVds , Ids0_dVgs ; -/* constants */ -double beta ; -double beta2 ; -double Leff , Leff_inv ; -double Weff ; -double Ldby ; -double Nsub , q_Nsub ; -double Nin ; -double Pb2 ; -double Pb20 ; -double Pb2c ; -double Eg , Eg300 ; -double Vfb ; -/* PART-1 */ -double Psum ; -double Psum_dVbs ; -double Psum_dVds ; -double sqrt_Psum ; -double cnst0 , cnst1 ; -double fac1 ; -double fac1_dVbs , fac1_dVds , fac1_dVgs ; -double fac1p2 ; -double fs01 ; -double fs01_dPs0 , fs01_dChi ; -double fs01_dVbs , fs01_dVds , fs01_dVgs ; -double fs02 ; -double fs02_dPs0 , fs02_dChi ; -double fs02_dVbs , fs02_dVds , fs02_dVgs ; -double fsl1 ; -double fsl1_dPsl ; -double fsl1_dVbs , fsl1_dVds ; -double fsl2 ; -double fsl2_dPsl ; -double fsl2_dVbs , fsl2_dVds ; -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.0 ; -double Qn0_dVbs , Qn0_dVds , Qn0_dVgs ; -double Qb0 ; -double Qb0_dVbs , Qb0_dVds , Qb0_dVgs = 0.0 ; -double Qn00 = 0.0 ; -double Qn00_dVbs = 0.0 , Qn00_dVds = 0.0 , Qn00_dVgs = 0.0 ; -double Qbnm ; -double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; -double DtPds ; -double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; -double Qbm ; -double Qbm_dVbs , Qbm_dVds , Qbm_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 ; -double Qdrat_dVbs , Qdrat_dVds , Qdrat_dVgs ; -double Idd ; -double Idd_dVbs , Idd_dVds , Idd_dVgs ; -double Qnm ; -double Qnm_dVbs , Qnm_dVds , Qnm_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 ; -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 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 Vdep ; -double Vdep_dVbs , Vdep_dVds , Vdep_dVgs ; -double Epkf ; -double Epkf_dVbs , Epkf_dVds , Epkf_dVgs ; -/* PART-3 (overlap) */ -double yn , yn2 , yn3 ; -double yn_dVbs , yn_dVds , yn_dVgs ; -double Lov , Lov2; -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 ; -double Cggo , Cgdo , Cgso , Cgbo ; -/* fringing capacitance */ -double Cf ; -double Qfd , Qfs ; -/* PART-4 (junction diode) */ -double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; -double js ; -double jssw ; -double isbs ; -double isbd ; -double Nvtm ; -/* junction capacitance */ -double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; -double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; -double arg , sarg ; -/* PART-5 (noise) */ -double NFalp , NFtrp , Cit , Nflic ; -/* Bias iteration accounting Rs/Rd */ -int lp_bs ; -double Ids_last ; -double vtol_iprv = 2.0e-1 ; -double vtol_pprv = 5.0e-2 ; -double Vbsc_dif = 0.0 , Vdsc_dif = 0.0 , Vgsc_dif = 0.0 , sum_vdif ; -double Rs , Rd ; -double Fbs , Fds , Fgs ; -double DJ , DJI = 0.0 ; -double JI11 , JI12 , JI13 , JI21 , JI22 , JI23 , JI31 , JI32 , JI33 ; -double dVbs = 0.0 , dVds = 0.0 , dVgs = 0.0 ; -double dV_sum ; -/* Junction Bias */ -double Vbsj , Vbdj ; -/* Accumulation zone */ -double Psa ; -double Psa_dVbs , Psa_dVds , Psa_dVgs ; -/* CLM */ -double Psdl = 0.0 , Psdl_dVbs = 0.0 , Psdl_dVds = 0.0 , Psdl_dVgs = 0.0 ; -double Ed , Ed_dVbs , Ed_dVds , Ed_dVgs ; -double Ec , Ec_dVbs , Ec_dVds , Ec_dVgs ; -double Lred = 0.0 , Lred_dVbs , Lred_dVds , Lred_dVgs ; -double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; -double Aclm ; -/* Pocket Implant */ -double Vthp, Vthp_dVbs, Vthp_dVds, Vthp_dVgs ; -double dVthLP,dVthLP_dVbs,dVthLP_dVds,dVthLP_dVgs ; -/* Poly-Depletion Effect */ -double dPpg = 0.0 , dPpg_dVds = 0.0 , dPpg_dVgs = 0.0 ; -/* Quantum Effect */ -double Tox = 0.0 , Tox_dVbs = 0.0 , Tox_dVds = 0.0 , Tox_dVgs = 0.0 ; -double dTox , dTox_dVbs , dTox_dVds , dTox_dVgs ; -double Cox = 0.0 , Cox_dVbs , Cox_dVds , Cox_dVgs ; -double Cox_inv , Cox_inv_dVbs , Cox_inv_dVds , Cox_inv_dVgs ; -double Vthq, Vthq_dVbs , Vthq_dVds ; -/* Igate , Igidl */ -double Egp12 , Egp32 ; -double E0 = 0.0 ; -double E1 , E1_dVbs , E1_dVds , E1_dVgs ; -double E2 , E2_dVbs , E2_dVds , E2_dVgs ; -double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; -double Egidl , Egidl_dVbs , Egidl_dVds , Egidl_dVgs ; -double Igate , Igate_dVbs , Igate_dVds , Igate_dVgs ; -double Igate_dVbse , Igate_dVdse , Igate_dVgse ; -double Igidl , Igidl_dVbs , Igidl_dVds , Igidl_dVgs ; -double Igidl_dVbse , Igidl_dVdse , Igidl_dVgse ; -double Cox0 ; -double Lgate ; -double rp1 , rp1_dVds ; -/* connecting function */ -double FD2 = 0.0 , FD2_dVbs = 0.0 , FD2_dVds = 0.0 , FD2_dVgs = 0.0 ; -double FMD , FMD_dVds = 0.0 ; -/* Phonon scattering */ -double Wgate ; -double mueph ; -/* temporary vars. */ -double T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ; -double TX , TX_dVbs , TX_dVds , TX_dVgs ; -double TY , TY_dVbs , TY_dVds , TY_dVgs ; -double T1_dVbs , T1_dVds , T1_dVgs ; -double T2_dVbs , T2_dVds , T2_dVgs ; -double T3_dVbs , T3_dVds , T3_dVgs ; -double T4_dVbs , T4_dVds; -double T7_dVbs , T7_dVds , T7_dVgs ; -double T8_dVbs , T8_dVds , T8_dVgs ; -double T10 , T20 , T21 , T30 , T31 ; - -/* intrinsic fringing capacitance */ -double Cgdf, Cgdfring ; - - NG_IGNORE(pMS); - -/*================ Start of executable code.=================*/ - - flg_info = sIN.info ; - -/*-----------------------------------------------------------* -* Change units into CGS. -* - This section may be moved to an interface routine. -*-----------------*/ - -/* device instances */ - sIN.xl *= C_m2cm ; - sIN.xw *= C_m2cm ; - sIN.as *= C_m2cm_p2 ; - sIN.ad *= C_m2cm_p2 ; - sIN.ps *= C_m2cm ; - sIN.pd *= C_m2cm ; - -/* model parameters */ - sIN.tox *= C_m2cm ; - sIN.xld *= C_m2cm ; - sIN.xwd *= C_m2cm ; - sIN.xj *= C_m2cm ; - sIN.lp *= C_m2cm ; - sIN.xpolyd *= C_m2cm ; - sIN.tpoly *= C_m2cm ; - sIN.rs *= C_m2cm ; - sIN.rd *= C_m2cm ; - sIN.sc3 *= C_m2cm ; - sIN.scp3 *= C_m2cm ; - sIN.parl2 *= C_m2cm ; - sIN.wfc *= C_m2cm ; - sIN.rpock1 *= C_m2cm_p1o2 ; - sIN.qme1 *= C_m2cm ; - sIN.qme3 *= C_m2cm ; - sIN.gidl1 /= C_m2cm_p1o2 ; - sIN.cgso /= C_m2cm ; - sIN.cgdo /= C_m2cm ; - sIN.cgbo /= C_m2cm ; - sIN.js0 /= C_m2cm_p2 ; - sIN.js0sw /= C_m2cm ; - sIN.cj /= C_m2cm_p2 ; - sIN.cjsw /= C_m2cm ; - sIN.cjswg /= C_m2cm ; - - -/*-----------------------------------------------------------* -* Start of the routine. (label) not being used so commenting out -*-----------------*/ - -/*start_of_routine:*/ - - -/*-----------------------------------------------------------* -* Temperature dependent constants. -*-----------------*/ - -/* Inverse of the thermal voltage */ - beta = C_QE / ( C_KB * sIN.temp ) ; - beta2 = beta * beta ; - -/* Band gap */ - Eg = C_Eg0 - sIN.temp - * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; - - Eg300 = C_Eg0 - C_T300 - * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ; - -/* Intrinsic carrier concentration */ - Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) - * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ; - -/*-----------------------------------------------------------* -* Fixed part. -*-----------------*/ - -/* Lgate in [cm] / [m] */ - Lgate = sIN.xl + 2.0e0 * sIN.xpolyd ; - Wgate = sIN.xw + 2.0e0 * sIN.xpolyd ; - -/* Phonon Scattering */ - T1 = log( Wgate ) ; - T2 = sIN.w0 - T1 - sti_dlt ; - T3 = T2 * T2 ; - T4 = sqrt( T3 + 4.0 * sti_dlt * sIN.w0 ) ; - T5 = sIN.w0 - ( T2 - T4 ) / 2 ; - mueph = sIN.mueph1 + sIN.mueph2 * T5 ; - -/* Metallurgical channel geometry */ - Weff = Wgate - 2.0e0 * sIN.xwd ; - Leff = Lgate - 2.0e0 * sIN.xld ; - Leff_inv = 1.0e0 / Leff ; - -/* Flat band voltage */ - Vfb = sIN.vfbc ; - -/* Surface impurity profile */ - if( Leff > sIN.lp ){ - Nsub = ( sIN.nsubc * ( Leff - sIN.lp ) - + sIN.nsubp * sIN.lp ) / Leff ; - } else { - Nsub = sIN.nsubp - + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Leff ) / sIN.lp ; - } - - q_Nsub = C_QE * Nsub ; - -/* 2 phi_B */ - /* @temp, with pocket */ - Pb2 = 2.0e0 / beta * log( Nsub / Nin ) ; - /* @300K, with pocket */ - Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; - /* @300K, w/o pocket */ - Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ; - -/* Debye length */ - Ldby = sqrt( C_ESI / beta / q_Nsub ) ; - -/* Coefficient of the F function for bulk charge */ - cnst0 = q_Nsub * Ldby * C_SQRT_2 ; - -/* cnst1: n_{p0} / p_{p0} */ - T1 = Nin / Nsub ; - cnst1 = T1 * T1 ; -/* Cox (clasical) */ - Cox0 = C_EOX / sIN.tox ; - - -/*-----------------------------------------------------------* -* Exchange bias conditions according to MOS type. -* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 -* are assumed.) -*-----------------*/ - - /* - Vbse = sIN.type * sIN.vbs ; - Vdse = sIN.type * sIN.vds ; - Vgse = sIN.type * sIN.vgs ; - Vbde = Vbse - Vdse ; - */ - /* modified by K. M. for SPICE3f5 */ - Vbse = sIN.vbs ; - Vdse = sIN.vds ; - Vgse = sIN.vgs ; - Vbde = Vbse - Vdse ; - - -/*---------------------------------------------------* -* Clamp too large biases. -* -note: Quantities are extrapolated in PART-5. -*-----------------*/ - - if ( Vbse < Vbs_min ) { - flg_vbsc = -1 ; - Vbsc = Vbs_min ; - } else if ( Vbse > 0.0 ) { - flg_vbsc = 1 ; - T1 = Vbse / Vbs_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbsc = Vbse / T2 ; - Vbsc_dVbse = Vbs_max * Vbs_max - / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; - } else { - flg_vbsc = 0 ; - Vbsc = Vbse ; - } - - - if ( Vdse > Vds_max ) { - flg_vdsc = 1 ; - Vdsc = Vds_max ; - } else { - flg_vdsc = 0 ; - Vdsc = Vdse ; - } - - if ( Vgse > Vgs_max ) { - flg_vgsc = 1 ; - Vgsc = Vgs_max ; - } else { - flg_vgsc = 0 ; - Vgsc = Vgse ; - } - - if ( Vbde < Vbd_min ) { - flg_vbdc = -1 ; - Vbdc = Vbd_min ; - } else if ( Vbde > Vbd_max ) { - Vbdc = Vbd_max ; - flg_vbdc = 1 ; - } else { - Vbdc = Vbde ; - flg_vbdc = 0 ; - } - - if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || - flg_vbdc != 0 ) { - flg_vxxc = 1 ; - } - - -/*-------------------------------------------------------------------* -* Set flags. -*-----------------*/ - - flg_rsrd = 0 ; - flg_iprv = 0 ; - flg_pprv = 0 ; - - if (sIN.mode == HiSIM_NORMAL_MODE) { - Rs = sIN.rs / Weff ; - Rd = sIN.rd / Weff ; - } - else { - Rd = sIN.rs / Weff ; - Rs = sIN.rd / Weff ; - } - - if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { - flg_rsrd = 1 ; - } - - if ( sIN.has_prv == 1 ) { - - Vbsc_dif = Vbsc - sIN.vbsc_prv ; - Vdsc_dif = Vdsc - sIN.vdsc_prv ; - Vgsc_dif = Vgsc - sIN.vgsc_prv ; - - sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) - + fabs( Vgsc_dif ) ; - - if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} - if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} - } - - if ( flg_rsrd == 0 ) { - lp_bs_max = 1 ; - flg_iprv = 0 ; - } - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* -* Bias loop: iteration to solve the system of equations of -* the small circuit taking account Rs and Rd. -* - Vxs are internal (or effective) biases. -* - Equations: -* Vbs = Vbsc - Rs * Ids -* Vds = Vdsc - ( Rs + Rd ) * Ids -* Vgs = Vgsc - Rs * Ids -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initial guesses for biases. -*-----------------*/ - - if ( flg_iprv == 1 ) { - - sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; - sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; - sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; - - dVbs = Vbsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; - dVds = Vdsc_dif * ( 1.0 - - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; - dVgs = Vgsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; - - /* - Ids = sIN.type * sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - */ - Ids = sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - - T1 = ( Ids - sIN.ids_prv ) ; - T2 = fabs( T1 ) ; - if ( Ids_maxvar * sIN.ids_prv < T2 ) { - Ids = sIN.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 ; - } - } - - Vbs = Vbsc - Ids * Rs ; - - Vds = Vdsc - Ids * ( Rs + Rd ) ; - if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } - - Vgs = Vgsc - Ids * Rs ; - - if ( flg_pprv == 1 ) { - - Ps0 = sIN.ps0_prv ; - - Ps0_dVbs = sIN.ps0_dvbs_prv ; - Ps0_dVds = sIN.ps0_dvds_prv ; - Ps0_dVgs = sIN.ps0_dvgs_prv ; - - Pds = sIN.pds_prv ; - - Pds_dVbs = sIN.pds_dvbs_prv ; - Pds_dVds = sIN.pds_dvds_prv ; - Pds_dVgs = sIN.pds_dvgs_prv ; - } - - -/*-----------------------------------------------------------* -* start of the loop. -*-----------------*/ - - for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { - - Ids_last = Ids ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-1: Basic device characteristics. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initialization. -*-----------------*/ - /* Initialization of counters is needed for restart. */ - lp_s0 = 0 ; - lp_sl = 0 ; - -/*-----------------------------------------------------------* -* Vxsz: Modified bias introduced to realize symmetry at Vds=0. -*-----------------*/ - - T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVds = 0.0 ; - } - - Vbsz = Vbs + Vzadd ; - Vbsz_dVbs = 1.0 ; - Vbsz_dVds = Vzadd_dVds ; - - Vdsz = Vds + 2 * Vzadd ; - Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; - - Vgsz = Vgs + Vzadd ; - Vgsz_dVgs = 1.0 ; - Vgsz_dVds = Vzadd_dVds ; - - -/*-----------------------------------------------------------* -* Quantum effect -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / C_EOX * T2 + sIN.qme2 ; - - T3 = - 0.5 * sIN.tox / C_EOX * T1 / T2 ; - Vthq_dVbs = T3 * Vbsz_dVbs ; - Vthq_dVds = T3 * Vbsz_dVds ; - - T1 = - sIN.qme2 ; - T2 = Vgsz - Vthq ; - T3 = sIN.qme1 * T1 * T1 + sIN.qme3 ; - T4 = sIN.qme1 * T2 * T2 + sIN.qme3 ; - T5 = T4 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T4 - T3 + qme_dlt ) / T6 ) ; - T8 = 2.0 * sIN.qme1 * T2 * T7 ; - - dTox_dVbs = T8 * ( - Vthq_dVbs ) ; - dTox_dVds = T8 * ( Vgsz_dVds - Vthq_dVds ) ; - dTox_dVgs = T8 * ( Vgsz_dVgs ) ; - - if ( Vgsz - Vthq > 0 ) { - T4 = sIN.qme3 ; - T5 = T4 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - dTox = T4 - 0.5 * ( T5 + T6 ) ; - dTox_dVbs = 0.0 ; - dTox_dVds = 0.0 ; - dTox_dVgs = 0.0 ; - } - - Tox = sIN.tox + dTox ; - Tox_dVbs = dTox_dVbs ; - Tox_dVds = dTox_dVds ; - Tox_dVgs = dTox_dVgs ; - - Cox = C_EOX / Tox ; - T1 = - C_EOX / ( Tox * Tox ) ; - Cox_dVbs = T1 * Tox_dVbs ; - Cox_dVds = T1 * Tox_dVds ; - Cox_dVgs = T1 * Tox_dVgs ; - - Cox_inv = Tox / C_EOX ; - T1 = 1.0 / C_EOX ; - Cox_inv_dVbs = T1 * Tox_dVbs ; - Cox_inv_dVds = T1 * Tox_dVds ; - Cox_inv_dVgs = T1 * Tox_dVgs ; - - -/*-----------------------------------------------------------* -* Threshold voltage. -*-----------------*/ - - Delta = 0.1 ; - - Vbs1 = 2.0 - 0.25 * Vbsz ; - Vbs2 = - Vbsz ; - - Vbsd = Vbs1 - Vbs2 - Delta ; - Vbsd_dVbs = 0.75 * Vbsz_dVbs ; - Vbsd_dVds = 0.75 * Vbsz_dVds ; - - T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; - - Psum = ( Pb20 - Vbsz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVbs = - Vbsz_dVbs ; - Psum_dVds = - Vbsz_dVds ; - } else { - Psum = epsm10 ; - Psum_dVbs = 0.0e0 ; - Psum_dVds = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - - -/*---------------------------------------------------* -* Vthp : Vth with pocket. -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Qb0_dVbs = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; - Qb0_dVds = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; - - Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; - - Vthp_dVbs = Qb0_dVbs * Cox_inv + Qb0 * Cox_inv_dVbs ; - Vthp_dVds = Qb0_dVds * Cox_inv + Qb0 * Cox_inv_dVds ; - Vthp_dVgs = Qb0 * Cox_inv_dVgs ; - - -/*-------------------------------------------* -* dVthLP : Short-channel effect induced by pocket. -* - Vth0 : Vth without pocket. -*-----------------*/ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbsz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * Cox_inv ; - - Vth0_dVbs = 0.5 * T1 / T2 * ( - Vbsz_dVbs ) * Cox_inv - + T2 * Cox_inv_dVbs ; - Vth0_dVds = 0.5 * T1 / T2 * ( - Vbsz_dVds ) * Cox_inv - + T2 * Cox_inv_dVds ; - Vth0_dVgs = T2 * Cox_inv_dVgs ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / sIN.parl1 / ( sIN.lp * sIN.lp ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - T1 = Vthp - Vth0 ; - T2 = sIN.scp1 + sIN.scp3 * Psum / sIN.lp ; - T3 = T2 + sIN.scp2 * Vdsz ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVbs = ( Vthp_dVbs - Vth0_dVbs ) * dVth0 * T3 - + T1 * dVth0_dVbs * T3 - + T1 * dVth0 * sIN.scp3 * Psum_dVbs / sIN.lp ; - dVthLP_dVds = ( Vthp_dVds - Vth0_dVds ) * dVth0 * T3 - + T1 * dVth0_dVds * T3 - + T1 * dVth0 - * ( sIN.scp3 * Psum_dVds / sIN.lp - + sIN.scp2 * Vdsz_dVds ) ; - - dVthLP_dVgs = ( Vthp_dVgs - Vth0_dVgs ) * dVth0 * T3 - + T1 * dVth0_dVgs * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVbs = 0.0e0 ; - dVthLP_dVds = 0.0e0 ; - dVthLP_dVgs = 0.0e0 ; - } - - -/*---------------------------------------------------* -* dVthSC : Short-channel effect induced by Vds. -*-----------------*/ - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = ( Leff - sIN.parl2 ) ; - T4 = 1.0e0 / sIN.parl1 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - - T4 = sIN.sc1 + sIN.sc3 * Psum / Leff ; - T4_dVbs = sIN.sc3 * Psum_dVbs / Leff ; - T4_dVds = sIN.sc3 * Psum_dVds / Leff ; - - T5 = sIN.sc2 ; - - dVthSC = dVth0 * ( T4 + T5 * Vdsz ) ; - - dVthSC_dVbs = dVth0_dVbs * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVbs ) ; - - dVthSC_dVds = dVth0_dVds * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVds + T5 * Vdsz_dVds ) ; - - dVthSC_dVgs = dVth0_dVgs * ( T4 + T5 * Vdsz ) ; - - -/*---------------------------------------------------* -* dVthW : narrow-channel effect. -*-----------------*/ - - T1 = 1.0 / Cox ; - T2 = T1 * T1 ; - T3 = 1.0 / ( Cox + sIN.wfc / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVbs = Qb0_dVbs * ( T1 - T3 ) - - Qb0 * Cox_dVbs * ( T2 - T4 ) ; - dVthW_dVds = Qb0_dVds * ( T1 - T3 ) - - Qb0 * Cox_dVds * ( T2 - T4 ) ; - dVthW_dVgs = - Qb0 * Cox_dVgs * ( T2 - T4 ) ; - - -/*---------------------------------------------------* -* dVth : Total variation. -* - Positive dVth means the decrease in Vth. -*-----------------*/ - - dVth = dVthSC + dVthLP + dVthW ; - dVth_dVbs = dVthSC_dVbs + dVthLP_dVbs + dVthW_dVbs ; - dVth_dVds = dVthSC_dVds + dVthLP_dVds + dVthW_dVds ; - dVth_dVgs = dVthSC_dVgs + dVthLP_dVgs + dVthW_dVgs ; - - -/*---------------------------------------------------* -* Vth : Threshold voltage. -*-----------------*/ - - Vth = Vthp - dVth ; - - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - dPpg = Nsub / sIN.nsubc * sIN.pgd1 - * exp( Vgsz - sIN.pgd2 - sIN.pgd3 * Vdsz ) ; - dPpg_dVds = - sIN.pgd3 * dPpg * Vdsz_dVds - + dPpg * Vgsz_dVds ; - dPpg_dVgs = dPpg * Vgsz_dVgs ; - - T1 = 1.0e0 - dPpg - pol_dlt ; - T1_dVds = - dPpg_dVds ; - T1_dVgs = - dPpg_dVgs ; - T2 = sqrt( T1 * T1 + 4.0e0 * pol_dlt ) ; - - dPpg = 1.0e0 - 0.5e0 * ( T1 + T2 ) ; - dPpg_dVds = - 0.5e0 * ( T1_dVds + T1 * T1_dVds / T2 ) ; - dPpg_dVgs = - 0.5e0 * ( T1_dVgs + T1 * T1_dVgs / T2 ) ; - - -/*---------------------------------------------------* -* Vgp : Effective gate bias with SCE & RSCE & flatband. -*-----------------*/ - - Vgp = Vgs - Vfb + dVth - dPpg ; - - Vgp_dVbs = dVth_dVbs ; - Vgp_dVds = dVth_dVds - dPpg_dVds ; - Vgp_dVgs = 1.0e0 + dVth_dVgs - dPpg_dVgs ; - - -/*---------------------------------------------------* -* Vgs_fb : Actual flatband voltage taking account Vbs. -* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . -*------------------*/ - - Vgs_fb = Vfb - dVth + dPpg + Vbs ; - - -/*-----------------------------------------------------------* -* Constants in the equation of Ps0 . -*-----------------*/ - - fac1 = cnst0 * Cox_inv ; - fac1_dVbs = cnst0 * Cox_inv_dVbs ; - fac1_dVds = cnst0 * Cox_inv_dVds ; - fac1_dVgs = cnst0 * Cox_inv_dVgs ; - - fac1p2 = fac1 * fac1 ; - - -/*-----------------------------------------------------------* -* Accumulation zone. (zone-A) -* - evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Vgs < Vgs_fb ) { - - -/*---------------------------------------------------* -* 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 = Eg - Pb2 ; - - TX = beta * ( Vgp - Vbs ) ; - - TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; - TX_dVds = beta * Vgp_dVds ; - TX_dVgs = beta * Vgp_dVgs ; - - TY = Cox / ( beta * cnst0 ) ; - - T1 = 1.0 / ( beta * cnst0 ) ; - TY_dVbs = T1 * Cox_dVbs ; - TY_dVds = T1 * Cox_dVds ; - TY_dVgs = T1 * Cox_dVgs ; - - 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 ; - - Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; - Ac31_dVbs = - 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac31_dVds = - 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac31_dVgs = - 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Ac3 = Ac31 * Ac31 ; - - Ac3_dVbs = 2.0 * Ac31 * Ac31_dVbs ; - Ac3_dVds = 2.0 * Ac31 * Ac31_dVds ; - Ac3_dVgs = 2.0 * Ac31 * Ac31_dVgs ; - - Ac2 = sqrt( Ac4 + Ac3 ) ; - Ac2_dVbs = 0.5 * ( Ac4_dVbs + Ac3_dVbs ) / Ac2 ; - Ac2_dVds = 0.5 * ( Ac4_dVds + Ac3_dVds ) / Ac2 ; - Ac2_dVgs = 0.5 * ( Ac4_dVgs + Ac3_dVgs ) / Ac2 ; - - Ac1 = -7.0 * C_SQRT_2 - + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; - - Ac1_dVbs = Ac2_dVbs - + 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac1_dVds = Ac2_dVds - + 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac1_dVgs = Ac2_dVgs - + 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Acd = pow( Ac1 , C_1o3 ) ; - - T1 = C_1o3 / ( Acd * Acd ) ; - Acd_dVbs = Ac1_dVbs * T1 ; - 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 ; - - Acn_dVbs = - 12.0 * TY_dVbs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVbs ; - Acn_dVds = - 12.0 * TY_dVds - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVds ; - Acn_dVgs = - 12.0 * TY_dVgs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVgs ; - - Chi = Acn / Acd ; - - T1 = 1.0 / ( Acd * Acd ) ; - - Chi_dVbs = ( Acn_dVbs * Acd - Acn * Acd_dVbs ) * T1 ; - Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; - Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; - - Psa = Chi / beta + Vbs ; - - Psa_dVbs = Chi_dVbs / beta + 1.0 ; - Psa_dVds = Chi_dVds / beta ; - Psa_dVgs = Chi_dVgs / beta ; - - T1 = Psa - Vbs ; - T2 = T1 / Ps0_min ; - T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; - - T9 = T2 / T3 / Ps0_min ; - T3_dVbs = T9 * ( Psa_dVbs - 1.0 ) ; - T3_dVds = T9 * ( Psa_dVds ) ; - T3_dVgs = T9 * ( Psa_dVgs ) ; - - Ps0 = T1 / T3 + Vbs ; - - T9 = 1.0 / ( T3 * T3 ) ; - - Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVbs ) - + 1.0 ; - Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVds ) ; - Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVgs ) ; - - -/*---------------------------------------------------* -* Characteristics. -*-----------------*/ - - T0 = - Weff * Leff ; - T1 = T0 * Cox ; - T2 = ( Vgp - Ps0 ) ; - - Qb = T1 * T2 ; - - Qb_dVbs = T1 * ( Vgp_dVbs - Ps0_dVbs ) - + T0 * Cox_dVbs * T2 ; - Qb_dVds = T1 * ( Vgp_dVds - Ps0_dVds ) - + T0 * Cox_dVds * T2 ; - Qb_dVgs = T1 * ( Vgp_dVgs - Ps0_dVgs ) - + T0 * Cox_dVgs * T2 ; - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Qi = 0.0e0 ; - Qi_dVbs = 0.0e0 ; - Qi_dVds = 0.0e0 ; - Qi_dVgs = 0.0e0 ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - 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 / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; - - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - - if ( flg_pprv == 1 ) { - - Ps0_ini = Ps0 + Ps0_dVbs * dVbs - + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; - - T1 = Ps0_ini - Ps0 ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } else { - Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { - -/*-------------------------------------------* -* Common part. -*-----------------*/ - - Chi = beta * ( Ps0_iniA - Vbs ) ; - -/*-----------------------------------* -* zone-D1/D2 -* - Ps0_ini is the analytical solution of Qs=Qb0 with -* Qb0 being approximated to 3-degree polynomial. -*-----------------*/ - - if ( Chi < znbd3 ) { - - TY = beta * ( Vgp - Vbs ) ; - T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; - T2 = 81 + 3 * T1 ; - T3 = -2916 - 81 * T1 + 27 * T1 * TY ; - T4 = 1458 - 81 * ( 54 + T1 ) + 27 * T1 * TY ; - T4 = T4 * T4 ; - T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; - TX = 3 - - ( C_2p_1o3 * T2 ) / ( 3 * T5 ) - + 1 / ( 3 * C_2p_1o3 ) * T5 ; - - Ps0_iniA = TX / beta + Vbs ; - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Weak inversion zone. -*-----------------*/ - } else if ( Vgs <= Vth ) { - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Strong inversion zone. -* - Ps0_iniB : upper bound. -*-----------------*/ - } else { - - T1 = ( Cox * Cox ) / ( cnst0 * cnst0 ) / cnst1 ; - T2 = T1 * Vgp * Vgp ; - T3 = beta + 2.0 / Vgp ; - - Ps0_iniB = log( T2 ) / T3 ; - - T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; - T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; - - Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; - - } - } - - if ( Ps0_ini < Vbs ) { - Ps0_ini = Vbs ; - } - - -/*---------------------------------------------------* -* Assign initial guess. -*-----------------*/ - - 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 ; - - for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) - / ( fs02 + fs02 ) ; - } else { - fs02 = sqrt( fb * fb + fs01 ) ; - fs02_dPs0 = beta * fb_dChi ; - } - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - } /* end of if ( Chi ... ) else block */ - - -/*-------------------------------------------* -* Update Ps0 . -* - clamped to Vbs if Ps0 < Vbs . -*-----------------*/ - - if ( fabs( dPs0 ) > dP_max ) { - dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; - } - - Ps0 = Ps0 + dPs0 ; - - if ( Ps0 < Vbs ) { - Ps0 = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { - break ; - } - - } /* end of Ps0 Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_s0 > lp_s0_max ) { - 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. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - cfs1 = cnst1 * exp_bVbs ; - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; - - T2 = 1.0e0 / ( fs02 + fs02 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; - fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) - * T2 ; - } else { - fs02_dPs0 = beta * fb_dChi ; - fs02_dVbs = - beta * fb_dChi ; - } - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - T1 = cnst0 ; - - Qb0 = T1 * fb ; - Qb0_dVbs = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; - Qb0_dVds = Ps0_dVds * T1 * beta * fb_dChi ; - Qb0_dVgs = Ps0_dVgs * T1 * beta * fb_dChi ; - - 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 ; - - T1 = 1.0 / ( fs02 + fb * fb ) ; - T2 = T1 * T1 ; - - Qn0 = cnst0 * fs01 * T1 ; - - T3 = 2.0 * fb_dChi * fb * beta ; - - Qn0_dVbs = cnst0 * ( - fs01_dVbs * T1 - - fs01 * ( fs02_dVbs - + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; - Qn0_dVds = cnst0 * ( - fs01_dVds * T1 - - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; - Qn0_dVgs = cnst0 * ( - fs01_dVgs * T1 - - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ; - - -/*-------------------------------------------* -* zone-D1. (Ps0) -* - Evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Chi < znbd3 ) { - - 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 ; - - T1 = - Weff * Leff ; - - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - if ( Qn0 < Cox * VgVt_small ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - Qi = T1 * Qn0 ; - Qi_dVbs = T1 * Qn0_dVbs ; - Qi_dVds = T1 * Qn0_dVds ; - Qi_dVgs = T1 * Qn0_dVgs ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-------------------------------------------* -* zone-D2 -*-----------------*/ - - Xi0 = Chi - 1.0e0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - Qn00 = Qn0 ; - Qn00_dVbs = Qn0_dVbs ; - Qn00_dVds = Qn0_dVds ; - Qn00_dVgs = Qn0_dVgs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - flg_noqi = 0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - T2 = 0.5e0 / Xi0p12 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - flg_noqi = 0 ; - - } /* end of if ( Chi ... ) block */ - - -/*-----------------------------------------------------------* -* NOTE: The following sections of this part are only for -* the conductive case. -*-----------------*/ - -/*-----------------------------------------------------------* -* Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 . -*-----------------*/ -/*-----------------------------------------------------------* -* Qn0 : Qi at source side. -* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) -* - Derivatives of fs01 are redefined here. -*-----------------*/ -/* note:------------------------ -* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; -* fs02 = sqrt( Xi0 + fs01 ) ; -*-------------------------------*/ - - Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; - - 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 ; - - Qn0_dVbs = Qn0 - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVds = Qn0 - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVgs = Qn0 - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ; - - -/*-----------------------------------------------------------* -* Qb0 : Qb at source side. -*-----------------*/ - - if ( Chi > znbd5 ) { - - Qb0 = cnst0 * Xi0p12 ; - Qb0_dVbs = cnst0 * Xi0p12_dVbs ; - Qb0_dVds = cnst0 * Xi0p12_dVds ; - Qb0_dVgs = cnst0 * Xi0p12_dVgs ; - - } - - -/*-----------------------------------------------------------* -* FD2 : connecting function for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - } - - -/*-----------------------------------------------------------* -* Modify Qn0 for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; - Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; - Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; - - Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; - - if ( Qn0 < 0.0 ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - } - - -/*---------------------------------------------------* -* VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) -*-----------------*/ - - VgVt = Qn0 * Cox_inv ; - VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVbs ; - VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVds ; - VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVgs ; - - -/*-----------------------------------------------------------* -* make Qi=Qd=Ids=0 if VgVt <= VgVt_small -*-----------------*/ - - if ( VgVt <= VgVt_small ) { - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Pds = 0.0 ; - Pds_dVbs = 0.0 ; - Pds_dVds = 0.0 ; - Pds_dVgs = 0.0 ; - - T1 = - Leff * Weff ; - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-----------------------------------------------------------* -* Start point of Psl (= Ps0 + Pds) calculation. (label) -* not really being used so commenting out -*-----------------*/ -/*start_of_Psl: ; */ - - exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; - - -/*---------------------------------------------------* -* Skip Psl calculation when Vds is very small. -*-----------------*/ - if ( Vds <= epsm10 ) { - Pds = 0.0 ; - Psl = Ps0 ; - goto end_of_loopl ; - } - - -/*-----------------------------------------------------------* -* Initial guess for Pds ( = Psl - Ps0 ). -*-----------------*/ - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - - if ( flg_pprv == 1 ) { - - Pds_ini = Pds + Pds_dVbs * dVbs - + Pds_dVds * dVds + Pds_dVgs * dVgs ; - - T1 = Pds_ini - Pds ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { - Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ) ; - - T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; - T2 = T1 - Vds - c_pslini_2 ; - T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; - - Pds_ini = T1 - ( T2 + T3 ) / 2 ; - - 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. -*-----------------*/ - - Pds = Pds_ini ; - Psl = Ps0 + Pds ; - - -/*---------------------------------------------------* -* Calculation of Psl by solving Poisson eqn. -* (beginning of Newton loop) -* - Fsl : Fsl = 0 is the equation to be solved. -* - dPsl : correction value. -*-----------------*/ - - for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { - - Chi = beta * ( Psl - Vbs ) ; - - -/*-------------------------------------------* -* zone-D2. (Psl) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) - / ( fsl2 + fsl2 ) ; - } else { - fsl2 = sqrt( fb * fb + fsl1 ) ; - fsl2_dPsl = beta * fb_dChi ; - } - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - if ( fsl1 < epsm10 * cnst1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - } - - -/*-------------------------------------------* -* Update Psl . -* - clamped to Vbs if Psl < Vbs . -*-----------------*/ - - if ( fabs( dPsl ) > dP_max ) { - dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; - } - - Psl = Psl + dPsl ; - - if ( Psl < Vbs ) { - Psl = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { - break ; - } - - } /* end of Psl Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_sl > lp_sl_max ) { - 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" ) ; - } - } - - -/*---------------------------------------------------* -* End of Psl calculation. (label) -*-----------------*/ -end_of_loopl: ; - -/*---------------------------------------------------* -* Assign Pds. -*-----------------*/ - - Pds = Psl - Ps0 ; - - if ( Pds < ps_conv ) { - Pds = 0.0 ; - Psl = Ps0 ; - } - - -/*---------------------------------------------------* -* 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. -*-----------------*/ - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ) ; - - /*note: cfs1 = cnst1 * exp_bVbsVds */ - fsl1 = cfs1 * fi * fi ; - fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; - fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; - fsl1_dVds = - cfs1 * beta * fi * fi ; - - 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 ) ; - - T2 = 0.5 / fsl2 ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; - fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; - fsl2_dVds = fsl1_dVds * T2 ; - } else { - fsl2_dPsl = beta * fb_dChi ; - fsl2_dVbs = - beta * fb_dChi ; - fsl2_dVds = 0.0 ; - } - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - Pds_dVbs = Psl_dVbs - Ps0_dVbs ; - Pds_dVds = Psl_dVds - Ps0_dVds ; - Pds_dVgs = Psl_dVgs - Ps0_dVgs ; - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; - fsl1_dVds = - beta * fsl1 ; - - - if ( fsl1 < epsm10 * T1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - fsl1_dVds = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - T2 = 0.5e0 / fsl2 ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; - - fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; - fsl2_dVds = ( fsl1_dVds ) * T2 ; - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - T2 = 0.5e0 / Xilp12 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - 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 ; - } - - -/*-----------------------------------------------------------* -* Evaluate Qb and Idd. -* - Eta : substantial variable of QB'/Pds and Idd/Pds. -* - note: Eta = 4 * GAMMA_{hisim_0} -*-----------------*/ - - Eta = beta * Pds / Xi0 ; - - Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) - / Xi0 ; - Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; - Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; - - - /* ( 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 = - 0.5e0 / Xi0p32 ; - T4 = - 0.5e0 / Eta1p12 * F00 ; - - F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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_1o3 / Xi0p12 * T1 ; - T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; - - F10_dVbs = Zeta32 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F10_dVds = Zeta32 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F10_dVgs = Zeta32 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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 = 2e0 / ( 5e0 * beta ) * Xi0p12 * T1 ; - T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 - + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; - - F30_dVbs = Zeta52 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F30_dVds = Zeta52 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F30_dVgs = Zeta52 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* F11 := PS11/Pds. -*-----------------*/ - - F11 = Ps0 * F10 + C_2o3 / beta * Xilp32 - F30 ; - - F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs - + ( Xi0_dVbs / beta + Pds_dVbs ) * Xilp12 - - F30_dVbs ; - F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds - + ( Xi0_dVds / beta + Pds_dVds ) * Xilp12 - - F30_dVds ; - F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs - + ( Xi0_dVgs / beta + Pds_dVgs ) * Xilp12 - - F30_dVgs ; - - -/*---------------------------------------------------* -* Fdd := Idd/Pds. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta - 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_dVbs * T1 - + T4 * ( - F10_dVbs + F00_dVbs ) ; - Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds ) - + beta * Cox_dVds * T1 - + T4 * ( - F10_dVds + F00_dVds ) ; - Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs ) - + beta * Cox_dVgs * T1 - + T4 * ( - F10_dVgs + F00_dVgs ) ; - - -/*---------------------------------------------------* -* Q_B : bulk charge. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta ; - 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_dVbs * T2 ) ; - Qbnm_dVds = cnst0 - * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds ) - + Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds ) - + Cox_dVds * T2 ) ; - Qbnm_dVgs = cnst0 - * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs ) - + Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs ) - + Cox_dVgs * T2 ) ; - - T1 = - Weff * beta * Leff ; - - Qb = T1 * Qbnm / Fdd ; - - T2 = T1 / ( Fdd * Fdd ) ; - - Qb_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; - Qb_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; - Qb_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; - - -/*---------------------------------------------------* -* Breaking point for Qi=Qd=0. -*-----------------*/ - - if ( flg_noqi != 0 ) { - goto end_of_part_1 ; - } - - -/*---------------------------------------------------* -* 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 ; - - -/*-----------------------------------------------------------* -* Channel Length Modulation. Lred: \Delta L -*-----------------*/ - - if( sIN.clm2 < epsm10 && sIN.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 ; - } - FMD = 1.0 ; - - goto end_of_CLM ; - } - - Ec = Idd / beta / Qn0 / Leff ; - Ec_dVbs = 1.0e0 / beta / Leff - * ( Idd_dVbs / Qn0 - Idd * Qn0_dVbs / Qn0 / Qn0 ) ; - Ec_dVds = ( Idd_dVds / Qn0 - Idd * Qn0_dVds / Qn0 / Qn0 ) - / beta / Leff ; - Ec_dVgs = 1.0e0 / beta / Leff - * ( Idd_dVgs / Qn0 - Idd * Qn0_dVgs / Qn0 / Qn0 ) ; - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - - T7 = Qn0 / Wd ; - T7_dVbs = ( Qn0_dVbs / Wd - Qn0 / Wd / Wd * Wd_dVbs ) ; - T7_dVds = ( Qn0_dVds / Wd - Qn0 / Wd / Wd * Wd_dVds ) ; - T7_dVgs = ( Qn0_dVgs / Wd - Qn0 / Wd / Wd * Wd_dVgs ) ; - - T8 = Ec * Ec + 2.0e0 / C_ESI * q_Nsub * ( Psdl - Psl ) + 1.0e3 ; - T8_dVbs = 2.0e0 * Ec * Ec_dVbs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVbs - Psl_dVbs ) ; - T8_dVds = 2.0e0 * Ec * Ec_dVds - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVds - Psl_dVds ) ; - T8_dVgs = 2.0e0 * Ec * Ec_dVgs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVgs - Psl_dVgs ) ; - - Ed = sqrt( T8 ) ; - Ed_dVbs = 0.5e0 / Ed * T8_dVbs ; - Ed_dVds = 0.5e0 / Ed * T8_dVds ; - Ed_dVgs = 0.5e0 / Ed * T8_dVgs ; - - - Lred = ( Ed - Ec ) - / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) * C_ESI ; - T1 = 1.0 / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) ; - T2 = T1 * T1 ; - Lred_dVbs = ( ( Ed_dVbs - Ec_dVbs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVbs ) * C_ESI ; - Lred_dVds = ( ( Ed_dVds - Ec_dVds ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVds ) * C_ESI ; - Lred_dVgs = ( ( Ed_dVgs - Ec_dVgs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVgs ) * C_ESI ; - - -/*---------------------------------------------------* -* Modify Lred for symmetry. -*-----------------*/ - - TX = Vds / cclmmdf ; - T2 = TX * TX ; - T5 = 1.0 + T2 ; - - FMD = 1.0 - 1.0 / T5 ; - FMD_dVds = 2.0 * Vds / ( T5 * T5 * cclmmdf * cclmmdf ) ; - - T6 = Lred ; - - Lred = FMD * T6 ; - Lred_dVbs *= FMD ; - Lred_dVds = FMD_dVds * ( T6 ) + FMD * Lred_dVds ; - Lred_dVgs *= FMD ; - - -/*-------------------------------------------* -* End point of CLM. (label) -*-----------------*/ -end_of_CLM: ; - - -/*---------------------------------------------------* -* preparation for Qi and Qd. -*-----------------*/ - - T1 = 2.0e0 * fac1 ; - - DtPds = T1 * ( F10 - Xi0p12 ) ; - - T2 = 2.0 * ( F10 - Xi0p12 ) ; - - DtPds_dVbs = T1 * ( F10_dVbs - - 0.5 * beta * ( Ps0_dVbs - 1.0e0 ) / Xi0p12 ) - + T2 * fac1_dVbs ; - DtPds_dVds = T1 * ( F10_dVds - - 0.5 * beta * Ps0_dVds / Xi0p12 ) - + T2 * fac1_dVds ; - DtPds_dVgs = T1 * ( F10_dVgs - - 0.5 * beta * Ps0_dVgs / Xi0p12 ) - + 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. -* - clamped to 0 if Alpha < 0. -*-----------------*/ - - Alpha = 1.0e0 - Achi / VgVt ; - - if ( Alpha >= 0.0e0 ) { - - Alpha_dVbs = - Achi_dVbs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVbs / VgVt ) ; - Alpha_dVds = - Achi_dVds / VgVt + ( Achi / VgVt ) - * ( VgVt_dVds / VgVt ) ; - Alpha_dVgs = - Achi_dVgs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVgs / VgVt ) ; - - } else { - - Alpha = 0.0e0 ; - Alpha_dVbs = 0.0e0 ; - Alpha_dVds = 0.0e0 ; - Alpha_dVgs = 0.0e0 ; - } - - -/*-----------------------------------------------------------* -* Q_I : inversion charge. -*-----------------*/ - - Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; - Qinm_dVbs = Alpha_dVbs * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVds = Alpha_dVds * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVgs = Alpha_dVgs * ( 1.0e0 + Alpha + Alpha ) ; - - Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; - Qidn_dVbs = Alpha_dVbs ; - Qidn_dVds = Alpha_dVds ; - Qidn_dVgs = Alpha_dVgs ; - - T1 = - Weff * ( Leff - Lred ) * C_2o3 * VgVt * Qinm / Qidn ; - - Qi = T1 * Cox ; - - Qi_dVbs = Qi * ( VgVt_dVbs / VgVt - + Qinm_dVbs / Qinm - Qidn_dVbs / Qidn - - Lred_dVbs/ ( Leff - Lred ) ) - + T1 * Cox_dVbs ; - Qi_dVds = Qi * ( VgVt_dVds / VgVt - + Qinm_dVds / Qinm - Qidn_dVds / Qidn - - Lred_dVds/ ( Leff - Lred ) ) - + T1 * Cox_dVds ; - Qi_dVgs = Qi * ( VgVt_dVgs / VgVt - + Qinm_dVgs / Qinm - Qidn_dVgs / Qidn - - Lred_dVgs/ ( Leff - Lred ) ) - + T1 * Cox_dVgs ; - - -/*-----------------------------------------------------------* -* Q_D : drain charge. -*-----------------*/ - - 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 ) { - Qdrat_dVbs = Quot * ( Qddn_dVbs / Qddn - Qdnm_dVbs / Qdnm ) ; - Qdrat_dVds = Quot * ( Qddn_dVds / Qddn - Qdnm_dVds / Qdnm ) ; - Qdrat_dVgs = Quot * ( Qddn_dVgs / Qddn - Qdnm_dVgs / Qdnm ) ; - } else { - Qdrat = 0.5e0 ; - Qdrat_dVbs = 0.0e0 ; - Qdrat_dVds = 0.0e0 ; - Qdrat_dVgs = 0.0e0 ; - } - - 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 ; - - -/*-----------------------------------------------------------* -* Modify charges for zone-D2. -* - FD2 must be defined previously. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - if ( Chi < znbd5 ) { - - 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 ; - - T5 = - Leff * Weff ; - - Qb_dVbs = FD2 * Qb_dVbs + FD2_dVbs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVbs - FD2_dVbs * T5 * Qb0 ; - Qb_dVds = FD2 * Qb_dVds + FD2_dVds * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVds - FD2_dVds * T5 * Qb0 ; - Qb_dVgs = FD2 * Qb_dVgs + FD2_dVgs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVgs - FD2_dVgs * T5 * Qb0 ; - - Qb = FD2 * Qb + ( 1.0 - FD2 ) * T5 * Qb0 ; - - if ( Qb > 0.0 ) { - Qb = 0.0 ; - Qb_dVbs = 0.0 ; - Qb_dVds = 0.0 ; - Qb_dVgs = 0.0 ; - } - - Qi_dVbs = FD2 * Qi_dVbs + FD2_dVbs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVbs - FD2_dVbs * T5 * Qn0 ; - Qi_dVds = FD2 * Qi_dVds + FD2_dVds * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVds - FD2_dVds * T5 * Qn0 ; - Qi_dVgs = FD2 * Qi_dVgs + FD2_dVgs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVgs - FD2_dVgs * T5 * Qn0 ; - - Qi = FD2 * Qi + ( 1.0 - FD2 ) * T5 * Qn0 ; - - if ( Qi > 0.0 ) { - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - } - - Qd_dVbs = FD2 * Qd_dVbs + FD2_dVbs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVbs / 2 - - FD2_dVbs * T5 * Qi / 2 ; - Qd_dVds = FD2 * Qd_dVds + FD2_dVds * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVds / 2 - - FD2_dVds * T5 * Qi / 2 ; - Qd_dVgs = FD2 * Qd_dVgs + FD2_dVgs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVgs / 2 - - FD2_dVgs * T5 * Qi / 2 ; - - Qd = FD2 * Qd + ( 1.0 - FD2 ) * T5 * Qi / 2 ; - - if ( Qd > 0.0 ) { - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - } - - } - - -/*-----------------------------------------------------------* -* Modified potential for symmetry. -*-----------------*/ - - T1 = exp( - ( Vds - Pds ) / ( 2.0 * sIN.pzadd0 ) ) ; - - Pzadd = sIN.pzadd0 * T1 ; - - T2 = - 0.5 * T1 ; - - Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; - Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; - Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; - - if ( fabs ( Pzadd ) < epsm10 ) { - Pzadd = 0.0 ; - 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 ; - - -/*-----------------------------------------------------------* -* Evaluate universal mobility. -*-----------------*/ - - Ps0Vbsz = Ps0z - Vbsz ; - Ps0Vbsz_dVbs = Ps0z_dVbs - Vbsz_dVbs ; - Ps0Vbsz_dVds = Ps0z_dVds - Vbsz_dVds ; - Ps0Vbsz_dVgs = Ps0z_dVgs ; - - -/*-------------------------------------------* -* Qbm -*-----------------*/ - - T1 = cnst0 ; - T2 = sqrt( beta * Ps0Vbsz - 1.0 ) ; - - Qbm = T1 * T2 ; - - T3 = 0.5 * beta * T1 / T2 ; - - Qbm_dVbs = T3 * Ps0Vbsz_dVbs ; - Qbm_dVds = T3 * Ps0Vbsz_dVds ; - Qbm_dVgs = T3 * Ps0Vbsz_dVgs ; - -/*-------------------------------------------* -* Qnm -*-----------------*/ - - Chi = beta * Ps0Vbsz ; - - exp_Chi = exp( Chi ) ; - - exp_bVbs = exp( beta * Vbsz ) ; - - cfs1 = cnst1 * exp_bVbs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - /* regard fs01 as a function of Chi and Vbs */ - fs01_dChi = cfs1 * ( exp_Chi ) ; - fs01_dVbs = beta * fs01 ; - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - Xi0z = Chi - 1.0e0 ; - - Xi0z_dVbs = beta * Ps0Vbsz_dVbs ; - Xi0z_dVds = beta * Ps0Vbsz_dVds ; - Xi0z_dVgs = beta * Ps0Vbsz_dVgs ; - - fs02 = sqrt( Xi0z + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - /* regard fs01 as a function of Chi and Vbs */ - fs02_dChi = ( 1.0 + fs01_dChi ) * T2 ; - fs02_dVbs = fs01_dVbs * T2 ; - - Xi0zp12 = sqrt( Xi0z ) ; - - Xi0zp12_dVbs = 0.5e0 * Xi0z_dVbs / Xi0zp12 ; - Xi0zp12_dVds = 0.5e0 * Xi0z_dVds / Xi0zp12 ; - Xi0zp12_dVgs = 0.5e0 * Xi0z_dVgs / Xi0zp12 ; - - T1 = 1.0 / ( fs02 + Xi0zp12 ) ; - - Qnm = cnst0 * fs01 * T1 ; - - fs01_dVds = beta * Ps0Vbsz_dVds * fs01_dChi - + fs01_dVbs * Vbsz_dVds ; - fs01_dVbs = beta * Ps0Vbsz_dVbs * fs01_dChi + fs01_dVbs ; - fs01_dVgs = beta * Ps0Vbsz_dVgs * fs01_dChi ; - - fs02_dVds = beta * Ps0Vbsz_dVds * fs02_dChi - + fs02_dVbs * Vbsz_dVds ; - fs02_dVbs = beta * Ps0Vbsz_dVbs * fs02_dChi + fs02_dVbs ; - fs02_dVgs = beta * Ps0Vbsz_dVgs * fs02_dChi ; - - Qnm_dVbs = Qnm - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0zp12_dVbs ) * T1 ) ; - Qnm_dVds = Qnm - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0zp12_dVds ) * T1 ) ; - Qnm_dVgs = Qnm - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0zp12_dVgs ) * T1 ) ; - - if ( Qbm < 0.0 ) { - Qbm = 0.0 ; - } - if ( Qnm < 0.0 ) { - Qnm = 0.0 ; - } - - -/*---------------------------------------------------* -* Muun : universal mobility. -*-----------------*/ - - /* removed Eqs. "Qbm = Qb0", "Qnm = Qn0", ... (4/Dec/01) */ - - T1 = sIN.ninv - sIN.ninvd * Vdsz ; - T1_dVds = - sIN.ninvd * Vdsz_dVds ; - - Eeff = ( sIN.ndep * Qbm + T1 * Qnm ) / C_ESI ; - Eeff_dVbs = ( sIN.ndep * Qbm_dVbs + T1 * Qnm_dVbs ) - / C_ESI ; - Eeff_dVds = ( sIN.ndep * Qbm_dVds + T1 * Qnm_dVds - + T1_dVds * Qnm ) - / C_ESI ; - Eeff_dVgs = ( sIN.ndep * Qbm_dVgs + T1 * Qnm_dVgs ) - / C_ESI ; - - Rns = Qnm / C_QE ; - - T10 = pow( sIN.temp / C_T300 , sIN.muetmp ) ; - T21 = pow( Eeff , sIN.mueph0 - 1.0e0 ) ; - T20 = T21 * Eeff ; - T31 = pow( Eeff , sIN.muesr0 - 1.0e0 ) ; - T30 = T31 * Eeff ; - - T1 = 1e0 / ( sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ) - + T10 - * T20 / mueph - + T30 / sIN.muesr1 ; - - Muun = 1e0 / T1 ; - - T1 = 1e0 / ( T1 * T1 ) ; - T2 = sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ; - T2 = 1e0 / ( T2 * T2 ) ; - T3 = T10 * sIN.mueph0 * T21 / mueph ; - T4 = sIN.muesr0 * T31 / sIN.muesr1 ; - - Muun_dVbs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVbs / C_QE * T2 - + Eeff_dVbs * T3 - + Eeff_dVbs * T4 ) - * T1 ; - Muun_dVds = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVds / C_QE * T2 - + Eeff_dVds * T3 - + Eeff_dVds * T4 ) - * T1 ; - Muun_dVgs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVgs / C_QE * T2 - + Eeff_dVgs * T3 - + Eeff_dVgs * T4 ) - * T1 ; - - -/*-----------------------------------------------------------* -* Mu : mobility -*-----------------*/ - - T1 = 1.0e0 / beta / ( Qn0 + small ) / ( Leff - Lred ) ; - T1_dVbs = 1.0e0 / beta * ( - Qn0_dVbs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVbs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVds = 1.0e0 / beta * ( - Qn0_dVds / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVds / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVgs = 1.0e0 / beta * ( - Qn0_dVgs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVgs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - - Ey = Idd * T1 ; - Ey_dVbs = Idd_dVbs * T1 + Idd * T1_dVbs ; - Ey_dVds = Idd_dVds * T1 + Idd * T1_dVds ; - Ey_dVgs = Idd_dVgs * T1 + Idd * T1_dVgs ; - - 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 = sIN.temp / C_T300 ; - - Vmax = sIN.vmax / ( 1.8 + 0.4 * T1 + 0.1 * T1 * T1 ) ; - - T2 = 1.0 - sIN.vover / pow( Leff , sIN.voverp ) ; - - if ( T2 < 0.01 ) { - fprintf( stderr , - "*** warning(HiSIM): Overshoot is too big.\n" ) ; - T2 = 0.01 ; - } - - Vmax = Vmax / T2 ; - - T1 = Em / Vmax ; - - /* note: sIN.bb = 2 (electron) ;1 (hole) */ - if ( 1.0e0 - epsm10 <= sIN.bb && sIN.bb <= 1.0e0 + epsm10 ) { - T3 = 1.0e0 ; - } else if ( 2.0e0 - epsm10 <= sIN.bb - && sIN.bb <= 2.0e0 + epsm10 ) { - T3 = T1 ; - } else { - T3 = pow( T1 , sIN.bb - 1.0e0 ) ; - } - T2 = T1 * T3 ; - T4 = 1.0e0 + T2 ; - T6 = pow( T4 , ( - 1.0e0 / sIN.bb - 1.0e0 ) ) ; - T5 = T4 * T6 ; - - Mu = Muun * T5 ; - Mu_dVbs = Muun_dVbs * T5 - Muun / Vmax * T6 * T3 * Em_dVbs ; - Mu_dVds = Muun_dVds * T5 - Muun / Vmax * T6 * T3 * Em_dVds ; - Mu_dVgs = Muun_dVgs * T5 - Muun / Vmax * T6 * T3 * Em_dVgs ; - - /*end_of_mobility : ;*/ - - -/*-----------------------------------------------------------* -* Ids: channel current. -*-----------------*/ - - T1 = Weff / beta / ( Leff - Lred ) ; - T1_dVbs = T1 / ( Leff - Lred ) * Lred_dVbs ; - T1_dVds = T1 / ( Leff - Lred ) * Lred_dVds ; - T1_dVgs = T1 / ( Leff - Lred ) * Lred_dVgs ; - - Ids0 = T1 * Idd * Mu ; - Ids0_dVbs = T1 * ( Mu * Idd_dVbs + Idd * Mu_dVbs ) - + T1_dVbs * Mu * Idd ; - Ids0_dVds = T1 * ( Mu * Idd_dVds + Idd * Mu_dVds ) - + T1_dVds * Mu * Idd ; - Ids0_dVgs = T1 * ( Mu * Idd_dVgs + Idd * Mu_dVgs ) - + T1_dVgs * Mu * Idd ; - - T1 = Vdsz + sIN.rpock2 ; - T2 = T1 * T1 + small ; - T2_dVbs = 0.0e0 ; - T2_dVds = 2.0 * T1 * Vdsz_dVds ; - T2_dVgs = 0.0e0 ; - - rp1 = FMD * sIN.rpock1 ; - rp1_dVds = FMD_dVds * sIN.rpock1 ; - - TX = Ids0 * sqrt( Leff ) / Weff ; - T3 = rp1 * TX ; - T4 = ( T3 + T2 ) * ( T3 + T2 ) ; - - Ids = Ids0 / ( 1.0 + T3 / T2 ) ; - - T5 = T2 * T2 / T4 ; - T6 = Ids0 * T3 / T4 ; - - Ids_dVbs = T5 * Ids0_dVbs + T6 * T2_dVbs ; - Ids_dVds = T5 * Ids0_dVds + T6 * T2_dVds - - Ids0 * T2 / T4 * rp1_dVds * TX ; - Ids_dVgs = T5 * Ids0_dVgs + T6 * T2_dVgs ; - - if ( Pds < ps_conv ) { - Ids_dVbs = 0.0 ; - Ids_dVgs = 0.0 ; - } - - Ids += Gdsmin * Vds ; - Ids_dVds += Gdsmin ; - - -/*-----------------------------------------------------------* -* 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 ) || - 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) not used so commenting out -*-----------------*/ -/*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 -- ; } - - -/*-----------------------------------------------------------* -* End of PART-1. (label) -*-----------------*/ -end_of_part_1: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-2: Substrate / gate / leak currents -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Isub : substrate current induced by impact ionization. -*-----------------*/ -/*-------------------------------------------* -* Accumulation zone or nonconductive case, in which Ids==0. -*-----------------*/ - - if ( Ids <= 0.0e0 || sIN.coisub >= 1 ) { - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - goto end_of_Isub ; - } - - -/*-------------------------------------------* -* Conductive case. -*-----------------*/ - - if ( sIN.sub1 > 0.0e0 && sIN.vmax > 0.0e0 ) { - - Vdep = Vds + Ps0 - sIN.sub3 * Psl ; - Vdep_dVbs = Ps0_dVbs - sIN.sub3 * Psl_dVbs ; - Vdep_dVds = 1.0e0 + Ps0_dVds - sIN.sub3 * Psl_dVds ; - Vdep_dVgs = Ps0_dVgs - sIN.sub3 * Psl_dVgs ; - - TX = - sIN.sub2 / Vdep ; - - Epkf = exp( TX ) ; - Epkf_dVbs = - TX * Vdep_dVbs / Vdep * Epkf ; - Epkf_dVds = - TX * Vdep_dVds / Vdep * Epkf ; - Epkf_dVgs = - TX * Vdep_dVgs / Vdep * Epkf ; - - T1 = Ids * Epkf ; - T1_dVbs = Ids_dVbs * Epkf + Ids * Epkf_dVbs ; - T1_dVds = Ids_dVds * Epkf + Ids * Epkf_dVds ; - T1_dVgs = Ids_dVgs * Epkf + Ids * Epkf_dVgs ; - - if( T1 < 1.0e-25 ){ - T1 = 1.0e-25 ; - T1_dVbs = 0.0e0 ; - T1_dVds = 0.0e0 ; - T1_dVgs = 0.0e0 ; - } - - Isub = sIN.sub1 * Vdep * T1 ; - Isub_dVbs = sIN.sub1 * ( Vdep_dVbs * T1 + Vdep * T1_dVbs ) ; - Isub_dVds = sIN.sub1 * ( Vdep_dVds * T1 + Vdep * T1_dVds ) ; - Isub_dVgs = sIN.sub1 * ( Vdep_dVgs * T1 + Vdep * T1_dVgs ) ; - - } else { - - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - - } /* end of if ( sIN.sub1 ... ) else block. */ - - -/*-------------------------------------------* -* End of Isub. (label) -*-----------------*/ -end_of_Isub: ; - - -/*-----------------------------------------------------------* -* Igate : Gate current induced by tunneling. -* - Vzadd is used for symmetrizing. -*-----------------*/ - - Egp12 = sqrt( Eg ) ; - Egp32 = Eg * Egp12 ; - - if ( sIN.coiigs >= 1 ) { - Igate = 0.0e0 ; - Igate_dVbs = 0.0e0 ; - Igate_dVds = 0.0e0 ; - Igate_dVgs = 0.0e0 ; - goto end_of_Igate ; - } - - Vgpz = Vgp + Vzadd ; - - Vgpz_dVbs = Vgp_dVbs ; - Vgpz_dVds = Vgp_dVds + Vzadd_dVds ; - Vgpz_dVgs = Vgp_dVgs ; - - T1 = Vgpz - ( Psl + Ps0 + 2.0 * Vzadd ) * sIN.gleak3 ; - - E0 = 10.0 ; - - E2 = T1 / Tox ; - - E2_dVbs = E2 - * ( ( Vgpz_dVbs - ( Psl_dVbs + Ps0_dVbs ) * sIN.gleak3 ) - / T1 - - Tox_dVbs / Tox ) ; - E2_dVds = E2 - * ( ( Vgpz_dVds - - ( Psl_dVds + Ps0_dVds + 2.0 * Vzadd_dVds ) - * sIN.gleak3 - ) / T1 - - Tox_dVds / Tox ) ; - E2_dVgs = E2 - * ( ( Vgpz_dVgs - ( Psl_dVgs + Ps0_dVgs ) * sIN.gleak3 ) - / T1 - - Tox_dVgs / Tox ) ; - - T1 = E2 - E0 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E2 ) ; - - Etun = E2 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = 2.0 * T1 * T4 + 0.5 ; - - Etun_dVbs = T5 * E2_dVbs ; - Etun_dVds = T5 * E2_dVds ; - Etun_dVgs = T5 * E2_dVgs ; - - T1 = exp( - sIN.gleak2 * Egp32 / Etun ) ; - - T2 = sIN.gleak1 / Egp12 * C_QE * Weff * Leff ; - - Igate = T2 * Etun * Etun * T1 ; - - T3 = T2 * T1 * ( 2.0 * Etun + sIN.gleak2 * Egp32 ) ; - - Igate_dVbs = T3 * Etun_dVbs ; - Igate_dVds = T3 * Etun_dVds ; - Igate_dVgs = T3 * Etun_dVgs ; - - end_of_Igate: ; - - -/*-----------------------------------------------------------* -* Igidl : GIDL -*-----------------*/ - - if ( sIN.cogidl >= 1 ) { - Igidl = 0.0e0 ; - Igidl_dVbs = 0.0e0 ; - Igidl_dVds = 0.0e0 ; - Igidl_dVgs = 0.0e0 ; - goto end_of_IGIDL ; - } - - T1 = sIN.gidl3 * Vdsz - Vgsz + Vfb - dVth + dPpg ; - - E1 = T1 / Tox ; - - E1_dVbs = E1 * ( - dVth_dVbs / T1 - Tox_dVbs / Tox ) ; - E1_dVds = E1 * ( ( sIN.gidl3 * Vdsz_dVds - - Vgsz_dVds - dVth_dVds + dPpg_dVds) / T1 - - Tox_dVds / Tox ) ; - E1_dVgs = E1 * ( ( -1.0 - dVth_dVgs + dPpg_dVgs) / T1 - Tox_dVgs / Tox ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egidl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egidl_dVbs = T5 * E1_dVbs ; - Egidl_dVds = T5 * E1_dVds ; - Egidl_dVgs = T5 * E1_dVgs ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egidl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Igidl = T2 * Egidl * Egidl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egidl + sIN.gidl2 * Egp32 ) ; - - Igidl_dVbs = T3 * Egidl_dVbs ; - Igidl_dVds = T3 * Egidl_dVds ; - Igidl_dVgs = T3 * Egidl_dVgs ; - - end_of_IGIDL: ; - - -/*-----------------------------------------------------------* -* End of PART-2. (label) not used so commenting out -*-----------------*/ -/* end_of_part_2: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-3: Overlap charge -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - -/*-------------------------------------------* -* Calculation of Psdl for cases of flg_noqi==1. -*-----------------*/ - - if ( flg_noqi != 0 ) { - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0e0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (simple, default, CLM1 < 1.0) <-- changed 04/Dec/01 -* (orig. "CLM1 must be 1.0") -*-----------------*/ - - if ( sIN.coovlp == 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T2 = - 1.0e+11 ; - yn = sqrt ( ( Psdl - Ps0 - Vds) / T2 ) ; - yn2 = yn * yn ; - yn3 = yn2 * yn ; - - if ( yn <= Lov ){ - Qgod = ( ( Vgs - Vds ) * Lov - T2 * yn3 / 3.0e0 ) * T1 ; - Qgod_dVbs = ( (-0.5e0) * yn * ( Psdl_dVbs - Ps0_dVbs ) ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - 0.5e0 * yn - * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ) * T1 ; - Qgod_dVgs = ( Lov - 0.5e0 * yn * ( Psdl_dVgs - Ps0_dVgs ) ) * T1 ; - }else{ - T3 = 0.5e0 / yn / T2 ; - yn_dVbs = T3 * ( Psdl_dVbs - Ps0_dVbs ) ; - yn_dVds = T3 * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ; - yn_dVgs = T3 * ( Psdl_dVgs - Ps0_dVgs ) ; - - T4 = (Lov - yn ) * (Lov - yn ) ; - T5 = T4 * (Lov - yn ) ; - Qgod = ( ( Vgs - Vds ) * Lov - T2 / 3.0e0 * ( T5 + yn3 ) ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs - + T2 * T4 * yn_dVbs ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds - + T2 * T4 * yn_dVds ) * T1 ; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs - + T2 * T4 * yn_dVgs ) * T1 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (complete) -*-----------------*/ - - else if( sIN.coovlp > 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T3 = 1e21 / pow( Lov , 3e0) ; - T1 = C_QE * T3 / ( C_ESI * 4e0 ) ; - T2 = Cox * Weff ; - - Lov2 = Lov * Lov ; - - yn = pow( C_ESI * 5e0 / ( C_QE * T3 ) - * ( Ps0 + Vds - Psdl ) - , 0.2e0 ) ; - yn2 = yn * yn ; - - if ( yn < Lov ) { - Qgod = ( ( Vgs - Vds ) * Lov + T1 / 3e0 * yn2 * yn2 * yn2 ) * T2 ; - Qgod_dVbs = ( yn / 2e0 * ( Ps0_dVbs - Psdl_dVbs ) ) * T2 ; - Qgod_dVds = ( - Lov + yn / 2e0 * ( Ps0_dVds + 1e0 - Psdl_dVds ) ) * T2 ; - Qgod_dVgs = ( Lov + yn / 2e0 * ( Ps0_dVgs - Psdl_dVgs ) ) * T2 ; - } else { - T3 = C_ESI * 5e0 / ( C_QE * T3 ) ; - - Qgod = ( ( Vgs + T1 * 4e0 / 5e0 * yn2 * yn2 * yn - Vds ) * Lov - + T1 / 30e0 * Lov2 * Lov2 * Lov2 - - T1 * yn2 * yn2 / 2e0 * Lov2 ) * T2 ; - Qgod_dVbs = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVbs - Psdl_dVbs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVbs - Psdl_dVbs ) * Lov2 ) - * T2 ; - Qgod_dVds = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVds + 1e0 - Psdl_dVds ) - 1e0 ) - * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVds + 1e0 - Psdl_dVds ) - * Lov2 ) * T2 ; - Qgod_dVgs = ( ( 1e0 + T1 * 4e0 / 5e0 * T3 * ( Ps0_dVgs - Psdl_dVgs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVgs - Psdl_dVgs ) * Lov2 ) - * T2 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (off) -*-----------------*/ - - else if( sIN.coovlp < 0 ){ - - Qgos = 0.0e0 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = 0.0e0 ; - - Qgod = 0.0e0 ; - Qgod_dVbs = 0.0e0 ; - Qgod_dVds = 0.0e0 ; - Qgod_dVgs = 0.0e0 ; - - } - - -/*-----------------------------------------------------------* -* End of PART-3. (label) not used so commenting out -*-----------------*/ -/* end_of_part_3: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-4: Substrate-source/drain junction diode. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - -/*-----------------------------------------------------------* -* Cbsj, Cbdj: node-base S/D biases. -*-----------------*/ - - if (sIN.mode == HiSIM_NORMAL_MODE ){ - Vbdj = Vbde ; - Vbsj = Vbse ; - } else { - Vbdj = Vbse ; - Vbsj = Vbde ; - } - - /* Vbdc = Vbsc - Vdsc ; */ - - js = sIN.js0 * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) / sIN.nj ) ; - jssw = sIN.js0sw * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) - / sIN.njsw ) ; - - Nvtm = sIN.nj / beta ; - - /* ibd */ - isbd = sIN.ad * js + sIN.pd * jssw ; - - if ( Vbdj < 0.5 ) { - Ibd = isbd * ( exp( Vbdj / Nvtm ) - 1 ) ; - Gbd = isbd / Nvtm * exp( Vbdj / Nvtm ) ; - } else { - Ibd = isbd * ( exp( 0.5 / Nvtm ) - 1 ) - + isbd / Nvtm * exp( 0.5 / Nvtm ) * ( Vbdj - 0.5 ) ; - Gbd = isbd / Nvtm * exp( 0.5 / Nvtm ) ; - } - - /* ibs */ - isbs = sIN.as * js + sIN.ps * jssw ; - - if ( Vbsj < 0.5 ) { - Ibs = isbs * ( exp( Vbsj / Nvtm ) - 1 ) ; - Gbs = isbs / Nvtm * exp( Vbsj / Nvtm ) ; - } else { - Ibs = isbs * ( exp( 0.5 / Nvtm ) - 1 ) - + isbs / Nvtm * exp( 0.5 / Nvtm ) * (Vbsj - 0.5 ) ; - Gbs = isbs / Nvtm * exp( 0.5 / Nvtm ) ; - } - - -/*---------------------------------------------------* -* Add Gjmin. -*-----------------*/ - - Ibd += Gjmin * Vbdj ; - Ibs += Gjmin * Vbsj ; - - 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 - */ - - czbd = sIN.cj * sIN.ad ; - czbs = sIN.cj * sIN.as ; - - /* Source Bulk Junction */ - if (sIN.ps > Weff) { - czbssw = sIN.cjsw * ( sIN.ps - Weff ) ; - czbsswg = sIN.cjswg * Weff ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbssw + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbssw > 0.0) - { arg = 1.0 - Vbsj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbs += sIN.pbsw * czbssw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbs += czbssw * sarg ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbssw + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbssw * sIN.mjsw * 0.5 / sIN.pbsw - + czbsswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbssw + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbssw * sIN.mjsw / sIN.pbsw - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbsswg = sIN.cjswg * sIN.ps ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbsswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - /* Drain Bulk Junction */ - if (sIN.pd > Weff) { - czbdsw = sIN.cjsw * ( sIN.pd - Weff ) ; - czbdswg = sIN.cjswg * Weff ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdsw + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdsw > 0.0) - { arg = 1.0 - Vbdj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbd += sIN.pbsw * czbdsw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbd += czbdsw * sarg ; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdsw + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdsw * sIN.mjsw * 0.5 / sIN.pbsw - + czbdswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdsw + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdsw * sIN.mjsw / sIN.pbsw - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbdswg = sIN.cjswg * sIN.pd ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - -/*-----------------------------------------------------------* -* End of PART-4. (label) not used so commenting out -*-----------------*/ -/* end_of_part_4: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-5: Noise Calculation. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - if ( sIN.conois != 0 ){ - - NFalp = sIN.nfalp ; - NFtrp = sIN.nftrp ; - Cit = sIN.cit ; - - T1 = Qn0 / C_QE ; - T2 = (Cox+Qn0/(Ps0-Vbs)+Cit)/beta/C_QE ; - T3 = 1.0E0/(T1+T2)+NFalp*Mu ; - Nflic = Ids*Ids*NFtrp/((Leff-Lred)*beta*Weff)*T3*T3 ; - } else { - Nflic = 0.0 ; - } - - -/*-----------------------------------------------------------* -* End of PART-5. (label) not used so commenting out -*-----------------*/ - -/* end_of_part_5: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-6: Evaluation of outputs. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Implicit quantities related to Alpha. -*-----------------*/ - - /* note: T1 = 1 + Delta */ - if ( flg_noqi == 0 && VgVt > VgVt_small && Pds > 0.0 ) { - T1 = Achi / Pds ; - Delta = T1 - 1.0e0 ; - Vdsat = VgVt / T1 ; - } else { - Alpha = 1.0 ; - Delta = 0.0 ; - Vdsat = 0.0 ; - Achi = 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 == 0 || 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 ; - - Igate_dVbse = Igate_dVbs ; - Igate_dVdse = Igate_dVds ; - Igate_dVgse = Igate_dVgs ; - - Igidl_dVbse = Igidl_dVbs ; - Igidl_dVdse = Igidl_dVds ; - Igidl_dVgse = Igidl_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 ; - - -/*---------------------------------------------------* -* Case Rs>0 or Rd>0 -*-----------------*/ - } else { - -/*-------------------------------------------* -* 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 ; - - 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 ; - - 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 ; - -/*---------------------------------------------------* -* 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 ; - - } /* end of if ( flg_rsrd == 0 ) blocks */ - -/*---------------------------------------------------* -* 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 ; - Igidl_dVbse *= Vbsc_dVbse ; - Qgos_dVbse *= Vbsc_dVbse ; - Qgod_dVbse *= Vbsc_dVbse ; - } - - if ( flg_vxxc != 0 ) { - - if ( flg_vbsc == -1 ) { - T1 = Vbse - Vbsc ; - } else { - T1 = 0.0 ; - } - - if ( flg_vdsc != 0 ) { - T2 = Vdse - Vdsc ; - } else { - T2 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T3 = Vgse - Vgsc ; - } else { - T3 = 0.0 ; - } - - if ( flg_vbdc != 0 ) { - T4 = Vbde - Vbdc ; - } else { - T4 = 0.0 ; - } - - TX = Ids + T1 * Ids_dVbse + T2 * Ids_dVdse + T3 * Ids_dVgse ; - if ( TX * Ids >= 0.0 ) { - Ids = TX ; - } else { - T7 = Ids / ( Ids - TX ) ; - Ids_dVbse *= T7 ; - Ids_dVdse *= T7 ; - Ids_dVgse *= T7 ; - Ids = 0.0 ; - } - - TX = Qb + T1 * Qb_dVbse + T2 * Qb_dVdse + T3 * Qb_dVgse ; - /*note: The sign of Qb can be changed.*/ - Qb = TX ; - - TX = Qd + T1 * Qd_dVbse + T2 * Qd_dVdse + T3 * Qd_dVgse ; - if ( TX * Qd >= 0.0 ) { - Qd = TX ; - } else { - T7 = Qd / ( Qd - TX ) ; - Qd_dVbse *= T7 ; - Qd_dVdse *= T7 ; - Qd_dVgse *= T7 ; - Qd = 0.0 ; - } - - TX = Qi + T1 * Qi_dVbse + T2 * Qi_dVdse + T3 * Qi_dVgse ; - if ( TX * Qi >= 0.0 ) { - Qi = TX ; - } else { - T7 = Qi / ( Qi - TX ) ; - Qi_dVbse *= T7 ; - Qi_dVdse *= T7 ; - Qi_dVgse *= T7 ; - Qi = 0.0 ; - } - - TX = Isub + T1 * Isub_dVbse + T2 * Isub_dVdse + T3 * Isub_dVgse ; - if ( TX * Isub >= 0.0 ) { - Isub = TX ; - } else { - T7 = Isub / ( Isub - TX ) ; - Isub_dVbse *= T7 ; - Isub_dVdse *= T7 ; - Isub_dVgse *= T7 ; - Isub = 0.0 ; - } - - TX = Igate + T1 * Igate_dVbse + T2 * Igate_dVdse + T3 * Igate_dVgse ; - if ( TX * Igate >= 0.0 ) { - Igate = TX ; - } else { - T7 = Igate / ( Igate - TX ) ; - Igate_dVbse *= T7 ; - Igate_dVdse *= T7 ; - Igate_dVgse *= T7 ; - Igate = 0.0 ; - } - - TX = Igidl + T1 * Igidl_dVbse + T2 * Igidl_dVdse + T3 * Igidl_dVgse ; - if ( TX * Igidl >= 0.0 ) { - Igidl = TX ; - } else { - T7 = Igidl / ( Igidl - TX ) ; - Igidl_dVbse *= T7 ; - Igidl_dVdse *= T7 ; - Igidl_dVgse *= T7 ; - Igidl = 0.0 ; - } - - TX = Qgod + T1 * Qgod_dVbse + T2 * Qgod_dVdse + T3 * Qgod_dVgse ; - if ( TX * Qgod >= 0.0 ) { - Qgod = TX ; - } else { - T7 = Qgod / ( Qgod - TX ) ; - Qgod_dVbse *= T7 ; - Qgod_dVdse *= T7 ; - Qgod_dVgse *= T7 ; - Qgod = 0.0 ; - } - - TX = Qgos + T1 * Qgos_dVbse + T2 * Qgos_dVdse + T3 * Qgos_dVgse ; - if ( TX * Qgos >= 0.0 ) { - Qgos = TX ; - } else { - T7 = Qgos / ( Qgos - TX ) ; - Qgos_dVbse *= T7 ; - Qgos_dVdse *= T7 ; - Qgos_dVgse *= T7 ; - Qgos = 0.0 ; - } - - - } - - -/*-----------------------------------------------------------* -* Warn negative conductance. -* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. -*-----------------*/ - - if ( sIN.mode == HiSIM_NORMAL_MODE ) { - T1 = Ids_dVdse ; - } else { - T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; - } - - if ( Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0 ) { - fprintf( stderr , - "*** warning(HiSIM): Negative Conductance\n" ) ; - fprintf( stderr , - " type = %d mode = %d\n" , sIN.type , sIN.mode ) ; - fprintf( stderr , - " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" , - Vbse , Vdse , Vgse ) ; - if ( flg_info >= 1 ) { - printf( "*** warning(HiSIM): Negative Conductance\n" ) ; - printf( " type = %d mode = %d\n" , sIN.type , sIN.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" , Ids_dVdse ) ; - printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - } - } - - if ( Ids_dVbse < 0.0e0 ) { - fprintf( stderr , " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; - flg_ncnv ++ ; - } - if ( T1 < 0.0e0 ) { - fprintf( stderr , " Ids_dVdse = %12.5e\n" , T1 ) ; - flg_ncnv ++ ; - } - if ( Ids_dVgse < 0.0e0 ) { - fprintf( stderr , " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - flg_ncnv ++ ; - } - - -/*-----------------------------------------------------------* -* Redefine overlap charges/capacitances. -*-----------------*/ - -/*---------------------------------------------------* -* Constant capacitance. -*-----------------*/ - - if ( sIN.cocgbo >= 1 ) { - Cgbo = sIN.cgbo * Lgate ; - } else { - Cgbo = 0.0 ; - } - - if ( sIN.cocgdo >= 1 ) { - Cgdo = - sIN.cgdo * Weff ; - Qgod = - Cgdo * ( Vgse - Vdse ) ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = Cgdo ; - Qgod_dVgse = - Qgod_dVdse ; - } else { - Cgdo = Qgos_dVdse + Qgod_dVdse ; - } - - if ( sIN.cocgso >= 1 ) { - Cgso = - sIN.cgso * Weff ; - Qgos = - Cgso * Vgse ; - Qgos_dVbse = 0.0 ; - Qgos_dVdse = 0.0 ; - Qgos_dVgse = - Cgso ; - } else { - Cgso = - ( Qgos_dVbse + Qgod_dVbse - + Qgos_dVdse + Qgod_dVdse - + Qgos_dVgse + Qgod_dVgse ) ; - } - - Cggo = Qgos_dVgse + Qgod_dVgse ; - - -/*---------------------------------------------------* -* Fringing capacitance. -*-----------------*/ - - Cf = C_EOX / ( C_Pi / 2.0e0 ) * Weff - * log( 1.0e0 + sIN.tpoly / sIN. tox ) ; - - Qfd = Cf * ( Vgse - Vdse ) ; - Qfs = Cf * Vgse ; - - -/*---------------------------------------------------* -* Add fringing charge/capacitance to overlap. -*-----------------*/ - - Qgod += Qfd ; - Qgos += Qfs ; - - Cggo += 2.0 * Cf ; - Cgdo += - Cf ; - Cgso += - Cf ; - - -/*-----------------------------------------------------------* -* Assign outputs. -*-----------------*/ - -/*---------------------------------------------------* -* Channel current and conductances. -*-----------------*/ - - /* pOT->ids = sIN.type * Ids ; */ - pOT->ids = Ids ; - pOT->gmbs = Ids_dVbse ; - pOT->gds = Ids_dVdse ; - pOT->gm = Ids_dVgse ; - - -/*---------------------------------------------------* -* Intrinsic charges/capacitances. -*-----------------*/ - - pOT->qg = - ( Qb + Qi ) ; - pOT->qd = Qd ; - pOT->qs = Qi - Qd ; - - pOT->cbgb = Qb_dVgse ; - pOT->cbdb = Qb_dVdse ; - pOT->cbsb = - ( Qb_dVbse + Qb_dVdse + Qb_dVgse ) ; - - pOT->cggb = - Qb_dVgse - Qi_dVgse ; - pOT->cgdb = - Qb_dVdse - Qi_dVdse ; - pOT->cgsb = Qb_dVbse + Qb_dVdse + Qb_dVgse - + Qi_dVbse + Qi_dVdse + Qi_dVgse ; - - pOT->cdgb = Qd_dVgse ; - pOT->cddb = Qd_dVdse ; - pOT->cdsb = - ( Qd_dVgse + Qd_dVdse + Qd_dVbse ) ; - - -/*---------------------------------------------------* -* Clamp capacitances. -*-----------------*/ - - if ( pOT->cbsb > -1e-27 ) { pOT->cbsb = 0e0 ; } - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - -/*---------------------------------------------------* -* Overlap capacitances. -*-----------------*/ - - pOT->cgdo = Cgdo ; - pOT->cgso = Cgso ; - pOT->cgbo = Cgbo ; - -/* - * Intrinsic fringing capacitance. - */ - - T1 = 2 * C_ESI * Weff / C_Pi ; - T2 = C_Pi * C_EOX / 2 / C_ESI ; - T3 = sIN.xj / sIN.tox * sin( T2 ) ; - Cgdf = T1 * log( 1.0e0 + T3 ) ; - - T4 = (-1) * ( pOT->cgdb ) ; - T5 = 2 * T4 / Cox / Weff / Leff ; - Cgdfring = Cgdf * ( 1.0e0 - T5 ) ; - - -/*---------------------------------------------------* -* Add S/D overlap charges/capacitances to intrinsic ones. -* - NOTE: This function depends on coadov, a control option. -*-----------------*/ - - if ( sIN.coadov == 1 ) { - pOT->qg += Qgod + Qgos ; - pOT->qd += - Qgod ; - pOT->qs += - Qgos ; - - pOT->cggb += Cggo ; - pOT->cgdb += Cgdo + (-1) * Cgdfring ; - pOT->cgsb += Cgso ; - - pOT->cdgb += - Qgod_dVgse - Cf ; - pOT->cddb += - Qgod_dVdse + Cf ; - pOT->cdsb += Qgod_dVbse + Qgod_dVdse + Qgod_dVgse ; - - pOT->cgdo = 0.0 ; - pOT->cgso = 0.0 ; - - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - } - - -/*---------------------------------------------------* -* Substrate/gate/leak currents. -*-----------------*/ - - pOT->isub = Isub ; - - pOT->gbbs = Isub_dVbse ; - pOT->gbds = Isub_dVdse ; - pOT->gbgs = Isub_dVgse ; - - pOT->igate = Igate ; - - pOT->ggbs = Igate_dVbse ; - pOT->ggds = Igate_dVdse ; - pOT->gggs = Igate_dVgse ; - - pOT->igidl = Igidl ; - - pOT->ggidlbs = Igidl_dVbse ; - pOT->ggidlds = Igidl_dVdse ; - pOT->ggidlgs = Igidl_dVgse ; - - -/*---------------------------------------------------* -* Von, Vdsat, -*-----------------*/ - - /* - pOT->von = sIN.type * Vth ; - pOT->vdsat = sIN.type * Vdsat ; - */ - pOT->von = Vth ; - pOT->vdsat = Vdsat ; - - -/*---------------------------------------------------* -* Parasitic conductances. -*-----------------*/ - -/*:org: -* pOT->gd = 1.0e+50 ; -* pOT->gs = 1.0e+50 ; -* modified according to CMIxxxeval.c. -* I don't know the reason why these can be zero. -*/ - pOT->gd = 0.0e0 ; - pOT->gs = 0.0e0 ; - - -/*---------------------------------------------------* -* Junction diode. -*-----------------*/ - - /* - pOT->ibs = sIN.type * Ibs ; - pOT->ibd = sIN.type * Ibd ; - */ - pOT->ibs = Ibs ; - pOT->ibd = Ibd ; - pOT->gbs = Gbse ; - pOT->gbd = Gbde ; - - pOT->qbs = Qbs ; - pOT->qbd = Qbd ; - pOT->capbs = Capbse ; - pOT->capbd = Capbde ; - - -/*-----------------------------------------------------------* -* Warn floating-point exceptions. -* - Function finite() in libm is called. -* - Go to start with info==5. -*-----------------*/ - - T1 = pOT->ids + pOT->gmbs + pOT->gds + pOT->gm ; - T1 = T1 + pOT->qd + pOT->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( "pOT->ids = %12.5e\n" , pOT->ids ) ; - printf( "pOT->gmbs = %12.5e\n" , pOT->gmbs ) ; - printf( "pOT->gds = %12.5e\n" , pOT->gds ) ; - printf( "pOT->gm = %12.5e\n" , pOT->gm ) ; - printf( "pOT->qd = %12.5e\n" , pOT->qd ) ; - printf( "pOT->cdsb = %12.5e\n" , pOT->cdsb ) ; - } - } - - T1 = pOT->isub + pOT->gbbs + pOT->gbds + pOT->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 = pOT->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 = pOT->ibs + pOT->ibd + pOT->gbs + pOT->gbd ; - T1 = T1 + pOT->qbs + pOT->qbd + pOT->capbs + pOT->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 ) { - return( HiSIM_ERROR ) ; - } - -/*-----------------------------------------------------------* -* Restore values for next calculation. -*-----------------*/ - - /* Confined biases */ - pOT->vbsc = Vbsc ; - pOT->vdsc = Vdsc ; - pOT->vgsc = Vgsc ; - - /* Surface potentials and derivatives w.r.t. internal biases */ - pOT->ps0 = Ps0 ; - pOT->ps0_dvbs = Ps0_dVbs ; - pOT->ps0_dvds = Ps0_dVds ; - pOT->ps0_dvgs = Ps0_dVgs ; - pOT->pds = Pds ; - pOT->pds_dvbs = Pds_dVbs ; - pOT->pds_dvds = Pds_dVds ; - pOT->pds_dvgs = Pds_dVgs ; - - /* Derivatives of channel current w.r.t. internal biases */ - pOT->ids_dvbs = Ids_dVbs ; - pOT->ids_dvds = Ids_dVds ; - pOT->ids_dvgs = Ids_dVgs ; - - pOT->nf = Nflic ; - pOT->mu = Mu ; - pOT->qg_int = - ( Qb + Qi ) ; - pOT->qd_int = Qd ; - pOT->qs_int = Qi - Qd ; - pOT->qb_int = Qb ; - - -/*-----------------------------------------------------------* -* End of PART-6. (label) not used so commenting out -*-----------------*/ - -/* end_of_part_6: ; */ - - -/*-----------------------------------------------------------* -* Bottom of hsm1eval. -*-----------------*/ - - - -return ( HiSIM_OK ) ; - -} /* end of hsm1eval102 */ - diff --git a/src/spicelib/devices/hisim/hsm1eval112.c b/src/spicelib/devices/hisim/hsm1eval112.c deleted file mode 100644 index be6e11b6c..000000000 --- a/src/spicelib/devices/hisim/hsm1eval112.c +++ /dev/null @@ -1,4719 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1eval112.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -/********************************************************************* -* Memorandum on programming -* -* (1) Bias (x: b|d|g) -* . sIN.vxs : Input argument. -* . Vxse: External bias taking account device type (pMOS->nMOS). -* . Vxsc: Confined bias within a specified region. -* . Vxs : Internal bias taking account Rs/Rd. -* . 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. -* . Ps0z: Modified Ps0. -* . The following variables are calculated as a function of -* modified biases or potential. -* Tox, Cox, (-- with quantum effect) -* Vth*, dVth*, dPpg, Qnm, Qbm, Igate, Igidl. -* . The following variables are calculated using a transform -* function. -* Lred, rp1(<-sIN.rpock1). -* -* (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 and -D1. -* . 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 "ngspice.h" - -/*-----------------------------------* -* HiSIM macros and structures. -* - All inputs and outputs are defined here. -*-----------------*/ -#include "hisim.h" -#include "hsm1evalenv.h" - -/*===========================================================* -* Function hsm1eval. -*=================*/ - -int HSM1evaluate112 -( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS -) -{ - -/*---------------------------------------------------* -* Local variables. -*-----------------*/ -/* Constans ----------------------- */ -int lp_s0_max = 20 ; -int lp_sl_max = 20 ; -int lp_bs_max = 10 ; -double Ids_tol = 1.0e-10 ; -double Ids_maxvar = 1.0e-1 ; -double dP_max = 0.1e0 ; -double ps_conv = 5.0e-13 ; -double gs_conv = 1.0e-8 ; -/** depletion **/ -double znbd3 = 3.0e0 ; -double znbd5 = 5.0e0 ; -double cn_nc3 = C_SQRT_2 / 108e0 ; -/* 5-degree, contact:Chi=5 */ -double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ -double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ -double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ -double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ -double cn_nc55 = 6.36964918866352e-5 ; /* (1509-1040*sqrt(2))/600000 */ -/** inversion **/ -/* 3-degree polynomial approx for ( exp[Chi]-1 )^{1/2} */ -double cn_im53 = 2.9693154855770998e-1 ; -double cn_im54 = -7.0536542840097616e-2 ; -double cn_im55 = 6.1152888951331797e-3 ; -/** initial guess **/ -double c_ps0ini_2 = 8.0e-4 ; -double c_pslini_1 = 0.3e0 ; -double c_pslini_2 = 3.0e-2 ; -double VgVt_small = 1.0e-12 ; -double Vbs_max = 0.5e0 ; -double Vbs_min = -10.5e0 ; -double Vds_max = 10.5e0 ; -double Vgs_max = 10.5e0 ; -double Vbd_max = 20.0e0 ; -double Vbd_min = -10.0e0 ; -double epsm10 = 10.0e0 * C_EPS_M ; -double small = 1.0e-50 ; -double Gdsmin = 0.0e0 ; -double Gjmin = sIN.gmin ; -double cclmmdf = 1.0e-1 ; -double qme_dlt = 1.0e-9 ; -double eef_dlt = 1.0e-2 ; -double sti1_dlt = -3.0e-3 ; -double sti2_dlt = 2.0e-3 ; -double pol_dlt = 2.0e-1 ; - -/* Internal flags --------------------*/ -int flg_err = 0 ; /* error level */ -int flg_ncnv = 0 ; /* Flag for negative conductance */ -int flg_rsrd ; /* Flag for bias loop accounting Rs and Rd */ -int flg_iprv ; /* Flag for initial guess of Ids */ -int flg_pprv ; /* Flag for initial guesses of Ps0 and Pds */ -int flg_noqi = 0 ; /* Flag for the cases regarding Qi=Qd=0 */ -int flg_vbsc = 0 ; /* Flag for Vbs confining */ -int flg_vdsc = 0 ; /* Flag for Vds confining */ -int flg_vgsc = 0 ; /* Flag for Vgs confining */ -int flg_vbdc = 0 ; /* Flag for Vbd confining */ -int flg_vxxc = 0 ; /* Flag whether some bias was confined */ -int flg_info = 0 ; - -/* Important Variables in HiSIM -------*/ -/* external bias */ -double Vbse , Vdse , Vgse , Vbde ; -/* confine bias */ -double Vbsc , Vdsc , Vgsc , Vbdc ; -double Vbsc_dVbse = 1.0 ; -/* internal bias */ -double Vbs , Vds , Vgs ; -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 = 0.0 ; -double Vgp_dVbs = 0.0 , Vgp_dVds = 0.0 , Vgp_dVgs = 0.0 ; -double Vgs_fb ; -/* Ps0 : surface potential at the source side */ -double Ps0 = 0.0 ; -double Ps0_dVbs = 0.0 , Ps0_dVds = 0.0 , Ps0_dVgs = 0.0 ; -double Ps0_ini = 0.0 , Ps0_iniA , Ps0_iniB ; -/* Psl : surface potential at the drain side */ -double Psl = 0.0 ; -double Psl_dVbs = 0.0 , Psl_dVds = 0.0 , Psl_dVgs = 0.0 ; -double Psl_lim ; -/* Pds := Psl - Ps0 */ -double Pds = 0.0 ; -double Pds_dVbs = 0.0 , Pds_dVds = 0.0 , Pds_dVgs = 0.0 ; -double Pds_ini = 0.0 ; -double Pds_max ; -/* iteration numbers of Ps0 and Psl equations. */ -int lp_s0 , lp_sl ; -/* 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 ; -double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; -/* Xil := beta * ( Psl - Vbs ) - 1. */ -double Xilp12 ; -double Xilp32 ; -double Xil ; -/* modified bias and potential for sym.*/ -double Vbsz , Vdsz = 0.0 , Vgsz = 0.0 ; -double Vbsz_dVbs , Vbsz_dVds ; -double Vdsz_dVds = 0.0 ; -double Vgsz_dVgs , Vgsz_dVds = 0.0 ; -double Vbs1 , Vbs2 , Vbsd ; -double Vbsd_dVbs , Vbsd_dVds ; -double Vzadd = 0.0 , Vzadd_dVds = 0.0; -double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; -double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; -double Ps0Vbsz , Ps0Vbsz_dVbs , Ps0Vbsz_dVds , Ps0Vbsz_dVgs ; -double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; -double Xi0z ; -double Xi0z_dVbs , Xi0z_dVds , Xi0z_dVgs ; -double Xi0zp12 ; -double Xi0zp12_dVbs , Xi0zp12_dVds , Xi0zp12_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 = 0.0 ; -double Vth_dVbs , Vth_dVds , Vth_dVgs ; -double Vth0 ; -double Vth0_dVbs , Vth0_dVds , Vth0_dVgs ; -/* variation of threshold voltage */ -double dVth = 0.0 ; -double dVth_dVbs = 0.0 , dVth_dVds = 0.0 , dVth_dVgs = 0.0 ; -double dVth0 ; -double dVth0_dVbs , dVth0_dVds , dVth0_dVgs ; -double dVthSC ; -double dVthSC_dVbs , dVthSC_dVds , dVthSC_dVgs ; -double dVthW ; -double dVthW_dVbs , dVthW_dVds , dVthW_dVgs ; -/* Alpha and related parameters */ -double Alpha ; -double Alpha_dVbs , Alpha_dVds , Alpha_dVgs ; -double Achi = 0.0 ; -double Achi_dVbs , Achi_dVds , Achi_dVgs ; -double VgVt = 0.0 ; -double VgVt_dVbs , VgVt_dVds , VgVt_dVgs ; -double Delta , Vdsat ; -/* Q_B and capacitances */ -double Qb = 0.0 , Qb_dVbs = 0.0 , Qb_dVds = 0.0 , Qb_dVgs = 0.0 ; -double Qb_dVbse , Qb_dVdse , Qb_dVgse ; -/* Q_I and capacitances */ -double Qi = 0.0 , Qi_dVbs = 0.0 , Qi_dVds = 0.0 , Qi_dVgs = 0.0 ; -double Qi_dVbse , Qi_dVdse , Qi_dVgse ; -/* Q_D and capacitances */ -double Qd = 0.0 , Qd_dVbs = 0.0 , Qd_dVds = 0.0 , Qd_dVgs = 0.0 ; -double Qd_dVbse , Qd_dVdse , Qd_dVgse ; -/* channel current */ -double Ids ; -double Ids_dVbs = 0.0 , Ids_dVds = 0.0 , Ids_dVgs = 0.0 ; -double Ids_dVbse , Ids_dVdse , Ids_dVgse ; -double Ids0 ; -double Ids0_dVbs , Ids0_dVds , Ids0_dVgs ; -/* STI */ -double Vgssti ; -double Vgssti_dVbs , Vgssti_dVds , Vgssti_dVgs ; -double costi0 , costi1 , costi3 ; -double costi4 , costi5 , costi6 , costi7 ; -double Psasti ; -double Psasti_dVbs , Psasti_dVds , Psasti_dVgs ; -double Asti ; -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 expsti ; -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 ; -double beta2 ; -double Leff , Leff_inv ; -double Weff ; -double Ldby ; -double Nsub , q_Nsub ; -double Nin ; -double Pb2 ; -double Pb20 ; -double Pb2c ; -double Eg , Eg300 ; -double Vfb ; -/* PART-1 */ -double Psum ; -double Psum_dVbs ; -double Psum_dVds ; -double sqrt_Psum ; -double cnst0 , cnst1 ; -double fac1 ; -double fac1_dVbs , fac1_dVds , fac1_dVgs ; -double fac1p2 ; -double fs01 ; -double fs01_dPs0 , fs01_dChi ; -double fs01_dVbs , fs01_dVds , fs01_dVgs ; -double fs02 ; -double fs02_dPs0 , fs02_dChi ; -double fs02_dVbs , fs02_dVds , fs02_dVgs ; -double fsl1 ; -double fsl1_dPsl ; -double fsl1_dVbs , fsl1_dVds ; -double fsl2 ; -double fsl2_dPsl ; -double fsl2_dVbs , fsl2_dVds ; -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.0 ; -double Qn0_dVbs , Qn0_dVds , Qn0_dVgs ; -double Qb0 ; -double Qb0_dVbs , Qb0_dVds , Qb0_dVgs = 0.0 ; -double Qn00 = 0.0 ; -double Qn00_dVbs = 0.0 , Qn00_dVds = 0.0 , Qn00_dVgs = 0.0 ; -double Qbnm ; -double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; -double DtPds ; -double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; -double Qbm ; -double Qbm_dVbs , Qbm_dVds , Qbm_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 ; -double Qdrat_dVbs , Qdrat_dVds , Qdrat_dVgs ; -double Idd ; -double Idd_dVbs , Idd_dVds , Idd_dVgs ; -double Qnm ; -double Qnm_dVbs , Qnm_dVds , Qnm_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 ; -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 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 Vdep ; -double Vdep_dVbs , Vdep_dVds , Vdep_dVgs ; -double Epkf ; -double Epkf_dVbs , Epkf_dVds , Epkf_dVgs ; -/* PART-3 (overlap) */ -double yn , yn2 , yn3 ; -double yn_dVbs , yn_dVds , yn_dVgs ; -double Lov , Lov2 ; -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 ; -double Cggo , Cgdo , Cgso , Cgbo ; -/* fringing capacitance */ -double Cf ; -double Qfd , Qfs ; -/* Cqy */ -double Pslk , Pslk_dVbs , Pslk_dVds , Pslk_dVgs ; -double Qy ; -double Cqyd, Cqyg, Cqys, Cqyb ; -/* PART-4 (junction diode) */ -double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; -double js ; -double jssw ; -double isbs ; -double isbd ; -double Nvtm ; -/* junction capacitance */ -double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; -double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; -double arg , sarg ; -/* PART-5 (noise) */ -double NFalp , NFtrp , Cit , Nflic ; -/* Bias iteration accounting Rs/Rd */ -int lp_bs ; -double Ids_last ; -double vtol_iprv = 2.0e-1 ; -double vtol_pprv = 5.0e-2 ; -double Vbsc_dif = 0.0 , Vdsc_dif = 0.0 , Vgsc_dif = 0.0 , sum_vdif ; -double Rs , Rd ; -double Fbs , Fds , Fgs ; -double DJ , DJI = 0.0 ; -double JI11 , JI12 , JI13 , JI21 , JI22 , JI23 , JI31 , JI32 , JI33 ; -double dVbs = 0.0 , dVds = 0.0 , dVgs = 0.0 ; -double dV_sum ; -/* Junction Bias */ -double Vbsj , Vbdj ; -/* Accumulation zone */ -double Psa ; -double Psa_dVbs , Psa_dVds , Psa_dVgs ; -/* CLM */ -double Psdl = 0.0 , Psdl_dVbs = 0.0 , Psdl_dVds = 0.0 , Psdl_dVgs = 0.0 ; -double Ed , Ed_dVbs , Ed_dVds , Ed_dVgs ; -double Ec = 0.0 , Ec_dVbs = 0.0 , Ec_dVds = 0.0 , Ec_dVgs = 0.0 ; -double Lred = 0.0 , Lred_dVbs , Lred_dVds , Lred_dVgs ; -double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; -double Aclm = 0.0; -/* Pocket Implant */ -double Vthp, Vthp_dVbs, Vthp_dVds, Vthp_dVgs ; -double dVthLP,dVthLP_dVbs,dVthLP_dVds,dVthLP_dVgs ; -/* Poly-Depletion Effect */ -double dPpg = 0.0 , dPpg_dVds = 0.0 , dPpg_dVgs = 0.0 ; -/* Quantum Effect */ -double Tox = 0.0 , Tox_dVbs = 0.0 , Tox_dVds = 0.0 , Tox_dVgs = 0.0 ; -double dTox , dTox_dVbs , dTox_dVds , dTox_dVgs ; -double Cox = 0.0 , Cox_dVbs , Cox_dVds , Cox_dVgs ; -double Cox_inv , Cox_inv_dVbs , Cox_inv_dVds , Cox_inv_dVgs ; -double Vthq, Vthq_dVbs , Vthq_dVds ; -/* Igate , Igidl */ -double Egp12 , Egp32 ; -double E0 = 0.0 ; -double E1 , E1_dVbs , E1_dVds , E1_dVgs ; -double E2 , E2_dVbs , E2_dVds , E2_dVgs ; -double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; -double Egidl , Egidl_dVbs , Egidl_dVds , Egidl_dVgs ; -double Igate , Igate_dVbs , Igate_dVds , Igate_dVgs ; -double Igate_dVbse , Igate_dVdse , Igate_dVgse ; -double Igidl , Igidl_dVbs , Igidl_dVds , Igidl_dVgs ; -double Igidl_dVbse , Igidl_dVdse , Igidl_dVgse ; -double Cox0 ; -double Lgate ; -double rp1 , rp1_dVds ; -/* connecting function */ -double FD2 = 0.0 , FD2_dVbs = 0.0 , FD2_dVds = 0.0 , FD2_dVgs = 0.0 ; -double FMD , FMD_dVds = 0.0 ; -/* Phonon scattering */ -double Wgate ; -double mueph ; -/* temporary vars. */ -double T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ; -double TX , TX_dVbs , TX_dVds , TX_dVgs ; -double TY , TY_dVbs , TY_dVds , TY_dVgs ; -double T1_dVbs , T1_dVds , T1_dVgs ; -double T2_dVbs , T2_dVds , T2_dVgs ; -double T3_dVbs , T3_dVds , T3_dVgs ; -double T4_dVbs , T4_dVds ; -double T7_dVbs , T7_dVds , T7_dVgs ; -double T8_dVbs , T8_dVds , T8_dVgs ; -double T10 , T20 , T21 , T30 , T31 ; - - NG_IGNORE(pMS); - -/*================ Start of executable code.=================*/ - - flg_info = sIN.info ; - - -/*-----------------------------------------------------------* -* Change units into CGS. -* - This section may be moved to an interface routine. -*-----------------*/ - -/* device instances */ - sIN.xl *= C_m2cm ; - sIN.xw *= C_m2cm ; - sIN.as *= C_m2cm_p2 ; - sIN.ad *= C_m2cm_p2 ; - sIN.ps *= C_m2cm ; - sIN.pd *= C_m2cm ; - -/* model parameters */ - sIN.tox *= C_m2cm ; - sIN.xld *= C_m2cm ; - sIN.xwd *= C_m2cm ; - sIN.xqy *= C_m2cm ; - sIN.lp *= C_m2cm ; - sIN.xpolyd *= C_m2cm ; - sIN.tpoly *= C_m2cm ; - sIN.rs *= C_m2cm ; - sIN.rd *= C_m2cm ; - sIN.sc3 *= C_m2cm ; - sIN.scp3 *= C_m2cm ; - sIN.parl2 *= C_m2cm ; - sIN.wfc *= C_m2cm ; - sIN.wsti *= C_m2cm ; - sIN.rpock1 *= C_m2cm_p1o2 ; - sIN.qme1 *= C_m2cm ; - sIN.qme3 *= C_m2cm ; - sIN.gidl1 *= C_m2cm_p1o2 ; - sIN.cgso /= C_m2cm ; - sIN.cgdo /= C_m2cm ; - sIN.cgbo /= C_m2cm ; - sIN.js0 /= C_m2cm_p2 ; - sIN.js0sw /= C_m2cm ; - sIN.cj /= C_m2cm_p2 ; - sIN.cjsw /= C_m2cm ; - sIN.cjswg /= C_m2cm ; - - -/*-----------------------------------------------------------* -* Start of the routine. (label) -*-----------------*/ - -/* start_of_routine: */ - - -/*-----------------------------------------------------------* -* Temperature dependent constants. -*-----------------*/ - -/* Inverse of the thermal voltage */ - beta = C_QE / ( C_KB * sIN.temp ) ; - beta2 = beta * beta ; - -/* Band gap */ - Eg = C_Eg0 - sIN.temp - * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; - - Eg300 = C_Eg0 - C_T300 - * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ; - -/* Intrinsic carrier concentration */ - Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) - * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ; - - -/*-----------------------------------------------------------* -* Fixed part. -*-----------------*/ - -/* Lgate in [cm] / [m] */ - Lgate = sIN.xl + 2.0e0 * sIN.xpolyd ; - Wgate = sIN.xw + 2.0e0 * sIN.xpolyd ; - -/* Phonon Scattering */ - T1 = log( Wgate ) ; - T2 = sIN.w0 - T1 - sti1_dlt ; - T3 = T2 * T2 ; - T4 = sqrt( T3 + 4.0 * sti1_dlt * sIN.w0 ) ; - T5 = sIN.w0 - ( T2 - T4 ) / 2 ; - mueph = sIN.mueph1 + sIN.mueph2 * T5 ; - -/* Metallurgical channel geometry */ - Weff = Wgate - 2.0e0 * sIN.xwd ; - Leff = Lgate - 2.0e0 * sIN.xld ; - Leff_inv = 1.0e0 / Leff ; - -/* Flat band voltage */ - Vfb = sIN.vfbc ; - -/* Surface impurity profile */ - if( Leff > sIN.lp ){ - Nsub = ( sIN.nsubc * ( Leff - sIN.lp ) - + sIN.nsubp * sIN.lp ) / Leff ; - } else { - Nsub = sIN.nsubp - + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Leff ) / sIN.lp ; - } - - q_Nsub = C_QE * Nsub ; - -/* 2 phi_B */ - /* @temp, with pocket */ - Pb2 = 2.0e0 / beta * log( Nsub / Nin ) ; - /* @300K, with pocket */ - Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; - /* @300K, w/o pocket */ - Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ; - -/* Debye length */ - Ldby = sqrt( C_ESI / beta / q_Nsub ) ; - -/* Coefficient of the F function for bulk charge */ - cnst0 = q_Nsub * Ldby * C_SQRT_2 ; - -/* cnst1: n_{p0} / p_{p0} */ - T1 = Nin / Nsub ; - cnst1 = T1 * T1 ; - -/* Cox (clasical) */ - Cox0 = C_EOX / sIN.tox ; - - -/*-----------------------------------------------------------* -* Exchange bias conditions according to MOS type. -* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 -* are assumed.) -*-----------------*/ - - /* - Vbse = sIN.type * sIN.vbs ; - Vdse = sIN.type * sIN.vds ; - Vgse = sIN.type * sIN.vgs ; - Vbde = Vbse - Vdse ; - */ - /* modified by K. M. for SPICE3f5 */ - Vbse = sIN.vbs ; - Vdse = sIN.vds ; - Vgse = sIN.vgs ; - Vbde = Vbse - Vdse ; - - -/*---------------------------------------------------* -* Clamp too large biases. -* -note: Quantities are extrapolated in PART-5. -*-----------------*/ - - if ( Vbse < Vbs_min ) { - flg_vbsc = -1 ; - Vbsc = Vbs_min ; - } else if ( Vbse > 0.0 ) { - flg_vbsc = 1 ; - T1 = Vbse / Vbs_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbsc = Vbse / T2 ; - Vbsc_dVbse = Vbs_max * Vbs_max - / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; - } else { - flg_vbsc = 0 ; - Vbsc = Vbse ; - } - - if ( Vdse > Vds_max ) { - flg_vdsc = 1 ; - Vdsc = Vds_max ; - } else { - flg_vdsc = 0 ; - Vdsc = Vdse ; - } - - if ( Vgse > Vgs_max ) { - flg_vgsc = 1 ; - Vgsc = Vgs_max ; - } else { - flg_vgsc = 0 ; - Vgsc = Vgse ; - } - - if ( Vbde < Vbd_min ) { - flg_vbdc = -1 ; - Vbdc = Vbd_min ; - } else if ( Vbde > Vbd_max ) { - Vbdc = Vbd_max ; - flg_vbdc = 1 ; - } else { - Vbdc = Vbde ; - flg_vbdc = 0 ; - } - - if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || - flg_vbdc != 0 ) { - flg_vxxc = 1 ; - } - - -/*-------------------------------------------------------------------* -* Set flags. -*-----------------*/ - - flg_rsrd = 0 ; - flg_iprv = 0 ; - flg_pprv = 0 ; - - if (sIN.mode == HiSIM_NORMAL_MODE) { - Rs = sIN.rs / Weff ; - Rd = sIN.rd / Weff ; - } - else { - Rd = sIN.rs / Weff ; - Rs = sIN.rd / Weff ; - } - - if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { - flg_rsrd = 1 ; - } - - if ( sIN.has_prv == 1 ) { - - Vbsc_dif = Vbsc - sIN.vbsc_prv ; - Vdsc_dif = Vdsc - sIN.vdsc_prv ; - Vgsc_dif = Vgsc - sIN.vgsc_prv ; - - sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) - + fabs( Vgsc_dif ) ; - - if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} - if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} - } - - if ( flg_rsrd == 0 ) { - lp_bs_max = 1 ; - flg_iprv = 0 ; - } - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* -* Bias loop: iteration to solve the system of equations of -* the small circuit taking account Rs and Rd. -* - Vxs are internal (or effective) biases. -* - Equations: -* Vbs = Vbsc - Rs * Ids -* Vds = Vdsc - ( Rs + Rd ) * Ids -* Vgs = Vgsc - Rs * Ids -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initial guesses for biases. -*-----------------*/ - - if ( flg_iprv == 1 ) { - - sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; - sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; - sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; - - dVbs = Vbsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; - dVds = Vdsc_dif * ( 1.0 - - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; - dVgs = Vgsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; - - /* - Ids = sIN.type * sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - */ - Ids = sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - - T1 = ( Ids - sIN.ids_prv ) ; - T2 = fabs( T1 ) ; - if ( Ids_maxvar * sIN.ids_prv < T2 ) { - Ids = sIN.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 ; - } - } - - Vbs = Vbsc - Ids * Rs ; - - Vds = Vdsc - Ids * ( Rs + Rd ) ; - if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } - - Vgs = Vgsc - Ids * Rs ; - - if ( flg_pprv == 1 ) { - - Ps0 = sIN.ps0_prv ; - - Ps0_dVbs = sIN.ps0_dvbs_prv ; - Ps0_dVds = sIN.ps0_dvds_prv ; - Ps0_dVgs = sIN.ps0_dvgs_prv ; - - Pds = sIN.pds_prv ; - - Pds_dVbs = sIN.pds_dvbs_prv ; - Pds_dVds = sIN.pds_dvds_prv ; - Pds_dVgs = sIN.pds_dvgs_prv ; - } - - -/*-----------------------------------------------------------* -* start of the loop. -*-----------------*/ - - for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { - - Ids_last = Ids ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-1: Basic device characteristics. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initialization. -*-----------------*/ - - /* Initialization of counters is needed for restart. */ - lp_s0 = 0 ; - lp_sl = 0 ; - - -/*-----------------------------------------------------------* -* Vxsz: Modified bias introduced to realize symmetry at Vds=0. -*-----------------*/ - - T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVds = 0.0 ; - } - - Vbsz = Vbs + Vzadd ; - Vbsz_dVbs = 1.0 ; - Vbsz_dVds = Vzadd_dVds ; - - Vdsz = Vds + 2 * Vzadd ; - Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; - - Vgsz = Vgs + Vzadd ; - Vgsz_dVgs = 1.0 ; - Vgsz_dVds = Vzadd_dVds ; - - -/*-----------------------------------------------------------* -* Quantum effect -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / C_EOX * T2 + sIN.qme2 ; - - T3 = - 0.5 * sIN.tox / C_EOX * T1 / T2 ; - Vthq_dVbs = T3 * Vbsz_dVbs ; - Vthq_dVds = T3 * Vbsz_dVds ; - - - T1 = - sIN.qme2 ; - T2 = Vgsz - Vthq ; - T3 = sIN.qme1 * T1 * T1 + sIN.qme3 ; - T4 = sIN.qme1 * T2 * T2 + sIN.qme3 ; - - T5 = T4 - T3 - qme_dlt ; - - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T4 - T3 + qme_dlt ) / T6 ) ; - - T8 = 2.0 * sIN.qme1 * T2 * T7 ; - - dTox_dVbs = T8 * ( - Vthq_dVbs ) ; - dTox_dVds = T8 * ( Vgsz_dVds - Vthq_dVds ) ; - dTox_dVgs = T8 * ( Vgsz_dVgs ) ; - - if ( Vgsz - Vthq > 0 ) { - T4 = sIN.qme3 ; - T5 = T4 - T3 - qme_dlt ; - - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - dTox_dVbs = 0.0 ; - dTox_dVds = 0.0 ; - dTox_dVgs = 0.0 ; - } - - Tox = sIN.tox + dTox ; - Tox_dVbs = dTox_dVbs ; - Tox_dVds = dTox_dVds ; - Tox_dVgs = dTox_dVgs ; - - Cox = C_EOX / Tox ; - T1 = - C_EOX / ( Tox * Tox ) ; - Cox_dVbs = T1 * Tox_dVbs ; - Cox_dVds = T1 * Tox_dVds ; - Cox_dVgs = T1 * Tox_dVgs ; - - Cox_inv = Tox / C_EOX ; - T1 = 1.0 / C_EOX ; - Cox_inv_dVbs = T1 * Tox_dVbs ; - Cox_inv_dVds = T1 * Tox_dVds ; - Cox_inv_dVgs = T1 * Tox_dVgs ; - - -/*-----------------------------------------------------------* -* Threshold voltage. -*-----------------*/ - - Delta = 0.1 ; - - Vbs1 = 2.0 - 0.25 * Vbsz ; - Vbs2 = - Vbsz ; - - Vbsd = Vbs1 - Vbs2 - Delta ; - Vbsd_dVbs = 0.75 * Vbsz_dVbs ; - Vbsd_dVds = 0.75 * Vbsz_dVds ; - - T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; - - Psum = ( Pb20 - Vbsz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVbs = - Vbsz_dVbs ; - Psum_dVds = - Vbsz_dVds ; - } else { - Psum = epsm10 ; - Psum_dVbs = 0.0e0 ; - Psum_dVds = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - - -/*---------------------------------------------------* -* Vthp : Vth with pocket. -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Qb0_dVbs = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; - Qb0_dVds = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; - - Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; - - Vthp_dVbs = Qb0_dVbs * Cox_inv + Qb0 * Cox_inv_dVbs ; - Vthp_dVds = Qb0_dVds * Cox_inv + Qb0 * Cox_inv_dVds ; - Vthp_dVgs = Qb0 * Cox_inv_dVgs ; - - -/*-------------------------------------------* -* dVthLP : Short-channel effect induced by pocket. -* - Vth0 : Vth without pocket. -*-----------------*/ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbsz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * Cox_inv ; - - Vth0_dVbs = 0.5 * T1 / T2 * ( - Vbsz_dVbs ) * Cox_inv - + T2 * Cox_inv_dVbs ; - Vth0_dVds = 0.5 * T1 / T2 * ( - Vbsz_dVds ) * Cox_inv - + T2 * Cox_inv_dVds ; - Vth0_dVgs = T2 * Cox_inv_dVgs ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / sIN.parl1 / ( sIN.lp * sIN.lp ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - T1 = Vthp - Vth0 ; - T2 = sIN.scp1 + sIN.scp3 * Psum / sIN.lp ; - T3 = T2 + sIN.scp2 * Vdsz ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVbs = ( Vthp_dVbs - Vth0_dVbs ) * dVth0 * T3 - + T1 * dVth0_dVbs * T3 - + T1 * dVth0 * sIN.scp3 * Psum_dVbs / sIN.lp ; - dVthLP_dVds = ( Vthp_dVds - Vth0_dVds ) * dVth0 * T3 - + T1 * dVth0_dVds * T3 - + T1 * dVth0 - * ( sIN.scp3 * Psum_dVds / sIN.lp - + sIN.scp2 * Vdsz_dVds ) ; - - dVthLP_dVgs = ( Vthp_dVgs - Vth0_dVgs ) * dVth0 * T3 - + T1 * dVth0_dVgs * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVbs = 0.0e0 ; - dVthLP_dVds = 0.0e0 ; - dVthLP_dVgs = 0.0e0 ; - } - - -/*---------------------------------------------------* -* dVthSC : Short-channel effect induced by Vds. -*-----------------*/ - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = ( Leff - sIN.parl2 ) ; - T4 = 1.0e0 / sIN.parl1 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - T4 = sIN.sc1 + sIN.sc3 * Psum / Leff ; - T4_dVbs = sIN.sc3 * Psum_dVbs / Leff ; - T4_dVds = sIN.sc3 * Psum_dVds / Leff ; - - T5 = sIN.sc2 ; - - dVthSC = dVth0 * ( T4 + T5 * Vdsz ) ; - - dVthSC_dVbs = dVth0_dVbs * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVbs ) ; - - dVthSC_dVds = dVth0_dVds * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVds + T5 * Vdsz_dVds ) ; - - dVthSC_dVgs = dVth0_dVgs * ( T4 + T5 * Vdsz ) ; - - -/*---------------------------------------------------* -* dVthW : narrow-channel effect. -*-----------------*/ - - T1 = 1.0 / Cox ; - T2 = T1 * T1 ; - T3 = 1.0 / ( Cox + sIN.wfc / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVbs = Qb0_dVbs * ( T1 - T3 ) - - Qb0 * Cox_dVbs * ( T2 - T4 ) ; - dVthW_dVds = Qb0_dVds * ( T1 - T3 ) - - Qb0 * Cox_dVds * ( T2 - T4 ) ; - dVthW_dVgs = - Qb0 * Cox_dVgs * ( T2 - T4 ) ; - - -/*---------------------------------------------------* -* dVth : Total variation. -* - Positive dVth means the decrease in Vth. -*-----------------*/ - - dVth = dVthSC + dVthLP + dVthW ; - dVth_dVbs = dVthSC_dVbs + dVthLP_dVbs + dVthW_dVbs ; - dVth_dVds = dVthSC_dVds + dVthLP_dVds + dVthW_dVds ; - dVth_dVgs = dVthSC_dVgs + dVthLP_dVgs + dVthW_dVgs ; - - -/*---------------------------------------------------* -* Vth : Threshold voltage. -*-----------------*/ - - Vth = Vthp - dVth ; - - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - dPpg = Nsub / sIN.nsubc * sIN.pgd1 - * exp( Vgsz - sIN.pgd2 - sIN.pgd3 * Vdsz ) ; - dPpg_dVds = - sIN.pgd3 * dPpg * Vdsz_dVds - + dPpg * Vgsz_dVds ; - dPpg_dVgs = dPpg * Vgsz_dVgs ; - - T1 = 1.0e0 - dPpg - pol_dlt ; - T1_dVds = - dPpg_dVds ; - T1_dVgs = - dPpg_dVgs ; - T2 = sqrt( T1 * T1 + 4.0e0 * pol_dlt ) ; - - dPpg = 1.0e0 - 0.5e0 * ( T1 + T2 ) ; - dPpg_dVds = - 0.5e0 * ( T1_dVds + T1 * T1_dVds / T2 ) ; - dPpg_dVgs = - 0.5e0 * ( T1_dVgs + T1 * T1_dVgs / T2 ) ; - - -/*---------------------------------------------------* -* Vgp : Effective gate bias with SCE & RSCE & flatband. -*-----------------*/ - - Vgp = Vgs - Vfb + dVth - dPpg ; - - Vgp_dVbs = dVth_dVbs ; - Vgp_dVds = dVth_dVds - dPpg_dVds ; - Vgp_dVgs = 1.0e0 + dVth_dVgs - dPpg_dVgs ; - - -/*---------------------------------------------------* -* Vgs_fb : Actual flatband voltage taking account Vbs. -* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . -*------------------*/ - - Vgs_fb = Vfb - dVth + dPpg + Vbs ; - - -/*-----------------------------------------------------------* -* Constants in the equation of Ps0 . -*-----------------*/ - - fac1 = cnst0 * Cox_inv ; - fac1_dVbs = cnst0 * Cox_inv_dVbs ; - fac1_dVds = cnst0 * Cox_inv_dVds ; - fac1_dVgs = cnst0 * Cox_inv_dVgs ; - - fac1p2 = fac1 * fac1 ; - - -/*-----------------------------------------------------------* -* Accumulation zone. (zone-A) -* - evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Vgs < Vgs_fb ) { - - -/*---------------------------------------------------* -* 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 = Eg - Pb2 ; - - TX = beta * ( Vgp - Vbs ) ; - - TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; - TX_dVds = beta * Vgp_dVds ; - TX_dVgs = beta * Vgp_dVgs ; - - TY = Cox / ( beta * cnst0 ) ; - - T1 = 1.0 / ( beta * cnst0 ) ; - TY_dVbs = T1 * Cox_dVbs ; - TY_dVds = T1 * Cox_dVds ; - TY_dVgs = T1 * Cox_dVgs ; - - 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 ; - - Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; - Ac31_dVbs = - 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac31_dVds = - 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac31_dVgs = - 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Ac3 = Ac31 * Ac31 ; - - Ac3_dVbs = 2.0 * Ac31 * Ac31_dVbs ; - Ac3_dVds = 2.0 * Ac31 * Ac31_dVds ; - Ac3_dVgs = 2.0 * Ac31 * Ac31_dVgs ; - - Ac2 = sqrt( Ac4 + Ac3 ) ; - Ac2_dVbs = 0.5 * ( Ac4_dVbs + Ac3_dVbs ) / Ac2 ; - Ac2_dVds = 0.5 * ( Ac4_dVds + Ac3_dVds ) / Ac2 ; - Ac2_dVgs = 0.5 * ( Ac4_dVgs + Ac3_dVgs ) / Ac2 ; - - Ac1 = -7.0 * C_SQRT_2 - + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; - - Ac1_dVbs = Ac2_dVbs - + 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac1_dVds = Ac2_dVds - + 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac1_dVgs = Ac2_dVgs - + 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Acd = pow( Ac1 , C_1o3 ) ; - - T1 = C_1o3 / ( Acd * Acd ) ; - Acd_dVbs = Ac1_dVbs * T1 ; - 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 ; - - Acn_dVbs = - 12.0 * TY_dVbs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVbs ; - Acn_dVds = - 12.0 * TY_dVds - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVds ; - Acn_dVgs = - 12.0 * TY_dVgs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVgs ; - - Chi = Acn / Acd ; - - T1 = 1.0 / ( Acd * Acd ) ; - - Chi_dVbs = ( Acn_dVbs * Acd - Acn * Acd_dVbs ) * T1 ; - Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; - Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; - - Psa = Chi / beta + Vbs ; - - Psa_dVbs = Chi_dVbs / beta + 1.0 ; - Psa_dVds = Chi_dVds / beta ; - Psa_dVgs = Chi_dVgs / beta ; - - T1 = Psa - Vbs ; - T2 = T1 / Ps0_min ; - T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; - - T9 = T2 / T3 / Ps0_min ; - T3_dVbs = T9 * ( Psa_dVbs - 1.0 ) ; - T3_dVds = T9 * ( Psa_dVds ) ; - T3_dVgs = T9 * ( Psa_dVgs ) ; - - Ps0 = T1 / T3 + Vbs ; - - T9 = 1.0 / ( T3 * T3 ) ; - - Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVbs ) - + 1.0 ; - Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVds ) ; - Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVgs ) ; - - -/*---------------------------------------------------* -* Characteristics. -*-----------------*/ - - T0 = - Weff * Leff ; - T1 = T0 * Cox ; - T2 = ( Vgp - Ps0 ) ; - - Qb = T1 * T2 ; - - Qb_dVbs = T1 * ( Vgp_dVbs - Ps0_dVbs ) - + T0 * Cox_dVbs * T2 ; - Qb_dVds = T1 * ( Vgp_dVds - Ps0_dVds ) - + T0 * Cox_dVds * T2 ; - Qb_dVgs = T1 * ( Vgp_dVgs - Ps0_dVgs ) - + T0 * Cox_dVgs * T2 ; - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Qi = 0.0e0 ; - Qi_dVbs = 0.0e0 ; - Qi_dVds = 0.0e0 ; - Qi_dVgs = 0.0e0 ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - 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 / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; - - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - - if ( flg_pprv == 1 ) { - - Ps0_ini = Ps0 + Ps0_dVbs * dVbs - + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; - - T1 = Ps0_ini - Ps0 ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } else { - Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - - if ( flg_pprv == 0 ) { - -/*-------------------------------------------* -* Common part. -*-----------------*/ - - Chi = beta * ( Ps0_iniA - Vbs ) ; - - -/*-----------------------------------* -* zone-D1/D2 -* - Ps0_ini is the analytical solution of Qs=Qb0 with -* Qb0 being approximated to 3-degree polynomial. -*-----------------*/ - - if ( Chi < znbd3 ) { - - TY = beta * ( Vgp - Vbs ) ; - T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; - T2 = 81 + 3 * T1 ; - T3 = -2916 - 81 * T1 + 27 * T1 * TY ; - T4 = 1458 - 81 * ( 54 + T1 ) + 27 * T1 * TY ; - T4 = T4 * T4 ; - T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; - TX = 3 - - ( C_2p_1o3 * T2 ) / ( 3 * T5 ) - + 1 / ( 3 * C_2p_1o3 ) * T5 ; - - Ps0_iniA = TX / beta + Vbs ; - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Weak inversion zone. -*-----------------*/ - - } else if ( Vgs <= Vth ) { - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Strong inversion zone. -* - Ps0_iniB : upper bound. -*-----------------*/ - - } else { - - T1 = ( Cox * Cox ) / ( cnst0 * cnst0 ) / cnst1 ; - T2 = T1 * Vgp * Vgp ; - T3 = beta + 2.0 / Vgp ; - - Ps0_iniB = log( T2 ) / T3 ; - - T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; - T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; - - Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; - - } - } - - if ( Ps0_ini < Vbs ) { - Ps0_ini = Vbs ; - } - - -/*---------------------------------------------------* -* Assign initial guess. -*-----------------*/ - - 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 ; - - for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) - / ( fs02 + fs02 ) ; - } else { - fs02 = sqrt( fb * fb + fs01 ) ; - fs02_dPs0 = beta * fb_dChi ; - } - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - - } else { - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - } /* end of if ( Chi ... ) else block */ - - -/*-------------------------------------------* -* Update Ps0 . -* - clamped to Vbs if Ps0 < Vbs . -*-----------------*/ - - if ( fabs( dPs0 ) > dP_max ) { - dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; - } - - Ps0 = Ps0 + dPs0 ; - - if ( Ps0 < Vbs ) { - Ps0 = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { - break ; - } - - } /* end of Ps0 Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_s0 > lp_s0_max ) { - 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. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - cfs1 = cnst1 * exp_bVbs ; - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; - - T2 = 1.0e0 / ( fs02 + fs02 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; - fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) - * T2 ; - } else { - fs02_dPs0 = beta * fb_dChi ; - fs02_dVbs = - beta * fb_dChi ; - } - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - T1 = cnst0 ; - - Qb0 = T1 * fb ; - Qb0_dVbs = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; - Qb0_dVds = Ps0_dVds * T1 * beta * fb_dChi ; - Qb0_dVgs = Ps0_dVgs * T1 * beta * fb_dChi ; - - 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 ; - - T1 = 1.0 / ( fs02 + fb * fb ) ; - T2 = T1 * T1 ; - - Qn0 = cnst0 * fs01 * T1 ; - - T3 = 2.0 * fb_dChi * fb * beta ; - - Qn0_dVbs = cnst0 * ( - fs01_dVbs * T1 - - fs01 * ( fs02_dVbs - + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; - Qn0_dVds = cnst0 * ( - fs01_dVds * T1 - - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; - Qn0_dVgs = cnst0 * ( - fs01_dVgs * T1 - - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ; - - -/*-------------------------------------------* -* zone-D1. (Ps0) -* - Evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Chi < znbd3 ) { - - 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 ; - - T1 = - Weff * Leff ; - - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - if ( Qn0 < Cox * VgVt_small ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - Qi = T1 * Qn0 ; - Qi_dVbs = T1 * Qn0_dVbs ; - Qi_dVds = T1 * Qn0_dVds ; - Qi_dVgs = T1 * Qn0_dVgs ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-------------------------------------------* -* zone-D2 -*-----------------*/ - - Xi0 = Chi - 1.0e0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - Qn00 = Qn0 ; - Qn00_dVbs = Qn0_dVbs ; - Qn00_dVds = Qn0_dVds ; - Qn00_dVgs = Qn0_dVgs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - - flg_noqi = 0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - - } else { - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - T2 = 0.5e0 / Xi0p12 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - flg_noqi = 0 ; - - - } /* end of if ( Chi ... ) block */ - - -/*-----------------------------------------------------------* -* NOTE: The following sections of this part are only for -* the conductive case. -*-----------------*/ - -/*-----------------------------------------------------------* -* Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 . -*-----------------*/ - -/*-----------------------------------------------------------* -* Qn0 : Qi at source side. -* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) -* - Derivatives of fs01 are redefined here. -*-----------------*/ - -/* note:------------------------ -* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; -* fs02 = sqrt( Xi0 + fs01 ) ; -*-------------------------------*/ - - Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; - - 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 ; - - Qn0_dVbs = Qn0 - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVds = Qn0 - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVgs = Qn0 - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ; - - -/*-----------------------------------------------------------* -* Qb0 : Qb at source side. -*-----------------*/ - - if ( Chi > znbd5 ) { - - Qb0 = cnst0 * Xi0p12 ; - Qb0_dVbs = cnst0 * Xi0p12_dVbs ; - Qb0_dVds = cnst0 * Xi0p12_dVds ; - Qb0_dVgs = cnst0 * Xi0p12_dVgs ; - - } - - -/*-----------------------------------------------------------* -* FD2 : connecting function for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - } - - -/*-----------------------------------------------------------* -* Modify Qn0 for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; - Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; - Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; - - Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; - - if ( Qn0 < 0.0 ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - } - - -/*---------------------------------------------------* -* VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) -*-----------------*/ - - VgVt = Qn0 * Cox_inv ; - VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVbs ; - VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVds ; - VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVgs ; - - -/*-----------------------------------------------------------* -* make Qi=Qd=Ids=0 if VgVt <= VgVt_small -*-----------------*/ - - if ( VgVt <= VgVt_small ) { - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Pds = 0.0 ; - Pds_dVbs = 0.0 ; - Pds_dVds = 0.0 ; - Pds_dVgs = 0.0 ; - - T1 = - Leff * Weff ; - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-----------------------------------------------------------* -* Start point of Psl (= Ps0 + Pds) calculation. (label) -*-----------------*/ - -/* start_of_Psl: ; */ - - exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; - - -/*---------------------------------------------------* -* Skip Psl calculation when Vds is very small. -*-----------------*/ - - if ( Vds <= epsm10 ) { - Pds = 0.0 ; - Psl = Ps0 ; - goto end_of_loopl ; - } - - -/*-----------------------------------------------------------* -* Initial guess for Pds ( = Psl - Ps0 ). -*-----------------*/ - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - - if ( flg_pprv == 1 ) { - - Pds_ini = Pds + Pds_dVbs * dVbs - + Pds_dVds * dVds + Pds_dVgs * dVgs ; - - T1 = Pds_ini - Pds ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - - if ( flg_pprv == 0 ) { - Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ) ; - - T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; - T2 = T1 - Vds - c_pslini_2 ; - T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; - - Pds_ini = T1 - ( T2 + T3 ) / 2 ; - - 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. -*-----------------*/ - - Pds = Pds_ini ; - Psl = Ps0 + Pds ; - - -/*---------------------------------------------------* -* Calculation of Psl by solving Poisson eqn. -* (beginning of Newton loop) -* - Fsl : Fsl = 0 is the equation to be solved. -* - dPsl : correction value. -*-----------------*/ - - for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { - - Chi = beta * ( Psl - Vbs ) ; - - -/*-------------------------------------------* -* zone-D2. (Psl) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) - / ( fsl2 + fsl2 ) ; - } else { - fsl2 = sqrt( fb * fb + fsl1 ) ; - fsl2_dPsl = beta * fb_dChi ; - } - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - if ( fsl1 < epsm10 * cnst1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - } - - -/*-------------------------------------------* -* Update Psl . -* - clamped to Vbs if Psl < Vbs . -*-----------------*/ - - if ( fabs( dPsl ) > dP_max ) { - dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; - } - - Psl = Psl + dPsl ; - - if ( Psl < Vbs ) { - Psl = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { - break ; - } - - } /* end of Psl Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_sl > lp_sl_max ) { - 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" ) ; - } - } - - -/*---------------------------------------------------* -* End of Psl calculation. (label) -*-----------------*/ - -end_of_loopl: ; - - -/*---------------------------------------------------* -* Assign Pds. -*-----------------*/ - - Pds = Psl - Ps0 ; - - if ( Pds < ps_conv ) { - Pds = 0.0 ; - Psl = Ps0 ; - } - - -/*---------------------------------------------------* -* 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. -*-----------------*/ - - Chi = beta * ( Psl - Vbs ) ; - - -/*-------------------------------------------* -* zone-D2. (Psl) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ) ; - - /*note: cfs1 = cnst1 * exp_bVbsVds */ - fsl1 = cfs1 * fi * fi ; - fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; - fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; - fsl1_dVds = - cfs1 * beta * fi * fi ; - - - 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 ) ; - - T2 = 0.5 / fsl2 ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; - fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; - fsl2_dVds = fsl1_dVds * T2 ; - } else { - fsl2_dPsl = beta * fb_dChi ; - fsl2_dVbs = - beta * fb_dChi ; - fsl2_dVds = 0.0 ; - } - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - Pds_dVbs = Psl_dVbs - Ps0_dVbs ; - Pds_dVds = Psl_dVds - Ps0_dVds ; - Pds_dVgs = Psl_dVgs - Ps0_dVgs ; - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; - fsl1_dVds = - beta * fsl1 ; - - if ( fsl1 < epsm10 * T1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - fsl1_dVds = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - T2 = 0.5e0 / fsl2 ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; - - fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; - fsl2_dVds = ( fsl1_dVds ) * T2 ; - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - T2 = 0.5e0 / Xilp12 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - 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 ; - } - - -/*-----------------------------------------------------------* -* Evaluate Qb and Idd. -* - Eta : substantial variable of QB'/Pds and Idd/Pds. -* - note: Eta = 4 * GAMMA_{hisim_0} -*-----------------*/ - - Eta = beta * Pds / Xi0 ; - - Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) - / Xi0 ; - Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; - Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; - - - /* ( 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 = - 0.5e0 / Xi0p32 ; - T4 = - 0.5e0 / Eta1p12 * F00 ; - - F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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_1o3 / Xi0p12 * T1 ; - T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; - - F10_dVbs = Zeta32 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F10_dVds = Zeta32 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F10_dVgs = Zeta32 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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 = 2e0 / ( 5e0 * beta ) * Xi0p12 * T1 ; - T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 - + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; - - F30_dVbs = Zeta52 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F30_dVds = Zeta52 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F30_dVgs = Zeta52 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* F11 := PS11/Pds. -*-----------------*/ - - F11 = Ps0 * F10 + C_2o3 / beta * Xilp32 - F30 ; - - F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs - + ( Xi0_dVbs / beta + Pds_dVbs ) * Xilp12 - - F30_dVbs ; - F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds - + ( Xi0_dVds / beta + Pds_dVds ) * Xilp12 - - F30_dVds ; - F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs - + ( Xi0_dVgs / beta + Pds_dVgs ) * Xilp12 - - F30_dVgs ; - - -/*---------------------------------------------------* -* Fdd := Idd/Pds. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta - 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_dVbs * T1 - + T4 * ( - F10_dVbs + F00_dVbs ) ; - Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds ) - + beta * Cox_dVds * T1 - + T4 * ( - F10_dVds + F00_dVds ) ; - Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs ) - + beta * Cox_dVgs * T1 - + T4 * ( - F10_dVgs + F00_dVgs ) ; - - -/*---------------------------------------------------* -* Q_B : bulk charge. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta ; - 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_dVbs * T2 ) ; - Qbnm_dVds = cnst0 - * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds ) - + Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds ) - + Cox_dVds * T2 ) ; - Qbnm_dVgs = cnst0 - * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs ) - + Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs ) - + Cox_dVgs * T2 ) ; - - T1 = - Weff * beta * Leff ; - - Qb = T1 * Qbnm / Fdd ; - - T2 = T1 / ( Fdd * Fdd ) ; - - Qb_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; - Qb_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; - Qb_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; - - -/*---------------------------------------------------* -* Breaking point for Qi=Qd=0. -*-----------------*/ - - if ( flg_noqi != 0 ) { - goto end_of_part_1 ; - } - - -/*---------------------------------------------------* -* 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 ; - - -/*-----------------------------------------------------------* -* Channel Length Modulation. Lred: \Delta L -*-----------------*/ - - if( sIN.clm2 < epsm10 && sIN.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 ; - } - FMD = 1.0e0 ; - - goto end_of_CLM ; - } - - Ec = Idd / beta / Qn0 / Leff ; - Ec_dVbs = 1.0e0 / beta / Leff - * ( Idd_dVbs / Qn0 - Idd * Qn0_dVbs / Qn0 / Qn0 ) ; - Ec_dVds = ( Idd_dVds / Qn0 - Idd * Qn0_dVds / Qn0 / Qn0 ) - / beta / Leff ; - Ec_dVgs = 1.0e0 / beta / Leff - * ( Idd_dVgs / Qn0 - Idd * Qn0_dVgs / Qn0 / Qn0 ) ; - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - - T7 = Qn0 / Wd ; - T7_dVbs = ( Qn0_dVbs / Wd - Qn0 / Wd / Wd * Wd_dVbs ) ; - T7_dVds = ( Qn0_dVds / Wd - Qn0 / Wd / Wd * Wd_dVds ) ; - T7_dVgs = ( Qn0_dVgs / Wd - Qn0 / Wd / Wd * Wd_dVgs ) ; - - T8 = Ec * Ec + 2.0e0 / C_ESI * q_Nsub * ( Psdl - Psl ) + 1.0e5 ; - T8_dVbs = 2.0e0 * Ec * Ec_dVbs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVbs - Psl_dVbs ) ; - T8_dVds = 2.0e0 * Ec * Ec_dVds - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVds - Psl_dVds ) ; - T8_dVgs = 2.0e0 * Ec * Ec_dVgs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVgs - Psl_dVgs ) ; - - Ed = sqrt( T8 ) ; - Ed_dVbs = 0.5e0 / Ed * T8_dVbs ; - Ed_dVds = 0.5e0 / Ed * T8_dVds ; - Ed_dVgs = 0.5e0 / Ed * T8_dVgs ; - - - Lred = ( Ed - Ec ) - / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) * C_ESI ; - T1 = 1.0 / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) ; - T2 = T1 * T1 ; - Lred_dVbs = ( ( Ed_dVbs - Ec_dVbs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVbs ) * C_ESI ; - Lred_dVds = ( ( Ed_dVds - Ec_dVds ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVds ) * C_ESI ; - Lred_dVgs = ( ( Ed_dVgs - Ec_dVgs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVgs ) * C_ESI ; - - -/*---------------------------------------------------* -* Modify Lred for symmetry. -*-----------------*/ - - TX = Vds / cclmmdf ; - T2 = TX * TX ; - T5 = 1.0 + T2 ; - - FMD = 1.0 - 1.0 / T5 ; - FMD_dVds = 2.0 * Vds / ( T5 * T5 * cclmmdf * cclmmdf ) ; - - T6 = Lred ; - - Lred = FMD * T6 ; - Lred_dVbs *= FMD ; - Lred_dVds = FMD_dVds * ( T6 ) + FMD * Lred_dVds ; - Lred_dVgs *= FMD ; - -/*-------------------------------------------* -* End point of CLM. (label) -*-----------------*/ - -end_of_CLM: ; - - -/*---------------------------------------------------* -* preparation for Qi and Qd. -*-----------------*/ - - T1 = 2.0e0 * fac1 ; - - DtPds = T1 * ( F10 - Xi0p12 ) ; - - T2 = 2.0 * ( F10 - Xi0p12 ) ; - - DtPds_dVbs = T1 * ( F10_dVbs - - 0.5 * beta * ( Ps0_dVbs - 1.0e0 ) / Xi0p12 ) - + T2 * fac1_dVbs ; - DtPds_dVds = T1 * ( F10_dVds - - 0.5 * beta * Ps0_dVds / Xi0p12 ) - + T2 * fac1_dVds ; - DtPds_dVgs = T1 * ( F10_dVgs - - 0.5 * beta * Ps0_dVgs / Xi0p12 ) - + 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. -* - clamped to 0 if Alpha < 0. -*-----------------*/ - - Alpha = 1.0e0 - Achi / VgVt ; - - if ( Alpha >= 0.0e0 ) { - - Alpha_dVbs = - Achi_dVbs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVbs / VgVt ) ; - Alpha_dVds = - Achi_dVds / VgVt + ( Achi / VgVt ) - * ( VgVt_dVds / VgVt ) ; - Alpha_dVgs = - Achi_dVgs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVgs / VgVt ) ; - - } else { - - Alpha = 0.0e0 ; - Alpha_dVbs = 0.0e0 ; - Alpha_dVds = 0.0e0 ; - Alpha_dVgs = 0.0e0 ; - } - - -/*-----------------------------------------------------------* -* Q_I : inversion charge. -*-----------------*/ - - Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; - Qinm_dVbs = Alpha_dVbs * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVds = Alpha_dVds * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVgs = Alpha_dVgs * ( 1.0e0 + Alpha + Alpha ) ; - - Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; - Qidn_dVbs = Alpha_dVbs ; - Qidn_dVds = Alpha_dVds ; - Qidn_dVgs = Alpha_dVgs ; - - T1 = - Weff * ( Leff - Lred ) * C_2o3 * VgVt * Qinm / Qidn ; - - Qi = T1 * Cox ; - - Qi_dVbs = Qi * ( VgVt_dVbs / VgVt - + Qinm_dVbs / Qinm - Qidn_dVbs / Qidn - - Lred_dVbs/ ( Leff - Lred ) ) - + T1 * Cox_dVbs ; - Qi_dVds = Qi * ( VgVt_dVds / VgVt - + Qinm_dVds / Qinm - Qidn_dVds / Qidn - - Lred_dVds/ ( Leff - Lred ) ) - + T1 * Cox_dVds ; - Qi_dVgs = Qi * ( VgVt_dVgs / VgVt - + Qinm_dVgs / Qinm - Qidn_dVgs / Qidn - - Lred_dVgs/ ( Leff - Lred ) ) - + T1 * Cox_dVgs ; - - -/*-----------------------------------------------------------* -* Q_D : drain charge. -*-----------------*/ - - 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 ) { - Qdrat_dVbs = Quot * ( Qddn_dVbs / Qddn - Qdnm_dVbs / Qdnm ) ; - Qdrat_dVds = Quot * ( Qddn_dVds / Qddn - Qdnm_dVds / Qdnm ) ; - Qdrat_dVgs = Quot * ( Qddn_dVgs / Qddn - Qdnm_dVgs / Qdnm ) ; - } else { - Qdrat = 0.5e0 ; - Qdrat_dVbs = 0.0e0 ; - Qdrat_dVds = 0.0e0 ; - Qdrat_dVgs = 0.0e0 ; - } - - 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 ; - - -/*-----------------------------------------------------------* -* Modify charges for zone-D2. -* - FD2 must be defined previously. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - if ( Chi < znbd5 ) { - - 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 ; - - T5 = - Leff * Weff ; - - Qb_dVbs = FD2 * Qb_dVbs + FD2_dVbs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVbs - FD2_dVbs * T5 * Qb0 ; - Qb_dVds = FD2 * Qb_dVds + FD2_dVds * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVds - FD2_dVds * T5 * Qb0 ; - Qb_dVgs = FD2 * Qb_dVgs + FD2_dVgs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVgs - FD2_dVgs * T5 * Qb0 ; - - Qb = FD2 * Qb + ( 1.0 - FD2 ) * T5 * Qb0 ; - - if ( Qb > 0.0 ) { - Qb = 0.0 ; - Qb_dVbs = 0.0 ; - Qb_dVds = 0.0 ; - Qb_dVgs = 0.0 ; - } - - Qi_dVbs = FD2 * Qi_dVbs + FD2_dVbs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVbs - FD2_dVbs * T5 * Qn0 ; - Qi_dVds = FD2 * Qi_dVds + FD2_dVds * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVds - FD2_dVds * T5 * Qn0 ; - Qi_dVgs = FD2 * Qi_dVgs + FD2_dVgs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVgs - FD2_dVgs * T5 * Qn0 ; - - Qi = FD2 * Qi + ( 1.0 - FD2 ) * T5 * Qn0 ; - - if ( Qi > 0.0 ) { - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - } - - Qd_dVbs = FD2 * Qd_dVbs + FD2_dVbs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVbs / 2 - - FD2_dVbs * T5 * Qi / 2 ; - Qd_dVds = FD2 * Qd_dVds + FD2_dVds * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVds / 2 - - FD2_dVds * T5 * Qi / 2 ; - Qd_dVgs = FD2 * Qd_dVgs + FD2_dVgs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVgs / 2 - - FD2_dVgs * T5 * Qi / 2 ; - - Qd = FD2 * Qd + ( 1.0 - FD2 ) * T5 * Qi / 2 ; - - if ( Qd > 0.0 ) { - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - } - - } - - -/*-----------------------------------------------------------* -* Modified potential for symmetry. -*-----------------*/ - - T1 = exp( - ( Vds - Pds ) / ( 2.0 * sIN.pzadd0 ) ) ; - - Pzadd = sIN.pzadd0 * T1 ; - - T2 = - 0.5 * T1 ; - - Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; - Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; - Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; - - if ( fabs ( Pzadd ) < epsm10 ) { - Pzadd = 0.0 ; - 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 ; - - -/*-----------------------------------------------------------* -* Evaluate universal mobility. -*-----------------*/ - - Ps0Vbsz = Ps0z - Vbsz ; - Ps0Vbsz_dVbs = Ps0z_dVbs - Vbsz_dVbs ; - Ps0Vbsz_dVds = Ps0z_dVds - Vbsz_dVds ; - Ps0Vbsz_dVgs = Ps0z_dVgs ; - - -/*-------------------------------------------* -* Qbm -*-----------------*/ - - T1 = cnst0 ; - T2 = sqrt( beta * Ps0Vbsz - 1.0 ) ; - - Qbm = T1 * T2 ; - - T3 = 0.5 * beta * T1 / T2 ; - - Qbm_dVbs = T3 * Ps0Vbsz_dVbs ; - Qbm_dVds = T3 * Ps0Vbsz_dVds ; - Qbm_dVgs = T3 * Ps0Vbsz_dVgs ; - - -/*-------------------------------------------* -* Qnm -*-----------------*/ - - Chi = beta * Ps0Vbsz ; - - exp_Chi = exp( Chi ) ; - - exp_bVbs = exp( beta * Vbsz ) ; - - cfs1 = cnst1 * exp_bVbs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - /* regard fs01 as a function of Chi and Vbs */ - fs01_dChi = cfs1 * ( exp_Chi ) ; - fs01_dVbs = beta * fs01 ; - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - Xi0z = Chi - 1.0e0 ; - - Xi0z_dVbs = beta * Ps0Vbsz_dVbs ; - Xi0z_dVds = beta * Ps0Vbsz_dVds ; - Xi0z_dVgs = beta * Ps0Vbsz_dVgs ; - - fs02 = sqrt( Xi0z + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - /* regard fs01 as a function of Chi and Vbs */ - fs02_dChi = ( 1.0 + fs01_dChi ) * T2 ; - fs02_dVbs = fs01_dVbs * T2 ; - - Xi0zp12 = sqrt( Xi0z ) ; - - Xi0zp12_dVbs = 0.5e0 * Xi0z_dVbs / Xi0zp12 ; - Xi0zp12_dVds = 0.5e0 * Xi0z_dVds / Xi0zp12 ; - Xi0zp12_dVgs = 0.5e0 * Xi0z_dVgs / Xi0zp12 ; - - T1 = 1.0 / ( fs02 + Xi0zp12 ) ; - - Qnm = cnst0 * fs01 * T1 ; - - fs01_dVds = beta * Ps0Vbsz_dVds * fs01_dChi - + fs01_dVbs * Vbsz_dVds ; - fs01_dVbs = beta * Ps0Vbsz_dVbs * fs01_dChi + fs01_dVbs ; - fs01_dVgs = beta * Ps0Vbsz_dVgs * fs01_dChi ; - - fs02_dVds = beta * Ps0Vbsz_dVds * fs02_dChi - + fs02_dVbs * Vbsz_dVds ; - fs02_dVbs = beta * Ps0Vbsz_dVbs * fs02_dChi + fs02_dVbs ; - fs02_dVgs = beta * Ps0Vbsz_dVgs * fs02_dChi ; - - Qnm_dVbs = Qnm - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0zp12_dVbs ) * T1 ) ; - Qnm_dVds = Qnm - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0zp12_dVds ) * T1 ) ; - Qnm_dVgs = Qnm - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0zp12_dVgs ) * T1 ) ; - - if ( Qbm < 0.0 ) { - Qbm = 0.0 ; - } - if ( Qnm < 0.0 ) { - Qnm = 0.0 ; - } - - -/*---------------------------------------------------* -* Muun : universal mobility. -*-----------------*/ - - /* removed Eqs. "Qbm = Qb0", "Qnm = Qn0", ... (4/Dec/01) */ - - T1 = sIN.ninv - sIN.ninvd * Vdsz ; - T1_dVds = - sIN.ninvd * Vdsz_dVds ; - - Eeff = ( sIN.ndep * Qbm + T1 * Qnm ) / C_ESI ; - Eeff_dVbs = ( sIN.ndep * Qbm_dVbs + T1 * Qnm_dVbs ) - / C_ESI ; - Eeff_dVds = ( sIN.ndep * Qbm_dVds + T1 * Qnm_dVds - + T1_dVds * Qnm ) - / C_ESI ; - Eeff_dVgs = ( sIN.ndep * Qbm_dVgs + T1 * Qnm_dVgs ) - / C_ESI ; - - Rns = Qnm / C_QE ; - - T10 = pow( sIN.temp / C_T300 , sIN.muetmp ) ; - T21 = pow( Eeff , sIN.mueph0 - 1.0e0 ) ; - T20 = T21 * Eeff ; - T31 = pow( Eeff , sIN.muesr0 - 1.0e0 ) ; - T30 = T31 * Eeff ; - - T1 = 1e0 / ( sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ) - + T10 - * T20 / mueph - + T30 / sIN.muesr1 ; - - Muun = 1e0 / T1 ; - - T1 = 1e0 / ( T1 * T1 ) ; - T2 = sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ; - T2 = 1e0 / ( T2 * T2 ) ; - T3 = T10 * sIN.mueph0 * T21 / mueph ; - T4 = sIN.muesr0 * T31 / sIN.muesr1 ; - - Muun_dVbs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVbs / C_QE * T2 - + Eeff_dVbs * T3 - + Eeff_dVbs * T4 ) - * T1 ; - Muun_dVds = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVds / C_QE * T2 - + Eeff_dVds * T3 - + Eeff_dVds * T4 ) - * T1 ; - Muun_dVgs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVgs / C_QE * T2 - + Eeff_dVgs * T3 - + Eeff_dVgs * T4 ) - * T1 ; - - -/*-----------------------------------------------------------* -* Mu : mobility -*-----------------*/ - - T1 = 1.0e0 / beta / ( Qn0 + small ) / ( Leff - Lred ) ; - T1_dVbs = 1.0e0 / beta * ( - Qn0_dVbs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVbs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVds = 1.0e0 / beta * ( - Qn0_dVds / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVds / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVgs = 1.0e0 / beta * ( - Qn0_dVgs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVgs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - - Ey = Idd * T1 ; - Ey_dVbs = Idd_dVbs * T1 + Idd * T1_dVbs ; - Ey_dVds = Idd_dVds * T1 + Idd * T1_dVds ; - Ey_dVgs = Idd_dVgs * T1 + Idd * T1_dVgs ; - - 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 = sIN.temp / C_T300 ; - - Vmax = sIN.vmax / ( 1.8 + 0.4 * T1 + 0.1 * T1 * T1 ) ; - - T2 = 1.0 - sIN.vover / pow( Leff , sIN.voverp ) ; - - if ( T2 < 0.01 ) { - fprintf( stderr , - "*** warning(HiSIM): Overshoot is too big.\n" ) ; - T2 = 0.01 ; - } - - Vmax = Vmax / T2 ; - - T1 = Em / Vmax ; - - /* note: sIN.bb = 2 (electron) ;1 (hole) */ - if ( 1.0e0 - epsm10 <= sIN.bb && sIN.bb <= 1.0e0 + epsm10 ) { - T3 = 1.0e0 ; - } else if ( 2.0e0 - epsm10 <= sIN.bb - && sIN.bb <= 2.0e0 + epsm10 ) { - T3 = T1 ; - } else { - T3 = pow( T1 , sIN.bb - 1.0e0 ) ; - } - T2 = T1 * T3 ; - T4 = 1.0e0 + T2 ; - T6 = pow( T4 , ( - 1.0e0 / sIN.bb - 1.0e0 ) ) ; - T5 = T4 * T6 ; - - Mu = Muun * T5 ; - Mu_dVbs = Muun_dVbs * T5 - Muun / Vmax * T6 * T3 * Em_dVbs ; - Mu_dVds = Muun_dVds * T5 - Muun / Vmax * T6 * T3 * Em_dVds ; - Mu_dVgs = Muun_dVgs * T5 - Muun / Vmax * T6 * T3 * Em_dVgs ; - - -/* end_of_mobility : ; */ - - -/*-----------------------------------------------------------* -* Ids: channel current. -*-----------------*/ - - T1 = Weff / beta / ( Leff - Lred ) ; - T1_dVbs = T1 / ( Leff - Lred ) * Lred_dVbs ; - T1_dVds = T1 / ( Leff - Lred ) * Lred_dVds ; - T1_dVgs = T1 / ( Leff - Lred ) * Lred_dVgs ; - - Ids0 = T1 * Idd * Mu ; - Ids0_dVbs = T1 * ( Mu * Idd_dVbs + Idd * Mu_dVbs ) - + T1_dVbs * Mu * Idd ; - Ids0_dVds = T1 * ( Mu * Idd_dVds + Idd * Mu_dVds ) - + T1_dVds * Mu * Idd ; - Ids0_dVgs = T1 * ( Mu * Idd_dVgs + Idd * Mu_dVgs ) - + T1_dVgs * Mu * Idd ; - - T1 = Vdsz + sIN.rpock2 ; - T2 = T1 * T1 + small ; - T2_dVbs = 0.0e0 ; - T2_dVds = 2.0 * T1 * Vdsz_dVds ; - T2_dVgs = 0.0e0 ; - - rp1 = FMD * sIN.rpock1 ; - rp1_dVds = FMD_dVds * sIN.rpock1 ; - - TX = pow( Ids0, sIN.rpocp1 ) * pow( Leff / 1.0e-4 , sIN.rpocp2 ) / Weff ; - T3 = rp1 * TX ; - T4 = ( T3 + T2 ) * ( T3 + T2 ) ; - - Ids = Ids0 / ( 1.0 + T3 / T2 ) ; - - T5 = T2 * ( T2 - ( sIN.rpocp1 - 1.0 ) * T3 ) / T4 ; - T6 = Ids0 * T3 / T4 ; - - Ids_dVbs = T5 * Ids0_dVbs + T6 * T2_dVbs ; - Ids_dVds = T5 * Ids0_dVds + T6 * T2_dVds - - Ids0 * T2 / T4 * rp1_dVds * TX ; - Ids_dVgs = T5 * Ids0_dVgs + T6 * T2_dVgs ; - - if ( Pds < ps_conv ) { - Ids_dVbs = 0.0 ; - Ids_dVgs = 0.0 ; - } - - Ids += Gdsmin * Vds ; - Ids_dVds += Gdsmin ; - - -/*-----------------------------------------------------------* -* STI -*-----------------*/ - if ( sIN.coisti == 0 ) { - goto end_of_STI ; - } - - Vth_dVbs = Vthp_dVbs - dVth_dVbs ; - Vth_dVds = Vthp_dVds - dVth_dVds ; - Vth_dVgs = Vthp_dVgs - dVth_dVgs ; - - Vgssti = Vgs - Vfb + Vth * sIN.wvthsc ; - Vgssti_dVbs = Vth_dVbs * sIN.wvthsc ; - Vgssti_dVds = Vth_dVds * sIN.wvthsc ; - Vgssti_dVgs = 1.0e0 + Vth_dVgs * sIN.wvthsc ; - - costi0 = sqrt (2.0e0 * C_QE * sIN.nsti * C_ESI / beta) ; - costi1 = Nin * Nin / sIN.nsti / sIN.nsti ; - costi3 = costi0 * costi0 / Cox / Cox ; - costi4 = costi3 * beta / 2.0e0 ; - costi5 = costi4 * beta * 2.0e0 ; - T1 = 1.0e0 + 4.0e0 * ( beta * ( Vgssti - Vbs ) - 1.0e0 ) / costi5 ; - if ( T1 > 0.0 ) { - costi6 = sqrt( T1 ) ; - Psasti = Vgssti + costi4 * (1.0e0 - costi6) ; - Psasti_dVbs = Vgssti_dVbs - (Vgssti_dVbs - 1.0e0)/costi6 ; - Psasti_dVds = Vgssti_dVds - Vgssti_dVds/costi6 ; - Psasti_dVgs = Vgssti_dVgs - Vgssti_dVgs/costi6 ; - } else { - Psasti = Psasti_dVbs = Psasti_dVds = Psasti_dVgs = 0.0 ; - } - - Asti = 1.0e0 / costi1 / costi3 ; - Psbsti = log(Asti * (Vgssti*Vgssti)) / (beta + 2.0e0 / Vgssti) ; - - Psbsti_dVbs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVbs ; - Psbsti_dVds = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVds ; - Psbsti_dVgs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * 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 ; - - Psti = Psbsti - 0.5e0 * (Psab - + sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti)) ; - - Psti_dVbs = Psbsti_dVbs - 0.5e0 * Psab_dVbs - - (Psab * Psab_dVbs +2.0e0 * sti2_dlt * Psbsti_dVbs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVds = Psbsti_dVds - 0.5e0 * Psab_dVds - - (Psab * Psab_dVds +2.0e0 * sti2_dlt * Psbsti_dVds) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVgs = Psbsti_dVgs - 0.5e0 * Psab_dVgs - - (Psab * Psab_dVgs +2.0e0 * sti2_dlt * Psbsti_dVgs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - - expsti = exp(beta * Psti) ; - sq1sti = sqrt(beta * (Psti - Vbs) - 1.0e0 +costi1 * expsti) ; - - sq1sti_dVbs = 0.50e0 * (beta * (Psti_dVbs - 1.0e0) - + costi1 * beta * Psti_dVbs * expsti) / sq1sti ; - sq1sti_dVds = 0.50e0 * (beta * Psti_dVds - + costi1 * beta * Psti_dVds * expsti) / sq1sti ; - sq1sti_dVgs = 0.50e0 * (beta * Psti_dVgs - + costi1 * beta * Psti_dVgs * expsti) / sq1sti ; - - sq2sti = sqrt(beta * (Psti - Vbs) - 1.0e0) ; - - sq2sti_dVbs = 0.50e0 * beta *(Psti_dVbs - 1.0e0) / sq2sti ; - sq2sti_dVds = 0.50e0 * beta *Psti_dVds / sq2sti ; - sq2sti_dVgs = 0.50e0 * beta *Psti_dVgs / sq2sti ; - - 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) ; - - costi7 = 2.0e0 * sIN.wsti / beta ; - Idssti = costi7 * Mu * Qn0sti * (1.0e0 - exp(-beta * Vds)) - / (Leff - Lred) ; - - Idssti_dVbs = costi7 * - ((( Mu_dVbs * Qn0sti + Mu * Qn0sti_dVbs ) * - ( 1.0e0 - exp( - beta * Vds ))) / ( Leff - Lred ) - + Lred_dVbs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - Idssti_dVds = costi7 * - ((( Mu_dVds * Qn0sti + Mu * Qn0sti_dVds ) * - ( 1.0e0 - exp( - beta * Vds )) - + beta * Mu * Qn0sti * exp( - beta * Vds )) / ( Leff - Lred ) - + Lred_dVds * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - Idssti_dVgs = costi7 * - ((( Mu_dVgs * Qn0sti + Mu * Qn0sti_dVgs ) * - ( 1.0e0 - exp( - beta * Vgs ))) / ( Leff - Lred ) - + Lred_dVgs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - - Ids = Ids + Idssti ; - - Ids_dVbs = Ids_dVbs + Idssti_dVbs ; - Ids_dVds = Ids_dVds + Idssti_dVds ; - Ids_dVgs = Ids_dVgs + Idssti_dVgs ; - - end_of_STI: ; - -/*-----------------------------------------------------------* -* 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 ) || - 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 -- ; } - - -/*-----------------------------------------------------------* -* End of PART-1. (label) -*-----------------*/ - -end_of_part_1: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-2: Substrate / gate / leak currents -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Isub : substrate current induced by impact ionization. -*-----------------*/ - -/*-------------------------------------------* -* Accumulation zone or nonconductive case, in which Ids==0. -*-----------------*/ - - if ( Ids <= 0.0e0 || sIN.coisub == 0 ) { - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - goto end_of_Isub ; - } - - -/*-------------------------------------------* -* Conductive case. -*-----------------*/ - - if ( sIN.sub1 > 0.0e0 && sIN.vmax > 0.0e0 ) { - - Vdep = Vds + Ps0 - sIN.sub3 * Psl ; - Vdep_dVbs = Ps0_dVbs - sIN.sub3 * Psl_dVbs ; - Vdep_dVds = 1.0e0 + Ps0_dVds - sIN.sub3 * Psl_dVds ; - Vdep_dVgs = Ps0_dVgs - sIN.sub3 * Psl_dVgs ; - - TX = - sIN.sub2 / Vdep ; - - Epkf = exp( TX ) ; - Epkf_dVbs = - TX * Vdep_dVbs / Vdep * Epkf ; - Epkf_dVds = - TX * Vdep_dVds / Vdep * Epkf ; - Epkf_dVgs = - TX * Vdep_dVgs / Vdep * Epkf ; - - T1 = Ids * Epkf ; - T1_dVbs = Ids_dVbs * Epkf + Ids * Epkf_dVbs ; - T1_dVds = Ids_dVds * Epkf + Ids * Epkf_dVds ; - T1_dVgs = Ids_dVgs * Epkf + Ids * Epkf_dVgs ; - - if( T1 < 1.0e-25 ){ - T1 = 1.0e-25 ; - T1_dVbs = 0.0e0 ; - T1_dVds = 0.0e0 ; - T1_dVgs = 0.0e0 ; - } - - Isub = sIN.sub1 * Vdep * T1 ; - Isub_dVbs = sIN.sub1 * ( Vdep_dVbs * T1 + Vdep * T1_dVbs ) ; - Isub_dVds = sIN.sub1 * ( Vdep_dVds * T1 + Vdep * T1_dVds ) ; - Isub_dVgs = sIN.sub1 * ( Vdep_dVgs * T1 + Vdep * T1_dVgs ) ; - - } else { - - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - - } /* end of if ( sIN.sub1 ... ) else block. */ - - -/*-------------------------------------------* -* End of Isub. (label) -*-----------------*/ - -end_of_Isub: ; - - -/*-----------------------------------------------------------* -* Igate : Gate current induced by tunneling. -* - Vzadd is used for symmetrizing. -*-----------------*/ - - Egp12 = sqrt( Eg ) ; - Egp32 = Eg * Egp12 ; - - if ( sIN.coiigs == 0 ) { - Igate = 0.0e0 ; - Igate_dVbs = 0.0e0 ; - Igate_dVds = 0.0e0 ; - Igate_dVgs = 0.0e0 ; - goto end_of_Igate ; - } - - Vgpz = Vgp + Vzadd ; - - Vgpz_dVbs = Vgp_dVbs ; - Vgpz_dVds = Vgp_dVds + Vzadd_dVds ; - Vgpz_dVgs = Vgp_dVgs ; - - T1 = Vgpz - ( Psl + Ps0 + 2.0 * Vzadd ) * sIN.gleak3 ; - - E0 = 10.0 ; - - E2 = T1 / Tox ; - - E2_dVbs = E2 - * ( ( Vgpz_dVbs - ( Psl_dVbs + Ps0_dVbs ) * sIN.gleak3 ) - / T1 - - Tox_dVbs / Tox ) ; - E2_dVds = E2 - * ( ( Vgpz_dVds - - ( Psl_dVds + Ps0_dVds + 2.0 * Vzadd_dVds ) - * sIN.gleak3 - ) / T1 - - Tox_dVds / Tox ) ; - E2_dVgs = E2 - * ( ( Vgpz_dVgs - ( Psl_dVgs + Ps0_dVgs ) * sIN.gleak3 ) - / T1 - - Tox_dVgs / Tox ) ; - - T1 = E2 - E0 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E2 ) ; - - Etun = E2 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = 2.0 * T1 * T4 + 0.5 ; - - Etun_dVbs = T5 * E2_dVbs ; - Etun_dVds = T5 * E2_dVds ; - Etun_dVgs = T5 * E2_dVgs ; - - T1 = exp( - sIN.gleak2 * Egp32 / Etun ) ; - - T2 = sIN.gleak1 / Egp12 * C_QE * Weff * Leff ; - - Igate = T2 * Etun * Etun * T1 ; - - T3 = T2 * T1 * ( 2.0 * Etun + sIN.gleak2 * Egp32 ) ; - - Igate_dVbs = T3 * Etun_dVbs ; - Igate_dVds = T3 * Etun_dVds ; - Igate_dVgs = T3 * Etun_dVgs ; - - end_of_Igate: ; - - -/*-----------------------------------------------------------* -* Igidl : GIDL -*-----------------*/ - - if ( sIN.cogidl == 0 ) { - Igidl = 0.0e0 ; - Igidl_dVbs = 0.0e0 ; - Igidl_dVds = 0.0e0 ; - Igidl_dVgs = 0.0e0 ; - goto end_of_IGIDL ; - } - - T1 = sIN.gidl3 * Vdsz - Vgsz + Vfb - dVth + dPpg ; - - E1 = T1 / Tox ; - - E1_dVbs = E1 * ( - dVth_dVbs / T1 - Tox_dVbs / Tox ) ; - E1_dVds = E1 * ( ( sIN.gidl3 * Vdsz_dVds - - Vgsz_dVds - dVth_dVds + dPpg_dVds) / T1 - - Tox_dVds / Tox ) ; - E1_dVgs = E1 * ( ( -1.0 - dVth_dVgs + dPpg_dVgs) / T1 - Tox_dVgs / Tox ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egidl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egidl_dVbs = T5 * E1_dVbs ; - Egidl_dVds = T5 * E1_dVds ; - Egidl_dVgs = T5 * E1_dVgs ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egidl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Igidl = T2 * Egidl * Egidl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egidl + sIN.gidl2 * Egp32 ) ; - - Igidl_dVbs = T3 * Egidl_dVbs ; - Igidl_dVds = T3 * Egidl_dVds ; - Igidl_dVgs = T3 * Egidl_dVgs ; - - end_of_IGIDL: ; - - -/*-----------------------------------------------------------* -* End of PART-2. (label) -*-----------------*/ - -/* end_of_part_2: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-3: Overlap charge -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-------------------------------------------* -* Calculation of Psdl for cases of flg_noqi==1. -*-----------------*/ - - if ( flg_noqi != 0 ) { - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0e0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - Ec = 0.0e0 ; - Ec_dVbs =0.0e0 ; - Ec_dVds =0.0e0 ; - Ec_dVgs =0.0e0 ; - - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - if ( Psl - Vbs > 0 ){ - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - }else{ - Wd = 0e0 ; - Wd_dVbs = 0e0 ; - Wd_dVds = 0e0 ; - Wd_dVgs = 0e0 ; - } - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (simple, default, CLM1 < 1.0) <-- changed 04/Dec/01 -* (orig. "CLM1 must be 1.0") -*-----------------*/ - - if ( sIN.coovlp == 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T2 = - 1.0e+11 ; - yn = sqrt ( ( Psdl - Ps0 - Vds) / T2 ) ; - yn2 = yn * yn ; - yn3 = yn2 * yn ; - - - if ( yn <= Lov ){ - Qgod = ( ( Vgs - Vds ) * Lov - T2 * yn3 / 3.0e0 ) * T1 ; - Qgod_dVbs = ( (-0.5e0) * yn * ( Psdl_dVbs - Ps0_dVbs ) ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - 0.5e0 * yn - * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ) * T1 ; - Qgod_dVgs = ( Lov - 0.5e0 * yn * ( Psdl_dVgs - Ps0_dVgs ) ) * T1 ; - }else{ - T3 = 0.5e0 / yn / T2 ; - yn_dVbs = T3 * ( Psdl_dVbs - Ps0_dVbs ) ; - yn_dVds = T3 * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ; - yn_dVgs = T3 * ( Psdl_dVgs - Ps0_dVgs ) ; - - T4 = (Lov - yn ) * (Lov - yn ) ; - T5 = T4 * (Lov - yn ) ; - Qgod = ( ( Vgs - Vds ) * Lov - T2 / 3.0e0 * ( T5 + yn3 ) ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs - + T2 * T4 * yn_dVbs ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds - + T2 * T4 * yn_dVds ) * T1 ; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs - + T2 * T4 * yn_dVgs ) * T1 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (complete) -*-----------------*/ - - else if( sIN.coovlp > 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T3 = 1e21 / pow( Lov , 3e0) ; - T1 = C_QE * T3 / ( C_ESI * 4e0 ) ; - T2 = Cox * Weff ; - - Lov2 = Lov * Lov ; - - yn = pow( C_ESI * 5e0 / ( C_QE * T3 ) - * ( Ps0 + Vds - Psdl ) - , 0.2e0 ) ; - yn2 = yn * yn ; - - if ( yn < Lov ) { - Qgod = ( ( Vgs - Vds ) * Lov + T1 / 3e0 * yn2 * yn2 * yn2 ) * T2 ; - Qgod_dVbs = ( yn / 2e0 * ( Ps0_dVbs - Psdl_dVbs ) ) * T2 ; - Qgod_dVds = ( - Lov + yn / 2e0 * ( Ps0_dVds + 1e0 - Psdl_dVds ) ) * T2 ; - Qgod_dVgs = ( Lov + yn / 2e0 * ( Ps0_dVgs - Psdl_dVgs ) ) * T2 ; - } else { - T3 = C_ESI * 5e0 / ( C_QE * T3 ) ; - - Qgod = ( ( Vgs + T1 * 4e0 / 5e0 * yn2 * yn2 * yn - Vds ) * Lov - + T1 / 30e0 * Lov2 * Lov2 * Lov2 - - T1 * yn2 * yn2 / 2e0 * Lov2 ) * T2 ; - Qgod_dVbs = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVbs - Psdl_dVbs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVbs - Psdl_dVbs ) * Lov2 ) - * T2 ; - Qgod_dVds = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVds + 1e0 - Psdl_dVds ) - 1e0 ) - * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVds + 1e0 - Psdl_dVds ) - * Lov2 ) * T2 ; - Qgod_dVgs = ( ( 1e0 + T1 * 4e0 / 5e0 * T3 * ( Ps0_dVgs - Psdl_dVgs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVgs - Psdl_dVgs ) * Lov2 ) - * T2 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (off) -*-----------------*/ - - else if( sIN.coovlp < 0 ){ - - Qgos = 0.0e0 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = 0.0e0 ; - - Qgod = 0.0e0 ; - Qgod_dVbs = 0.0e0 ; - Qgod_dVds = 0.0e0 ; - Qgod_dVgs = 0.0e0 ; - - } - - -/*-----------------------------------------------------------* -* End of PART-3. (label) -*-----------------*/ - -/* end_of_part_3: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-4: Substrate-source/drain junction diode. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Cbsj, Cbdj: node-base S/D biases. -*-----------------*/ - - if (sIN.mode == HiSIM_NORMAL_MODE ){ - Vbdj = Vbde ; - Vbsj = Vbse ; - } else { - Vbdj = Vbse ; - Vbsj = Vbde ; - } - - /* Vbdc = Vbsc - Vdsc ;*/ - - js = sIN.js0 * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) / sIN.nj ) ; - jssw = sIN.js0sw * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) - / sIN.njsw ) ; - - Nvtm = sIN.nj / beta ; - - /* ibd */ - isbd = sIN.ad * js + sIN.pd * jssw ; - - if ( Vbdj < 0.5 ) { - Ibd = isbd * ( exp( Vbdj / Nvtm ) - 1 ) ; - Gbd = isbd / Nvtm * exp( Vbdj / Nvtm ) ; - - } else { - Ibd = isbd * ( exp( 0.5 / Nvtm ) - 1 ) - + isbd / Nvtm * exp( 0.5 / Nvtm ) * ( Vbdj - 0.5 ) ; - Gbd = isbd / Nvtm * exp( 0.5 / Nvtm ) ; - } - - /* ibs */ - isbs = sIN.as * js + sIN.ps * jssw ; - - if ( Vbsj < 0.5 ) { - Ibs = isbs * ( exp( Vbsj / Nvtm ) - 1 ) ; - Gbs = isbs / Nvtm * exp( Vbsj / Nvtm ) ; - - } else { - Ibs = isbs * ( exp( 0.5 / Nvtm ) - 1 ) - + isbs / Nvtm * exp( 0.5 / Nvtm ) * (Vbsj - 0.5 ) ; - Gbs = isbs / Nvtm * exp( 0.5 / Nvtm ) ; - } - - -/*---------------------------------------------------* -* Add Gjmin. -*-----------------*/ - - Ibd += Gjmin * Vbdj ; - Ibs += Gjmin * Vbsj ; - - 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 - */ - - czbd = sIN.cj * sIN.ad ; - czbs = sIN.cj * sIN.as ; - - /* Source Bulk Junction */ - if (sIN.ps > Weff) { - czbssw = sIN.cjsw * ( sIN.ps - Weff ) ; - czbsswg = sIN.cjswg * Weff ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbssw + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbssw > 0.0) - { arg = 1.0 - Vbsj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbs += sIN.pbsw * czbssw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbs += czbssw * sarg ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbssw + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbssw * sIN.mjsw * 0.5 / sIN.pbsw - + czbsswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbssw + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbssw * sIN.mjsw / sIN.pbsw - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbsswg = sIN.cjswg * sIN.ps ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbsswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - /* Drain Bulk Junction */ - if (sIN.pd > Weff) { - czbdsw = sIN.cjsw * ( sIN.pd - Weff ) ; - czbdswg = sIN.cjswg * Weff ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdsw + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdsw > 0.0) - { arg = 1.0 - Vbdj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbd += sIN.pbsw * czbdsw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbd += czbdsw * sarg; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdsw + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdsw * sIN.mjsw * 0.5 / sIN.pbsw - + czbdswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdsw + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdsw * sIN.mjsw / sIN.pbsw - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbdswg = sIN.cjswg * sIN.pd ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - -/*-----------------------------------------------------------* -* End of PART-4. (label) -*-----------------*/ - -/* end_of_part_4: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-5: Noise Calculation. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - if ( sIN.conois != 0 ){ - - NFalp = sIN.nfalp ; - NFtrp = sIN.nftrp ; - Cit = sIN.cit ; - - T1 = Qn0 / C_QE ; - T2 = (Cox+Qn0/(Ps0-Vbs)+Cit)/beta/C_QE ; - T3 = 1.0E0/(T1+T2)+NFalp*Mu ; - Nflic = Ids*Ids*NFtrp/((Leff-Lred)*beta*Weff)*T3*T3 ; - - } else { - Nflic = 0.0 ; - } - - -/*-----------------------------------------------------------* -* End of PART-5. (label) -*-----------------*/ - -/* end_of_part_5: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-6: Evaluation of outputs. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Implicit quantities related to Alpha. -*-----------------*/ - - /* note: T1 = 1 + Delta */ - if ( flg_noqi == 0 && VgVt > VgVt_small && Pds > 0.0 ) { - T1 = Achi / Pds ; - Delta = T1 - 1.0e0 ; - Vdsat = VgVt / T1 ; - } else { - Alpha = 1.0 ; - Delta = 0.0 ; - Vdsat = 0.0 ; - Achi = 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 == 0 || 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 ; - - Igate_dVbse = Igate_dVbs ; - Igate_dVdse = Igate_dVds ; - Igate_dVgse = Igate_dVgs ; - - Igidl_dVbse = Igidl_dVbs ; - Igidl_dVdse = Igidl_dVds ; - Igidl_dVgse = Igidl_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 ; - - -/*---------------------------------------------------* -* Case Rs>0 or Rd>0 -*-----------------*/ - - } else { - - -/*-------------------------------------------* -* 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 ; - - 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 ; - - 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 ; - - -/*---------------------------------------------------* -* 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 ; - - } /* end of if ( flg_rsrd == 0 ) blocks */ - - -/*---------------------------------------------------* -* 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 ; - Igidl_dVbse *= Vbsc_dVbse ; - Qgos_dVbse *= Vbsc_dVbse ; - Qgod_dVbse *= Vbsc_dVbse ; - } - - if ( flg_vxxc != 0 ) { - - if ( flg_vbsc == -1 ) { - T1 = Vbse - Vbsc ; - } else { - T1 = 0.0 ; - } - - - if ( flg_vdsc != 0 ) { - T2 = Vdse - Vdsc ; - } else { - T2 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T3 = Vgse - Vgsc ; - } else { - T3 = 0.0 ; - } - - if ( flg_vbdc != 0 ) { - T4 = Vbde - Vbdc ; - } else { - T4 = 0.0 ; - } - - - TX = Ids + T1 * Ids_dVbse + T2 * Ids_dVdse + T3 * Ids_dVgse ; - if ( TX * Ids >= 0.0 ) { - Ids = TX ; - } else { - T7 = Ids / ( Ids - TX ) ; - Ids_dVbse *= T7 ; - Ids_dVdse *= T7 ; - Ids_dVgse *= T7 ; - Ids = 0.0 ; - } - - TX = Qb + T1 * Qb_dVbse + T2 * Qb_dVdse + T3 * Qb_dVgse ; - /*note: The sign of Qb can be changed.*/ - Qb = TX ; - - TX = Qd + T1 * Qd_dVbse + T2 * Qd_dVdse + T3 * Qd_dVgse ; - if ( TX * Qd >= 0.0 ) { - Qd = TX ; - } else { - T7 = Qd / ( Qd - TX ) ; - Qd_dVbse *= T7 ; - Qd_dVdse *= T7 ; - Qd_dVgse *= T7 ; - Qd = 0.0 ; - } - - TX = Qi + T1 * Qi_dVbse + T2 * Qi_dVdse + T3 * Qi_dVgse ; - if ( TX * Qi >= 0.0 ) { - Qi = TX ; - } else { - T7 = Qi / ( Qi - TX ) ; - Qi_dVbse *= T7 ; - Qi_dVdse *= T7 ; - Qi_dVgse *= T7 ; - Qi = 0.0 ; - } - - TX = Isub + T1 * Isub_dVbse + T2 * Isub_dVdse + T3 * Isub_dVgse ; - if ( TX * Isub >= 0.0 ) { - Isub = TX ; - } else { - T7 = Isub / ( Isub - TX ) ; - Isub_dVbse *= T7 ; - Isub_dVdse *= T7 ; - Isub_dVgse *= T7 ; - Isub = 0.0 ; - } - - TX = Igate + T1 * Igate_dVbse + T2 * Igate_dVdse + T3 * Igate_dVgse ; - if ( TX * Igate >= 0.0 ) { - Igate = TX ; - } else { - T7 = Igate / ( Igate - TX ) ; - Igate_dVbse *= T7 ; - Igate_dVdse *= T7 ; - Igate_dVgse *= T7 ; - Igate = 0.0 ; - } - - TX = Igidl + T1 * Igidl_dVbse + T2 * Igidl_dVdse + T3 * Igidl_dVgse ; - if ( TX * Igidl >= 0.0 ) { - Igidl = TX ; - } else { - T7 = Igidl / ( Igidl - TX ) ; - Igidl_dVbse *= T7 ; - Igidl_dVdse *= T7 ; - Igidl_dVgse *= T7 ; - Igidl = 0.0 ; - } - - TX = Qgod + T1 * Qgod_dVbse + T2 * Qgod_dVdse + T3 * Qgod_dVgse ; - if ( TX * Qgod >= 0.0 ) { - Qgod = TX ; - } else { - T7 = Qgod / ( Qgod - TX ) ; - Qgod_dVbse *= T7 ; - Qgod_dVdse *= T7 ; - Qgod_dVgse *= T7 ; - Qgod = 0.0 ; - } - - TX = Qgos + T1 * Qgos_dVbse + T2 * Qgos_dVdse + T3 * Qgos_dVgse ; - if ( TX * Qgos >= 0.0 ) { - Qgos = TX ; - } else { - T7 = Qgos / ( Qgos - TX ) ; - Qgos_dVbse *= T7 ; - Qgos_dVdse *= T7 ; - Qgos_dVgse *= T7 ; - Qgos = 0.0 ; - } - - } - - -/*-----------------------------------------------------------* -* Warn negative conductance. -* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. -*-----------------*/ - - if ( sIN.mode == HiSIM_NORMAL_MODE ) { - T1 = Ids_dVdse ; - } else { - T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; - } - - if ( Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0 ) { - fprintf( stderr , - "*** warning(HiSIM): Negative Conductance\n" ) ; - fprintf( stderr , - " type = %d mode = %d\n" , sIN.type , sIN.mode ) ; - fprintf( stderr , - " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" , - Vbse , Vdse , Vgse ) ; - if ( flg_info >= 1 ) { - printf( "*** warning(HiSIM): Negative Conductance\n" ) ; - printf( " type = %d mode = %d\n" , sIN.type , sIN.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" , Ids_dVdse ) ; - printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - } - } - - if ( Ids_dVbse < 0.0e0 ) { - fprintf( stderr , " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; - flg_ncnv ++ ; - } - if ( T1 < 0.0e0 ) { - fprintf( stderr , " Ids_dVdse = %12.5e\n" , T1 ) ; - flg_ncnv ++ ; - } - if ( Ids_dVgse < 0.0e0 ) { - fprintf( stderr , " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - flg_ncnv ++ ; - } - - -/*-----------------------------------------------------------* -* Redefine overlap charges/capacitances. -*-----------------*/ - -/*---------------------------------------------------* -* Constant capacitance. -*-----------------*/ - - if ( sIN.cocgbo >= 1 ) { - Cgbo = sIN.cgbo * Lgate ; - } else { - Cgbo = 0.0 ; - } - - if ( sIN.cocgdo >= 1 ) { - Cgdo = - sIN.cgdo * Weff ; - Qgod = - Cgdo * ( Vgse - Vdse ) ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = Cgdo ; - Qgod_dVgse = - Qgod_dVdse ; - } else { - Cgdo = Qgos_dVdse + Qgod_dVdse ; - } - - if ( sIN.cocgso >= 1 ) { - Cgso = - sIN.cgso * Weff ; - Qgos = - Cgso * Vgse ; - Qgos_dVbse = 0.0 ; - Qgos_dVdse = 0.0 ; - Qgos_dVgse = - Cgso ; - } else { - Cgso = - ( Qgos_dVbse + Qgod_dVbse - + Qgos_dVdse + Qgod_dVdse - + Qgos_dVgse + Qgod_dVgse ) ; - } - - Cggo = Qgos_dVgse + Qgod_dVgse ; - - -/*---------------------------------------------------* -* Fringing capacitance. -*-----------------*/ - - Cf = C_EOX / ( C_Pi / 2.0e0 ) * Weff - * log( 1.0e0 + sIN.tpoly / sIN. tox ) ; - - Qfd = Cf * ( Vgse - Vdse ) ; - Qfs = Cf * Vgse ; - - -/*---------------------------------------------------* -* Add fringing charge/capacitance to overlap. -*-----------------*/ - - Qgod += Qfd ; - Qgos += Qfs ; - - Cggo += 2.0 * Cf ; - Cgdo += - Cf ; - Cgso += - Cf ; - - -/*-----------------------------------------------------------* -* Assign outputs. -*-----------------*/ - -/*---------------------------------------------------* -* Channel current and conductances. -*-----------------*/ - - /* pOT->ids = sIN.type * Ids ; */ - pOT->ids = Ids ; - pOT->gmbs = Ids_dVbse ; - pOT->gds = Ids_dVdse ; - pOT->gm = Ids_dVgse ; - - -/*---------------------------------------------------* -* Intrinsic charges/capacitances. -*-----------------*/ - - pOT->qg = - ( Qb + Qi ) ; - pOT->qd = Qd ; - pOT->qs = Qi - Qd ; - - pOT->cbgb = Qb_dVgse ; - pOT->cbdb = Qb_dVdse ; - pOT->cbsb = - ( Qb_dVbse + Qb_dVdse + Qb_dVgse ) ; - - pOT->cggb = - Qb_dVgse - Qi_dVgse ; - pOT->cgdb = - Qb_dVdse - Qi_dVdse ; - pOT->cgsb = Qb_dVbse + Qb_dVdse + Qb_dVgse - + Qi_dVbse + Qi_dVdse + Qi_dVgse ; - - pOT->cdgb = Qd_dVgse ; - pOT->cddb = Qd_dVdse ; - pOT->cdsb = - ( Qd_dVgse + Qd_dVdse + Qd_dVbse ) ; - - -/*---------------------------------------------------* -* Overlap capacitances. -*-----------------*/ - - pOT->cgdo = Cgdo ; - pOT->cgso = Cgso ; - pOT->cgbo = Cgbo ; - - -/*---------------------------------------------------* -* Lateral-field-induced capacitance. -*-----------------*/ - - if ( sIN.xqy == 0 ){ - Qy = 0e0 ; - Cqyd = 0e0 ; - Cqyg = 0e0 ; - Cqyb = 0e0 ; - Cqys = 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 ; - if ( Pslk > Psdl ){ - Pslk = Psdl ; - Pslk_dVbs = Psdl_dVbs ; - Pslk_dVds = Psdl_dVds ; - Pslk_dVgs = Psdl_dVgs ; - } - - T1 = Aclm * ( Vds + Ps0 ) + ( 1.0e0 - Aclm ) * Pslk ; - T1_dVbs = Aclm * ( Ps0_dVbs ) + ( 1.0e0 - Aclm ) * Pslk_dVbs ; - T1_dVds = Aclm * ( 1.0 + Ps0_dVds ) + ( 1.0e0 - Aclm ) * Pslk_dVds ; - T1_dVgs = Aclm * ( Ps0_dVgs ) + ( 1.0e0 - Aclm ) * Pslk_dVgs ; - - T10 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - T3 = T10 * 1.3 ; - T2 = C_ESI * Weff * T3 ; - - Qy = ( ( Ps0 + Vds - T1 ) / sIN.xqy ) * T2 ; - Cqyd = ( ( Ps0_dVds + 1.0e0 - T1_dVds ) / sIN.xqy ) * T2 ; - if ( Cqyd < 0.0e0 ) Cqyd = 0.0 ; - Cqyg = ( ( Ps0_dVgs - T1_dVgs ) / sIN.xqy ) * T2 ; - Cqyb = ( ( Ps0_dVbs - T1_dVbs ) / sIN.xqy ) * T2 ; - Cqys = - ( Cqyb + Cqyd + Cqyg ) ; - } - - -/*---------------------------------------------------* -* Add S/D overlap charges/capacitances to intrinsic ones. -* - NOTE: This function depends on coadov, a control option. -*-----------------*/ - - if ( sIN.coadov == 1 ) { - pOT->qg += Qgod + Qgos + Qy ; - pOT->qd += - Qgod - Qy ; - pOT->qs += - Qgos ; - - pOT->cggb += Cggo + Cqyg ; - pOT->cgdb += Cgdo + (-1) * Cqyd ; - pOT->cgsb += Cgso + (-1) * Cqys ; - - pOT->cdgb += - Qgod_dVgse - Cf + Cqyg ; - pOT->cddb += - Qgod_dVdse + Cf - Cqyd ; - pOT->cdsb += Qgod_dVbse + Qgod_dVdse + Qgod_dVgse + Cqys ; - - pOT->cgdo = 0.0 ; - pOT->cgso = 0.0 ; - - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - } - - -/*---------------------------------------------------* -* Substrate/gate/leak currents. -*-----------------*/ - - pOT->isub = Isub ; - - pOT->gbbs = Isub_dVbse ; - pOT->gbds = Isub_dVdse ; - pOT->gbgs = Isub_dVgse ; - - pOT->igate = Igate ; - - pOT->ggbs = Igate_dVbse ; - pOT->ggds = Igate_dVdse ; - pOT->gggs = Igate_dVgse ; - - pOT->igidl = Igidl ; - - pOT->ggidlbs = Igidl_dVbse ; - pOT->ggidlds = Igidl_dVdse ; - pOT->ggidlgs = Igidl_dVgse ; - - -/*---------------------------------------------------* -* Von, Vdsat. -*-----------------*/ - - /* - pOT->von = sIN.type * Vth ; - pOT->vdsat = sIN.type * Vdsat ; - */ - pOT->von = Vth ; - pOT->vdsat = Vdsat ; - - -/*---------------------------------------------------* -* Parasitic conductances. -*-----------------*/ - -/*:org: -* pOT->gd = 1.0e+50 ; -* pOT->gs = 1.0e+50 ; -* modified according to CMIxxxeval.c. -* I don't know the reason why these can be zero. -*/ - pOT->gd = 0.0e0 ; - pOT->gs = 0.0e0 ; - - -/*---------------------------------------------------* -* Junction diode. -*-----------------*/ - - /* - pOT->ibs = sIN.type * Ibs ; - pOT->ibd = sIN.type * Ibd ; - */ - pOT->ibs = Ibs ; - pOT->ibd = Ibd ; - pOT->gbs = Gbse ; - pOT->gbd = Gbde ; - - pOT->qbs = Qbs ; - pOT->qbd = Qbd ; - pOT->capbs = Capbse ; - pOT->capbd = Capbde ; - - -/*-----------------------------------------------------------* -* Warn floating-point exceptions. -* - Function finite() in libm is called. -* - Go to start with info==5. -*-----------------*/ - - T1 = pOT->ids + pOT->gmbs + pOT->gds + pOT->gm ; - T1 = T1 + pOT->qd + pOT->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( "pOT->ids = %12.5e\n" , pOT->ids ) ; - printf( "pOT->gmbs = %12.5e\n" , pOT->gmbs ) ; - printf( "pOT->gds = %12.5e\n" , pOT->gds ) ; - printf( "pOT->gm = %12.5e\n" , pOT->gm ) ; - printf( "pOT->qd = %12.5e\n" , pOT->qd ) ; - printf( "pOT->cdsb = %12.5e\n" , pOT->cdsb ) ; - } - } - - T1 = pOT->isub + pOT->gbbs + pOT->gbds + pOT->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 = pOT->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 = pOT->ibs + pOT->ibd + pOT->gbs + pOT->gbd ; - T1 = T1 + pOT->qbs + pOT->qbd + pOT->capbs + pOT->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 ) { - return( HiSIM_ERROR ) ; - } - - -/*-----------------------------------------------------------* -* Restore values for next calculation. -*-----------------*/ - - /* Confined biases */ - pOT->vbsc = Vbsc ; - pOT->vdsc = Vdsc ; - pOT->vgsc = Vgsc ; - - /* Surface potentials and derivatives w.r.t. internal biases */ - pOT->ps0 = Ps0 ; - pOT->ps0_dvbs = Ps0_dVbs ; - pOT->ps0_dvds = Ps0_dVds ; - pOT->ps0_dvgs = Ps0_dVgs ; - pOT->pds = Pds ; - pOT->pds_dvbs = Pds_dVbs ; - pOT->pds_dvds = Pds_dVds ; - pOT->pds_dvgs = Pds_dVgs ; - - /* Derivatives of channel current w.r.t. internal biases */ - pOT->ids_dvbs = Ids_dVbs ; - pOT->ids_dvds = Ids_dVds ; - pOT->ids_dvgs = Ids_dVgs ; - - pOT->nf = Nflic ; - pOT->mu = Mu ; - pOT->qg_int = - ( Qb + Qi ) ; - pOT->qd_int = Qd ; - pOT->qs_int = Qi - Qd ; - pOT->qb_int = Qb ; - -/*-----------------------------------------------------------* -* End of PART-6. (label) -*-----------------*/ - -/* end_of_part_6: ; */ - - -/*-----------------------------------------------------------* -* Bottom of hsm1eval. -*-----------------*/ - - - -return ( HiSIM_OK ) ; - -} /* end of hsm1eval112 */ - diff --git a/src/spicelib/devices/hisim/hsm1eval120.c b/src/spicelib/devices/hisim/hsm1eval120.c deleted file mode 100644 index b5f568c5c..000000000 --- a/src/spicelib/devices/hisim/hsm1eval120.c +++ /dev/null @@ -1,5501 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1eval120.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -/********************************************************************* -* Memorandum on programming -* -* (1) Bias (x: b|d|g) -* . sIN.vxs : Input argument. -* . Vxse: External bias taking account device type (pMOS->nMOS). -* . Vxsc: Confined bias within a specified region. -* . Vxs : Internal bias taking account Rs/Rd. -* . 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. -* . Ps0z: Modified Ps0. -* . The following variables are calculated as a function of -* modified biases or potential. -* Tox, Cox, (-- with quantum effect) -* Vth*, dVth*, dPpg, Qnm, Qbm, Igate, Igidl, Igisl. -* . The following variables are calculated using a transform -* function. -* Lred, rp1(<-sIN.rpock1). -* -* (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 and -D1. -* . 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 "ngspice.h" - -/*-----------------------------------* -* HiSIM macros and structures. -* - All inputs and outputs are defined here. -*-----------------*/ -#include "hisim.h" -#include "hsm1evalenv.h" - - -/*-----------------------------------* - * Constants for Smoothing functions - *---------------*/ -static const double Vgsz_pol_sat = 2.0 ; -static const double Vdsz_pol_sat = 3.5 ; -static const double Vgsz_qme_sat = 2.0 ; -static const double Vdsz_lp_sat = 3.5 ; -static const double Vdsz_sc_sat = 3.5 ; -static const double pol_vgs_dlt = 2.0e-2 ; -static const double pol_vds_dlt = 2.0e-2 ; -static const double qme_vgs_dlt = 9.5e-3 ; -static const double lp_vds_dlt = 2.0e-2 ; -static const double sc_vds_dlt = 2.0e-2 ; - - -/*===========================================================* -* Function hsm1eval. -*=================*/ - -int HSM1evaluate120 -( - HiSIM_input sIN, - HiSIM_output *pOT, - HiSIM_messenger *pMS -) -{ - -/*---------------------------------------------------* -* Local variables. -*-----------------*/ -/* Constans ----------------------- */ -int lp_s0_max = 20 ; -int lp_sl_max = 20 ; -int lp_bs_max = 10 ; -double Ids_tol = 1.0e-10 ; -double Ids_maxvar = 1.0e-1 ; -double dP_max = 0.1e0 ; -double ps_conv = 5.0e-13 ; -double gs_conv = 1.0e-8 ; -/** depletion **/ -double znbd3 = 3.0e0 ; -double znbd5 = 5.0e0 ; -double cn_nc3 = C_SQRT_2 / 108e0 ; -/* 5-degree, contact:Chi=5 */ -double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ -double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ -double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ -double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ -double cn_nc55 = 6.36964918866352e-5 ; /* (1509-1040*sqrt(2))/600000 */ -/** inversion **/ -/* 3-degree polynomial approx for ( exp[Chi]-1 )^{1/2} */ -double cn_im53 = 2.9693154855770998e-1 ; -double cn_im54 = -7.0536542840097616e-2 ; -double cn_im55 = 6.1152888951331797e-3 ; -/** initial guess **/ -double c_ps0ini_2 = 8.0e-4 ; -double c_pslini_1 = 0.3e0 ; -double c_pslini_2 = 3.0e-2 ; -double VgVt_small = 1.0e-12 ; -double Vbs_max = 0.8e0 ; -double Vbs_min = -10.5e0 ; -double Vds_max = 10.5e0 ; -double Vgs_max = 10.5e0 ; -double Vbd_max = 0.8e0 ; -double Vbd_min = -10.5e0 ; -double Vgd_max = 10.5e0 ; -double epsm10 = 10.0e0 * C_EPS_M ; -double small = 1.0e-50 ; -double Gdsmin = 0.0 ; -double Gjmin = sIN.gmin ; -double cclmmdf = 1.0e-1 ; -double qme_dlt = 1.0e-9 ; -double eef_dlt = 1.0e-2 ; -double sti1_dlt = -3.0e-3 ; -double sti2_dlt = 2.0e-3 ; -double pol2_dlt = 1.0e-5 ; -double pol_tmp = 1.0 ; - -/* Internal flags --------------------*/ -int flg_err = 0 ; /* error level */ -int flg_ncnv = 0 ; /* Flag for negative conductance */ -int flg_rsrd ; /* Flag for bias loop accounting Rs and Rd */ -int flg_iprv ; /* Flag for initial guess of Ids */ -int flg_pprv ; /* Flag for initial guesses of Ps0 and Pds */ -int flg_noqi = 0; /* Flag for the cases regarding Qi=Qd=0 */ -int flg_vbsc = 0 ; /* Flag for Vbs confining */ -int flg_vdsc = 0 ; /* Flag for Vds confining */ -int flg_vgsc = 0 ; /* Flag for Vgs confining */ -int flg_vbdc = 0 ; /* Flag for Vbd confining */ -int flg_vsdc = 0 ; /* Flag for Vsd confining */ -int flg_vgdc = 0 ; /* Flag for Vgd confining */ -int flg_vxxc = 0 ; /* Flag whether some bias was confined */ -int flg_info = 0 ; -int flg_clamp = 0 ; /* Flag for clamping biases */ - -/* flags for smoothing (take account of smoothing or not) ----------*/ -int flg_smoothing_qme_vg = 1 ; /* Flag for smoothing vgs for QM */ -int flg_smoothing_pl_vd = 1 ; /* Flag for smoothing vds for LP */ -int flg_smoothing_sc_vd = 1 ; /* Flag for smoothing vds for SC */ -int flg_smoothing_pde_vg = 1 ; /* Flag for smoothing vgs for PDE */ -int flg_smoothing_pde_vd = 1 ; /* Flag for smoothing vds for PDE */ - -/* flag for D reference calc (GISL(normal), GIDL(reverse)) */ -int flg_gidsl_d = 0 ; - -/* Important Variables in HiSIM -------*/ -/* external bias */ -double Vbse , Vdse , Vgse ; -double Vbde , Vsde = 0.0 , Vgde = 0.0 ; -/* confine bias */ -double Vbsc = 0.0 , Vdsc , Vgsc ; -double Vbdc = 0.0 , Vsdc = 0.0 , Vgdc = 0.0; -double Vbsc_dVbse = 1.0 ; -double Vbdc_dVbde = 1.0 ; -/* internal bias */ -double Vbs , Vds , Vgs ; -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 = 0.0 ; -double Vgp_dVbs = 0.0 , Vgp_dVds = 0.0 , Vgp_dVgs = 0.0 ; -double Vgs_fb ; -double Vbd , Vsd , Vgd ; -double Vbd_dVbde = 1.0 , Vbd_dVsde = 0.0 , Vbd_dVgde = 0.0 ; -double Vsd_dVbde = 0.0 , Vsd_dVsde = 1.0 , Vsd_dVgde = 0.0 ; -double Vgd_dVbde = 0.0 , Vgd_dVsde = 0.0 , Vgd_dVgde = 1.0 ; -/* Ps0 : surface potential at the source side */ -double Ps0 = 0.0 ; -double Ps0_dVbs = 0.0 , Ps0_dVds = 0.0 , Ps0_dVgs = 0.0 ; -double Ps0_ini = 0.0 , Ps0_iniA , Ps0_iniB ; -/* Psl : surface potential at the drain side */ -double Psl = 0.0 ; -double Psl_dVbs = 0.0 , Psl_dVds = 0.0 , Psl_dVgs = 0.0 ; -double Psl_lim ; -/* Pds := Psl - Ps0 */ -double Pds = 0.0 ; -double Pds_dVbs = 0.0 , Pds_dVds = 0.0 , Pds_dVgs = 0.0 ; -double Pds_ini = 0.0 ; -double Pds_max ; -/* iteration numbers of Ps0 and Psl equations. */ -int lp_s0 , lp_sl ; -/* 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 ; -double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; -/* Xil := beta * ( Psl - Vbs ) - 1. */ -double Xilp12 ; -double Xilp32 ; -double Xil ; -/* modified bias and potential for sym.*/ -double Vbsz , Vdsz = 0.0 , Vgsz = 0.0 ; -double Vbsz_dVbs , Vbsz_dVds ; -double Vdsz_dVds = 0.0 ; -double Vgsz_dVgs = 0.0 ; -double Vbs1 , Vbs2 , Vbsd ; -double Vbsd_dVbs , Vbsd_dVds ; -double Vgsz_dVds = 0.0; -double Vzadd = 0.0 , Vzadd_dVds = 0.0 , Vzadd_dVsd ; -double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; -double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; -double Ps0Vbsz , Ps0Vbsz_dVbs , Ps0Vbsz_dVds , Ps0Vbsz_dVgs ; -double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; -double Xi0z ; -double Xi0z_dVbs , Xi0z_dVds , Xi0z_dVgs ; -double Xi0zp12 ; -double Xi0zp12_dVbs , Xi0zp12_dVds , Xi0zp12_dVgs ; -double Vbdz , Vsdz , Vgdz ; -double Vbdz_dVbd , Vbdz_dVsd , Vbdz_dVgd ; -double Vsdz_dVsd ; -double Vsdz_dVgd = 0.0 ; -double Vsdz_dVbd = 0.0 ; -double Vgdz_dVgd , Vgdz_dVsd ; -double Vgdz_dVbd = 0.0 ; -double Vbdzm ; -double Vbdzm_dVb , Vbdzm_dVs ; -double Vbd1 , Vbd2 , Vbdd ; -double Vbdd_dVbd , Vbdd_dVsd ; -/* 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 = 0.0 ; -double Vth_dVb , Vth_dVd , Vth_dVg ; -double Vth0 ; -double Vth0_dVb , Vth0_dVd , Vth0_dVs , Vth0_dVg ; -/* variation of threshold voltage */ -double dVth = 0.0 ; -double dVth_dVb = 0.0 , dVth_dVd = 0.0 , dVth_dVg = 0.0 ; -double dVth0 ; -double dVth0_dVb , dVth0_dVd , dVth0_dVs , dVth0_dVg ; -double dVthSC ; -double dVthSC_dVb , dVthSC_dVd , dVthSC_dVs , dVthSC_dVg ; -double delta0 = 1.0e-5 ; -double Vgpa , Psi_a , Pb20a , Pb20b , cnst3 = 0.0 ; -double Psi_a_dVg, Pb20a_dVg, Pb20b_dVg ; -double dVthW ; -double dVthW_dVb , dVthW_dVd , dVthW_dVs , dVthW_dVg ; -double dVthP ; -double dVthP_dVb , dVthP_dVs , dVthP_dVg ; -/* Alpha and related parameters */ -double Alpha ; -double Alpha_dVbs , Alpha_dVds , Alpha_dVgs ; -double Achi = 0.0 ; -double Achi_dVbs , Achi_dVds , Achi_dVgs ; -double VgVt = 0.0 ; -double VgVt_dVbs , VgVt_dVds , VgVt_dVgs ; -double Delta , Vdsat ; -/* Q_B and capacitances */ -double Qb = 0.0 , Qb_dVbs = 0.0 , Qb_dVds = 0.0 , Qb_dVgs = 0.0 ; -double Qb_dVbse , Qb_dVdse , Qb_dVgse ; -/* Q_I and capacitances */ -double Qi = 0.0 , Qi_dVbs = 0.0 , Qi_dVds = 0.0 , Qi_dVgs = 0.0 ; -double Qi_dVbse , Qi_dVdse , Qi_dVgse ; -/* Q_D and capacitances */ -double Qd = 0.0 , Qd_dVbs = 0.0 , Qd_dVds = 0.0 , Qd_dVgs = 0.0 ; -double Qd_dVbse , Qd_dVdse , Qd_dVgse ; -/* channel current */ -double Ids ; -double Ids_dVbs = 0.0 , Ids_dVds = 0.0 , Ids_dVgs = 0.0 ; -double Ids_dVbse , Ids_dVdse , Ids_dVgse ; -double Ids0 ; -double Ids0_dVbs , Ids0_dVds , Ids0_dVgs ; -double Isd_dVbde , Isd_dVsde , Isd_dVgde ; -/* STI */ -double Vgssti ; -double Vgssti_dVbs , Vgssti_dVds , Vgssti_dVgs ; -double costi0 , costi1 , costi3 ; -double costi4 , costi5 , costi6 , costi7 ; -double Psasti ; -double Psasti_dVbs , Psasti_dVds , Psasti_dVgs ; -double Asti ; -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 expsti ; -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 ; -double beta2 ; -double Leff , Leff_inv ; -double Weff ; -double Ldby ; -double Nsub , q_Nsub ; -double Nin ; -double Pb2 ; -double Pb20 ; -double Pb2c ; -double Eg , Eg300 ; -double Vfb ; -/* PART-1 */ -double Psum ; -double Psum_dVb ; -double Psum_dVd ; -double Psum_dVs ; -double sqrt_Psum ; -double cnst0 , cnst1 ; -double fac1 ; -double fac1_dVbs , fac1_dVds , fac1_dVgs ; -double fac1p2 ; -double fs01 ; -double fs01_dPs0 , fs01_dChi ; -double fs01_dVbs , fs01_dVds , fs01_dVgs ; -double fs02 ; -double fs02_dPs0 , fs02_dChi ; -double fs02_dVbs , fs02_dVds , fs02_dVgs ; -double fsl1 ; -double fsl1_dPsl ; -double fsl1_dVbs , fsl1_dVds ; -double fsl2 ; -double fsl2_dPsl ; -double fsl2_dVbs , fsl2_dVds ; -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_dVs ,Qb0_dVg = 0.0 ; -double Qn00 = 0.0 ; -double Qn00_dVbs = 0.0 , Qn00_dVds = 0.0 , Qn00_dVgs = 0.0 ; -double Qbnm ; -double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; -double DtPds ; -double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; -double Qbm ; -double Qbm_dVbs , Qbm_dVds , Qbm_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 ; -double Qdrat_dVbs , Qdrat_dVds , Qdrat_dVgs ; -double Idd ; -double Idd_dVbs , Idd_dVds , Idd_dVgs ; -double Qnm ; -double Qnm_dVbs , Qnm_dVds , Qnm_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 = 0.0 ; -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 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 Vdep ; -double Vdep_dVbs , Vdep_dVds , Vdep_dVgs ; -double Epkf ; -double Epkf_dVbs , Epkf_dVds , Epkf_dVgs ; -/* PART-3 (overlap) */ -double yn , yn2 , yn3 ; -double yn_dVbs , yn_dVds , yn_dVgs ; -double Lov , Lov2 ; -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 ; -double Cggo , Cgdo , Cgso , Cgbo ; -/* fringing capacitance */ -double Cf ; -double Qfd , Qfs ; -/* Cqy */ -double Pslk , Pslk_dVbs , Pslk_dVds , Pslk_dVgs ; -double Qy ; -double Cqyd, Cqyg, Cqys, Cqyb ; -/* PART-4 (junction diode) */ -double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; -double js ; -double jssw ; -double isbs ; -double isbd ; -double Nvtm ; -/* junction capacitance */ -double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; -double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; -double arg , sarg ; -/* PART-5 (noise) */ -double NFalp , NFtrp , Cit , Nflic ; -/* Bias iteration accounting Rs/Rd */ -int lp_bs ; -double Ids_last ; -double vtol_iprv = 2.0e-1 ; -double vtol_pprv = 5.0e-2 ; -double Vbsc_dif = 0.0 , Vdsc_dif = 0.0 , Vgsc_dif = 0.0 , sum_vdif ; -double Rs , Rd ; -double Fbs , Fds , Fgs ; -double DJ , DJI = 0.0 , DJIP ; -double JI11 , JI12 , JI13 , JI21 , JI22 , JI23 , JI31 , JI32 , JI33 ; -double dVbs = 0.0 , dVds = 0.0 , dVgs = 0.0 ; -double dV_sum ; -/* Junction Bias */ -double Vbsj , Vbdj ; -/* Accumulation zone */ -double Psa ; -double Psa_dVbs , Psa_dVds , Psa_dVgs ; -/* CLM */ -double Psdl = 0.0 , Psdl_dVbs = 0.0 , Psdl_dVds = 0.0 , Psdl_dVgs = 0.0 ; -double Ed , Ed_dVbs , Ed_dVds , Ed_dVgs ; -double Ec = 0.0 , Ec_dVbs = 0.0 , Ec_dVds = 0.0 , Ec_dVgs = 0.0 ; -double Lred = 0.0 , Lred_dVbs , Lred_dVds , Lred_dVgs ; -double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; -double Aclm = 0.0 ; -/* Pocket Implant */ -double Vthp, Vthp_dVb, Vthp_dVd, Vthp_dVs, Vthp_dVg ; -double dVthLP, dVthLP_dVb, dVthLP_dVd, dVthLP_dVs, dVthLP_dVg ; -/* Poly-Depletion Effect */ -double dPpg = 0.0 , dPpg_dVd = 0.0 , dPpg_dVg = 0.0 , dPpg_dVb = 0.0 ; -double dPpgP , dPpgP_dVs , dPpgP_dVg , dPpgP_dVb ; -/* Quantum Effect */ -double Tox = 0.0 , Tox_dVb = 0.0 , Tox_dVd = 0.0 , Tox_dVg = 0.0 ; -double dTox , dTox_dVb , dTox_dVd , dTox_dVs , dTox_dVg ; -double Cox = 0.0 , Cox_dVb , Cox_dVd , Cox_dVg ; -double Cox_inv , Cox_inv_dVb , Cox_inv_dVd , Cox_inv_dVg ; -double Vthq, Vthq_dVb , Vthq_dVd , Vthq_dVs ; -double ToxP , ToxP_dVb , ToxP_dVs , ToxP_dVg ; -double CoxP , CoxP_dVb , CoxP_dVs , CoxP_dVg ; -double CoxP_inv , CoxP_inv_dVb , CoxP_inv_dVs , CoxP_inv_dVg ; -/* Igate , Igidl , Igisl */ -double Egp12 , Egp32 ; -double E0 ; -double E1 , E1_dVb , E1_dVd , E1_dVs , E1_dVg ; -double E2 , E2_dVbs , E2_dVds , E2_dVgs ; -double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; -double Egidl , Egidl_dVb , Egidl_dVd , Egidl_dVg ; -double Egisl , Egisl_dVb , Egisl_dVs , Egisl_dVg ; -double Igate , Igate_dVbs , Igate_dVds , Igate_dVgs ; -double Igate_dVbse , Igate_dVdse , Igate_dVgse ; -double Igidl , Igidl_dVbs , Igidl_dVds , Igidl_dVgs ; -double Igidl_dVbse , Igidl_dVdse , Igidl_dVgse ; -double Igisl , Igisl_dVbd , Igisl_dVsd , Igisl_dVgd ; -double Igisl_dVbde , Igisl_dVsde , Igisl_dVgde ; -double Cox0 ; -double Lgate ; -double rp1 , rp1_dVds ; -/* connecting function */ -double FD2 = 0.0 , FD2_dVbs = 0.0 , FD2_dVds = 0.0 , FD2_dVgs = 0.0 ; -double FMD , FMD_dVds ; -/* Phonon scattering */ -double Wgate ; -double mueph ; -/* temporary vars. */ -double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T13 ; -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_dVs ; -double T5_dVd , T5_dVs , T5_dVg ; -double T7_dVb , T7_dVd , T7_dVs , T7_dVg ; -double T8_dVb , T8_dVd , T8_dVs , T8_dVg ; -double T9_dVd , T9_dVs , T9_dVg ; -double T10_dVd , T10_dVs , T10_dVg ; -double T11_dVd , T11_dVs , T11_dVg ; -double T13_dVd , T13_dVs , T13_dVg ; -double T20 , T21 , T30 , T31 ; - -double c_eox ; - - NG_IGNORE(pMS); - -/*================ Start of executable code.=================*/ - - flg_info = sIN.info ; - - flg_gidsl_d = ((sIN.mode == HiSIM_NORMAL_MODE && sIN.cogisl) || - (sIN.mode == HiSIM_REVERSE_MODE && sIN.cogidl)) ? 1 : 0 ; - - -/*-----------------------------------------------------------* -* Change units into CGS. -* - This section may be moved to an interface routine. -*-----------------*/ - -/* device instances */ - sIN.xl *= C_m2cm ; - sIN.xw *= C_m2cm ; - sIN.as *= C_m2cm_p2 ; - sIN.ad *= C_m2cm_p2 ; - sIN.ps *= C_m2cm ; - sIN.pd *= C_m2cm ; - -/* model parameters */ - sIN.tox *= C_m2cm ; - sIN.xld *= C_m2cm ; - sIN.xwd *= C_m2cm ; - sIN.xqy *= C_m2cm ; - sIN.lp *= C_m2cm ; - sIN.xpolyd *= C_m2cm ; - sIN.tpoly *= C_m2cm ; - sIN.rs *= C_m2cm ; - sIN.rd *= C_m2cm ; - sIN.sc3 *= C_m2cm ; - sIN.scp3 *= C_m2cm ; - sIN.parl2 *= C_m2cm ; - sIN.wfc *= C_m2cm ; - sIN.wsti *= C_m2cm ; - sIN.rpock1 *= C_m2cm_p1o2 ; - sIN.qme1 *= C_m2cm ; - sIN.qme3 *= C_m2cm ; - sIN.gidl1 *= C_m2cm_p1o2 ; - sIN.cgso /= C_m2cm ; - sIN.cgdo /= C_m2cm ; - sIN.cgbo /= C_m2cm ; - sIN.js0 /= C_m2cm_p2 ; - sIN.js0sw /= C_m2cm ; - sIN.cj /= C_m2cm_p2 ; - sIN.cjsw /= C_m2cm ; - sIN.cjswg /= C_m2cm ; - sIN.xdiffd *= C_m2cm ; - - -/*-----------------------------------------------------------* -* Start of the routine. (label) -*-----------------*/ -/* start_of_routine: */ - - - -/*-----------------------------------------------------------* -* Temperature dependent constants. -*-----------------*/ - -/* Inverse of the thermal voltage */ - beta = C_QE / ( C_KB * sIN.temp ) ; - beta2 = beta * beta ; - -/* Band gap */ - Eg = C_Eg0 - sIN.temp - * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; - - Eg300 = C_Eg0 - C_T300 - * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ; - -/* Intrinsic carrier concentration */ - Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) - * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ; - - -/*-----------------------------------------------------------* -* Fixed part. -*-----------------*/ - -/* Lgate in [cm] / [m] */ - Lgate = sIN.xl + 2.0e0 * sIN.xpolyd ; - Wgate = sIN.xw + 2.0e0 * sIN.xdiffd ; - -/* Phonon Scattering */ - T1 = log( Wgate ) ; - T2 = sIN.w0 - T1 - sti1_dlt ; - T3 = T2 * T2 ; - T4 = sqrt( T3 + 4.0 * sti1_dlt * sIN.w0 ) ; - T5 = sIN.w0 - ( T2 - T4 ) / 2 ; - mueph = sIN.mueph1 + sIN.mueph2 * T5 ; - -/* Metallurgical channel geometry */ - Weff = Wgate - 2.0e0 * sIN.xwd ; - Leff = Lgate - 2.0e0 * sIN.xld ; - Leff_inv = 1.0e0 / Leff ; - -/* Flat band voltage */ - Vfb = sIN.vfbc ; - -/* Surface impurity profile */ - if( Leff > sIN.lp ){ - Nsub = ( sIN.nsubc * ( Leff - sIN.lp ) - + sIN.nsubp * sIN.lp ) / Leff ; - } else { - Nsub = sIN.nsubp - + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Leff ) / sIN.lp ; - } - - q_Nsub = C_QE * Nsub ; - -/* 2 phi_B */ - /* @temp, with pocket */ - Pb2 = 2.0e0 / beta * log( Nsub / Nin ) ; - /* @300K, with pocket */ - Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; - /* @300K, w/o pocket */ - Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ; - -/* Debye length */ - Ldby = sqrt( C_ESI / beta / q_Nsub ) ; - -/* Coefficient of the F function for bulk charge */ - cnst0 = q_Nsub * Ldby * C_SQRT_2 ; - -/* cnst1: n_{p0} / p_{p0} */ - T1 = Nin / Nsub ; - cnst1 = T1 * T1 ; - -/* C_EOX */ - c_eox = C_VAC * sIN.kappa ; - -/* Cox (classical) */ - Cox0 = c_eox / sIN.tox ; - - -/*-----------------------------------------------------------* -* Exchange bias conditions according to MOS type. -* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 -* are assumed.) -*-----------------*/ - - Vbse = sIN.vbs ; - Vdse = sIN.vds ; - Vgse = sIN.vgs ; - Vbde = Vbse - Vdse ; - if ( flg_gidsl_d ) { - Vgde = Vgse - Vdse ; - Vsde = -Vdse ; - } - - -/*---------------------------------------------------* -* Clamp too large biases. -* -note: Quantities are extrapolated in PART-5. -*-----------------*/ - - if ( Vbse > 0.0 ) { - flg_vbsc = 1 ; - T1 = Vbse / Vbs_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbsc = Vbse / T2 ; - Vbsc_dVbse = Vbs_max * Vbs_max - / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; - } else if ( Vbse < Vbs_min ) { - flg_vbsc = -1 ; - Vbsc = Vbs_min ; - } else if ( Vbse >= Vbs_min && Vbse <= 0.0 ) { - flg_vbsc = 0 ; - Vbsc = Vbse ; - } - - if ( Vbde > 0.0 ) { - flg_vbdc = 1 ; - T1 = Vbde / Vbd_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbdc = Vbde / T2 ; - Vbdc_dVbde = Vbd_max * Vbd_max - / ( ( Vbd_max * Vbd_max + Vbde * Vbde ) * T2 ) ; - } else if ( Vbde < Vbd_min ) { - flg_vbdc = -1 ; - Vbdc = Vbd_min ; - } else if ( Vbde >= Vbd_min && Vbde <= 0.0 ) { - flg_vbdc = 0 ; - Vbdc = Vbde ; - } - - if (flg_clamp) { - - if ( Vdse > Vds_max ) { - flg_vdsc = 1 ; - Vdsc = Vds_max ; - } else { - flg_vdsc = 0 ; - Vdsc = Vdse ; - } - - if ( Vgse > Vgs_max ) { - flg_vgsc = 1 ; - Vgsc = Vgs_max ; - } else { - flg_vgsc = 0 ; - Vgsc = Vgse ; - } - if ( flg_gidsl_d ) { - - if ( Vsde < -Vds_max ) { - flg_vsdc = 1 ; - Vsdc = -Vds_max ; - } else { - flg_vsdc = 0 ; - Vsdc = Vsde ; - } - - if ( Vgde > Vgd_max ) { - flg_vgdc = 1 ; - Vgdc = Vgd_max ; - } else { - flg_vgdc = 0 ; - Vgdc = Vgde ; - } - - } - - } - else { - - flg_vdsc = 0 ; Vdsc = Vdse ; - flg_vgsc = 0 ; Vgsc = Vgse ; - flg_vsdc = 0 ; Vsdc = Vsde ; - flg_vgdc = 0 ; Vgdc = Vgde ; - } - - if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || - flg_vbdc == -1 || flg_vsdc != 0 || flg_vgdc != 0 ) { - flg_vxxc = 1 ; - } - - -/*-------------------------------------------------------------------* -* Set flags. -*-----------------*/ - - flg_rsrd = 0 ; - flg_iprv = 0 ; - flg_pprv = 0 ; - - if (sIN.mode == HiSIM_NORMAL_MODE) { - Rs = sIN.rs / Weff ; - Rd = sIN.rd / Weff ; - } - else { - Rd = sIN.rs / Weff ; - Rs = sIN.rd / Weff ; - } - - if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { - flg_rsrd = 1 ; - } - - if ( sIN.has_prv == 1 ) { - - Vbsc_dif = Vbsc - sIN.vbsc_prv ; - Vdsc_dif = Vdsc - sIN.vdsc_prv ; - Vgsc_dif = Vgsc - sIN.vgsc_prv ; - - sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) - + fabs( Vgsc_dif ) ; - - if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} - if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} - } - - if ( flg_rsrd == 0 ) { - lp_bs_max = 1 ; - flg_iprv = 0 ; - } - - if ( sIN.cosmbi == 0 ) { - flg_smoothing_qme_vg = 0 ; - flg_smoothing_pl_vd = 0 ; - flg_smoothing_sc_vd = 0 ; - flg_smoothing_pde_vg = 0 ; - flg_smoothing_pde_vd = 0 ; - } - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* -* Bias loop: iteration to solve the system of equations of -* the small circuit taking account Rs and Rd. -* - Vxs are internal (or effective) biases. -* - Equations: -* Vbs = Vbsc - Rs * Ids -* Vds = Vdsc - ( Rs + Rd ) * Ids -* Vgs = Vgsc - Rs * Ids -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initial guesses for biases. -*-----------------*/ - - if ( flg_iprv == 1 ) { - - sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; - sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; - sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; - - dVbs = Vbsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; - dVds = Vdsc_dif * ( 1.0 - - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; - dVgs = Vgsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; - - /* - Ids = sIN.type * sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - */ - Ids = sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - - T1 = ( Ids - sIN.ids_prv ) ; - T2 = fabs( T1 ) ; - if ( Ids_maxvar * sIN.ids_prv < T2 ) { - Ids = sIN.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 ; - } - } - - Vbs = Vbsc - Ids * Rs ; - - Vds = Vdsc - Ids * ( Rs + Rd ) ; - if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } - - Vgs = Vgsc - Ids * Rs ; - - if ( flg_pprv == 1 ) { - - Ps0 = sIN.ps0_prv ; - - Ps0_dVbs = sIN.ps0_dvbs_prv ; - Ps0_dVds = sIN.ps0_dvds_prv ; - Ps0_dVgs = sIN.ps0_dvgs_prv ; - - Pds = sIN.pds_prv ; - - Pds_dVbs = sIN.pds_dvbs_prv ; - Pds_dVds = sIN.pds_dvds_prv ; - Pds_dVgs = sIN.pds_dvgs_prv ; - } - - -/*-----------------------------------------------------------* -* start of the loop. -*-----------------*/ - - for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { - - - Ids_last = Ids ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-1: Basic device characteristics. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initialization. -*-----------------*/ - - /* Initialization of counters is needed for restart. */ - lp_s0 = 0 ; - lp_sl = 0 ; - - -/*-----------------------------------------------------------* -* Vxsz: Modified bias introduced to realize symmetry at Vds=0. -*-----------------*/ - - T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVds = 0.0 ; - } - - Vbsz = Vbs + Vzadd ; - Vbsz_dVbs = 1.0 ; - Vbsz_dVds = Vzadd_dVds ; - - Vdsz = Vds + 2 * Vzadd ; - Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; - - Vgsz = Vgs + Vzadd ; - Vgsz_dVgs = 1.0 ; - Vgsz_dVds = Vzadd_dVds ; - - -/*-----------------------------------------------------------* -* Quantum effect -*-----------------*/ - - T9 = sIN.qme1 ; - T11 = sIN.qme3 ; - T10 = sIN.qme2 ; - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / c_eox * T2 + T10 ; - - T3 = - 0.5 * sIN.tox / c_eox * T1 / T2 ; - Vthq_dVb = T3 * Vbsz_dVbs ; - Vthq_dVd = T3 * Vbsz_dVds ; - - if (flg_smoothing_qme_vg) { - T5 = Vgsz_qme_sat - Vgsz - qme_vgs_dlt ; - T5_dVd = - Vgsz_dVds ; - T5_dVg = - Vgsz_dVgs ; - T6 = sqrt( T5 * T5 + 4.0 * qme_vgs_dlt * Vgsz_qme_sat) ; - T13 = Vgsz_qme_sat - 0.5 * (T5 + T6) ; - T13_dVd = -0.5 * ( T5_dVd + T5 * T5_dVd / T6 ) ; - T13_dVg = -0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; - } - else { - T13 = Vgsz ; - T13_dVd = Vgsz_dVds ; - T13_dVg = Vgsz_dVgs ; - } - - T1 = - T10 ; - T2 = T13 - Vthq ; - T3 = T9 * T1 * T1 + T11 ; - T4 = T9 * T2 * T2 + T11 ; - T5 = T4 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T5 + 2.0 * qme_dlt ) / T6 ) ; - T8 = 2.0 * T9 * T2 * T7 ; - - dTox_dVb = T8 * ( - Vthq_dVb ) ; - dTox_dVd = T8 * ( T13_dVd - Vthq_dVd ) ; - dTox_dVg = T8 * ( T13_dVg ) ; - - if ( T13 - Vthq > 0 ) { - T5 = T11 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T11 ) ; - - dTox = T11 - 0.5 * ( T5 + T6 ) ; - dTox_dVb = 0.0 ; - dTox_dVd = 0.0 ; - dTox_dVg = 0.0 ; - } - - Tox = sIN.tox + 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 ; - - -/*-----------------------------------------------------------* -* Threshold voltage. -*-----------------*/ - - Delta = 0.1 ; - - Vbs1 = 2.0 - 0.25 * Vbsz ; - Vbs2 = - Vbsz ; - - Vbsd = Vbs1 - Vbs2 - Delta ; - Vbsd_dVbs = 0.75 * Vbsz_dVbs ; - Vbsd_dVds = 0.75 * Vbsz_dVds ; - - T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; - - Psum = ( Pb20 - Vbsz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVb = - Vbsz_dVbs ; - Psum_dVd = - Vbsz_dVds ; - } else { - Psum = epsm10 ; - Psum_dVb = 0.0e0 ; - Psum_dVd = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - - -/*---------------------------------------------------* -* Vthp : Vth with pocket. -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Qb0_dVb = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; - Qb0_dVd = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; - - Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; - - Vthp_dVb = Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ; - Vthp_dVd = Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ; - Vthp_dVg = Qb0 * Cox_inv_dVg ; - - -/*-------------------------------------------* -* dVthLP : Short-channel effect induced by pocket. -* - Vth0 : Vth without pocket. -*-----------------*/ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbsz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * Cox_inv ; - - Vth0_dVb = 0.5 * T1 / T2 * ( - Vbsz_dVbs ) * Cox_inv - + T2 * Cox_inv_dVb ; - Vth0_dVd = 0.5 * T1 / T2 * ( - Vbsz_dVds ) * Cox_inv - + T2 * Cox_inv_dVd ; - Vth0_dVg = T2 * Cox_inv_dVg ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / sIN.parl1 / ( sIN.lp * sIN.lp ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVb = T6 * Psum_dVb + T7 * Cox_inv_dVb ; - dVth0_dVd = T6 * Psum_dVd + T7 * Cox_inv_dVd ; - dVth0_dVg = T7 * Cox_inv_dVg ; - - T4 = sIN.scp1 ; - T5 = sIN.scp2 ; - T6 = sIN.scp3 ; - - if (flg_smoothing_pl_vd) { - T8 = Vdsz_lp_sat - Vdsz - lp_vds_dlt ; - T8_dVd = - Vdsz_dVds ; - T9 = sqrt( T8 * T8 + 4.0 * lp_vds_dlt * Vdsz_lp_sat) ; - T7 = Vdsz_lp_sat - 0.5 * (T8 + T9) ; - T7_dVd = -0.5 * ( T8_dVd + T8 * T8_dVd / T9 ) ; - } - else { - T7 = Vdsz ; - T7_dVd = Vdsz_dVds ; - } - - T1 = Vthp - Vth0 ; - T2 = T4 + T6 * Psum / sIN.lp ; - T3 = T2 + T5 * T7 ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVb = ( Vthp_dVb - Vth0_dVb ) * dVth0 * T3 - + T1 * dVth0_dVb * T3 - + T1 * dVth0 * T6 * Psum_dVb / sIN.lp ; - - dVthLP_dVd = ( Vthp_dVd - Vth0_dVd ) * dVth0 * T3 - + T1 * dVth0_dVd * T3 - + T1 * dVth0 - * ( T6 * Psum_dVd / sIN.lp - + T5 * T7_dVd ) ; - - dVthLP_dVg = ( Vthp_dVg - Vth0_dVg ) * dVth0 * T3 - + T1 * dVth0_dVg * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVb = 0.0e0 ; - dVthLP_dVd = 0.0e0 ; - dVthLP_dVg = 0.0e0 ; - } - - -/*---------------------------------------------------* -* dVthSC : Short-channel effect induced by Vds. -*-----------------*/ - - /* Modify Pb20 to Pb20b */ - - Vgpa = Vgsz - Vfb ; - cnst3 = ( cnst0 * cnst0 ) / ( Cox * Cox ) ; - T1 = 1.0e0 + 4.0e0 * (beta * Vgpa - 1.0e0 ) / ( cnst3 * beta * beta ) ; - if ( T1 > 0.0 ) { - T2 = sqrt(T1) ; - Psi_a = Vgpa + cnst3 * beta / 2.0e0 * ( 1.0e0 - T2 ) ; - Psi_a_dVg = Vgsz_dVgs * ( 1.0e0 - 1.0e0 / T2 ) ; - } else { - Psi_a = Psi_a_dVg = 0.0 ; - } - - T1 = sqrt( ( Pb20 - Psi_a - delta0 ) * ( Pb20 - Psi_a - delta0 ) - + 4.0e0 * delta0 * Pb20 ) ; - Pb20a = Pb20 - 0.5e0 * ( Pb20 - Psi_a - delta0 + T1 ) ; - Pb20a_dVg = 0.5e0 * Psi_a_dVg * ( 1.0e0 + ( Pb20 - Psi_a - delta0 ) / T1 ) ; - Pb20b = Pb20 + sIN.pthrou * ( Pb20a - Pb20 ) ; - Pb20b_dVg = sIN.pthrou * Pb20a_dVg ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = ( Leff - sIN.parl2 ) ; - T4 = 1.0e0 / sIN.parl1 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20b ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVb = T6 * Psum_dVb + T7 * Cox_inv_dVb ; - dVth0_dVd = T6 * Psum_dVd + T7 * Cox_inv_dVd ; - dVth0_dVg = T7 * Cox_inv_dVg + 2.0e0 * T1 * T2 * T4 * ( - Pb20b_dVg ) ; - - T5 = sIN.sc1 ; - T6 = sIN.sc2 ; - T7 = sIN.sc3 ; - - if (flg_smoothing_sc_vd) { - T9 = Vdsz_sc_sat - Vdsz - sc_vds_dlt ; - T9_dVd = - Vdsz_dVds ; - T10 = sqrt( T9 * T9 + 4.0 * sc_vds_dlt * Vdsz_sc_sat) ; - T8 = Vdsz_sc_sat - 0.5 * (T9 + T10) ; - T8_dVd = -0.5 * ( T9_dVd + T9 * T9_dVd / T10 ) ; - } - else { - T8 = Vdsz ; - T8_dVd = Vdsz_dVds ; - } - - T4 = T5 + T7 * Psum / Leff ; - T4_dVb = T7 * Psum_dVb / Leff ; - T4_dVd = T7 * Psum_dVd / Leff ; - - dVthSC = dVth0 * ( T4 + T6 * T8 ) ; - - dVthSC_dVb = dVth0_dVb * ( T4 + T6 * T8 ) - + dVth0 * ( T4_dVb ) ; - - dVthSC_dVd = dVth0_dVd * ( T4 + T6 * T8 ) - + dVth0 * ( T4_dVd + T6 * T8_dVd ) ; - - dVthSC_dVg = dVth0_dVg * ( T4 + T6 * T8 ) ; - - -/*---------------------------------------------------* -* dVthW : narrow-channel effect. -*-----------------*/ - - T5 = sIN.wfc ; - - T1 = 1.0 / Cox ; - T2 = T1 * T1 ; - T3 = 1.0 / ( Cox + T5 / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVb = Qb0_dVb * ( T1 - T3 ) - - Qb0 * Cox_dVb * ( T2 - T4 ) ; - dVthW_dVd = Qb0_dVd * ( T1 - T3 ) - - Qb0 * Cox_dVd * ( T2 - T4 ) ; - dVthW_dVg = - Qb0 * Cox_dVg * ( T2 - T4 ) ; - - -/*---------------------------------------------------* -* dVth : Total variation. -* - Positive dVth means the decrease in Vth. -*-----------------*/ - - dVth = dVthSC + dVthLP + dVthW ; - dVth_dVb = dVthSC_dVb + dVthLP_dVb + dVthW_dVb ; - dVth_dVd = dVthSC_dVd + dVthLP_dVd + dVthW_dVd ; - dVth_dVg = dVthSC_dVg + dVthLP_dVg + dVthW_dVg ; - - -/*---------------------------------------------------* -* Vth : Threshold voltage. -*-----------------*/ - - Vth = Vthp - dVth ; - - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - T1 = sIN.pgd1 ; - T2 = sIN.pgd2 ; - T3 = sIN.pgd3 ; - - if (flg_smoothing_pde_vg) { - T5 = Vgsz_pol_sat - Vgsz - pol_vgs_dlt ; - /* T5_dVb = 0.0 ;*/ - T5_dVd = - Vgsz_dVds ; - T5_dVg = - Vgsz_dVgs ; - T6 = sqrt( T5 * T5 + 4.0 * pol_vgs_dlt * Vgsz_pol_sat ) ; - T7 = Vgsz_pol_sat - 0.5 * (T5 + T6) ; - /* T7_dVb = -0.5 * ( T5_dVb + T5 * T5_dVb / T6 ) ; */ - T7_dVd = -0.5 * ( T5_dVd + T5 * T5_dVd / T6 ) ; - T7_dVg = -0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; - } - else { - T7 = Vgsz ; - /* T7_dVb = 0.0 ; */ - T7_dVd = Vgsz_dVds ; - T7_dVg = Vgsz_dVgs ; - } - - if (flg_smoothing_pde_vd) { - T5 = Vdsz_pol_sat - Vdsz - pol_vds_dlt ; - /* T5_dVb = 0.0 ;*/ - T5_dVd = - Vdsz_dVds ; - /* T5_dVg = 0.0 ;*/ - T6 = sqrt( T5 * T5 + 4.0 * pol_vds_dlt * Vdsz_pol_sat ) ; - T8 = Vdsz_pol_sat - 0.5 * (T5 + T6) ; - /* T8_dVb = -0.5 * ( T5_dVb + T5 * T5_dVb / T6 ) ; */ - T8_dVd = -0.5 * ( T5_dVd + T5 * T5_dVd / T6 ) ; - /* T8_dVg = -0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; */ - } - else { - T8 = Vdsz ; - /* T8_dVb = 0.0 ; */ - T8_dVd = Vdsz_dVds ; - /* T8_dVg = 0.0 ; */ - } - - T9 = - T1 * ( T7 - T2 - T3 * T8 ) - pol2_dlt ; - T9_dVd = - T1 * (T7_dVd - T3 * T8_dVd) ; - T9_dVg = - T1 * (T7_dVg /*- T3 * T8_dVg*/) ; - - T10 = T9 * T9 ; - T10_dVd = 2.0e0 * T9 * T9_dVd ; - T10_dVg = 2.0e0 * T9 * T9_dVg ; - - T11 = sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) ; - T11_dVd = T10_dVd / sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) * 0.5e0 ; - T11_dVg = T10_dVg / sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) * 0.5e0 ; - - dPpg = ( T11 - T9 ) * 0.5e0 ; - dPpg_dVd = ( T11_dVd - T9_dVd ) * 0.5e0 ; - dPpg_dVg = ( T11_dVg - T9_dVg ) * 0.5e0 ; - dPpg_dVb = 0.0 ; - - -/*---------------------------------------------------* -* 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 ; - - -/*---------------------------------------------------* -* Vgs_fb : Actual flatband voltage taking account Vbs. -* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . -*------------------*/ - - Vgs_fb = Vfb - dVth + dPpg + Vbs ; - - -/*-----------------------------------------------------------* -* 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 ; - - -/*-----------------------------------------------------------* -* Accumulation zone. (zone-A) -* - evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Vgs < Vgs_fb ) { - - -/*---------------------------------------------------* -* 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 = Eg - Pb2 ; - - TX = beta * ( Vgp - Vbs ) ; - - TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; - TX_dVds = beta * Vgp_dVds ; - TX_dVgs = beta * Vgp_dVgs ; - - TY = Cox / ( beta * cnst0 ) ; - - T1 = 1.0 / ( beta * cnst0 ) ; - 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 ; - - Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; - Ac31_dVbs = - 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac31_dVds = - 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac31_dVgs = - 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Ac3 = Ac31 * Ac31 ; - - Ac3_dVbs = 2.0 * Ac31 * Ac31_dVbs ; - Ac3_dVds = 2.0 * Ac31 * Ac31_dVds ; - Ac3_dVgs = 2.0 * Ac31 * Ac31_dVgs ; - - Ac2 = sqrt( Ac4 + Ac3 ) ; - Ac2_dVbs = 0.5 * ( Ac4_dVbs + Ac3_dVbs ) / Ac2 ; - Ac2_dVds = 0.5 * ( Ac4_dVds + Ac3_dVds ) / Ac2 ; - Ac2_dVgs = 0.5 * ( Ac4_dVgs + Ac3_dVgs ) / Ac2 ; - - Ac1 = -7.0 * C_SQRT_2 - + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; - - Ac1_dVbs = Ac2_dVbs - + 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac1_dVds = Ac2_dVds - + 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac1_dVgs = Ac2_dVgs - + 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Acd = pow( Ac1 , C_1o3 ) ; - - T1 = C_1o3 / ( Acd * Acd ) ; - Acd_dVbs = Ac1_dVbs * T1 ; - 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 ; - - Acn_dVbs = - 12.0 * TY_dVbs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVbs ; - Acn_dVds = - 12.0 * TY_dVds - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVds ; - Acn_dVgs = - 12.0 * TY_dVgs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVgs ; - - Chi = Acn / Acd ; - - T1 = 1.0 / ( Acd * Acd ) ; - - Chi_dVbs = ( Acn_dVbs * Acd - Acn * Acd_dVbs ) * T1 ; - Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; - Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; - - Psa = Chi / beta + Vbs ; - - Psa_dVbs = Chi_dVbs / beta + 1.0 ; - Psa_dVds = Chi_dVds / beta ; - Psa_dVgs = Chi_dVgs / beta ; - - 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 ) ; - - 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 ) ; - - -/*---------------------------------------------------* -* Characteristics. -*-----------------*/ - - T0 = - Weff * Leff ; - T1 = T0 * Cox ; - T2 = ( Vgp - Ps0 ) ; - - Qb = T1 * T2 ; - - Qb_dVbs = T1 * ( Vgp_dVbs - Ps0_dVbs ) - + T0 * Cox_dVb * T2 ; - Qb_dVds = T1 * ( Vgp_dVds - Ps0_dVds ) - + T0 * Cox_dVd * T2 ; - Qb_dVgs = T1 * ( Vgp_dVgs - Ps0_dVgs ) - + T0 * Cox_dVg * T2 ; - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Qi = 0.0e0 ; - Qi_dVbs = 0.0e0 ; - Qi_dVds = 0.0e0 ; - Qi_dVgs = 0.0e0 ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - 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 / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; - - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - if ( flg_pprv == 1 ) { - - Ps0_ini = Ps0 + Ps0_dVbs * dVbs - + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; - - T1 = Ps0_ini - Ps0 ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } else { - Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - - if ( flg_pprv == 0 ) { - -/*-------------------------------------------* -* Common part. -*-----------------*/ - - Chi = beta * ( Ps0_iniA - Vbs ) ; - -/*-----------------------------------* -* zone-D1/D2 -* - Ps0_ini is the analytical solution of Qs=Qb0 with -* Qb0 being approximated to 3-degree polynomial. -*-----------------*/ - - if ( Chi < znbd3 ) { - - TY = beta * ( Vgp - Vbs ) ; - T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; - T2 = 81 + 3 * T1 ; - T3 = -2916 - 81 * T1 + 27 * T1 * TY ; - T4 = 1458 - 81 * ( 54 + T1 ) + 27 * T1 * TY ; - T4 = T4 * T4 ; - T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; - TX = 3 - - ( C_2p_1o3 * T2 ) / ( 3 * T5 ) - + 1 / ( 3 * C_2p_1o3 ) * T5 ; - - Ps0_iniA = TX / beta + Vbs ; - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Weak inversion zone. -*-----------------*/ - - } else if ( Vgs <= Vth ) { - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Strong inversion zone. -* - Ps0_iniB : upper bound. -*-----------------*/ - - } else { - - T1 = ( Cox * Cox ) / ( cnst0 * cnst0 ) / cnst1 ; - T2 = T1 * Vgp * Vgp ; - T3 = beta + 2.0 / Vgp ; - - Ps0_iniB = log( T2 ) / T3 ; - - T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; - T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; - - Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; - - } - } - - if ( Ps0_ini < Vbs ) { - Ps0_ini = Vbs ; - } - - -/*---------------------------------------------------* -* Assign initial guess. -*-----------------*/ - - 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 ; - - for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) - / ( fs02 + fs02 ) ; - } else { - fs02 = sqrt( fb * fb + fs01 ) ; - fs02_dPs0 = beta * fb_dChi ; - } - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - - } else { - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - } /* end of if ( Chi ... ) else block */ - - -/*-------------------------------------------* -* Update Ps0 . -* - clamped to Vbs if Ps0 < Vbs . -*-----------------*/ - - if ( fabs( dPs0 ) > dP_max ) { - dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; - } - - Ps0 = Ps0 + dPs0 ; - - if ( Ps0 < Vbs ) { - Ps0 = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { - break ; - } - - } /* end of Ps0 Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_s0 > lp_s0_max ) { - 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. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - cfs1 = cnst1 * exp_bVbs ; - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; - - T2 = 1.0e0 / ( fs02 + fs02 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; - fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) - * T2 ; - } else { - fs02_dPs0 = beta * fb_dChi ; - fs02_dVbs = - beta * fb_dChi ; - } - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - T1 = cnst0 ; - - Qb0 = T1 * fb ; - Qb0_dVb = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; - Qb0_dVd = Ps0_dVds * T1 * beta * fb_dChi ; - Qb0_dVg = Ps0_dVgs * T1 * beta * fb_dChi ; - - 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 ; - - T1 = 1.0 / ( fs02 + fb * fb ) ; - T2 = T1 * T1 ; - - Qn0 = cnst0 * fs01 * T1 ; - - T3 = 2.0 * fb_dChi * fb * beta ; - - Qn0_dVbs = cnst0 * ( - fs01_dVbs * T1 - - fs01 * ( fs02_dVbs - + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; - Qn0_dVds = cnst0 * ( - fs01_dVds * T1 - - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; - Qn0_dVgs = cnst0 * ( - fs01_dVgs * T1 - - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ; - - -/*-------------------------------------------* -* zone-D1. (Ps0) -* - Evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Chi < znbd3 ) { - - 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 ; - - T1 = - Weff * Leff ; - - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVb ; - Qb_dVds = T1 * Qb0_dVd ; - Qb_dVgs = T1 * Qb0_dVg ; - - if ( Qn0 < Cox * VgVt_small ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - Qi = T1 * Qn0 ; - Qi_dVbs = T1 * Qn0_dVbs ; - Qi_dVds = T1 * Qn0_dVds ; - Qi_dVgs = T1 * Qn0_dVgs ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-------------------------------------------* -* zone-D2 -*-----------------*/ - - Xi0 = Chi - 1.0e0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - Qn00 = Qn0 ; - Qn00_dVbs = Qn0_dVbs ; - Qn00_dVds = Qn0_dVds ; - Qn00_dVgs = Qn0_dVgs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - - flg_noqi = 0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - - } else { - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - T2 = 0.5e0 / Xi0p12 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - flg_noqi = 0 ; - - } /* end of if ( Chi ... ) block */ - - -/*-----------------------------------------------------------* -* NOTE: The following sections of this part are only for -* the conductive case. -*-----------------*/ - -/*-----------------------------------------------------------* -* Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 . -*-----------------*/ -/*-----------------------------------------------------------* -* Qn0 : Qi at source side. -* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) -* - Derivatives of fs01 are redefined here. -*-----------------*/ -/* note:------------------------ -* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; -* fs02 = sqrt( Xi0 + fs01 ) ; -*-------------------------------*/ - - Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; - - 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 ; - - Qn0_dVbs = Qn0 - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVds = Qn0 - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVgs = Qn0 - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ; - - -/*-----------------------------------------------------------* -* Qb0 : Qb at source side. -*-----------------*/ - - if ( Chi > znbd5 ) { - - Qb0 = cnst0 * Xi0p12 ; - Qb0_dVb = cnst0 * Xi0p12_dVbs ; - Qb0_dVd = cnst0 * Xi0p12_dVds ; - Qb0_dVg = cnst0 * Xi0p12_dVgs ; - - } - - -/*-----------------------------------------------------------* -* FD2 : connecting function for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - } - - -/*-----------------------------------------------------------* -* Modify Qn0 for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; - Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; - Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; - - Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; - - if ( Qn0 < 0.0 ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - } - - -/*---------------------------------------------------* -* 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 ) { - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Pds = 0.0 ; - Pds_dVbs = 0.0 ; - Pds_dVds = 0.0 ; - Pds_dVgs = 0.0 ; - - T1 = - Leff * Weff ; - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVb ; - Qb_dVds = T1 * Qb0_dVd ; - Qb_dVgs = T1 * Qb0_dVg ; - - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - -/*-----------------------------------------------------------* -* Start point of Psl (= Ps0 + Pds) calculation. (label) -*-----------------*/ - -/* start_of_Psl: ; */ - - exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; - - -/*---------------------------------------------------* -* Skip Psl calculation when Vds is very small. -*-----------------*/ - - if ( Vds <= epsm10 ) { - Pds = 0.0 ; - Psl = Ps0 ; - goto end_of_loopl ; - } - - -/*-----------------------------------------------------------* -* Initial guess for Pds ( = Psl - Ps0 ). -*-----------------*/ - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - - if ( flg_pprv == 1 ) { - - Pds_ini = Pds + Pds_dVbs * dVbs - + Pds_dVds * dVds + Pds_dVgs * dVgs ; - - T1 = Pds_ini - Pds ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } - - } - - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - - if ( flg_pprv == 0 ) { - Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ) ; - - T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; - T2 = T1 - Vds - c_pslini_2 ; - T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; - - Pds_ini = T1 - ( T2 + T3 ) / 2 ; - - 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. -*-----------------*/ - - Pds = Pds_ini ; - Psl = Ps0 + Pds ; - - -/*---------------------------------------------------* -* Calculation of Psl by solving Poisson eqn. -* (beginning of Newton loop) -* - Fsl : Fsl = 0 is the equation to be solved. -* - dPsl : correction value. -*-----------------*/ - - for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { - - Chi = beta * ( Psl - Vbs ) ; - - -/*-------------------------------------------* -* zone-D2. (Psl) -* - Qb0 is approximated to 5-degree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) - / ( fsl2 + fsl2 ) ; - } else { - fsl2 = sqrt( fb * fb + fsl1 ) ; - fsl2_dPsl = beta * fb_dChi ; - } - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - if ( fsl1 < epsm10 * cnst1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - } - - -/*-------------------------------------------* -* Update Psl . -* - clamped to Vbs if Psl < Vbs . -*-----------------*/ - - if ( fabs( dPsl ) > dP_max ) { - dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; - } - - Psl = Psl + dPsl ; - - if ( Psl < Vbs ) { - Psl = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { - break ; - } - - } /* end of Psl Newton loop */ - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - - if ( lp_sl > lp_sl_max ) { - 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" ) ; - } - } - - -/*---------------------------------------------------* -* End of Psl calculation. (label) -*-----------------*/ - -end_of_loopl: ; - - -/*---------------------------------------------------* -* Assign Pds. -*-----------------*/ - - Pds = Psl - Ps0 ; - - if ( Pds < ps_conv ) { - Pds = 0.0 ; - Psl = Ps0 ; - } - - -/*---------------------------------------------------* -* 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. -*-----------------*/ - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ) ; - - /*note: cfs1 = cnst1 * exp_bVbsVds */ - fsl1 = cfs1 * fi * fi ; - fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; - fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; - fsl1_dVds = - cfs1 * beta * fi * fi ; - - 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 ) ; - - T2 = 0.5 / fsl2 ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; - fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; - fsl2_dVds = fsl1_dVds * T2 ; - } else { - fsl2_dPsl = beta * fb_dChi ; - fsl2_dVbs = - beta * fb_dChi ; - fsl2_dVds = 0.0 ; - } - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - Pds_dVbs = Psl_dVbs - Ps0_dVbs ; - Pds_dVds = Psl_dVds - Ps0_dVds ; - Pds_dVgs = Psl_dVgs - Ps0_dVgs ; - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; - fsl1_dVds = - beta * fsl1 ; - - if ( fsl1 < epsm10 * T1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - fsl1_dVds = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - T2 = 0.5e0 / fsl2 ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; - - fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; - fsl2_dVds = ( fsl1_dVds ) * T2 ; - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - T2 = 0.5e0 / Xilp12 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - 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 ; - } - - -/*-----------------------------------------------------------* -* Evaluate Qb and Idd. -* - Eta : substantial variable of QB'/Pds and Idd/Pds. -* - note: Eta = 4 * GAMMA_{hisim_0} -*-----------------*/ - - Eta = beta * Pds / Xi0 ; - - Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) - / Xi0 ; - Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; - Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; - - - /* ( 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 = - 0.5e0 / Xi0p32 ; - T4 = - 0.5e0 / Eta1p12 * F00 ; - - F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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_1o3 / Xi0p12 * T1 ; - T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; - - F10_dVbs = Zeta32 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F10_dVds = Zeta32 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F10_dVgs = Zeta32 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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 = 2e0 / ( 5e0 * beta ) * Xi0p12 * T1 ; - T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 - + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; - - F30_dVbs = Zeta52 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F30_dVds = Zeta52 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F30_dVgs = Zeta52 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* F11 := PS11/Pds. -*-----------------*/ - - F11 = Ps0 * F10 + C_2o3 / beta * Xilp32 - F30 ; - - F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs - + ( Xi0_dVbs / beta + Pds_dVbs ) * Xilp12 - - F30_dVbs ; - F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds - + ( Xi0_dVds / beta + Pds_dVds ) * Xilp12 - - F30_dVds ; - F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs - + ( Xi0_dVgs / beta + Pds_dVgs ) * Xilp12 - - F30_dVgs ; - - -/*---------------------------------------------------* -* Fdd := Idd/Pds. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta - 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 ) ; - - -/*---------------------------------------------------* -* Q_B : bulk charge. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta ; - 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 = - Weff * beta * Leff ; - - Qb = T1 * Qbnm / Fdd ; - - T2 = T1 / ( Fdd * Fdd ) ; - - Qb_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; - Qb_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; - Qb_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; - -/*---------------------------------------------------* -* Breaking point for Qi=Qd=0. -*-----------------*/ - - if ( flg_noqi != 0 ) { - goto end_of_part_1 ; - } - - -/*---------------------------------------------------* -* 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 ; - - -/*-----------------------------------------------------------* -* Channel Length Modulation. Lred: \Delta L -*-----------------*/ - - if( sIN.clm2 < epsm10 && sIN.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 ; - } - - FMD = 1.0e0 ; - FMD_dVds = 0.0 ; - - goto end_of_CLM ; - } - - Ec = Idd / beta / Qn0 / Leff ; - Ec_dVbs = 1.0e0 / beta / Leff - * ( Idd_dVbs / Qn0 - Idd * Qn0_dVbs / Qn0 / Qn0 ) ; - Ec_dVds = ( Idd_dVds / Qn0 - Idd * Qn0_dVds / Qn0 / Qn0 ) - / beta / Leff ; - Ec_dVgs = 1.0e0 / beta / Leff - * ( Idd_dVgs / Qn0 - Idd * Qn0_dVgs / Qn0 / Qn0 ) ; - - T13 = Vds ; - T13_dVd = 1.0 ; - - /* - T2 = Vds + Ps0 ; - T2_dVb = Ps0_dVbs ; - T2_dVd = 1.0 + Ps0_dVds ; - T2_dVg = Ps0_dVgs ; - */ - T2 = T13 + Ps0 ; - T2_dVb = Ps0_dVbs ; - T2_dVd = T13_dVd + Ps0_dVds ; - T2_dVg = Ps0_dVgs ; - - T10 = sIN.clm1 ; - - Aclm = T10 ; - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVb + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVd + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVg + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - /* - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - */ - if ( Psdl > Ps0 + T13 - epsm10 ) { - Psdl = Ps0 + T13 - epsm10 ; - } - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - - T7 = Qn0 / Wd ; - T7_dVb = ( Qn0_dVbs / Wd - Qn0 / Wd / Wd * Wd_dVbs ) ; - T7_dVd = ( Qn0_dVds / Wd - Qn0 / Wd / Wd * Wd_dVds ) ; - T7_dVg = ( Qn0_dVgs / Wd - Qn0 / Wd / Wd * Wd_dVgs ) ; - - T8 = Ec * Ec + 2.0e0 / C_ESI * q_Nsub * ( Psdl - Psl ) + 1.0e5 ; - T8_dVb = 2.0e0 * Ec * Ec_dVbs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVbs - Psl_dVbs ) ; - T8_dVd = 2.0e0 * Ec * Ec_dVds - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVds - Psl_dVds ) ; - T8_dVg = 2.0e0 * Ec * Ec_dVgs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVgs - Psl_dVgs ) ; - - Ed = sqrt( T8 ) ; - Ed_dVbs = 0.5e0 / Ed * T8_dVb ; - Ed_dVds = 0.5e0 / Ed * T8_dVd ; - Ed_dVgs = 0.5e0 / Ed * T8_dVg ; - - - Lred = ( Ed - Ec ) - / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) * C_ESI ; - T1 = 1.0 / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) ; - T2 = T1 * T1 ; - Lred_dVbs = ( ( Ed_dVbs - Ec_dVbs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVb ) * C_ESI ; - Lred_dVds = ( ( Ed_dVds - Ec_dVds ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVd ) * C_ESI ; - Lred_dVgs = ( ( Ed_dVgs - Ec_dVgs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVg ) * C_ESI ; - - -/*---------------------------------------------------* -* Modify Lred for symmetry. -*-----------------*/ - - /* TX = Vds / cclmmdf ; */ - TX = T13 / cclmmdf ; - T2 = TX * TX ; - T5 = 1.0 + T2 ; - - FMD = 1.0 - 1.0 / T5 ; - /* FMD_dVds = 2.0 * Vds / ( T5 * T5 * cclmmdf * cclmmdf ) ; */ - FMD_dVds = 2.0 * T13 * T13_dVd / ( T5 * T5 * cclmmdf * cclmmdf ) ; - - T6 = Lred ; - - Lred = FMD * T6 ; - Lred_dVbs *= FMD ; - Lred_dVds = FMD_dVds * ( T6 ) + FMD * Lred_dVds ; - Lred_dVgs *= FMD ; - - -/*-------------------------------------------* -* End point of CLM. (label) -*-----------------*/ - -end_of_CLM: ; - - -/*---------------------------------------------------* -* preparation for Qi and Qd. -*-----------------*/ - - T1 = 2.0e0 * fac1 ; - - DtPds = T1 * ( F10 - Xi0p12 ) ; - - T2 = 2.0 * ( F10 - Xi0p12 ) ; - - DtPds_dVbs = T1 * ( F10_dVbs - - 0.5 * beta * ( Ps0_dVbs - 1.0e0 ) / Xi0p12 ) - + T2 * fac1_dVbs ; - DtPds_dVds = T1 * ( F10_dVds - - 0.5 * beta * Ps0_dVds / Xi0p12 ) - + T2 * fac1_dVds ; - DtPds_dVgs = T1 * ( F10_dVgs - - 0.5 * beta * Ps0_dVgs / Xi0p12 ) - + 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. -* - clamped to 0 if Alpha < 0. -*-----------------*/ - - Alpha = 1.0e0 - Achi / VgVt ; - - if ( Alpha >= 0.0e0 ) { - - Alpha_dVbs = - Achi_dVbs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVbs / VgVt ) ; - Alpha_dVds = - Achi_dVds / VgVt + ( Achi / VgVt ) - * ( VgVt_dVds / VgVt ) ; - Alpha_dVgs = - Achi_dVgs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVgs / VgVt ) ; - - } else { - - Alpha = 0.0e0 ; - Alpha_dVbs = 0.0e0 ; - Alpha_dVds = 0.0e0 ; - Alpha_dVgs = 0.0e0 ; - } - - -/*-----------------------------------------------------------* -* Q_I : inversion charge. -*-----------------*/ - - Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; - Qinm_dVbs = Alpha_dVbs * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVds = Alpha_dVds * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVgs = Alpha_dVgs * ( 1.0e0 + Alpha + Alpha ) ; - - Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; - Qidn_dVbs = Alpha_dVbs ; - Qidn_dVds = Alpha_dVds ; - Qidn_dVgs = Alpha_dVgs ; - - T1 = - Weff * ( Leff - Lred ) * C_2o3 * VgVt * Qinm / Qidn ; - - Qi = T1 * Cox ; - - Qi_dVbs = Qi * ( VgVt_dVbs / VgVt - + Qinm_dVbs / Qinm - Qidn_dVbs / Qidn - - Lred_dVbs/ ( Leff - Lred ) ) - + T1 * Cox_dVb ; - Qi_dVds = Qi * ( VgVt_dVds / VgVt - + Qinm_dVds / Qinm - Qidn_dVds / Qidn - - Lred_dVds/ ( Leff - Lred ) ) - + T1 * Cox_dVd ; - Qi_dVgs = Qi * ( VgVt_dVgs / VgVt - + Qinm_dVgs / Qinm - Qidn_dVgs / Qidn - - Lred_dVgs/ ( Leff - Lred ) ) - + T1 * Cox_dVg ; - - -/*-----------------------------------------------------------* -* Q_D : drain charge. -*-----------------*/ - - 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 ) { - Qdrat_dVbs = Quot * ( Qddn_dVbs / Qddn - Qdnm_dVbs / Qdnm ) ; - Qdrat_dVds = Quot * ( Qddn_dVds / Qddn - Qdnm_dVds / Qdnm ) ; - Qdrat_dVgs = Quot * ( Qddn_dVgs / Qddn - Qdnm_dVgs / Qdnm ) ; - } else { - Qdrat = 0.5e0 ; - Qdrat_dVbs = 0.0e0 ; - Qdrat_dVds = 0.0e0 ; - Qdrat_dVgs = 0.0e0 ; - } - - 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 ; - - -/*-----------------------------------------------------------* -* Modify charges for zone-D2. -* - FD2 must be defined previously. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - if ( Chi < znbd5 ) { - - 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 ; - - T5 = - Leff * Weff ; - - Qb_dVbs = FD2 * Qb_dVbs + FD2_dVbs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVb - FD2_dVbs * T5 * Qb0 ; - Qb_dVds = FD2 * Qb_dVds + FD2_dVds * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVd - FD2_dVds * T5 * Qb0 ; - Qb_dVgs = FD2 * Qb_dVgs + FD2_dVgs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVg - FD2_dVgs * T5 * Qb0 ; - - Qb = FD2 * Qb + ( 1.0 - FD2 ) * T5 * Qb0 ; - - if ( Qb > 0.0 ) { - Qb = 0.0 ; - Qb_dVbs = 0.0 ; - Qb_dVds = 0.0 ; - Qb_dVgs = 0.0 ; - } - - Qi_dVbs = FD2 * Qi_dVbs + FD2_dVbs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVbs - FD2_dVbs * T5 * Qn0 ; - Qi_dVds = FD2 * Qi_dVds + FD2_dVds * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVds - FD2_dVds * T5 * Qn0 ; - Qi_dVgs = FD2 * Qi_dVgs + FD2_dVgs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVgs - FD2_dVgs * T5 * Qn0 ; - - Qi = FD2 * Qi + ( 1.0 - FD2 ) * T5 * Qn0 ; - - if ( Qi > 0.0 ) { - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - } - - Qd_dVbs = FD2 * Qd_dVbs + FD2_dVbs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVbs / 2 - - FD2_dVbs * T5 * Qi / 2 ; - Qd_dVds = FD2 * Qd_dVds + FD2_dVds * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVds / 2 - - FD2_dVds * T5 * Qi / 2 ; - Qd_dVgs = FD2 * Qd_dVgs + FD2_dVgs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVgs / 2 - - FD2_dVgs * T5 * Qi / 2 ; - - Qd = FD2 * Qd + ( 1.0 - FD2 ) * T5 * Qi / 2 ; - - if ( Qd > 0.0 ) { - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - } - - } - - -/*-----------------------------------------------------------* -* Modified potential for symmetry. -*-----------------*/ - - T1 = exp( - ( Vds - Pds ) / ( 2.0 * sIN.pzadd0 ) ) ; - - Pzadd = sIN.pzadd0 * T1 ; - - T2 = - 0.5 * T1 ; - - Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; - Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; - Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; - - if ( fabs ( Pzadd ) < epsm10 ) { - Pzadd = 0.0 ; - 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 ; - - -/*-----------------------------------------------------------* -* Evaluate universal mobility. -*-----------------*/ - - Ps0Vbsz = Ps0z - Vbsz ; - Ps0Vbsz_dVbs = Ps0z_dVbs - Vbsz_dVbs ; - Ps0Vbsz_dVds = Ps0z_dVds - Vbsz_dVds ; - Ps0Vbsz_dVgs = Ps0z_dVgs ; - - -/*-------------------------------------------* -* Qbm -*-----------------*/ - - T1 = cnst0 ; - T2 = sqrt( beta * Ps0Vbsz - 1.0 ) ; - - Qbm = T1 * T2 ; - - T3 = 0.5 * beta * T1 / T2 ; - - Qbm_dVbs = T3 * Ps0Vbsz_dVbs ; - Qbm_dVds = T3 * Ps0Vbsz_dVds ; - Qbm_dVgs = T3 * Ps0Vbsz_dVgs ; - - -/*-------------------------------------------* -* Qnm -*-----------------*/ - - Chi = beta * Ps0Vbsz ; - - exp_Chi = exp( Chi ) ; - - exp_bVbs = exp( beta * Vbsz ) ; - - cfs1 = cnst1 * exp_bVbs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - /* regard fs01 as a function of Chi and Vbs */ - fs01_dChi = cfs1 * ( exp_Chi ) ; - fs01_dVbs = beta * fs01 ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - Xi0z = Chi - 1.0e0 ; - - Xi0z_dVbs = beta * Ps0Vbsz_dVbs ; - Xi0z_dVds = beta * Ps0Vbsz_dVds ; - Xi0z_dVgs = beta * Ps0Vbsz_dVgs ; - - fs02 = sqrt( Xi0z + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - /* regard fs01 as a function of Chi and Vbs */ - fs02_dChi = ( 1.0 + fs01_dChi ) * T2 ; - fs02_dVbs = fs01_dVbs * T2 ; - - Xi0zp12 = sqrt( Xi0z ) ; - - Xi0zp12_dVbs = 0.5e0 * Xi0z_dVbs / Xi0zp12 ; - Xi0zp12_dVds = 0.5e0 * Xi0z_dVds / Xi0zp12 ; - Xi0zp12_dVgs = 0.5e0 * Xi0z_dVgs / Xi0zp12 ; - - T1 = 1.0 / ( fs02 + Xi0zp12 ) ; - - Qnm = cnst0 * fs01 * T1 ; - - fs01_dVds = beta * Ps0Vbsz_dVds * fs01_dChi - + fs01_dVbs * Vbsz_dVds ; - fs01_dVbs = beta * Ps0Vbsz_dVbs * fs01_dChi + fs01_dVbs ; - fs01_dVgs = beta * Ps0Vbsz_dVgs * fs01_dChi ; - - fs02_dVds = beta * Ps0Vbsz_dVds * fs02_dChi - + fs02_dVbs * Vbsz_dVds ; - fs02_dVbs = beta * Ps0Vbsz_dVbs * fs02_dChi + fs02_dVbs ; - fs02_dVgs = beta * Ps0Vbsz_dVgs * fs02_dChi ; - - Qnm_dVbs = Qnm - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0zp12_dVbs ) * T1 ) ; - Qnm_dVds = Qnm - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0zp12_dVds ) * T1 ) ; - Qnm_dVgs = Qnm - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0zp12_dVgs ) * T1 ) ; - - if ( Qbm < 0.0 ) { - Qbm = 0.0 ; - } - if ( Qnm < 0.0 ) { - Qnm = 0.0 ; - } - - -/*---------------------------------------------------* -* Muun : universal mobility. -*-----------------*/ - - /* removed Eqs. "Qbm = Qb0", "Qnm = Qn0", ... (4/Dec/01) */ - - T1 = sIN.ninv - sIN.ninvd * Vdsz ; - T1_dVd = - sIN.ninvd * Vdsz_dVds ; - - Eeff = ( sIN.ndep * Qbm + T1 * Qnm ) / C_ESI ; - Eeff_dVbs = ( sIN.ndep * Qbm_dVbs + T1 * Qnm_dVbs ) - / C_ESI ; - Eeff_dVds = ( sIN.ndep * Qbm_dVds + T1 * Qnm_dVds - + T1_dVd * Qnm ) - / C_ESI ; - Eeff_dVgs = ( sIN.ndep * Qbm_dVgs + T1 * Qnm_dVgs ) - / C_ESI ; - - Rns = Qnm / C_QE ; - - T10 = pow( sIN.temp / C_T300 , sIN.muetmp ) ; - T21 = pow( Eeff , sIN.mueph0 - 1.0e0 ) ; - T20 = T21 * Eeff ; - - T11 = sIN.muesr0 ; - - T31 = pow( Eeff , T11 - 1.0e0 ) ; - T30 = T31 * Eeff ; - /* - T31 = pow( Eeff , sIN.muesr0 - 1.0e0 ) ; - T30 = T31 * Eeff ; - */ - - T1 = 1e0 / ( sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ) - + T10 - * T20 / mueph - + T30 / sIN.muesr1 ; - - Muun = 1e0 / T1 ; - - T1 = 1e0 / ( T1 * T1 ) ; - T2 = sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ; - T2 = 1e0 / ( T2 * T2 ) ; - T3 = T10 * sIN.mueph0 * T21 / mueph ; - T4 = T11 * T31 / sIN.muesr1 ; - /* - T4 = sIN.muesr0 * T31 / sIN.muesr1 ; - */ - - Muun_dVbs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVbs / C_QE * T2 - + Eeff_dVbs * T3 - + Eeff_dVbs * T4 ) - * T1 ; - Muun_dVds = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVds / C_QE * T2 - + Eeff_dVds * T3 - + Eeff_dVds * T4 ) - * T1 ; - Muun_dVgs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVgs / C_QE * T2 - + Eeff_dVgs * T3 - + Eeff_dVgs * T4 ) - * T1 ; - - -/*-----------------------------------------------------------* -* Mu : mobility -*-----------------*/ - - T1 = 1.0e0 / beta / ( Qn0 + small ) / ( Leff - Lred ) ; - T1_dVb = 1.0e0 / beta * ( - Qn0_dVbs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVbs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVd = 1.0e0 / beta * ( - Qn0_dVds / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVds / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVg = 1.0e0 / beta * ( - Qn0_dVgs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVgs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - - Ey = Idd * T1 ; - Ey_dVbs = Idd_dVbs * T1 + Idd * T1_dVb ; - Ey_dVds = Idd_dVds * T1 + Idd * T1_dVd ; - Ey_dVgs = Idd_dVgs * T1 + Idd * T1_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 = sIN.temp / C_T300 ; - - Vmax = sIN.vmax / ( 1.8 + 0.4 * T1 + 0.1 * T1 * T1 ) ; - - T2 = 1.0 - sIN.vover / pow( Leff , sIN.voverp ) ; - - if ( T2 < 0.01 ) { - fprintf( stderr , - "*** warning(HiSIM): Overshoot is too big.\n" ) ; - T2 = 0.01 ; - } - - Vmax = Vmax / T2 ; - - T1 = Em / Vmax ; - - /* note: sIN.bb = 2 (electron) ;1 (hole) */ - if ( 1.0e0 - epsm10 <= sIN.bb && sIN.bb <= 1.0e0 + epsm10 ) { - T3 = 1.0e0 ; - } else if ( 2.0e0 - epsm10 <= sIN.bb - && sIN.bb <= 2.0e0 + epsm10 ) { - T3 = T1 ; - } else { - T3 = pow( T1 , sIN.bb - 1.0e0 ) ; - } - T2 = T1 * T3 ; - T4 = 1.0e0 + T2 ; - T6 = pow( T4 , ( - 1.0e0 / sIN.bb - 1.0e0 ) ) ; - T5 = T4 * T6 ; - - Mu = Muun * T5 ; - Mu_dVbs = Muun_dVbs * T5 - Muun / Vmax * T6 * T3 * Em_dVbs ; - Mu_dVds = Muun_dVds * T5 - Muun / Vmax * T6 * T3 * Em_dVds ; - Mu_dVgs = Muun_dVgs * T5 - Muun / Vmax * T6 * T3 * Em_dVgs ; - -/* end_of_mobility : ; */ - - -/*-----------------------------------------------------------* -* Ids: channel current. -*-----------------*/ - - T1 = Weff / beta / ( Leff - Lred ) ; - T1_dVb = T1 / ( Leff - Lred ) * Lred_dVbs ; - T1_dVd = T1 / ( Leff - Lred ) * Lred_dVds ; - T1_dVg = T1 / ( Leff - Lred ) * Lred_dVgs ; - - Ids0 = T1 * Idd * Mu ; - Ids0_dVbs = T1 * ( Mu * Idd_dVbs + Idd * Mu_dVbs ) - + T1_dVb * Mu * Idd ; - Ids0_dVds = T1 * ( Mu * Idd_dVds + Idd * Mu_dVds ) - + T1_dVd * Mu * Idd ; - Ids0_dVgs = T1 * ( Mu * Idd_dVgs + Idd * Mu_dVgs ) - + T1_dVg * Mu * Idd ; - - T1 = Vdsz + sIN.rpock2 ; - T2 = T1 * T1 + small ; - T2_dVb = 0.0e0 ; - T2_dVd = 2.0 * T1 * Vdsz_dVds ; - T2_dVg = 0.0e0 ; - - rp1 = FMD * sIN.rpock1 ; - rp1_dVds = FMD_dVds * sIN.rpock1 ; - - TX = pow( Ids0, sIN.rpocp1 ) * pow( Leff / 1.0e-4 , sIN.rpocp2 ) / Weff ; - - T3 = rp1 * TX ; - T4 = ( T3 + T2 ) * ( T3 + T2 ) ; - - Ids = Ids0 / ( 1.0 + T3 / T2 ) ; - - T5 = T2 * ( T2 - ( sIN.rpocp1 - 1.0 ) * T3 ) / T4 ; - T6 = Ids0 * T3 / T4 ; - - Ids_dVbs = T5 * Ids0_dVbs + T6 * T2_dVb ; - Ids_dVds = T5 * Ids0_dVds + T6 * T2_dVd - - Ids0 * T2 / T4 * rp1_dVds * TX ; - Ids_dVgs = T5 * Ids0_dVgs + T6 * T2_dVg ; - - if ( Pds < ps_conv ) { - Ids_dVbs = 0.0 ; - Ids_dVgs = 0.0 ; - } - - Ids += Gdsmin * Vds ; - Ids_dVds += Gdsmin ; - - -/*-----------------------------------------------------------* -* STI -*-----------------*/ - - if ( sIN.coisti == 0 ) { - goto end_of_STI ; - } - - Vth_dVb = Vthp_dVb - dVth_dVb ; - Vth_dVd = Vthp_dVd - dVth_dVd ; - Vth_dVg = Vthp_dVg - dVth_dVg ; - - Vgssti = Vgs - Vfb + Vth * sIN.wvthsc ; - Vgssti_dVbs = Vth_dVb * sIN.wvthsc ; - Vgssti_dVds = Vth_dVd * sIN.wvthsc ; - Vgssti_dVgs = 1.0e0 + Vth_dVg * sIN.wvthsc ; - - costi0 = sqrt (2.0e0 * C_QE * sIN.nsti * C_ESI / beta) ; - costi1 = Nin * Nin / sIN.nsti / sIN.nsti ; - costi3 = costi0 * costi0 / Cox / Cox ; - costi4 = costi3 * beta / 2.0e0 ; - costi5 = costi4 * beta * 2.0e0 ; - T1 = 1.0e0 + 4.0e0 * ( beta * ( Vgssti - Vbs ) - 1.0e0 ) / costi5 ; - if ( T1 > 0.0 ) { - costi6 = sqrt( T1 ) ; - Psasti = Vgssti + costi4 * (1.0e0 - costi6) ; - Psasti_dVbs = Vgssti_dVbs - (Vgssti_dVbs - 1.0e0)/costi6 ; - Psasti_dVds = Vgssti_dVds - Vgssti_dVds/costi6 ; - Psasti_dVgs = Vgssti_dVgs - Vgssti_dVgs/costi6 ; - } else { - Psasti = Psasti_dVbs = Psasti_dVds = Psasti_dVgs = 0.0 ; - } - - Asti = 1.0e0 / costi1 / costi3 ; - Psbsti = log(Asti * (Vgssti*Vgssti)) / (beta + 2.0e0 / Vgssti) ; - - Psbsti_dVbs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVbs ; - Psbsti_dVds = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVds ; - Psbsti_dVgs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * 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 ; - - Psti = Psbsti - 0.5e0 * (Psab - + sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti)) ; - - Psti_dVbs = Psbsti_dVbs - 0.5e0 * Psab_dVbs - - (Psab * Psab_dVbs +2.0e0 * sti2_dlt * Psbsti_dVbs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVds = Psbsti_dVds - 0.5e0 * Psab_dVds - - (Psab * Psab_dVds +2.0e0 * sti2_dlt * Psbsti_dVds) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVgs = Psbsti_dVgs - 0.5e0 * Psab_dVgs - - (Psab * Psab_dVgs +2.0e0 * sti2_dlt * Psbsti_dVgs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - - expsti = exp(beta * Psti) ; - sq1sti = sqrt(beta * (Psti - Vbs) - 1.0e0 +costi1 * expsti) ; - - sq1sti_dVbs = 0.50e0 * (beta * (Psti_dVbs - 1.0e0) - + costi1 * beta * Psti_dVbs * expsti) / sq1sti ; - sq1sti_dVds = 0.50e0 * (beta * Psti_dVds - + costi1 * beta * Psti_dVds * expsti) / sq1sti ; - sq1sti_dVgs = 0.50e0 * (beta * Psti_dVgs - + costi1 * beta * Psti_dVgs * expsti) / sq1sti ; - - sq2sti = sqrt(beta * (Psti - Vbs) - 1.0e0) ; - - sq2sti_dVbs = 0.50e0 * beta *(Psti_dVbs - 1.0e0) / sq2sti ; - sq2sti_dVds = 0.50e0 * beta *Psti_dVds / sq2sti ; - sq2sti_dVgs = 0.50e0 * beta *Psti_dVgs / sq2sti ; - - 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) ; - - costi7 = 2.0e0 * sIN.wsti / beta ; - Idssti = costi7 * Mu * Qn0sti * (1.0e0 - exp(-beta * Vds)) - / (Leff - Lred) ; - - Idssti_dVbs = costi7 * - ((( Mu_dVbs * Qn0sti + Mu * Qn0sti_dVbs ) * - ( 1.0e0 - exp( - beta * Vds ))) / ( Leff - Lred ) - + Lred_dVbs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - Idssti_dVds = costi7 * - ((( Mu_dVds * Qn0sti + Mu * Qn0sti_dVds ) * - ( 1.0e0 - exp( - beta * Vds )) - + beta * Mu * Qn0sti * exp( - beta * Vds )) / ( Leff - Lred ) - + Lred_dVds * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - Idssti_dVgs = costi7 * - ((( Mu_dVgs * Qn0sti + Mu * Qn0sti_dVgs ) * - ( 1.0e0 - exp( - beta * Vgs ))) / ( Leff - Lred ) - + Lred_dVgs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred ) / ( Leff - Lred )) ; - - Ids = Ids + Idssti ; - - Ids_dVbs = Ids_dVbs + Idssti_dVbs ; - Ids_dVds = Ids_dVds + Idssti_dVds ; - Ids_dVgs = Ids_dVgs + Idssti_dVgs ; - - end_of_STI: ; - - -/*-----------------------------------------------------------* -* Break point for the case of Rs=Rd=0. -*-----------------*/ - - if ( flg_rsrd == 0 ) { - DJI = 1.0 ; - DJIP = 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 ) || - 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 -- ; } - - -/*-----------------------------------------------------------* -* End of PART-1. (label) -*-----------------*/ - -end_of_part_1: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-2: Substrate / gate / leak currents -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Isub : substrate current induced by impact ionization. -*-----------------*/ -/*-------------------------------------------* -* Accumulation zone or nonconductive case, in which Ids==0. -*-----------------*/ - - if ( Ids <= 0.0e0 || sIN.coisub == 0 ) { - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - goto end_of_Isub ; - } - - -/*-------------------------------------------* -* Conductive case. -*-----------------*/ - - if ( sIN.sub1 > 0.0e0 && sIN.vmax > 0.0e0 ) { - - Vdep = Vds + Ps0 - sIN.sub3 * Psl ; - Vdep_dVbs = Ps0_dVbs - sIN.sub3 * Psl_dVbs ; - Vdep_dVds = 1.0e0 + Ps0_dVds - sIN.sub3 * Psl_dVds ; - Vdep_dVgs = Ps0_dVgs - sIN.sub3 * Psl_dVgs ; - - TX = - sIN.sub2 / Vdep ; - - Epkf = exp( TX ) ; - Epkf_dVbs = - TX * Vdep_dVbs / Vdep * Epkf ; - Epkf_dVds = - TX * Vdep_dVds / Vdep * Epkf ; - Epkf_dVgs = - TX * Vdep_dVgs / Vdep * Epkf ; - - T1 = Ids * Epkf ; - T1_dVb = Ids_dVbs * Epkf + Ids * Epkf_dVbs ; - T1_dVd = Ids_dVds * Epkf + Ids * Epkf_dVds ; - T1_dVg = Ids_dVgs * Epkf + Ids * Epkf_dVgs ; - - if( T1 < 1.0e-25 ){ - T1 = 1.0e-25 ; - T1_dVb = 0.0e0 ; - T1_dVd = 0.0e0 ; - T1_dVg = 0.0e0 ; - } - - Isub = sIN.sub1 * Vdep * T1 ; - Isub_dVbs = sIN.sub1 * ( Vdep_dVbs * T1 + Vdep * T1_dVb ) ; - Isub_dVds = sIN.sub1 * ( Vdep_dVds * T1 + Vdep * T1_dVd ) ; - Isub_dVgs = sIN.sub1 * ( Vdep_dVgs * T1 + Vdep * T1_dVg ) ; - - } else { - - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - - } /* end of if ( sIN.sub1 ... ) else block. */ - - -/*-------------------------------------------* -* End of Isub. (label) -*-----------------*/ - -end_of_Isub: ; - - -/*-----------------------------------------------------------* -* Igate : Gate current induced by tunneling. -* - Vzadd is used for symmetrizing. -*-----------------*/ - - Egp12 = sqrt( Eg ) ; - Egp32 = Eg * Egp12 ; - - E0 = 10.0 ; - - if ( sIN.coiigs == 0 ) { - Igate = 0.0e0 ; - Igate_dVbs = 0.0e0 ; - Igate_dVds = 0.0e0 ; - Igate_dVgs = 0.0e0 ; - goto end_of_Igate ; - } - - Vgpz = Vgp + Vzadd ; - - Vgpz_dVbs = Vgp_dVbs ; - Vgpz_dVds = Vgp_dVds + Vzadd_dVds ; - Vgpz_dVgs = Vgp_dVgs ; - - T1 = Vgpz - ( Psl + Ps0 + 2.0 * Vzadd ) * sIN.gleak3 ; - - E2 = T1 / Tox ; - - E2_dVbs = E2 - * ( ( Vgpz_dVbs - ( Psl_dVbs + Ps0_dVbs ) * sIN.gleak3 ) - / T1 - - Tox_dVb / Tox ) ; - E2_dVds = E2 - * ( ( Vgpz_dVds - - ( Psl_dVds + Ps0_dVds + 2.0 * Vzadd_dVds ) - * sIN.gleak3 - ) / T1 - - Tox_dVd / Tox ) ; - E2_dVgs = E2 - * ( ( Vgpz_dVgs - ( Psl_dVgs + Ps0_dVgs ) * sIN.gleak3 ) - / T1 - - Tox_dVg / Tox ) ; - - T1 = E2 - E0 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E2 ) ; - - Etun = E2 - ( T1 - T3 ) / 2 ; - if ( Etun < 0 ) { - Igate = 0.0e0 ; - Igate_dVbs = 0.0e0 ; - Igate_dVds = 0.0e0 ; - Igate_dVgs = 0.0e0 ; - goto end_of_Igate ; - } - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = 2.0 * T1 * T4 + 0.5 ; - - Etun_dVbs = T5 * E2_dVbs ; - Etun_dVds = T5 * E2_dVds ; - Etun_dVgs = T5 * E2_dVgs ; - - T1 = exp( - sIN.gleak2 * Egp32 / Etun ) ; - - T2 = sIN.gleak1 / Egp12 * C_QE * Weff * Leff ; - - Igate = T2 * Etun * Etun * T1 ; - - T3 = T2 * T1 * ( 2.0 * Etun + sIN.gleak2 * Egp32 ) ; - - Igate_dVbs = T3 * Etun_dVbs ; - Igate_dVds = T3 * Etun_dVds ; - Igate_dVgs = T3 * Etun_dVgs ; - - end_of_Igate: ; - - -/*-----------------------------------------------------------* -* Igidl : GIDL -*-----------------*/ - - if ( (sIN.mode == HiSIM_NORMAL_MODE && sIN.cogidl == 0) || - (sIN.mode == HiSIM_REVERSE_MODE && sIN.cogisl == 0) ) { - Igidl = 0.0e0 ; - Igidl_dVbs = 0.0e0 ; - Igidl_dVds = 0.0e0 ; - Igidl_dVgs = 0.0e0 ; - goto end_of_IGIDL ; - } - - T1 = sIN.gidl3 * Vdsz - Vgsz + Vfb - dVth + dPpg ; - - E1 = T1 / Tox ; - - E1_dVb = E1 * ( ( - dVth_dVb + dPpg_dVb ) / T1 - Tox_dVb / Tox ) ; - E1_dVd = E1 * ( ( sIN.gidl3 * Vdsz_dVds - - Vgsz_dVds - dVth_dVd + dPpg_dVd) / T1 - - Tox_dVd / Tox ) ; - E1_dVg = E1 * ( ( -1.0 - dVth_dVg + dPpg_dVg) / T1 - Tox_dVg / Tox ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egidl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egidl_dVb = T5 * E1_dVb ; - Egidl_dVd = T5 * E1_dVd ; - Egidl_dVg = T5 * E1_dVg ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egidl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Igidl = T2 * Egidl * Egidl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egidl + sIN.gidl2 * Egp32 ) ; - - Igidl_dVbs = T3 * Egidl_dVb ; - Igidl_dVds = T3 * Egidl_dVd ; - Igidl_dVgs = T3 * Egidl_dVg ; - - end_of_IGIDL: ; - - -/*-----------------------------------------------------------* -* Igisl : GISL -*-----------------*/ - - if ( (sIN.mode == HiSIM_NORMAL_MODE && sIN.cogisl == 0) || - (sIN.mode == HiSIM_REVERSE_MODE && sIN.cogidl == 0) ) { - Igisl = 0.0e0 ; - Igisl_dVbd = 0.0e0 ; - Igisl_dVsd = 0.0e0 ; - Igisl_dVgd = 0.0e0 ; - goto end_of_IGISL ; - } - -/* dVthP and dPpgP are required for GISL */ - -/* internal biases (drain reference) */ - Vsd = -Vds ; - Vgd = Vgs - Vds ; - Vbd = Vbs - Vds ; - - T1 = exp(/* - */Vbdc_dVbde * Vsd / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVsd = 0.5 * Vbdc_dVbde * T1 ; - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVsd = 0.0 ; - } - - Vbdz = Vbd + Vzadd ; - Vbdz_dVgd = 0.0 ; - Vbdz_dVsd = Vzadd_dVsd ; - Vbdz_dVbd = 1.0 ; - - Vsdz = Vsd + 2 * Vzadd ; - Vsdz_dVgd = 0.0 ; - Vsdz_dVsd = 1.0 + 2 * Vzadd_dVsd ; - Vsdz_dVbd = 0.0 ; - - Vgdz = Vgd + Vzadd ; - Vgdz_dVgd = 1.0 ; - Vgdz_dVsd = Vzadd_dVsd ; - Vgdz_dVbd = 0.0 ; - -/* Quantum effect (GISL) */ - - T9 = sIN.qme1 ; - T11 = sIN.qme3 ; - T10 = sIN.qme2 ; - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbdz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / c_eox * T2 + T10 ; - - T3 = - 0.5 * sIN.tox / c_eox * T1 / T2 ; - Vthq_dVb = T3 * Vbdz_dVbd ; - Vthq_dVs = T3 * Vbdz_dVsd ; - - if (flg_smoothing_qme_vg) { - T5 = Vgsz_qme_sat - Vgdz - qme_vgs_dlt ; - T5_dVs = - Vgdz_dVsd ; - T5_dVg = - Vgdz_dVgd ; - T6 = sqrt( T5 * T5 + 4.0 * qme_vgs_dlt * Vgsz_qme_sat) ; - T13 = Vgsz_qme_sat - 0.5 * (T5 + T6) ; - T13_dVs = -0.5 * ( T5_dVs + T5 * T5_dVs / T6 ) ; - T13_dVg = -0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; - } - else { - T13 = Vgdz ; - T13_dVs = Vgdz_dVsd ; - T13_dVg = Vgdz_dVgd ; - } - - T1 = - T10 ; - T2 = T13 - Vthq ; - T3 = T9 * T1 * T1 + T11 ; - T4 = T9 * T2 * T2 + T11 ; - T5 = T4 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T5 + 2.0 * qme_dlt ) / T6 ) ; - T8 = 2.0 * T9 * T2 * T7 ; - - dTox_dVb = T8 * ( - Vthq_dVb ) ; - dTox_dVs = T8 * ( T13_dVs - Vthq_dVs ) ; - dTox_dVg = T8 * ( T13_dVg ) ; - - if ( T13 - Vthq > 0 ) { - T5 = T11 - T3 - qme_dlt ; - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T11 ) ; - - dTox = T11 - 0.5 * ( T5 + T6 ) ; - dTox_dVb = 0.0 ; - dTox_dVs = 0.0 ; - dTox_dVg = 0.0 ; - } - - ToxP = sIN.tox + dTox ; - ToxP_dVb = dTox_dVb ; - ToxP_dVs = dTox_dVs ; - ToxP_dVg = dTox_dVg ; - - CoxP = c_eox / ToxP ; - T1 = - c_eox / ( ToxP * ToxP ) ; - CoxP_dVb = T1 * ToxP_dVb ; - CoxP_dVs = T1 * ToxP_dVs ; - CoxP_dVg = T1 * ToxP_dVg ; - - CoxP_inv = ToxP / c_eox ; - T1 = 1.0 / c_eox ; - CoxP_inv_dVb = T1 * ToxP_dVb ; - CoxP_inv_dVs = T1 * ToxP_dVs ; - CoxP_inv_dVg = T1 * ToxP_dVg ; - -/* Threshold voltage. (GISL) */ - - Delta = 0.1 ; - - Vbd1 = 2.0 - 0.25 * Vbdz ; - Vbd2 = - Vbdz ; - - Vbdd = Vbd1 - Vbd2 - Delta ; - Vbdd_dVbd = 0.75 * Vbdz_dVbd ; - Vbdd_dVsd = 0.75 * Vbdz_dVsd ; - - T1 = sqrt( Vbdd * Vbdd + 4.0 * Delta ) ; - - Vbdzm = - Vbd1 + 0.5 * ( Vbdd + T1 ) ; - Vbdzm_dVb = 0.25 * Vbdz_dVbd - + 0.5 * ( Vbdd_dVbd + Vbdd * Vbdd_dVbd / T1 ) ; - Vbdzm_dVs = 0.25 * Vbdz_dVsd - + 0.5 * ( Vbdd_dVsd + Vbdd * Vbdd_dVsd / T1 ) ; - - Psum = ( Pb20 - Vbdz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVb = - Vbdz_dVbd ; - Psum_dVs = - Vbdz_dVsd ; - } else { - Psum = epsm10 ; - Psum_dVb = 0.0e0 ; - Psum_dVs = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - -/* Vthp : Vth with pocket. (GISL) */ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbdz ) ) ; - - Qb0_dVb = 0.5 * T1 / Qb0 * ( - Vbdz_dVbd ) ; - Qb0_dVs = 0.5 * T1 / Qb0 * ( - Vbdz_dVsd ) ; - - Vthp = Pb20 + Vfb + Qb0 * CoxP_inv ; - - Vthp_dVb = Qb0_dVb * CoxP_inv + Qb0 * CoxP_inv_dVb ; - Vthp_dVs = Qb0_dVs * CoxP_inv + Qb0 * CoxP_inv_dVs ; - Vthp_dVg = Qb0 * CoxP_inv_dVg ; - -/* dVthLP : Short-channel effect induced by pocket. - * - Vth0 : Vth without pocket. (GISL) */ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbdz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * CoxP_inv ; - - Vth0_dVb = 0.5 * T1 / T2 * ( - Vbdz_dVbd ) * CoxP_inv - + T2 * CoxP_inv_dVb ; - Vth0_dVs = 0.5 * T1 / T2 * ( - Vbdz_dVsd ) * CoxP_inv - + T2 * CoxP_inv_dVs ; - Vth0_dVg = T2 * CoxP_inv_dVg ; - - T1 = C_ESI * CoxP_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / sIN.parl1 / ( sIN.lp * sIN.lp ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVb = T6 * Psum_dVb + T7 * CoxP_inv_dVb ; - dVth0_dVs = T6 * Psum_dVs + T7 * CoxP_inv_dVs ; - dVth0_dVg = T7 * CoxP_inv_dVg ; - - T4 = sIN.scp1 ; - T5 = sIN.scp2 ; - T6 = sIN.scp3 ; - - if (flg_smoothing_pl_vd) { - T8 = Vdsz_lp_sat + Vsdz - lp_vds_dlt ; - T8_dVs = Vsdz_dVsd ; - T9 = sqrt( T8 * T8 + 4.0 * lp_vds_dlt * Vdsz_lp_sat) ; - T7 = -( Vdsz_lp_sat - 0.5 * (T8 + T9) ) ; - T7_dVs = 0.5 * ( T8_dVs + T8 * T8_dVs / T9 ) ; - } - else { - T7 = Vsdz ; - T7_dVs = Vsdz_dVsd ; - } - - T1 = Vthp - Vth0 ; - T2 = T4 + T6 * Psum / sIN.lp ; - T3 = T2 + T5 * T7 ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVb = ( Vthp_dVb - Vth0_dVb ) * dVth0 * T3 - + T1 * dVth0_dVb * T3 - + T1 * dVth0 * T6 * Psum_dVb / sIN.lp ; - - dVthLP_dVs = ( Vthp_dVs - Vth0_dVs ) * dVth0 * T3 - + T1 * dVth0_dVs * T3 - + T1 * dVth0 - * ( T6 * Psum_dVs / sIN.lp - + T5 * T7_dVs ) ; - - dVthLP_dVg = ( Vthp_dVg - Vth0_dVg ) * dVth0 * T3 - + T1 * dVth0_dVg * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVb = 0.0e0 ; - dVthLP_dVs = 0.0e0 ; - dVthLP_dVg = 0.0e0 ; - } - -/* dVthSC : Short-channel effect induced by Vds. (GISL) */ - - /* Modify Pb20 to Pb20b */ - - Vgpa = Vgd - Vfb ; - T1 = 1.0e0 + 4.0e0 * (beta * Vgpa - 1.0e0 ) / ( cnst3 * beta * beta ) ; - if ( T1 > 0.0 ) { - T2 = sqrt(T1) ; - Psi_a = Vgpa + cnst3 * beta / 2.0e0 * ( 1.0e0 - T2 ) ; - Psi_a_dVg = Vgdz_dVgd * ( 1.0e0 - 1.0e0 / T2 ) ; - } else { - Psi_a = Psi_a_dVg = 0.0 ; - } - - T1 = sqrt( ( Pb20 - Psi_a - delta0 ) * ( Pb20 - Psi_a - delta0 ) - + 4.0e0 * delta0 * Pb20 ) ; - Pb20a = Pb20 - 0.5e0 * ( Pb20 - Psi_a - delta0 + T1 ) ; - Pb20a_dVg = 0.5e0 * Psi_a_dVg * ( 1.0e0 + ( Pb20 - Psi_a - delta0 ) / T1 ) ; - Pb20b = Pb20 + sIN.pthrou * ( Pb20a - Pb20 ) ; - Pb20b_dVg = sIN.pthrou * Pb20a_dVg ; - - T1 = C_ESI * CoxP_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = ( Leff - sIN.parl2 ) ; - T4 = 1.0e0 / sIN.parl1 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20b ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVb = T6 * Psum_dVb + T7 * CoxP_inv_dVb ; - dVth0_dVs = T6 * Psum_dVs + T7 * CoxP_inv_dVs ; - dVth0_dVg = T7 * CoxP_inv_dVg + 2.0e0 * T1 * T2 * T4 * ( - Pb20b_dVg ) ; - - T5 = sIN.sc1 ; - T6 = sIN.sc2 ; - T7 = sIN.sc3 ; - - if (flg_smoothing_sc_vd) { - T9 = Vdsz_sc_sat + Vsdz - sc_vds_dlt ; - T9_dVs = Vsdz_dVsd ; - T10 = sqrt( T9 * T9 + 4.0 * sc_vds_dlt * Vdsz_sc_sat) ; - T8 = -(Vdsz_sc_sat - 0.5 * (T9 + T10)) ; - T8_dVs = 0.5 * ( T9_dVs + T9 * T9_dVs / T10 ) ; - } - else { - T8 = Vsdz ; - T8_dVs = Vsdz_dVsd ; - } - - T4 = T5 + T7 * Psum / Leff ; - T4_dVb = T7 * Psum_dVb / Leff ; - T4_dVs = T7 * Psum_dVs / Leff ; - - dVthSC = dVth0 * ( T4 + T6 * T8 ) ; - - dVthSC_dVb = dVth0_dVb * ( T4 + T6 * T8 ) - + dVth0 * ( T4_dVb ) ; - - dVthSC_dVs = dVth0_dVs * ( T4 + T6 * T8 ) - + dVth0 * ( T4_dVs + T6 * T8_dVs ) ; - - dVthSC_dVg = dVth0_dVg * ( T4 + T6 * T8 ) ; - -/* dVthW : narrow-channel effect. (GISL) */ - - T5 = sIN.wfc ; - - T1 = 1.0 / CoxP ; - T2 = T1 * T1 ; - T3 = 1.0 / ( CoxP + T5 / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVb = Qb0_dVb * ( T1 - T3 ) - Qb0 * CoxP_dVb * ( T2 - T4 ) ; - dVthW_dVs = Qb0_dVs * ( T1 - T3 ) - Qb0 * CoxP_dVs * ( T2 - T4 ) ; - dVthW_dVg = - Qb0 * CoxP_dVg * ( T2 - T4 ) ; - -/* dVth : Total variation. - * - Positive dVth means the decrease in Vth. (GISL) */ - - dVthP = dVthSC + dVthLP + dVthW ; - dVthP_dVb = dVthSC_dVb + dVthLP_dVb + dVthW_dVb ; - dVthP_dVs = dVthSC_dVs + dVthLP_dVs + dVthW_dVs ; - dVthP_dVg = dVthSC_dVg + dVthLP_dVg + dVthW_dVg ; - -/* Poly-Depletion Effect (GISL) */ - - T1 = sIN.pgd1 ; - T2 = sIN.pgd2 ; - T3 = sIN.pgd3 ; - - if (flg_smoothing_pde_vg) { - T5 = Vgsz_pol_sat - Vgdz - pol_vgs_dlt ; - /* T5_dVbs = 0.0 ;*/ - T5_dVs = - Vgdz_dVsd ; - T5_dVg = - Vgdz_dVgd ; - T6 = sqrt( T5 * T5 + 4.0 * pol_vgs_dlt * Vgsz_pol_sat ) ; - T7 = Vgsz_pol_sat - 0.5 * (T5 + T6) ; - /* T7_dVb = -0.5 * ( T5_dVb + T5 * T5_dVb / T6 ) ; */ - T7_dVs = -0.5 * ( T5_dVs + T5 * T5_dVs / T6 ) ; - T7_dVg = -0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; - } else { - T7 = Vgdz ; - /* T7_dVb = 0.0 ; */ - T7_dVs = Vgdz_dVsd ; - T7_dVg = Vgdz_dVgd ; - } - - if (flg_smoothing_pde_vd) { - T5 = Vdsz_pol_sat + Vsdz - pol_vds_dlt ; - /* T5_dVb = 0.0 ;*/ - T5_dVs = Vsdz_dVsd ; - /* T5_dVg = 0.0 ;*/ - T6 = sqrt( T5 * T5 + 4.0 * pol_vds_dlt * Vdsz_pol_sat ) ; - T8 = -(Vdsz_pol_sat - 0.5 * (T5 + T6)) ; - /* T8_dVb = 0.5 * ( T5_dVb + T5 * T5_dVb / T6 ) ; */ - T8_dVs = 0.5 * ( T5_dVs + T5 * T5_dVs / T6 ) ; - /* T8_dVg = 0.5 * ( T5_dVg + T5 * T5_dVg / T6 ) ; */ - - } else { - T8 = Vsdz ; - /* T8_dVb = 0.0 ; */ - T8_dVs = Vsdz_dVsd ; - /* T8_dVg = 0.0 ; */ - } - - T9 = - T1 * ( T7 - T2 - T3 * T8 ) - pol2_dlt ; - T9_dVs = - T1 * (T7_dVs - T3 * T8_dVs) ; - T9_dVg = - T1 * (T7_dVg /*- T3 * T8_dVg*/) ; - - T10 = T9 * T9 ; - T10_dVs = 2.0e0 * T9 * T9_dVs ; - T10_dVg = 2.0e0 * T9 * T9_dVg ; - - T11 = sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) ; - T11_dVs = T10_dVs / sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) * 0.5e0 ; - T11_dVg = T10_dVg / sqrt( T10 + 4.0e0 * pol2_dlt * pol_tmp ) * 0.5e0 ; - - dPpgP = ( T11 - T9 ) * 0.5e0 ; - dPpgP_dVs = ( T11_dVs - T9_dVs ) * 0.5e0 ; - dPpgP_dVg = ( T11_dVg - T9_dVg ) * 0.5e0 ; - dPpgP_dVb = 0.0 ; - -/* GISL */ - - T1 = sIN.gidl3 * Vsdz - Vgdz + Vfb - dVthP + dPpgP ; - - E1 = T1 / ToxP ; - - E1_dVb = E1 * ( ( - dVthP_dVb + dPpgP_dVb ) / T1 - ToxP_dVb / ToxP ) ; - E1_dVs = E1 * ( ( sIN.gidl3 * Vsdz_dVsd - - Vgdz_dVsd - dVthP_dVs + dPpgP_dVs) / T1 - - ToxP_dVs / ToxP ) ; - E1_dVg = E1 * ( ( -1.0 - dVthP_dVg + dPpgP_dVg) / T1 - ToxP_dVg / ToxP ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egisl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egisl_dVb = T5 * E1_dVb ; - Egisl_dVs = T5 * E1_dVs ; - Egisl_dVg = T5 * E1_dVg ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egisl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Igisl = T2 * Egisl * Egisl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egisl + sIN.gidl2 * Egp32 ) ; - - Igisl_dVbd = T3 * Egisl_dVb ; - Igisl_dVsd = T3 * Egisl_dVs ; - Igisl_dVgd = T3 * Egisl_dVg ; - - end_of_IGISL: ; - - -/*-----------------------------------------------------------* -* End of PART-2. (label) -*-----------------*/ - -/* end_of_part_2: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-3: Overlap charge -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-------------------------------------------* -* Calculation of Psdl for cases of flg_noqi==1. -*-----------------*/ - - if ( flg_noqi != 0 ) { - - T2 = Vds + Ps0 ; - T2_dVb = Ps0_dVbs ; - T2_dVd = 1.0e0 + Ps0_dVds ; - T2_dVg = Ps0_dVgs ; - - T10 = sIN.clm1 ; - - Aclm = T10 ; - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVb + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVd + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVg + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - Ec = 0.0e0 ; - Ec_dVbs =0.0e0 ; - Ec_dVds =0.0e0 ; - Ec_dVgs =0.0e0 ; - - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - if ( Psl - Vbs > 0 ){ - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - }else{ - Wd = 0e0 ; - Wd_dVbs = 0e0 ; - Wd_dVds = 0e0 ; - Wd_dVgs = 0e0 ; - } - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (simple, default, CLM1 < 1.0) <-- changed 04/Dec/01 -* (orig. "CLM1 must be 1.0") -*-----------------*/ - - if ( sIN.coovlp == 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T2 = - 1.0e+11 ; - yn = sqrt ( ( Psdl - Ps0 - Vds) / T2 ) ; - yn2 = yn * yn ; - yn3 = yn2 * yn ; - - - if ( yn <= Lov ){ - Qgod = ( ( Vgs - Vds ) * Lov - T2 * yn3 / 3.0e0 ) * T1 ; - Qgod_dVbs = ( (-0.5e0) * yn * ( Psdl_dVbs - Ps0_dVbs ) ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - 0.5e0 * yn - * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ) * T1 ; - Qgod_dVgs = ( Lov - 0.5e0 * yn * ( Psdl_dVgs - Ps0_dVgs ) ) * T1 ; - }else{ - T3 = 0.5e0 / yn / T2 ; - yn_dVbs = T3 * ( Psdl_dVbs - Ps0_dVbs ) ; - yn_dVds = T3 * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ; - yn_dVgs = T3 * ( Psdl_dVgs - Ps0_dVgs ) ; - - T4 = (Lov - yn ) * (Lov - yn ) ; - T5 = T4 * (Lov - yn ) ; - Qgod = ( ( Vgs - Vds ) * Lov - T2 / 3.0e0 * ( T5 + yn3 ) ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs - + T2 * T4 * yn_dVbs ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds - + T2 * T4 * yn_dVds ) * T1 ; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs - + T2 * T4 * yn_dVgs ) * T1 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (complete) -*-----------------*/ - - else if( sIN.coovlp > 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T3 = 1e21 / ( pow(Lov , 3e0) + epsm10 ) ; - T1 = C_QE * T3 / ( C_ESI * 4e0 ) ; - T2 = Cox * Weff ; - - Lov2 = Lov * Lov ; - - yn = pow( C_ESI * 5e0 / ( C_QE * T3 ) - * ( Ps0 + Vds - Psdl ) - , 0.2e0 ) ; - yn2 = yn * yn ; - - if ( yn < Lov ) { - Qgod = ( ( Vgs - Vds ) * Lov + T1 / 3e0 * yn2 * yn2 * yn2 ) * T2 ; - Qgod_dVbs = ( yn / 2e0 * ( Ps0_dVbs - Psdl_dVbs ) ) * T2 ; - Qgod_dVds = ( - Lov + yn / 2e0 * ( Ps0_dVds + 1e0 - Psdl_dVds ) ) * T2 ; - Qgod_dVgs = ( Lov + yn / 2e0 * ( Ps0_dVgs - Psdl_dVgs ) ) * T2 ; - } else { - T3 = C_ESI * 5e0 / ( C_QE * T3 ) ; - - Qgod = ( ( Vgs + T1 * 4e0 / 5e0 * yn2 * yn2 * yn - Vds ) * Lov - + T1 / 30e0 * Lov2 * Lov2 * Lov2 - - T1 * yn2 * yn2 / 2e0 * Lov2 ) * T2 ; - Qgod_dVbs = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVbs - Psdl_dVbs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVbs - Psdl_dVbs ) * Lov2 ) - * T2 ; - Qgod_dVds = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVds + 1e0 - Psdl_dVds ) - 1e0 ) - * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVds + 1e0 - Psdl_dVds ) - * Lov2 ) * T2 ; - Qgod_dVgs = ( ( 1e0 + T1 * 4e0 / 5e0 * T3 * ( Ps0_dVgs - Psdl_dVgs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVgs - Psdl_dVgs ) * Lov2 ) - * T2 ; - } - } - -/*-------------------------------------------* -* Overlap charge (off) -*-----------------*/ - - else if( sIN.coovlp < 0 ){ - - Qgos = 0.0e0 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = 0.0e0 ; - - Qgod = 0.0e0 ; - Qgod_dVbs = 0.0e0 ; - Qgod_dVds = 0.0e0 ; - Qgod_dVgs = 0.0e0 ; - - } - - -/*-----------------------------------------------------------* -* End of PART-3. (label) -*-----------------*/ - -/* end_of_part_3: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-4: Substrate-source/drain junction diode. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Cbsj, Cbdj: node-base S/D biases. -*-----------------*/ - - if (sIN.mode == HiSIM_NORMAL_MODE ){ - Vbdj = Vbde ; - Vbsj = Vbse ; - } else { - Vbdj = Vbse ; - Vbsj = Vbde ; - } - - /* Vbdc = Vbsc - Vdsc ;*/ - - js = sIN.js0 * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) / sIN.nj ) ; - jssw = sIN.js0sw * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) - / sIN.njsw ) ; - - Nvtm = sIN.nj / beta ; - - /* ibd */ - isbd = sIN.ad * js + sIN.pd * jssw ; - - if ( Vbdj < sIN.vdiffj ) { - Ibd = isbd * ( exp( Vbdj / Nvtm ) - 1 ) ; - Gbd = isbd / Nvtm * exp( Vbdj / Nvtm ) ; - - } else { - Ibd = isbd * ( exp( sIN.vdiffj / Nvtm ) - 1 ) - + isbd / Nvtm * exp( sIN.vdiffj / Nvtm ) * ( Vbdj - sIN.vdiffj ) ; - Gbd = isbd / Nvtm * exp( sIN.vdiffj / Nvtm ) ; - } - - /* ibs */ - isbs = sIN.as * js + sIN.ps * jssw ; - - if ( Vbsj < sIN.vdiffj ) { - Ibs = isbs * ( exp( Vbsj / Nvtm ) - 1 ) ; - Gbs = isbs / Nvtm * exp( Vbsj / Nvtm ) ; - - } else { - Ibs = isbs * ( exp( sIN.vdiffj / Nvtm ) - 1 ) - + isbs / Nvtm * exp( sIN.vdiffj / Nvtm ) * (Vbsj - sIN.vdiffj ) ; - Gbs = isbs / Nvtm * exp( sIN.vdiffj / Nvtm ) ; - } - - -/*---------------------------------------------------* -* Add Gjmin. -*-----------------*/ - - Ibd += Gjmin * Vbdj ; - Ibs += Gjmin * Vbsj ; - - 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 - */ - - czbd = sIN.cj * sIN.ad ; - czbs = sIN.cj * sIN.as ; - - /* Source Bulk Junction */ - if (sIN.ps > Weff) { - czbssw = sIN.cjsw * ( sIN.ps - Weff ) ; - czbsswg = sIN.cjswg * Weff ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbssw + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbssw > 0.0) - { arg = 1.0 - Vbsj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbs += sIN.pbsw * czbssw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbs += czbssw * sarg ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbssw + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbssw * sIN.mjsw * 0.5 / sIN.pbsw - + czbsswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbssw + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbssw * sIN.mjsw / sIN.pbsw - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbsswg = sIN.cjswg * sIN.ps ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0 ; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbs += czbsswg * sarg ; - } - } - else - { Qbs = Vbsj * (czbs + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbsswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbs = czbs - + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbsswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - /* Drain Bulk Junction */ - if (sIN.pd > Weff) { - czbdsw = sIN.cjsw * ( sIN.pd - Weff ) ; - czbdswg = sIN.cjswg * Weff ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdsw + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdsw > 0.0) - { arg = 1.0 - Vbdj / sIN.pbsw ; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjsw * log(arg)) ; - Qbd += sIN.pbsw * czbdsw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw) ; - Capbd += czbdsw * sarg ; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdsw + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdsw * sIN.mjsw * 0.5 / sIN.pbsw - + czbdswg * sIN.mjswg - * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdsw + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdsw * sIN.mjsw / sIN.pbsw - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - - } else { - czbdswg = sIN.cjswg * sIN.pd ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0 ; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg ; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mjswg * log(arg)) ; - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg) ; - Capbd += czbdswg * sarg ; - } - } - else - { Qbd = Vbdj * (czbd + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdswg * sIN.mjswg * 0.5 / sIN.pbswg) ; - Capbd = czbd - + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdswg * sIN.mjswg / sIN.pbswg ) ; - } - } - - -/*-----------------------------------------------------------* -* End of PART-4. (label) -*-----------------*/ - -/* end_of_part_4: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-5: Noise Calculation. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - if ( sIN.conois != 0 ){ - - NFalp = sIN.nfalp ; - NFtrp = sIN.nftrp ; - Cit = sIN.cit ; - - T1 = Qn0 / C_QE ; - T2 = (Cox+Qn0/(Ps0-Vbs)+Cit)/beta/C_QE ; - T3 = -2.0E0*Qi/C_QE/(Leff-Lred)/Weff-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 ; - Nflic = Ids*Ids*NFtrp/((Leff-Lred)*beta*Weff)*T4 ; - - } else { - Nflic = 0.0 ; - } - - -/*-----------------------------------------------------------* -* End of PART-5. (label) -*-----------------*/ - -/* end_of_part_5: ; */ - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-6: Evaluation of outputs. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Implicit quantities related to Alpha. -*-----------------*/ - - /* note: T1 = 1 + Delta */ - if ( flg_noqi == 0 && VgVt > VgVt_small && Pds > 0.0 ) { - T1 = Achi / Pds ; - Delta = T1 - 1.0e0 ; - Vdsat = VgVt / T1 ; - } else { - Alpha = 1.0 ; - Delta = 0.0 ; - Vdsat = 0.0 ; - Achi = 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 == 0 || 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 ; - - Igate_dVbse = Igate_dVbs ; - Igate_dVdse = Igate_dVds ; - Igate_dVgse = Igate_dVgs ; - - Igidl_dVbse = Igidl_dVbs ; - Igidl_dVdse = Igidl_dVds ; - Igidl_dVgse = Igidl_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 ; - - -/*---------------------------------------------------* -* Case Rs>0 or Rd>0 -*-----------------*/ - - } else { - - -/*-------------------------------------------* -* 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 ; - - 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 ; - - 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 ; - - -/*---------------------------------------------------* -* 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 ; - - } /* end of if ( flg_rsrd == 0 ) blocks */ - - /* for GISL (GIDL in REVERSE mode) */ - if ( flg_rsrd == 0 || Ids < 0.0 ) { - Igisl_dVbde = Igisl_dVbd ; - Igisl_dVsde = Igisl_dVsd ; - Igisl_dVgde = Igisl_dVgd ; - } else { - DJIP = 1.0 / - (1.0 + Rd * (-Ids_dVbs) + ( Rd + Rs ) * Ids_dVds + Rd * (-Ids_dVgs)) ; - Isd_dVbde = (-Ids_dVbs) * DJIP ; - Isd_dVsde = Ids_dVds * DJIP ; - Isd_dVgde = (-Ids_dVgs) * DJIP ; - - Vbd_dVbde = ( 1.0 - Rd * Isd_dVbde ) ; - Vbd_dVsde = - Rd * Isd_dVsde ; - Vbd_dVgde = - Rd * Isd_dVgde ; - - Vsd_dVbde = - ( Rd + Rs ) * Isd_dVbde ; - Vsd_dVsde = ( 1.0 - ( Rd + Rs ) * Isd_dVsde ) ; - Vsd_dVgde = - ( Rd + Rs ) * Isd_dVgde ; - - Vgd_dVbde = - Rd * Isd_dVbde ; - Vgd_dVsde = - Rd * Isd_dVsde ; - Vgd_dVgde = ( 1.0 - Rd * Isd_dVgde ) ; - - Igisl_dVbde = Igisl_dVbd * Vbd_dVbde + Igisl_dVsd * Vsd_dVbde - + Igisl_dVgd * Vgd_dVbde ; - Igisl_dVsde = Igisl_dVbd * Vbd_dVsde + Igisl_dVsd * Vsd_dVsde - + Igisl_dVgd * Vgd_dVsde ; - Igisl_dVgde = Igisl_dVbd * Vbd_dVgde + Igisl_dVsd * Vsd_dVgde - + Igisl_dVgd * Vgd_dVgde ; - } - - -/*---------------------------------------------------* -* 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 ; - Igidl_dVbse *= Vbsc_dVbse ; - Qgos_dVbse *= Vbsc_dVbse ; - Qgod_dVbse *= Vbsc_dVbse ; - } - - if (flg_vbdc == 1) - Igisl_dVbde *= Vbdc_dVbde ; - - if ( flg_vxxc != 0 ) { - - if ( flg_vbsc == -1 ) { - T1 = Vbse - Vbsc ; - } else { - T1 = 0.0 ; - } - - if ( flg_vdsc != 0 ) { - T2 = Vdse - Vdsc ; - } else { - T2 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T3 = Vgse - Vgsc ; - } else { - T3 = 0.0 ; - } - - if ( flg_vbdc != 0 ) { - T4 = Vbde - Vbdc ; - } else { - T4 = 0.0 ; - } - - TX = Ids + T1 * Ids_dVbse + T2 * Ids_dVdse + T3 * Ids_dVgse ; - if ( TX * Ids >= 0.0 ) { - Ids = TX ; - } else { - T7 = Ids / ( Ids - TX ) ; - Ids_dVbse *= T7 ; - Ids_dVdse *= T7 ; - Ids_dVgse *= T7 ; - Ids = 0.0 ; - } - - TX = Qb + T1 * Qb_dVbse + T2 * Qb_dVdse + T3 * Qb_dVgse ; - /*note: The sign of Qb can be changed.*/ - Qb = TX ; - - TX = Qd + T1 * Qd_dVbse + T2 * Qd_dVdse + T3 * Qd_dVgse ; - if ( TX * Qd >= 0.0 ) { - Qd = TX ; - } else { - T7 = Qd / ( Qd - TX ) ; - Qd_dVbse *= T7 ; - Qd_dVdse *= T7 ; - Qd_dVgse *= T7 ; - Qd = 0.0 ; - } - - TX = Qi + T1 * Qi_dVbse + T2 * Qi_dVdse + T3 * Qi_dVgse ; - if ( TX * Qi >= 0.0 ) { - Qi = TX ; - } else { - T7 = Qi / ( Qi - TX ) ; - Qi_dVbse *= T7 ; - Qi_dVdse *= T7 ; - Qi_dVgse *= T7 ; - Qi = 0.0 ; - } - - TX = Isub + T1 * Isub_dVbse + T2 * Isub_dVdse + T3 * Isub_dVgse ; - if ( TX * Isub >= 0.0 ) { - Isub = TX ; - } else { - T7 = Isub / ( Isub - TX ) ; - Isub_dVbse *= T7 ; - Isub_dVdse *= T7 ; - Isub_dVgse *= T7 ; - Isub = 0.0 ; - } - - TX = Igate + T1 * Igate_dVbse + T2 * Igate_dVdse + T3 * Igate_dVgse ; - if ( TX * Igate >= 0.0 ) { - Igate = TX ; - } else { - T7 = Igate / ( Igate - TX ) ; - Igate_dVbse *= T7 ; - Igate_dVdse *= T7 ; - Igate_dVgse *= T7 ; - Igate = 0.0 ; - } - - TX = Igidl + T1 * Igidl_dVbse + T2 * Igidl_dVdse + T3 * Igidl_dVgse ; - if ( TX * Igidl >= 0.0 ) { - Igidl = TX ; - } else { - T7 = Igidl / ( Igidl - TX ) ; - Igidl_dVbse *= T7 ; - Igidl_dVdse *= T7 ; - Igidl_dVgse *= T7 ; - Igidl = 0.0 ; - } - - /* for GISL */ - if ( flg_vbdc == -1 ) { - T5 = Vbde - Vbdc ; - } else { - T5 = 0.0 ; - } - - if ( flg_vdsc != 0 ) { - T6 = Vsde - Vsdc ; - } else { - T6 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T7 = Vgde - Vgdc ; - } else { - T7 = 0.0 ; - } - - TX = Igisl + T5 * Igisl_dVbde + T6 * Igisl_dVsde + T7 * Igisl_dVgde ; - if ( TX * Igisl >= 0.0 ) { - Igisl = TX ; - } else { - T8 = Igisl / ( Igisl - TX ) ; - Igisl_dVbde *= T8 ; - Igisl_dVsde *= T8 ; - Igisl_dVgde *= T8 ; - Igisl = 0.0 ; - } - - TX = Qgod + T1 * Qgod_dVbse + T2 * Qgod_dVdse + T3 * Qgod_dVgse ; - if ( TX * Qgod >= 0.0 ) { - Qgod = TX ; - } else { - T7 = Qgod / ( Qgod - TX ) ; - Qgod_dVbse *= T7 ; - Qgod_dVdse *= T7 ; - Qgod_dVgse *= T7 ; - Qgod = 0.0 ; - } - - TX = Qgos + T1 * Qgos_dVbse + T2 * Qgos_dVdse + T3 * Qgos_dVgse ; - if ( TX * Qgos >= 0.0 ) { - Qgos = TX ; - } else { - T7 = Qgos / ( Qgos - TX ) ; - Qgos_dVbse *= T7 ; - Qgos_dVdse *= T7 ; - Qgos_dVgse *= T7 ; - Qgos = 0.0 ; - } - - } - - -/*-----------------------------------------------------------* -* Warn negative conductance. -* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. -*-----------------*/ - - if ( sIN.mode == HiSIM_NORMAL_MODE ) { - T1 = Ids_dVdse ; - } else { - T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; - } - - 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" , sIN.type , sIN.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 ) ; - } - - if ( Ids_dVbse < 0.0e0 ) { - fprintf( stderr , " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; - flg_ncnv ++ ; - } - if ( T1 < 0.0e0 ) { - fprintf( stderr , " Ids_dVdse = %12.5e\n" , T1 ) ; - flg_ncnv ++ ; - } - if ( Ids_dVgse < 0.0e0 ) { - fprintf( stderr , " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - flg_ncnv ++ ; - } - - -/*-----------------------------------------------------------* -* Redefine overlap charges/capacitances. -*-----------------*/ - -/*---------------------------------------------------* -* Constant capacitance. -*-----------------*/ - - if ( sIN.cocgbo >= 1 ) { - Cgbo = sIN.cgbo * Lgate ; - } else { - Cgbo = 0.0 ; - } - - if ( sIN.cocgdo >= 1 ) { - Cgdo = - sIN.cgdo * Weff ; - Qgod = - Cgdo * ( Vgse - Vdse ) ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = Cgdo ; - Qgod_dVgse = - Qgod_dVdse ; - } else { - Cgdo = Qgos_dVdse + Qgod_dVdse ; - } - - if ( sIN.cocgso >= 1 ) { - Cgso = - sIN.cgso * Weff ; - Qgos = - Cgso * Vgse ; - Qgos_dVbse = 0.0 ; - Qgos_dVdse = 0.0 ; - Qgos_dVgse = - Cgso ; - } else { - Cgso = - ( Qgos_dVbse + Qgod_dVbse - + Qgos_dVdse + Qgod_dVdse - + Qgos_dVgse + Qgod_dVgse ) ; - } - - Cggo = Qgos_dVgse + Qgod_dVgse ; - - -/*---------------------------------------------------* -* Fringing capacitance. -*-----------------*/ - - Cf = C_EOX / ( C_Pi / 2.0e0 ) * Weff - * log( 1.0e0 + sIN.tpoly / sIN. tox ) ; - - Qfd = Cf * ( Vgse - Vdse ) ; - Qfs = Cf * Vgse ; - - -/*---------------------------------------------------* -* Add fringing charge/capacitance to overlap. -*-----------------*/ - - Qgod += Qfd ; - Qgos += Qfs ; - - Cggo += 2.0 * Cf ; - Cgdo += - Cf ; - Cgso += - Cf ; - - -/*-----------------------------------------------------------* -* Assign outputs. -*-----------------*/ - -/*---------------------------------------------------* -* Channel current and conductances. -*-----------------*/ - - /* pOT->ids = sIN.type * Ids ; */ - pOT->ids = Ids ; - pOT->gmbs = (Ids_dVbse >= 0.0) ? Ids_dVbse : Gjmin ; - pOT->gds = (Ids_dVdse >= 0.0) ? Ids_dVdse : Gjmin ; - pOT->gm = (Ids_dVgse >= 0.0) ? Ids_dVgse : Gjmin ; - - -/*---------------------------------------------------* -* Intrinsic charges/capacitances. -*-----------------*/ - - pOT->qg = - ( Qb + Qi ) ; - pOT->qd = Qd ; - pOT->qs = Qi - Qd ; - - pOT->cbgb = Qb_dVgse ; - pOT->cbdb = Qb_dVdse ; - pOT->cbsb = - ( Qb_dVbse + Qb_dVdse + Qb_dVgse ) ; - - pOT->cggb = - Qb_dVgse - Qi_dVgse ; - pOT->cgdb = - Qb_dVdse - Qi_dVdse ; - pOT->cgsb = Qb_dVbse + Qb_dVdse + Qb_dVgse - + Qi_dVbse + Qi_dVdse + Qi_dVgse ; - - pOT->cdgb = Qd_dVgse ; - pOT->cddb = Qd_dVdse ; - pOT->cdsb = - ( Qd_dVgse + Qd_dVdse + Qd_dVbse ) ; - - -/*---------------------------------------------------* -* Overlap capacitances. -*-----------------*/ - - pOT->cgdo = Cgdo ; - pOT->cgso = Cgso ; - pOT->cgbo = Cgbo ; - - -/*---------------------------------------------------* -* Lateral-field-induced capacitance. -*-----------------*/ - - if ( sIN.xqy == 0 ){ - Qy = 0e0 ; - Cqyd = 0e0 ; - Cqyg = 0e0 ; - Cqyb = 0e0 ; - Cqys = 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; - if ( Pslk > Psdl ){ - Pslk = Psdl ; - Pslk_dVbs = Psdl_dVbs ; - Pslk_dVds = Psdl_dVds ; - Pslk_dVgs = Psdl_dVgs ; - } - - T1 = Aclm * ( Vds + Ps0 ) + ( 1.0e0 - Aclm ) * Pslk ; - T1_dVb = Aclm * ( Ps0_dVbs ) + ( 1.0e0 - Aclm ) * Pslk_dVbs ; - T1_dVd = Aclm * ( 1.0 + Ps0_dVds ) + ( 1.0e0 - Aclm ) * Pslk_dVds ; - T1_dVg = Aclm * ( Ps0_dVgs ) + ( 1.0e0 - Aclm ) * Pslk_dVgs ; - - T10 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - T3 = T10 * 1.3 ; - T2 = C_ESI * Weff * T3 ; - - Qy = ( ( Ps0 + Vds - T1 ) / sIN.xqy ) * T2 ; - Cqyd = ( ( Ps0_dVds + 1.0e0 - T1_dVd ) / sIN.xqy ) * T2 ; - if ( Cqyd < 0.0e0 ) Cqyd = 0.0 ; - Cqyg = ( ( Ps0_dVgs - T1_dVg ) / sIN.xqy ) * T2 ; - Cqyb = ( ( Ps0_dVbs - T1_dVb ) / sIN.xqy ) * T2 ; - Cqys = - ( Cqyb + Cqyd + Cqyg ) ; - } - - -/*---------------------------------------------------* -* Add S/D overlap charges/capacitances to intrinsic ones. -* - NOTE: This function depends on coadov, a control option. -*-----------------*/ - - if ( sIN.coadov == 1 ) { - pOT->qg += Qgod + Qgos + Qy ; - pOT->qd += - Qgod - Qy ; - pOT->qs += - Qgos ; - - pOT->cggb += Cggo + Cqyg ; - pOT->cgdb += Cgdo + (-1) * Cqyd ; - pOT->cgsb += Cgso + (-1) * Cqys ; - - pOT->cdgb += - Qgod_dVgse - Cf + Cqyg ; - pOT->cddb += - Qgod_dVdse + Cf - Cqyd ; - pOT->cdsb += Qgod_dVbse + Qgod_dVdse + Qgod_dVgse + Cqys ; - - pOT->cgdo = 0.0 ; - pOT->cgso = 0.0 ; - - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - } - - -/*---------------------------------------------------* -* Substrate/gate/leak currents. -*-----------------*/ - - pOT->isub = Isub ; - - pOT->gbbs = Isub_dVbse ; - pOT->gbds = Isub_dVdse ; - pOT->gbgs = Isub_dVgse ; - - pOT->igateb = (1.0 - sIN.glpart1) * Igate ; - - pOT->ggbbs = (1.0 - sIN.glpart1) * Igate_dVbse ; - pOT->ggbgs = (1.0 - sIN.glpart1) * Igate_dVgse ; - if (sIN.mode == HiSIM_NORMAL_MODE) { - pOT->ggbds = (1.0 - sIN.glpart1) * Igate_dVdse ; - } else { - pOT->ggbds = - (1.0 - sIN.glpart1) * - ( Igate_dVbse + Igate_dVdse + Igate_dVgse ) ; - } - - if (sIN.mode == HiSIM_NORMAL_MODE) { - pOT->igated = sIN.glpart1 * sIN.glpart2 * Igate ; - - pOT->ggdbs = sIN.glpart1 * sIN.glpart2 * Igate_dVbse ; - pOT->ggdds = sIN.glpart1 * sIN.glpart2 * Igate_dVdse ; - pOT->ggdgs = sIN.glpart1 * sIN.glpart2 * Igate_dVgse ; - } else { - pOT->igated = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate ; - - pOT->ggdbs = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVbse ; - pOT->ggdds = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVdse ; - pOT->ggdgs = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVgse ; - } - - if (sIN.mode == HiSIM_NORMAL_MODE) { - pOT->igates = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate ; - - pOT->ggsbs = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVbse ; - pOT->ggsds = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVdse ; - pOT->ggsgs = sIN.glpart1 * (1.0 - sIN.glpart2) * Igate_dVgse ; - } else { - pOT->igates = sIN.glpart1 * sIN.glpart2 * Igate ; - - pOT->ggsbs = sIN.glpart1 * sIN.glpart2 * Igate_dVbse ; - pOT->ggsds = sIN.glpart1 * sIN.glpart2 * Igate_dVdse ; - pOT->ggsgs = sIN.glpart1 * sIN.glpart2 * Igate_dVgse ; - } - - pOT->igidl = (sIN.mode == HiSIM_NORMAL_MODE) ? Igidl : Igisl ; - - pOT->ggidlbs = (sIN.mode == HiSIM_NORMAL_MODE) ? Igidl_dVbse : Igisl_dVbde ; - pOT->ggidlds = (sIN.mode == HiSIM_NORMAL_MODE) ? Igidl_dVdse : Igisl_dVsde ; - pOT->ggidlgs = (sIN.mode == HiSIM_NORMAL_MODE) ? Igidl_dVgse : Igisl_dVgde ; - - pOT->igisl = (sIN.mode == HiSIM_NORMAL_MODE) ? Igisl : Igidl ; - - pOT->ggislbd = (sIN.mode == HiSIM_NORMAL_MODE) ? Igisl_dVbde : Igidl_dVbse ; - pOT->ggislsd = (sIN.mode == HiSIM_NORMAL_MODE) ? Igisl_dVsde : Igidl_dVdse ; - pOT->ggislgd = (sIN.mode == HiSIM_NORMAL_MODE) ? Igisl_dVgde : Igidl_dVgse ; - - -/*---------------------------------------------------* -* Von, Vdsat. -*-----------------*/ - - /* - pOT->von = sIN.type * Vth ; - pOT->vdsat = sIN.type * Vdsat ; - */ - pOT->von = Vth ; - pOT->vdsat = Vdsat ; - - -/*---------------------------------------------------* -* Parasitic conductances. -*-----------------*/ - -/*:org: -* pOT->gd = 1.0e+50 ; -* pOT->gs = 1.0e+50 ; -* modified according to CMIxxxeval.c. -* I don't know the reason why these can be zero. -*/ - pOT->gd = 0.0e0 ; - pOT->gs = 0.0e0 ; - - -/*---------------------------------------------------* -* Junction diode. -*-----------------*/ - - /* - pOT->ibs = sIN.type * Ibs ; - pOT->ibd = sIN.type * Ibd ; - */ - pOT->ibs = Ibs ; - pOT->ibd = Ibd ; - pOT->gbs = Gbse ; - pOT->gbd = Gbde ; - - pOT->qbs = Qbs ; - pOT->qbd = Qbd ; - pOT->capbs = Capbse ; - pOT->capbd = Capbde ; - - -/*-----------------------------------------------------------* -* Warn floating-point exceptions. -* - Function finite() in libm is called. -* - Go to start with info==5. -*-----------------*/ - - T1 = pOT->ids + pOT->gmbs + pOT->gds + pOT->gm ; - T1 = T1 + pOT->qd + pOT->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( "pOT->ids = %12.5e\n" , pOT->ids ) ; - printf( "pOT->gmbs = %12.5e\n" , pOT->gmbs ) ; - printf( "pOT->gds = %12.5e\n" , pOT->gds ) ; - printf( "pOT->gm = %12.5e\n" , pOT->gm ) ; - printf( "pOT->qd = %12.5e\n" , pOT->qd ) ; - printf( "pOT->cdsb = %12.5e\n" , pOT->cdsb ) ; - } - } - - T1 = pOT->isub + pOT->gbbs + pOT->gbds + pOT->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 = pOT->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 = pOT->ibs + pOT->ibd + pOT->gbs + pOT->gbd ; - T1 = T1 + pOT->qbs + pOT->qbd + pOT->capbs + pOT->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 ) { - return( HiSIM_ERROR ) ; - } - - -/*-----------------------------------------------------------* -* Restore values for next calculation. -*-----------------*/ - - /* Confined biases */ - pOT->vbsc = Vbsc ; - pOT->vdsc = Vdsc ; - pOT->vgsc = Vgsc ; - - /* Surface potentials and derivatives w.r.t. internal biases */ - pOT->ps0 = Ps0 ; - pOT->ps0_dvbs = Ps0_dVbs ; - pOT->ps0_dvds = Ps0_dVds ; - pOT->ps0_dvgs = Ps0_dVgs ; - pOT->pds = Pds ; - pOT->pds_dvbs = Pds_dVbs ; - pOT->pds_dvds = Pds_dVds ; - pOT->pds_dvgs = Pds_dVgs ; - - /* Derivatives of channel current w.r.t. internal biases */ - pOT->ids_dvbs = Ids_dVbs ; - pOT->ids_dvds = Ids_dVds ; - pOT->ids_dvgs = Ids_dVgs ; - - -/*-----------------------------------------------------------* -* etc. -*-----------------*/ - - pOT->nf = Nflic ; - pOT->mu = Mu ; - pOT->qg_int = - ( Qb + Qi ) ; - pOT->qd_int = Qd ; - pOT->qs_int = Qi - Qd ; - pOT->qb_int = Qb ; - - -/*-----------------------------------------------------------* -* End of PART-6. (label) -*-----------------*/ - -/* end_of_part_6: ; */ - - -/*-----------------------------------------------------------* -* Bottom of hsm1eval. -*-----------------*/ - - - -return ( HiSIM_OK ) ; - -} /* end of hsm1eval120 */ - diff --git a/src/spicelib/devices/hisim/hsm1eval1_0.c b/src/spicelib/devices/hisim/hsm1eval1_0.c deleted file mode 100644 index a2cab9c66..000000000 --- a/src/spicelib/devices/hisim/hsm1eval1_0.c +++ /dev/null @@ -1,4572 +0,0 @@ -/*********************************************************************** - HiSIM v1.1.0 - File: hsm1eval1_0.c of HiSIM v1.1.0 - - Copyright (C) 2002 STARC - - June 30, 2002: developed by Hiroshima University and STARC - June 30, 2002: posted by Keiichi MORIKAWA, STARC Physical Design Group -***********************************************************************/ - -/* - * Modified by Paolo Nenzi 2002 - * ngspice integration - */ - -/********************************************************************* -* Memorandum on programming -* -* (1) Bias (x: b|d|g) -* . sIN.vxs : Input argument. -* . Vxse: External bias taking account device type (pMOS->nMOS). -* . Vxsc: Confined bias within a specified region. -* . Vxs : Internal bias taking account Rs/Rd. -* . 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. -* . Ps0z: Modified Ps0. -* . The following variables are calculated as a function of -* modified biases or potential. -* Tox, Cox, (-- with quantum effect) -* Vth*, dVth*, dPpg, Qnm, Qbm, Igs, Ilg. -* . The following variables are calculated using a transform -* function. -* Lred, rp1(<-sIN.rpock1). -* -* (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 and -D1. -* . 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 - -/*-----------------------------------* -* HiSIM macros and structures. -* - All inputs and outputs are defined here. -*-----------------*/ -#include "hisim.h" -#include "hsm1evalenv.h" - -/*===========================================================* -* Function hsm1eval. (HiSIM1.0.x) -*=================*/ -int HSM1evaluate1_0( HiSIM_input sIN, HiSIM_output *pOT, - HiSIM_messenger *pMS) -{ - -/*---------------------------------------------------* -* Local variables. -*-----------------*/ -/* Constans ----------------------- */ -int lp_s0_max = 20 ; -int lp_sl_max = 20 ; -int lp_bs_max = 10 ; -double Ids_tol = 1.0e-10 ; -double Ids_maxvar = 1.0e-1 ; -double dP_max = 0.1e0 ; -double ps_conv = 5.0e-13 ; -double gs_conv = 1.0e-8 ; -/*-----*/ -/** depletion **/ -double znbd3 = 3.0e0 ; -double znbd5 = 5.0e0 ; -double cn_nc3 = C_SQRT_2 / 108e0 ; -/* 5-degree, contact:Chi=5 */ -double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ -double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ -double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ -double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ -double cn_nc55 = 6.36964918866352e-5; /*(1509-1040*sqrt(2))/600000*/ -/** inversion **/ -/* 3-dgree polynomial approx for ( exp[Chi]-1 )^{1/2} */ -double cn_im53 = 2.9693154855770998e-1 ; -double cn_im54 = -7.0536542840097616e-2 ; -double cn_im55 = 6.1152888951331797e-3 ; -/* 3-dgree polynomial approx for ( exp[Chi]-Chi-1 )^{1/2} */ -double cn_ik53 = 2.6864599830664019e-1 ; -double cn_ik54 = -6.1399531828413338e-2 ; -double cn_ik55 = 5.3528499428744690e-3 ; -/** initial guess **/ -double c_ps0ini_2 = 8.0e-4 ; -double c_pslini_1 = 0.3e0 ; -double c_pslini_2 = 3.0e-2 ; -double VgVt_small = 1.0e-12 ; -double Vbs_max = 0.5e0 ; -double Vbs_min = -10.5e0 ; -double Vds_max = 10.5e0 ; -double Vgs_max = 10.5e0 ; -/*-----*/ -double Vbd_max = 20.0e0 ; -double Vbd_min = -10.0e0 ; -/*-----*/ -double epsm10 = 10.0e0 * C_EPS_M ; -double small = 1.0e-50 ; -/*-----*/ -double Vz_dlt = 5.0e-3 ; -/*-----*/ -double Gdsmin = 1.0e-12 ; -/*-----*/ -/* double Gjmin = 1.0e-12 ; */ -double Gjmin = sIN.gmin; /* modified by K.M. for SPICE3f5 */ -/*-----*/ -double cclmmdf = 1.0e-1 ; -/*-----*/ -double qme_dlt = 1.0e-2 ; -double eef_dlt = 1.0e-2 ; -double sti_dlt = -3.0e-3 ; -double pol_dlt = 1.0e-2 ; - -/* Internal flags --------------------*/ -int flg_err = 0 ; /* error level */ -int flg_ncnv = 0 ; /* Flag for negative conductance */ -int flg_rsrd ; /* Flag for bias loop accounting Rs and Rd */ -int flg_iprv ; /* Flag for initial guess of Ids */ -int flg_pprv ; /* 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_vdsc = 0 ; /* Flag for Vds confining */ -int flg_vgsc = 0 ; /* Flag for Vgs confining */ -int flg_vbdc = 0 ; /* Flag for Vgs confining */ -int flg_vxxc = 0 ; /* Flag whether some bias was confined */ -int flg_info = 0 ; - -/* Important Variables in HiSIM -------*/ -/* external bias */ -double Vbse , Vdse , Vgse , Vbde ; -/* confine bias */ -double Vbsc , Vdsc , Vgsc , Vbdc ; -double Vbsc_dVbse = 1.0 ; -/* internal bias */ -double Vbs , Vds , Vgs ; -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 ; -/* Pds := Psl - Ps0 */ -double Pds ; -double Pds_dVbs , Pds_dVds , Pds_dVgs ; -double Pds_ini ; -double Pds_max ; -/* iteration numbers of Ps0 and Psl equations. */ -int lp_s0 , lp_sl ; -/* 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 ; -double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; -/* 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 Vbszm ; -double Vbszm_dVbs , Vbszm_dVds ; -double Vbs1 , Vbs2 , Vbsd ; -double Vbsd_dVbs , Vbsd_dVds ; -double Vzadd , Vzadd_dVds , Vzadd_dA ; -double VzaddA , VzaddA_dVds ; -double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; -double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; -double Ps0Vbsz , Ps0Vbsz_dVbs , Ps0Vbsz_dVds , Ps0Vbsz_dVgs ; -double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; -double Xi0z ; -double Xi0z_dVbs , Xi0z_dVds , Xi0z_dVgs ; -double Xi0zp12 ; -double Xi0zp12_dVbs , Xi0zp12_dVds , Xi0zp12_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_dVbs , Vth0_dVds , Vth0_dVgs ; -/* variation of threshold voltage */ -double dVth ; -double dVth_dVbs , dVth_dVds , dVth_dVgs ; -double dVth0 ; -double dVth0_dVbs , dVth0_dVds , dVth0_dVgs ; -double dVthSC ; -double dVthSC_dVbs , dVthSC_dVds , dVthSC_dVgs ; -double dVthW ; -double dVthW_dVbs , dVthW_dVds , dVthW_dVgs ; -/* 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 , VgVt_dVds , VgVt_dVgs ; -double Delta , Vdsat ; -/*-----*/ -/* Q_B and capacitances */ -double Qb , Qb_dVbs , Qb_dVds , Qb_dVgs ; -double Qb_dVbse , Qb_dVdse , Qb_dVgse ; -/* Q_I and capacitances */ -double Qi , Qi_dVbs , Qi_dVds , Qi_dVgs ; -double Qi_dVbse , Qi_dVdse , Qi_dVgse ; -/* Q_D and capacitances */ -double Qd , Qd_dVbs , Qd_dVds , Qd_dVgs ; -double Qd_dVbse , Qd_dVdse , Qd_dVgse ; -/* 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 ; -/* (for debug) */ -double user1 , user2 , user3 , user4 ; - -/* constants ------- */ -double beta ; -double beta2 ; -/* device instances */ -double Leff , Leff_inv ; -double Weff ; -double Ldby ; -double Nsub , q_Nsub ; -double Nin ; -double Pb2 ; -double Pb20 ; -double Pb2c ; -double Eg , Eg300 ; -double Vfb ; -/* PART-1 ---------- */ -double Psum ; -double Psum_dVbs ; -double Psum_dVds ; -double sqrt_Psum ; -double cnst0 , cnst1 ; -double fac1 ; -double fac1_dVbs , fac1_dVds , fac1_dVgs ; -double fac1p2 ; -/*-----*/ -double fs01 ; -double fs01_dPs0 , fs01_dChi ; -double fs01_dVbs , fs01_dVds , fs01_dVgs ; -double fs02 ; -double fs02_dPs0 , fs02_dChi ; -double fs02_dVbs , fs02_dVds , fs02_dVgs ; -double fsl1 ; -double fsl1_dPsl ; -double fsl1_dVbs , fsl1_dVds ; -double fsl2 ; -double fsl2_dPsl ; -double fsl2_dVbs , fsl2_dVds ; -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 ; -double Qn0_dVbs , Qn0_dVds , Qn0_dVgs ; -double Qb0 ; -double Qb0_dVbs , Qb0_dVds , Qb0_dVgs ; -double Qn00 ; -double Qn00_dVbs , Qn00_dVds , Qn00_dVgs ; -/* unused: -* double Qnl ; -*/ -/*-----*/ -double Qbnm ; -double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; -double DtPds ; -double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; -/*-----*/ -double Fid2 ; -double Fid2_dVbs , Fid2_dVds , Fid2_dVgs ; -double Fid3 ; -double Fid3_dVbs , Fid3_dVds , Fid3_dVgs ; -double Fid4 ; -double Fid4_dVbs , Fid4_dVds , Fid4_dVgs ; -double Fid5 ; -double Fid5_dVbs , Fid5_dVds , Fid5_dVgs ; -/*-----*/ -double PVds0 ; -double XiVds0 ; -double XiVds0p12 ; -double XiVds0p12_dVbs , XiVds0p12_dVds , XiVds0p12_dVgs ; -double XiVds0p32 ; -double XiVds0p32_dVbs , XiVds0p32_dVds , XiVds0p32_dVgs ; -double Qbm ; -double Qbm_dVbs , Qbm_dVds , Qbm_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 ; -double Qdrat_dVbs , Qdrat_dVds , Qdrat_dVgs ; -double Idd ; -double Idd_dVbs , Idd_dVds , Idd_dVgs ; -double Qnm ; -double Qnm_dVbs , Qnm_dVds , Qnm_dVgs ; -/*-----*/ -double Fdd ; -double Fdd_dVbs , Fdd_dVds , Fdd_dVgs ; -/*-----*/ -double Eeff ; -double Eeff_dVbs , Eeff_dVds , Eeff_dVgs ; -double Rns ; -double Mu ; -double Mu_dVbs , Mu_dVds , Mu_dVgs ; -double Muun , Muun_dVbs , Muun_dVds , Muun_dVgs ; -double Ey ; -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 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 Vdep ; -double Vdep_dVbs , Vdep_dVds , Vdep_dVgs ; -double Epkf ; -double Epkf_dVbs , Epkf_dVds , Epkf_dVgs ; -/**/ -/*-----*/ -/* PART-3 (overlap) */ -double yn , yn2 , yn3 ; -double yn_dVbs , yn_dVds , yn_dVgs ; -double yned , yned2 ; -double yned_dVbs , yned_dVds , yned_dVgs ; -double Lov , Lov2 , Lov23 ; -double Ndsat , Gjnp; -double Qgos , Qgos_dVbs , Qgos_dVds , Qgos_dVgs ; -double Qgos_dVbse , Qgos_dVdse , Qgos_dVgse ; -double Qgod , Qgod_dVbs , Qgod_dVds , Qgod_dVgs ; -double Qgod_dVbse , Qgod_dVdse , Qgod_dVgse ; -double Cggo , Cgdo , Cgso , Cgbo ; -/* fringing capacitance */ -double Cf ; -double Qfd , Qfs ; -/* PART-4 (junction diode) */ -double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; -double js ; -double jssw ; -double isbs ; -double isbd ; -double Nvtm ; -/* junction capacitance */ -double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; -double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; -double arg , sarg ; -/* PART-5 (noise) */ -/* matsu */ -double NFalp , NFtrp , Freq , Cit , Nflic ; -/* Bias iteration accounting Rs/Rd */ -int lp_bs ; -double Ids_last ; -double vtol_iprv = 2.0e-1 ; -double vtol_pprv = 5.0e-2 ; -double Vbsc_dif , Vdsc_dif , Vgsc_dif , sum_vdif ; -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 ; -/* Junction Bias */ -double Vbsj, Vbdj; -/* Accumulation zone */ -double Psa ; -double Psa_dVbs , Psa_dVds , Psa_dVgs ; -/* CLM */ -double Psdl , Psdl_dVbs , Psdl_dVds , Psdl_dVgs ; -double Ed , Ed_dVbs , Ed_dVds , Ed_dVgs ; -double Ec , Ec_dVbs , Ec_dVds , Ec_dVgs ; -double Lred , Lred_dVbs , Lred_dVds , Lred_dVgs ; -double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; -double Aclm ; -/* Pocket Implant */ -double Vthp, Vthp_dVbs, Vthp_dVds, Vthp_dVgs ; -double dVthLP,dVthLP_dVbs,dVthLP_dVds,dVthLP_dVgs ; -double LEY ; -/* Poly-Depletion Effect */ -double dPpg , dPpg_dVds , dPpg_dVgs ; -/* Quantum Effect */ -double Tox , Tox_dVbs , Tox_dVds , Tox_dVgs ; -double dTox , dTox_dVbs , dTox_dVds , dTox_dVgs ; -double Cox , Cox_dVbs , Cox_dVds , Cox_dVgs ; -double Cox_inv , Cox_inv_dVbs , Cox_inv_dVds , Cox_inv_dVgs ; -double Vthq, Vthq_dVbs , Vthq_dVds ; -/* Igs , Ilg */ -double Egp12 , Egp32 ; -double E0 ; -double E1 , E1_dVbs , E1_dVds , E1_dVgs ; -double E2 , E2_dVbs , E2_dVds , E2_dVgs ; -double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; -double Egidl , Egidl_dVbs , Egidl_dVds , Egidl_dVgs ; -double Igs , Igs_dVbs , Igs_dVds , Igs_dVgs ; -double Igs_dVbse , Igs_dVdse , Igs_dVgse ; -double Ilg , Ilg_dVbs , Ilg_dVds , Ilg_dVgs ; -double Ilg_dVbse , Ilg_dVdse , Ilg_dVgse ; -double Cox0 ; -double Lgate ; -double rp1 , rp1_dVds ; -/* connecting function */ -double FD2 , FD2_dVbs , FD2_dVds , FD2_dVgs ; -double FMD , FMD_dVds ; -/* Phonon scattering */ -double Wgate ; -double mueph ; -/* temporary vars.-- */ -double T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ; -double TX , TX_dVbs , TX_dVds , TX_dVgs ; -double TY , TY_dVbs , TY_dVds , TY_dVgs ; -double T1_dVbs , T1_dVds , T1_dVgs ; -double T2_dVbs , T2_dVds , T2_dVgs ; -double T3_dVbs , T3_dVds , T3_dVgs ; -double T4_dVbs , T4_dVds , T4_dVgs ; -double T5_dVbs , T5_dVds , T5_dVgs ; -double T6_dVbs , T6_dVds , T6_dVgs ; -double T7_dVbs , T7_dVds , T7_dVgs ; -double T8_dVbs , T8_dVds , T8_dVgs ; -double T9_dVbs , T9_dVds , T9_dVgs ; -double T10 , T20 , T21 , T30 , T31 ; - -/* intrinsic finging capacitance */ -double Cgdf, Cgdfring; - - -/*================ Start of executable code.=================*/ - - flg_info = sIN.info ; - -/*-----------------------------------------------------------* -* Change units into CGS. -* - This section may be moved to an interface routine. -*-----------------*/ - -/* device instances */ - sIN.xl *= C_m2cm ; - sIN.xw *= C_m2cm ; - sIN.as *= C_m2cm_p2 ; - sIN.ad *= C_m2cm_p2 ; - sIN.ps *= C_m2cm ; - sIN.pd *= C_m2cm ; - -/* model parameters */ - sIN.tox *= C_m2cm ; - sIN.xld *= C_m2cm ; - sIN.xwd *= C_m2cm ; - - sIN.xj *= C_m2cm ; - - sIN.lp *= C_m2cm ; - sIN.xpolyd *= C_m2cm ; - sIN.tpoly *= C_m2cm ; - - sIN.rs *= C_m2cm ; - sIN.rd *= C_m2cm ; - - sIN.sc3 *= C_m2cm ; - sIN.scp3 *= C_m2cm ; - sIN.parl2 *= C_m2cm ; - - sIN.wfc *= C_m2cm ; - sIN.clm2 /= C_m2cm ; - - sIN.rpock1 *= C_m2cm_p1o2 ; - - sIN.qme1 *= C_m2cm ; - sIN.qme3 *= C_m2cm ; - - sIN.gidl1 /= C_m2cm ; - - sIN.gleak1 /= C_m2cm ; - - sIN.cgso /= C_m2cm ; - sIN.cgdo /= C_m2cm ; - sIN.cgbo /= C_m2cm ; - - sIN.js0 /= C_m2cm_p2 ; - sIN.js0sw /= C_m2cm ; - - sIN.cj /= C_m2cm_p2 ; - sIN.cjsw /= C_m2cm ; - sIN.cjswg /= C_m2cm ; - -/*-----------------------------------------------------------* -* Start of the routine. (label) -*-----------------*/ -start_of_routine: - - - -/*-----------------------------------------------------------* -* Temperature dependent constants. -*-----------------*/ - -/* Inverse of the thermal voltage */ - beta = C_QE / ( C_KB * sIN.temp ) ; - beta2 = beta * beta ; - -/* Band gap */ - Eg = C_Eg0 - sIN.temp - * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; - - Eg300 = C_Eg0 - C_T300 - * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ; - -/* Intrinsic carrier concentration */ - Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) - * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ; - -/*-----------------------------------------------------------* -* Fixed part. -*-----------------*/ - - -/* Lgate in [cm] / [m] */ - Lgate = sIN.xl ; - Wgate = sIN.xw ; - -/* Phonon Scattering */ - T1 = log( Wgate ) ; - T2 = sIN.w0 - T1 - sti_dlt ; - T3 = T2 * T2 ; - T4 = sqrt( T3 + 4.0 * sti_dlt * sIN.w0 ) ; - T5 = sIN.w0 - ( T2 - T4 ) / 2 ; - mueph = sIN.mueph1 + sIN.mueph2 * T5 ; - -/* Metallurgical channel geometry */ - Weff = sIN.xw - 2.0e0 * sIN.xwd ; - Leff = sIN.xl - 2.0e0 * sIN.xld ; - Leff_inv = 1.0e0 / Leff ; - -/* Flat band voltage */ - Vfb = sIN.vfbc ; - -/* Surface impurity profile */ - - if( Lgate > sIN.lp ){ - Nsub = ( sIN.nsubc * ( Lgate - sIN.lp ) - + sIN.nsubp * sIN.lp ) / Lgate ; - } else { - Nsub = sIN.nsubp - + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Lgate ) / sIN.lp ; - } - - q_Nsub = C_QE * Nsub ; - -/* 2 phi_B */ - /* @temp, with pocket */ - Pb2 = 2.0e0 / beta * log( Nsub / Nin ); - /* @300K, with pocket */ - Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; - /* @300K, w/o pocket */ - Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ; - -/* Debye length */ - Ldby = sqrt( C_ESI / beta / q_Nsub ) ; - -/* Coefficient of the F function for bulk charge */ - cnst0 = q_Nsub * Ldby * C_SQRT_2 ; - -/* cnst1: n_{p0} / p_{p0} */ - T1 = Nin / Nsub ; - cnst1 = T1 * T1 ; -/* Cox (clasical) */ - Cox0 = C_EOX / sIN.tox ; - - - -/*-----------------------------------------------------------* -* Exchange bias conditions according to MOS type. -* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 -* are assumed.) -*-----------------*/ - - /* - Vbse = sIN.type * sIN.vbs ; - Vdse = sIN.type * sIN.vds ; - Vgse = sIN.type * sIN.vgs ; - Vbde = Vbse - Vdse ; - */ - /* modified by K. M. for SPICE3f5 */ - Vbse = sIN.vbs; - Vdse = sIN.vds; - Vgse = sIN.vgs; - Vbde = Vbse - Vdse; - - -/*---------------------------------------------------* -* Cramp too large biases. -* -note: Quantities are extrapolated in PART-5. -*-----------------*/ - - if ( Vbse < Vbs_min ) { - flg_vbsc = -1 ; - Vbsc = Vbs_min ; - } else if ( Vbse > 0.0 ) { - flg_vbsc = 1 ; - T1 = Vbse / Vbs_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbsc = Vbse / T2 ; - Vbsc_dVbse = Vbs_max * Vbs_max - / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; - } else { - flg_vbsc = 0 ; - Vbsc = Vbse ; - } - - - if ( Vdse > Vds_max ) { - flg_vdsc = 1 ; - Vdsc = Vds_max ; - } else { - flg_vdsc = 0 ; - Vdsc = Vdse ; - } - - if ( Vgse > Vgs_max ) { - flg_vgsc = 1 ; - Vgsc = Vgs_max ; - } else { - flg_vgsc = 0 ; - Vgsc = Vgse ; - } - - if ( Vbde < Vbd_min ) { - flg_vbdc = -1 ; - Vbdc = Vbd_min ; - } else if ( Vbde > Vbd_max ) { - Vbdc = Vbd_max ; - flg_vbdc = 1 ; - } else { - Vbdc = Vbde ; - flg_vbdc = 0 ; - } - - if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || - flg_vbdc != 0 ) { - flg_vxxc = 1 ; - } - - -/*-------------------------------------------------------------------* -* Set flags. -*-----------------*/ - - flg_rsrd = 0 ; - flg_iprv = 0 ; - flg_pprv = 0 ; - - Rs = sIN.rs / Weff ; - Rd = sIN.rd / Weff ; - - if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { - flg_rsrd = 1 ; - } - - if ( sIN.has_prv == 1 ) { - - Vbsc_dif = Vbsc - sIN.vbsc_prv ; - Vdsc_dif = Vdsc - sIN.vdsc_prv ; - Vgsc_dif = Vgsc - sIN.vgsc_prv ; - - sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) - + fabs( Vgsc_dif ) ; - - if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} - if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} - } - - if ( flg_rsrd == 0 ) { - lp_bs_max = 1 ; - flg_iprv = 0 ; - } - - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* -* Bias loop: iteration to solve the system of equations of -* the small circuit taking account Rs and Rd. -* - Vxs are internal (or effective) biases. -* - Equations: -* Vbs = Vbsc - Rs * Ids -* Vds = Vdsc - ( Rs + Rd ) * Ids -* Vgs = Vgsc - Rs * Ids -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initial guesses for biases. -*-----------------*/ - - if ( flg_iprv == 1 ) { - - sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; - sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; - sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; - - dVbs = Vbsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; - dVds = Vdsc_dif * ( 1.0 - - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; - dVgs = Vgsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; - - /* - Ids = sIN.type * sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - */ - Ids = sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - - T1 = ( Ids - sIN.ids_prv ) ; - T2 = fabs( T1 ) ; - if ( Ids_maxvar * sIN.ids_prv < T2 ) { - Ids = sIN.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 ; - } - } - - Vbs = Vbsc - Ids * Rs ; - - Vds = Vdsc - Ids * ( Rs + Rd ) ; - if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } - - Vgs = Vgsc - Ids * Rs ; - - if ( flg_pprv == 1 ) { - - Ps0 = sIN.ps0_prv ; - - Ps0_dVbs = sIN.ps0_dvbs_prv ; - Ps0_dVds = sIN.ps0_dvds_prv ; - Ps0_dVgs = sIN.ps0_dvgs_prv ; - - Pds = sIN.pds_prv ; - - Pds_dVbs = sIN.pds_dvbs_prv ; - Pds_dVds = sIN.pds_dvds_prv ; - Pds_dVgs = sIN.pds_dvgs_prv ; - } - - -/*-----------------------------------------------------------* -* start of the loop. -*-----------------*/ - - for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { - - - Ids_last = Ids ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-1: Basic device characteristics. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initialization. -*-----------------*/ - /* Initialization of counters is needed for restart. */ - lp_s0 = 0 ; - lp_sl = 0 ; - -/*-----------------------------------------------------------* -* Vxsz: Modified bias introduced to realize symmetry at Vds=0. -*-----------------*/ - - T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; - - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVds = 0.0 ; - } - - Vbsz = Vbs + Vzadd ; - Vbsz_dVbs = 1.0 ; - Vbsz_dVds = Vzadd_dVds ; - - Vdsz = Vds + 2 * Vzadd ; - Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; - - Vgsz = Vgs + Vzadd ; - Vgsz_dVgs = 1.0 ; - Vgsz_dVds = Vzadd_dVds ; - - -/*-----------------------------------------------------------* -* Quantum effect -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / C_EOX * T2 + sIN.qme2 ; - - T3 = - 0.5 * sIN.tox / C_EOX * T1 / T2 ; - Vthq_dVbs = T3 * Vbsz_dVbs ; - Vthq_dVds = T3 * Vbsz_dVds ; - - - T1 = - Vfb - sIN.qme2 ; - T2 = Vgsz - Vthq ; - T3 = sIN.qme1 * T1 * T1 + sIN.qme3 ; - T4 = sIN.qme1 * T2 * T2 + sIN.qme3 ; - - T5 = T4 - T3 - qme_dlt ; - - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T4 - T3 + qme_dlt ) / T6 ) ; - - T8 = 2.0 * sIN.qme1 * T2 * T7 ; - - dTox_dVbs = T8 * ( - Vthq_dVbs ) ; - dTox_dVds = T8 * ( Vgsz_dVds - Vthq_dVds ) ; - dTox_dVgs = T8 * ( Vgsz_dVgs ) ; - - Tox = sIN.tox + dTox ; - Tox_dVbs = dTox_dVbs ; - Tox_dVds = dTox_dVds ; - Tox_dVgs = dTox_dVgs ; - - Cox = C_EOX / Tox ; - T1 = - C_EOX / ( Tox * Tox ) ; - Cox_dVbs = T1 * Tox_dVbs ; - Cox_dVds = T1 * Tox_dVds ; - Cox_dVgs = T1 * Tox_dVgs ; - - Cox_inv = Tox / C_EOX ; - T1 = 1.0 / C_EOX ; - Cox_inv_dVbs = T1 * Tox_dVbs ; - Cox_inv_dVds = T1 * Tox_dVds ; - Cox_inv_dVgs = T1 * Tox_dVgs ; - - -/*-----------------------------------------------------------* -* Threshold voltage. -*-----------------*/ - - Delta = 0.1 ; - - Vbs1 = 2.0 - 0.25 * Vbsz ; - Vbs2 = - Vbsz ; - - Vbsd = Vbs1 - Vbs2 - Delta ; - Vbsd_dVbs = 0.75 * Vbsz_dVbs ; - Vbsd_dVds = 0.75 * Vbsz_dVds ; - - T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; - - Vbszm = - Vbs1 + 0.5 * ( Vbsd + T1 ) ; - Vbszm_dVbs = 0.25 * Vbsz_dVbs - + 0.5 * ( Vbsd_dVbs + Vbsd * Vbsd_dVbs / T1 ) ; - Vbszm_dVds = 0.25 * Vbsz_dVds - + 0.5 * ( Vbsd_dVds + Vbsd * Vbsd_dVds / T1 ) ; - - Psum = ( Pb20 - Vbsz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVbs = - Vbsz_dVbs ; - Psum_dVds = - Vbsz_dVds ; - } else { - Psum = epsm10 ; - Psum_dVbs = 0.0e0 ; - Psum_dVds = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - - - -/*---------------------------------------------------* -* Vthp : Vth with pocket. -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Qb0_dVbs = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; - Qb0_dVds = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; - - Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; - - Vthp_dVbs = Qb0_dVbs * Cox_inv + Qb0 * Cox_inv_dVbs ; - Vthp_dVds = Qb0_dVds * Cox_inv + Qb0 * Cox_inv_dVds ; - Vthp_dVgs = Qb0 * Cox_inv_dVgs ; - -/*-------------------------------------------* -* dVthLP : Short-channel effect induced by pocket. -* - Vth0 : Vth without pocket. -*-----------------*/ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbsz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * Cox_inv ; - - Vth0_dVbs = 0.5 * T1 / T2 * ( - Vbsz_dVbs ) * Cox_inv - + T2 * Cox_inv_dVbs ; - Vth0_dVds = 0.5 * T1 / T2 * ( - Vbsz_dVds ) * Cox_inv - + T2 * Cox_inv_dVds ; - Vth0_dVgs = T2 * Cox_inv_dVgs ; - - LEY = sIN.parl1 * sIN.lp ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / ( LEY * LEY ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - T1 = Vthp - Vth0 ; - T2 = sIN.scp1 + sIN.scp3 * Psum / sIN.lp ; - T3 = T2 + sIN.scp2 * Vdsz ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVbs = ( Vthp_dVbs - Vth0_dVbs ) * dVth0 * T3 - + T1 * dVth0_dVbs * T3 - + T1 * dVth0 * sIN.scp3 * Psum_dVbs / sIN.lp ; - dVthLP_dVds = ( Vthp_dVds - Vth0_dVds ) * dVth0 * T3 - + T1 * dVth0_dVds * T3 - + T1 * dVth0 - * ( sIN.scp3 * Psum_dVds / sIN.lp - + sIN.scp2 * Vdsz_dVds ) ; - - dVthLP_dVgs = ( Vthp_dVgs - Vth0_dVgs ) * dVth0 * T3 - + T1 * dVth0_dVgs * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVbs = 0.0e0 ; - dVthLP_dVds = 0.0e0 ; - dVthLP_dVgs = 0.0e0 ; - } - -/*---------------------------------------------------* -* dVthSC : Short-channel effect induced by Vds. -*-----------------*/ - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = sIN.parl1 * ( Lgate - sIN.parl2 ) ; - T4 = 1.0e0 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - - T4 = sIN.sc1 + sIN.sc3 * Psum / Lgate ; - T4_dVbs = sIN.sc3 * Psum_dVbs / Lgate ; - T4_dVds = sIN.sc3 * Psum_dVds / Lgate ; - - T5 = sIN.sc2 ; - - dVthSC = dVth0 * ( T4 + T5 * Vdsz ) ; - - dVthSC_dVbs = dVth0_dVbs * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVbs ) ; - - dVthSC_dVds = dVth0_dVds * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVds + T5 * Vdsz_dVds ) ; - - dVthSC_dVgs = dVth0_dVgs * ( T4 + T5 * Vdsz ) ; - -/*---------------------------------------------------* -* dVthW : narrow-channel effect. -*-----------------*/ - - T1 = 1.0 / Cox ; - T2 = T1 * T1 ; - T3 = 1.0 / ( Cox + sIN.wfc / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVbs = Qb0_dVbs * ( T1 - T3 ) - - Qb0 * Cox_dVbs * ( T2 - T4 ) ; - dVthW_dVds = Qb0_dVds * ( T1 - T3 ) - - Qb0 * Cox_dVds * ( T2 - T4 ) ; - dVthW_dVgs = - Qb0 * Cox_dVgs * ( T2 - T4 ) ; - -/*---------------------------------------------------* -* dVth : Total variation. -* - Positive dVth means the decrease in Vth. -*-----------------*/ - - dVth = dVthSC + dVthLP + dVthW ; - dVth_dVbs = dVthSC_dVbs + dVthLP_dVbs + dVthW_dVbs ; - dVth_dVds = dVthSC_dVds + dVthLP_dVds + dVthW_dVds ; - dVth_dVgs = dVthSC_dVgs + dVthLP_dVgs + dVthW_dVgs ; - - - -/*---------------------------------------------------* -* Vth : Threshold voltage. -*-----------------*/ - - Vth = Vthp - dVth ; - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - dPpg = Nsub / sIN.nsubc * sIN.pgd1 - * exp( Vgsz - sIN.pgd2 - sIN.pgd3 * Vdsz ) ; - dPpg_dVds = - sIN.pgd3 * dPpg * Vdsz_dVds - + dPpg * Vgsz_dVds ; - dPpg_dVgs = dPpg * Vgsz_dVgs ; - - T1 = 1.0e0 - dPpg - pol_dlt ; - T1_dVds = - dPpg_dVds ; - T1_dVgs = - dPpg_dVgs ; - T2 = sqrt( T1 * T1 + 4.0e0 * pol_dlt ) ; - - dPpg = 1.0e0 - 0.5e0 * ( T1 + T2 ) ; - dPpg_dVds = - 0.5e0 * ( T1_dVds + T1 * T1_dVds / T2 ) ; - dPpg_dVgs = - 0.5e0 * ( T1_dVgs + T1 * T1_dVgs / T2 ) ; - - - -/*---------------------------------------------------* -* Vgp : Effective gate bias with SCE & RSCE & flatband. -*-----------------*/ - - Vgp = Vgs - Vfb + dVth - dPpg ; - - Vgp_dVbs = dVth_dVbs ; - Vgp_dVds = dVth_dVds - dPpg_dVds ; - Vgp_dVgs = 1.0e0 + dVth_dVgs - dPpg_dVgs ; - -/*---------------------------------------------------* -* Vgs_fb : Actual flatband voltage taking account Vbs. -* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . -*------------------*/ - - Vgs_fb = Vfb - dVth + dPpg + Vbs ; - - - -/*-----------------------------------------------------------* -* Constants in the equation of Ps0 . -*-----------------*/ - - fac1 = cnst0 * Cox_inv ; - fac1_dVbs = cnst0 * Cox_inv_dVbs ; - fac1_dVds = cnst0 * Cox_inv_dVds ; - fac1_dVgs = cnst0 * Cox_inv_dVgs ; - - fac1p2 = fac1 * fac1 ; - -/*-----------------------------------------------------------* -* Accumulation zone. (zone-A) -* - evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Vgs < Vgs_fb ) { - - -/*---------------------------------------------------* -* Evaluation of Ps0. -* - Psa : Analytical solution of -* Cox( Vgp - Psa ) = cnst0 * Qacc -* where Qacc is the 3-dgree series of (fdep)^{1/2}. -* The unkown is transformed to Chi=beta(Ps0-Vbs). -* - Ps0_min : |Ps0_min| when Vbs=0. -*-----------------*/ - - Ps0_min = Eg - Pb2 ; - - TX = beta * ( Vgp - Vbs ) ; - - TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; - TX_dVds = beta * Vgp_dVds ; - TX_dVgs = beta * Vgp_dVgs ; - - TY = Cox / ( beta * cnst0 ) ; - - T1 = 1.0 / ( beta * cnst0 ) ; - TY_dVbs = T1 * Cox_dVbs ; - TY_dVds = T1 * Cox_dVds ; - TY_dVgs = T1 * Cox_dVgs ; - - 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 ; - - Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; - Ac31_dVbs = - 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac31_dVds = - 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac31_dVgs = - 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Ac3 = Ac31 * Ac31 ; - - Ac3_dVbs = 2.0 * Ac31 * Ac31_dVbs ; - Ac3_dVds = 2.0 * Ac31 * Ac31_dVds ; - Ac3_dVgs = 2.0 * Ac31 * Ac31_dVgs ; - - Ac2 = sqrt( Ac4 + Ac3 ) ; - Ac2_dVbs = 0.5 * ( Ac4_dVbs + Ac3_dVbs ) / Ac2 ; - Ac2_dVds = 0.5 * ( Ac4_dVds + Ac3_dVds ) / Ac2 ; - Ac2_dVgs = 0.5 * ( Ac4_dVgs + Ac3_dVgs ) / Ac2 ; - - Ac1 = -7.0 * C_SQRT_2 - + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; - - Ac1_dVbs = Ac2_dVbs - + 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac1_dVds = Ac2_dVds - + 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac1_dVgs = Ac2_dVgs - + 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Acd = pow( Ac1 , C_1o3 ) ; - - T1 = C_1o3 / ( Acd * Acd ) ; - Acd_dVbs = Ac1_dVbs * T1 ; - 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 ; - - Acn_dVbs = - 12.0 * TY_dVbs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVbs ; - Acn_dVds = - 12.0 * TY_dVds - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVds ; - Acn_dVgs = - 12.0 * TY_dVgs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVgs ; - - Chi = Acn / Acd ; - - T1 = 1.0 / ( Acd * Acd ) ; - - Chi_dVbs = ( Acn_dVbs * Acd - Acn * Acd_dVbs ) * T1 ; - Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; - Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; - - Psa = Chi / beta + Vbs ; - - Psa_dVbs = Chi_dVbs / beta + 1.0 ; - Psa_dVds = Chi_dVds / beta ; - Psa_dVgs = Chi_dVgs / beta ; - - T1 = Psa - Vbs ; - T2 = T1 / Ps0_min ; - T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; - - T9 = T2 / T3 / Ps0_min ; - T3_dVbs = T9 * ( Psa_dVbs - 1.0 ) ; - T3_dVds = T9 * ( Psa_dVds ) ; - T3_dVgs = T9 * ( Psa_dVgs ) ; - - Ps0 = T1 / T3 + Vbs ; - - T9 = 1.0 / ( T3 * T3 ) ; - - Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVbs ) - + 1.0 ; - Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVds ) ; - Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVgs ) ; - - - -/*---------------------------------------------------* -* Characteristics. -*-----------------*/ - - T0 = - Weff * Leff ; - T1 = T0 * Cox ; - T2 = ( Vgp - Ps0 ) ; - - Qb = T1 * T2 ; - - Qb_dVbs = T1 * ( Vgp_dVbs - Ps0_dVbs ) - + T0 * Cox_dVbs * T2 ; - Qb_dVds = T1 * ( Vgp_dVds - Ps0_dVds ) - + T0 * Cox_dVds * T2 ; - Qb_dVgs = T1 * ( Vgp_dVgs - Ps0_dVgs ) - + T0 * Cox_dVgs * T2 ; - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Qi = 0.0e0 ; - Qi_dVbs = 0.0e0 ; - Qi_dVds = 0.0e0 ; - Qi_dVgs = 0.0e0 ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - 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 / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; - - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - if ( flg_pprv == 1 ) { - - Ps0_ini = Ps0 + Ps0_dVbs * dVbs - + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; - - T1 = Ps0_ini - Ps0 ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } else { - Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; - } - - } - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { -/*-------------------------------------------* -* Common part. -*-----------------*/ - - Chi = beta * ( Ps0_iniA - Vbs ) ; - -/*-----------------------------------* -* zone-D1/D2 -* - Ps0_ini is the analytical solution of Qs=Qb0 with -* Qb0 being approximated to 3-degree polynomial. -*-----------------*/ - if ( Chi < znbd3 ) { - - TY = beta * ( Vgp - Vbs ) ; - T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; - T2 = 81 + 3 * T1 ; - T3 = -2916 - 81 * T1 + 27 * T1 * TY ; - T4 = 1458 - 81 * ( 54 + T1 ) + 27 * T1 * TY ; - T4 = T4 * T4 ; - T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; - TX = 3 - - ( C_2p_1o3 * T2 ) / ( 3 * T5 ) - + 1 / ( 3 * C_2p_1o3 ) * T5 ; - - Ps0_iniA = TX / beta + Vbs ; - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Weak inversion zone. -*-----------------*/ - } else if ( Vgs <= Vth ) { - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Strong inversion zone. -* - Ps0_iniB : upper bound. -*-----------------*/ - } else { - - T1 = ( Cox * Cox ) / ( cnst0 * cnst0 ) / cnst1 ; - T2 = T1 * Vgp * Vgp ; - T3 = beta + 2.0 / Vgp ; - - Ps0_iniB = log( T2 ) / T3 ; - - T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; - T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; - - Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; - - } - } - - if ( Ps0_ini < Vbs ) { - Ps0_ini = Vbs ; - } - - - -/*---------------------------------------------------* -* Assign initial guess. -*-----------------*/ - - 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 ; - - for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - } - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -* - Qb0 is approximated to 5-dgree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) - / ( fs02 + fs02 ) ; - } else { - fs02 = sqrt( fb * fb + fs01 ) ; - fs02_dPs0 = beta * fb_dChi ; - } - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - } /* end of if ( Chi ... ) else block */ - -/*-------------------------------------------* -* Update Ps0 . -* - cramped to Vbs if Ps0 < Vbs . -*-----------------*/ - - if ( fabs( dPs0 ) > dP_max ) { - dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; - } - - Ps0 = Ps0 + dPs0 ; - - if ( Ps0 < Vbs ) { - Ps0 = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { - break ; - } - - } /* end of Ps0 Newton loop */ - - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - if ( lp_s0 > lp_s0_max ) { - 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. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - cfs1 = cnst1 * exp_bVbs ; - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; - - T2 = 1.0e0 / ( fs02 + fs02 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; - fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) - * T2 ; - } else { - fs02_dPs0 = beta * fb_dChi ; - fs02_dVbs = - beta * fb_dChi ; - } - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - - T1 = cnst0 ; - - Qb0 = T1 * fb ; - Qb0_dVbs = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; - Qb0_dVds = Ps0_dVds * T1 * beta * fb_dChi ; - Qb0_dVgs = Ps0_dVgs * T1 * beta * fb_dChi ; - - 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 ; - - T1 = 1.0 / ( fs02 + fb * fb ) ; - T2 = T1 * T1 ; - - Qn0 = cnst0 * fs01 * T1 ; - - T3 = 2.0 * fb_dChi * fb * beta ; - - Qn0_dVbs = cnst0 * ( - fs01_dVbs * T1 - - fs01 * ( fs02_dVbs - + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; - Qn0_dVds = cnst0 * ( - fs01_dVds * T1 - - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; - Qn0_dVgs = cnst0 * ( - fs01_dVgs * T1 - - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ; - - -/*-------------------------------------------* -* zone-D1. (Ps0) -* - Evaluate basic characteristics and exit from this part. -*-----------------*/ - if ( Chi < znbd3 ) { - - - 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 ; - - T1 = - Weff * Leff ; - - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - if ( Qn0 < Cox * VgVt_small ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - Qi = T1 * Qn0 ; - Qi_dVbs = T1 * Qn0_dVbs ; - Qi_dVds = T1 * Qn0_dVds ; - Qi_dVgs = T1 * Qn0_dVgs ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - -/*-------------------------------------------* -* zone-D2 -*-----------------*/ - - Xi0 = Chi - 1.0e0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - Qn00 = Qn0 ; - Qn00_dVbs = Qn0_dVbs ; - Qn00_dVds = Qn0_dVds ; - Qn00_dVgs = Qn0_dVgs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - - flg_noqi = 0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - T2 = 0.5e0 / Xi0p12 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - flg_noqi = 0 ; - - - } /* end of if ( Chi ... ) block */ - - - -/*-----------------------------------------------------------* -* NOTE: The following sections of this part are only for -* the conductive case. -*-----------------*/ - -/*-----------------------------------------------------------* -* Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 . -*-----------------*/ -/*-----------------------------------------------------------* -* Qn0 : Qi at source side. -* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) -* - Derivatives of fs01 are redefined here. -*-----------------*/ -/* note:------------------------ -* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; -* fs02 = sqrt( Xi0 + fs01 ) ; -*-------------------------------*/ - - Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; - - 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 ; - - Qn0_dVbs = Qn0 - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVds = Qn0 - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVgs = Qn0 - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ; - -/*-----------------------------------------------------------* -* Qb0 : Qb at source side. -*-----------------*/ - - if ( Chi > znbd5 ) { - - Qb0 = cnst0 * Xi0p12 ; - Qb0_dVbs = cnst0 * Xi0p12_dVbs ; - Qb0_dVds = cnst0 * Xi0p12_dVds ; - Qb0_dVgs = cnst0 * Xi0p12_dVgs ; - - } - -/*-----------------------------------------------------------* -* FD2 : connecting function for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - } - -/*-----------------------------------------------------------* -* Modify Qn0 for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; - Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; - Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; - - Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; - - if ( Qn0 < 0.0 ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - } - - - -/*---------------------------------------------------* -* VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) -*-----------------*/ - - VgVt = Qn0 * Cox_inv ; - VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVbs ; - VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVds ; - VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVgs ; - -/*-----------------------------------------------------------* -* make Qi=Qd=Ids=0 if VgVt <= VgVt_small -*-----------------*/ - - - if ( VgVt <= VgVt_small ) { - - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Pds = 0.0 ; - Pds_dVbs = 0.0 ; - Pds_dVds = 0.0 ; - Pds_dVgs = 0.0 ; - - T1 = - Leff * Weff ; - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - - -/*-----------------------------------------------------------* -* Start point of Psl (= Ps0 + Pds) calculation. (label) -*-----------------*/ -start_of_Psl: ; - - exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; - -/*---------------------------------------------------* -* Skip Psl calculation when Vds is very small. -*-----------------*/ - if ( Vds <= epsm10 ) { - Pds = 0.0 ; - Psl = Ps0 ; - goto end_of_loopl ; - } - -/*-----------------------------------------------------------* -* Initial guess for Pds ( = Psl - Ps0 ). -*-----------------*/ - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - if ( flg_pprv == 1 ) { - - Pds_ini = Pds + Pds_dVbs * dVbs - + Pds_dVds * dVds + Pds_dVgs * dVgs ; - - T1 = Pds_ini - Pds ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } - - } - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { - Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ); - - T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; - T2 = T1 - Vds - c_pslini_2 ; - T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; - - Pds_ini = T1 - ( T2 + T3 ) / 2 ; - - 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. -*-----------------*/ - - Pds = Pds_ini ; - Psl = Ps0 + Pds ; - - -/*---------------------------------------------------* -* Calculation of Psl by solving Poisson eqn. -* (beginning of Newton loop) -* - Fsl : Fsl = 0 is the equation to be solved. -* - dPsl : correction value. -*-----------------*/ - - - for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -* - Qb0 is approximated to 5-dgree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) - / ( fsl2 + fsl2 ) ; - } else { - fsl2 = sqrt( fb * fb + fsl1 ) ; - fsl2_dPsl = beta * fb_dChi ; - } - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - - if ( fsl1 < epsm10 * cnst1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - - } - -/*-------------------------------------------* -* Update Psl . -* - cramped to Vbs if Psl < Vbs . -*-----------------*/ - - if ( fabs( dPsl ) > dP_max ) { - dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; - } - - Psl = Psl + dPsl ; - - if ( Psl < Vbs ) { - Psl = Vbs ; - } - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { - break ; - } - - } /* end of Psl Newton loop */ - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - if ( lp_sl > lp_sl_max ) { - 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" ) ; - } - } - - -/*---------------------------------------------------* -* End of Psl calculation. (label) -*-----------------*/ -end_of_loopl: ; - -/*---------------------------------------------------* -* Assign Pds. -*-----------------*/ - - Pds = Psl - Ps0 ; - - if ( Pds < ps_conv ) { - Pds = 0.0 ; - Psl = Ps0 ; - } - - - -/*---------------------------------------------------* -* 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. -*-----------------*/ - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ) ; - - - /*note: cfs1 = cnst1 * exp_bVbsVds */ - fsl1 = cfs1 * fi * fi ; - fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; - fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; - fsl1_dVds = - cfs1 * beta * fi * fi ; - - - 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 ) ; - - T2 = 0.5 / fsl2 ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; - fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; - fsl2_dVds = fsl1_dVds * T2 ; - } else { - fsl2_dPsl = beta * fb_dChi ; - fsl2_dVbs = - beta * fb_dChi ; - fsl2_dVds = 0.0 ; - } - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - Pds_dVbs = Psl_dVbs - Ps0_dVbs ; - Pds_dVds = Psl_dVds - Ps0_dVds ; - Pds_dVgs = Psl_dVgs - Ps0_dVgs ; - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; - fsl1_dVds = - beta * fsl1 ; - - - if ( fsl1 < epsm10 * T1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - fsl1_dVds = 0.0 ; - } - - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - T2 = 0.5e0 / fsl2 ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; - - fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; - fsl2_dVds = ( fsl1_dVds ) * T2 ; - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - T2 = 0.5e0 / Xilp12 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - 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 ; - } - - - -/*-----------------------------------------------------------* -* Evaluate Qb and Idd. -* - Eta : substantial variable of QB'/Pds and Idd/Pds. -* - note: Eta = 4 * GAMMA_{hisim_0} -*-----------------*/ - - Eta = beta * Pds / Xi0 ; - - Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) - / Xi0 ; - Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; - Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; - - - /* ( 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 = - 0.5e0 / Xi0p32 ; - T4 = - 0.5e0 / Eta1p12 * F00 ; - - F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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_1o3 / Xi0p12 * T1 ; - T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; - - F10_dVbs = Zeta32 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F10_dVds = Zeta32 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F10_dVgs = Zeta32 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - -/*---------------------------------------------------* -* 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 = 2e0 / ( 5e0 * beta ) * Xi0p12 * T1 ; - T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 - + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; - - F30_dVbs = Zeta52 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F30_dVds = Zeta52 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F30_dVgs = Zeta52 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - -/*---------------------------------------------------* -* F11 := PS11/Pds. -*-----------------*/ - - F11 = Ps0 * F10 + C_2o3 / beta * Xilp32 - F30 ; - - F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs - + ( Xi0_dVbs / beta + Pds_dVbs ) * Xilp12 - - F30_dVbs ; - F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds - + ( Xi0_dVds / beta + Pds_dVds ) * Xilp12 - - F30_dVds ; - F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs - + ( Xi0_dVgs / beta + Pds_dVgs ) * Xilp12 - - F30_dVgs ; - -/*---------------------------------------------------* -* Fdd := Idd/Pds. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta - 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_dVbs * T1 - + T4 * ( - F10_dVbs + F00_dVbs ) ; - Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds ) - + beta * Cox_dVds * T1 - + T4 * ( - F10_dVds + F00_dVds ) ; - Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs ) - + beta * Cox_dVgs * T1 - + T4 * ( - F10_dVgs + F00_dVgs ) ; - -/*---------------------------------------------------* -* Q_B : bulk charge. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta ; - 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_dVbs * T2 ) ; - Qbnm_dVds = cnst0 - * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds ) - + Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds ) - + Cox_dVds * T2 ) ; - Qbnm_dVgs = cnst0 - * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs ) - + Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs ) - + Cox_dVgs * T2 ) ; - - T1 = - Weff * beta * Leff ; - - Qb = T1 * Qbnm / Fdd ; - - T2 = T1 / ( Fdd * Fdd ) ; - - Qb_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; - Qb_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; - Qb_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; - -/*---------------------------------------------------* -* Breaking point for Qi=Qd=0. -*-----------------*/ - - if ( flg_noqi != 0 ) { - goto end_of_part_1 ; - } - -/*---------------------------------------------------* -* 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 ; - - - -/*-----------------------------------------------------------* -* Channel Length Modulation. Lred: \Delta L -*-----------------*/ - - if( sIN.clm2 < epsm10 && sIN.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 ; - } - - goto end_of_CLM ; - } - - - Ec = Idd / beta / Qn0 / Leff ; - Ec_dVbs = 1.0e0 / beta / Leff - * ( Idd_dVbs / Qn0 - Idd * Qn0_dVbs / Qn0 / Qn0 ) ; - Ec_dVds = ( Idd_dVds / Qn0 - Idd * Qn0_dVds / Qn0 / Qn0 ) - / beta / Leff ; - Ec_dVgs = 1.0e0 / beta / Leff - * ( Idd_dVgs / Qn0 - Idd * Qn0_dVgs / Qn0 / Qn0 ) ; - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - - T7 = Qn0 / Wd ; - T7_dVbs = ( Qn0_dVbs / Wd - Qn0 / Wd / Wd * Wd_dVbs ) ; - T7_dVds = ( Qn0_dVds / Wd - Qn0 / Wd / Wd * Wd_dVds ) ; - T7_dVgs = ( Qn0_dVgs / Wd - Qn0 / Wd / Wd * Wd_dVgs ) ; - - T8 = Ec * Ec + 2.0e0 / C_ESI * q_Nsub * ( Psdl - Psl ) + 1.0e3 ; - T8_dVbs = 2.0e0 * Ec * Ec_dVbs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVbs - Psl_dVbs ) ; - T8_dVds = 2.0e0 * Ec * Ec_dVds - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVds - Psl_dVds ) ; - T8_dVgs = 2.0e0 * Ec * Ec_dVgs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVgs - Psl_dVgs ) ; - - Ed = sqrt( T8 ) ; - Ed_dVbs = 0.5e0 / Ed * T8_dVbs ; - Ed_dVds = 0.5e0 / Ed * T8_dVds ; - Ed_dVgs = 0.5e0 / Ed * T8_dVgs ; - - - Lred = ( Ed - Ec ) - / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) * C_ESI ; - T1 = 1.0 / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) ; - T2 = T1 * T1 ; - Lred_dVbs = ( ( Ed_dVbs - Ec_dVbs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVbs ) * C_ESI ; - Lred_dVds = ( ( Ed_dVds - Ec_dVds ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVds ) * C_ESI ; - Lred_dVgs = ( ( Ed_dVgs - Ec_dVgs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVgs ) * C_ESI ; - -/*---------------------------------------------------* -* Modify Lred for symmetry. -*-----------------*/ - - end_of_CLM2: ; - - TX = Vds / cclmmdf ; - T2 = TX * TX ; - T5 = 1.0 + T2 ; - - FMD = 1.0 - 1.0 / T5 ; - FMD_dVds = 2.0 * Vds / ( T5 * T5 * cclmmdf * cclmmdf ) ; - - T6 = Lred ; - - Lred = FMD * T6 ; - Lred_dVbs *= FMD ; - Lred_dVds = FMD_dVds * ( T6 ) + FMD * Lred_dVds ; - Lred_dVgs *= FMD ; - -/*-------------------------------------------* -* End point of CLM. (label) -*-----------------*/ -end_of_CLM: ; - - -/*---------------------------------------------------* -* preparation for Qi and Qd. -*-----------------*/ - - T1 = 2.0e0 * fac1 ; - - DtPds = T1 * ( F10 - Xi0p12 ) ; - - T2 = 2.0 * ( F10 - Xi0p12 ) ; - - DtPds_dVbs = T1 * ( F10_dVbs - - 0.5 * beta * ( Ps0_dVbs - 1.0e0 ) / Xi0p12 ) - + T2 * fac1_dVbs ; - DtPds_dVds = T1 * ( F10_dVds - - 0.5 * beta * Ps0_dVds / Xi0p12 ) - + T2 * fac1_dVds ; - DtPds_dVgs = T1 * ( F10_dVgs - - 0.5 * beta * Ps0_dVgs / Xi0p12 ) - + 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. -* - cramped to 0 if Alpha < 0. -*-----------------*/ - - Alpha = 1.0e0 - Achi / VgVt ; - - if ( Alpha >= 0.0e0 ) { - - Alpha_dVbs = - Achi_dVbs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVbs / VgVt ) ; - Alpha_dVds = - Achi_dVds / VgVt + ( Achi / VgVt ) - * ( VgVt_dVds / VgVt ) ; - Alpha_dVgs = - Achi_dVgs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVgs / VgVt ) ; - - } else { - - Alpha = 0.0e0 ; - Alpha_dVbs = 0.0e0 ; - Alpha_dVds = 0.0e0 ; - Alpha_dVgs = 0.0e0 ; - } - -/*-----------------------------------------------------------* -* Q_I : inversion charge. -*-----------------*/ - - Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; - Qinm_dVbs = Alpha_dVbs * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVds = Alpha_dVds * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVgs = Alpha_dVgs * ( 1.0e0 + Alpha + Alpha ) ; - - Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; - Qidn_dVbs = Alpha_dVbs ; - Qidn_dVds = Alpha_dVds ; - Qidn_dVgs = Alpha_dVgs ; - - T1 = - Weff * ( Leff - Lred ) * C_2o3 * VgVt * Qinm / Qidn ; - - Qi = T1 * Cox ; - - Qi_dVbs = Qi * ( VgVt_dVbs / VgVt - + Qinm_dVbs / Qinm - Qidn_dVbs / Qidn - - Lred_dVbs/ ( Leff - Lred ) ) - + T1 * Cox_dVbs ; - Qi_dVds = Qi * ( VgVt_dVds / VgVt - + Qinm_dVds / Qinm - Qidn_dVds / Qidn - - Lred_dVds/ ( Leff - Lred ) ) - + T1 * Cox_dVds ; - Qi_dVgs = Qi * ( VgVt_dVgs / VgVt - + Qinm_dVgs / Qinm - Qidn_dVgs / Qidn - - Lred_dVgs/ ( Leff - Lred ) ) - + T1 * Cox_dVgs ; - -/*-----------------------------------------------------------* -* Q_D : drain charge. -*-----------------*/ - - 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 ) { - Qdrat_dVbs = Quot * ( Qddn_dVbs / Qddn - Qdnm_dVbs / Qdnm ) ; - Qdrat_dVds = Quot * ( Qddn_dVds / Qddn - Qdnm_dVds / Qdnm ) ; - Qdrat_dVgs = Quot * ( Qddn_dVgs / Qddn - Qdnm_dVgs / Qdnm ) ; - } else { - Qdrat = 0.5e0 ; - Qdrat_dVbs = 0.0e0 ; - Qdrat_dVds = 0.0e0 ; - Qdrat_dVgs = 0.0e0 ; - } - - 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 ; - -/*-----------------------------------------------------------* -* Modify charges for zone-D2. -* - FD2 must be defined previously. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - if ( Chi < znbd5 ) { - - 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 ; - - T5 = - Leff * Weff ; - - Qb_dVbs = FD2 * Qb_dVbs + FD2_dVbs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVbs - FD2_dVbs * T5 * Qb0 ; - Qb_dVds = FD2 * Qb_dVds + FD2_dVds * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVds - FD2_dVds * T5 * Qb0 ; - Qb_dVgs = FD2 * Qb_dVgs + FD2_dVgs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVgs - FD2_dVgs * T5 * Qb0 ; - - Qb = FD2 * Qb + ( 1.0 - FD2 ) * T5 * Qb0 ; - - if ( Qb > 0.0 ) { - Qb = 0.0 ; - Qb_dVbs = 0.0 ; - Qb_dVds = 0.0 ; - Qb_dVgs = 0.0 ; - } - - Qi_dVbs = FD2 * Qi_dVbs + FD2_dVbs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVbs - FD2_dVbs * T5 * Qn0 ; - Qi_dVds = FD2 * Qi_dVds + FD2_dVds * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVds - FD2_dVds * T5 * Qn0 ; - Qi_dVgs = FD2 * Qi_dVgs + FD2_dVgs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVgs - FD2_dVgs * T5 * Qn0 ; - - Qi = FD2 * Qi + ( 1.0 - FD2 ) * T5 * Qn0 ; - - if ( Qi > 0.0 ) { - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - } - - Qd_dVbs = FD2 * Qd_dVbs + FD2_dVbs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVbs / 2 - - FD2_dVbs * T5 * Qi / 2 ; - Qd_dVds = FD2 * Qd_dVds + FD2_dVds * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVds / 2 - - FD2_dVds * T5 * Qi / 2 ; - Qd_dVgs = FD2 * Qd_dVgs + FD2_dVgs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVgs / 2 - - FD2_dVgs * T5 * Qi / 2 ; - - Qd = FD2 * Qd + ( 1.0 - FD2 ) * T5 * Qi / 2 ; - - if ( Qd > 0.0 ) { - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - } - - } - - - -/*-----------------------------------------------------------* -* Modified potential for symmetry. -*-----------------*/ - - T1 = exp( - ( Vds - Pds ) / ( 2.0 * sIN.pzadd0 ) ) ; - - Pzadd = sIN.pzadd0 * T1 ; - - T2 = - 0.5 * T1 ; - - Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; - Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; - Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; - - if ( fabs ( Pzadd ) < epsm10 ) { - Pzadd = 0.0 ; - 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 ; - - -/*-----------------------------------------------------------* -* Evaluate universal mobility. -*-----------------*/ - - Ps0Vbsz = Ps0z - Vbsz ; - Ps0Vbsz_dVbs = Ps0z_dVbs - Vbsz_dVbs ; - Ps0Vbsz_dVds = Ps0z_dVds - Vbsz_dVds ; - Ps0Vbsz_dVgs = Ps0z_dVgs ; - - -/*-------------------------------------------* -* Qbm -*-----------------*/ - - T1 = cnst0 ; - T2 = sqrt( beta * Ps0Vbsz - 1.0 ) ; - - Qbm = T1 * T2 ; - - T3 = 0.5 * beta * T1 / T2 ; - - Qbm_dVbs = T3 * Ps0Vbsz_dVbs ; - Qbm_dVds = T3 * Ps0Vbsz_dVds ; - Qbm_dVgs = T3 * Ps0Vbsz_dVgs ; - -/*-------------------------------------------* -* Qnm -*-----------------*/ - - Chi = beta * Ps0Vbsz ; - - exp_Chi = exp( Chi ) ; - - exp_bVbs = exp( beta * Vbsz ) ; - - cfs1 = cnst1 * exp_bVbs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - /* regard fs01 as a function of Chi and Vbs */ - fs01_dChi = cfs1 * ( exp_Chi ) ; - fs01_dVbs = beta * fs01 ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - Xi0z = Chi - 1.0e0 ; - - Xi0z_dVbs = beta * Ps0Vbsz_dVbs ; - Xi0z_dVds = beta * Ps0Vbsz_dVds ; - Xi0z_dVgs = beta * Ps0Vbsz_dVgs ; - - fs02 = sqrt( Xi0z + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - /* regard fs01 as a function of Chi and Vbs */ - fs02_dChi = ( 1.0 + fs01_dChi ) * T2 ; - fs02_dVbs = fs01_dVbs * T2 ; - - Xi0zp12 = sqrt( Xi0z ) ; - - Xi0zp12_dVbs = 0.5e0 * Xi0z_dVbs / Xi0zp12 ; - Xi0zp12_dVds = 0.5e0 * Xi0z_dVds / Xi0zp12 ; - Xi0zp12_dVgs = 0.5e0 * Xi0z_dVgs / Xi0zp12 ; - - T1 = 1.0 / ( fs02 + Xi0zp12 ) ; - - Qnm = cnst0 * fs01 * T1 ; - - fs01_dVds = beta * Ps0Vbsz_dVds * fs01_dChi - + fs01_dVbs * Vbsz_dVds ; - fs01_dVbs = beta * Ps0Vbsz_dVbs * fs01_dChi + fs01_dVbs ; - fs01_dVgs = beta * Ps0Vbsz_dVgs * fs01_dChi ; - - fs02_dVds = beta * Ps0Vbsz_dVds * fs02_dChi - + fs02_dVbs * Vbsz_dVds ; - fs02_dVbs = beta * Ps0Vbsz_dVbs * fs02_dChi + fs02_dVbs ; - fs02_dVgs = beta * Ps0Vbsz_dVgs * fs02_dChi ; - - Qnm_dVbs = Qnm - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0zp12_dVbs ) * T1 ) ; - Qnm_dVds = Qnm - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0zp12_dVds ) * T1 ) ; - Qnm_dVgs = Qnm - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0zp12_dVgs ) * T1 ) ; - - if ( Qbm < 0.0 ) { - Qbm = 0.0 ; - } - if ( Qnm < 0.0 ) { - Qnm = 0.0 ; - } - - - -/*---------------------------------------------------* -* Muun : universal mobility. -*-----------------*/ - - /* removed Eqs. "Qbm = Qb0", "Qnm = Qn0", ... (4/Dec/01) */ - - T1 = sIN.ninv - sIN.ninvd * Vdsz ; - T1_dVds = - sIN.ninvd * Vdsz_dVds ; - - Eeff = ( sIN.ndep * Qbm + T1 * Qnm ) / C_ESI ; - Eeff_dVbs = ( sIN.ndep * Qbm_dVbs + T1 * Qnm_dVbs ) - / C_ESI ; - Eeff_dVds = ( sIN.ndep * Qbm_dVds + T1 * Qnm_dVds - + T1_dVds * Qnm ) - / C_ESI ; - Eeff_dVgs = ( sIN.ndep * Qbm_dVgs + T1 * Qnm_dVgs ) - / C_ESI ; - - Rns = Qnm / C_QE ; - - T10 = pow( sIN.temp / C_T300 , sIN.muetmp ) ; - T21 = pow( Eeff , sIN.mueph0 - 1.0e0 ) ; - T20 = T21 * Eeff ; - T31 = pow( Eeff , sIN.muesr0 - 1.0e0 ) ; - T30 = T31 * Eeff ; - - T1 = 1e0 / ( sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ) - + T10 - * T20 / mueph - + T30 / sIN.muesr1 ; - - Muun = 1e0 / T1 ; - - T1 = 1e0 / ( T1 * T1 ) ; - T2 = sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ; - T2 = 1e0 / ( T2 * T2 ) ; - T3 = T10 * sIN.mueph0 * T21 / mueph ; - T4 = sIN.muesr0 * T31 / sIN.muesr1 ; - - Muun_dVbs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVbs / C_QE * T2 - + Eeff_dVbs * T3 - + Eeff_dVbs * T4 ) - * T1 ; - Muun_dVds = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVds / C_QE * T2 - + Eeff_dVds * T3 - + Eeff_dVds * T4 ) - * T1 ; - Muun_dVgs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVgs / C_QE * T2 - + Eeff_dVgs * T3 - + Eeff_dVgs * T4 ) - * T1 ; - - -/*-----------------------------------------------------------* -* Mu : mobility -*-----------------*/ - - T1 = 1.0e0 / beta / ( Qn0 + small ) / ( Leff - Lred ) ; - T1_dVbs = 1.0e0 / beta * ( - Qn0_dVbs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVbs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVds = 1.0e0 / beta * ( - Qn0_dVds / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVds / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVgs = 1.0e0 / beta * ( - Qn0_dVgs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVgs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - - Ey = Idd * T1 ; - Ey_dVbs = Idd_dVbs * T1 + Idd * T1_dVbs ; - Ey_dVds = Idd_dVds * T1 + Idd * T1_dVds ; - Ey_dVgs = Idd_dVgs * T1 + Idd * T1_dVgs ; - - - 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 = sIN.temp / C_T300 ; - - Vmax = sIN.vmax / ( 1.8 + 0.4 * T1 + 0.1 * T1 * T1 ) ; - - T2 = 1.0 - sIN.vover / pow( Lgate , sIN.voverp ) ; - - if ( T2 < 0.01 ) { - fprintf( stderr , - "*** warning(HiSIM): Overshoot is too big.\n" ) ; - T2 = 0.01 ; - } - - Vmax = Vmax / T2 ; - - T1 = Em / Vmax ; - - /* note: sIN.bb = 2 (electron) ;1 (hole) */ - if ( 1.0e0 - epsm10 <= sIN.bb && sIN.bb <= 1.0e0 + epsm10 ) { - T3 = 1.0e0 ; - } else if ( 2.0e0 - epsm10 <= sIN.bb - && sIN.bb <= 2.0e0 + epsm10 ) { - T3 = T1 ; - } else { - T3 = pow( T1 , sIN.bb - 1.0e0 ) ; - } - T2 = T1 * T3 ; - T4 = 1.0e0 + T2 ; - T6 = pow( T4 , ( - 1.0e0 / sIN.bb - 1.0e0 ) ) ; - T5 = T4 * T6 ; - - Mu = Muun * T5 ; - Mu_dVbs = Muun_dVbs * T5 - Muun / Vmax * T6 * T3 * Em_dVbs ; - Mu_dVds = Muun_dVds * T5 - Muun / Vmax * T6 * T3 * Em_dVds ; - Mu_dVgs = Muun_dVgs * T5 - Muun / Vmax * T6 * T3 * Em_dVgs ; - - -end_of_mobility : ; - -/*-----------------------------------------------------------* -* Ids: channel current. -*-----------------*/ - - - T1 = Weff / beta / ( Leff - Lred ) ; - T1_dVbs = T1 / ( Leff - Lred ) * Lred_dVbs ; - T1_dVds = T1 / ( Leff - Lred ) * Lred_dVds ; - T1_dVgs = T1 / ( Leff - Lred ) * Lred_dVgs ; - - Ids0 = T1 * Idd * Mu ; - Ids0_dVbs = T1 * ( Mu * Idd_dVbs + Idd * Mu_dVbs ) - + T1_dVbs * Mu * Idd ; - Ids0_dVds = T1 * ( Mu * Idd_dVds + Idd * Mu_dVds ) - + T1_dVds * Mu * Idd ; - Ids0_dVgs = T1 * ( Mu * Idd_dVgs + Idd * Mu_dVgs ) - + T1_dVgs * Mu * Idd ; - - T1 = Vdsz + sIN.rpock2 ; - T2 = T1 * T1 + small ; - T2_dVbs = 0.0e0 ; - T2_dVds = 2.0 * T1 * Vdsz_dVds ; - T2_dVgs = 0.0e0 ; - - rp1 = FMD * sIN.rpock1 ; - rp1_dVds = FMD_dVds * sIN.rpock1 ; - - TX = Ids0 * sqrt( Leff ) / Weff ; - T3 = rp1 * TX ; - T4 = ( T3 + T2 ) * ( T3 + T2 ); - - Ids = Ids0 / ( 1.0 + T3 / T2 ) ; - - T5 = T2 * T2 / T4 ; - T6 = Ids0 * T3 / T4 ; - - Ids_dVbs = T5 * Ids0_dVbs + T6 * T2_dVbs ; - Ids_dVds = T5 * Ids0_dVds + T6 * T2_dVds - - Ids0 * T2 / T4 * rp1_dVds * TX ; - Ids_dVgs = T5 * Ids0_dVgs + T6 * T2_dVgs ; - - if ( Pds < ps_conv ) { - Ids_dVbs = 0.0 ; - Ids_dVgs = 0.0 ; - } - - Ids += Gdsmin * Vds ; - Ids_dVds += Gdsmin ; - - -/*-----------------------------------------------------------* -* 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 ) || - 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 -- ; } - - -/*-----------------------------------------------------------* -* End of PART-1. (label) -*-----------------*/ -end_of_part_1: ; - - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-2: Substrate / gate / leak currents -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Isub : substrate current induced by impact ionization. -*-----------------*/ -/*-------------------------------------------* -* Accumulation zone or nonconductive case, in which Ids==0. -*-----------------*/ - - if ( Ids <= 0.0e0 || sIN.coisub >= 1 ) { - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - goto end_of_Isub ; - } - -/*-------------------------------------------* -* Conductive case. -*-----------------*/ - - if ( sIN.sub1 > 0.0e0 && sIN.vmax > 0.0e0 ) { - - Vdep = Vds + Ps0 - sIN.sub3 * Psl ; - Vdep_dVbs = Ps0_dVbs - sIN.sub3 * Psl_dVbs ; - Vdep_dVds = 1.0e0 + Ps0_dVds - sIN.sub3 * Psl_dVds ; - Vdep_dVgs = Ps0_dVgs - sIN.sub3 * Psl_dVgs ; - - TX = - sIN.sub2 / Vdep ; - - Epkf = exp( TX ) ; - Epkf_dVbs = - TX * Vdep_dVbs / Vdep * Epkf ; - Epkf_dVds = - TX * Vdep_dVds / Vdep * Epkf ; - Epkf_dVgs = - TX * Vdep_dVgs / Vdep * Epkf ; - - T1 = Ids * Epkf ; - T1_dVbs = Ids_dVbs * Epkf + Ids * Epkf_dVbs ; - T1_dVds = Ids_dVds * Epkf + Ids * Epkf_dVds ; - T1_dVgs = Ids_dVgs * Epkf + Ids * Epkf_dVgs ; - - if( T1 < 1.0e-25 ){ - T1 = 1.0e-25 ; - T1_dVbs = 0.0e0 ; - T1_dVds = 0.0e0 ; - T1_dVgs = 0.0e0 ; - } - - Isub = sIN.sub1 * Vdep * T1 ; - Isub_dVbs = sIN.sub1 * ( Vdep_dVbs * T1 + Vdep * T1_dVbs ) ; - Isub_dVds = sIN.sub1 * ( Vdep_dVds * T1 + Vdep * T1_dVds ) ; - Isub_dVgs = sIN.sub1 * ( Vdep_dVgs * T1 + Vdep * T1_dVgs ) ; - - } else { - - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - - } /* end of if ( sIN.sub1 ... ) else block. */ - -/*-------------------------------------------* -* End of Isub. (label) -*-----------------*/ -end_of_Isub: ; - -/*-----------------------------------------------------------* -* Igs : Gate current induced by tunneling. -* - Vzadd is used for symmetrizing. -*-----------------*/ - - if ( sIN.coiigs >= 1 ) { - Igs = 0.0e0 ; - Igs_dVbs = 0.0e0 ; - Igs_dVds = 0.0e0 ; - Igs_dVgs = 0.0e0 ; - goto end_of_Igs ; - } - - Egp12 = sqrt( Eg ) ; - Egp32 = Eg * Egp12 ; - - Vgpz = Vgp + Vzadd ; - - Vgpz_dVbs = Vgp_dVbs ; - Vgpz_dVds = Vgp_dVds + Vzadd_dVds ; - Vgpz_dVgs = Vgp_dVgs ; - - T1 = Vgpz - ( Psl + Ps0 + 2.0 * Vzadd ) * sIN.gleak3 ; - - E0 = 10.0 ; - - E2 = T1 / Tox ; - - E2_dVbs = E2 - * ( ( Vgpz_dVbs - ( Psl_dVbs + Ps0_dVbs ) * sIN.gleak3 ) - / T1 - - Tox_dVbs / Tox ) ; - E2_dVds = E2 - * ( ( Vgpz_dVds - - ( Psl_dVds + Ps0_dVds + 2.0 * Vzadd_dVds ) - * sIN.gleak3 - ) / T1 - - Tox_dVds / Tox ) ; - E2_dVgs = E2 - * ( ( Vgpz_dVgs - ( Psl_dVgs + Ps0_dVgs ) * sIN.gleak3 ) - / T1 - - Tox_dVgs / Tox ) ; - - T1 = E2 - E0 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E2 ) ; - - Etun = E2 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = 2.0 * T1 * T4 + 0.5 ; - - Etun_dVbs = T5 * E2_dVbs ; - Etun_dVds = T5 * E2_dVds ; - Etun_dVgs = T5 * E2_dVgs ; - - T1 = exp( - sIN.gleak2 * Egp32 / Etun ) ; - - T2 = sIN.gleak1 / Egp12 * C_QE * Weff * Leff ; - - Igs = T2 * Etun * Etun * T1 ; - - T3 = T2 * T1 * ( 2.0 * Etun + sIN.gleak2 * Egp32 ) ; - - Igs_dVbs = T3 * Etun_dVbs ; - Igs_dVds = T3 * Etun_dVds ; - Igs_dVgs = T3 * Etun_dVgs ; - - end_of_Igs: ; - -/*-----------------------------------------------------------* -* Ilg : GIDL -*-----------------*/ - - if ( sIN.cogidl >= 1 ) { - Ilg = 0.0e0 ; - Ilg_dVbs = 0.0e0 ; - Ilg_dVds = 0.0e0 ; - Ilg_dVgs = 0.0e0 ; - goto end_of_IGIDL ; - } - - T1 = sIN.gidl3 * Vdsz - Vgsz + dVth ; - - E1 = T1 / Tox ; - - E1_dVbs = E1 * ( dVth_dVbs / T1 - Tox_dVbs / Tox ) ; - E1_dVds = E1 * ( ( sIN.gidl3 * Vdsz_dVds - Vgsz_dVds + dVth_dVds ) - / T1 - - Tox_dVds / Tox ) ; - E1_dVgs = E1 * ( ( -1.0 + dVth_dVgs ) / T1 - Tox_dVgs / Tox ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egidl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egidl_dVbs = T5 * E1_dVbs ; - Egidl_dVds = T5 * E1_dVds ; - Egidl_dVgs = T5 * E1_dVgs ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egidl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Ilg = T2 * Egidl * Egidl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egidl + sIN.gidl2 * Egp32 ) ; - - Ilg_dVbs = T3 * Egidl_dVbs ; - Ilg_dVds = T3 * Egidl_dVds ; - Ilg_dVgs = T3 * Egidl_dVgs ; - - end_of_IGIDL: ; - -/*-----------------------------------------------------------* -* End of PART-2. (label) -*-----------------*/ -end_of_part_2: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-3: Overlap charge -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - -/*-------------------------------------------* -* Calculation of Psdl for cases of flg_noqi==1. -*-----------------*/ - - if ( flg_noqi != 0 ) { - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0e0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (simple, default, CLM1 < 1.0) <-- changed 04/Dec/01 -* (orig. "CLM1 must be 1.0") -*-----------------*/ - if ( sIN.coovlp == 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld + sIN.xpolyd ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T2 = - 1.0e+11 ; - yn = sqrt ( ( Psdl - Ps0 - Vds) / T2 ) ; - yn2 = yn * yn ; - yn3 = yn2 * yn ; - T3 = 0.5e0 / yn / T2 ; - - yn_dVbs = T3 * ( Psdl_dVbs - Ps0_dVbs ) ; - yn_dVds = T3 * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ; - yn_dVgs = T3 * ( Psdl_dVgs - Ps0_dVgs ) ; - - if ( yn <= Lov ){ - Qgod = ( ( Vgs - Vds ) * Lov - T2 * yn3 / 3.0e0 ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds ) * T1 ; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs ) * T1 ; - }else{ - T4 = (Lov - yn ) * (Lov - yn ) ; - T5 = T4 * (Lov - yn ) ; - Qgod = ( ( Vgs - Vds ) * Lov - T2 / 3.0e0 * ( T5 + yn3 ) ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs - + T2 * T4 * yn_dVbs ) * T1; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds - + T2 * T4 * yn_dVds ) * T1; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs - + T2 * T4 * yn_dVgs ) * T1; - } - } -/*-------------------------------------------* -* Overlap charge (complete) -*-----------------*/ - - else if( sIN.coovlp > 0 ){ - - T1 = Cox * Weff ; - - Qgos = Vgs * ( sIN.xld + sIN.xpolyd ) * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = ( sIN.xld + sIN.xpolyd ) * T1 ; - - T3 = 1e21 / pow( sIN.xld + sIN.xpolyd , 3e0) ; - T1 = C_QE * T3 / ( C_ESI * 4e0 ) ; - T2 = Cox * Weff ; - - Lov = sIN.xld + sIN.xpolyd ; - Lov2 = Lov * Lov ; - - yn = pow( C_ESI * 5e0 / ( C_QE * T3 ) - * ( Ps0 + Vds - Psdl ) - , 0.2e0 ) ; - yn2 = yn * yn ; - - if ( yn < Lov ) { - Qgod = ( ( Vgs - Vds ) * ( sIN.xld + sIN.xpolyd ) - + T1 / 3e0 * yn2 * yn2 * yn2 ) * T2 ; - Qgod_dVbs = ( yn / 2e0 * ( Ps0_dVbs - Psdl_dVbs ) ) * T2 ; - Qgod_dVds = ( - 1e0 * ( sIN.xld + sIN.xpolyd ) - + yn / 2e0 * ( Ps0_dVds + 1e0 - Psdl_dVds ) ) * T2 ; - Qgod_dVgs = ( 1e0 * ( sIN.xld + sIN.xpolyd ) - + yn / 2e0 * ( Ps0_dVgs - Psdl_dVgs ) ) * T2 ; - } else { - T3 = C_ESI * 5e0 / ( C_QE * T3 ) ; - - Qgod = ( ( Vgs + T1 * 4e0 / 5e0 * yn2 * yn2 * yn - Vds ) * Lov - + T1 / 30e0 * Lov2 * Lov2 * Lov2 - - T1 * yn2 * yn2 / 2e0 * Lov2 ) * T2 ; - Qgod_dVbs = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVbs - Psdl_dVbs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVbs - Psdl_dVbs ) * Lov2 ) - * T2 ; - Qgod_dVds = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVds + 1e0 - Psdl_dVds ) - 1e0 ) - * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVds + 1e0 - Psdl_dVds ) - * Lov2 ) * T2 ; - Qgod_dVgs = ( ( 1e0 + T1 * 4e0 / 5e0 * T3 * ( Ps0_dVgs - Psdl_dVgs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVgs - Psdl_dVgs ) * Lov2 ) - * T2 ; - } - } - -/*-------------------------------------------* -* Overlap charge (off) -*-----------------*/ - - else if( sIN.coovlp < 0 ){ - - Qgos = 0.0e0 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = 0.0e0 ; - - Qgod = 0.0e0 ; - Qgod_dVbs = 0.0e0 ; - Qgod_dVds = 0.0e0 ; - Qgod_dVgs = 0.0e0 ; - - } - -/*-----------------------------------------------------------* -* End of PART-3. (label) -*-----------------*/ -end_of_part_3: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-4: Substrate-source/drain junction diode. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - - -/*-----------------------------------------------------------* -* Cbsj, Cbdj: node-base S/D biases. -*-----------------*/ - - if (sIN.mode == HiSIM_NORMAL_MODE ){ - Vbdj = Vbde ; - Vbsj = Vbse ; - } else { - Vbdj = Vbse ; - Vbsj = Vbde ; - } - - /* Vbdc = Vbsc - Vdsc ;*/ - - js = sIN.js0 * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) / sIN.nj ) ; - jssw = sIN.js0sw * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) - / sIN.njsw ) ; - - Nvtm = sIN.nj / beta ; - - - /* ibd */ - isbd = sIN.ad * js + sIN.pd * jssw ; - - if ( Vbdj < 0.5 ) { - Ibd = isbd * ( exp( Vbdj / Nvtm ) - 1 ) ; - Gbd = isbd / Nvtm * exp( Vbdj / Nvtm ) ; - - } else { - Ibd = isbd * ( exp( 0.5 / Nvtm ) - 1 ) - + isbd / Nvtm * exp( 0.5 / Nvtm ) * ( Vbdj - 0.5 ) ; - Gbd = isbd / Nvtm * exp( 0.5 / Nvtm ) ; - } - - - /* ibs */ - isbs = sIN.as * js + sIN.ps * jssw ; - - if ( Vbsj < 0.5 ) { - Ibs = isbs * ( exp( Vbsj / Nvtm ) - 1 ) ; - Gbs = isbs / Nvtm * exp( Vbsj / Nvtm ) ; - - } else { - Ibs = isbs * ( exp( 0.5 / Nvtm ) - 1 ) - + isbs / Nvtm * exp( 0.5 / Nvtm ) * (Vbsj - 0.5 ) ; - Gbs = isbs / Nvtm * exp( 0.5 / Nvtm ) ; - } - -/*---------------------------------------------------* -* Add Gjmin. -*-----------------*/ - - Ibd += Gjmin * Vbdj ; - Ibs += Gjmin * Vbsj ; - - 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 - */ - - czbd = sIN.cj * sIN.ad ; - czbs = sIN.cj * sIN.as ; - - /* Source Bulk Junction */ - if (sIN.ps > Weff) { - czbssw = sIN.cjsw * ( sIN.ps - Weff ) ; - czbsswg = sIN.cjswg * Weff ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbssw ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0; - } - if (czbssw > 0.0) - { arg = 1.0 - Vbsj / sIN.pbsw; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjsw * log(arg)); - Qbs += sIN.pbsw * czbssw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw); - Capbs += czbssw * sarg; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbs += czbsswg * sarg; - } - } - else - { Qbs = Vbsj * (czbs + czbssw + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbssw * sIN.mjsw * 0.5 / sIN.pbsw - + czbsswg * sIN.mjswg - * 0.5 / sIN.pbswg); - Capbs = czbs - + czbssw + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbssw * sIN.mjsw / sIN.pbsw - + czbsswg * sIN.mjswg / sIN.pbswg ); - } - - } else { - czbsswg = sIN.cjswg * sIN.ps ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbs += czbsswg * sarg; - } - } - else - { Qbs = Vbsj * (czbs + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbsswg * sIN.mjswg * 0.5 / sIN.pbswg); - Capbs = czbs - + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbsswg * sIN.mjswg / sIN.pbswg ); - } - } - - - /* Drain Bulk Junction */ - if (sIN.pd > Weff) { - czbdsw = sIN.cjsw * ( sIN.pd - Weff ) ; - czbdswg = sIN.cjswg * Weff ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdsw ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0; - } - if (czbdsw > 0.0) - { arg = 1.0 - Vbdj / sIN.pbsw; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjsw * log(arg)); - Qbd += sIN.pbsw * czbdsw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw); - Capbd += czbdsw * sarg; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbd += czbdswg * sarg; - } - } - else - { Qbd = Vbdj * (czbd + czbdsw + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdsw * sIN.mjsw * 0.5 / sIN.pbsw - + czbdswg * sIN.mjswg - * 0.5 / sIN.pbswg); - Capbd = czbd - + czbdsw + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdsw * sIN.mjsw / sIN.pbsw - + czbdswg * sIN.mjswg / sIN.pbswg ); - } - - } else { - czbdswg = sIN.cjswg * sIN.pd ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbd += czbdswg * sarg; - } - } - else - { Qbd = Vbdj * (czbd + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdswg * sIN.mjswg * 0.5 / sIN.pbswg); - Capbd = czbd - + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdswg * sIN.mjswg / sIN.pbswg ); - } - } - - - -/*-----------------------------------------------------------* -* End of PART-4. (label) -*-----------------*/ -end_of_part_4: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-5: Noise Calculation. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - if ( sIN.conois != 0 ){ - - NFalp = sIN.nfalp ; - NFtrp = sIN.nftrp ; - Cit = sIN.cit ; - - T1 = Qn0 / C_QE ; - T2 = (Cox+Qn0/(Ps0-Vbs)+Cit)/beta/C_QE ; - T3 = 1.0E0/(T1+T2)+NFalp*Mu ; - Nflic = Ids*Ids*NFtrp/((Leff-Lred)*beta*Weff)*T3*T3 ; - - } else { - Nflic = 0.0 ; - } - - -/*-----------------------------------------------------------* -* End of PART-5. (label) -*-----------------*/ -end_of_part_5: ; - - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-6: Evaluation of outputs. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Implicit quantities related to Alpha. -*-----------------*/ - - /* note: T1 = 1 + Delta */ - if ( flg_noqi == 0 && VgVt > VgVt_small && Pds > 0.0 ) { - T1 = Achi / Pds ; - Delta = T1 - 1.0e0 ; - Vdsat = VgVt / T1 ; - } else { - Alpha = 1.0 ; - Delta = 0.0 ; - Vdsat = 0.0 ; - Achi = 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 == 0 || 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 ; - - Igs_dVbse = Igs_dVbs ; - Igs_dVdse = Igs_dVds ; - Igs_dVgse = Igs_dVgs ; - - Ilg_dVbse = Ilg_dVbs ; - Ilg_dVdse = Ilg_dVds ; - Ilg_dVgse = Ilg_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 ; - - -/*---------------------------------------------------* -* Case Rs>0 or Rd>0 -*-----------------*/ - } else { - -/*-------------------------------------------* -* 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 ; - - 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 ; - - Ilg_dVbse = Ilg_dVbs * Vbs_dVbse + Ilg_dVds * Vds_dVbse - + Ilg_dVgs * Vgs_dVbse ; - Ilg_dVdse = Ilg_dVbs * Vbs_dVdse + Ilg_dVds * Vds_dVdse - + Ilg_dVgs * Vgs_dVdse ; - Ilg_dVgse = Ilg_dVbs * Vbs_dVgse + Ilg_dVds * Vds_dVgse - + Ilg_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 ; - - } /* end of if ( flg_rsrd == 0 ) blocks */ - -/*---------------------------------------------------* -* 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 ; - Igs_dVbse *= Vbsc_dVbse ; - Ilg_dVbse *= Vbsc_dVbse ; - Qgos_dVbse *= Vbsc_dVbse ; - Qgod_dVbse *= Vbsc_dVbse ; - } - - if ( flg_vxxc != 0 ) { - - if ( flg_vbsc == -1 ) { - T1 = Vbse - Vbsc ; - } else { - T1 = 0.0 ; - } - - - if ( flg_vdsc != 0 ) { - T2 = Vdse - Vdsc ; - } else { - T2 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T3 = Vgse - Vgsc ; - } else { - T3 = 0.0 ; - } - - if ( flg_vbdc != 0 ) { - T4 = Vbde - Vbdc ; - } else { - T4 = 0.0 ; - } - - - TX = Ids + T1 * Ids_dVbse + T2 * Ids_dVdse + T3 * Ids_dVgse ; - if ( TX * Ids >= 0.0 ) { - Ids = TX ; - } else { - T7 = Ids / ( Ids - TX ) ; - Ids_dVbse *= T7 ; - Ids_dVdse *= T7 ; - Ids_dVgse *= T7 ; - Ids = 0.0 ; - } - - TX = Qb + T1 * Qb_dVbse + T2 * Qb_dVdse + T3 * Qb_dVgse ; - /*note: The sign of Qb can be changed.*/ - Qb = TX ; - - TX = Qd + T1 * Qd_dVbse + T2 * Qd_dVdse + T3 * Qd_dVgse ; - if ( TX * Qd >= 0.0 ) { - Qd = TX ; - } else { - T7 = Qd / ( Qd - TX ) ; - Qd_dVbse *= T7 ; - Qd_dVdse *= T7 ; - Qd_dVgse *= T7 ; - Qd = 0.0 ; - } - - TX = Qi + T1 * Qi_dVbse + T2 * Qi_dVdse + T3 * Qi_dVgse ; - if ( TX * Qi >= 0.0 ) { - Qi = TX ; - } else { - T7 = Qi / ( Qi - TX ) ; - Qi_dVbse *= T7 ; - Qi_dVdse *= T7 ; - Qi_dVgse *= T7 ; - Qi = 0.0 ; - } - - TX = Isub + T1 * Isub_dVbse + T2 * Isub_dVdse + T3 * Isub_dVgse ; - if ( TX * Isub >= 0.0 ) { - Isub = TX ; - } else { - T7 = Isub / ( Isub - TX ) ; - Isub_dVbse *= T7 ; - Isub_dVdse *= T7 ; - Isub_dVgse *= T7 ; - Isub = 0.0 ; - } - - TX = Igs + T1 * Igs_dVbse + T2 * Igs_dVdse + T3 * Igs_dVgse ; - if ( TX * Igs >= 0.0 ) { - Igs = TX ; - } else { - T7 = Igs / ( Igs - TX ) ; - Igs_dVbse *= T7 ; - Igs_dVdse *= T7 ; - Igs_dVgse *= T7 ; - Igs = 0.0 ; - } - - TX = Ilg + T1 * Ilg_dVbse + T2 * Ilg_dVdse + T3 * Ilg_dVgse ; - if ( TX * Ilg >= 0.0 ) { - Ilg = TX ; - } else { - T7 = Ilg / ( Ilg - TX ) ; - Ilg_dVbse *= T7 ; - Ilg_dVdse *= T7 ; - Ilg_dVgse *= T7 ; - Ilg = 0.0 ; - } - - TX = Qgod + T1 * Qgod_dVbse + T2 * Qgod_dVdse + T3 * Qgod_dVgse ; - if ( TX * Qgod >= 0.0 ) { - Qgod = TX ; - } else { - T7 = Qgod / ( Qgod - TX ) ; - Qgod_dVbse *= T7 ; - Qgod_dVdse *= T7 ; - Qgod_dVgse *= T7 ; - Qgod = 0.0 ; - } - - TX = Qgos + T1 * Qgos_dVbse + T2 * Qgos_dVdse + T3 * Qgos_dVgse ; - if ( TX * Qgos >= 0.0 ) { - Qgos = TX ; - } else { - T7 = Qgos / ( Qgos - TX ) ; - Qgos_dVbse *= T7 ; - Qgos_dVdse *= T7 ; - Qgos_dVgse *= T7 ; - Qgos = 0.0 ; - } - - - } - -/*-----------------------------------------------------------* -* Warn negative conductance. -* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. -*-----------------*/ - - if ( sIN.mode == HiSIM_NORMAL_MODE ) { - T1 = Ids_dVdse ; - } else { - T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; - } - - if ( Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0 ) { - fprintf( stderr , - "*** warning(HiSIM): Negative Conductance\n" ) ; - fprintf( stderr , - " type = %d mode = %d\n" , sIN.type , sIN.mode ) ; - fprintf( stderr , - " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" , - Vbse , Vdse , Vgse ) ; - if ( flg_info >= 1 ) { - printf( "*** warning(HiSIM): Negative Conductance\n" ) ; - printf( " type = %d mode = %d\n" , sIN.type , sIN.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" , Ids_dVdse ) ; - printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - } - } - - if ( Ids_dVbse < 0.0e0 ) { - fprintf( stderr , " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; - flg_ncnv ++ ; - } - if ( T1 < 0.0e0 ) { - fprintf( stderr , " Ids_dVdse = %12.5e\n" , T1 ) ; - flg_ncnv ++ ; - } - if ( Ids_dVgse < 0.0e0 ) { - fprintf( stderr , " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - flg_ncnv ++ ; - } - - - -/*-----------------------------------------------------------* -* Redefine overlap charges/capacitances. -*-----------------*/ - -/*---------------------------------------------------* -* Constant capacitance. -*-----------------*/ - - if ( sIN.cocgbo >= 1 ) { - Cgbo = sIN.cgbo * Lgate ; - } else { - Cgbo = 0.0 ; - } - - if ( sIN.cocgdo >= 1 ) { - Cgdo = - sIN.cgdo * Weff ; - Qgod = - Cgdo * ( Vgse - Vdse ) ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = Cgdo ; - Qgod_dVgse = - Qgod_dVdse ; - } else { - Cgdo = Qgos_dVdse + Qgod_dVdse ; - } - - if ( sIN.cocgso >= 1 ) { - Cgso = - sIN.cgso * Weff ; - Qgos = - Cgso * Vgse ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = 0.0 ; - Qgos_dVgse = - Cgso ; - } else { - Cgso = - ( Qgos_dVbse + Qgod_dVbse - + Qgos_dVdse + Qgod_dVdse - + Qgos_dVgse + Qgod_dVgse ) ; - } - - Cggo = Qgos_dVgse + Qgod_dVgse ; - -/*---------------------------------------------------* -* Fringing capacitance. -*-----------------*/ - - Cf = C_EOX / ( C_Pi / 2.0e0 ) * Weff - * log( 1.0e0 + sIN.tpoly / sIN. tox ) ; - - /* added 2 Eqs. below. (4/Dec/01) */ - - Qfd = Cf * ( Vgse - Vdse ) ; - Qfs = Cf * Vgse ; - - /* end of additional Eqs. */ - -/*---------------------------------------------------* -* Add fringing charge/capacitance to overlap. -*-----------------*/ - - /* added 2 Eqs. below. (4/Dec/01) */ - - Qgod += Qfd ; - Qgos += Qfs ; - - /* end of additional Eqs. */ - - Cggo += 2.0 * Cf ; - Cgdo += - Cf ; - Cgso += - Cf ; - -/*-----------------------------------------------------------* -* Assign outputs. -*-----------------*/ - -/*---------------------------------------------------* -* Channel current and conductances. -*-----------------*/ - - /* pOT->ids = sIN.type * Ids ; */ - pOT->ids = Ids ; - pOT->gmbs = Ids_dVbse ; - pOT->gds = Ids_dVdse ; - pOT->gm = Ids_dVgse ; - -/*---------------------------------------------------* -* Intrinsic charges/capacitances. -*-----------------*/ - - pOT->qg = - ( Qb + Qi ) ; - pOT->qd = Qd ; - pOT->qs = Qi - Qd ; - - pOT->cbgb = Qb_dVgse ; - pOT->cbdb = Qb_dVdse ; - pOT->cbsb = - ( Qb_dVbse + Qb_dVdse + Qb_dVgse ) ; - - pOT->cggb = - Qb_dVgse - Qi_dVgse ; - pOT->cgdb = - Qb_dVdse - Qi_dVdse ; - pOT->cgsb = Qb_dVbse + Qb_dVdse + Qb_dVgse - + Qi_dVbse + Qi_dVdse + Qi_dVgse ; - - pOT->cdgb = Qd_dVgse ; - pOT->cddb = Qd_dVdse ; - pOT->cdsb = - ( Qd_dVgse + Qd_dVdse + Qd_dVbse ) ; - - -/*---------------------------------------------------* -* Cramp capcitances. -*-----------------*/ - if ( pOT->cbsb > -1e-27 ) { pOT->cbsb = 0e0 ; } - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - -/*---------------------------------------------------* -* Overlap capacitances. -*-----------------*/ - - pOT->cgdo = Cgdo ; - pOT->cgso = Cgso ; - pOT->cgbo = Cgbo ; - -/* - * Intrinsic fringing capacitance. - */ - - T1 = 2 * C_ESI * Weff / C_Pi; - T2 = C_Pi * C_EOX / 2 / C_ESI; - T3 = sIN.xj / sIN.tox * sin( T2 ); - Cgdf = T1 * log( 1.0e0 + T3 ); - - T4 = (-1) * ( pOT->cgdb ); - T5 = 2 * T4 / Cox / Weff / Leff; - Cgdfring = Cgdf * ( 1.0e0 - T5 ); - - -/*---------------------------------------------------* -* Add S/D overlap charges/capacitances to intrinsic ones. -* - NOTE: This function depends on coadov, a control option. -*-----------------*/ - - if ( sIN.coadov == 1 ) { - pOT->qg += Qgod + Qgos ; - pOT->qd += - Qgod ; - pOT->qs += - Qgos ; - - pOT->cggb += Cggo ; - pOT->cgdb = pOT->cgdb + Cgdo + (-1) * Cgdfring ; - pOT->cgsb += Cgso ; - - pOT->cdgb += - Qgod_dVgse - Cf ; - pOT->cddb += - Qgod_dVdse + Cf ; - pOT->cdsb += Qgod_dVbse + Qgod_dVdse + Qgod_dVgse ; - - pOT->cgdo = 0.0 ; - pOT->cgso = 0.0 ; - - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - } - - -/*---------------------------------------------------* -* Substrate/gate/leak currents. -*-----------------*/ - - pOT->isub = Isub ; - - pOT->gbbs = Isub_dVbse ; - pOT->gbds = Isub_dVdse ; - pOT->gbgs = Isub_dVgse ; - - pOT->igs = Igs ; - - pOT->ggbs = Igs_dVbse ; - pOT->ggds = Igs_dVdse ; - pOT->gggs = Igs_dVgse ; - - pOT->ilg = Ilg ; - - pOT->glbs = Ilg_dVbse ; - pOT->glds = Ilg_dVdse ; - pOT->glgs = Ilg_dVgse ; - -/*---------------------------------------------------* -* Meyer's capacitances. -*-----------------*/ - - pOT->capgs = - pOT->cgsb - Cgso + Cf ; - pOT->capgd = - pOT->cgdb - Cgdo + Cf ; - pOT->capgb = pOT->cggb + pOT->cgdb + pOT->cgbo ; - -/*---------------------------------------------------* -* Von, Vdsat, -*-----------------*/ - - /* - pOT->von = sIN.type * Vth ; - pOT->vdsat = sIN.type * Vdsat ; - */ - pOT->von = Vth ; - pOT->vdsat = Vdsat ; - -/*---------------------------------------------------* -* Parasitic conductances. -*-----------------*/ - -/*:org: -* pOT->gd = 1.0e+50 ; -* pOT->gs = 1.0e+50 ; -* modified according to CMIxxxeval.c. -* I don't know the reason why these can be zero. -*/ - pOT->gd = 0.0e0 ; - pOT->gs = 0.0e0 ; - -/*---------------------------------------------------* -* Junction diode. -*-----------------*/ - - /* - pOT->ibs = sIN.type * Ibs ; - pOT->ibd = sIN.type * Ibd ; - */ - pOT->ibs = Ibs ; - pOT->ibd = Ibd ; - pOT->gbs = Gbse ; - pOT->gbd = Gbde ; - - pOT->qbs = Qbs ; - pOT->qbd = Qbd ; - pOT->capbs = Capbse ; - pOT->capbd = Capbde ; - - - -/*-----------------------------------------------------------* -* Warn floating-point exceptions. -* - Function finite() in libm is called. -* - Go to start with info==5. -*-----------------*/ - - T1 = pOT->ids + pOT->gmbs + pOT->gds + pOT->gm ; - T1 = T1 + pOT->qd + pOT->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( "pOT->ids = %12.5e\n" , pOT->ids ) ; - printf( "pOT->gmbs = %12.5e\n" , pOT->gmbs ) ; - printf( "pOT->gds = %12.5e\n" , pOT->gds ) ; - printf( "pOT->gm = %12.5e\n" , pOT->gm ) ; - printf( "pOT->qd = %12.5e\n" , pOT->qd ) ; - printf( "pOT->cdsb = %12.5e\n" , pOT->cdsb ) ; - } - } - - T1 = pOT->isub + pOT->gbbs + pOT->gbds + pOT->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 = pOT->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 = pOT->ibs + pOT->ibd + pOT->gbs + pOT->gbd ; - T1 = T1 + pOT->qbs + pOT->qbd + pOT->capbs + pOT->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 ) { - return( HiSIM_ERROR ) ; - } - -/*-----------------------------------------------------------* -* Restore values for next calculation. -*-----------------*/ - - /* Confined biases */ - pOT->vbsc = Vbsc ; - pOT->vdsc = Vdsc ; - pOT->vgsc = Vgsc ; - /* Surface potentials and derivatives w.r.t. internal biases */ - pOT->ps0 = Ps0 ; - pOT->ps0_dvbs = Ps0_dVbs ; - pOT->ps0_dvds = Ps0_dVds ; - pOT->ps0_dvgs = Ps0_dVgs ; - pOT->pds = Pds ; - pOT->pds_dvbs = Pds_dVbs ; - pOT->pds_dvds = Pds_dVds ; - pOT->pds_dvgs = Pds_dVgs ; - /* Derivatives of channel current w.r.t. internal biases */ - pOT->ids_dvbs = Ids_dVbs ; - pOT->ids_dvds = Ids_dVds ; - pOT->ids_dvgs = Ids_dVgs ; - - pOT->nf = Nflic ; - - /* mobility added by K.M. */ - pOT->mu = Mu; - -/*-----------------------------------------------------------* -* End of PART-6. (label) -*-----------------*/ -end_of_part_6: ; - - -/*-----------------------------------------------------------* -* Bottom of hsm1eval. -*-----------------*/ - - - -return ( HiSIM_OK ) ; - -} /* end of hsm1eval1_0 */ diff --git a/src/spicelib/devices/hisim/hsm1eval1_1.c b/src/spicelib/devices/hisim/hsm1eval1_1.c deleted file mode 100644 index 9126936a1..000000000 --- a/src/spicelib/devices/hisim/hsm1eval1_1.c +++ /dev/null @@ -1,4758 +0,0 @@ -/*********************************************************************** - HiSIM v1.1.0 - File: hsm1eval1_1.c of HiSIM v1.1.0 - - Copyright (C) 2002 STARC - - June 30, 2002: developed by Hiroshima University and STARC - June 30, 2002: posted by Keiichi MORIKAWA, STARC Physical Design Group -***********************************************************************/ - -/* - * Modified by Paolo Nenzi 2002 - * ngspice integration - */ - -/********************************************************************* -* Memorandum on programming -* -* (1) Bias (x: b|d|g) -* . sIN.vxs : Input argument. -* . Vxse: External bias taking account device type (pMOS->nMOS). -* . Vxsc: Confined bias within a specified region. -* . Vxs : Internal bias taking account Rs/Rd. -* . 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. -* . Ps0z: Modified Ps0. -* . The following variables are calculated as a function of -* modified biases or potential. -* Tox, Cox, (-- with quantum effect) -* Vth*, dVth*, dPpg, Qnm, Qbm, Igs, Ilg. -* . The following variables are calculated using a transform -* function. -* Lred, rp1(<-sIN.rpock1). -* -* (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 and -D1. -* . 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 - -/*-----------------------------------* -* HiSIM macros and structures. -* - All inputs and outputs are defined here. -*-----------------*/ -#include "hisim.h" -#include "hsm1evalenv.h" - -/*===========================================================* -* Function hsm1eval. -*=================*/ - -int HSM1evaluate1_1( HiSIM_input sIN, HiSIM_output *pOT, - HiSIM_messenger *pMS) -{ - -/*---------------------------------------------------* -* Local variables. -*-----------------*/ -/* Constans ----------------------- */ -int lp_s0_max = 20 ; -int lp_sl_max = 20 ; -int lp_bs_max = 10 ; -double Ids_tol = 1.0e-10 ; -double Ids_maxvar = 1.0e-1 ; -double dP_max = 0.1e0 ; -double ps_conv = 5.0e-13 ; -double gs_conv = 1.0e-8 ; -/*-----*/ -/** depletion **/ -double znbd3 = 3.0e0 ; -double znbd5 = 5.0e0 ; -double cn_nc3 = C_SQRT_2 / 108e0 ; -/* 5-degree, contact:Chi=5 */ -double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */ -double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */ -double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */ -double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */ -double cn_nc55 = 6.36964918866352e-5; /*(1509-1040*sqrt(2))/600000*/ -/** inversion **/ -/* 3-dgree polynomial approx for ( exp[Chi]-1 )^{1/2} */ -double cn_im53 = 2.9693154855770998e-1 ; -double cn_im54 = -7.0536542840097616e-2 ; -double cn_im55 = 6.1152888951331797e-3 ; -/* 3-dgree polynomial approx for ( exp[Chi]-Chi-1 )^{1/2} */ -double cn_ik53 = 2.6864599830664019e-1 ; -double cn_ik54 = -6.1399531828413338e-2 ; -double cn_ik55 = 5.3528499428744690e-3 ; -/** initial guess **/ -double c_ps0ini_2 = 8.0e-4 ; -double c_pslini_1 = 0.3e0 ; -double c_pslini_2 = 3.0e-2 ; -double VgVt_small = 1.0e-12 ; -double Vbs_max = 0.5e0 ; -double Vbs_min = -10.5e0 ; -double Vds_max = 10.5e0 ; -double Vgs_max = 10.5e0 ; -/*-----*/ -double Vbd_max = 20.0e0 ; -double Vbd_min = -10.0e0 ; -/*-----*/ -double epsm10 = 10.0e0 * C_EPS_M ; -double small = 1.0e-50 ; -/*-----*/ -double Vz_dlt = 5.0e-3 ; -/*-----*/ -double Gdsmin = 1.0e-12 ; -/*-----*/ -/* double Gjmin = 1.0e-12 ; */ -double Gjmin = sIN.gmin; /* modified by K.M. for SPICE3f5 */ -/*-----*/ -double cclmmdf = 1.0e-1 ; -/*-----*/ -double qme_dlt = 1.0e-9 ; -double eef_dlt = 1.0e-2 ; -double sti1_dlt = -3.0e-3 ; -double sti2_dlt = 2.0e-3 ; -double pol_dlt = 2.0e-1 ; - -/* Internal flags --------------------*/ -int flg_err = 0 ; /* error level */ -int flg_ncnv = 0 ; /* Flag for negative conductance */ -int flg_rsrd ; /* Flag for bias loop accounting Rs and Rd */ -int flg_iprv ; /* Flag for initial guess of Ids */ -int flg_pprv ; /* 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_vdsc = 0 ; /* Flag for Vds confining */ -int flg_vgsc = 0 ; /* Flag for Vgs confining */ -int flg_vbdc = 0 ; /* Flag for Vgs confining */ -int flg_vxxc = 0 ; /* Flag whether some bias was confined */ -int flg_info = 0 ; - -/* Important Variables in HiSIM -------*/ -/* external bias */ -double Vbse , Vdse , Vgse , Vbde ; -/* confine bias */ -double Vbsc , Vdsc , Vgsc , Vbdc ; -double Vbsc_dVbse = 1.0 ; -/* internal bias */ -double Vbs , Vds , Vgs ; -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 ; -/* Pds := Psl - Ps0 */ -double Pds ; -double Pds_dVbs , Pds_dVds , Pds_dVgs ; -double Pds_ini ; -double Pds_max ; -/* iteration numbers of Ps0 and Psl equations. */ -int lp_s0 , lp_sl ; -/* 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 ; -double Xi0p32_dVbs , Xi0p32_dVds , Xi0p32_dVgs ; -/* 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 Vbszm ; -double Vbszm_dVbs , Vbszm_dVds ; -double Vbs1 , Vbs2 , Vbsd ; -double Vbsd_dVbs , Vbsd_dVds ; -double Vzadd , Vzadd_dVds , Vzadd_dA ; -double VzaddA , VzaddA_dVds ; -double Ps0z , Ps0z_dVbs , Ps0z_dVds , Ps0z_dVgs ; -double Pzadd , Pzadd_dVbs , Pzadd_dVds , Pzadd_dVgs ; -double Ps0Vbsz , Ps0Vbsz_dVbs , Ps0Vbsz_dVds , Ps0Vbsz_dVgs ; -double Vgpz , Vgpz_dVbs , Vgpz_dVds , Vgpz_dVgs ; -double Xi0z ; -double Xi0z_dVbs , Xi0z_dVds , Xi0z_dVgs ; -double Xi0zp12 ; -double Xi0zp12_dVbs , Xi0zp12_dVds , Xi0zp12_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 Vth_dVbs , Vth_dVds , Vth_dVgs ; -double Vth0 ; -double Vth0_dVbs , Vth0_dVds , Vth0_dVgs ; -/* variation of threshold voltage */ -double dVth ; -double dVth_dVbs , dVth_dVds , dVth_dVgs ; -double dVth0 ; -double dVth0_dVbs , dVth0_dVds , dVth0_dVgs ; -double dVthSC ; -double dVthSC_dVbs , dVthSC_dVds , dVthSC_dVgs ; -double dVthW ; -double dVthW_dVbs , dVthW_dVds , dVthW_dVgs ; -/* 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 , VgVt_dVds , VgVt_dVgs ; -double Delta , Vdsat ; -/*-----*/ -/* Q_B and capacitances */ -double Qb , Qb_dVbs , Qb_dVds , Qb_dVgs ; -double Qb_dVbse , Qb_dVdse , Qb_dVgse ; -/* Q_I and capacitances */ -double Qi , Qi_dVbs , Qi_dVds , Qi_dVgs ; -double Qi_dVbse , Qi_dVdse , Qi_dVgse ; -/* Q_D and capacitances */ -double Qd , Qd_dVbs , Qd_dVds , Qd_dVgs ; -double Qd_dVbse , Qd_dVdse , Qd_dVgse ; -/* 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 Vgssti ; -double Vgssti_dVbs , Vgssti_dVds , Vgssti_dVgs ; -double costi0 , costi1 , costi2 , costi3 ; -double costi4 , costi5 , costi6 , costi7 ; -double Psasti ; -double Psasti_dVbs , Psasti_dVds , Psasti_dVgs ; -double Asti ; -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 expsti ; -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 ; - -/* (for debug) */ -double user1 , user2 , user3 , user4 ; - -/* constants ------- */ -double beta ; -double beta2 ; -/* device instances */ -double Leff , Leff_inv ; -double Weff ; -double Ldby ; -double Nsub , q_Nsub ; -double Nin ; -double Pb2 ; -double Pb20 ; -double Pb2c ; -double Eg , Eg300 ; -double Vfb ; -/* PART-1 ---------- */ -double Psum ; -double Psum_dVbs ; -double Psum_dVds ; -double sqrt_Psum ; -double cnst0 , cnst1 ; -double fac1 ; -double fac1_dVbs , fac1_dVds , fac1_dVgs ; -double fac1p2 ; -/*-----*/ -double fs01 ; -double fs01_dPs0 , fs01_dChi ; -double fs01_dVbs , fs01_dVds , fs01_dVgs ; -double fs02 ; -double fs02_dPs0 , fs02_dChi ; -double fs02_dVbs , fs02_dVds , fs02_dVgs ; -double fsl1 ; -double fsl1_dPsl ; -double fsl1_dVbs , fsl1_dVds ; -double fsl2 ; -double fsl2_dPsl ; -double fsl2_dVbs , fsl2_dVds ; -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 ; -double Qn0_dVbs , Qn0_dVds , Qn0_dVgs ; -double Qb0 ; -double Qb0_dVbs , Qb0_dVds , Qb0_dVgs ; -double Qn00 ; -double Qn00_dVbs , Qn00_dVds , Qn00_dVgs ; -/* unused: -* double Qnl ; -*/ -/*-----*/ -double Qbnm ; -double Qbnm_dVbs , Qbnm_dVds , Qbnm_dVgs ; -double DtPds ; -double DtPds_dVbs , DtPds_dVds , DtPds_dVgs ; -/*-----*/ -double Fid2 ; -double Fid2_dVbs , Fid2_dVds , Fid2_dVgs ; -double Fid3 ; -double Fid3_dVbs , Fid3_dVds , Fid3_dVgs ; -double Fid4 ; -double Fid4_dVbs , Fid4_dVds , Fid4_dVgs ; -double Fid5 ; -double Fid5_dVbs , Fid5_dVds , Fid5_dVgs ; -/*-----*/ -double PVds0 ; -double XiVds0 ; -double XiVds0p12 ; -double XiVds0p12_dVbs , XiVds0p12_dVds , XiVds0p12_dVgs ; -double XiVds0p32 ; -double XiVds0p32_dVbs , XiVds0p32_dVds , XiVds0p32_dVgs ; -double Qbm ; -double Qbm_dVbs , Qbm_dVds , Qbm_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 ; -double Qdrat_dVbs , Qdrat_dVds , Qdrat_dVgs ; -double Idd ; -double Idd_dVbs , Idd_dVds , Idd_dVgs ; -double Qnm ; -double Qnm_dVbs , Qnm_dVds , Qnm_dVgs ; -/*-----*/ -double Fdd ; -double Fdd_dVbs , Fdd_dVds , Fdd_dVgs ; -/*-----*/ -double Eeff ; -double Eeff_dVbs , Eeff_dVds , Eeff_dVgs ; -double Rns ; -double Mu ; -double Mu_dVbs , Mu_dVds , Mu_dVgs ; -double Muun , Muun_dVbs , Muun_dVds , Muun_dVgs ; -double Ey ; -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 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 Vdep ; -double Vdep_dVbs , Vdep_dVds , Vdep_dVgs ; -double Epkf ; -double Epkf_dVbs , Epkf_dVds , Epkf_dVgs ; -/**/ -/*-----*/ -/* PART-3 (overlap) */ -double yn , yn2 , yn3 ; -double yn_dVbs , yn_dVds , yn_dVgs ; -double yned , yned2 ; -double yned_dVbs , yned_dVds , yned_dVgs ; -double Lov , Lov2 , Lov23 ; -double Ndsat , Gjnp; -double Qgos , Qgos_dVbs , Qgos_dVds , Qgos_dVgs ; -double Qgos_dVbse , Qgos_dVdse , Qgos_dVgse ; -double Qgod , Qgod_dVbs , Qgod_dVds , Qgod_dVgs ; -double Qgod_dVbse , Qgod_dVdse , Qgod_dVgse ; -double Cggo , Cgdo , Cgso , Cgbo ; -/* fringing capacitance */ -double Cf ; -double Qfd , Qfs ; -/* Cqy */ -double Pslk , Pslk_dVbs , Pslk_dVds , Pslk_dVgs ; -double Qy ; -double Cqyd, Cqyg, Cqys, Cqyb ; -double qy_dlt ; -/* PART-4 (junction diode) */ -double Ibs , Ibd , Gbs , Gbd , Gbse , Gbde ; -double js ; -double jssw ; -double isbs ; -double isbd ; -double Nvtm ; -/* junction capacitance */ -double Qbs , Qbd , Capbs , Capbd , Capbse , Capbde ; -double czbd , czbdsw , czbdswg , czbs , czbssw , czbsswg ; -double arg , sarg ; -/* PART-5 (noise) */ -/* matsu */ -double NFalp , NFtrp , Freq , Cit , Nflic ; -/* Bias iteration accounting Rs/Rd */ -int lp_bs ; -double Ids_last ; -double vtol_iprv = 2.0e-1 ; -double vtol_pprv = 5.0e-2 ; -double Vbsc_dif , Vdsc_dif , Vgsc_dif , sum_vdif ; -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 ; -/* Junction Bias */ -double Vbsj, Vbdj; -/* Accumulation zone */ -double Psa ; -double Psa_dVbs , Psa_dVds , Psa_dVgs ; -/* CLM */ -double Psdl , Psdl_dVbs , Psdl_dVds , Psdl_dVgs ; -double Ed , Ed_dVbs , Ed_dVds , Ed_dVgs ; -double Ec , Ec_dVbs , Ec_dVds , Ec_dVgs ; -double Lred , Lred_dVbs , Lred_dVds , Lred_dVgs ; -double Wd , Wd_dVbs , Wd_dVds , Wd_dVgs ; -double Aclm ; -/* Pocket Implant */ -double Vthp, Vthp_dVbs, Vthp_dVds, Vthp_dVgs ; -double dVthLP,dVthLP_dVbs,dVthLP_dVds,dVthLP_dVgs ; -double LEY ; -/* Poly-Depletion Effect */ -double dPpg , dPpg_dVds , dPpg_dVgs ; -/* Quantum Effect */ -double Tox , Tox_dVbs , Tox_dVds , Tox_dVgs ; -double dTox , dTox_dVbs , dTox_dVds , dTox_dVgs ; -double Cox , Cox_dVbs , Cox_dVds , Cox_dVgs ; -double Cox_inv , Cox_inv_dVbs , Cox_inv_dVds , Cox_inv_dVgs ; -double Vthq, Vthq_dVbs , Vthq_dVds ; -/* Igs , Ilg */ -double Egp12 , Egp32 ; -double E0 ; -double E1 , E1_dVbs , E1_dVds , E1_dVgs ; -double E2 , E2_dVbs , E2_dVds , E2_dVgs ; -double Etun , Etun_dVbs , Etun_dVds , Etun_dVgs ; -double Egidl , Egidl_dVbs , Egidl_dVds , Egidl_dVgs ; -double Igs , Igs_dVbs , Igs_dVds , Igs_dVgs ; -double Igs_dVbse , Igs_dVdse , Igs_dVgse ; -double Ilg , Ilg_dVbs , Ilg_dVds , Ilg_dVgs ; -double Ilg_dVbse , Ilg_dVdse , Ilg_dVgse ; -double Cox0 ; -double Lgate ; -double rp1 , rp1_dVds ; -/* connecting function */ -double FD2 , FD2_dVbs , FD2_dVds , FD2_dVgs ; -double FMD , FMD_dVds ; -/* Phonon scattering */ -double Wgate ; -double mueph ; -/* temporary vars.-- */ -double T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ; -double TX , TX_dVbs , TX_dVds , TX_dVgs ; -double TY , TY_dVbs , TY_dVds , TY_dVgs ; -double T1_dVbs , T1_dVds , T1_dVgs ; -double T2_dVbs , T2_dVds , T2_dVgs ; -double T3_dVbs , T3_dVds , T3_dVgs ; -double T4_dVbs , T4_dVds , T4_dVgs ; -double T5_dVbs , T5_dVds , T5_dVgs ; -double T6_dVbs , T6_dVds , T6_dVgs ; -double T7_dVbs , T7_dVds , T7_dVgs ; -double T8_dVbs , T8_dVds , T8_dVgs ; -double T9_dVbs , T9_dVds , T9_dVgs ; -double T10 , T20 , T21 , T30 , T31 ; - - -/*================ Start of executable code.=================*/ - - flg_info = sIN.info ; - -/*-----------------------------------------------------------* -* Change units into CGS. -* - This section may be moved to an interface routine. -*-----------------*/ - -/* device instances */ - sIN.xl *= C_m2cm ; - sIN.xw *= C_m2cm ; - sIN.as *= C_m2cm_p2 ; - sIN.ad *= C_m2cm_p2 ; - sIN.ps *= C_m2cm ; - sIN.pd *= C_m2cm ; - -/* model parameters */ - sIN.tox *= C_m2cm ; - sIN.xld *= C_m2cm ; - sIN.xwd *= C_m2cm ; - - sIN.xqy *= C_m2cm ; - - sIN.lp *= C_m2cm ; - sIN.xpolyd *= C_m2cm ; - sIN.tpoly *= C_m2cm ; - - sIN.rs *= C_m2cm ; - sIN.rd *= C_m2cm ; - - sIN.sc3 *= C_m2cm ; - sIN.scp3 *= C_m2cm ; - sIN.parl2 *= C_m2cm ; - - sIN.wfc *= C_m2cm ; - sIN.wsti *= C_m2cm ; - - sIN.rpock1 *= C_m2cm_p1o2 ; - - sIN.qme1 *= C_m2cm ; - sIN.qme3 *= C_m2cm ; - - sIN.gidl1 *= C_m2cm_p1o2 ; - - sIN.cgso /= C_m2cm ; - sIN.cgdo /= C_m2cm ; - sIN.cgbo /= C_m2cm ; - - sIN.js0 /= C_m2cm_p2 ; - sIN.js0sw /= C_m2cm ; - - sIN.cj /= C_m2cm_p2 ; - sIN.cjsw /= C_m2cm ; - sIN.cjswg /= C_m2cm ; - -/*-----------------------------------------------------------* -* Start of the routine. (label) -*-----------------*/ -start_of_routine: - - - -/*-----------------------------------------------------------* -* Temperature dependent constants. -*-----------------*/ - -/* Inverse of the thermal voltage */ - beta = C_QE / ( C_KB * sIN.temp ) ; - beta2 = beta * beta ; - -/* Band gap */ - Eg = C_Eg0 - sIN.temp - * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; - - Eg300 = C_Eg0 - C_T300 - * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ; - -/* Intrinsic carrier concentration */ - Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) - * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ; - -/*-----------------------------------------------------------* -* Fixed part. -*-----------------*/ - - -/* Lgate in [cm] / [m] */ - Lgate = sIN.xl ; - Wgate = sIN.xw ; - -/* Phonon Scattering */ - T1 = log( Wgate ) ; - T2 = sIN.w0 - T1 - sti1_dlt ; - T3 = T2 * T2 ; - T4 = sqrt( T3 + 4.0 * sti1_dlt * sIN.w0 ) ; - T5 = sIN.w0 - ( T2 - T4 ) / 2 ; - mueph = sIN.mueph1 + sIN.mueph2 * T5 ; - -/* Metallurgical channel geometry */ - Weff = sIN.xw - 2.0e0 * sIN.xwd ; - Leff = sIN.xl - 2.0e0 * sIN.xld ; - Leff_inv = 1.0e0 / Leff ; - -/* Flat band voltage */ - Vfb = sIN.vfbc ; - -/* Surface impurity profile */ - - if( Lgate > sIN.lp ){ - Nsub = ( sIN.nsubc * ( Lgate - sIN.lp ) - + sIN.nsubp * sIN.lp ) / Lgate ; - } else { - Nsub = sIN.nsubp - + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Lgate ) / sIN.lp ; - } - - q_Nsub = C_QE * Nsub ; - -/* 2 phi_B */ - /* @temp, with pocket */ - Pb2 = 2.0e0 / beta * log( Nsub / Nin ); - /* @300K, with pocket */ - Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; - /* @300K, w/o pocket */ - Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ; - -/* Debye length */ - Ldby = sqrt( C_ESI / beta / q_Nsub ) ; - -/* Coefficient of the F function for bulk charge */ - cnst0 = q_Nsub * Ldby * C_SQRT_2 ; - -/* cnst1: n_{p0} / p_{p0} */ - T1 = Nin / Nsub ; - cnst1 = T1 * T1 ; -/* Cox (clasical) */ - Cox0 = C_EOX / sIN.tox ; - - - -/*-----------------------------------------------------------* -* Exchange bias conditions according to MOS type. -* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0 -* are assumed.) -*-----------------*/ - - /* - Vbse = sIN.type * sIN.vbs ; - Vdse = sIN.type * sIN.vds ; - Vgse = sIN.type * sIN.vgs ; - Vbde = Vbse - Vdse ; - */ - /* modified by K. M. for SPICE3f5 */ - Vbse = sIN.vbs; - Vdse = sIN.vds; - Vgse = sIN.vgs; - Vbde = Vbse - Vdse; - - -/*---------------------------------------------------* -* Cramp too large biases. -* -note: Quantities are extrapolated in PART-5. -*-----------------*/ - - if ( Vbse < Vbs_min ) { - flg_vbsc = -1 ; - Vbsc = Vbs_min ; - } else if ( Vbse > 0.0 ) { - flg_vbsc = 1 ; - T1 = Vbse / Vbs_max ; - T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; - Vbsc = Vbse / T2 ; - Vbsc_dVbse = Vbs_max * Vbs_max - / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; - } else { - flg_vbsc = 0 ; - Vbsc = Vbse ; - } - - - if ( Vdse > Vds_max ) { - flg_vdsc = 1 ; - Vdsc = Vds_max ; - } else { - flg_vdsc = 0 ; - Vdsc = Vdse ; - } - - if ( Vgse > Vgs_max ) { - flg_vgsc = 1 ; - Vgsc = Vgs_max ; - } else { - flg_vgsc = 0 ; - Vgsc = Vgse ; - } - - if ( Vbde < Vbd_min ) { - flg_vbdc = -1 ; - Vbdc = Vbd_min ; - } else if ( Vbde > Vbd_max ) { - Vbdc = Vbd_max ; - flg_vbdc = 1 ; - } else { - Vbdc = Vbde ; - flg_vbdc = 0 ; - } - - if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || - flg_vbdc != 0 ) { - flg_vxxc = 1 ; - } - - -/*-------------------------------------------------------------------* -* Set flags. -*-----------------*/ - - flg_rsrd = 0 ; - flg_iprv = 0 ; - flg_pprv = 0 ; - - Rs = sIN.rs / Weff ; - Rd = sIN.rd / Weff ; - - if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { - flg_rsrd = 1 ; - } - - if ( sIN.has_prv == 1 ) { - - Vbsc_dif = Vbsc - sIN.vbsc_prv ; - Vdsc_dif = Vdsc - sIN.vdsc_prv ; - Vgsc_dif = Vgsc - sIN.vgsc_prv ; - - sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) - + fabs( Vgsc_dif ) ; - - if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} - if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} - } - - if ( flg_rsrd == 0 ) { - lp_bs_max = 1 ; - flg_iprv = 0 ; - } - - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++* -* Bias loop: iteration to solve the system of equations of -* the small circuit taking account Rs and Rd. -* - Vxs are internal (or effective) biases. -* - Equations: -* Vbs = Vbsc - Rs * Ids -* Vds = Vdsc - ( Rs + Rd ) * Ids -* Vgs = Vgsc - Rs * Ids -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initial guesses for biases. -*-----------------*/ - - if ( flg_iprv == 1 ) { - - sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; - sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; - sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; - - dVbs = Vbsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; - dVds = Vdsc_dif * ( 1.0 - - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; - dVgs = Vgsc_dif * ( 1.0 - - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; - - /* - Ids = sIN.type * sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - */ - Ids = sIN.ids_prv - + sIN.ids_dvbs_prv * dVbs - + sIN.ids_dvds_prv * dVds - + sIN.ids_dvgs_prv * dVgs ; - - T1 = ( Ids - sIN.ids_prv ) ; - T2 = fabs( T1 ) ; - if ( Ids_maxvar * sIN.ids_prv < T2 ) { - Ids = sIN.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 ; - } - } - - Vbs = Vbsc - Ids * Rs ; - - Vds = Vdsc - Ids * ( Rs + Rd ) ; - if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } - - Vgs = Vgsc - Ids * Rs ; - - if ( flg_pprv == 1 ) { - - Ps0 = sIN.ps0_prv ; - - Ps0_dVbs = sIN.ps0_dvbs_prv ; - Ps0_dVds = sIN.ps0_dvds_prv ; - Ps0_dVgs = sIN.ps0_dvgs_prv ; - - Pds = sIN.pds_prv ; - - Pds_dVbs = sIN.pds_dvbs_prv ; - Pds_dVds = sIN.pds_dvds_prv ; - Pds_dVgs = sIN.pds_dvgs_prv ; - } - - -/*-----------------------------------------------------------* -* start of the loop. -*-----------------*/ - - for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { - - - Ids_last = Ids ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-1: Basic device characteristics. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Initialization. -*-----------------*/ - /* Initialization of counters is needed for restart. */ - lp_s0 = 0 ; - lp_sl = 0 ; - -/*-----------------------------------------------------------* -* Vxsz: Modified bias introduced to realize symmetry at Vds=0. -*-----------------*/ - - T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; - Vzadd = sIN.vzadd0 * T1 ; - Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; - - - if ( Vzadd < ps_conv ) { - Vzadd = 0.0 ; - Vzadd_dVds = 0.0 ; - } - - Vbsz = Vbs + Vzadd ; - Vbsz_dVbs = 1.0 ; - Vbsz_dVds = Vzadd_dVds ; - - Vdsz = Vds + 2 * Vzadd ; - Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; - - Vgsz = Vgs + Vzadd ; - Vgsz_dVgs = 1.0 ; - Vgsz_dVds = Vzadd_dVds ; - - -/*-----------------------------------------------------------* -* Quantum effect -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Vthq = Pb20 + Vfb + sIN.tox / C_EOX * T2 + sIN.qme2 ; - - T3 = - 0.5 * sIN.tox / C_EOX * T1 / T2 ; - Vthq_dVbs = T3 * Vbsz_dVbs ; - Vthq_dVds = T3 * Vbsz_dVds ; - - - T1 = - Vthq ; - T2 = Vgsz - Vthq ; - T3 = sIN.qme1 * T1 * T1 + sIN.qme3 ; - T4 = sIN.qme1 * T2 * T2 + sIN.qme3 ; - - T5 = T4 - T3 - qme_dlt ; - - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ) ; - - /* dTox_dT4 */ - T7 = 1.0 - 0.5 * ( 1.0 + ( T4 - T3 + qme_dlt ) / T6 ) ; - - T8 = 2.0 * sIN.qme1 * T2 * T7 ; - - dTox_dVbs = T8 * ( - Vthq_dVbs ) ; - dTox_dVds = T8 * ( Vgsz_dVds - Vthq_dVds ) ; - dTox_dVgs = T8 * ( Vgsz_dVgs ) ; - - if ( Vgsz - Vthq > 0 ) { - T4 = sIN.qme3 ; - T5 = T4 - T3 - qme_dlt ; - - T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; - - dTox = T4 - 0.5 * ( T5 + T6 ); - - dTox_dVbs = 0.0 ; - dTox_dVds = 0.0 ; - dTox_dVgs = 0.0 ; - } - - Tox = sIN.tox + dTox ; - Tox_dVbs = dTox_dVbs ; - Tox_dVds = dTox_dVds ; - Tox_dVgs = dTox_dVgs ; - - Cox = C_EOX / Tox ; - T1 = - C_EOX / ( Tox * Tox ) ; - Cox_dVbs = T1 * Tox_dVbs ; - Cox_dVds = T1 * Tox_dVds ; - Cox_dVgs = T1 * Tox_dVgs ; - - Cox_inv = Tox / C_EOX ; - T1 = 1.0 / C_EOX ; - Cox_inv_dVbs = T1 * Tox_dVbs ; - Cox_inv_dVds = T1 * Tox_dVds ; - Cox_inv_dVgs = T1 * Tox_dVgs ; - - -/*-----------------------------------------------------------* -* Threshold voltage. -*-----------------*/ - - Delta = 0.1 ; - - Vbs1 = 2.0 - 0.25 * Vbsz ; - Vbs2 = - Vbsz ; - - Vbsd = Vbs1 - Vbs2 - Delta ; - Vbsd_dVbs = 0.75 * Vbsz_dVbs ; - Vbsd_dVds = 0.75 * Vbsz_dVds ; - - T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; - - Vbszm = - Vbs1 + 0.5 * ( Vbsd + T1 ) ; - Vbszm_dVbs = 0.25 * Vbsz_dVbs - + 0.5 * ( Vbsd_dVbs + Vbsd * Vbsd_dVbs / T1 ) ; - Vbszm_dVds = 0.25 * Vbsz_dVds - + 0.5 * ( Vbsd_dVds + Vbsd * Vbsd_dVds / T1 ) ; - - Psum = ( Pb20 - Vbsz ) ; - - if ( Psum >= epsm10 ) { - Psum_dVbs = - Vbsz_dVbs ; - Psum_dVds = - Vbsz_dVds ; - } else { - Psum = epsm10 ; - Psum_dVbs = 0.0e0 ; - Psum_dVds = 0.0e0 ; - } - - sqrt_Psum = sqrt( Psum ) ; - - - -/*---------------------------------------------------* -* Vthp : Vth with pocket. -*-----------------*/ - - T1 = 2.0 * q_Nsub * C_ESI ; - Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; - - Qb0_dVbs = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; - Qb0_dVds = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; - - Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; - - Vthp_dVbs = Qb0_dVbs * Cox_inv + Qb0 * Cox_inv_dVbs ; - Vthp_dVds = Qb0_dVds * Cox_inv + Qb0 * Cox_inv_dVds ; - Vthp_dVgs = Qb0 * Cox_inv_dVgs ; - -/*-------------------------------------------* -* dVthLP : Short-channel effect induced by pocket. -* - Vth0 : Vth without pocket. -*-----------------*/ - - if ( sIN.lp != 0.0 ) { - - T1 = 2.0 * C_QE * sIN.nsubc * C_ESI ; - T2 = sqrt( T1 * ( Pb2c - Vbsz ) ) ; - - Vth0 = Pb2c + Vfb + T2 * Cox_inv ; - - Vth0_dVbs = 0.5 * T1 / T2 * ( - Vbsz_dVbs ) * Cox_inv - + T2 * Cox_inv_dVbs ; - Vth0_dVds = 0.5 * T1 / T2 * ( - Vbsz_dVds ) * Cox_inv - + T2 * Cox_inv_dVds ; - Vth0_dVgs = T2 * Cox_inv_dVgs ; - - LEY = sIN.parl1 * sIN.lp ; - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / C_QE / sIN.nsubp ) ; - T4 = 1.0e0 / ( LEY * LEY ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - - T6 = 0.5 * T5 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - T1 = Vthp - Vth0 ; - T2 = sIN.scp1 + sIN.scp3 * Psum / sIN.lp ; - T3 = T2 + sIN.scp2 * Vdsz ; - - dVthLP = T1 * dVth0 * T3 ; - - dVthLP_dVbs = ( Vthp_dVbs - Vth0_dVbs ) * dVth0 * T3 - + T1 * dVth0_dVbs * T3 - + T1 * dVth0 * sIN.scp3 * Psum_dVbs / sIN.lp ; - dVthLP_dVds = ( Vthp_dVds - Vth0_dVds ) * dVth0 * T3 - + T1 * dVth0_dVds * T3 - + T1 * dVth0 - * ( sIN.scp3 * Psum_dVds / sIN.lp - + sIN.scp2 * Vdsz_dVds ) ; - - dVthLP_dVgs = ( Vthp_dVgs - Vth0_dVgs ) * dVth0 * T3 - + T1 * dVth0_dVgs * T3 ; - - } else { - dVthLP = 0.0e0 ; - dVthLP_dVbs = 0.0e0 ; - dVthLP_dVds = 0.0e0 ; - dVthLP_dVgs = 0.0e0 ; - } - -/*---------------------------------------------------* -* dVthSC : Short-channel effect induced by Vds. -*-----------------*/ - - T1 = C_ESI * Cox_inv ; - T2 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T3 = sIN.parl1 * ( Lgate - sIN.parl2 ) ; - T4 = 1.0e0 / ( T3 * T3 ) ; - T5 = 2.0e0 * ( C_Vbi - Pb20 ) * T1 * T2 * T4 ; - - dVth0 = T5 * sqrt_Psum ; - T6 = T5 / 2 / sqrt_Psum ; - T7 = 2.0e0 * ( C_Vbi - Pb20 ) * C_ESI * T2 * T4 * sqrt_Psum ; - dVth0_dVbs = T6 * Psum_dVbs + T7 * Cox_inv_dVbs ; - dVth0_dVds = T6 * Psum_dVds + T7 * Cox_inv_dVds ; - dVth0_dVgs = T7 * Cox_inv_dVgs ; - - - T4 = sIN.sc1 + sIN.sc3 * Psum / Lgate ; - T4_dVbs = sIN.sc3 * Psum_dVbs / Lgate ; - T4_dVds = sIN.sc3 * Psum_dVds / Lgate ; - - T5 = sIN.sc2 ; - - dVthSC = dVth0 * ( T4 + T5 * Vdsz ) ; - - dVthSC_dVbs = dVth0_dVbs * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVbs ) ; - - dVthSC_dVds = dVth0_dVds * ( T4 + T5 * Vdsz ) - + dVth0 * ( T4_dVds + T5 * Vdsz_dVds ) ; - - dVthSC_dVgs = dVth0_dVgs * ( T4 + T5 * Vdsz ) ; - -/*---------------------------------------------------* -* dVthW : narrow-channel effect. -*-----------------*/ - - T1 = 1.0 / Cox ; - T2 = T1 * T1 ; - T3 = 1.0 / ( Cox + sIN.wfc / Weff ) ; - T4 = T3 * T3 ; - - dVthW = Qb0 * ( T1 - T3 ) ; - - dVthW_dVbs = Qb0_dVbs * ( T1 - T3 ) - - Qb0 * Cox_dVbs * ( T2 - T4 ) ; - dVthW_dVds = Qb0_dVds * ( T1 - T3 ) - - Qb0 * Cox_dVds * ( T2 - T4 ) ; - dVthW_dVgs = - Qb0 * Cox_dVgs * ( T2 - T4 ) ; - -/*---------------------------------------------------* -* dVth : Total variation. -* - Positive dVth means the decrease in Vth. -*-----------------*/ - - dVth = dVthSC + dVthLP + dVthW ; - dVth_dVbs = dVthSC_dVbs + dVthLP_dVbs + dVthW_dVbs ; - dVth_dVds = dVthSC_dVds + dVthLP_dVds + dVthW_dVds ; - dVth_dVgs = dVthSC_dVgs + dVthLP_dVgs + dVthW_dVgs ; - - - -/*---------------------------------------------------* -* Vth : Threshold voltage. -*-----------------*/ - - Vth = Vthp - dVth ; - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - -/*---------------------------------------------------* -* Poly-Depletion Effect -*-----------------*/ - - dPpg = Nsub / sIN.nsubc * sIN.pgd1 - * exp( Vgsz - sIN.pgd2 - sIN.pgd3 * Vdsz ) ; - dPpg_dVds = - sIN.pgd3 * dPpg * Vdsz_dVds - + dPpg * Vgsz_dVds ; - dPpg_dVgs = dPpg * Vgsz_dVgs ; - - T1 = 1.0e0 - dPpg - pol_dlt ; - T1_dVds = - dPpg_dVds ; - T1_dVgs = - dPpg_dVgs ; - T2 = sqrt( T1 * T1 + 4.0e0 * pol_dlt ) ; - - dPpg = 1.0e0 - 0.5e0 * ( T1 + T2 ) ; - dPpg_dVds = - 0.5e0 * ( T1_dVds + T1 * T1_dVds / T2 ) ; - dPpg_dVgs = - 0.5e0 * ( T1_dVgs + T1 * T1_dVgs / T2 ) ; - - - -/*---------------------------------------------------* -* Vgp : Effective gate bias with SCE & RSCE & flatband. -*-----------------*/ - - Vgp = Vgs - Vfb + dVth - dPpg ; - - Vgp_dVbs = dVth_dVbs ; - Vgp_dVds = dVth_dVds - dPpg_dVds ; - Vgp_dVgs = 1.0e0 + dVth_dVgs - dPpg_dVgs ; - -/*---------------------------------------------------* -* Vgs_fb : Actual flatband voltage taking account Vbs. -* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs . -*------------------*/ - - Vgs_fb = Vfb - dVth + dPpg + Vbs ; - - - -/*-----------------------------------------------------------* -* Constants in the equation of Ps0 . -*-----------------*/ - - fac1 = cnst0 * Cox_inv ; - fac1_dVbs = cnst0 * Cox_inv_dVbs ; - fac1_dVds = cnst0 * Cox_inv_dVds ; - fac1_dVgs = cnst0 * Cox_inv_dVgs ; - - fac1p2 = fac1 * fac1 ; - -/*-----------------------------------------------------------* -* Accumulation zone. (zone-A) -* - evaluate basic characteristics and exit from this part. -*-----------------*/ - - if ( Vgs < Vgs_fb ) { - - -/*---------------------------------------------------* -* Evaluation of Ps0. -* - Psa : Analytical solution of -* Cox( Vgp - Psa ) = cnst0 * Qacc -* where Qacc is the 3-dgree series of (fdep)^{1/2}. -* The unknown is transformed to Chi=beta(Ps0-Vbs). -* - Ps0_min : |Ps0_min| when Vbs=0. -*-----------------*/ - - Ps0_min = Eg - Pb2 ; - - TX = beta * ( Vgp - Vbs ) ; - - TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ; - TX_dVds = beta * Vgp_dVds ; - TX_dVgs = beta * Vgp_dVgs ; - - TY = Cox / ( beta * cnst0 ) ; - - T1 = 1.0 / ( beta * cnst0 ) ; - TY_dVbs = T1 * Cox_dVbs ; - TY_dVds = T1 * Cox_dVds ; - TY_dVgs = T1 * Cox_dVgs ; - - 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 ; - - Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ; - Ac31_dVbs = - 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac31_dVds = - 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac31_dVgs = - 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Ac3 = Ac31 * Ac31 ; - - Ac3_dVbs = 2.0 * Ac31 * Ac31_dVbs ; - Ac3_dVds = 2.0 * Ac31 * Ac31_dVds ; - Ac3_dVgs = 2.0 * Ac31 * Ac31_dVgs ; - - Ac2 = sqrt( Ac4 + Ac3 ) ; - Ac2_dVbs = 0.5 * ( Ac4_dVbs + Ac3_dVbs ) / Ac2 ; - Ac2_dVds = 0.5 * ( Ac4_dVds + Ac3_dVds ) / Ac2 ; - Ac2_dVgs = 0.5 * ( Ac4_dVgs + Ac3_dVgs ) / Ac2 ; - - Ac1 = -7.0 * C_SQRT_2 - + Ac2 + 9.0 * TY * ( TX - 2.0 ) ; - - Ac1_dVbs = Ac2_dVbs - + 9.0 * ( TY_dVbs * ( TX - 2.0 ) + TY * TX_dVbs ) ; - Ac1_dVds = Ac2_dVds - + 9.0 * ( TY_dVds * ( TX - 2.0 ) + TY * TX_dVds ) ; - Ac1_dVgs = Ac2_dVgs - + 9.0 * ( TY_dVgs * ( TX - 2.0 ) + TY * TX_dVgs ) ; - - Acd = pow( Ac1 , C_1o3 ) ; - - T1 = C_1o3 / ( Acd * Acd ) ; - Acd_dVbs = Ac1_dVbs * T1 ; - 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 ; - - Acn_dVbs = - 12.0 * TY_dVbs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVbs ; - Acn_dVds = - 12.0 * TY_dVds - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVds ; - Acn_dVgs = - 12.0 * TY_dVgs - + ( 2.0 + 2.0 * C_SQRT_2 * Acd ) * Acd_dVgs ; - - Chi = Acn / Acd ; - - T1 = 1.0 / ( Acd * Acd ) ; - - Chi_dVbs = ( Acn_dVbs * Acd - Acn * Acd_dVbs ) * T1 ; - Chi_dVds = ( Acn_dVds * Acd - Acn * Acd_dVds ) * T1 ; - Chi_dVgs = ( Acn_dVgs * Acd - Acn * Acd_dVgs ) * T1 ; - - Psa = Chi / beta + Vbs ; - - Psa_dVbs = Chi_dVbs / beta + 1.0 ; - Psa_dVds = Chi_dVds / beta ; - Psa_dVgs = Chi_dVgs / beta ; - - T1 = Psa - Vbs ; - T2 = T1 / Ps0_min ; - T3 = sqrt( 1.0 + ( T2 * T2 ) ) ; - - T9 = T2 / T3 / Ps0_min ; - T3_dVbs = T9 * ( Psa_dVbs - 1.0 ) ; - T3_dVds = T9 * ( Psa_dVds ) ; - T3_dVgs = T9 * ( Psa_dVgs ) ; - - Ps0 = T1 / T3 + Vbs ; - - T9 = 1.0 / ( T3 * T3 ) ; - - Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVbs ) - + 1.0 ; - Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVds ) ; - Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVgs ) ; - - - -/*---------------------------------------------------* -* Characteristics. -*-----------------*/ - - T0 = - Weff * Leff ; - T1 = T0 * Cox ; - T2 = ( Vgp - Ps0 ) ; - - Qb = T1 * T2 ; - - Qb_dVbs = T1 * ( Vgp_dVbs - Ps0_dVbs ) - + T0 * Cox_dVbs * T2 ; - Qb_dVds = T1 * ( Vgp_dVds - Ps0_dVds ) - + T0 * Cox_dVds * T2 ; - Qb_dVgs = T1 * ( Vgp_dVgs - Ps0_dVgs ) - + T0 * Cox_dVgs * T2 ; - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Qi = 0.0e0 ; - Qi_dVbs = 0.0e0 ; - Qi_dVds = 0.0e0 ; - Qi_dVgs = 0.0e0 ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - 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 / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ; - - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - if ( flg_pprv == 1 ) { - - Ps0_ini = Ps0 + Ps0_dVbs * dVbs - + Ps0_dVds * dVds + Ps0_dVgs * dVgs ; - - T1 = Ps0_ini - Ps0 ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } else { - Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ; - } - - } - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { -/*-------------------------------------------* -* Common part. -*-----------------*/ - - Chi = beta * ( Ps0_iniA - Vbs ) ; - -/*-----------------------------------* -* zone-D1/D2 -* - Ps0_ini is the analytical solution of Qs=Qb0 with -* Qb0 being approximated to 3-degree polynomial. -*-----------------*/ - if ( Chi < znbd3 ) { - - TY = beta * ( Vgp - Vbs ) ; - T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ; - T2 = 81 + 3 * T1 ; - T3 = -2916 - 81 * T1 + 27 * T1 * TY ; - T4 = 1458 - 81 * ( 54 + T1 ) + 27 * T1 * TY ; - T4 = T4 * T4 ; - T5 = pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ; - TX = 3 - - ( C_2p_1o3 * T2 ) / ( 3 * T5 ) - + 1 / ( 3 * C_2p_1o3 ) * T5 ; - - Ps0_iniA = TX / beta + Vbs ; - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Weak inversion zone. -*-----------------*/ - } else if ( Vgs <= Vth ) { - - Ps0_ini = Ps0_iniA ; - - -/*-----------------------------------* -* Strong inversion zone. -* - Ps0_iniB : upper bound. -*-----------------*/ - } else { - - T1 = ( Cox * Cox ) / ( cnst0 * cnst0 ) / cnst1 ; - T2 = T1 * Vgp * Vgp ; - T3 = beta + 2.0 / Vgp ; - - Ps0_iniB = log( T2 ) / T3 ; - - T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; - T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; - - Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; - - } - } - - if ( Ps0_ini < Vbs ) { - Ps0_ini = Vbs ; - } - - - -/*---------------------------------------------------* -* Assign initial guess. -*-----------------*/ - - 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 ; - - for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - } - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -* - Qb0 is approximated to 5-dgree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) - / ( fs02 + fs02 ) ; - } else { - fs02 = sqrt( fb * fb + fs01 ) ; - fs02_dPs0 = beta * fb_dChi ; - } - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; - - Fs0 = Vgp - Ps0 - fac1 * fs02 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - dPs0 = - Fs0 / Fs0_dPs0 ; - - } /* end of if ( Chi ... ) else block */ - -/*-------------------------------------------* -* Update Ps0 . -* - cramped to Vbs if Ps0 < Vbs . -*-----------------*/ - - if ( fabs( dPs0 ) > dP_max ) { - dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; - } - - Ps0 = Ps0 + dPs0 ; - - if ( Ps0 < Vbs ) { - Ps0 = Vbs ; - } - - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { - break ; - } - - } /* end of Ps0 Newton loop */ - - - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - if ( lp_s0 > lp_s0_max ) { - 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. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - exp_Chi = exp( Chi ) ; - - cfs1 = cnst1 * exp_bVbs ; - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - -/*-------------------------------------------* -* zone-D1/D2. (Ps0) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; - - T2 = 1.0e0 / ( fs02 + fs02 ) ; - - if ( fs02 >= epsm10 ) { - fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; - fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) - * T2 ; - } else { - fs02_dPs0 = beta * fb_dChi ; - fs02_dVbs = - beta * fb_dChi ; - } - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - - T1 = cnst0 ; - - Qb0 = T1 * fb ; - Qb0_dVbs = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; - Qb0_dVds = Ps0_dVds * T1 * beta * fb_dChi ; - Qb0_dVgs = Ps0_dVgs * T1 * beta * fb_dChi ; - - 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 ; - - T1 = 1.0 / ( fs02 + fb * fb ) ; - T2 = T1 * T1 ; - - Qn0 = cnst0 * fs01 * T1 ; - - T3 = 2.0 * fb_dChi * fb * beta ; - - Qn0_dVbs = cnst0 * ( - fs01_dVbs * T1 - - fs01 * ( fs02_dVbs - + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; - Qn0_dVds = cnst0 * ( - fs01_dVds * T1 - - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; - Qn0_dVgs = cnst0 * ( - fs01_dVgs * T1 - - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ; - - -/*-------------------------------------------* -* zone-D1. (Ps0) -* - Evaluate basic characteristics and exit from this part. -*-----------------*/ - if ( Chi < znbd3 ) { - - - 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 ; - - T1 = - Weff * Leff ; - - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - if ( Qn0 < Cox * VgVt_small ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - Qi = T1 * Qn0 ; - Qi_dVbs = T1 * Qn0_dVbs ; - Qi_dVds = T1 * Qn0_dVds ; - Qi_dVgs = T1 * Qn0_dVgs ; - - Qd = 0.0e0 ; - Qd_dVbs = 0.0e0 ; - Qd_dVds = 0.0e0 ; - Qd_dVgs = 0.0e0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - VgVt = 0.0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - -/*-------------------------------------------* -* zone-D2 -*-----------------*/ - - Xi0 = Chi - 1.0e0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - Qn00 = Qn0 ; - Qn00_dVbs = Qn0_dVbs ; - Qn00_dVds = Qn0_dVds ; - Qn00_dVgs = Qn0_dVgs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - - flg_noqi = 0 ; - - -/*-------------------------------------------* -* zone-D3. (Ps0) -*-----------------*/ - } else { - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; - fs01_dVbs = - cfs1 * beta ; - - - Xi0 = Chi - 1.0e0 ; - - Xi0p12 = sqrt( Xi0 ) ; - Xi0p32 = Xi0 * Xi0p12 ; - - fs02 = sqrt( Xi0 + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; - - fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; - - /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ - - T2 = 0.5e0 / Xi0p12 ; - - Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; - - Ps0_dVbs = - ( Vgp_dVbs - - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) - ) / Fs0_dPs0 ; - - Ps0_dVds = - ( Vgp_dVds - - fac1_dVds * fs02 - ) / Fs0_dPs0 ; - Ps0_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fs02 - ) / Fs0_dPs0 ; - - Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; - Xi0_dVds = beta * Ps0_dVds ; - Xi0_dVgs = beta * Ps0_dVgs ; - - Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; - Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; - Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; - - Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; - Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; - Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; - - flg_noqi = 0 ; - - - } /* end of if ( Chi ... ) block */ - - - -/*-----------------------------------------------------------* -* NOTE: The following sections of this part are only for -* the conductive case. -*-----------------*/ - -/*-----------------------------------------------------------* -* Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 . -*-----------------*/ -/*-----------------------------------------------------------* -* Qn0 : Qi at source side. -* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) -* - Derivatives of fs01 are redefined here. -*-----------------*/ -/* note:------------------------ -* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ; -* fs02 = sqrt( Xi0 + fs01 ) ; -*-------------------------------*/ - - Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; - - 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 ; - - Qn0_dVbs = Qn0 - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVds = Qn0 - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; - Qn0_dVgs = Qn0 - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ; - -/*-----------------------------------------------------------* -* Qb0 : Qb at source side. -*-----------------*/ - - if ( Chi > znbd5 ) { - - Qb0 = cnst0 * Xi0p12 ; - Qb0_dVbs = cnst0 * Xi0p12_dVbs ; - Qb0_dVds = cnst0 * Xi0p12_dVds ; - Qb0_dVgs = cnst0 * Xi0p12_dVgs ; - - } - -/*-----------------------------------------------------------* -* FD2 : connecting function for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ; - } - -/*-----------------------------------------------------------* -* Modify Qn0 for zone-D2. -*-----------------*/ - - if ( Chi < znbd5 ) { - - Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; - Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; - Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 - + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; - - Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; - - if ( Qn0 < 0.0 ) { - Qn0 = 0.0 ; - Qn0_dVbs = 0.0 ; - Qn0_dVds = 0.0 ; - Qn0_dVgs = 0.0 ; - } - - } - - - -/*---------------------------------------------------* -* VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) -*-----------------*/ - - VgVt = Qn0 * Cox_inv ; - VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVbs ; - VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVds ; - VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVgs ; - -/*-----------------------------------------------------------* -* make Qi=Qd=Ids=0 if VgVt <= VgVt_small -*-----------------*/ - - - if ( VgVt <= VgVt_small ) { - - - Psl = Ps0 ; - Psl_dVbs = Ps0_dVbs ; - Psl_dVds = Ps0_dVds ; - Psl_dVgs = Ps0_dVgs ; - - Psdl = Psl ; - Psdl_dVbs = Psl_dVbs ; - Psdl_dVds = Psl_dVds ; - Psdl_dVgs = Psl_dVgs ; - - Pds = 0.0 ; - Pds_dVbs = 0.0 ; - Pds_dVds = 0.0 ; - Pds_dVgs = 0.0 ; - - T1 = - Leff * Weff ; - Qb = T1 * Qb0 ; - Qb_dVbs = T1 * Qb0_dVbs ; - Qb_dVds = T1 * Qb0_dVds ; - Qb_dVgs = T1 * Qb0_dVgs ; - - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - - Ids = 0.0e0 ; - Ids_dVbs = 0.0e0 ; - Ids_dVds = 0.0e0 ; - Ids_dVgs = 0.0e0 ; - - flg_noqi = 1 ; - - goto end_of_part_1 ; - } - - - -/*-----------------------------------------------------------* -* Start point of Psl (= Ps0 + Pds) calculation. (label) -*-----------------*/ -start_of_Psl: ; - - exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; - -/*---------------------------------------------------* -* Skip Psl calculation when Vds is very small. -*-----------------*/ - if ( Vds <= epsm10 ) { - Pds = 0.0 ; - Psl = Ps0 ; - goto end_of_loopl ; - } - -/*-----------------------------------------------------------* -* Initial guess for Pds ( = Psl - Ps0 ). -*-----------------*/ - -/*---------------------------------------------------* -* Use previous value. -*-----------------*/ - if ( flg_pprv == 1 ) { - - Pds_ini = Pds + Pds_dVbs * dVbs - + Pds_dVds * dVds + Pds_dVgs * dVgs ; - - T1 = Pds_ini - Pds ; - - if ( T1 < - dP_max || T1 > dP_max ) { - flg_pprv = 0 ; - } - - } - -/*---------------------------------------------------* -* Analytical initial guess. -*-----------------*/ - if ( flg_pprv == 0 ) { - Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ); - - T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; - T2 = T1 - Vds - c_pslini_2 ; - T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; - - Pds_ini = T1 - ( T2 + T3 ) / 2 ; - - 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. -*-----------------*/ - - Pds = Pds_ini ; - Psl = Ps0 + Pds ; - - -/*---------------------------------------------------* -* Calculation of Psl by solving Poisson eqn. -* (beginning of Newton loop) -* - Fsl : Fsl = 0 is the equation to be solved. -* - dPsl : correction value. -*-----------------*/ - - - for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -* - Qb0 is approximated to 5-dgree polynomial. -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) - / ( fsl2 + fsl2 ) ; - } else { - fsl2 = sqrt( fb * fb + fsl1 ) ; - fsl2_dPsl = beta * fb_dChi ; - } - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - - if ( fsl1 < epsm10 * cnst1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - } - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; - - Fsl = Vgp - Psl - fac1 * fsl2 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - dPsl = - Fsl / Fsl_dPsl ; - - - } - -/*-------------------------------------------* -* Update Psl . -* - cramped to Vbs if Psl < Vbs . -*-----------------*/ - - if ( fabs( dPsl ) > dP_max ) { - dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; - } - - Psl = Psl + dPsl ; - - if ( Psl < Vbs ) { - Psl = Vbs ; - } - -/*-------------------------------------------* -* Check convergence. -* NOTE: This condition may be too rigid. -*-----------------*/ - - if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { - break ; - } - - } /* end of Psl Newton loop */ - -/*-------------------------------------------* -* Procedure for diverged case. -*-----------------*/ - if ( lp_sl > lp_sl_max ) { - 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" ) ; - } - } - - -/*---------------------------------------------------* -* End of Psl calculation. (label) -*-----------------*/ -end_of_loopl: ; - -/*---------------------------------------------------* -* Assign Pds. -*-----------------*/ - - Pds = Psl - Ps0 ; - - if ( Pds < ps_conv ) { - Pds = 0.0 ; - Psl = Ps0 ; - } - - - -/*---------------------------------------------------* -* 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. -*-----------------*/ - - Chi = beta * ( Psl - Vbs ) ; - -/*-------------------------------------------* -* zone-D2. (Psl) -*-----------------*/ - - if ( Chi < znbd5 ) { - - 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 ) ) ; - - - /*note: cfs1 = cnst1 * exp_bVbsVds */ - fsl1 = cfs1 * fi * fi ; - fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; - fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; - fsl1_dVds = - cfs1 * beta * fi * fi ; - - - 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 ) ; - - T2 = 0.5 / fsl2 ; - - if ( fsl2 >= epsm10 ) { - fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; - fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; - fsl2_dVds = fsl1_dVds * T2 ; - } else { - fsl2_dPsl = beta * fb_dChi ; - fsl2_dVbs = - beta * fb_dChi ; - fsl2_dVds = 0.0 ; - } - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - Pds_dVbs = Psl_dVbs - Ps0_dVbs ; - Pds_dVds = Psl_dVds - Ps0_dVds ; - Pds_dVgs = Psl_dVgs - Ps0_dVgs ; - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - -/*-------------------------------------------* -* zone-D3. (Psl) -*-----------------*/ - } else { - - Rho = beta * ( Psl - Vds ) ; - - exp_Rho = exp( Rho ) ; - - fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; - - fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; - - fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; - fsl1_dVds = - beta * fsl1 ; - - - if ( fsl1 < epsm10 * T1 ) { - fsl1 = 0.0 ; - fsl1_dPsl = 0.0 ; - fsl1_dVds = 0.0 ; - } - - - Xil = Chi - 1.0e0 ; - - Xilp12 = sqrt( Xil ) ; - Xilp32 = Xil * Xilp12 ; - - fsl2 = sqrt( Xil + fsl1 ) ; - - T2 = 0.5e0 / fsl2 ; - - fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; - - fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; - fsl2_dVds = ( fsl1_dVds ) * T2 ; - - /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ - - T2 = 0.5e0 / Xilp12 ; - - Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; - - Psl_dVbs = - ( Vgp_dVbs - - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) - ) / Fsl_dPsl ; - - Psl_dVds = - ( Vgp_dVds - - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) - ) / Fsl_dPsl ; - Psl_dVgs = - ( Vgp_dVgs - - fac1_dVgs * fsl2 - ) / Fsl_dPsl ; - - 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 ; - } - - - -/*-----------------------------------------------------------* -* Evaluate Qb and Idd. -* - Eta : substantial variable of QB'/Pds and Idd/Pds. -* - note: Eta = 4 * GAMMA_{hisim_0} -*-----------------*/ - - Eta = beta * Pds / Xi0 ; - - Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) - / Xi0 ; - Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; - Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; - - - /* ( 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 = - 0.5e0 / Xi0p32 ; - T4 = - 0.5e0 / Eta1p12 * F00 ; - - F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - - -/*---------------------------------------------------* -* 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_1o3 / Xi0p12 * T1 ; - T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ; - - F10_dVbs = Zeta32 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F10_dVds = Zeta32 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F10_dVgs = Zeta32 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - -/*---------------------------------------------------* -* 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 = 2e0 / ( 5e0 * beta ) * Xi0p12 * T1 ; - T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 - + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ; - - F30_dVbs = Zeta52 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; - F30_dVds = Zeta52 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; - F30_dVgs = Zeta52 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ; - -/*---------------------------------------------------* -* F11 := PS11/Pds. -*-----------------*/ - - F11 = Ps0 * F10 + C_2o3 / beta * Xilp32 - F30 ; - - F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs - + ( Xi0_dVbs / beta + Pds_dVbs ) * Xilp12 - - F30_dVbs ; - F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds - + ( Xi0_dVds / beta + Pds_dVds ) * Xilp12 - - F30_dVds ; - F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs - + ( Xi0_dVgs / beta + Pds_dVgs ) * Xilp12 - - F30_dVgs ; - -/*---------------------------------------------------* -* Fdd := Idd/Pds. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta - 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_dVbs * T1 - + T4 * ( - F10_dVbs + F00_dVbs ) ; - Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds ) - + beta * Cox_dVds * T1 - + T4 * ( - F10_dVds + F00_dVds ) ; - Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs ) - + beta * Cox_dVgs * T1 - + T4 * ( - F10_dVgs + F00_dVgs ) ; - -/*---------------------------------------------------* -* Q_B : bulk charge. -*-----------------*/ - - T1 = Vgp + 1.0e0 / beta ; - 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_dVbs * T2 ) ; - Qbnm_dVds = cnst0 - * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds ) - + Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds ) - + Cox_dVds * T2 ) ; - Qbnm_dVgs = cnst0 - * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs ) - + Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs ) - + Cox_dVgs * T2 ) ; - - T1 = - Weff * beta * Leff ; - - Qb = T1 * Qbnm / Fdd ; - - T2 = T1 / ( Fdd * Fdd ) ; - - Qb_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ; - Qb_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ; - Qb_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ; - -/*---------------------------------------------------* -* Breaking point for Qi=Qd=0. -*-----------------*/ - - if ( flg_noqi != 0 ) { - goto end_of_part_1 ; - } - -/*---------------------------------------------------* -* 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 ; - - - -/*-----------------------------------------------------------* -* Channel Length Modulation. Lred: \Delta L -*-----------------*/ - - if( sIN.clm2 < epsm10 && sIN.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 ; - } - - goto end_of_CLM ; - } - - - Ec = Idd / beta / Qn0 / Leff ; - Ec_dVbs = 1.0e0 / beta / Leff - * ( Idd_dVbs / Qn0 - Idd * Qn0_dVbs / Qn0 / Qn0 ) ; - Ec_dVds = ( Idd_dVds / Qn0 - Idd * Qn0_dVds / Qn0 / Qn0 ) - / beta / Leff ; - Ec_dVgs = 1.0e0 / beta / Leff - * ( Idd_dVgs / Qn0 - Idd * Qn0_dVgs / Qn0 / Qn0 ) ; - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - - T7 = Qn0 / Wd ; - T7_dVbs = ( Qn0_dVbs / Wd - Qn0 / Wd / Wd * Wd_dVbs ) ; - T7_dVds = ( Qn0_dVds / Wd - Qn0 / Wd / Wd * Wd_dVds ) ; - T7_dVgs = ( Qn0_dVgs / Wd - Qn0 / Wd / Wd * Wd_dVgs ) ; - - T8 = Ec * Ec + 2.0e0 / C_ESI * q_Nsub * ( Psdl - Psl ) + 1.0e5 ; - T8_dVbs = 2.0e0 * Ec * Ec_dVbs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVbs - Psl_dVbs ) ; - T8_dVds = 2.0e0 * Ec * Ec_dVds - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVds - Psl_dVds ) ; - T8_dVgs = 2.0e0 * Ec * Ec_dVgs - + 2.0e0 / C_ESI * q_Nsub * ( Psdl_dVgs - Psl_dVgs ) ; - - Ed = sqrt( T8 ) ; - Ed_dVbs = 0.5e0 / Ed * T8_dVbs ; - Ed_dVds = 0.5e0 / Ed * T8_dVds ; - Ed_dVgs = 0.5e0 / Ed * T8_dVgs ; - - - Lred = ( Ed - Ec ) - / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) * C_ESI ; - T1 = 1.0 / ( sIN.clm2 * q_Nsub + sIN.clm3 * T7 ) ; - T2 = T1 * T1 ; - Lred_dVbs = ( ( Ed_dVbs - Ec_dVbs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVbs ) * C_ESI ; - Lred_dVds = ( ( Ed_dVds - Ec_dVds ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVds ) * C_ESI ; - Lred_dVgs = ( ( Ed_dVgs - Ec_dVgs ) * T1 - - ( Ed - Ec ) * T2 * sIN.clm3 * T7_dVgs ) * C_ESI ; - -/*---------------------------------------------------* -* Modify Lred for symmetry. -*-----------------*/ - - end_of_CLM2: ; - - TX = Vds / cclmmdf ; - T2 = TX * TX ; - T5 = 1.0 + T2 ; - - FMD = 1.0 - 1.0 / T5 ; - FMD_dVds = 2.0 * Vds / ( T5 * T5 * cclmmdf * cclmmdf ) ; - - T6 = Lred ; - - Lred = FMD * T6 ; - Lred_dVbs *= FMD ; - Lred_dVds = FMD_dVds * ( T6 ) + FMD * Lred_dVds ; - Lred_dVgs *= FMD ; - -/*-------------------------------------------* -* End point of CLM. (label) -*-----------------*/ -end_of_CLM: ; - - -/*---------------------------------------------------* -* preparation for Qi and Qd. -*-----------------*/ - - T1 = 2.0e0 * fac1 ; - - DtPds = T1 * ( F10 - Xi0p12 ) ; - - T2 = 2.0 * ( F10 - Xi0p12 ) ; - - DtPds_dVbs = T1 * ( F10_dVbs - - 0.5 * beta * ( Ps0_dVbs - 1.0e0 ) / Xi0p12 ) - + T2 * fac1_dVbs ; - DtPds_dVds = T1 * ( F10_dVds - - 0.5 * beta * Ps0_dVds / Xi0p12 ) - + T2 * fac1_dVds ; - DtPds_dVgs = T1 * ( F10_dVgs - - 0.5 * beta * Ps0_dVgs / Xi0p12 ) - + 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. -* - cramped to 0 if Alpha < 0. -*-----------------*/ - - Alpha = 1.0e0 - Achi / VgVt ; - - if ( Alpha >= 0.0e0 ) { - - Alpha_dVbs = - Achi_dVbs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVbs / VgVt ) ; - Alpha_dVds = - Achi_dVds / VgVt + ( Achi / VgVt ) - * ( VgVt_dVds / VgVt ) ; - Alpha_dVgs = - Achi_dVgs / VgVt + ( Achi / VgVt ) - * ( VgVt_dVgs / VgVt ) ; - - } else { - - Alpha = 0.0e0 ; - Alpha_dVbs = 0.0e0 ; - Alpha_dVds = 0.0e0 ; - Alpha_dVgs = 0.0e0 ; - } - -/*-----------------------------------------------------------* -* Q_I : inversion charge. -*-----------------*/ - - Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ; - Qinm_dVbs = Alpha_dVbs * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVds = Alpha_dVds * ( 1.0e0 + Alpha + Alpha ) ; - Qinm_dVgs = Alpha_dVgs * ( 1.0e0 + Alpha + Alpha ) ; - - Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ; - Qidn_dVbs = Alpha_dVbs ; - Qidn_dVds = Alpha_dVds ; - Qidn_dVgs = Alpha_dVgs ; - - T1 = - Weff * ( Leff - Lred ) * C_2o3 * VgVt * Qinm / Qidn ; - - Qi = T1 * Cox ; - - Qi_dVbs = Qi * ( VgVt_dVbs / VgVt - + Qinm_dVbs / Qinm - Qidn_dVbs / Qidn - - Lred_dVbs/ ( Leff - Lred ) ) - + T1 * Cox_dVbs ; - Qi_dVds = Qi * ( VgVt_dVds / VgVt - + Qinm_dVds / Qinm - Qidn_dVds / Qidn - - Lred_dVds/ ( Leff - Lred ) ) - + T1 * Cox_dVds ; - Qi_dVgs = Qi * ( VgVt_dVgs / VgVt - + Qinm_dVgs / Qinm - Qidn_dVgs / Qidn - - Lred_dVgs/ ( Leff - Lred ) ) - + T1 * Cox_dVgs ; - -/*-----------------------------------------------------------* -* Q_D : drain charge. -*-----------------*/ - - 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 ) { - Qdrat_dVbs = Quot * ( Qddn_dVbs / Qddn - Qdnm_dVbs / Qdnm ) ; - Qdrat_dVds = Quot * ( Qddn_dVds / Qddn - Qdnm_dVds / Qdnm ) ; - Qdrat_dVgs = Quot * ( Qddn_dVgs / Qddn - Qdnm_dVgs / Qdnm ) ; - } else { - Qdrat = 0.5e0 ; - Qdrat_dVbs = 0.0e0 ; - Qdrat_dVds = 0.0e0 ; - Qdrat_dVgs = 0.0e0 ; - } - - 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 ; - -/*-----------------------------------------------------------* -* Modify charges for zone-D2. -* - FD2 must be defined previously. -*-----------------*/ - - Chi = beta * ( Ps0 - Vbs ) ; - - if ( Chi < znbd5 ) { - - 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 ; - - T5 = - Leff * Weff ; - - Qb_dVbs = FD2 * Qb_dVbs + FD2_dVbs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVbs - FD2_dVbs * T5 * Qb0 ; - Qb_dVds = FD2 * Qb_dVds + FD2_dVds * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVds - FD2_dVds * T5 * Qb0 ; - Qb_dVgs = FD2 * Qb_dVgs + FD2_dVgs * Qb - + ( 1.0 - FD2 ) * T5 * Qb0_dVgs - FD2_dVgs * T5 * Qb0 ; - - Qb = FD2 * Qb + ( 1.0 - FD2 ) * T5 * Qb0 ; - - if ( Qb > 0.0 ) { - Qb = 0.0 ; - Qb_dVbs = 0.0 ; - Qb_dVds = 0.0 ; - Qb_dVgs = 0.0 ; - } - - Qi_dVbs = FD2 * Qi_dVbs + FD2_dVbs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVbs - FD2_dVbs * T5 * Qn0 ; - Qi_dVds = FD2 * Qi_dVds + FD2_dVds * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVds - FD2_dVds * T5 * Qn0 ; - Qi_dVgs = FD2 * Qi_dVgs + FD2_dVgs * Qi - + ( 1.0 - FD2 ) * T5 * Qn0_dVgs - FD2_dVgs * T5 * Qn0 ; - - Qi = FD2 * Qi + ( 1.0 - FD2 ) * T5 * Qn0 ; - - if ( Qi > 0.0 ) { - Qi = 0.0 ; - Qi_dVbs = 0.0 ; - Qi_dVds = 0.0 ; - Qi_dVgs = 0.0 ; - } - - Qd_dVbs = FD2 * Qd_dVbs + FD2_dVbs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVbs / 2 - - FD2_dVbs * T5 * Qi / 2 ; - Qd_dVds = FD2 * Qd_dVds + FD2_dVds * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVds / 2 - - FD2_dVds * T5 * Qi / 2 ; - Qd_dVgs = FD2 * Qd_dVgs + FD2_dVgs * Qd - + ( 1.0 - FD2 ) * T5 * Qi_dVgs / 2 - - FD2_dVgs * T5 * Qi / 2 ; - - Qd = FD2 * Qd + ( 1.0 - FD2 ) * T5 * Qi / 2 ; - - if ( Qd > 0.0 ) { - Qd = 0.0 ; - Qd_dVbs = 0.0 ; - Qd_dVds = 0.0 ; - Qd_dVgs = 0.0 ; - } - - } - - - -/*-----------------------------------------------------------* -* Modified potential for symmetry. -*-----------------*/ - - T1 = exp( - ( Vds - Pds ) / ( 2.0 * sIN.pzadd0 ) ) ; - - Pzadd = sIN.pzadd0 * T1 ; - - T2 = - 0.5 * T1 ; - - Pzadd_dVbs = T2 * ( - Pds_dVbs ) ; - Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ; - Pzadd_dVgs = T2 * ( - Pds_dVgs ) ; - - if ( fabs ( Pzadd ) < epsm10 ) { - Pzadd = 0.0 ; - 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 ; - - -/*-----------------------------------------------------------* -* Evaluate universal mobility. -*-----------------*/ - - Ps0Vbsz = Ps0z - Vbsz ; - Ps0Vbsz_dVbs = Ps0z_dVbs - Vbsz_dVbs ; - Ps0Vbsz_dVds = Ps0z_dVds - Vbsz_dVds ; - Ps0Vbsz_dVgs = Ps0z_dVgs ; - - -/*-------------------------------------------* -* Qbm -*-----------------*/ - - T1 = cnst0 ; - T2 = sqrt( beta * Ps0Vbsz - 1.0 ) ; - - Qbm = T1 * T2 ; - - T3 = 0.5 * beta * T1 / T2 ; - - Qbm_dVbs = T3 * Ps0Vbsz_dVbs ; - Qbm_dVds = T3 * Ps0Vbsz_dVds ; - Qbm_dVgs = T3 * Ps0Vbsz_dVgs ; - -/*-------------------------------------------* -* Qnm -*-----------------*/ - - Chi = beta * Ps0Vbsz ; - - exp_Chi = exp( Chi ) ; - - exp_bVbs = exp( beta * Vbsz ) ; - - cfs1 = cnst1 * exp_bVbs ; - - fs01 = cfs1 * ( exp_Chi - 1.0 ) ; - - /* regard fs01 as a function of Chi and Vbs */ - fs01_dChi = cfs1 * ( exp_Chi ) ; - fs01_dVbs = beta * fs01 ; - - - if ( fs01 < epsm10 * cfs1 ) { - fs01 = 0.0 ; - fs01_dPs0 = 0.0 ; - fs01_dVbs = 0.0 ; - } - - Xi0z = Chi - 1.0e0 ; - - Xi0z_dVbs = beta * Ps0Vbsz_dVbs ; - Xi0z_dVds = beta * Ps0Vbsz_dVds ; - Xi0z_dVgs = beta * Ps0Vbsz_dVgs ; - - fs02 = sqrt( Xi0z + fs01 ) ; - - T2 = 0.5e0 / fs02 ; - - /* regard fs01 as a function of Chi and Vbs */ - fs02_dChi = ( 1.0 + fs01_dChi ) * T2 ; - fs02_dVbs = fs01_dVbs * T2 ; - - Xi0zp12 = sqrt( Xi0z ) ; - - Xi0zp12_dVbs = 0.5e0 * Xi0z_dVbs / Xi0zp12 ; - Xi0zp12_dVds = 0.5e0 * Xi0z_dVds / Xi0zp12 ; - Xi0zp12_dVgs = 0.5e0 * Xi0z_dVgs / Xi0zp12 ; - - T1 = 1.0 / ( fs02 + Xi0zp12 ) ; - - Qnm = cnst0 * fs01 * T1 ; - - fs01_dVds = beta * Ps0Vbsz_dVds * fs01_dChi - + fs01_dVbs * Vbsz_dVds ; - fs01_dVbs = beta * Ps0Vbsz_dVbs * fs01_dChi + fs01_dVbs ; - fs01_dVgs = beta * Ps0Vbsz_dVgs * fs01_dChi ; - - fs02_dVds = beta * Ps0Vbsz_dVds * fs02_dChi - + fs02_dVbs * Vbsz_dVds ; - fs02_dVbs = beta * Ps0Vbsz_dVbs * fs02_dChi + fs02_dVbs ; - fs02_dVgs = beta * Ps0Vbsz_dVgs * fs02_dChi ; - - Qnm_dVbs = Qnm - * ( fs01_dVbs / fs01 - - ( fs02_dVbs + Xi0zp12_dVbs ) * T1 ) ; - Qnm_dVds = Qnm - * ( fs01_dVds / fs01 - - ( fs02_dVds + Xi0zp12_dVds ) * T1 ) ; - Qnm_dVgs = Qnm - * ( fs01_dVgs / fs01 - - ( fs02_dVgs + Xi0zp12_dVgs ) * T1 ) ; - - if ( Qbm < 0.0 ) { - Qbm = 0.0 ; - } - if ( Qnm < 0.0 ) { - Qnm = 0.0 ; - } - - - -/*---------------------------------------------------* -* Muun : universal mobility. -*-----------------*/ - - /* removed Eqs. "Qbm = Qb0", "Qnm = Qn0", ... (4/Dec/01) */ - - T1 = sIN.ninv - sIN.ninvd * Vdsz ; - T1_dVds = - sIN.ninvd * Vdsz_dVds ; - - Eeff = ( sIN.ndep * Qbm + T1 * Qnm ) / C_ESI ; - Eeff_dVbs = ( sIN.ndep * Qbm_dVbs + T1 * Qnm_dVbs ) - / C_ESI ; - Eeff_dVds = ( sIN.ndep * Qbm_dVds + T1 * Qnm_dVds - + T1_dVds * Qnm ) - / C_ESI ; - Eeff_dVgs = ( sIN.ndep * Qbm_dVgs + T1 * Qnm_dVgs ) - / C_ESI ; - - Rns = Qnm / C_QE ; - - T10 = pow( sIN.temp / C_T300 , sIN.muetmp ) ; - T21 = pow( Eeff , sIN.mueph0 - 1.0e0 ) ; - T20 = T21 * Eeff ; - T31 = pow( Eeff , sIN.muesr0 - 1.0e0 ) ; - T30 = T31 * Eeff ; - - T1 = 1e0 / ( sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ) - + T10 - * T20 / mueph - + T30 / sIN.muesr1 ; - - Muun = 1e0 / T1 ; - - T1 = 1e0 / ( T1 * T1 ) ; - T2 = sIN.muecb0 + sIN.muecb1 * Rns / 1e11 ; - T2 = 1e0 / ( T2 * T2 ) ; - T3 = T10 * sIN.mueph0 * T21 / mueph ; - T4 = sIN.muesr0 * T31 / sIN.muesr1 ; - - Muun_dVbs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVbs / C_QE * T2 - + Eeff_dVbs * T3 - + Eeff_dVbs * T4 ) - * T1 ; - Muun_dVds = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVds / C_QE * T2 - + Eeff_dVds * T3 - + Eeff_dVds * T4 ) - * T1 ; - Muun_dVgs = - 1 * ( - 1e-11 * sIN.muecb1 * Qnm_dVgs / C_QE * T2 - + Eeff_dVgs * T3 - + Eeff_dVgs * T4 ) - * T1 ; - - -/*-----------------------------------------------------------* -* Mu : mobility -*-----------------*/ - - T1 = 1.0e0 / beta / ( Qn0 + small ) / ( Leff - Lred ) ; - T1_dVbs = 1.0e0 / beta * ( - Qn0_dVbs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVbs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVds = 1.0e0 / beta * ( - Qn0_dVds / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVds / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - T1_dVgs = 1.0e0 / beta * ( - Qn0_dVgs / ( Qn0 + small ) - / ( Qn0 + small ) / ( Leff - Lred ) - + Lred_dVgs / ( Qn0 + small ) / ( Leff - Lred ) - / ( Leff - Lred ) ) ; - - Ey = Idd * T1 ; - Ey_dVbs = Idd_dVbs * T1 + Idd * T1_dVbs ; - Ey_dVds = Idd_dVds * T1 + Idd * T1_dVds ; - Ey_dVgs = Idd_dVgs * T1 + Idd * T1_dVgs ; - - - 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 = sIN.temp / C_T300 ; - - Vmax = sIN.vmax / ( 1.8 + 0.4 * T1 + 0.1 * T1 * T1 ) ; - - T2 = 1.0 - sIN.vover / pow( Lgate , sIN.voverp ) ; - - if ( T2 < 0.01 ) { - fprintf( stderr , - "*** warning(HiSIM): Overshoot is too big.\n" ) ; - T2 = 0.01 ; - } - - Vmax = Vmax / T2 ; - - T1 = Em / Vmax ; - - /* note: sIN.bb = 2 (electron) ;1 (hole) */ - if ( 1.0e0 - epsm10 <= sIN.bb && sIN.bb <= 1.0e0 + epsm10 ) { - T3 = 1.0e0 ; - } else if ( 2.0e0 - epsm10 <= sIN.bb - && sIN.bb <= 2.0e0 + epsm10 ) { - T3 = T1 ; - } else { - T3 = pow( T1 , sIN.bb - 1.0e0 ) ; - } - T2 = T1 * T3 ; - T4 = 1.0e0 + T2 ; - T6 = pow( T4 , ( - 1.0e0 / sIN.bb - 1.0e0 ) ) ; - T5 = T4 * T6 ; - - Mu = Muun * T5 ; - Mu_dVbs = Muun_dVbs * T5 - Muun / Vmax * T6 * T3 * Em_dVbs ; - Mu_dVds = Muun_dVds * T5 - Muun / Vmax * T6 * T3 * Em_dVds ; - Mu_dVgs = Muun_dVgs * T5 - Muun / Vmax * T6 * T3 * Em_dVgs ; - - -end_of_mobility : ; - -/*-----------------------------------------------------------* -* Ids: channel current. -*-----------------*/ - - - T1 = Weff / beta / ( Leff - Lred ) ; - T1_dVbs = T1 / ( Leff - Lred ) * Lred_dVbs ; - T1_dVds = T1 / ( Leff - Lred ) * Lred_dVds ; - T1_dVgs = T1 / ( Leff - Lred ) * Lred_dVgs ; - - Ids0 = T1 * Idd * Mu ; - Ids0_dVbs = T1 * ( Mu * Idd_dVbs + Idd * Mu_dVbs ) - + T1_dVbs * Mu * Idd ; - Ids0_dVds = T1 * ( Mu * Idd_dVds + Idd * Mu_dVds ) - + T1_dVds * Mu * Idd ; - Ids0_dVgs = T1 * ( Mu * Idd_dVgs + Idd * Mu_dVgs ) - + T1_dVgs * Mu * Idd ; - - T1 = Vdsz + sIN.rpock2 ; - T2 = T1 * T1 + small ; - T2_dVbs = 0.0e0 ; - T2_dVds = 2.0 * T1 * Vdsz_dVds ; - T2_dVgs = 0.0e0 ; - - rp1 = FMD * sIN.rpock1 ; - rp1_dVds = FMD_dVds * sIN.rpock1 ; - - TX = pow( Ids0, sIN.rpocp1 ) * pow( Leff / 1.0e-4 , sIN.rpocp2 ) / Weff ; - T3 = rp1 * TX ; - T4 = ( T3 + T2 ) * ( T3 + T2 ); - - Ids = Ids0 / ( 1.0 + T3 / T2 ) ; - - T5 = T2 * ( T2 - ( sIN.rpocp1 - 1.0 ) * T3 ) / T4 ; - T6 = Ids0 * T3 / T4 ; - - Ids_dVbs = T5 * Ids0_dVbs + T6 * T2_dVbs ; - Ids_dVds = T5 * Ids0_dVds + T6 * T2_dVds - - Ids0 * T2 / T4 * rp1_dVds * TX ; - Ids_dVgs = T5 * Ids0_dVgs + T6 * T2_dVgs ; - - if ( Pds < ps_conv ) { - Ids_dVbs = 0.0 ; - Ids_dVgs = 0.0 ; - } - - Ids += Gdsmin * Vds ; - Ids_dVds += Gdsmin ; - -/*-----------------------------------------------------------* -* STI -*-----------------*/ - if ( sIN.coisti == 0 ) { - goto end_of_STI ; - } - - Vth_dVbs = Vthp_dVbs - dVth_dVbs ; - Vth_dVds = Vthp_dVds - dVth_dVds ; - Vth_dVbs = Vthp_dVgs - dVth_dVgs ; - - Vgssti = Vgs - Vfb + Vth * sIN.wvthsc; - Vgssti_dVbs = Vth_dVbs * sIN.wvthsc; - Vgssti_dVds = Vth_dVds * sIN.wvthsc; - Vgssti_dVgs = 1.0e0 + Vth_dVgs * sIN.wvthsc; - - costi0 = sqrt (2.0e0 * C_QE * sIN.nsti * C_ESI / beta); - costi1 = Nin * Nin / sIN.nsti / sIN.nsti ; - costi3 = costi0 * costi0 / Cox / Cox ; - costi4 = costi3 * beta / 2.0e0 ; - costi5 = costi4 * beta * 2.0e0 ; - costi6 = sqrt(1.0e0 - + 4.0e0 * (beta * (Vgssti - Vbs)-1.0e0) /costi5) ; - - Psasti = Vgssti + costi4 * (1.0e0 - costi6) ; - - Psasti_dVbs = Vgssti_dVbs - (Vgssti_dVbs - 1.0e0)/costi6 ; - Psasti_dVds = Vgssti_dVds - Vgssti_dVds/costi6 ; - Psasti_dVgs = Vgssti_dVgs - Vgssti_dVgs/costi6 ; - - Asti = 1.0e0 / costi1 / costi3 ; - Psbsti = log(Asti * (Vgssti*Vgssti)) / (beta + 2.0e0 / Vgssti) ; - - Psbsti_dVbs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVbs ; - Psbsti_dVds = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * Vgssti_dVds ; - Psbsti_dVgs = 2.0e0 / (beta*Vgssti + 2.0e0) - * (1.0e0 + Psbsti/Vgssti) * 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 ; - - Psti = Psbsti - 0.5e0 * (Psab - + sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti)) ; - - Psti_dVbs = Psbsti_dVbs - 0.5e0 * Psab_dVbs - - (Psab * Psab_dVbs +2.0e0 * sti2_dlt * Psbsti_dVbs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVds = Psbsti_dVds - 0.5e0 * Psab_dVds - - (Psab * Psab_dVds +2.0e0 * sti2_dlt * Psbsti_dVds) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - Psti_dVgs = Psbsti_dVgs - 0.5e0 * Psab_dVgs - - (Psab * Psab_dVgs +2.0e0 * sti2_dlt * Psbsti_dVgs) - * 0.5e0 / sqrt(Psab * Psab + 4.0e0 * sti2_dlt * Psbsti) ; - - expsti = exp(beta * Psti) ; - sq1sti = sqrt(beta * (Psti - Vbs) - 1.0e0 +costi1 * expsti) ; - - sq1sti_dVbs = 0.50e0 * (beta * (Psti_dVbs - 1.0e0) - + costi1 * beta * Psti_dVbs * expsti) / sq1sti ; - sq1sti_dVds = 0.50e0 * (beta * Psti_dVds - + costi1 * beta * Psti_dVds * expsti) / sq1sti ; - sq1sti_dVgs = 0.50e0 * (beta * Psti_dVgs - + costi1 * beta * Psti_dVgs * expsti) / sq1sti ; - - sq2sti = sqrt(beta * (Psti - Vbs) - 1.0e0) ; - - sq2sti_dVbs = 0.50e0 * beta *(Psti_dVbs - 1.0e0) / sq2sti ; - sq2sti_dVds = 0.50e0 * beta *Psti_dVds / sq2sti ; - sq2sti_dVgs = 0.50e0 * beta *Psti_dVgs / sq2sti ; - - 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) ; - - costi7 = 2.0e0 * sIN.wsti / beta ; - Idssti = costi7 * Mu * Qn0sti * (1.0e0 - exp(-beta * Vds)) - / (Leff - Lred) ; - - Idssti_dVbs = costi7 * (( Mu_dVbs * Qn0sti + Mu * Qn0sti_dVbs ) - * ( 1.0e0 - exp( - beta * Vds )) - + Lred_dVbs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred )) ; - Idssti_dVds = costi7 * (( Mu_dVds * Qn0sti + Mu * Qn0sti_dVds - + beta * Mu * Qn0sti ) * ( 1.0e0 - exp( - beta * Vds )) - + Lred_dVds * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred )) ; - Idssti_dVgs = costi7 * (( Mu_dVgs * Qn0sti + Mu * Qn0sti_dVgs ) - * ( 1.0e0 - exp( - beta * Vds )) - + Lred_dVgs * Mu * Qn0sti * ( 1.0e0 - exp( - beta * Vds )) - / ( Leff - Lred )) ; - - Ids = Ids + Idssti ; - - Ids_dVbs = Ids_dVbs + Idssti_dVbs ; - Ids_dVds = Ids_dVds + Idssti_dVds ; - Ids_dVgs = Ids_dVgs + Idssti_dVgs ; - end_of_STI: ; - - -/*-----------------------------------------------------------* -* 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 ) || - 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 -- ; } - - -/*-----------------------------------------------------------* -* End of PART-1. (label) -*-----------------*/ -end_of_part_1: ; - - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-2: Substrate / gate / leak currents -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Isub : substrate current induced by impact ionization. -*-----------------*/ -/*-------------------------------------------* -* Accumulation zone or nonconductive case, in which Ids==0. -*-----------------*/ - - if ( Ids <= 0.0e0 || sIN.coisub == 0 ) { - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - goto end_of_Isub ; - } - -/*-------------------------------------------* -* Conductive case. -*-----------------*/ - - if ( sIN.sub1 > 0.0e0 && sIN.vmax > 0.0e0 ) { - - Vdep = Vds + Ps0 - sIN.sub3 * Psl ; - Vdep_dVbs = Ps0_dVbs - sIN.sub3 * Psl_dVbs ; - Vdep_dVds = 1.0e0 + Ps0_dVds - sIN.sub3 * Psl_dVds ; - Vdep_dVgs = Ps0_dVgs - sIN.sub3 * Psl_dVgs ; - - TX = - sIN.sub2 / Vdep ; - - Epkf = exp( TX ) ; - Epkf_dVbs = - TX * Vdep_dVbs / Vdep * Epkf ; - Epkf_dVds = - TX * Vdep_dVds / Vdep * Epkf ; - Epkf_dVgs = - TX * Vdep_dVgs / Vdep * Epkf ; - - T1 = Ids * Epkf ; - T1_dVbs = Ids_dVbs * Epkf + Ids * Epkf_dVbs ; - T1_dVds = Ids_dVds * Epkf + Ids * Epkf_dVds ; - T1_dVgs = Ids_dVgs * Epkf + Ids * Epkf_dVgs ; - - if( T1 < 1.0e-25 ){ - T1 = 1.0e-25 ; - T1_dVbs = 0.0e0 ; - T1_dVds = 0.0e0 ; - T1_dVgs = 0.0e0 ; - } - - Isub = sIN.sub1 * Vdep * T1 ; - Isub_dVbs = sIN.sub1 * ( Vdep_dVbs * T1 + Vdep * T1_dVbs ) ; - Isub_dVds = sIN.sub1 * ( Vdep_dVds * T1 + Vdep * T1_dVds ) ; - Isub_dVgs = sIN.sub1 * ( Vdep_dVgs * T1 + Vdep * T1_dVgs ) ; - - } else { - - Isub = 0.0e0 ; - Isub_dVbs = 0.0e0 ; - Isub_dVds = 0.0e0 ; - Isub_dVgs = 0.0e0 ; - - } /* end of if ( sIN.sub1 ... ) else block. */ - -/*-------------------------------------------* -* End of Isub. (label) -*-----------------*/ -end_of_Isub: ; - -/*-----------------------------------------------------------* -* Igs : Gate current induced by tunneling. -* - Vzadd is used for symmetrizing. -*-----------------*/ - - Egp12 = sqrt( Eg ) ; - Egp32 = Eg * Egp12 ; - - if ( sIN.coiigs == 0 ) { - Igs = 0.0e0 ; - Igs_dVbs = 0.0e0 ; - Igs_dVds = 0.0e0 ; - Igs_dVgs = 0.0e0 ; - goto end_of_Igs ; - } - - Vgpz = Vgp + Vzadd ; - - Vgpz_dVbs = Vgp_dVbs ; - Vgpz_dVds = Vgp_dVds + Vzadd_dVds ; - Vgpz_dVgs = Vgp_dVgs ; - - T1 = Vgpz - ( Psl + Ps0 + 2.0 * Vzadd ) * sIN.gleak3 ; - - E0 = 10.0 ; - - E2 = T1 / Tox ; - - E2_dVbs = E2 - * ( ( Vgpz_dVbs - ( Psl_dVbs + Ps0_dVbs ) * sIN.gleak3 ) - / T1 - - Tox_dVbs / Tox ) ; - E2_dVds = E2 - * ( ( Vgpz_dVds - - ( Psl_dVds + Ps0_dVds + 2.0 * Vzadd_dVds ) - * sIN.gleak3 - ) / T1 - - Tox_dVds / Tox ) ; - E2_dVgs = E2 - * ( ( Vgpz_dVgs - ( Psl_dVgs + Ps0_dVgs ) * sIN.gleak3 ) - / T1 - - Tox_dVgs / Tox ) ; - - T1 = E2 - E0 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E2 ) ; - - Etun = E2 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = 2.0 * T1 * T4 + 0.5 ; - - Etun_dVbs = T5 * E2_dVbs ; - Etun_dVds = T5 * E2_dVds ; - Etun_dVgs = T5 * E2_dVgs ; - - T1 = exp( - sIN.gleak2 * Egp32 / Etun ) ; - - T2 = sIN.gleak1 / Egp12 * C_QE * Weff * Leff ; - - Igs = T2 * Etun * Etun * T1 ; - - T3 = T2 * T1 * ( 2.0 * Etun + sIN.gleak2 * Egp32 ) ; - - Igs_dVbs = T3 * Etun_dVbs ; - Igs_dVds = T3 * Etun_dVds ; - Igs_dVgs = T3 * Etun_dVgs ; - - end_of_Igs: ; - -/*-----------------------------------------------------------* -* Ilg : GIDL -*-----------------*/ - - if ( sIN.cogidl == 0 ) { - Ilg = 0.0e0 ; - Ilg_dVbs = 0.0e0 ; - Ilg_dVds = 0.0e0 ; - Ilg_dVgs = 0.0e0 ; - goto end_of_IGIDL ; - } - - T1 = sIN.gidl3 * Vdsz - Vgsz + dVth ; - - E1 = T1 / Tox ; - - E1_dVbs = E1 * ( dVth_dVbs / T1 - Tox_dVbs / Tox ) ; - E1_dVds = E1 * ( ( sIN.gidl3 * Vdsz_dVds - Vgsz_dVds + dVth_dVds ) - / T1 - - Tox_dVds / Tox ) ; - E1_dVgs = E1 * ( ( -1.0 + dVth_dVgs ) / T1 - Tox_dVgs / Tox ) ; - - T1 = E0 - E1 - eef_dlt ; - T2 = T1 * T1 ; - - T3 = sqrt( T2 + 4.0 * eef_dlt * E0 ) ; - - Egidl = E0 - ( T1 - T3 ) / 2 ; - - T4 = 1.0 / ( 4.0 * T3 ) ; - T5 = - 2.0 * T1 * T4 + 0.5 ; - - Egidl_dVbs = T5 * E1_dVbs ; - Egidl_dVds = T5 * E1_dVds ; - Egidl_dVgs = T5 * E1_dVgs ; - - T1 = exp( - sIN.gidl2 * Egp32 / Egidl ) ; - - T2 = sIN.gidl1 / Egp12 * C_QE * Weff ; - - Ilg = T2 * Egidl * Egidl * T1 ; - - T3 = T2 * T1 * ( 2.0 * Egidl + sIN.gidl2 * Egp32 ) ; - - Ilg_dVbs = T3 * Egidl_dVbs ; - Ilg_dVds = T3 * Egidl_dVds ; - Ilg_dVgs = T3 * Egidl_dVgs ; - - end_of_IGIDL: ; - -/*-----------------------------------------------------------* -* End of PART-2. (label) -*-----------------*/ -end_of_part_2: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-3: Overlap charge -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - -/*-------------------------------------------* -* Calculation of Psdl for cases of flg_noqi==1. -*-----------------*/ - - if ( flg_noqi != 0 ) { - - T2 = Vds + Ps0 ; - T2_dVbs = Ps0_dVbs ; - T2_dVds = 1.0e0 + Ps0_dVds ; - T2_dVgs = Ps0_dVgs ; - - Aclm = sIN.clm1 ; - - Psdl = Aclm * T2 + ( 1.0e0 - Aclm ) * Psl ; - Psdl_dVbs = Aclm * T2_dVbs + ( 1.0e0 - Aclm ) * Psl_dVbs ; - Psdl_dVds = Aclm * T2_dVds + ( 1.0e0 - Aclm ) * Psl_dVds ; - Psdl_dVgs = Aclm * T2_dVgs + ( 1.0e0 - Aclm ) * Psl_dVgs ; - - Ec = 0.0e0 ; - Ec_dVbs =0.0e0 ; - Ec_dVds =0.0e0 ; - Ec_dVgs =0.0e0 ; - - T1 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - if ( Psl - Vbs > 0 ){ - T9 = sqrt( Psl - Vbs ) ; - Wd = T1 * T9 ; - Wd_dVbs = 0.5e0 * T1 / T9 * ( Psl_dVbs - 1.0e0 ) ; - Wd_dVds = 0.5e0 * T1 / T9 * Psl_dVds ; - Wd_dVgs = 0.5e0 * T1 / T9 * Psl_dVgs ; - }else{ - Wd = 0e0 ; - Wd_dVbs = 0e0 ; - Wd_dVds = 0e0 ; - Wd_dVgs = 0e0 ; - } - - if ( Psdl > Ps0 + Vds - epsm10 ) { - Psdl = Ps0 + Vds - epsm10 ; - } - } - - -/*-------------------------------------------* -* Overlap charge (simple, default, CLM1 < 1.0) <-- changed 04/Dec/01 -* (orig. "CLM1 must be 1.0") -*-----------------*/ - if ( sIN.coovlp == 0 ){ - - T1 = Cox * Weff ; - Lov = sIN.xld + sIN.xpolyd ; - Qgos = Vgs * Lov * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = Lov * T1 ; - - T2 = - 1.0e+11 ; - yn = sqrt ( ( Psdl - Ps0 - Vds) / T2 ) ; - yn2 = yn * yn ; - yn3 = yn2 * yn ; - - - if ( yn <= Lov ){ - Qgod = ( ( Vgs - Vds ) * Lov - T2 * yn3 / 3.0e0 ) * T1 ; - Qgod_dVbs = ( (-0.5e0) * yn * ( Psdl_dVbs - Ps0_dVbs ) ) * T1 ; - Qgod_dVds = ( (-1.0e0) * Lov - 0.5e0 * yn - * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ) * T1 ; - Qgod_dVgs = ( Lov - 0.5e0 * yn * ( Psdl_dVgs - Ps0_dVgs ) ) * T1 ; - }else{ - T3 = 0.5e0 / yn / T2 ; - yn_dVbs = T3 * ( Psdl_dVbs - Ps0_dVbs ) ; - yn_dVds = T3 * ( Psdl_dVds - Ps0_dVds - 1.0e0 ) ; - yn_dVgs = T3 * ( Psdl_dVgs - Ps0_dVgs ) ; - - T4 = (Lov - yn ) * (Lov - yn ) ; - T5 = T4 * (Lov - yn ) ; - Qgod = ( ( Vgs - Vds ) * Lov - T2 / 3.0e0 * ( T5 + yn3 ) ) * T1 ; - Qgod_dVbs = ( (-1.0e0) * T2 * yn2 * yn_dVbs - + T2 * T4 * yn_dVbs ) * T1; - Qgod_dVds = ( (-1.0e0) * Lov - T2 * yn2 * yn_dVds - + T2 * T4 * yn_dVds ) * T1; - Qgod_dVgs = ( Lov - T2 * yn2 * yn_dVgs - + T2 * T4 * yn_dVgs ) * T1; - } - } -/*-------------------------------------------* -* Overlap charge (complete) -*-----------------*/ - - else if( sIN.coovlp > 0 ){ - - T1 = Cox * Weff ; - - Qgos = Vgs * ( sIN.xld + sIN.xpolyd ) * T1 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = ( sIN.xld + sIN.xpolyd ) * T1 ; - - T3 = 1e21 / pow( sIN.xld + sIN.xpolyd , 3e0) ; - T1 = C_QE * T3 / ( C_ESI * 4e0 ) ; - T2 = Cox * Weff ; - - Lov = sIN.xld + sIN.xpolyd ; - Lov2 = Lov * Lov ; - - yn = pow( C_ESI * 5e0 / ( C_QE * T3 ) - * ( Ps0 + Vds - Psdl ) - , 0.2e0 ) ; - yn2 = yn * yn ; - - if ( yn < Lov ) { - Qgod = ( ( Vgs - Vds ) * ( sIN.xld + sIN.xpolyd ) - + T1 / 3e0 * yn2 * yn2 * yn2 ) * T2 ; - Qgod_dVbs = ( yn / 2e0 * ( Ps0_dVbs - Psdl_dVbs ) ) * T2 ; - Qgod_dVds = ( - 1e0 * ( sIN.xld + sIN.xpolyd ) - + yn / 2e0 * ( Ps0_dVds + 1e0 - Psdl_dVds ) ) * T2 ; - Qgod_dVgs = ( 1e0 * ( sIN.xld + sIN.xpolyd ) - + yn / 2e0 * ( Ps0_dVgs - Psdl_dVgs ) ) * T2 ; - } else { - T3 = C_ESI * 5e0 / ( C_QE * T3 ) ; - - Qgod = ( ( Vgs + T1 * 4e0 / 5e0 * yn2 * yn2 * yn - Vds ) * Lov - + T1 / 30e0 * Lov2 * Lov2 * Lov2 - - T1 * yn2 * yn2 / 2e0 * Lov2 ) * T2 ; - Qgod_dVbs = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVbs - Psdl_dVbs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVbs - Psdl_dVbs ) * Lov2 ) - * T2 ; - Qgod_dVds = ( ( T1 * 4e0 / 5e0 * T3 * ( Ps0_dVds + 1e0 - Psdl_dVds ) - 1e0 ) - * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVds + 1e0 - Psdl_dVds ) - * Lov2 ) * T2 ; - Qgod_dVgs = ( ( 1e0 + T1 * 4e0 / 5e0 * T3 * ( Ps0_dVgs - Psdl_dVgs ) ) * Lov - - 2e0 * T1 / 5e0 * T3 / yn * ( Ps0_dVgs - Psdl_dVgs ) * Lov2 ) - * T2 ; - } - } - -/*-------------------------------------------* -* Overlap charge (off) -*-----------------*/ - - else if( sIN.coovlp < 0 ){ - - Qgos = 0.0e0 ; - Qgos_dVbs = 0.0e0 ; - Qgos_dVds = 0.0e0 ; - Qgos_dVgs = 0.0e0 ; - - Qgod = 0.0e0 ; - Qgod_dVbs = 0.0e0 ; - Qgod_dVds = 0.0e0 ; - Qgod_dVgs = 0.0e0 ; - - } - -/*-----------------------------------------------------------* -* End of PART-3. (label) -*-----------------*/ -end_of_part_3: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-4: Substrate-source/drain junction diode. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - - -/*-----------------------------------------------------------* -* Cbsj, Cbdj: node-base S/D biases. -*-----------------*/ - - if (sIN.mode == HiSIM_NORMAL_MODE ){ - Vbdj = Vbde ; - Vbsj = Vbse ; - } else { - Vbdj = Vbse ; - Vbsj = Vbde ; - } - - /* Vbdc = Vbsc - Vdsc ;*/ - - js = sIN.js0 * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) / sIN.nj ) ; - jssw = sIN.js0sw * exp( ( Eg300 * C_b300 - Eg * beta - + sIN.xti * log( sIN.temp / C_T300 ) ) - / sIN.njsw ) ; - - Nvtm = sIN.nj / beta ; - - - /* ibd */ - isbd = sIN.ad * js + sIN.pd * jssw ; - - if ( Vbdj < 0.5 ) { - Ibd = isbd * ( exp( Vbdj / Nvtm ) - 1 ) ; - Gbd = isbd / Nvtm * exp( Vbdj / Nvtm ) ; - - } else { - Ibd = isbd * ( exp( 0.5 / Nvtm ) - 1 ) - + isbd / Nvtm * exp( 0.5 / Nvtm ) * ( Vbdj - 0.5 ) ; - Gbd = isbd / Nvtm * exp( 0.5 / Nvtm ) ; - } - - - /* ibs */ - isbs = sIN.as * js + sIN.ps * jssw ; - - if ( Vbsj < 0.5 ) { - Ibs = isbs * ( exp( Vbsj / Nvtm ) - 1 ) ; - Gbs = isbs / Nvtm * exp( Vbsj / Nvtm ) ; - - } else { - Ibs = isbs * ( exp( 0.5 / Nvtm ) - 1 ) - + isbs / Nvtm * exp( 0.5 / Nvtm ) * (Vbsj - 0.5 ) ; - Gbs = isbs / Nvtm * exp( 0.5 / Nvtm ) ; - } - -/*---------------------------------------------------* -* Add Gjmin. -*-----------------*/ - - Ibd += Gjmin * Vbdj ; - Ibs += Gjmin * Vbsj ; - - 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 - */ - - czbd = sIN.cj * sIN.ad ; - czbs = sIN.cj * sIN.as ; - - /* Source Bulk Junction */ - if (sIN.ps > Weff) { - czbssw = sIN.cjsw * ( sIN.ps - Weff ) ; - czbsswg = sIN.cjswg * Weff ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbssw ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0; - } - if (czbssw > 0.0) - { arg = 1.0 - Vbsj / sIN.pbsw; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjsw * log(arg)); - Qbs += sIN.pbsw * czbssw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw); - Capbs += czbssw * sarg; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbs += czbsswg * sarg; - } - } - else - { Qbs = Vbsj * (czbs + czbssw + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbssw * sIN.mjsw * 0.5 / sIN.pbsw - + czbsswg * sIN.mjswg - * 0.5 / sIN.pbswg); - Capbs = czbs - + czbssw + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbssw * sIN.mjsw / sIN.pbsw - + czbsswg * sIN.mjswg / sIN.pbswg ); - } - - } else { - czbsswg = sIN.cjswg * sIN.ps ; - if (Vbsj == 0.0) - { Qbs = 0.0 ; - Capbs = czbs + czbsswg ; - } - else if (Vbsj < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - Vbsj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbs = sIN.pb * czbs - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbs = czbs * sarg ; - } - else - { Qbs = 0.0 ; - Capbs = 0.0; - } - if (czbsswg > 0.0) - { arg = 1.0 - Vbsj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbs += sIN.pbswg * czbsswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbs += czbsswg * sarg; - } - } - else - { Qbs = Vbsj * (czbs + czbsswg) - + Vbsj * Vbsj * (czbs * sIN.mj * 0.5 / sIN.pb - + czbsswg * sIN.mjswg * 0.5 / sIN.pbswg); - Capbs = czbs - + czbsswg + Vbsj * (czbs * sIN.mj /sIN.pb - + czbsswg * sIN.mjswg / sIN.pbswg ); - } - } - - - /* Drain Bulk Junction */ - if (sIN.pd > Weff) { - czbdsw = sIN.cjsw * ( sIN.pd - Weff ) ; - czbdswg = sIN.cjswg * Weff ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdsw ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0; - } - if (czbdsw > 0.0) - { arg = 1.0 - Vbdj / sIN.pbsw; - if (sIN.mjsw == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjsw * log(arg)); - Qbd += sIN.pbsw * czbdsw - * (1.0 - arg * sarg) / (1.0 - sIN.mjsw); - Capbd += czbdsw * sarg; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbd += czbdswg * sarg; - } - } - else - { Qbd = Vbdj * (czbd + czbdsw + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdsw * sIN.mjsw * 0.5 / sIN.pbsw - + czbdswg * sIN.mjswg - * 0.5 / sIN.pbswg); - Capbd = czbd - + czbdsw + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdsw * sIN.mjsw / sIN.pbsw - + czbdswg * sIN.mjswg / sIN.pbswg ); - } - - } else { - czbdswg = sIN.cjswg * sIN.pd ; - if (Vbdj == 0.0) - { Qbd = 0.0 ; - Capbd = czbd + czbdswg ; - } - else if (Vbdj < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - Vbdj / sIN.pb ; - if (sIN.mj == 0.5) - sarg = 1.0 / sqrt(arg) ; - else - sarg = exp(-sIN.mj * log(arg)) ; - Qbd = sIN.pb * czbd - * (1.0 - arg * sarg) / (1.0 - sIN.mj) ; - Capbd = czbd * sarg ; - } - else - { Qbd = 0.0 ; - Capbd = 0.0; - } - if (czbdswg > 0.0) - { arg = 1.0 - Vbdj / sIN.pbswg; - if (sIN.mjswg == 0.5) - sarg = 1.0 / sqrt(arg); - else - sarg = exp(-sIN.mjswg * log(arg)); - Qbd += sIN.pbswg * czbdswg - * (1.0 - arg * sarg) / (1.0 - sIN.mjswg); - Capbd += czbdswg * sarg; - } - } - else - { Qbd = Vbdj * (czbd + czbdswg) - + Vbdj * Vbdj * (czbd * sIN.mj * 0.5 / sIN.pb - + czbdswg * sIN.mjswg * 0.5 / sIN.pbswg); - Capbd = czbd - + czbdswg + Vbdj * (czbd * sIN.mj /sIN.pb - + czbdswg * sIN.mjswg / sIN.pbswg ); - } - } - - - -/*-----------------------------------------------------------* -* End of PART-4. (label) -*-----------------*/ -end_of_part_4: ; - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-5: Noise Calculation. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - - if ( sIN.conois != 0 ){ - - NFalp = sIN.nfalp ; - NFtrp = sIN.nftrp ; - Cit = sIN.cit ; - - T1 = Qn0 / C_QE ; - T2 = (Cox+Qn0/(Ps0-Vbs)+Cit)/beta/C_QE ; - T3 = 1.0E0/(T1+T2)+NFalp*Mu ; - Nflic = Ids*Ids*NFtrp/((Leff-Lred)*beta*Weff)*T3*T3 ; - - } else { - Nflic = 0.0 ; - } - - -/*-----------------------------------------------------------* -* End of PART-5. (label) -*-----------------*/ -end_of_part_5: ; - - - -/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -* PART-6: Evaluation of outputs. -*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ - -/*-----------------------------------------------------------* -* Implicit quantities related to Alpha. -*-----------------*/ - - /* note: T1 = 1 + Delta */ - if ( flg_noqi == 0 && VgVt > VgVt_small && Pds > 0.0 ) { - T1 = Achi / Pds ; - Delta = T1 - 1.0e0 ; - Vdsat = VgVt / T1 ; - } else { - Alpha = 1.0 ; - Delta = 0.0 ; - Vdsat = 0.0 ; - Achi = 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 == 0 || 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 ; - - Igs_dVbse = Igs_dVbs ; - Igs_dVdse = Igs_dVds ; - Igs_dVgse = Igs_dVgs ; - - Ilg_dVbse = Ilg_dVbs ; - Ilg_dVdse = Ilg_dVds ; - Ilg_dVgse = Ilg_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 ; - - -/*---------------------------------------------------* -* Case Rs>0 or Rd>0 -*-----------------*/ - } else { - -/*-------------------------------------------* -* 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 ; - - 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 ; - - Ilg_dVbse = Ilg_dVbs * Vbs_dVbse + Ilg_dVds * Vds_dVbse - + Ilg_dVgs * Vgs_dVbse ; - Ilg_dVdse = Ilg_dVbs * Vbs_dVdse + Ilg_dVds * Vds_dVdse - + Ilg_dVgs * Vgs_dVdse ; - Ilg_dVgse = Ilg_dVbs * Vbs_dVgse + Ilg_dVds * Vds_dVgse - + Ilg_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 ; - - } /* end of if ( flg_rsrd == 0 ) blocks */ - -/*---------------------------------------------------* -* 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 ; - Igs_dVbse *= Vbsc_dVbse ; - Ilg_dVbse *= Vbsc_dVbse ; - Qgos_dVbse *= Vbsc_dVbse ; - Qgod_dVbse *= Vbsc_dVbse ; - } - - if ( flg_vxxc != 0 ) { - - if ( flg_vbsc == -1 ) { - T1 = Vbse - Vbsc ; - } else { - T1 = 0.0 ; - } - - - if ( flg_vdsc != 0 ) { - T2 = Vdse - Vdsc ; - } else { - T2 = 0.0 ; - } - - if ( flg_vgsc != 0 ) { - T3 = Vgse - Vgsc ; - } else { - T3 = 0.0 ; - } - - if ( flg_vbdc != 0 ) { - T4 = Vbde - Vbdc ; - } else { - T4 = 0.0 ; - } - - - TX = Ids + T1 * Ids_dVbse + T2 * Ids_dVdse + T3 * Ids_dVgse ; - if ( TX * Ids >= 0.0 ) { - Ids = TX ; - } else { - T7 = Ids / ( Ids - TX ) ; - Ids_dVbse *= T7 ; - Ids_dVdse *= T7 ; - Ids_dVgse *= T7 ; - Ids = 0.0 ; - } - - TX = Qb + T1 * Qb_dVbse + T2 * Qb_dVdse + T3 * Qb_dVgse ; - /*note: The sign of Qb can be changed.*/ - Qb = TX ; - - TX = Qd + T1 * Qd_dVbse + T2 * Qd_dVdse + T3 * Qd_dVgse ; - if ( TX * Qd >= 0.0 ) { - Qd = TX ; - } else { - T7 = Qd / ( Qd - TX ) ; - Qd_dVbse *= T7 ; - Qd_dVdse *= T7 ; - Qd_dVgse *= T7 ; - Qd = 0.0 ; - } - - TX = Qi + T1 * Qi_dVbse + T2 * Qi_dVdse + T3 * Qi_dVgse ; - if ( TX * Qi >= 0.0 ) { - Qi = TX ; - } else { - T7 = Qi / ( Qi - TX ) ; - Qi_dVbse *= T7 ; - Qi_dVdse *= T7 ; - Qi_dVgse *= T7 ; - Qi = 0.0 ; - } - - TX = Isub + T1 * Isub_dVbse + T2 * Isub_dVdse + T3 * Isub_dVgse ; - if ( TX * Isub >= 0.0 ) { - Isub = TX ; - } else { - T7 = Isub / ( Isub - TX ) ; - Isub_dVbse *= T7 ; - Isub_dVdse *= T7 ; - Isub_dVgse *= T7 ; - Isub = 0.0 ; - } - - TX = Igs + T1 * Igs_dVbse + T2 * Igs_dVdse + T3 * Igs_dVgse ; - if ( TX * Igs >= 0.0 ) { - Igs = TX ; - } else { - T7 = Igs / ( Igs - TX ) ; - Igs_dVbse *= T7 ; - Igs_dVdse *= T7 ; - Igs_dVgse *= T7 ; - Igs = 0.0 ; - } - - TX = Ilg + T1 * Ilg_dVbse + T2 * Ilg_dVdse + T3 * Ilg_dVgse ; - if ( TX * Ilg >= 0.0 ) { - Ilg = TX ; - } else { - T7 = Ilg / ( Ilg - TX ) ; - Ilg_dVbse *= T7 ; - Ilg_dVdse *= T7 ; - Ilg_dVgse *= T7 ; - Ilg = 0.0 ; - } - - TX = Qgod + T1 * Qgod_dVbse + T2 * Qgod_dVdse + T3 * Qgod_dVgse ; - if ( TX * Qgod >= 0.0 ) { - Qgod = TX ; - } else { - T7 = Qgod / ( Qgod - TX ) ; - Qgod_dVbse *= T7 ; - Qgod_dVdse *= T7 ; - Qgod_dVgse *= T7 ; - Qgod = 0.0 ; - } - - TX = Qgos + T1 * Qgos_dVbse + T2 * Qgos_dVdse + T3 * Qgos_dVgse ; - if ( TX * Qgos >= 0.0 ) { - Qgos = TX ; - } else { - T7 = Qgos / ( Qgos - TX ) ; - Qgos_dVbse *= T7 ; - Qgos_dVdse *= T7 ; - Qgos_dVgse *= T7 ; - Qgos = 0.0 ; - } - - - } - -/*-----------------------------------------------------------* -* Warn negative conductance. -* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias. -*-----------------*/ - - if ( sIN.mode == HiSIM_NORMAL_MODE ) { - T1 = Ids_dVdse ; - } else { - T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; - } - - if ( Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0 ) { - fprintf( stderr , - "*** warning(HiSIM): Negative Conductance\n" ) ; - fprintf( stderr , - " type = %d mode = %d\n" , sIN.type , sIN.mode ) ; - fprintf( stderr , - " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" , - Vbse , Vdse , Vgse ) ; - if ( flg_info >= 1 ) { - printf( "*** warning(HiSIM): Negative Conductance\n" ) ; - printf( " type = %d mode = %d\n" , sIN.type , sIN.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" , Ids_dVdse ) ; - printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - } - } - - if ( Ids_dVbse < 0.0e0 ) { - fprintf( stderr , " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ; - flg_ncnv ++ ; - } - if ( T1 < 0.0e0 ) { - fprintf( stderr , " Ids_dVdse = %12.5e\n" , T1 ) ; - flg_ncnv ++ ; - } - if ( Ids_dVgse < 0.0e0 ) { - fprintf( stderr , " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ; - flg_ncnv ++ ; - } - - - -/*-----------------------------------------------------------* -* Redefine overlap charges/capacitances. -*-----------------*/ - -/*---------------------------------------------------* -* Constant capacitance. -*-----------------*/ - - if ( sIN.cocgbo >= 1 ) { - Cgbo = sIN.cgbo * Lgate ; - } else { - Cgbo = 0.0 ; - } - - if ( sIN.cocgdo >= 1 ) { - Cgdo = - sIN.cgdo * Weff ; - Qgod = - Cgdo * ( Vgse - Vdse ) ; - Qgod_dVbse = 0.0 ; - Qgod_dVdse = Cgdo ; - Qgod_dVgse = - Qgod_dVdse ; - } else { - Cgdo = Qgos_dVdse + Qgod_dVdse ; - } - - if ( sIN.cocgso >= 1 ) { - Cgso = - sIN.cgso * Weff ; - Qgos = - Cgso * Vgse ; - Qgos_dVbse = 0.0 ; - Qgos_dVdse = 0.0 ; - Qgos_dVgse = - Cgso ; - } else { - Cgso = - ( Qgos_dVbse + Qgod_dVbse - + Qgos_dVdse + Qgod_dVdse - + Qgos_dVgse + Qgod_dVgse ) ; - } - - Cggo = Qgos_dVgse + Qgod_dVgse ; - -/*---------------------------------------------------* -* Fringing capacitance. -*-----------------*/ - - Cf = C_EOX / ( C_Pi / 2.0e0 ) * Weff - * log( 1.0e0 + sIN.tpoly / sIN. tox ) ; - - /* added 2 Eqs. below. (4/Dec/01) */ - - Qfd = Cf * ( Vgse - Vdse ) ; - Qfs = Cf * Vgse ; - - /* end of additional Eqs. */ - -/*---------------------------------------------------* -* Add fringing charge/capacitance to overlap. -*-----------------*/ - - /* added 2 Eqs. below. (4/Dec/01) */ - - Qgod += Qfd ; - Qgos += Qfs ; - - /* end of additional Eqs. */ - - Cggo += 2.0 * Cf ; - Cgdo += - Cf ; - Cgso += - Cf ; - -/*-----------------------------------------------------------* -* Assign outputs. -*-----------------*/ - -/*---------------------------------------------------* -* Channel current and conductances. -*-----------------*/ - - /* pOT->ids = sIN.type * Ids ; */ - pOT->ids = Ids ; - pOT->gmbs = Ids_dVbse ; - pOT->gds = Ids_dVdse ; - pOT->gm = Ids_dVgse ; - -/*---------------------------------------------------* -* Intrinsic charges/capacitances. -*-----------------*/ - - pOT->qg = - ( Qb + Qi ) ; - pOT->qd = Qd ; - pOT->qs = Qi - Qd ; - - pOT->cbgb = Qb_dVgse ; - pOT->cbdb = Qb_dVdse ; - pOT->cbsb = - ( Qb_dVbse + Qb_dVdse + Qb_dVgse ) ; - - pOT->cggb = - Qb_dVgse - Qi_dVgse ; - pOT->cgdb = - Qb_dVdse - Qi_dVdse ; - pOT->cgsb = Qb_dVbse + Qb_dVdse + Qb_dVgse - + Qi_dVbse + Qi_dVdse + Qi_dVgse ; - - pOT->cdgb = Qd_dVgse ; - pOT->cddb = Qd_dVdse ; - pOT->cdsb = - ( Qd_dVgse + Qd_dVdse + Qd_dVbse ) ; - - -/*---------------------------------------------------* -* Overlap capacitances. -*-----------------*/ - - pOT->cgdo = Cgdo ; - pOT->cgso = Cgso ; - pOT->cgbo = Cgbo ; - -/*------------------------------------ - * Lateral-field-induced capasitance ------------------------------------*/ - - if ( sIN.xqy == 0 ){ - Qy = 0e0 ; - Cqyd = 0e0 ; - Cqyg = 0e0 ; - Cqyb = 0e0 ; - Cqys = 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; - if ( Pslk > Psdl ){ - Pslk = Psdl ; - Pslk_dVbs = Psdl_dVbs ; - Pslk_dVds = Psdl_dVds ; - Pslk_dVgs = Psdl_dVgs ; - } - - T1 = Aclm * ( Vds + Ps0 ) + ( 1.0e0 - Aclm ) * Pslk ; - T1_dVbs = Aclm * ( Ps0_dVbs ) + ( 1.0e0 - Aclm ) * Pslk_dVbs ; - T1_dVds = Aclm * ( 1.0 + Ps0_dVds ) + ( 1.0e0 - Aclm ) * Pslk_dVds ; - T1_dVgs = Aclm * ( Ps0_dVgs ) + ( 1.0e0 - Aclm ) * Pslk_dVgs ; - - T10 = sqrt( 2.0e0 * C_ESI / q_Nsub ) ; - - T3 = T10 * 1.3; - T2 = C_ESI * Weff * T3 ; - - Qy = ( ( Ps0 + Vds - T1 ) / sIN.xqy - Ec ) * T2 ; - - Cqyd = ( ( Ps0_dVds + 1.0e0 - T1_dVds ) / sIN.xqy - Ec_dVds ) * T2; - Cqyg = ( ( Ps0_dVgs - T1_dVgs ) / sIN.xqy - Ec_dVgs ) * T2; - Cqyb = ( ( Ps0_dVbs - T1_dVbs ) / sIN.xqy - Ec_dVbs ) * T2; - Cqys = - ( Cqyb + Cqyd + Cqyg ) ; - } - - -/*---------------------------------------------------* -* Add S/D overlap charges/capacitances to intrinsic ones. -* - NOTE: This function depends on coadov, a control option. -*-----------------*/ - - if ( sIN.coadov == 1 ) { - pOT->qg += Qgod + Qgos - Qy ; - pOT->qd += - Qgod + Qy ; - pOT->qs += - Qgos ; - - pOT->cggb += Cggo - Cqyg ; - pOT->cgdb = pOT->cgdb + Cgdo + (-1) * Cqyd ; - pOT->cgsb += Cgso + (-1) * Cqys ; - - pOT->cdgb += - Qgod_dVgse - Cf + Cqyg ; - pOT->cddb += - Qgod_dVdse + Cf + Cqyd ; - pOT->cdsb += Qgod_dVbse + Qgod_dVdse + Qgod_dVgse + Cqys ; - - pOT->cgdo = 0.0 ; - pOT->cgso = 0.0 ; - - if ( pOT->cgdb > -1e-27 ) { pOT->cgdb = 0e0 ; } - if ( pOT->cgsb > -1e-27 ) { pOT->cgsb = 0e0 ; } - } - - -/*---------------------------------------------------* -* Substrate/gate/leak currents. -*-----------------*/ - - pOT->isub = Isub ; - - pOT->gbbs = Isub_dVbse ; - pOT->gbds = Isub_dVdse ; - pOT->gbgs = Isub_dVgse ; - - pOT->igs = Igs ; - - pOT->ggbs = Igs_dVbse ; - pOT->ggds = Igs_dVdse ; - pOT->gggs = Igs_dVgse ; - - pOT->ilg = Ilg ; - - pOT->glbs = Ilg_dVbse ; - pOT->glds = Ilg_dVdse ; - pOT->glgs = Ilg_dVgse ; - -/*---------------------------------------------------* -* Meyer's capacitances. -*-----------------*/ - - pOT->capgs = - pOT->cgsb - Cgso ; - pOT->capgd = - pOT->cgdb - Cgdo ; - pOT->capgb = pOT->cggb + pOT->cgdb + pOT->cgbo ; - -/*---------------------------------------------------* -* Von, Vdsat, -*-----------------*/ - - /* - pOT->von = sIN.type * Vth ; - pOT->vdsat = sIN.type * Vdsat ; - */ - pOT->von = Vth ; - pOT->vdsat = Vdsat ; - -/*---------------------------------------------------* -* Parasitic conductances. -*-----------------*/ - -/*:org: -* pOT->gd = 1.0e+50 ; -* pOT->gs = 1.0e+50 ; -* modified according to CMIxxxeval.c. -* I don't know the reason why these can be zero. -*/ - pOT->gd = 0.0e0 ; - pOT->gs = 0.0e0 ; - -/*---------------------------------------------------* -* Junction diode. -*-----------------*/ - - /* - pOT->ibs = sIN.type * Ibs ; - pOT->ibd = sIN.type * Ibd ; - */ - pOT->ibs = Ibs ; - pOT->ibd = Ibd ; - pOT->gbs = Gbse ; - pOT->gbd = Gbde ; - - pOT->qbs = Qbs ; - pOT->qbd = Qbd ; - pOT->capbs = Capbse ; - pOT->capbd = Capbde ; - - - -/*-----------------------------------------------------------* -* Warn floating-point exceptions. -* - Function finite() in libm is called. -* - Go to start with info==5. -*-----------------*/ - - T1 = pOT->ids + pOT->gmbs + pOT->gds + pOT->gm ; - T1 = T1 + pOT->qd + pOT->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( "pOT->ids = %12.5e\n" , pOT->ids ) ; - printf( "pOT->gmbs = %12.5e\n" , pOT->gmbs ) ; - printf( "pOT->gds = %12.5e\n" , pOT->gds ) ; - printf( "pOT->gm = %12.5e\n" , pOT->gm ) ; - printf( "pOT->qd = %12.5e\n" , pOT->qd ) ; - printf( "pOT->cdsb = %12.5e\n" , pOT->cdsb ) ; - } - } - - T1 = pOT->isub + pOT->gbbs + pOT->gbds + pOT->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 = pOT->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 = pOT->ibs + pOT->ibd + pOT->gbs + pOT->gbd ; - T1 = T1 + pOT->qbs + pOT->qbd + pOT->capbs + pOT->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 ) { - return( HiSIM_ERROR ) ; - } - -/*-----------------------------------------------------------* -* Restore values for next calculation. -*-----------------*/ - - /* Confined biases */ - pOT->vbsc = Vbsc ; - pOT->vdsc = Vdsc ; - pOT->vgsc = Vgsc ; - /* Surface potentials and derivatives w.r.t. internal biases */ - pOT->ps0 = Ps0 ; - pOT->ps0_dvbs = Ps0_dVbs ; - pOT->ps0_dvds = Ps0_dVds ; - pOT->ps0_dvgs = Ps0_dVgs ; - pOT->pds = Pds ; - pOT->pds_dvbs = Pds_dVbs ; - pOT->pds_dvds = Pds_dVds ; - pOT->pds_dvgs = Pds_dVgs ; - /* Derivatives of channel current w.r.t. internal biases */ - pOT->ids_dvbs = Ids_dVbs ; - pOT->ids_dvds = Ids_dVds ; - pOT->ids_dvgs = Ids_dVgs ; - - pOT->nf = Nflic ; - - /* mobility added by K.M. */ - pOT->mu = Mu; - -/*-----------------------------------------------------------* -* End of PART-6. (label) -*-----------------*/ -end_of_part_6: ; - - -/*-----------------------------------------------------------* -* Bottom of hsm1eval1_1. -*-----------------*/ - - - -return ( HiSIM_OK ) ; - -} /* end of hsm1eval1_1 */ diff --git a/src/spicelib/devices/hisim/hsm1evalenv.h b/src/spicelib/devices/hisim/hsm1evalenv.h deleted file mode 100644 index 4ccfa9092..000000000 --- a/src/spicelib/devices/hisim/hsm1evalenv.h +++ /dev/null @@ -1,80 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1evalenv.h of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#ifndef HSM1_EVAL_ENV_H -#define HSM1_EVAL_ENV_H - -/* macros and constants used in hsm1eval1_y_z.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 - -/* 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) - -/*---------------------------------------------------* -* 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) - -/* Build-in potential */ -#define C_Vbi (1.0e0) - -/* 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 /* HSM1_EVAL_ENV_H */ diff --git a/src/spicelib/devices/hisim/hsm1ext.h b/src/spicelib/devices/hisim/hsm1ext.h deleted file mode 100644 index a597308d0..000000000 --- a/src/spicelib/devices/hisim/hsm1ext.h +++ /dev/null @@ -1,32 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1ext.h of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -extern int HSM1acLoad(GENmodel *,CKTcircuit*); -extern int HSM1ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); -extern int HSM1convTest(GENmodel *,CKTcircuit*); -extern int HSM1delete(GENmodel*,IFuid,GENinstance**); -extern void HSM1destroy(GENmodel**); -extern int HSM1getic(GENmodel*,CKTcircuit*); -extern int HSM1load(GENmodel*,CKTcircuit*); -extern int HSM1mAsk(CKTcircuit*,GENmodel *,int, IFvalue*); -extern int HSM1mDelete(GENmodel**,IFuid,GENmodel*); -extern int HSM1mParam(int,IFvalue*,GENmodel*); -extern void HSM1mosCap(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 HSM1param(int,IFvalue*,GENinstance*,IFvalue*); -extern int HSM1pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); -extern int HSM1setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); -extern int HSM1unsetup(GENmodel*,CKTcircuit*); -extern int HSM1temp(GENmodel*,CKTcircuit*); -extern int HSM1trunc(GENmodel*,CKTcircuit*,double*); -extern int HSM1noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); diff --git a/src/spicelib/devices/hisim/hsm1getic.c b/src/spicelib/devices/hisim/hsm1getic.c deleted file mode 100644 index a175f9b9a..000000000 --- a/src/spicelib/devices/hisim/hsm1getic.c +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1getic of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1getic(GENmodel *inModel, CKTcircuit *ckt) -{ - HSM1model *model = (HSM1model*)inModel; - HSM1instance *here; - /* - * grab initial conditions out of rhs array. User specified, so use - * external nodes to get values - */ - - for ( ;model ;model = model->HSM1nextModel ) { - for ( here = model->HSM1instances; here ;here = here->HSM1nextInstance ) { - - - if (here->HSM1owner != ARCHme) - continue; - - if (!here->HSM1_icVBS_Given) { - here->HSM1_icVBS = - *(ckt->CKTrhs + here->HSM1bNode) - - *(ckt->CKTrhs + here->HSM1sNode); - } - if (!here->HSM1_icVDS_Given) { - here->HSM1_icVDS = - *(ckt->CKTrhs + here->HSM1dNode) - - *(ckt->CKTrhs + here->HSM1sNode); - } - if (!here->HSM1_icVGS_Given) { - here->HSM1_icVGS = - *(ckt->CKTrhs + here->HSM1gNode) - - *(ckt->CKTrhs + here->HSM1sNode); - } - } - } - return(OK); -} - diff --git a/src/spicelib/devices/hisim/hsm1init.c b/src/spicelib/devices/hisim/hsm1init.c deleted file mode 100644 index 7ab83eb9d..000000000 --- a/src/spicelib/devices/hisim/hsm1init.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "config.h" - -#include "devdefs.h" - -#include "hsm1def.h" -#include "hsm1itf.h" -#include "hsm1init.h" - -SPICEdev HSM1info = { - { "HiSIM1", - "Hiroshima University STARC IGFET Model 1.2.0", - - &HSM1nSize, - &HSM1nSize, - HSM1names, - - &HSM1pTSize, - HSM1pTable, - - &HSM1mPTSize, - HSM1mPTable, - -#ifdef XSPICE -/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ - NULL, /* This is a SPICE device, it has no MIF info data */ - - 0, /* This is a SPICE device, it has no MIF info data */ - NULL, /* This is a SPICE device, it has no MIF info data */ - - 0, /* This is a SPICE device, it has no MIF info data */ - NULL, /* This is a SPICE device, it has no MIF info data */ - - 0, /* This is a SPICE device, it has no MIF info data */ - NULL, /* This is a SPICE device, it has no MIF info data */ -/*--------------------------- End of SDB fix -------------------------*/ -#endif - - DEV_DEFAULT - }, - - /* DEVparam */ HSM1param, - /* DEVmodParam */ HSM1mParam, - /* DEVload */ HSM1load, - /* DEVsetup */ HSM1setup, - /* DEVunsetup */ HSM1unsetup, - /* DEVpzSetup */ HSM1setup, - /* DEVtemperature*/ HSM1temp, - /* DEVtrunc */ HSM1trunc, - /* DEVfindBranch */ NULL, - /* DEVacLoad */ HSM1acLoad, - /* DEVaccept */ NULL, - /* DEVdestroy */ HSM1destroy, - /* DEVmodDelete */ HSM1mDelete, - /* DEVdelete */ HSM1delete, - /* DEVsetic */ HSM1getic, - /* DEVask */ HSM1ask, - /* DEVmodAsk */ HSM1mAsk, - /* DEVpzLoad */ HSM1pzLoad, - /* DEVconvTest */ HSM1convTest, - /* DEVsenSetup */ NULL, - /* DEVsenLoad */ NULL, - /* DEVsenUpdate */ NULL, - /* DEVsenAcLoad */ NULL, - /* DEVsenPrint */ NULL, - /* DEVsenTrunc */ NULL, - /* DEVdisto */ NULL, - /* DEVnoise */ HSM1noise, -#ifdef CIDER - /* DEVdump */ NULL, - /* DEVacct */ NULL, -#endif - /* DEVinstSize */ &HSM1iSize, - /* DEVmodSize */ &HSM1mSize - -}; - - -SPICEdev * -get_hsm1_info(void) -{ - return &HSM1info; -} diff --git a/src/spicelib/devices/hisim/hsm1init.h b/src/spicelib/devices/hisim/hsm1init.h deleted file mode 100644 index 48d0d3627..000000000 --- a/src/spicelib/devices/hisim/hsm1init.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _HISIMINIT_H -#define _HISIMINIT_H - -extern IFparm HSM1pTable[ ]; -extern IFparm HSM1mPTable[ ]; -extern char *HSM1names[ ]; -extern int HSM1pTSize; -extern int HSM1mPTSize; -extern int HSM1nSize; -extern int HSM1iSize; -extern int HSM1mSize; - -#endif diff --git a/src/spicelib/devices/hisim/hsm1itf.h b/src/spicelib/devices/hisim/hsm1itf.h deleted file mode 100644 index fa23b4299..000000000 --- a/src/spicelib/devices/hisim/hsm1itf.h +++ /dev/null @@ -1,16 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1itf.h of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#ifndef DEV_HISIM1 -#define DEV_HISIM1 - -SPICEdev *get_hsm1_info(void); - -#endif diff --git a/src/spicelib/devices/hisim/hsm1ld.c b/src/spicelib/devices/hisim/hsm1ld.c deleted file mode 100644 index d0ad6e32d..000000000 --- a/src/spicelib/devices/hisim/hsm1ld.c +++ /dev/null @@ -1,1387 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1ld.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "hisim.h" -#include "trandefs.h" -#include "const.h" -#include "sperror.h" -#include "devdefs.h" -#include "suffix.h" - -#define SHOW_EPS_QUANT 1.0e-15 - -static void -ShowPhysVals(HSM1instance *here, HSM1model *model,int isFirst, double vds, - double vgs, double vbs, double vgd, double vbd, double vgb) -{ - NG_IGNORE(vgd); - NG_IGNORE(vbd); - - /* 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->HSM1_show) { - case 1: - if (isFirst) printf("Vds Ids\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_mode*here->HSM1_ids); - break; - case 2: - if (isFirst) printf("Vgs Ids\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_mode*here->HSM1_ids); - break; - case 3: - if (isFirst) printf("Vgs log10(|Ids|)\n"); - printf("%e %e\n", model->HSM1_type*vgs, log10(here->HSM1_ids)); - break; - case 4: - if (isFirst) printf("log10(|Ids|) gm/|Ids|\n"); - if (here->HSM1_ids == 0.0) - printf("I can't show gm/Ids - log10(Ids), because Ids = 0.\n"); - else - printf("%e %e\n", log10(here->HSM1_ids), here->HSM1_gm/here->HSM1_ids); - break; - case 5: - if (isFirst) printf("Vds gds\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_gds); - break; - case 6: - if (isFirst) printf("Vgs gm\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_gm); - break; - case 7: - if (isFirst) printf("Vbs gbs\n"); - printf("%e %e\n", model->HSM1_type*vbs, here->HSM1_gmbs); - break; - case 8: - if (isFirst) printf("Vgs Cgg\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cggb); - break; - case 9: - if (isFirst) printf("Vgs Cgs\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cgsb); - break; - case 10: - if (isFirst) printf("Vgs Cgd\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cgdb); - break; - case 11: - if (isFirst) printf("Vgs Cgb\n"); - printf("%e %e\n", model->HSM1_type*vgs, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb)); - break; - case 12: - if (isFirst) printf("Vds Csg\n"); - printf("%e %e\n", model->HSM1_type*vds, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb)); - break; - case 13: - if (isFirst) printf("Vds Cdg\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cdgb); - break; - case 14: - if (isFirst) printf("Vds Cbg\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cbgb); - break; - case 15: - if (isFirst) printf("Vds Cgg\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cggb); - break; - case 16: - if (isFirst) printf("Vds Cgs\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cgsb); - break; - case 17: - if (isFirst) printf("Vds Cgd\n"); - printf("%e %e\n", model->HSM1_type*vds, here->HSM1_cgdb); - break; - case 18: - if (isFirst) printf("Vds Cgb\n"); - printf("%e %e\n", model->HSM1_type*vds, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb)); - break; - case 19: - if (isFirst) printf("Vgs Csg\n"); - printf("%e %e\n", model->HSM1_type*vgs, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb)); - break; - case 20: - if (isFirst) printf("Vgs Cdg\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cdgb); - break; - case 21: - if (isFirst) printf("Vgs Cbg\n"); - printf("%e %e\n", model->HSM1_type*vgs, here->HSM1_cbgb); - break; - case 22: - if (isFirst) printf("Vgb Cgb\n"); - printf("%e %e\n", model->HSM1_type*vgb, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_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->HSM1_type*vgs, model->HSM1_type*vds, model->HSM1_type*vbs, model->HSM1_type*vgb, here->HSM1_mode*here->HSM1_ids, log10(here->HSM1_ids), here->HSM1_gm/here->HSM1_ids, here->HSM1_gm, here->HSM1_gds, here->HSM1_gmbs, here->HSM1_cggb, here->HSM1_cgsb, -(here->HSM1_cggb+here->HSM1_cgsb+here->HSM1_cgdb), here->HSM1_cgdb, -(here->HSM1_cggb+here->HSM1_cbgb+here->HSM1_cdgb), here->HSM1_cbgb, here->HSM1_cdgb); - break; - default: - /* - printf("There is no physical value corrsponding to %d\n", flag); - */ - break; - } -} - -int HSM1load(GENmodel *inModel, register CKTcircuit *ckt) - /* actually load the current value into the - * sparse matrix previously provided - */ -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; - HiSIM_input sIN; - HiSIM_output sOT; - HiSIM_messenger sMS; - double cbhat = 0.0, cdrain, cdhat = 0.0, cdreq; - double cgbhat = 0.0, cgshat = 0.0, cgdhat = 0.0; - double Ibtot = 0.0, Idtot, Igbtot = 0.0, Igstot = 0.0, Igdtot = 0.0; - double ceq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg; - double delvbd, delvbs, delvds, delvgd, delvgs; - double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb; - double gcgdb, gcggb, gcgsb, gcsdb, gcsgb, gcssb; - double geq; -#ifndef PREDICTOR - double xfact; -#endif - double vbd, vbs, vcrit, vds, vgb, vgd, vgdo, vgs, von; - double qgd, qgs, qgb; - double gbbdp, gbbsp, gbspg, gbspdp, gbspb, gbspsp; - double qgate, qbulk, qdrn, qsrc; - double cqgate, cqbulk, cqdrn; - double gbdpdp, gbdpg, gbdpb, gbdpsp; - double cgdo, cgso, cgbo; - double gm, gmbs, FwdSum, RevSum; - double vt0, 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; - int ByPass, Check, error; -#ifndef NOBYPASS - double tempv; -#endif /*NOBYPASS*/ - int tmp; -#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 = 0.0; - - double m; /* Parallel multiplier */ - - /* loop through all the HSM1 device models */ - for (; model != NULL; model = model->HSM1nextModel ) { - /* loop through all the instances of the model */ - for (here = model->HSM1instances; here != NULL; - here = here->HSM1nextInstance) { - - if (here->HSM1owner != ARCHme) - continue; - - showPhysVal = 0; - Check=1; - ByPass = 0; - if ( ckt->CKTmode & MODEINITSMSIG ) { - vbs= *(ckt->CKTstate0 + here->HSM1vbs); - vgs= *(ckt->CKTstate0 + here->HSM1vgs); - vds= *(ckt->CKTstate0 + here->HSM1vds); - } - else if ( ckt->CKTmode & MODEINITTRAN ) { - vbs= *(ckt->CKTstate1 + here->HSM1vbs); - vgs= *(ckt->CKTstate1 + here->HSM1vgs); - vds= *(ckt->CKTstate1 + here->HSM1vds); - } - else if ( (ckt->CKTmode & MODEINITJCT) && !here->HSM1_off ) { - vds= model->HSM1_type * here->HSM1_icVDS; - vgs= model->HSM1_type * here->HSM1_icVGS; - vbs= model->HSM1_type * here->HSM1_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 (same as BSIM3)*/ - vbs = 0.0; - /* vt0 = model->HSM1_type * (-1.0 * model->HSM1_vfbc);*/ - vt0 = model->HSM1_type * model->HSM1_vfbc; - vgs = vt0 + 0.1; - vds = 0.1; - } - } - else if ( ( ckt->CKTmode & (MODEINITJCT | MODEINITFIX) ) && - here->HSM1_off ) { - vbs = vgs = vds = 0.0; - } - else { -#ifndef PREDICTOR /* BSIM3 style */ - if (ckt->CKTmode & MODEINITPRED) { - xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; - *(ckt->CKTstate0 + here->HSM1vbs) = - *(ckt->CKTstate1 + here->HSM1vbs); - vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vbs)) - -(xfact * (*(ckt->CKTstate2 + here->HSM1vbs))); - *(ckt->CKTstate0 + here->HSM1vgs) = - *(ckt->CKTstate1 + here->HSM1vgs); - vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vgs)) - -(xfact * (*(ckt->CKTstate2 + here->HSM1vgs))); - *(ckt->CKTstate0 + here->HSM1vds) = - *(ckt->CKTstate1 + here->HSM1vds); - vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HSM1vds)) - -(xfact * (*(ckt->CKTstate2 + here->HSM1vds))); - *(ckt->CKTstate0 + here->HSM1vbd) = - *(ckt->CKTstate0 + here->HSM1vbs)- - *(ckt->CKTstate0 + here->HSM1vds); - } - else { -#endif /* PREDICTOR */ - /* get biases from CKT */ - vbs = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1bNode) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); - vgs = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1gNode) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); - vds = model->HSM1_type * - (*(ckt->CKTrhsOld+here->HSM1dNodePrime) - - *(ckt->CKTrhsOld+here->HSM1sNodePrime)); -#ifndef PREDICTOR - } -#endif /* PREDICTOR */ - - vbd = vbs - vds; - vgd = vgs - vds; - vgdo = *(ckt->CKTstate0 + here->HSM1vgs) - - *(ckt->CKTstate0 + here->HSM1vds); - delvbs = vbs - *(ckt->CKTstate0 + here->HSM1vbs); - delvbd = vbd - *(ckt->CKTstate0 + here->HSM1vbd); - delvgs = vgs - *(ckt->CKTstate0 + here->HSM1vgs); - delvds = vds - *(ckt->CKTstate0 + here->HSM1vds); - delvgd = vgd - vgdo; - - if (here->HSM1_mode >= 0) { - Idtot = here->HSM1_ids + here->HSM1_isub - here->HSM1_ibd - + here->HSM1_igidl; - cdhat = Idtot - here->HSM1_gbd * delvbd - + (here->HSM1_gmbs + here->HSM1_gbbs + here->HSM1_gigidlbs) * delvbs - + (here->HSM1_gm + here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgs - + (here->HSM1_gds + here->HSM1_gbds + here->HSM1_gigidlds) * delvds; - Ibtot = here->HSM1_ibs + here->HSM1_ibd - here->HSM1_isub - - here->HSM1_igidl - here->HSM1_igisl; - cbhat = Ibtot + here->HSM1_gbd * delvbd - + (here->HSM1_gbs - here->HSM1_gbbs - here->HSM1_gigidlbs) * delvbs - - (here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgs - - (here->HSM1_gbds + here->HSM1_gigidlds) * delvds - - here->HSM1_gigislgd * delvgd - here->HSM1_gigislbd * delvbd - + here->HSM1_gigislsd * delvds; - Igstot = here->HSM1_igs; - cgshat = Igstot + here->HSM1_gigsg * delvgs + - here->HSM1_gigsd * delvds + here->HSM1_gigsb * delvbs; - Igdtot = here->HSM1_igd; - cgdhat = Igdtot + here->HSM1_gigdg * delvgs + - here->HSM1_gigdd * delvds + here->HSM1_gigdb * delvbs; - Igbtot = here->HSM1_igb; - cgbhat = Igbtot + here->HSM1_gigbg * delvgs + - here->HSM1_gigbd * delvds + here->HSM1_gigbb * delvbs; - } - else { - Idtot = here->HSM1_ids + here->HSM1_ibd - here->HSM1_igidl; - cdhat = Idtot + (here->HSM1_gbd + here->HSM1_gmbs) * delvbd - + here->HSM1_gm * delvgd - here->HSM1_gds * delvds - - here->HSM1_gigidlgs * delvgd - here->HSM1_gigidlbs * delvbd - + here->HSM1_gigidlds * delvds; - Ibtot = here->HSM1_ibs + here->HSM1_ibd - here->HSM1_isub - - here->HSM1_igidl - here->HSM1_igisl; - cbhat = Ibtot + here->HSM1_gbs * delvbs - + (here->HSM1_gbd - here->HSM1_gbbs - here->HSM1_gigidlbs) * delvbd - - (here->HSM1_gbgs + here->HSM1_gigidlgs) * delvgd - + (here->HSM1_gbds + here->HSM1_gigidlds) * delvds - - here->HSM1_gigislgd * delvgd - here->HSM1_gigislbd * delvbd - + here->HSM1_gigislsd * delvds; - Igbtot = here->HSM1_igb; - cgbhat = Igbtot + here->HSM1_gigbg * delvgd - - here->HSM1_gigbs * delvds + here->HSM1_gigbb * delvbd; - Igstot = here->HSM1_igs; - cgshat = Igstot + here->HSM1_gigsg * delvgd - - here->HSM1_gigss * delvds + here->HSM1_gigsb * delvbd; - Igdtot = here->HSM1_igd; - cgdhat = Igdtot + here->HSM1_gigdg * delvgd - - here->HSM1_gigds * delvds + here->HSM1_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) && ckt->CKTbypass ) - if ( fabs(delvbs) < - ( ckt->CKTreltol * - MAX(fabs(vbs), fabs(*(ckt->CKTstate0+here->HSM1vbs))) + - ckt->CKTvoltTol ) ) - if ( fabs(delvbd) < - ( ckt->CKTreltol * - MAX(fabs(vbd), fabs(*(ckt->CKTstate0+here->HSM1vbd))) + - ckt->CKTvoltTol ) ) - if ( fabs(delvgs) < - ( ckt->CKTreltol * - MAX(fabs(vgs), fabs(*(ckt->CKTstate0+here->HSM1vgs))) + - ckt->CKTvoltTol ) ) - if ( fabs(delvds) < - ( ckt->CKTreltol * - MAX(fabs(vds), fabs(*(ckt->CKTstate0+here->HSM1vds))) + - ckt->CKTvoltTol ) ) - if ( fabs(cdhat - Idtot) < - ( ckt->CKTreltol * - MAX(fabs(cdhat),fabs(Idtot)) + ckt->CKTabstol ) ) - if (!model->HSM1_coiigs || - (fabs(cgbhat - Igbtot) < ckt->CKTreltol - * MAX(fabs(cgbhat), fabs(Igbtot)) + ckt->CKTabstol)) - if (!model->HSM1_coiigs || - (fabs(cgshat - Igstot) < ckt->CKTreltol - * MAX(fabs(cgshat), fabs(Igstot)) + ckt->CKTabstol)) - if (!model->HSM1_coiigs || - (fabs(cgdhat - Igdtot) < ckt->CKTreltol - * MAX(fabs(cgdhat), fabs(Igdtot)) + ckt->CKTabstol)){ - tempv = MAX(fabs(cbhat),fabs(Ibtot)) + ckt->CKTabstol; - if ((fabs(cbhat - Ibtot)) < ckt->CKTreltol * tempv) { - /* bypass code */ - vbs = *(ckt->CKTstate0 + here->HSM1vbs); - vbd = *(ckt->CKTstate0 + here->HSM1vbd); - vgs = *(ckt->CKTstate0 + here->HSM1vgs); - vds = *(ckt->CKTstate0 + here->HSM1vds); - - vgd = vgs - vds; - vgb = vgs - vbs; - - cdrain = here->HSM1_ids; - if ((ckt->CKTmode & (MODETRAN | MODEAC)) || - ((ckt->CKTmode & MODETRANOP) && - (ckt->CKTmode & MODEUIC))) { - ByPass = 1; - qgate = here->HSM1_qg; - qbulk = here->HSM1_qb; - qdrn = here->HSM1_qd; - goto line755; - } - else - goto line850; - } - } -#endif /*NOBYPASS*/ - - /* von = model->HSM1_type * here->HSM1_von; */ - von = here->HSM1_von; - if(*(ckt->CKTstate0 + here->HSM1vds) >= 0.0) { - vgs = DEVfetlim(vgs, *(ckt->CKTstate0 + here->HSM1vgs), von); - vds = vgs - vgd; - vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->HSM1vds)); - vgd = vgs - vds; - } - else { - vgd = DEVfetlim(vgd, vgdo, von); - vds = vgs - vgd; - vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0 + here->HSM1vds))); - vgs = vgd + vds; - } - if (vds >= 0.0) { - vcrit = CONSTvt0 * log( CONSTvt0 / (CONSTroot2 * 1.0e-14) ); - /* SourceSatCurrent = 1.0e-14 */ - vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->HSM1vbs), - CONSTvt0,vcrit,&Check); - vbd = vbs - vds; - } - else { - vcrit = CONSTvt0 * log( CONSTvt0 / (CONSTroot2 * 1.0e-14) ); - /* DrainSatCurrent = 1.0e-14 */ - vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->HSM1vbd), - CONSTvt0,vcrit,&Check); - vbs = vbd + vds; - } - } - - vbd = vbs - vds; - vgd = vgs - vds; - vgb = vgs - vbs; - - /* Input data for HiSIM evaluation part */ - sIN.gmin = ckt->CKTgmin; /* minimum conductance */ - - if (vds >= 0) { /* normal mode */ - here->HSM1_mode = 1; - sIN.vds = vds; - sIN.vgs = vgs; - sIN.vbs = vbs; - } - else { /* reverse mode */ - here->HSM1_mode = -1; - sIN.vds = -vds; - sIN.vgs = vgd; - sIN.vbs = vbd; - } - - sIN.type = model->HSM1_type; - sIN.mode = here->HSM1_mode; - /* sIN.qflag = ChargeComputationNeeded; no use */ - sIN.info = model->HSM1_info; - - sIN.xl = here->HSM1_l; - sIN.xw = here->HSM1_w; - - sIN.ad = here->HSM1_ad; - sIN.as = here->HSM1_as; - - sIN.pd = here->HSM1_pd; - sIN.ps = here->HSM1_ps; - - sIN.nrd = here->HSM1_nrd; - sIN.nrs = here->HSM1_nrs; - - sIN.temp = ckt->CKTtemp; - if ( here->HSM1_temp_Given ) sIN.temp = here->HSM1_temp; - if ( here->HSM1_dtemp_Given ) sIN.temp = ckt->CKTtemp + here->HSM1_dtemp; - - sIN.tox = model->HSM1_tox; - sIN.xld = model->HSM1_xld; - sIN.xwd = model->HSM1_xwd; - - if (model->HSM1_version == 102) { /* HiSIM 1.0.2 */ - sIN.xj = model->HSM1_xj; - } - else if (model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM 1.1.2 / 1.2.0 */ - sIN.xqy = model->HSM1_xqy; - } - sIN.vmax = model->HSM1_vmax; - sIN.bgtmp1 = model->HSM1_bgtmp1; - sIN.bgtmp2 = model->HSM1_bgtmp2; - sIN.rs = model->HSM1_rs; - sIN.rd = model->HSM1_rd; - sIN.vfbc = model->HSM1_vfbc; - sIN.nsubc = model->HSM1_nsubc; - sIN.lp = model->HSM1_lp; - sIN.nsubp = model->HSM1_nsubp; - sIN.scp1 = model->HSM1_scp1; - sIN.scp2 = model->HSM1_scp2; - sIN.scp3 = model->HSM1_scp3; - sIN.parl1 = model->HSM1_parl1; - sIN.parl2 = model->HSM1_parl2; - sIN.sc1 = model->HSM1_sc1; - sIN.sc2 = model->HSM1_sc2; - sIN.sc3 = model->HSM1_sc3; - sIN.pgd1 = model->HSM1_pgd1; - sIN.pgd2 = model->HSM1_pgd2; - sIN.pgd3 = model->HSM1_pgd3; - sIN.ndep = model->HSM1_ndep; - sIN.ninv = model->HSM1_ninv; - sIN.ninvd = model->HSM1_ninvd; - sIN.muecb0 = model->HSM1_muecb0; - sIN.muecb1 = model->HSM1_muecb1; - sIN.mueph1 = model->HSM1_mueph1; - sIN.mueph0 = model->HSM1_mueph0; - sIN.mueph2 = model->HSM1_mueph2; - sIN.w0 = model->HSM1_w0; - sIN.muesr1 = model->HSM1_muesr1; - sIN.muesr0 = model->HSM1_muesr0; - sIN.muetmp = model->HSM1_muetmp; - if (model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM 1.1.2 / 1.2.0 */ - sIN.wvthsc = model->HSM1_wvthsc; - sIN.nsti = model->HSM1_nsti; - sIN.wsti = model->HSM1_wsti; - } - - if ( model->HSM1_bb_Given ) sIN.bb = model->HSM1_bb; - else - if ( model->HSM1_type == NMOS ) sIN.bb = 2.0e0; - else sIN.bb = 1.0e0; - - sIN.sub1 = model->HSM1_sub1; - sIN.sub2 = model->HSM1_sub2; - sIN.sub3 = model->HSM1_sub3; - - if ( model->HSM1_cgso_Given ) sIN.cocgso = 1; - else sIN.cocgso = 0; - - if ( model->HSM1_cgdo_Given ) sIN.cocgdo = 1; - else sIN.cocgdo = 0; - - if ( model->HSM1_cgbo_Given ) sIN.cocgbo = 1; - else sIN.cocgbo = 0; - - if ( here->HSM1_mode == 1 ) { - sIN.cgso = model->HSM1_cgso; - sIN.cgdo = model->HSM1_cgdo; - } - else { - tmp = sIN.cocgso; - sIN.cocgso = sIN.cocgdo; - sIN.cocgdo = tmp; - sIN.cgso = model->HSM1_cgdo; - sIN.cgdo = model->HSM1_cgso; - } - - sIN.cgbo = model->HSM1_cgbo; - sIN.tpoly = model->HSM1_tpoly; - sIN.js0 = model->HSM1_js0; - sIN.js0sw = model->HSM1_js0sw; - sIN.nj = model->HSM1_nj; - sIN.njsw = model->HSM1_njsw; - sIN.xti = model->HSM1_xti; - sIN.cj = model->HSM1_cj; - sIN.cjsw = model->HSM1_cjsw; - sIN.cjswg = model->HSM1_cjswg; - sIN.mj = model->HSM1_mj; - sIN.mjsw = model->HSM1_mjsw; - sIN.mjswg = model->HSM1_mjswg; - sIN.pb = model->HSM1_pb; - sIN.pbsw = model->HSM1_pbsw; - sIN.pbswg = model->HSM1_pbswg; - sIN.xpolyd = model->HSM1_xpolyd; - sIN.clm1 = model->HSM1_clm1; - sIN.clm2 = model->HSM1_clm2; - sIN.clm3 = model->HSM1_clm3; - sIN.rpock1 = model->HSM1_rpock1; - sIN.rpock2 = model->HSM1_rpock2; - if (model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM 1.1.2 / 1.2.0 */ - sIN.rpocp1 = model->HSM1_rpocp1; - sIN.rpocp2 = model->HSM1_rpocp2; - } - sIN.vover = model->HSM1_vover; - sIN.voverp = model->HSM1_voverp; - sIN.wfc = model->HSM1_wfc; - sIN.qme1 = model->HSM1_qme1; - sIN.qme2 = model->HSM1_qme2; - sIN.qme3 = model->HSM1_qme3; - sIN.gidl1 = model->HSM1_gidl1; - sIN.gidl2 = model->HSM1_gidl2; - sIN.gidl3 = model->HSM1_gidl3; - sIN.gleak1 = model->HSM1_gleak1; - sIN.gleak2 = model->HSM1_gleak2; - sIN.gleak3 = model->HSM1_gleak3; - sIN.vzadd0 = model->HSM1_vzadd0; - sIN.pzadd0 = model->HSM1_pzadd0; - - /* no use in SPICE3f5 */ - /* - sMS.ims[0] = 0; - sMS.dms[0] = 0.0e0; - sMS.ims[1] = 0; - sMS.dms[1] = pslot->timepoint; I don't know - * no use in SPICE3f5 - */ - - if ( ! strcmp(here->HSM1_called, "yes" ) ) { - sIN.has_prv = 1; - } - else { - sIN.has_prv = 0; - strcpy( here->HSM1_called , "yes" ); - } - - sIN.corsrd = model->HSM1_corsrd; - sIN.coiprv = model->HSM1_coiprv; - sIN.copprv = model->HSM1_copprv; - sIN.cocgbo = model->HSM1_cocgbo; - sIN.coadov = model->HSM1_coadov; - sIN.coxx08 = model->HSM1_coxx08; - sIN.coxx09 = model->HSM1_coxx09; - sIN.coisub = model->HSM1_coisub; - sIN.coiigs = model->HSM1_coiigs; - sIN.cogidl = model->HSM1_cogidl; - sIN.cogisl = model->HSM1_cogisl; - sIN.coovlp = model->HSM1_coovlp; - sIN.conois = model->HSM1_conois; - if (model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM 1.1.2 / 1.2.0 */ - sIN.coisti = model->HSM1_coisti; - } - if (model->HSM1_version == 120) { /* HiSIM 1.2.0 */ - sIN.cosmbi = model->HSM1_cosmbi; - sIN.glpart1 = model->HSM1_glpart1; - sIN.glpart2 = model->HSM1_glpart2; - sIN.kappa = model->HSM1_kappa; - sIN.xdiffd = model->HSM1_xdiffd; - sIN.pthrou = model->HSM1_pthrou; - sIN.vdiffj = model->HSM1_vdiffj; - } - sIN.version = model->HSM1_version; - - sIN.vbsc_prv = here->HSM1_vbsc_prv; - sIN.vdsc_prv = here->HSM1_vdsc_prv; - sIN.vgsc_prv = here->HSM1_vgsc_prv; - sIN.ps0_prv = here->HSM1_ps0_prv; - sIN.ps0_dvbs_prv = here->HSM1_ps0_dvbs_prv; - sIN.ps0_dvds_prv = here->HSM1_ps0_dvds_prv; - sIN.ps0_dvgs_prv = here->HSM1_ps0_dvgs_prv; - sIN.pds_prv = here->HSM1_pds_prv; - sIN.pds_dvbs_prv = here->HSM1_pds_dvbs_prv; - sIN.pds_dvds_prv = here->HSM1_pds_dvds_prv; - sIN.pds_dvgs_prv = here->HSM1_pds_dvgs_prv; - sIN.ids_prv = here->HSM1_ids_prv; - sIN.ids_dvbs_prv = here->HSM1_ids_dvbs_prv; - sIN.ids_dvds_prv = here->HSM1_ids_dvds_prv; - sIN.ids_dvgs_prv = here->HSM1_ids_dvgs_prv; - - sIN.nftrp = model->HSM1_nftrp; - sIN.nfalp = model->HSM1_nfalp; - sIN.cit = model->HSM1_cit; - - if ( sIN.info >= 5 ) { /* mode, bias conditions ... */ - printf( "--- variables given to HSM1evaluate() ----\n" ); - printf( "type = %s\n" , (sIN.type>0) ? "NMOS" : "PMOS" ); - printf( "mode = %s\n" , (sIN.mode>0) ? "NORMAL" : "REVERSE" ); - - printf( "vbs = %12.5e\n" , sIN.vbs ); - printf( "vds = %12.5e\n" , sIN.vds ); - printf( "vgs = %12.5e\n" , sIN.vgs ); - } - if ( sIN.info >= 6 ) { /* input flags */ - printf( "corsrd = %s\n" , (sIN.corsrd) ? "true" : "false" ); - printf( "coiprv = %s\n" , (sIN.coiprv) ? "true" : "false" ); - printf( "copprv = %s\n" , (sIN.copprv) ? "true" : "false" ); - printf( "cocgso = %s\n" , (sIN.cocgso) ? "true" : "false" ); - printf( "cocgdo = %s\n" , (sIN.cocgdo) ? "true" : "false" ); - printf( "cocgbo = %s\n" , (sIN.cocgbo) ? "true" : "false" ); - printf( "coadov = %s\n" , (sIN.coadov) ? "true" : "false" ); - printf( "coisub = %s\n" , (sIN.coisub) ? "true" : "false" ); - printf( "coiigs = %s\n" , (sIN.coiigs) ? "true" : "false" ); - printf( "cogidl = %s\n" , (sIN.cogidl) ? "true" : "false" ); - printf( "cogisl = %s\n" , (sIN.cogisl) ? "true" : "false" ); - printf( "coovlp = %s\n" , (sIN.coovlp) ? "true" : "false" ); - printf( "conois = %s\n" , (sIN.conois) ? "true" : "false" ); - if (model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM 1.1.2 / 1.2.0 */ - printf( "coisti = %s\n" , (sIN.coisti) ? "true" : "false" ); - } - } - /* print inputs ------------AA */ - - /* call model evaluation */ - if (model->HSM1_version == 102) { /* HiSIM 1.0.2 */ - if ( HSM1evaluate102(sIN, &sOT, &sMS) == HiSIM_ERROR ) - return (HiSIM_ERROR); - } - else if (model->HSM1_version == 112) { /* HiSIM 1.1.2 */ - if ( HSM1evaluate112(sIN, &sOT, &sMS) == HiSIM_ERROR ) - return (HiSIM_ERROR); - } - else if (model->HSM1_version == 120) { /* HiSIM 1.2.0 */ - if ( HSM1evaluate120(sIN, &sOT, &sMS) == HiSIM_ERROR ) - return (HiSIM_ERROR); - } - - /* store values for next calculation */ - /* note: derivatives are ones w.r.t. internal biases */ - here->HSM1_vbsc_prv = sOT.vbsc; - here->HSM1_vdsc_prv = sOT.vdsc; - here->HSM1_vgsc_prv = sOT.vgsc; - here->HSM1_ps0_prv = sOT.ps0; - here->HSM1_ps0_dvbs_prv = sOT.ps0_dvbs; - here->HSM1_ps0_dvds_prv = sOT.ps0_dvds; - here->HSM1_ps0_dvgs_prv = sOT.ps0_dvgs; - here->HSM1_pds_prv = sOT.pds; - here->HSM1_pds_dvbs_prv = sOT.pds_dvbs; - here->HSM1_pds_dvds_prv = sOT.pds_dvds; - here->HSM1_pds_dvgs_prv = sOT.pds_dvgs; - here->HSM1_ids_prv = sOT.ids; - here->HSM1_ids_dvbs_prv = sOT.ids_dvbs; - here->HSM1_ids_dvds_prv = sOT.ids_dvds; - here->HSM1_ids_dvgs_prv = sOT.ids_dvgs; - - /* for noise calc */ - here->HSM1_nfc = sOT.nf; - - /* outputs */ - here->HSM1_gd = sOT.gd; /* drain conductance */ - here->HSM1_gs = sOT.gs; /* source conductance */ - - here->HSM1_von = model->HSM1_type * sOT.von; - here->HSM1_vdsat = model->HSM1_type * sOT.vdsat; - /* - here->HSM1_von = sOT.von; - here->HSM1_vdsat = sOT.vdsat; - */ - cdrain = here->HSM1_ids = sOT.ids; /* cdrain */ - - here->HSM1_gds = sOT.gds; - here->HSM1_gm = sOT.gm; - here->HSM1_gmbs = sOT.gmbs; - - /* overlap capacitances */ - here->HSM1_cgso = sOT.cgso; /* G-S */ - here->HSM1_cgdo = sOT.cgdo; /* G-D */ - here->HSM1_cgbo = sOT.cgbo; /* G-B */ - - /* intrinsic charge ONLY */ - qgate = here->HSM1_qg = sOT.qg; /* gate */ - qdrn = here->HSM1_qd = sOT.qd; /* drain */ - /* here->HSM1_qs = sOT.qs; source */ - qbulk = here->HSM1_qb = -1.0 * ( sOT.qg + sOT.qd + sOT.qs ); /* bulk */ - - /* charge caps (intrisic ONLY) */ - here->HSM1_cggb = sOT.cggb; - here->HSM1_cgsb = sOT.cgsb; - here->HSM1_cgdb = sOT.cgdb; - here->HSM1_cbgb = sOT.cbgb; - here->HSM1_cbsb = sOT.cbsb; - here->HSM1_cbdb = sOT.cbdb; - here->HSM1_cdgb = sOT.cdgb; - here->HSM1_cdsb = sOT.cdsb; - here->HSM1_cddb = sOT.cddb; - - /* substrate diode */ - here->HSM1_ibd = sOT.ibd; - here->HSM1_ibs = sOT.ibs; - /* - here->HSM1_ibd = model->HSM1_type * sOT.ibd; - here->HSM1_ibs = model->HSM1_type * sOT.ibs; - */ - here->HSM1_gbd = sOT.gbd; - here->HSM1_gbs = sOT.gbs; - here->HSM1_capbd = sOT.capbd; - here->HSM1_capbs = sOT.capbs; - *(ckt->CKTstate0 + here->HSM1qbd) = sOT.qbd; - *(ckt->CKTstate0 + here->HSM1qbs) = sOT.qbs; - - /* substrate impact ionization current */ - here->HSM1_isub = sOT.isub; - here->HSM1_gbgs = sOT.gbgs; - here->HSM1_gbds = sOT.gbds; - here->HSM1_gbbs = sOT.gbbs; - - /* 1/f noise */ - /* here->HSM1_nois_idsfl = sOT.nois_idsfl;*/ - - /* mobility added by K.M. */ - here->HSM1_mu = sOT.mu; - /* gate induced drain leakage */ - here->HSM1_igidl = sOT.igidl; - here->HSM1_gigidlgs = sOT.ggidlgs; - here->HSM1_gigidlds = sOT.ggidlds; - here->HSM1_gigidlbs = sOT.ggidlbs; - if (model->HSM1_version == 120) { /* HiSIM 1.2.0 */ - /* gate induced source leakage */ - here->HSM1_igisl = sOT.igisl; - here->HSM1_gigislgd = sOT.ggislgd; - here->HSM1_gigislsd = sOT.ggislsd; - here->HSM1_gigislbd = sOT.ggislbd; - - /* gate tunneling current (gate to bulk) */ - here->HSM1_igb = sOT.igateb; - here->HSM1_gigbg = sOT.ggbgs; - here->HSM1_gigbd = sOT.ggbds; - here->HSM1_gigbb = sOT.ggbbs; - here->HSM1_gigbs = -( here->HSM1_gigbg + here->HSM1_gigbd - + here->HSM1_gigbb ); - /* gate tunneling current (gate to source) */ - here->HSM1_igs = sOT.igates; - here->HSM1_gigsg = sOT.ggsgs; - here->HSM1_gigsd = sOT.ggsds; - here->HSM1_gigsb = sOT.ggsbs; - here->HSM1_gigss = -( here->HSM1_gigsg + here->HSM1_gigsd - + here->HSM1_gigsb ); - /* gate tunneling current (gate to drain) */ - here->HSM1_igd = sOT.igated; - here->HSM1_gigdg = sOT.ggdgs; - here->HSM1_gigdd = sOT.ggdds; - here->HSM1_gigdb = sOT.ggdbs; - here->HSM1_gigds = -( here->HSM1_gigdg + here->HSM1_gigdd - + here->HSM1_gigdb ); - } - else { - /* gate induced source leakage */ - here->HSM1_igisl = 0.0; - here->HSM1_gigislgd = 0.0; - here->HSM1_gigislsd = 0.0; - here->HSM1_gigislbd = 0.0; - - /* gate tunneling current (gate to bulk) */ - here->HSM1_igb = sOT.igate; - here->HSM1_gigbg = sOT.gggs; - here->HSM1_gigbd = sOT.ggds; - here->HSM1_gigbb = sOT.ggbs; - here->HSM1_gigbs = -( here->HSM1_gigbg + here->HSM1_gigbd - + here->HSM1_gigbb ); - /* gate tunneling current (gate to source) */ - here->HSM1_igs = 0.0; - here->HSM1_gigsg = 0.0; - here->HSM1_gigsd = 0.0; - here->HSM1_gigsb = 0.0; - here->HSM1_gigss = 0.0; - /* gate tunneling current (gate to drain) */ - here->HSM1_igd = 0.0; - here->HSM1_gigdg = 0.0; - here->HSM1_gigdd = 0.0; - here->HSM1_gigdb = 0.0; - here->HSM1_gigds = 0.0; - } - /* intrinsic charges without overlap charge etc. */ - here->HSM1_qg_int = sOT.qg_int; - here->HSM1_qd_int = sOT.qd_int; - here->HSM1_qs_int = sOT.qs_int; - here->HSM1_qb_int = sOT.qb_int; - - /* print all outputs ------------VV */ - if ( sIN.info >= 4 ) { - printf( "--- variables returned from HSM1evaluate() ----\n" ); - printf( "gd = %12.5e\n" , sOT.gd ); - printf( "gs = %12.5e\n" , sOT.gs ); - - printf( "von = %12.5e\n" , sOT.von ); - printf( "vdsat = %12.5e\n" , sOT.vdsat ); - printf( "ids = %12.5e\n" , sOT.ids ); - - printf( "gds = %12.5e\n" , sOT.gds ); - printf( "gm = %12.5e\n" , sOT.gm ); - printf( "gmbs = %12.5e\n" , sOT.gmbs ); - - printf( "cgbo = %12.5e\n" , sOT.cgbo ); - - printf( "qg = %12.5e\n" , sOT.qg ); - printf( "qd = %12.5e\n" , sOT.qd ); - printf( "qs = %12.5e\n" , sOT.qs ); - - printf( "cggb = %12.5e\n" , sOT.cggb ); - printf( "cgsb = %12.5e\n" , sOT.cgsb ); - printf( "cgdb = %12.5e\n" , sOT.cgdb ); - printf( "cbgb = %12.5e\n" , sOT.cbgb ); - printf( "cbsb = %12.5e\n" , sOT.cbsb ); - printf( "cbdb = %12.5e\n" , sOT.cbdb ); - printf( "cdgb = %12.5e\n" , sOT.cdgb ); - printf( "cdsb = %12.5e\n" , sOT.cdsb ); - printf( "cddb = %12.5e\n" , sOT.cddb ); - - printf( "ibd = %12.5e\n" , sOT.ibd ); - printf( "ibs = %12.5e\n" , sOT.ibs ); - printf( "gbd = %12.5e\n" , sOT.gbd ); - printf( "gbs = %12.5e\n" , sOT.gbs ); - printf( "capbd = %12.5e\n" , sOT.capbd ); - printf( "capbs = %12.5e\n" , sOT.capbs ); - printf( "qbd = %12.5e\n" , sOT.qbd ); - printf( "qbs = %12.5e\n" , sOT.qbs ); - - printf( "isub = %12.5e\n" , sOT.isub ); - printf( "gbgs = %12.5e\n" , sOT.gbgs ); - printf( "gbds = %12.5e\n" , sOT.gbds ); - printf( "gbbs = %12.5e\n" , sOT.gbbs ); - - /* printf( "flicker noise = %12.5e\n" , sOT.nois_idsfl );*/ - printf( "flicker noise = %12.5e\n" , sOT.nf ); - } - /* print all outputs ------------AA */ - - if ( sIN.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, Ps0 Psl\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 %12.5e %12.5e\n", - vbs, vds, vgs , - sOT.cggb, sOT.cgdb, sOT.cgsb, - sOT.cbgb, sOT.cbdb, sOT.cbsb, - sOT.cdgb, sOT.cddb, sOT.cdsb, - sOT.ps0, sOT.ps0 + sOT.pds); - - } - - /* - * check convergence - */ - isConv = 1; - if ( (here->HSM1_off == 0) || !(ckt->CKTmode & MODEINITFIX) ) { - if (Check == 1) { - ckt->CKTnoncon++; - isConv = 0; -#ifndef NEWCONV - } - else { - if (here->HSM1_mode >= 0) - Idtot = here->HSM1_ids + here->HSM1_isub - - here->HSM1_ibd + here->HSM1_igidl; - else - Idtot = here->HSM1_ids + here->HSM1_ibd - - here->HSM1_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->HSM1_ibs + here->HSM1_ibd - - here->HSM1_isub - here->HSM1_igidl - here->HSM1_igisl; - tol = ckt->CKTreltol * - MAX(fabs(cbhat), fabs(Ibtot)) + ckt->CKTabstol; - if (fabs(cbhat - Ibtot) > tol) { - ckt->CKTnoncon++; - isConv = 0; - } - } - } -#endif - } - } - *(ckt->CKTstate0 + here->HSM1vbs) = vbs; - *(ckt->CKTstate0 + here->HSM1vbd) = vbd; - *(ckt->CKTstate0 + here->HSM1vgs) = vgs; - *(ckt->CKTstate0 + here->HSM1vds) = vds; - - if ((ckt->CKTmode & MODEDC) && - !(ckt->CKTmode & MODEINITFIX) && !(ckt->CKTmode & MODEINITJCT)) - showPhysVal = 1; - - /* - if ((ckt->CKTmode & MODEDC) && !(ckt->CKTmode & MODEINITFIX) && - !(ckt->CKTmode & MODEINITJCT)) { - if ((!(ckt->CKTmode & MODEINITPRED) && vds != vds_pre) || - ((ckt->CKTmode & MODEINITPRED) && vds == vds_pre)) - showPhysVal = 1; - } - */ - - if (model->HSM1_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; -#ifndef NOBYPASS - line755: -#endif - cgdo = here->HSM1_cgdo; - cgso = here->HSM1_cgso; - cgbo = here->HSM1_cgbo; - - ag0 = ckt->CKTag[0]; - if (here->HSM1_mode > 0) { /* NORMAL mode */ - gcggb = (here->HSM1_cggb + cgdo + cgso + cgbo ) * ag0; - gcgdb = (here->HSM1_cgdb - cgdo) * ag0; - gcgsb = (here->HSM1_cgsb - cgso) * ag0; - - gcdgb = (here->HSM1_cdgb - cgdo) * ag0; - gcddb = (here->HSM1_cddb + here->HSM1_capbd + cgdo) * ag0; - gcdsb = here->HSM1_cdsb * ag0; - - gcsgb = -(here->HSM1_cggb + here->HSM1_cbgb - + here->HSM1_cdgb + cgso) * ag0; - gcsdb = -(here->HSM1_cgdb + here->HSM1_cbdb - + here->HSM1_cddb) * ag0; - gcssb = (here->HSM1_capbs + cgso - - (here->HSM1_cgsb + here->HSM1_cbsb + here->HSM1_cdsb)) * ag0; - - gcbgb = (here->HSM1_cbgb - cgbo) * ag0; - gcbdb = (here->HSM1_cbdb - here->HSM1_capbd) * ag0; - gcbsb = (here->HSM1_cbsb - here->HSM1_capbs) * ag0; - - if (sIN.coadov != 1) { - qgd = cgdo * vgd; - qgs = cgso * vgs; - qgb = cgbo * vgb; - qgate += qgd + qgs + qgb; - qbulk -= qgb; - qdrn -= qgd; - /* qsrc = -(qgate + qbulk + qdrn); */ - } - } - else { /* REVERSE mode */ - gcggb = (here->HSM1_cggb + cgdo + cgso + cgbo ) * ag0; - gcgdb = (here->HSM1_cgsb - cgdo) * ag0; - gcgsb = (here->HSM1_cgdb - cgso) * ag0; - - gcdgb = -(here->HSM1_cggb + - here->HSM1_cbgb + here->HSM1_cdgb + cgdo) * ag0; - gcddb = (here->HSM1_capbd + cgdo - - (here->HSM1_cgsb + here->HSM1_cbsb + here->HSM1_cdsb)) * ag0; - gcdsb = -(here->HSM1_cgdb + here->HSM1_cbdb + here->HSM1_cddb) * ag0; - - gcsgb = (here->HSM1_cdgb - cgso) * ag0; - gcsdb = here->HSM1_cdsb * ag0; - gcssb = (here->HSM1_cddb + here->HSM1_capbs + cgso) * ag0; - - gcbgb = (here->HSM1_cbgb - cgbo) * ag0; - gcbdb = (here->HSM1_cbsb - here->HSM1_capbd) * ag0; - gcbsb = (here->HSM1_cbdb - here->HSM1_capbs) * ag0; - - if (sIN.coadov != 1) { - qgd = cgdo * vgd; - qgs = cgso * vgs; - qgb = cgbo * vgb; - qgate += qgd + qgs + qgb; - qbulk -= qgb; - qsrc = qdrn - qgs; - qdrn = -(qgate + qbulk + qsrc); - } - else { - qdrn = -(qgate + qbulk + qdrn); - } - } - - if (ByPass) goto line860; - - *(ckt->CKTstate0 + here->HSM1qg) = qgate; - *(ckt->CKTstate0 + here->HSM1qd) = qdrn - *(ckt->CKTstate0 + here->HSM1qbd); - *(ckt->CKTstate0 + here->HSM1qb) = - qbulk + *(ckt->CKTstate0 + here->HSM1qbd) + *(ckt->CKTstate0 + here->HSM1qbs); - - /* - printf( "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\n" ); - printf( "HSM1qg = %12.5e\n" , *(ckt->CKTstate0 + here->HSM1qg) ); - printf( "HSM1qd = %12.5e\n" , *(ckt->CKTstate0 + here->HSM1qd) ); - printf( "HSM1qb = %12.5e\n" , *(ckt->CKTstate0 + here->HSM1qb) ); - printf( "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\n" ); - */ - - /* store small signal parameters */ - if (ckt->CKTmode & MODEINITSMSIG) goto line1000; - if (!ChargeComputationNeeded) goto line850; - - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->HSM1qb) = *(ckt->CKTstate0 + here->HSM1qb); - *(ckt->CKTstate1 + here->HSM1qg) = *(ckt->CKTstate0 + here->HSM1qg); - *(ckt->CKTstate1 + here->HSM1qd) = *(ckt->CKTstate0 + here->HSM1qd); - } - - if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM1qb)) != 0) return(error); - if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM1qg)) != 0) return(error); - if ((error = NIintegrate(ckt, &geq, &ceq, 0.0, here->HSM1qd)) != 0) return(error); - - goto line860; - - line850: - /* initialize to zero charge conductance and current */ - ceqqg = ceqqb = ceqqd = 0.0; - - gcdgb = gcddb = gcdsb = 0.0; - gcsgb = gcsdb = gcssb = 0.0; - gcggb = gcgdb = gcgsb = 0.0; - gcbgb = gcbdb = gcbsb = 0.0; - - goto line900; - - line860: - /* evaluate equivalent charge current */ - - cqgate = *(ckt->CKTstate0 + here->HSM1cqg); - cqbulk = *(ckt->CKTstate0 + here->HSM1cqb); - cqdrn = *(ckt->CKTstate0 + here->HSM1cqd); - - /* - printf( "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n" ); - printf( "cqgate = %12.5e\n" , cqgate ); - printf( "cqbulk = %12.5e\n" , cqbulk ); - printf( "cqdrn = %12.5e\n" , cqdrn ); - printf( "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n" ); - */ - - ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs; - ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs; - ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs; - - if (ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->HSM1cqb) = *(ckt->CKTstate0 + here->HSM1cqb); - *(ckt->CKTstate1 + here->HSM1cqg) = *(ckt->CKTstate0 + here->HSM1cqg); - *(ckt->CKTstate1 + here->HSM1cqd) = *(ckt->CKTstate0 + here->HSM1cqd); - } - - /* - * load current vector - */ - line900: - - m = here->HSM1_m; - - if (here->HSM1_mode >= 0) { /* NORMAL mode */ - gm = here->HSM1_gm; - gmbs = here->HSM1_gmbs; - FwdSum = gm + gmbs; - RevSum = 0.0; - - cdreq = model->HSM1_type * - (cdrain - here->HSM1_gds * vds - here->HSM1_gm * vgs - here->HSM1_gmbs * vbs); - ceqbd = -model->HSM1_type * - (here->HSM1_isub + here->HSM1_igidl - - (here->HSM1_gbds + here->HSM1_gigidlds) * vds - - (here->HSM1_gbgs + here->HSM1_gigidlgs) * vgs - - (here->HSM1_gbbs + here->HSM1_gigidlbs) * vbs); - ceqbs = -model->HSM1_type * - (here->HSM1_igisl - + here->HSM1_gigislsd * vds - - here->HSM1_gigislgd * vgd - - here->HSM1_gigislbd * vbd); - - gbbdp = -here->HSM1_gbds; - gbbsp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = here->HSM1_gbgs; - gbdpdp = here->HSM1_gbds; - gbdpb = here->HSM1_gbbs; - gbdpsp = -(gbdpg + gbdpdp + gbdpb); - - gbspg = 0.0; - gbspdp = 0.0; - gbspb = 0.0; - gbspsp = 0.0; - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - Ibtoteq = model->HSM1_type * - (here->HSM1_igb - here->HSM1_gigbg * vgs - - here->HSM1_gigbd * vds - here->HSM1_gigbb * vbs); - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - Istoteq = model->HSM1_type * - (here->HSM1_igs - here->HSM1_gigsg * vgs - - here->HSM1_gigsd * vds - here->HSM1_gigsb * vbs); - - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - Idtoteq = model->HSM1_type * - (here->HSM1_igd - here->HSM1_gigdg * vgs - - here->HSM1_gigdd * vds - here->HSM1_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->HSM1_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->HSM1_gm; - gmbs = -here->HSM1_gmbs; - FwdSum = 0.0; - RevSum = -(gm + gmbs); - - cdreq = -model->HSM1_type * - (cdrain + here->HSM1_gds * vds - - here->HSM1_gm * vgd - here->HSM1_gmbs * vbd); - ceqbs = -model->HSM1_type * - (here->HSM1_isub + here->HSM1_igisl - + (here->HSM1_gbds + here->HSM1_gigislsd) * vds - - (here->HSM1_gbgs + here->HSM1_gigislgd) * vgd - - (here->HSM1_gbbs + here->HSM1_gigislbd) * vbd); - ceqbd = -model->HSM1_type * - ( here->HSM1_igidl - - here->HSM1_gigidlds * vds - - here->HSM1_gigidlgs * vgs - - here->HSM1_gigidlbs * vbs); - - gbbsp = -here->HSM1_gbds; - gbbdp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = 0.0; - gbdpsp = 0.0; - gbdpb = 0.0; - gbdpdp = 0.0; - - gbspg = here->HSM1_gbgs; - gbspsp = here->HSM1_gbds; - gbspb = here->HSM1_gbbs; - gbspdp = -(gbspg + gbspsp + gbspb); - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - Ibtoteq = model->HSM1_type * - (here->HSM1_igb - here->HSM1_gigbg * vgd - + here->HSM1_gigbs * vds - here->HSM1_gigbb * vbd); - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - Istoteq = model->HSM1_type * - (here->HSM1_igs - here->HSM1_gigsg * vgd - + here->HSM1_gigss * vds - here->HSM1_gigsb * vbd); - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - Idtoteq = model->HSM1_type * - (here->HSM1_igd - here->HSM1_gigdg * vgd - + here->HSM1_gigds * vds - here->HSM1_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->HSM1_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->HSM1_type > 0) { - ceqbs += here->HSM1_ibs - here->HSM1_gbs * vbs; - ceqbd += here->HSM1_ibd - here->HSM1_gbd * vbd; - } - else { - ceqbs -= here->HSM1_ibs - here->HSM1_gbs * vbs; - ceqbd -= here->HSM1_ibd - here->HSM1_gbd * vbd; - ceqqg = -ceqqg; - ceqqb = -ceqqb; - ceqqd = -ceqqd; - } - - /* - 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" ); - */ - - *(ckt->CKTrhs + here->HSM1gNode) -= m * (ceqqg + Igtoteq); - *(ckt->CKTrhs + here->HSM1bNode) -= m * (ceqbs + ceqbd + ceqqb - Ibtoteq); - *(ckt->CKTrhs + here->HSM1dNodePrime) += m * (ceqbd - cdreq - ceqqd + Idtoteq); - *(ckt->CKTrhs + here->HSM1sNodePrime) += m * (cdreq + ceqbs + ceqqg + ceqqb + ceqqd + Istoteq); - - /* - * load y matrix - */ - - *(here->HSM1DdPtr) += m * here->HSM1drainConductance; - *(here->HSM1GgPtr) += m * (gcggb + gIgtotg); - *(here->HSM1SsPtr) += m * here->HSM1sourceConductance; - *(here->HSM1BbPtr) += m * (here->HSM1_gbd + here->HSM1_gbs - - gcbgb - gcbdb - gcbsb - - here->HSM1_gbbs - gIbtotb); - *(here->HSM1DPdpPtr) += m * (here->HSM1drainConductance - + here->HSM1_gds + here->HSM1_gbd - + RevSum + gcddb + gbdpdp - gIdtotd); - *(here->HSM1SPspPtr) += m * (here->HSM1sourceConductance - + here->HSM1_gds + here->HSM1_gbs - + FwdSum + gcssb + gbspsp - gIstots); - *(here->HSM1DdpPtr) -= m * here->HSM1drainConductance; - *(here->HSM1GbPtr) -= m * (gcggb + gcgdb + gcgsb - gIgtotb); - *(here->HSM1GdpPtr) += m * (gcgdb + gIgtotd); - *(here->HSM1GspPtr) += m * (gcgsb + gIgtots); - *(here->HSM1SspPtr) -= m * (here->HSM1sourceConductance); - *(here->HSM1BgPtr) += m * (gcbgb - here->HSM1_gbgs - gIbtotg); - *(here->HSM1BdpPtr) += m * (gcbdb - here->HSM1_gbd + gbbdp - - gIbtotd); - *(here->HSM1BspPtr) += m * (gcbsb - here->HSM1_gbs + gbbsp - - gIbtots); - *(here->HSM1DPdPtr) -= m * (here->HSM1drainConductance); - *(here->HSM1DPgPtr) += m * (gm + gcdgb + gbdpg - gIdtotg); - *(here->HSM1DPbPtr) -= m * (here->HSM1_gbd - gmbs + gcdgb + gcddb - + gcdsb - gIdtotb); - *(here->HSM1DPspPtr) -= m * (here->HSM1_gds + FwdSum - gcdsb - gbdpsp - + gIdtots); - *(here->HSM1SPgPtr) += m * (gcsgb - gm + gbspg - gIstotg); - *(here->HSM1SPsPtr) -= m * (here->HSM1sourceConductance); - *(here->HSM1SPbPtr) -= m * (here->HSM1_gbs + gmbs + gcsgb + gcsdb - + gcssb - gbspb + gIstotb); - *(here->HSM1SPdpPtr) -= m * (here->HSM1_gds + RevSum - gcsdb - gbspdp - + gIstotd); - - /* stamp GIDL */ - *(here->HSM1DPdpPtr) += m * here->HSM1_gigidlds; - *(here->HSM1DPgPtr) += m * here->HSM1_gigidlgs; - *(here->HSM1DPspPtr) -= m *(here->HSM1_gigidlgs - + here->HSM1_gigidlds - + here->HSM1_gigidlbs); - *(here->HSM1DPbPtr) += m * here->HSM1_gigidlbs; - *(here->HSM1BdpPtr) -= m * here->HSM1_gigidlds; - *(here->HSM1BgPtr) -= m * here->HSM1_gigidlgs; - *(here->HSM1BspPtr) += m * (here->HSM1_gigidlgs - + here->HSM1_gigidlds - + here->HSM1_gigidlbs); - *(here->HSM1BbPtr) -= m * here->HSM1_gigidlbs; - /* stamp GISL */ - *(here->HSM1SPdpPtr) -= m * (here->HSM1_gigislsd - + here->HSM1_gigislgd - + here->HSM1_gigislbd); - *(here->HSM1SPgPtr) += m * here->HSM1_gigislgd; - *(here->HSM1SPspPtr) += m * here->HSM1_gigislsd; - *(here->HSM1SPbPtr) += m * here->HSM1_gigislbd; - *(here->HSM1BdpPtr) += m * (here->HSM1_gigislgd - + here->HSM1_gigislsd - + here->HSM1_gigislbd); - *(here->HSM1BgPtr) -= m * here->HSM1_gigislgd; - *(here->HSM1BspPtr) -= m * here->HSM1_gigislsd; - *(here->HSM1BbPtr) -= m * here->HSM1_gigislbd; - - line1000: - ; - - } /* End of MOSFET Instance */ - } /* End of Model Instance */ - return(OK); -} diff --git a/src/spicelib/devices/hisim/hsm1mask.c b/src/spicelib/devices/hisim/hsm1mask.c deleted file mode 100644 index 86487584e..000000000 --- a/src/spicelib/devices/hisim/hsm1mask.c +++ /dev/null @@ -1,393 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1mask.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "ifsim.h" -#include "cktdefs.h" -#include "devdefs.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1mAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value) -{ - HSM1model *model = (HSM1model *)inst; - - NG_IGNORE(ckt); - - switch (which) { - case HSM1_MOD_NMOS: - value->iValue = model->HSM1_type; - return(OK); - case HSM1_MOD_PMOS: - value->iValue = model->HSM1_type; - return(OK); - case HSM1_MOD_LEVEL: - value->iValue = model->HSM1_level; - return(OK); - case HSM1_MOD_INFO: - value->iValue = model->HSM1_info; - return(OK); - case HSM1_MOD_NOISE: - value->iValue = model->HSM1_noise; - return(OK); - case HSM1_MOD_VERSION: - value->iValue = model->HSM1_version; - return(OK); - case HSM1_MOD_SHOW: - value->iValue = model->HSM1_show; - return(OK); - case HSM1_MOD_CORSRD: - value->iValue = model->HSM1_corsrd; - return(OK); - case HSM1_MOD_COIPRV: - value->iValue = model->HSM1_coiprv; - return(OK); - case HSM1_MOD_COPPRV: - value->iValue = model->HSM1_copprv; - return(OK); - case HSM1_MOD_COCGSO: - value->iValue = model->HSM1_cocgso; - return(OK); - case HSM1_MOD_COCGDO: - value->iValue = model->HSM1_cocgdo; - return(OK); - case HSM1_MOD_COCGBO: - value->rValue = model->HSM1_cocgbo; - return(OK); - case HSM1_MOD_COADOV: - value->iValue = model->HSM1_coadov; - return(OK); - case HSM1_MOD_COXX08: - value->iValue = model->HSM1_coxx08; - return(OK); - case HSM1_MOD_COXX09: - value->iValue = model->HSM1_coxx09; - return(OK); - case HSM1_MOD_COISUB: - value->iValue = model->HSM1_coisub; - return(OK); - case HSM1_MOD_COIIGS: - value->iValue = model->HSM1_coiigs; - return(OK); - case HSM1_MOD_COGIDL: - value->iValue = model->HSM1_cogidl; - return(OK); - case HSM1_MOD_COGISL: - value->iValue = model->HSM1_cogisl; - return(OK); - case HSM1_MOD_COOVLP: - value->iValue = model->HSM1_coovlp; - return(OK); - case HSM1_MOD_CONOIS: - value->iValue = model->HSM1_conois; - return(OK); - case HSM1_MOD_COISTI: /* HiSIM1.1 */ - value->iValue = model->HSM1_coisti; - return(OK); - case HSM1_MOD_COSMBI: /* HiSIM1.2 */ - value->iValue = model->HSM1_cosmbi; - return(OK); - case HSM1_MOD_VMAX: - value->rValue = model->HSM1_vmax; - return(OK); - case HSM1_MOD_BGTMP1: - value->rValue = model->HSM1_bgtmp1; - return(OK); - case HSM1_MOD_BGTMP2: - value->rValue = model->HSM1_bgtmp2; - return(OK); - case HSM1_MOD_TOX: - value->rValue = model->HSM1_tox; - return(OK); - case HSM1_MOD_XLD: - value->rValue = model->HSM1_xld; - return(OK); - case HSM1_MOD_XWD: - value->rValue = model->HSM1_xwd; - return(OK); - case HSM1_MOD_XJ: /* HiSIM1.0 */ - value->rValue = model->HSM1_xj; - return(OK); - case HSM1_MOD_XQY: /* HiSIM1.1 */ - value->rValue = model->HSM1_xqy; - return(OK); - case HSM1_MOD_RS: - value->rValue = model->HSM1_rs; - return(OK); - case HSM1_MOD_RD: - value->rValue = model->HSM1_rd; - return(OK); - case HSM1_MOD_VFBC: - value->rValue = model->HSM1_vfbc; - return(OK); - case HSM1_MOD_NSUBC: - value->rValue = model->HSM1_nsubc; - return(OK); - case HSM1_MOD_PARL1: - value->rValue = model->HSM1_parl1; - return(OK); - case HSM1_MOD_PARL2: - value->rValue = model->HSM1_parl2; - return(OK); - case HSM1_MOD_LP: - value->rValue = model->HSM1_lp; - return(OK); - case HSM1_MOD_NSUBP: - value->rValue = model->HSM1_nsubp; - return(OK); - case HSM1_MOD_SCP1: - value->rValue = model->HSM1_scp1; - return(OK); - case HSM1_MOD_SCP2: - value->rValue = model->HSM1_scp2; - return(OK); - case HSM1_MOD_SCP3: - value->rValue = model->HSM1_scp3; - return(OK); - case HSM1_MOD_SC1: - value->rValue = model->HSM1_sc1; - return(OK); - case HSM1_MOD_SC2: - value->rValue = model->HSM1_sc2; - return(OK); - case HSM1_MOD_SC3: - value->rValue = model->HSM1_sc3; - return(OK); - case HSM1_MOD_PGD1: - value->rValue = model->HSM1_pgd1; - return(OK); - case HSM1_MOD_PGD2: - value->rValue = model->HSM1_pgd2; - return(OK); - case HSM1_MOD_PGD3: - value->rValue = model->HSM1_pgd3; - return(OK); - case HSM1_MOD_NDEP: - value->rValue = model->HSM1_ndep; - return(OK); - case HSM1_MOD_NINV: - value->rValue = model->HSM1_ninv; - return(OK); - case HSM1_MOD_NINVD: - value->rValue = model->HSM1_ninvd; - return(OK); - case HSM1_MOD_MUECB0: - value->rValue = model->HSM1_muecb0; - return(OK); - case HSM1_MOD_MUECB1: - value->rValue = model->HSM1_muecb1; - return(OK); - case HSM1_MOD_MUEPH1: - value->rValue = model->HSM1_mueph1; - return(OK); - case HSM1_MOD_MUEPH0: - value->rValue = model->HSM1_mueph0; - return(OK); - case HSM1_MOD_MUEPH2: - value->rValue = model->HSM1_mueph2; - return(OK); - case HSM1_MOD_W0: - value->rValue = model->HSM1_w0; - return(OK); - case HSM1_MOD_MUESR1: - value->rValue = model->HSM1_muesr1; - return(OK); - case HSM1_MOD_MUESR0: - value->rValue = model->HSM1_muesr0; - return(OK); - case HSM1_MOD_BB: - value->rValue = model->HSM1_bb; - return(OK); - case HSM1_MOD_SUB1: - value->rValue = model->HSM1_sub1; - return(OK); - case HSM1_MOD_SUB2: - value->rValue = model->HSM1_sub2; - return(OK); - case HSM1_MOD_SUB3: - value->rValue = model->HSM1_sub3; - return(OK); - case HSM1_MOD_WVTHSC: /* HiSIM1.1 */ - value->rValue = model->HSM1_wvthsc; - return(OK); - case HSM1_MOD_NSTI: /* HiSIM1.1 */ - value->rValue = model->HSM1_nsti; - return(OK); - case HSM1_MOD_WSTI: /* HiSIM1.1 */ - value->rValue = model->HSM1_wsti; - return(OK); - case HSM1_MOD_CGSO: - value->rValue = model->HSM1_cgso; - return(OK); - case HSM1_MOD_CGDO: - value->rValue = model->HSM1_cgdo; - return(OK); - case HSM1_MOD_CGBO: - value->rValue = model->HSM1_cgbo; - return(OK); - case HSM1_MOD_TPOLY: - value->rValue = model->HSM1_tpoly; - return(OK); - case HSM1_MOD_JS0: - value->rValue = model->HSM1_js0; - return(OK); - case HSM1_MOD_JS0SW: - value->rValue = model->HSM1_js0sw; - return(OK); - case HSM1_MOD_NJ: - value->rValue = model->HSM1_nj; - return(OK); - case HSM1_MOD_NJSW: - value->rValue = model->HSM1_njsw; - return(OK); - case HSM1_MOD_XTI: - value->rValue = model->HSM1_xti; - return(OK); - case HSM1_MOD_CJ: - value->rValue = model->HSM1_cj; - return(OK); - case HSM1_MOD_CJSW: - value->rValue = model->HSM1_cjsw; - return(OK); - case HSM1_MOD_CJSWG: - value->rValue = model->HSM1_cjswg; - return(OK); - case HSM1_MOD_MJ: - value->rValue = model->HSM1_mj; - return(OK); - case HSM1_MOD_MJSW: - value->rValue = model->HSM1_mjsw; - return(OK); - case HSM1_MOD_MJSWG: - value->rValue = model->HSM1_mjswg; - return(OK); - case HSM1_MOD_PB: - value->rValue = model->HSM1_pbsw; - return(OK); - case HSM1_MOD_PBSW: - value->rValue = model->HSM1_pbsw; - return(OK); - case HSM1_MOD_PBSWG: - value->rValue = model->HSM1_pbswg; - return(OK); - case HSM1_MOD_XPOLYD: - value->rValue = model->HSM1_xpolyd; - return(OK); - case HSM1_MOD_CLM1: - value->rValue = model->HSM1_clm1; - return(OK); - case HSM1_MOD_CLM2: - value->rValue = model->HSM1_clm2; - return(OK); - case HSM1_MOD_CLM3: - value->rValue = model->HSM1_clm3; - return(OK); - case HSM1_MOD_MUETMP: - value->rValue = model->HSM1_muetmp; - return(OK); - case HSM1_MOD_RPOCK1: - value->rValue = model->HSM1_rpock1; - return(OK); - case HSM1_MOD_RPOCK2: - value->rValue = model->HSM1_rpock2; - return(OK); - case HSM1_MOD_RPOCP1: /* HiSIM1.1 */ - value->rValue = model->HSM1_rpocp1; - return(OK); - case HSM1_MOD_RPOCP2: /* HiSIM1.1 */ - value->rValue = model->HSM1_rpocp2; - return(OK); - case HSM1_MOD_VOVER: - value->rValue = model->HSM1_vover; - return(OK); - case HSM1_MOD_VOVERP: - value->rValue = model->HSM1_voverp; - return(OK); - case HSM1_MOD_WFC: - value->rValue = model->HSM1_wfc; - return(OK); - case HSM1_MOD_QME1: - value->rValue = model->HSM1_qme1; - return(OK); - case HSM1_MOD_QME2: - value->rValue = model->HSM1_qme2; - return(OK); - case HSM1_MOD_QME3: - value->rValue = model->HSM1_qme3; - return(OK); - case HSM1_MOD_GIDL1: - value->rValue = model->HSM1_gidl1; - return(OK); - case HSM1_MOD_GIDL2: - value->rValue = model->HSM1_gidl2; - return(OK); - case HSM1_MOD_GIDL3: - value->rValue = model->HSM1_gidl3; - return(OK); - case HSM1_MOD_GLEAK1: - value->rValue = model->HSM1_gleak1; - return(OK); - case HSM1_MOD_GLEAK2: - value->rValue = model->HSM1_gleak2; - return(OK); - case HSM1_MOD_GLEAK3: - value->rValue = model->HSM1_gleak3; - return(OK); - case HSM1_MOD_VZADD0: - value->rValue = model->HSM1_vzadd0; - return(OK); - case HSM1_MOD_PZADD0: - value->rValue = model->HSM1_pzadd0; - return(OK); - case HSM1_MOD_NFTRP: - value->rValue = model->HSM1_nftrp; - return(OK); - case HSM1_MOD_NFALP: - value->rValue = model->HSM1_nfalp; - return(OK); - case HSM1_MOD_CIT: - value->rValue = model->HSM1_cit; - return(OK); - case HSM1_MOD_GLPART1: /* HiSIM1.2 */ - value->rValue = model->HSM1_glpart1; - return(OK); - case HSM1_MOD_GLPART2: /* HiSIM1.2 */ - value->rValue = model->HSM1_glpart2; - return(OK); - case HSM1_MOD_KAPPA: /* HiSIM1.2 */ - value->rValue = model->HSM1_kappa; - return(OK); - case HSM1_MOD_XDIFFD: /* HiSIM1.2 */ - value->rValue = model->HSM1_xdiffd; - return(OK); - case HSM1_MOD_PTHROU: /* HiSIM1.2 */ - value->rValue = model->HSM1_pthrou; - return(OK); - case HSM1_MOD_VDIFFJ: /* HiSIM1.2 */ - value->rValue = model->HSM1_vdiffj; - return(OK); - case HSM1_MOD_KF: - value->rValue = model->HSM1_kf; - return(OK); - case HSM1_MOD_AF: - value->rValue = model->HSM1_af; - return(OK); - case HSM1_MOD_EF: - value->rValue = model->HSM1_ef; - return(OK); - default: - return(E_BADPARM); - } - /* NOTREACHED */ -} - - diff --git a/src/spicelib/devices/hisim/hsm1mdel.c b/src/spicelib/devices/hisim/hsm1mdel.c deleted file mode 100644 index 8746474f7..000000000 --- a/src/spicelib/devices/hisim/hsm1mdel.c +++ /dev/null @@ -1,44 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1mdel.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1mDelete(GENmodel **inModel, IFuid modname, GENmodel *kill) -{ - HSM1model **model = (HSM1model**)inModel; - HSM1model *modfast = (HSM1model*)kill; - HSM1instance *here; - HSM1instance *prev = NULL; - HSM1model **oldmod; - - oldmod = model; - for ( ;*model ;model = &((*model)->HSM1nextModel) ) { - if ( (*model)->HSM1modName == modname || - (modfast && *model == modfast) ) goto delgot; - oldmod = model; - } - return(E_NOMOD); - - delgot: - *oldmod = (*model)->HSM1nextModel; /* cut deleted device out of list */ - for ( here = (*model)->HSM1instances ; - here ;here = here->HSM1nextInstance ) { - if (prev) FREE(prev); - prev = here; - } - if (prev) FREE(prev); - FREE(*model); - return(OK); -} - diff --git a/src/spicelib/devices/hisim/hsm1mpar.c b/src/spicelib/devices/hisim/hsm1mpar.c deleted file mode 100644 index b536a4672..000000000 --- a/src/spicelib/devices/hisim/hsm1mpar.c +++ /dev/null @@ -1,511 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1mpar.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "hsm1def.h" -#include "ifsim.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1mParam(int param, IFvalue *value, GENmodel *inMod) -{ - HSM1model *mod = (HSM1model*)inMod; - switch (param) { - case HSM1_MOD_NMOS : - if (value->iValue) { - mod->HSM1_type = 1; - mod->HSM1_type_Given = TRUE; - } - break; - case HSM1_MOD_PMOS : - if (value->iValue) { - mod->HSM1_type = - 1; - mod->HSM1_type_Given = TRUE; - } - break; - case HSM1_MOD_LEVEL: - mod->HSM1_level = value->iValue; - mod->HSM1_level_Given = TRUE; - break; - case HSM1_MOD_INFO: - mod->HSM1_info = value->iValue; - mod->HSM1_info_Given = TRUE; - break; - case HSM1_MOD_NOISE: - mod->HSM1_noise = value->iValue; - mod->HSM1_noise_Given = TRUE; - break; - case HSM1_MOD_VERSION: - mod->HSM1_version = value->iValue; - mod->HSM1_version_Given = TRUE; - break; - case HSM1_MOD_SHOW: - mod->HSM1_show = value->iValue; - mod->HSM1_show_Given = TRUE; - break; - case HSM1_MOD_CORSRD: - mod->HSM1_corsrd = value->iValue; - mod->HSM1_corsrd_Given = TRUE; - break; - case HSM1_MOD_COIPRV: - mod->HSM1_coiprv = value->iValue; - mod->HSM1_coiprv_Given = TRUE; - break; - case HSM1_MOD_COPPRV: - mod->HSM1_copprv = value->iValue; - mod->HSM1_copprv_Given = TRUE; - break; - case HSM1_MOD_COCGSO: - mod->HSM1_cocgso = value->iValue; - mod->HSM1_cocgso_Given = TRUE; - break; - case HSM1_MOD_COCGDO: - mod->HSM1_cocgdo = value->iValue; - mod->HSM1_cocgdo_Given = TRUE; - break; - case HSM1_MOD_COCGBO: - mod->HSM1_cocgbo = value->iValue; - mod->HSM1_cocgbo_Given = TRUE; - break; - case HSM1_MOD_COADOV: - mod->HSM1_coadov = value->iValue; - mod->HSM1_coadov_Given = TRUE; - break; - case HSM1_MOD_COXX08: - mod->HSM1_coxx08 = value->iValue; - mod->HSM1_coxx08_Given = TRUE; - break; - case HSM1_MOD_COXX09: - mod->HSM1_coxx09 = value->iValue; - mod->HSM1_coxx09_Given = TRUE; - break; - case HSM1_MOD_COISUB: - mod->HSM1_coisub = value->iValue; - mod->HSM1_coisub_Given = TRUE; - break; - case HSM1_MOD_COIIGS: - mod->HSM1_coiigs = value->iValue; - mod->HSM1_coiigs_Given = TRUE; - break; - case HSM1_MOD_COGIDL: - mod->HSM1_cogidl = value->iValue; - mod->HSM1_cogidl_Given = TRUE; - break; - case HSM1_MOD_COGISL: - mod->HSM1_cogisl = value->iValue; - mod->HSM1_cogisl_Given = TRUE; - break; - case HSM1_MOD_COOVLP: - mod->HSM1_coovlp = value->iValue; - mod->HSM1_coovlp_Given = TRUE; - break; - case HSM1_MOD_CONOIS: - mod->HSM1_conois = value->iValue; - mod->HSM1_conois_Given = TRUE; - break; - case HSM1_MOD_COISTI: /* HiSIM1.1 */ - mod->HSM1_coisti = value->iValue; - mod->HSM1_coisti_Given = TRUE; - break; - case HSM1_MOD_COSMBI: /* HiSIM1.2 */ - mod->HSM1_cosmbi = value->iValue; - mod->HSM1_cosmbi_Given = TRUE; - break; - case HSM1_MOD_VMAX: - mod->HSM1_vmax = value->rValue; - mod->HSM1_vmax_Given = TRUE; - break; - case HSM1_MOD_BGTMP1: - mod->HSM1_bgtmp1 = value->rValue; - mod->HSM1_bgtmp1_Given = TRUE; - break; - case HSM1_MOD_BGTMP2: - mod->HSM1_bgtmp2 = value->rValue; - mod->HSM1_bgtmp2_Given = TRUE; - break; - case HSM1_MOD_TOX: - mod->HSM1_tox = value->rValue; - mod->HSM1_tox_Given = TRUE; - break; - case HSM1_MOD_XLD: - mod->HSM1_xld = value->rValue; - mod->HSM1_xld_Given = TRUE; - break; - case HSM1_MOD_XWD: - mod->HSM1_xwd = value->rValue; - mod->HSM1_xwd_Given = TRUE; - break; - case HSM1_MOD_XJ: /* HiSIM1.0 */ - mod->HSM1_xj = value->rValue; - mod->HSM1_xj_Given = TRUE; - break; - case HSM1_MOD_XQY: /* HiSIM1.1 */ - mod->HSM1_xqy = value->rValue; - mod->HSM1_xqy_Given = TRUE; - break; - case HSM1_MOD_RS: - mod->HSM1_rs = value->rValue; - mod->HSM1_rs_Given = TRUE; - break; - case HSM1_MOD_RD: - mod->HSM1_rd = value->rValue; - mod->HSM1_rd_Given = TRUE; - break; - case HSM1_MOD_VFBC: - mod->HSM1_vfbc = value->rValue; - mod->HSM1_vfbc_Given = TRUE; - break; - case HSM1_MOD_NSUBC: - mod->HSM1_nsubc = value->rValue; - mod->HSM1_nsubc_Given = TRUE; - break; - case HSM1_MOD_PARL1: - mod->HSM1_parl1 = value->rValue; - mod->HSM1_parl1_Given = TRUE; - break; - case HSM1_MOD_PARL2: - mod->HSM1_parl2 = value->rValue; - mod->HSM1_parl2_Given = TRUE; - break; - case HSM1_MOD_LP: - mod->HSM1_lp = value->rValue; - mod->HSM1_lp_Given = TRUE; - break; - case HSM1_MOD_NSUBP: - mod->HSM1_nsubp = value->rValue; - mod->HSM1_nsubp_Given = TRUE; - break; - case HSM1_MOD_SCP1: - mod->HSM1_scp1 = value->rValue; - mod->HSM1_scp1_Given = TRUE; - break; - case HSM1_MOD_SCP2: - mod->HSM1_scp2 = value->rValue; - mod->HSM1_scp2_Given = TRUE; - break; - case HSM1_MOD_SCP3: - mod->HSM1_scp3 = value->rValue; - mod->HSM1_scp3_Given = TRUE; - break; - case HSM1_MOD_SC1: - mod->HSM1_sc1 = value->rValue; - mod->HSM1_sc1_Given = TRUE; - break; - case HSM1_MOD_SC2: - mod->HSM1_sc2 = value->rValue; - mod->HSM1_sc2_Given = TRUE; - break; - case HSM1_MOD_SC3: - mod->HSM1_sc3 = value->rValue; - mod->HSM1_sc3_Given = TRUE; - break; - case HSM1_MOD_PGD1: - mod->HSM1_pgd1 = value->rValue; - mod->HSM1_pgd1_Given = TRUE; - break; - case HSM1_MOD_PGD2: - mod->HSM1_pgd2 = value->rValue; - mod->HSM1_pgd2_Given = TRUE; - break; - case HSM1_MOD_PGD3: - mod->HSM1_pgd3 = value->rValue; - mod->HSM1_pgd3_Given = TRUE; - break; - case HSM1_MOD_NDEP: - mod->HSM1_ndep = value->rValue; - mod->HSM1_ndep_Given = TRUE; - break; - case HSM1_MOD_NINV: - mod->HSM1_ninv = value->rValue; - mod->HSM1_ninv_Given = TRUE; - break; - case HSM1_MOD_NINVD: - mod->HSM1_ninvd = value->rValue; - mod->HSM1_ninvd_Given = TRUE; - break; - case HSM1_MOD_MUECB0: - mod->HSM1_muecb0 = value->rValue; - mod->HSM1_muecb0_Given = TRUE; - break; - case HSM1_MOD_MUECB1: - mod->HSM1_muecb1 = value->rValue; - mod->HSM1_muecb1_Given = TRUE; - break; - case HSM1_MOD_MUEPH1: - mod->HSM1_mueph1 = value->rValue; - mod->HSM1_mueph1_Given = TRUE; - break; - case HSM1_MOD_MUEPH0: - mod->HSM1_mueph0 = value->rValue; - mod->HSM1_mueph0_Given = TRUE; - break; - case HSM1_MOD_MUEPH2: - mod->HSM1_mueph2 = value->rValue; - mod->HSM1_mueph2_Given = TRUE; - break; - case HSM1_MOD_W0: - mod->HSM1_w0 = value->rValue; - mod->HSM1_w0_Given = TRUE; - break; - case HSM1_MOD_MUESR1: - mod->HSM1_muesr1 = value->rValue; - mod->HSM1_muesr1_Given = TRUE; - break; - case HSM1_MOD_MUESR0: - mod->HSM1_muesr0 = value->rValue; - mod->HSM1_muesr0_Given = TRUE; - break; - case HSM1_MOD_BB: - mod->HSM1_bb = value->rValue; - mod->HSM1_bb_Given = TRUE; - break; - case HSM1_MOD_SUB1: - mod->HSM1_sub1 = value->rValue; - mod->HSM1_sub1_Given = TRUE; - break; - case HSM1_MOD_SUB2: - mod->HSM1_sub2 = value->rValue; - mod->HSM1_sub2_Given = TRUE; - break; - case HSM1_MOD_SUB3: - mod->HSM1_sub3 = value->rValue; - mod->HSM1_sub3_Given = TRUE; - break; - case HSM1_MOD_WVTHSC: /* HiSIM1.1 */ - mod->HSM1_wvthsc = value->rValue; - mod->HSM1_wvthsc_Given = TRUE; - break; - case HSM1_MOD_NSTI: /* HiSIM1.1 */ - mod->HSM1_nsti = value->rValue; - mod->HSM1_nsti_Given = TRUE; - break; - case HSM1_MOD_WSTI: /* HiSIM1.1 */ - mod->HSM1_wsti = value->rValue; - mod->HSM1_wsti_Given = TRUE; - break; - case HSM1_MOD_CGSO: - mod->HSM1_cgso = value->rValue; - mod->HSM1_cgso_Given = TRUE; - break; - case HSM1_MOD_CGDO: - mod->HSM1_cgdo = value->rValue; - mod->HSM1_cgdo_Given = TRUE; - break; - case HSM1_MOD_CGBO: - mod->HSM1_cgbo = value->rValue; - mod->HSM1_cgbo_Given = TRUE; - break; - case HSM1_MOD_TPOLY: - mod->HSM1_tpoly = value->rValue; - mod->HSM1_tpoly_Given = TRUE; - break; - case HSM1_MOD_JS0: - mod->HSM1_js0 = value->rValue; - mod->HSM1_js0_Given = TRUE; - break; - case HSM1_MOD_JS0SW: - mod->HSM1_js0sw = value->rValue; - mod->HSM1_js0sw_Given = TRUE; - break; - case HSM1_MOD_NJ: - mod->HSM1_nj = value->rValue; - mod->HSM1_nj_Given = TRUE; - break; - case HSM1_MOD_NJSW: - mod->HSM1_njsw = value->rValue; - mod->HSM1_njsw_Given = TRUE; - break; - case HSM1_MOD_XTI: - mod->HSM1_xti = value->rValue; - mod->HSM1_xti_Given = TRUE; - break; - case HSM1_MOD_CJ: - mod->HSM1_cj = value->rValue; - mod->HSM1_cj_Given = TRUE; - break; - case HSM1_MOD_CJSW: - mod->HSM1_cjsw = value->rValue; - mod->HSM1_cjsw_Given = TRUE; - break; - case HSM1_MOD_CJSWG: - mod->HSM1_cjswg = value->rValue; - mod->HSM1_cjswg_Given = TRUE; - break; - case HSM1_MOD_MJ: - mod->HSM1_mj = value->rValue; - mod->HSM1_mj_Given = TRUE; - break; - case HSM1_MOD_MJSW: - mod->HSM1_mjsw = value->rValue; - mod->HSM1_mjsw_Given = TRUE; - break; - case HSM1_MOD_MJSWG: - mod->HSM1_mjswg = value->rValue; - mod->HSM1_mjswg_Given = TRUE; - break; - case HSM1_MOD_PB: - mod->HSM1_pb = value->rValue; - mod->HSM1_pb_Given = TRUE; - break; - case HSM1_MOD_PBSW: - mod->HSM1_pbsw = value->rValue; - mod->HSM1_pbsw_Given = TRUE; - break; - case HSM1_MOD_PBSWG: - mod->HSM1_pbswg = value->rValue; - mod->HSM1_pbswg_Given = TRUE; - break; - case HSM1_MOD_XPOLYD: - mod->HSM1_xpolyd = value->rValue; - mod->HSM1_xpolyd_Given = TRUE; - break; - case HSM1_MOD_CLM1: - mod->HSM1_clm1 = value->rValue; - mod->HSM1_clm1_Given = TRUE; - break; - case HSM1_MOD_CLM2: - mod->HSM1_clm2 = value->rValue; - mod->HSM1_clm2_Given = TRUE; - break; - case HSM1_MOD_CLM3: - mod->HSM1_clm3 = value->rValue; - mod->HSM1_clm3_Given = TRUE; - break; - case HSM1_MOD_MUETMP: - mod->HSM1_muetmp = value->rValue; - mod->HSM1_muetmp_Given = TRUE; - break; - case HSM1_MOD_RPOCK1: - mod->HSM1_rpock1 = value->rValue; - mod->HSM1_rpock1_Given = TRUE; - break; - case HSM1_MOD_RPOCK2: - mod->HSM1_rpock2 = value->rValue; - mod->HSM1_rpock2_Given = TRUE; - break; - case HSM1_MOD_RPOCP1: /* HiSIM1.1 */ - mod->HSM1_rpocp1 = value->rValue; - mod->HSM1_rpocp1_Given = TRUE; - break; - case HSM1_MOD_RPOCP2: /* HiSIM1.1 */ - mod->HSM1_rpocp2 = value->rValue; - mod->HSM1_rpocp2_Given = TRUE; - break; - case HSM1_MOD_VOVER: - mod->HSM1_vover = value->rValue; - mod->HSM1_vover_Given = TRUE; - break; - case HSM1_MOD_VOVERP: - mod->HSM1_voverp = value->rValue; - mod->HSM1_voverp_Given = TRUE; - break; - case HSM1_MOD_WFC: - mod->HSM1_wfc = value->rValue; - mod->HSM1_wfc_Given = TRUE; - break; - case HSM1_MOD_QME1: - mod->HSM1_qme1 = value->rValue; - mod->HSM1_qme1_Given = TRUE; - break; - case HSM1_MOD_QME2: - mod->HSM1_qme2 = value->rValue; - mod->HSM1_qme2_Given = TRUE; - break; - case HSM1_MOD_QME3: - mod->HSM1_qme3 = value->rValue; - mod->HSM1_qme3_Given = TRUE; - break; - case HSM1_MOD_GIDL1: - mod->HSM1_gidl1 = value->rValue; - mod->HSM1_gidl1_Given = TRUE; - break; - case HSM1_MOD_GIDL2: - mod->HSM1_gidl2 = value->rValue; - mod->HSM1_gidl2_Given = TRUE; - break; - case HSM1_MOD_GIDL3: - mod->HSM1_gidl3 = value->rValue; - mod->HSM1_gidl3_Given = TRUE; - break; - case HSM1_MOD_GLEAK1: - mod->HSM1_gleak1 = value->rValue; - mod->HSM1_gleak1_Given = TRUE; - break; - case HSM1_MOD_GLEAK2: - mod->HSM1_gleak2 = value->rValue; - mod->HSM1_gleak2_Given = TRUE; - break; - case HSM1_MOD_GLEAK3: - mod->HSM1_gleak3 = value->rValue; - mod->HSM1_gleak3_Given = TRUE; - break; - case HSM1_MOD_VZADD0: - mod->HSM1_vzadd0 = value->rValue; - mod->HSM1_vzadd0_Given = TRUE; - break; - case HSM1_MOD_PZADD0: - mod->HSM1_pzadd0 = value->rValue; - mod->HSM1_pzadd0_Given = TRUE; - break; - case HSM1_MOD_NFTRP: - mod->HSM1_nftrp = value->rValue; - mod->HSM1_nftrp_Given = TRUE; - break; - case HSM1_MOD_NFALP: - mod->HSM1_nfalp = value->rValue; - mod->HSM1_nfalp_Given = TRUE; - break; - case HSM1_MOD_CIT: - mod->HSM1_cit = value->rValue; - mod->HSM1_cit_Given = TRUE; - break; - case HSM1_MOD_GLPART1: /* HiSIM1.2 */ - mod->HSM1_glpart1 = value->rValue; - mod->HSM1_glpart1_Given = TRUE; - break; - case HSM1_MOD_GLPART2: /* HiSIM1.2 */ - mod->HSM1_glpart2 = value->rValue; - mod->HSM1_glpart2_Given = TRUE; - break; - case HSM1_MOD_KAPPA: /* HiSIM1.2 */ - mod->HSM1_kappa = value->rValue; - mod->HSM1_kappa_Given = TRUE; - break; - case HSM1_MOD_XDIFFD: /* HiSIM1.2 */ - mod->HSM1_xdiffd = value->rValue; - mod->HSM1_xdiffd_Given = TRUE; - break; - case HSM1_MOD_PTHROU: /* HiSIM1.2 */ - mod->HSM1_pthrou = value->rValue; - mod->HSM1_pthrou_Given = TRUE; - break; - case HSM1_MOD_VDIFFJ: /* HiSIM1.2 */ - mod->HSM1_vdiffj = value->rValue; - mod->HSM1_vdiffj_Given = TRUE; - break; - case HSM1_MOD_KF: - mod->HSM1_kf = value->rValue; - mod->HSM1_kf_Given = TRUE; - break; - case HSM1_MOD_AF: - mod->HSM1_af = value->rValue; - mod->HSM1_af_Given = TRUE; - break; - case HSM1_MOD_EF: - mod->HSM1_ef = value->rValue; - mod->HSM1_ef_Given = TRUE; - break; - default: - return(E_BADPARM); - } - return(OK); -} - diff --git a/src/spicelib/devices/hisim/hsm1noi.c b/src/spicelib/devices/hisim/hsm1noi.c deleted file mode 100644 index 7df0ef78f..000000000 --- a/src/spicelib/devices/hisim/hsm1noi.c +++ /dev/null @@ -1,273 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1noi.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "hsm1def.h" -#include "cktdefs.h" -#include "iferrmsg.h" -#include "noisedef.h" -#include "suffix.h" -#include "const.h" /* jwan */ - -/* - * HSM1noise (mode, operation, firstModel, ckt, data, OnDens) - * This routine names and evaluates all of the noise sources - * associated with MOSFET's. It starts with the model *firstModel and - * traverses all of its insts. It then proceeds to any other models - * on the linked list. The total output noise density generated by - * all of the MOSFET's is summed with the variable "OnDens". - */ - -/* - Channel thermal and flicker noises are calculated based on the value - of model->HSM1_noise. - If model->HSM1_noise = 1, - Channel thermal noise = SPICE2 model - Flicker noise = SPICE2 model - If model->HSM1_noise = 2, - Channel thermal noise = HiSIM1 model corresponding to BSIM3 model - Flicker noise = HiSIM1 model - If model->HSM1_noise = 3, - Channel thermal noise = SPICE2 model - Flicker noise = HiSIM1 model - If model->HSM1_noise = 4, - Channel thermal noise = HiSIM1 model corresponding to BSIM3 model - Flicker noise = SPICE2 model - If model->HSM1_noise = 5, - Channel thermal noise = NONE - Flicker noise = HiSIM1 model - */ - - -int -HSM1noise (int mode, int operation, GENmodel *inModel, CKTcircuit *ckt, - register Ndata *data, double *OnDens) -{ - register HSM1model *model = (HSM1model *)inModel; - register HSM1instance *here; - char name[N_MXVLNTH]; - double tempOnoise; - double tempInoise; - double noizDens[HSM1NSRCS]; - double lnNdens[HSM1NSRCS]; - register int i; - - /* define the names of the noise sources */ - static char * HSM1nNames[HSM1NSRCS] = { - /* Note that we have to keep the order - consistent with the index definitions - in hsm1defs.h */ - ".rd", /* noise due to rd */ - ".rs", /* noise due to rs */ - ".id", /* noise due to id */ - ".1ovf", /* flicker (1/f) noise */ - "" /* total transistor noise */ - }; - - for ( ;model != NULL; model = model->HSM1nextModel ) { - for ( here = model->HSM1instances; here != NULL; - here = here->HSM1nextInstance ) { - - if (here->HSM1owner != ARCHme) - continue; - - - 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 < HSM1NSRCS; i++ ) { - (void) sprintf(name, "onoise.%s%s", - (char *)here->HSM1name, HSM1nNames[i]); - data->namelist = - TREALLOC(IFuid, data->namelist, data->numPlots + 1); - if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, NULL); - } - break; - case INT_NOIZ: - for ( i = 0; i < HSM1NSRCS; i++ ) { - (void) sprintf(name, "onoise_total.%s%s", - (char *)here->HSM1name, HSM1nNames[i]); - data->namelist = - TREALLOC(IFuid, data->namelist, data->numPlots + 1); - if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, NULL); - - (void) sprintf(name, "inoise_total.%s%s", - (char *)here->HSM1name, HSM1nNames[i]); - data->namelist = - TREALLOC(IFuid, data->namelist, data->numPlots + 1); - if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, NULL); - } - break; - } - } - break; - case N_CALC: - switch (mode) { - case N_DENS: - NevalSrc(&noizDens[HSM1RDNOIZ], &lnNdens[HSM1RDNOIZ], - ckt, THERMNOISE, - here->HSM1dNodePrime, here->HSM1dNode, - here->HSM1drainConductance * here->HSM1_m); - - NevalSrc(&noizDens[HSM1RSNOIZ], &lnNdens[HSM1RSNOIZ], - ckt, THERMNOISE, - here->HSM1sNodePrime, here->HSM1sNode, - here->HSM1sourceConductance * here->HSM1_m); - - switch( model->HSM1_noise ) { - double I; - case 1: - case 3: - I = here->HSM1_gm + here->HSM1_gds + here->HSM1_gmbs; - I *= (I < 0.0) ? -1.0 : 1.0; - I *= 2.0/3.0; - I *= here->HSM1_m; /* PN */ - NevalSrc(&noizDens[HSM1IDNOIZ], &lnNdens[HSM1IDNOIZ], - ckt, THERMNOISE, - here->HSM1dNodePrime, here->HSM1sNodePrime, I); - break; - case 2: - case 4: - I = -1.0 * (here->HSM1_qg + here->HSM1_qb) - / (here->HSM1_weff * here->HSM1_leff); - I *= (I < 0.0) ? -1.0 : 1.0; - I *= here->HSM1_mu; - I *= here->HSM1_m; /* PN */ - NevalSrc(&noizDens[HSM1IDNOIZ], &lnNdens[HSM1IDNOIZ], - ckt, THERMNOISE, - here->HSM1dNodePrime, here->HSM1sNodePrime, I); - break; - case 5: - NevalSrc(&noizDens[HSM1IDNOIZ], &lnNdens[HSM1IDNOIZ], - ckt, THERMNOISE, - here->HSM1dNodePrime, here->HSM1sNodePrime, 0.0); - break; - } - NevalSrc(&noizDens[HSM1FLNOIZ], NULL, - ckt, N_GAIN, - here->HSM1dNodePrime, here->HSM1sNodePrime, - (double) 0.0); - - /* flicker noise */ - switch ( model->HSM1_noise ) { - case 1: - case 4: /* SPICE2 model */ - noizDens[HSM1FLNOIZ] *= here->HSM1_m * model->HSM1_kf - * exp(model->HSM1_af * log(MAX(fabs(here->HSM1_ids), N_MINLOG))) - / (pow(data->freq, model->HSM1_ef) * here->HSM1_leff - * here->HSM1_leff * (3.453133e-11 / model->HSM1_tox)); - /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cox */ - break; - case 2: - case 3: - case 5: - /* from HiSIM */ - noizDens[HSM1FLNOIZ] *= here->HSM1_nfc / data->freq; - break; - } - - lnNdens[HSM1FLNOIZ] = log(MAX(noizDens[HSM1FLNOIZ], N_MINLOG)); - - noizDens[HSM1TOTNOIZ] = noizDens[HSM1RDNOIZ] + noizDens[HSM1RSNOIZ] - + noizDens[HSM1IDNOIZ] + noizDens[HSM1FLNOIZ]; - lnNdens[HSM1TOTNOIZ] = log(MAX(noizDens[HSM1TOTNOIZ], N_MINLOG)); - - *OnDens += noizDens[HSM1TOTNOIZ]; - - if ( data->delFreq == 0.0 ) { - /* if we haven't done any previous - integration, we need to initialize our - "history" variables. - */ - - for ( i = 0; i < HSM1NSRCS; i++ ) - here->HSM1nVar[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 < HSM1NSRCS; i++) { - here->HSM1nVar[OUTNOIZ][i] = 0.0; - here->HSM1nVar[INNOIZ][i] = 0.0; - } - } - } - else { - /* data->delFreq != 0.0, - we have to integrate. - */ - for ( i = 0; i < HSM1NSRCS; i++ ) { - if ( i != HSM1TOTNOIZ ) { - tempOnoise = - Nintegrate(noizDens[i], lnNdens[i], - here->HSM1nVar[LNLSTDENS][i], data); - tempInoise = - Nintegrate(noizDens[i] * data->GainSqInv, - lnNdens[i] + data->lnGainInv, - here->HSM1nVar[LNLSTDENS][i] + data->lnGainInv, - data); - here->HSM1nVar[LNLSTDENS][i] = lnNdens[i]; - data->outNoiz += tempOnoise; - data->inNoise += tempInoise; - if ( ((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0 ) { - here->HSM1nVar[OUTNOIZ][i] += tempOnoise; - here->HSM1nVar[OUTNOIZ][HSM1TOTNOIZ] += tempOnoise; - here->HSM1nVar[INNOIZ][i] += tempInoise; - here->HSM1nVar[INNOIZ][HSM1TOTNOIZ] += tempInoise; - } - } - } - } - if ( data->prtSummary ) { - for (i = 0; i < HSM1NSRCS; 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 < HSM1NSRCS; i++ ) { - data->outpVector[data->outNumber++] = here->HSM1nVar[OUTNOIZ][i]; - data->outpVector[data->outNumber++] = here->HSM1nVar[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/hisim/hsm1par.c b/src/spicelib/devices/hisim/hsm1par.c deleted file mode 100644 index ab3907e08..000000000 --- a/src/spicelib/devices/hisim/hsm1par.c +++ /dev/null @@ -1,104 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1par.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "ifsim.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1param(int param, IFvalue *value, GENinstance *inst, IFvalue *select) -{ - HSM1instance *here = (HSM1instance*)inst; - - NG_IGNORE(select); - - switch (param) { - case HSM1_W: - here->HSM1_w = value->rValue; - here->HSM1_w_Given = TRUE; - break; - case HSM1_L: - here->HSM1_l = value->rValue; - here->HSM1_l_Given = TRUE; - break; - case HSM1_M: - here->HSM1_m = value->rValue; - here->HSM1_m_Given = TRUE; - break; - case HSM1_AS: - here->HSM1_as = value->rValue; - here->HSM1_as_Given = TRUE; - break; - case HSM1_AD: - here->HSM1_ad = value->rValue; - here->HSM1_ad_Given = TRUE; - break; - case HSM1_PS: - here->HSM1_ps = value->rValue; - here->HSM1_ps_Given = TRUE; - break; - case HSM1_PD: - here->HSM1_pd = value->rValue; - here->HSM1_pd_Given = TRUE; - break; - case HSM1_NRS: - here->HSM1_nrs = value->rValue; - here->HSM1_nrs_Given = TRUE; - break; - case HSM1_NRD: - here->HSM1_nrd = value->rValue; - here->HSM1_nrd_Given = TRUE; - break; - case HSM1_TEMP: - here->HSM1_temp = value->rValue; - here->HSM1_temp_Given = TRUE; - break; - case HSM1_DTEMP: - here->HSM1_dtemp = value->rValue; - here->HSM1_dtemp_Given = TRUE; - break; - case HSM1_OFF: - here->HSM1_off = value->iValue; - break; - case HSM1_IC_VBS: - here->HSM1_icVBS = value->rValue; - here->HSM1_icVBS_Given = TRUE; - break; - case HSM1_IC_VDS: - here->HSM1_icVDS = value->rValue; - here->HSM1_icVDS_Given = TRUE; - break; - case HSM1_IC_VGS: - here->HSM1_icVGS = value->rValue; - here->HSM1_icVGS_Given = TRUE; - break; - case HSM1_IC: - switch (value->v.numValue) { - case 3: - here->HSM1_icVBS = *(value->v.vec.rVec + 2); - here->HSM1_icVBS_Given = TRUE; - case 2: - here->HSM1_icVGS = *(value->v.vec.rVec + 1); - here->HSM1_icVGS_Given = TRUE; - case 1: - here->HSM1_icVDS = *(value->v.vec.rVec); - here->HSM1_icVDS_Given = TRUE; - break; - default: - return(E_BADPARM); - } - break; - default: - return(E_BADPARM); - } - return(OK); -} diff --git a/src/spicelib/devices/hisim/hsm1pzld.c b/src/spicelib/devices/hisim/hsm1pzld.c deleted file mode 100644 index 52a8c4afd..000000000 --- a/src/spicelib/devices/hisim/hsm1pzld.c +++ /dev/null @@ -1,305 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1pzld.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "complex.h" -#include "sperror.h" -#include "hsm1def.h" -#include "suffix.h" - -int -HSM1pzLoad(GENmodel *inModel, register CKTcircuit *ckt, - register SPcomplex *s) -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; - double xcggb, xcgdb, xcgsb, xcgbb, xcbgb, xcbdb, xcbsb, xcbbb; - double xcdgb, xcddb, xcdsb, xcdbb, xcsgb, xcsdb, xcssb, xcsbb; - double gdpr, gspr, gds, gbd, gbs, capbd, capbs, FwdSum, RevSum, gm, gmbs; - double cggb, cgdb, cgsb, cbgb, cbdb, cbsb, cddb, cdgb, cdsb; - double cgso, cgdo, cgbo; - 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 m; /* Multiplier */ - - NG_IGNORE(ckt); - - for ( ;model != NULL ;model = model->HSM1nextModel ) { - for ( here = model->HSM1instances ;here!= NULL ; - here = here->HSM1nextInstance ) { - - if (here->HSM1owner != ARCHme) - continue; - - if ( here->HSM1_mode >= 0 ) { - gm = here->HSM1_gm; - gmbs = here->HSM1_gmbs; - FwdSum = gm + gmbs; - RevSum = 0.0; - - gbbdp = -here->HSM1_gbds; - gbbsp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = here->HSM1_gbgs; - gbdpdp = here->HSM1_gbds; - gbdpb = here->HSM1_gbbs; - gbdpsp = -(gbdpg + gbdpdp + gbdpb); - - gbspg = 0.0; - gbspdp = 0.0; - gbspb = 0.0; - gbspsp = 0.0; - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - - } - else { - gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; - gIstotg = gIstotd = gIstots = gIstotb = 0.0; - gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; - } - - if (model->HSM1_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->HSM1_cggb; - cgsb = here->HSM1_cgsb; - cgdb = here->HSM1_cgdb; - - cbgb = here->HSM1_cbgb; - cbsb = here->HSM1_cbsb; - cbdb = here->HSM1_cbdb; - - cdgb = here->HSM1_cdgb; - cdsb = here->HSM1_cdsb; - cddb = here->HSM1_cddb; - - } - else { - gm = -here->HSM1_gm; - gmbs = -here->HSM1_gmbs; - FwdSum = 0.0; - RevSum = -(gm + gmbs); - - gbbsp = -here->HSM1_gbds; - gbbdp = here->HSM1_gbds + here->HSM1_gbgs + here->HSM1_gbbs; - - gbdpg = 0.0; - gbdpsp = 0.0; - gbdpb = 0.0; - gbdpdp = 0.0; - - if (model->HSM1_coiigs) { - gIbtotg = here->HSM1_gigbg; - gIbtotd = here->HSM1_gigbd; - gIbtots = here->HSM1_gigbs; - gIbtotb = here->HSM1_gigbb; - - gIstotg = here->HSM1_gigsg; - gIstotd = here->HSM1_gigsd; - gIstots = here->HSM1_gigss; - gIstotb = here->HSM1_gigsb; - - gIdtotg = here->HSM1_gigdg; - gIdtotd = here->HSM1_gigdd; - gIdtots = here->HSM1_gigds; - gIdtotb = here->HSM1_gigdb; - } - else { - gIbtotg = gIbtotd = gIbtots = gIbtotb = 0.0; - gIstotg = gIstotd = gIstots = gIstotb = 0.0; - gIdtotg = gIdtotd = gIdtots = gIdtotb = 0.0; - } - - if (model->HSM1_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->HSM1_gbgs; - gbspsp = here->HSM1_gbds; - gbspb = here->HSM1_gbbs; - gbspdp = -(gbspg + gbspsp + gbspb); - - cggb = here->HSM1_cggb; - cgsb = here->HSM1_cgdb; - cgdb = here->HSM1_cgsb; - - cbgb = here->HSM1_cbgb; - cbsb = here->HSM1_cbdb; - cbdb = here->HSM1_cbsb; - - cdgb = -(here->HSM1_cdgb + cggb + cbgb); - cdsb = -(here->HSM1_cddb + cgsb + cbsb); - cddb = -(here->HSM1_cdsb + cgdb + cbdb); - } - - gdpr = here->HSM1drainConductance; - gspr = here->HSM1sourceConductance; - gds = here->HSM1_gds; - gbd = here->HSM1_gbd; - gbs = here->HSM1_gbs; - capbd = here->HSM1_capbd; - capbs = here->HSM1_capbs; - - cgso = here->HSM1_cgso; - cgdo = here->HSM1_cgdo; - cgbo = here->HSM1_cgbo; - - xcdgb = (cdgb - cgdo); - xcddb = (cddb + capbd + cgdo); - xcdsb = cdsb; - xcdbb = -(xcdgb + xcddb + xcdsb); - xcsgb = -(cggb + cbgb + cdgb + cgso); - xcsdb = -(cgdb + cbdb + cddb); - xcssb = (capbs + cgso - (cgsb + cbsb + cdsb)); - xcsbb = -(xcsgb + xcsdb + xcssb); - xcggb = (cggb + cgdo + cgso + cgbo); - xcgdb = (cgdb - cgdo); - xcgsb = (cgsb - cgso); - xcgbb = -(xcggb + xcgdb + xcgsb); - xcbgb = (cbgb - cgbo); - xcbdb = (cbdb - capbd); - xcbsb = (cbsb - capbs); - xcbbb = -(xcbgb + xcbdb + xcbsb); - - m = here->HSM1_m; - - *(here->HSM1GgPtr ) += m * xcggb * s->real; - *(here->HSM1GgPtr +1) += m * xcggb * s->imag; - *(here->HSM1GgPtr) += m * gIgtotg; - *(here->HSM1BbPtr ) += m * xcbbb * s->real; - *(here->HSM1BbPtr +1) += m * xcbbb * s->imag; - *(here->HSM1GbPtr) += m * gIgtotb; - *(here->HSM1DPdpPtr ) += m * xcddb * s->real; - *(here->HSM1DPdpPtr +1) += m * xcddb * s->imag; - *(here->HSM1SPspPtr ) += m * xcssb * s->real; - *(here->HSM1SPspPtr +1) += m * xcssb * s->imag; - - *(here->HSM1GbPtr ) += m * xcgbb * s->real; - *(here->HSM1GbPtr +1) += m * xcgbb * s->imag; - *(here->HSM1GdpPtr ) += m * xcgdb * s->real; - *(here->HSM1GdpPtr +1) += m * xcgdb * s->imag; - *(here->HSM1GdpPtr) += m * gIgtotd; - *(here->HSM1GspPtr ) += m * xcgsb * s->real; - *(here->HSM1GspPtr +1) += m * xcgsb * s->imag; - *(here->HSM1GspPtr) += m * gIgtots; - - *(here->HSM1BgPtr ) += m * xcbgb * s->real; - *(here->HSM1BgPtr +1) += m * xcbgb * s->imag; - *(here->HSM1BdpPtr ) += m * xcbdb * s->real; - *(here->HSM1BdpPtr +1) += m * xcbdb * s->imag; - *(here->HSM1BspPtr ) += m * xcbsb * s->real; - *(here->HSM1BspPtr +1) += m * xcbsb * s->imag; - - *(here->HSM1DPgPtr ) += m * xcdgb * s->real; - *(here->HSM1DPgPtr +1) += m * xcdgb * s->imag; - *(here->HSM1DPbPtr ) += m * xcdbb * s->real; - *(here->HSM1DPbPtr +1) += m * xcdbb * s->imag; - *(here->HSM1DPspPtr ) += m * xcdsb * s->real; - *(here->HSM1DPspPtr +1) += m * xcdsb * s->imag; - - *(here->HSM1SPgPtr ) += m * xcsgb * s->real; - *(here->HSM1SPgPtr +1) += m * xcsgb * s->imag; - *(here->HSM1SPbPtr ) += m * xcsbb * s->real; - *(here->HSM1SPbPtr +1) += m * xcsbb * s->imag; - *(here->HSM1SPdpPtr ) += m * xcsdb * s->real; - *(here->HSM1SPdpPtr +1) += m * xcsdb * s->imag; - - *(here->HSM1DdPtr) += m * gdpr; - *(here->HSM1DdpPtr) -= m * gdpr; - *(here->HSM1DPdPtr) -= m * gdpr; - - *(here->HSM1SsPtr) += m * gspr; - *(here->HSM1SspPtr) -= m * gspr; - *(here->HSM1SPsPtr) -= m * gspr; - - *(here->HSM1BgPtr) -= m * (here->HSM1_gbgs + gIbtotg); - *(here->HSM1BbPtr) += m * (gbd + gbs - here->HSM1_gbbs - gIbtotb); - *(here->HSM1BdpPtr) -= m * (gbd - gbbdp + gIbtotd); - *(here->HSM1BspPtr) -= m * (gbs - gbbsp + gIbtots); - - *(here->HSM1DPgPtr) += m * (gm + gbdpg - gIdtotg); - *(here->HSM1DPdpPtr) += m * (gdpr + gds + gbd + RevSum + gbdpdp - - gIdtotd); - *(here->HSM1DPspPtr) -= m * (gds + FwdSum - gbdpsp + gIdtots); - *(here->HSM1DPbPtr) -= m * (gbd - gmbs - gbdpb + gIdtotb); - - *(here->HSM1SPgPtr) -= m * (gm - gbspg + gIstotg); - *(here->HSM1SPspPtr) += m * (gspr + gds + gbs + FwdSum + gbspsp - - gIstots); - *(here->HSM1SPbPtr) -= m * (gbs + gmbs - gbspb + gIstotb); - *(here->HSM1SPdpPtr) -= m * (gds + RevSum - gbspdp + gIstotd); - - /* stamp gidl */ - *(here->HSM1DPdpPtr) += m * here->HSM1_gigidlds; - *(here->HSM1DPgPtr) += m * here->HSM1_gigidlgs; - *(here->HSM1DPspPtr) -= m * (here->HSM1_gigidlgs + - here->HSM1_gigidlds + here->HSM1_gigidlbs); - *(here->HSM1DPbPtr) += m * here->HSM1_gigidlbs; - *(here->HSM1BdpPtr) -= m * here->HSM1_gigidlds; - *(here->HSM1BgPtr) -= m * here->HSM1_gigidlgs; - *(here->HSM1BspPtr) += m * (here->HSM1_gigidlgs + - here->HSM1_gigidlds + here->HSM1_gigidlbs); - *(here->HSM1BbPtr) -= m * here->HSM1_gigidlbs; - /* stamp gisl */ - *(here->HSM1SPdpPtr) -= m * (here->HSM1_gigislsd + - here->HSM1_gigislgd + here->HSM1_gigislbd); - *(here->HSM1SPgPtr) += m * here->HSM1_gigislgd; - *(here->HSM1SPspPtr) += m * here->HSM1_gigislsd; - *(here->HSM1SPbPtr) += m * here->HSM1_gigislbd; - *(here->HSM1BdpPtr) += m * (here->HSM1_gigislgd + - here->HSM1_gigislsd + here->HSM1_gigislbd); - *(here->HSM1BgPtr) -= m * here->HSM1_gigislgd; - *(here->HSM1BspPtr) -= m * here->HSM1_gigislsd; - *(here->HSM1BbPtr) -= m * here->HSM1_gigislbd; - - /* - *(here->HSM1GgPtr) -= m * xgtg; - *(here->HSM1GbPtr) -= m * xgtb; - *(here->HSM1GdpPtr) -= m * xgtd; - *(here->HSM1GspPtr) -= m * xgts; - */ - - } - } - return(OK); -} - diff --git a/src/spicelib/devices/hisim/hsm1set.c b/src/spicelib/devices/hisim/hsm1set.c deleted file mode 100644 index 040e495a8..000000000 --- a/src/spicelib/devices/hisim/hsm1set.c +++ /dev/null @@ -1,445 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1set.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "smpdefs.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "const.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1setup(register SMPmatrix *matrix, register GENmodel *inModel, - register CKTcircuit *ckt, int *states) - /* load the HSM1 device structure with those pointers needed later - * for fast matrix loading - */ -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; - int error; - CKTnode *tmp; - - CKTnode *tmpNode; - IFuid tmpName; - - /* loop through all the HSM1 device models */ - for ( ;model != NULL ;model = model->HSM1nextModel ) { - /* Default value Processing for HSM1 MOSFET Models */ - if ( !model->HSM1_type_Given ) - model->HSM1_type = NMOS ; - /***/ - if ( !model->HSM1_info_Given ) model->HSM1_info = 0 ; - if ( !model->HSM1_noise_Given) model->HSM1_noise = 5; /* select noise model 5 */ - if ( !model->HSM1_version_Given) { - model->HSM1_version = 120; /* default 120 */ - printf(" 120 is selected for VERSION. (default) \n"); - } - if ( model->HSM1_version == 100 || model->HSM1_version == 101) { - printf("warning(HiSIM1): For the model parameter VERSION, 102 or 112 or 120 is acceptable.\n"); - printf(" 102 is selected for VERSION \n"); - model->HSM1_version = 102 ; - } - else if ( model->HSM1_version == 110 || model->HSM1_version == 111) { - printf("warning(HiSIM1): For the model parameter VERSION, 102 or 112 or 120 is acceptable.\n"); - printf(" 112 is selected for VERSION \n"); - model->HSM1_version = 112 ; - } - else if ( model->HSM1_version != 102 && - model->HSM1_version != 112 && - model->HSM1_version != 120) { - printf("warning(HiSIM1): For the model parameter VERSION, 102 or 112 or 120 is acceptable.\n"); - printf(" 120 is selected for VERSION compulsorily.\n"); - model->HSM1_version = 120 ; - } - else { -/* printf(" %d is selected for VERSION \n", (int)model->HSM1_version); */ - } - - if ( !model->HSM1_corsrd_Given ) model->HSM1_corsrd = 0 ; - if ( !model->HSM1_coiprv_Given ) model->HSM1_coiprv = 1 ; - if ( !model->HSM1_copprv_Given ) model->HSM1_copprv = 1 ; - if ( !model->HSM1_cocgso_Given ) model->HSM1_cocgso = 0 ; - if ( !model->HSM1_cocgdo_Given ) model->HSM1_cocgdo = 0 ; - if ( !model->HSM1_cocgbo_Given ) model->HSM1_cocgbo = 0 ; - if ( !model->HSM1_coadov_Given ) model->HSM1_coadov = 1 ; - if ( !model->HSM1_coxx08_Given ) model->HSM1_coxx08 = 0 ; - if ( !model->HSM1_coxx09_Given ) model->HSM1_coxx09 = 0 ; - if ( !model->HSM1_coisub_Given ) model->HSM1_coisub = 0 ; - if ( !model->HSM1_coiigs_Given ) model->HSM1_coiigs = 0 ; - if ( !model->HSM1_cogidl_Given ) model->HSM1_cogidl = 0 ; - if ( model->HSM1_version == 120 ) {/* HiSIM1.2.0 */ - if ( !model->HSM1_cogisl_Given ) model->HSM1_cogisl = 0 ; - } - if ( !model->HSM1_coovlp_Given ) model->HSM1_coovlp = 0 ; - if ( !model->HSM1_conois_Given ) model->HSM1_conois = 0 ; - if ( model->HSM1_version == 112 || model->HSM1_version == 120) { - /* HiSIM1.1.2 HiSIM1.2.0*/ - if ( !model->HSM1_coisti_Given ) model->HSM1_coisti = 0 ; - } - if ( model->HSM1_version == 120 ) {/* HiSIM1.2.0 */ - if ( !model->HSM1_cosmbi_Given ) model->HSM1_cosmbi = 0 ; - } - else { - if (model->HSM1_cosmbi_Given) - printf ("warning(HiSIM1): COSMBI is only available for VERSION = 120\n"); - if ( model->HSM1_kappa_Given ) - printf ("warning(HiSIM1): KAPPA is only available for VERSION = 120\n"); - if ( model->HSM1_xdiffd_Given ) - printf ("warning(HiSIM1): XDIFFD is only available for VERSION = 120\n"); - if ( model->HSM1_vdiffj_Given ) - printf ("warning(HiSIM1): VDIFFJ is only available for VERSION = 120\n"); - if ( model->HSM1_pthrou_Given ) - printf ("warning(HiSIM1): PTHROU is only available for VERSION = 120\n"); - if ( model->HSM1_glpart1_Given ) - printf ("warning(HiSIM1): GLPART1 is only available for VERSION = 120\n"); - if ( model->HSM1_glpart2_Given ) - printf ("warning(HiSIM1): GLPART2 is only available for VERSION = 120\n"); - - /* - printf (" This parameter is ignored.\n"); - */ - } - - /***/ - if ( !model->HSM1_vmax_Given ) model->HSM1_vmax = 7.00e+6 ; - if ( !model->HSM1_bgtmp1_Given ) model->HSM1_bgtmp1 = 90.25e-6 ; - if ( !model->HSM1_bgtmp2_Given ) model->HSM1_bgtmp2 = 100.0e-9 ; - if ( !model->HSM1_tox_Given ) model->HSM1_tox = 5.0e-9 ; - else if ( model->HSM1_tox < 0 ) { - printf("warning(HiSIM1): The model parameter TOX must be positive.\n"); - } - if ( !model->HSM1_xld_Given ) model->HSM1_xld = 0.0 ; - if ( !model->HSM1_xwd_Given ) model->HSM1_xwd = 0.0 ; - if ( model->HSM1_version == 102 ) { /* HiSIM1.0 */ - if ( !model->HSM1_xj_Given ) model->HSM1_xj = 0.0 ; - else if ( model->HSM1_xj < 0 ) { - printf("warning(HiSIM1): The model parameter XJ must be positive.\n"); - } - if ( model->HSM1_xqy_Given ) { - printf("warning(HiSIM1): XQY is only available for VERSION = 112 or 120\n"); - } - } - else if ( model->HSM1_version == 112 || - model->HSM1_version == 120 ) { /* HiSIM1.1.2 / 1.2.0 */ - if ( !model->HSM1_xqy_Given ) model->HSM1_xqy = 0.0; - else if ( model->HSM1_xqy < 0 ) { - printf("warning(HiSIM1): The model parameter XQY must be positive.\n"); - } - if ( model->HSM1_xj_Given ) { - printf("warning(HiSIM1): XJ is only available for VERSION = 102\n"); - } - } - if ( !model->HSM1_rs_Given ) model->HSM1_rs = 80.0e-6 ; - else if ( model->HSM1_rs < 0 ) { - printf("warning(HiSIM1): The model parameter RS must be positive.\n"); - } - if ( !model->HSM1_rd_Given ) model->HSM1_rd = 80.0e-6 ; - else if ( model->HSM1_rd < 0 ) { - printf("warning(HiSIM1): The model parameter RD must be positive.\n"); - } - if ( !model->HSM1_vfbc_Given ) model->HSM1_vfbc = -1.0 ; - if ( !model->HSM1_nsubc_Given ) model->HSM1_nsubc = 1.0e+17 ; - else if ( model->HSM1_nsubc < 0 ) { - printf("warning(HiSIM1): The model parameter NSUBC must be positive.\n"); - } - if ( model->HSM1_version == 120 ) model->HSM1_parl1 = 1.0 ; - else { - if ( !model->HSM1_parl1_Given ) model->HSM1_parl1 = 1.0 ; - } - if ( !model->HSM1_parl2_Given ) model->HSM1_parl2 = 0.0 ; - if ( !model->HSM1_lp_Given ) model->HSM1_lp = 15.0e-9 ; - if ( !model->HSM1_nsubp_Given ) model->HSM1_nsubp = 1.0e+17 ; - else if ( model->HSM1_nsubp < 0 ) { - printf("warning(HiSIM1): The model parameter NSUBP must be positive.\n"); - } - if ( !model->HSM1_scp1_Given ) model->HSM1_scp1 = 0.0 ; - if ( !model->HSM1_scp2_Given ) model->HSM1_scp2 = 0.0 ; - if ( !model->HSM1_scp3_Given ) model->HSM1_scp3 = 0.0 ; - if ( !model->HSM1_sc1_Given ) model->HSM1_sc1 = 0.0 ; - if ( !model->HSM1_sc2_Given ) model->HSM1_sc2 = 0.0 ; - if ( !model->HSM1_sc3_Given ) model->HSM1_sc3 = 0.0 ; - if ( !model->HSM1_pgd1_Given ) model->HSM1_pgd1 = 10.0e-3 ; - if ( !model->HSM1_pgd2_Given ) model->HSM1_pgd2 = 1.0 ; - if ( !model->HSM1_pgd3_Given ) model->HSM1_pgd3 = 0.8 ; - if ( !model->HSM1_ndep_Given ) model->HSM1_ndep = 1.0 ; - if ( !model->HSM1_ninv_Given ) model->HSM1_ninv = 0.5 ; - if ( !model->HSM1_ninvd_Given ) model->HSM1_ninvd = 1.0e-9 ; - if ( !model->HSM1_muecb0_Given ) model->HSM1_muecb0 = 300.0 ; - if ( !model->HSM1_muecb1_Given ) model->HSM1_muecb1 = 30.0 ; - if ( !model->HSM1_mueph1_Given ) model->HSM1_mueph1 = 25.0e3 ; - if ( !model->HSM1_mueph0_Given ) model->HSM1_mueph0 = 300.0e-3 ; - if ( !model->HSM1_mueph2_Given ) model->HSM1_mueph2 = 0.0 ; - if ( !model->HSM1_w0_Given ) model->HSM1_w0 = 0.0 ; - if ( !model->HSM1_muesr1_Given ) model->HSM1_muesr1 = 2.0e15; - if ( !model->HSM1_muesr0_Given ) model->HSM1_muesr0 = 2.0 ; - if ( !model->HSM1_muetmp_Given ) model->HSM1_muetmp = 1.5 ; - /***/ - if ( !model->HSM1_bb_Given ) { - if (model->HSM1_type == NMOS) model->HSM1_bb = 2.0 ; - else model->HSM1_bb = 1.0 ; - } - /***/ - if ( !model->HSM1_sub1_Given ) model->HSM1_sub1 = 10.0 ; - if ( !model->HSM1_sub2_Given ) model->HSM1_sub2 = 20.0 ; - if ( !model->HSM1_sub3_Given ) model->HSM1_sub3 = 0.8 ; - if ( model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM1.1.2 / 1.2.0 */ - if ( !model->HSM1_wvthsc_Given ) model->HSM1_wvthsc = 0.0 ; - if ( !model->HSM1_nsti_Given ) model->HSM1_nsti = 1.0e17 ; - if ( !model->HSM1_wsti_Given ) model->HSM1_wsti = 0.0 ; - } else { - if ( model->HSM1_wvthsc_Given ) - printf ("warning(HiSIM1): WVTHSC is only available for VERSION = 112 or 120\n"); - if ( model->HSM1_nsti_Given ) - printf ("warning(HiSIM1): NSTI is only available for VERSION = 112 or 120\n"); - if ( model->HSM1_wsti_Given ) - printf ("warning(HiSIM1): WSTI is only available for VERSION = 112 or 120\n"); - } - if ( !model->HSM1_tpoly_Given ) model->HSM1_tpoly = 0.0 ; - if ( !model->HSM1_js0_Given ) model->HSM1_js0 = 1.0e-4 ; - if ( !model->HSM1_js0sw_Given ) model->HSM1_js0sw = 0.0 ; - if ( !model->HSM1_nj_Given ) model->HSM1_nj = 1.0 ; - if ( !model->HSM1_njsw_Given ) model->HSM1_njsw = 1.0 ; - if ( !model->HSM1_xti_Given ) model->HSM1_xti = 3.0 ; - if ( !model->HSM1_cj_Given ) model->HSM1_cj = 5.0e-04 ; - if ( !model->HSM1_cjsw_Given ) model->HSM1_cjsw = 5.0e-10 ; - if ( !model->HSM1_cjswg_Given ) model->HSM1_cjswg = 5.0e-10 ; - if ( !model->HSM1_mj_Given ) model->HSM1_mj = 0.5 ; - if ( !model->HSM1_mjsw_Given ) model->HSM1_mjsw = 0.33 ; - if ( !model->HSM1_mjswg_Given ) model->HSM1_mjswg = 0.33 ; - if ( !model->HSM1_pb_Given ) model->HSM1_pb = 1.0 ; - if ( !model->HSM1_pbsw_Given ) model->HSM1_pbsw = 1.0 ; - if ( !model->HSM1_pbswg_Given ) model->HSM1_pbswg = 1.0 ; - if ( !model->HSM1_xpolyd_Given ) model->HSM1_xpolyd = 0.0 ; - if ( !model->HSM1_clm1_Given ) model->HSM1_clm1 = 700.0e-3 ; - if ( !model->HSM1_clm2_Given ) model->HSM1_clm2 = 2.0 ; - if ( !model->HSM1_clm3_Given ) model->HSM1_clm3 = 1.0 ; - if ( !model->HSM1_rpock1_Given ) { - if ( model->HSM1_version == 102 ) { - model->HSM1_rpock1 = 10.0e-3 ; - } else if ( model->HSM1_version == 112 || model->HSM1_version == 120 ) { - model->HSM1_rpock1 = 0.1e-3 ; - } - } - if ( !model->HSM1_rpock2_Given ) model->HSM1_rpock2 = 100.0e-3 ; - if ( model->HSM1_version == 112 || - model->HSM1_version == 120) { /* HiSIM1.1.2 / 1.2.0 */ - if ( !model->HSM1_rpocp1_Given ) model->HSM1_rpocp1 = 1.0 ; - if ( !model->HSM1_rpocp2_Given ) model->HSM1_rpocp2 = 0.5 ; - } else { - if ( model->HSM1_rpocp1_Given ) - printf ("warning(HiSIM1): RPOCP1 is only available for VERSION = 112 or 120\n"); - if ( model->HSM1_rpocp2_Given ) - printf ("warning(HiSIM1): RPOCP2 is only available for VERSION = 112 or 120\n"); - } - if ( !model->HSM1_vover_Given ) model->HSM1_vover = 10.0e-3 ; - if ( !model->HSM1_voverp_Given ) model->HSM1_voverp = 100.0e-3 ; - if ( !model->HSM1_wfc_Given ) model->HSM1_wfc = 0.0 ; - if ( !model->HSM1_qme1_Given ) model->HSM1_qme1 = 40.0e-12 ; - if ( !model->HSM1_qme2_Given ) model->HSM1_qme2 = 300.0e-12 ; - if ( !model->HSM1_qme3_Given ) model->HSM1_qme3 = 0.0 ; - if ( !model->HSM1_gidl1_Given ) { - if (model->HSM1_version == 101) model->HSM1_gidl1 = 5.0e-3 ; - else if (model->HSM1_version == 112 || - model->HSM1_version == 120) model->HSM1_gidl1 = 5.0e-6 ; - } - if ( !model->HSM1_gidl2_Given ) model->HSM1_gidl2 = 1.0e6 ; - if ( !model->HSM1_gidl3_Given ) model->HSM1_gidl3 = 300.0e-3 ; - if ( !model->HSM1_gleak1_Given ) { - if (model->HSM1_version == 101) model->HSM1_gleak1 = 0.01e6 ; - else if (model->HSM1_version == 112 || - model->HSM1_version == 120) model->HSM1_gleak1 = 10.0e3 ; - } - if ( !model->HSM1_gleak2_Given ) model->HSM1_gleak2 = 20.0e6 ; - if ( !model->HSM1_gleak3_Given ) model->HSM1_gleak3 = 300.0e-3 ; - if ( !model->HSM1_vzadd0_Given ) model->HSM1_vzadd0 = 10.0e-3 ; - if ( !model->HSM1_pzadd0_Given ) model->HSM1_pzadd0 = 5.0e-3 ; - if ( !model->HSM1_nftrp_Given ) model->HSM1_nftrp = 10e9 ; - if ( !model->HSM1_nfalp_Given ) model->HSM1_nfalp = 1.0e-16 ; - if ( !model->HSM1_cit_Given ) model->HSM1_cit = 0.0 ; - if ( model->HSM1_version == 120) { /* HiSIM1.2.0 */ - if ( !model->HSM1_glpart1_Given ) model->HSM1_glpart1 = 1 ; - if ( !model->HSM1_glpart2_Given ) model->HSM1_glpart2 = 0.5 ; - if ( !model->HSM1_kappa_Given ) model->HSM1_kappa = 3.90 ; - if ( !model->HSM1_xdiffd_Given ) model->HSM1_xdiffd = 0.0; - if ( !model->HSM1_pthrou_Given ) model->HSM1_pthrou = 0.0; - if ( !model->HSM1_vdiffj_Given ) model->HSM1_vdiffj = 0.5; - } - - /* for flicker noise the same as BSIM3 */ - if ( !model->HSM1_ef_Given ) model->HSM1_ef = 0.0; - if ( !model->HSM1_af_Given ) model->HSM1_af = 1.0; - if ( !model->HSM1_kf_Given ) model->HSM1_kf = 0.0; - - /* loop through all the instances of the model */ - for ( here = model->HSM1instances ;here != NULL ; - here = here->HSM1nextInstance ) { - - if(here->HSM1owner == ARCHme) - { - /* allocate a chunk of the state vector */ - here->HSM1states = *states; - *states += HSM1numStates; - } - - /* perform the parameter defaulting */ - if ( !here->HSM1_l_Given ) here->HSM1_l = 5.0e-6 ; - if ( !here->HSM1_w_Given ) here->HSM1_w = 5.0e-6 ; - if ( !here->HSM1_m_Given ) here->HSM1_m = 1; - if ( !here->HSM1_ad_Given ) here->HSM1_ad = 0.0 ; - if ( !here->HSM1_as_Given ) here->HSM1_as = 0.0 ; - if ( !here->HSM1_pd_Given ) here->HSM1_pd = 0.0 ; - if ( !here->HSM1_ps_Given ) here->HSM1_ps = 0.0 ; - if ( !here->HSM1_nrd_Given ) here->HSM1_nrd = 0.0 ; - if ( !here->HSM1_nrs_Given ) here->HSM1_nrs = 0.0 ; - if ( !here->HSM1_temp_Given ) here->HSM1_temp = 300.15 ; - if ( !here->HSM1_dtemp_Given ) here->HSM1_dtemp = 0.0 ; - - if ( !here->HSM1_icVBS_Given ) here->HSM1_icVBS = 0.0; - if ( !here->HSM1_icVDS_Given ) here->HSM1_icVDS = 0.0; - if ( !here->HSM1_icVGS_Given ) here->HSM1_icVGS = 0.0; - - here->HSM1_weff = here->HSM1_w - 2.0e0 * model->HSM1_xdiffd - 2.0e0 * model->HSM1_xwd ; - here->HSM1_leff = here->HSM1_l - 2.0e0 * model->HSM1_xpolyd - 2.0e0 * model->HSM1_xld ; - - /* process source/drain series resistance added by K.M. */ - /* Drain and source conductances are always zero, - because there is no sheet resistance in HSM1 model param. - if ( model->HSM1_corsrd ) - here->HSM1drainConductance = 0.0; - else - here->HSM1drainConductance = model->HSM1_rs / here->HSM1_weff; - - if ( here->HSM1drainConductance > 0.0 ) - here->HSM1drainConductance = 1.0 / here->HSM1drainConductance; - else - here->HSM1drainConductance = 0.0; - - if ( model->HSM1_corsrd ) - here->HSM1sourceConductance = 0.0; - else - here->HSM1sourceConductance = model->HSM1_rd / here->HSM1_weff; - - if ( here->HSM1sourceConductance > 0.0 ) - here->HSM1sourceConductance = 1.0 / here->HSM1sourceConductance; - else - here->HSM1sourceConductance = 0.0; - */ - here->HSM1drainConductance = 0.0; - here->HSM1sourceConductance = 0.0; - - /* process drain series resistance */ - if( here->HSM1drainConductance > 0.0 && here->HSM1dNodePrime == 0 ) { - error = CKTmkVolt(ckt, &tmp, here->HSM1name, "drain"); - if (error) return(error); - here->HSM1dNodePrime = tmp->number; - - if (ckt->CKTcopyNodesets) { - if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } - - } - else { - here->HSM1dNodePrime = here->HSM1dNode; - } - - /* process source series resistance */ - if( here->HSM1sourceConductance > 0.0 && here->HSM1sNodePrime == 0 ) { - if ( here->HSM1sNodePrime == 0 ) { - error = CKTmkVolt(ckt, &tmp, here->HSM1name, "source"); - if (error) return(error); - here->HSM1sNodePrime = tmp->number; - - if (ckt->CKTcopyNodesets) { - if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } - - } - } - else { - here->HSM1sNodePrime = here->HSM1sNode; - } - - /* 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)) == NULL){\ - return(E_NOMEM);\ -} - - TSTALLOC(HSM1DdPtr, HSM1dNode, HSM1dNode) - TSTALLOC(HSM1GgPtr, HSM1gNode, HSM1gNode) - TSTALLOC(HSM1SsPtr, HSM1sNode, HSM1sNode) - TSTALLOC(HSM1BbPtr, HSM1bNode, HSM1bNode) - TSTALLOC(HSM1DPdpPtr, HSM1dNodePrime, HSM1dNodePrime) - TSTALLOC(HSM1SPspPtr, HSM1sNodePrime, HSM1sNodePrime) - TSTALLOC(HSM1DdpPtr, HSM1dNode, HSM1dNodePrime) - TSTALLOC(HSM1GbPtr, HSM1gNode, HSM1bNode) - TSTALLOC(HSM1GdpPtr, HSM1gNode, HSM1dNodePrime) - TSTALLOC(HSM1GspPtr, HSM1gNode, HSM1sNodePrime) - TSTALLOC(HSM1SspPtr, HSM1sNode, HSM1sNodePrime) - TSTALLOC(HSM1BdpPtr, HSM1bNode, HSM1dNodePrime) - TSTALLOC(HSM1BspPtr, HSM1bNode, HSM1sNodePrime) - TSTALLOC(HSM1DPspPtr, HSM1dNodePrime, HSM1sNodePrime) - TSTALLOC(HSM1DPdPtr, HSM1dNodePrime, HSM1dNode) - TSTALLOC(HSM1BgPtr, HSM1bNode, HSM1gNode) - TSTALLOC(HSM1DPgPtr, HSM1dNodePrime, HSM1gNode) - TSTALLOC(HSM1SPgPtr, HSM1sNodePrime, HSM1gNode) - TSTALLOC(HSM1SPsPtr, HSM1sNodePrime, HSM1sNode) - TSTALLOC(HSM1DPbPtr, HSM1dNodePrime, HSM1bNode) - TSTALLOC(HSM1SPbPtr, HSM1sNodePrime, HSM1bNode) - TSTALLOC(HSM1SPdpPtr, HSM1sNodePrime, HSM1dNodePrime) - - } - } - return(OK); -} - -int -HSM1unsetup (GENmodel *inModel, CKTcircuit *ckt) -{ - HSM1model *model; - HSM1instance *here; - - for (model = (HSM1model *) inModel; model != NULL; - model = model->HSM1nextModel) - { - for (here = model->HSM1instances; here != NULL; - here = here->HSM1nextInstance) - { - if (here->HSM1dNodePrime - && here->HSM1dNodePrime != here->HSM1dNode) - { - CKTdltNNum (ckt, here->HSM1dNodePrime); - here->HSM1dNodePrime = 0; - } - if (here->HSM1sNodePrime - && here->HSM1sNodePrime != here->HSM1sNode) - { - CKTdltNNum (ckt, here->HSM1sNodePrime); - here->HSM1sNodePrime = 0; - } - } - } - return OK; -} diff --git a/src/spicelib/devices/hisim/hsm1temp.c b/src/spicelib/devices/hisim/hsm1temp.c deleted file mode 100644 index 90cb6429b..000000000 --- a/src/spicelib/devices/hisim/hsm1temp.c +++ /dev/null @@ -1,38 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1temp.c of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "smpdefs.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "const.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1temp(GENmodel *inModel, CKTcircuit *ckt) -{ - NG_IGNORE(inModel); - NG_IGNORE(ckt); - - /* "ckt->CKTtemp" dependence of HiSIM parameters is treated all in - * HSM1evaluate102/112/120(). So there is no task in HSM1temp(). - */ - - /* PN: - * Hope the temp dependence treated in the evaluate function does - * not break the parallel code. Parallel code structure here suggests: - - if (here->HSM1owner != ARCHme) - continue; - */ - - return(OK); -} diff --git a/src/spicelib/devices/hisim/hsm1trunc.c b/src/spicelib/devices/hisim/hsm1trunc.c deleted file mode 100644 index 1b109fcd2..000000000 --- a/src/spicelib/devices/hisim/hsm1trunc.c +++ /dev/null @@ -1,49 +0,0 @@ -/*********************************************************************** - HiSIM (Hiroshima University STARC IGFET Model) - Copyright (C) 2003 STARC - - VERSION : HiSIM 1.2.0 - FILE : hsm1trunc of HiSIM 1.2.0 - - April 9, 2003 : released by STARC Physical Design Group -***********************************************************************/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "hsm1def.h" -#include "sperror.h" -#include "suffix.h" - -int -HSM1trunc(GENmodel *inModel, register CKTcircuit *ckt, double *timeStep) -{ - register HSM1model *model = (HSM1model*)inModel; - register HSM1instance *here; -#ifdef STEPDEBUG - double debugtemp; -#endif /* STEPDEBUG */ - - for ( ;model != NULL ;model = model->HSM1nextModel ) { - for ( here=model->HSM1instances ;here!=NULL ; - here = here->HSM1nextInstance ) { - - if (here->HSM1owner != ARCHme) - continue; - -#ifdef STEPDEBUG - debugtemp = *timeStep; -#endif /* STEPDEBUG */ - CKTterr(here->HSM1qb,ckt,timeStep); - CKTterr(here->HSM1qg,ckt,timeStep); - CKTterr(here->HSM1qd,ckt,timeStep); -#ifdef STEPDEBUG - if ( debugtemp != *timeStep ) - printf("device %s reduces step from %g to %g\n", - here->HSM1name, debugtemp, *timeStep); -#endif /* STEPDEBUG */ - } - } - return(OK); -} - -