27 changed files with 8536 additions and 8536 deletions
-
346src/spicelib/devices/mos9/mos9.c
-
252src/spicelib/devices/mos9/mos9acld.c
-
886src/spicelib/devices/mos9/mos9ask.c
-
206src/spicelib/devices/mos9/mos9conv.c
-
1116src/spicelib/devices/mos9/mos9defs.h
-
76src/spicelib/devices/mos9/mos9del.c
-
76src/spicelib/devices/mos9/mos9dest.c
-
2770src/spicelib/devices/mos9/mos9dist.c
-
1956src/spicelib/devices/mos9/mos9dset.c
-
58src/spicelib/devices/mos9/mos9ext.h
-
96src/spicelib/devices/mos9/mos9ic.c
-
14src/spicelib/devices/mos9/mos9itf.h
-
2712src/spicelib/devices/mos9/mos9load.c
-
340src/spicelib/devices/mos9/mos9mask.c
-
88src/spicelib/devices/mos9/mos9mdel.c
-
402src/spicelib/devices/mos9/mos9mpar.c
-
436src/spicelib/devices/mos9/mos9noi.c
-
230src/spicelib/devices/mos9/mos9par.c
-
278src/spicelib/devices/mos9/mos9pzld.c
-
1562src/spicelib/devices/mos9/mos9sacl.c
-
586src/spicelib/devices/mos9/mos9set.c
-
1248src/spicelib/devices/mos9/mos9sld.c
-
128src/spicelib/devices/mos9/mos9sprt.c
-
106src/spicelib/devices/mos9/mos9sset.c
-
362src/spicelib/devices/mos9/mos9supd.c
-
682src/spicelib/devices/mos9/mos9temp.c
-
60src/spicelib/devices/mos9/mos9trun.c
@ -1,174 +1,174 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
Author: 1987 Thomas L. Quarles |
Author: 1987 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
|
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "devdefs.h" |
|
||||
#include "ifsim.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
IFparm MOS9pTable[] = { /* parameters */ |
|
||||
|
|
||||
IOPU("m", MOS9_M, IF_REAL , "Multiplier"), |
|
||||
IOPU("l", MOS9_L, IF_REAL , "Length"), |
|
||||
IOPU("w", MOS9_W, IF_REAL , "Width"), |
|
||||
IOPU("ad", MOS9_AD, IF_REAL , "Drain area"), |
|
||||
IOPU("as", MOS9_AS, IF_REAL , "Source area"), |
|
||||
IOPU("pd", MOS9_PD, IF_REAL , "Drain perimeter"), |
|
||||
IOPU("ps", MOS9_PS, IF_REAL , "Source perimeter"), |
|
||||
OP("id", MOS9_CD, IF_REAL, "Drain current"), |
|
||||
OPR("cd", MOS9_CD, IF_REAL, "Drain current"), |
|
||||
OPU("ibd", MOS9_CBD, IF_REAL, "B-D junction current"), |
|
||||
OPU("ibs", MOS9_CBS, IF_REAL, "B-S junction current"), |
|
||||
OPU("is", MOS9_CS, IF_REAL, "Source current"), |
|
||||
OPU("ig", MOS9_CG, IF_REAL, "Gate current"), |
|
||||
OPU("ib", MOS9_CB, IF_REAL, "Bulk current"), |
|
||||
OP("vgs", MOS9_VGS, IF_REAL, "Gate-Source voltage"), |
|
||||
OP("vds", MOS9_VDS, IF_REAL, "Drain-Source voltage"), |
|
||||
OP("vbs", MOS9_VBS, IF_REAL, "Bulk-Source voltage"), |
|
||||
OPU("vbd", MOS9_VBD, IF_REAL, "Bulk-Drain voltage"), |
|
||||
IOPU("nrd", MOS9_NRD, IF_REAL , "Drain squares"), |
|
||||
IOPU("nrs", MOS9_NRS, IF_REAL , "Source squares"), |
|
||||
IP("off", MOS9_OFF, IF_FLAG , "Device initially off"), |
|
||||
IOPAU("icvds", MOS9_IC_VDS, IF_REAL , "Initial D-S voltage"), |
|
||||
IOPAU("icvgs", MOS9_IC_VGS, IF_REAL , "Initial G-S voltage"), |
|
||||
IOPAU("icvbs", MOS9_IC_VBS, IF_REAL , "Initial B-S voltage"), |
|
||||
IOPU("ic", MOS9_IC, IF_REALVEC, "Vector of D-S, G-S, B-S voltages"), |
|
||||
IOPU("temp", MOS9_TEMP, IF_REAL , "Instance operating temperature"), |
|
||||
IP("sens_l", MOS9_L_SENS, IF_FLAG, "flag to request sensitivity WRT length"), |
|
||||
IP("sens_w", MOS9_W_SENS, IF_FLAG, "flag to request sensitivity WRT width"), |
|
||||
OPU("dnode", MOS9_DNODE, IF_INTEGER, "Number of drain node"), |
|
||||
OPU("gnode", MOS9_GNODE, IF_INTEGER, "Number of gate node"), |
|
||||
OPU("snode", MOS9_SNODE, IF_INTEGER, "Number of source node"), |
|
||||
OPU("bnode", MOS9_BNODE, IF_INTEGER, "Number of bulk node"), |
|
||||
OPU("dnodeprime", MOS9_DNODEPRIME,IF_INTEGER,"Number of internal drain node"), |
|
||||
OPU("snodeprime", MOS9_SNODEPRIME,IF_INTEGER,"Number of internal source node"), |
|
||||
OP("von", MOS9_VON, IF_REAL, "Turn-on voltage"), |
|
||||
OP("vdsat", MOS9_VDSAT, IF_REAL, "Saturation drain voltage"), |
|
||||
OPU("sourcevcrit", MOS9_SOURCEVCRIT, IF_REAL, "Critical source voltage"), |
|
||||
OPU("drainvcrit", MOS9_DRAINVCRIT, IF_REAL, "Critical drain voltage"), |
|
||||
OP("rs", MOS9_SOURCERESIST, IF_REAL, "Source resistance"), |
|
||||
OPU("sourceconductance", MOS9_SOURCECONDUCT, IF_REAL, "Source conductance"), |
|
||||
OP("rd", MOS9_DRAINRESIST, IF_REAL, "Drain resistance"), |
|
||||
OPU("drainconductance", MOS9_DRAINCONDUCT, IF_REAL, "Drain conductance"), |
|
||||
OP("gm", MOS9_GM, IF_REAL, "Transconductance"), |
|
||||
OP("gds", MOS9_GDS, IF_REAL, "Drain-Source conductance"), |
|
||||
OP("gmb", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), |
|
||||
OPR("gmbs", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), |
|
||||
OPU("gbd", MOS9_GBD, IF_REAL, "Bulk-Drain conductance"), |
|
||||
OPU("gbs", MOS9_GBS, IF_REAL, "Bulk-Source conductance"), |
|
||||
|
|
||||
OP("cbd", MOS9_CAPBD, IF_REAL, "Bulk-Drain capacitance"), |
|
||||
OP("cbs", MOS9_CAPBS, IF_REAL, "Bulk-Source capacitance"), |
|
||||
OP("cgs", MOS9_CAPGS, IF_REAL, "Gate-Source capacitance"), |
|
||||
/* OPR("cgs", MOS9_CGS, IF_REAL , "Gate-Source capacitance"),*/ |
|
||||
OP("cgd", MOS9_CAPGD, IF_REAL, "Gate-Drain capacitance"), |
|
||||
/* OPR("cgd", MOS9_CGD, IF_REAL , "Gate-Drain capacitance"),*/ |
|
||||
OP("cgb", MOS9_CAPGB, IF_REAL, "Gate-Bulk capacitance"), |
|
||||
|
|
||||
OPU("cqgs",MOS9_CQGS,IF_REAL,"Capacitance due to gate-source charge storage"), |
|
||||
OPU("cqgd",MOS9_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), |
|
||||
OPU("cqgb",MOS9_CQGB, IF_REAL,"Capacitance due to gate-bulk charge storage"), |
|
||||
OPU("cqbd",MOS9_CQBD,IF_REAL,"Capacitance due to bulk-drain charge storage"), |
|
||||
OPU("cqbs",MOS9_CQBS,IF_REAL,"Capacitance due to bulk-source charge storage"), |
|
||||
|
|
||||
OPU("cbd0",MOS9_CAPZEROBIASBD,IF_REAL,"Zero-Bias B-D junction capacitance"), |
|
||||
OPU("cbdsw0",MOS9_CAPZEROBIASBDSW,IF_REAL, |
|
||||
"Zero-Bias B-D sidewall capacitance"), |
|
||||
OPU("cbs0",MOS9_CAPZEROBIASBS,IF_REAL,"Zero-Bias B-S junction capacitance"), |
|
||||
OPU("cbssw0",MOS9_CAPZEROBIASBSSW,IF_REAL, |
|
||||
"Zero-Bias B-S sidewall capacitance"), |
|
||||
OPU("qbs", MOS9_QBS, IF_REAL, "Bulk-Source charge storage"), |
|
||||
OPU("qgs", MOS9_QGS, IF_REAL, "Gate-Source charge storage"), |
|
||||
OPU("qgd", MOS9_QGD, IF_REAL, "Gate-Drain charge storage"), |
|
||||
OPU("qgb", MOS9_QGB, IF_REAL, "Gate-Bulk charge storage"), |
|
||||
OPU("qbd", MOS9_QBD, IF_REAL, "Bulk-Drain charge storage"), |
|
||||
OPU("p", MOS9_POWER, IF_REAL, "Instantaneous power"), |
|
||||
OPU("sens_l_dc", MOS9_L_SENS_DC, IF_REAL, "dc sensitivity wrt length"), |
|
||||
OPU("sens_l_real",MOS9_L_SENS_REAL, IF_REAL, |
|
||||
"real part of ac sensitivity wrt length"), |
|
||||
OPU("sens_l_imag",MOS9_L_SENS_IMAG, IF_REAL, |
|
||||
"imag part of ac sensitivity wrt length"), |
|
||||
OPU("sens_l_cplx",MOS9_L_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt length"), |
|
||||
OPU("sens_l_mag", MOS9_L_SENS_MAG, IF_REAL, |
|
||||
"sensitivity wrt l of ac magnitude"), |
|
||||
OPU("sens_l_ph", MOS9_L_SENS_PH, IF_REAL, "sensitivity wrt l of ac phase"), |
|
||||
OPU("sens_w_dc", MOS9_W_SENS_DC, IF_REAL, "dc sensitivity wrt width"), |
|
||||
OPU("sens_w_real",MOS9_W_SENS_REAL, IF_REAL, |
|
||||
"real part of ac sensitivity wrt width"), |
|
||||
OPU("sens_w_imag",MOS9_W_SENS_IMAG, IF_REAL, |
|
||||
"imag part of ac sensitivity wrt width"), |
|
||||
OPU("sens_w_mag", MOS9_W_SENS_MAG, IF_REAL, |
|
||||
"sensitivity wrt w of ac magnitude"), |
|
||||
OPU("sens_w_ph", MOS9_W_SENS_PH, IF_REAL, "sensitivity wrt w of ac phase"), |
|
||||
OPU("sens_w_cplx",MOS9_W_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt width") |
|
||||
}; |
|
||||
|
|
||||
IFparm MOS9mPTable[] = { /* model parameters */ |
|
||||
OP("type", MOS9_MOD_TYPE, IF_STRING ,"N-channel or P-channel MOS"), |
|
||||
IP("nmos", MOS9_MOD_NMOS, IF_FLAG ,"N type MOSfet model"), |
|
||||
IP("pmos", MOS9_MOD_PMOS, IF_FLAG ,"P type MOSfet model"), |
|
||||
IOP("vto", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), |
|
||||
IOPR("vt0", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), |
|
||||
IOP("kp", MOS9_MOD_KP, IF_REAL ,"Transconductance parameter"), |
|
||||
IOP("gamma", MOS9_MOD_GAMMA, IF_REAL ,"Bulk threshold parameter"), |
|
||||
IOP("phi", MOS9_MOD_PHI, IF_REAL ,"Surface potential"), |
|
||||
IOP("rd", MOS9_MOD_RD, IF_REAL ,"Drain ohmic resistance"), |
|
||||
IOP("rs", MOS9_MOD_RS, IF_REAL ,"Source ohmic resistance"), |
|
||||
IOPA("cbd", MOS9_MOD_CBD, IF_REAL ,"B-D junction capacitance"), |
|
||||
IOPA("cbs", MOS9_MOD_CBS, IF_REAL ,"B-S junction capacitance"), |
|
||||
IOP("is", MOS9_MOD_IS, IF_REAL ,"Bulk junction sat. current"), |
|
||||
IOP("pb", MOS9_MOD_PB, IF_REAL ,"Bulk junction potential"), |
|
||||
IOPA("cgso", MOS9_MOD_CGSO, IF_REAL ,"Gate-source overlap cap."), |
|
||||
IOPA("cgdo", MOS9_MOD_CGDO, IF_REAL ,"Gate-drain overlap cap."), |
|
||||
IOPA("cgbo", MOS9_MOD_CGBO, IF_REAL ,"Gate-bulk overlap cap."), |
|
||||
IOP("rsh", MOS9_MOD_RSH, IF_REAL ,"Sheet resistance"), |
|
||||
IOPA("cj", MOS9_MOD_CJ, IF_REAL ,"Bottom junction cap per area"), |
|
||||
IOP("mj", MOS9_MOD_MJ, IF_REAL ,"Bottom grading coefficient"), |
|
||||
IOPA("cjsw", MOS9_MOD_CJSW, IF_REAL ,"Side junction cap per area"), |
|
||||
IOP("mjsw", MOS9_MOD_MJSW, IF_REAL ,"Side grading coefficient"), |
|
||||
IOPU("js", MOS9_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), |
|
||||
IOP("tox", MOS9_MOD_TOX, IF_REAL ,"Oxide thickness"), |
|
||||
IOP("ld", MOS9_MOD_LD, IF_REAL ,"Lateral diffusion"), |
|
||||
IOP("xl", MOS9_MOD_XL, IF_REAL ,"Length mask adjustment"), |
|
||||
IOP("wd", MOS9_MOD_WD, IF_REAL ,"Width Narrowing (Diffusion)"), |
|
||||
IOP("xw", MOS9_MOD_XW, IF_REAL ,"Width mask adjustment"), |
|
||||
IOPU("delvto", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), |
|
||||
IOPR("delvt0", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), |
|
||||
IOP("u0", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), |
|
||||
IOPR("uo", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), |
|
||||
IOP("fc", MOS9_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), |
|
||||
IOP("nsub", MOS9_MOD_NSUB, IF_REAL ,"Substrate doping"), |
|
||||
IOP("tpg", MOS9_MOD_TPG, IF_INTEGER,"Gate type"), |
|
||||
IOP("nss", MOS9_MOD_NSS, IF_REAL ,"Surface state density"), |
|
||||
IOP("vmax", MOS9_MOD_VMAX, IF_REAL ,"Maximum carrier drift velocity"), |
|
||||
IOP("xj", MOS9_MOD_XJ, IF_REAL ,"Junction depth"), |
|
||||
IOP("nfs", MOS9_MOD_NFS, IF_REAL ,"Fast surface state density"), |
|
||||
IOP("xd", MOS9_MOD_XD, IF_REAL ,"Depletion layer width"), |
|
||||
IOP("alpha", MOS9_MOD_ALPHA, IF_REAL ,"Alpha"), |
|
||||
IOP("eta", MOS9_MOD_ETA, IF_REAL ,"Vds dependence of threshold voltage"), |
|
||||
IOP("delta", MOS9_MOD_DELTA, IF_REAL ,"Width effect on threshold"), |
|
||||
IOPR("input_delta", MOS9_DELTA, IF_REAL ,""), |
|
||||
IOP("theta", MOS9_MOD_THETA, IF_REAL ,"Vgs dependence on mobility"), |
|
||||
IOP("kappa", MOS9_MOD_KAPPA, IF_REAL ,"Kappa"), |
|
||||
IOPU("tnom", MOS9_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), |
|
||||
IOP("kf", MOS9_MOD_KF, IF_REAL ,"Flicker noise coefficient"), |
|
||||
IOP("af", MOS9_MOD_AF, IF_REAL ,"Flicker noise exponent") |
|
||||
}; |
|
||||
|
|
||||
char *MOS9names[] = { |
|
||||
"Drain", |
|
||||
"Gate", |
|
||||
"Source", |
|
||||
"Bulk" |
|
||||
}; |
|
||||
|
|
||||
int MOS9nSize = NUMELEMS(MOS9names); |
|
||||
int MOS9pTSize = NUMELEMS(MOS9pTable); |
|
||||
int MOS9mPTSize = NUMELEMS(MOS9mPTable); |
|
||||
int MOS9iSize = sizeof(MOS9instance); |
|
||||
int MOS9mSize = sizeof(MOS9model); |
|
||||
|
Modified: Alan Gillespie |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "devdefs.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
IFparm MOS9pTable[] = { /* parameters */ |
||||
|
|
||||
|
IOPU("m", MOS9_M, IF_REAL , "Multiplier"), |
||||
|
IOPU("l", MOS9_L, IF_REAL , "Length"), |
||||
|
IOPU("w", MOS9_W, IF_REAL , "Width"), |
||||
|
IOPU("ad", MOS9_AD, IF_REAL , "Drain area"), |
||||
|
IOPU("as", MOS9_AS, IF_REAL , "Source area"), |
||||
|
IOPU("pd", MOS9_PD, IF_REAL , "Drain perimeter"), |
||||
|
IOPU("ps", MOS9_PS, IF_REAL , "Source perimeter"), |
||||
|
OP("id", MOS9_CD, IF_REAL, "Drain current"), |
||||
|
OPR("cd", MOS9_CD, IF_REAL, "Drain current"), |
||||
|
OPU("ibd", MOS9_CBD, IF_REAL, "B-D junction current"), |
||||
|
OPU("ibs", MOS9_CBS, IF_REAL, "B-S junction current"), |
||||
|
OPU("is", MOS9_CS, IF_REAL, "Source current"), |
||||
|
OPU("ig", MOS9_CG, IF_REAL, "Gate current"), |
||||
|
OPU("ib", MOS9_CB, IF_REAL, "Bulk current"), |
||||
|
OP("vgs", MOS9_VGS, IF_REAL, "Gate-Source voltage"), |
||||
|
OP("vds", MOS9_VDS, IF_REAL, "Drain-Source voltage"), |
||||
|
OP("vbs", MOS9_VBS, IF_REAL, "Bulk-Source voltage"), |
||||
|
OPU("vbd", MOS9_VBD, IF_REAL, "Bulk-Drain voltage"), |
||||
|
IOPU("nrd", MOS9_NRD, IF_REAL , "Drain squares"), |
||||
|
IOPU("nrs", MOS9_NRS, IF_REAL , "Source squares"), |
||||
|
IP("off", MOS9_OFF, IF_FLAG , "Device initially off"), |
||||
|
IOPAU("icvds", MOS9_IC_VDS, IF_REAL , "Initial D-S voltage"), |
||||
|
IOPAU("icvgs", MOS9_IC_VGS, IF_REAL , "Initial G-S voltage"), |
||||
|
IOPAU("icvbs", MOS9_IC_VBS, IF_REAL , "Initial B-S voltage"), |
||||
|
IOPU("ic", MOS9_IC, IF_REALVEC, "Vector of D-S, G-S, B-S voltages"), |
||||
|
IOPU("temp", MOS9_TEMP, IF_REAL , "Instance operating temperature"), |
||||
|
IP("sens_l", MOS9_L_SENS, IF_FLAG, "flag to request sensitivity WRT length"), |
||||
|
IP("sens_w", MOS9_W_SENS, IF_FLAG, "flag to request sensitivity WRT width"), |
||||
|
OPU("dnode", MOS9_DNODE, IF_INTEGER, "Number of drain node"), |
||||
|
OPU("gnode", MOS9_GNODE, IF_INTEGER, "Number of gate node"), |
||||
|
OPU("snode", MOS9_SNODE, IF_INTEGER, "Number of source node"), |
||||
|
OPU("bnode", MOS9_BNODE, IF_INTEGER, "Number of bulk node"), |
||||
|
OPU("dnodeprime", MOS9_DNODEPRIME,IF_INTEGER,"Number of internal drain node"), |
||||
|
OPU("snodeprime", MOS9_SNODEPRIME,IF_INTEGER,"Number of internal source node"), |
||||
|
OP("von", MOS9_VON, IF_REAL, "Turn-on voltage"), |
||||
|
OP("vdsat", MOS9_VDSAT, IF_REAL, "Saturation drain voltage"), |
||||
|
OPU("sourcevcrit", MOS9_SOURCEVCRIT, IF_REAL, "Critical source voltage"), |
||||
|
OPU("drainvcrit", MOS9_DRAINVCRIT, IF_REAL, "Critical drain voltage"), |
||||
|
OP("rs", MOS9_SOURCERESIST, IF_REAL, "Source resistance"), |
||||
|
OPU("sourceconductance", MOS9_SOURCECONDUCT, IF_REAL, "Source conductance"), |
||||
|
OP("rd", MOS9_DRAINRESIST, IF_REAL, "Drain resistance"), |
||||
|
OPU("drainconductance", MOS9_DRAINCONDUCT, IF_REAL, "Drain conductance"), |
||||
|
OP("gm", MOS9_GM, IF_REAL, "Transconductance"), |
||||
|
OP("gds", MOS9_GDS, IF_REAL, "Drain-Source conductance"), |
||||
|
OP("gmb", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), |
||||
|
OPR("gmbs", MOS9_GMBS, IF_REAL, "Bulk-Source transconductance"), |
||||
|
OPU("gbd", MOS9_GBD, IF_REAL, "Bulk-Drain conductance"), |
||||
|
OPU("gbs", MOS9_GBS, IF_REAL, "Bulk-Source conductance"), |
||||
|
|
||||
|
OP("cbd", MOS9_CAPBD, IF_REAL, "Bulk-Drain capacitance"), |
||||
|
OP("cbs", MOS9_CAPBS, IF_REAL, "Bulk-Source capacitance"), |
||||
|
OP("cgs", MOS9_CAPGS, IF_REAL, "Gate-Source capacitance"), |
||||
|
/* OPR("cgs", MOS9_CGS, IF_REAL , "Gate-Source capacitance"),*/ |
||||
|
OP("cgd", MOS9_CAPGD, IF_REAL, "Gate-Drain capacitance"), |
||||
|
/* OPR("cgd", MOS9_CGD, IF_REAL , "Gate-Drain capacitance"),*/ |
||||
|
OP("cgb", MOS9_CAPGB, IF_REAL, "Gate-Bulk capacitance"), |
||||
|
|
||||
|
OPU("cqgs",MOS9_CQGS,IF_REAL,"Capacitance due to gate-source charge storage"), |
||||
|
OPU("cqgd",MOS9_CQGD, IF_REAL,"Capacitance due to gate-drain charge storage"), |
||||
|
OPU("cqgb",MOS9_CQGB, IF_REAL,"Capacitance due to gate-bulk charge storage"), |
||||
|
OPU("cqbd",MOS9_CQBD,IF_REAL,"Capacitance due to bulk-drain charge storage"), |
||||
|
OPU("cqbs",MOS9_CQBS,IF_REAL,"Capacitance due to bulk-source charge storage"), |
||||
|
|
||||
|
OPU("cbd0",MOS9_CAPZEROBIASBD,IF_REAL,"Zero-Bias B-D junction capacitance"), |
||||
|
OPU("cbdsw0",MOS9_CAPZEROBIASBDSW,IF_REAL, |
||||
|
"Zero-Bias B-D sidewall capacitance"), |
||||
|
OPU("cbs0",MOS9_CAPZEROBIASBS,IF_REAL,"Zero-Bias B-S junction capacitance"), |
||||
|
OPU("cbssw0",MOS9_CAPZEROBIASBSSW,IF_REAL, |
||||
|
"Zero-Bias B-S sidewall capacitance"), |
||||
|
OPU("qbs", MOS9_QBS, IF_REAL, "Bulk-Source charge storage"), |
||||
|
OPU("qgs", MOS9_QGS, IF_REAL, "Gate-Source charge storage"), |
||||
|
OPU("qgd", MOS9_QGD, IF_REAL, "Gate-Drain charge storage"), |
||||
|
OPU("qgb", MOS9_QGB, IF_REAL, "Gate-Bulk charge storage"), |
||||
|
OPU("qbd", MOS9_QBD, IF_REAL, "Bulk-Drain charge storage"), |
||||
|
OPU("p", MOS9_POWER, IF_REAL, "Instantaneous power"), |
||||
|
OPU("sens_l_dc", MOS9_L_SENS_DC, IF_REAL, "dc sensitivity wrt length"), |
||||
|
OPU("sens_l_real",MOS9_L_SENS_REAL, IF_REAL, |
||||
|
"real part of ac sensitivity wrt length"), |
||||
|
OPU("sens_l_imag",MOS9_L_SENS_IMAG, IF_REAL, |
||||
|
"imag part of ac sensitivity wrt length"), |
||||
|
OPU("sens_l_cplx",MOS9_L_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt length"), |
||||
|
OPU("sens_l_mag", MOS9_L_SENS_MAG, IF_REAL, |
||||
|
"sensitivity wrt l of ac magnitude"), |
||||
|
OPU("sens_l_ph", MOS9_L_SENS_PH, IF_REAL, "sensitivity wrt l of ac phase"), |
||||
|
OPU("sens_w_dc", MOS9_W_SENS_DC, IF_REAL, "dc sensitivity wrt width"), |
||||
|
OPU("sens_w_real",MOS9_W_SENS_REAL, IF_REAL, |
||||
|
"real part of ac sensitivity wrt width"), |
||||
|
OPU("sens_w_imag",MOS9_W_SENS_IMAG, IF_REAL, |
||||
|
"imag part of ac sensitivity wrt width"), |
||||
|
OPU("sens_w_mag", MOS9_W_SENS_MAG, IF_REAL, |
||||
|
"sensitivity wrt w of ac magnitude"), |
||||
|
OPU("sens_w_ph", MOS9_W_SENS_PH, IF_REAL, "sensitivity wrt w of ac phase"), |
||||
|
OPU("sens_w_cplx",MOS9_W_SENS_CPLX, IF_COMPLEX, "ac sensitivity wrt width") |
||||
|
}; |
||||
|
|
||||
|
IFparm MOS9mPTable[] = { /* model parameters */ |
||||
|
OP("type", MOS9_MOD_TYPE, IF_STRING ,"N-channel or P-channel MOS"), |
||||
|
IP("nmos", MOS9_MOD_NMOS, IF_FLAG ,"N type MOSfet model"), |
||||
|
IP("pmos", MOS9_MOD_PMOS, IF_FLAG ,"P type MOSfet model"), |
||||
|
IOP("vto", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), |
||||
|
IOPR("vt0", MOS9_MOD_VTO, IF_REAL ,"Threshold voltage"), |
||||
|
IOP("kp", MOS9_MOD_KP, IF_REAL ,"Transconductance parameter"), |
||||
|
IOP("gamma", MOS9_MOD_GAMMA, IF_REAL ,"Bulk threshold parameter"), |
||||
|
IOP("phi", MOS9_MOD_PHI, IF_REAL ,"Surface potential"), |
||||
|
IOP("rd", MOS9_MOD_RD, IF_REAL ,"Drain ohmic resistance"), |
||||
|
IOP("rs", MOS9_MOD_RS, IF_REAL ,"Source ohmic resistance"), |
||||
|
IOPA("cbd", MOS9_MOD_CBD, IF_REAL ,"B-D junction capacitance"), |
||||
|
IOPA("cbs", MOS9_MOD_CBS, IF_REAL ,"B-S junction capacitance"), |
||||
|
IOP("is", MOS9_MOD_IS, IF_REAL ,"Bulk junction sat. current"), |
||||
|
IOP("pb", MOS9_MOD_PB, IF_REAL ,"Bulk junction potential"), |
||||
|
IOPA("cgso", MOS9_MOD_CGSO, IF_REAL ,"Gate-source overlap cap."), |
||||
|
IOPA("cgdo", MOS9_MOD_CGDO, IF_REAL ,"Gate-drain overlap cap."), |
||||
|
IOPA("cgbo", MOS9_MOD_CGBO, IF_REAL ,"Gate-bulk overlap cap."), |
||||
|
IOP("rsh", MOS9_MOD_RSH, IF_REAL ,"Sheet resistance"), |
||||
|
IOPA("cj", MOS9_MOD_CJ, IF_REAL ,"Bottom junction cap per area"), |
||||
|
IOP("mj", MOS9_MOD_MJ, IF_REAL ,"Bottom grading coefficient"), |
||||
|
IOPA("cjsw", MOS9_MOD_CJSW, IF_REAL ,"Side junction cap per area"), |
||||
|
IOP("mjsw", MOS9_MOD_MJSW, IF_REAL ,"Side grading coefficient"), |
||||
|
IOPU("js", MOS9_MOD_JS, IF_REAL ,"Bulk jct. sat. current density"), |
||||
|
IOP("tox", MOS9_MOD_TOX, IF_REAL ,"Oxide thickness"), |
||||
|
IOP("ld", MOS9_MOD_LD, IF_REAL ,"Lateral diffusion"), |
||||
|
IOP("xl", MOS9_MOD_XL, IF_REAL ,"Length mask adjustment"), |
||||
|
IOP("wd", MOS9_MOD_WD, IF_REAL ,"Width Narrowing (Diffusion)"), |
||||
|
IOP("xw", MOS9_MOD_XW, IF_REAL ,"Width mask adjustment"), |
||||
|
IOPU("delvto", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), |
||||
|
IOPR("delvt0", MOS9_MOD_DELVTO, IF_REAL ,"Threshold voltage Adjust"), |
||||
|
IOP("u0", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), |
||||
|
IOPR("uo", MOS9_MOD_U0, IF_REAL ,"Surface mobility"), |
||||
|
IOP("fc", MOS9_MOD_FC, IF_REAL ,"Forward bias jct. fit parm."), |
||||
|
IOP("nsub", MOS9_MOD_NSUB, IF_REAL ,"Substrate doping"), |
||||
|
IOP("tpg", MOS9_MOD_TPG, IF_INTEGER,"Gate type"), |
||||
|
IOP("nss", MOS9_MOD_NSS, IF_REAL ,"Surface state density"), |
||||
|
IOP("vmax", MOS9_MOD_VMAX, IF_REAL ,"Maximum carrier drift velocity"), |
||||
|
IOP("xj", MOS9_MOD_XJ, IF_REAL ,"Junction depth"), |
||||
|
IOP("nfs", MOS9_MOD_NFS, IF_REAL ,"Fast surface state density"), |
||||
|
IOP("xd", MOS9_MOD_XD, IF_REAL ,"Depletion layer width"), |
||||
|
IOP("alpha", MOS9_MOD_ALPHA, IF_REAL ,"Alpha"), |
||||
|
IOP("eta", MOS9_MOD_ETA, IF_REAL ,"Vds dependence of threshold voltage"), |
||||
|
IOP("delta", MOS9_MOD_DELTA, IF_REAL ,"Width effect on threshold"), |
||||
|
IOPR("input_delta", MOS9_DELTA, IF_REAL ,""), |
||||
|
IOP("theta", MOS9_MOD_THETA, IF_REAL ,"Vgs dependence on mobility"), |
||||
|
IOP("kappa", MOS9_MOD_KAPPA, IF_REAL ,"Kappa"), |
||||
|
IOPU("tnom", MOS9_MOD_TNOM, IF_REAL ,"Parameter measurement temperature"), |
||||
|
IOP("kf", MOS9_MOD_KF, IF_REAL ,"Flicker noise coefficient"), |
||||
|
IOP("af", MOS9_MOD_AF, IF_REAL ,"Flicker noise exponent") |
||||
|
}; |
||||
|
|
||||
|
char *MOS9names[] = { |
||||
|
"Drain", |
||||
|
"Gate", |
||||
|
"Source", |
||||
|
"Bulk" |
||||
|
}; |
||||
|
|
||||
|
int MOS9nSize = NUMELEMS(MOS9names); |
||||
|
int MOS9pTSize = NUMELEMS(MOS9pTable); |
||||
|
int MOS9mPTSize = NUMELEMS(MOS9mPTable); |
||||
|
int MOS9iSize = sizeof(MOS9instance); |
||||
|
int MOS9mSize = sizeof(MOS9model); |
||||
@ -1,128 +1,128 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9acLoad(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
int xnrm; |
|
||||
int xrev; |
|
||||
double EffectiveLength; |
|
||||
double EffectiveWidth; |
|
||||
double xgs; |
|
||||
double xgd; |
|
||||
double xgb; |
|
||||
double xbd; |
|
||||
double xbs; |
|
||||
double capgs; |
|
||||
double capgd; |
|
||||
double capgb; |
|
||||
double GateBulkOverlapCap; |
|
||||
double GateDrainOverlapCap; |
|
||||
double GateSourceOverlapCap; |
|
||||
|
|
||||
for( ; model != NULL; model = model->MOS9nextModel) { |
|
||||
for(here = model->MOS9instances; here!= NULL; |
|
||||
here = here->MOS9nextInstance) { |
|
||||
|
|
||||
if (here->MOS9mode < 0) { |
|
||||
xnrm=0; |
|
||||
xrev=1; |
|
||||
} else { |
|
||||
xnrm=1; |
|
||||
xrev=0; |
|
||||
} |
|
||||
/* |
|
||||
* charge oriented model parameters |
|
||||
*/ |
|
||||
EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ |
|
||||
model->MOS9widthAdjust; |
|
||||
EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ |
|
||||
model->MOS9lengthAdjust; |
|
||||
GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveWidth; |
|
||||
GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveWidth; |
|
||||
GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveLength; |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
|
||||
/* |
|
||||
* meyer"s model parameters |
|
||||
*/ |
|
||||
capgs = ( *(ckt->CKTstate0+here->MOS9capgs)+ |
|
||||
*(ckt->CKTstate0+here->MOS9capgs) + |
|
||||
GateSourceOverlapCap ); |
|
||||
capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ |
|
||||
*(ckt->CKTstate0+here->MOS9capgd) + |
|
||||
GateDrainOverlapCap ); |
|
||||
capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ |
|
||||
*(ckt->CKTstate0+here->MOS9capgb) + |
|
||||
GateBulkOverlapCap ); |
|
||||
xgs = capgs * ckt->CKTomega; |
|
||||
xgd = capgd * ckt->CKTomega; |
|
||||
xgb = capgb * ckt->CKTomega; |
|
||||
xbd = here->MOS9capbd * ckt->CKTomega; |
|
||||
xbs = here->MOS9capbs * ckt->CKTomega; |
|
||||
|
|
||||
/* |
|
||||
* load matrix |
|
||||
*/ |
|
||||
|
|
||||
*(here->MOS9GgPtr +1) += xgd+xgs+xgb; |
|
||||
*(here->MOS9BbPtr +1) += xgb+xbd+xbs; |
|
||||
*(here->MOS9DPdpPtr +1) += xgd+xbd; |
|
||||
*(here->MOS9SPspPtr +1) += xgs+xbs; |
|
||||
*(here->MOS9GbPtr +1) -= xgb; |
|
||||
*(here->MOS9GdpPtr +1) -= xgd; |
|
||||
*(here->MOS9GspPtr +1) -= xgs; |
|
||||
*(here->MOS9BgPtr +1) -= xgb; |
|
||||
*(here->MOS9BdpPtr +1) -= xbd; |
|
||||
*(here->MOS9BspPtr +1) -= xbs; |
|
||||
*(here->MOS9DPgPtr +1) -= xgd; |
|
||||
*(here->MOS9DPbPtr +1) -= xbd; |
|
||||
*(here->MOS9SPgPtr +1) -= xgs; |
|
||||
*(here->MOS9SPbPtr +1) -= xbs; |
|
||||
*(here->MOS9DdPtr) += here->MOS9drainConductance; |
|
||||
*(here->MOS9SsPtr) += here->MOS9sourceConductance; |
|
||||
*(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; |
|
||||
*(here->MOS9DPdpPtr) += here->MOS9drainConductance+ |
|
||||
here->MOS9gds+here->MOS9gbd+ |
|
||||
xrev*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9SPspPtr) += here->MOS9sourceConductance+ |
|
||||
here->MOS9gds+here->MOS9gbs+ |
|
||||
xnrm*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9DdpPtr) -= here->MOS9drainConductance; |
|
||||
*(here->MOS9SspPtr) -= here->MOS9sourceConductance; |
|
||||
*(here->MOS9BdpPtr) -= here->MOS9gbd; |
|
||||
*(here->MOS9BspPtr) -= here->MOS9gbs; |
|
||||
*(here->MOS9DPdPtr) -= here->MOS9drainConductance; |
|
||||
*(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; |
|
||||
*(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; |
|
||||
*(here->MOS9DPspPtr) -= here->MOS9gds+ |
|
||||
xnrm*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; |
|
||||
*(here->MOS9SPsPtr) -= here->MOS9sourceConductance; |
|
||||
*(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; |
|
||||
*(here->MOS9SPdpPtr) -= here->MOS9gds+ |
|
||||
xrev*(here->MOS9gm+here->MOS9gmbs); |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9acLoad(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
int xnrm; |
||||
|
int xrev; |
||||
|
double EffectiveLength; |
||||
|
double EffectiveWidth; |
||||
|
double xgs; |
||||
|
double xgd; |
||||
|
double xgb; |
||||
|
double xbd; |
||||
|
double xbs; |
||||
|
double capgs; |
||||
|
double capgd; |
||||
|
double capgb; |
||||
|
double GateBulkOverlapCap; |
||||
|
double GateDrainOverlapCap; |
||||
|
double GateSourceOverlapCap; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MOS9nextModel) { |
||||
|
for(here = model->MOS9instances; here!= NULL; |
||||
|
here = here->MOS9nextInstance) { |
||||
|
|
||||
|
if (here->MOS9mode < 0) { |
||||
|
xnrm=0; |
||||
|
xrev=1; |
||||
|
} else { |
||||
|
xnrm=1; |
||||
|
xrev=0; |
||||
|
} |
||||
|
/* |
||||
|
* charge oriented model parameters |
||||
|
*/ |
||||
|
EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ |
||||
|
model->MOS9widthAdjust; |
||||
|
EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ |
||||
|
model->MOS9lengthAdjust; |
||||
|
GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveWidth; |
||||
|
GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveWidth; |
||||
|
GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveLength; |
||||
|
|
||||
|
|
||||
|
/* |
||||
|
* meyer"s model parameters |
||||
|
*/ |
||||
|
capgs = ( *(ckt->CKTstate0+here->MOS9capgs)+ |
||||
|
*(ckt->CKTstate0+here->MOS9capgs) + |
||||
|
GateSourceOverlapCap ); |
||||
|
capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ |
||||
|
*(ckt->CKTstate0+here->MOS9capgd) + |
||||
|
GateDrainOverlapCap ); |
||||
|
capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ |
||||
|
*(ckt->CKTstate0+here->MOS9capgb) + |
||||
|
GateBulkOverlapCap ); |
||||
|
xgs = capgs * ckt->CKTomega; |
||||
|
xgd = capgd * ckt->CKTomega; |
||||
|
xgb = capgb * ckt->CKTomega; |
||||
|
xbd = here->MOS9capbd * ckt->CKTomega; |
||||
|
xbs = here->MOS9capbs * ckt->CKTomega; |
||||
|
|
||||
|
/* |
||||
|
* load matrix |
||||
|
*/ |
||||
|
|
||||
|
*(here->MOS9GgPtr +1) += xgd+xgs+xgb; |
||||
|
*(here->MOS9BbPtr +1) += xgb+xbd+xbs; |
||||
|
*(here->MOS9DPdpPtr +1) += xgd+xbd; |
||||
|
*(here->MOS9SPspPtr +1) += xgs+xbs; |
||||
|
*(here->MOS9GbPtr +1) -= xgb; |
||||
|
*(here->MOS9GdpPtr +1) -= xgd; |
||||
|
*(here->MOS9GspPtr +1) -= xgs; |
||||
|
*(here->MOS9BgPtr +1) -= xgb; |
||||
|
*(here->MOS9BdpPtr +1) -= xbd; |
||||
|
*(here->MOS9BspPtr +1) -= xbs; |
||||
|
*(here->MOS9DPgPtr +1) -= xgd; |
||||
|
*(here->MOS9DPbPtr +1) -= xbd; |
||||
|
*(here->MOS9SPgPtr +1) -= xgs; |
||||
|
*(here->MOS9SPbPtr +1) -= xbs; |
||||
|
*(here->MOS9DdPtr) += here->MOS9drainConductance; |
||||
|
*(here->MOS9SsPtr) += here->MOS9sourceConductance; |
||||
|
*(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; |
||||
|
*(here->MOS9DPdpPtr) += here->MOS9drainConductance+ |
||||
|
here->MOS9gds+here->MOS9gbd+ |
||||
|
xrev*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9SPspPtr) += here->MOS9sourceConductance+ |
||||
|
here->MOS9gds+here->MOS9gbs+ |
||||
|
xnrm*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9DdpPtr) -= here->MOS9drainConductance; |
||||
|
*(here->MOS9SspPtr) -= here->MOS9sourceConductance; |
||||
|
*(here->MOS9BdpPtr) -= here->MOS9gbd; |
||||
|
*(here->MOS9BspPtr) -= here->MOS9gbs; |
||||
|
*(here->MOS9DPdPtr) -= here->MOS9drainConductance; |
||||
|
*(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; |
||||
|
*(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; |
||||
|
*(here->MOS9DPspPtr) -= here->MOS9gds+ |
||||
|
xnrm*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; |
||||
|
*(here->MOS9SPsPtr) -= here->MOS9sourceConductance; |
||||
|
*(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; |
||||
|
*(here->MOS9SPdpPtr) -= here->MOS9gds+ |
||||
|
xrev*(here->MOS9gm+here->MOS9gmbs); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -1,444 +1,444 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1987 Mathew Lew and Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Mathew Lew and Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "const.h" |
|
||||
#include "ifsim.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "devdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
/*ARGSUSED*/ |
|
||||
int |
|
||||
MOS9ask(ckt,inst,which,value,select) |
|
||||
CKTcircuit *ckt; |
|
||||
GENinstance *inst; |
|
||||
int which; |
|
||||
IFvalue *value; |
|
||||
IFvalue *select; |
|
||||
{ |
|
||||
MOS9instance *here = (MOS9instance *)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 MOS9_TEMP: |
|
||||
value->rValue = here->MOS9temp-CONSTCtoK; |
|
||||
return(OK); |
|
||||
case MOS9_CGS: |
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); |
|
||||
return(OK); |
|
||||
case MOS9_CGD: |
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); |
|
||||
return(OK); |
|
||||
case MOS9_M: |
|
||||
value->rValue = here->MOS9m; |
|
||||
return(OK); |
|
||||
case MOS9_L: |
|
||||
value->rValue = here->MOS9l; |
|
||||
return(OK); |
|
||||
case MOS9_W: |
|
||||
value->rValue = here->MOS9w; |
|
||||
return(OK); |
|
||||
case MOS9_AS: |
|
||||
value->rValue = here->MOS9sourceArea; |
|
||||
return(OK); |
|
||||
case MOS9_AD: |
|
||||
value->rValue = here->MOS9drainArea; |
|
||||
return(OK); |
|
||||
case MOS9_PS: |
|
||||
value->rValue = here->MOS9sourcePerimiter; |
|
||||
return(OK); |
|
||||
case MOS9_PD: |
|
||||
value->rValue = here->MOS9drainPerimiter; |
|
||||
return(OK); |
|
||||
case MOS9_NRS: |
|
||||
value->rValue = here->MOS9sourceSquares; |
|
||||
return(OK); |
|
||||
case MOS9_NRD: |
|
||||
value->rValue = here->MOS9drainSquares; |
|
||||
return(OK); |
|
||||
case MOS9_OFF: |
|
||||
value->rValue = here->MOS9off; |
|
||||
return(OK); |
|
||||
case MOS9_IC_VBS: |
|
||||
value->rValue = here->MOS9icVBS; |
|
||||
return(OK); |
|
||||
case MOS9_IC_VDS: |
|
||||
value->rValue = here->MOS9icVDS; |
|
||||
return(OK); |
|
||||
case MOS9_IC_VGS: |
|
||||
value->rValue = here->MOS9icVGS; |
|
||||
return(OK); |
|
||||
case MOS9_DNODE: |
|
||||
value->iValue = here->MOS9dNode; |
|
||||
return(OK); |
|
||||
case MOS9_GNODE: |
|
||||
value->iValue = here->MOS9gNode; |
|
||||
return(OK); |
|
||||
case MOS9_SNODE: |
|
||||
value->iValue = here->MOS9sNode; |
|
||||
return(OK); |
|
||||
case MOS9_BNODE: |
|
||||
value->iValue = here->MOS9bNode; |
|
||||
return(OK); |
|
||||
case MOS9_DNODEPRIME: |
|
||||
value->iValue = here->MOS9dNodePrime; |
|
||||
return(OK); |
|
||||
case MOS9_SNODEPRIME: |
|
||||
value->iValue = here->MOS9sNodePrime; |
|
||||
return(OK); |
|
||||
case MOS9_SOURCECONDUCT: |
|
||||
value->rValue = here->MOS9sourceConductance; |
|
||||
return(OK); |
|
||||
case MOS9_DRAINCONDUCT: |
|
||||
value->rValue = here->MOS9drainConductance; |
|
||||
return(OK); |
|
||||
case MOS9_SOURCERESIST: |
|
||||
if (here->MOS9sNodePrime != here->MOS9sNode) |
|
||||
value->rValue = 1.0 / here->MOS9sourceConductance; |
|
||||
else |
|
||||
value->rValue = 0.0; |
|
||||
return(OK); |
|
||||
case MOS9_DRAINRESIST: |
|
||||
if (here->MOS9dNodePrime != here->MOS9dNode) |
|
||||
value->rValue = 1.0 / here->MOS9drainConductance; |
|
||||
else |
|
||||
value->rValue = 0.0; |
|
||||
return(OK); |
|
||||
case MOS9_VON: |
|
||||
value->rValue = here->MOS9von; |
|
||||
return(OK); |
|
||||
case MOS9_VDSAT: |
|
||||
value->rValue = here->MOS9vdsat; |
|
||||
return(OK); |
|
||||
case MOS9_SOURCEVCRIT: |
|
||||
value->rValue = here->MOS9sourceVcrit; |
|
||||
return(OK); |
|
||||
case MOS9_DRAINVCRIT: |
|
||||
value->rValue = here->MOS9drainVcrit; |
|
||||
return(OK); |
|
||||
case MOS9_CD: |
|
||||
value->rValue = here->MOS9cd; |
|
||||
return(OK); |
|
||||
case MOS9_CBS: |
|
||||
value->rValue = here->MOS9cbs; |
|
||||
return(OK); |
|
||||
case MOS9_CBD: |
|
||||
value->rValue = here->MOS9cbd; |
|
||||
return(OK); |
|
||||
case MOS9_GMBS: |
|
||||
value->rValue = here->MOS9gmbs; |
|
||||
return(OK); |
|
||||
case MOS9_GM: |
|
||||
value->rValue = here->MOS9gm; |
|
||||
return(OK); |
|
||||
case MOS9_GDS: |
|
||||
value->rValue = here->MOS9gds; |
|
||||
return(OK); |
|
||||
case MOS9_GBD: |
|
||||
value->rValue = here->MOS9gbd; |
|
||||
return(OK); |
|
||||
case MOS9_GBS: |
|
||||
value->rValue = here->MOS9gbs; |
|
||||
return(OK); |
|
||||
case MOS9_CAPBD: |
|
||||
value->rValue = here->MOS9capbd; |
|
||||
return(OK); |
|
||||
case MOS9_CAPBS: |
|
||||
value->rValue = here->MOS9capbs; |
|
||||
return(OK); |
|
||||
case MOS9_CAPZEROBIASBD: |
|
||||
value->rValue = here->MOS9Cbd; |
|
||||
return(OK); |
|
||||
case MOS9_CAPZEROBIASBDSW: |
|
||||
value->rValue = here->MOS9Cbdsw; |
|
||||
return(OK); |
|
||||
case MOS9_CAPZEROBIASBS: |
|
||||
value->rValue = here->MOS9Cbs; |
|
||||
return(OK); |
|
||||
case MOS9_CAPZEROBIASBSSW: |
|
||||
value->rValue = here->MOS9Cbssw; |
|
||||
return(OK); |
|
||||
case MOS9_VBD: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9vbd); |
|
||||
return(OK); |
|
||||
case MOS9_VBS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9vbs); |
|
||||
return(OK); |
|
||||
case MOS9_VGS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9vgs); |
|
||||
return(OK); |
|
||||
case MOS9_VDS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9vds); |
|
||||
return(OK); |
|
||||
case MOS9_CAPGS: |
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); |
|
||||
/* add overlap capacitance */ |
|
||||
value->rValue += (here->MOS9modPtr->MOS9gateSourceOverlapCapFactor) |
|
||||
* here->MOS9m |
|
||||
* (here->MOS9w |
|
||||
+here->MOS9modPtr->MOS9widthAdjust |
|
||||
-2*(here->MOS9modPtr->MOS9widthNarrow)); |
|
||||
return(OK); |
|
||||
case MOS9_QGS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9qgs); |
|
||||
return(OK); |
|
||||
case MOS9_CQGS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgs); |
|
||||
return(OK); |
|
||||
case MOS9_CAPGD: |
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); |
|
||||
/* add overlap capacitance */ |
|
||||
value->rValue += (here->MOS9modPtr->MOS9gateDrainOverlapCapFactor) |
|
||||
* here->MOS9m |
|
||||
* (here->MOS9w |
|
||||
+here->MOS9modPtr->MOS9widthAdjust |
|
||||
-2*(here->MOS9modPtr->MOS9widthNarrow)); |
|
||||
return(OK); |
|
||||
case MOS9_QGD: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9qgd); |
|
||||
return(OK); |
|
||||
case MOS9_CQGD: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgd); |
|
||||
return(OK); |
|
||||
case MOS9_CAPGB: |
|
||||
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgb); |
|
||||
/* add overlap capacitance */ |
|
||||
value->rValue += (here->MOS9modPtr->MOS9gateBulkOverlapCapFactor) |
|
||||
* here->MOS9m |
|
||||
* (here->MOS9l |
|
||||
+here->MOS9modPtr->MOS9lengthAdjust |
|
||||
-2*(here->MOS9modPtr->MOS9latDiff)); |
|
||||
return(OK); |
|
||||
case MOS9_QGB: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9qgb); |
|
||||
return(OK); |
|
||||
case MOS9_CQGB: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgb); |
|
||||
return(OK); |
|
||||
case MOS9_QBD: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9qbd); |
|
||||
return(OK); |
|
||||
case MOS9_CQBD: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9cqbd); |
|
||||
return(OK); |
|
||||
case MOS9_QBS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9qbs); |
|
||||
return(OK); |
|
||||
case MOS9_CQBS: |
|
||||
value->rValue = *(ckt->CKTstate0 + here->MOS9cqbs); |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_DC: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_REAL: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_IMAG: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_MAG: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
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->MOS9senParmNo); |
|
||||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
value->rValue = (vr * sr + vi * si)/vm; |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_PH: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
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->MOS9senParmNo); |
|
||||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
value->rValue = (vr * si - vi * sr)/vm; |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_L_SENS_CPLX: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->cValue.real= |
|
||||
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
value->cValue.imag= |
|
||||
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_DC: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_REAL: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_IMAG: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_MAG: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
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->MOS9senParmNo + here->MOS9sens_l); |
|
||||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
value->rValue = (vr * sr + vi * si)/vm; |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_PH: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
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->MOS9senParmNo + here->MOS9sens_l); |
|
||||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
value->rValue = (vr * si - vi * sr)/vm; |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_W_SENS_CPLX: |
|
||||
if(ckt->CKTsenInfo){ |
|
||||
value->cValue.real= |
|
||||
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
value->cValue.imag= |
|
||||
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|
||||
here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_CB : |
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|
||||
errMsg = MALLOC(strlen(msg)+1); |
|
||||
errRtn = "MOS9ask.c"; |
|
||||
strcpy(errMsg,msg); |
|
||||
return(E_ASKCURRENT); |
|
||||
} else { |
|
||||
value->rValue = here->MOS9cbd + here->MOS9cbs - *(ckt->CKTstate0 |
|
||||
+ here->MOS9cqgb); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_CG : |
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|
||||
errMsg = MALLOC(strlen(msg)+1); |
|
||||
errRtn = "MOS9ask.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->MOS9cqgb) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgd) + *(ckt->CKTstate0 + |
|
||||
here->MOS9cqgs); |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_CS : |
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|
||||
errMsg = MALLOC(strlen(msg)+1); |
|
||||
errRtn = "MOS9ask.c"; |
|
||||
strcpy(errMsg,msg); |
|
||||
return(E_ASKCURRENT); |
|
||||
} else { |
|
||||
value->rValue = -here->MOS9cd; |
|
||||
value->rValue -= here->MOS9cbd + here->MOS9cbs - |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgb); |
|
||||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|
||||
!(ckt->CKTmode & MODETRANOP)) { |
|
||||
value->rValue -= *(ckt->CKTstate0 + here->MOS9cqgb) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgd) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgs); |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
case MOS9_POWER : |
|
||||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|
||||
errMsg = MALLOC(strlen(msg)+1); |
|
||||
errRtn = "MOS9ask.c"; |
|
||||
strcpy(errMsg,msg); |
|
||||
return(E_ASKPOWER); |
|
||||
} else { |
|
||||
double temp; |
|
||||
|
|
||||
value->rValue = here->MOS9cd * |
|
||||
*(ckt->CKTrhsOld + here->MOS9dNode); |
|
||||
value->rValue += (here->MOS9cbd + here->MOS9cbs - |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgb)) * |
|
||||
*(ckt->CKTrhsOld + here->MOS9bNode); |
|
||||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|
||||
!(ckt->CKTmode & MODETRANOP)) { |
|
||||
value->rValue += (*(ckt->CKTstate0 + here->MOS9cqgb) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgd) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgs)) * |
|
||||
*(ckt->CKTrhsOld + here->MOS9gNode); |
|
||||
} |
|
||||
temp = -here->MOS9cd; |
|
||||
temp -= here->MOS9cbd + here->MOS9cbs ; |
|
||||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|
||||
!(ckt->CKTmode & MODETRANOP)) { |
|
||||
temp -= *(ckt->CKTstate0 + here->MOS9cqgb) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgd) + |
|
||||
*(ckt->CKTstate0 + here->MOS9cqgs); |
|
||||
} |
|
||||
value->rValue += temp * *(ckt->CKTrhsOld + here->MOS9sNode); |
|
||||
} |
|
||||
return(OK); |
|
||||
default: |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
/* NOTREACHED */ |
|
||||
} |
|
||||
|
|
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
/*ARGSUSED*/ |
||||
|
int |
||||
|
MOS9ask(ckt,inst,which,value,select) |
||||
|
CKTcircuit *ckt; |
||||
|
GENinstance *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
MOS9instance *here = (MOS9instance *)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 MOS9_TEMP: |
||||
|
value->rValue = here->MOS9temp-CONSTCtoK; |
||||
|
return(OK); |
||||
|
case MOS9_CGS: |
||||
|
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); |
||||
|
return(OK); |
||||
|
case MOS9_CGD: |
||||
|
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); |
||||
|
return(OK); |
||||
|
case MOS9_M: |
||||
|
value->rValue = here->MOS9m; |
||||
|
return(OK); |
||||
|
case MOS9_L: |
||||
|
value->rValue = here->MOS9l; |
||||
|
return(OK); |
||||
|
case MOS9_W: |
||||
|
value->rValue = here->MOS9w; |
||||
|
return(OK); |
||||
|
case MOS9_AS: |
||||
|
value->rValue = here->MOS9sourceArea; |
||||
|
return(OK); |
||||
|
case MOS9_AD: |
||||
|
value->rValue = here->MOS9drainArea; |
||||
|
return(OK); |
||||
|
case MOS9_PS: |
||||
|
value->rValue = here->MOS9sourcePerimiter; |
||||
|
return(OK); |
||||
|
case MOS9_PD: |
||||
|
value->rValue = here->MOS9drainPerimiter; |
||||
|
return(OK); |
||||
|
case MOS9_NRS: |
||||
|
value->rValue = here->MOS9sourceSquares; |
||||
|
return(OK); |
||||
|
case MOS9_NRD: |
||||
|
value->rValue = here->MOS9drainSquares; |
||||
|
return(OK); |
||||
|
case MOS9_OFF: |
||||
|
value->rValue = here->MOS9off; |
||||
|
return(OK); |
||||
|
case MOS9_IC_VBS: |
||||
|
value->rValue = here->MOS9icVBS; |
||||
|
return(OK); |
||||
|
case MOS9_IC_VDS: |
||||
|
value->rValue = here->MOS9icVDS; |
||||
|
return(OK); |
||||
|
case MOS9_IC_VGS: |
||||
|
value->rValue = here->MOS9icVGS; |
||||
|
return(OK); |
||||
|
case MOS9_DNODE: |
||||
|
value->iValue = here->MOS9dNode; |
||||
|
return(OK); |
||||
|
case MOS9_GNODE: |
||||
|
value->iValue = here->MOS9gNode; |
||||
|
return(OK); |
||||
|
case MOS9_SNODE: |
||||
|
value->iValue = here->MOS9sNode; |
||||
|
return(OK); |
||||
|
case MOS9_BNODE: |
||||
|
value->iValue = here->MOS9bNode; |
||||
|
return(OK); |
||||
|
case MOS9_DNODEPRIME: |
||||
|
value->iValue = here->MOS9dNodePrime; |
||||
|
return(OK); |
||||
|
case MOS9_SNODEPRIME: |
||||
|
value->iValue = here->MOS9sNodePrime; |
||||
|
return(OK); |
||||
|
case MOS9_SOURCECONDUCT: |
||||
|
value->rValue = here->MOS9sourceConductance; |
||||
|
return(OK); |
||||
|
case MOS9_DRAINCONDUCT: |
||||
|
value->rValue = here->MOS9drainConductance; |
||||
|
return(OK); |
||||
|
case MOS9_SOURCERESIST: |
||||
|
if (here->MOS9sNodePrime != here->MOS9sNode) |
||||
|
value->rValue = 1.0 / here->MOS9sourceConductance; |
||||
|
else |
||||
|
value->rValue = 0.0; |
||||
|
return(OK); |
||||
|
case MOS9_DRAINRESIST: |
||||
|
if (here->MOS9dNodePrime != here->MOS9dNode) |
||||
|
value->rValue = 1.0 / here->MOS9drainConductance; |
||||
|
else |
||||
|
value->rValue = 0.0; |
||||
|
return(OK); |
||||
|
case MOS9_VON: |
||||
|
value->rValue = here->MOS9von; |
||||
|
return(OK); |
||||
|
case MOS9_VDSAT: |
||||
|
value->rValue = here->MOS9vdsat; |
||||
|
return(OK); |
||||
|
case MOS9_SOURCEVCRIT: |
||||
|
value->rValue = here->MOS9sourceVcrit; |
||||
|
return(OK); |
||||
|
case MOS9_DRAINVCRIT: |
||||
|
value->rValue = here->MOS9drainVcrit; |
||||
|
return(OK); |
||||
|
case MOS9_CD: |
||||
|
value->rValue = here->MOS9cd; |
||||
|
return(OK); |
||||
|
case MOS9_CBS: |
||||
|
value->rValue = here->MOS9cbs; |
||||
|
return(OK); |
||||
|
case MOS9_CBD: |
||||
|
value->rValue = here->MOS9cbd; |
||||
|
return(OK); |
||||
|
case MOS9_GMBS: |
||||
|
value->rValue = here->MOS9gmbs; |
||||
|
return(OK); |
||||
|
case MOS9_GM: |
||||
|
value->rValue = here->MOS9gm; |
||||
|
return(OK); |
||||
|
case MOS9_GDS: |
||||
|
value->rValue = here->MOS9gds; |
||||
|
return(OK); |
||||
|
case MOS9_GBD: |
||||
|
value->rValue = here->MOS9gbd; |
||||
|
return(OK); |
||||
|
case MOS9_GBS: |
||||
|
value->rValue = here->MOS9gbs; |
||||
|
return(OK); |
||||
|
case MOS9_CAPBD: |
||||
|
value->rValue = here->MOS9capbd; |
||||
|
return(OK); |
||||
|
case MOS9_CAPBS: |
||||
|
value->rValue = here->MOS9capbs; |
||||
|
return(OK); |
||||
|
case MOS9_CAPZEROBIASBD: |
||||
|
value->rValue = here->MOS9Cbd; |
||||
|
return(OK); |
||||
|
case MOS9_CAPZEROBIASBDSW: |
||||
|
value->rValue = here->MOS9Cbdsw; |
||||
|
return(OK); |
||||
|
case MOS9_CAPZEROBIASBS: |
||||
|
value->rValue = here->MOS9Cbs; |
||||
|
return(OK); |
||||
|
case MOS9_CAPZEROBIASBSSW: |
||||
|
value->rValue = here->MOS9Cbssw; |
||||
|
return(OK); |
||||
|
case MOS9_VBD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9vbd); |
||||
|
return(OK); |
||||
|
case MOS9_VBS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9vbs); |
||||
|
return(OK); |
||||
|
case MOS9_VGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9vgs); |
||||
|
return(OK); |
||||
|
case MOS9_VDS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9vds); |
||||
|
return(OK); |
||||
|
case MOS9_CAPGS: |
||||
|
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgs); |
||||
|
/* add overlap capacitance */ |
||||
|
value->rValue += (here->MOS9modPtr->MOS9gateSourceOverlapCapFactor) |
||||
|
* here->MOS9m |
||||
|
* (here->MOS9w |
||||
|
+here->MOS9modPtr->MOS9widthAdjust |
||||
|
-2*(here->MOS9modPtr->MOS9widthNarrow)); |
||||
|
return(OK); |
||||
|
case MOS9_QGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9qgs); |
||||
|
return(OK); |
||||
|
case MOS9_CQGS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgs); |
||||
|
return(OK); |
||||
|
case MOS9_CAPGD: |
||||
|
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgd); |
||||
|
/* add overlap capacitance */ |
||||
|
value->rValue += (here->MOS9modPtr->MOS9gateDrainOverlapCapFactor) |
||||
|
* here->MOS9m |
||||
|
* (here->MOS9w |
||||
|
+here->MOS9modPtr->MOS9widthAdjust |
||||
|
-2*(here->MOS9modPtr->MOS9widthNarrow)); |
||||
|
return(OK); |
||||
|
case MOS9_QGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9qgd); |
||||
|
return(OK); |
||||
|
case MOS9_CQGD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgd); |
||||
|
return(OK); |
||||
|
case MOS9_CAPGB: |
||||
|
value->rValue = 2* *(ckt->CKTstate0 + here->MOS9capgb); |
||||
|
/* add overlap capacitance */ |
||||
|
value->rValue += (here->MOS9modPtr->MOS9gateBulkOverlapCapFactor) |
||||
|
* here->MOS9m |
||||
|
* (here->MOS9l |
||||
|
+here->MOS9modPtr->MOS9lengthAdjust |
||||
|
-2*(here->MOS9modPtr->MOS9latDiff)); |
||||
|
return(OK); |
||||
|
case MOS9_QGB: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9qgb); |
||||
|
return(OK); |
||||
|
case MOS9_CQGB: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9cqgb); |
||||
|
return(OK); |
||||
|
case MOS9_QBD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9qbd); |
||||
|
return(OK); |
||||
|
case MOS9_CQBD: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9cqbd); |
||||
|
return(OK); |
||||
|
case MOS9_QBS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9qbs); |
||||
|
return(OK); |
||||
|
case MOS9_CQBS: |
||||
|
value->rValue = *(ckt->CKTstate0 + here->MOS9cqbs); |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_DC: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_REAL: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_IMAG: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_MAG: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
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->MOS9senParmNo); |
||||
|
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
value->rValue = (vr * sr + vi * si)/vm; |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_PH: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
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->MOS9senParmNo); |
||||
|
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
value->rValue = (vr * si - vi * sr)/vm; |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_L_SENS_CPLX: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->cValue.real= |
||||
|
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
value->cValue.imag= |
||||
|
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_DC: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_REAL: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_IMAG: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_MAG: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
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->MOS9senParmNo + here->MOS9sens_l); |
||||
|
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
value->rValue = (vr * sr + vi * si)/vm; |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_PH: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
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->MOS9senParmNo + here->MOS9sens_l); |
||||
|
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
value->rValue = (vr * si - vi * sr)/vm; |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_W_SENS_CPLX: |
||||
|
if(ckt->CKTsenInfo){ |
||||
|
value->cValue.real= |
||||
|
*(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
value->cValue.imag= |
||||
|
*(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
||||
|
here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_CB : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MOS9ask.c"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKCURRENT); |
||||
|
} else { |
||||
|
value->rValue = here->MOS9cbd + here->MOS9cbs - *(ckt->CKTstate0 |
||||
|
+ here->MOS9cqgb); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_CG : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MOS9ask.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->MOS9cqgb) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgd) + *(ckt->CKTstate0 + |
||||
|
here->MOS9cqgs); |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_CS : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MOS9ask.c"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKCURRENT); |
||||
|
} else { |
||||
|
value->rValue = -here->MOS9cd; |
||||
|
value->rValue -= here->MOS9cbd + here->MOS9cbs - |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgb); |
||||
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
||||
|
!(ckt->CKTmode & MODETRANOP)) { |
||||
|
value->rValue -= *(ckt->CKTstate0 + here->MOS9cqgb) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgd) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgs); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
case MOS9_POWER : |
||||
|
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
||||
|
errMsg = MALLOC(strlen(msg)+1); |
||||
|
errRtn = "MOS9ask.c"; |
||||
|
strcpy(errMsg,msg); |
||||
|
return(E_ASKPOWER); |
||||
|
} else { |
||||
|
double temp; |
||||
|
|
||||
|
value->rValue = here->MOS9cd * |
||||
|
*(ckt->CKTrhsOld + here->MOS9dNode); |
||||
|
value->rValue += (here->MOS9cbd + here->MOS9cbs - |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgb)) * |
||||
|
*(ckt->CKTrhsOld + here->MOS9bNode); |
||||
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
||||
|
!(ckt->CKTmode & MODETRANOP)) { |
||||
|
value->rValue += (*(ckt->CKTstate0 + here->MOS9cqgb) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgd) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgs)) * |
||||
|
*(ckt->CKTrhsOld + here->MOS9gNode); |
||||
|
} |
||||
|
temp = -here->MOS9cd; |
||||
|
temp -= here->MOS9cbd + here->MOS9cbs ; |
||||
|
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
||||
|
!(ckt->CKTmode & MODETRANOP)) { |
||||
|
temp -= *(ckt->CKTstate0 + here->MOS9cqgb) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgd) + |
||||
|
*(ckt->CKTstate0 + here->MOS9cqgs); |
||||
|
} |
||||
|
value->rValue += temp * *(ckt->CKTrhsOld + here->MOS9sNode); |
||||
|
} |
||||
|
return(OK); |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
|
|
||||
@ -1,104 +1,104 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
|
|
||||
#include "suffix.h" |
|
||||
|
|
||||
int |
|
||||
MOS9convTest(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
double delvbs; |
|
||||
double delvbd; |
|
||||
double delvgs; |
|
||||
double delvds; |
|
||||
double delvgd; |
|
||||
double cbhat; |
|
||||
double cdhat; |
|
||||
double vbs; |
|
||||
double vbd; |
|
||||
double vgs; |
|
||||
double vds; |
|
||||
double vgd; |
|
||||
double vgdo; |
|
||||
double tol; |
|
||||
|
|
||||
for( ; model != NULL; model = model->MOS9nextModel) { |
|
||||
for(here = model->MOS9instances; here!= NULL; |
|
||||
here = here->MOS9nextInstance) { |
|
||||
|
|
||||
vbs = model->MOS9type * ( |
|
||||
*(ckt->CKTrhs+here->MOS9bNode) - |
|
||||
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
|
||||
vgs = model->MOS9type * ( |
|
||||
*(ckt->CKTrhs+here->MOS9gNode) - |
|
||||
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
|
||||
vds = model->MOS9type * ( |
|
||||
*(ckt->CKTrhs+here->MOS9dNodePrime) - |
|
||||
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
|
||||
vbd=vbs-vds; |
|
||||
vgd=vgs-vds; |
|
||||
vgdo = *(ckt->CKTstate0 + here->MOS9vgs) - |
|
||||
*(ckt->CKTstate0 + here->MOS9vds); |
|
||||
delvbs = vbs - *(ckt->CKTstate0 + here->MOS9vbs); |
|
||||
delvbd = vbd - *(ckt->CKTstate0 + here->MOS9vbd); |
|
||||
delvgs = vgs - *(ckt->CKTstate0 + here->MOS9vgs); |
|
||||
delvds = vds - *(ckt->CKTstate0 + here->MOS9vds); |
|
||||
delvgd = vgd-vgdo; |
|
||||
|
|
||||
/* these are needed for convergence testing */ |
|
||||
|
|
||||
if (here->MOS9mode >= 0) { |
|
||||
cdhat= |
|
||||
here->MOS9cd- |
|
||||
here->MOS9gbd * delvbd + |
|
||||
here->MOS9gmbs * delvbs + |
|
||||
here->MOS9gm * delvgs + |
|
||||
here->MOS9gds * delvds ; |
|
||||
} else { |
|
||||
cdhat= |
|
||||
here->MOS9cd - |
|
||||
( here->MOS9gbd - |
|
||||
here->MOS9gmbs) * delvbd - |
|
||||
here->MOS9gm * delvgd + |
|
||||
here->MOS9gds * delvds ; |
|
||||
} |
|
||||
cbhat= |
|
||||
here->MOS9cbs + |
|
||||
here->MOS9cbd + |
|
||||
here->MOS9gbd * delvbd + |
|
||||
here->MOS9gbs * delvbs ; |
|
||||
/* |
|
||||
* check convergence |
|
||||
*/ |
|
||||
tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(here->MOS9cd))+ |
|
||||
ckt->CKTabstol; |
|
||||
if (fabs(cdhat-here->MOS9cd) >= tol) { |
|
||||
ckt->CKTnoncon++; |
|
||||
ckt->CKTtroubleElt = (GENinstance *) here; |
|
||||
return(OK); /* no reason to continue, we haven't converged */ |
|
||||
} else { |
|
||||
tol=ckt->CKTreltol* |
|
||||
MAX(fabs(cbhat),fabs(here->MOS9cbs+here->MOS9cbd)) |
|
||||
+ ckt->CKTabstol; |
|
||||
if (fabs(cbhat-(here->MOS9cbs+here->MOS9cbd)) > tol) { |
|
||||
ckt->CKTnoncon++; |
|
||||
ckt->CKTtroubleElt = (GENinstance *) here; |
|
||||
return(OK); /* no reason to continue, we haven't converged*/ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
|
||||
|
#include "suffix.h" |
||||
|
|
||||
|
int |
||||
|
MOS9convTest(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
double delvbs; |
||||
|
double delvbd; |
||||
|
double delvgs; |
||||
|
double delvds; |
||||
|
double delvgd; |
||||
|
double cbhat; |
||||
|
double cdhat; |
||||
|
double vbs; |
||||
|
double vbd; |
||||
|
double vgs; |
||||
|
double vds; |
||||
|
double vgd; |
||||
|
double vgdo; |
||||
|
double tol; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MOS9nextModel) { |
||||
|
for(here = model->MOS9instances; here!= NULL; |
||||
|
here = here->MOS9nextInstance) { |
||||
|
|
||||
|
vbs = model->MOS9type * ( |
||||
|
*(ckt->CKTrhs+here->MOS9bNode) - |
||||
|
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
||||
|
vgs = model->MOS9type * ( |
||||
|
*(ckt->CKTrhs+here->MOS9gNode) - |
||||
|
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
||||
|
vds = model->MOS9type * ( |
||||
|
*(ckt->CKTrhs+here->MOS9dNodePrime) - |
||||
|
*(ckt->CKTrhs+here->MOS9sNodePrime)); |
||||
|
vbd=vbs-vds; |
||||
|
vgd=vgs-vds; |
||||
|
vgdo = *(ckt->CKTstate0 + here->MOS9vgs) - |
||||
|
*(ckt->CKTstate0 + here->MOS9vds); |
||||
|
delvbs = vbs - *(ckt->CKTstate0 + here->MOS9vbs); |
||||
|
delvbd = vbd - *(ckt->CKTstate0 + here->MOS9vbd); |
||||
|
delvgs = vgs - *(ckt->CKTstate0 + here->MOS9vgs); |
||||
|
delvds = vds - *(ckt->CKTstate0 + here->MOS9vds); |
||||
|
delvgd = vgd-vgdo; |
||||
|
|
||||
|
/* these are needed for convergence testing */ |
||||
|
|
||||
|
if (here->MOS9mode >= 0) { |
||||
|
cdhat= |
||||
|
here->MOS9cd- |
||||
|
here->MOS9gbd * delvbd + |
||||
|
here->MOS9gmbs * delvbs + |
||||
|
here->MOS9gm * delvgs + |
||||
|
here->MOS9gds * delvds ; |
||||
|
} else { |
||||
|
cdhat= |
||||
|
here->MOS9cd - |
||||
|
( here->MOS9gbd - |
||||
|
here->MOS9gmbs) * delvbd - |
||||
|
here->MOS9gm * delvgd + |
||||
|
here->MOS9gds * delvds ; |
||||
|
} |
||||
|
cbhat= |
||||
|
here->MOS9cbs + |
||||
|
here->MOS9cbd + |
||||
|
here->MOS9gbd * delvbd + |
||||
|
here->MOS9gbs * delvbs ; |
||||
|
/* |
||||
|
* check convergence |
||||
|
*/ |
||||
|
tol=ckt->CKTreltol*MAX(fabs(cdhat),fabs(here->MOS9cd))+ |
||||
|
ckt->CKTabstol; |
||||
|
if (fabs(cdhat-here->MOS9cd) >= tol) { |
||||
|
ckt->CKTnoncon++; |
||||
|
ckt->CKTtroubleElt = (GENinstance *) here; |
||||
|
return(OK); /* no reason to continue, we haven't converged */ |
||||
|
} else { |
||||
|
tol=ckt->CKTreltol* |
||||
|
MAX(fabs(cbhat),fabs(here->MOS9cbs+here->MOS9cbd)) |
||||
|
+ ckt->CKTabstol; |
||||
|
if (fabs(cbhat-(here->MOS9cbs+here->MOS9cbd)) > tol) { |
||||
|
ckt->CKTnoncon++; |
||||
|
ckt->CKTtroubleElt = (GENinstance *) here; |
||||
|
return(OK); /* no reason to continue, we haven't converged*/ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
1116
src/spicelib/devices/mos9/mos9defs.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,39 +1,39 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h>
|
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9delete(inModel,name,inst) |
|
||||
GENmodel *inModel; |
|
||||
IFuid name; |
|
||||
GENinstance **inst; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance **fast = (MOS9instance **)inst; |
|
||||
MOS9instance **prev = NULL; |
|
||||
MOS9instance *here; |
|
||||
|
|
||||
for( ; model ; model = model->MOS9nextModel) { |
|
||||
prev = &(model->MOS9instances); |
|
||||
for(here = *prev; here ; here = *prev) { |
|
||||
if(here->MOS9name == name || (fast && here==*fast) ) { |
|
||||
*prev= here->MOS9nextInstance; |
|
||||
FREE(here); |
|
||||
return(OK); |
|
||||
} |
|
||||
prev = &(here->MOS9nextInstance); |
|
||||
} |
|
||||
} |
|
||||
return(E_NODEV); |
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9delete(inModel,name,inst) |
||||
|
GENmodel *inModel; |
||||
|
IFuid name; |
||||
|
GENinstance **inst; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance **fast = (MOS9instance **)inst; |
||||
|
MOS9instance **prev = NULL; |
||||
|
MOS9instance *here; |
||||
|
|
||||
|
for( ; model ; model = model->MOS9nextModel) { |
||||
|
prev = &(model->MOS9instances); |
||||
|
for(here = *prev; here ; here = *prev) { |
||||
|
if(here->MOS9name == name || (fast && here==*fast) ) { |
||||
|
*prev= here->MOS9nextInstance; |
||||
|
FREE(here); |
||||
|
return(OK); |
||||
|
} |
||||
|
prev = &(here->MOS9nextInstance); |
||||
|
} |
||||
|
} |
||||
|
return(E_NODEV); |
||||
|
} |
||||
@ -1,40 +1,40 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
Author: 1985 Thomas L. Quarles |
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h>
|
|
||||
#include "mos9defs.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
void |
|
||||
MOS9destroy(inModel) |
|
||||
GENmodel **inModel; |
|
||||
{ |
|
||||
MOS9model **model = (MOS9model **)inModel; |
|
||||
MOS9instance *here; |
|
||||
MOS9instance *prev = NULL; |
|
||||
MOS9model *mod = *model; |
|
||||
MOS9model *oldmod = NULL; |
|
||||
|
|
||||
for( ; mod ; mod = mod->MOS9nextModel) { |
|
||||
if(oldmod) FREE(oldmod); |
|
||||
oldmod = mod; |
|
||||
prev = (MOS9instance *)NULL; |
|
||||
for(here = mod->MOS9instances ; here ; here = here->MOS9nextInstance) { |
|
||||
if(prev){ |
|
||||
if(prev->MOS9sens) FREE(prev->MOS9sens); |
|
||||
FREE(prev); |
|
||||
} |
|
||||
prev = here; |
|
||||
} |
|
||||
if(prev) FREE(prev); |
|
||||
} |
|
||||
if(oldmod) FREE(oldmod); |
|
||||
*model = NULL; |
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mos9defs.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
void |
||||
|
MOS9destroy(inModel) |
||||
|
GENmodel **inModel; |
||||
|
{ |
||||
|
MOS9model **model = (MOS9model **)inModel; |
||||
|
MOS9instance *here; |
||||
|
MOS9instance *prev = NULL; |
||||
|
MOS9model *mod = *model; |
||||
|
MOS9model *oldmod = NULL; |
||||
|
|
||||
|
for( ; mod ; mod = mod->MOS9nextModel) { |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
oldmod = mod; |
||||
|
prev = (MOS9instance *)NULL; |
||||
|
for(here = mod->MOS9instances ; here ; here = here->MOS9nextInstance) { |
||||
|
if(prev){ |
||||
|
if(prev->MOS9sens) FREE(prev->MOS9sens); |
||||
|
FREE(prev); |
||||
|
} |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
} |
||||
|
if(oldmod) FREE(oldmod); |
||||
|
*model = NULL; |
||||
|
} |
||||
2770
src/spicelib/devices/mos9/mos9dist.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
1956
src/spicelib/devices/mos9/mos9dset.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,30 +1,30 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
extern int MOS9acLoad(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
|
||||
extern int MOS9convTest(GENmodel *,CKTcircuit *); |
|
||||
extern int MOS9delete(GENmodel*,IFuid,GENinstance**); |
|
||||
extern void MOS9destroy(GENmodel**); |
|
||||
extern int MOS9getic(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9load(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
|
||||
extern int MOS9mDelete(GENmodel**,IFuid,GENmodel*); |
|
||||
extern int MOS9mParam(int,IFvalue*,GENmodel*); |
|
||||
extern int MOS9param(int,IFvalue*,GENinstance*,IFvalue*); |
|
||||
extern int MOS9pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); |
|
||||
extern int MOS9sAcLoad(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9sLoad(GENmodel*,CKTcircuit*); |
|
||||
extern void MOS9sPrint(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9sSetup(SENstruct*,GENmodel*); |
|
||||
extern int MOS9sUpdate(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
|
||||
extern int MOS9unsetup(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9temp(GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9trunc(GENmodel*,CKTcircuit*,double*); |
|
||||
extern int MOS9disto(int,GENmodel*,CKTcircuit*); |
|
||||
extern int MOS9noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); |
|
||||
extern int MOS9dSetup(GENmodel*,CKTcircuit*); |
|
||||
|
**********/ |
||||
|
|
||||
|
extern int MOS9acLoad(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9ask(CKTcircuit*,GENinstance*,int,IFvalue*,IFvalue*); |
||||
|
extern int MOS9convTest(GENmodel *,CKTcircuit *); |
||||
|
extern int MOS9delete(GENmodel*,IFuid,GENinstance**); |
||||
|
extern void MOS9destroy(GENmodel**); |
||||
|
extern int MOS9getic(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9load(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
||||
|
extern int MOS9mDelete(GENmodel**,IFuid,GENmodel*); |
||||
|
extern int MOS9mParam(int,IFvalue*,GENmodel*); |
||||
|
extern int MOS9param(int,IFvalue*,GENinstance*,IFvalue*); |
||||
|
extern int MOS9pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); |
||||
|
extern int MOS9sAcLoad(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9sLoad(GENmodel*,CKTcircuit*); |
||||
|
extern void MOS9sPrint(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9sSetup(SENstruct*,GENmodel*); |
||||
|
extern int MOS9sUpdate(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
||||
|
extern int MOS9unsetup(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9temp(GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9trunc(GENmodel*,CKTcircuit*,double*); |
||||
|
extern int MOS9disto(int,GENmodel*,CKTcircuit*); |
||||
|
extern int MOS9noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); |
||||
|
extern int MOS9dSetup(GENmodel*,CKTcircuit*); |
||||
@ -1,49 +1,49 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9getic(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
/* |
|
||||
* grab initial conditions out of rhs array. User specified, so use |
|
||||
* external nodes to get values |
|
||||
*/ |
|
||||
|
|
||||
for( ; model ; model = model->MOS9nextModel) { |
|
||||
for(here = model->MOS9instances; here ; here = here->MOS9nextInstance) { |
|
||||
if(!here->MOS9icVBSGiven) { |
|
||||
here->MOS9icVBS = |
|
||||
*(ckt->CKTrhs + here->MOS9bNode) - |
|
||||
*(ckt->CKTrhs + here->MOS9sNode); |
|
||||
} |
|
||||
if(!here->MOS9icVDSGiven) { |
|
||||
here->MOS9icVDS = |
|
||||
*(ckt->CKTrhs + here->MOS9dNode) - |
|
||||
*(ckt->CKTrhs + here->MOS9sNode); |
|
||||
} |
|
||||
if(!here->MOS9icVGSGiven) { |
|
||||
here->MOS9icVGS = |
|
||||
*(ckt->CKTrhs + here->MOS9gNode) - |
|
||||
*(ckt->CKTrhs + here->MOS9sNode); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9getic(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
/* |
||||
|
* grab initial conditions out of rhs array. User specified, so use |
||||
|
* external nodes to get values |
||||
|
*/ |
||||
|
|
||||
|
for( ; model ; model = model->MOS9nextModel) { |
||||
|
for(here = model->MOS9instances; here ; here = here->MOS9nextInstance) { |
||||
|
if(!here->MOS9icVBSGiven) { |
||||
|
here->MOS9icVBS = |
||||
|
*(ckt->CKTrhs + here->MOS9bNode) - |
||||
|
*(ckt->CKTrhs + here->MOS9sNode); |
||||
|
} |
||||
|
if(!here->MOS9icVDSGiven) { |
||||
|
here->MOS9icVDS = |
||||
|
*(ckt->CKTrhs + here->MOS9dNode) - |
||||
|
*(ckt->CKTrhs + here->MOS9sNode); |
||||
|
} |
||||
|
if(!here->MOS9icVGSGiven) { |
||||
|
here->MOS9icVGS = |
||||
|
*(ckt->CKTrhs + here->MOS9gNode) - |
||||
|
*(ckt->CKTrhs + here->MOS9sNode); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -1,10 +1,10 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
**********/ |
|
||||
|
|
||||
#ifndef DEV_MOS9 |
|
||||
#define DEV_MOS9 |
|
||||
|
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
**********/ |
||||
|
|
||||
|
#ifndef DEV_MOS9 |
||||
|
#define DEV_MOS9 |
||||
|
|
||||
SPICEdev *get_mos9_info(void); |
SPICEdev *get_mos9_info(void); |
||||
|
|
||||
#endif |
#endif |
||||
2712
src/spicelib/devices/mos9/mos9load.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,171 +1,171 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1987 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1987 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "const.h" |
|
||||
#include "ifsim.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "devdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
/*ARGSUSED*/ |
|
||||
int |
|
||||
MOS9mAsk(ckt,inst,which,value) |
|
||||
CKTcircuit *ckt; |
|
||||
GENmodel *inst; |
|
||||
int which; |
|
||||
IFvalue *value; |
|
||||
{ |
|
||||
MOS9model *here = (MOS9model *)inst; |
|
||||
switch(which) { |
|
||||
case MOS9_MOD_TNOM: |
|
||||
value->rValue = here->MOS9tnom-CONSTCtoK; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_VTO: |
|
||||
value->rValue = here->MOS9vt0; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_KP: |
|
||||
value->rValue = here->MOS9transconductance; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_GAMMA: |
|
||||
value->rValue = here->MOS9gamma; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_PHI: |
|
||||
value->rValue = here->MOS9phi; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_RD: |
|
||||
value->rValue = here->MOS9drainResistance; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_RS: |
|
||||
value->rValue = here->MOS9sourceResistance; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CBD: |
|
||||
value->rValue = here->MOS9capBD; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CBS: |
|
||||
value->rValue = here->MOS9capBS; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_IS: |
|
||||
value->rValue = here->MOS9jctSatCur; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_PB: |
|
||||
value->rValue = here->MOS9bulkJctPotential; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CGSO: |
|
||||
value->rValue = here->MOS9gateSourceOverlapCapFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CGDO: |
|
||||
value->rValue = here->MOS9gateDrainOverlapCapFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CGBO: |
|
||||
value->rValue = here->MOS9gateBulkOverlapCapFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CJ: |
|
||||
value->rValue = here->MOS9bulkCapFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_MJ: |
|
||||
value->rValue = here->MOS9bulkJctBotGradingCoeff; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_CJSW: |
|
||||
value->rValue = here->MOS9sideWallCapFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_MJSW: |
|
||||
value->rValue = here->MOS9bulkJctSideGradingCoeff; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_JS: |
|
||||
value->rValue = here->MOS9jctSatCurDensity; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_TOX: |
|
||||
value->rValue = here->MOS9oxideThickness; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_LD: |
|
||||
value->rValue = here->MOS9latDiff; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_XL: |
|
||||
value->rValue = here->MOS9lengthAdjust; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_WD: |
|
||||
value->rValue = here->MOS9widthNarrow; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_XW: |
|
||||
value->rValue = here->MOS9widthAdjust; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_DELVTO: |
|
||||
value->rValue = here->MOS9delvt0; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_RSH: |
|
||||
value->rValue = here->MOS9sheetResistance; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_U0: |
|
||||
value->rValue = here->MOS9surfaceMobility; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_FC: |
|
||||
value->rValue = here->MOS9fwdCapDepCoeff; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_NSUB: |
|
||||
value->rValue = here->MOS9substrateDoping; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_TPG: |
|
||||
value->iValue = here->MOS9gateType; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_NSS: |
|
||||
value->rValue = here->MOS9surfaceStateDensity; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_NFS: |
|
||||
value->rValue = here->MOS9fastSurfaceStateDensity; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_DELTA: |
|
||||
value->rValue = here->MOS9narrowFactor; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_VMAX: |
|
||||
value->rValue = here->MOS9maxDriftVel; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_XJ: |
|
||||
value->rValue = here->MOS9junctionDepth; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_ETA: |
|
||||
value->rValue = here->MOS9eta; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_XD: |
|
||||
value->rValue = here->MOS9coeffDepLayWidth; |
|
||||
return(OK); |
|
||||
case MOS9_DELTA: |
|
||||
value->rValue = here->MOS9delta; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_THETA: |
|
||||
value->rValue = here->MOS9theta; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_ALPHA: |
|
||||
value->rValue = here->MOS9alpha; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_KAPPA: |
|
||||
value->rValue = here->MOS9kappa; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_KF: |
|
||||
value->rValue = here->MOS9fNcoef; |
|
||||
return(OK); |
|
||||
case MOS9_MOD_AF: |
|
||||
value->rValue = here->MOS9fNexp; |
|
||||
return(OK); |
|
||||
|
|
||||
case MOS9_MOD_TYPE: |
|
||||
if (here->MOS9type > 0) |
|
||||
value->sValue = "nmos"; |
|
||||
else |
|
||||
value->sValue = "pmos"; |
|
||||
return(OK); |
|
||||
default: |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
/* NOTREACHED */ |
|
||||
} |
|
||||
|
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "devdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/*ARGSUSED*/ |
||||
|
int |
||||
|
MOS9mAsk(ckt,inst,which,value) |
||||
|
CKTcircuit *ckt; |
||||
|
GENmodel *inst; |
||||
|
int which; |
||||
|
IFvalue *value; |
||||
|
{ |
||||
|
MOS9model *here = (MOS9model *)inst; |
||||
|
switch(which) { |
||||
|
case MOS9_MOD_TNOM: |
||||
|
value->rValue = here->MOS9tnom-CONSTCtoK; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_VTO: |
||||
|
value->rValue = here->MOS9vt0; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_KP: |
||||
|
value->rValue = here->MOS9transconductance; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_GAMMA: |
||||
|
value->rValue = here->MOS9gamma; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_PHI: |
||||
|
value->rValue = here->MOS9phi; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_RD: |
||||
|
value->rValue = here->MOS9drainResistance; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_RS: |
||||
|
value->rValue = here->MOS9sourceResistance; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CBD: |
||||
|
value->rValue = here->MOS9capBD; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CBS: |
||||
|
value->rValue = here->MOS9capBS; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_IS: |
||||
|
value->rValue = here->MOS9jctSatCur; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_PB: |
||||
|
value->rValue = here->MOS9bulkJctPotential; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CGSO: |
||||
|
value->rValue = here->MOS9gateSourceOverlapCapFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CGDO: |
||||
|
value->rValue = here->MOS9gateDrainOverlapCapFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CGBO: |
||||
|
value->rValue = here->MOS9gateBulkOverlapCapFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CJ: |
||||
|
value->rValue = here->MOS9bulkCapFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_MJ: |
||||
|
value->rValue = here->MOS9bulkJctBotGradingCoeff; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_CJSW: |
||||
|
value->rValue = here->MOS9sideWallCapFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_MJSW: |
||||
|
value->rValue = here->MOS9bulkJctSideGradingCoeff; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_JS: |
||||
|
value->rValue = here->MOS9jctSatCurDensity; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_TOX: |
||||
|
value->rValue = here->MOS9oxideThickness; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_LD: |
||||
|
value->rValue = here->MOS9latDiff; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_XL: |
||||
|
value->rValue = here->MOS9lengthAdjust; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_WD: |
||||
|
value->rValue = here->MOS9widthNarrow; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_XW: |
||||
|
value->rValue = here->MOS9widthAdjust; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_DELVTO: |
||||
|
value->rValue = here->MOS9delvt0; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_RSH: |
||||
|
value->rValue = here->MOS9sheetResistance; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_U0: |
||||
|
value->rValue = here->MOS9surfaceMobility; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_FC: |
||||
|
value->rValue = here->MOS9fwdCapDepCoeff; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_NSUB: |
||||
|
value->rValue = here->MOS9substrateDoping; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_TPG: |
||||
|
value->iValue = here->MOS9gateType; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_NSS: |
||||
|
value->rValue = here->MOS9surfaceStateDensity; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_NFS: |
||||
|
value->rValue = here->MOS9fastSurfaceStateDensity; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_DELTA: |
||||
|
value->rValue = here->MOS9narrowFactor; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_VMAX: |
||||
|
value->rValue = here->MOS9maxDriftVel; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_XJ: |
||||
|
value->rValue = here->MOS9junctionDepth; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_ETA: |
||||
|
value->rValue = here->MOS9eta; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_XD: |
||||
|
value->rValue = here->MOS9coeffDepLayWidth; |
||||
|
return(OK); |
||||
|
case MOS9_DELTA: |
||||
|
value->rValue = here->MOS9delta; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_THETA: |
||||
|
value->rValue = here->MOS9theta; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_ALPHA: |
||||
|
value->rValue = here->MOS9alpha; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_KAPPA: |
||||
|
value->rValue = here->MOS9kappa; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_KF: |
||||
|
value->rValue = here->MOS9fNcoef; |
||||
|
return(OK); |
||||
|
case MOS9_MOD_AF: |
||||
|
value->rValue = here->MOS9fNexp; |
||||
|
return(OK); |
||||
|
|
||||
|
case MOS9_MOD_TYPE: |
||||
|
if (here->MOS9type > 0) |
||||
|
value->sValue = "nmos"; |
||||
|
else |
||||
|
value->sValue = "pmos"; |
||||
|
return(OK); |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
/* NOTREACHED */ |
||||
|
} |
||||
|
|
||||
@ -1,45 +1,45 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h>
|
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9mDelete(inModel,modname,kill) |
|
||||
GENmodel **inModel; |
|
||||
IFuid modname; |
|
||||
GENmodel *kill; |
|
||||
{ |
|
||||
MOS9model **model = (MOS9model **)inModel; |
|
||||
MOS9model *modfast = (MOS9model *)kill; |
|
||||
MOS9instance *here; |
|
||||
MOS9instance *prev = NULL; |
|
||||
MOS9model **oldmod; |
|
||||
oldmod = model; |
|
||||
for( ; *model ; model = &((*model)->MOS9nextModel)) { |
|
||||
if( (*model)->MOS9modName == modname || |
|
||||
(modfast && *model == modfast) ) goto delgot; |
|
||||
oldmod = model; |
|
||||
} |
|
||||
return(E_NOMOD); |
|
||||
|
|
||||
delgot: |
|
||||
*oldmod = (*model)->MOS9nextModel; /* cut deleted device out of list */ |
|
||||
for(here = (*model)->MOS9instances ; here ; here = here->MOS9nextInstance) { |
|
||||
if(prev) FREE(prev); |
|
||||
prev = here; |
|
||||
} |
|
||||
if(prev) FREE(prev); |
|
||||
FREE(*model); |
|
||||
return(OK); |
|
||||
|
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9mDelete(inModel,modname,kill) |
||||
|
GENmodel **inModel; |
||||
|
IFuid modname; |
||||
|
GENmodel *kill; |
||||
|
{ |
||||
|
MOS9model **model = (MOS9model **)inModel; |
||||
|
MOS9model *modfast = (MOS9model *)kill; |
||||
|
MOS9instance *here; |
||||
|
MOS9instance *prev = NULL; |
||||
|
MOS9model **oldmod; |
||||
|
oldmod = model; |
||||
|
for( ; *model ; model = &((*model)->MOS9nextModel)) { |
||||
|
if( (*model)->MOS9modName == modname || |
||||
|
(modfast && *model == modfast) ) goto delgot; |
||||
|
oldmod = model; |
||||
|
} |
||||
|
return(E_NOMOD); |
||||
|
|
||||
|
delgot: |
||||
|
*oldmod = (*model)->MOS9nextModel; /* cut deleted device out of list */ |
||||
|
for(here = (*model)->MOS9instances ; here ; here = here->MOS9nextInstance) { |
||||
|
if(prev) FREE(prev); |
||||
|
prev = here; |
||||
|
} |
||||
|
if(prev) FREE(prev); |
||||
|
FREE(*model); |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
@ -1,202 +1,202 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "const.h" |
|
||||
#include "ifsim.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9mParam(param,value,inModel) |
|
||||
int param; |
|
||||
IFvalue *value; |
|
||||
GENmodel *inModel; |
|
||||
{ |
|
||||
register MOS9model *model = (MOS9model *)inModel; |
|
||||
switch(param) { |
|
||||
case MOS9_MOD_VTO: |
|
||||
model->MOS9vt0 = value->rValue; |
|
||||
model->MOS9vt0Given = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_KP: |
|
||||
model->MOS9transconductance = value->rValue; |
|
||||
model->MOS9transconductanceGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_GAMMA: |
|
||||
model->MOS9gamma = value->rValue; |
|
||||
model->MOS9gammaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_PHI: |
|
||||
model->MOS9phi = value->rValue; |
|
||||
model->MOS9phiGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_RD: |
|
||||
model->MOS9drainResistance = value->rValue; |
|
||||
model->MOS9drainResistanceGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_RS: |
|
||||
model->MOS9sourceResistance = value->rValue; |
|
||||
model->MOS9sourceResistanceGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CBD: |
|
||||
model->MOS9capBD = value->rValue; |
|
||||
model->MOS9capBDGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CBS: |
|
||||
model->MOS9capBS = value->rValue; |
|
||||
model->MOS9capBSGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_IS: |
|
||||
model->MOS9jctSatCur = value->rValue; |
|
||||
model->MOS9jctSatCurGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_PB: |
|
||||
model->MOS9bulkJctPotential = value->rValue; |
|
||||
model->MOS9bulkJctPotentialGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CGSO: |
|
||||
model->MOS9gateSourceOverlapCapFactor = value->rValue; |
|
||||
model->MOS9gateSourceOverlapCapFactorGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CGDO: |
|
||||
model->MOS9gateDrainOverlapCapFactor = value->rValue; |
|
||||
model->MOS9gateDrainOverlapCapFactorGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CGBO: |
|
||||
model->MOS9gateBulkOverlapCapFactor = value->rValue; |
|
||||
model->MOS9gateBulkOverlapCapFactorGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_RSH: |
|
||||
model->MOS9sheetResistance = value->rValue; |
|
||||
model->MOS9sheetResistanceGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CJ: |
|
||||
model->MOS9bulkCapFactor = value->rValue; |
|
||||
model->MOS9bulkCapFactorGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_MJ: |
|
||||
model->MOS9bulkJctBotGradingCoeff = value->rValue; |
|
||||
model->MOS9bulkJctBotGradingCoeffGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_CJSW: |
|
||||
model->MOS9sideWallCapFactor = value->rValue; |
|
||||
model->MOS9sideWallCapFactorGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_MJSW: |
|
||||
model->MOS9bulkJctSideGradingCoeff = value->rValue; |
|
||||
model->MOS9bulkJctSideGradingCoeffGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_JS: |
|
||||
model->MOS9jctSatCurDensity = value->rValue; |
|
||||
model->MOS9jctSatCurDensityGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_TOX: |
|
||||
model->MOS9oxideThickness = value->rValue; |
|
||||
model->MOS9oxideThicknessGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_LD: |
|
||||
model->MOS9latDiff = value->rValue; |
|
||||
model->MOS9latDiffGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_XL: |
|
||||
model->MOS9lengthAdjust = value->rValue; |
|
||||
model->MOS9lengthAdjustGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_WD: |
|
||||
model->MOS9widthNarrow = value->rValue; |
|
||||
model->MOS9widthNarrowGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_XW: |
|
||||
model->MOS9widthAdjust = value->rValue; |
|
||||
model->MOS9widthAdjustGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_DELVTO: |
|
||||
model->MOS9delvt0 = value->rValue; |
|
||||
model->MOS9delvt0Given = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_U0: |
|
||||
model->MOS9surfaceMobility = value->rValue; |
|
||||
model->MOS9surfaceMobilityGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_FC: |
|
||||
model->MOS9fwdCapDepCoeff = value->rValue; |
|
||||
model->MOS9fwdCapDepCoeffGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_NSUB: |
|
||||
model->MOS9substrateDoping = value->rValue; |
|
||||
model->MOS9substrateDopingGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_TPG: |
|
||||
model->MOS9gateType = value->iValue; |
|
||||
model->MOS9gateTypeGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_NSS: |
|
||||
model->MOS9surfaceStateDensity = value->rValue; |
|
||||
model->MOS9surfaceStateDensityGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_ETA: |
|
||||
model->MOS9eta = value->rValue; |
|
||||
model->MOS9etaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_DELTA: |
|
||||
model->MOS9delta = value->rValue; |
|
||||
model->MOS9deltaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_NFS: |
|
||||
model->MOS9fastSurfaceStateDensity = value->rValue; |
|
||||
model->MOS9fastSurfaceStateDensityGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_THETA: |
|
||||
model->MOS9theta = value->rValue; |
|
||||
model->MOS9thetaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_VMAX: |
|
||||
model->MOS9maxDriftVel = value->rValue; |
|
||||
model->MOS9maxDriftVelGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_KAPPA: |
|
||||
model->MOS9kappa = value->rValue; |
|
||||
model->MOS9kappaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_NMOS: |
|
||||
if(value->iValue) { |
|
||||
model->MOS9type = 1; |
|
||||
model->MOS9typeGiven = TRUE; |
|
||||
} |
|
||||
break; |
|
||||
case MOS9_MOD_PMOS: |
|
||||
if(value->iValue) { |
|
||||
model->MOS9type = -1; |
|
||||
model->MOS9typeGiven = TRUE; |
|
||||
} |
|
||||
break; |
|
||||
case MOS9_MOD_XJ: |
|
||||
model->MOS9junctionDepth = value->rValue; |
|
||||
model->MOS9junctionDepthGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_TNOM: |
|
||||
model->MOS9tnom = value->rValue+CONSTCtoK; |
|
||||
model->MOS9tnomGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_KF: |
|
||||
model->MOS9fNcoef = value->rValue; |
|
||||
model->MOS9fNcoefGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_MOD_AF: |
|
||||
model->MOS9fNexp = value->rValue; |
|
||||
model->MOS9fNexpGiven = TRUE; |
|
||||
break; |
|
||||
default: |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9mParam(param,value,inModel) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENmodel *inModel; |
||||
|
{ |
||||
|
register MOS9model *model = (MOS9model *)inModel; |
||||
|
switch(param) { |
||||
|
case MOS9_MOD_VTO: |
||||
|
model->MOS9vt0 = value->rValue; |
||||
|
model->MOS9vt0Given = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_KP: |
||||
|
model->MOS9transconductance = value->rValue; |
||||
|
model->MOS9transconductanceGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_GAMMA: |
||||
|
model->MOS9gamma = value->rValue; |
||||
|
model->MOS9gammaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_PHI: |
||||
|
model->MOS9phi = value->rValue; |
||||
|
model->MOS9phiGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_RD: |
||||
|
model->MOS9drainResistance = value->rValue; |
||||
|
model->MOS9drainResistanceGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_RS: |
||||
|
model->MOS9sourceResistance = value->rValue; |
||||
|
model->MOS9sourceResistanceGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CBD: |
||||
|
model->MOS9capBD = value->rValue; |
||||
|
model->MOS9capBDGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CBS: |
||||
|
model->MOS9capBS = value->rValue; |
||||
|
model->MOS9capBSGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_IS: |
||||
|
model->MOS9jctSatCur = value->rValue; |
||||
|
model->MOS9jctSatCurGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_PB: |
||||
|
model->MOS9bulkJctPotential = value->rValue; |
||||
|
model->MOS9bulkJctPotentialGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CGSO: |
||||
|
model->MOS9gateSourceOverlapCapFactor = value->rValue; |
||||
|
model->MOS9gateSourceOverlapCapFactorGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CGDO: |
||||
|
model->MOS9gateDrainOverlapCapFactor = value->rValue; |
||||
|
model->MOS9gateDrainOverlapCapFactorGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CGBO: |
||||
|
model->MOS9gateBulkOverlapCapFactor = value->rValue; |
||||
|
model->MOS9gateBulkOverlapCapFactorGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_RSH: |
||||
|
model->MOS9sheetResistance = value->rValue; |
||||
|
model->MOS9sheetResistanceGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CJ: |
||||
|
model->MOS9bulkCapFactor = value->rValue; |
||||
|
model->MOS9bulkCapFactorGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_MJ: |
||||
|
model->MOS9bulkJctBotGradingCoeff = value->rValue; |
||||
|
model->MOS9bulkJctBotGradingCoeffGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_CJSW: |
||||
|
model->MOS9sideWallCapFactor = value->rValue; |
||||
|
model->MOS9sideWallCapFactorGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_MJSW: |
||||
|
model->MOS9bulkJctSideGradingCoeff = value->rValue; |
||||
|
model->MOS9bulkJctSideGradingCoeffGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_JS: |
||||
|
model->MOS9jctSatCurDensity = value->rValue; |
||||
|
model->MOS9jctSatCurDensityGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_TOX: |
||||
|
model->MOS9oxideThickness = value->rValue; |
||||
|
model->MOS9oxideThicknessGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_LD: |
||||
|
model->MOS9latDiff = value->rValue; |
||||
|
model->MOS9latDiffGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_XL: |
||||
|
model->MOS9lengthAdjust = value->rValue; |
||||
|
model->MOS9lengthAdjustGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_WD: |
||||
|
model->MOS9widthNarrow = value->rValue; |
||||
|
model->MOS9widthNarrowGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_XW: |
||||
|
model->MOS9widthAdjust = value->rValue; |
||||
|
model->MOS9widthAdjustGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_DELVTO: |
||||
|
model->MOS9delvt0 = value->rValue; |
||||
|
model->MOS9delvt0Given = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_U0: |
||||
|
model->MOS9surfaceMobility = value->rValue; |
||||
|
model->MOS9surfaceMobilityGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_FC: |
||||
|
model->MOS9fwdCapDepCoeff = value->rValue; |
||||
|
model->MOS9fwdCapDepCoeffGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_NSUB: |
||||
|
model->MOS9substrateDoping = value->rValue; |
||||
|
model->MOS9substrateDopingGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_TPG: |
||||
|
model->MOS9gateType = value->iValue; |
||||
|
model->MOS9gateTypeGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_NSS: |
||||
|
model->MOS9surfaceStateDensity = value->rValue; |
||||
|
model->MOS9surfaceStateDensityGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_ETA: |
||||
|
model->MOS9eta = value->rValue; |
||||
|
model->MOS9etaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_DELTA: |
||||
|
model->MOS9delta = value->rValue; |
||||
|
model->MOS9deltaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_NFS: |
||||
|
model->MOS9fastSurfaceStateDensity = value->rValue; |
||||
|
model->MOS9fastSurfaceStateDensityGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_THETA: |
||||
|
model->MOS9theta = value->rValue; |
||||
|
model->MOS9thetaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_VMAX: |
||||
|
model->MOS9maxDriftVel = value->rValue; |
||||
|
model->MOS9maxDriftVelGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_KAPPA: |
||||
|
model->MOS9kappa = value->rValue; |
||||
|
model->MOS9kappaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_NMOS: |
||||
|
if(value->iValue) { |
||||
|
model->MOS9type = 1; |
||||
|
model->MOS9typeGiven = TRUE; |
||||
|
} |
||||
|
break; |
||||
|
case MOS9_MOD_PMOS: |
||||
|
if(value->iValue) { |
||||
|
model->MOS9type = -1; |
||||
|
model->MOS9typeGiven = TRUE; |
||||
|
} |
||||
|
break; |
||||
|
case MOS9_MOD_XJ: |
||||
|
model->MOS9junctionDepth = value->rValue; |
||||
|
model->MOS9junctionDepthGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_TNOM: |
||||
|
model->MOS9tnom = value->rValue+CONSTCtoK; |
||||
|
model->MOS9tnomGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_KF: |
||||
|
model->MOS9fNcoef = value->rValue; |
||||
|
model->MOS9fNcoefGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_MOD_AF: |
||||
|
model->MOS9fNexp = value->rValue; |
||||
|
model->MOS9fNexpGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -1,219 +1,219 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
Author: 1987 Gary W. Ng |
Author: 1987 Gary W. Ng |
||||
Modified: Alan Gillespie |
|
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "mos9defs.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "iferrmsg.h" |
|
||||
#include "noisedef.h"
|
|
||||
#include "suffix.h" |
|
||||
|
|
||||
/* |
|
||||
* MOS9noise (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 |
|
||||
MOS9noise (mode, operation, genmodel, ckt, data, OnDens) |
|
||||
int mode; |
|
||||
int operation; |
|
||||
GENmodel *genmodel; |
|
||||
CKTcircuit *ckt; |
|
||||
Ndata *data; |
|
||||
double *OnDens; |
|
||||
{ |
|
||||
MOS9model *firstModel = (MOS9model *) genmodel; |
|
||||
MOS9model *model; |
|
||||
MOS9instance *inst; |
|
||||
char name[N_MXVLNTH]; |
|
||||
double tempOnoise; |
|
||||
double tempInoise; |
|
||||
double noizDens[MOS9NSRCS]; |
|
||||
double lnNdens[MOS9NSRCS]; |
|
||||
int error; |
|
||||
int i; |
|
||||
|
|
||||
/* define the names of the noise sources */ |
|
||||
|
|
||||
static char *MOS9nNames[MOS9NSRCS] = { /* Note that we have to keep the order */ |
|
||||
"_rd", /* noise due to rd */ /* consistent with the index definitions */ |
|
||||
"_rs", /* noise due to rs */ /* in MOS9defs.h */ |
|
||||
"_id", /* noise due to id */ |
|
||||
"_1overf", /* flicker (1/f) noise */ |
|
||||
"" /* total transistor noise */ |
|
||||
}; |
|
||||
|
|
||||
for (model=firstModel; model != NULL; model=model->MOS9nextModel) { |
|
||||
for (inst=model->MOS9instances; inst != NULL; inst=inst->MOS9nextInstance) { |
|
||||
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 < MOS9NSRCS; i++) { |
|
||||
(void)sprintf(name,"onoise_%s%s",inst->MOS9name,MOS9nNames[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 < MOS9NSRCS; i++) { |
|
||||
(void)sprintf(name,"onoise_total_%s%s",inst->MOS9name,MOS9nNames[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->MOS9name,MOS9nNames[i]); |
|
||||
|
|
||||
|
|
||||
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); |
|
||||
if (!data->namelist) return(E_NOMEM); |
|
||||
(*(SPfrontEnd->IFnewUid))(ckt, |
|
||||
&(data->namelist[data->numPlots++]), |
|
||||
(IFuid)NULL,name,UID_OTHER,(void **)NULL); |
|
||||
/* we've added one more plot */ |
|
||||
|
|
||||
|
|
||||
|
|
||||
} |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
break; |
|
||||
|
|
||||
case N_CALC: |
|
||||
switch (mode) { |
|
||||
|
|
||||
case N_DENS: |
|
||||
NevalSrc(&noizDens[MOS9RDNOIZ],&lnNdens[MOS9RDNOIZ], |
|
||||
ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9dNode, |
|
||||
inst->MOS9drainConductance); |
|
||||
|
|
||||
NevalSrc(&noizDens[MOS9RSNOIZ],&lnNdens[MOS9RSNOIZ], |
|
||||
ckt,THERMNOISE,inst->MOS9sNodePrime,inst->MOS9sNode, |
|
||||
inst->MOS9sourceConductance); |
|
||||
|
|
||||
NevalSrc(&noizDens[MOS9IDNOIZ],&lnNdens[MOS9IDNOIZ], |
|
||||
ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9sNodePrime, |
|
||||
(2.0/3.0 * fabs(inst->MOS9gm))); |
|
||||
|
|
||||
NevalSrc(&noizDens[MOS9FLNOIZ],(double*)NULL,ckt, |
|
||||
N_GAIN,inst->MOS9dNodePrime, inst->MOS9sNodePrime, |
|
||||
(double)0.0); |
|
||||
noizDens[MOS9FLNOIZ] *= model->MOS9fNcoef * |
|
||||
exp(model->MOS9fNexp * |
|
||||
log(MAX(fabs(inst->MOS9cd),N_MINLOG))) / |
|
||||
(data->freq * |
|
||||
(inst->MOS9w - 2*model->MOS9widthNarrow) * |
|
||||
inst->MOS9m * |
|
||||
(inst->MOS9l - 2*model->MOS9latDiff) * |
|
||||
model->MOS9oxideCapFactor * model->MOS9oxideCapFactor); |
|
||||
lnNdens[MOS9FLNOIZ] = |
|
||||
log(MAX(noizDens[MOS9FLNOIZ],N_MINLOG)); |
|
||||
|
|
||||
noizDens[MOS9TOTNOIZ] = noizDens[MOS9RDNOIZ] + |
|
||||
noizDens[MOS9RSNOIZ] + |
|
||||
noizDens[MOS9IDNOIZ] + |
|
||||
noizDens[MOS9FLNOIZ]; |
|
||||
lnNdens[MOS9TOTNOIZ] = |
|
||||
log(MAX(noizDens[MOS9TOTNOIZ], N_MINLOG)); |
|
||||
|
|
||||
*OnDens += noizDens[MOS9TOTNOIZ]; |
|
||||
|
|
||||
if (data->delFreq == 0.0) { |
|
||||
|
|
||||
/* if we haven't done any previous integration, we need to */ |
|
||||
/* initialize our "history" variables */ |
|
||||
|
|
||||
for (i=0; i < MOS9NSRCS; i++) { |
|
||||
inst->MOS9nVar[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 < MOS9NSRCS; i++) { |
|
||||
inst->MOS9nVar[OUTNOIZ][i] = 0.0; |
|
||||
inst->MOS9nVar[INNOIZ][i] = 0.0; |
|
||||
} |
|
||||
} |
|
||||
} else { /* data->delFreq != 0.0 (we have to integrate) */ |
|
||||
for (i=0; i < MOS9NSRCS; i++) { |
|
||||
if (i != MOS9TOTNOIZ) { |
|
||||
tempOnoise = Nintegrate(noizDens[i], lnNdens[i], |
|
||||
inst->MOS9nVar[LNLSTDENS][i], data); |
|
||||
tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , |
|
||||
lnNdens[i] + data->lnGainInv, |
|
||||
inst->MOS9nVar[LNLSTDENS][i] + data->lnGainInv, |
|
||||
data); |
|
||||
inst->MOS9nVar[LNLSTDENS][i] = lnNdens[i]; |
|
||||
data->outNoiz += tempOnoise; |
|
||||
data->inNoise += tempInoise; |
|
||||
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { |
|
||||
inst->MOS9nVar[OUTNOIZ][i] += tempOnoise; |
|
||||
inst->MOS9nVar[OUTNOIZ][MOS9TOTNOIZ] += tempOnoise; |
|
||||
inst->MOS9nVar[INNOIZ][i] += tempInoise; |
|
||||
inst->MOS9nVar[INNOIZ][MOS9TOTNOIZ] += tempInoise; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
if (data->prtSummary) { |
|
||||
for (i=0; i < MOS9NSRCS; 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 < MOS9NSRCS; i++) { |
|
||||
data->outpVector[data->outNumber++] = inst->MOS9nVar[OUTNOIZ][i]; |
|
||||
data->outpVector[data->outNumber++] = inst->MOS9nVar[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); |
|
||||
} |
|
||||
|
Modified: Alan Gillespie |
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "mos9defs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "iferrmsg.h" |
||||
|
#include "noisedef.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
/* |
||||
|
* MOS9noise (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 |
||||
|
MOS9noise (mode, operation, genmodel, ckt, data, OnDens) |
||||
|
int mode; |
||||
|
int operation; |
||||
|
GENmodel *genmodel; |
||||
|
CKTcircuit *ckt; |
||||
|
Ndata *data; |
||||
|
double *OnDens; |
||||
|
{ |
||||
|
MOS9model *firstModel = (MOS9model *) genmodel; |
||||
|
MOS9model *model; |
||||
|
MOS9instance *inst; |
||||
|
char name[N_MXVLNTH]; |
||||
|
double tempOnoise; |
||||
|
double tempInoise; |
||||
|
double noizDens[MOS9NSRCS]; |
||||
|
double lnNdens[MOS9NSRCS]; |
||||
|
int error; |
||||
|
int i; |
||||
|
|
||||
|
/* define the names of the noise sources */ |
||||
|
|
||||
|
static char *MOS9nNames[MOS9NSRCS] = { /* Note that we have to keep the order */ |
||||
|
"_rd", /* noise due to rd */ /* consistent with the index definitions */ |
||||
|
"_rs", /* noise due to rs */ /* in MOS9defs.h */ |
||||
|
"_id", /* noise due to id */ |
||||
|
"_1overf", /* flicker (1/f) noise */ |
||||
|
"" /* total transistor noise */ |
||||
|
}; |
||||
|
|
||||
|
for (model=firstModel; model != NULL; model=model->MOS9nextModel) { |
||||
|
for (inst=model->MOS9instances; inst != NULL; inst=inst->MOS9nextInstance) { |
||||
|
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 < MOS9NSRCS; i++) { |
||||
|
(void)sprintf(name,"onoise_%s%s",inst->MOS9name,MOS9nNames[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 < MOS9NSRCS; i++) { |
||||
|
(void)sprintf(name,"onoise_total_%s%s",inst->MOS9name,MOS9nNames[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->MOS9name,MOS9nNames[i]); |
||||
|
|
||||
|
|
||||
|
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid)); |
||||
|
if (!data->namelist) return(E_NOMEM); |
||||
|
(*(SPfrontEnd->IFnewUid))(ckt, |
||||
|
&(data->namelist[data->numPlots++]), |
||||
|
(IFuid)NULL,name,UID_OTHER,(void **)NULL); |
||||
|
/* we've added one more plot */ |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
break; |
||||
|
|
||||
|
case N_CALC: |
||||
|
switch (mode) { |
||||
|
|
||||
|
case N_DENS: |
||||
|
NevalSrc(&noizDens[MOS9RDNOIZ],&lnNdens[MOS9RDNOIZ], |
||||
|
ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9dNode, |
||||
|
inst->MOS9drainConductance); |
||||
|
|
||||
|
NevalSrc(&noizDens[MOS9RSNOIZ],&lnNdens[MOS9RSNOIZ], |
||||
|
ckt,THERMNOISE,inst->MOS9sNodePrime,inst->MOS9sNode, |
||||
|
inst->MOS9sourceConductance); |
||||
|
|
||||
|
NevalSrc(&noizDens[MOS9IDNOIZ],&lnNdens[MOS9IDNOIZ], |
||||
|
ckt,THERMNOISE,inst->MOS9dNodePrime,inst->MOS9sNodePrime, |
||||
|
(2.0/3.0 * fabs(inst->MOS9gm))); |
||||
|
|
||||
|
NevalSrc(&noizDens[MOS9FLNOIZ],(double*)NULL,ckt, |
||||
|
N_GAIN,inst->MOS9dNodePrime, inst->MOS9sNodePrime, |
||||
|
(double)0.0); |
||||
|
noizDens[MOS9FLNOIZ] *= model->MOS9fNcoef * |
||||
|
exp(model->MOS9fNexp * |
||||
|
log(MAX(fabs(inst->MOS9cd),N_MINLOG))) / |
||||
|
(data->freq * |
||||
|
(inst->MOS9w - 2*model->MOS9widthNarrow) * |
||||
|
inst->MOS9m * |
||||
|
(inst->MOS9l - 2*model->MOS9latDiff) * |
||||
|
model->MOS9oxideCapFactor * model->MOS9oxideCapFactor); |
||||
|
lnNdens[MOS9FLNOIZ] = |
||||
|
log(MAX(noizDens[MOS9FLNOIZ],N_MINLOG)); |
||||
|
|
||||
|
noizDens[MOS9TOTNOIZ] = noizDens[MOS9RDNOIZ] + |
||||
|
noizDens[MOS9RSNOIZ] + |
||||
|
noizDens[MOS9IDNOIZ] + |
||||
|
noizDens[MOS9FLNOIZ]; |
||||
|
lnNdens[MOS9TOTNOIZ] = |
||||
|
log(MAX(noizDens[MOS9TOTNOIZ], N_MINLOG)); |
||||
|
|
||||
|
*OnDens += noizDens[MOS9TOTNOIZ]; |
||||
|
|
||||
|
if (data->delFreq == 0.0) { |
||||
|
|
||||
|
/* if we haven't done any previous integration, we need to */ |
||||
|
/* initialize our "history" variables */ |
||||
|
|
||||
|
for (i=0; i < MOS9NSRCS; i++) { |
||||
|
inst->MOS9nVar[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 < MOS9NSRCS; i++) { |
||||
|
inst->MOS9nVar[OUTNOIZ][i] = 0.0; |
||||
|
inst->MOS9nVar[INNOIZ][i] = 0.0; |
||||
|
} |
||||
|
} |
||||
|
} else { /* data->delFreq != 0.0 (we have to integrate) */ |
||||
|
for (i=0; i < MOS9NSRCS; i++) { |
||||
|
if (i != MOS9TOTNOIZ) { |
||||
|
tempOnoise = Nintegrate(noizDens[i], lnNdens[i], |
||||
|
inst->MOS9nVar[LNLSTDENS][i], data); |
||||
|
tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , |
||||
|
lnNdens[i] + data->lnGainInv, |
||||
|
inst->MOS9nVar[LNLSTDENS][i] + data->lnGainInv, |
||||
|
data); |
||||
|
inst->MOS9nVar[LNLSTDENS][i] = lnNdens[i]; |
||||
|
data->outNoiz += tempOnoise; |
||||
|
data->inNoise += tempInoise; |
||||
|
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { |
||||
|
inst->MOS9nVar[OUTNOIZ][i] += tempOnoise; |
||||
|
inst->MOS9nVar[OUTNOIZ][MOS9TOTNOIZ] += tempOnoise; |
||||
|
inst->MOS9nVar[INNOIZ][i] += tempInoise; |
||||
|
inst->MOS9nVar[INNOIZ][MOS9TOTNOIZ] += tempInoise; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if (data->prtSummary) { |
||||
|
for (i=0; i < MOS9NSRCS; 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 < MOS9NSRCS; i++) { |
||||
|
data->outpVector[data->outNumber++] = inst->MOS9nVar[OUTNOIZ][i]; |
||||
|
data->outpVector[data->outNumber++] = inst->MOS9nVar[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); |
||||
|
} |
||||
@ -1,116 +1,116 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "const.h" |
|
||||
#include "ifsim.h"
|
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
/* ARGSUSED */ |
|
||||
int |
|
||||
MOS9param(param,value,inst,select) |
|
||||
int param; |
|
||||
IFvalue *value; |
|
||||
GENinstance *inst; |
|
||||
IFvalue *select; |
|
||||
{ |
|
||||
MOS9instance *here = (MOS9instance *)inst; |
|
||||
switch(param) { |
|
||||
|
|
||||
case MOS9_M: |
|
||||
here->MOS9m = value->rValue; |
|
||||
here->MOS9mGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_W: |
|
||||
here->MOS9w = value->rValue; |
|
||||
here->MOS9wGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_L: |
|
||||
here->MOS9l = value->rValue; |
|
||||
here->MOS9lGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_AS: |
|
||||
here->MOS9sourceArea = value->rValue; |
|
||||
here->MOS9sourceAreaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_AD: |
|
||||
here->MOS9drainArea = value->rValue; |
|
||||
here->MOS9drainAreaGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_PS: |
|
||||
here->MOS9sourcePerimiter = value->rValue; |
|
||||
here->MOS9sourcePerimiterGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_PD: |
|
||||
here->MOS9drainPerimiter = value->rValue; |
|
||||
here->MOS9drainPerimiterGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_NRS: |
|
||||
here->MOS9sourceSquares = value->rValue; |
|
||||
here->MOS9sourceSquaresGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_NRD: |
|
||||
here->MOS9drainSquares = value->rValue; |
|
||||
here->MOS9drainSquaresGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_OFF: |
|
||||
here->MOS9off = value->iValue; |
|
||||
break; |
|
||||
case MOS9_IC_VBS: |
|
||||
here->MOS9icVBS = value->rValue; |
|
||||
here->MOS9icVBSGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_IC_VDS: |
|
||||
here->MOS9icVDS = value->rValue; |
|
||||
here->MOS9icVDSGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_IC_VGS: |
|
||||
here->MOS9icVGS = value->rValue; |
|
||||
here->MOS9icVGSGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_TEMP: |
|
||||
here->MOS9temp = value->rValue+CONSTCtoK; |
|
||||
here->MOS9tempGiven = TRUE; |
|
||||
break; |
|
||||
case MOS9_IC: |
|
||||
switch(value->v.numValue){ |
|
||||
case 3: |
|
||||
here->MOS9icVBS = *(value->v.vec.rVec+2); |
|
||||
here->MOS9icVBSGiven = TRUE; |
|
||||
case 2: |
|
||||
here->MOS9icVGS = *(value->v.vec.rVec+1); |
|
||||
here->MOS9icVGSGiven = TRUE; |
|
||||
case 1: |
|
||||
here->MOS9icVDS = *(value->v.vec.rVec); |
|
||||
here->MOS9icVDSGiven = TRUE; |
|
||||
break; |
|
||||
default: |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
break; |
|
||||
case MOS9_L_SENS: |
|
||||
if(value->iValue) { |
|
||||
here->MOS9senParmNo = 1; |
|
||||
here->MOS9sens_l = 1; |
|
||||
} |
|
||||
break; |
|
||||
case MOS9_W_SENS: |
|
||||
if(value->iValue) { |
|
||||
here->MOS9senParmNo = 1; |
|
||||
here->MOS9sens_w = 1; |
|
||||
} |
|
||||
break; |
|
||||
default: |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "const.h" |
||||
|
#include "ifsim.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
/* ARGSUSED */ |
||||
|
int |
||||
|
MOS9param(param,value,inst,select) |
||||
|
int param; |
||||
|
IFvalue *value; |
||||
|
GENinstance *inst; |
||||
|
IFvalue *select; |
||||
|
{ |
||||
|
MOS9instance *here = (MOS9instance *)inst; |
||||
|
switch(param) { |
||||
|
|
||||
|
case MOS9_M: |
||||
|
here->MOS9m = value->rValue; |
||||
|
here->MOS9mGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_W: |
||||
|
here->MOS9w = value->rValue; |
||||
|
here->MOS9wGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_L: |
||||
|
here->MOS9l = value->rValue; |
||||
|
here->MOS9lGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_AS: |
||||
|
here->MOS9sourceArea = value->rValue; |
||||
|
here->MOS9sourceAreaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_AD: |
||||
|
here->MOS9drainArea = value->rValue; |
||||
|
here->MOS9drainAreaGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_PS: |
||||
|
here->MOS9sourcePerimiter = value->rValue; |
||||
|
here->MOS9sourcePerimiterGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_PD: |
||||
|
here->MOS9drainPerimiter = value->rValue; |
||||
|
here->MOS9drainPerimiterGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_NRS: |
||||
|
here->MOS9sourceSquares = value->rValue; |
||||
|
here->MOS9sourceSquaresGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_NRD: |
||||
|
here->MOS9drainSquares = value->rValue; |
||||
|
here->MOS9drainSquaresGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_OFF: |
||||
|
here->MOS9off = value->iValue; |
||||
|
break; |
||||
|
case MOS9_IC_VBS: |
||||
|
here->MOS9icVBS = value->rValue; |
||||
|
here->MOS9icVBSGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_IC_VDS: |
||||
|
here->MOS9icVDS = value->rValue; |
||||
|
here->MOS9icVDSGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_IC_VGS: |
||||
|
here->MOS9icVGS = value->rValue; |
||||
|
here->MOS9icVGSGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_TEMP: |
||||
|
here->MOS9temp = value->rValue+CONSTCtoK; |
||||
|
here->MOS9tempGiven = TRUE; |
||||
|
break; |
||||
|
case MOS9_IC: |
||||
|
switch(value->v.numValue){ |
||||
|
case 3: |
||||
|
here->MOS9icVBS = *(value->v.vec.rVec+2); |
||||
|
here->MOS9icVBSGiven = TRUE; |
||||
|
case 2: |
||||
|
here->MOS9icVGS = *(value->v.vec.rVec+1); |
||||
|
here->MOS9icVGSGiven = TRUE; |
||||
|
case 1: |
||||
|
here->MOS9icVDS = *(value->v.vec.rVec); |
||||
|
here->MOS9icVDSGiven = TRUE; |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
break; |
||||
|
case MOS9_L_SENS: |
||||
|
if(value->iValue) { |
||||
|
here->MOS9senParmNo = 1; |
||||
|
here->MOS9sens_l = 1; |
||||
|
} |
||||
|
break; |
||||
|
case MOS9_W_SENS: |
||||
|
if(value->iValue) { |
||||
|
here->MOS9senParmNo = 1; |
||||
|
here->MOS9sens_w = 1; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -1,141 +1,141 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
/* |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "complex.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
|
|
||||
int |
|
||||
MOS9pzLoad(inModel,ckt,s) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
SPcomplex *s; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
int xnrm; |
|
||||
int xrev; |
|
||||
double xgs; |
|
||||
double xgd; |
|
||||
double xgb; |
|
||||
double xbd; |
|
||||
double xbs; |
|
||||
double capgs; |
|
||||
double capgd; |
|
||||
double capgb; |
|
||||
double GateBulkOverlapCap; |
|
||||
double GateDrainOverlapCap; |
|
||||
double GateSourceOverlapCap; |
|
||||
double EffectiveLength; |
|
||||
double EffectiveWidth; |
|
||||
|
|
||||
for( ; model != NULL; model = model->MOS9nextModel) { |
|
||||
for(here = model->MOS9instances; here!= NULL; |
|
||||
here = here->MOS9nextInstance) { |
|
||||
|
|
||||
if (here->MOS9mode < 0) { |
|
||||
xnrm=0; |
|
||||
xrev=1; |
|
||||
} else { |
|
||||
xnrm=1; |
|
||||
xrev=0; |
|
||||
} |
|
||||
/* |
|
||||
* meyer's model parameters |
|
||||
*/ |
|
||||
|
|
||||
EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ |
|
||||
model->MOS9widthAdjust; |
|
||||
EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ |
|
||||
model->MOS9lengthAdjust; |
|
||||
|
|
||||
GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveWidth; |
|
||||
GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveWidth; |
|
||||
GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * |
|
||||
here->MOS9m * EffectiveLength; |
|
||||
|
**********/ |
||||
|
/* |
||||
|
*/ |
||||
|
|
||||
capgs = ( 2* *(ckt->CKTstate0+here->MOS9capgs)+ |
|
||||
GateSourceOverlapCap ); |
|
||||
capgd = ( 2* *(ckt->CKTstate0+here->MOS9capgd)+ |
|
||||
GateDrainOverlapCap ); |
|
||||
capgb = ( 2* *(ckt->CKTstate0+here->MOS9capgb)+ |
|
||||
GateBulkOverlapCap ); |
|
||||
xgs = capgs; |
|
||||
xgd = capgd; |
|
||||
xgb = capgb; |
|
||||
xbd = here->MOS9capbd; |
|
||||
xbs = here->MOS9capbs; |
|
||||
/*printf("mos2: xgs=%g, xgd=%g, xgb=%g, xbd=%g, xbs=%g\n", |
|
||||
xgs,xgd,xgb,xbd,xbs);*/ |
|
||||
/* |
|
||||
* load matrix |
|
||||
*/ |
|
||||
|
|
||||
*(here->MOS9GgPtr ) += (xgd+xgs+xgb)*s->real; |
|
||||
*(here->MOS9GgPtr +1) += (xgd+xgs+xgb)*s->imag; |
|
||||
*(here->MOS9BbPtr ) += (xgb+xbd+xbs)*s->real; |
|
||||
*(here->MOS9BbPtr +1) += (xgb+xbd+xbs)*s->imag; |
|
||||
*(here->MOS9DPdpPtr ) += (xgd+xbd)*s->real; |
|
||||
*(here->MOS9DPdpPtr +1) += (xgd+xbd)*s->imag; |
|
||||
*(here->MOS9SPspPtr ) += (xgs+xbs)*s->real; |
|
||||
*(here->MOS9SPspPtr +1) += (xgs+xbs)*s->imag; |
|
||||
*(here->MOS9GbPtr ) -= xgb*s->real; |
|
||||
*(here->MOS9GbPtr +1) -= xgb*s->imag; |
|
||||
*(here->MOS9GdpPtr ) -= xgd*s->real; |
|
||||
*(here->MOS9GdpPtr +1) -= xgd*s->imag; |
|
||||
*(here->MOS9GspPtr ) -= xgs*s->real; |
|
||||
*(here->MOS9GspPtr +1) -= xgs*s->imag; |
|
||||
*(here->MOS9BgPtr ) -= xgb*s->real; |
|
||||
*(here->MOS9BgPtr +1) -= xgb*s->imag; |
|
||||
*(here->MOS9BdpPtr ) -= xbd*s->real; |
|
||||
*(here->MOS9BdpPtr +1) -= xbd*s->imag; |
|
||||
*(here->MOS9BspPtr ) -= xbs*s->real; |
|
||||
*(here->MOS9BspPtr +1) -= xbs*s->imag; |
|
||||
*(here->MOS9DPgPtr ) -= xgd*s->real; |
|
||||
*(here->MOS9DPgPtr +1) -= xgd*s->imag; |
|
||||
*(here->MOS9DPbPtr ) -= xbd*s->real; |
|
||||
*(here->MOS9DPbPtr +1) -= xbd*s->imag; |
|
||||
*(here->MOS9SPgPtr ) -= xgs*s->real; |
|
||||
*(here->MOS9SPgPtr +1) -= xgs*s->imag; |
|
||||
*(here->MOS9SPbPtr ) -= xbs*s->real; |
|
||||
*(here->MOS9SPbPtr +1) -= xbs*s->imag; |
|
||||
*(here->MOS9DdPtr) += here->MOS9drainConductance; |
|
||||
*(here->MOS9SsPtr) += here->MOS9sourceConductance; |
|
||||
*(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; |
|
||||
*(here->MOS9DPdpPtr) += here->MOS9drainConductance+ |
|
||||
here->MOS9gds+here->MOS9gbd+ |
|
||||
xrev*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9SPspPtr) += here->MOS9sourceConductance+ |
|
||||
here->MOS9gds+here->MOS9gbs+ |
|
||||
xnrm*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9DdpPtr) -= here->MOS9drainConductance; |
|
||||
*(here->MOS9SspPtr) -= here->MOS9sourceConductance; |
|
||||
*(here->MOS9BdpPtr) -= here->MOS9gbd; |
|
||||
*(here->MOS9BspPtr) -= here->MOS9gbs; |
|
||||
*(here->MOS9DPdPtr) -= here->MOS9drainConductance; |
|
||||
*(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; |
|
||||
*(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; |
|
||||
*(here->MOS9DPspPtr) -= here->MOS9gds+ |
|
||||
xnrm*(here->MOS9gm+here->MOS9gmbs); |
|
||||
*(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; |
|
||||
*(here->MOS9SPsPtr) -= here->MOS9sourceConductance; |
|
||||
*(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; |
|
||||
*(here->MOS9SPdpPtr) -= here->MOS9gds+ |
|
||||
xrev*(here->MOS9gm+here->MOS9gmbs); |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "complex.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
|
||||
|
int |
||||
|
MOS9pzLoad(inModel,ckt,s) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
SPcomplex *s; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
int xnrm; |
||||
|
int xrev; |
||||
|
double xgs; |
||||
|
double xgd; |
||||
|
double xgb; |
||||
|
double xbd; |
||||
|
double xbs; |
||||
|
double capgs; |
||||
|
double capgd; |
||||
|
double capgb; |
||||
|
double GateBulkOverlapCap; |
||||
|
double GateDrainOverlapCap; |
||||
|
double GateSourceOverlapCap; |
||||
|
double EffectiveLength; |
||||
|
double EffectiveWidth; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MOS9nextModel) { |
||||
|
for(here = model->MOS9instances; here!= NULL; |
||||
|
here = here->MOS9nextInstance) { |
||||
|
|
||||
|
if (here->MOS9mode < 0) { |
||||
|
xnrm=0; |
||||
|
xrev=1; |
||||
|
} else { |
||||
|
xnrm=1; |
||||
|
xrev=0; |
||||
|
} |
||||
|
/* |
||||
|
* meyer's model parameters |
||||
|
*/ |
||||
|
|
||||
|
EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ |
||||
|
model->MOS9widthAdjust; |
||||
|
EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ |
||||
|
model->MOS9lengthAdjust; |
||||
|
|
||||
|
GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveWidth; |
||||
|
GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveWidth; |
||||
|
GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * |
||||
|
here->MOS9m * EffectiveLength; |
||||
|
|
||||
|
capgs = ( 2* *(ckt->CKTstate0+here->MOS9capgs)+ |
||||
|
GateSourceOverlapCap ); |
||||
|
capgd = ( 2* *(ckt->CKTstate0+here->MOS9capgd)+ |
||||
|
GateDrainOverlapCap ); |
||||
|
capgb = ( 2* *(ckt->CKTstate0+here->MOS9capgb)+ |
||||
|
GateBulkOverlapCap ); |
||||
|
xgs = capgs; |
||||
|
xgd = capgd; |
||||
|
xgb = capgb; |
||||
|
xbd = here->MOS9capbd; |
||||
|
xbs = here->MOS9capbs; |
||||
|
/*printf("mos2: xgs=%g, xgd=%g, xgb=%g, xbd=%g, xbs=%g\n", |
||||
|
xgs,xgd,xgb,xbd,xbs);*/ |
||||
|
/* |
||||
|
* load matrix |
||||
|
*/ |
||||
|
|
||||
|
*(here->MOS9GgPtr ) += (xgd+xgs+xgb)*s->real; |
||||
|
*(here->MOS9GgPtr +1) += (xgd+xgs+xgb)*s->imag; |
||||
|
*(here->MOS9BbPtr ) += (xgb+xbd+xbs)*s->real; |
||||
|
*(here->MOS9BbPtr +1) += (xgb+xbd+xbs)*s->imag; |
||||
|
*(here->MOS9DPdpPtr ) += (xgd+xbd)*s->real; |
||||
|
*(here->MOS9DPdpPtr +1) += (xgd+xbd)*s->imag; |
||||
|
*(here->MOS9SPspPtr ) += (xgs+xbs)*s->real; |
||||
|
*(here->MOS9SPspPtr +1) += (xgs+xbs)*s->imag; |
||||
|
*(here->MOS9GbPtr ) -= xgb*s->real; |
||||
|
*(here->MOS9GbPtr +1) -= xgb*s->imag; |
||||
|
*(here->MOS9GdpPtr ) -= xgd*s->real; |
||||
|
*(here->MOS9GdpPtr +1) -= xgd*s->imag; |
||||
|
*(here->MOS9GspPtr ) -= xgs*s->real; |
||||
|
*(here->MOS9GspPtr +1) -= xgs*s->imag; |
||||
|
*(here->MOS9BgPtr ) -= xgb*s->real; |
||||
|
*(here->MOS9BgPtr +1) -= xgb*s->imag; |
||||
|
*(here->MOS9BdpPtr ) -= xbd*s->real; |
||||
|
*(here->MOS9BdpPtr +1) -= xbd*s->imag; |
||||
|
*(here->MOS9BspPtr ) -= xbs*s->real; |
||||
|
*(here->MOS9BspPtr +1) -= xbs*s->imag; |
||||
|
*(here->MOS9DPgPtr ) -= xgd*s->real; |
||||
|
*(here->MOS9DPgPtr +1) -= xgd*s->imag; |
||||
|
*(here->MOS9DPbPtr ) -= xbd*s->real; |
||||
|
*(here->MOS9DPbPtr +1) -= xbd*s->imag; |
||||
|
*(here->MOS9SPgPtr ) -= xgs*s->real; |
||||
|
*(here->MOS9SPgPtr +1) -= xgs*s->imag; |
||||
|
*(here->MOS9SPbPtr ) -= xbs*s->real; |
||||
|
*(here->MOS9SPbPtr +1) -= xbs*s->imag; |
||||
|
*(here->MOS9DdPtr) += here->MOS9drainConductance; |
||||
|
*(here->MOS9SsPtr) += here->MOS9sourceConductance; |
||||
|
*(here->MOS9BbPtr) += here->MOS9gbd+here->MOS9gbs; |
||||
|
*(here->MOS9DPdpPtr) += here->MOS9drainConductance+ |
||||
|
here->MOS9gds+here->MOS9gbd+ |
||||
|
xrev*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9SPspPtr) += here->MOS9sourceConductance+ |
||||
|
here->MOS9gds+here->MOS9gbs+ |
||||
|
xnrm*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9DdpPtr) -= here->MOS9drainConductance; |
||||
|
*(here->MOS9SspPtr) -= here->MOS9sourceConductance; |
||||
|
*(here->MOS9BdpPtr) -= here->MOS9gbd; |
||||
|
*(here->MOS9BspPtr) -= here->MOS9gbs; |
||||
|
*(here->MOS9DPdPtr) -= here->MOS9drainConductance; |
||||
|
*(here->MOS9DPgPtr) += (xnrm-xrev)*here->MOS9gm; |
||||
|
*(here->MOS9DPbPtr) += -here->MOS9gbd+(xnrm-xrev)*here->MOS9gmbs; |
||||
|
*(here->MOS9DPspPtr) -= here->MOS9gds+ |
||||
|
xnrm*(here->MOS9gm+here->MOS9gmbs); |
||||
|
*(here->MOS9SPgPtr) -= (xnrm-xrev)*here->MOS9gm; |
||||
|
*(here->MOS9SPsPtr) -= here->MOS9sourceConductance; |
||||
|
*(here->MOS9SPbPtr) -= here->MOS9gbs+(xnrm-xrev)*here->MOS9gmbs; |
||||
|
*(here->MOS9SPdpPtr) -= here->MOS9gds+ |
||||
|
xrev*(here->MOS9gm+here->MOS9gmbs); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
1562
src/spicelib/devices/mos9/mos9sacl.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,294 +1,294 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "smpdefs.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h"
|
|
||||
#include "const.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
/* assuming silicon - make definition for epsilon of silicon */ |
|
||||
#define EPSSIL (11.7 * 8.854214871e-12) |
|
||||
|
|
||||
int |
|
||||
MOS9setup(matrix,inModel,ckt,states) |
|
||||
SMPmatrix *matrix; |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
int *states; |
|
||||
/* load the MOS9 device structure with those pointers needed later |
|
||||
* for fast matrix loading |
|
||||
*/ |
|
||||
|
|
||||
{ |
|
||||
register MOS9model *model = (MOS9model *)inModel; |
|
||||
register MOS9instance *here; |
|
||||
int error; |
|
||||
CKTnode *tmp; |
|
||||
|
|
||||
/* loop through all the MOS9 device models */ |
|
||||
for( ; model != NULL; model = model->MOS9nextModel ) { |
|
||||
|
|
||||
/* perform model defaulting */ |
|
||||
if(!model->MOS9typeGiven) { |
|
||||
model->MOS9type = NMOS; |
|
||||
} |
|
||||
if(!model->MOS9latDiffGiven) { |
|
||||
model->MOS9latDiff = 0; |
|
||||
} |
|
||||
if(!model->MOS9lengthAdjustGiven) { |
|
||||
model->MOS9lengthAdjust = 0; |
|
||||
} |
|
||||
if(!model->MOS9widthNarrowGiven) { |
|
||||
model->MOS9widthNarrow = 0; |
|
||||
} |
|
||||
if(!model->MOS9widthAdjustGiven) { |
|
||||
model->MOS9widthAdjust = 0; |
|
||||
} |
|
||||
if(!model->MOS9delvt0Given) { |
|
||||
model->MOS9delvt0 = 0; |
|
||||
} |
|
||||
if(!model->MOS9jctSatCurDensityGiven) { |
|
||||
model->MOS9jctSatCurDensity = 0; |
|
||||
} |
|
||||
if(!model->MOS9jctSatCurGiven) { |
|
||||
model->MOS9jctSatCur = 1e-14; |
|
||||
} |
|
||||
if(!model->MOS9drainResistanceGiven) { |
|
||||
model->MOS9drainResistance = 0; |
|
||||
} |
|
||||
if(!model->MOS9sourceResistanceGiven) { |
|
||||
model->MOS9sourceResistance = 0; |
|
||||
} |
|
||||
if(!model->MOS9sheetResistanceGiven) { |
|
||||
model->MOS9sheetResistance = 0; |
|
||||
} |
|
||||
if(!model->MOS9transconductanceGiven) { |
|
||||
model->MOS9transconductance = 2e-5; |
|
||||
} |
|
||||
if(!model->MOS9gateSourceOverlapCapFactorGiven) { |
|
||||
model->MOS9gateSourceOverlapCapFactor = 0; |
|
||||
} |
|
||||
if(!model->MOS9gateDrainOverlapCapFactorGiven) { |
|
||||
model->MOS9gateDrainOverlapCapFactor = 0; |
|
||||
} |
|
||||
if(!model->MOS9gateBulkOverlapCapFactorGiven) { |
|
||||
model->MOS9gateBulkOverlapCapFactor = 0; |
|
||||
} |
|
||||
if(!model->MOS9vt0Given) { |
|
||||
model->MOS9vt0 = 0; |
|
||||
} |
|
||||
if(!model->MOS9capBDGiven) { |
|
||||
model->MOS9capBD = 0; |
|
||||
} |
|
||||
if(!model->MOS9capBSGiven) { |
|
||||
model->MOS9capBS = 0; |
|
||||
} |
|
||||
if(!model->MOS9bulkCapFactorGiven) { |
|
||||
model->MOS9bulkCapFactor = 0; |
|
||||
} |
|
||||
if(!model->MOS9sideWallCapFactorGiven) { |
|
||||
model->MOS9sideWallCapFactor = 0; |
|
||||
} |
|
||||
if(!model->MOS9bulkJctPotentialGiven) { |
|
||||
model->MOS9bulkJctPotential = .8; |
|
||||
} |
|
||||
if(!model->MOS9bulkJctBotGradingCoeffGiven) { |
|
||||
model->MOS9bulkJctBotGradingCoeff = .5; |
|
||||
} |
|
||||
if(!model->MOS9bulkJctSideGradingCoeffGiven) { |
|
||||
model->MOS9bulkJctSideGradingCoeff = .33; |
|
||||
} |
|
||||
if(!model->MOS9fwdCapDepCoeffGiven) { |
|
||||
model->MOS9fwdCapDepCoeff = .5; |
|
||||
} |
|
||||
if(!model->MOS9phiGiven) { |
|
||||
model->MOS9phi = .6; |
|
||||
} |
|
||||
if(!model->MOS9gammaGiven) { |
|
||||
model->MOS9gamma = 0; |
|
||||
} |
|
||||
if(!model->MOS9deltaGiven) { |
|
||||
model->MOS9delta = 0; |
|
||||
} |
|
||||
if(!model->MOS9maxDriftVelGiven) { |
|
||||
model->MOS9maxDriftVel = 0; |
|
||||
} |
|
||||
if(!model->MOS9junctionDepthGiven) { |
|
||||
model->MOS9junctionDepth = 0; |
|
||||
} |
|
||||
if(!model->MOS9fastSurfaceStateDensityGiven) { |
|
||||
model->MOS9fastSurfaceStateDensity = 0; |
|
||||
} |
|
||||
if(!model->MOS9etaGiven) { |
|
||||
model->MOS9eta = 0; |
|
||||
} |
|
||||
if(!model->MOS9thetaGiven) { |
|
||||
model->MOS9theta = 0; |
|
||||
} |
|
||||
if(!model->MOS9kappaGiven) { |
|
||||
model->MOS9kappa = .2; |
|
||||
} |
|
||||
if(!model->MOS9oxideThicknessGiven) { |
|
||||
model->MOS9oxideThickness = 1e-7; |
|
||||
} |
|
||||
if(!model->MOS9fNcoefGiven) { |
|
||||
model->MOS9fNcoef = 0; |
|
||||
} |
|
||||
if(!model->MOS9fNexpGiven) { |
|
||||
model->MOS9fNexp = 1; |
|
||||
} |
|
||||
|
|
||||
/* loop through all the instances of the model */ |
|
||||
for (here = model->MOS9instances; here != NULL ; |
|
||||
here=here->MOS9nextInstance) { |
|
||||
|
|
||||
CKTnode *tmpNode; |
|
||||
IFuid tmpName; |
|
||||
|
|
||||
/* allocate a chunk of the state vector */ |
|
||||
here->MOS9states = *states; |
|
||||
*states += MOS9NUMSTATES; |
|
||||
|
|
||||
if(!here->MOS9drainAreaGiven) { |
|
||||
here->MOS9drainArea = ckt->CKTdefaultMosAD; |
|
||||
} |
|
||||
if(!here->MOS9drainPerimiterGiven) { |
|
||||
here->MOS9drainPerimiter = 0; |
|
||||
} |
|
||||
if(!here->MOS9drainSquaresGiven) { |
|
||||
here->MOS9drainSquares = 1; |
|
||||
} |
|
||||
if(!here->MOS9icVBSGiven) { |
|
||||
here->MOS9icVBS = 0; |
|
||||
} |
|
||||
if(!here->MOS9icVDSGiven) { |
|
||||
here->MOS9icVDS = 0; |
|
||||
} |
|
||||
if(!here->MOS9icVGSGiven) { |
|
||||
here->MOS9icVGS = 0; |
|
||||
} |
|
||||
if(!here->MOS9sourcePerimiterGiven) { |
|
||||
here->MOS9sourcePerimiter = 0; |
|
||||
} |
|
||||
if(!here->MOS9sourceSquaresGiven) { |
|
||||
here->MOS9sourceSquares = 1; |
|
||||
} |
|
||||
if(!here->MOS9vdsatGiven) { |
|
||||
here->MOS9vdsat = 0; |
|
||||
} |
|
||||
if(!here->MOS9vonGiven) { |
|
||||
here->MOS9von = 0; |
|
||||
} |
|
||||
if(!here->MOS9modeGiven) { |
|
||||
here->MOS9mode = 1; |
|
||||
} |
|
||||
|
|
||||
if((model->MOS9drainResistance != 0 || |
|
||||
(model->MOS9sheetResistance != 0 && |
|
||||
here->MOS9drainSquares != 0 ) ) && |
|
||||
here->MOS9dNodePrime==0) { |
|
||||
error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#drain"); |
|
||||
if(error) return(error); |
|
||||
here->MOS9dNodePrime = 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->MOS9dNodePrime = here->MOS9dNode; |
|
||||
} |
|
||||
|
|
||||
if((model->MOS9sourceResistance != 0 || |
|
||||
(model->MOS9sheetResistance != 0 && |
|
||||
here->MOS9sourceSquares != 0 ) ) && |
|
||||
here->MOS9sNodePrime==0) { |
|
||||
error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#source"); |
|
||||
if(error) return(error); |
|
||||
here->MOS9sNodePrime = tmp->number; |
|
||||
if (ckt->CKTcopyNodesets) { |
|
||||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
|
||||
if (tmpNode->nsGiven) { |
|
||||
tmp->nodeset=tmpNode->nodeset; |
|
||||
tmp->nsGiven=tmpNode->nsGiven; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} else { |
|
||||
here->MOS9sNodePrime = here->MOS9sNode; |
|
||||
} |
|
||||
|
|
||||
/* 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(MOS9DdPtr, MOS9dNode, MOS9dNode) |
|
||||
TSTALLOC(MOS9GgPtr, MOS9gNode, MOS9gNode) |
|
||||
TSTALLOC(MOS9SsPtr, MOS9sNode, MOS9sNode) |
|
||||
TSTALLOC(MOS9BbPtr, MOS9bNode, MOS9bNode) |
|
||||
TSTALLOC(MOS9DPdpPtr, MOS9dNodePrime, MOS9dNodePrime) |
|
||||
TSTALLOC(MOS9SPspPtr, MOS9sNodePrime, MOS9sNodePrime) |
|
||||
TSTALLOC(MOS9DdpPtr, MOS9dNode, MOS9dNodePrime) |
|
||||
TSTALLOC(MOS9GbPtr, MOS9gNode, MOS9bNode) |
|
||||
TSTALLOC(MOS9GdpPtr, MOS9gNode, MOS9dNodePrime) |
|
||||
TSTALLOC(MOS9GspPtr, MOS9gNode, MOS9sNodePrime) |
|
||||
TSTALLOC(MOS9SspPtr, MOS9sNode, MOS9sNodePrime) |
|
||||
TSTALLOC(MOS9BdpPtr, MOS9bNode, MOS9dNodePrime) |
|
||||
TSTALLOC(MOS9BspPtr, MOS9bNode, MOS9sNodePrime) |
|
||||
TSTALLOC(MOS9DPspPtr, MOS9dNodePrime, MOS9sNodePrime) |
|
||||
TSTALLOC(MOS9DPdPtr, MOS9dNodePrime, MOS9dNode) |
|
||||
TSTALLOC(MOS9BgPtr, MOS9bNode, MOS9gNode) |
|
||||
TSTALLOC(MOS9DPgPtr, MOS9dNodePrime, MOS9gNode) |
|
||||
TSTALLOC(MOS9SPgPtr, MOS9sNodePrime, MOS9gNode) |
|
||||
TSTALLOC(MOS9SPsPtr, MOS9sNodePrime, MOS9sNode) |
|
||||
TSTALLOC(MOS9DPbPtr, MOS9dNodePrime, MOS9bNode) |
|
||||
TSTALLOC(MOS9SPbPtr, MOS9sNodePrime, MOS9bNode) |
|
||||
TSTALLOC(MOS9SPdpPtr, MOS9sNodePrime, MOS9dNodePrime) |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
|
||||
int |
|
||||
MOS9unsetup(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model; |
|
||||
MOS9instance *here; |
|
||||
|
|
||||
for (model = (MOS9model *)inModel; model != NULL; |
|
||||
model = model->MOS9nextModel) |
|
||||
{ |
|
||||
for (here = model->MOS9instances; here != NULL; |
|
||||
here=here->MOS9nextInstance) |
|
||||
{ |
|
||||
if (here->MOS9dNodePrime |
|
||||
&& here->MOS9dNodePrime != here->MOS9dNode) |
|
||||
{ |
|
||||
CKTdltNNum(ckt, here->MOS9dNodePrime); |
|
||||
here->MOS9dNodePrime= 0; |
|
||||
} |
|
||||
if (here->MOS9sNodePrime |
|
||||
&& here->MOS9sNodePrime != here->MOS9sNode) |
|
||||
{ |
|
||||
CKTdltNNum(ckt, here->MOS9sNodePrime); |
|
||||
here->MOS9sNodePrime= 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return OK; |
|
||||
} |
|
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
/* assuming silicon - make definition for epsilon of silicon */ |
||||
|
#define EPSSIL (11.7 * 8.854214871e-12) |
||||
|
|
||||
|
int |
||||
|
MOS9setup(matrix,inModel,ckt,states) |
||||
|
SMPmatrix *matrix; |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
int *states; |
||||
|
/* load the MOS9 device structure with those pointers needed later |
||||
|
* for fast matrix loading |
||||
|
*/ |
||||
|
|
||||
|
{ |
||||
|
register MOS9model *model = (MOS9model *)inModel; |
||||
|
register MOS9instance *here; |
||||
|
int error; |
||||
|
CKTnode *tmp; |
||||
|
|
||||
|
/* loop through all the MOS9 device models */ |
||||
|
for( ; model != NULL; model = model->MOS9nextModel ) { |
||||
|
|
||||
|
/* perform model defaulting */ |
||||
|
if(!model->MOS9typeGiven) { |
||||
|
model->MOS9type = NMOS; |
||||
|
} |
||||
|
if(!model->MOS9latDiffGiven) { |
||||
|
model->MOS9latDiff = 0; |
||||
|
} |
||||
|
if(!model->MOS9lengthAdjustGiven) { |
||||
|
model->MOS9lengthAdjust = 0; |
||||
|
} |
||||
|
if(!model->MOS9widthNarrowGiven) { |
||||
|
model->MOS9widthNarrow = 0; |
||||
|
} |
||||
|
if(!model->MOS9widthAdjustGiven) { |
||||
|
model->MOS9widthAdjust = 0; |
||||
|
} |
||||
|
if(!model->MOS9delvt0Given) { |
||||
|
model->MOS9delvt0 = 0; |
||||
|
} |
||||
|
if(!model->MOS9jctSatCurDensityGiven) { |
||||
|
model->MOS9jctSatCurDensity = 0; |
||||
|
} |
||||
|
if(!model->MOS9jctSatCurGiven) { |
||||
|
model->MOS9jctSatCur = 1e-14; |
||||
|
} |
||||
|
if(!model->MOS9drainResistanceGiven) { |
||||
|
model->MOS9drainResistance = 0; |
||||
|
} |
||||
|
if(!model->MOS9sourceResistanceGiven) { |
||||
|
model->MOS9sourceResistance = 0; |
||||
|
} |
||||
|
if(!model->MOS9sheetResistanceGiven) { |
||||
|
model->MOS9sheetResistance = 0; |
||||
|
} |
||||
|
if(!model->MOS9transconductanceGiven) { |
||||
|
model->MOS9transconductance = 2e-5; |
||||
|
} |
||||
|
if(!model->MOS9gateSourceOverlapCapFactorGiven) { |
||||
|
model->MOS9gateSourceOverlapCapFactor = 0; |
||||
|
} |
||||
|
if(!model->MOS9gateDrainOverlapCapFactorGiven) { |
||||
|
model->MOS9gateDrainOverlapCapFactor = 0; |
||||
|
} |
||||
|
if(!model->MOS9gateBulkOverlapCapFactorGiven) { |
||||
|
model->MOS9gateBulkOverlapCapFactor = 0; |
||||
|
} |
||||
|
if(!model->MOS9vt0Given) { |
||||
|
model->MOS9vt0 = 0; |
||||
|
} |
||||
|
if(!model->MOS9capBDGiven) { |
||||
|
model->MOS9capBD = 0; |
||||
|
} |
||||
|
if(!model->MOS9capBSGiven) { |
||||
|
model->MOS9capBS = 0; |
||||
|
} |
||||
|
if(!model->MOS9bulkCapFactorGiven) { |
||||
|
model->MOS9bulkCapFactor = 0; |
||||
|
} |
||||
|
if(!model->MOS9sideWallCapFactorGiven) { |
||||
|
model->MOS9sideWallCapFactor = 0; |
||||
|
} |
||||
|
if(!model->MOS9bulkJctPotentialGiven) { |
||||
|
model->MOS9bulkJctPotential = .8; |
||||
|
} |
||||
|
if(!model->MOS9bulkJctBotGradingCoeffGiven) { |
||||
|
model->MOS9bulkJctBotGradingCoeff = .5; |
||||
|
} |
||||
|
if(!model->MOS9bulkJctSideGradingCoeffGiven) { |
||||
|
model->MOS9bulkJctSideGradingCoeff = .33; |
||||
|
} |
||||
|
if(!model->MOS9fwdCapDepCoeffGiven) { |
||||
|
model->MOS9fwdCapDepCoeff = .5; |
||||
|
} |
||||
|
if(!model->MOS9phiGiven) { |
||||
|
model->MOS9phi = .6; |
||||
|
} |
||||
|
if(!model->MOS9gammaGiven) { |
||||
|
model->MOS9gamma = 0; |
||||
|
} |
||||
|
if(!model->MOS9deltaGiven) { |
||||
|
model->MOS9delta = 0; |
||||
|
} |
||||
|
if(!model->MOS9maxDriftVelGiven) { |
||||
|
model->MOS9maxDriftVel = 0; |
||||
|
} |
||||
|
if(!model->MOS9junctionDepthGiven) { |
||||
|
model->MOS9junctionDepth = 0; |
||||
|
} |
||||
|
if(!model->MOS9fastSurfaceStateDensityGiven) { |
||||
|
model->MOS9fastSurfaceStateDensity = 0; |
||||
|
} |
||||
|
if(!model->MOS9etaGiven) { |
||||
|
model->MOS9eta = 0; |
||||
|
} |
||||
|
if(!model->MOS9thetaGiven) { |
||||
|
model->MOS9theta = 0; |
||||
|
} |
||||
|
if(!model->MOS9kappaGiven) { |
||||
|
model->MOS9kappa = .2; |
||||
|
} |
||||
|
if(!model->MOS9oxideThicknessGiven) { |
||||
|
model->MOS9oxideThickness = 1e-7; |
||||
|
} |
||||
|
if(!model->MOS9fNcoefGiven) { |
||||
|
model->MOS9fNcoef = 0; |
||||
|
} |
||||
|
if(!model->MOS9fNexpGiven) { |
||||
|
model->MOS9fNexp = 1; |
||||
|
} |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MOS9instances; here != NULL ; |
||||
|
here=here->MOS9nextInstance) { |
||||
|
|
||||
|
CKTnode *tmpNode; |
||||
|
IFuid tmpName; |
||||
|
|
||||
|
/* allocate a chunk of the state vector */ |
||||
|
here->MOS9states = *states; |
||||
|
*states += MOS9NUMSTATES; |
||||
|
|
||||
|
if(!here->MOS9drainAreaGiven) { |
||||
|
here->MOS9drainArea = ckt->CKTdefaultMosAD; |
||||
|
} |
||||
|
if(!here->MOS9drainPerimiterGiven) { |
||||
|
here->MOS9drainPerimiter = 0; |
||||
|
} |
||||
|
if(!here->MOS9drainSquaresGiven) { |
||||
|
here->MOS9drainSquares = 1; |
||||
|
} |
||||
|
if(!here->MOS9icVBSGiven) { |
||||
|
here->MOS9icVBS = 0; |
||||
|
} |
||||
|
if(!here->MOS9icVDSGiven) { |
||||
|
here->MOS9icVDS = 0; |
||||
|
} |
||||
|
if(!here->MOS9icVGSGiven) { |
||||
|
here->MOS9icVGS = 0; |
||||
|
} |
||||
|
if(!here->MOS9sourcePerimiterGiven) { |
||||
|
here->MOS9sourcePerimiter = 0; |
||||
|
} |
||||
|
if(!here->MOS9sourceSquaresGiven) { |
||||
|
here->MOS9sourceSquares = 1; |
||||
|
} |
||||
|
if(!here->MOS9vdsatGiven) { |
||||
|
here->MOS9vdsat = 0; |
||||
|
} |
||||
|
if(!here->MOS9vonGiven) { |
||||
|
here->MOS9von = 0; |
||||
|
} |
||||
|
if(!here->MOS9modeGiven) { |
||||
|
here->MOS9mode = 1; |
||||
|
} |
||||
|
|
||||
|
if((model->MOS9drainResistance != 0 || |
||||
|
(model->MOS9sheetResistance != 0 && |
||||
|
here->MOS9drainSquares != 0 ) ) && |
||||
|
here->MOS9dNodePrime==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#drain"); |
||||
|
if(error) return(error); |
||||
|
here->MOS9dNodePrime = 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->MOS9dNodePrime = here->MOS9dNode; |
||||
|
} |
||||
|
|
||||
|
if((model->MOS9sourceResistance != 0 || |
||||
|
(model->MOS9sheetResistance != 0 && |
||||
|
here->MOS9sourceSquares != 0 ) ) && |
||||
|
here->MOS9sNodePrime==0) { |
||||
|
error = CKTmkVolt(ckt,&tmp,here->MOS9name,"internal#source"); |
||||
|
if(error) return(error); |
||||
|
here->MOS9sNodePrime = tmp->number; |
||||
|
if (ckt->CKTcopyNodesets) { |
||||
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
||||
|
if (tmpNode->nsGiven) { |
||||
|
tmp->nodeset=tmpNode->nodeset; |
||||
|
tmp->nsGiven=tmpNode->nsGiven; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
here->MOS9sNodePrime = here->MOS9sNode; |
||||
|
} |
||||
|
|
||||
|
/* 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(MOS9DdPtr, MOS9dNode, MOS9dNode) |
||||
|
TSTALLOC(MOS9GgPtr, MOS9gNode, MOS9gNode) |
||||
|
TSTALLOC(MOS9SsPtr, MOS9sNode, MOS9sNode) |
||||
|
TSTALLOC(MOS9BbPtr, MOS9bNode, MOS9bNode) |
||||
|
TSTALLOC(MOS9DPdpPtr, MOS9dNodePrime, MOS9dNodePrime) |
||||
|
TSTALLOC(MOS9SPspPtr, MOS9sNodePrime, MOS9sNodePrime) |
||||
|
TSTALLOC(MOS9DdpPtr, MOS9dNode, MOS9dNodePrime) |
||||
|
TSTALLOC(MOS9GbPtr, MOS9gNode, MOS9bNode) |
||||
|
TSTALLOC(MOS9GdpPtr, MOS9gNode, MOS9dNodePrime) |
||||
|
TSTALLOC(MOS9GspPtr, MOS9gNode, MOS9sNodePrime) |
||||
|
TSTALLOC(MOS9SspPtr, MOS9sNode, MOS9sNodePrime) |
||||
|
TSTALLOC(MOS9BdpPtr, MOS9bNode, MOS9dNodePrime) |
||||
|
TSTALLOC(MOS9BspPtr, MOS9bNode, MOS9sNodePrime) |
||||
|
TSTALLOC(MOS9DPspPtr, MOS9dNodePrime, MOS9sNodePrime) |
||||
|
TSTALLOC(MOS9DPdPtr, MOS9dNodePrime, MOS9dNode) |
||||
|
TSTALLOC(MOS9BgPtr, MOS9bNode, MOS9gNode) |
||||
|
TSTALLOC(MOS9DPgPtr, MOS9dNodePrime, MOS9gNode) |
||||
|
TSTALLOC(MOS9SPgPtr, MOS9sNodePrime, MOS9gNode) |
||||
|
TSTALLOC(MOS9SPsPtr, MOS9sNodePrime, MOS9sNode) |
||||
|
TSTALLOC(MOS9DPbPtr, MOS9dNodePrime, MOS9bNode) |
||||
|
TSTALLOC(MOS9SPbPtr, MOS9sNodePrime, MOS9bNode) |
||||
|
TSTALLOC(MOS9SPdpPtr, MOS9sNodePrime, MOS9dNodePrime) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
MOS9unsetup(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model; |
||||
|
MOS9instance *here; |
||||
|
|
||||
|
for (model = (MOS9model *)inModel; model != NULL; |
||||
|
model = model->MOS9nextModel) |
||||
|
{ |
||||
|
for (here = model->MOS9instances; here != NULL; |
||||
|
here=here->MOS9nextInstance) |
||||
|
{ |
||||
|
if (here->MOS9dNodePrime |
||||
|
&& here->MOS9dNodePrime != here->MOS9dNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->MOS9dNodePrime); |
||||
|
here->MOS9dNodePrime= 0; |
||||
|
} |
||||
|
if (here->MOS9sNodePrime |
||||
|
&& here->MOS9sNodePrime != here->MOS9sNode) |
||||
|
{ |
||||
|
CKTdltNNum(ckt, here->MOS9sNodePrime); |
||||
|
here->MOS9sNodePrime= 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return OK; |
||||
|
} |
||||
1248
src/spicelib/devices/mos9/mos9sld.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,65 +1,65 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
/* Pretty print the sensitivity info for all the MOS9 |
|
||||
* devices in the circuit. |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "smpdefs.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h"
|
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
void |
|
||||
MOS9sPrint(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
register CKTcircuit *ckt; |
|
||||
{ |
|
||||
register MOS9model *model = (MOS9model *)inModel; |
|
||||
register MOS9instance *here; |
|
||||
|
|
||||
printf("LEVEL 3 MOSFETS (AG) -----------------\n"); |
|
||||
/* loop through all the MOS9 models */ |
|
||||
for( ; model != NULL; model = model->MOS9nextModel ) { |
|
||||
|
|
||||
printf("Model name:%s\n",model->MOS9modName); |
|
||||
|
|
||||
/* loop through all the instances of the model */ |
|
||||
for (here = model->MOS9instances; here != NULL ; |
|
||||
here=here->MOS9nextInstance) { |
|
||||
|
|
||||
printf(" Instance name:%s\n",here->MOS9name); |
|
||||
printf(" Drain, Gate , Source nodes: %s, %s ,%s\n", |
|
||||
CKTnodName(ckt,here->MOS9dNode),CKTnodName(ckt,here->MOS9gNode), |
|
||||
CKTnodName(ckt,here->MOS9sNode)); |
|
||||
|
|
||||
printf(" Multiplier: %g ",here->MOS9m); |
|
||||
printf(here->MOS9mGiven ? "(specified)\n" : "(default)\n"); |
|
||||
printf(" Length: %g ",here->MOS9l); |
|
||||
printf(here->MOS9lGiven ? "(specified)\n" : "(default)\n"); |
|
||||
printf(" Width: %g ",here->MOS9w); |
|
||||
printf(here->MOS9wGiven ? "(specified)\n" : "(default)\n"); |
|
||||
if(here->MOS9sens_l == 1){ |
|
||||
printf(" MOS9senParmNo:l = %d ",here->MOS9senParmNo); |
|
||||
} |
|
||||
else{ |
|
||||
printf(" MOS9senParmNo:l = 0 "); |
|
||||
} |
|
||||
if(here->MOS9sens_w == 1){ |
|
||||
printf(" w = %d \n",here->MOS9senParmNo + here->MOS9sens_l); |
|
||||
} |
|
||||
else{ |
|
||||
printf(" w = 0 \n"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
**********/ |
||||
|
|
||||
|
/* Pretty print the sensitivity info for all the MOS9 |
||||
|
* devices in the circuit. |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
void |
||||
|
MOS9sPrint(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
register CKTcircuit *ckt; |
||||
|
{ |
||||
|
register MOS9model *model = (MOS9model *)inModel; |
||||
|
register MOS9instance *here; |
||||
|
|
||||
|
printf("LEVEL 3 MOSFETS (AG) -----------------\n"); |
||||
|
/* loop through all the MOS9 models */ |
||||
|
for( ; model != NULL; model = model->MOS9nextModel ) { |
||||
|
|
||||
|
printf("Model name:%s\n",model->MOS9modName); |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MOS9instances; here != NULL ; |
||||
|
here=here->MOS9nextInstance) { |
||||
|
|
||||
|
printf(" Instance name:%s\n",here->MOS9name); |
||||
|
printf(" Drain, Gate , Source nodes: %s, %s ,%s\n", |
||||
|
CKTnodName(ckt,here->MOS9dNode),CKTnodName(ckt,here->MOS9gNode), |
||||
|
CKTnodName(ckt,here->MOS9sNode)); |
||||
|
|
||||
|
printf(" Multiplier: %g ",here->MOS9m); |
||||
|
printf(here->MOS9mGiven ? "(specified)\n" : "(default)\n"); |
||||
|
printf(" Length: %g ",here->MOS9l); |
||||
|
printf(here->MOS9lGiven ? "(specified)\n" : "(default)\n"); |
||||
|
printf(" Width: %g ",here->MOS9w); |
||||
|
printf(here->MOS9wGiven ? "(specified)\n" : "(default)\n"); |
||||
|
if(here->MOS9sens_l == 1){ |
||||
|
printf(" MOS9senParmNo:l = %d ",here->MOS9senParmNo); |
||||
|
} |
||||
|
else{ |
||||
|
printf(" MOS9senParmNo:l = 0 "); |
||||
|
} |
||||
|
if(here->MOS9sens_w == 1){ |
||||
|
printf(" w = %d \n",here->MOS9senParmNo + here->MOS9sens_l); |
||||
|
} |
||||
|
else{ |
||||
|
printf(" w = 0 \n"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -1,54 +1,54 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
/* loop through all the devices and |
|
||||
* allocate parameter #s to design parameters |
|
||||
*/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "smpdefs.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h"
|
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
int |
|
||||
MOS9sSetup(info,inModel) |
|
||||
SENstruct *info; |
|
||||
GENmodel *inModel; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
|
|
||||
/* loop through all the models */ |
|
||||
for( ; model != NULL; model = model->MOS9nextModel ) { |
|
||||
|
|
||||
/* loop through all the instances of the model */ |
|
||||
for (here = model->MOS9instances; here != NULL ; |
|
||||
here=here->MOS9nextInstance) { |
|
||||
|
|
||||
|
|
||||
if(here->MOS9senParmNo){ |
|
||||
if((here->MOS9sens_l)&&(here->MOS9sens_w)){ |
|
||||
here->MOS9senParmNo = ++(info->SENparms); |
|
||||
++(info->SENparms);/* MOS has two design parameters */ |
|
||||
} |
|
||||
else{ |
|
||||
here->MOS9senParmNo = ++(info->SENparms); |
|
||||
} |
|
||||
} |
|
||||
here->MOS9senPertFlag = OFF; |
|
||||
if((here->MOS9sens = (double *)MALLOC(72*sizeof(double))) == NULL) { |
|
||||
return(E_NOMEM); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
**********/ |
||||
|
|
||||
|
/* loop through all the devices and |
||||
|
* allocate parameter #s to design parameters |
||||
|
*/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
int |
||||
|
MOS9sSetup(info,inModel) |
||||
|
SENstruct *info; |
||||
|
GENmodel *inModel; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
|
||||
|
/* loop through all the models */ |
||||
|
for( ; model != NULL; model = model->MOS9nextModel ) { |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MOS9instances; here != NULL ; |
||||
|
here=here->MOS9nextInstance) { |
||||
|
|
||||
|
|
||||
|
if(here->MOS9senParmNo){ |
||||
|
if((here->MOS9sens_l)&&(here->MOS9sens_w)){ |
||||
|
here->MOS9senParmNo = ++(info->SENparms); |
||||
|
++(info->SENparms);/* MOS has two design parameters */ |
||||
|
} |
||||
|
else{ |
||||
|
here->MOS9senParmNo = ++(info->SENparms); |
||||
|
} |
||||
|
} |
||||
|
here->MOS9senPertFlag = OFF; |
||||
|
if((here->MOS9sens = (double *)MALLOC(72*sizeof(double))) == NULL) { |
||||
|
return(E_NOMEM); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
|
|
||||
|
|
||||
@ -1,182 +1,182 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
#include <stdio.h> |
|
||||
#include "ngspice.h" |
|
||||
#include "smpdefs.h" |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
int |
|
||||
MOS9sUpdate(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
int iparmno; |
|
||||
double sb; |
|
||||
double sg; |
|
||||
double sdprm; |
|
||||
double ssprm; |
|
||||
double sxpgs; |
|
||||
double sxpgd; |
|
||||
double sxpbs; |
|
||||
double sxpbd; |
|
||||
double sxpgb; |
|
||||
double dummy1; |
|
||||
double dummy2; |
|
||||
SENstruct *info; |
|
||||
|
|
||||
|
|
||||
if(ckt->CKTtime == 0) return(OK); |
|
||||
info = ckt->CKTsenInfo; |
|
||||
|
|
||||
#ifdef SENSDEBUG |
|
||||
printf("MOS9senupdate\n"); |
|
||||
printf("CKTtime = %.5e\n",ckt->CKTtime); |
|
||||
#endif /* SENSDEBUG */ |
|
||||
|
|
||||
sxpgs = 0; |
|
||||
sxpgd = 0; |
|
||||
sxpbs = 0; |
|
||||
sxpbd = 0; |
|
||||
sxpgb = 0; |
|
||||
dummy1 = 0; |
|
||||
dummy2 = 0; |
|
||||
|
|
||||
/* loop through all the MOS9 models */ |
|
||||
for( ; model != NULL; model = model->MOS9nextModel ) { |
|
||||
|
|
||||
/* loop through all the instances of the model */ |
|
||||
for (here = model->MOS9instances; here != NULL ; |
|
||||
here=here->MOS9nextInstance) { |
|
||||
|
|
||||
|
|
||||
#ifdef SENSDEBUG |
|
||||
printf("senupdate instance name %s\n",here->MOS9name); |
|
||||
printf("before loading\n"); |
|
||||
printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n", |
|
||||
ckt->CKTag[0],ckt->CKTag[1]); |
|
||||
printf("capgs = %.7e\n",here->MOS9cgs); |
|
||||
printf("capgd = %.7e\n",here->MOS9cgd); |
|
||||
printf("capgb = %.7e\n",here->MOS9cgb); |
|
||||
printf("capbs = %.7e\n",here->MOS9capbs); |
|
||||
printf("capbd = %.7e\n",here->MOS9capbd); |
|
||||
#endif /* SENSDEBUG */ |
|
||||
|
|
||||
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ |
|
||||
|
|
||||
sb = *(info->SEN_Sap[here->MOS9bNode] + iparmno); |
|
||||
sg = *(info->SEN_Sap[here->MOS9gNode] + iparmno); |
|
||||
ssprm = *(info->SEN_Sap[here->MOS9sNodePrime] + iparmno); |
|
||||
sdprm = *(info->SEN_Sap[here->MOS9dNodePrime] + iparmno); |
|
||||
#ifdef SENSDEBUG |
|
||||
printf("iparmno = %d\n",iparmno); |
|
||||
printf("sb = %.7e,sg = %.7e\n",sb,sg); |
|
||||
printf("ssprm = %.7e,sdprm = %.7e\n",ssprm,sdprm); |
|
||||
#endif /* SENSDEBUG */ |
|
||||
|
|
||||
sxpgs = (sg - ssprm) * here->MOS9cgs ; |
|
||||
sxpgd = (sg - sdprm) * here->MOS9cgd ; |
|
||||
sxpgb = (sg - sb) * here->MOS9cgb ; |
|
||||
sxpbs = (sb - ssprm) * here->MOS9capbs ; |
|
||||
sxpbd = (sb - sdprm) * here->MOS9capbd ; |
|
||||
|
|
||||
if(here->MOS9sens_l && (iparmno == here->MOS9senParmNo)){ |
|
||||
sxpgs += *(here->MOS9dphigs_dl); |
|
||||
sxpgd += *(here->MOS9dphigd_dl); |
|
||||
sxpbs += *(here->MOS9dphibs_dl); |
|
||||
sxpbd += *(here->MOS9dphibd_dl); |
|
||||
sxpgb += *(here->MOS9dphigb_dl); |
|
||||
} |
|
||||
if(here->MOS9sens_w && |
|
||||
(iparmno == (here->MOS9senParmNo+here->MOS9sens_l))){ |
|
||||
sxpgs += *(here->MOS9dphigs_dw); |
|
||||
sxpgd += *(here->MOS9dphigd_dw); |
|
||||
sxpbs += *(here->MOS9dphibs_dw); |
|
||||
sxpbd += *(here->MOS9dphibd_dw); |
|
||||
sxpgb += *(here->MOS9dphigb_dw); |
|
||||
} |
|
||||
if(ckt->CKTmode & MODEINITTRAN) { |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgs + |
|
||||
10 * (iparmno - 1)) = sxpgs; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgd + |
|
||||
10 * (iparmno - 1)) = sxpgd; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpbs + |
|
||||
10 * (iparmno - 1)) = sxpbs; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpbd + |
|
||||
10 * (iparmno - 1)) = sxpbd; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgb + |
|
||||
10 * (iparmno - 1)) = sxpgb; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgs + |
|
||||
10 * (iparmno - 1) + 1) = 0; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgd + |
|
||||
10 * (iparmno - 1) + 1) = 0; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpbs + |
|
||||
10 * (iparmno - 1) + 1) = 0; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpbd + |
|
||||
10 * (iparmno - 1) + 1) = 0; |
|
||||
*(ckt->CKTstate1 + here->MOS9sensxpgb + |
|
||||
10 * (iparmno - 1) + 1) = 0; |
|
||||
goto next; |
|
||||
} |
|
||||
|
|
||||
*(ckt->CKTstate0 + here->MOS9sensxpgs + |
|
||||
10 * (iparmno - 1)) = sxpgs; |
|
||||
*(ckt->CKTstate0 + here->MOS9sensxpgd + |
|
||||
10 * (iparmno - 1)) = sxpgd; |
|
||||
*(ckt->CKTstate0 + here->MOS9sensxpbs + |
|
||||
10 * (iparmno - 1)) = sxpbs; |
|
||||
*(ckt->CKTstate0 + here->MOS9sensxpbd + |
|
||||
10 * (iparmno - 1)) = sxpbd; |
|
||||
*(ckt->CKTstate0 + here->MOS9sensxpgb + |
|
||||
10 * (iparmno - 1)) = sxpgb; |
|
||||
|
|
||||
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgs, |
|
||||
here->MOS9sensxpgs + 10*(iparmno -1)); |
|
||||
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgd, |
|
||||
here->MOS9sensxpgd + 10*(iparmno -1)); |
|
||||
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgb, |
|
||||
here->MOS9sensxpgb + 10*(iparmno -1)); |
|
||||
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbs, |
|
||||
here->MOS9sensxpbs + 10*(iparmno -1)); |
|
||||
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbd, |
|
||||
here->MOS9sensxpbd + 10*(iparmno -1)); |
|
||||
|
|
||||
|
|
||||
next: |
|
||||
; |
|
||||
#ifdef SENSDEBUG |
|
||||
printf("after loading\n"); |
|
||||
printf("sxpgs = %.7e,sdotxpgs = %.7e\n", |
|
||||
sxpgs,*(ckt->CKTstate0 + here->MOS9sensxpgs + |
|
||||
10 * (iparmno - 1) + 1)); |
|
||||
printf("sxpgd = %.7e,sdotxpgd = %.7e\n", |
|
||||
sxpgd,*(ckt->CKTstate0 + here->MOS9sensxpgd + |
|
||||
10 * (iparmno - 1) + 1)); |
|
||||
printf("sxpgb = %.7e,sdotxpgb = %.7e\n", |
|
||||
sxpgb,*(ckt->CKTstate0 + here->MOS9sensxpgb + |
|
||||
10 * (iparmno - 1) + 1)); |
|
||||
printf("sxpbs = %.7e,sdotxpbs = %.7e\n", |
|
||||
sxpbs,*(ckt->CKTstate0 + here->MOS9sensxpbs + |
|
||||
10 * (iparmno - 1) + 1)); |
|
||||
printf("sxpbd = %.7e,sdotxpbd = %.7e\n", |
|
||||
sxpbd,*(ckt->CKTstate0 + here->MOS9sensxpbd + |
|
||||
10 * (iparmno - 1) + 1)); |
|
||||
#endif /* SENSDEBUG */ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
#ifdef SENSDEBUG |
|
||||
printf("MOS9senupdate end\n"); |
|
||||
#endif /* SENSDEBUG */ |
|
||||
return(OK); |
|
||||
|
|
||||
} |
|
||||
|
|
||||
|
**********/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include "ngspice.h" |
||||
|
#include "smpdefs.h" |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
int |
||||
|
MOS9sUpdate(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
int iparmno; |
||||
|
double sb; |
||||
|
double sg; |
||||
|
double sdprm; |
||||
|
double ssprm; |
||||
|
double sxpgs; |
||||
|
double sxpgd; |
||||
|
double sxpbs; |
||||
|
double sxpbd; |
||||
|
double sxpgb; |
||||
|
double dummy1; |
||||
|
double dummy2; |
||||
|
SENstruct *info; |
||||
|
|
||||
|
|
||||
|
if(ckt->CKTtime == 0) return(OK); |
||||
|
info = ckt->CKTsenInfo; |
||||
|
|
||||
|
#ifdef SENSDEBUG |
||||
|
printf("MOS9senupdate\n"); |
||||
|
printf("CKTtime = %.5e\n",ckt->CKTtime); |
||||
|
#endif /* SENSDEBUG */ |
||||
|
|
||||
|
sxpgs = 0; |
||||
|
sxpgd = 0; |
||||
|
sxpbs = 0; |
||||
|
sxpbd = 0; |
||||
|
sxpgb = 0; |
||||
|
dummy1 = 0; |
||||
|
dummy2 = 0; |
||||
|
|
||||
|
/* loop through all the MOS9 models */ |
||||
|
for( ; model != NULL; model = model->MOS9nextModel ) { |
||||
|
|
||||
|
/* loop through all the instances of the model */ |
||||
|
for (here = model->MOS9instances; here != NULL ; |
||||
|
here=here->MOS9nextInstance) { |
||||
|
|
||||
|
|
||||
|
#ifdef SENSDEBUG |
||||
|
printf("senupdate instance name %s\n",here->MOS9name); |
||||
|
printf("before loading\n"); |
||||
|
printf("CKTag[0] = %.2e,CKTag[1] = %.2e\n", |
||||
|
ckt->CKTag[0],ckt->CKTag[1]); |
||||
|
printf("capgs = %.7e\n",here->MOS9cgs); |
||||
|
printf("capgd = %.7e\n",here->MOS9cgd); |
||||
|
printf("capgb = %.7e\n",here->MOS9cgb); |
||||
|
printf("capbs = %.7e\n",here->MOS9capbs); |
||||
|
printf("capbd = %.7e\n",here->MOS9capbd); |
||||
|
#endif /* SENSDEBUG */ |
||||
|
|
||||
|
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ |
||||
|
|
||||
|
sb = *(info->SEN_Sap[here->MOS9bNode] + iparmno); |
||||
|
sg = *(info->SEN_Sap[here->MOS9gNode] + iparmno); |
||||
|
ssprm = *(info->SEN_Sap[here->MOS9sNodePrime] + iparmno); |
||||
|
sdprm = *(info->SEN_Sap[here->MOS9dNodePrime] + iparmno); |
||||
|
#ifdef SENSDEBUG |
||||
|
printf("iparmno = %d\n",iparmno); |
||||
|
printf("sb = %.7e,sg = %.7e\n",sb,sg); |
||||
|
printf("ssprm = %.7e,sdprm = %.7e\n",ssprm,sdprm); |
||||
|
#endif /* SENSDEBUG */ |
||||
|
|
||||
|
sxpgs = (sg - ssprm) * here->MOS9cgs ; |
||||
|
sxpgd = (sg - sdprm) * here->MOS9cgd ; |
||||
|
sxpgb = (sg - sb) * here->MOS9cgb ; |
||||
|
sxpbs = (sb - ssprm) * here->MOS9capbs ; |
||||
|
sxpbd = (sb - sdprm) * here->MOS9capbd ; |
||||
|
|
||||
|
if(here->MOS9sens_l && (iparmno == here->MOS9senParmNo)){ |
||||
|
sxpgs += *(here->MOS9dphigs_dl); |
||||
|
sxpgd += *(here->MOS9dphigd_dl); |
||||
|
sxpbs += *(here->MOS9dphibs_dl); |
||||
|
sxpbd += *(here->MOS9dphibd_dl); |
||||
|
sxpgb += *(here->MOS9dphigb_dl); |
||||
|
} |
||||
|
if(here->MOS9sens_w && |
||||
|
(iparmno == (here->MOS9senParmNo+here->MOS9sens_l))){ |
||||
|
sxpgs += *(here->MOS9dphigs_dw); |
||||
|
sxpgd += *(here->MOS9dphigd_dw); |
||||
|
sxpbs += *(here->MOS9dphibs_dw); |
||||
|
sxpbd += *(here->MOS9dphibd_dw); |
||||
|
sxpgb += *(here->MOS9dphigb_dw); |
||||
|
} |
||||
|
if(ckt->CKTmode & MODEINITTRAN) { |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgs + |
||||
|
10 * (iparmno - 1)) = sxpgs; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgd + |
||||
|
10 * (iparmno - 1)) = sxpgd; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpbs + |
||||
|
10 * (iparmno - 1)) = sxpbs; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpbd + |
||||
|
10 * (iparmno - 1)) = sxpbd; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgb + |
||||
|
10 * (iparmno - 1)) = sxpgb; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgs + |
||||
|
10 * (iparmno - 1) + 1) = 0; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgd + |
||||
|
10 * (iparmno - 1) + 1) = 0; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpbs + |
||||
|
10 * (iparmno - 1) + 1) = 0; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpbd + |
||||
|
10 * (iparmno - 1) + 1) = 0; |
||||
|
*(ckt->CKTstate1 + here->MOS9sensxpgb + |
||||
|
10 * (iparmno - 1) + 1) = 0; |
||||
|
goto next; |
||||
|
} |
||||
|
|
||||
|
*(ckt->CKTstate0 + here->MOS9sensxpgs + |
||||
|
10 * (iparmno - 1)) = sxpgs; |
||||
|
*(ckt->CKTstate0 + here->MOS9sensxpgd + |
||||
|
10 * (iparmno - 1)) = sxpgd; |
||||
|
*(ckt->CKTstate0 + here->MOS9sensxpbs + |
||||
|
10 * (iparmno - 1)) = sxpbs; |
||||
|
*(ckt->CKTstate0 + here->MOS9sensxpbd + |
||||
|
10 * (iparmno - 1)) = sxpbd; |
||||
|
*(ckt->CKTstate0 + here->MOS9sensxpgb + |
||||
|
10 * (iparmno - 1)) = sxpgb; |
||||
|
|
||||
|
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgs, |
||||
|
here->MOS9sensxpgs + 10*(iparmno -1)); |
||||
|
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgd, |
||||
|
here->MOS9sensxpgd + 10*(iparmno -1)); |
||||
|
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9cgb, |
||||
|
here->MOS9sensxpgb + 10*(iparmno -1)); |
||||
|
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbs, |
||||
|
here->MOS9sensxpbs + 10*(iparmno -1)); |
||||
|
NIintegrate(ckt,&dummy1,&dummy2,here->MOS9capbd, |
||||
|
here->MOS9sensxpbd + 10*(iparmno -1)); |
||||
|
|
||||
|
|
||||
|
next: |
||||
|
; |
||||
|
#ifdef SENSDEBUG |
||||
|
printf("after loading\n"); |
||||
|
printf("sxpgs = %.7e,sdotxpgs = %.7e\n", |
||||
|
sxpgs,*(ckt->CKTstate0 + here->MOS9sensxpgs + |
||||
|
10 * (iparmno - 1) + 1)); |
||||
|
printf("sxpgd = %.7e,sdotxpgd = %.7e\n", |
||||
|
sxpgd,*(ckt->CKTstate0 + here->MOS9sensxpgd + |
||||
|
10 * (iparmno - 1) + 1)); |
||||
|
printf("sxpgb = %.7e,sdotxpgb = %.7e\n", |
||||
|
sxpgb,*(ckt->CKTstate0 + here->MOS9sensxpgb + |
||||
|
10 * (iparmno - 1) + 1)); |
||||
|
printf("sxpbs = %.7e,sdotxpbs = %.7e\n", |
||||
|
sxpbs,*(ckt->CKTstate0 + here->MOS9sensxpbs + |
||||
|
10 * (iparmno - 1) + 1)); |
||||
|
printf("sxpbd = %.7e,sdotxpbd = %.7e\n", |
||||
|
sxpbd,*(ckt->CKTstate0 + here->MOS9sensxpbd + |
||||
|
10 * (iparmno - 1) + 1)); |
||||
|
#endif /* SENSDEBUG */ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#ifdef SENSDEBUG |
||||
|
printf("MOS9senupdate end\n"); |
||||
|
#endif /* SENSDEBUG */ |
||||
|
return(OK); |
||||
|
|
||||
|
} |
||||
|
|
||||
@ -1,343 +1,343 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
Author: 1985 Thomas L. Quarles |
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
|
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h"
|
|
||||
#include "const.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
/* assuming silicon - make definition for epsilon of silicon */ |
|
||||
#define EPSSIL (11.7 * 8.854214871e-12) |
|
||||
|
|
||||
int |
|
||||
MOS9temp(inModel,ckt) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
double wkfngs; |
|
||||
double wkfng; |
|
||||
double fermig; |
|
||||
double fermis; |
|
||||
double vfb; |
|
||||
double fact1,fact2; |
|
||||
double vt,vtnom; |
|
||||
double kt,kt1; |
|
||||
double ratio,ratio4; |
|
||||
double egfet,egfet1; |
|
||||
double pbfact,pbfact1,pbo; |
|
||||
double phio; |
|
||||
double arg1; |
|
||||
double capfact; |
|
||||
double gmanew,gmaold; |
|
||||
double ni_temp, nifact; |
|
||||
/* loop through all the mosfet models */ |
|
||||
for( ; model != NULL; model = model->MOS9nextModel) { |
|
||||
|
|
||||
if(!model->MOS9tnomGiven) { |
|
||||
model->MOS9tnom = ckt->CKTnomTemp; |
|
||||
} |
|
||||
fact1 = model->MOS9tnom/REFTEMP; |
|
||||
vtnom = model->MOS9tnom*CONSTKoverQ; |
|
||||
kt1 = CONSTboltz * model->MOS9tnom; |
|
||||
egfet1 = 1.16-(7.02e-4*model->MOS9tnom*model->MOS9tnom)/ |
|
||||
(model->MOS9tnom+1108); |
|
||||
arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
|
||||
pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); |
|
||||
|
|
||||
nifact=(model->MOS9tnom/300)*sqrt(model->MOS9tnom/300); |
|
||||
nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS9tnom))/ |
|
||||
CONSTKoverQ); |
|
||||
ni_temp=1.45e16*nifact;
|
|
||||
|
|
||||
|
|
||||
model->MOS9oxideCapFactor = 3.9 * 8.854214871e-12/ |
|
||||
model->MOS9oxideThickness; |
|
||||
if(!model->MOS9surfaceMobilityGiven) model->MOS9surfaceMobility=600; |
|
||||
if(!model->MOS9transconductanceGiven) { |
|
||||
model->MOS9transconductance = model->MOS9surfaceMobility * |
|
||||
model->MOS9oxideCapFactor * 1e-4; |
|
||||
} |
|
||||
if(model->MOS9substrateDopingGiven) { |
|
||||
if(model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) { |
|
||||
|
Modified: Alan Gillespie |
||||
|
**********/ |
||||
|
|
||||
if(!model->MOS9phiGiven) { |
|
||||
model->MOS9phi = 2*vtnom* |
|
||||
log(model->MOS9substrateDoping* |
|
||||
|
|
||||
1e6/*(cm**3/m**3)*//ni_temp); |
|
||||
|
|
||||
model->MOS9phi = MAX(.1,model->MOS9phi); |
|
||||
} |
|
||||
fermis = model->MOS9type * .5 * model->MOS9phi; |
|
||||
wkfng = 3.2; |
|
||||
if(!model->MOS9gateTypeGiven) model->MOS9gateType=1; |
|
||||
if(model->MOS9gateType != 0) { |
|
||||
fermig = model->MOS9type * model->MOS9gateType*.5*egfet1; |
|
||||
wkfng = 3.25 + .5 * egfet1 - fermig; |
|
||||
} |
|
||||
wkfngs = wkfng - (3.25 + .5 * egfet1 +fermis); |
|
||||
if(!model->MOS9gammaGiven) { |
|
||||
model->MOS9gamma = sqrt(2 * EPSSIL * |
|
||||
CHARGE * model->MOS9substrateDoping* |
|
||||
1e6 /*(cm**3/m**3)*/ )/ model->MOS9oxideCapFactor; |
|
||||
} |
|
||||
if(!model->MOS9vt0Given) { |
|
||||
if(!model->MOS9surfaceStateDensityGiven) |
|
||||
model->MOS9surfaceStateDensity=0; |
|
||||
vfb = wkfngs - model->MOS9surfaceStateDensity * 1e4 |
|
||||
* CHARGE/model->MOS9oxideCapFactor; |
|
||||
model->MOS9vt0 = vfb + model->MOS9type * |
|
||||
(model->MOS9gamma * sqrt(model->MOS9phi)+ |
|
||||
model->MOS9phi); |
|
||||
} else { |
|
||||
vfb = model->MOS9vt0 - model->MOS9type * (model->MOS9gamma* |
|
||||
sqrt(model->MOS9phi)+model->MOS9phi); |
|
||||
} |
|
||||
model->MOS9alpha = (EPSSIL+EPSSIL)/ |
|
||||
(CHARGE*model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ ); |
|
||||
model->MOS9coeffDepLayWidth = sqrt(model->MOS9alpha); |
|
||||
} else { |
|
||||
model->MOS9substrateDoping = 0; |
|
||||
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
|
||||
"%s: Nsub < Ni ",&(model->MOS9modName)); |
|
||||
return(E_BADPARM); |
|
||||
} |
|
||||
} |
|
||||
/* now model parameter preprocessing */ |
|
||||
model->MOS9narrowFactor = model->MOS9delta * 0.5 * M_PI * EPSSIL / |
|
||||
model->MOS9oxideCapFactor ; |
|
||||
|
|
||||
|
|
||||
/* loop through all instances of the model */ |
|
||||
for(here = model->MOS9instances; here!= NULL; |
|
||||
here = here->MOS9nextInstance) { |
|
||||
|
|
||||
double czbd; /* zero voltage bulk-drain capacitance */ |
|
||||
double czbdsw; /* zero voltage bulk-drain sidewall capacitance */ |
|
||||
double czbs; /* zero voltage bulk-source capacitance */ |
|
||||
double czbssw; /* zero voltage bulk-source sidewall capacitance */ |
|
||||
double arg; /* 1 - fc */ |
|
||||
double sarg; /* (1-fc) ^^ (-mj) */ |
|
||||
double sargsw; /* (1-fc) ^^ (-mjsw) */ |
|
||||
|
|
||||
/* perform the parameter defaulting */ |
|
||||
|
|
||||
if(!here->MOS9tempGiven) { |
|
||||
here->MOS9temp = ckt->CKTtemp; |
|
||||
} |
|
||||
vt = here->MOS9temp * CONSTKoverQ; |
|
||||
ratio = here->MOS9temp/model->MOS9tnom; |
|
||||
fact2 = here->MOS9temp/REFTEMP; |
|
||||
kt = here->MOS9temp * CONSTboltz; |
|
||||
egfet = 1.16-(7.02e-4*here->MOS9temp*here->MOS9temp)/ |
|
||||
(here->MOS9temp+1108); |
|
||||
arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
|
||||
pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); |
|
||||
|
|
||||
if(!here->MOS9mGiven) { |
|
||||
here->MOS9m = ckt->CKTdefaultMosM; |
|
||||
} |
|
||||
|
|
||||
if(!here->MOS9lGiven) { |
|
||||
here->MOS9l = ckt->CKTdefaultMosL; |
|
||||
} |
|
||||
if(!here->MOS9sourceAreaGiven) { |
|
||||
here->MOS9sourceArea = ckt->CKTdefaultMosAS; |
|
||||
} |
|
||||
if(!here->MOS9wGiven) { |
|
||||
here->MOS9w = ckt->CKTdefaultMosW; |
|
||||
} |
|
||||
if(model->MOS9drainResistanceGiven) { |
|
||||
if(model->MOS9drainResistance != 0) { |
|
||||
here->MOS9drainConductance = here->MOS9m / |
|
||||
model->MOS9drainResistance; |
|
||||
} else { |
|
||||
here->MOS9drainConductance = 0; |
|
||||
} |
|
||||
} else if (model->MOS9sheetResistanceGiven) { |
|
||||
if ((model->MOS9sheetResistance != 0) && |
|
||||
(here->MOS9drainSquares != 0)) { |
|
||||
here->MOS9drainConductance = |
|
||||
here->MOS9m / |
|
||||
(model->MOS9sheetResistance*here->MOS9drainSquares); |
|
||||
} else { |
|
||||
here->MOS9drainConductance = 0; |
|
||||
} |
|
||||
} else { |
|
||||
here->MOS9drainConductance = 0; |
|
||||
} |
|
||||
if(model->MOS9sourceResistanceGiven) { |
|
||||
if(model->MOS9sourceResistance != 0) { |
|
||||
here->MOS9sourceConductance = here->MOS9m / |
|
||||
model->MOS9sourceResistance; |
|
||||
} else { |
|
||||
here->MOS9sourceConductance = 0; |
|
||||
} |
|
||||
} else if (model->MOS9sheetResistanceGiven) { |
|
||||
if ((model->MOS9sheetResistance != 0) && |
|
||||
(here->MOS9sourceSquares != 0)) { |
|
||||
here->MOS9sourceConductance = |
|
||||
here->MOS9m / |
|
||||
(model->MOS9sheetResistance*here->MOS9sourceSquares); |
|
||||
} else { |
|
||||
here->MOS9sourceConductance = 0; |
|
||||
} |
|
||||
} else { |
|
||||
here->MOS9sourceConductance = 0; |
|
||||
} |
|
||||
|
|
||||
if(here->MOS9l - 2 * model->MOS9latDiff + |
|
||||
model->MOS9lengthAdjust <1e-6) { |
|
||||
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
|
||||
"%s: effective channel length less than zero", |
|
||||
&(here->MOS9name)); |
|
||||
return(E_PARMVAL); |
|
||||
} |
|
||||
|
|
||||
if(here->MOS9w - 2 * model->MOS9widthNarrow + |
|
||||
model->MOS9widthAdjust <1e-6) { |
|
||||
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
|
||||
"%s: effective channel width less than zero", |
|
||||
&(here->MOS9name)); |
|
||||
return(E_PARMVAL); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
ratio4 = ratio * sqrt(ratio); |
|
||||
here->MOS9tTransconductance = model->MOS9transconductance / ratio4; |
|
||||
here->MOS9tSurfMob = model->MOS9surfaceMobility/ratio4; |
|
||||
phio= (model->MOS9phi-pbfact1)/fact1; |
|
||||
here->MOS9tPhi = fact2 * phio + pbfact; |
|
||||
here->MOS9tVbi = |
|
||||
model->MOS9delvt0 + |
|
||||
model->MOS9vt0 - model->MOS9type * |
|
||||
(model->MOS9gamma* sqrt(model->MOS9phi)) |
|
||||
+.5*(egfet1-egfet) |
|
||||
+ model->MOS9type*.5* (here->MOS9tPhi-model->MOS9phi); |
|
||||
here->MOS9tVto = here->MOS9tVbi + model->MOS9type * |
|
||||
model->MOS9gamma * sqrt(here->MOS9tPhi); |
|
||||
here->MOS9tSatCur = model->MOS9jctSatCur* |
|
||||
exp(-egfet/vt+egfet1/vtnom); |
|
||||
here->MOS9tSatCurDens = model->MOS9jctSatCurDensity * |
|
||||
exp(-egfet/vt+egfet1/vtnom); |
|
||||
pbo = (model->MOS9bulkJctPotential - pbfact1)/fact1; |
|
||||
gmaold = (model->MOS9bulkJctPotential-pbo)/pbo; |
|
||||
capfact = 1/(1+model->MOS9bulkJctBotGradingCoeff* |
|
||||
(4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); |
|
||||
here->MOS9tCbd = model->MOS9capBD * capfact; |
|
||||
here->MOS9tCbs = model->MOS9capBS * capfact; |
|
||||
here->MOS9tCj = model->MOS9bulkCapFactor * capfact; |
|
||||
capfact = 1/(1+model->MOS9bulkJctSideGradingCoeff* |
|
||||
(4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); |
|
||||
here->MOS9tCjsw = model->MOS9sideWallCapFactor * capfact; |
|
||||
here->MOS9tBulkPot = fact2 * pbo+pbfact; |
|
||||
gmanew = (here->MOS9tBulkPot-pbo)/pbo; |
|
||||
capfact = (1+model->MOS9bulkJctBotGradingCoeff* |
|
||||
(4e-4*(here->MOS9temp-REFTEMP)-gmanew)); |
|
||||
here->MOS9tCbd *= capfact; |
|
||||
here->MOS9tCbs *= capfact; |
|
||||
here->MOS9tCj *= capfact; |
|
||||
capfact = (1+model->MOS9bulkJctSideGradingCoeff* |
|
||||
(4e-4*(here->MOS9temp-REFTEMP)-gmanew)); |
|
||||
here->MOS9tCjsw *= capfact; |
|
||||
here->MOS9tDepCap = model->MOS9fwdCapDepCoeff * here->MOS9tBulkPot; |
|
||||
|
|
||||
if( (model->MOS9jctSatCurDensity == 0) || |
|
||||
(here->MOS9drainArea == 0) || |
|
||||
(here->MOS9sourceArea == 0) ) { |
|
||||
here->MOS9sourceVcrit = here->MOS9drainVcrit = |
|
||||
vt*log(vt/(CONSTroot2*here->MOS9m*here->MOS9tSatCur)); |
|
||||
} else { |
|
||||
here->MOS9drainVcrit = |
|
||||
vt * log( vt / (CONSTroot2 * |
|
||||
here->MOS9m * |
|
||||
here->MOS9tSatCurDens * here->MOS9drainArea)); |
|
||||
here->MOS9sourceVcrit = |
|
||||
vt * log( vt / (CONSTroot2 * |
|
||||
here->MOS9m * |
|
||||
here->MOS9tSatCurDens * here->MOS9sourceArea)); |
|
||||
} |
|
||||
if(model->MOS9capBDGiven) { |
|
||||
czbd = here->MOS9tCbd * here->MOS9m; |
|
||||
} else { |
|
||||
if(model->MOS9bulkCapFactorGiven) { |
|
||||
czbd=here->MOS9tCj*here->MOS9drainArea * here->MOS9m; |
|
||||
} else { |
|
||||
czbd=0; |
|
||||
} |
|
||||
} |
|
||||
if(model->MOS9sideWallCapFactorGiven) { |
|
||||
czbdsw= here->MOS9tCjsw * here->MOS9drainPerimiter * |
|
||||
here->MOS9m; |
|
||||
} else { |
|
||||
czbdsw=0; |
|
||||
} |
|
||||
arg = 1-model->MOS9fwdCapDepCoeff; |
|
||||
sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); |
|
||||
sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); |
|
||||
here->MOS9Cbd = czbd; |
|
||||
here->MOS9Cbdsw = czbdsw; |
|
||||
here->MOS9f2d = czbd*(1-model->MOS9fwdCapDepCoeff* |
|
||||
(1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg |
|
||||
+ czbdsw*(1-model->MOS9fwdCapDepCoeff* |
|
||||
(1+model->MOS9bulkJctSideGradingCoeff))* |
|
||||
sargsw/arg; |
|
||||
here->MOS9f3d = czbd * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ |
|
||||
here->MOS9tBulkPot |
|
||||
+ czbdsw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / |
|
||||
here->MOS9tBulkPot;
|
|
||||
here->MOS9f4d = czbd*here->MOS9tBulkPot*(1-arg*sarg)/ |
|
||||
(1-model->MOS9bulkJctBotGradingCoeff) |
|
||||
+ czbdsw*here->MOS9tBulkPot*(1-arg*sargsw)/ |
|
||||
(1-model->MOS9bulkJctSideGradingCoeff) |
|
||||
-here->MOS9f3d/2* |
|
||||
(here->MOS9tDepCap*here->MOS9tDepCap) |
|
||||
-here->MOS9tDepCap * here->MOS9f2d; |
|
||||
if(model->MOS9capBSGiven) { |
|
||||
czbs = here->MOS9tCbs * here->MOS9m; |
|
||||
} else { |
|
||||
if(model->MOS9bulkCapFactorGiven) { |
|
||||
czbs=here->MOS9tCj*here->MOS9sourceArea * here->MOS9m; |
|
||||
} else { |
|
||||
czbs=0; |
|
||||
} |
|
||||
} |
|
||||
if(model->MOS9sideWallCapFactorGiven) { |
|
||||
czbssw = here->MOS9tCjsw * here->MOS9sourcePerimiter * |
|
||||
here->MOS9m; |
|
||||
} else { |
|
||||
czbssw=0; |
|
||||
} |
|
||||
arg = 1-model->MOS9fwdCapDepCoeff; |
|
||||
sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); |
|
||||
sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); |
|
||||
here->MOS9Cbs = czbs; |
|
||||
here->MOS9Cbssw = czbssw; |
|
||||
here->MOS9f2s = czbs*(1-model->MOS9fwdCapDepCoeff* |
|
||||
(1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg |
|
||||
+ czbssw*(1-model->MOS9fwdCapDepCoeff* |
|
||||
(1+model->MOS9bulkJctSideGradingCoeff))* |
|
||||
sargsw/arg; |
|
||||
here->MOS9f3s = czbs * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ |
|
||||
here->MOS9tBulkPot |
|
||||
+ czbssw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / |
|
||||
here->MOS9tBulkPot; |
|
||||
here->MOS9f4s = czbs*here->MOS9tBulkPot*(1-arg*sarg)/ |
|
||||
(1-model->MOS9bulkJctBotGradingCoeff) |
|
||||
+ czbssw*here->MOS9tBulkPot*(1-arg*sargsw)/ |
|
||||
(1-model->MOS9bulkJctSideGradingCoeff) |
|
||||
-here->MOS9f3s/2* |
|
||||
(here->MOS9tDepCap*here->MOS9tDepCap) |
|
||||
-here->MOS9tDepCap * here->MOS9f2s; |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "const.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
/* assuming silicon - make definition for epsilon of silicon */ |
||||
|
#define EPSSIL (11.7 * 8.854214871e-12) |
||||
|
|
||||
|
int |
||||
|
MOS9temp(inModel,ckt) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
double wkfngs; |
||||
|
double wkfng; |
||||
|
double fermig; |
||||
|
double fermis; |
||||
|
double vfb; |
||||
|
double fact1,fact2; |
||||
|
double vt,vtnom; |
||||
|
double kt,kt1; |
||||
|
double ratio,ratio4; |
||||
|
double egfet,egfet1; |
||||
|
double pbfact,pbfact1,pbo; |
||||
|
double phio; |
||||
|
double arg1; |
||||
|
double capfact; |
||||
|
double gmanew,gmaold; |
||||
|
double ni_temp, nifact; |
||||
|
/* loop through all the mosfet models */ |
||||
|
for( ; model != NULL; model = model->MOS9nextModel) { |
||||
|
|
||||
|
if(!model->MOS9tnomGiven) { |
||||
|
model->MOS9tnom = ckt->CKTnomTemp; |
||||
|
} |
||||
|
fact1 = model->MOS9tnom/REFTEMP; |
||||
|
vtnom = model->MOS9tnom*CONSTKoverQ; |
||||
|
kt1 = CONSTboltz * model->MOS9tnom; |
||||
|
egfet1 = 1.16-(7.02e-4*model->MOS9tnom*model->MOS9tnom)/ |
||||
|
(model->MOS9tnom+1108); |
||||
|
arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
||||
|
pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1); |
||||
|
|
||||
|
nifact=(model->MOS9tnom/300)*sqrt(model->MOS9tnom/300); |
||||
|
nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS9tnom))/ |
||||
|
CONSTKoverQ); |
||||
|
ni_temp=1.45e16*nifact;
|
||||
|
|
||||
|
|
||||
|
model->MOS9oxideCapFactor = 3.9 * 8.854214871e-12/ |
||||
|
model->MOS9oxideThickness; |
||||
|
if(!model->MOS9surfaceMobilityGiven) model->MOS9surfaceMobility=600; |
||||
|
if(!model->MOS9transconductanceGiven) { |
||||
|
model->MOS9transconductance = model->MOS9surfaceMobility * |
||||
|
model->MOS9oxideCapFactor * 1e-4; |
||||
|
} |
||||
|
if(model->MOS9substrateDopingGiven) { |
||||
|
if(model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) { |
||||
|
|
||||
|
if(!model->MOS9phiGiven) { |
||||
|
model->MOS9phi = 2*vtnom* |
||||
|
log(model->MOS9substrateDoping* |
||||
|
|
||||
|
1e6/*(cm**3/m**3)*//ni_temp); |
||||
|
|
||||
|
model->MOS9phi = MAX(.1,model->MOS9phi); |
||||
|
} |
||||
|
fermis = model->MOS9type * .5 * model->MOS9phi; |
||||
|
wkfng = 3.2; |
||||
|
if(!model->MOS9gateTypeGiven) model->MOS9gateType=1; |
||||
|
if(model->MOS9gateType != 0) { |
||||
|
fermig = model->MOS9type * model->MOS9gateType*.5*egfet1; |
||||
|
wkfng = 3.25 + .5 * egfet1 - fermig; |
||||
|
} |
||||
|
wkfngs = wkfng - (3.25 + .5 * egfet1 +fermis); |
||||
|
if(!model->MOS9gammaGiven) { |
||||
|
model->MOS9gamma = sqrt(2 * EPSSIL * |
||||
|
CHARGE * model->MOS9substrateDoping* |
||||
|
1e6 /*(cm**3/m**3)*/ )/ model->MOS9oxideCapFactor; |
||||
|
} |
||||
|
if(!model->MOS9vt0Given) { |
||||
|
if(!model->MOS9surfaceStateDensityGiven) |
||||
|
model->MOS9surfaceStateDensity=0; |
||||
|
vfb = wkfngs - model->MOS9surfaceStateDensity * 1e4 |
||||
|
* CHARGE/model->MOS9oxideCapFactor; |
||||
|
model->MOS9vt0 = vfb + model->MOS9type * |
||||
|
(model->MOS9gamma * sqrt(model->MOS9phi)+ |
||||
|
model->MOS9phi); |
||||
|
} else { |
||||
|
vfb = model->MOS9vt0 - model->MOS9type * (model->MOS9gamma* |
||||
|
sqrt(model->MOS9phi)+model->MOS9phi); |
||||
|
} |
||||
|
model->MOS9alpha = (EPSSIL+EPSSIL)/ |
||||
|
(CHARGE*model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ ); |
||||
|
model->MOS9coeffDepLayWidth = sqrt(model->MOS9alpha); |
||||
|
} else { |
||||
|
model->MOS9substrateDoping = 0; |
||||
|
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
||||
|
"%s: Nsub < Ni ",&(model->MOS9modName)); |
||||
|
return(E_BADPARM); |
||||
|
} |
||||
|
} |
||||
|
/* now model parameter preprocessing */ |
||||
|
model->MOS9narrowFactor = model->MOS9delta * 0.5 * M_PI * EPSSIL / |
||||
|
model->MOS9oxideCapFactor ; |
||||
|
|
||||
|
|
||||
|
/* loop through all instances of the model */ |
||||
|
for(here = model->MOS9instances; here!= NULL; |
||||
|
here = here->MOS9nextInstance) { |
||||
|
|
||||
|
double czbd; /* zero voltage bulk-drain capacitance */ |
||||
|
double czbdsw; /* zero voltage bulk-drain sidewall capacitance */ |
||||
|
double czbs; /* zero voltage bulk-source capacitance */ |
||||
|
double czbssw; /* zero voltage bulk-source sidewall capacitance */ |
||||
|
double arg; /* 1 - fc */ |
||||
|
double sarg; /* (1-fc) ^^ (-mj) */ |
||||
|
double sargsw; /* (1-fc) ^^ (-mjsw) */ |
||||
|
|
||||
|
/* perform the parameter defaulting */ |
||||
|
|
||||
|
if(!here->MOS9tempGiven) { |
||||
|
here->MOS9temp = ckt->CKTtemp; |
||||
|
} |
||||
|
vt = here->MOS9temp * CONSTKoverQ; |
||||
|
ratio = here->MOS9temp/model->MOS9tnom; |
||||
|
fact2 = here->MOS9temp/REFTEMP; |
||||
|
kt = here->MOS9temp * CONSTboltz; |
||||
|
egfet = 1.16-(7.02e-4*here->MOS9temp*here->MOS9temp)/ |
||||
|
(here->MOS9temp+1108); |
||||
|
arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
||||
|
pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg); |
||||
|
|
||||
|
if(!here->MOS9mGiven) { |
||||
|
here->MOS9m = ckt->CKTdefaultMosM; |
||||
|
} |
||||
|
|
||||
|
if(!here->MOS9lGiven) { |
||||
|
here->MOS9l = ckt->CKTdefaultMosL; |
||||
|
} |
||||
|
if(!here->MOS9sourceAreaGiven) { |
||||
|
here->MOS9sourceArea = ckt->CKTdefaultMosAS; |
||||
|
} |
||||
|
if(!here->MOS9wGiven) { |
||||
|
here->MOS9w = ckt->CKTdefaultMosW; |
||||
|
} |
||||
|
if(model->MOS9drainResistanceGiven) { |
||||
|
if(model->MOS9drainResistance != 0) { |
||||
|
here->MOS9drainConductance = here->MOS9m / |
||||
|
model->MOS9drainResistance; |
||||
|
} else { |
||||
|
here->MOS9drainConductance = 0; |
||||
|
} |
||||
|
} else if (model->MOS9sheetResistanceGiven) { |
||||
|
if ((model->MOS9sheetResistance != 0) && |
||||
|
(here->MOS9drainSquares != 0)) { |
||||
|
here->MOS9drainConductance = |
||||
|
here->MOS9m / |
||||
|
(model->MOS9sheetResistance*here->MOS9drainSquares); |
||||
|
} else { |
||||
|
here->MOS9drainConductance = 0; |
||||
|
} |
||||
|
} else { |
||||
|
here->MOS9drainConductance = 0; |
||||
|
} |
||||
|
if(model->MOS9sourceResistanceGiven) { |
||||
|
if(model->MOS9sourceResistance != 0) { |
||||
|
here->MOS9sourceConductance = here->MOS9m / |
||||
|
model->MOS9sourceResistance; |
||||
|
} else { |
||||
|
here->MOS9sourceConductance = 0; |
||||
|
} |
||||
|
} else if (model->MOS9sheetResistanceGiven) { |
||||
|
if ((model->MOS9sheetResistance != 0) && |
||||
|
(here->MOS9sourceSquares != 0)) { |
||||
|
here->MOS9sourceConductance = |
||||
|
here->MOS9m / |
||||
|
(model->MOS9sheetResistance*here->MOS9sourceSquares); |
||||
|
} else { |
||||
|
here->MOS9sourceConductance = 0; |
||||
|
} |
||||
|
} else { |
||||
|
here->MOS9sourceConductance = 0; |
||||
|
} |
||||
|
|
||||
|
if(here->MOS9l - 2 * model->MOS9latDiff + |
||||
|
model->MOS9lengthAdjust <1e-6) { |
||||
|
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
||||
|
"%s: effective channel length less than zero", |
||||
|
&(here->MOS9name)); |
||||
|
return(E_PARMVAL); |
||||
|
} |
||||
|
|
||||
|
if(here->MOS9w - 2 * model->MOS9widthNarrow + |
||||
|
model->MOS9widthAdjust <1e-6) { |
||||
|
(*(SPfrontEnd->IFerror))(ERR_FATAL, |
||||
|
"%s: effective channel width less than zero", |
||||
|
&(here->MOS9name)); |
||||
|
return(E_PARMVAL); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
ratio4 = ratio * sqrt(ratio); |
||||
|
here->MOS9tTransconductance = model->MOS9transconductance / ratio4; |
||||
|
here->MOS9tSurfMob = model->MOS9surfaceMobility/ratio4; |
||||
|
phio= (model->MOS9phi-pbfact1)/fact1; |
||||
|
here->MOS9tPhi = fact2 * phio + pbfact; |
||||
|
here->MOS9tVbi = |
||||
|
model->MOS9delvt0 + |
||||
|
model->MOS9vt0 - model->MOS9type * |
||||
|
(model->MOS9gamma* sqrt(model->MOS9phi)) |
||||
|
+.5*(egfet1-egfet) |
||||
|
+ model->MOS9type*.5* (here->MOS9tPhi-model->MOS9phi); |
||||
|
here->MOS9tVto = here->MOS9tVbi + model->MOS9type * |
||||
|
model->MOS9gamma * sqrt(here->MOS9tPhi); |
||||
|
here->MOS9tSatCur = model->MOS9jctSatCur* |
||||
|
exp(-egfet/vt+egfet1/vtnom); |
||||
|
here->MOS9tSatCurDens = model->MOS9jctSatCurDensity * |
||||
|
exp(-egfet/vt+egfet1/vtnom); |
||||
|
pbo = (model->MOS9bulkJctPotential - pbfact1)/fact1; |
||||
|
gmaold = (model->MOS9bulkJctPotential-pbo)/pbo; |
||||
|
capfact = 1/(1+model->MOS9bulkJctBotGradingCoeff* |
||||
|
(4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); |
||||
|
here->MOS9tCbd = model->MOS9capBD * capfact; |
||||
|
here->MOS9tCbs = model->MOS9capBS * capfact; |
||||
|
here->MOS9tCj = model->MOS9bulkCapFactor * capfact; |
||||
|
capfact = 1/(1+model->MOS9bulkJctSideGradingCoeff* |
||||
|
(4e-4*(model->MOS9tnom-REFTEMP)-gmaold)); |
||||
|
here->MOS9tCjsw = model->MOS9sideWallCapFactor * capfact; |
||||
|
here->MOS9tBulkPot = fact2 * pbo+pbfact; |
||||
|
gmanew = (here->MOS9tBulkPot-pbo)/pbo; |
||||
|
capfact = (1+model->MOS9bulkJctBotGradingCoeff* |
||||
|
(4e-4*(here->MOS9temp-REFTEMP)-gmanew)); |
||||
|
here->MOS9tCbd *= capfact; |
||||
|
here->MOS9tCbs *= capfact; |
||||
|
here->MOS9tCj *= capfact; |
||||
|
capfact = (1+model->MOS9bulkJctSideGradingCoeff* |
||||
|
(4e-4*(here->MOS9temp-REFTEMP)-gmanew)); |
||||
|
here->MOS9tCjsw *= capfact; |
||||
|
here->MOS9tDepCap = model->MOS9fwdCapDepCoeff * here->MOS9tBulkPot; |
||||
|
|
||||
|
if( (model->MOS9jctSatCurDensity == 0) || |
||||
|
(here->MOS9drainArea == 0) || |
||||
|
(here->MOS9sourceArea == 0) ) { |
||||
|
here->MOS9sourceVcrit = here->MOS9drainVcrit = |
||||
|
vt*log(vt/(CONSTroot2*here->MOS9m*here->MOS9tSatCur)); |
||||
|
} else { |
||||
|
here->MOS9drainVcrit = |
||||
|
vt * log( vt / (CONSTroot2 * |
||||
|
here->MOS9m * |
||||
|
here->MOS9tSatCurDens * here->MOS9drainArea)); |
||||
|
here->MOS9sourceVcrit = |
||||
|
vt * log( vt / (CONSTroot2 * |
||||
|
here->MOS9m * |
||||
|
here->MOS9tSatCurDens * here->MOS9sourceArea)); |
||||
|
} |
||||
|
if(model->MOS9capBDGiven) { |
||||
|
czbd = here->MOS9tCbd * here->MOS9m; |
||||
|
} else { |
||||
|
if(model->MOS9bulkCapFactorGiven) { |
||||
|
czbd=here->MOS9tCj*here->MOS9drainArea * here->MOS9m; |
||||
|
} else { |
||||
|
czbd=0; |
||||
|
} |
||||
|
} |
||||
|
if(model->MOS9sideWallCapFactorGiven) { |
||||
|
czbdsw= here->MOS9tCjsw * here->MOS9drainPerimiter * |
||||
|
here->MOS9m; |
||||
|
} else { |
||||
|
czbdsw=0; |
||||
|
} |
||||
|
arg = 1-model->MOS9fwdCapDepCoeff; |
||||
|
sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); |
||||
|
sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); |
||||
|
here->MOS9Cbd = czbd; |
||||
|
here->MOS9Cbdsw = czbdsw; |
||||
|
here->MOS9f2d = czbd*(1-model->MOS9fwdCapDepCoeff* |
||||
|
(1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg |
||||
|
+ czbdsw*(1-model->MOS9fwdCapDepCoeff* |
||||
|
(1+model->MOS9bulkJctSideGradingCoeff))* |
||||
|
sargsw/arg; |
||||
|
here->MOS9f3d = czbd * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ |
||||
|
here->MOS9tBulkPot |
||||
|
+ czbdsw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / |
||||
|
here->MOS9tBulkPot; |
||||
|
here->MOS9f4d = czbd*here->MOS9tBulkPot*(1-arg*sarg)/ |
||||
|
(1-model->MOS9bulkJctBotGradingCoeff) |
||||
|
+ czbdsw*here->MOS9tBulkPot*(1-arg*sargsw)/ |
||||
|
(1-model->MOS9bulkJctSideGradingCoeff) |
||||
|
-here->MOS9f3d/2* |
||||
|
(here->MOS9tDepCap*here->MOS9tDepCap) |
||||
|
-here->MOS9tDepCap * here->MOS9f2d; |
||||
|
if(model->MOS9capBSGiven) { |
||||
|
czbs = here->MOS9tCbs * here->MOS9m; |
||||
|
} else { |
||||
|
if(model->MOS9bulkCapFactorGiven) { |
||||
|
czbs=here->MOS9tCj*here->MOS9sourceArea * here->MOS9m; |
||||
|
} else { |
||||
|
czbs=0; |
||||
|
} |
||||
|
} |
||||
|
if(model->MOS9sideWallCapFactorGiven) { |
||||
|
czbssw = here->MOS9tCjsw * here->MOS9sourcePerimiter * |
||||
|
here->MOS9m; |
||||
|
} else { |
||||
|
czbssw=0; |
||||
|
} |
||||
|
arg = 1-model->MOS9fwdCapDepCoeff; |
||||
|
sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) ); |
||||
|
sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) ); |
||||
|
here->MOS9Cbs = czbs; |
||||
|
here->MOS9Cbssw = czbssw; |
||||
|
here->MOS9f2s = czbs*(1-model->MOS9fwdCapDepCoeff* |
||||
|
(1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg |
||||
|
+ czbssw*(1-model->MOS9fwdCapDepCoeff* |
||||
|
(1+model->MOS9bulkJctSideGradingCoeff))* |
||||
|
sargsw/arg; |
||||
|
here->MOS9f3s = czbs * model->MOS9bulkJctBotGradingCoeff * sarg/arg/ |
||||
|
here->MOS9tBulkPot |
||||
|
+ czbssw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg / |
||||
|
here->MOS9tBulkPot; |
||||
|
here->MOS9f4s = czbs*here->MOS9tBulkPot*(1-arg*sarg)/ |
||||
|
(1-model->MOS9bulkJctBotGradingCoeff) |
||||
|
+ czbssw*here->MOS9tBulkPot*(1-arg*sargsw)/ |
||||
|
(1-model->MOS9bulkJctSideGradingCoeff) |
||||
|
-here->MOS9f3s/2* |
||||
|
(here->MOS9tDepCap*here->MOS9tDepCap) |
||||
|
-here->MOS9tDepCap * here->MOS9f2s; |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
@ -1,31 +1,31 @@ |
|||||
/********** |
|
||||
Copyright 1990 Regents of the University of California. All rights reserved. |
|
||||
Author: 1985 Thomas L. Quarles |
|
||||
|
/********** |
||||
|
Copyright 1990 Regents of the University of California. All rights reserved. |
||||
|
Author: 1985 Thomas L. Quarles |
||||
Modified: Alan Gillespie |
Modified: Alan Gillespie |
||||
**********/ |
|
||||
|
|
||||
#include "ngspice.h" |
|
||||
#include <stdio.h> |
|
||||
#include "cktdefs.h" |
|
||||
#include "mos9defs.h" |
|
||||
#include "sperror.h" |
|
||||
#include "suffix.h" |
|
||||
|
|
||||
int |
|
||||
MOS9trunc(inModel,ckt,timeStep) |
|
||||
GENmodel *inModel; |
|
||||
CKTcircuit *ckt; |
|
||||
double *timeStep; |
|
||||
{ |
|
||||
MOS9model *model = (MOS9model *)inModel; |
|
||||
MOS9instance *here; |
|
||||
|
|
||||
for( ; model != NULL; model = model->MOS9nextModel) { |
|
||||
for(here=model->MOS9instances;here!=NULL;here = here->MOS9nextInstance){ |
|
||||
CKTterr(here->MOS9qgs,ckt,timeStep); |
|
||||
CKTterr(here->MOS9qgd,ckt,timeStep); |
|
||||
CKTterr(here->MOS9qgb,ckt,timeStep); |
|
||||
} |
|
||||
} |
|
||||
return(OK); |
|
||||
} |
|
||||
|
**********/ |
||||
|
|
||||
|
#include "ngspice.h" |
||||
|
#include <stdio.h> |
||||
|
#include "cktdefs.h" |
||||
|
#include "mos9defs.h" |
||||
|
#include "sperror.h" |
||||
|
#include "suffix.h" |
||||
|
|
||||
|
int |
||||
|
MOS9trunc(inModel,ckt,timeStep) |
||||
|
GENmodel *inModel; |
||||
|
CKTcircuit *ckt; |
||||
|
double *timeStep; |
||||
|
{ |
||||
|
MOS9model *model = (MOS9model *)inModel; |
||||
|
MOS9instance *here; |
||||
|
|
||||
|
for( ; model != NULL; model = model->MOS9nextModel) { |
||||
|
for(here=model->MOS9instances;here!=NULL;here = here->MOS9nextInstance){ |
||||
|
CKTterr(here->MOS9qgs,ckt,timeStep); |
||||
|
CKTterr(here->MOS9qgd,ckt,timeStep); |
||||
|
CKTterr(here->MOS9qgb,ckt,timeStep); |
||||
|
} |
||||
|
} |
||||
|
return(OK); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue