24 changed files with 8328 additions and 0 deletions
-
32src/spicelib/devices/soi3/Makefile.am
-
55src/spicelib/devices/soi3/README
-
239src/spicelib/devices/soi3/soi3.c
-
406src/spicelib/devices/soi3/soi3acld.c
-
505src/spicelib/devices/soi3/soi3ask.c
-
590src/spicelib/devices/soi3/soi3cap.c
-
217src/spicelib/devices/soi3/soi3conv.c
-
800src/spicelib/devices/soi3/soi3defs.h
-
50src/spicelib/devices/soi3/soi3del.c
-
51src/spicelib/devices/soi3/soi3dest.c
-
95src/spicelib/devices/soi3/soi3ext.h
-
65src/spicelib/devices/soi3/soi3ic.c
-
65src/spicelib/devices/soi3/soi3init.c
-
13src/spicelib/devices/soi3/soi3init.h
-
26src/spicelib/devices/soi3/soi3itf.h
-
2560src/spicelib/devices/soi3/soi3load.c
-
286src/spicelib/devices/soi3/soi3mask.c
-
56src/spicelib/devices/soi3/soi3mdel.c
-
390src/spicelib/devices/soi3/soi3mpar.c
-
279src/spicelib/devices/soi3/soi3nois.c
-
153src/spicelib/devices/soi3/soi3par.c
-
751src/spicelib/devices/soi3/soi3set.c
-
597src/spicelib/devices/soi3/soi3temp.c
-
47src/spicelib/devices/soi3/soi3trun.c
@ -0,0 +1,32 @@ |
|||
## Process this file with automake to produce Makefile.in
|
|||
|
|||
pkglib_LTLIBRARIES = libsoi3.la |
|||
|
|||
libsoi3_la_SOURCES = \
|
|||
soi3.c \
|
|||
soi3acld.c \
|
|||
soi3ask.c \
|
|||
soi3cap.c \
|
|||
soi3conv.c \
|
|||
soi3defs.h \
|
|||
soi3del.c \
|
|||
soi3dest.c \
|
|||
soi3ext.h \
|
|||
soi3ic.c \
|
|||
soi3init.c \
|
|||
soi3init.h \
|
|||
soi3itf.h \
|
|||
soi3load.c \
|
|||
soi3mask.c \
|
|||
soi3mdel.c \
|
|||
soi3mpar.c \
|
|||
soi3nois.c \
|
|||
soi3par.c \
|
|||
soi3set.c \
|
|||
soi3temp.c \
|
|||
soi3trun.c |
|||
|
|||
|
|||
|
|||
INCLUDES = -I$(top_srcdir)/src/include |
|||
MAINTAINERCLEANFILES = Makefile.in |
|||
@ -0,0 +1,55 @@ |
|||
Licence Agreement (STAG) from DERA |
|||
|
|||
1. The STAG Computer Model is subject to Copyright owned by the United Kingdom |
|||
Secretary of State for Defence acting through the Defence Evaluation and Research Agency |
|||
(DERA). It is made available to licensee (hereinafter LICENSEE) on the following conditions:- |
|||
|
|||
2. Downloading the STAG Model deems acceptance of the terms of the licence. |
|||
|
|||
3. DERA grants to LICENSEE a royalty free non-exclusive licence to use the furnished STAG |
|||
Model. LICENSEE is permitted to copy, distribute, and transfer the STAG Model to |
|||
customers for their royalty free use on the same licence terms. |
|||
|
|||
4. LICENSEE acknowledges that STAG is a research tool still in the development stage, that |
|||
it is being supplied "as is", without any accompanying services or improvements from |
|||
DERA. |
|||
|
|||
5. LICENSEE acknowledges that STAG is a Model developed by the Department of |
|||
Electronics and Computer Science at the University of Southampton (UOS), England, and is |
|||
incorporated within SPICE 3f5, a program developed by the Department of Electrical |
|||
Engineering and Computer Science at the University of California, Berkeley, California |
|||
(UCB). As such, LICENSEE acknowledges that in addition to the rights licensed by DERA, |
|||
UCB itself imposes restrictions on use, copying, and distribution of the SPICE 3f5 program |
|||
and its derivatives. |
|||
|
|||
6. LICENSEE undertakes to obtain any separate licence required for the use of SPICE 3f5 |
|||
from UCB. |
|||
|
|||
7. DERA make no representations or warranties, express or implied. DERA shall not be held |
|||
liable for any liability nor for any direct, indirect, or consequential damages with respect to |
|||
any claim by LICENSEE or any third party on account of or arising from this Agreement or |
|||
use of STAG. |
|||
|
|||
8. Title to copyright of all portions of STAG developed at UOS and/or DERA together with |
|||
associated documentation shall at all times remain with DERA, and LICENSEE agrees to |
|||
preserve same. LICENSEE agrees to ensure that this information and appropriate copyright |
|||
notice is reproduced with any copies of STAG or any modified versions derived from it. |
|||
|
|||
9. This agreement shall be construed, interpreted, and applied in accordance with the laws |
|||
of England. |
|||
|
|||
for DERA by: |
|||
|
|||
J B EDWARDS |
|||
IPD5A |
|||
10 NOV 1997 |
|||
|
|||
Intellectual Property Department |
|||
Defence Evaluation and Research Agency |
|||
St Andrews Road |
|||
Malvern |
|||
WR14 3PS |
|||
United Kingdom |
|||
|
|||
phone: +44 - 1684 - 894234 |
|||
fax: +44 - 1684 - 894146 |
|||
@ -0,0 +1,239 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "devdefs.h" |
|||
#include "ifsim.h" |
|||
#include "soi3defs.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
|
|||
char *SOI3names[] = { |
|||
"Drain", |
|||
"Front Gate", |
|||
"Source", |
|||
"Back Gate", |
|||
"Bulk", |
|||
"Thermal" |
|||
}; |
|||
|
|||
|
|||
IFparm SOI3pTable[] = { /* parameters */ |
|||
IOP("l", SOI3_L, IF_REAL, "Length"), |
|||
IOP("w", SOI3_W, IF_REAL, "Width"), |
|||
IOP("nrd", SOI3_NRD, IF_REAL, "Drain squares"), |
|||
IOP("nrs", SOI3_NRS, IF_REAL, "Source squares"), |
|||
IP("off", SOI3_OFF, IF_FLAG, "Device initially off"), |
|||
IOP("icvds", SOI3_IC_VDS, IF_REAL, "Initial D-S voltage"), |
|||
IOP("icvgfs", SOI3_IC_VGFS, IF_REAL, "Initial GF-S voltage"), |
|||
IOP("icvgbs", SOI3_IC_VGBS, IF_REAL, "Initial GB-S voltage"), |
|||
IOP("icvbs", SOI3_IC_VBS, IF_REAL, "Initial B-S voltage"), |
|||
IOP("temp", SOI3_TEMP, IF_REAL, "Instance temperature"), |
|||
IOP("rt", SOI3_RT, IF_REAL, "Instance Lumped Thermal Resistance"), |
|||
IOP("ct", SOI3_CT, IF_REAL, "Instance Lumped Thermal Capacitance"), |
|||
IOP("rt1", SOI3_RT1, IF_REAL, "Second Thermal Resistance"), |
|||
IOP("ct1", SOI3_CT1, IF_REAL, "Second Thermal Capacitance"), |
|||
IOP("rt2", SOI3_RT2, IF_REAL, "Third Thermal Resistance"), |
|||
IOP("ct2", SOI3_CT2, IF_REAL, "Third Thermal Capacitance"), |
|||
IOP("rt3", SOI3_RT3, IF_REAL, "Fourth Thermal Resistance"), |
|||
IOP("ct3", SOI3_CT3, IF_REAL, "Fourth Thermal Capacitance"), |
|||
IOP("rt4", SOI3_RT4, IF_REAL, "Fifth Thermal Resistance"), |
|||
IOP("ct4", SOI3_CT4, IF_REAL, "Fifth Thermal Capacitance"), |
|||
|
|||
IP( "ic", SOI3_IC, IF_REALVEC,"Vector of D-S, GF-S, GB-S, B-S voltages"), |
|||
/* IP( "sens_l", SOI3_L_SENS, IF_FLAG, "flag to request sensitivity WRT length"), |
|||
IP( "sens_w", SOI3_W_SENS, IF_FLAG, "flag to request sensitivity WRT width"),*/ |
|||
OP( "dnode", SOI3_DNODE, IF_INTEGER, "Number of the drain node "), |
|||
OP( "gfnode", SOI3_GFNODE, IF_INTEGER, "Number of frt. gate node "), |
|||
OP( "snode", SOI3_SNODE, IF_INTEGER, "Number of the source node "), |
|||
OP( "gbnode", SOI3_GBNODE, IF_INTEGER, "Number of back gate node "), |
|||
OP( "bnode", SOI3_BNODE, IF_INTEGER, "Number of the body node "), |
|||
OP( "dnodeprime", SOI3_DNODEPRIME, IF_INTEGER, "Number of int. drain node"), |
|||
OP( "snodeprime", SOI3_SNODEPRIME, IF_INTEGER, "Number of int. source node "), |
|||
OP( "tnode", SOI3_TNODE, IF_INTEGER, "Number of thermal node "), |
|||
OP( "branch", SOI3_BRANCH, IF_INTEGER, "Number of thermal branch "), |
|||
OP( "sourceconductance", SOI3_SOURCECONDUCT, IF_REAL, "Conductance of source"), |
|||
OP( "drainconductance", SOI3_DRAINCONDUCT, IF_REAL, "Conductance of drain"), |
|||
OP( "von", SOI3_VON, IF_REAL, "Effective Threshold Voltage (von) "), |
|||
OP( "vfbf", SOI3_VFBF, IF_REAL, "Temperature adjusted flat band voltage"), |
|||
OP( "vdsat", SOI3_VDSAT, IF_REAL, "Saturation drain voltage"), |
|||
OP( "sourcevcrit", SOI3_SOURCEVCRIT,IF_REAL, "Critical source voltage"), |
|||
OP( "drainvcrit", SOI3_DRAINVCRIT, IF_REAL, "Critical drain voltage"), |
|||
OP( "id", SOI3_ID, IF_REAL, "Drain current"), |
|||
OP( "ibs", SOI3_IBS, IF_REAL, "B-S junction current"), |
|||
OP( "ibd", SOI3_IBD, IF_REAL, "B-D junction current"), |
|||
OP( "gmbs", SOI3_GMBS, IF_REAL, "Bulk-Source transconductance"), |
|||
OP( "gmf", SOI3_GMF, IF_REAL, "Front transconductance"), |
|||
OP( "gmb", SOI3_GMB, IF_REAL, "Back transconductance"), |
|||
OP( "gds", SOI3_GDS, IF_REAL, "Drain-Source conductance"), |
|||
OP( "gbd", SOI3_GBD, IF_REAL, "Bulk-Drain conductance"), |
|||
OP( "gbs", SOI3_GBS, IF_REAL, "Bulk-Source conductance"), |
|||
OP( "capbd", SOI3_CAPBD, IF_REAL, "Bulk-Drain capacitance"), |
|||
OP( "capbs", SOI3_CAPBS, IF_REAL, "Bulk-Source capacitance"), |
|||
OP( "cbd0", SOI3_CAPZEROBIASBD, IF_REAL, "Zero-Bias B-D junction capacitance"), |
|||
OP( "cbs0", SOI3_CAPZEROBIASBS, IF_REAL, "Zero-Bias B-S junction capacitance"), |
|||
OP( "vbd", SOI3_VBD, IF_REAL, "Bulk-Drain voltage"), |
|||
OP( "vbs", SOI3_VBS, IF_REAL, "Bulk-Source voltage"), |
|||
OP( "vgfs", SOI3_VGFS, IF_REAL, "Front gate-Source voltage"), |
|||
OP( "vgbs", SOI3_VGBS, IF_REAL, "Back gate-Source voltage"), |
|||
OP( "vds", SOI3_VDS, IF_REAL, "Drain-Source voltage"), |
|||
OP( "qgf", SOI3_QGF, IF_REAL, "Front Gate charge storage"), |
|||
OP( "iqgf",SOI3_IQGF,IF_REAL,"Current due to front gate charge storage"), |
|||
/* |
|||
OP( "qgb", SOI3_QGB, IF_REAL, "Back Gate charge storage"), |
|||
OP( "iqgb",SOI3_IQGB,IF_REAL,"Current due to back gate charge storage"), |
|||
*/ |
|||
OP( "qd", SOI3_QD, IF_REAL, "Drain charge storage"), |
|||
OP( "iqd",SOI3_IQD,IF_REAL,"Current due to drain charge storage"), |
|||
OP( "qs", SOI3_QS, IF_REAL, "Source charge storage"), |
|||
OP( "iqs",SOI3_IQS,IF_REAL,"Current due to source charge storage"), |
|||
OP( "qbd", SOI3_QBD, IF_REAL, "Bulk-Drain charge storage"), |
|||
OP( "iqbd",SOI3_IQBD,IF_REAL,"Current due to bulk-drain charge storage"), |
|||
OP( "qbs", SOI3_QBS, IF_REAL, "Bulk-Source charge storage"), |
|||
OP( "iqbs",SOI3_IQBS,IF_REAL,"Currnet due to bulk-source charge storage"), |
|||
/* extra stuff for newer model -msll Jan96 */ |
|||
OP( "vfbb", SOI3_VFBB, IF_REAL, "Temperature adjusted back flat band voltage") |
|||
|
|||
/*, |
|||
OP( "sens_l_dc", SOI3_L_SENS_DC, IF_REAL, "dc sensitivity wrt length"), |
|||
OP( "sens_l_real", SOI3_L_SENS_REAL,IF_REAL, |
|||
"real part of ac sensitivity wrt length"), |
|||
OP( "sens_l_imag", SOI3_L_SENS_IMAG,IF_REAL, |
|||
"imag part of ac sensitivity wrt length"), |
|||
OP( "sens_l_mag", SOI3_L_SENS_MAG, IF_REAL, |
|||
"sensitivity wrt l of ac magnitude"), |
|||
OP( "sens_l_ph", SOI3_L_SENS_PH, IF_REAL, |
|||
"sensitivity wrt l of ac phase"), |
|||
OP( "sens_l_cplx", SOI3_L_SENS_CPLX,IF_COMPLEX, "ac sensitivity wrt length"), |
|||
OP( "sens_w_dc", SOI3_W_SENS_DC, IF_REAL, "dc sensitivity wrt width"), |
|||
OP( "sens_w_real", SOI3_W_SENS_REAL,IF_REAL, |
|||
"real part of ac sensitivity wrt width"), |
|||
OP( "sens_w_imag", SOI3_W_SENS_IMAG,IF_REAL, |
|||
"imag part of ac sensitivity wrt width"), |
|||
OP( "sens_w_mag", SOI3_W_SENS_MAG, IF_REAL, |
|||
"sensitivity wrt w of ac magnitude"), |
|||
OP( "sens_w_ph", SOI3_W_SENS_PH, IF_REAL, |
|||
"sensitivity wrt w of ac phase"), |
|||
OP( "sens_w_cplx", SOI3_W_SENS_CPLX,IF_COMPLEX, "ac sensitivity wrt width")*/ |
|||
}; |
|||
|
|||
IFparm SOI3mPTable[] = { /* model parameters */ |
|||
IOP("vto", SOI3_MOD_VTO, IF_REAL ,"Threshold voltage"), |
|||
IOP("vt0", SOI3_MOD_VTO, IF_REAL ,"Threshold voltage"), |
|||
IOP("vfbf", SOI3_MOD_VFBF, IF_REAL ,"Flat band voltage"), |
|||
IOP("kp", SOI3_MOD_KP, IF_REAL ,"Transconductance parameter"), |
|||
IOP("gamma", SOI3_MOD_GAMMA, IF_REAL ,"Body Factor"), |
|||
IOP("phi", SOI3_MOD_PHI, IF_REAL ,"Surface potential"), |
|||
IOP("lambda",SOI3_MOD_LAMBDA,IF_REAL ,"Channel length modulation"), |
|||
IOP("theta", SOI3_MOD_THETA, IF_REAL ,"Vertical field mobility degradation"), |
|||
IOP("rd", SOI3_MOD_RD, IF_REAL ,"Drain ohmic resistance"), |
|||
IOP("rs", SOI3_MOD_RS, IF_REAL ,"Source ohmic resistance"), |
|||
IOP("cbd", SOI3_MOD_CBD, IF_REAL ,"B-D junction capacitance"), |
|||
IOP("cbs", SOI3_MOD_CBS, IF_REAL ,"B-S junction capacitance"), |
|||
IOP("is", SOI3_MOD_IS, IF_REAL ,"Bulk junction sat. current"), |
|||
IOP("is1", SOI3_MOD_IS1, IF_REAL ,"2nd Bulk junction sat. current"), |
|||
IOP("pb", SOI3_MOD_PB, IF_REAL ,"Bulk junction potential"), |
|||
IOP("cgfso", SOI3_MOD_CGFSO, IF_REAL ,"Front Gate-source overlap cap."), |
|||
IOP("cgfdo", SOI3_MOD_CGFDO, IF_REAL ,"Front Gate-drain overlap cap."), |
|||
IOP("cgfbo", SOI3_MOD_CGFBO, IF_REAL ,"Front Gate-bulk overlap cap."), |
|||
IOP("cgbso", SOI3_MOD_CGBSO, IF_REAL ,"Back Gate-source overlap cap."), |
|||
IOP("cgbdo", SOI3_MOD_CGBDO, IF_REAL ,"Back Gate-drain overlap cap."), |
|||
IOP("cgb_bo", SOI3_MOD_CGB_BO, IF_REAL ,"Back Gate-bulk overlap cap."), |
|||
IOP("rsh", SOI3_MOD_RSH, IF_REAL ,"Sheet resistance"), |
|||
IOP("cj", SOI3_MOD_CJSW, IF_REAL ,"Side junction cap per area"), |
|||
IOP("mj", SOI3_MOD_MJSW, IF_REAL ,"Side grading coefficient"), |
|||
IOP("js", SOI3_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), |
|||
IOP("js1", SOI3_MOD_JS1, IF_REAL ,"2nd Bulk jct. sat. current density"), |
|||
IOP("tof", SOI3_MOD_TOF, IF_REAL ,"Front Oxide thickness"), |
|||
IOP("tob", SOI3_MOD_TOB, IF_REAL ,"Back Oxide thickness"), |
|||
IOP("tb", SOI3_MOD_TB, IF_REAL ,"Bulk film thickness"), |
|||
IOP("ld", SOI3_MOD_LD, IF_REAL ,"Lateral diffusion"), |
|||
IOP("u0", SOI3_MOD_U0, IF_REAL ,"Surface mobility"), |
|||
IOP("uo", SOI3_MOD_U0, IF_REAL ,"Surface mobility"), |
|||
IOP("fc", SOI3_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), |
|||
IP("nsoi", SOI3_MOD_NSOI3, IF_FLAG ,"N type SOI3fet model"), |
|||
IP("psoi", SOI3_MOD_PSOI3, IF_FLAG ,"P type SOI3fet model"), |
|||
IOP("kox", SOI3_MOD_KOX, IF_REAL ,"Oxide thermal conductivity"), |
|||
IOP("shsi", SOI3_MOD_SHSI, IF_REAL ,"Specific heat of silicon"), |
|||
IOP("dsi", SOI3_MOD_DSI, IF_REAL ,"Density of silicon"), |
|||
IOP("nsub", SOI3_MOD_NSUB, IF_REAL ,"Substrate doping"), |
|||
IOP("tpg", SOI3_MOD_TPG, IF_INTEGER,"Gate type"), |
|||
IOP("nqff", SOI3_MOD_NQFF, IF_REAL ,"Front fixed oxide charge density"), |
|||
IOP("nqfb", SOI3_MOD_NQFB, IF_REAL ,"Back fixed oxide charge density"), |
|||
IOP("nssf", SOI3_MOD_NSSF, IF_REAL ,"Front surface state density"), |
|||
IOP("nssb", SOI3_MOD_NSSB, IF_REAL ,"Back surface state density"), |
|||
IOP("tnom", SOI3_MOD_TNOM, IF_REAL ,"Parameter measurement temp"), |
|||
IP("kf", SOI3_MOD_KF, IF_REAL ,"Flicker noise coefficient"), |
|||
IP("af", SOI3_MOD_AF, IF_REAL ,"Flicker noise exponent"), |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
IOP("sigma", SOI3_MOD_SIGMA, IF_REAL ,"DIBL coefficient"), |
|||
IOP("chifb", SOI3_MOD_CHIFB, IF_REAL ,"Temperature coeff of flatband voltage"), |
|||
IOP("chiphi",SOI3_MOD_CHIPHI, IF_REAL ,"Temperature coeff of PHI"), |
|||
IOP("deltaw",SOI3_MOD_DELTAW,IF_REAL ,"Narrow width factor"), |
|||
IOP("deltal",SOI3_MOD_DELTAL,IF_REAL ,"Short channel factor"), |
|||
IOP("vsat", SOI3_MOD_VSAT, IF_REAL ,"Saturation velocity"), |
|||
IOP("k", SOI3_MOD_K, IF_REAL ,"Thermal exponent"), |
|||
IOP("lx", SOI3_MOD_LX, IF_REAL ,"Channel length modulation (alternative)"), |
|||
IOP("vp", SOI3_MOD_VP, IF_REAL ,"Channel length modulation (alt. empirical)"), |
|||
IOP("eta", SOI3_MOD_ETA, IF_REAL ,"Impact ionization field adjustment factor"), |
|||
IOP("alpha0",SOI3_MOD_ALPHA0,IF_REAL ,"First impact ionisation coeff (alpha0)"), |
|||
IOP("beta0", SOI3_MOD_BETA0, IF_REAL ,"Second impact ionisation coeff (beta0)"), |
|||
IOP("lm", SOI3_MOD_LM, IF_REAL ,"Impact ion. drain region length"), |
|||
IOP("lm1", SOI3_MOD_LM1, IF_REAL ,"Impact ion. drain region length coeff"), |
|||
IOP("lm2", SOI3_MOD_LM2, IF_REAL ,"Impact ion. drain region length coeff"), |
|||
IOP("etad", SOI3_MOD_ETAD, IF_REAL ,"Diode ideality factor"), |
|||
IOP("etad1", SOI3_MOD_ETAD1, IF_REAL ,"2nd Diode ideality factor"), |
|||
IOP("chibeta",SOI3_MOD_CHIBETA,IF_REAL ,"Impact ionisation temperature coefficient"), |
|||
IOP("vfbb", SOI3_MOD_VFBB, IF_REAL ,"Back Flat band voltage"), |
|||
IOP("gammab",SOI3_MOD_GAMMAB,IF_REAL ,"Back Body Factor"), |
|||
IOP("chid", SOI3_MOD_CHID, IF_REAL ,"Junction temperature factor"), |
|||
IOP("chid1", SOI3_MOD_CHID1, IF_REAL ,"2nd Junction temperature factor"), |
|||
IOP("dvt", SOI3_MOD_DVT, IF_INTEGER,"Switch for temperature dependence of vt in diodes"), |
|||
IOP("nlev", SOI3_MOD_NLEV, IF_INTEGER,"Level switch for flicker noise model"), |
|||
IOP("betabjt",SOI3_MOD_BETABJT,IF_REAL ,"Beta for BJT"), |
|||
IOP("tauf", SOI3_MOD_TAUFBJT,IF_REAL ,"Forward tau for BJT"), |
|||
IOP("taur", SOI3_MOD_TAURBJT,IF_REAL ,"Reverse tau for BJT"), |
|||
IOP("betaexp",SOI3_MOD_BETAEXP,IF_REAL ,"Exponent for Beta of BJT"), |
|||
IOP("tauexp", SOI3_MOD_TAUEXP,IF_REAL, "Exponent for Transit time of BJT"), |
|||
IOP("rsw", SOI3_MOD_RSW, IF_REAL ,"Source resistance width scaling factor"), |
|||
IOP("rdw", SOI3_MOD_RDW, IF_REAL ,"Drain resistance width scaling factor"), |
|||
IOP("fmin", SOI3_MOD_FMIN, IF_REAL ,"Minimum feature size of technology"), |
|||
IOP("vtex", SOI3_MOD_VTEX, IF_REAL ,"Extracted threshold voltage"), |
|||
IOP("vdex", SOI3_MOD_VDEX, IF_REAL ,"Drain bias at which vtex extracted"), |
|||
IOP("delta0",SOI3_MOD_DELTA0,IF_REAL ,"Surface potential factor for vtex conversion"), |
|||
IOP("csf", SOI3_MOD_CSF ,IF_REAL ,"Saturation region charge sharing factor"), |
|||
IOP("nplus", SOI3_MOD_NPLUS ,IF_REAL ,"Doping concentration of N+ or P+ regions"), |
|||
IOP("rta", SOI3_MOD_RTA ,IF_REAL ,"Thermal resistance area scaling factor"), |
|||
IOP("cta", SOI3_MOD_CTA ,IF_REAL ,"Thermal capacitance area scaling factor") |
|||
|
|||
}; |
|||
|
|||
|
|||
|
|||
int SOI3nSize = NUMELEMS(SOI3names); |
|||
int SOI3pTSize = NUMELEMS(SOI3pTable); |
|||
int SOI3mPTSize = NUMELEMS(SOI3mPTable); |
|||
int SOI3iSize = sizeof(SOI3instance); |
|||
int SOI3mSize = sizeof(SOI3model); |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,406 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3acLoad(inModel,ckt) |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
{ |
|||
SOI3model *model = (SOI3model*)inModel; |
|||
SOI3instance *here; |
|||
int xnrm; |
|||
int xrev; |
|||
|
|||
double cgfgf,cgfd,cgfs,cgfdeltaT; |
|||
double cdgf,cdd,cds,cddeltaT; |
|||
double csgf,csd,css,csdeltaT; |
|||
double cbgf,cbd,cbs,cbdeltaT,cbgb; |
|||
double cgbgb,cgbsb,cgbdb; |
|||
|
|||
double xcgfgf,xcgfd,xcgfs,xcgfdeltaT; |
|||
double xcdgf,xcdd,xcds,xcddeltaT; |
|||
double xcsgf,xcsd,xcss,xcsdeltaT; |
|||
double xcbgf,xcbd,xcbs,xcbdeltaT,xcbgb; |
|||
double xcgbgb,xcgbsb,xcgbdb; |
|||
|
|||
double capbd,capbs; /* diode capacitances */ |
|||
|
|||
double xcBJTbsbs,xcBJTbsdeltaT; |
|||
double xcBJTbdbd,xcBJTbddeltaT; |
|||
|
|||
double rtargs[5]; |
|||
double grt[5]; |
|||
double ctargs[5]; |
|||
double xct[5]; /* 1/reactance of thermal cap */ |
|||
int tnodeindex; |
|||
|
|||
double cgfb0; |
|||
double cgfd0; |
|||
double cgfs0; |
|||
|
|||
double cgbb0; |
|||
double cgbd0; |
|||
double cgbs0; |
|||
|
|||
double xcgbd0,xcgbs0; |
|||
|
|||
double EffectiveLength; |
|||
|
|||
double omega; |
|||
|
|||
omega = ckt->CKTomega; |
|||
|
|||
for( ; model != NULL; model = model->SOI3nextModel) |
|||
{ |
|||
for(here = model->SOI3instances; here!= NULL; |
|||
here = here->SOI3nextInstance) |
|||
{ |
|||
|
|||
if (here->SOI3mode < 0) |
|||
{ |
|||
xnrm=0; |
|||
xrev=1; |
|||
} |
|||
else |
|||
{ |
|||
xnrm=1; |
|||
xrev=0; |
|||
} |
|||
|
|||
EffectiveLength=here->SOI3l - 2*model->SOI3latDiff; |
|||
cgfs0 = model->SOI3frontGateSourceOverlapCapFactor * here->SOI3w; |
|||
cgfd0 = model->SOI3frontGateDrainOverlapCapFactor * here->SOI3w; |
|||
cgfb0 = model->SOI3frontGateBulkOverlapCapFactor * EffectiveLength; |
|||
|
|||
/* JimB - can use basic device geometry to calculate source/back gate */ |
|||
/* and drain/back gate capacitances to a first approximation. Use this*/ |
|||
/* default model if capacitance factors aren't given in model netlist. */ |
|||
|
|||
if(model->SOI3backGateSourceOverlapCapFactorGiven) |
|||
{ |
|||
cgbs0 = model->SOI3backGateSourceOverlapCapFactor * here->SOI3w; |
|||
} |
|||
else |
|||
{ |
|||
/* As a basic circuit designers approximation, length of drain and */ |
|||
/* source regions often taken to have length of twice the minimum */ |
|||
/* feature size for that technology. */ |
|||
cgbs0 = 2*1e-6*model->SOI3minimumFeatureSize * here->SOI3w |
|||
* model->SOI3backOxideCapFactor; |
|||
} |
|||
if(model->SOI3backGateDrainOverlapCapFactorGiven) |
|||
{ |
|||
cgbd0 = model->SOI3backGateDrainOverlapCapFactor * here->SOI3w; |
|||
} |
|||
else |
|||
{ |
|||
/* As a basic circuit designer's approximation, length of drain and */ |
|||
/* source regions often taken to have length of twice the minimum */ |
|||
/* feature size for that technology. */ |
|||
cgbd0 = 2*1e-6*model->SOI3minimumFeatureSize * here->SOI3w |
|||
* model->SOI3backOxideCapFactor; |
|||
} |
|||
cgbb0 = model->SOI3backGateBulkOverlapCapFactor * EffectiveLength; |
|||
|
|||
capbd = here->SOI3capbd; |
|||
capbs = here->SOI3capbs; |
|||
|
|||
cgfgf = *(ckt->CKTstate0 + here->SOI3cgfgf); |
|||
cgfd = *(ckt->CKTstate0 + here->SOI3cgfd); |
|||
cgfs = *(ckt->CKTstate0 + here->SOI3cgfs); |
|||
cgfdeltaT = *(ckt->CKTstate0 + here->SOI3cgfdeltaT); |
|||
csgf = *(ckt->CKTstate0 + here->SOI3csgf); |
|||
csd = *(ckt->CKTstate0 + here->SOI3csd); |
|||
css = *(ckt->CKTstate0 + here->SOI3css); |
|||
csdeltaT = *(ckt->CKTstate0 + here->SOI3csdeltaT); |
|||
cdgf = *(ckt->CKTstate0 + here->SOI3cdgf); |
|||
cdd = *(ckt->CKTstate0 + here->SOI3cdd); |
|||
cds = *(ckt->CKTstate0 + here->SOI3cds); |
|||
cddeltaT = *(ckt->CKTstate0 + here->SOI3cddeltaT); |
|||
cgbgb = *(ckt->CKTstate0 + here->SOI3cgbgb); |
|||
cgbsb = *(ckt->CKTstate0 + here->SOI3cgbsb); |
|||
cgbdb = *(ckt->CKTstate0 + here->SOI3cgbdb); |
|||
cbgf = -(cgfgf + cdgf + csgf); |
|||
cbd = -(cgfd + cdd + csd + cgbdb); |
|||
cbs = -(cgfs + cds + css + cgbsb); |
|||
cbdeltaT = -(cgfdeltaT + cddeltaT + csdeltaT); |
|||
cbgb = -cgbgb; |
|||
|
|||
xcgfgf = (cgfgf + cgfd0 + cgfs0 + cgfb0) * omega; |
|||
xcgfd = (cgfd - cgfd0) * omega; |
|||
xcgfs = (cgfs - cgfs0) * omega; |
|||
xcgfdeltaT = cgfdeltaT * omega; |
|||
xcsgf = (csgf - cgfs0) * omega; |
|||
xcsd = csd * omega; |
|||
xcss = (css + capbs + cgfs0) * omega; |
|||
xcsdeltaT = csdeltaT * omega; |
|||
xcdgf = (cdgf - cgfd0) * omega; |
|||
xcdd = (cdd + capbd + cgfd0) * omega; |
|||
xcds = cds * omega; |
|||
xcddeltaT = cddeltaT * omega; |
|||
xcgbgb = (cgbgb + cgbb0 + cgbd0 + cgbs0) * omega; |
|||
xcgbsb = (cgbsb - cgbs0) * omega; |
|||
xcgbdb = -cgbd0 * omega; |
|||
xcbgf = (cbgf - cgfb0) * omega; |
|||
xcbd = (cbd - capbd) * omega; |
|||
xcbs = (cbs - capbs) * omega; |
|||
xcbdeltaT = cbdeltaT * omega; |
|||
xcbgb = cbgb * omega; |
|||
|
|||
xcgbs0 = cgbs0 * omega; |
|||
xcgbd0 = cgbd0 * omega; |
|||
|
|||
xcBJTbsbs = *(ckt->CKTstate0 + here->SOI3cBJTbsbs) * omega; |
|||
xcBJTbsdeltaT = *(ckt->CKTstate0 + here->SOI3cBJTbsdeltaT) * omega; |
|||
xcBJTbdbd = *(ckt->CKTstate0 + here->SOI3cBJTbdbd) * omega; |
|||
xcBJTbddeltaT = *(ckt->CKTstate0 + here->SOI3cBJTbddeltaT) * omega; |
|||
|
|||
/* JimB - 15/9/99 */ |
|||
/* Code for multiple thermal time constants. Start by moving all */ |
|||
/* rt and ct constants into arrays. */ |
|||
rtargs[0]=here->SOI3rt; |
|||
rtargs[1]=here->SOI3rt1; |
|||
rtargs[2]=here->SOI3rt2; |
|||
rtargs[3]=here->SOI3rt3; |
|||
rtargs[4]=here->SOI3rt4; |
|||
|
|||
ctargs[0]=here->SOI3ct; |
|||
ctargs[1]=here->SOI3ct1; |
|||
ctargs[2]=here->SOI3ct2; |
|||
ctargs[3]=here->SOI3ct3; |
|||
ctargs[4]=here->SOI3ct4; |
|||
|
|||
/* Set all admittance components to zero. */ |
|||
grt[0]=grt[1]=grt[2]=grt[3]=grt[4]=0.0; |
|||
xct[0]=xct[1]=xct[2]=xct[3]=xct[4]=0.0; |
|||
/* Now calculate conductances and susceptances from rt and ct. */ |
|||
/* Don't need to worry about divide by zero when calculating */ |
|||
/* grt components, as soi3setup() only creates a thermal node */ |
|||
/* if corresponding rt is greater than zero. */ |
|||
for(tnodeindex=0;tnodeindex<here->SOI3numThermalNodes;tnodeindex++) |
|||
{ |
|||
xct[tnodeindex] = ctargs[tnodeindex] * ckt->CKTomega; |
|||
grt[tnodeindex] = 1/rtargs[tnodeindex]; |
|||
} |
|||
/* End JimB */ |
|||
|
|||
/* |
|||
* load matrix |
|||
*/ |
|||
|
|||
*(here->SOI3GF_gfPtr + 1) += xcgfgf; |
|||
*(here->SOI3GB_gbPtr + 1) += xcgbgb; |
|||
*(here->SOI3B_bPtr + 1) += -(xcbgf+xcbd+xcbs+xcbgb) |
|||
+xcBJTbsbs+xcBJTbdbd; |
|||
|
|||
*(here->SOI3DP_dpPtr + 1) += xcdd+xcgbd0+xcBJTbdbd; |
|||
*(here->SOI3SP_spPtr + 1) += xcss+xcgbs0+xcBJTbsbs; |
|||
|
|||
*(here->SOI3GF_dpPtr + 1) += xcgfd; |
|||
*(here->SOI3GF_spPtr + 1) += xcgfs; |
|||
*(here->SOI3GF_bPtr + 1) -= (xcgfgf + xcgfd + xcgfs); |
|||
|
|||
*(here->SOI3GB_dpPtr + 1) += xcgbdb; |
|||
*(here->SOI3GB_spPtr + 1) += xcgbsb; |
|||
*(here->SOI3GB_bPtr + 1) -= (xcgbgb + xcgbdb + xcgbsb); |
|||
|
|||
*(here->SOI3B_gfPtr + 1) += xcbgf; |
|||
*(here->SOI3B_gbPtr + 1) += xcbgb; |
|||
*(here->SOI3B_dpPtr + 1) += xcbd-xcBJTbdbd; |
|||
*(here->SOI3B_spPtr + 1) += xcbs-xcBJTbsbs; |
|||
|
|||
*(here->SOI3DP_gfPtr + 1) += xcdgf; |
|||
*(here->SOI3DP_gbPtr + 1) += -xcgbd0; |
|||
*(here->SOI3DP_bPtr + 1) += -(xcdgf + xcdd + xcds + xcBJTbdbd); |
|||
*(here->SOI3DP_spPtr + 1) += xcds; |
|||
|
|||
*(here->SOI3SP_gfPtr + 1) += xcsgf; |
|||
*(here->SOI3SP_gbPtr + 1) += -xcgbs0; |
|||
*(here->SOI3SP_bPtr + 1) += -(xcsgf + xcsd + xcss + xcBJTbsbs); |
|||
*(here->SOI3SP_dpPtr + 1) += xcsd; |
|||
|
|||
/* if no thermal behaviour specified, then put in zero valued indpt. voltage source |
|||
between TOUT and ground */ |
|||
if (here->SOI3rt==0) |
|||
{ |
|||
*(here->SOI3TOUT_ibrPtr + 1) += 1.0; |
|||
*(here->SOI3IBR_toutPtr + 1) += 1.0; |
|||
*(ckt->CKTirhs + (here->SOI3branch)) = 0; |
|||
} |
|||
else |
|||
{ |
|||
*(here->SOI3TOUT_toutPtr + 1) += xct[0]; |
|||
if (here->SOI3numThermalNodes > 1) |
|||
{ |
|||
*(here->SOI3TOUT_tout1Ptr + 1) += -xct[0]; |
|||
*(here->SOI3TOUT1_toutPtr + 1) += -xct[0]; |
|||
*(here->SOI3TOUT1_tout1Ptr + 1) += xct[0]+xct[1]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 2) |
|||
{ |
|||
*(here->SOI3TOUT1_tout2Ptr + 1) += -xct[1]; |
|||
*(here->SOI3TOUT2_tout1Ptr + 1) += -xct[1]; |
|||
*(here->SOI3TOUT2_tout2Ptr + 1) += xct[1]+xct[2]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 3) |
|||
{ |
|||
*(here->SOI3TOUT2_tout3Ptr + 1) += -xct[2]; |
|||
*(here->SOI3TOUT3_tout2Ptr + 1) += -xct[2]; |
|||
*(here->SOI3TOUT3_tout3Ptr + 1) += xct[2]+xct[3]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 4) |
|||
{ |
|||
*(here->SOI3TOUT3_tout4Ptr + 1) += -xct[3]; |
|||
*(here->SOI3TOUT4_tout3Ptr + 1) += -xct[3]; |
|||
*(here->SOI3TOUT4_tout4Ptr + 1) += xct[3]+xct[4]; |
|||
} |
|||
*(here->SOI3GF_toutPtr + 1) += xcgfdeltaT*model->SOI3type; |
|||
*(here->SOI3DP_toutPtr + 1) += (xcddeltaT - xcBJTbddeltaT)*model->SOI3type; |
|||
*(here->SOI3SP_toutPtr + 1) += (xcsdeltaT - xcBJTbsdeltaT)*model->SOI3type; |
|||
*(here->SOI3B_toutPtr + 1) += model->SOI3type* |
|||
(xcbdeltaT + xcBJTbsdeltaT + xcBJTbddeltaT); |
|||
} |
|||
|
|||
|
|||
/* and now real part */ |
|||
*(here->SOI3D_dPtr) += (here->SOI3drainConductance); |
|||
*(here->SOI3S_sPtr) += (here->SOI3sourceConductance); |
|||
*(here->SOI3B_bPtr) += (here->SOI3gbd+here->SOI3gbs - |
|||
here->SOI3gMmbs |
|||
- here->SOI3gBJTdb_bs - here->SOI3gBJTsb_bd); |
|||
|
|||
*(here->SOI3DP_dpPtr) += |
|||
(here->SOI3drainConductance+here->SOI3gds+ |
|||
here->SOI3gbd+xrev*(here->SOI3gmf+here->SOI3gmbs+ |
|||
here->SOI3gmb)+xnrm*here->SOI3gMd); |
|||
*(here->SOI3SP_spPtr) += |
|||
(here->SOI3sourceConductance+here->SOI3gds+ |
|||
here->SOI3gbs+xnrm*(here->SOI3gmf+here->SOI3gmbs+ |
|||
here->SOI3gmb)+xrev*here->SOI3gMd); |
|||
|
|||
*(here->SOI3D_dpPtr) += (-here->SOI3drainConductance); |
|||
|
|||
*(here->SOI3S_spPtr) += (-here->SOI3sourceConductance); |
|||
*(here->SOI3B_gfPtr) += -here->SOI3gMmf; |
|||
*(here->SOI3B_gbPtr) += -(here->SOI3gMmb); |
|||
*(here->SOI3B_dpPtr) += -(here->SOI3gbd) + here->SOI3gBJTsb_bd + |
|||
xrev*(here->SOI3gMmf+here->SOI3gMmb+ |
|||
here->SOI3gMmbs+here->SOI3gMd) - |
|||
xnrm*here->SOI3gMd; |
|||
*(here->SOI3B_spPtr) += -(here->SOI3gbs) + here->SOI3gBJTdb_bs + |
|||
xnrm*(here->SOI3gMmf+here->SOI3gMmb+ |
|||
here->SOI3gMmbs+here->SOI3gMd) - |
|||
xrev*here->SOI3gMd; |
|||
*(here->SOI3DP_dPtr) += (-here->SOI3drainConductance); |
|||
*(here->SOI3SP_sPtr) += (-here->SOI3sourceConductance); |
|||
|
|||
*(here->SOI3DP_gfPtr) += ((xnrm-xrev)*here->SOI3gmf + |
|||
xnrm*here->SOI3gMmf); |
|||
*(here->SOI3DP_gbPtr) += ((xnrm-xrev)*here->SOI3gmb + |
|||
xnrm*here->SOI3gMmb); |
|||
*(here->SOI3DP_bPtr) += (-here->SOI3gbd + here->SOI3gBJTdb_bs |
|||
+(xnrm-xrev)*here->SOI3gmbs+ |
|||
xnrm*here->SOI3gMmbs); |
|||
*(here->SOI3DP_spPtr) += (-here->SOI3gds - here->SOI3gBJTdb_bs |
|||
-xnrm*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs + |
|||
here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)); |
|||
|
|||
*(here->SOI3SP_gfPtr) += (-(xnrm-xrev)*here->SOI3gmf+ |
|||
xrev*here->SOI3gMmf); |
|||
*(here->SOI3SP_gbPtr) += (-(xnrm-xrev)*here->SOI3gmb+ |
|||
xrev*here->SOI3gMmb); |
|||
*(here->SOI3SP_bPtr) += (-here->SOI3gbs + here->SOI3gBJTsb_bd |
|||
-(xnrm-xrev)*here->SOI3gmbs+ |
|||
xrev*here->SOI3gMmbs); |
|||
*(here->SOI3SP_dpPtr) += (-here->SOI3gds - here->SOI3gBJTsb_bd |
|||
-xrev*(here->SOI3gmf+here->SOI3gmb+here->SOI3gmbs+ |
|||
here->SOI3gMmf+here->SOI3gMmb+here->SOI3gMmbs+here->SOI3gMd)); |
|||
|
|||
/* if no thermal behaviour specified, then put in zero valued indpt. voltage source |
|||
between TOUT and ground */ |
|||
if (here->SOI3rt==0) |
|||
{ |
|||
*(here->SOI3TOUT_ibrPtr) += 1.0; |
|||
*(here->SOI3IBR_toutPtr) += 1.0; |
|||
*(ckt->CKTrhs + (here->SOI3branch)) = 0; |
|||
} |
|||
else |
|||
{ |
|||
*(here->SOI3TOUT_toutPtr) += -(here->SOI3gPdT)+grt[0]; |
|||
if (here->SOI3numThermalNodes > 1) |
|||
{ |
|||
*(here->SOI3TOUT_tout1Ptr) += -grt[0]; |
|||
*(here->SOI3TOUT1_toutPtr) += -grt[0]; |
|||
*(here->SOI3TOUT1_tout1Ptr) += grt[0]+grt[1]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 2) |
|||
{ |
|||
*(here->SOI3TOUT1_tout2Ptr) += -grt[1]; |
|||
*(here->SOI3TOUT2_tout1Ptr) += -grt[1]; |
|||
*(here->SOI3TOUT2_tout2Ptr) += grt[1]+grt[2]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 3) |
|||
{ |
|||
*(here->SOI3TOUT2_tout3Ptr) += -grt[2]; |
|||
*(here->SOI3TOUT3_tout2Ptr) += -grt[2]; |
|||
*(here->SOI3TOUT3_tout3Ptr) += grt[2]+grt[3]; |
|||
} |
|||
if (here->SOI3numThermalNodes > 4) |
|||
{ |
|||
*(here->SOI3TOUT3_tout4Ptr) += -grt[3]; |
|||
*(here->SOI3TOUT4_tout3Ptr) += -grt[3]; |
|||
*(here->SOI3TOUT4_tout4Ptr) += grt[3]+grt[4]; |
|||
} |
|||
|
|||
*(here->SOI3TOUT_dpPtr) += xnrm*(-(here->SOI3gPds*model->SOI3type)) |
|||
+xrev*(here->SOI3gPds+here->SOI3gPmf+ |
|||
here->SOI3gPmb+here->SOI3gPmbs)* |
|||
model->SOI3type; |
|||
*(here->SOI3TOUT_gfPtr) += -(here->SOI3gPmf*model->SOI3type); |
|||
*(here->SOI3TOUT_gbPtr) += -(here->SOI3gPmb*model->SOI3type); |
|||
*(here->SOI3TOUT_bPtr) += -(here->SOI3gPmbs*model->SOI3type); |
|||
*(here->SOI3TOUT_spPtr) += xnrm*(here->SOI3gPds+here->SOI3gPmf+ |
|||
here->SOI3gPmb+here->SOI3gPmbs)*model->SOI3type |
|||
+xrev*(-(here->SOI3gPds*model->SOI3type)); |
|||
|
|||
*(here->SOI3DP_toutPtr) += (xnrm-xrev)*here->SOI3gt*model->SOI3type; |
|||
*(here->SOI3SP_toutPtr) += (xrev-xnrm)*here->SOI3gt*model->SOI3type; |
|||
/* need to mult by type in above as conductances will be used with exterior voltages |
|||
which will be -ve for PMOS except for gPdT */ |
|||
/* now for thermal influence on impact ionisation current and tranisent stuff */ |
|||
*(here->SOI3DP_toutPtr) += (xnrm*here->SOI3gMdeltaT - |
|||
here->SOI3gbdT + here->SOI3gBJTdb_deltaT)*model->SOI3type; |
|||
*(here->SOI3SP_toutPtr) += (xrev*here->SOI3gMdeltaT - |
|||
here->SOI3gbsT + here->SOI3gBJTsb_deltaT)*model->SOI3type; |
|||
*(here->SOI3B_toutPtr) -= (here->SOI3gMdeltaT - here->SOI3gbsT - |
|||
here->SOI3gbdT + here->SOI3gBJTdb_deltaT + |
|||
here->SOI3gBJTsb_deltaT)*model->SOI3type; |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,505 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "cktdefs.h" |
|||
#include "devdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/*ARGSUSED*/ |
|||
int |
|||
SOI3ask(ckt,inst,which,value,select) |
|||
CKTcircuit *ckt; |
|||
GENinstance *inst; |
|||
int which; |
|||
IFvalue *value; |
|||
IFvalue *select; |
|||
{ |
|||
SOI3instance *here = (SOI3instance*)inst; |
|||
double vr; |
|||
double vi; |
|||
double sr; |
|||
double si; |
|||
double vm; |
|||
static char *msg = "Current and power not available for ac analysis"; |
|||
switch(which) { |
|||
case SOI3_L: |
|||
value->rValue = here->SOI3l; |
|||
return(OK); |
|||
case SOI3_W: |
|||
value->rValue = here->SOI3w; |
|||
return(OK); |
|||
case SOI3_NRS: |
|||
value->rValue = here->SOI3sourceSquares; |
|||
return(OK); |
|||
case SOI3_NRD: |
|||
value->rValue = here->SOI3drainSquares; |
|||
return(OK); |
|||
case SOI3_OFF: |
|||
value->rValue = here->SOI3off; |
|||
return(OK); |
|||
case SOI3_IC_VDS: |
|||
value->rValue = here->SOI3icVDS; |
|||
return(OK); |
|||
case SOI3_IC_VGFS: |
|||
value->rValue = here->SOI3icVGFS; |
|||
return(OK); |
|||
case SOI3_IC_VGBS: |
|||
value->rValue = here->SOI3icVGBS; |
|||
return(OK); |
|||
case SOI3_IC_VBS: |
|||
value->rValue = here->SOI3icVBS; |
|||
return(OK); |
|||
case SOI3_TEMP: |
|||
value->rValue = here->SOI3temp-CONSTCtoK; |
|||
return(OK); |
|||
case SOI3_RT: |
|||
value->rValue = here->SOI3rt; |
|||
return(OK); |
|||
case SOI3_CT: |
|||
value->rValue = here->SOI3ct; |
|||
return(OK); |
|||
case SOI3_DNODE: |
|||
value->iValue = here->SOI3dNode; |
|||
return(OK); |
|||
case SOI3_GFNODE: |
|||
value->iValue = here->SOI3gfNode; |
|||
return(OK); |
|||
case SOI3_SNODE: |
|||
value->iValue = here->SOI3sNode; |
|||
return(OK); |
|||
case SOI3_GBNODE: |
|||
value->iValue = here->SOI3gbNode; |
|||
return(OK); |
|||
case SOI3_BNODE: |
|||
value->iValue = here->SOI3bNode; |
|||
return(OK); |
|||
case SOI3_DNODEPRIME: |
|||
value->iValue = here->SOI3dNodePrime; |
|||
return(OK); |
|||
case SOI3_SNODEPRIME: |
|||
value->iValue = here->SOI3sNodePrime; |
|||
return(OK); |
|||
case SOI3_TNODE: |
|||
value->iValue = here->SOI3toutNode; |
|||
return(OK); |
|||
case SOI3_BRANCH: |
|||
value->iValue = here->SOI3branch; |
|||
return(OK); |
|||
case SOI3_SOURCECONDUCT: |
|||
value->rValue = here->SOI3sourceConductance; |
|||
return(OK); |
|||
case SOI3_DRAINCONDUCT: |
|||
value->rValue = here->SOI3drainConductance; |
|||
return(OK); |
|||
case SOI3_VON: |
|||
value->rValue = here->SOI3tVto; |
|||
return(OK); |
|||
case SOI3_VFBF: |
|||
value->rValue = here->SOI3tVfbF; |
|||
return(OK); |
|||
case SOI3_VDSAT: |
|||
value->rValue = here->SOI3vdsat; |
|||
return(OK); |
|||
case SOI3_SOURCEVCRIT: |
|||
value->rValue = here->SOI3sourceVcrit; |
|||
return(OK); |
|||
case SOI3_DRAINVCRIT: |
|||
value->rValue = here->SOI3drainVcrit; |
|||
return(OK); |
|||
case SOI3_ID: |
|||
value->rValue = here->SOI3id; |
|||
return(OK); |
|||
case SOI3_IBS: |
|||
value->rValue = here->SOI3ibs; |
|||
return(OK); |
|||
case SOI3_IBD: |
|||
value->rValue = here->SOI3ibd; |
|||
return(OK); |
|||
case SOI3_GMBS: |
|||
value->rValue = here->SOI3gmbs; |
|||
return(OK); |
|||
case SOI3_GMF: |
|||
value->rValue = here->SOI3gmf; |
|||
return(OK); |
|||
case SOI3_GMB: |
|||
value->rValue = here->SOI3gmb; |
|||
return(OK); |
|||
case SOI3_GDS: |
|||
value->rValue = here->SOI3gds; |
|||
return(OK); |
|||
case SOI3_GBD: |
|||
value->rValue = here->SOI3gbd; |
|||
return(OK); |
|||
case SOI3_GBS: |
|||
value->rValue = here->SOI3gbs; |
|||
return(OK); |
|||
case SOI3_CAPBD: |
|||
value->rValue = here->SOI3capbd; |
|||
return(OK); |
|||
case SOI3_CAPBS: |
|||
value->rValue = here->SOI3capbs; |
|||
return(OK); |
|||
case SOI3_CAPZEROBIASBD: |
|||
value->rValue = here->SOI3Cbd; |
|||
return(OK); |
|||
case SOI3_CAPZEROBIASBS: |
|||
value->rValue = here->SOI3Cbs; |
|||
return(OK); |
|||
case SOI3_VBD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3vbd); |
|||
return(OK); |
|||
case SOI3_VBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3vbs); |
|||
return(OK); |
|||
case SOI3_VGFS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3vgfs); |
|||
return(OK); |
|||
case SOI3_VGBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3vgbs); |
|||
return(OK); |
|||
case SOI3_VDS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3vds); |
|||
return(OK); |
|||
case SOI3_QGF: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3qgf); |
|||
return(OK); |
|||
case SOI3_IQGF: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqgf); |
|||
return(OK); |
|||
case SOI3_QD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3qd); |
|||
return(OK); |
|||
case SOI3_IQD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqd); |
|||
return(OK); |
|||
case SOI3_QS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3qs); |
|||
return(OK); |
|||
case SOI3_IQS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqs); |
|||
return(OK); |
|||
case SOI3_CGFGF: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cgfgf); |
|||
return (OK); |
|||
case SOI3_CGFD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cgfd); |
|||
return (OK); |
|||
case SOI3_CGFS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cgfs); |
|||
return (OK); |
|||
case SOI3_CGFDELTAT: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cgfdeltaT); |
|||
return (OK); |
|||
case SOI3_CDGF: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cdgf); |
|||
return (OK); |
|||
case SOI3_CDD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cdd); |
|||
return (OK); |
|||
case SOI3_CDS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cds); |
|||
return (OK); |
|||
case SOI3_CDDELTAT: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3cddeltaT); |
|||
return (OK); |
|||
case SOI3_CSGF: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3csgf); |
|||
return (OK); |
|||
case SOI3_CSD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3csd); |
|||
return (OK); |
|||
case SOI3_CSS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3css); |
|||
return (OK); |
|||
case SOI3_CSDELTAT: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3csdeltaT); |
|||
return (OK); |
|||
case SOI3_QBD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3qbd); |
|||
return(OK); |
|||
case SOI3_IQBD: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqbd); |
|||
return(OK); |
|||
case SOI3_QBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3qbs); |
|||
return(OK); |
|||
case SOI3_IQBS: |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqbs); |
|||
return(OK); |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
case SOI3_VFBB: |
|||
value->rValue = here->SOI3tVfbB; |
|||
return(OK); |
|||
case SOI3_RT1: |
|||
value->rValue = here->SOI3rt1; |
|||
return(OK); |
|||
case SOI3_CT1: |
|||
value->rValue = here->SOI3ct1; |
|||
return(OK); |
|||
case SOI3_RT2: |
|||
value->rValue = here->SOI3rt2; |
|||
return(OK); |
|||
case SOI3_CT2: |
|||
value->rValue = here->SOI3ct2; |
|||
return(OK); |
|||
case SOI3_RT3: |
|||
value->rValue = here->SOI3rt3; |
|||
return(OK); |
|||
case SOI3_CT3: |
|||
value->rValue = here->SOI3ct3; |
|||
return(OK); |
|||
case SOI3_RT4: |
|||
value->rValue = here->SOI3rt4; |
|||
return(OK); |
|||
case SOI3_CT4: |
|||
value->rValue = here->SOI3ct4; |
|||
return(OK); |
|||
|
|||
/* |
|||
case SOI3_L_SENS_DC: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
} |
|||
return(OK); |
|||
case SOI3_L_SENS_REAL: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
} |
|||
return(OK); |
|||
case SOI3_L_SENS_IMAG: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
} |
|||
return(OK); |
|||
case SOI3_L_SENS_MAG: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
vr = *(ckt->CKTrhsOld + select->iValue + 1); |
|||
vi = *(ckt->CKTirhsOld + select->iValue + 1); |
|||
vm = sqrt(vr*vr + vi*vi); |
|||
if(vm == 0){ |
|||
value->rValue = 0; |
|||
return(OK); |
|||
} |
|||
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
value->rValue = (vr * sr + vi * si)/vm; |
|||
} |
|||
return(OK); |
|||
case SOI3_L_SENS_PH: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
vr = *(ckt->CKTrhsOld + select->iValue + 1); |
|||
vi = *(ckt->CKTirhsOld + select->iValue + 1); |
|||
vm = vr*vr + vi*vi; |
|||
if(vm == 0){ |
|||
value->rValue = 0; |
|||
return(OK); |
|||
} |
|||
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
value->rValue = (vr * si - vi * sr)/vm; |
|||
} |
|||
return(OK); |
|||
case SOI3_L_SENS_CPLX: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_l){ |
|||
value->cValue.real= |
|||
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
value->cValue.imag= |
|||
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo); |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_DC: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_REAL: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_IMAG: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_MAG: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
vr = *(ckt->CKTrhsOld + select->iValue + 1); |
|||
vi = *(ckt->CKTirhsOld + select->iValue + 1); |
|||
vm = sqrt(vr*vr + vi*vi); |
|||
if(vm == 0){ |
|||
value->rValue = 0; |
|||
return(OK); |
|||
} |
|||
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
value->rValue = (vr * sr + vi * si)/vm; |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_PH: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
vr = *(ckt->CKTrhsOld + select->iValue + 1); |
|||
vi = *(ckt->CKTirhsOld + select->iValue + 1); |
|||
vm = vr*vr + vi*vi; |
|||
if(vm == 0){ |
|||
value->rValue = 0; |
|||
return(OK); |
|||
} |
|||
sr = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
value->rValue = (vr * si - vi * sr)/vm; |
|||
} |
|||
return(OK); |
|||
case SOI3_W_SENS_CPLX: |
|||
if(ckt->CKTsenInfo && here->SOI3sens_w){ |
|||
value->cValue.real= |
|||
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
value->cValue.imag= |
|||
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->SOI3senParmNo + here->SOI3sens_l); |
|||
} |
|||
return(OK); */ |
|||
|
|||
/* |
|||
case SOI3_IS : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = MALLOC(strlen(msg)+1); |
|||
errRtn = "SOI3ask.c"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKCURRENT); |
|||
} else { |
|||
value->rValue = -here->SOI3id; |
|||
value->rValue -= here->SOI3ibd + here->SOI3ibs - |
|||
*(ckt->CKTstate0 + here->SOI3iqgfb); |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
!(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue -= *(ckt->CKTstate0 + here->SOI3iqgfb) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfd) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfs); |
|||
} |
|||
} |
|||
return(OK); |
|||
case SOI3_IB : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = MALLOC(strlen(msg)+1); |
|||
errRtn = "SOI3ask.c"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKCURRENT); |
|||
} else { |
|||
value->rValue = here->SOI3ibd + here->SOI3ibs - |
|||
*(ckt->CKTstate0 + here->SOI3iqgfb); |
|||
} |
|||
return(OK); |
|||
case SOI3_IGF : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = MALLOC(strlen(msg)+1); |
|||
errRtn = "SOI3ask.c"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKCURRENT); |
|||
} else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) { |
|||
value->rValue = 0; |
|||
} else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue = 0; |
|||
} else { |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqgfb) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfd) + *(ckt->CKTstate0 + |
|||
here->SOI3iqgfs); |
|||
} |
|||
return(OK); |
|||
case SOI3_IGB : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = MALLOC(strlen(msg)+1); |
|||
errRtn = "SOI3ask.c"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKCURRENT); |
|||
} else if (ckt->CKTcurrentAnalysis & (DOING_DCOP | DOING_TRCV)) { |
|||
value->rValue = 0; |
|||
} else if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue = 0; |
|||
} else { |
|||
value->rValue = *(ckt->CKTstate0 + here->SOI3iqgfb) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfd) + *(ckt->CKTstate0 + |
|||
here->SOI3iqgfs); |
|||
} |
|||
return(OK); |
|||
case SOI3_POWER : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = MALLOC(strlen(msg)+1); |
|||
errRtn = "SOI3ask.c"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKPOWER); |
|||
} else { |
|||
double temp; |
|||
|
|||
value->rValue = here->SOI3id * |
|||
*(ckt->CKTrhsOld + here->SOI3dNode); |
|||
value->rValue += ((here->SOI3ibd + here->SOI3ibs) - |
|||
*(ckt->CKTstate0 + here->SOI3iqgfb)) * |
|||
*(ckt->CKTrhsOld + here->SOI3bNode); |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
!(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue += (*(ckt->CKTstate0 + here->SOI3iqgfb) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfd) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfs)) * |
|||
*(ckt->CKTrhsOld + here->SOI3gfNode); |
|||
} |
|||
temp = -here->SOI3id; |
|||
temp -= here->SOI3ibd + here->SOI3ibs ; |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
!(ckt->CKTmode & MODETRANOP)) { |
|||
temp -= *(ckt->CKTstate0 + here->SOI3iqgfb) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfd) + |
|||
*(ckt->CKTstate0 + here->SOI3iqgfs); |
|||
} |
|||
value->rValue += temp * *(ckt->CKTrhsOld + here->SOI3sNode); |
|||
} |
|||
return(OK); |
|||
*/ |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
/* NOTREACHED */ |
|||
} |
|||
|
|||
@ -0,0 +1,590 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "suffix.h" |
|||
#include "soi3defs.h" |
|||
#include "trandefs.h" |
|||
#include "const.h" |
|||
|
|||
|
|||
void |
|||
SOI3cap(vgB,Phiplusvsb,gammaB, |
|||
paramargs, |
|||
Bfargs,alpha_args,psi_st0args, |
|||
vGTargs, |
|||
psi_sLargs,psi_s0args, |
|||
ldargs, |
|||
Qg,Qb,Qd,QgB, |
|||
cggf,cgd,cgs,cgdeltaT, |
|||
cbgf,cbd,cbs,cbdeltaT,cbgb, |
|||
cdgf,cdd,cds,cddeltaT, |
|||
cgbgb,cgbsb |
|||
) |
|||
|
|||
double vgB,Phiplusvsb,gammaB; |
|||
double paramargs[10]; |
|||
double Bfargs[2],alpha_args[5]; |
|||
double psi_st0args[5]; |
|||
double vGTargs[5]; |
|||
double psi_sLargs[5],psi_s0args[5]; |
|||
double ldargs[5]; |
|||
|
|||
double *Qg,*Qb,*Qd,*QgB; |
|||
double *cggf,*cgd,*cgs,*cgdeltaT; |
|||
double *cbgf,*cbd,*cbs,*cbdeltaT,*cbgb; |
|||
double *cdgf,*cdd,*cds,*cddeltaT; |
|||
double *cgbgb,*cgbsb; |
|||
|
|||
|
|||
/****** Part 1 - declare local variables. ******/ |
|||
|
|||
{ |
|||
double WCox,WCob,L; |
|||
double gamma,eta_s,vt,delta,sigma,chiFB; |
|||
double Bf,pDBf_Dpsi_st0; |
|||
double alpha,Dalpha_Dvgfb,Dalpha_Dvdb,Dalpha_Dvsb,Dalpha_DdeltaT; |
|||
double Dpsi_st0_Dvgfb,Dpsi_st0_Dvdb,Dpsi_st0_Dvsb,Dpsi_st0_DdeltaT; |
|||
double vGT,DvGT_Dvgfb,DvGT_Dvdb,DvGT_Dvsb,DvGT_DdeltaT; |
|||
double psi_sL,Dpsi_sL_Dvgfb,Dpsi_sL_Dvdb,Dpsi_sL_Dvsb,Dpsi_sL_DdeltaT; |
|||
double psi_s0,Dpsi_s0_Dvgfb,Dpsi_s0_Dvdb,Dpsi_s0_Dvsb,Dpsi_s0_DdeltaT; |
|||
double ld,Dld_Dvgfb,Dld_Dvdb,Dld_Dvsb,Dld_DdeltaT; |
|||
|
|||
double Lprime,Fc; |
|||
double Qbprime,Qcprime,Qdprime,Qgprime,Qb2prime,Qc2prime,Qd2prime,Qg2prime; |
|||
double Dlimc,Dlimd; |
|||
double Vqd,Vqs; |
|||
double F,F2; |
|||
double cq,dq; |
|||
double dercq,derdq; |
|||
double sigmaC,Eqc,Eqd; |
|||
double DVqs_Dvgfb,DVqs_Dvdb,DVqs_Dvsb,DVqs_DdeltaT; |
|||
double DF_Dvgfb,DF_Dvdb,DF_Dvsb,DF_DdeltaT; |
|||
double ccgf,ccd,ccs,ccdeltaT; |
|||
|
|||
double A0B,EA0B,tmpsb; |
|||
double Vgmax0B,VgBx0,EBmax0,tmpmax0,tmpmaxsb; |
|||
double VgBy0,EBy0,tmpmin0; |
|||
double SgB0; |
|||
|
|||
double vg,vgacc,Egacc,tmpacc,Qacc; |
|||
double csf; |
|||
|
|||
/****** Part 2 - extract variables passed from soi3load(), which ******/ |
|||
/****** have been passed to soi3cap() in *arg arrays. ******/ |
|||
|
|||
WCox = paramargs[0]; |
|||
L = paramargs[1]; |
|||
gamma = paramargs[2]; |
|||
eta_s = paramargs[3]; |
|||
vt = paramargs[4]; |
|||
delta = paramargs[5]; |
|||
WCob = paramargs[6]; |
|||
sigma = paramargs[7]; |
|||
chiFB = paramargs[8]; |
|||
csf = paramargs[9]; |
|||
Bf = Bfargs[0]; |
|||
pDBf_Dpsi_st0 = Bfargs[1]; |
|||
alpha = alpha_args[0]; |
|||
Dalpha_Dvgfb = alpha_args[1]; |
|||
Dalpha_Dvdb = alpha_args[2]; |
|||
Dalpha_Dvsb = alpha_args[3]; |
|||
Dalpha_DdeltaT = alpha_args[4]; |
|||
|
|||
Dpsi_st0_Dvgfb = psi_st0args[1]; |
|||
Dpsi_st0_Dvdb = psi_st0args[2]; |
|||
Dpsi_st0_Dvsb = psi_st0args[3]; |
|||
Dpsi_st0_DdeltaT = psi_st0args[4]; |
|||
|
|||
vGT = vGTargs[0]; |
|||
DvGT_Dvgfb = vGTargs[1]; |
|||
DvGT_Dvdb = vGTargs[2]; |
|||
DvGT_Dvsb = vGTargs[3]; |
|||
DvGT_DdeltaT = vGTargs[4]; |
|||
|
|||
psi_sL = psi_sLargs[0]; |
|||
Dpsi_sL_Dvgfb = psi_sLargs[1]; |
|||
Dpsi_sL_Dvdb = psi_sLargs[2]; |
|||
Dpsi_sL_Dvsb = psi_sLargs[3]; |
|||
Dpsi_sL_DdeltaT = psi_sLargs[4]; |
|||
psi_s0 = psi_s0args[0]; |
|||
Dpsi_s0_Dvgfb = psi_s0args[1]; |
|||
Dpsi_s0_Dvdb = psi_s0args[2]; |
|||
Dpsi_s0_Dvsb = psi_s0args[3]; |
|||
Dpsi_s0_DdeltaT = psi_s0args[4]; |
|||
ld = ldargs[0]; |
|||
Dld_Dvgfb = ldargs[1]; |
|||
Dld_Dvdb = ldargs[2]; |
|||
Dld_Dvsb = ldargs[3]; |
|||
Dld_DdeltaT = ldargs[4]; |
|||
|
|||
|
|||
/****** Part 3 - define some important quantities. ******/ |
|||
|
|||
sigmaC = 1E-8; |
|||
|
|||
Vqd = (vGT - alpha*psi_sL); /* This is -qd/Cof */ |
|||
Vqs = (vGT - alpha*psi_s0); /* This is -qs/Cof */ |
|||
if (Vqs<=0) { /* deep subthreshold contingency */ |
|||
F = 1; |
|||
} else { |
|||
F = Vqd/Vqs; |
|||
if (F<0) { /* physically impossible situation */ |
|||
F=0; |
|||
} |
|||
} |
|||
F2 = F*F; |
|||
|
|||
Fc = 1 + ld/L; |
|||
Lprime = L/Fc; |
|||
|
|||
|
|||
/****** Part 4 - calculate normalised (see note below) terminal ******/ |
|||
/****** charge expressions for the GCA region. ******/ |
|||
|
|||
/* JimB - important note */ |
|||
/* The charge expressions Qcprime, Qd2prime etc in this file are not charges */ |
|||
/* but voltages! Each expression is equal to the derived expression for the */ |
|||
/* total charge in each region, but divided by a factor WL'Cof. This is */ |
|||
/* compensated for later on. */ |
|||
|
|||
/* Channel charge Qc1 */ |
|||
cq = (F*F + F + 1)/(F+1); |
|||
Qcprime = -2*Vqs*cq/3; |
|||
|
|||
if ((-Qcprime/sigmaC)<MAX_EXP_ARG) { |
|||
Eqc = exp(-Qcprime/sigmaC); |
|||
Qcprime = -sigmaC*log(1 + Eqc); |
|||
Dlimc = Eqc/(1+Eqc); |
|||
} else { |
|||
Dlimc = 1; |
|||
} |
|||
|
|||
/* Drain charge Qd1 */ |
|||
dq = (3*F2*F + 6*F2 + 4*F + 2)/((1+F)*(1+F)); |
|||
Qdprime = -2*Vqs*dq/15; |
|||
|
|||
if((-Qdprime/sigmaC)<MAX_EXP_ARG) { |
|||
Eqd = exp(-Qdprime/sigmaC); |
|||
Qdprime = -sigmaC*log(1 + Eqd); |
|||
Dlimd = Eqd/(1+Eqd); |
|||
} else { |
|||
Dlimd = 1; |
|||
} |
|||
|
|||
/* Body charge Qb1 */ |
|||
Qbprime = -gamma*(Bf + (delta/alpha)*(vGT + Qcprime)); |
|||
|
|||
/* Gate charge Qg1 */ |
|||
Qgprime = -Qcprime-Qbprime; |
|||
|
|||
|
|||
/****** Part 5 - calculate capacitances and transcapacitances ******/ |
|||
/****** for the GCA region. For the moment, we are not taking ******/ |
|||
/****** account of the bias dependence of ld and Lprime. This ******/ |
|||
/****** will be done in Part 8, when both GCA and drain charge ******/ |
|||
/****** terms will be included in the final capacitance ******/ |
|||
/****** expressions. ******/ |
|||
|
|||
DVqs_Dvgfb = DvGT_Dvgfb - alpha*Dpsi_s0_Dvgfb - psi_s0*Dalpha_Dvgfb; |
|||
DVqs_Dvdb = DvGT_Dvdb - alpha*Dpsi_s0_Dvdb - psi_s0*Dalpha_Dvdb; |
|||
DVqs_Dvsb = DvGT_Dvsb - alpha*Dpsi_s0_Dvsb - psi_s0*Dalpha_Dvsb; |
|||
DVqs_DdeltaT = DvGT_DdeltaT - alpha*Dpsi_s0_DdeltaT - psi_s0*Dalpha_DdeltaT; |
|||
|
|||
if (Vqs==0) { |
|||
DF_Dvgfb = 0; |
|||
DF_Dvdb = 0; |
|||
DF_Dvsb = 0; |
|||
DF_DdeltaT = 0; |
|||
} else { |
|||
DF_Dvgfb = (DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb - |
|||
F*DVqs_Dvgfb)/Vqs; |
|||
DF_Dvdb = (DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb - |
|||
F*DVqs_Dvdb)/Vqs; |
|||
DF_Dvsb = (DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb - |
|||
F*DVqs_Dvsb)/Vqs; |
|||
DF_DdeltaT = (DvGT_DdeltaT - alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT - |
|||
F*DVqs_DdeltaT)/Vqs; |
|||
} |
|||
|
|||
dercq = F*(2+F)/((1+F)*(1+F)); |
|||
|
|||
ccgf = Dlimc*(-2*(DVqs_Dvgfb*cq + Vqs*dercq*DF_Dvgfb)/3); |
|||
ccd = Dlimc*(-2*(DVqs_Dvdb*cq + Vqs*dercq*DF_Dvdb)/3); |
|||
ccs = Dlimc*(-2*(DVqs_Dvsb*cq + Vqs*dercq*DF_Dvsb)/3); |
|||
ccdeltaT = Dlimc*(-2*(DVqs_DdeltaT*cq + Vqs*dercq*DF_DdeltaT)/3); |
|||
|
|||
derdq = F*(3*F2 + 9*F + 8)/((1+F)*(1+F)*(1+F)); |
|||
|
|||
*cdgf = Dlimd*(-2*(DVqs_Dvgfb * dq + Vqs*derdq*DF_Dvgfb)/15); |
|||
*cdd = Dlimd*(-2*(DVqs_Dvdb * dq + Vqs*derdq*DF_Dvdb)/15); |
|||
*cds = Dlimd*(-2*(DVqs_Dvsb * dq + Vqs*derdq*DF_Dvsb)/15); |
|||
*cddeltaT = Dlimd*(-2*(DVqs_DdeltaT * dq + Vqs*derdq*DF_DdeltaT)/15); |
|||
|
|||
/* JimB - note that for the following expressions, the Vx dependence of */ |
|||
/* delta is accounted for by the term (vGT+Qcprime)*(Dalpha_Dvx/gamma). */ |
|||
|
|||
*cbgf = -gamma * (pDBf_Dpsi_st0*Dpsi_st0_Dvgfb + |
|||
(alpha*(delta*(DvGT_Dvgfb + ccgf) + |
|||
(vGT+Qcprime)*(Dalpha_Dvgfb/gamma)) - |
|||
delta*(vGT+Qcprime)*Dalpha_Dvgfb |
|||
)/(alpha*alpha) |
|||
); |
|||
*cbd = -gamma * (pDBf_Dpsi_st0*Dpsi_st0_Dvdb + |
|||
(alpha*(delta*(DvGT_Dvdb + ccd) + |
|||
(vGT+Qcprime)*(Dalpha_Dvdb/gamma)) - |
|||
delta*(vGT+Qcprime)*Dalpha_Dvdb |
|||
)/(alpha*alpha) |
|||
); |
|||
*cbs = -gamma * (pDBf_Dpsi_st0*Dpsi_st0_Dvsb + |
|||
(alpha*(delta*(DvGT_Dvsb + ccs) + |
|||
(vGT+Qcprime)*(Dalpha_Dvsb/gamma)) - |
|||
delta*(vGT+Qcprime)*Dalpha_Dvsb |
|||
)/(alpha*alpha) |
|||
); |
|||
*cbdeltaT = -gamma * (pDBf_Dpsi_st0*Dpsi_st0_DdeltaT + |
|||
(alpha*(delta*(DvGT_DdeltaT + ccdeltaT) + |
|||
(vGT+Qcprime)*(Dalpha_DdeltaT/gamma)) - |
|||
delta*(vGT+Qcprime)*Dalpha_DdeltaT |
|||
)/(alpha*alpha) |
|||
); |
|||
|
|||
|
|||
/****** Part 6 - Normalised expressions from part 4 are adjusted ******/ |
|||
/****** by WCox*Lprime, then accumulation charge is added to give ******/ |
|||
/****** final expression for GCA region charges. ******/ |
|||
|
|||
/* Accumulation charge to be added to Qb */ |
|||
|
|||
vg = vGT + gamma*Bf; |
|||
if ((-vg/vt) > MAX_EXP_ARG) { |
|||
vgacc = vg; |
|||
tmpacc = 1; |
|||
} else { |
|||
Egacc = exp(-vg/vt); |
|||
vgacc = -vt*log(1+Egacc); |
|||
tmpacc = Egacc/(1+Egacc); |
|||
} |
|||
Qacc = -WCox*L*vgacc; |
|||
|
|||
/* Now work out GCA region charges */ |
|||
|
|||
*Qb = WCox*Lprime*Qbprime + Qacc; |
|||
|
|||
*Qd = WCox*Lprime*Qdprime; |
|||
|
|||
*Qg = WCox*Lprime*Qgprime - Qacc; |
|||
|
|||
|
|||
/****** Part 7 - calculate normalised (see note below) terminal ******/ |
|||
/****** charge expressions for the saturated drain region. ******/ |
|||
|
|||
Qc2prime = -Vqd; |
|||
|
|||
/* Basic expression for the intrinsic body charge in the saturation region is */ |
|||
/* modified by csf, to reflect the fact that the body charge will be shared */ |
|||
/* between the gate and the drain/body depletion region. This factor must be */ |
|||
/* between 0 and 1, since it represents the fraction of ld over which qb is */ |
|||
/* integrated to give Qb2. */ |
|||
Qb2prime = -gamma*csf*(Bf + delta*psi_sL); |
|||
|
|||
Qd2prime = 0.5*Qc2prime; |
|||
/* JimB - 9/1/99. Re-partition drain region charge */ |
|||
/* Qd2prime = Qc2prime; */ |
|||
|
|||
Qg2prime = -Qc2prime-Qb2prime; |
|||
|
|||
*Qb += WCox*ld*Qb2prime; |
|||
*Qd += WCox*ld*Qd2prime; |
|||
*Qg += WCox*ld*Qg2prime; |
|||
|
|||
|
|||
/****** Part 8 - calculate full capacitance expressions, accounting ******/ |
|||
/****** for both GCA and drain region contributions. As explained ******/ |
|||
/****** in part 5, *cbgf, *cbd etc only derivatives of GCA charge ******/ |
|||
/****** expression w.r.t. Vx. Now need to include Lprime/ld ******/ |
|||
/****** dependence on Vx as well. ******/ |
|||
|
|||
*cbgf = WCox*(Lprime*(*cbgf) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvgfb + delta*Dpsi_sL_Dvgfb + |
|||
(psi_sL*Dalpha_Dvgfb/gamma)) + |
|||
(Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvgfb |
|||
); |
|||
*cbd = WCox*(Lprime*(*cbd) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvdb + delta*Dpsi_sL_Dvdb + |
|||
(psi_sL*Dalpha_Dvdb/gamma)) + |
|||
(Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvdb |
|||
); |
|||
*cbs = WCox*(Lprime*(*cbs) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_Dvsb + delta*Dpsi_sL_Dvsb + |
|||
(psi_sL*Dalpha_Dvsb/gamma)) + |
|||
(Qb2prime - Qbprime/(Fc*Fc))*Dld_Dvsb |
|||
); |
|||
*cbdeltaT = WCox*(Lprime*(*cbdeltaT) - ld*csf*(pDBf_Dpsi_st0*Dpsi_st0_DdeltaT + delta*Dpsi_sL_DdeltaT + |
|||
(psi_sL*Dalpha_DdeltaT/gamma)) + |
|||
(Qb2prime - Qbprime/(Fc*Fc))*Dld_DdeltaT |
|||
); |
|||
|
|||
|
|||
ccgf = WCox*(Lprime*(ccgf) - ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + |
|||
(Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvgfb |
|||
); |
|||
ccd = WCox*(Lprime*(ccd) - ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + |
|||
(Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvdb |
|||
); |
|||
ccs = WCox*(Lprime*(ccs) - ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + |
|||
(Qc2prime - Qcprime/(Fc*Fc))*Dld_Dvsb |
|||
); |
|||
ccdeltaT = WCox*(Lprime*(ccdeltaT) - |
|||
ld*(DvGT_DdeltaT - alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + |
|||
(Qc2prime - Qcprime/(Fc*Fc))*Dld_DdeltaT |
|||
); |
|||
|
|||
|
|||
/* JimB - 9/1/99. Re-partition drain region charge */ |
|||
|
|||
/* |
|||
*cdgf = WCox*(Lprime*(*cdgf) - ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvgfb |
|||
); |
|||
*cdd = WCox*(Lprime*(*cdd) - ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvdb |
|||
); |
|||
*cds = WCox*(Lprime*(*cds) - ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvsb |
|||
); |
|||
*cddeltaT = WCox*(Lprime*(*cddeltaT) - ld*(DvGT_DdeltaT - |
|||
alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_DdeltaT |
|||
); |
|||
*/ |
|||
|
|||
*cdgf = WCox*(Lprime*(*cdgf) - 0.5*ld*(DvGT_Dvgfb - alpha*Dpsi_sL_Dvgfb - psi_sL*Dalpha_Dvgfb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvgfb |
|||
); |
|||
*cdd = WCox*(Lprime*(*cdd) - 0.5*ld*(DvGT_Dvdb - alpha*Dpsi_sL_Dvdb - psi_sL*Dalpha_Dvdb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvdb |
|||
); |
|||
*cds = WCox*(Lprime*(*cds) - 0.5*ld*(DvGT_Dvsb - alpha*Dpsi_sL_Dvsb - psi_sL*Dalpha_Dvsb) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_Dvsb |
|||
); |
|||
*cddeltaT = WCox*(Lprime*(*cddeltaT) - 0.5*ld*(DvGT_DdeltaT - |
|||
alpha*Dpsi_sL_DdeltaT - psi_sL*Dalpha_DdeltaT) + |
|||
(Qd2prime - Qdprime/(Fc*Fc))*Dld_DdeltaT |
|||
); |
|||
|
|||
|
|||
/****** Part 9 - Finally, include accumulation charge derivatives. ******/ |
|||
|
|||
/* Now include accumulation charge derivs */ |
|||
|
|||
*cbgf += -WCox*L*tmpacc; |
|||
*cbd += -WCox*L*tmpacc*sigma; |
|||
*cbs += -WCox*L*tmpacc*(-sigma); |
|||
*cbdeltaT += -WCox*L*tmpacc*chiFB; |
|||
|
|||
*cggf = -(ccgf + *cbgf); |
|||
*cgd = -(ccd + *cbd); |
|||
*cgs = -(ccs + *cbs); |
|||
*cgdeltaT = -(ccdeltaT + *cbdeltaT); |
|||
|
|||
|
|||
/****** Part 10 - Back gate stuff - doesn't work, so commented out. ******/ |
|||
|
|||
/* front gate stuff is self consistent by itself, now add in back gate stuff |
|||
we're not too interested in EXACT back gate behaviour, so this is quite a |
|||
rough model. |
|||
But even this causes convergence problems in transient - so leave it out |
|||
for now. Scope for further work. |
|||
*/ |
|||
/* |
|||
if (Phiplusvsb > vt*MAX_EXP_ARG) { |
|||
A0B = Phiplusvsb; |
|||
tmpsb = 1; |
|||
} else { |
|||
EA0B = exp(Phiplusvsb/vt); |
|||
A0B = vt*log(1+EA0B); |
|||
tmpsb = EA0B/(1+EA0B); |
|||
} |
|||
|
|||
Vgmax0B = A0B + gammaB*sqrt(A0B); |
|||
|
|||
if ((Vgmax0B-vgB)>vt*MAX_EXP_ARG) { |
|||
VgBx0=vgB; |
|||
tmpmax0 = 1; |
|||
tmpmaxsb = 0; |
|||
} else { |
|||
EBmax0 = exp((Vgmax0B - vgB)/vt); |
|||
VgBx0=Vgmax0B - vt*log(1+EBmax0); |
|||
tmpmax0 = EBmax0/(1+EBmax0); |
|||
tmpmaxsb = 1/(1+EBmax0); |
|||
} |
|||
|
|||
if (VgBx0>vt*MAX_EXP_ARG) { |
|||
VgBy0 = VgBx0; |
|||
tmpmin0 = 1; |
|||
} else { |
|||
EBy0 = exp(VgBx0/vt); |
|||
VgBy0 = vt*log(1+EBy0); |
|||
tmpmin0 = EBy0/(1+EBy0); |
|||
} |
|||
|
|||
SgB0 = sqrt(gammaB*gammaB + 4*VgBy0); |
|||
|
|||
*QgB = -WCob*L*gammaB*0.5*(gammaB-SgB0); |
|||
*Qb -= *QgB; |
|||
|
|||
*cgbgb = (WCob*L*gammaB/SgB0)*tmpmin0*tmpmax0; |
|||
*cgbsb = (WCob*L*gammaB/SgB0)*tmpmin0*tmpmaxsb*(1+0.5*gammaB/sqrt(A0B))*tmpsb; |
|||
|
|||
*cbgb = -(*cgbgb); |
|||
*cbs -= *cgbsb; |
|||
*/ |
|||
|
|||
*QgB = 0; |
|||
*cbgb = 0; |
|||
*cgbgb = 0; |
|||
*cgbsb = 0; |
|||
|
|||
} |
|||
|
|||
void |
|||
SOI3capEval(ckt, |
|||
Frontcapargs, |
|||
Backcapargs, |
|||
cgfgf,cgfd,cgfs,cgfdeltaT, |
|||
cdgf,cdd,cds,cddeltaT, |
|||
csgf,csd,css,csdeltaT, |
|||
cbgf,cbd,cbs,cbdeltaT,cbgb, |
|||
cgbgb,cgbsb, |
|||
gcgfgf,gcgfd,gcgfs,gcgfdeltaT, |
|||
gcdgf,gcdd,gcds,gcddeltaT, |
|||
gcsgf,gcsd,gcss,gcsdeltaT, |
|||
gcbgf,gcbd,gcbs,gcbdeltaT,gcbgb, |
|||
gcgbgb,gcgbsb,gcgbdb, |
|||
gcgbs0,gcgbd0, |
|||
qgatef,qbody,qdrn,qsrc,qgateb) |
|||
|
|||
register CKTcircuit *ckt; |
|||
double Frontcapargs[6]; |
|||
double Backcapargs[6]; |
|||
|
|||
|
|||
double cgfgf,cgfd,cgfs,cgfdeltaT; |
|||
double cdgf,cdd,cds,cddeltaT; |
|||
double csgf,csd,css,csdeltaT; |
|||
double cbgf,cbd,cbs,cbdeltaT,cbgb; |
|||
double cgbgb,cgbsb; |
|||
|
|||
double *gcgfgf,*gcgfd,*gcgfs,*gcgfdeltaT; |
|||
double *gcdgf,*gcdd,*gcds,*gcddeltaT; |
|||
double *gcsgf,*gcsd,*gcss,*gcsdeltaT; |
|||
double *gcbgf,*gcbd,*gcbs,*gcbdeltaT,*gcbgb; |
|||
double *gcgbgb,*gcgbsb,*gcgbdb; |
|||
double *gcgbs0,*gcgbd0; |
|||
|
|||
double *qgatef; |
|||
double *qbody; |
|||
double *qdrn; |
|||
double *qsrc; |
|||
double *qgateb; |
|||
|
|||
{ |
|||
double vgfd,vgfs,vgfb; |
|||
double vgbd,vgbs,vgbb; |
|||
double cgd0,cgs0,cgb0; |
|||
double cgbd0,cgbs0,cgbb0; |
|||
double ag0; |
|||
double qgd,qgs,qgb; |
|||
double qgb_d,qgb_s,qgb_b; |
|||
|
|||
cgd0 = Frontcapargs[0]; |
|||
cgs0 = Frontcapargs[1]; |
|||
cgb0 = Frontcapargs[2]; |
|||
vgfd = Frontcapargs[3]; |
|||
vgfs = Frontcapargs[4]; |
|||
vgfb = Frontcapargs[5]; |
|||
|
|||
cgbd0 = Backcapargs[0]; |
|||
cgbs0 = Backcapargs[1]; |
|||
cgbb0 = Backcapargs[2]; |
|||
vgbd = Backcapargs[3]; |
|||
vgbs = Backcapargs[4]; |
|||
vgbb = Backcapargs[5]; |
|||
|
|||
/* stuff below includes overlap caps' conductances */ |
|||
ag0 = ckt->CKTag[0]; |
|||
|
|||
*gcgfgf = (cgfgf + cgd0 + cgs0 + cgb0) * ag0; |
|||
*gcgfd = (cgfd - cgd0) * ag0; |
|||
*gcgfs = (cgfs - cgs0) * ag0; |
|||
*gcgfdeltaT = cgfdeltaT * ag0; |
|||
|
|||
*gcdgf = (cdgf - cgd0) * ag0; |
|||
*gcdd = (cdd + cgd0) * ag0; |
|||
*gcds = cds * ag0; |
|||
*gcddeltaT = cddeltaT * ag0; |
|||
|
|||
*gcsgf = (csgf - cgs0) * ag0; |
|||
*gcsd = csd * ag0; |
|||
*gcss = (css + cgs0) * ag0; |
|||
*gcsdeltaT = csdeltaT * ag0; |
|||
|
|||
*gcbgf = (cbgf - cgb0) * ag0; |
|||
*gcbd = cbd * ag0; |
|||
*gcbs = cbs * ag0; |
|||
*gcbdeltaT = cbdeltaT * ag0; |
|||
|
|||
*gcbgb = cbgb * ag0; |
|||
/* |
|||
*gcbgb = (cbgb - cgbb0) * ag0; |
|||
|
|||
|
|||
*gcgbgb = (cgbgb + cgbb0 + cgbd0 + cgbs0) * ag0; |
|||
*gcgbsb = (cgbsb - cgbs0) * ag0; |
|||
*gcgbdb = -cgbd0 * ag0; |
|||
|
|||
*gcgbd0 = cgbd0 * ag0; |
|||
*gcgbs0 = cgbs0 * ag0; |
|||
*/ |
|||
|
|||
*gcgbgb = cgbgb * ag0; |
|||
*gcgbsb = cgbsb * ag0; |
|||
*gcgbdb = 0; |
|||
|
|||
*gcgbd0 = 0; |
|||
*gcgbs0 = 0; |
|||
|
|||
qgd = cgd0 * vgfd; |
|||
qgs = cgs0 * vgfs; |
|||
qgb = cgb0 * vgfb; |
|||
|
|||
/* |
|||
qgb_d = cgbd0 * vgbd; |
|||
qgb_s = cgbs0 * vgbs; |
|||
qgb_b = cgbb0 * vgbb; |
|||
*/ |
|||
qgb_d = 0; |
|||
qgb_s = 0; |
|||
qgb_b = 0; |
|||
|
|||
*qgatef = *qgatef + qgd + qgs + qgb; |
|||
*qbody = *qbody - qgb - qgb_b; |
|||
*qdrn = *qdrn - qgd - qgb_d; |
|||
*qgateb = *qgateb + qgb_d + qgb_s + qgb_b; |
|||
*qsrc = -(*qgatef + *qbody + *qdrn + *qgateb); |
|||
} |
|||
@ -0,0 +1,217 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3convTest(inModel,ckt) |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
{ |
|||
SOI3model *model = (SOI3model*)inModel; |
|||
SOI3instance *here; |
|||
double delvbs; |
|||
double delvbd; |
|||
double delvgfs; |
|||
double delvgbs; |
|||
double delvds; |
|||
double delvgfd; |
|||
double delvgbd; |
|||
double deldeltaT; |
|||
double ibhat; |
|||
double idhat; |
|||
double iPthat; |
|||
double vbs; |
|||
double vbd; |
|||
double vgfs; |
|||
double vgbs; |
|||
double vds; |
|||
double deltaT; |
|||
double vgfd; |
|||
double vgbd; |
|||
double vgfdo; |
|||
double vgbdo; |
|||
double tol; |
|||
FILE *fp,*fopen(); |
|||
|
|||
for( ; model != NULL; model = model->SOI3nextModel) { |
|||
for(here = model->SOI3instances; here!= NULL; |
|||
here = here->SOI3nextInstance) { |
|||
|
|||
vbs = model->SOI3type * ( |
|||
*(ckt->CKTrhs+here->SOI3bNode) - |
|||
*(ckt->CKTrhs+here->SOI3sNodePrime)); |
|||
vgfs = model->SOI3type * ( |
|||
*(ckt->CKTrhs+here->SOI3gfNode) - |
|||
*(ckt->CKTrhs+here->SOI3sNodePrime)); |
|||
vgbs = model->SOI3type * ( |
|||
*(ckt->CKTrhs+here->SOI3gbNode) - |
|||
*(ckt->CKTrhs+here->SOI3sNodePrime)); |
|||
vds = model->SOI3type * ( |
|||
*(ckt->CKTrhs+here->SOI3dNodePrime) - |
|||
*(ckt->CKTrhs+here->SOI3sNodePrime)); |
|||
deltaT = MAX(0,*(ckt->CKTrhs+here->SOI3toutNode)); |
|||
/* voltage deltaT is V(tout) wrt thermal ground */ |
|||
vbd=vbs-vds; |
|||
vgfd=vgfs-vds; |
|||
vgbd=vgbs-vds; |
|||
vgfdo = *(ckt->CKTstate0 + here->SOI3vgfs) - |
|||
*(ckt->CKTstate0 + here->SOI3vds); |
|||
vgbdo = *(ckt->CKTstate0 + here->SOI3vgbs) - |
|||
*(ckt->CKTstate0 + here->SOI3vds); |
|||
delvbs = vbs - *(ckt->CKTstate0 + here->SOI3vbs); |
|||
delvbd = vbd - *(ckt->CKTstate0 + here->SOI3vbd); |
|||
delvgfs = vgfs - *(ckt->CKTstate0 + here->SOI3vgfs); |
|||
delvgbs = vgbs - *(ckt->CKTstate0 + here->SOI3vgbs); |
|||
delvds = vds - *(ckt->CKTstate0 + here->SOI3vds); |
|||
delvgfd = vgfd-vgfdo; |
|||
delvgbd = vgbd-vgbdo; |
|||
deldeltaT = deltaT - *(ckt->CKTstate0 + here->SOI3deltaT); |
|||
|
|||
/* these are needed for convergence testing */ |
|||
|
|||
if (here->SOI3mode >= 0) { /* normal */ |
|||
idhat= |
|||
here->SOI3id- |
|||
here->SOI3gbd * delvbd - |
|||
here->SOI3gbdT * deldeltaT + /* for -ibd bit of id */ |
|||
(here->SOI3gmbs + |
|||
here->SOI3gMmbs) * delvbs + |
|||
(here->SOI3gmf + |
|||
here->SOI3gMmf) * delvgfs + |
|||
(here->SOI3gmb + |
|||
here->SOI3gMmb) * delvgbs + |
|||
(here->SOI3gds + |
|||
here->SOI3gMd) * delvds + |
|||
(here->SOI3gt + |
|||
here->SOI3gMdeltaT) * deldeltaT + |
|||
here->SOI3gBJTdb_bs * delvbs + |
|||
here->SOI3gBJTdb_deltaT * deldeltaT; |
|||
ibhat= |
|||
here->SOI3ibs + |
|||
here->SOI3ibd + |
|||
here->SOI3gbd * delvbd + |
|||
here->SOI3gbdT * deldeltaT + |
|||
here->SOI3gbs * delvbs + |
|||
here->SOI3gbsT * deldeltaT - |
|||
here->SOI3iMdb - |
|||
here->SOI3gMmbs * delvbs - |
|||
(here->SOI3gMmf)* delvgfs - |
|||
(here->SOI3gMmb)* delvgbs - |
|||
here->SOI3gMd * delvds - |
|||
here->SOI3gMdeltaT * deldeltaT - |
|||
here->SOI3iBJTsb - |
|||
here->SOI3gBJTsb_bd * delvbd - |
|||
here->SOI3gBJTsb_deltaT * deldeltaT - |
|||
here->SOI3iBJTdb - |
|||
here->SOI3gBJTdb_bs * delvbs - |
|||
here->SOI3gBJTdb_deltaT * deldeltaT; |
|||
} else { /* A over T */ |
|||
idhat= |
|||
here->SOI3id - |
|||
( here->SOI3gbd + |
|||
here->SOI3gmbs) * delvbd - |
|||
(here->SOI3gmf) * delvgfd - |
|||
(here->SOI3gmb) * delvgbd + |
|||
(here->SOI3gds) * delvds - |
|||
(here->SOI3gt + |
|||
here->SOI3gbdT) * deldeltaT + |
|||
here->SOI3gBJTdb_bs * delvbs + |
|||
here->SOI3gBJTdb_deltaT * deldeltaT; |
|||
ibhat= |
|||
here->SOI3ibs + |
|||
here->SOI3ibd + |
|||
here->SOI3gbd * delvbd + |
|||
here->SOI3gbdT * deldeltaT + |
|||
here->SOI3gbs * delvbs + |
|||
here->SOI3gbsT * deldeltaT - |
|||
here->SOI3iMsb - |
|||
here->SOI3gMmbs * delvbd - |
|||
here->SOI3gMmf * delvgfd - |
|||
here->SOI3gMmb * delvgbd + |
|||
here->SOI3gMd * delvds - /* gMd should go with vsd */ |
|||
here->SOI3gMdeltaT * deldeltaT - |
|||
here->SOI3iBJTsb - |
|||
here->SOI3gBJTsb_bd * delvbd - |
|||
here->SOI3gBJTsb_deltaT * deldeltaT - |
|||
here->SOI3iBJTdb - |
|||
here->SOI3gBJTdb_bs * delvbs - |
|||
here->SOI3gBJTdb_deltaT * deldeltaT; |
|||
} |
|||
iPthat = |
|||
here->SOI3iPt + |
|||
here->SOI3gPmbs * delvbs + |
|||
here->SOI3gPmf * delvgfs + |
|||
here->SOI3gPmb * delvgbs + |
|||
here->SOI3gPds * delvds * here->SOI3mode + |
|||
here->SOI3gPdT * deldeltaT; |
|||
/* |
|||
* check convergence |
|||
*/ |
|||
tol=ckt->CKTreltol*MAX(fabs(idhat),fabs(here->SOI3id))+ |
|||
ckt->CKTabstol; |
|||
if (fabs(idhat-here->SOI3id) >= tol) { |
|||
ckt->CKTnoncon++; |
|||
/* JimB - Remove line containing ckt->CKTtroubleElt for the */ |
|||
/* Simetrix DLL version - element removed from ckt structure */ |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
return(OK); /* no reason to continue, we haven't converged */ |
|||
} else { |
|||
tol=ckt->CKTreltol* |
|||
MAX(fabs(ibhat),fabs(here->SOI3ibs+here->SOI3ibd |
|||
- here->SOI3iMdb - here->SOI3iMsb |
|||
- here->SOI3iBJTdb - here->SOI3iBJTsb))+ |
|||
ckt->CKTabstol; |
|||
if (fabs(ibhat-(here->SOI3ibs+here->SOI3ibd |
|||
- here->SOI3iMdb - here->SOI3iMsb |
|||
- here->SOI3iBJTdb - here->SOI3iBJTsb)) > tol) { |
|||
ckt->CKTnoncon++; |
|||
/* JimB - Remove line containing ckt->CKTtroubleElt for the */ |
|||
/* Simetrix DLL version - element removed from ckt structure */ |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
return(OK); /* no reason to continue,we haven't converged*/ |
|||
} else { |
|||
tol=ckt->CKTreltol*MAX(fabs(iPthat), |
|||
fabs(here->SOI3iPt))+ckt->CKTabstol; |
|||
if (fabs(iPthat-here->SOI3iPt) >= tol) { |
|||
ckt->CKTnoncon++; |
|||
/* JimB - Remove line containing ckt->CKTtroubleElt for the */ |
|||
/* Simetrix DLL version - element removed from ckt structure */ |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
return(OK); /* no reason to continue,we haven't converged*/ |
|||
} |
|||
} |
|||
} |
|||
/* debug stuff */ |
|||
/* fp=fopen("level3.dat","a"); |
|||
fprintf(fp,"%2.3f %2.3f %.15e %.15e %.15e %.15e %.15e %.15e %.15e\n", |
|||
vgfs-vbs,vds,ckt->CKTtime,here->SOI3debug1,here->SOI3debug2,here->SOI3debug3, |
|||
here->SOI3debug4,here->SOI3debug5,here->SOI3debug6); |
|||
fclose(fp); |
|||
*/ |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,800 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
#ifndef SOI3 |
|||
#define SOI3 |
|||
|
|||
#include "ifsim.h" |
|||
#include "cktdefs.h" |
|||
#include "gendefs.h" |
|||
#include "complex.h" |
|||
#include "noisedef.h" |
|||
|
|||
|
|||
/* declarations for SOI3 MOSFETs */ |
|||
|
|||
/* information needed for each instance */ |
|||
|
|||
typedef struct sSOI3instance { |
|||
|
|||
|
|||
struct sSOI3model *sSOI3modPtr; /* backpointer to model */ |
|||
struct sSOI3instance *SOI3nextInstance; /* pointer to next instance of |
|||
*current model*/ |
|||
IFuid SOI3name; /* pointer to character string naming this instance */ |
|||
int SOI3owner; /* number of owner process */ |
|||
int SOI3states; /* index into state table for this device */ |
|||
|
|||
|
|||
int SOI3dNode; /* number of the drain node of the mosfet */ |
|||
int SOI3gfNode; /* number of the front gate node of the mosfet */ |
|||
int SOI3sNode; /* number of the source node of the mosfet */ |
|||
int SOI3gbNode; /* number of the back gate node of the mosfet */ |
|||
int SOI3bNode; /* number of the bulk node of the mosfet */ |
|||
int SOI3toutNode; /* number of thermal output node (tout) */ |
|||
|
|||
int SOI3branch; /* branch number for zero voltage source if no thermal */ |
|||
|
|||
int SOI3dNodePrime; /* number of the internal drain node of the mosfet */ |
|||
int SOI3sNodePrime; /* number of the internal source node of the mosfet */ |
|||
|
|||
|
|||
|
|||
int SOI3tout1Node; /* first internal thermal node */ |
|||
int SOI3tout2Node; /* second internal thermal node */ |
|||
int SOI3tout3Node; /* third internal thermal node */ |
|||
int SOI3tout4Node; /* fourth internal thermal node */ |
|||
|
|||
double SOI3l; /* the length of the channel region */ |
|||
double SOI3w; /* the width of the channel region */ |
|||
|
|||
double SOI3drainSquares; /* the length of the drain in squares */ |
|||
double SOI3sourceSquares; /* the length of the source in squares */ |
|||
|
|||
double SOI3sourceConductance; /*conductance of source(or 0):set in setup*/ |
|||
double SOI3drainConductance; /*conductance of drain(or 0):set in setup*/ |
|||
double SOI3temp; /* operating temperature of this instance */ |
|||
double SOI3rt; /* Thermal resistance */ |
|||
double SOI3ct; /* Thermal capacitance */ |
|||
double SOI3rt1; /* 1st internal Thermal resistance */ |
|||
double SOI3ct1; /* 1st internal Thermal capacitance */ |
|||
double SOI3rt2; /* 2nd internal Thermal resistance */ |
|||
double SOI3ct2; /* 2nd internal Thermal capacitance */ |
|||
double SOI3rt3; /* 3rd internal Thermal resistance */ |
|||
double SOI3ct3; /* 3rd internal Thermal capacitance */ |
|||
double SOI3rt4; /* 4th internal Thermal resistance */ |
|||
double SOI3ct4; /* 4th internal Thermal capacitance */ |
|||
|
|||
|
|||
double SOI3tTransconductance; /* temperature corrected transconductance (KP param) */ |
|||
double SOI3ueff; /* passed on to noise model */ |
|||
double SOI3tSurfMob; /* temperature corrected surface mobility */ |
|||
double SOI3tPhi; /* temperature corrected Phi */ |
|||
double SOI3tVto; /* temperature corrected Vto */ |
|||
double SOI3tVfbF; /* temperature corrected Vfb */ |
|||
double SOI3tVfbB; /* temperature corrected Vfb (back gate) */ |
|||
double SOI3tSatCur; /* temperature corrected jnct saturation Cur. */ |
|||
double SOI3tSatCur1; /* temperature corrected jnct saturation Cur. */ |
|||
double SOI3tSatCurDens; /* temperature corrected jnct saturation Cur. density */ |
|||
double SOI3tSatCurDens1; /* temperature corrected jnct saturation Cur. density */ |
|||
double SOI3tCbd; /* temperature corrected B-D Capacitance */ |
|||
double SOI3tCbs; /* temperature corrected B-S Capacitance */ |
|||
double SOI3tCjsw; /* temperature corrected Bulk side Capacitance */ |
|||
double SOI3tBulkPot; /* temperature corrected Bulk potential */ |
|||
double SOI3tDepCap; /* temperature adjusted transition point in */ |
|||
/* the curve matching Fc * Vj */ |
|||
double SOI3tVbi; /* temperature adjusted Vbi diode built-in voltage */ |
|||
|
|||
double SOI3icVBS; /* initial condition B-S voltage */ |
|||
double SOI3icVDS; /* initial condition D-S voltage */ |
|||
double SOI3icVGFS; /* initial condition GF-S voltage */ |
|||
double SOI3icVGBS; /* initial condition GB-S voltage */ |
|||
double SOI3von; |
|||
double SOI3vdsat; |
|||
double SOI3sourceVcrit; /* Vcrit for pos. vds */ |
|||
double SOI3drainVcrit; /* Vcrit for pos. vds */ |
|||
double SOI3id; /* drain current */ |
|||
double SOI3ibs; /* bulk source current */ |
|||
double SOI3ibd; /* bulk drain current */ |
|||
double SOI3iMdb; /* drain bulk impact ionisation current */ |
|||
double SOI3iMsb; /* source bulk impact ionisation cur. (rev mode) */ |
|||
double SOI3iPt; /* heat 'current' in thermal circuit */ |
|||
double SOI3gmbs; |
|||
double SOI3gmf; |
|||
double SOI3gmb; |
|||
double SOI3gds; |
|||
double SOI3gt; /* change of channel current wrt deltaT */ |
|||
double SOI3gdsnotherm; /* gds0 at elevated temp - ac use only) */ |
|||
double SOI3gMmbs; |
|||
double SOI3gMmf; |
|||
double SOI3gMmb; |
|||
double SOI3gMd; |
|||
double SOI3gMdeltaT; |
|||
double SOI3iBJTdb; |
|||
double SOI3gBJTdb_bs; |
|||
double SOI3gBJTdb_deltaT; |
|||
double SOI3iBJTsb; |
|||
double SOI3gBJTsb_bd; |
|||
double SOI3gBJTsb_deltaT; |
|||
double SOI3gPmf; /* change of Pt wrt vgfs */ |
|||
double SOI3gPmb; /* change of Pt wrt vgbs */ |
|||
double SOI3gPmbs; /* change of Pt wrt vbs */ |
|||
double SOI3gPds; /* change of Pt wrt vds */ |
|||
double SOI3gPdT; /* change of Pt wrt deltaT */ |
|||
double SOI3gbd; /* for body drain current */ |
|||
double SOI3gbdT; /* for body drain current */ |
|||
double SOI3gbs; /* for body source current */ |
|||
double SOI3gbsT; /* for body source current */ |
|||
double SOI3capbd; |
|||
double SOI3capbs; |
|||
double SOI3Cbd; |
|||
double SOI3Cbs; |
|||
double SOI3f2d; |
|||
double SOI3f3d; |
|||
double SOI3f4d; |
|||
double SOI3f2s; |
|||
double SOI3f3s; |
|||
double SOI3f4s; |
|||
double SOI3dDT_dVds; /* sm-sig gT term */ |
|||
double SOI3dId_dDT; /* sm-sig source term */ |
|||
/*debug stuff*/ |
|||
double SOI3debug1; |
|||
double SOI3debug2; |
|||
double SOI3debug3; |
|||
double SOI3debug4; |
|||
double SOI3debug5; |
|||
double SOI3debug6; |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
|
|||
/* |
|||
* naming convention: |
|||
* x = vgs |
|||
* y = vbs |
|||
* z = vds |
|||
* cdr = cdrain |
|||
*/ |
|||
int SOI3mode; /* device mode : 1 = normal, -1 = inverse */ |
|||
int SOI3backstate; /* indicates charge condition of back surface */ |
|||
int SOI3numThermalNodes; /* Number of thermal nodes required */ |
|||
|
|||
unsigned SOI3off:1; /* non-zero to indicate device is off for dc analysis*/ |
|||
unsigned SOI3tempGiven :1; /* instance temperature specified */ |
|||
unsigned SOI3lGiven :1; |
|||
unsigned SOI3wGiven :1; |
|||
unsigned SOI3drainSquaresGiven :1; |
|||
unsigned SOI3sourceSquaresGiven :1; |
|||
unsigned SOI3dNodePrimeSet :1; |
|||
unsigned SOI3sNodePrimeSet :1; |
|||
unsigned SOI3icVBSGiven :1; |
|||
unsigned SOI3icVDSGiven :1; |
|||
unsigned SOI3icVGFSGiven:1; |
|||
unsigned SOI3icVGBSGiven:1; |
|||
unsigned SOI3rtGiven:1; |
|||
unsigned SOI3ctGiven:1; |
|||
unsigned SOI3rt1Given:1; |
|||
unsigned SOI3ct1Given:1; |
|||
unsigned SOI3rt2Given:1; |
|||
unsigned SOI3ct2Given:1; |
|||
unsigned SOI3rt3Given:1; |
|||
unsigned SOI3ct3Given:1; |
|||
unsigned SOI3rt4Given:1; |
|||
unsigned SOI3ct4Given:1; |
|||
unsigned SOI3vonGiven :1; |
|||
unsigned SOI3vdsatGiven :1; |
|||
unsigned SOI3modeGiven :1; |
|||
|
|||
|
|||
double *SOI3D_dPtr; /* pointer to sparse matrix element at |
|||
* (Drain node,drain node) */ |
|||
double *SOI3GF_gfPtr; /* pointer to sparse matrix element at |
|||
* (front gate node,front gate node) */ |
|||
double *SOI3S_sPtr; /* pointer to sparse matrix element at |
|||
* (source node,source node) */ |
|||
double *SOI3B_bPtr; /* pointer to sparse matrix element at |
|||
* (bulk node,bulk node) */ |
|||
double *SOI3GB_gbPtr; /* pointer to sparse matrix element at |
|||
* (back gate node,back gate node) */ |
|||
double *SOI3DP_dpPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,drain prime node) */ |
|||
double *SOI3SP_spPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,source prime node) */ |
|||
double *SOI3D_dpPtr; /* pointer to sparse matrix element at |
|||
* (drain node,drain prime node) */ |
|||
double *SOI3GF_bPtr; /* pointer to sparse matrix element at |
|||
* (front gate node,bulk node) */ |
|||
double *SOI3GB_bPtr; /* pointer to sparse matrix element at |
|||
* (back gate node,bulk node) */ |
|||
double *SOI3GF_dpPtr; /* pointer to sparse matrix element at |
|||
* (front gate node,drain prime node) */ |
|||
double *SOI3GB_dpPtr; /* pointer to sparse matrix element at |
|||
* (back gate node,drain prime node) */ |
|||
double *SOI3GF_spPtr; /* pointer to sparse matrix element at |
|||
* (front gate node,source prime node) */ |
|||
double *SOI3GB_spPtr; /* pointer to sparse matrix element at |
|||
* (back gate node,source prime node) */ |
|||
double *SOI3S_spPtr; /* pointer to sparse matrix element at |
|||
* (source node,source prime node) */ |
|||
double *SOI3B_dpPtr; /* pointer to sparse matrix element at |
|||
* (bulk node,drain prime node) */ |
|||
double *SOI3B_spPtr; /* pointer to sparse matrix element at |
|||
* (bulk node,source prime node) */ |
|||
double *SOI3DP_spPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,source prime node) */ |
|||
double *SOI3DP_dPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,drain node) */ |
|||
double *SOI3B_gfPtr; /* pointer to sparse matrix element at |
|||
* (bulk node,front gate node) */ |
|||
double *SOI3B_gbPtr; /* pointer to sparse matrix element at |
|||
* (bulk node,back gate node) */ |
|||
double *SOI3DP_gfPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,front gate node) */ |
|||
double *SOI3DP_gbPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,back gate node) */ |
|||
double *SOI3SP_gfPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,front gate node) */ |
|||
double *SOI3SP_gbPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,back gate node) */ |
|||
double *SOI3SP_sPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,source node) */ |
|||
double *SOI3DP_bPtr; /* pointer to sparse matrix element at |
|||
* (drain prime node,bulk node) */ |
|||
double *SOI3SP_bPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,bulk node) */ |
|||
double *SOI3SP_dpPtr; /* pointer to sparse matrix element at |
|||
* (source prime node,drain prime node) */ |
|||
|
|||
/** Now for Thermal Node **/ |
|||
|
|||
double *SOI3TOUT_toutPtr; |
|||
double *SOI3TOUT_dpPtr; |
|||
double *SOI3TOUT_gfPtr; |
|||
double *SOI3TOUT_gbPtr; |
|||
double *SOI3TOUT_bPtr; |
|||
double *SOI3TOUT_spPtr; |
|||
|
|||
double *SOI3GF_toutPtr; |
|||
double *SOI3DP_toutPtr; |
|||
double *SOI3SP_toutPtr; |
|||
|
|||
double *SOI3TOUT_ibrPtr; /* these are for zero voltage source should */ |
|||
double *SOI3IBR_toutPtr; /* no thermal behaviour be specified */ |
|||
|
|||
double *SOI3B_toutPtr; /* for impact ionisation current source */ |
|||
|
|||
double *SOI3TOUT_tout1Ptr; |
|||
double *SOI3TOUT1_toutPtr; |
|||
double *SOI3TOUT1_tout1Ptr; |
|||
double *SOI3TOUT1_tout2Ptr; |
|||
double *SOI3TOUT2_tout1Ptr; |
|||
double *SOI3TOUT2_tout2Ptr; |
|||
double *SOI3TOUT2_tout3Ptr; |
|||
double *SOI3TOUT3_tout2Ptr; |
|||
double *SOI3TOUT3_tout3Ptr; |
|||
double *SOI3TOUT3_tout4Ptr; |
|||
double *SOI3TOUT4_tout3Ptr; |
|||
double *SOI3TOUT4_tout4Ptr; |
|||
|
|||
|
|||
/* indices to the array of SOI(3) noise sources */ |
|||
|
|||
#define SOI3RDNOIZ 0 |
|||
#define SOI3RSNOIZ 1 |
|||
#define SOI3IDNOIZ 2 |
|||
#define SOI3FLNOIZ 3 |
|||
#define SOI3TOTNOIZ 4 |
|||
|
|||
#define SOI3NSRCS 5 /* the number of SOI(3) noise sources */ |
|||
|
|||
#ifndef NONOISE |
|||
double SOI3nVar[NSTATVARS][SOI3NSRCS]; |
|||
#else /* NONOISE */ |
|||
double **SOI3nVar; |
|||
#endif /* NONOISE */ |
|||
|
|||
} SOI3instance ; |
|||
|
|||
#define SOI3vbd SOI3states+ 0 /* bulk-drain voltage */ |
|||
#define SOI3vbs SOI3states+ 1 /* bulk-source voltage */ |
|||
#define SOI3vgfs SOI3states+ 2 /* front gate-source voltage */ |
|||
#define SOI3vgbs SOI3states+ 3 /* back gate-source voltage */ |
|||
#define SOI3vds SOI3states+ 4 /* drain-source voltage */ |
|||
#define SOI3deltaT SOI3states+ 5 /* final temperature difference */ |
|||
|
|||
#define SOI3qgf SOI3states + 6 /* front gate charge */ |
|||
#define SOI3iqgf SOI3states +7 /* front gate current */ |
|||
|
|||
#define SOI3qgb SOI3states+ 8 /* back gate charge */ |
|||
#define SOI3iqgb SOI3states+ 9 /* back gate current */ |
|||
|
|||
#define SOI3qd SOI3states+ 10 /* drain charge */ |
|||
#define SOI3iqd SOI3states+ 11 /* drain current */ |
|||
|
|||
#define SOI3qs SOI3states+ 14 /* body charge */ |
|||
#define SOI3iqs SOI3states+ 15 /* body current */ |
|||
|
|||
#define SOI3cgfgf SOI3states+ 16 |
|||
#define SOI3cgfd SOI3states+ 17 |
|||
#define SOI3cgfs SOI3states+ 18 |
|||
#define SOI3cgfdeltaT SOI3states+ 19 |
|||
|
|||
#define SOI3cdgf SOI3states+ 20 |
|||
#define SOI3cdd SOI3states+ 21 |
|||
#define SOI3cds SOI3states+ 22 |
|||
#define SOI3cddeltaT SOI3states+ 23 |
|||
|
|||
#define SOI3csgf SOI3states+ 24 |
|||
#define SOI3csd SOI3states+ 25 |
|||
#define SOI3css SOI3states+ 26 |
|||
#define SOI3csdeltaT SOI3states+ 27 |
|||
|
|||
#define SOI3cgbgb SOI3states + 28 |
|||
#define SOI3cgbsb SOI3states + 29 |
|||
#define SOI3cgbdb SOI3states + 30 |
|||
|
|||
#define SOI3qbd SOI3states+ 31 /* body-drain capacitor charge */ |
|||
#define SOI3iqbd SOI3states+ 32 /* body-drain capacitor current */ |
|||
|
|||
#define SOI3qbs SOI3states+ 33 /* body-source capacitor charge */ |
|||
#define SOI3iqbs SOI3states+ 34 /* body-source capacitor current */ |
|||
|
|||
#define SOI3qt SOI3states+ 35 /* Energy or 'charge' associated with ct */ |
|||
#define SOI3iqt SOI3states+ 36 /* equiv current source for ct */ |
|||
#define SOI3qt1 SOI3states+ 37 /* Energy or 'charge' associated with ct */ |
|||
#define SOI3iqt1 SOI3states+ 38 /* equiv current source for ct */ |
|||
#define SOI3qt2 SOI3states+ 39 /* Energy or 'charge' associated with ct */ |
|||
#define SOI3iqt2 SOI3states+ 40 /* equiv current source for ct */ |
|||
#define SOI3qt3 SOI3states+ 41 /* Energy or 'charge' associated with ct */ |
|||
#define SOI3iqt3 SOI3states+ 42 /* equiv current source for ct */ |
|||
#define SOI3qt4 SOI3states+ 43 /* Energy or 'charge' associated with ct */ |
|||
#define SOI3iqt4 SOI3states+ 44 /* equiv current source for ct */ |
|||
|
|||
#define SOI3qBJTbs SOI3states+ 45 |
|||
#define SOI3iqBJTbs SOI3states+ 46 |
|||
|
|||
#define SOI3qBJTbd SOI3states+ 47 |
|||
#define SOI3iqBJTbd SOI3states+ 48 |
|||
|
|||
#define SOI3cBJTbsbs SOI3states+ 49 |
|||
#define SOI3cBJTbsdeltaT SOI3states+ 50 |
|||
|
|||
#define SOI3cBJTbdbd SOI3states+ 51 |
|||
#define SOI3cBJTbddeltaT SOI3states+ 52 |
|||
|
|||
#define SOI3idrain SOI3states+ 53 /* final drain current at timepoint (no define) */ |
|||
|
|||
#define SOI3deltaT1 SOI3states+ 54 /* final temperature difference */ |
|||
#define SOI3deltaT2 SOI3states+ 55 /* final temperature difference */ |
|||
#define SOI3deltaT3 SOI3states+ 56 /* final temperature difference */ |
|||
#define SOI3deltaT4 SOI3states+ 57 /* final temperature difference */ |
|||
#define SOI3deltaT5 SOI3states+ 58 /* final temperature difference */ |
|||
|
|||
#define SOI3numStates 59 |
|||
|
|||
/* per model data */ |
|||
|
|||
/* NOTE: parameters marked 'input - use xxxx' are paramters for |
|||
* which a temperature correction is applied in SOI3temp, thus |
|||
* the SOI3xxxx value in the per-instance structure should be used |
|||
* instead in all calculations |
|||
*/ |
|||
|
|||
|
|||
typedef struct sSOI3model { /* model structure for an SOI3 MOSFET */ |
|||
|
|||
|
|||
int SOI3modType; /* type index to this device type */ |
|||
struct sSOI3model *SOI3nextModel; /* pointer to next possible model |
|||
*in linked list */ |
|||
SOI3instance * SOI3instances; /* pointer to list of instances |
|||
* that have this model */ |
|||
IFuid SOI3modName; /* pointer to character string naming this model */ |
|||
int SOI3type; /* device type : 1 = nsoi, -1 = psoi */ |
|||
double SOI3tnom; /* temperature at which parameters measured */ |
|||
double SOI3latDiff; |
|||
double SOI3jctSatCurDensity; /* input - use tSatCurDens (jnct)*/ |
|||
double SOI3jctSatCurDensity1; /* input - use tSatCurDens1 (jnct)*/ |
|||
double SOI3jctSatCur; /* input - use tSatCur (jnct Is)*/ |
|||
double SOI3jctSatCur1; /* input - use tSatCur1 (jnct Is)*/ |
|||
double SOI3drainResistance; |
|||
double SOI3sourceResistance; |
|||
double SOI3sheetResistance; |
|||
double SOI3transconductance; /* (KP) input - use tTransconductance */ |
|||
double SOI3frontGateSourceOverlapCapFactor; |
|||
double SOI3frontGateDrainOverlapCapFactor; |
|||
double SOI3frontGateBulkOverlapCapFactor; |
|||
double SOI3backGateSourceOverlapCapFactor; |
|||
double SOI3backGateDrainOverlapCapFactor; |
|||
double SOI3backGateBulkOverlapCapFactor; |
|||
double SOI3frontOxideCapFactor; /* Cof NO DEFINES */ |
|||
double SOI3backOxideCapFactor; /* Cob OR */ |
|||
double SOI3bodyCapFactor; /* Cb FLAGS */ |
|||
double SOI3C_bb; /* Cb in series with Cob */ |
|||
double SOI3C_fb; /* Cb in series with Cof */ |
|||
double SOI3C_ssf; /* q*NQFF */ |
|||
double SOI3C_ssb; /* q*NQFB */ |
|||
double SOI3C_fac; /* C_ob/(C_ob+C_b+C_ssb) */ |
|||
double SOI3vt0; /* input - use tVto */ |
|||
double SOI3vfbF; /* flat-band voltage. input - use tVfbF */ |
|||
double SOI3vfbB; /* back flat-band voltage. input - use tVfbB */ |
|||
double SOI3gamma; /* gamma */ |
|||
double SOI3gammaB; /* back gamma */ |
|||
double SOI3capBD; /* input - use tCbd */ |
|||
double SOI3capBS; /* input - use tCbs */ |
|||
double SOI3sideWallCapFactor; /* input - use tCjsw */ |
|||
double SOI3bulkJctPotential; /* input - use tBulkPot */ |
|||
double SOI3bulkJctSideGradingCoeff; /* MJSW */ |
|||
double SOI3fwdCapDepCoeff; /* FC */ |
|||
double SOI3phi; /* input - use tPhi */ |
|||
double SOI3vbi; /* input - use tVbi */ |
|||
double SOI3lambda; |
|||
double SOI3theta; |
|||
double SOI3substrateDoping; /* Nsub */ |
|||
double SOI3substrateCharge; /* Qb - no define/flag */ |
|||
int SOI3gateType; /* +1=same, -1=different, 0=Al */ |
|||
double SOI3frontFixedChargeDensity; |
|||
double SOI3backFixedChargeDensity; |
|||
double SOI3frontSurfaceStateDensity; |
|||
double SOI3backSurfaceStateDensity; |
|||
double SOI3frontOxideThickness; |
|||
double SOI3backOxideThickness; |
|||
double SOI3bodyThickness; |
|||
double SOI3surfaceMobility; /* input - use tSurfMob */ |
|||
double SOI3oxideThermalConductivity; |
|||
double SOI3siliconSpecificHeat; |
|||
double SOI3siliconDensity; |
|||
double SOI3fNcoef; |
|||
double SOI3fNexp; |
|||
/* new stuff for newer model - msll Jan96 */ |
|||
double SOI3sigma; /* DIBL factor */ |
|||
double SOI3chiFB; /* temperature coeff of flatband voltage */ |
|||
double SOI3chiPHI; /* temperature coeff of PHI */ |
|||
double SOI3deltaW; /* narrow width effect factor */ |
|||
double SOI3deltaL; /* short channel effect factor */ |
|||
double SOI3vsat; /* input - saturation velocity, use tVsat */ |
|||
double SOI3TVF0; /* internal use - precalculation of exp to save time */ |
|||
double SOI3k; /* thermal exponent for mobility factor */ |
|||
double SOI3lx; /* channel length modulation factor */ |
|||
double SOI3vp; /* channel length modulation empirical voltage */ |
|||
double SOI3eta; /* Imp. ion. field adjustment factor */ |
|||
double SOI3alpha0; /* 1st impact ionisation coeff */ |
|||
double SOI3beta0; /* 2nd impact ionisation coeff */ |
|||
double SOI3lm; /* impact ion. drain region length cf LX */ |
|||
double SOI3lm1; /* impact ion. drain region coeff */ |
|||
double SOI3lm2; /* impact ion. drain region coeff */ |
|||
double SOI3etad; /* diode ideality factor */ |
|||
double SOI3etad1; /* 2nd diode ideality factor */ |
|||
double SOI3chibeta; /* temp coeff of BETA0 */ |
|||
double SOI3chid; /* temp factor for junction 1 */ |
|||
double SOI3chid1; /* temp factor for junction 2 */ |
|||
int SOI3dvt; /* switch for temp dependence of vt in diodes */ |
|||
int SOI3nLev; /* level switch for noise model */ |
|||
double SOI3betaBJT; /* beta for Eber Moll BJT model */ |
|||
double SOI3tauFBJT; /* forward BJT transit time */ |
|||
double SOI3tauRBJT; /* reverse BJT transit time */ |
|||
double SOI3betaEXP; |
|||
double SOI3tauEXP; |
|||
double SOI3rsw; /* source resistance width scaling factor */ |
|||
double SOI3rdw; /* drain resistance width scaling factor */ |
|||
double SOI3minimumFeatureSize; /* minimum feature size of simulated process technology */ |
|||
double SOI3vtex; /* Extracted threshold voltage */ |
|||
double SOI3vdex; /* Drain bias at which vtex extracted */ |
|||
double SOI3delta0; /* Surface potential factor for vtex conversion */ |
|||
double SOI3satChargeShareFactor; /* Saturation region charge sharing factor */ |
|||
double SOI3nplusDoping; /* Doping concentration of N+ or P+ regions */ |
|||
double SOI3rta; /* thermal resistance area scaling factor */ |
|||
double SOI3cta; /* thermal capacitance area scaling factor */ |
|||
|
|||
unsigned SOI3typeGiven :1; |
|||
unsigned SOI3latDiffGiven :1; |
|||
unsigned SOI3jctSatCurDensityGiven :1; |
|||
unsigned SOI3jctSatCurDensity1Given :1; |
|||
unsigned SOI3jctSatCurGiven :1; |
|||
unsigned SOI3jctSatCur1Given :1; |
|||
unsigned SOI3drainResistanceGiven :1; |
|||
unsigned SOI3sourceResistanceGiven :1; |
|||
unsigned SOI3sheetResistanceGiven :1; |
|||
unsigned SOI3transconductanceGiven :1; |
|||
unsigned SOI3frontGateSourceOverlapCapFactorGiven :1; |
|||
unsigned SOI3frontGateDrainOverlapCapFactorGiven :1; |
|||
unsigned SOI3frontGateBulkOverlapCapFactorGiven :1; |
|||
unsigned SOI3backGateSourceOverlapCapFactorGiven :1; |
|||
unsigned SOI3backGateDrainOverlapCapFactorGiven :1; |
|||
unsigned SOI3backGateBulkOverlapCapFactorGiven :1; |
|||
unsigned SOI3subsBiasFactorGiven :1; |
|||
unsigned SOI3bodyFactorGiven :1; |
|||
unsigned SOI3vt0Given :1; |
|||
unsigned SOI3vfbFGiven :1; |
|||
unsigned SOI3vfbBGiven :1; |
|||
unsigned SOI3gammaGiven :1; |
|||
unsigned SOI3gammaBGiven :1; |
|||
unsigned SOI3capBDGiven :1; |
|||
unsigned SOI3capBSGiven :1; |
|||
unsigned SOI3sideWallCapFactorGiven :1; |
|||
unsigned SOI3bulkJctPotentialGiven :1; |
|||
unsigned SOI3bulkJctSideGradingCoeffGiven :1; |
|||
unsigned SOI3fwdCapDepCoeffGiven :1; |
|||
unsigned SOI3phiGiven :1; |
|||
unsigned SOI3lambdaGiven :1; |
|||
unsigned SOI3thetaGiven :1; |
|||
unsigned SOI3substrateDopingGiven :1; |
|||
unsigned SOI3gateTypeGiven :1; |
|||
unsigned SOI3frontFixedChargeDensityGiven :1; |
|||
unsigned SOI3backFixedChargeDensityGiven :1; |
|||
unsigned SOI3frontSurfaceStateDensityGiven :1; |
|||
unsigned SOI3backSurfaceStateDensityGiven :1; |
|||
unsigned SOI3frontOxideThicknessGiven :1; |
|||
unsigned SOI3backOxideThicknessGiven :1; |
|||
unsigned SOI3bodyThicknessGiven :1; |
|||
unsigned SOI3surfaceMobilityGiven :1; |
|||
unsigned SOI3tnomGiven :1; |
|||
unsigned SOI3oxideThermalConductivityGiven :1; |
|||
unsigned SOI3siliconSpecificHeatGiven :1; |
|||
unsigned SOI3siliconDensityGiven :1; |
|||
unsigned SOI3fNcoefGiven :1; |
|||
unsigned SOI3fNexpGiven :1; |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
unsigned SOI3sigmaGiven :1; |
|||
unsigned SOI3chiFBGiven :1; |
|||
unsigned SOI3chiPHIGiven :1; |
|||
unsigned SOI3deltaWGiven :1; |
|||
unsigned SOI3deltaLGiven :1; |
|||
unsigned SOI3vsatGiven :1; |
|||
unsigned SOI3kGiven :1; |
|||
unsigned SOI3lxGiven :1; |
|||
unsigned SOI3vpGiven :1; |
|||
unsigned SOI3useLAMBDA :1; |
|||
unsigned SOI3etaGiven :1; |
|||
unsigned SOI3alpha0Given :1; |
|||
unsigned SOI3beta0Given :1; |
|||
unsigned SOI3lmGiven :1; |
|||
unsigned SOI3lm1Given :1; |
|||
unsigned SOI3lm2Given :1; |
|||
unsigned SOI3etadGiven :1; |
|||
unsigned SOI3etad1Given :1; |
|||
unsigned SOI3chibetaGiven :1; |
|||
unsigned SOI3chidGiven :1; |
|||
unsigned SOI3chid1Given :1; |
|||
unsigned SOI3dvtGiven :1; |
|||
unsigned SOI3nLevGiven :1; |
|||
unsigned SOI3betaBJTGiven :1; |
|||
unsigned SOI3tauFBJTGiven :1; |
|||
unsigned SOI3tauRBJTGiven :1; |
|||
unsigned SOI3betaEXPGiven :1; |
|||
unsigned SOI3tauEXPGiven :1; |
|||
unsigned SOI3rswGiven :1; |
|||
unsigned SOI3rdwGiven :1; |
|||
unsigned SOI3minimumFeatureSizeGiven :1; |
|||
unsigned SOI3vtexGiven :1; |
|||
unsigned SOI3vdexGiven :1; |
|||
unsigned SOI3delta0Given :1; |
|||
unsigned SOI3satChargeShareFactorGiven :1; |
|||
unsigned SOI3nplusDopingGiven :1; |
|||
unsigned SOI3rtaGiven :1; |
|||
unsigned SOI3ctaGiven :1; |
|||
|
|||
} SOI3model; |
|||
|
|||
#ifndef NSOI3 |
|||
#define NSOI3 1 |
|||
#define PSOI3 -1 |
|||
#endif /*NSOI3*/ |
|||
|
|||
/* device parameters */ |
|||
#define SOI3_W 1 |
|||
#define SOI3_L 2 |
|||
#define SOI3_AS 3 |
|||
#define SOI3_AD 4 |
|||
#define SOI3_PS 5 |
|||
#define SOI3_PD 6 |
|||
#define SOI3_NRS 7 |
|||
#define SOI3_NRD 8 |
|||
#define SOI3_OFF 9 |
|||
#define SOI3_IC 10 |
|||
#define SOI3_IC_VBS 11 |
|||
#define SOI3_IC_VDS 12 |
|||
#define SOI3_IC_VGFS 13 |
|||
#define SOI3_IC_VGBS 21 |
|||
#define SOI3_W_SENS 14 |
|||
#define SOI3_L_SENS 15 |
|||
#define SOI3_IB 16 |
|||
#define SOI3_IGF 17 |
|||
#define SOI3_IGB 22 |
|||
#define SOI3_IS 18 |
|||
#define SOI3_POWER 19 |
|||
#define SOI3_TEMP 20 |
|||
|
|||
/* model parameters */ |
|||
#define SOI3_MOD_VTO 101 |
|||
#define SOI3_MOD_VFBF 149 |
|||
#define SOI3_MOD_KP 102 |
|||
#define SOI3_MOD_GAMMA 103 |
|||
#define SOI3_MOD_PHI 104 |
|||
#define SOI3_MOD_LAMBDA 105 |
|||
#define SOI3_MOD_THETA 139 |
|||
#define SOI3_MOD_RD 106 |
|||
#define SOI3_MOD_RS 107 |
|||
#define SOI3_MOD_CBD 108 |
|||
#define SOI3_MOD_CBS 109 |
|||
#define SOI3_MOD_IS 110 |
|||
#define SOI3_MOD_PB 111 |
|||
#define SOI3_MOD_CGFSO 112 |
|||
#define SOI3_MOD_CGFDO 113 |
|||
#define SOI3_MOD_CGFBO 114 |
|||
#define SOI3_MOD_CGBSO 144 |
|||
#define SOI3_MOD_CGBDO 145 |
|||
#define SOI3_MOD_CGB_BO 146 |
|||
#define SOI3_MOD_CJ 115 |
|||
#define SOI3_MOD_MJ 116 |
|||
#define SOI3_MOD_CJSW 117 |
|||
#define SOI3_MOD_MJSW 118 |
|||
#define SOI3_MOD_JS 119 |
|||
#define SOI3_MOD_TOF 120 |
|||
#define SOI3_MOD_TOB 133 |
|||
#define SOI3_MOD_TB 134 |
|||
#define SOI3_MOD_LD 121 |
|||
#define SOI3_MOD_RSH 122 |
|||
#define SOI3_MOD_U0 123 |
|||
#define SOI3_MOD_FC 124 |
|||
#define SOI3_MOD_NSUB 125 |
|||
#define SOI3_MOD_TPG 126 |
|||
#define SOI3_MOD_NQFF 147 |
|||
#define SOI3_MOD_NQFB 148 |
|||
#define SOI3_MOD_NSSF 127 |
|||
#define SOI3_MOD_NSSB 135 |
|||
#define SOI3_MOD_NSOI3 128 |
|||
#define SOI3_MOD_PSOI3 129 |
|||
#define SOI3_MOD_TNOM 130 |
|||
#define SOI3_MOD_KF 131 |
|||
#define SOI3_MOD_AF 132 |
|||
#define SOI3_MOD_KOX 142 |
|||
#define SOI3_MOD_SHSI 143 |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
#define SOI3_MOD_SIGMA 150 |
|||
#define SOI3_MOD_CHIFB 151 |
|||
#define SOI3_MOD_CHIPHI 152 |
|||
#define SOI3_MOD_DELTAW 153 |
|||
#define SOI3_MOD_DELTAL 154 |
|||
#define SOI3_MOD_VSAT 155 |
|||
#define SOI3_MOD_K 156 |
|||
#define SOI3_MOD_LX 157 |
|||
#define SOI3_MOD_VP 158 |
|||
#define SOI3_MOD_ETA 159 |
|||
#define SOI3_MOD_ALPHA0 140 |
|||
#define SOI3_MOD_BETA0 141 |
|||
#define SOI3_MOD_LM 160 |
|||
#define SOI3_MOD_LM1 161 |
|||
#define SOI3_MOD_LM2 162 |
|||
#define SOI3_MOD_ETAD 163 |
|||
#define SOI3_MOD_ETAD1 164 |
|||
#define SOI3_MOD_IS1 165 |
|||
#define SOI3_MOD_JS1 166 |
|||
#define SOI3_MOD_CHIBETA 167 |
|||
#define SOI3_MOD_VFBB 168 |
|||
#define SOI3_MOD_GAMMAB 169 |
|||
#define SOI3_MOD_CHID 170 |
|||
#define SOI3_MOD_CHID1 171 |
|||
#define SOI3_MOD_DVT 172 |
|||
#define SOI3_MOD_NLEV 173 |
|||
#define SOI3_MOD_BETABJT 174 |
|||
#define SOI3_MOD_TAUFBJT 176 |
|||
#define SOI3_MOD_TAURBJT 177 |
|||
#define SOI3_MOD_BETAEXP 178 |
|||
#define SOI3_MOD_TAUEXP 179 |
|||
#define SOI3_MOD_RSW 180 |
|||
#define SOI3_MOD_RDW 181 |
|||
#define SOI3_MOD_FMIN 382 |
|||
#define SOI3_MOD_VTEX 383 |
|||
#define SOI3_MOD_VDEX 384 |
|||
#define SOI3_MOD_DELTA0 385 |
|||
#define SOI3_MOD_CSF 386 |
|||
#define SOI3_MOD_DSI 387 |
|||
#define SOI3_MOD_NPLUS 388 |
|||
#define SOI3_MOD_RTA 389 |
|||
#define SOI3_MOD_CTA 390 |
|||
|
|||
/* device questions */ |
|||
#define SOI3_DNODE 201 |
|||
#define SOI3_GFNODE 202 |
|||
#define SOI3_SNODE 203 |
|||
#define SOI3_GBNODE 204 |
|||
#define SOI3_BNODE 205 |
|||
#define SOI3_DNODEPRIME 206 |
|||
#define SOI3_SNODEPRIME 207 |
|||
#define SOI3_TNODE 208 |
|||
#define SOI3_BRANCH 209 |
|||
#define SOI3_SOURCECONDUCT 210 |
|||
#define SOI3_DRAINCONDUCT 211 |
|||
#define SOI3_VON 212 |
|||
#define SOI3_VFBF 213 |
|||
#define SOI3_VDSAT 214 |
|||
#define SOI3_SOURCEVCRIT 215 |
|||
#define SOI3_DRAINVCRIT 216 |
|||
#define SOI3_ID 217 |
|||
#define SOI3_IBS 218 |
|||
#define SOI3_IBD 219 |
|||
#define SOI3_GMBS 220 |
|||
#define SOI3_GMF 221 |
|||
#define SOI3_GMB 222 |
|||
#define SOI3_GDS 223 |
|||
#define SOI3_GBD 224 |
|||
#define SOI3_GBS 225 |
|||
#define SOI3_CAPBD 226 |
|||
#define SOI3_CAPBS 227 |
|||
#define SOI3_CAPZEROBIASBD 228 |
|||
#define SOI3_CAPZEROBIASBDSW 229 |
|||
#define SOI3_CAPZEROBIASBS 230 |
|||
#define SOI3_CAPZEROBIASBSSW 231 |
|||
#define SOI3_VBD 232 |
|||
#define SOI3_VBS 233 |
|||
#define SOI3_VGFS 234 |
|||
#define SOI3_VGBS 235 |
|||
#define SOI3_VDS 236 |
|||
#define SOI3_QGF 237 |
|||
#define SOI3_IQGF 238 |
|||
#define SOI3_QGB 239 |
|||
#define SOI3_IQGB 240 |
|||
#define SOI3_QD 241 |
|||
#define SOI3_IQD 242 |
|||
#define SOI3_QS 243 |
|||
#define SOI3_IQS 244 |
|||
#define SOI3_QBD 245 |
|||
#define SOI3_IQBD 246 |
|||
#define SOI3_QBS 247 |
|||
#define SOI3_IQBS 248 |
|||
#define SOI3_CGFGF 249 |
|||
#define SOI3_CGFD 250 |
|||
#define SOI3_CGFS 251 |
|||
#define SOI3_CGFDELTAT 252 |
|||
#define SOI3_CDGF 253 |
|||
#define SOI3_CDD 254 |
|||
#define SOI3_CDS 255 |
|||
#define SOI3_CDDELTAT 256 |
|||
#define SOI3_CSGF 257 |
|||
#define SOI3_CSD 258 |
|||
#define SOI3_CSS 259 |
|||
#define SOI3_CSDELTAT 260 |
|||
#define SOI3_L_SENS_REAL 261 |
|||
#define SOI3_L_SENS_IMAG 262 |
|||
#define SOI3_L_SENS_MAG 263 |
|||
#define SOI3_L_SENS_PH 264 |
|||
#define SOI3_L_SENS_CPLX 265 |
|||
#define SOI3_W_SENS_REAL 266 |
|||
#define SOI3_W_SENS_IMAG 267 |
|||
#define SOI3_W_SENS_MAG 268 |
|||
#define SOI3_W_SENS_PH 269 |
|||
#define SOI3_W_SENS_CPLX 270 |
|||
#define SOI3_L_SENS_DC 271 |
|||
#define SOI3_W_SENS_DC 272 |
|||
#define SOI3_RT 273 |
|||
#define SOI3_CT 274 |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
#define SOI3_VFBB 275 |
|||
#define SOI3_RT1 276 |
|||
#define SOI3_CT1 277 |
|||
#define SOI3_RT2 278 |
|||
#define SOI3_CT2 279 |
|||
#define SOI3_RT3 280 |
|||
#define SOI3_CT3 281 |
|||
#define SOI3_RT4 282 |
|||
#define SOI3_CT4 283 |
|||
|
|||
/* model questions */ |
|||
|
|||
#include "soi3ext.h" |
|||
|
|||
#endif /*SOI3*/ |
|||
|
|||
@ -0,0 +1,50 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3delete(inModel,name,inst) |
|||
GENmodel *inModel; |
|||
IFuid name; |
|||
GENinstance **inst; |
|||
{ |
|||
SOI3model *model = (SOI3model *)inModel; |
|||
SOI3instance **fast = (SOI3instance **)inst; |
|||
SOI3instance **prev = NULL; |
|||
SOI3instance *here; |
|||
|
|||
for( ; model ; model = model->SOI3nextModel) { |
|||
prev = &(model->SOI3instances); |
|||
for(here = *prev; here ; here = *prev) { |
|||
if(here->SOI3name == name || (fast && here==*fast) ) { |
|||
*prev= here->SOI3nextInstance; |
|||
FREE(here); |
|||
return(OK); |
|||
} |
|||
prev = &(here->SOI3nextInstance); |
|||
} |
|||
} |
|||
return(E_NODEV); |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "soi3defs.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
void |
|||
SOI3destroy(inModel) |
|||
GENmodel **inModel; |
|||
{ |
|||
SOI3model **model = (SOI3model**)inModel; |
|||
SOI3instance *here; |
|||
SOI3instance *prev = NULL; |
|||
SOI3model *mod = *model; |
|||
SOI3model *oldmod = NULL; |
|||
|
|||
for( ; mod ; mod = mod->SOI3nextModel) { |
|||
if(oldmod) FREE(oldmod); |
|||
oldmod = mod; |
|||
prev = (SOI3instance *)NULL; |
|||
for(here = mod->SOI3instances ; here ; here = here->SOI3nextInstance) { |
|||
if(prev){ |
|||
/* if(prev->SOI3sens) FREE(prev->SOI3sens); */ |
|||
FREE(prev); |
|||
} |
|||
prev = here; |
|||
} |
|||
if(prev) FREE(prev); |
|||
} |
|||
if(oldmod) FREE(oldmod); |
|||
*model = NULL; |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
#ifdef __STDC__ |
|||
extern int SOI3acLoad(GENmodel *,CKTcircuit*); |
|||
extern int SOI3ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
|||
extern int SOI3delete(GENmodel*,IFuid,GENinstance**); |
|||
extern void SOI3destroy(GENmodel**); |
|||
extern int SOI3getic(GENmodel*,CKTcircuit*); |
|||
extern int SOI3load(GENmodel*,CKTcircuit*); |
|||
extern int SOI3mAsk(CKTcircuit *,GENmodel *,int,IFvalue*); |
|||
extern int SOI3mDelete(GENmodel**,IFuid,GENmodel*); |
|||
extern int SOI3mParam(int,IFvalue*,GENmodel*); |
|||
extern void SOI3cap(double,double,double, |
|||
double*,double*,double*,double*,double*,double*, |
|||
double*,double*,double*,double*, |
|||
double*,double*,double*,double*,double*,double*,double*,double*, |
|||
double*,double*,double*,double*,double*,double*,double*,double*,double*); |
|||
extern void SOI3capEval(CKTcircuit*,double*,double*, |
|||
double,double,double,double, |
|||
double,double,double,double, |
|||
double,double,double,double, |
|||
double,double,double,double,double, |
|||
double,double, |
|||
double*,double*,double*,double*, |
|||
double*,double*,double*,double*, |
|||
double*,double*,double*,double*, |
|||
double*,double*,double*,double*,double*, |
|||
double*,double*,double*, |
|||
double*,double*, |
|||
double*,double*,double*,double*,double*); |
|||
extern int SOI3param(int,IFvalue*,GENinstance*,IFvalue*); |
|||
/* extern int SOI3pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); | |
|||
extern int SOI3sAcLoad(GENmodel*,CKTcircuit*); | |
|||
extern int SOI3sLoad(GENmodel*,CKTcircuit*); | Ignored |
|||
extern void SOI3sPrint(GENmodel*,CKTcircuit*); | |
|||
extern int SOI3sSetup(SENstruct*,GENmodel*); | |
|||
extern int SOI3sUpdate(GENmodel*,CKTcircuit*); | */ |
|||
extern int SOI3setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
|||
extern int SOI3unsetup(GENmodel*,CKTcircuit*); |
|||
extern int SOI3temp(GENmodel*,CKTcircuit*); |
|||
extern int SOI3trunc(GENmodel*,CKTcircuit*,double*); |
|||
|
|||
#ifdef SIMETRIX_VERSION |
|||
/* NTL modification 27.4.98 - add lastAttempt */ |
|||
extern int SOI3convTest(GENmodel*,CKTcircuit*,int lastAttempt); |
|||
/* end NTL modification */ |
|||
#else /* SIMETRIX_VERSION */ |
|||
extern int SOI3convTest(GENmodel*,CKTcircuit*); |
|||
#endif /* SIMETRIX_VERSION */ |
|||
|
|||
/* extern int SOI3disto(int,GENmodel*,CKTcircuit*); */ |
|||
extern int SOI3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); |
|||
|
|||
#else /* stdc */ |
|||
extern int SOI3acLoad(); |
|||
extern int SOI3ask(); |
|||
extern int SOI3delete(); |
|||
extern void SOI3destroy(); |
|||
extern int SOI3getic(); |
|||
extern int SOI3load(); |
|||
extern int SOI3mAsk(); |
|||
extern int SOI3mDelete(); |
|||
extern int SOI3mParam(); |
|||
extern void SOI3cap(); |
|||
extern void SOI3capEval(); |
|||
extern int SOI3param(); |
|||
/* extern int SOI3pzLoad(); | |
|||
extern int SOI3sAcLoad(); | |
|||
extern int SOI3sLoad(); | ignored |
|||
extern void SOI3sPrint(); | |
|||
extern int SOI3sSetup(); | |
|||
extern int SOI3sUpdate(); */ |
|||
extern int SOI3setup(); |
|||
extern int SOI3unsetup(); |
|||
extern int SOI3temp(); |
|||
extern int SOI3trunc(); |
|||
extern int SOI3convTest(); |
|||
/* extern int SOI3disto(); */ |
|||
extern int SOI3noise(); |
|||
#endif /* stdc */ |
|||
@ -0,0 +1,65 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3getic(inModel,ckt) |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
{ |
|||
SOI3model *model = (SOI3model *)inModel; |
|||
SOI3instance *here; |
|||
/* |
|||
* grab initial conditions out of rhs array. User specified, so use |
|||
* external nodes to get values |
|||
*/ |
|||
|
|||
for( ; model ; model = model->SOI3nextModel) { |
|||
for(here = model->SOI3instances; here ; here = here->SOI3nextInstance) { |
|||
if(!here->SOI3icVBSGiven) { |
|||
here->SOI3icVBS = |
|||
*(ckt->CKTrhs + here->SOI3bNode) - |
|||
*(ckt->CKTrhs + here->SOI3sNode); |
|||
} |
|||
if(!here->SOI3icVDSGiven) { |
|||
here->SOI3icVDS = |
|||
*(ckt->CKTrhs + here->SOI3dNode) - |
|||
*(ckt->CKTrhs + here->SOI3sNode); |
|||
} |
|||
if(!here->SOI3icVGFSGiven) { |
|||
here->SOI3icVGFS = |
|||
*(ckt->CKTrhs + here->SOI3gfNode) - |
|||
*(ckt->CKTrhs + here->SOI3sNode); |
|||
} |
|||
if(!here->SOI3icVGBSGiven) { |
|||
here->SOI3icVGBS = |
|||
*(ckt->CKTrhs + here->SOI3gbNode) - |
|||
*(ckt->CKTrhs + here->SOI3sNode); |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
#include <config.h> |
|||
|
|||
#include <devdefs.h> |
|||
|
|||
#include "soi3itf.h" |
|||
#include "soi3ext.h" |
|||
#include "soi3init.h" |
|||
|
|||
|
|||
SPICEdev SOI3info = { |
|||
{ |
|||
"SOI3", |
|||
"Basic Thick Film SOI3 model", |
|||
|
|||
&SOI3nSize, |
|||
&SOI3nSize, |
|||
SOI3names, |
|||
|
|||
&SOI3pTSize, |
|||
SOI3pTable, |
|||
|
|||
&SOI3mPTSize, |
|||
SOI3mPTable, |
|||
DEV_DEFAULT |
|||
}, |
|||
|
|||
DEVparam : SOI3param, |
|||
DEVmodParam : SOI3mParam, |
|||
DEVload : SOI3load, |
|||
DEVsetup : SOI3setup, |
|||
DEVunsetup : SOI3unsetup, |
|||
DEVpzSetup : SOI3setup, |
|||
DEVtemperature: SOI3temp, |
|||
DEVtrunc : SOI3trunc, |
|||
DEVfindBranch : NULL, |
|||
DEVacLoad : SOI3acLoad, |
|||
DEVaccept : NULL, |
|||
DEVdestroy : SOI3destroy, |
|||
DEVmodDelete : SOI3mDelete, |
|||
DEVdelete : SOI3delete, |
|||
DEVsetic : SOI3getic, |
|||
DEVask : SOI3ask, |
|||
DEVmodAsk : SOI3mAsk, |
|||
DEVpzLoad : NULL, |
|||
DEVconvTest : SOI3convTest, |
|||
DEVsenSetup : NULL, |
|||
DEVsenLoad : NULL, |
|||
DEVsenUpdate : NULL, |
|||
DEVsenAcLoad : NULL, |
|||
DEVsenPrint : NULL, |
|||
DEVsenTrunc : NULL, |
|||
DEVdisto : NULL, |
|||
DEVnoise : SOI3noise, |
|||
|
|||
DEVinstSize : &SOI3iSize, |
|||
DEVmodSize : &SOI3mSize |
|||
|
|||
}; |
|||
|
|||
|
|||
SPICEdev * |
|||
get_soi3_info(void) |
|||
{ |
|||
return &SOI3info; |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
#ifndef _SOI3INIT_H |
|||
#define _SOI3INIT_H |
|||
|
|||
extern IFparm SOI3pTable[ ]; |
|||
extern IFparm SOI3mPTable[ ]; |
|||
extern char *SOI3names[ ]; |
|||
extern int SOI3pTSize; |
|||
extern int SOI3mPTSize; |
|||
extern int SOI3nSize; |
|||
extern int SOI3iSize; |
|||
extern int SOI3mSize; |
|||
|
|||
#endif |
|||
@ -0,0 +1,26 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#ifndef DEV_SOI3 |
|||
#define DEV_SOI3 |
|||
|
|||
SPICEdev *get_soi3_info(void); |
|||
|
|||
|
|||
#endif |
|||
2560
src/spicelib/devices/soi3/soi3load.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,286 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: Paolo Nenzi 2001 */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "cktdefs.h" |
|||
#include "devdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/*ARGSUSED*/ |
|||
int |
|||
SOI3mAsk(ckt,inst,which,value) |
|||
CKTcircuit *ckt; |
|||
GENmodel *inst; |
|||
int which; |
|||
IFvalue *value; |
|||
{ |
|||
SOI3model *model = (SOI3model *)inst; |
|||
switch(which) { |
|||
case SOI3_MOD_VTO: |
|||
value->rValue = model->SOI3vt0; |
|||
return(OK); |
|||
case SOI3_MOD_VFBF: |
|||
value->rValue = model->SOI3vfbF; |
|||
return(OK); |
|||
case SOI3_MOD_KP: |
|||
value->rValue = model->SOI3transconductance; |
|||
return(OK); |
|||
case SOI3_MOD_GAMMA: |
|||
value->rValue = model->SOI3gamma; |
|||
return(OK); |
|||
case SOI3_MOD_PHI: |
|||
value->rValue = model->SOI3phi; |
|||
return(OK); |
|||
case SOI3_MOD_LAMBDA: |
|||
value->rValue = model->SOI3lambda; |
|||
return(OK); |
|||
case SOI3_MOD_THETA: |
|||
value->rValue = model->SOI3theta; |
|||
return(OK); |
|||
case SOI3_MOD_RD: |
|||
value->rValue = model->SOI3drainResistance; |
|||
return(OK); |
|||
case SOI3_MOD_RS: |
|||
value->rValue = model->SOI3sourceResistance; |
|||
return(OK); |
|||
case SOI3_MOD_CBD: |
|||
value->rValue = model->SOI3capBD; |
|||
return(OK); |
|||
case SOI3_MOD_CBS: |
|||
value->rValue = model->SOI3capBS; |
|||
return(OK); |
|||
case SOI3_MOD_IS: |
|||
value->rValue = model->SOI3jctSatCur; |
|||
return(OK); |
|||
case SOI3_MOD_IS1: |
|||
value->rValue = model->SOI3jctSatCur1; |
|||
return(OK); |
|||
case SOI3_MOD_PB: |
|||
value->rValue = model->SOI3bulkJctPotential; |
|||
return(OK); |
|||
case SOI3_MOD_CGFSO: |
|||
value->rValue = model->SOI3frontGateSourceOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_CGFDO: |
|||
value->rValue = model->SOI3frontGateDrainOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_CGFBO: |
|||
value->rValue = model->SOI3frontGateBulkOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_CGBSO: |
|||
value->rValue = model->SOI3backGateSourceOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_CGBDO: |
|||
value->rValue = model->SOI3backGateDrainOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_CGB_BO: |
|||
value->rValue = model->SOI3backGateBulkOverlapCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_RSH: |
|||
value->rValue = model->SOI3sheetResistance; |
|||
return(OK); |
|||
case SOI3_MOD_CJSW: |
|||
value->rValue = model->SOI3sideWallCapFactor; |
|||
return(OK); |
|||
case SOI3_MOD_MJSW: |
|||
value->rValue = model->SOI3bulkJctSideGradingCoeff; |
|||
return(OK); |
|||
case SOI3_MOD_JS: |
|||
value->rValue = model->SOI3jctSatCurDensity; |
|||
return(OK); |
|||
case SOI3_MOD_JS1: |
|||
value->rValue = model->SOI3jctSatCurDensity1; |
|||
return(OK); |
|||
case SOI3_MOD_TOF: |
|||
value->rValue = model->SOI3frontOxideThickness; |
|||
return(OK); |
|||
case SOI3_MOD_TOB: |
|||
value->rValue = model->SOI3backOxideThickness; |
|||
return(OK); |
|||
case SOI3_MOD_TB: |
|||
value->rValue = model->SOI3bodyThickness; |
|||
return(OK); |
|||
case SOI3_MOD_LD: |
|||
value->rValue = model->SOI3latDiff; |
|||
return(OK); |
|||
case SOI3_MOD_U0: |
|||
value->rValue = model->SOI3surfaceMobility; |
|||
return(OK); |
|||
case SOI3_MOD_FC: |
|||
value->rValue = model->SOI3fwdCapDepCoeff; |
|||
return(OK); |
|||
case SOI3_MOD_KOX: |
|||
value->rValue = model->SOI3oxideThermalConductivity; |
|||
return(OK); |
|||
case SOI3_MOD_SHSI: |
|||
value->rValue = model->SOI3siliconSpecificHeat; |
|||
return(OK); |
|||
case SOI3_MOD_DSI: |
|||
value->rValue = model->SOI3siliconDensity; |
|||
return(OK); |
|||
case SOI3_MOD_NSUB: |
|||
value->rValue = model->SOI3substrateDoping; |
|||
return(OK); |
|||
case SOI3_MOD_TPG: |
|||
value->iValue = model->SOI3gateType; |
|||
return(OK); |
|||
case SOI3_MOD_NQFF: |
|||
value->rValue = model->SOI3frontFixedChargeDensity; |
|||
return(OK); |
|||
case SOI3_MOD_NQFB: |
|||
value->rValue = model->SOI3backFixedChargeDensity; |
|||
return(OK); |
|||
case SOI3_MOD_NSSF: |
|||
value->rValue = model->SOI3frontSurfaceStateDensity; |
|||
return(OK); |
|||
case SOI3_MOD_NSSB: |
|||
value->rValue = model->SOI3backSurfaceStateDensity; |
|||
return(OK); |
|||
case SOI3_MOD_TNOM: |
|||
value->rValue = model->SOI3tnom-CONSTCtoK; |
|||
return(OK); |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
case SOI3_MOD_SIGMA: |
|||
value->rValue = model->SOI3sigma; |
|||
return(OK); |
|||
case SOI3_MOD_CHIFB: |
|||
value->rValue = model->SOI3chiFB; |
|||
return(OK); |
|||
case SOI3_MOD_CHIPHI: |
|||
value->rValue = model->SOI3chiPHI; |
|||
return(OK); |
|||
case SOI3_MOD_DELTAW: |
|||
value->rValue = model->SOI3deltaW; |
|||
return(OK); |
|||
case SOI3_MOD_DELTAL: |
|||
value->rValue = model->SOI3deltaL; |
|||
return(OK); |
|||
case SOI3_MOD_VSAT: |
|||
value->rValue = model->SOI3vsat; |
|||
return(OK); |
|||
case SOI3_MOD_K: |
|||
value->rValue = model->SOI3k; |
|||
return(OK); |
|||
case SOI3_MOD_LX: |
|||
value->rValue = model->SOI3lx; |
|||
return(OK); |
|||
case SOI3_MOD_VP: |
|||
value->rValue = model->SOI3vp; |
|||
return(OK); |
|||
case SOI3_MOD_ETA: |
|||
value->rValue = model->SOI3eta; |
|||
return(OK); |
|||
case SOI3_MOD_ALPHA0: |
|||
value->rValue = model->SOI3alpha0; |
|||
return(OK); |
|||
case SOI3_MOD_BETA0: |
|||
value->rValue = model->SOI3beta0; |
|||
return(OK); |
|||
case SOI3_MOD_LM: |
|||
value->rValue = model->SOI3lm; |
|||
return(OK); |
|||
case SOI3_MOD_LM1: |
|||
value->rValue = model->SOI3lm1; |
|||
return(OK); |
|||
case SOI3_MOD_LM2: |
|||
value->rValue = model->SOI3lm2; |
|||
return(OK); |
|||
case SOI3_MOD_ETAD: |
|||
value->rValue = model->SOI3etad; |
|||
return(OK); |
|||
case SOI3_MOD_ETAD1: |
|||
value->rValue = model->SOI3etad1; |
|||
return(OK); |
|||
case SOI3_MOD_CHIBETA: |
|||
value->rValue = model->SOI3chibeta; |
|||
return(OK); |
|||
case SOI3_MOD_VFBB: |
|||
value->rValue = model->SOI3vfbB; |
|||
return(OK); |
|||
case SOI3_MOD_GAMMAB: |
|||
value->rValue = model->SOI3gammaB; |
|||
return(OK); |
|||
case SOI3_MOD_CHID: |
|||
value->rValue = model->SOI3chid; |
|||
return(OK); |
|||
case SOI3_MOD_CHID1: |
|||
value->rValue = model->SOI3chid1; |
|||
return(OK); |
|||
case SOI3_MOD_DVT: |
|||
value->iValue = model->SOI3dvt; |
|||
return(OK); |
|||
case SOI3_MOD_NLEV: |
|||
value->iValue = model->SOI3nLev; |
|||
return(OK); |
|||
case SOI3_MOD_BETABJT: |
|||
value->rValue = model->SOI3betaBJT; |
|||
return(OK); |
|||
case SOI3_MOD_TAUFBJT: |
|||
value->rValue = model->SOI3tauFBJT; |
|||
return(OK); |
|||
case SOI3_MOD_TAURBJT: |
|||
value->rValue = model->SOI3tauRBJT; |
|||
return(OK); |
|||
case SOI3_MOD_BETAEXP: |
|||
value->rValue = model->SOI3betaEXP; |
|||
return(OK); |
|||
case SOI3_MOD_TAUEXP: |
|||
value->rValue = model->SOI3tauEXP; |
|||
return(OK); |
|||
case SOI3_MOD_RSW: |
|||
value->rValue = model->SOI3rsw; |
|||
return(OK); |
|||
case SOI3_MOD_RDW: |
|||
value->rValue = model->SOI3rdw; |
|||
return(OK); |
|||
case SOI3_MOD_FMIN: |
|||
value->rValue = model->SOI3minimumFeatureSize; |
|||
return(OK); |
|||
case SOI3_MOD_VTEX: |
|||
value->rValue = model->SOI3vtex; |
|||
return(OK); |
|||
case SOI3_MOD_VDEX: |
|||
value->rValue = model->SOI3vdex; |
|||
return(OK); |
|||
case SOI3_MOD_DELTA0: |
|||
value->rValue = model->SOI3delta0; |
|||
return(OK); |
|||
case SOI3_MOD_CSF: |
|||
value->rValue = model->SOI3satChargeShareFactor; |
|||
return(OK); |
|||
case SOI3_MOD_NPLUS: |
|||
value->rValue = model->SOI3nplusDoping; |
|||
return(OK); |
|||
case SOI3_MOD_RTA: |
|||
value->rValue = model->SOI3rta; |
|||
return(OK); |
|||
case SOI3_MOD_CTA: |
|||
value->rValue = model->SOI3cta; |
|||
return(OK); |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
/* NOTREACHED */ |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3mDelete(inModel,modname,kill) |
|||
GENmodel **inModel; |
|||
IFuid modname; |
|||
GENmodel *kill; |
|||
{ |
|||
SOI3model **model = (SOI3model **)inModel; |
|||
SOI3model *modfast = (SOI3model *)kill; |
|||
SOI3instance *here; |
|||
SOI3instance *prev = NULL; |
|||
SOI3model **oldmod; |
|||
oldmod = model; |
|||
for( ; *model ; model = &((*model)->SOI3nextModel)) { |
|||
if( (*model)->SOI3modName == modname || |
|||
(modfast && *model == modfast) ) goto delgot; |
|||
oldmod = model; |
|||
} |
|||
return(E_NOMOD); |
|||
|
|||
delgot: |
|||
*oldmod = (*model)->SOI3nextModel; /* cut deleted device out of list */ |
|||
for(here = (*model)->SOI3instances ; here ; here = here->SOI3nextInstance) { |
|||
if(prev) FREE(prev); |
|||
prev = here; |
|||
} |
|||
if(prev) FREE(prev); |
|||
FREE(*model); |
|||
return(OK); |
|||
|
|||
} |
|||
@ -0,0 +1,390 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
int |
|||
SOI3mParam(param,value,inModel) |
|||
int param; |
|||
IFvalue *value; |
|||
GENmodel *inModel; |
|||
{ |
|||
register SOI3model *model = (SOI3model *)inModel; |
|||
switch(param) { |
|||
case SOI3_MOD_VTO: |
|||
model->SOI3vt0 = value->rValue; |
|||
model->SOI3vt0Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_VFBF: |
|||
model->SOI3vfbF = value->rValue; |
|||
model->SOI3vfbFGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_KP: |
|||
model->SOI3transconductance = value->rValue; |
|||
model->SOI3transconductanceGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_GAMMA: |
|||
model->SOI3gamma = value->rValue; |
|||
model->SOI3gammaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_PHI: |
|||
model->SOI3phi = value->rValue; |
|||
model->SOI3phiGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_LAMBDA: |
|||
model->SOI3lambda = value->rValue; |
|||
model->SOI3lambdaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_THETA: |
|||
model->SOI3theta = value->rValue; |
|||
model->SOI3thetaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_RD: |
|||
model->SOI3drainResistance = value->rValue; |
|||
model->SOI3drainResistanceGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_RS: |
|||
model->SOI3sourceResistance = value->rValue; |
|||
model->SOI3sourceResistanceGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CBD: |
|||
model->SOI3capBD = value->rValue; |
|||
model->SOI3capBDGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CBS: |
|||
model->SOI3capBS = value->rValue; |
|||
model->SOI3capBSGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_IS: |
|||
model->SOI3jctSatCur = value->rValue; |
|||
model->SOI3jctSatCurGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_IS1: |
|||
model->SOI3jctSatCur1 = value->rValue; |
|||
model->SOI3jctSatCur1Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_PB: |
|||
model->SOI3bulkJctPotential = value->rValue; |
|||
model->SOI3bulkJctPotentialGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGFSO: |
|||
model->SOI3frontGateSourceOverlapCapFactor = value->rValue; |
|||
model->SOI3frontGateSourceOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGFDO: |
|||
model->SOI3frontGateDrainOverlapCapFactor = value->rValue; |
|||
model->SOI3frontGateDrainOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGFBO: |
|||
model->SOI3frontGateBulkOverlapCapFactor = value->rValue; |
|||
model->SOI3frontGateBulkOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGBSO: |
|||
model->SOI3backGateSourceOverlapCapFactor = value->rValue; |
|||
model->SOI3backGateSourceOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGBDO: |
|||
model->SOI3backGateDrainOverlapCapFactor = value->rValue; |
|||
model->SOI3backGateDrainOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CGB_BO: |
|||
model->SOI3backGateBulkOverlapCapFactor = value->rValue; |
|||
model->SOI3backGateBulkOverlapCapFactorGiven = TRUE; |
|||
break; |
|||
/* case SOI3_MOD_CJ: |
|||
model->SOI3bulkCapFactor = value->rValue; |
|||
model->SOI3bulkCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_MJ: |
|||
model->SOI3bulkJctBotGradingCoeff = value->rValue; |
|||
model->SOI3bulkJctBotGradingCoeffGiven = TRUE; |
|||
break; */ |
|||
case SOI3_MOD_RSH: |
|||
model->SOI3sheetResistance = value->rValue; |
|||
model->SOI3sheetResistanceGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CJSW: |
|||
model->SOI3sideWallCapFactor = value->rValue; |
|||
model->SOI3sideWallCapFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_MJSW: |
|||
model->SOI3bulkJctSideGradingCoeff = value->rValue; |
|||
model->SOI3bulkJctSideGradingCoeffGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_JS: |
|||
model->SOI3jctSatCurDensity = value->rValue; |
|||
model->SOI3jctSatCurDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_JS1: |
|||
model->SOI3jctSatCurDensity1 = value->rValue; |
|||
model->SOI3jctSatCurDensity1Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_TOF: |
|||
model->SOI3frontOxideThickness = value->rValue; |
|||
model->SOI3frontOxideThicknessGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TOB: |
|||
model->SOI3backOxideThickness = value->rValue; |
|||
model->SOI3backOxideThicknessGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TB: |
|||
model->SOI3bodyThickness = value->rValue; |
|||
model->SOI3bodyThicknessGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_LD: |
|||
model->SOI3latDiff = value->rValue; |
|||
model->SOI3latDiffGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_U0: |
|||
model->SOI3surfaceMobility = value->rValue; |
|||
model->SOI3surfaceMobilityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_FC: |
|||
model->SOI3fwdCapDepCoeff = value->rValue; |
|||
model->SOI3fwdCapDepCoeffGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NSOI3: |
|||
if(value->iValue) { |
|||
model->SOI3type = 1; |
|||
model->SOI3typeGiven = TRUE; |
|||
} |
|||
break; |
|||
case SOI3_MOD_PSOI3: |
|||
if(value->iValue) { |
|||
model->SOI3type = -1; |
|||
model->SOI3typeGiven = TRUE; |
|||
} |
|||
break; |
|||
case SOI3_MOD_KOX: |
|||
model->SOI3oxideThermalConductivity = value->rValue; |
|||
model->SOI3oxideThermalConductivityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_SHSI: |
|||
model->SOI3siliconSpecificHeat = value->rValue; |
|||
model->SOI3siliconSpecificHeatGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_DSI: |
|||
model->SOI3siliconDensity = value->rValue; |
|||
model->SOI3siliconDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NSUB: |
|||
model->SOI3substrateDoping = value->rValue; |
|||
model->SOI3substrateDopingGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TPG: |
|||
model->SOI3gateType = value->iValue; |
|||
model->SOI3gateTypeGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NQFF: |
|||
model->SOI3frontFixedChargeDensity = value->rValue; |
|||
model->SOI3frontFixedChargeDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NQFB: |
|||
model->SOI3backFixedChargeDensity = value->rValue; |
|||
model->SOI3backFixedChargeDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NSSF: |
|||
model->SOI3frontSurfaceStateDensity = value->rValue; |
|||
model->SOI3frontSurfaceStateDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NSSB: |
|||
model->SOI3backSurfaceStateDensity = value->rValue; |
|||
model->SOI3backSurfaceStateDensityGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TNOM: |
|||
model->SOI3tnom = value->rValue+CONSTCtoK; |
|||
model->SOI3tnomGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_KF: |
|||
model->SOI3fNcoef = value->rValue; |
|||
model->SOI3fNcoefGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_AF: |
|||
model->SOI3fNexp = value->rValue; |
|||
model->SOI3fNexpGiven = TRUE; |
|||
break; |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
case SOI3_MOD_SIGMA: |
|||
model->SOI3sigma = value->rValue; |
|||
model->SOI3sigmaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CHIFB: |
|||
model->SOI3chiFB = value->rValue; |
|||
model->SOI3chiFBGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CHIPHI: |
|||
model->SOI3chiPHI = value->rValue; |
|||
model->SOI3chiPHIGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_DELTAW: |
|||
model->SOI3deltaW = value->rValue; |
|||
model->SOI3deltaWGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_DELTAL: |
|||
model->SOI3deltaL = value->rValue; |
|||
model->SOI3deltaLGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_VSAT: |
|||
model->SOI3vsat = value->rValue; |
|||
model->SOI3vsatGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_K: |
|||
model->SOI3k = value->rValue; |
|||
model->SOI3kGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_LX: |
|||
model->SOI3lx = value->rValue; |
|||
model->SOI3lxGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_VP: |
|||
model->SOI3vp = value->rValue; |
|||
model->SOI3vpGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_ETA: |
|||
model->SOI3eta = value->rValue; |
|||
model->SOI3etaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_ALPHA0: |
|||
model->SOI3alpha0 = value->rValue; |
|||
model->SOI3alpha0Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_BETA0: |
|||
model->SOI3beta0 = value->rValue; |
|||
model->SOI3beta0Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_LM: |
|||
model->SOI3lm = value->rValue; |
|||
model->SOI3lmGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_LM1: |
|||
model->SOI3lm1 = value->rValue; |
|||
model->SOI3lm1Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_LM2: |
|||
model->SOI3lm2 = value->rValue; |
|||
model->SOI3lm2Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_ETAD: |
|||
model->SOI3etad = value->rValue; |
|||
model->SOI3etadGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_ETAD1: |
|||
model->SOI3etad1 = value->rValue; |
|||
model->SOI3etad1Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_CHIBETA: |
|||
model->SOI3chibeta = value->rValue; |
|||
model->SOI3chibetaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_VFBB: |
|||
model->SOI3vfbB = value->rValue; |
|||
model->SOI3vfbBGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_GAMMAB: |
|||
model->SOI3gammaB = value->rValue; |
|||
model->SOI3gammaBGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CHID: |
|||
model->SOI3chid = value->rValue; |
|||
model->SOI3chidGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CHID1: |
|||
model->SOI3chid1 = value->rValue; |
|||
model->SOI3chid1Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_DVT: |
|||
model->SOI3dvt = value->iValue; |
|||
model->SOI3dvtGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NLEV: |
|||
model->SOI3nLev = value->iValue; |
|||
model->SOI3nLevGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_BETABJT: |
|||
model->SOI3betaBJT = value->rValue; |
|||
model->SOI3betaBJTGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TAUFBJT: |
|||
model->SOI3tauFBJT = value->rValue; |
|||
model->SOI3tauFBJTGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TAURBJT: |
|||
model->SOI3tauRBJT = value->rValue; |
|||
model->SOI3tauRBJTGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_BETAEXP: |
|||
model->SOI3betaEXP = value->rValue; |
|||
model->SOI3betaEXPGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_TAUEXP: |
|||
model->SOI3tauEXP = value->rValue; |
|||
model->SOI3tauEXPGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_RSW: |
|||
model->SOI3rsw = value->rValue; |
|||
model->SOI3rswGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_RDW: |
|||
model->SOI3rdw = value->rValue; |
|||
model->SOI3rdwGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_FMIN: |
|||
model->SOI3minimumFeatureSize = value->rValue; |
|||
model->SOI3minimumFeatureSizeGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_VTEX: |
|||
model->SOI3vtex = value->rValue; |
|||
model->SOI3vtexGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_VDEX: |
|||
model->SOI3vdex = value->rValue; |
|||
model->SOI3vdexGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_DELTA0: |
|||
model->SOI3delta0 = value->rValue; |
|||
model->SOI3delta0Given = TRUE; |
|||
break; |
|||
case SOI3_MOD_CSF: |
|||
model->SOI3satChargeShareFactor = value->rValue; |
|||
model->SOI3satChargeShareFactorGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_NPLUS: |
|||
model->SOI3nplusDoping = value->rValue; |
|||
model->SOI3nplusDopingGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_RTA: |
|||
model->SOI3rta = value->rValue; |
|||
model->SOI3rtaGiven = TRUE; |
|||
break; |
|||
case SOI3_MOD_CTA: |
|||
model->SOI3cta = value->rValue; |
|||
model->SOI3ctaGiven = TRUE; |
|||
break; |
|||
|
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,279 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "soi3defs.h" |
|||
#include "cktdefs.h" |
|||
#include "iferrmsg.h" |
|||
#include "noisedef.h" |
|||
#include "const.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
|
|||
/* This routine is VERY closely based on the standard MOS noise function. |
|||
* SOI3noise (mode, operation, firstModel, ckt, data, OnDens) |
|||
* This routine names and evaluates all of the noise sources |
|||
* associated with MOSFET's. It starts with the model *firstModel and |
|||
* traverses all of its insts. It then proceeds to any other models |
|||
* on the linked list. The total output noise density generated by |
|||
* all of the MOSFET's is summed with the variable "OnDens". |
|||
*/ |
|||
|
|||
extern void NevalSrc(); |
|||
extern double Nintegrate(); |
|||
|
|||
int |
|||
SOI3noise (mode, operation, genmodel, ckt, data, OnDens) |
|||
int mode; |
|||
int operation; |
|||
GENmodel *genmodel; |
|||
CKTcircuit *ckt; |
|||
register Ndata *data; |
|||
double *OnDens; |
|||
{ |
|||
SOI3model *firstModel = (SOI3model *) genmodel; |
|||
register SOI3model *model; |
|||
register SOI3instance *inst; |
|||
char name[N_MXVLNTH]; |
|||
double tempOnoise; |
|||
double tempInoise; |
|||
double noizDens[SOI3NSRCS]; |
|||
double lnNdens[SOI3NSRCS]; |
|||
double gain; |
|||
double EffectiveLength; |
|||
int error; |
|||
int i; |
|||
|
|||
/* define the names of the noise sources */ |
|||
|
|||
static char *SOI3nNames[SOI3NSRCS] = { /* Note that we have to keep the order */ |
|||
"_rd", /* noise due to rd */ /* consistent with the index definitions */ |
|||
"_rs", /* noise due to rs */ /* in SOI3defs.h */ |
|||
"_id", /* noise due to id */ |
|||
"_1overf", /* flicker (1/f) noise */ |
|||
"" /* total transistor noise */ |
|||
}; |
|||
|
|||
for (model=firstModel; model != NULL; model=model->SOI3nextModel) { |
|||
for (inst=model->SOI3instances; inst != NULL; inst=inst->SOI3nextInstance) { |
|||
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 < SOI3NSRCS; i++) { |
|||
|
|||
(void)sprintf(name,"onoise_%s%s",inst->SOI3name,SOI3nNames[i]); |
|||
|
|||
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
(*(SPfrontEnd->IFnewUid))(ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL,name,UID_OTHER,(void **)NULL); |
|||
/* we've added one more plot */ |
|||
|
|||
|
|||
} |
|||
break; |
|||
|
|||
case INT_NOIZ: |
|||
for (i=0; i < SOI3NSRCS; i++) { |
|||
|
|||
(void)sprintf(name,"onoise_total_%s%s",inst->SOI3name,SOI3nNames[i]); |
|||
|
|||
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
(*(SPfrontEnd->IFnewUid))(ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL,name,UID_OTHER,(void **)NULL); |
|||
/* we've added one more plot */ |
|||
|
|||
(void)sprintf(name,"inoise_total_%s%s",inst->SOI3name,SOI3nNames[i]); |
|||
|
|||
|
|||
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
(*(SPfrontEnd->IFnewUid))(ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL,name,UID_OTHER,(void **)NULL); |
|||
/* we've added one more plot */ |
|||
|
|||
|
|||
|
|||
} |
|||
break; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case N_CALC: |
|||
switch (mode) { |
|||
|
|||
case N_DENS: |
|||
/* just get gain from eval routine. Do thermal |
|||
* noise ourselves as we have local temperature |
|||
* rise. Also can use channel charge so model |
|||
* is valid in ALL regions and not just saturation. |
|||
*/ |
|||
EffectiveLength=inst->SOI3l - 2*model->SOI3latDiff; |
|||
NevalSrc(&noizDens[SOI3RDNOIZ],(double*)NULL, |
|||
ckt,N_GAIN,inst->SOI3dNodePrime,inst->SOI3dNode, |
|||
(double)0.0); |
|||
noizDens[SOI3RDNOIZ] *= 4 * CONSTboltz * |
|||
(ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * |
|||
inst->SOI3drainConductance; |
|||
lnNdens[SOI3RDNOIZ] = log(MAX(noizDens[SOI3RDNOIZ],N_MINLOG)); |
|||
|
|||
NevalSrc(&noizDens[SOI3RSNOIZ],(double*)NULL, |
|||
ckt,N_GAIN,inst->SOI3sNodePrime,inst->SOI3sNode, |
|||
(double)0.0); |
|||
noizDens[SOI3RSNOIZ] *= 4 * CONSTboltz * |
|||
(ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * |
|||
inst->SOI3sourceConductance; |
|||
lnNdens[SOI3RSNOIZ] = log(MAX(noizDens[SOI3RSNOIZ],N_MINLOG)); |
|||
|
|||
NevalSrc(&gain,(double*)NULL,ckt, |
|||
N_GAIN,inst->SOI3dNodePrime, inst->SOI3sNodePrime, |
|||
(double)0.0); |
|||
|
|||
noizDens[SOI3IDNOIZ] = (gain * 4 * CONSTboltz * |
|||
(ckt->CKTtemp + *(ckt->CKTstate0 + inst->SOI3deltaT)) * |
|||
inst->SOI3ueff * |
|||
fabs(*(ckt->CKTstate0 + inst->SOI3qd) + |
|||
*(ckt->CKTstate0 + inst->SOI3qs)))/ |
|||
(EffectiveLength*EffectiveLength); |
|||
lnNdens[SOI3IDNOIZ] = log(MAX(noizDens[SOI3IDNOIZ],N_MINLOG)); |
|||
|
|||
switch (model->SOI3nLev) { |
|||
case 2: |
|||
noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * |
|||
(inst->SOI3gmf)*(inst->SOI3gmf)/ |
|||
(model->SOI3frontOxideCapFactor * |
|||
inst->SOI3w * EffectiveLength * |
|||
exp(model->SOI3fNexp * |
|||
log(MAX(fabs(data->freq),N_MINLOG))) |
|||
); |
|||
break; |
|||
|
|||
case 1: |
|||
noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * |
|||
exp(model->SOI3fNexp * |
|||
log(MAX(fabs(inst->SOI3id),N_MINLOG))) / |
|||
(data->freq * EffectiveLength * inst->SOI3w * |
|||
model->SOI3frontOxideCapFactor); |
|||
break; |
|||
|
|||
case 0: |
|||
default: |
|||
noizDens[SOI3FLNOIZ] = gain * model->SOI3fNcoef * |
|||
exp(model->SOI3fNexp * |
|||
log(MAX(fabs(inst->SOI3id),N_MINLOG))) / |
|||
(data->freq * EffectiveLength * EffectiveLength * |
|||
model->SOI3frontOxideCapFactor); |
|||
break; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
lnNdens[SOI3FLNOIZ] = |
|||
log(MAX(noizDens[SOI3FLNOIZ],N_MINLOG)); |
|||
|
|||
noizDens[SOI3TOTNOIZ] = noizDens[SOI3RDNOIZ] + |
|||
noizDens[SOI3RSNOIZ] + |
|||
noizDens[SOI3IDNOIZ] + |
|||
noizDens[SOI3FLNOIZ]; |
|||
lnNdens[SOI3TOTNOIZ] = |
|||
log(MAX(noizDens[SOI3TOTNOIZ], N_MINLOG)); |
|||
|
|||
*OnDens += noizDens[SOI3TOTNOIZ]; |
|||
|
|||
if (data->delFreq == 0.0) { |
|||
|
|||
/* if we haven't done any previous integration, we need to */ |
|||
/* initialize our "history" variables */ |
|||
|
|||
for (i=0; i < SOI3NSRCS; i++) { |
|||
inst->SOI3nVar[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 < SOI3NSRCS; i++) { |
|||
inst->SOI3nVar[OUTNOIZ][i] = 0.0; |
|||
inst->SOI3nVar[INNOIZ][i] = 0.0; |
|||
} |
|||
} |
|||
} else { /* data->delFreq != 0.0 (we have to integrate) */ |
|||
for (i=0; i < SOI3NSRCS; i++) { |
|||
if (i != SOI3TOTNOIZ) { |
|||
tempOnoise = Nintegrate(noizDens[i], lnNdens[i], |
|||
inst->SOI3nVar[LNLSTDENS][i], data); |
|||
tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , |
|||
lnNdens[i] + data->lnGainInv, |
|||
inst->SOI3nVar[LNLSTDENS][i] + data->lnGainInv, |
|||
data); |
|||
inst->SOI3nVar[LNLSTDENS][i] = lnNdens[i]; |
|||
data->outNoiz += tempOnoise; |
|||
data->inNoise += tempInoise; |
|||
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { |
|||
inst->SOI3nVar[OUTNOIZ][i] += tempOnoise; |
|||
inst->SOI3nVar[OUTNOIZ][SOI3TOTNOIZ] += tempOnoise; |
|||
inst->SOI3nVar[INNOIZ][i] += tempInoise; |
|||
inst->SOI3nVar[INNOIZ][SOI3TOTNOIZ] += tempInoise; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if (data->prtSummary) { |
|||
for (i=0; i < SOI3NSRCS; 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 < SOI3NSRCS; i++) { |
|||
data->outpVector[data->outNumber++] = inst->SOI3nVar[OUTNOIZ][i]; |
|||
data->outpVector[data->outNumber++] = inst->SOI3nVar[INNOIZ][i]; |
|||
} |
|||
} /* if */ |
|||
break; |
|||
} /* switch (mode) */ |
|||
break; |
|||
|
|||
case N_CLOSE: |
|||
return (OK); /* do nothing, the main calling routine will close */ |
|||
break; /* the plots */ |
|||
} /* switch (operation) */ |
|||
} /* for inst */ |
|||
} /* for model */ |
|||
|
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,153 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/* ARGSUSED */ |
|||
int |
|||
SOI3param(param,value,inst,select) |
|||
int param; |
|||
IFvalue *value; |
|||
GENinstance *inst; |
|||
IFvalue *select; |
|||
{ |
|||
SOI3instance *here = (SOI3instance *)inst; |
|||
switch(param) { |
|||
case SOI3_L: |
|||
here->SOI3l = value->rValue; |
|||
here->SOI3lGiven = TRUE; |
|||
break; |
|||
case SOI3_W: |
|||
here->SOI3w = value->rValue; |
|||
here->SOI3wGiven = TRUE; |
|||
break; |
|||
case SOI3_NRD: |
|||
here->SOI3drainSquares = value->rValue; |
|||
here->SOI3drainSquaresGiven = TRUE; |
|||
break; |
|||
case SOI3_NRS: |
|||
here->SOI3sourceSquares = value->rValue; |
|||
here->SOI3sourceSquaresGiven = TRUE; |
|||
break; |
|||
case SOI3_OFF: |
|||
here->SOI3off = value->iValue; |
|||
break; |
|||
case SOI3_IC_VDS: |
|||
here->SOI3icVDS = value->rValue; |
|||
here->SOI3icVDSGiven = TRUE; |
|||
break; |
|||
case SOI3_IC_VGFS: |
|||
here->SOI3icVGFS = value->rValue; |
|||
here->SOI3icVGFSGiven = TRUE; |
|||
break; |
|||
case SOI3_IC_VGBS: |
|||
here->SOI3icVGBS = value->rValue; |
|||
here->SOI3icVGBSGiven = TRUE; |
|||
break; |
|||
case SOI3_IC_VBS: |
|||
here->SOI3icVBS = value->rValue; |
|||
here->SOI3icVBSGiven = TRUE; |
|||
break; |
|||
case SOI3_TEMP: |
|||
here->SOI3temp = value->rValue+CONSTCtoK; |
|||
here->SOI3tempGiven = TRUE; |
|||
break; |
|||
case SOI3_RT: |
|||
here->SOI3rt = value->rValue; |
|||
here->SOI3rtGiven = TRUE; |
|||
break; |
|||
case SOI3_CT: |
|||
here->SOI3ct = value->rValue; |
|||
here->SOI3ctGiven = TRUE; |
|||
break; |
|||
case SOI3_RT1: |
|||
here->SOI3rt1 = value->rValue; |
|||
here->SOI3rt1Given = TRUE; |
|||
break; |
|||
case SOI3_CT1: |
|||
here->SOI3ct1 = value->rValue; |
|||
here->SOI3ct1Given = TRUE; |
|||
break; |
|||
case SOI3_RT2: |
|||
here->SOI3rt2 = value->rValue; |
|||
here->SOI3rt2Given = TRUE; |
|||
break; |
|||
case SOI3_CT2: |
|||
here->SOI3ct2 = value->rValue; |
|||
here->SOI3ct2Given = TRUE; |
|||
break; |
|||
case SOI3_RT3: |
|||
here->SOI3rt3 = value->rValue; |
|||
here->SOI3rt3Given = TRUE; |
|||
break; |
|||
case SOI3_CT3: |
|||
here->SOI3ct3 = value->rValue; |
|||
here->SOI3ct3Given = TRUE; |
|||
break; |
|||
case SOI3_RT4: |
|||
here->SOI3rt4 = value->rValue; |
|||
here->SOI3rt4Given = TRUE; |
|||
break; |
|||
case SOI3_CT4: |
|||
here->SOI3ct4 = value->rValue; |
|||
here->SOI3ct4Given = TRUE; |
|||
break; |
|||
case SOI3_IC: |
|||
switch(value->v.numValue){ |
|||
case 4: |
|||
here->SOI3icVBS = *(value->v.vec.rVec+3); |
|||
here->SOI3icVBSGiven = TRUE; |
|||
case 3: |
|||
here->SOI3icVGBS = *(value->v.vec.rVec+2); |
|||
here->SOI3icVGBSGiven = TRUE; |
|||
case 2: |
|||
here->SOI3icVGFS = *(value->v.vec.rVec+1); |
|||
here->SOI3icVGFSGiven = TRUE; |
|||
case 1: |
|||
here->SOI3icVDS = *(value->v.vec.rVec); |
|||
here->SOI3icVDSGiven = TRUE; |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
break; |
|||
/* case SOI3_L_SENS: |
|||
if(value->iValue) { |
|||
here->SOI3senParmNo = 1; |
|||
here->SOI3sens_l = 1; |
|||
} |
|||
break; |
|||
case SOI3_W_SENS: |
|||
if(value->iValue) { |
|||
here->SOI3senParmNo = 1; |
|||
here->SOI3sens_w = 1; |
|||
} |
|||
break; */ |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -0,0 +1,751 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "smpdefs.h" |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3setup(matrix,inModel,ckt,states) |
|||
SMPmatrix *matrix; |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
int *states; |
|||
{ |
|||
SOI3model *model = (SOI3model *)inModel; |
|||
SOI3instance *here; |
|||
int error; |
|||
CKTnode *tmp; |
|||
|
|||
/* JimB - new variable for RT and CT scaling */ |
|||
double thermal_area; |
|||
|
|||
double rtargs[5]; |
|||
double * rtptr; |
|||
int node_count; |
|||
|
|||
/****** Part 1 - set any model parameters that are not present in ******/ |
|||
/****** the netlist to default values. ******/ |
|||
|
|||
/* loop through all the SOI3 device models */ |
|||
for( ; model != NULL; model = model->SOI3nextModel ) { |
|||
|
|||
if(!model->SOI3typeGiven) { |
|||
model->SOI3type = NSOI3; |
|||
} |
|||
if(!model->SOI3latDiffGiven) { |
|||
model->SOI3latDiff = 0; |
|||
} |
|||
if(!model->SOI3jctSatCurDensityGiven) { |
|||
model->SOI3jctSatCurDensity = 1.0e-10; |
|||
} |
|||
if(!model->SOI3jctSatCurDensity1Given) { |
|||
model->SOI3jctSatCurDensity1 = 0.0; |
|||
} |
|||
if(!model->SOI3jctSatCurGiven) { |
|||
model->SOI3jctSatCur = 0.0; |
|||
} |
|||
if(!model->SOI3jctSatCur1Given) { |
|||
model->SOI3jctSatCur1 = 0.0; |
|||
} |
|||
if(!model->SOI3transconductanceGiven) { |
|||
model->SOI3transconductance = 2e-5; |
|||
} |
|||
if(!model->SOI3frontGateSourceOverlapCapFactorGiven) { |
|||
model->SOI3frontGateSourceOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3frontGateDrainOverlapCapFactorGiven) { |
|||
model->SOI3frontGateDrainOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3frontGateBulkOverlapCapFactorGiven) { |
|||
model->SOI3frontGateBulkOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3backGateSourceOverlapCapFactorGiven) { |
|||
model->SOI3backGateSourceOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3backGateDrainOverlapCapFactorGiven) { |
|||
model->SOI3backGateDrainOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3backGateBulkOverlapCapFactorGiven) { |
|||
model->SOI3backGateBulkOverlapCapFactor = 0; |
|||
} |
|||
if(!model->SOI3sideWallCapFactorGiven) { |
|||
model->SOI3sideWallCapFactor = 0; |
|||
} |
|||
if(!model->SOI3bulkJctPotentialGiven) { |
|||
model->SOI3bulkJctPotential = 0.8; |
|||
} |
|||
if(!model->SOI3bulkJctSideGradingCoeffGiven) { |
|||
model->SOI3bulkJctSideGradingCoeff = 0.5; |
|||
} |
|||
if(!model->SOI3fwdCapDepCoeffGiven) { |
|||
model->SOI3fwdCapDepCoeff = 0.5; |
|||
} |
|||
if(!model->SOI3lambdaGiven) { |
|||
model->SOI3lambda = 0; |
|||
} |
|||
if(!model->SOI3thetaGiven) { |
|||
model->SOI3theta = 0; |
|||
} |
|||
/* JimB - If SiO2 thermal conductivity given in netlist then use */ |
|||
/* that value, otherwise use literature value. (Units W/K*m). */ |
|||
if(!model->SOI3oxideThermalConductivityGiven) { |
|||
model->SOI3oxideThermalConductivity = 1.4; |
|||
} |
|||
/* JimB - If Si specific heat given in netlist then use that value, */ |
|||
/* otherwise use literature value. (Units J/kg*K). */ |
|||
if(!model->SOI3siliconSpecificHeatGiven) { |
|||
model->SOI3siliconSpecificHeat = 700; |
|||
} |
|||
/* JimB - If density of Si given in netlist then use that value, */ |
|||
/* otherwise use literature value. (kg/m^3). */ |
|||
if(!model->SOI3siliconDensityGiven) { |
|||
model->SOI3siliconDensity = 2330; |
|||
} |
|||
if(!model->SOI3frontFixedChargeDensityGiven) { |
|||
model->SOI3frontFixedChargeDensity = 0; |
|||
} |
|||
if(!model->SOI3backFixedChargeDensityGiven) { |
|||
model->SOI3backFixedChargeDensity = 0; |
|||
} |
|||
if(!model->SOI3frontSurfaceStateDensityGiven) { |
|||
model->SOI3frontSurfaceStateDensity = 0; |
|||
} |
|||
if(!model->SOI3backSurfaceStateDensityGiven) { |
|||
model->SOI3backSurfaceStateDensity = 0; |
|||
} |
|||
if(!model->SOI3gammaGiven) { |
|||
model->SOI3gamma = 0; |
|||
} |
|||
if(!model->SOI3fNcoefGiven) { |
|||
model->SOI3fNcoef = 0; |
|||
} |
|||
if(!model->SOI3fNexpGiven) { |
|||
model->SOI3fNexp = 1; |
|||
} |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
if(!model->SOI3sigmaGiven) { |
|||
model->SOI3sigma = 0; |
|||
} |
|||
if(!model->SOI3chiFBGiven) { |
|||
model->SOI3chiFB = 0; |
|||
} |
|||
if(!model->SOI3chiPHIGiven) { |
|||
model->SOI3chiPHI = 0; |
|||
} |
|||
if(!model->SOI3deltaWGiven) { |
|||
model->SOI3deltaW = 0; |
|||
} |
|||
if(!model->SOI3deltaLGiven) { |
|||
model->SOI3deltaL = 0; |
|||
} |
|||
if(!model->SOI3vsatGiven) { |
|||
model->SOI3vsat = 0; /* special case - must check for it */ |
|||
} |
|||
if(!model->SOI3kGiven) { |
|||
model->SOI3k = 1.5; /* defaults to old SPICE value */ |
|||
} |
|||
if(!model->SOI3lxGiven) { |
|||
model->SOI3lx = 0; |
|||
} |
|||
if(!model->SOI3vpGiven) { |
|||
model->SOI3vp = 0; |
|||
} |
|||
if(!model->SOI3gammaBGiven) { |
|||
model->SOI3gammaB = 0; |
|||
} |
|||
/* now check to determine which CLM model to use */ |
|||
if((model->SOI3lx != 0) && (model->SOI3lambda != 0)) { |
|||
(*(SPfrontEnd->IFerror))(ERR_WARNING, |
|||
"%s: Non-zero values for BOTH LAMBDA and LX. \nDefaulting to simple LAMBDA model", |
|||
&model->SOI3modName); |
|||
model->SOI3useLAMBDA = TRUE; |
|||
} |
|||
|
|||
/* if only lx given and vp!=0, use froody model, else basic */ |
|||
if ((model->SOI3lxGiven) && (model->SOI3lx != 0) && |
|||
(!model->SOI3lambdaGiven) && (model->SOI3vp != 0)) { |
|||
model->SOI3useLAMBDA = FALSE; |
|||
} else { |
|||
model->SOI3useLAMBDA = TRUE; |
|||
} |
|||
if(!model->SOI3etaGiven) { |
|||
model->SOI3eta = 1.0; /* normal field for imp. ion. */ |
|||
} |
|||
if(!model->SOI3alpha0Given) { |
|||
model->SOI3alpha0=0; |
|||
} |
|||
if(!model->SOI3beta0Given) { |
|||
model->SOI3beta0=1.92e6; |
|||
} |
|||
if(!model->SOI3lmGiven) { |
|||
model->SOI3lm = 0; |
|||
} |
|||
if(!model->SOI3lm1Given) { |
|||
model->SOI3lm1 = 0; |
|||
} |
|||
if(!model->SOI3lm2Given) { |
|||
model->SOI3lm2 = 0; |
|||
} |
|||
if((!model->SOI3etadGiven) || (model->SOI3etad == 0 )) { |
|||
model->SOI3etad = 1.0; |
|||
} |
|||
if((!model->SOI3etad1Given) || (model->SOI3etad1 == 0 )) { |
|||
model->SOI3etad1 = 1.0; |
|||
} |
|||
if(!model->SOI3chibetaGiven) { |
|||
model->SOI3chibeta = 0.0; |
|||
} |
|||
if(!model->SOI3dvtGiven) { |
|||
model->SOI3dvt = 1; |
|||
} |
|||
if(!model->SOI3nLevGiven) { |
|||
model->SOI3nLev = 0; |
|||
} |
|||
if(!model->SOI3betaBJTGiven) { |
|||
model->SOI3betaBJT = 0.0; |
|||
} |
|||
if(!model->SOI3tauFBJTGiven) { |
|||
model->SOI3tauFBJT = 0.0; |
|||
} |
|||
if(!model->SOI3tauRBJTGiven) { |
|||
model->SOI3tauRBJT = 0.0; |
|||
} |
|||
if(!model->SOI3betaEXPGiven) { |
|||
model->SOI3betaEXP = 2.0; |
|||
} |
|||
if(!model->SOI3tauEXPGiven) { |
|||
model->SOI3tauEXP = 0.0; |
|||
} |
|||
if(!model->SOI3rswGiven) { |
|||
model->SOI3rsw = 0.0; |
|||
} |
|||
if(!model->SOI3rdwGiven) { |
|||
model->SOI3rdw = 0.0; |
|||
} |
|||
if(!model->SOI3minimumFeatureSizeGiven) { |
|||
model->SOI3minimumFeatureSize = 0.0; |
|||
} |
|||
if(!model->SOI3vtexGiven) { |
|||
model->SOI3vtex = 0.0; |
|||
} |
|||
if(!model->SOI3vdexGiven) { |
|||
model->SOI3vdex = 0.0; |
|||
} |
|||
if(!model->SOI3delta0Given) { |
|||
model->SOI3delta0 = 0.0; |
|||
} |
|||
if(!model->SOI3satChargeShareFactorGiven) { |
|||
model->SOI3satChargeShareFactor = 0.5; |
|||
} |
|||
if(!model->SOI3nplusDopingGiven) { |
|||
model->SOI3nplusDoping = 1e20; |
|||
} |
|||
if(!model->SOI3rtaGiven) { |
|||
model->SOI3rta = 0; |
|||
} |
|||
if(!model->SOI3ctaGiven) { |
|||
model->SOI3cta = 0; |
|||
} |
|||
|
|||
|
|||
/****** Part 2 - set any instance parameters that are not present ******/ |
|||
/****** in the netlist to default values. ******/ |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->SOI3instances; here != NULL ; |
|||
here=here->SOI3nextInstance) { |
|||
|
|||
CKTnode *tmpNode; |
|||
IFuid tmpName; |
|||
|
|||
|
|||
|
|||
if(!here->SOI3icVBSGiven) { |
|||
here->SOI3icVBS = 0; |
|||
} |
|||
if(!here->SOI3icVDSGiven) { |
|||
here->SOI3icVDS = 0; |
|||
} |
|||
if(!here->SOI3icVGFSGiven) { |
|||
here->SOI3icVGFS = 0; |
|||
} |
|||
if(!here->SOI3icVGBSGiven) { |
|||
here->SOI3icVGBS = 0; |
|||
} |
|||
if(!here->SOI3drainSquaresGiven || here->SOI3drainSquares==0) { |
|||
here->SOI3drainSquares=1; |
|||
} |
|||
if(!here->SOI3sourceSquaresGiven || here->SOI3sourceSquares==0) { |
|||
here->SOI3sourceSquares=1; |
|||
} |
|||
|
|||
/****** Part 3 - Initialise transconductances. ******/ |
|||
|
|||
/* initialise gM's */ |
|||
here->SOI3iMdb= 0.0; |
|||
here->SOI3iMsb= 0.0; |
|||
here->SOI3gMmbs = 0.0; |
|||
here->SOI3gMmf = 0.0; |
|||
here->SOI3gMmb = 0.0; |
|||
here->SOI3gMd = 0.0; |
|||
here->SOI3gMdeltaT = 0.0; |
|||
/* allocate a chunk of the state vector */ |
|||
here->SOI3states = *states; |
|||
*states += SOI3numStates; |
|||
/* if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ |
|||
*states += 10 * (ckt->CKTsenInfo->SENparms); |
|||
} |
|||
*/ |
|||
|
|||
/****** Part 4 - check resistance values for internal nodes, ******/ |
|||
/****** to see which internal nodes need to be created. ******/ |
|||
|
|||
/* Start with internal source and drain nodes */ |
|||
|
|||
if((model->SOI3drainResistance != 0 |
|||
|| (model->SOI3sheetResistance != 0 && |
|||
here->SOI3drainSquares != 0) |
|||
|| model->SOI3rdw != 0) |
|||
&& here->SOI3dNodePrime == 0) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"drain"); |
|||
if(error) |
|||
{ |
|||
return(error); |
|||
} |
|||
here->SOI3dNodePrime = 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->SOI3dNodePrime = here->SOI3dNode; |
|||
} |
|||
|
|||
if((model->SOI3sourceResistance != 0 || |
|||
(model->SOI3sheetResistance != 0 && |
|||
here->SOI3sourceSquares != 0) || |
|||
model->SOI3rsw != 0) && |
|||
here->SOI3sNodePrime==0) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"source"); |
|||
if(error) |
|||
{ |
|||
return(error); |
|||
} |
|||
here->SOI3sNodePrime = 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->SOI3sNodePrime = here->SOI3sNode; |
|||
} |
|||
|
|||
/* Now for thermal node */ |
|||
|
|||
/* JimB - If minimum feature size has non-zero value, then this */ |
|||
/* will be used to calculate thermal area of SiO2 - this gives */ |
|||
/* more accurate values of RT for short-channel devices. Assume*/ |
|||
/* 4*fmin added to L, and 2*fmin added to W (fmin in microns). */ |
|||
thermal_area = (here->SOI3w + 2*1e-6*model->SOI3minimumFeatureSize) |
|||
* (here->SOI3l + 4*1e-6*model->SOI3minimumFeatureSize); |
|||
|
|||
/* Now calculate RT and CT. */ |
|||
|
|||
/* If RT is given on instance line, use it, otherwise calculate from */ |
|||
/* above variables. */ |
|||
if (!here->SOI3rtGiven) |
|||
{ |
|||
if (model->SOI3rtaGiven) |
|||
{ |
|||
here->SOI3rt = model->SOI3rta/thermal_area; |
|||
} |
|||
else |
|||
{ |
|||
if (model->SOI3oxideThermalConductivity != 0) |
|||
{ |
|||
here->SOI3rt = model->SOI3backOxideThickness / |
|||
(model->SOI3oxideThermalConductivity * thermal_area); |
|||
} |
|||
else |
|||
/* If conductivity set to zero in netlist, switch off self-heating. */ |
|||
{ |
|||
here->SOI3rt = 0; |
|||
} |
|||
} |
|||
} |
|||
if (!here->SOI3rt1Given) |
|||
{ |
|||
here->SOI3rt1=0; |
|||
} |
|||
if (!here->SOI3rt2Given) |
|||
{ |
|||
here->SOI3rt2=0; |
|||
} |
|||
if (!here->SOI3rt3Given) |
|||
{ |
|||
here->SOI3rt3=0; |
|||
} |
|||
if (!here->SOI3rt4Given) |
|||
{ |
|||
here->SOI3rt4=0; |
|||
} |
|||
|
|||
/* Now same thing for CT, but less complex as CT=0 does not cause problems */ |
|||
if (!here->SOI3ctGiven) |
|||
{ |
|||
if (model->SOI3ctaGiven) |
|||
{ |
|||
here->SOI3ct = model->SOI3cta*thermal_area; |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3ct = model->SOI3siliconDensity * model->SOI3siliconSpecificHeat * |
|||
thermal_area * model->SOI3bodyThickness; |
|||
} |
|||
} |
|||
if (!here->SOI3ct1Given) |
|||
{ |
|||
here->SOI3ct1=0; |
|||
} |
|||
if (!here->SOI3ct2Given) |
|||
{ |
|||
here->SOI3ct2=0; |
|||
} |
|||
if (!here->SOI3ct3Given) |
|||
{ |
|||
here->SOI3ct3=0; |
|||
} |
|||
if (!here->SOI3ct4Given) |
|||
{ |
|||
here->SOI3ct4=0; |
|||
} |
|||
|
|||
/* JimB - 15/9/99 */ |
|||
rtargs[0]=here->SOI3rt; |
|||
rtargs[1]=here->SOI3rt1; |
|||
rtargs[2]=here->SOI3rt2; |
|||
rtargs[3]=here->SOI3rt3; |
|||
rtargs[4]=here->SOI3rt4; |
|||
rtptr = rtargs; /* Set pointer to start address of rtargs array. */ |
|||
node_count=0; |
|||
|
|||
while ( (*rtptr) && (node_count<5) ) |
|||
{ |
|||
node_count++; |
|||
if (node_count<5) |
|||
{ |
|||
rtptr++; /* Increment pointer to next array element. */ |
|||
} |
|||
} |
|||
here->SOI3numThermalNodes=node_count; |
|||
|
|||
/* Thermal node is now external and so is automatically created by CKTcreate in INP2A. |
|||
It is also bound to the created node's number. However, if rt=0 then no thermal so |
|||
make tout be the thermal ground. Can't simply use CKTbindNode 'cos the row and column |
|||
associated with the original node has already been created. Thus problems will occur |
|||
during pivoting. Instead put zero voltage source here. First create branch for it.*/ |
|||
|
|||
if ((here->SOI3rt == 0) && (here->SOI3branch == 0)) |
|||
{ |
|||
error = CKTmkCur(ckt,&tmp,here->SOI3name,"branch"); |
|||
|
|||
if(error) |
|||
{ |
|||
return(error); |
|||
} |
|||
here->SOI3branch = 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 |
|||
{ /* have thermal - now how many time constants ? */ |
|||
if ((here->SOI3numThermalNodes > 1) && |
|||
(here->SOI3tout1Node == 0)) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout1"); |
|||
if (error) return (error); |
|||
here->SOI3tout1Node = 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->SOI3tout1Node = 0; |
|||
} |
|||
if ((here->SOI3numThermalNodes > 2) && |
|||
(here->SOI3tout2Node == 0)) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout2"); |
|||
if (error) return (error); |
|||
here->SOI3tout2Node = 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->SOI3tout2Node = 0; |
|||
} |
|||
if ((here->SOI3numThermalNodes > 3) && |
|||
(here->SOI3tout3Node == 0)) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout3"); |
|||
if (error) return (error); |
|||
here->SOI3tout3Node = 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->SOI3tout3Node = 0; |
|||
} |
|||
if ((here->SOI3numThermalNodes > 4) && |
|||
(here->SOI3tout4Node == 0)) |
|||
{ |
|||
error = CKTmkVolt(ckt,&tmp,here->SOI3name,"tout4"); |
|||
if (error) return (error); |
|||
here->SOI3tout4Node = 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->SOI3tout4Node = 0; |
|||
} |
|||
} |
|||
|
|||
|
|||
/****** Part 5 - allocate memory to matrix elements corresponding to ******/ |
|||
/****** pairs of nodes. ******/ |
|||
|
|||
/* macro to make elements with built in test for out of memory */ |
|||
|
|||
#define TSTALLOC(ptr,first,second) \ |
|||
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\ |
|||
return(E_NOMEM);\ |
|||
} |
|||
|
|||
TSTALLOC(SOI3D_dPtr,SOI3dNode,SOI3dNode) |
|||
TSTALLOC(SOI3GF_gfPtr,SOI3gfNode,SOI3gfNode) |
|||
TSTALLOC(SOI3S_sPtr,SOI3sNode,SOI3sNode) |
|||
TSTALLOC(SOI3GB_gbPtr,SOI3gbNode,SOI3gbNode) |
|||
TSTALLOC(SOI3B_bPtr,SOI3bNode,SOI3bNode) |
|||
TSTALLOC(SOI3DP_dpPtr,SOI3dNodePrime,SOI3dNodePrime) |
|||
TSTALLOC(SOI3SP_spPtr,SOI3sNodePrime,SOI3sNodePrime) |
|||
TSTALLOC(SOI3D_dpPtr,SOI3dNode,SOI3dNodePrime) |
|||
TSTALLOC(SOI3GF_bPtr,SOI3gfNode,SOI3bNode) |
|||
TSTALLOC(SOI3GF_dpPtr,SOI3gfNode,SOI3dNodePrime) |
|||
TSTALLOC(SOI3GF_spPtr,SOI3gfNode,SOI3sNodePrime) |
|||
TSTALLOC(SOI3GB_bPtr,SOI3gbNode,SOI3bNode) |
|||
TSTALLOC(SOI3GB_dpPtr,SOI3gbNode,SOI3dNodePrime) |
|||
TSTALLOC(SOI3GB_spPtr,SOI3gbNode,SOI3sNodePrime) |
|||
TSTALLOC(SOI3S_spPtr,SOI3sNode,SOI3sNodePrime) |
|||
TSTALLOC(SOI3B_dpPtr,SOI3bNode,SOI3dNodePrime) |
|||
TSTALLOC(SOI3B_spPtr,SOI3bNode,SOI3sNodePrime) |
|||
TSTALLOC(SOI3DP_spPtr,SOI3dNodePrime,SOI3sNodePrime) |
|||
TSTALLOC(SOI3DP_dPtr,SOI3dNodePrime,SOI3dNode) |
|||
TSTALLOC(SOI3B_gfPtr,SOI3bNode,SOI3gfNode) |
|||
TSTALLOC(SOI3DP_gfPtr,SOI3dNodePrime,SOI3gfNode) |
|||
TSTALLOC(SOI3SP_gfPtr,SOI3sNodePrime,SOI3gfNode) |
|||
TSTALLOC(SOI3B_gbPtr,SOI3bNode,SOI3gbNode) |
|||
TSTALLOC(SOI3DP_gbPtr,SOI3dNodePrime,SOI3gbNode) |
|||
TSTALLOC(SOI3SP_gbPtr,SOI3sNodePrime,SOI3gbNode) |
|||
TSTALLOC(SOI3SP_sPtr,SOI3sNodePrime,SOI3sNode) |
|||
TSTALLOC(SOI3DP_bPtr,SOI3dNodePrime,SOI3bNode) |
|||
TSTALLOC(SOI3SP_bPtr,SOI3sNodePrime,SOI3bNode) |
|||
TSTALLOC(SOI3SP_dpPtr,SOI3sNodePrime,SOI3dNodePrime) |
|||
|
|||
if (here->SOI3rt == 0) |
|||
{ |
|||
TSTALLOC(SOI3TOUT_ibrPtr,SOI3toutNode,SOI3branch) |
|||
TSTALLOC(SOI3IBR_toutPtr,SOI3branch,SOI3toutNode) |
|||
} |
|||
else |
|||
{ |
|||
TSTALLOC(SOI3TOUT_toutPtr,SOI3toutNode,SOI3toutNode) |
|||
if (here->SOI3numThermalNodes > 1) |
|||
{ |
|||
TSTALLOC(SOI3TOUT_tout1Ptr,SOI3toutNode,SOI3tout1Node) |
|||
TSTALLOC(SOI3TOUT1_toutPtr,SOI3tout1Node,SOI3toutNode) |
|||
TSTALLOC(SOI3TOUT1_tout1Ptr,SOI3tout1Node,SOI3tout1Node) |
|||
} |
|||
if (here->SOI3numThermalNodes > 2) |
|||
{ |
|||
TSTALLOC(SOI3TOUT1_tout2Ptr,SOI3tout1Node,SOI3tout2Node) |
|||
TSTALLOC(SOI3TOUT2_tout1Ptr,SOI3tout2Node,SOI3tout1Node) |
|||
TSTALLOC(SOI3TOUT2_tout2Ptr,SOI3tout2Node,SOI3tout2Node) |
|||
} |
|||
if (here->SOI3numThermalNodes > 3) |
|||
{ |
|||
TSTALLOC(SOI3TOUT2_tout3Ptr,SOI3tout2Node,SOI3tout3Node) |
|||
TSTALLOC(SOI3TOUT3_tout2Ptr,SOI3tout3Node,SOI3tout2Node) |
|||
TSTALLOC(SOI3TOUT3_tout3Ptr,SOI3tout3Node,SOI3tout3Node) |
|||
} |
|||
if (here->SOI3numThermalNodes > 4) |
|||
{ |
|||
TSTALLOC(SOI3TOUT3_tout4Ptr,SOI3tout3Node,SOI3tout4Node) |
|||
TSTALLOC(SOI3TOUT4_tout3Ptr,SOI3tout4Node,SOI3tout3Node) |
|||
TSTALLOC(SOI3TOUT4_tout4Ptr,SOI3tout4Node,SOI3tout4Node) |
|||
} |
|||
|
|||
TSTALLOC(SOI3TOUT_toutPtr,SOI3toutNode,SOI3toutNode) |
|||
TSTALLOC(SOI3TOUT_dpPtr,SOI3toutNode,SOI3dNodePrime) |
|||
TSTALLOC(SOI3TOUT_gfPtr,SOI3toutNode,SOI3gfNode) |
|||
TSTALLOC(SOI3TOUT_gbPtr,SOI3toutNode,SOI3gbNode) |
|||
TSTALLOC(SOI3TOUT_bPtr,SOI3toutNode,SOI3bNode) |
|||
TSTALLOC(SOI3TOUT_spPtr,SOI3toutNode,SOI3sNodePrime) |
|||
|
|||
TSTALLOC(SOI3GF_toutPtr,SOI3gfNode,SOI3toutNode) |
|||
TSTALLOC(SOI3DP_toutPtr,SOI3dNodePrime,SOI3toutNode) |
|||
TSTALLOC(SOI3SP_toutPtr,SOI3sNodePrime,SOI3toutNode) |
|||
|
|||
TSTALLOC(SOI3B_toutPtr,SOI3bNode,SOI3toutNode) |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
|
|||
/* JimB - SIMetrix is based on SPICE3e2. Since */ |
|||
/* unsetup is a SPICE3f5 function, only use it in */ |
|||
/* the standard version */ |
|||
|
|||
int |
|||
SOI3unsetup(inModel,ckt) |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
{ |
|||
SOI3model *model; |
|||
SOI3instance *here; |
|||
|
|||
for (model = (SOI3model *)inModel; model != NULL; |
|||
model = model->SOI3nextModel) |
|||
{ |
|||
for (here = model->SOI3instances; here != NULL; |
|||
here=here->SOI3nextInstance) |
|||
{ |
|||
if (here->SOI3dNodePrime |
|||
&& here->SOI3dNodePrime != here->SOI3dNode) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3dNodePrime); |
|||
here->SOI3dNodePrime= 0; |
|||
} |
|||
if (here->SOI3sNodePrime |
|||
&& here->SOI3sNodePrime != here->SOI3sNode) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3sNodePrime); |
|||
here->SOI3sNodePrime= 0; |
|||
} |
|||
if (here->SOI3branch) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3branch); |
|||
here->SOI3branch=0; |
|||
} |
|||
if (here->SOI3tout1Node) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3tout1Node); |
|||
here->SOI3tout1Node = 0; |
|||
} |
|||
if (here->SOI3tout2Node) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3tout2Node); |
|||
here->SOI3tout2Node = 0; |
|||
} |
|||
if (here->SOI3tout3Node) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3tout3Node); |
|||
here->SOI3tout3Node = 0; |
|||
} |
|||
if (here->SOI3tout4Node) |
|||
{ |
|||
CKTdltNNum(ckt, here->SOI3tout4Node); |
|||
here->SOI3tout4Node = 0; |
|||
} |
|||
} |
|||
} |
|||
return OK; |
|||
} |
|||
@ -0,0 +1,597 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3temp(inModel,ckt) |
|||
GENmodel *inModel; |
|||
CKTcircuit *ckt; |
|||
{ |
|||
SOI3model *model = (SOI3model *)inModel; |
|||
SOI3instance *here; |
|||
|
|||
/* All variables ending in 1 denote that they pertain to the model |
|||
and so use model->SOI3tnom for temperature - the others use |
|||
here->SOI3temp. REFTEMP is temp at which hard-coded quantities |
|||
are given. */ |
|||
|
|||
double egfet,egfet1; /* Band Gap */ |
|||
double fact1,fact2; /* temperature/REFTEMP */ |
|||
double kt,kt1; /* kT @ various temps */ |
|||
double arg1; /* ??? */ |
|||
double ratio,ratio4; /* (temp/tnom) and (temp/tnom)^(3/2) */ |
|||
double phio; /* temp adjusted phi PHI0*/ |
|||
double pbo; |
|||
double gmanew,gmaold; |
|||
double capfact; |
|||
double pbfact1,pbfact; /* ??? */ |
|||
double vt,vtnom; |
|||
double wkfngfs; /* work function difference phi(gate,Si) */ |
|||
double wkfngf; /* work fn of front gate */ |
|||
double wkfngbs; /* work fn diff of back gate = 0 usu. */ |
|||
double fermig; /* fermi level of gate */ |
|||
double fermis; /* fermi level of Si */ |
|||
double xd_max; /* Minimum Si film thickness for this model to be valid */ |
|||
double eta_s; |
|||
|
|||
/* JimB - new variables for improved threshold voltage conversion model. */ |
|||
|
|||
double Edelta0; |
|||
double psi_delta0; |
|||
|
|||
/* loop through all the transistor models */ |
|||
for( ; model != NULL; model = model->SOI3nextModel) |
|||
{ |
|||
|
|||
/* perform model defaulting */ |
|||
if(!model->SOI3tnomGiven) |
|||
{ |
|||
model->SOI3tnom = ckt->CKTnomTemp; |
|||
} |
|||
|
|||
fact1 = model->SOI3tnom/REFTEMP; |
|||
vtnom = model->SOI3tnom*CONSTKoverQ; |
|||
kt1 = CONSTboltz * model->SOI3tnom; |
|||
egfet1 = 1.16-(7.02e-4*model->SOI3tnom*model->SOI3tnom)/ |
|||
(model->SOI3tnom+1108); |
|||
arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
|||
/* this is -Egnom + Egref. - sign due to it being in bracket with log(fact1) |
|||
'cos we wanted log(1/fact1). */ |
|||
pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); |
|||
/* 2 comes from fact phi=2*phi_F |
|||
^ */ |
|||
|
|||
/* now model parameter preprocessing */ |
|||
|
|||
if(!model->SOI3frontOxideThicknessGiven || |
|||
model->SOI3frontOxideThickness == 0 || |
|||
!model->SOI3backOxideThicknessGiven || |
|||
model->SOI3backOxideThickness == 0 || |
|||
!model->SOI3bodyThicknessGiven || |
|||
model->SOI3bodyThickness == 0) |
|||
{ |
|||
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
|||
"%s: SOI3 device film thickness must be supplied", |
|||
&model->SOI3modName); |
|||
return(E_BADPARM); |
|||
} |
|||
else /* Oxide and film thicknesses are supplied. */ |
|||
{ |
|||
model->SOI3frontOxideCapFactor = 3.9 * 8.854214871e-12/ |
|||
model->SOI3frontOxideThickness; |
|||
model->SOI3backOxideCapFactor = 3.9 * 8.854214871e-12/ |
|||
model->SOI3backOxideThickness; |
|||
model->SOI3bodyCapFactor = 11.7 * 8.854214871e-12/ |
|||
model->SOI3bodyThickness; |
|||
model->SOI3C_ssf = CHARGE*model->SOI3frontSurfaceStateDensity*1e4; |
|||
model->SOI3C_ssb = CHARGE*model->SOI3backSurfaceStateDensity*1e4; |
|||
eta_s = 1 + model->SOI3C_ssf/model->SOI3frontOxideCapFactor; |
|||
|
|||
if(!model->SOI3transconductanceGiven) |
|||
{ |
|||
if(!model->SOI3surfaceMobilityGiven) |
|||
{ |
|||
model->SOI3surfaceMobility=600; |
|||
} |
|||
model->SOI3transconductance = model->SOI3surfaceMobility * |
|||
model->SOI3frontOxideCapFactor * 1e-4 /*(m**2/cm**2) |
|||
for mobility */; |
|||
} |
|||
|
|||
if(model->SOI3substrateDopingGiven) |
|||
{ /* work everything out */ |
|||
if(model->SOI3substrateDoping*1e6 /*(cm**3/m**3)*/ >1.45e16) |
|||
{ |
|||
if(!model->SOI3phiGiven) |
|||
{ |
|||
model->SOI3phi = 2*vtnom* |
|||
log(model->SOI3substrateDoping* |
|||
1e6/*(cm**3/m**3)*//1.45e16); |
|||
model->SOI3phi = MAX(0.1,model->SOI3phi); |
|||
} |
|||
/* Now that we have ascertained both the doping * |
|||
* and the body film thickness, check to see * |
|||
* if we have a thick film device. If not, complain ! */ |
|||
xd_max=2*sqrt((2* 11.7 * 8.854214871e-12 * model->SOI3phi)/ |
|||
(CHARGE*1e6 /*(cm**3/m**3)*/ * model->SOI3substrateDoping)); |
|||
|
|||
if(model->SOI3bodyThickness < xd_max) |
|||
{ |
|||
(*(SPfrontEnd->IFerror))(ERR_WARNING, |
|||
"%s: Body Film thickness may be too small \nfor this model to be valid", |
|||
&model->SOI3modName); |
|||
/* return(E_PAUSE); don't want to stop, |
|||
just issue a warning */ |
|||
} |
|||
/* End of thick film check - msll 21/2/94 |
|||
Changed to only give warning - msll 31/10/95 */ |
|||
if(!model->SOI3vfbFGiven) |
|||
{ |
|||
if(!model->SOI3frontFixedChargeDensityGiven) |
|||
model->SOI3frontFixedChargeDensity = 0; |
|||
fermis = model->SOI3type * 0.5 * model->SOI3phi; |
|||
wkfngf = 3.2; |
|||
if(!model->SOI3gateTypeGiven) model->SOI3gateType=1; |
|||
if(model->SOI3gateType != 0) |
|||
{ |
|||
fermig = model->SOI3type *model->SOI3gateType*0.5*egfet1; |
|||
wkfngf = 3.25 + 0.5 * egfet1 - fermig; |
|||
} |
|||
wkfngfs = wkfngf - (3.25 + 0.5 * egfet1 +fermis); |
|||
|
|||
/* Fixed oxide charge is normally +ve for both |
|||
n and p-channel, so need -ve voltage to neutralise it */ |
|||
model->SOI3vfbF = wkfngfs - |
|||
model->SOI3frontFixedChargeDensity * |
|||
1e4 /*(cm**2/m**2)*/ * |
|||
CHARGE/model->SOI3frontOxideCapFactor; |
|||
} |
|||
if(!model->SOI3vfbBGiven) |
|||
{ |
|||
wkfngbs = (1-model->SOI3type)*0.5*model->SOI3phi; |
|||
/* assume p-sub */ |
|||
model->SOI3vfbB = wkfngbs - |
|||
model->SOI3backFixedChargeDensity * |
|||
1e4 /*(cm**2/m**2)*/ * |
|||
CHARGE/model->SOI3backOxideCapFactor; |
|||
} |
|||
|
|||
if(!model->SOI3gammaGiven) |
|||
{ |
|||
model->SOI3gamma = sqrt(2 * 11.70 * 8.854214871e-12 * |
|||
CHARGE * model->SOI3substrateDoping * |
|||
1e6 /*(cm**3/m**3)*/)/model->SOI3frontOxideCapFactor; |
|||
} |
|||
|
|||
if(!model->SOI3gammaBGiven) |
|||
{ |
|||
model->SOI3gammaB = sqrt(2 * 11.70 * 8.854214871e-12 * |
|||
CHARGE * model->SOI3substrateDoping * |
|||
1e6 /*(cm**3/m**3)*/)/model->SOI3backOxideCapFactor; |
|||
} |
|||
if(model->SOI3vt0Given) |
|||
{ /* NSUB given AND VT0 given - change vfbF */ |
|||
model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * |
|||
(eta_s*model->SOI3phi + |
|||
model->SOI3gamma*sqrt(model->SOI3phi)); |
|||
} |
|||
else |
|||
{ |
|||
if(model->SOI3vtexGiven) |
|||
{ /* JimB - Improved threshold voltage conversion model. */ |
|||
if (model->SOI3delta0 < 0) |
|||
{ |
|||
model->SOI3delta0 = 0; |
|||
} |
|||
if (model->SOI3vdex < 0) |
|||
{ |
|||
/* Use convention that Vd at which Vtex was extracted */ |
|||
/* is always +ve. */ |
|||
model->SOI3vdex = -model->SOI3vdex; |
|||
} |
|||
/* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ |
|||
Edelta0 = exp(MIN(MAX_EXP_ARG, |
|||
(model->SOI3delta0*model->SOI3phi)/(2*vtnom)) |
|||
); |
|||
/* Modified surface potential term (2+delta)*phiF + vdex/2 */ |
|||
/* (SOI3phi = 2phiF) */ |
|||
psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + |
|||
model->SOI3vdex/2; |
|||
model->SOI3vfbF = model->SOI3vtex - model->SOI3type * |
|||
(eta_s*psi_delta0 + model->SOI3gamma* |
|||
sqrt(psi_delta0 + vtnom*Edelta0) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
else /* Substrate doping less than intrinsic silicon, so set to zero. */ |
|||
{ |
|||
model->SOI3substrateDoping = 0; |
|||
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
|||
"%s: Nsub < Ni",&model->SOI3modName); |
|||
return(E_BADPARM); |
|||
} |
|||
} |
|||
else /* NSUB not given, have to assume that VT0, PHI and GAMMA are given */ |
|||
{ |
|||
xd_max=(2* 11.7 * 8.854214871e-12*sqrt(model->SOI3phi))/ |
|||
(model->SOI3gamma*model->SOI3frontOxideCapFactor); |
|||
if(model->SOI3bodyThickness < xd_max) |
|||
{ |
|||
(*(SPfrontEnd->IFerror))(ERR_WARNING, |
|||
"%s :Body Film thickness may be too small \nfor this model to be valid", |
|||
&model->SOI3modName); |
|||
/* return(E_PAUSE); */ |
|||
} |
|||
/* End of thick film check - msll 21/2/94 |
|||
Changed to only give warning - msll 31/10/95 */ |
|||
|
|||
/* If vtext given in netlist, but no vt0. */ |
|||
if( (model->SOI3vtexGiven) && (!model->SOI3vt0Given) ) |
|||
{ /* JimB - Improved threshold voltage conversion model. */ |
|||
if (model->SOI3delta0 < 0) |
|||
{ |
|||
model->SOI3delta0 = 0; |
|||
} |
|||
if (model->SOI3vdex < 0) |
|||
{ |
|||
/* Use convention that Vd at which Vtex was extracted */ |
|||
/* is always +ve. */ |
|||
model->SOI3vdex = -model->SOI3vdex; |
|||
} |
|||
/* Exponential term delta*phiF/phit (SOI3phi = 2phiF) */ |
|||
Edelta0 = exp(MIN(MAX_EXP_ARG, |
|||
(model->SOI3delta0*model->SOI3phi)/(2*vtnom)) |
|||
); |
|||
/* Modified surface potential term (2+delta)*phiF + vdex/2 */ |
|||
/* (SOI3phi = 2phiF) */ |
|||
psi_delta0 = ((2+model->SOI3delta0)*model->SOI3phi/2) + |
|||
model->SOI3vdex/2; |
|||
model->SOI3vfbF = model->SOI3vtex - model->SOI3type * |
|||
(eta_s*psi_delta0 + model->SOI3gamma* |
|||
sqrt(psi_delta0 + vtnom*Edelta0) |
|||
); |
|||
} |
|||
else /* If no vtex, then use vt0, either netlist or default value. */ |
|||
{ /* Use standard threshold voltage model. */ |
|||
model->SOI3vfbF = model->SOI3vt0 - model->SOI3type * |
|||
(eta_s*model->SOI3phi + model->SOI3gamma*sqrt(model->SOI3phi)); |
|||
} |
|||
if (!model->SOI3vfbBGiven) |
|||
{ |
|||
model->SOI3vfbB = 0; /* NSUB not given, vfbB not given */ |
|||
} |
|||
} |
|||
} |
|||
if((model->SOI3vsatGiven)&&(model->SOI3vsat != 0)) |
|||
{ |
|||
model->SOI3TVF0 = 0.8*exp(model->SOI3tnom/600); |
|||
} |
|||
else |
|||
{ |
|||
model->SOI3TVF0 = 0; |
|||
} |
|||
|
|||
|
|||
/* loop through all instances of the model */ |
|||
for(here = model->SOI3instances; here!= NULL; |
|||
here = here->SOI3nextInstance) |
|||
{ |
|||
|
|||
double czbd; /* zero voltage bulk-drain capacitance */ |
|||
double czbs; /* zero voltage bulk-source capacitance */ |
|||
double cj0; /* default value of zero voltage bulk-source/drain capacitance*/ |
|||
double Nratio; /* ratio of Nsub*Nplus/Nsub+Nplus */ |
|||
double arg; /* 1 - fc */ |
|||
double sarg; /* (1-fc) ^^ (-mj) */ |
|||
|
|||
/* perform the parameter defaulting */ |
|||
if(!here->SOI3tempGiven) |
|||
{ |
|||
here->SOI3temp = ckt->CKTtemp; |
|||
} |
|||
vt = here->SOI3temp * CONSTKoverQ; |
|||
ratio = here->SOI3temp/model->SOI3tnom; |
|||
fact2 = here->SOI3temp/REFTEMP; |
|||
kt = here->SOI3temp * CONSTboltz; |
|||
egfet = 1.16-(7.02e-4*here->SOI3temp*here->SOI3temp)/ |
|||
(here->SOI3temp+1108); |
|||
if (!model->SOI3chidGiven) |
|||
{ |
|||
model->SOI3chid = CHARGE*egfet/CONSTboltz; |
|||
} |
|||
if (!model->SOI3chid1Given) |
|||
{ |
|||
model->SOI3chid1 = CHARGE*egfet/CONSTboltz; |
|||
} |
|||
arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
|||
pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); |
|||
|
|||
if(!here->SOI3lGiven) |
|||
{ |
|||
here->SOI3l = ckt->CKTdefaultMosL; |
|||
} |
|||
if(!here->SOI3wGiven) |
|||
{ |
|||
here->SOI3w = ckt->CKTdefaultMosW; |
|||
} |
|||
|
|||
if(here->SOI3l - 2 * model->SOI3latDiff <=0) |
|||
{ |
|||
(*(SPfrontEnd->IFerror))(ERR_WARNING, |
|||
"%s: Effective channel length less than zero \nIncreasing \ |
|||
this instance length by 2*LD to remove effect of LD", |
|||
&(here->SOI3name)); |
|||
here->SOI3l += 2*model->SOI3latDiff; |
|||
} |
|||
ratio4 = exp(model->SOI3k*log(ratio)); /* ratio4 = (temp/tnom)^k */ |
|||
/* i.e. mobilitites prop to */ |
|||
/* T^-(k) where k=1.5 for old SPICE */ |
|||
here->SOI3tTransconductance = model->SOI3transconductance / ratio4; |
|||
here->SOI3tSurfMob = model->SOI3surfaceMobility/ratio4; |
|||
phio= (model->SOI3phi-pbfact1)/fact1; /* this is PHI @ REFTEMP */ |
|||
here->SOI3tPhi = fact2 * phio + pbfact; |
|||
here->SOI3tVfbF = model->SOI3vfbF + |
|||
(model->SOI3type * model->SOI3gateType * 0.5*(egfet1-egfet)) + |
|||
(model->SOI3type * 0.5 * (model->SOI3phi - here->SOI3tPhi)); |
|||
here->SOI3tVfbB = model->SOI3vfbB + |
|||
(1-model->SOI3type)*0.5*(here->SOI3tPhi-model->SOI3phi); |
|||
|
|||
here->SOI3tVto = here->SOI3tVfbF + model->SOI3type * |
|||
(model->SOI3gamma * sqrt(here->SOI3tPhi) + eta_s*here->SOI3tPhi); |
|||
|
|||
here->SOI3tSatCur = model->SOI3jctSatCur* |
|||
exp(-egfet/vt+egfet1/vtnom); |
|||
here->SOI3tSatCur1 = model->SOI3jctSatCur1* |
|||
exp(-egfet/vt+egfet1/vtnom); |
|||
here->SOI3tSatCurDens = model->SOI3jctSatCurDensity * |
|||
exp(-egfet/vt+egfet1/vtnom); |
|||
here->SOI3tSatCurDens1 = model->SOI3jctSatCurDensity1 * |
|||
exp(-egfet/vt+egfet1/vtnom); |
|||
|
|||
pbo = (model->SOI3bulkJctPotential - pbfact1)/fact1; |
|||
gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; |
|||
capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); |
|||
here->SOI3tCbd = model->SOI3capBD * capfact; |
|||
here->SOI3tCbs = model->SOI3capBS * capfact; |
|||
here->SOI3tCjsw = model->SOI3sideWallCapFactor * capfact; |
|||
here->SOI3tBulkPot = fact2 * pbo+pbfact; |
|||
gmanew = (here->SOI3tBulkPot-pbo)/pbo; |
|||
capfact = (1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(here->SOI3temp-REFTEMP)-gmanew)); |
|||
here->SOI3tCbd *= capfact; |
|||
here->SOI3tCbs *= capfact; |
|||
here->SOI3tCjsw *= capfact; |
|||
here->SOI3tDepCap = model->SOI3fwdCapDepCoeff * here->SOI3tBulkPot; |
|||
|
|||
if (here->SOI3tSatCurDens == 0) |
|||
{ |
|||
if (here->SOI3tSatCur == 0) |
|||
{ |
|||
here->SOI3sourceVcrit = here->SOI3drainVcrit = |
|||
vt*log(vt/(CONSTroot2*1.0e-15)); |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3sourceVcrit = here->SOI3drainVcrit = |
|||
vt*log(vt/(CONSTroot2*here->SOI3tSatCur)); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3drainVcrit = |
|||
vt * log( vt / (CONSTroot2 * |
|||
here->SOI3tSatCurDens * (here->SOI3w))); |
|||
here->SOI3sourceVcrit = |
|||
vt * log( vt / (CONSTroot2 * |
|||
here->SOI3tSatCurDens * (here->SOI3w))); |
|||
} |
|||
|
|||
if(model->SOI3capBDGiven) |
|||
{ |
|||
czbd = here->SOI3tCbd; |
|||
} |
|||
else |
|||
{ |
|||
if(model->SOI3sideWallCapFactorGiven) |
|||
{ |
|||
czbd = here->SOI3tCjsw * (here->SOI3w*model->SOI3bodyThickness); |
|||
} |
|||
/* JimB - 2/1/99. Calculate default value for Cj0 */ |
|||
/* using PN junction theory. */ |
|||
else |
|||
{ |
|||
Nratio = (1e6*model->SOI3nplusDoping * model->SOI3substrateDoping)/ |
|||
(model->SOI3nplusDoping + model->SOI3substrateDoping); |
|||
cj0 = sqrt((Nratio * 11.7 * 8.854214871e-12 * CHARGE)/ |
|||
(2 * here->SOI3tBulkPot)); |
|||
|
|||
/* JimB - temperature dependence code */ |
|||
gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; |
|||
capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); |
|||
cj0 *= capfact; |
|||
gmanew = (here->SOI3tBulkPot-pbo)/pbo; |
|||
capfact = (1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(here->SOI3temp-REFTEMP)-gmanew)); |
|||
cj0 *= capfact; |
|||
|
|||
czbd = cj0 * (here->SOI3w*model->SOI3bodyThickness); |
|||
} |
|||
} |
|||
|
|||
arg = 1-model->SOI3fwdCapDepCoeff; |
|||
sarg = exp( (-model->SOI3bulkJctSideGradingCoeff) * log(arg) ); |
|||
here->SOI3Cbd = czbd; |
|||
here->SOI3f2d = czbd*(1-model->SOI3fwdCapDepCoeff* |
|||
(1+model->SOI3bulkJctSideGradingCoeff))* |
|||
sarg/arg; |
|||
here->SOI3f3d = czbd * model->SOI3bulkJctSideGradingCoeff * sarg/arg / |
|||
here->SOI3tBulkPot; |
|||
here->SOI3f4d = czbd*here->SOI3tBulkPot*(1-arg*sarg)/ |
|||
(1-model->SOI3bulkJctSideGradingCoeff) |
|||
-here->SOI3f3d/2* |
|||
(here->SOI3tDepCap*here->SOI3tDepCap) |
|||
-here->SOI3tDepCap * here->SOI3f2d; |
|||
|
|||
if(model->SOI3capBSGiven) |
|||
{ |
|||
czbs=here->SOI3tCbs; |
|||
} |
|||
else |
|||
{ |
|||
if(model->SOI3sideWallCapFactorGiven) |
|||
{ |
|||
czbs=here->SOI3tCjsw * (here->SOI3w*model->SOI3bodyThickness); |
|||
} |
|||
/* JimB - 2/1/99. Calculate default value for Cj0 */ |
|||
/* using PN junction theory. */ |
|||
else |
|||
{ |
|||
Nratio = (1e6*model->SOI3nplusDoping * model->SOI3substrateDoping)/ |
|||
(model->SOI3nplusDoping + model->SOI3substrateDoping); |
|||
cj0 = sqrt((Nratio * 11.7 * 8.854214871e-12 * CHARGE)/ |
|||
(2 * here->SOI3tBulkPot)); |
|||
|
|||
/* JimB - temperature dependence code */ |
|||
gmaold = (model->SOI3bulkJctPotential-pbo)/pbo; |
|||
capfact = 1/(1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(model->SOI3tnom-REFTEMP)-gmaold)); |
|||
cj0 *= capfact; |
|||
gmanew = (here->SOI3tBulkPot-pbo)/pbo; |
|||
capfact = (1+model->SOI3bulkJctSideGradingCoeff* |
|||
(4e-4*(here->SOI3temp-REFTEMP)-gmanew)); |
|||
cj0 *= capfact; |
|||
|
|||
czbs = cj0 * (here->SOI3w*model->SOI3bodyThickness); |
|||
} |
|||
} |
|||
arg = 1-model->SOI3fwdCapDepCoeff; |
|||
sarg = exp( (-model->SOI3bulkJctSideGradingCoeff) * log(arg) ); |
|||
here->SOI3Cbs = czbs; |
|||
here->SOI3f2s = czbs*(1-model->SOI3fwdCapDepCoeff* |
|||
(1+model->SOI3bulkJctSideGradingCoeff))* |
|||
sarg/arg; |
|||
here->SOI3f3s = czbs * model->SOI3bulkJctSideGradingCoeff * sarg/arg / |
|||
here->SOI3tBulkPot; |
|||
here->SOI3f4s = czbs*here->SOI3tBulkPot*(1-arg*sarg)/ |
|||
(1-model->SOI3bulkJctSideGradingCoeff) |
|||
-here->SOI3f3s/2* |
|||
(here->SOI3tDepCap*here->SOI3tDepCap) |
|||
-here->SOI3tDepCap * here->SOI3f2s; |
|||
|
|||
if(model->SOI3drainResistanceGiven) |
|||
{ |
|||
if(model->SOI3drainResistance != 0) |
|||
{ |
|||
here->SOI3drainConductance = 1/model->SOI3drainResistance; |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3drainConductance = 0; |
|||
} |
|||
} |
|||
else if (model->SOI3sheetResistanceGiven) |
|||
{ |
|||
if(model->SOI3sheetResistance != 0) |
|||
{ |
|||
here->SOI3drainConductance = |
|||
1/(model->SOI3sheetResistance*here->SOI3drainSquares); |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3drainConductance = 0; |
|||
} |
|||
} |
|||
else if(model->SOI3rdwGiven) |
|||
{ |
|||
if (model->SOI3rdw != 0) |
|||
{ |
|||
/* JimB - 1e6 multiplying factor converts W from m to microns */ |
|||
here->SOI3drainConductance = |
|||
(here->SOI3w/model->SOI3rdw)*1e6; |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3drainConductance = 0; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3drainConductance = 0; |
|||
} |
|||
|
|||
if(model->SOI3sourceResistanceGiven) |
|||
{ |
|||
if(model->SOI3sourceResistance != 0) |
|||
{ |
|||
here->SOI3sourceConductance = 1/model->SOI3sourceResistance; |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3sourceConductance = 0; |
|||
} |
|||
} |
|||
else if (model->SOI3sheetResistanceGiven) |
|||
{ |
|||
if(model->SOI3sheetResistance != 0) |
|||
{ |
|||
here->SOI3sourceConductance = |
|||
1/(model->SOI3sheetResistance*here->SOI3sourceSquares); |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3sourceConductance = 0; |
|||
} |
|||
} |
|||
else if(model->SOI3rswGiven) |
|||
{ |
|||
if (model->SOI3rsw != 0) |
|||
{ |
|||
/* JimB - 1e6 multiplying factor converts W from m to microns */ |
|||
here->SOI3sourceConductance = |
|||
(here->SOI3w/model->SOI3rsw)*1e6; |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3sourceConductance = 0; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
here->SOI3sourceConductance = 0; |
|||
} |
|||
/* extra stuff for newer model - msll Jan96 */ |
|||
} /* finish looping through all instances of the model*/ |
|||
} /* finish looping through all the transistor models */ |
|||
return(OK); |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,47 @@ |
|||
/********** |
|||
STAG version 2.6 |
|||
Copyright 2000 owned by the United Kingdom Secretary of State for Defence |
|||
acting through the Defence Evaluation and Research Agency. |
|||
Developed by : Jim Benson, |
|||
Department of Electronics and Computer Science, |
|||
University of Southampton, |
|||
United Kingdom. |
|||
With help from : Nele D'Halleweyn, Bill Redman-White, and Craig Easson. |
|||
|
|||
Based on STAG version 2.1 |
|||
Developed by : Mike Lee, |
|||
With help from : Bernard Tenbroek, Bill Redman-White, Mike Uren, Chris Edwards |
|||
and John Bunyan. |
|||
Acknowledgements : Rupert Howes and Pete Mole. |
|||
**********/ |
|||
|
|||
/* Modified: 2001 Paolo Nenzi */ |
|||
|
|||
#include "ngspice.h" |
|||
#include <stdio.h> |
|||
#include "cktdefs.h" |
|||
#include "soi3defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
SOI3trunc(inModel,ckt,timeStep) |
|||
GENmodel *inModel; |
|||
register CKTcircuit *ckt; |
|||
double *timeStep; |
|||
{ |
|||
register SOI3model *model = (SOI3model *)inModel; |
|||
register SOI3instance *here; |
|||
|
|||
for( ; model != NULL; model = model->SOI3nextModel) |
|||
{ |
|||
for(here=model->SOI3instances;here!=NULL;here = here->SOI3nextInstance) |
|||
{ |
|||
CKTterr(here->SOI3qgf,ckt,timeStep); |
|||
CKTterr(here->SOI3qd,ckt,timeStep); |
|||
CKTterr(here->SOI3qs,ckt,timeStep); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue