Added stag 26 model (as level 62 and M type)

This commit is contained in:
pnenzi 2001-05-02 20:31:09 +00:00
parent 0dae4607a0
commit 9332fc213f
24 changed files with 8328 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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 */
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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*/

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

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 */
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}