32 changed files with 0 additions and 7871 deletions
-
6src/spicelib/devices/bjt2/.cvsignore
-
45src/spicelib/devices/bjt2/Makefile.am
-
178src/spicelib/devices/bjt2/bjt2.c
-
106src/spicelib/devices/bjt2/bjt2acld.c
-
328src/spicelib/devices/bjt2/bjt2ask.c
-
76src/spicelib/devices/bjt2/bjt2conv.c
-
590src/spicelib/devices/bjt2/bjt2defs.h
-
39src/spicelib/devices/bjt2/bjt2del.c
-
46src/spicelib/devices/bjt2/bjt2dest.c
-
1838src/spicelib/devices/bjt2/bjt2disto.c
-
727src/spicelib/devices/bjt2/bjt2dset.c
-
5src/spicelib/devices/bjt2/bjt2dset.h
-
35src/spicelib/devices/bjt2/bjt2ext.h
-
49src/spicelib/devices/bjt2/bjt2getic.c
-
84src/spicelib/devices/bjt2/bjt2init.c
-
13src/spicelib/devices/bjt2/bjt2init.h
-
11src/spicelib/devices/bjt2/bjt2itf.h
-
817src/spicelib/devices/bjt2/bjt2load.c
-
231src/spicelib/devices/bjt2/bjt2mask.c
-
43src/spicelib/devices/bjt2/bjt2mdel.c
-
254src/spicelib/devices/bjt2/bjt2mpar.c
-
221src/spicelib/devices/bjt2/bjt2noise.c
-
86src/spicelib/devices/bjt2/bjt2param.c
-
120src/spicelib/devices/bjt2/bjt2pzld.c
-
712src/spicelib/devices/bjt2/bjt2sacl.c
-
348src/spicelib/devices/bjt2/bjt2setup.c
-
332src/spicelib/devices/bjt2/bjt2sload.c
-
54src/spicelib/devices/bjt2/bjt2sprt.c
-
52src/spicelib/devices/bjt2/bjt2sset.c
-
156src/spicelib/devices/bjt2/bjt2supd.c
-
231src/spicelib/devices/bjt2/bjt2temp.c
-
38src/spicelib/devices/bjt2/bjt2trun.c
@ -1,6 +0,0 @@ |
|||
Makefile.in |
|||
Makefile |
|||
.deps |
|||
.libs |
|||
*.lo |
|||
*.la |
|||
@ -1,45 +0,0 @@ |
|||
## Process this file with automake to produce Makefile.in
|
|||
|
|||
## Not all file are compiled in since this device need some additional
|
|||
## work.
|
|||
## Sensitivity analysis not compiled in.
|
|||
|
|||
noinst_LTLIBRARIES = libbjt2.la |
|||
|
|||
libbjt2_la_SOURCES = \
|
|||
bjt2.c \
|
|||
bjt2acld.c \
|
|||
bjt2ask.c \
|
|||
bjt2conv.c \
|
|||
bjt2defs.h \
|
|||
bjt2del.c \
|
|||
bjt2dest.c \
|
|||
bjt2disto.c \
|
|||
bjt2dset.c \
|
|||
bjt2dset.h \
|
|||
bjt2ext.h \
|
|||
bjt2getic.c \
|
|||
bjt2init.c \
|
|||
bjt2init.h \
|
|||
bjt2itf.h \
|
|||
bjt2load.c \
|
|||
bjt2mask.c \
|
|||
bjt2mdel.c \
|
|||
bjt2mpar.c \
|
|||
bjt2noise.c \
|
|||
bjt2param.c \
|
|||
bjt2pzld.c \
|
|||
bjt2sacl.c \
|
|||
bjt2setup.c \
|
|||
bjt2sload.c \
|
|||
bjt2sprt.c \
|
|||
bjt2sset.c \
|
|||
bjt2supd.c \
|
|||
bjt2temp.c \
|
|||
bjt2trun.c |
|||
|
|||
|
|||
|
|||
AM_CPPFLAGS = -I$(top_srcdir)/src/include |
|||
|
|||
MAINTAINERCLEANFILES = Makefile.in |
|||
@ -1,178 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This file defines the BJT2 data structures that are |
|||
* available to the next level(s) up the calling hierarchy |
|||
*/ |
|||
|
|||
/* |
|||
* You may define the preprocessor symbolo |
|||
* BJT2_COMPAT to enable compatibility with |
|||
* archaic spice2 bjt model |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "devdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "suffix.h" |
|||
|
|||
IFparm BJT2pTable[] = { /* parameters */ |
|||
IOPU("off", BJT2_OFF, IF_FLAG, "Device initially off"), |
|||
IOPAU("icvbe", BJT2_IC_VBE, IF_REAL, "Initial B-E voltage"), |
|||
IOPAU("icvce", BJT2_IC_VCE, IF_REAL, "Initial C-E voltage"), |
|||
IOPU("area", BJT2_AREA, IF_REAL, "(Emitter) Area factor"), |
|||
IOPU("areab", BJT2_AREAB, IF_REAL, "Base area factor"), |
|||
IOPU("areac", BJT2_AREAC, IF_REAL, "Collector area factor"), |
|||
IOPU("m", BJT2_M, IF_REAL, "Parallel Multiplier"), |
|||
IP("ic", BJT2_IC, IF_REALVEC, "Initial condition vector"), |
|||
IP("sens_area",BJT2_AREA_SENS,IF_FLAG, "flag to request sensitivity WRT area"), |
|||
OPU("colnode", BJT2_QUEST_COLNODE, IF_INTEGER, "Number of collector node"), |
|||
OPU("basenode", BJT2_QUEST_BASENODE, IF_INTEGER, "Number of base node"), |
|||
OPU("emitnode", BJT2_QUEST_EMITNODE, IF_INTEGER, "Number of emitter node"), |
|||
OPU("substnode",BJT2_QUEST_SUBSTNODE,IF_INTEGER, "Number of substrate node"), |
|||
OPU("colprimenode",BJT2_QUEST_COLPRIMENODE,IF_INTEGER, |
|||
"Internal collector node"), |
|||
OPU("baseprimenode",BJT2_QUEST_BASEPRIMENODE,IF_INTEGER,"Internal base node"), |
|||
OPU("emitprimenode",BJT2_QUEST_EMITPRIMENODE,IF_INTEGER, |
|||
"Internal emitter node"), |
|||
OP("ic", BJT2_QUEST_CC, IF_REAL, "Current at collector node"), |
|||
OP("ib", BJT2_QUEST_CB, IF_REAL, "Current at base node"), |
|||
OP("ie", BJT2_QUEST_CE, IF_REAL, "Emitter current"), |
|||
OPU("is", BJT2_QUEST_CS, IF_REAL, "Substrate current"), |
|||
OP("vbe", BJT2_QUEST_VBE, IF_REAL, "B-E voltage"), |
|||
OP("vbc", BJT2_QUEST_VBC, IF_REAL, "B-C voltage"), |
|||
OP("gm", BJT2_QUEST_GM, IF_REAL, "Small signal transconductance"), |
|||
OP("gpi", BJT2_QUEST_GPI, IF_REAL, "Small signal input conductance - pi"), |
|||
OP("gmu", BJT2_QUEST_GMU, IF_REAL, "Small signal conductance - mu"), |
|||
OP("gx", BJT2_QUEST_GX, IF_REAL, "Conductance from base to internal base"), |
|||
OP("go", BJT2_QUEST_GO, IF_REAL, "Small signal output conductance"), |
|||
OPU("geqcb",BJT2_QUEST_GEQCB,IF_REAL, "d(Ibe)/d(Vbc)"), |
|||
OPU("gcsub", BJT2_QUEST_GCSUB, IF_REAL, "Internal Subs. cap. equiv. cond."), |
|||
OPU("gdsub", BJT2_QUEST_GDSUB, IF_REAL, "Internal Subs. Diode equiv. cond."), |
|||
OPU("geqbx",BJT2_QUEST_GEQBX,IF_REAL, "Internal C-B-base cap. equiv. cond."), |
|||
|
|||
OP("cpi",BJT2_QUEST_CPI, IF_REAL, "Internal base to emitter capactance"), |
|||
OP("cmu",BJT2_QUEST_CMU, IF_REAL, "Internal base to collector capactiance"), |
|||
OP("cbx",BJT2_QUEST_CBX, IF_REAL, "Base to collector capacitance"), |
|||
OP("csub",BJT2_QUEST_CSUB, IF_REAL, "Substrate capacitance"), |
|||
OPU("cqbe",BJT2_QUEST_CQBE, IF_REAL, "Cap. due to charge storage in B-E jct."), |
|||
OPU("cqbc",BJT2_QUEST_CQBC, IF_REAL, "Cap. due to charge storage in B-C jct."), |
|||
OPU("cqsub", BJT2_QUEST_CQSUB, IF_REAL, "Cap. due to charge storage in Subs. jct."), |
|||
OPU("cqbx", BJT2_QUEST_CQBX, IF_REAL, "Cap. due to charge storage in B-X jct."), |
|||
OPU("cexbc",BJT2_QUEST_CEXBC,IF_REAL, "Total Capacitance in B-X junction"), |
|||
|
|||
OPU("qbe", BJT2_QUEST_QBE, IF_REAL, "Charge storage B-E junction"), |
|||
OPU("qbc", BJT2_QUEST_QBC, IF_REAL, "Charge storage B-C junction"), |
|||
OPU("qsub", BJT2_QUEST_QSUB, IF_REAL, "Charge storage Subs. junction"), |
|||
OPU("qbx", BJT2_QUEST_QBX, IF_REAL, "Charge storage B-X junction"), |
|||
OPU("p", BJT2_QUEST_POWER,IF_REAL, "Power dissipation"), |
|||
OPU("sens_dc", BJT2_QUEST_SENS_DC, IF_REAL, "dc sensitivity "), |
|||
OPU("sens_real", BJT2_QUEST_SENS_REAL, IF_REAL,"real part of ac sensitivity"), |
|||
OPU("sens_imag",BJT2_QUEST_SENS_IMAG,IF_REAL, |
|||
"dc sens. & imag part of ac sens."), |
|||
OPU("sens_mag", BJT2_QUEST_SENS_MAG, IF_REAL, "sensitivity of ac magnitude"), |
|||
OPU("sens_ph", BJT2_QUEST_SENS_PH, IF_REAL, "sensitivity of ac phase"), |
|||
OPU("sens_cplx", BJT2_QUEST_SENS_CPLX, IF_COMPLEX, "ac sensitivity"), |
|||
IOPU("temp", BJT2_TEMP, IF_REAL, "instance temperature"), |
|||
IOPU("dtemp", BJT2_DTEMP, IF_REAL, "instance temperature delta from circuit") |
|||
}; |
|||
|
|||
IFparm BJT2mPTable[] = { /* model parameters */ |
|||
OP("type", BJT2_MOD_TYPE, IF_STRING, "NPN or PNP"), |
|||
IOPU("npn", BJT2_MOD_NPN, IF_FLAG, "NPN type device"), |
|||
IOPU("pnp", BJT2_MOD_PNP, IF_FLAG, "PNP type device"), |
|||
IOPU("subs", BJT2_MOD_SUBS, IF_INTEGER, "Vertical or Lateral device"), |
|||
IOP("is", BJT2_MOD_IS, IF_REAL, "Saturation Current"), |
|||
IOP("iss", BJT2_MOD_ISS, IF_REAL, "Substrate Jct. Saturation Current"), |
|||
IOP("bf", BJT2_MOD_BF, IF_REAL, "Ideal forward beta"), |
|||
IOP("nf", BJT2_MOD_NF, IF_REAL, "Forward emission coefficient"), |
|||
IOP("vaf", BJT2_MOD_VAF, IF_REAL, "Forward Early voltage"), |
|||
IOPR("va", BJT2_MOD_VAF, IF_REAL, "Forward Early voltage"), |
|||
IOP("ikf", BJT2_MOD_IKF, IF_REAL, "Forward beta roll-off corner current"), |
|||
IOPR("ik", BJT2_MOD_IKF, IF_REAL, "Forward beta roll-off corner current"), |
|||
IOP("ise", BJT2_MOD_ISE, IF_REAL, "B-E leakage saturation current"), |
|||
#ifdef BJT2_COMPAT |
|||
IOP("c2", BJT2_MOD_C2, IF_REAL, "Obsolete parameter name"), |
|||
#endif |
|||
IOP("ne", BJT2_MOD_NE, IF_REAL, "B-E leakage emission coefficient"), |
|||
IOP("br", BJT2_MOD_BR, IF_REAL, "Ideal reverse beta"), |
|||
IOP("nr", BJT2_MOD_NR, IF_REAL, "Reverse emission coefficient"), |
|||
IOP("var", BJT2_MOD_VAR, IF_REAL, "Reverse Early voltage"), |
|||
IOPR("vb", BJT2_MOD_VAR, IF_REAL, "Reverse Early voltage"), |
|||
IOP("ikr", BJT2_MOD_IKR, IF_REAL, "reverse beta roll-off corner current"), |
|||
IOP("isc", BJT2_MOD_ISC, IF_REAL, "B-C leakage saturation current"), |
|||
#ifdef BJT2_COMPAT |
|||
IOP("c4", BJT2_MOD_C4, IF_REAL, "Obsolete parameter name"), |
|||
#endif |
|||
IOP("nc", BJT2_MOD_NC, IF_REAL, "B-C leakage emission coefficient"), |
|||
IOP("rb", BJT2_MOD_RB, IF_REAL, "Zero bias base resistance"), |
|||
IOP("irb", BJT2_MOD_IRB, IF_REAL, "Current for base resistance=(rb+rbm)/2"), |
|||
IOP("rbm", BJT2_MOD_RBM, IF_REAL, "Minimum base resistance"), |
|||
IOP("re", BJT2_MOD_RE, IF_REAL, "Emitter resistance"), |
|||
IOP("rc", BJT2_MOD_RC, IF_REAL, "Collector resistance"), |
|||
IOPA("cje", BJT2_MOD_CJE, IF_REAL,"Zero bias B-E depletion capacitance"), |
|||
IOPA("vje", BJT2_MOD_VJE, IF_REAL, "B-E built in potential"), |
|||
IOPR("pe", BJT2_MOD_VJE, IF_REAL, "B-E built in potential"), |
|||
IOPA("mje", BJT2_MOD_MJE, IF_REAL, "B-E junction grading coefficient"), |
|||
IOPR("me", BJT2_MOD_MJE, IF_REAL, "B-E junction grading coefficient"), |
|||
IOPA("tf", BJT2_MOD_TF, IF_REAL, "Ideal forward transit time"), |
|||
IOPA("xtf", BJT2_MOD_XTF, IF_REAL, "Coefficient for bias dependence of TF"), |
|||
IOPA("vtf", BJT2_MOD_VTF, IF_REAL, "Voltage giving VBC dependence of TF"), |
|||
IOPA("itf", BJT2_MOD_ITF, IF_REAL, "High current dependence of TF"), |
|||
IOPA("ptf", BJT2_MOD_PTF, IF_REAL, "Excess phase"), |
|||
IOPA("cjc", BJT2_MOD_CJC, IF_REAL, "Zero bias B-C depletion capacitance"), |
|||
IOPA("vjc", BJT2_MOD_VJC, IF_REAL, "B-C built in potential"), |
|||
IOPR("pc", BJT2_MOD_VJC, IF_REAL, "B-C built in potential"), |
|||
IOPA("mjc", BJT2_MOD_MJC, IF_REAL, "B-C junction grading coefficient"), |
|||
IOPR("mc", BJT2_MOD_MJC, IF_REAL, "B-C junction grading coefficient"), |
|||
IOPA("xcjc",BJT2_MOD_XCJC, IF_REAL, "Fraction of B-C cap to internal base"), |
|||
IOPA("tr", BJT2_MOD_TR, IF_REAL, "Ideal reverse transit time"), |
|||
IOPA("cjs", BJT2_MOD_CJS, IF_REAL, "Zero bias Substrate capacitance"), |
|||
IOPR("csub", BJT2_MOD_CJS, IF_REAL, "Zero bias Substrate capacitance"), |
|||
IOPA("vjs", BJT2_MOD_VJS, IF_REAL, "Substrate junction built in potential"), |
|||
IOPR("ps", BJT2_MOD_VJS, IF_REAL, "Substrate junction built in potential"), |
|||
IOPA("mjs", BJT2_MOD_MJS, IF_REAL, "Substrate junction grading coefficient"), |
|||
IOPR("ms", BJT2_MOD_MJS, IF_REAL, "Substrate junction grading coefficient"), |
|||
IOP("xtb", BJT2_MOD_XTB, IF_REAL, "Forward and reverse beta temp. exp."), |
|||
IOP("eg", BJT2_MOD_EG, IF_REAL, "Energy gap for IS temp. dependency"), |
|||
IOP("xti", BJT2_MOD_XTI, IF_REAL, "Temp. exponent for IS"), |
|||
IOP("tre1", BJT2_MOD_TRE1, IF_REAL, "Temp. coefficient 1 for RE"), |
|||
IOP("tre2", BJT2_MOD_TRE2, IF_REAL, "Temp. coefficient 2 for RE"), |
|||
IOP("trc1", BJT2_MOD_TRC1, IF_REAL, "Temp. coefficient 1 for RC"), |
|||
IOP("trc2", BJT2_MOD_TRC2, IF_REAL, "Temp. coefficient 2 for RC"), |
|||
IOP("trb1", BJT2_MOD_TRB1, IF_REAL, "Temp. coefficient 1 for RB"), |
|||
IOP("trb2", BJT2_MOD_TRB2, IF_REAL, "Temp. coefficient 2 for RB"), |
|||
IOP("trbm1", BJT2_MOD_TRBM1, IF_REAL, "Temp. coefficient 1 for RBM"), |
|||
IOP("trbm2", BJT2_MOD_TRBM2, IF_REAL, "Temp. coefficient 2 for RBM"), |
|||
IOP("fc", BJT2_MOD_FC, IF_REAL, "Forward bias junction fit parameter"), |
|||
OPU("invearlyvoltf",BJT2_MOD_INVEARLYF,IF_REAL,"Inverse early voltage:forward"), |
|||
OPU("invearlyvoltr",BJT2_MOD_INVEARLYR,IF_REAL,"Inverse early voltage:reverse"), |
|||
OPU("invrollofff",BJT2_MOD_INVROLLOFFF, IF_REAL,"Inverse roll off - forward"), |
|||
OPU("invrolloffr",BJT2_MOD_INVROLLOFFR, IF_REAL,"Inverse roll off - reverse"), |
|||
OPU("collectorconduct",BJT2_MOD_COLCONDUCT,IF_REAL,"Collector conductance"), |
|||
OPU("emitterconduct", BJT2_MOD_EMITTERCONDUCT,IF_REAL, "Emitter conductance"), |
|||
OPU("transtimevbcfact",BJT2_MOD_TRANSVBCFACT,IF_REAL,"Transit time VBC factor"), |
|||
OPU("excessphasefactor",BJT2_MOD_EXCESSPHASEFACTOR,IF_REAL, |
|||
"Excess phase fact."), |
|||
IOP("tnom", BJT2_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), |
|||
IOP("kf", BJT2_MOD_KF, IF_REAL, "Flicker Noise Coefficient"), |
|||
IOP("af",BJT2_MOD_AF, IF_REAL,"Flicker Noise Exponent") |
|||
}; |
|||
|
|||
char *BJT2names[] = { |
|||
"collector", |
|||
"base", |
|||
"emitter", |
|||
"substrate" |
|||
}; |
|||
|
|||
|
|||
int BJT2nSize = NUMELEMS(BJT2names); |
|||
int BJT2pTSize = NUMELEMS(BJT2pTable); |
|||
int BJT2mPTSize = NUMELEMS(BJT2mPTable); |
|||
int BJT2iSize = sizeof(BJT2instance); |
|||
int BJT2mSize = sizeof(BJT2model); |
|||
@ -1,106 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* Function to load the COMPLEX circuit matrix using the |
|||
* small signal parameters saved during a previous DC operating |
|||
* point analysis. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
int |
|||
BJT2acLoad(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2instance *here; |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
double gcpr; |
|||
double gepr; |
|||
double gpi; |
|||
double gmu; |
|||
double go; |
|||
double xgm; |
|||
double td; |
|||
double arg; |
|||
double gm; |
|||
double gx; |
|||
double xcpi; |
|||
double xcmu; |
|||
double xcbx; |
|||
double xcsub; |
|||
double xcmcb; |
|||
double m; |
|||
|
|||
for( ; model != NULL; model = model->BJT2nextModel) { |
|||
for( here = model->BJT2instances; here!= NULL; |
|||
here = here->BJT2nextInstance) { |
|||
|
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
m = here->BJT2m; |
|||
|
|||
gcpr=here->BJT2tCollectorConduct * here->BJT2area; |
|||
gepr=here->BJT2tEmitterConduct * here->BJT2area; |
|||
gpi= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
gmu= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
gm= *(ckt->CKTstate0 + here->BJT2gm); |
|||
go= *(ckt->CKTstate0 + here->BJT2go); |
|||
xgm=0; |
|||
td=model->BJT2excessPhaseFactor; |
|||
if(td != 0) { |
|||
arg = td*ckt->CKTomega; |
|||
gm = gm+go; |
|||
xgm = -gm * sin(arg); |
|||
gm = gm * cos(arg)-go; |
|||
} |
|||
gx= *(ckt->CKTstate0 + here->BJT2gx); |
|||
xcpi= *(ckt->CKTstate0 + here->BJT2cqbe) * ckt->CKTomega; |
|||
xcmu= *(ckt->CKTstate0 + here->BJT2cqbc) * ckt->CKTomega; |
|||
xcbx= *(ckt->CKTstate0 + here->BJT2cqbx) * ckt->CKTomega; |
|||
xcsub= *(ckt->CKTstate0 + here->BJT2cqsub) * ckt->CKTomega; |
|||
xcmcb= *(ckt->CKTstate0 + here->BJT2cexbc) * ckt->CKTomega; |
|||
*(here->BJT2colColPtr) += m * (gcpr); |
|||
*(here->BJT2baseBasePtr) += m * (gx); |
|||
*(here->BJT2baseBasePtr + 1) += m * (xcbx); |
|||
*(here->BJT2emitEmitPtr) += m * (gepr); |
|||
*(here->BJT2colPrimeColPrimePtr) += m * (gmu+go+gcpr); |
|||
*(here->BJT2colPrimeColPrimePtr + 1) += m * (xcmu+xcbx); |
|||
*(here->BJT2substConSubstConPtr + 1) += m * (xcsub); |
|||
*(here->BJT2basePrimeBasePrimePtr) += m * (gx+gpi+gmu); |
|||
*(here->BJT2basePrimeBasePrimePtr + 1) += m * (xcpi+xcmu+xcmcb); |
|||
*(here->BJT2emitPrimeEmitPrimePtr) += m * (gpi+gepr+gm+go); |
|||
*(here->BJT2emitPrimeEmitPrimePtr + 1) += m * (xcpi+xgm); |
|||
*(here->BJT2colColPrimePtr) += m * (-gcpr); |
|||
*(here->BJT2baseBasePrimePtr) += m * (-gx); |
|||
*(here->BJT2emitEmitPrimePtr) += m * (-gepr); |
|||
*(here->BJT2colPrimeColPtr) += m * (-gcpr); |
|||
*(here->BJT2colPrimeBasePrimePtr) += m * (-gmu+gm); |
|||
*(here->BJT2colPrimeBasePrimePtr + 1) += m * (-xcmu+xgm); |
|||
*(here->BJT2colPrimeEmitPrimePtr) += m * (-gm-go); |
|||
*(here->BJT2colPrimeEmitPrimePtr + 1) += m * (-xgm); |
|||
*(here->BJT2basePrimeBasePtr) += m * (-gx); |
|||
*(here->BJT2basePrimeColPrimePtr) += m * (-gmu); |
|||
*(here->BJT2basePrimeColPrimePtr + 1) += m * (-xcmu-xcmcb); |
|||
*(here->BJT2basePrimeEmitPrimePtr) += m * (-gpi); |
|||
*(here->BJT2basePrimeEmitPrimePtr + 1) += m * (-xcpi); |
|||
*(here->BJT2emitPrimeEmitPtr) += m * (-gepr); |
|||
*(here->BJT2emitPrimeColPrimePtr) += m * (-go); |
|||
*(here->BJT2emitPrimeColPrimePtr + 1) += m * (xcmcb); |
|||
*(here->BJT2emitPrimeBasePrimePtr) += m * (-gpi-gm); |
|||
*(here->BJT2emitPrimeBasePrimePtr + 1) += m * (-xcpi-xgm-xcmcb); |
|||
*(here->BJT2substSubstPtr + 1) += m * (xcsub); |
|||
*(here->BJT2substConSubstPtr + 1) += m * (-xcsub); |
|||
*(here->BJT2substSubstConPtr + 1) += m * (-xcsub); |
|||
*(here->BJT2baseColPrimePtr + 1) += m * (-xcbx); |
|||
*(here->BJT2colPrimeBasePtr + 1) += m * (-xcbx); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,328 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Mathew Lew and Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This routine gives access to the internal device |
|||
* parameters for BJT2s |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "const.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "ifsim.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
/*ARGSUSED*/ |
|||
int |
|||
BJT2ask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, |
|||
IFvalue *select) |
|||
{ |
|||
BJT2instance *here = (BJT2instance*)instPtr; |
|||
double tmp; |
|||
int itmp; |
|||
double vr; |
|||
double vi; |
|||
double sr; |
|||
double si; |
|||
double vm; |
|||
static char *msg = "Current and power not available for ac analysis"; |
|||
switch(which) { |
|||
case BJT2_QUEST_FT: |
|||
tmp = MAX(*(ckt->CKTstate0 + here->BJT2cqbc), |
|||
*(ckt->CKTstate0 + here->BJT2cqbx)); |
|||
value->rValue = here->BJT2gm/(2 * M_PI * |
|||
MAX(*(ckt->CKTstate0 + here->BJT2cqbe),tmp)); |
|||
return(OK); |
|||
case BJT2_TEMP: |
|||
value->rValue = here->BJT2temp - CONSTCtoK; |
|||
return(OK); |
|||
case BJT2_DTEMP: |
|||
value->rValue = here->BJT2dtemp; |
|||
return(OK); |
|||
case BJT2_AREA: |
|||
value->rValue = here->BJT2area; |
|||
return(OK); |
|||
case BJT2_AREAB: |
|||
value->rValue = here->BJT2areab; |
|||
return(OK); |
|||
case BJT2_AREAC: |
|||
value->rValue = here->BJT2areac; |
|||
return(OK); |
|||
case BJT2_M: |
|||
value->rValue = here->BJT2m; |
|||
return(OK); |
|||
case BJT2_OFF: |
|||
value->iValue = here->BJT2off; |
|||
return(OK); |
|||
case BJT2_IC_VBE: |
|||
value->rValue = here->BJT2icVBE; |
|||
return(OK); |
|||
case BJT2_IC_VCE: |
|||
value->rValue = here->BJT2icVCE; |
|||
return(OK); |
|||
case BJT2_QUEST_COLNODE: |
|||
value->iValue = here->BJT2colNode; |
|||
return(OK); |
|||
case BJT2_QUEST_BASENODE: |
|||
value->iValue = here->BJT2baseNode; |
|||
return(OK); |
|||
case BJT2_QUEST_EMITNODE: |
|||
value->iValue = here->BJT2emitNode; |
|||
return(OK); |
|||
case BJT2_QUEST_SUBSTNODE: |
|||
value->iValue = here->BJT2substNode; |
|||
return(OK); |
|||
case BJT2_QUEST_COLPRIMENODE: |
|||
value->iValue = here->BJT2colPrimeNode; |
|||
return(OK); |
|||
case BJT2_QUEST_BASEPRIMENODE: |
|||
value->iValue = here->BJT2basePrimeNode; |
|||
return(OK); |
|||
case BJT2_QUEST_EMITPRIMENODE: |
|||
value->iValue = here->BJT2emitPrimeNode; |
|||
return(OK); |
|||
case BJT2_QUEST_VBE: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2vbe); |
|||
return(OK); |
|||
case BJT2_QUEST_VBC: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2vbc); |
|||
return(OK); |
|||
case BJT2_QUEST_CC: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cc); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cb); |
|||
if (here->BJT2modPtr->BJT2subs==LATERAL) { |
|||
value->rValue -= *(ckt->CKTstate0 + here->BJT2cdsub); |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
!(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue -= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
} |
|||
}; |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GPI: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gpi); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GMU: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gmu); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GM: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gm); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GO: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2go); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_QBE: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2qbe); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CQBE: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_QBC: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2qbc); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CQBC: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_QSUB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2qsub); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CQSUB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_QBX: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2qbx); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CQBX: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GX: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gx); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CEXBC: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GEQCB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2geqcb); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GCSUB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gcsub); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GDSUB: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2gdsub); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_GEQBX: |
|||
value->rValue = *(ckt->CKTstate0 + here->BJT2geqbx); |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_SENS_DC: |
|||
if(ckt->CKTsenInfo){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_Sap[select->iValue + 1]+ |
|||
here->BJT2senParmNo); |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_SENS_REAL: |
|||
if(ckt->CKTsenInfo){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_RHS[select->iValue + 1]+ |
|||
here->BJT2senParmNo); |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_SENS_IMAG: |
|||
if(ckt->CKTsenInfo){ |
|||
value->rValue = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->BJT2senParmNo); |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_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->BJT2senParmNo); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->BJT2senParmNo); |
|||
value->rValue = (vr * sr + vi * si)/vm; |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_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->BJT2senParmNo); |
|||
si = *(ckt->CKTsenInfo->SEN_iRHS[select->iValue + 1]+ |
|||
here->BJT2senParmNo); |
|||
|
|||
value->rValue = (vr * si - vi * sr)/vm; |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_SENS_CPLX: |
|||
if(ckt->CKTsenInfo){ |
|||
itmp = select->iValue + 1; |
|||
value->cValue.real= *(ckt->CKTsenInfo->SEN_RHS[itmp]+ |
|||
here->BJT2senParmNo); |
|||
value->cValue.imag= *(ckt->CKTsenInfo->SEN_iRHS[itmp]+ |
|||
here->BJT2senParmNo); |
|||
} |
|||
return(OK); |
|||
case BJT2_QUEST_CS : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = TMALLOC(char, strlen(msg) + 1); |
|||
errRtn = "BJT2ask"; |
|||
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 = -(here->BJT2modPtr->BJT2subs * |
|||
(*(ckt->CKTstate0 + here->BJT2cqsub) + |
|||
*(ckt->CKTstate0 + here->BJT2cdsub))); |
|||
} |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CE : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = TMALLOC(char, strlen(msg) + 1); |
|||
errRtn = "BJT2ask"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKCURRENT); |
|||
} else { |
|||
value->rValue = -*(ckt->CKTstate0 + here->BJT2cc); |
|||
value->rValue -= *(ckt->CKTstate0 + here->BJT2cb); |
|||
if (here->BJT2modPtr->BJT2subs==VERTICAL) { |
|||
value->rValue += *(ckt->CKTstate0 + here->BJT2cdsub); |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && |
|||
!(ckt->CKTmode & MODETRANOP)) { |
|||
value->rValue += *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
} |
|||
} |
|||
} |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_POWER : |
|||
if (ckt->CKTcurrentAnalysis & DOING_AC) { |
|||
errMsg = TMALLOC(char, strlen(msg) + 1); |
|||
errRtn = "BJT2ask"; |
|||
strcpy(errMsg,msg); |
|||
return(E_ASKPOWER); |
|||
} else { |
|||
value->rValue = fabs( *(ckt->CKTstate0 + here->BJT2cc) * |
|||
(*(ckt->CKTrhsOld + here->BJT2colNode)- |
|||
*(ckt->CKTrhsOld + here->BJT2emitNode)) |
|||
); |
|||
value->rValue +=fabs( *(ckt->CKTstate0 + here->BJT2cb) * |
|||
(*(ckt->CKTrhsOld + here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld + here->BJT2emitNode)) |
|||
); |
|||
value->rValue +=fabs( *(ckt->CKTstate0 + here->BJT2cdsub) * |
|||
(*(ckt->CKTrhsOld + here->BJT2substConNode)- |
|||
*(ckt->CKTrhsOld + here->BJT2substNode)) |
|||
); |
|||
if ((ckt->CKTcurrentAnalysis & DOING_TRAN) && !(ckt->CKTmode & |
|||
MODETRANOP)) { |
|||
value->rValue += *(ckt->CKTstate0 + here->BJT2cqsub) * |
|||
fabs(*(ckt->CKTrhsOld + here->BJT2substConNode)- |
|||
*(ckt->CKTrhsOld + here->BJT2substNode)); |
|||
} |
|||
} |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CPI: |
|||
value->rValue = here->BJT2capbe; |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CMU: |
|||
value->rValue = here->BJT2capbc; |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CBX: |
|||
value->rValue = here->BJT2capbx; |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
case BJT2_QUEST_CSUB: |
|||
value->rValue = here->BJT2capsub; |
|||
value->rValue *= here->BJT2m; |
|||
return(OK); |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
/* NOTREACHED */ |
|||
} |
|||
|
|||
@ -1,76 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This routine performs the device convergence test for |
|||
* BJT2s in the circuit. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
int |
|||
BJT2convTest(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2instance *here; |
|||
BJT2model *model = (BJT2model *) inModel; |
|||
double tol; |
|||
double cc; |
|||
double cchat; |
|||
double cb; |
|||
double cbhat; |
|||
double vbe; |
|||
double vbc; |
|||
double delvbe; |
|||
double delvbc; |
|||
|
|||
|
|||
|
|||
for( ; model != NULL; model = model->BJT2nextModel) { |
|||
for(here=model->BJT2instances;here!=NULL;here = here->BJT2nextInstance){ |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
vbe=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2basePrimeNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2emitPrimeNode)); |
|||
vbc=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2basePrimeNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
delvbe=vbe- *(ckt->CKTstate0 + here->BJT2vbe); |
|||
delvbc=vbc- *(ckt->CKTstate0 + here->BJT2vbc); |
|||
cchat= *(ckt->CKTstate0 + here->BJT2cc)+(*(ckt->CKTstate0 + |
|||
here->BJT2gm)+ *(ckt->CKTstate0 + here->BJT2go))*delvbe- |
|||
(*(ckt->CKTstate0 + here->BJT2go)+*(ckt->CKTstate0 + |
|||
here->BJT2gmu))*delvbc; |
|||
cbhat= *(ckt->CKTstate0 + here->BJT2cb)+ *(ckt->CKTstate0 + |
|||
here->BJT2gpi)*delvbe+ *(ckt->CKTstate0 + here->BJT2gmu)* |
|||
delvbc; |
|||
cc = *(ckt->CKTstate0 + here->BJT2cc); |
|||
cb = *(ckt->CKTstate0 + here->BJT2cb); |
|||
/* |
|||
* check convergence |
|||
*/ |
|||
tol=ckt->CKTreltol*MAX(fabs(cchat),fabs(cc))+ckt->CKTabstol; |
|||
if (fabs(cchat-cc) > tol) { |
|||
ckt->CKTnoncon++; |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
return(OK); /* no reason to continue - we've failed... */ |
|||
} else { |
|||
tol=ckt->CKTreltol*MAX(fabs(cbhat),fabs(cb))+ |
|||
ckt->CKTabstol; |
|||
if (fabs(cbhat-cb) > tol) { |
|||
ckt->CKTnoncon++; |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
return(OK); /* no reason to continue - we've failed... */ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,590 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
#ifndef BJT2 |
|||
#define BJT2 |
|||
|
|||
#include "cktdefs.h" |
|||
#include "ifsim.h" |
|||
#include "gendefs.h" |
|||
#include "complex.h" |
|||
#include "noisedef.h" |
|||
|
|||
/* structures to describe Bipolar Junction Transistors */ |
|||
|
|||
/* data needed to describe a single instance */ |
|||
|
|||
typedef struct sBJT2instance { |
|||
struct sBJT2model *BJT2modPtr; /* backpointer to model */ |
|||
struct sBJT2instance *BJT2nextInstance; /* pointer to next instance of |
|||
* current model*/ |
|||
IFuid BJT2name; /* pointer to character string naming this instance */ |
|||
int BJT2owner; /* number of owner process */ |
|||
int BJT2state; /* pointer to start of state vector for bjt2 */ |
|||
|
|||
int BJT2colNode; /* number of collector node of bjt2 */ |
|||
int BJT2baseNode; /* number of base node of bjt2 */ |
|||
int BJT2emitNode; /* number of emitter node of bjt2 */ |
|||
int BJT2substNode; /* number of substrate node of bjt2 */ |
|||
int BJT2colPrimeNode; /* number of internal collector node of bjt2 */ |
|||
int BJT2basePrimeNode; /* number of internal base node of bjt2 */ |
|||
int BJT2emitPrimeNode; /* number of internal emitter node of bjt2 */ |
|||
int BJT2substConNode; /* number of node which substrate is connected to */ |
|||
/* Substrate connection is either base prime * |
|||
* or collector prime depending on whether * |
|||
* the device is VERTICAL or LATERAL */ |
|||
double BJT2area; /* (emitter) area factor for the bjt2 */ |
|||
double BJT2areab; /* base area factor for the bjt2 */ |
|||
double BJT2areac; /* collector area factor for the bjt2 */ |
|||
double BJT2m; /* parallel multiplier */ |
|||
double BJT2icVBE; /* initial condition voltage B-E*/ |
|||
double BJT2icVCE; /* initial condition voltage C-E*/ |
|||
double BJT2temp; /* instance temperature */ |
|||
double BJT2dtemp; /* instance delta temperature from circuit */ |
|||
double BJT2tSatCur; /* temperature adjusted saturation current */ |
|||
double BJT2tSubSatCur; /* temperature adjusted subst. saturation current */ |
|||
double BJT2tEmitterConduct; /* emitter conductance */ |
|||
double BJT2tCollectorConduct; /* collector conductance */ |
|||
double BJT2tBaseResist; /* temperature adjusted base resistance */ |
|||
double BJT2tMinBaseResist; /* temperature adjusted base resistance */ |
|||
double BJT2tBetaF; /* temperature adjusted forward beta */ |
|||
double BJT2tBetaR; /* temperature adjusted reverse beta */ |
|||
double BJT2tBEleakCur; /* temperature adjusted B-E leakage current */ |
|||
double BJT2tBCleakCur; /* temperature adjusted B-C leakage current */ |
|||
double BJT2tBEcap; /* temperature adjusted B-E capacitance */ |
|||
double BJT2tBEpot; /* temperature adjusted B-E potential */ |
|||
double BJT2tBCcap; /* temperature adjusted B-C capacitance */ |
|||
double BJT2tBCpot; /* temperature adjusted B-C potential */ |
|||
double BJT2tSubcap; /* temperature adjusted Substrate capacitance */ |
|||
double BJT2tSubpot; /* temperature adjusted Substrate potential */ |
|||
double BJT2tDepCap; /* temperature adjusted join point in diode curve */ |
|||
double BJT2tf1; /* temperature adjusted polynomial coefficient */ |
|||
double BJT2tf4; /* temperature adjusted polynomial coefficient */ |
|||
double BJT2tf5; /* temperature adjusted polynomial coefficient */ |
|||
double BJT2tVcrit; /* temperature adjusted critical voltage */ |
|||
double BJT2tSubVcrit; /* temperature adjusted substrate critical voltage */ |
|||
|
|||
double *BJT2colColPrimePtr; /* pointer to sparse matrix at |
|||
* (collector,collector prime) */ |
|||
double *BJT2baseBasePrimePtr; /* pointer to sparse matrix at |
|||
* (base,base prime) */ |
|||
double *BJT2emitEmitPrimePtr; /* pointer to sparse matrix at |
|||
* (emitter,emitter prime) */ |
|||
double *BJT2colPrimeColPtr; /* pointer to sparse matrix at |
|||
* (collector prime,collector) */ |
|||
double *BJT2colPrimeBasePrimePtr; /* pointer to sparse matrix at |
|||
* (collector prime,base prime) */ |
|||
double *BJT2colPrimeEmitPrimePtr; /* pointer to sparse matrix at |
|||
* (collector prime,emitter prime) */ |
|||
double *BJT2basePrimeBasePtr; /* pointer to sparse matrix at |
|||
* (base prime,base ) */ |
|||
double *BJT2basePrimeColPrimePtr; /* pointer to sparse matrix at |
|||
* (base prime,collector prime) */ |
|||
double *BJT2basePrimeEmitPrimePtr; /* pointer to sparse matrix at |
|||
* (base primt,emitter prime) */ |
|||
double *BJT2emitPrimeEmitPtr; /* pointer to sparse matrix at |
|||
* (emitter prime,emitter) */ |
|||
double *BJT2emitPrimeColPrimePtr; /* pointer to sparse matrix at |
|||
* (emitter prime,collector prime) */ |
|||
double *BJT2emitPrimeBasePrimePtr; /* pointer to sparse matrix at |
|||
* (emitter prime,base prime) */ |
|||
double *BJT2colColPtr; /* pointer to sparse matrix at |
|||
* (collector,collector) */ |
|||
double *BJT2baseBasePtr; /* pointer to sparse matrix at |
|||
* (base,base) */ |
|||
double *BJT2emitEmitPtr; /* pointer to sparse matrix at |
|||
* (emitter,emitter) */ |
|||
double *BJT2colPrimeColPrimePtr; /* pointer to sparse matrix at |
|||
* (collector prime,collector prime) */ |
|||
double *BJT2basePrimeBasePrimePtr; /* pointer to sparse matrix at |
|||
* (base prime,base prime) */ |
|||
double *BJT2emitPrimeEmitPrimePtr; /* pointer to sparse matrix at |
|||
* (emitter prime,emitter prime) */ |
|||
double *BJT2substSubstPtr; /* pointer to sparse matrix at |
|||
* (substrate,substrate) */ |
|||
double *BJT2substConSubstPtr; /* pointer to sparse matrix at |
|||
* (Substrate connection, substrate) */ |
|||
double *BJT2substSubstConPtr; /* pointer to sparse matrix at |
|||
* (substrate, Substrate connection) */ |
|||
double *BJT2substConSubstConPtr; /* pointer to sparse matrix at |
|||
* (Substrate connection, Substrate connection) */ |
|||
/* Substrate connection is either base prime * |
|||
* or collector prime depending on whether * |
|||
* the device is VERTICAL or LATERAL */ |
|||
double *BJT2baseColPrimePtr; /* pointer to sparse matrix at |
|||
* (base,collector prime) */ |
|||
double *BJT2colPrimeBasePtr; /* pointer to sparse matrix at |
|||
* (collector prime,base) */ |
|||
|
|||
unsigned BJT2off :1; /* 'off' flag for bjt2 */ |
|||
unsigned BJT2tempGiven :1; /* temperature given for bjt2 instance*/ |
|||
unsigned BJT2dtempGiven :1; /* temperature given for bjt2 instance*/ |
|||
unsigned BJT2areaGiven :1; /* flag to indicate (emitter) area was specified */ |
|||
unsigned BJT2areabGiven :1; /* flag to indicate base area was specified */ |
|||
unsigned BJT2areacGiven :1; /* flag to indicate collector area was specified */ |
|||
unsigned BJT2mGiven :1; /* flag to indicate m parameter specified */ |
|||
unsigned BJT2icVBEGiven :1; /* flag to indicate VBE init. cond. given */ |
|||
unsigned BJT2icVCEGiven :1; /* flag to indicate VCE init. cond. given */ |
|||
unsigned BJT2senPertFlag :1; /* indictes whether the the parameter of |
|||
the particular instance is to be perturbed */ |
|||
|
|||
int BJT2senParmNo; /* parameter # for sensitivity use; |
|||
set equal to 0 if not a design parameter*/ |
|||
double BJT2capbe; |
|||
double BJT2capbc; |
|||
double BJT2capsub; |
|||
double BJT2capbx; |
|||
double *BJT2sens; |
|||
|
|||
#define BJT2senGpi BJT2sens /* stores the perturbed values of gpi */ |
|||
#define BJT2senGmu BJT2sens+5 /* stores the perturbed values of gmu */ |
|||
#define BJT2senGm BJT2sens+10 /* stores the perturbed values of gm */ |
|||
#define BJT2senGo BJT2sens+15 /* stores the perturbed values of go */ |
|||
#define BJT2senGx BJT2sens+20 /* stores the perturbed values of gx */ |
|||
#define BJT2senCpi BJT2sens+25 /* stores the perturbed values of cpi */ |
|||
#define BJT2senCmu BJT2sens+30 /* stores the perturbed values of cmu */ |
|||
#define BJT2senCbx BJT2sens+35 /* stores the perturbed values of cbx */ |
|||
#define BJT2senCmcb BJT2sens+40 /* stores the perturbed values of cmcb */ |
|||
#define BJT2senCsub BJT2sens+45 /* stores the perturbed values of csub */ |
|||
#define BJT2dphibedp BJT2sens+51 |
|||
#define BJT2dphibcdp BJT2sens+52 |
|||
#define BJT2dphisubdp BJT2sens+53 |
|||
#define BJT2dphibxdp BJT2sens+54 |
|||
|
|||
/* |
|||
* distortion stuff |
|||
* the following naming convention is used: |
|||
* x = vbe |
|||
* y = vbc |
|||
* z = vbb |
|||
* w = vbed (vbe delayed for the linear gm delay) |
|||
* therefore ic_xyz stands for the coefficient of the vbe*vbc*vbb |
|||
* term in the multidimensional Taylor expansion for ic; and ibb_x2y |
|||
* for the coeff. of the vbe*vbe*vbc term in the ibb expansion. |
|||
*/ |
|||
|
|||
#define BJT2NDCOEFFS 65 |
|||
|
|||
#ifndef NODISTO |
|||
double BJT2dCoeffs[BJT2NDCOEFFS]; |
|||
#else /* NODISTO */ |
|||
double *BJT2dCoeffs; |
|||
#endif /* NODISTO */ |
|||
|
|||
#ifndef CONFIG |
|||
|
|||
#define ic_x BJT2dCoeffs[0] |
|||
#define ic_y BJT2dCoeffs[1] |
|||
#define ic_xd BJT2dCoeffs[2] |
|||
#define ic_x2 BJT2dCoeffs[3] |
|||
#define ic_y2 BJT2dCoeffs[4] |
|||
#define ic_w2 BJT2dCoeffs[5] |
|||
#define ic_xy BJT2dCoeffs[6] |
|||
#define ic_yw BJT2dCoeffs[7] |
|||
#define ic_xw BJT2dCoeffs[8] |
|||
#define ic_x3 BJT2dCoeffs[9] |
|||
#define ic_y3 BJT2dCoeffs[10] |
|||
#define ic_w3 BJT2dCoeffs[11] |
|||
#define ic_x2w BJT2dCoeffs[12] |
|||
#define ic_x2y BJT2dCoeffs[13] |
|||
#define ic_y2w BJT2dCoeffs[14] |
|||
#define ic_xy2 BJT2dCoeffs[15] |
|||
#define ic_xw2 BJT2dCoeffs[16] |
|||
#define ic_yw2 BJT2dCoeffs[17] |
|||
#define ic_xyw BJT2dCoeffs[18] |
|||
|
|||
#define ib_x BJT2dCoeffs[19] |
|||
#define ib_y BJT2dCoeffs[20] |
|||
#define ib_x2 BJT2dCoeffs[21] |
|||
#define ib_y2 BJT2dCoeffs[22] |
|||
#define ib_xy BJT2dCoeffs[23] |
|||
#define ib_x3 BJT2dCoeffs[24] |
|||
#define ib_y3 BJT2dCoeffs[25] |
|||
#define ib_x2y BJT2dCoeffs[26] |
|||
#define ib_xy2 BJT2dCoeffs[27] |
|||
|
|||
#define ibb_x BJT2dCoeffs[28] |
|||
#define ibb_y BJT2dCoeffs[29] |
|||
#define ibb_z BJT2dCoeffs[30] |
|||
#define ibb_x2 BJT2dCoeffs[31] |
|||
#define ibb_y2 BJT2dCoeffs[32] |
|||
#define ibb_z2 BJT2dCoeffs[33] |
|||
#define ibb_xy BJT2dCoeffs[34] |
|||
#define ibb_yz BJT2dCoeffs[35] |
|||
#define ibb_xz BJT2dCoeffs[36] |
|||
#define ibb_x3 BJT2dCoeffs[37] |
|||
#define ibb_y3 BJT2dCoeffs[38] |
|||
#define ibb_z3 BJT2dCoeffs[39] |
|||
#define ibb_x2z BJT2dCoeffs[40] |
|||
#define ibb_x2y BJT2dCoeffs[41] |
|||
#define ibb_y2z BJT2dCoeffs[42] |
|||
#define ibb_xy2 BJT2dCoeffs[43] |
|||
#define ibb_xz2 BJT2dCoeffs[44] |
|||
#define ibb_yz2 BJT2dCoeffs[45] |
|||
#define ibb_xyz BJT2dCoeffs[46] |
|||
|
|||
#define qbe_x BJT2dCoeffs[47] |
|||
#define qbe_y BJT2dCoeffs[48] |
|||
#define qbe_x2 BJT2dCoeffs[49] |
|||
#define qbe_y2 BJT2dCoeffs[50] |
|||
#define qbe_xy BJT2dCoeffs[51] |
|||
#define qbe_x3 BJT2dCoeffs[52] |
|||
#define qbe_y3 BJT2dCoeffs[53] |
|||
#define qbe_x2y BJT2dCoeffs[54] |
|||
#define qbe_xy2 BJT2dCoeffs[55] |
|||
|
|||
#define capbc1 BJT2dCoeffs[56] |
|||
#define capbc2 BJT2dCoeffs[57] |
|||
#define capbc3 BJT2dCoeffs[58] |
|||
|
|||
#define capbx1 BJT2dCoeffs[59] |
|||
#define capbx2 BJT2dCoeffs[60] |
|||
#define capbx3 BJT2dCoeffs[61] |
|||
|
|||
#define capsc1 BJT2dCoeffs[62] |
|||
#define capsc2 BJT2dCoeffs[63] |
|||
#define capsc3 BJT2dCoeffs[64] |
|||
|
|||
#endif |
|||
|
|||
/* indices to array of BJT2 noise sources */ |
|||
|
|||
#define BJT2RCNOIZ 0 |
|||
#define BJT2RBNOIZ 1 |
|||
#define BJT2_RE_NOISE 2 |
|||
#define BJT2ICNOIZ 3 |
|||
#define BJT2IBNOIZ 4 |
|||
#define BJT2FLNOIZ 5 |
|||
#define BJT2TOTNOIZ 6 |
|||
|
|||
#define BJT2NSRCS 7 /* the number of BJT2 noise sources */ |
|||
|
|||
#ifndef NONOISE |
|||
double BJT2nVar[NSTATVARS][BJT2NSRCS]; |
|||
#else /*NONOISE*/ |
|||
double **BJT2nVar; |
|||
#endif /*NONOISE*/ |
|||
/* the above to avoid allocating memory when it is not needed */ |
|||
|
|||
} BJT2instance ; |
|||
|
|||
/* entries in the state vector for bjt2: */ |
|||
#define BJT2vbe BJT2state |
|||
#define BJT2vbc BJT2state+1 |
|||
#define BJT2cc BJT2state+2 |
|||
#define BJT2cb BJT2state+3 |
|||
#define BJT2gpi BJT2state+4 |
|||
#define BJT2gmu BJT2state+5 |
|||
#define BJT2gm BJT2state+6 |
|||
#define BJT2go BJT2state+7 |
|||
#define BJT2qbe BJT2state+8 |
|||
#define BJT2cqbe BJT2state+9 |
|||
#define BJT2qbc BJT2state+10 |
|||
#define BJT2cqbc BJT2state+11 |
|||
#define BJT2qsub BJT2state+12 |
|||
#define BJT2cqsub BJT2state+13 |
|||
#define BJT2qbx BJT2state+14 |
|||
#define BJT2cqbx BJT2state+15 |
|||
#define BJT2gx BJT2state+16 |
|||
#define BJT2cexbc BJT2state+17 |
|||
#define BJT2geqcb BJT2state+18 |
|||
#define BJT2gcsub BJT2state+19 |
|||
#define BJT2geqbx BJT2state+20 |
|||
#define BJT2vsub BJT2state+21 |
|||
#define BJT2cdsub BJT2state+22 |
|||
#define BJT2gdsub BJT2state+23 |
|||
#define BJT2numStates 24 |
|||
|
|||
#define BJT2sensxpbe BJT2state+24 /* charge sensitivities and their |
|||
derivatives. +25 for the derivatives - |
|||
pointer to the beginning of the array */ |
|||
#define BJT2sensxpbc BJT2state+26 |
|||
#define BJT2sensxpsub BJT2state+28 |
|||
#define BJT2sensxpbx BJT2state+30 |
|||
|
|||
#define BJT2numSenStates 8 |
|||
|
|||
|
|||
/* per model data */ |
|||
typedef struct sBJT2model { /* model structure for a bjt2 */ |
|||
int BJT2modType; /* type index of this device type */ |
|||
struct sBJT2model *BJT2nextModel; /* pointer to next possible model in |
|||
* linked list */ |
|||
BJT2instance * BJT2instances; /* pointer to list of instances |
|||
* that have this model */ |
|||
IFuid BJT2modName; /* pointer to character string naming this model */ |
|||
int BJT2type; |
|||
|
|||
|
|||
int BJT2subs; |
|||
double BJT2tnom; /* nominal temperature */ |
|||
double BJT2satCur; /* input - don't use */ |
|||
double BJT2subSatCur; /* input - don't use */ |
|||
double BJT2betaF; /* input - don't use */ |
|||
double BJT2emissionCoeffF; |
|||
double BJT2earlyVoltF; |
|||
double BJT2rollOffF; |
|||
double BJT2leakBEcurrent; /* input - don't use */ |
|||
double BJT2c2; |
|||
double BJT2leakBEemissionCoeff; |
|||
double BJT2betaR; /* input - don't use */ |
|||
double BJT2emissionCoeffR; |
|||
double BJT2earlyVoltR; |
|||
double BJT2rollOffR; |
|||
double BJT2leakBCcurrent; /* input - don't use */ |
|||
double BJT2c4; |
|||
double BJT2leakBCemissionCoeff; |
|||
double BJT2baseResist; |
|||
double BJT2baseCurrentHalfResist; |
|||
double BJT2minBaseResist; |
|||
double BJT2emitterResist; |
|||
double BJT2collectorResist; |
|||
double BJT2depletionCapBE; /* input - don't use */ |
|||
double BJT2potentialBE; /* input - don't use */ |
|||
double BJT2junctionExpBE; |
|||
double BJT2transitTimeF; |
|||
double BJT2transitTimeBiasCoeffF; |
|||
double BJT2transitTimeFVBC; |
|||
double BJT2transitTimeHighCurrentF; |
|||
double BJT2excessPhase; |
|||
double BJT2depletionCapBC; /* input - don't use */ |
|||
double BJT2potentialBC; /* input - don't use */ |
|||
double BJT2junctionExpBC; |
|||
double BJT2baseFractionBCcap; |
|||
double BJT2transitTimeR; |
|||
double BJT2capSub; |
|||
double BJT2potentialSubstrate; |
|||
double BJT2exponentialSubstrate; |
|||
double BJT2betaExp; |
|||
double BJT2energyGap; |
|||
double BJT2tempExpIS; |
|||
double BJT2reTempCoeff1; |
|||
double BJT2reTempCoeff2; |
|||
double BJT2rcTempCoeff1; |
|||
double BJT2rcTempCoeff2; |
|||
double BJT2rbTempCoeff1; |
|||
double BJT2rbTempCoeff2; |
|||
double BJT2rbmTempCoeff1; |
|||
double BJT2rbmTempCoeff2; |
|||
double BJT2depletionCapCoeff; |
|||
double BJT2fNcoef; |
|||
double BJT2fNexp; |
|||
|
|||
double BJT2invEarlyVoltF; /* inverse of BJT2earlyVoltF */ |
|||
double BJT2invEarlyVoltR; /* inverse of BJT2earlyVoltR */ |
|||
double BJT2invRollOffF; /* inverse of BJT2rollOffF */ |
|||
double BJT2invRollOffR; /* inverse of BJT2rollOffR */ |
|||
double BJT2collectorConduct; /* collector conductance */ |
|||
double BJT2emitterConduct; /* emitter conductance */ |
|||
double BJT2transitTimeVBCFactor; /* */ |
|||
double BJT2excessPhaseFactor; |
|||
double BJT2f2; |
|||
double BJT2f3; |
|||
double BJT2f6; |
|||
double BJT2f7; |
|||
|
|||
unsigned BJT2subsGiven : 1; |
|||
unsigned BJT2tnomGiven : 1; |
|||
unsigned BJT2satCurGiven : 1; |
|||
unsigned BJT2subSatCurGiven : 1; |
|||
unsigned BJT2betaFGiven : 1; |
|||
unsigned BJT2emissionCoeffFGiven : 1; |
|||
unsigned BJT2earlyVoltFGiven : 1; |
|||
unsigned BJT2rollOffFGiven : 1; |
|||
unsigned BJT2leakBEcurrentGiven : 1; |
|||
unsigned BJT2c2Given : 1; |
|||
unsigned BJT2leakBEemissionCoeffGiven : 1; |
|||
unsigned BJT2betaRGiven : 1; |
|||
unsigned BJT2emissionCoeffRGiven : 1; |
|||
unsigned BJT2earlyVoltRGiven : 1; |
|||
unsigned BJT2rollOffRGiven : 1; |
|||
unsigned BJT2leakBCcurrentGiven : 1; |
|||
unsigned BJT2c4Given : 1; |
|||
unsigned BJT2leakBCemissionCoeffGiven : 1; |
|||
unsigned BJT2baseResistGiven : 1; |
|||
unsigned BJT2baseCurrentHalfResistGiven : 1; |
|||
unsigned BJT2minBaseResistGiven : 1; |
|||
unsigned BJT2emitterResistGiven : 1; |
|||
unsigned BJT2collectorResistGiven : 1; |
|||
unsigned BJT2depletionCapBEGiven : 1; |
|||
unsigned BJT2potentialBEGiven : 1; |
|||
unsigned BJT2junctionExpBEGiven : 1; |
|||
unsigned BJT2transitTimeFGiven : 1; |
|||
unsigned BJT2transitTimeBiasCoeffFGiven : 1; |
|||
unsigned BJT2transitTimeFVBCGiven : 1; |
|||
unsigned BJT2transitTimeHighCurrentFGiven : 1; |
|||
unsigned BJT2excessPhaseGiven : 1; |
|||
unsigned BJT2depletionCapBCGiven : 1; |
|||
unsigned BJT2potentialBCGiven : 1; |
|||
unsigned BJT2junctionExpBCGiven : 1; |
|||
unsigned BJT2baseFractionBCcapGiven : 1; |
|||
unsigned BJT2transitTimeRGiven : 1; |
|||
unsigned BJT2capSubGiven : 1; |
|||
unsigned BJT2potentialSubstrateGiven : 1; |
|||
unsigned BJT2exponentialSubstrateGiven : 1; |
|||
unsigned BJT2betaExpGiven : 1; |
|||
unsigned BJT2energyGapGiven : 1; |
|||
unsigned BJT2tempExpISGiven : 1; |
|||
unsigned BJT2reTempCoeff1Given : 1; |
|||
unsigned BJT2reTempCoeff2Given : 1; |
|||
unsigned BJT2rcTempCoeff1Given : 1; |
|||
unsigned BJT2rcTempCoeff2Given : 1; |
|||
unsigned BJT2rbTempCoeff1Given : 1; |
|||
unsigned BJT2rbTempCoeff2Given : 1; |
|||
unsigned BJT2rbmTempCoeff1Given : 1; |
|||
unsigned BJT2rbmTempCoeff2Given : 1; |
|||
unsigned BJT2depletionCapCoeffGiven : 1; |
|||
unsigned BJT2fNcoefGiven : 1; |
|||
unsigned BJT2fNexpGiven :1; |
|||
} BJT2model; |
|||
|
|||
#ifndef NPN |
|||
#define NPN 1 |
|||
#define PNP -1 |
|||
#endif /*NPN*/ |
|||
|
|||
/* |
|||
* BJT2 defaults to vertical for both NPN and |
|||
* PNP devices. It is possible to alter this |
|||
* behavior defining the GEOMETRY_COMPAT macro. |
|||
*/ |
|||
#ifndef VERTICAL |
|||
#define VERTICAL 1 |
|||
#define LATERAL -1 |
|||
#endif /* VERTICAL */ |
|||
|
|||
|
|||
/* device parameters */ |
|||
#define BJT2_AREA 1 |
|||
#define BJT2_OFF 2 |
|||
#define BJT2_IC_VBE 3 |
|||
#define BJT2_IC_VCE 4 |
|||
#define BJT2_IC 5 |
|||
#define BJT2_AREA_SENS 6 |
|||
#define BJT2_TEMP 7 |
|||
#define BJT2_DTEMP 8 |
|||
#define BJT2_M 9 |
|||
#define BJT2_AREAB 10 |
|||
#define BJT2_AREAC 11 |
|||
|
|||
/* model parameters */ |
|||
#define BJT2_MOD_NPN 101 |
|||
#define BJT2_MOD_PNP 102 |
|||
#define BJT2_MOD_IS 103 |
|||
#define BJT2_MOD_ISS 146 |
|||
#define BJT2_MOD_BF 104 |
|||
#define BJT2_MOD_NF 105 |
|||
#define BJT2_MOD_VAF 106 |
|||
#define BJT2_MOD_IKF 107 |
|||
#define BJT2_MOD_ISE 108 |
|||
#define BJT2_MOD_C2 109 |
|||
#define BJT2_MOD_NE 110 |
|||
#define BJT2_MOD_BR 111 |
|||
#define BJT2_MOD_NR 112 |
|||
#define BJT2_MOD_VAR 113 |
|||
#define BJT2_MOD_IKR 114 |
|||
#define BJT2_MOD_ISC 115 |
|||
#define BJT2_MOD_C4 116 |
|||
#define BJT2_MOD_NC 117 |
|||
#define BJT2_MOD_RB 118 |
|||
#define BJT2_MOD_IRB 119 |
|||
#define BJT2_MOD_RBM 120 |
|||
#define BJT2_MOD_RE 121 |
|||
#define BJT2_MOD_RC 122 |
|||
#define BJT2_MOD_CJE 123 |
|||
#define BJT2_MOD_VJE 124 |
|||
#define BJT2_MOD_MJE 125 |
|||
#define BJT2_MOD_TF 126 |
|||
#define BJT2_MOD_XTF 127 |
|||
#define BJT2_MOD_VTF 128 |
|||
#define BJT2_MOD_ITF 129 |
|||
#define BJT2_MOD_PTF 130 |
|||
#define BJT2_MOD_CJC 131 |
|||
#define BJT2_MOD_VJC 132 |
|||
#define BJT2_MOD_MJC 133 |
|||
#define BJT2_MOD_XCJC 134 |
|||
#define BJT2_MOD_TR 135 |
|||
#define BJT2_MOD_CJS 136 |
|||
#define BJT2_MOD_VJS 137 |
|||
#define BJT2_MOD_MJS 138 |
|||
#define BJT2_MOD_XTB 139 |
|||
#define BJT2_MOD_EG 140 |
|||
#define BJT2_MOD_XTI 141 |
|||
#define BJT2_MOD_FC 142 |
|||
#define BJT2_MOD_TNOM 143 |
|||
#define BJT2_MOD_AF 144 |
|||
#define BJT2_MOD_KF 145 |
|||
#define BJT2_MOD_SUBS 147 |
|||
#define BJT2_MOD_TRE1 148 |
|||
#define BJT2_MOD_TRE2 149 |
|||
#define BJT2_MOD_TRC1 150 |
|||
#define BJT2_MOD_TRC2 151 |
|||
#define BJT2_MOD_TRB1 152 |
|||
#define BJT2_MOD_TRB2 153 |
|||
#define BJT2_MOD_TRBM1 154 |
|||
#define BJT2_MOD_TRBM2 155 |
|||
|
|||
|
|||
/* device questions */ |
|||
#define BJT2_QUEST_FT 201 |
|||
#define BJT2_QUEST_COLNODE 202 |
|||
#define BJT2_QUEST_BASENODE 203 |
|||
#define BJT2_QUEST_EMITNODE 204 |
|||
#define BJT2_QUEST_SUBSTNODE 205 |
|||
#define BJT2_QUEST_COLPRIMENODE 206 |
|||
#define BJT2_QUEST_BASEPRIMENODE 207 |
|||
#define BJT2_QUEST_EMITPRIMENODE 208 |
|||
#define BJT2_QUEST_VBE 209 |
|||
#define BJT2_QUEST_VBC 210 |
|||
#define BJT2_QUEST_CC 211 |
|||
#define BJT2_QUEST_CB 212 |
|||
#define BJT2_QUEST_GPI 213 |
|||
#define BJT2_QUEST_GMU 214 |
|||
#define BJT2_QUEST_GM 215 |
|||
#define BJT2_QUEST_GO 216 |
|||
#define BJT2_QUEST_QBE 217 |
|||
#define BJT2_QUEST_CQBE 218 |
|||
#define BJT2_QUEST_QBC 219 |
|||
#define BJT2_QUEST_CQBC 220 |
|||
#define BJT2_QUEST_QSUB 221 |
|||
#define BJT2_QUEST_CQSUB 222 |
|||
#define BJT2_QUEST_QBX 223 |
|||
#define BJT2_QUEST_CQBX 224 |
|||
#define BJT2_QUEST_GX 225 |
|||
#define BJT2_QUEST_CEXBC 226 |
|||
#define BJT2_QUEST_GEQCB 227 |
|||
#define BJT2_QUEST_GCSUB 228 |
|||
#define BJT2_QUEST_GDSUB 243 |
|||
#define BJT2_QUEST_GEQBX 229 |
|||
#define BJT2_QUEST_SENS_REAL 230 |
|||
#define BJT2_QUEST_SENS_IMAG 231 |
|||
#define BJT2_QUEST_SENS_MAG 232 |
|||
#define BJT2_QUEST_SENS_PH 233 |
|||
#define BJT2_QUEST_SENS_CPLX 234 |
|||
#define BJT2_QUEST_SENS_DC 235 |
|||
#define BJT2_QUEST_CE 236 |
|||
#define BJT2_QUEST_CS 237 |
|||
#define BJT2_QUEST_POWER 238 |
|||
|
|||
#define BJT2_QUEST_CPI 239 |
|||
#define BJT2_QUEST_CMU 240 |
|||
#define BJT2_QUEST_CBX 241 |
|||
#define BJT2_QUEST_CSUB 242 |
|||
|
|||
/* model questions */ |
|||
#define BJT2_MOD_INVEARLYF 301 |
|||
#define BJT2_MOD_INVEARLYR 302 |
|||
#define BJT2_MOD_INVROLLOFFF 303 |
|||
#define BJT2_MOD_INVROLLOFFR 304 |
|||
#define BJT2_MOD_COLCONDUCT 305 |
|||
#define BJT2_MOD_EMITTERCONDUCT 306 |
|||
#define BJT2_MOD_TRANSVBCFACT 307 |
|||
#define BJT2_MOD_EXCESSPHASEFACTOR 308 |
|||
#define BJT2_MOD_TYPE 309 |
|||
#define BJT2_MOD_QUEST_SUBS 310 |
|||
|
|||
#include "bjt2ext.h" |
|||
#endif /*BJT2*/ |
|||
@ -1,39 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This routine deletes a BJT2 instance from the circuit and frees |
|||
* the storage it was using. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2delete(GENmodel *inModel, IFuid name, GENinstance **kill) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance **fast = (BJT2instance**)kill; |
|||
|
|||
BJT2instance **prev = NULL; |
|||
BJT2instance *here; |
|||
|
|||
for( ; model ; model = model->BJT2nextModel) { |
|||
prev = &(model->BJT2instances); |
|||
for(here = *prev; here ; here = *prev) { |
|||
if(here->BJT2name == name || (fast && here==*fast) ) { |
|||
*prev= here->BJT2nextInstance; |
|||
FREE(here); |
|||
return(OK); |
|||
} |
|||
prev = &(here->BJT2nextInstance); |
|||
} |
|||
} |
|||
return(E_NODEV); |
|||
} |
|||
@ -1,46 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine deletes all BJT2s from the circuit and frees |
|||
* all storage they were using. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "bjt2defs.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
void |
|||
BJT2destroy(GENmodel **inModel) |
|||
{ |
|||
BJT2model **model = (BJT2model**)inModel; |
|||
BJT2instance *here; |
|||
BJT2instance *prev = NULL; |
|||
BJT2model *mod = *model; |
|||
BJT2model *oldmod = NULL; |
|||
|
|||
for( ; mod ; mod = mod->BJT2nextModel) { |
|||
if(oldmod) FREE(oldmod); |
|||
oldmod = mod; |
|||
prev = (BJT2instance *)NULL; |
|||
for(here = mod->BJT2instances ; here ; here = here->BJT2nextInstance) { |
|||
if(prev){ |
|||
if(prev->BJT2sens) FREE(prev->BJT2sens); |
|||
FREE(prev); |
|||
} |
|||
prev = here; |
|||
} |
|||
if(prev){ |
|||
if(prev->BJT2sens) FREE(prev->BJT2sens); |
|||
FREE(prev); |
|||
} |
|||
} |
|||
if(oldmod) FREE(oldmod); |
|||
*model = NULL; |
|||
} |
|||
1838
src/spicelib/devices/bjt2/bjt2disto.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,727 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1988 Jaijeet S Roychowdhury |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "distodef.h" |
|||
#include "sperror.h" |
|||
#include "devdefs.h" |
|||
#include "suffix.h" |
|||
|
|||
/* |
|||
* This function initialises the Taylor coeffs for the |
|||
* BJT2's in the circuit |
|||
*/ |
|||
|
|||
int BJT2dSetup(GENmodel *inModel, CKTcircuit *ckt) |
|||
/* actually load the current resistance value into the |
|||
* sparse matrix previously provided |
|||
*/ |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
double arg; |
|||
double c2; |
|||
double c4; |
|||
double lcapbe1,lcapbe2,lcapbe3; |
|||
double lcapbx1,lcapbx2,lcapbx3; |
|||
double cb = 0.0; |
|||
double cbc; |
|||
double cbcn; |
|||
double cbe; |
|||
double cben; |
|||
double cdis; |
|||
double csat; |
|||
double ctot; |
|||
double czbc; |
|||
double czbcf2; |
|||
double czbe; |
|||
double czbef2; |
|||
double czbx; |
|||
double czbxf2; |
|||
double czcs; |
|||
double evbc; |
|||
double evbcn; |
|||
double evbe; |
|||
double evben; |
|||
double f1; |
|||
double f2; |
|||
double f3; |
|||
double fcpc; |
|||
double fcpe; |
|||
double gbb1 = 0.0; |
|||
double gbc; |
|||
double gbcn; |
|||
double gbe; |
|||
double gbe2,gbe3; |
|||
double gbc2,gbc3; |
|||
double gben2,gben3; |
|||
double gbcn2,gbcn3; |
|||
double gben; |
|||
double gbb2 = 0.0, gbb3 = 0.0; |
|||
double oik; |
|||
double oikr; |
|||
double ovtf; |
|||
double pc; |
|||
double pe; |
|||
double ps; |
|||
double q1; |
|||
double q2; |
|||
double qb; |
|||
double rbpi; |
|||
double rbpr; |
|||
double sarg; |
|||
double sqarg; |
|||
double tf; |
|||
double tr; |
|||
double vbc; |
|||
double vbe; |
|||
double vbx; |
|||
double vsc; |
|||
double vt; |
|||
double vtc; |
|||
double vte; |
|||
double vtn; |
|||
double xjrb; |
|||
double xjtf; |
|||
double xmc; |
|||
double xme; |
|||
double xms; |
|||
double xtf; |
|||
double vbed; |
|||
double vbb; |
|||
|
|||
double lcapbc1 = 0.0; |
|||
double lcapbc2 = 0.0; |
|||
double lcapbc3 = 0.0; |
|||
|
|||
double lcapsc1 = 0.0; |
|||
double lcapsc2 = 0.0; |
|||
double lcapsc3 = 0.0; |
|||
double ic; |
|||
double dummy; |
|||
Dderivs d_p, d_q, d_r; |
|||
Dderivs d_dummy, d_q1, d_qb, d_dummy2; |
|||
Dderivs d_arg, d_sqarg, d_ic, d_q2; |
|||
Dderivs d_z, d_tanz, d_vbb, d_ibb, d_rbb; |
|||
Dderivs d_ib, d_cbe, d_tff, d_qbe; |
|||
|
|||
d_p.value = 0.0; |
|||
d_p.d1_p = 1.0; |
|||
d_p.d1_q = 0.0; |
|||
d_p.d1_r = 0.0; |
|||
d_p.d2_p2 = 0.0; |
|||
d_p.d2_q2 = 0.0; |
|||
d_p.d2_r2 = 0.0; |
|||
d_p.d2_pq = 0.0; |
|||
d_p.d2_qr = 0.0; |
|||
d_p.d2_pr = 0.0; |
|||
d_p.d3_p3 = 0.0; |
|||
d_p.d3_q3 = 0.0; |
|||
d_p.d3_r3 = 0.0; |
|||
d_p.d3_p2q = 0.0; |
|||
d_p.d3_p2r = 0.0; |
|||
d_p.d3_pq2 = 0.0; |
|||
d_p.d3_q2r = 0.0; |
|||
d_p.d3_pr2 = 0.0; |
|||
d_p.d3_qr2 = 0.0; |
|||
d_p.d3_pqr = 0.0; |
|||
|
|||
EqualDeriv(&d_q, &d_p); |
|||
d_q.d1_q = 1.0; |
|||
d_q.d1_p = 0.0; |
|||
|
|||
EqualDeriv(&d_r, &d_p); |
|||
d_r.d1_r = 1.0; |
|||
d_r.d1_p = 0.0; |
|||
|
|||
|
|||
/* loop through all the models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
|
|||
vt = here->BJT2temp * CONSTKoverQ; |
|||
|
|||
|
|||
/* |
|||
* dc model paramters |
|||
*/ |
|||
csat=here->BJT2tSatCur*here->BJT2area * here->BJT2m; |
|||
rbpr=model->BJT2minBaseResist/(here->BJT2area * here->BJT2m); |
|||
rbpi=model->BJT2baseResist/(here->BJT2area * here->BJT2m) - rbpr; |
|||
oik=model->BJT2invRollOffF/(here->BJT2area * here->BJT2m); |
|||
c2=here->BJT2tBEleakCur*here->BJT2area * here->BJT2m; |
|||
vte=model->BJT2leakBEemissionCoeff*vt; |
|||
oikr=model->BJT2invRollOffR/(here->BJT2area * here->BJT2m); |
|||
|
|||
c4=here->BJT2tBCleakCur * here->BJT2m; |
|||
if (model->BJT2subs == VERTICAL) |
|||
c4 *= here->BJT2areab; |
|||
else |
|||
c4 *= here->BJT2areac; /* lateral transistor */ |
|||
|
|||
vtc=model->BJT2leakBCemissionCoeff*vt; |
|||
xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area * here->BJT2m; |
|||
|
|||
|
|||
/* |
|||
* initialization |
|||
*/ |
|||
vbe= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2basePrimeNode) - |
|||
*(ckt->CKTrhsOld + here->BJT2emitPrimeNode)); |
|||
vbc= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2baseNode) - |
|||
*(ckt->CKTrhsOld + here->BJT2colPrimeNode)); |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsc=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
|
|||
vbb=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode) - |
|||
*(ckt->CKTrhsOld+here->BJT2basePrimeNode)); |
|||
|
|||
|
|||
vbed = vbe; /* this is just a dummy variable |
|||
* it is the delayed vbe to be |
|||
* used in the delayed gm generator |
|||
*/ |
|||
|
|||
|
|||
/* ic = f1(vbe,vbc,vbed) + f2(vbc) + f3(vbc) |
|||
* |
|||
* we shall calculate the taylor coeffs of |
|||
* ic wrt vbe, vbed, and vbc and store them away. |
|||
* the equations f1 f2 and f3 are given elsewhere; |
|||
* we shall start off with f1, compute |
|||
* derivs. upto third order and then do f2 and |
|||
* f3 and add their derivatives. |
|||
* |
|||
* Since f1 above is a function of three variables, it |
|||
* will be convenient to use derivative structures |
|||
* to compute the derivatives of f1. For this |
|||
* computation, p=vbe, q=vbc, r=vbed. |
|||
* |
|||
* ib = f1(vbe) + f2(vbc) (not the same f's as |
|||
* above, in case you are |
|||
* wondering!) |
|||
* the gbe's gbc's gben's and gbcn's are |
|||
* convenient subsidiary variables. |
|||
* |
|||
* irb = f(vbe, vbc, vbb) - the vbe & vbc |
|||
* dependencies arise from the |
|||
* qb term. |
|||
* qbe = f1(vbe,vbc) + f2(vbe) |
|||
* |
|||
* derivative structures will be used again in the |
|||
* above two equations. p=vbe, q=vbc, r=vbb. |
|||
* |
|||
* qbc = f(vbc) ; qbx = f(vbx) |
|||
* |
|||
* qss = f(vsc) |
|||
*/ |
|||
/* |
|||
* determine dc current and derivitives |
|||
*/ |
|||
vtn=vt*model->BJT2emissionCoeffF; |
|||
if(vbe > -5*vtn){ |
|||
evbe=exp(vbe/vtn); |
|||
cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; |
|||
gbe=csat*evbe/vtn+ckt->CKTgmin; |
|||
gbe2 = csat*evbe/vtn/vtn; |
|||
gbe3 = gbe2/vtn; |
|||
|
|||
/* note - these are actually derivs, not Taylor |
|||
* coeffs. - not divided by 2! and 3! |
|||
*/ |
|||
if (c2 == 0) { |
|||
cben=0; |
|||
gben=gben2=gben3=0; |
|||
} else { |
|||
evben=exp(vbe/vte); |
|||
cben=c2*(evben-1); |
|||
gben=c2*evben/vte; |
|||
gben2=gben/vte; |
|||
gben3=gben2/vte; |
|||
} |
|||
} else { |
|||
gbe = -csat/vbe+ckt->CKTgmin; |
|||
gbe2=gbe3=gben2=gben3=0; |
|||
cbe=gbe*vbe; |
|||
gben = -c2/vbe; |
|||
cben=gben*vbe; |
|||
} |
|||
vtn=vt*model->BJT2emissionCoeffR; |
|||
if(vbc > -5*vtn) { |
|||
evbc=exp(vbc/vtn); |
|||
cbc=csat*(evbc-1)+ckt->CKTgmin*vbc; |
|||
gbc=csat*evbc/vtn+ckt->CKTgmin; |
|||
gbc2=csat*evbc/vtn/vtn; |
|||
gbc3=gbc2/vtn; |
|||
if (c4 == 0) { |
|||
cbcn=0; |
|||
gbcn=0; |
|||
gbcn2=gbcn3=0; |
|||
} else { |
|||
evbcn=exp(vbc/vtc); |
|||
cbcn=c4*(evbcn-1); |
|||
gbcn=c4*evbcn/vtc; |
|||
gbcn2=gbcn/vtc; |
|||
gbcn3=gbcn2/vtc; |
|||
} |
|||
} else { |
|||
gbc = -csat/vbc+ckt->CKTgmin; |
|||
gbc2=gbc3=0; |
|||
cbc = gbc*vbc; |
|||
gbcn = -c4/vbc; |
|||
gbcn2=gbcn3=0; |
|||
cbcn=gbcn*vbc; |
|||
} |
|||
/* |
|||
* determine base charge terms |
|||
*/ |
|||
/* q1 is a function of 2 variables p=vbe and q=vbc. r= |
|||
* anything |
|||
*/ |
|||
q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); |
|||
dummy = (1-model->BJT2invEarlyVoltF*vbc- |
|||
model->BJT2invEarlyVoltR*vbe); |
|||
EqualDeriv(&d_dummy, &d_p); |
|||
d_dummy.value = dummy; |
|||
d_dummy.d1_p = - model->BJT2invEarlyVoltR; |
|||
d_dummy.d1_q = - model->BJT2invEarlyVoltF; |
|||
/* q1 = 1/dummy */ |
|||
InvDeriv(&d_q1, &d_dummy); /* now q1 and its derivatives are |
|||
set up */ |
|||
if(oik == 0 && oikr == 0) { |
|||
qb=q1; |
|||
EqualDeriv(&d_qb, &d_q1); |
|||
} else { |
|||
q2=oik*cbe+oikr*cbc; |
|||
EqualDeriv(&d_q2, &d_p); |
|||
d_q2.value = q2; |
|||
d_q2.d1_p = oik*gbe; |
|||
d_q2.d1_q = oikr*gbc; |
|||
d_q2.d2_p2 = oik*gbe2; |
|||
d_q2.d2_q2 = oikr*gbc2; |
|||
d_q2.d3_p3 = oik*gbe3; |
|||
d_q2.d3_q3 = oikr*gbc3; |
|||
arg=MAX(0,1+4*q2); |
|||
if (arg == 0.) |
|||
{ |
|||
EqualDeriv(&d_arg,&d_p); |
|||
d_arg.d1_p = 0.0; |
|||
} |
|||
else |
|||
{ |
|||
TimesDeriv(&d_arg,&d_q2,4.0); |
|||
d_arg.value += 1.; |
|||
} |
|||
sqarg=1; |
|||
EqualDeriv(&d_sqarg,&d_p); |
|||
d_sqarg.value = 1.0; |
|||
d_sqarg.d1_p = 0.0; |
|||
if(arg != 0){ |
|||
sqarg=sqrt(arg); |
|||
SqrtDeriv(&d_sqarg, &d_arg); |
|||
} |
|||
|
|||
qb=q1*(1+sqarg)/2; |
|||
dummy = 1 + sqarg; |
|||
EqualDeriv(&d_dummy, &d_sqarg); |
|||
d_dummy.value += 1.0; |
|||
MultDeriv(&d_qb, &d_q1, &d_dummy); |
|||
TimesDeriv(&d_qb, &d_qb, 0.5); |
|||
} |
|||
|
|||
ic = (cbe - cbc)/qb; |
|||
/* cbe is a fn of vbed only; cbc of vbc; and qb of vbe and vbc */ |
|||
/* p=vbe, q=vbc, r=vbed; now dummy = cbe - cbc */ |
|||
EqualDeriv(&d_dummy, &d_p); |
|||
d_dummy.d1_p = 0.0; |
|||
d_dummy.value = cbe-cbc; |
|||
d_dummy.d1_r = gbe; |
|||
d_dummy.d2_r2 = gbe2; |
|||
d_dummy.d3_r3 = gbe3; |
|||
d_dummy.d1_q = -gbc; |
|||
d_dummy.d2_q2 = -gbc2; |
|||
d_dummy.d3_q3 = -gbc3; |
|||
|
|||
DivDeriv(&d_ic, &d_dummy, &d_qb); |
|||
|
|||
|
|||
d_ic.value -= cbc/here->BJT2tBetaR + cbcn; |
|||
d_ic.d1_q -= gbc/here->BJT2tBetaR + gbcn; |
|||
d_ic.d2_q2 -= gbc2/here->BJT2tBetaR + gbcn2; |
|||
d_ic.d3_q3 -= gbc3/here->BJT2tBetaR + gbcn3; |
|||
|
|||
/* check this point: where is the f2(vbe) contribution to ic ? */ |
|||
|
|||
/* ic derivatives all set up now */ |
|||
/* base spread resistance */ |
|||
|
|||
if ( !((rbpr == 0.0) && (rbpi == 0.0))) |
|||
{ |
|||
cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; |
|||
/* we are calculating derivatives w.r.t cb itself */ |
|||
/* |
|||
gx=rbpr+rbpi/qb; |
|||
*/ |
|||
|
|||
if (cb != 0.0) { |
|||
if((xjrb != 0.0) && (rbpi != 0.0)) { |
|||
/* p = ib, q, r = anything */ |
|||
dummy=MAX(cb/xjrb,1e-9); |
|||
EqualDeriv(&d_dummy, &d_p); |
|||
d_dummy.value = dummy; |
|||
d_dummy.d1_p = 1/xjrb; |
|||
SqrtDeriv(&d_dummy, &d_dummy); |
|||
TimesDeriv(&d_dummy, &d_dummy, 2.4317); |
|||
|
|||
/* |
|||
dummy2=(-1+sqrt(1+14.59025*MAX(cb/xjrb,1e-9))); |
|||
*/ |
|||
EqualDeriv(&d_dummy2, &d_p); |
|||
d_dummy2.value = 1+14.59025*MAX(cb/xjrb,1e-9); |
|||
d_dummy2.d1_p = 14.59025/xjrb; |
|||
SqrtDeriv(&d_dummy2, &d_dummy2); |
|||
d_dummy2.value -= 1.0; |
|||
|
|||
DivDeriv(&d_z, &d_dummy2, &d_dummy); |
|||
TanDeriv(&d_tanz, &d_z); |
|||
|
|||
/*now using dummy = tanz - z and dummy2 = z*tanz*tanz */ |
|||
TimesDeriv(&d_dummy, &d_z, -1.0); |
|||
PlusDeriv(&d_dummy, &d_dummy, &d_tanz); |
|||
|
|||
MultDeriv(&d_dummy2, &d_tanz, &d_tanz); |
|||
MultDeriv(&d_dummy2, &d_dummy2, &d_z); |
|||
|
|||
DivDeriv(&d_rbb , &d_dummy, &d_dummy2); |
|||
TimesDeriv(&d_rbb,&d_rbb, 3.0*rbpi); |
|||
d_rbb.value += rbpr; |
|||
|
|||
MultDeriv(&d_vbb, &d_rbb, &d_p); |
|||
|
|||
/* power series inversion to get the conductance derivatives */ |
|||
|
|||
if (d_vbb.d1_p != 0) { |
|||
gbb1 = 1/d_vbb.d1_p; |
|||
gbb2 = -(d_vbb.d2_p2*0.5)*gbb1*gbb1; |
|||
gbb3 = gbb1*gbb1*gbb1*gbb1*(-(d_vbb.d3_p3/6.0) |
|||
+ 2*(d_vbb.d2_p2*0.5)*(d_vbb.d2_p2*0.5)*gbb1); |
|||
} |
|||
else |
|||
printf("\nd_vbb.d1_p = 0 in base spread resistance calculations\n"); |
|||
|
|||
|
|||
/* r = vbb */ |
|||
EqualDeriv(&d_ibb, &d_r); |
|||
d_ibb.value = cb; |
|||
d_ibb.d1_r = gbb1; |
|||
d_ibb.d2_r2 = 2*gbb2; |
|||
d_ibb.d3_r3 = 6.0*gbb3; |
|||
} |
|||
else |
|||
{ |
|||
/* |
|||
rbb = rbpr + rbpi/qb; |
|||
ibb = vbb /rbb; = f(vbe, vbc, vbb) |
|||
*/ |
|||
|
|||
EqualDeriv(&d_rbb,&d_p); |
|||
d_rbb.d1_p = 0.0; |
|||
if (rbpi != 0.0) { |
|||
InvDeriv(&d_rbb, &d_qb); |
|||
TimesDeriv(&d_rbb, &d_rbb,rbpi); |
|||
} |
|||
d_rbb.value += rbpr; |
|||
|
|||
EqualDeriv(&d_ibb,&d_r); |
|||
d_ibb.value = vbb; |
|||
DivDeriv(&d_ibb,&d_ibb,&d_rbb); |
|||
|
|||
} |
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_ibb,&d_r); |
|||
if (rbpr != 0.0) |
|||
d_ibb.d1_r = 1/rbpr; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_ibb,&d_p); |
|||
d_ibb.d1_p = 0.0; |
|||
} |
|||
|
|||
/* formulae for base spread resistance over! */ |
|||
|
|||
/* ib term */ |
|||
|
|||
EqualDeriv(&d_ib, &d_p); |
|||
d_ib.d1_p = 0.0; |
|||
d_ib.value = cb; |
|||
d_ib.d1_p = gbe/here->BJT2tBetaF + gben; |
|||
d_ib.d2_p2 = gbe2/here->BJT2tBetaF + gben2; |
|||
d_ib.d3_p3 = gbe3/here->BJT2tBetaF + gben3; |
|||
|
|||
d_ib.d1_q = gbc/here->BJT2tBetaR + gbcn; |
|||
d_ib.d2_q2 = gbc2/here->BJT2tBetaR + gbcn2; |
|||
d_ib.d3_q3 = gbc3/here->BJT2tBetaR + gbcn3; |
|||
|
|||
/* ib term over */ |
|||
/* |
|||
* charge storage elements |
|||
*/ |
|||
tf=model->BJT2transitTimeF; |
|||
tr=model->BJT2transitTimeR; |
|||
czbe=here->BJT2tBEcap*here->BJT2area * here->BJT2m; |
|||
pe=here->BJT2tBEpot; |
|||
xme=model->BJT2junctionExpBE; |
|||
cdis=model->BJT2baseFractionBCcap; |
|||
|
|||
ctot=here->BJT2tBCcap * here->BJT2m; |
|||
|
|||
if (model->BJT2subs == VERTICAL) |
|||
ctot *= here->BJT2areab; |
|||
else |
|||
ctot *= here->BJT2areac; |
|||
|
|||
czbc=ctot*cdis; |
|||
czbx=ctot-czbc; |
|||
pc=here->BJT2tBCpot; |
|||
xmc=model->BJT2junctionExpBC; |
|||
fcpe=here->BJT2tDepCap; |
|||
|
|||
czcs=model->BJT2capSub * here->BJT2m; /* PN */ |
|||
|
|||
if (model->BJT2subs == VERTICAL) |
|||
czcs *= here->BJT2areac; |
|||
else |
|||
czcs *= here->BJT2areab; |
|||
|
|||
ps=model->BJT2potentialSubstrate; |
|||
xms=model->BJT2exponentialSubstrate; |
|||
xtf=model->BJT2transitTimeBiasCoeffF; |
|||
ovtf=model->BJT2transitTimeVBCFactor; |
|||
xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area * here->BJT2m; |
|||
if(tf != 0 && vbe >0) { |
|||
EqualDeriv(&d_cbe, &d_p); |
|||
d_cbe.value = cbe; |
|||
d_cbe.d1_p = gbe; |
|||
d_cbe.d2_p2 = gbe2; |
|||
d_cbe.d3_p3 = gbe3; |
|||
if(xtf != 0){ |
|||
if(ovtf != 0) { |
|||
/* dummy = exp ( vbc*ovtf) */ |
|||
EqualDeriv(&d_dummy, &d_q); |
|||
d_dummy.value = vbc*ovtf; |
|||
d_dummy.d1_q = ovtf; |
|||
ExpDeriv(&d_dummy, &d_dummy); |
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_dummy,&d_p); |
|||
d_dummy.value = 1.0; |
|||
d_dummy.d1_p = 0.0; |
|||
} |
|||
if(xjtf != 0) { |
|||
EqualDeriv(&d_dummy2, &d_cbe); |
|||
d_dummy2.value += xjtf; |
|||
DivDeriv(&d_dummy2, &d_cbe, &d_dummy2); |
|||
MultDeriv (&d_dummy2, &d_dummy2, &d_dummy2); |
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_dummy2,&d_p); |
|||
d_dummy2.value = 1.0; |
|||
d_dummy2.d1_p = 0.0; |
|||
} |
|||
|
|||
MultDeriv(&d_tff, &d_dummy, &d_dummy2); |
|||
TimesDeriv(&d_tff, &d_tff, tf*xtf); |
|||
d_tff.value += tf; |
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_tff,&d_p); |
|||
d_tff.value = tf; |
|||
d_tff.d1_p = 0.0; |
|||
} |
|||
|
|||
|
|||
|
|||
|
|||
/* qbe = tff/qb*cbe */ |
|||
|
|||
/* |
|||
dummy = tff/qb; |
|||
*/ |
|||
/* these are the cbe coeffs */ |
|||
DivDeriv(&d_dummy, &d_tff, &d_qb); |
|||
MultDeriv(&d_qbe, &d_dummy, &d_cbe); |
|||
|
|||
} |
|||
else |
|||
{ |
|||
EqualDeriv(&d_qbe, &d_p); |
|||
d_qbe.value = 0.0; |
|||
d_qbe.d1_p = 0.0; |
|||
} |
|||
if (vbe < fcpe) { |
|||
arg=1-vbe/pe; |
|||
sarg=exp(-xme*log(arg)); |
|||
lcapbe1 = czbe*sarg; |
|||
lcapbe2 = |
|||
0.5*czbe*xme*sarg/(arg*pe); |
|||
lcapbe3 = |
|||
czbe*xme*(xme+1)*sarg/(arg*arg*pe*pe*6); |
|||
} else { |
|||
f1=here->BJT2tf1; |
|||
f2=model->BJT2f2; |
|||
f3=model->BJT2f3; |
|||
czbef2=czbe/f2; |
|||
lcapbe1 = czbef2*(f3+xme*vbe/pe); |
|||
lcapbe2 = 0.5*xme*czbef2/pe; |
|||
lcapbe3 = 0.0; |
|||
} |
|||
d_qbe.d1_p += lcapbe1; |
|||
d_qbe.d2_p2 += lcapbe2*2.; |
|||
d_qbe.d3_p3 += lcapbe3*6.; |
|||
|
|||
|
|||
fcpc=here->BJT2tf4; |
|||
f1=here->BJT2tf5; |
|||
f2=model->BJT2f6; |
|||
f3=model->BJT2f7; |
|||
if (vbc < fcpc) { |
|||
arg=1-vbc/pc; |
|||
sarg=exp(-xmc*log(arg)); |
|||
lcapbc1 = czbc*sarg; |
|||
lcapbc2 = |
|||
0.5*czbc*xmc*sarg/(arg*pc); |
|||
lcapbc3 = |
|||
czbc*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); |
|||
} else { |
|||
czbcf2=czbc/f2; |
|||
lcapbc1 = czbcf2*(f3+xmc*vbc/pc); |
|||
lcapbc2 = 0.5*xmc*czbcf2/pc; |
|||
lcapbc3 = 0; |
|||
} |
|||
if(vbx < fcpc) { |
|||
arg=1-vbx/pc; |
|||
sarg=exp(-xmc*log(arg)); |
|||
lcapbx1 = czbx*sarg; |
|||
lcapbx2 = |
|||
0.5*czbx*xmc*sarg/(arg*pc); |
|||
lcapbx3 = |
|||
czbx*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); |
|||
} else { |
|||
czbxf2=czbx/f2; |
|||
lcapbx1 = czbxf2*(f3+xmc*vbx/pc); |
|||
lcapbx2 = 0.5*xmc*czbxf2/pc; |
|||
lcapbx3 = 0; |
|||
} |
|||
if(vsc < 0){ |
|||
arg=1-vsc/ps; |
|||
sarg=exp(-xms*log(arg)); |
|||
lcapsc1 = czcs*sarg; |
|||
lcapsc2 = |
|||
0.5*czcs*xms*sarg/(arg*ps); |
|||
lcapsc3 = |
|||
czcs*xms*(xms+1)*sarg/(arg*arg*ps*ps*6); |
|||
} else { |
|||
lcapsc1 = czcs*(1+xms*vsc/ps); |
|||
lcapsc2 = czcs*0.5*xms/ps; |
|||
lcapsc3 = 0; |
|||
} |
|||
|
|||
/* |
|||
* store small-signal parameters |
|||
*/ |
|||
here->ic_x = d_ic.d1_p; |
|||
here->ic_y = d_ic.d1_q; |
|||
here->ic_xd = d_ic.d1_r; |
|||
here->ic_x2 = 0.5*model->BJT2type*d_ic.d2_p2; |
|||
here->ic_y2 = 0.5*model->BJT2type*d_ic.d2_q2; |
|||
here->ic_w2 = 0.5*model->BJT2type*d_ic.d2_r2; |
|||
here->ic_xy = model->BJT2type*d_ic.d2_pq; |
|||
here->ic_yw = model->BJT2type*d_ic.d2_qr; |
|||
here->ic_xw = model->BJT2type*d_ic.d2_pr; |
|||
here->ic_x3 = d_ic.d3_p3/6.; |
|||
here->ic_y3 = d_ic.d3_q3/6.; |
|||
here->ic_w3 = d_ic.d3_r3/6.; |
|||
here->ic_x2w = 0.5*d_ic.d3_p2r; |
|||
here->ic_x2y = 0.5*d_ic.d3_p2q; |
|||
here->ic_y2w = 0.5*d_ic.d3_q2r; |
|||
here->ic_xy2 = 0.5*d_ic.d3_pq2; |
|||
here->ic_xw2 = 0.5*d_ic.d3_pr2; |
|||
here->ic_yw2 = 0.5*d_ic.d3_qr2; |
|||
here->ic_xyw = d_ic.d3_pqr; |
|||
|
|||
here->ib_x = d_ib.d1_p; |
|||
here->ib_y = d_ib.d1_q; |
|||
here->ib_x2 = 0.5*model->BJT2type*d_ib.d2_p2; |
|||
here->ib_y2 = 0.5*model->BJT2type*d_ib.d2_q2; |
|||
here->ib_xy = model->BJT2type*d_ib.d2_pq; |
|||
here->ib_x3 = d_ib.d3_p3/6.; |
|||
here->ib_y3 = d_ib.d3_q3/6.; |
|||
here->ib_x2y = 0.5*d_ib.d3_p2q; |
|||
here->ib_xy2 = 0.5*d_ib.d3_pq2; |
|||
|
|||
here->ibb_x = d_ibb.d1_p; |
|||
here->ibb_y = d_ibb.d1_q; |
|||
here->ibb_z = d_ibb.d1_r; |
|||
here->ibb_x2 = 0.5*model->BJT2type*d_ibb.d2_p2; |
|||
here->ibb_y2 = 0.5*model->BJT2type*d_ibb.d2_q2; |
|||
here->ibb_z2 = 0.5*model->BJT2type*d_ibb.d2_r2; |
|||
here->ibb_xy = model->BJT2type*d_ibb.d2_pq; |
|||
here->ibb_yz = model->BJT2type*d_ibb.d2_qr; |
|||
here->ibb_xz = model->BJT2type*d_ibb.d2_pr; |
|||
here->ibb_x3 = d_ibb.d3_p3/6.; |
|||
here->ibb_y3 = d_ibb.d3_q3/6.; |
|||
here->ibb_z3 = d_ibb.d3_r3/6.; |
|||
here->ibb_x2z = 0.5*d_ibb.d3_p2r; |
|||
here->ibb_x2y = 0.5*d_ibb.d3_p2q; |
|||
here->ibb_y2z = 0.5*d_ibb.d3_q2r; |
|||
here->ibb_xy2 = 0.5*d_ibb.d3_pq2; |
|||
here->ibb_xz2 = 0.5*d_ibb.d3_pr2; |
|||
here->ibb_yz2 = 0.5*d_ibb.d3_qr2; |
|||
here->ibb_xyz = d_ibb.d3_pqr; |
|||
|
|||
here->qbe_x = d_qbe.d1_p; |
|||
here->qbe_y = d_qbe.d1_q; |
|||
here->qbe_x2 = 0.5*model->BJT2type*d_qbe.d2_p2; |
|||
here->qbe_y2 = 0.5*model->BJT2type*d_qbe.d2_q2; |
|||
here->qbe_xy = model->BJT2type*d_qbe.d2_pq; |
|||
here->qbe_x3 = d_qbe.d3_p3/6.; |
|||
here->qbe_y3 = d_qbe.d3_q3/6.; |
|||
here->qbe_x2y = 0.5*d_qbe.d3_p2q; |
|||
here->qbe_xy2 = 0.5*d_qbe.d3_pq2; |
|||
|
|||
here->capbc1 = lcapbc1; |
|||
here->capbc2 = lcapbc2; |
|||
here->capbc3 = lcapbc3; |
|||
|
|||
here->capbx1 = lcapbx1; |
|||
here->capbx2 = lcapbx2; |
|||
here->capbx3 = lcapbx3; |
|||
|
|||
here->capsc1 = lcapsc1; |
|||
here->capsc2 = lcapsc2; |
|||
here->capsc3 = lcapsc3; |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,5 +0,0 @@ |
|||
#ifndef __BJT2DSET_H |
|||
#define __BJT2DSET_H |
|||
|
|||
|
|||
#endif |
|||
@ -1,35 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
#ifndef __BJT2EXT_H |
|||
#define __BJT2EXT_H |
|||
|
|||
|
|||
extern int BJT2acLoad(GENmodel *,CKTcircuit*); |
|||
extern int BJT2ask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); |
|||
extern int BJT2convTest(GENmodel*,CKTcircuit*); |
|||
extern int BJT2delete(GENmodel*,IFuid,GENinstance**); |
|||
extern void BJT2destroy(GENmodel**); |
|||
extern int BJT2getic(GENmodel*,CKTcircuit*); |
|||
extern int BJT2load(GENmodel*,CKTcircuit*); |
|||
extern int BJT2mAsk(CKTcircuit*,GENmodel*,int,IFvalue*); |
|||
extern int BJT2mDelete(GENmodel**,IFuid,GENmodel*); |
|||
extern int BJT2mParam(int,IFvalue*,GENmodel*); |
|||
extern int BJT2param(int,IFvalue*,GENinstance*,IFvalue*); |
|||
extern int BJT2pzLoad(GENmodel*,CKTcircuit*,SPcomplex*); |
|||
extern int BJT2sAcLoad(GENmodel*,CKTcircuit*); |
|||
extern int BJT2sLoad(GENmodel*,CKTcircuit*); |
|||
extern void BJT2sPrint(GENmodel*,CKTcircuit*); |
|||
extern int BJT2sSetup(SENstruct*,GENmodel*); |
|||
extern int BJT2sUpdate(GENmodel*,CKTcircuit*); |
|||
extern int BJT2setup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); |
|||
extern int BJT2unsetup(GENmodel*,CKTcircuit*); |
|||
extern int BJT2temp(GENmodel*,CKTcircuit*); |
|||
extern int BJT2trunc(GENmodel*,CKTcircuit*,double*); |
|||
extern int BJT2disto(int,GENmodel*,CKTcircuit*); |
|||
extern int BJT2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); |
|||
extern int BJT2dSetup(GENmodel*, register CKTcircuit*); |
|||
|
|||
#endif |
|||
@ -1,49 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine gets the device initial conditions for the BJT2s |
|||
* from the RHS vector |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2getic(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
|
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
/* |
|||
* grab initial conditions out of rhs array. User specified, so use |
|||
* external nodes to get values |
|||
*/ |
|||
|
|||
for( ; model ; model = model->BJT2nextModel) { |
|||
for(here = model->BJT2instances; here ; here = here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
if(!here->BJT2icVBEGiven) { |
|||
here->BJT2icVBE = |
|||
*(ckt->CKTrhs + here->BJT2baseNode) - |
|||
*(ckt->CKTrhs + here->BJT2emitNode); |
|||
} |
|||
if(!here->BJT2icVCEGiven) { |
|||
here->BJT2icVCE = |
|||
*(ckt->CKTrhs + here->BJT2colNode) - |
|||
*(ckt->CKTrhs + here->BJT2emitNode); |
|||
} |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,84 +0,0 @@ |
|||
#include "config.h" |
|||
|
|||
#include "devdefs.h" |
|||
|
|||
#include "bjt2itf.h" |
|||
#include "bjt2ext.h" |
|||
#include "bjt2init.h" |
|||
|
|||
|
|||
SPICEdev BJT2info = { |
|||
{ |
|||
"BJT2", |
|||
"Bipolar Junction Transistor Level 2", |
|||
|
|||
&BJT2nSize, |
|||
&BJT2nSize, |
|||
BJT2names, |
|||
|
|||
&BJT2pTSize, |
|||
BJT2pTable, |
|||
|
|||
&BJT2mPTSize, |
|||
BJT2mPTable, |
|||
|
|||
#ifdef XSPICE |
|||
/*---- Fixed by SDB 5.2.2003 to enable XSPICE/tclspice integration -----*/ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
|
|||
0, /* This is a SPICE device, it has no MIF info data */ |
|||
NULL, /* This is a SPICE device, it has no MIF info data */ |
|||
/*--------------------------- End of SDB fix -------------------------*/ |
|||
#endif |
|||
|
|||
DEV_DEFAULT |
|||
}, |
|||
|
|||
/* DEVparam */ BJT2param, |
|||
/* DEVmodParam */ BJT2mParam, |
|||
/* DEVload */ BJT2load, |
|||
/* DEVsetup */ BJT2setup, |
|||
/* DEVunsetup */ BJT2unsetup, |
|||
/* DEVpzSetup */ BJT2setup, |
|||
/* DEVtemperature*/ BJT2temp, |
|||
/* DEVtrunc */ BJT2trunc, |
|||
/* DEVfindBranch */ NULL, |
|||
/* DEVacLoad */ BJT2acLoad, |
|||
/* DEVaccept */ NULL, |
|||
/* DEVdestroy */ BJT2destroy, |
|||
/* DEVmodDelete */ BJT2mDelete, |
|||
/* DEVdelete */ BJT2delete, |
|||
/* DEVsetic */ BJT2getic, |
|||
/* DEVask */ BJT2ask, |
|||
/* DEVmodAsk */ BJT2mAsk, |
|||
/* DEVpzLoad */ BJT2pzLoad, |
|||
/* DEVconvTest */ BJT2convTest, |
|||
/* DEVsenSetup */ BJT2sSetup, |
|||
/* DEVsenLoad */ BJT2sLoad, |
|||
/* DEVsenUpdate */ BJT2sUpdate, |
|||
/* DEVsenAcLoad */ BJT2sAcLoad, |
|||
/* DEVsenPrint */ BJT2sPrint, |
|||
/* DEVsenTrunc */ NULL, |
|||
/* DEVdisto */ BJT2disto, |
|||
/* DEVnoise */ BJT2noise, |
|||
#ifdef CIDER |
|||
/* DEVdump */ NULL, |
|||
/* DEVacct */ NULL, |
|||
#endif |
|||
/* DEVinstSize */ &BJT2iSize, |
|||
/* DEVmodSize */ &BJT2mSize |
|||
|
|||
}; |
|||
|
|||
|
|||
SPICEdev * |
|||
get_bjt2_info(void) |
|||
{ |
|||
return &BJT2info; |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
#ifndef _BJT2INIT_H |
|||
#define _BJT2INIT_H |
|||
|
|||
extern IFparm BJT2pTable[ ]; |
|||
extern IFparm BJT2mPTable[ ]; |
|||
extern char *BJT2names[ ]; |
|||
extern int BJT2pTSize; |
|||
extern int BJT2mPTSize; |
|||
extern int BJT2nSize; |
|||
extern int BJT2iSize; |
|||
extern int BJT2mSize; |
|||
|
|||
#endif |
|||
@ -1,11 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
#ifndef DEV_BJT2 |
|||
#define DEV_BJT2 |
|||
|
|||
extern SPICEdev *get_bjt2_info(void); |
|||
|
|||
|
|||
#endif |
|||
@ -1,817 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This is the function called each iteration to evaluate the |
|||
* BJT2s in the circuit and load them into the matrix as appropriate |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "trandefs.h" |
|||
#include "sperror.h" |
|||
#include "devdefs.h" |
|||
#include "suffix.h" |
|||
|
|||
int |
|||
BJT2load(GENmodel *inModel, CKTcircuit *ckt) |
|||
/* actually load the current resistance value into the |
|||
* sparse matrix previously provided |
|||
*/ |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
double arg1; |
|||
double arg2; |
|||
double arg3; |
|||
double arg; |
|||
double argtf; |
|||
double c2; |
|||
double c4; |
|||
double capbc; |
|||
double capbe; |
|||
double capbx=0; |
|||
double capsub=0; |
|||
double cb; |
|||
double cbc; |
|||
double cbcn; |
|||
double cbe; |
|||
double cben; |
|||
double cbhat; |
|||
double cc; |
|||
double cchat; |
|||
double cdis; |
|||
double ceq; |
|||
double ceqbc; |
|||
double ceqbe; |
|||
double ceqbx; |
|||
double geqsub; |
|||
double ceqsub; |
|||
double cex; |
|||
double csat; |
|||
double csubsat; |
|||
double ctot; |
|||
double czbc; |
|||
double czbcf2; |
|||
double czbe; |
|||
double czbef2; |
|||
double czbx; |
|||
double czbxf2; |
|||
double czsub; |
|||
double delvbc; |
|||
double delvbe; |
|||
double denom; |
|||
double dqbdvc; |
|||
double dqbdve; |
|||
double evbc; |
|||
double evbcn; |
|||
double evbe; |
|||
double evben; |
|||
double f1; |
|||
double f2; |
|||
double f3; |
|||
double fcpc; |
|||
double fcpe; |
|||
double gbc; |
|||
double gbcn; |
|||
double gbe; |
|||
double gben; |
|||
double gcsub; |
|||
double gcpr; |
|||
double gepr; |
|||
double geq; |
|||
double geqbx; |
|||
double geqcb; |
|||
double gex; |
|||
double gm; |
|||
double gmu; |
|||
double go; |
|||
double gpi; |
|||
double gx; |
|||
double oik; |
|||
double oikr; |
|||
double ovtf; |
|||
double pc; |
|||
double pe; |
|||
double ps; |
|||
double q1; |
|||
double q2; |
|||
double qb; |
|||
double rbpi; |
|||
double rbpr; |
|||
double sarg; |
|||
double sqarg; |
|||
double td; |
|||
double temp; |
|||
double tf; |
|||
double tr; |
|||
double vbc; |
|||
double vbe; |
|||
double vbx = 0.0; |
|||
double vce; |
|||
double vsub = 0.0; |
|||
double vt; |
|||
double vtc; |
|||
double vte; |
|||
double vtn; |
|||
#ifndef PREDICTOR |
|||
double xfact; |
|||
#endif |
|||
double xjrb; |
|||
double xjtf; |
|||
double xmc; |
|||
double xme; |
|||
double xms; |
|||
double xtf; |
|||
double evsub; |
|||
double gdsub; |
|||
double cdsub; |
|||
int icheck; |
|||
int ichk1; |
|||
int error; |
|||
int SenCond=0; |
|||
double m; |
|||
|
|||
/* loop through all the models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
vt = here->BJT2temp * CONSTKoverQ; |
|||
|
|||
if(ckt->CKTsenInfo){ |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2load \n"); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& |
|||
(here->BJT2senPertFlag == OFF)) continue; |
|||
SenCond = here->BJT2senPertFlag; |
|||
} |
|||
|
|||
|
|||
gcsub=0; |
|||
ceqsub=0; |
|||
geqbx=0; |
|||
ceqbx=0; |
|||
geqcb=0; |
|||
/* |
|||
* dc model paramters |
|||
*/ |
|||
csat=here->BJT2tSatCur*here->BJT2area; |
|||
csubsat=here->BJT2tSubSatCur*here->BJT2area; |
|||
rbpr=here->BJT2tMinBaseResist/here->BJT2area; |
|||
rbpi=here->BJT2tBaseResist/here->BJT2area-rbpr; |
|||
gcpr=here->BJT2tCollectorConduct*here->BJT2area; |
|||
gepr=here->BJT2tEmitterConduct*here->BJT2area; |
|||
oik=model->BJT2invRollOffF/here->BJT2area; |
|||
c2=here->BJT2tBEleakCur*here->BJT2area; |
|||
vte=model->BJT2leakBEemissionCoeff*vt; |
|||
oikr=model->BJT2invRollOffR/here->BJT2area; |
|||
|
|||
if (model->BJT2subs == VERTICAL) |
|||
c4=here->BJT2tBCleakCur * here->BJT2areab; |
|||
else |
|||
c4=here->BJT2tBCleakCur * here->BJT2areac; |
|||
|
|||
vtc=model->BJT2leakBCemissionCoeff*vt; |
|||
td=model->BJT2excessPhaseFactor; |
|||
xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area; |
|||
|
|||
if(SenCond){ |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senPertFlag = ON \n"); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
if((ckt->CKTsenInfo->SENmode == TRANSEN)&& |
|||
(ckt->CKTmode & MODEINITTRAN)) { |
|||
vbe = *(ckt->CKTstate1 + here->BJT2vbe); |
|||
vbc = *(ckt->CKTstate1 + here->BJT2vbc); |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOp+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOp+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOp+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOp+here->BJT2substConNode)); |
|||
} |
|||
else{ |
|||
vbe = *(ckt->CKTstate0 + here->BJT2vbe); |
|||
vbc = *(ckt->CKTstate0 + here->BJT2vbc); |
|||
if((ckt->CKTsenInfo->SENmode == DCSEN)|| |
|||
(ckt->CKTsenInfo->SENmode == TRANSEN)){ |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2substConNode)); |
|||
} |
|||
if(ckt->CKTsenInfo->SENmode == ACSEN){ |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOp+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOp+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOp+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOp+here->BJT2substConNode)); |
|||
} |
|||
} |
|||
goto next1; |
|||
} |
|||
|
|||
/* |
|||
* initialization |
|||
*/ |
|||
icheck=1; |
|||
if(ckt->CKTmode & MODEINITSMSIG) { |
|||
vbe= *(ckt->CKTstate0 + here->BJT2vbe); |
|||
vbc= *(ckt->CKTstate0 + here->BJT2vbc); |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2substConNode)); |
|||
} else if(ckt->CKTmode & MODEINITTRAN) { |
|||
vbe = *(ckt->CKTstate1 + here->BJT2vbe); |
|||
vbc = *(ckt->CKTstate1 + here->BJT2vbc); |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2substConNode)); |
|||
if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { |
|||
vbx=model->BJT2type*(here->BJT2icVBE-here->BJT2icVCE); |
|||
vsub=0; |
|||
} |
|||
} else if((ckt->CKTmode & MODEINITJCT) && |
|||
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ |
|||
vbe=model->BJT2type*here->BJT2icVBE; |
|||
vce=model->BJT2type*here->BJT2icVCE; |
|||
vbc=vbe-vce; |
|||
vbx=vbc; |
|||
vsub=0; |
|||
} else if((ckt->CKTmode & MODEINITJCT) && (here->BJT2off==0)) { |
|||
vbe=here->BJT2tVcrit; |
|||
vbc=0; |
|||
/* ERROR: need to initialize VCS, VBX here */ |
|||
vsub=vbx=0; |
|||
} else if((ckt->CKTmode & MODEINITJCT) || |
|||
( (ckt->CKTmode & MODEINITFIX) && (here->BJT2off!=0))) { |
|||
vbe=0; |
|||
vbc=0; |
|||
/* ERROR: need to initialize VCS, VBX here */ |
|||
vsub=vbx=0; |
|||
} else { |
|||
#ifndef PREDICTOR |
|||
if(ckt->CKTmode & MODEINITPRED) { |
|||
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = |
|||
*(ckt->CKTstate1 + here->BJT2vbe); |
|||
vbe = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbe)- |
|||
xfact* *(ckt->CKTstate2 + here->BJT2vbe); |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = |
|||
*(ckt->CKTstate1 + here->BJT2vbc); |
|||
vbc = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbc)- |
|||
xfact* *(ckt->CKTstate2 + here->BJT2vbc); |
|||
*(ckt->CKTstate0 + here->BJT2cc) = |
|||
*(ckt->CKTstate1 + here->BJT2cc); |
|||
*(ckt->CKTstate0 + here->BJT2cb) = |
|||
*(ckt->CKTstate1 + here->BJT2cb); |
|||
*(ckt->CKTstate0 + here->BJT2gpi) = |
|||
*(ckt->CKTstate1 + here->BJT2gpi); |
|||
*(ckt->CKTstate0 + here->BJT2gmu) = |
|||
*(ckt->CKTstate1 + here->BJT2gmu); |
|||
*(ckt->CKTstate0 + here->BJT2gm) = |
|||
*(ckt->CKTstate1 + here->BJT2gm); |
|||
*(ckt->CKTstate0 + here->BJT2go) = |
|||
*(ckt->CKTstate1 + here->BJT2go); |
|||
*(ckt->CKTstate0 + here->BJT2gx) = |
|||
*(ckt->CKTstate1 + here->BJT2gx); |
|||
*(ckt->CKTstate0 + here->BJT2vsub) = |
|||
*(ckt->CKTstate1 + here->BJT2vsub); |
|||
vsub = (1+xfact)**(ckt->CKTstate1 + here->BJT2vsub)- |
|||
xfact* *(ckt->CKTstate2 + here->BJT2vsub); |
|||
} else { |
|||
#endif /* PREDICTOR */ |
|||
/* |
|||
* compute new nonlinear branch voltages |
|||
*/ |
|||
vbe=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2basePrimeNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2emitPrimeNode)); |
|||
vbc=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2basePrimeNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2substConNode)); |
|||
#ifndef PREDICTOR |
|||
} |
|||
#endif /* PREDICTOR */ |
|||
delvbe=vbe- *(ckt->CKTstate0 + here->BJT2vbe); |
|||
delvbc=vbc- *(ckt->CKTstate0 + here->BJT2vbc); |
|||
vbx=model->BJT2type*( |
|||
*(ckt->CKTrhsOld+here->BJT2baseNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2colPrimeNode)); |
|||
vsub=model->BJT2type*model->BJT2subs*( |
|||
*(ckt->CKTrhsOld+here->BJT2substNode)- |
|||
*(ckt->CKTrhsOld+here->BJT2substConNode)); |
|||
cchat= *(ckt->CKTstate0 + here->BJT2cc)+(*(ckt->CKTstate0 + |
|||
here->BJT2gm)+ *(ckt->CKTstate0 + here->BJT2go))*delvbe- |
|||
(*(ckt->CKTstate0 + here->BJT2go)+*(ckt->CKTstate0 + |
|||
here->BJT2gmu))*delvbc; |
|||
cbhat= *(ckt->CKTstate0 + here->BJT2cb)+ *(ckt->CKTstate0 + |
|||
here->BJT2gpi)*delvbe+ *(ckt->CKTstate0 + here->BJT2gmu)* |
|||
delvbc; |
|||
#ifndef NOBYPASS |
|||
/* |
|||
* bypass if solution has not changed |
|||
*/ |
|||
/* the following collections of if's would be just one |
|||
* if the average compiler could handle it, but many |
|||
* find the expression too complicated, thus the split. |
|||
*/ |
|||
if( (ckt->CKTbypass) && |
|||
(!(ckt->CKTmode & MODEINITPRED)) && |
|||
(fabs(delvbe) < (ckt->CKTreltol*MAX(fabs(vbe), |
|||
fabs(*(ckt->CKTstate0 + here->BJT2vbe)))+ |
|||
ckt->CKTvoltTol)) ) |
|||
if( (fabs(delvbc) < ckt->CKTreltol*MAX(fabs(vbc), |
|||
fabs(*(ckt->CKTstate0 + here->BJT2vbc)))+ |
|||
ckt->CKTvoltTol) ) |
|||
if( (fabs(cchat-*(ckt->CKTstate0 + here->BJT2cc)) < |
|||
ckt->CKTreltol* MAX(fabs(cchat), |
|||
fabs(*(ckt->CKTstate0 + here->BJT2cc)))+ |
|||
ckt->CKTabstol) ) |
|||
if( (fabs(cbhat-*(ckt->CKTstate0 + here->BJT2cb)) < |
|||
ckt->CKTreltol* MAX(fabs(cbhat), |
|||
fabs(*(ckt->CKTstate0 + here->BJT2cb)))+ |
|||
ckt->CKTabstol) ) { |
|||
/* |
|||
* bypassing.... |
|||
*/ |
|||
vbe = *(ckt->CKTstate0 + here->BJT2vbe); |
|||
vbc = *(ckt->CKTstate0 + here->BJT2vbc); |
|||
cc = *(ckt->CKTstate0 + here->BJT2cc); |
|||
cb = *(ckt->CKTstate0 + here->BJT2cb); |
|||
gpi = *(ckt->CKTstate0 + here->BJT2gpi); |
|||
gmu = *(ckt->CKTstate0 + here->BJT2gmu); |
|||
gm = *(ckt->CKTstate0 + here->BJT2gm); |
|||
go = *(ckt->CKTstate0 + here->BJT2go); |
|||
gx = *(ckt->CKTstate0 + here->BJT2gx); |
|||
geqcb = *(ckt->CKTstate0 + here->BJT2geqcb); |
|||
gcsub = *(ckt->CKTstate0 + here->BJT2gcsub); |
|||
geqbx = *(ckt->CKTstate0 + here->BJT2geqbx); |
|||
vsub = *(ckt->CKTstate0 + here->BJT2vsub); |
|||
gdsub = *(ckt->CKTstate0 + here->BJT2gdsub); |
|||
cdsub = *(ckt->CKTstate0 + here->BJT2cdsub); |
|||
goto load; |
|||
} |
|||
#endif /*NOBYPASS*/ |
|||
/* |
|||
* limit nonlinear branch voltages |
|||
*/ |
|||
ichk1=1; |
|||
vbe = DEVpnjlim(vbe,*(ckt->CKTstate0 + here->BJT2vbe),vt, |
|||
here->BJT2tVcrit,&icheck); |
|||
vbc = DEVpnjlim(vbc,*(ckt->CKTstate0 + here->BJT2vbc),vt, |
|||
here->BJT2tVcrit,&ichk1); |
|||
if (ichk1 == 1) icheck=1; |
|||
vsub = DEVpnjlim(vsub,*(ckt->CKTstate0 + here->BJT2vsub),vt, |
|||
here->BJT2tSubVcrit,&ichk1); |
|||
if (ichk1 == 1) icheck=1; |
|||
} |
|||
/* |
|||
* determine dc current and derivitives |
|||
*/ |
|||
next1: vtn=vt*model->BJT2emissionCoeffF; |
|||
if(vbe >= -3*vtn){ |
|||
evbe=exp(vbe/vtn); |
|||
cbe=csat*(evbe-1); |
|||
gbe=csat*evbe/vtn; |
|||
} else { |
|||
arg=3*vtn/(vbe*CONSTe); |
|||
arg = arg * arg * arg; |
|||
cbe = -csat*(1+arg); |
|||
gbe = csat*3*arg/vbe; |
|||
} |
|||
if (c2 == 0) { |
|||
cben=0; |
|||
gben=0; |
|||
} else { |
|||
if(vbe >= -3*vte){ |
|||
evben=exp(vbe/vte); |
|||
cben=c2*(evben-1); |
|||
gben=c2*evben/vte; |
|||
} else { |
|||
arg=3*vte/(vbe*CONSTe); |
|||
arg = arg * arg * arg; |
|||
cben = -c2*(1+arg); |
|||
gben = c2*3*arg/vbe; |
|||
} |
|||
} |
|||
gben+=ckt->CKTgmin; |
|||
cben+=ckt->CKTgmin*vbe; |
|||
vtn=vt*model->BJT2emissionCoeffR; |
|||
if(vbc >= -3*vtn) { |
|||
evbc=exp(vbc/vtn); |
|||
cbc=csat*(evbc-1); |
|||
gbc=csat*evbc/vtn; |
|||
} else { |
|||
arg=3*vtn/(vbc*CONSTe); |
|||
arg = arg * arg * arg; |
|||
cbc = -csat*(1+arg); |
|||
gbc = csat*3*arg/vbc; |
|||
} |
|||
if (c4 == 0) { |
|||
cbcn=0; |
|||
gbcn=0; |
|||
} else { |
|||
if(vbc >= -3*vtc) { |
|||
evbcn=exp(vbc/vtc); |
|||
cbcn=c4*(evbcn-1); |
|||
gbcn=c4*evbcn/vtc; |
|||
} else { |
|||
arg=3*vtc/(vbc*CONSTe); |
|||
arg = arg * arg * arg; |
|||
cbcn = -c4*(1+arg); |
|||
gbcn = c4*3*arg/vbc; |
|||
} |
|||
} |
|||
gbcn+=ckt->CKTgmin; |
|||
cbcn+=ckt->CKTgmin*vbc; |
|||
if(vsub <= -3*vt) { |
|||
arg=3*vt/(vsub*CONSTe); |
|||
arg = arg * arg * arg; |
|||
gdsub = csubsat*3*arg/vsub+ckt->CKTgmin; |
|||
cdsub = -csubsat*(1+arg)+ckt->CKTgmin*vsub; |
|||
} else { |
|||
evsub = exp(MIN(MAX_EXP_ARG,vsub/vt)); |
|||
gdsub = csubsat*evsub/vt + ckt->CKTgmin; |
|||
cdsub = csubsat*(evsub-1) + ckt->CKTgmin*vsub; |
|||
} |
|||
/* |
|||
* determine base charge terms |
|||
*/ |
|||
q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); |
|||
if(oik == 0 && oikr == 0) { |
|||
qb=q1; |
|||
dqbdve=q1*qb*model->BJT2invEarlyVoltR; |
|||
dqbdvc=q1*qb*model->BJT2invEarlyVoltF; |
|||
} else { |
|||
q2=oik*cbe+oikr*cbc; |
|||
arg=MAX(0,1+4*q2); |
|||
sqarg=1; |
|||
if(arg != 0) sqarg=sqrt(arg); |
|||
qb=q1*(1+sqarg)/2; |
|||
dqbdve=q1*(qb*model->BJT2invEarlyVoltR+oik*gbe/sqarg); |
|||
dqbdvc=q1*(qb*model->BJT2invEarlyVoltF+oikr*gbc/sqarg); |
|||
} |
|||
/* |
|||
* weil's approx. for excess phase applied with backward- |
|||
* euler integration |
|||
*/ |
|||
cc=0; |
|||
cex=cbe; |
|||
gex=gbe; |
|||
if(ckt->CKTmode & (MODETRAN | MODEAC) && td != 0) { |
|||
arg1=ckt->CKTdelta/td; |
|||
arg2=3*arg1; |
|||
arg1=arg2*arg1; |
|||
denom=1+arg1+arg2; |
|||
arg3=arg1/denom; |
|||
if(ckt->CKTmode & MODEINITTRAN) { |
|||
*(ckt->CKTstate1 + here->BJT2cexbc)=cbe/qb; |
|||
*(ckt->CKTstate2 + here->BJT2cexbc)= |
|||
*(ckt->CKTstate1 + here->BJT2cexbc); |
|||
} |
|||
cc=(*(ckt->CKTstate1 + here->BJT2cexbc)*(1+ckt->CKTdelta/ |
|||
ckt->CKTdeltaOld[1]+arg2)- |
|||
*(ckt->CKTstate2 + here->BJT2cexbc)*ckt->CKTdelta/ |
|||
ckt->CKTdeltaOld[1])/denom; |
|||
cex=cbe*arg3; |
|||
gex=gbe*arg3; |
|||
*(ckt->CKTstate0 + here->BJT2cexbc)=cc+cex/qb; |
|||
} |
|||
/* |
|||
* determine dc incremental conductances |
|||
*/ |
|||
cc=cc+(cex-cbc)/qb-cbc/here->BJT2tBetaR-cbcn; |
|||
cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; |
|||
gx=rbpr+rbpi/qb; |
|||
if(xjrb != 0) { |
|||
arg1=MAX(cb/xjrb,1e-9); |
|||
arg2=(-1+sqrt(1+14.59025*arg1))/2.4317/sqrt(arg1); |
|||
arg1=tan(arg2); |
|||
gx=rbpr+3*rbpi*(arg1-arg2)/arg2/arg1/arg1; |
|||
} |
|||
if(gx != 0) gx=1/gx; |
|||
gpi=gbe/here->BJT2tBetaF+gben; |
|||
gmu=gbc/here->BJT2tBetaR+gbcn; |
|||
go=(gbc+(cex-cbc)*dqbdvc/qb)/qb; |
|||
gm=(gex-(cex-cbc)*dqbdve/qb)/qb-go; |
|||
if( (ckt->CKTmode & (MODETRAN | MODEAC)) || |
|||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || |
|||
(ckt->CKTmode & MODEINITSMSIG)) { |
|||
/* |
|||
* charge storage elements |
|||
*/ |
|||
tf=model->BJT2transitTimeF; |
|||
tr=model->BJT2transitTimeR; |
|||
czbe=here->BJT2tBEcap*here->BJT2area; |
|||
pe=here->BJT2tBEpot; |
|||
xme=model->BJT2junctionExpBE; |
|||
cdis=model->BJT2baseFractionBCcap; |
|||
|
|||
if (model->BJT2subs == VERTICAL) |
|||
ctot=here->BJT2tBCcap*here->BJT2areab; |
|||
else |
|||
ctot=here->BJT2tBCcap*here->BJT2areac; |
|||
|
|||
czbc=ctot*cdis; |
|||
czbx=ctot-czbc; |
|||
pc=here->BJT2tBCpot; |
|||
xmc=model->BJT2junctionExpBC; |
|||
fcpe=here->BJT2tDepCap; |
|||
|
|||
if (model->BJT2subs == VERTICAL) |
|||
czsub=here->BJT2tSubcap*here->BJT2areac; |
|||
else |
|||
czsub=here->BJT2tSubcap*here->BJT2areab; |
|||
|
|||
ps=here->BJT2tSubpot; |
|||
xms=model->BJT2exponentialSubstrate; |
|||
xtf=model->BJT2transitTimeBiasCoeffF; |
|||
ovtf=model->BJT2transitTimeVBCFactor; |
|||
xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area; |
|||
if(tf != 0 && vbe >0) { |
|||
argtf=0; |
|||
arg2=0; |
|||
arg3=0; |
|||
if(xtf != 0){ |
|||
argtf=xtf; |
|||
if(ovtf != 0) { |
|||
argtf=argtf*exp(vbc*ovtf); |
|||
} |
|||
arg2=argtf; |
|||
if(xjtf != 0) { |
|||
temp=cbe/(cbe+xjtf); |
|||
argtf=argtf*temp*temp; |
|||
arg2=argtf*(3-temp-temp); |
|||
} |
|||
arg3=cbe*argtf*ovtf; |
|||
} |
|||
cbe=cbe*(1+argtf)/qb; |
|||
gbe=(gbe*(1+arg2)-cbe*dqbdve)/qb; |
|||
geqcb=tf*(arg3-cbe*dqbdvc)/qb; |
|||
} |
|||
if (vbe < fcpe) { |
|||
arg=1-vbe/pe; |
|||
sarg=exp(-xme*log(arg)); |
|||
*(ckt->CKTstate0 + here->BJT2qbe)=tf*cbe+pe*czbe* |
|||
(1-arg*sarg)/(1-xme); |
|||
capbe=tf*gbe+czbe*sarg; |
|||
} else { |
|||
f1=here->BJT2tf1; |
|||
f2=model->BJT2f2; |
|||
f3=model->BJT2f3; |
|||
czbef2=czbe/f2; |
|||
*(ckt->CKTstate0 + here->BJT2qbe) = tf*cbe+czbe*f1+czbef2* |
|||
(f3*(vbe-fcpe) +(xme/(pe+pe))*(vbe*vbe-fcpe*fcpe)); |
|||
capbe=tf*gbe+czbef2*(f3+xme*vbe/pe); |
|||
} |
|||
fcpc=here->BJT2tf4; |
|||
f1=here->BJT2tf5; |
|||
f2=model->BJT2f6; |
|||
f3=model->BJT2f7; |
|||
if (vbc < fcpc) { |
|||
arg=1-vbc/pc; |
|||
sarg=exp(-xmc*log(arg)); |
|||
*(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+pc*czbc*( |
|||
1-arg*sarg)/(1-xmc); |
|||
capbc=tr*gbc+czbc*sarg; |
|||
} else { |
|||
czbcf2=czbc/f2; |
|||
*(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+czbc*f1+czbcf2* |
|||
(f3*(vbc-fcpc) +(xmc/(pc+pc))*(vbc*vbc-fcpc*fcpc)); |
|||
capbc=tr*gbc+czbcf2*(f3+xmc*vbc/pc); |
|||
} |
|||
if(vbx < fcpc) { |
|||
arg=1-vbx/pc; |
|||
sarg=exp(-xmc*log(arg)); |
|||
*(ckt->CKTstate0 + here->BJT2qbx)= |
|||
pc*czbx* (1-arg*sarg)/(1-xmc); |
|||
capbx=czbx*sarg; |
|||
} else { |
|||
czbxf2=czbx/f2; |
|||
*(ckt->CKTstate0 + here->BJT2qbx)=czbx*f1+czbxf2* |
|||
(f3*(vbx-fcpc)+(xmc/(pc+pc))*(vbx*vbx-fcpc*fcpc)); |
|||
capbx=czbxf2*(f3+xmc*vbx/pc); |
|||
} |
|||
if(vsub < 0){ |
|||
arg=1-vsub/ps; |
|||
sarg=exp(-xms*log(arg)); |
|||
*(ckt->CKTstate0 + here->BJT2qsub) = ps*czsub*(1-arg*sarg)/ |
|||
(1-xms); |
|||
capsub=czsub*sarg; |
|||
} else { |
|||
*(ckt->CKTstate0 + here->BJT2qsub) = vsub*czsub*(1+xms*vsub/ |
|||
(2*ps)); |
|||
capsub=czsub*(1+xms*vsub/ps); |
|||
} |
|||
here->BJT2capbe = capbe; |
|||
here->BJT2capbc = capbc; |
|||
here->BJT2capsub = capsub; |
|||
here->BJT2capbx = capbx; |
|||
|
|||
/* |
|||
* store small-signal parameters |
|||
*/ |
|||
if ( (!(ckt->CKTmode & MODETRANOP))|| |
|||
(!(ckt->CKTmode & MODEUIC)) ) { |
|||
if(ckt->CKTmode & MODEINITSMSIG) { |
|||
*(ckt->CKTstate0 + here->BJT2cqbe) = capbe; |
|||
*(ckt->CKTstate0 + here->BJT2cqbc) = capbc; |
|||
*(ckt->CKTstate0 + here->BJT2cqsub) = capsub; |
|||
*(ckt->CKTstate0 + here->BJT2cqbx) = capbx; |
|||
*(ckt->CKTstate0 + here->BJT2cexbc) = geqcb; |
|||
if(SenCond){ |
|||
*(ckt->CKTstate0 + here->BJT2cc) = cc; |
|||
*(ckt->CKTstate0 + here->BJT2cb) = cb; |
|||
*(ckt->CKTstate0 + here->BJT2gpi) = gpi; |
|||
*(ckt->CKTstate0 + here->BJT2gmu) = gmu; |
|||
*(ckt->CKTstate0 + here->BJT2gm) = gm; |
|||
*(ckt->CKTstate0 + here->BJT2go) = go; |
|||
*(ckt->CKTstate0 + here->BJT2gx) = gx; |
|||
*(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; |
|||
*(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; |
|||
} |
|||
#ifdef SENSDEBUG |
|||
printf("storing small signal parameters for op\n"); |
|||
printf("capbe = %.7e ,capbc = %.7e\n",capbe,capbc); |
|||
printf("capsub = %.7e ,capbx = %.7e\n",capsub,capbx); |
|||
printf("geqcb = %.7e ,gpi = %.7e\n",geqcb,gpi); |
|||
printf("gmu = %.7e ,gm = %.7e\n",gmu,gm); |
|||
printf("go = %.7e ,gx = %.7e\n",go,gx); |
|||
printf("gcsub = %.7e ,geqbx = %.7e\n",gcsub,geqbx); |
|||
printf("cc = %.7e ,cb = %.7e\n",cc,cb); |
|||
#endif /* SENSDEBUG */ |
|||
continue; /* go to 1000 */ |
|||
} |
|||
/* |
|||
* transient analysis |
|||
*/ |
|||
if(SenCond && ckt->CKTsenInfo->SENmode == TRANSEN){ |
|||
*(ckt->CKTstate0 + here->BJT2cc) = cc; |
|||
*(ckt->CKTstate0 + here->BJT2cb) = cb; |
|||
*(ckt->CKTstate0 + here->BJT2gx) = gx; |
|||
continue; |
|||
} |
|||
|
|||
if(ckt->CKTmode & MODEINITTRAN) { |
|||
*(ckt->CKTstate1 + here->BJT2qbe) = |
|||
*(ckt->CKTstate0 + here->BJT2qbe) ; |
|||
*(ckt->CKTstate1 + here->BJT2qbc) = |
|||
*(ckt->CKTstate0 + here->BJT2qbc) ; |
|||
*(ckt->CKTstate1 + here->BJT2qbx) = |
|||
*(ckt->CKTstate0 + here->BJT2qbx) ; |
|||
*(ckt->CKTstate1 + here->BJT2qsub) = |
|||
*(ckt->CKTstate0 + here->BJT2qsub) ; |
|||
} |
|||
error = NIintegrate(ckt,&geq,&ceq,capbe,here->BJT2qbe); |
|||
if(error) return(error); |
|||
geqcb=geqcb*ckt->CKTag[0]; |
|||
gpi=gpi+geq; |
|||
cb=cb+*(ckt->CKTstate0 + here->BJT2cqbe); |
|||
error = NIintegrate(ckt,&geq,&ceq,capbc,here->BJT2qbc); |
|||
if(error) return(error); |
|||
gmu=gmu+geq; |
|||
cb=cb+*(ckt->CKTstate0 + here->BJT2cqbc); |
|||
cc=cc-*(ckt->CKTstate0 + here->BJT2cqbc); |
|||
if(ckt->CKTmode & MODEINITTRAN) { |
|||
*(ckt->CKTstate1 + here->BJT2cqbe) = |
|||
*(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(ckt->CKTstate1 + here->BJT2cqbc) = |
|||
*(ckt->CKTstate0 + here->BJT2cqbc); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if(SenCond) goto next2; |
|||
|
|||
/* |
|||
* check convergence |
|||
*/ |
|||
if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->BJT2off))) { |
|||
if (icheck == 1) { |
|||
ckt->CKTnoncon++; |
|||
ckt->CKTtroubleElt = (GENinstance *) here; |
|||
} |
|||
} |
|||
|
|||
/* |
|||
* charge storage for c-s and b-x junctions |
|||
*/ |
|||
if(ckt->CKTmode & (MODETRAN | MODEAC)) { |
|||
error = NIintegrate(ckt,&gcsub,&ceq,capsub,here->BJT2qsub); |
|||
if(error) return(error); |
|||
error = NIintegrate(ckt,&geqbx,&ceq,capbx,here->BJT2qbx); |
|||
if(error) return(error); |
|||
if(ckt->CKTmode & MODEINITTRAN) { |
|||
*(ckt->CKTstate1 + here->BJT2cqbx) = |
|||
*(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(ckt->CKTstate1 + here->BJT2cqsub) = |
|||
*(ckt->CKTstate0 + here->BJT2cqsub); |
|||
} |
|||
} |
|||
next2: |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbe; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbc; |
|||
*(ckt->CKTstate0 + here->BJT2cc) = cc; |
|||
*(ckt->CKTstate0 + here->BJT2cb) = cb; |
|||
*(ckt->CKTstate0 + here->BJT2gpi) = gpi; |
|||
*(ckt->CKTstate0 + here->BJT2gmu) = gmu; |
|||
*(ckt->CKTstate0 + here->BJT2gm) = gm; |
|||
*(ckt->CKTstate0 + here->BJT2go) = go; |
|||
*(ckt->CKTstate0 + here->BJT2gx) = gx; |
|||
*(ckt->CKTstate0 + here->BJT2geqcb) = geqcb; |
|||
*(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; |
|||
*(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; |
|||
*(ckt->CKTstate0 + here->BJT2vsub) = vsub; |
|||
*(ckt->CKTstate0 + here->BJT2gdsub) = gdsub; |
|||
*(ckt->CKTstate0 + here->BJT2cdsub) = cdsub; |
|||
|
|||
|
|||
/* Do not load the Jacobian and the rhs if |
|||
perturbation is being carried out */ |
|||
|
|||
if(SenCond)continue; |
|||
#ifndef NOBYPASS |
|||
load: |
|||
#endif |
|||
m = here->BJT2m; |
|||
/* |
|||
* load current excitation vector |
|||
*/ |
|||
geqsub = gcsub + gdsub; |
|||
ceqsub=model->BJT2type * model->BJT2subs * |
|||
(*(ckt->CKTstate0 + here->BJT2cqsub) + cdsub - vsub*geqsub); |
|||
/* |
|||
ceqsub=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqsub) + |
|||
model->BJT2subs*cdsub - vsub*geqsub); |
|||
*/ |
|||
ceqbx=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqbx) - |
|||
vbx * geqbx); |
|||
ceqbe=model->BJT2type * (cc + cb - vbe * (gm + go + gpi) + vbc * |
|||
(go - geqcb)); |
|||
ceqbc=model->BJT2type * (-cc + vbe * (gm + go) - vbc * (gmu + go)); |
|||
|
|||
*(ckt->CKTrhs + here->BJT2baseNode) += m * (-ceqbx); |
|||
*(ckt->CKTrhs + here->BJT2colPrimeNode) += |
|||
m * (ceqbx+ceqbc); |
|||
*(ckt->CKTrhs + here->BJT2substConNode) += m * ceqsub; |
|||
*(ckt->CKTrhs + here->BJT2basePrimeNode) += |
|||
m * (-ceqbe-ceqbc); |
|||
*(ckt->CKTrhs + here->BJT2emitPrimeNode) += m * (ceqbe); |
|||
*(ckt->CKTrhs + here->BJT2substNode) += m * (-ceqsub); |
|||
|
|||
/* |
|||
* load y matrix |
|||
*/ |
|||
*(here->BJT2colColPtr) += m * (gcpr); |
|||
*(here->BJT2baseBasePtr) += m * (gx+geqbx); |
|||
*(here->BJT2emitEmitPtr) += m * (gepr); |
|||
*(here->BJT2colPrimeColPrimePtr) += m * (gmu+go+gcpr+geqbx); |
|||
*(here->BJT2substConSubstConPtr) += m * (geqsub); |
|||
*(here->BJT2basePrimeBasePrimePtr) += m * (gx +gpi+gmu+geqcb); |
|||
*(here->BJT2emitPrimeEmitPrimePtr) += m * (gpi+gepr+gm+go); |
|||
*(here->BJT2colColPrimePtr) += m * (-gcpr); |
|||
*(here->BJT2baseBasePrimePtr) += m * (-gx); |
|||
*(here->BJT2emitEmitPrimePtr) += m * (-gepr); |
|||
*(here->BJT2colPrimeColPtr) += m * (-gcpr); |
|||
*(here->BJT2colPrimeBasePrimePtr) += m * (-gmu+gm); |
|||
*(here->BJT2colPrimeEmitPrimePtr) += m * (-gm-go); |
|||
*(here->BJT2basePrimeBasePtr) += m * (-gx); |
|||
*(here->BJT2basePrimeColPrimePtr) += m * (-gmu-geqcb); |
|||
*(here->BJT2basePrimeEmitPrimePtr) += m * (-gpi); |
|||
*(here->BJT2emitPrimeEmitPtr) += m * (-gepr); |
|||
*(here->BJT2emitPrimeColPrimePtr) += m * (-go+geqcb); |
|||
*(here->BJT2emitPrimeBasePrimePtr) += m * (-gpi-gm-geqcb); |
|||
*(here->BJT2substSubstPtr) += m * (geqsub); |
|||
*(here->BJT2substConSubstPtr) += m * (-geqsub); |
|||
*(here->BJT2substSubstConPtr) += m * (-geqsub); |
|||
*(here->BJT2baseColPrimePtr) += m * (-geqbx); |
|||
*(here->BJT2colPrimeBasePtr) += m * (-geqbx); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,231 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1987 Mathew Lew and Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "cktdefs.h" |
|||
#include "devdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/*ARGSUSED*/ |
|||
int |
|||
BJT2mAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) |
|||
{ |
|||
BJT2model *here = (BJT2model*)instPtr; |
|||
|
|||
NG_IGNORE(ckt); |
|||
|
|||
switch(which) { |
|||
case BJT2_MOD_TNOM: |
|||
value->rValue = here->BJT2tnom-CONSTCtoK; |
|||
return(OK); |
|||
case BJT2_MOD_IS: |
|||
value->rValue = here->BJT2satCur; |
|||
return(OK); |
|||
case BJT2_MOD_ISS: |
|||
value->rValue = here->BJT2subSatCur; |
|||
return(OK); |
|||
case BJT2_MOD_BF: |
|||
value->rValue = here->BJT2betaF; |
|||
return(OK); |
|||
case BJT2_MOD_NF: |
|||
value->rValue = here->BJT2emissionCoeffF; |
|||
return(OK); |
|||
case BJT2_MOD_VAF: |
|||
value->rValue = here->BJT2earlyVoltF; |
|||
return(OK); |
|||
case BJT2_MOD_IKF: |
|||
value->rValue = here->BJT2rollOffF; |
|||
return(OK); |
|||
case BJT2_MOD_ISE: |
|||
value->rValue = here->BJT2leakBEcurrent; |
|||
return(OK); |
|||
case BJT2_MOD_C2: |
|||
value->rValue = here->BJT2c2; |
|||
return(OK); |
|||
case BJT2_MOD_NE: |
|||
value->rValue = here->BJT2leakBEemissionCoeff; |
|||
return(OK); |
|||
case BJT2_MOD_BR: |
|||
value->rValue = here->BJT2betaR; |
|||
return(OK); |
|||
case BJT2_MOD_NR: |
|||
value->rValue = here->BJT2emissionCoeffR; |
|||
return(OK); |
|||
case BJT2_MOD_VAR: |
|||
value->rValue = here->BJT2earlyVoltR; |
|||
return(OK); |
|||
case BJT2_MOD_IKR: |
|||
value->rValue = here->BJT2rollOffR; |
|||
return(OK); |
|||
case BJT2_MOD_ISC: |
|||
value->rValue = here->BJT2leakBCcurrent; |
|||
return(OK); |
|||
case BJT2_MOD_C4: |
|||
value->rValue = here->BJT2c4; |
|||
return(OK); |
|||
case BJT2_MOD_NC: |
|||
value->rValue = here->BJT2leakBCemissionCoeff; |
|||
return(OK); |
|||
case BJT2_MOD_RB: |
|||
value->rValue = here->BJT2baseResist; |
|||
return(OK); |
|||
case BJT2_MOD_IRB: |
|||
value->rValue = here->BJT2baseCurrentHalfResist; |
|||
return(OK); |
|||
case BJT2_MOD_RBM: |
|||
value->rValue = here->BJT2minBaseResist; |
|||
return(OK); |
|||
case BJT2_MOD_RE: |
|||
value->rValue = here->BJT2emitterResist; |
|||
return(OK); |
|||
case BJT2_MOD_RC: |
|||
value->rValue = here->BJT2collectorResist; |
|||
return(OK); |
|||
case BJT2_MOD_CJE: |
|||
value->rValue = here->BJT2depletionCapBE; |
|||
return(OK); |
|||
case BJT2_MOD_VJE: |
|||
value->rValue = here->BJT2potentialBE; |
|||
return(OK); |
|||
case BJT2_MOD_MJE: |
|||
value->rValue = here->BJT2junctionExpBE; |
|||
return(OK); |
|||
case BJT2_MOD_TF: |
|||
value->rValue = here->BJT2transitTimeF; |
|||
return(OK); |
|||
case BJT2_MOD_XTF: |
|||
value->rValue = here->BJT2transitTimeBiasCoeffF; |
|||
return(OK); |
|||
case BJT2_MOD_VTF: |
|||
value->rValue = here->BJT2transitTimeFVBC; |
|||
return(OK); |
|||
case BJT2_MOD_ITF: |
|||
value->rValue = here->BJT2transitTimeHighCurrentF; |
|||
return(OK); |
|||
case BJT2_MOD_PTF: |
|||
value->rValue = here->BJT2excessPhase; |
|||
return(OK); |
|||
case BJT2_MOD_CJC: |
|||
value->rValue = here->BJT2depletionCapBC; |
|||
return(OK); |
|||
case BJT2_MOD_VJC: |
|||
value->rValue = here->BJT2potentialBC; |
|||
return(OK); |
|||
case BJT2_MOD_MJC: |
|||
value->rValue = here->BJT2junctionExpBC; |
|||
return(OK); |
|||
case BJT2_MOD_XCJC: |
|||
value->rValue = here->BJT2baseFractionBCcap; |
|||
return(OK); |
|||
case BJT2_MOD_TR: |
|||
value->rValue = here->BJT2transitTimeR; |
|||
return(OK); |
|||
case BJT2_MOD_CJS: |
|||
value->rValue = here->BJT2capSub; |
|||
return(OK); |
|||
case BJT2_MOD_VJS: |
|||
value->rValue = here->BJT2potentialSubstrate; |
|||
return(OK); |
|||
case BJT2_MOD_MJS: |
|||
value->rValue = here->BJT2exponentialSubstrate; |
|||
return(OK); |
|||
case BJT2_MOD_XTB: |
|||
value->rValue = here->BJT2betaExp; |
|||
return(OK); |
|||
case BJT2_MOD_EG: |
|||
value->rValue = here->BJT2energyGap; |
|||
return(OK); |
|||
case BJT2_MOD_XTI: |
|||
value->rValue = here->BJT2tempExpIS; |
|||
return(OK); |
|||
case BJT2_MOD_TRE1: |
|||
value->rValue = here->BJT2reTempCoeff1; |
|||
return(OK); |
|||
case BJT2_MOD_TRE2: |
|||
value->rValue = here->BJT2reTempCoeff2; |
|||
return(OK); |
|||
case BJT2_MOD_TRC1: |
|||
value->rValue = here->BJT2rcTempCoeff1; |
|||
return(OK); |
|||
case BJT2_MOD_TRC2: |
|||
value->rValue = here->BJT2rcTempCoeff2; |
|||
return(OK); |
|||
case BJT2_MOD_TRB1: |
|||
value->rValue = here->BJT2rbTempCoeff1; |
|||
return(OK); |
|||
case BJT2_MOD_TRB2: |
|||
value->rValue = here->BJT2rbTempCoeff2; |
|||
return(OK); |
|||
case BJT2_MOD_TRBM1: |
|||
value->rValue = here->BJT2rbmTempCoeff1; |
|||
return(OK); |
|||
case BJT2_MOD_TRBM2: |
|||
value->rValue = here->BJT2rbmTempCoeff2; |
|||
return(OK); |
|||
case BJT2_MOD_FC: |
|||
value->rValue = here->BJT2depletionCapCoeff; |
|||
return(OK); |
|||
case BJT2_MOD_INVEARLYF: |
|||
value->rValue = here->BJT2invEarlyVoltF; |
|||
return(OK); |
|||
case BJT2_MOD_INVEARLYR: |
|||
value->rValue = here->BJT2invEarlyVoltR; |
|||
return(OK); |
|||
case BJT2_MOD_INVROLLOFFF: |
|||
value->rValue = here->BJT2invRollOffF; |
|||
return(OK); |
|||
case BJT2_MOD_INVROLLOFFR: |
|||
value->rValue = here->BJT2invRollOffR; |
|||
return(OK); |
|||
case BJT2_MOD_COLCONDUCT: |
|||
value->rValue = here->BJT2collectorConduct; |
|||
return(OK); |
|||
case BJT2_MOD_EMITTERCONDUCT: |
|||
value->rValue = here->BJT2emitterConduct; |
|||
return(OK); |
|||
case BJT2_MOD_TRANSVBCFACT: |
|||
value->rValue = here->BJT2transitTimeVBCFactor; |
|||
return(OK); |
|||
case BJT2_MOD_EXCESSPHASEFACTOR: |
|||
value->rValue = here->BJT2excessPhaseFactor; |
|||
return(OK); |
|||
case BJT2_MOD_KF: |
|||
if (here->BJT2fNcoefGiven) |
|||
value->rValue = here->BJT2fNcoef; |
|||
else |
|||
value->rValue = 0.0; |
|||
return(OK); |
|||
case BJT2_MOD_AF: |
|||
if (here->BJT2fNexpGiven) |
|||
value->rValue = here->BJT2fNexp; |
|||
else |
|||
value->rValue = 0.0; |
|||
return(OK); |
|||
case BJT2_MOD_TYPE: |
|||
if (here->BJT2type == NPN) |
|||
value->sValue = "npn"; |
|||
else |
|||
value->sValue = "pnp"; |
|||
return(OK); |
|||
case BJT2_MOD_SUBS: |
|||
if (here->BJT2subs == LATERAL) |
|||
value->sValue = "Lateral"; |
|||
else |
|||
value->sValue = "Vertical"; |
|||
return(OK); |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
/* NOTREACHED */ |
|||
} |
|||
|
|||
@ -1,43 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine deletes a BJT2 model from the circuit and frees |
|||
* the storage it was using. |
|||
* returns an error if the model has instances |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2mDelete(GENmodel **inModels, IFuid modname, GENmodel *kill) |
|||
|
|||
{ |
|||
BJT2model **model = (BJT2model**)inModels; |
|||
BJT2model *modfast = (BJT2model*)kill; |
|||
|
|||
BJT2model **oldmod; |
|||
oldmod = model; |
|||
for( ; *model ; model = &((*model)->BJT2nextModel)) { |
|||
if( (*model)->BJT2modName == modname || |
|||
(modfast && *model == modfast) ) goto delgot; |
|||
oldmod = model; |
|||
} |
|||
return(E_NOMOD); |
|||
|
|||
delgot: |
|||
if( (*model)->BJT2instances ) return(E_NOTEMPTY); |
|||
*oldmod = (*model)->BJT2nextModel; /* cut deleted device out of list */ |
|||
FREE(*model); |
|||
return(OK); |
|||
|
|||
} |
|||
@ -1,254 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine sets model parameters for |
|||
* BJT2s in the circuit. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2mParam(int param, IFvalue *value, GENmodel *inModel) |
|||
{ |
|||
BJT2model *mods = (BJT2model*)inModel; |
|||
|
|||
switch(param) { |
|||
case BJT2_MOD_NPN: |
|||
if(value->iValue) { |
|||
mods->BJT2type = NPN; |
|||
} |
|||
break; |
|||
case BJT2_MOD_PNP: |
|||
if(value->iValue) { |
|||
mods->BJT2type = PNP; |
|||
} |
|||
break; |
|||
case BJT2_MOD_SUBS: |
|||
mods->BJT2subs = value->iValue; |
|||
mods->BJT2subsGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_TNOM: |
|||
mods->BJT2tnom = value->rValue+CONSTCtoK; |
|||
mods->BJT2tnomGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_IS: |
|||
mods->BJT2satCur = value->rValue; |
|||
mods->BJT2satCurGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_ISS: |
|||
mods->BJT2subSatCur = value->rValue; |
|||
mods->BJT2subSatCurGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_BF: |
|||
mods->BJT2betaF = value->rValue; |
|||
mods->BJT2betaFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_NF: |
|||
mods->BJT2emissionCoeffF = value->rValue; |
|||
mods->BJT2emissionCoeffFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VAF: |
|||
mods->BJT2earlyVoltF = value->rValue; |
|||
mods->BJT2earlyVoltFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_IKF: |
|||
mods->BJT2rollOffF = value->rValue; |
|||
mods->BJT2rollOffFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_ISE: |
|||
mods->BJT2leakBEcurrent = value->rValue; |
|||
mods->BJT2leakBEcurrentGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_C2: |
|||
mods->BJT2c2 = value->rValue; |
|||
mods->BJT2c2Given=TRUE; |
|||
break; |
|||
case BJT2_MOD_NE: |
|||
mods->BJT2leakBEemissionCoeff = value->rValue; |
|||
mods->BJT2leakBEemissionCoeffGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_BR: |
|||
mods->BJT2betaR = value->rValue; |
|||
mods->BJT2betaRGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_NR: |
|||
mods->BJT2emissionCoeffR = value->rValue; |
|||
mods->BJT2emissionCoeffRGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VAR: |
|||
mods->BJT2earlyVoltR = value->rValue; |
|||
mods->BJT2earlyVoltRGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_IKR: |
|||
mods->BJT2rollOffR = value->rValue; |
|||
mods->BJT2rollOffRGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_ISC: |
|||
mods->BJT2leakBCcurrent = value->rValue; |
|||
mods->BJT2leakBCcurrentGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_C4: |
|||
mods->BJT2c4 = value->rValue; |
|||
mods->BJT2c4Given=TRUE; |
|||
break; |
|||
case BJT2_MOD_NC: |
|||
mods->BJT2leakBCemissionCoeff = value->rValue; |
|||
mods->BJT2leakBCemissionCoeffGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_RB: |
|||
mods->BJT2baseResist = value->rValue; |
|||
mods->BJT2baseResistGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_IRB: |
|||
mods->BJT2baseCurrentHalfResist = value->rValue; |
|||
mods->BJT2baseCurrentHalfResistGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_RBM: |
|||
mods->BJT2minBaseResist = value->rValue; |
|||
mods->BJT2minBaseResistGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_RE: |
|||
mods->BJT2emitterResist = value->rValue; |
|||
mods->BJT2emitterResistGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_RC: |
|||
mods->BJT2collectorResist = value->rValue; |
|||
mods->BJT2collectorResistGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_CJE: |
|||
mods->BJT2depletionCapBE = value->rValue; |
|||
mods->BJT2depletionCapBEGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VJE: |
|||
mods->BJT2potentialBE = value->rValue; |
|||
mods->BJT2potentialBEGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_MJE: |
|||
mods->BJT2junctionExpBE = value->rValue; |
|||
mods->BJT2junctionExpBEGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_TF: |
|||
mods->BJT2transitTimeF = value->rValue; |
|||
mods->BJT2transitTimeFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_XTF: |
|||
mods->BJT2transitTimeBiasCoeffF = value->rValue; |
|||
mods->BJT2transitTimeBiasCoeffFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VTF: |
|||
mods->BJT2transitTimeFVBC = value->rValue; |
|||
mods->BJT2transitTimeFVBCGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_ITF: |
|||
mods->BJT2transitTimeHighCurrentF = value->rValue; |
|||
mods->BJT2transitTimeHighCurrentFGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_PTF: |
|||
mods->BJT2excessPhase = value->rValue; |
|||
mods->BJT2excessPhaseGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_CJC: |
|||
mods->BJT2depletionCapBC = value->rValue; |
|||
mods->BJT2depletionCapBCGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VJC: |
|||
mods->BJT2potentialBC = value->rValue; |
|||
mods->BJT2potentialBCGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_MJC: |
|||
mods->BJT2junctionExpBC = value->rValue; |
|||
mods->BJT2junctionExpBCGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_XCJC: |
|||
mods->BJT2baseFractionBCcap = value->rValue; |
|||
mods->BJT2baseFractionBCcapGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_TR: |
|||
mods->BJT2transitTimeR = value->rValue; |
|||
mods->BJT2transitTimeRGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_CJS: |
|||
mods->BJT2capSub = value->rValue; |
|||
mods->BJT2capSubGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_VJS: |
|||
mods->BJT2potentialSubstrate = value->rValue; |
|||
mods->BJT2potentialSubstrateGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_MJS: |
|||
mods->BJT2exponentialSubstrate = value->rValue; |
|||
mods->BJT2exponentialSubstrateGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_XTB: |
|||
mods->BJT2betaExp = value->rValue; |
|||
mods->BJT2betaExpGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_EG: |
|||
mods->BJT2energyGap = value->rValue; |
|||
mods->BJT2energyGapGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_XTI: |
|||
mods->BJT2tempExpIS = value->rValue; |
|||
mods->BJT2tempExpISGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRE1: |
|||
mods->BJT2reTempCoeff1 = value->rValue; |
|||
mods->BJT2reTempCoeff1Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRE2: |
|||
mods->BJT2reTempCoeff2 = value->rValue; |
|||
mods->BJT2reTempCoeff2Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRC1: |
|||
mods->BJT2rcTempCoeff1 = value->rValue; |
|||
mods->BJT2rcTempCoeff1Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRC2: |
|||
mods->BJT2rcTempCoeff2 = value->rValue; |
|||
mods->BJT2rcTempCoeff2Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRB1: |
|||
mods->BJT2rbTempCoeff1 = value->rValue; |
|||
mods->BJT2rbTempCoeff1Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRB2: |
|||
mods->BJT2rbTempCoeff2 = value->rValue; |
|||
mods->BJT2rbTempCoeff2Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRBM1: |
|||
mods->BJT2rbmTempCoeff1 = value->rValue; |
|||
mods->BJT2rbmTempCoeff1Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_TRBM2: |
|||
mods->BJT2rbmTempCoeff2 = value->rValue; |
|||
mods->BJT2rbmTempCoeff2Given = TRUE; |
|||
break; |
|||
case BJT2_MOD_FC: |
|||
mods->BJT2depletionCapCoeff = value->rValue; |
|||
mods->BJT2depletionCapCoeffGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_KF: |
|||
mods->BJT2fNcoef = value->rValue; |
|||
mods->BJT2fNcoefGiven = TRUE; |
|||
break; |
|||
case BJT2_MOD_AF: |
|||
mods->BJT2fNexp = value->rValue; |
|||
mods->BJT2fNexpGiven = TRUE; |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,221 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1987 Gary W. Ng |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "bjt2defs.h" |
|||
#include "cktdefs.h" |
|||
#include "iferrmsg.h" |
|||
#include "noisedef.h" |
|||
#include "suffix.h" |
|||
|
|||
/* |
|||
* BJT2noise (mode, operation, firstModel, ckt, data, OnDens) |
|||
* |
|||
* This routine names and evaluates all of the noise sources |
|||
* associated with BJT2'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 BJT2's is summed with the variable "OnDens". |
|||
*/ |
|||
|
|||
|
|||
int |
|||
BJT2noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, |
|||
Ndata *data, double *OnDens) |
|||
{ |
|||
BJT2model *firstModel = (BJT2model *) genmodel; |
|||
BJT2model *model; |
|||
BJT2instance *inst; |
|||
char name[N_MXVLNTH]; |
|||
double tempOnoise; |
|||
double tempInoise; |
|||
double noizDens[BJT2NSRCS]; |
|||
double lnNdens[BJT2NSRCS]; |
|||
int i; |
|||
|
|||
/* define the names of the noise sources */ |
|||
|
|||
static char *BJT2nNames[BJT2NSRCS] = { /* Note that we have to keep the order */ |
|||
"_rc", /* noise due to rc */ /* consistent with the index definitions */ |
|||
"_rb", /* noise due to rb */ /* in BJT2defs.h */ |
|||
"_re", /* noise due to re */ |
|||
"_ic", /* noise due to ic */ |
|||
"_ib", /* noise due to ib */ |
|||
"_1overf", /* flicker (1/f) noise */ |
|||
"" /* total transistor noise */ |
|||
}; |
|||
|
|||
for (model=firstModel; model != NULL; model=model->BJT2nextModel) { |
|||
for (inst=model->BJT2instances; inst != NULL; inst=inst->BJT2nextInstance) { |
|||
if (inst->BJT2owner != ARCHme) continue; |
|||
|
|||
switch (operation) { |
|||
|
|||
case N_OPEN: |
|||
|
|||
/* see if we have to to produce a summary report */ |
|||
/* if so, name all the noise generators */ |
|||
|
|||
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { |
|||
switch (mode) { |
|||
|
|||
case N_DENS: |
|||
for (i=0; i < BJT2NSRCS; i++) { |
|||
(void)sprintf(name,"onoise_%s%s", |
|||
inst->BJT2name,BJT2nNames[i]); |
|||
|
|||
|
|||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
} |
|||
break; |
|||
|
|||
case INT_NOIZ: |
|||
for (i=0; i < BJT2NSRCS; i++) { |
|||
(void)sprintf(name,"onoise_total_%s%s", |
|||
inst->BJT2name,BJT2nNames[i]); |
|||
|
|||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
|
|||
(void)sprintf(name,"inoise_total_%s%s", |
|||
inst->BJT2name,BJT2nNames[i]); |
|||
|
|||
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); |
|||
if (!data->namelist) return(E_NOMEM); |
|||
SPfrontEnd->IFnewUid (ckt, |
|||
&(data->namelist[data->numPlots++]), |
|||
(IFuid)NULL, name, UID_OTHER, NULL); |
|||
/* we've added one more plot */ |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
break; |
|||
|
|||
case N_CALC: |
|||
switch (mode) { |
|||
|
|||
case N_DENS: |
|||
NevalSrc(&noizDens[BJT2RCNOIZ],&lnNdens[BJT2RCNOIZ], |
|||
ckt,THERMNOISE,inst->BJT2colPrimeNode,inst->BJT2colNode, |
|||
model->BJT2collectorConduct * inst->BJT2area * inst->BJT2m); |
|||
|
|||
NevalSrc(&noizDens[BJT2RBNOIZ],&lnNdens[BJT2RBNOIZ], |
|||
ckt,THERMNOISE,inst->BJT2basePrimeNode,inst->BJT2baseNode, |
|||
*(ckt->CKTstate0 + inst->BJT2gx) * inst->BJT2m); |
|||
|
|||
NevalSrc(&noizDens[BJT2_RE_NOISE],&lnNdens[BJT2_RE_NOISE], |
|||
ckt,THERMNOISE,inst->BJT2emitPrimeNode,inst->BJT2emitNode, |
|||
model->BJT2emitterConduct * inst->BJT2area * inst->BJT2m); |
|||
|
|||
NevalSrc(&noizDens[BJT2ICNOIZ],&lnNdens[BJT2ICNOIZ], |
|||
ckt,SHOTNOISE,inst->BJT2colPrimeNode, inst->BJT2emitPrimeNode, |
|||
*(ckt->CKTstate0 + inst->BJT2cc) * inst->BJT2m); |
|||
|
|||
NevalSrc(&noizDens[BJT2IBNOIZ],&lnNdens[BJT2IBNOIZ], |
|||
ckt,SHOTNOISE,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode, |
|||
*(ckt->CKTstate0 + inst->BJT2cb) * inst->BJT2m); |
|||
|
|||
NevalSrc(&noizDens[BJT2FLNOIZ],(double*)NULL,ckt, |
|||
N_GAIN,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode, |
|||
(double)0.0); |
|||
noizDens[BJT2FLNOIZ] *= inst->BJT2m * model->BJT2fNcoef * |
|||
exp(model->BJT2fNexp * |
|||
log(MAX(fabs(*(ckt->CKTstate0 + inst->BJT2cb)),N_MINLOG))) / |
|||
data->freq; |
|||
lnNdens[BJT2FLNOIZ] = |
|||
log(MAX(noizDens[BJT2FLNOIZ],N_MINLOG)); |
|||
|
|||
noizDens[BJT2TOTNOIZ] = noizDens[BJT2RCNOIZ] + |
|||
noizDens[BJT2RBNOIZ] + |
|||
noizDens[BJT2_RE_NOISE] + |
|||
noizDens[BJT2ICNOIZ] + |
|||
noizDens[BJT2IBNOIZ] + |
|||
noizDens[BJT2FLNOIZ]; |
|||
lnNdens[BJT2TOTNOIZ] = |
|||
log(noizDens[BJT2TOTNOIZ]); |
|||
|
|||
*OnDens += noizDens[BJT2TOTNOIZ]; |
|||
|
|||
if (data->delFreq == 0.0) { |
|||
|
|||
/* if we haven't done any previous integration, we need to */ |
|||
/* initialize our "history" variables */ |
|||
|
|||
for (i=0; i < BJT2NSRCS; i++) { |
|||
inst->BJT2nVar[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 < BJT2NSRCS; i++) { |
|||
inst->BJT2nVar[OUTNOIZ][i] = 0.0; |
|||
inst->BJT2nVar[INNOIZ][i] = 0.0; |
|||
} |
|||
} |
|||
} else { /* data->delFreq != 0.0 (we have to integrate) */ |
|||
|
|||
/* In order to get the best curve fit, we have to integrate each component separately */ |
|||
|
|||
for (i=0; i < BJT2NSRCS; i++) { |
|||
if (i != BJT2TOTNOIZ) { |
|||
tempOnoise = Nintegrate(noizDens[i], lnNdens[i], |
|||
inst->BJT2nVar[LNLSTDENS][i], data); |
|||
tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , |
|||
lnNdens[i] + data->lnGainInv, |
|||
inst->BJT2nVar[LNLSTDENS][i] + data->lnGainInv, |
|||
data); |
|||
inst->BJT2nVar[LNLSTDENS][i] = lnNdens[i]; |
|||
data->outNoiz += tempOnoise; |
|||
data->inNoise += tempInoise; |
|||
if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) { |
|||
inst->BJT2nVar[OUTNOIZ][i] += tempOnoise; |
|||
inst->BJT2nVar[OUTNOIZ][BJT2TOTNOIZ] += tempOnoise; |
|||
inst->BJT2nVar[INNOIZ][i] += tempInoise; |
|||
inst->BJT2nVar[INNOIZ][BJT2TOTNOIZ] += tempInoise; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if (data->prtSummary) { |
|||
for (i=0; i < BJT2NSRCS; 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 < BJT2NSRCS; i++) { |
|||
data->outpVector[data->outNumber++] = inst->BJT2nVar[OUTNOIZ][i]; |
|||
data->outpVector[data->outNumber++] = inst->BJT2nVar[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,86 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine sets instance parameters for |
|||
* BJT2s in the circuit. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "const.h" |
|||
#include "ifsim.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/* ARGSUSED */ |
|||
int |
|||
BJT2param(int param, IFvalue *value, GENinstance *instPtr, IFvalue *select) |
|||
{ |
|||
BJT2instance *here = (BJT2instance*)instPtr; |
|||
|
|||
NG_IGNORE(select); |
|||
|
|||
switch(param) { |
|||
case BJT2_AREA: |
|||
here->BJT2area = value->rValue; |
|||
here->BJT2areaGiven = TRUE; |
|||
break; |
|||
case BJT2_AREAB: |
|||
here->BJT2areab = value->rValue; |
|||
here->BJT2areabGiven = TRUE; |
|||
break; |
|||
case BJT2_AREAC: |
|||
here->BJT2areac = value->rValue; |
|||
here->BJT2areacGiven = TRUE; |
|||
break; |
|||
case BJT2_M: |
|||
here->BJT2m = value->rValue; |
|||
here->BJT2mGiven = TRUE; |
|||
break; |
|||
case BJT2_TEMP: |
|||
here->BJT2temp = value->rValue + CONSTCtoK; |
|||
here->BJT2tempGiven = TRUE; |
|||
break; |
|||
case BJT2_DTEMP: |
|||
here->BJT2dtemp = value->rValue; |
|||
here->BJT2dtempGiven = TRUE; |
|||
break; |
|||
case BJT2_OFF: |
|||
here->BJT2off = (value->iValue != 0); |
|||
break; |
|||
case BJT2_IC_VBE: |
|||
here->BJT2icVBE = value->rValue; |
|||
here->BJT2icVBEGiven = TRUE; |
|||
break; |
|||
case BJT2_IC_VCE: |
|||
here->BJT2icVCE = value->rValue; |
|||
here->BJT2icVCEGiven = TRUE; |
|||
break; |
|||
case BJT2_AREA_SENS: |
|||
here->BJT2senParmNo = value->iValue; |
|||
break; |
|||
case BJT2_IC : |
|||
switch(value->v.numValue) { |
|||
case 2: |
|||
here->BJT2icVCE = *(value->v.vec.rVec+1); |
|||
here->BJT2icVCEGiven = TRUE; |
|||
case 1: |
|||
here->BJT2icVBE = *(value->v.vec.rVec); |
|||
here->BJT2icVBEGiven = TRUE; |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
break; |
|||
default: |
|||
return(E_BADPARM); |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,120 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "complex.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2pzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
double gcpr; |
|||
double gepr; |
|||
double gpi; |
|||
double gmu; |
|||
double go; |
|||
double xgm; |
|||
double gm; |
|||
double gx; |
|||
double xcpi; |
|||
double xcmu; |
|||
double xcbx; |
|||
double xccs; |
|||
double xcmcb; |
|||
double m; |
|||
|
|||
for( ; model != NULL; model = model->BJT2nextModel) { |
|||
for( here = model->BJT2instances; here!= NULL; |
|||
here = here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
m = here->BJT2m; |
|||
|
|||
gcpr=model->BJT2collectorConduct * here->BJT2area; |
|||
gepr=model->BJT2emitterConduct * here->BJT2area; |
|||
gpi= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
gmu= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
gm= *(ckt->CKTstate0 + here->BJT2gm); |
|||
go= *(ckt->CKTstate0 + here->BJT2go); |
|||
xgm=0; |
|||
gx= *(ckt->CKTstate0 + here->BJT2gx); |
|||
xcpi= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
xcmu= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
xcbx= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
xccs= *(ckt->CKTstate0 + here->BJT2cqsub); /* PN */ |
|||
xcmcb= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
|
|||
|
|||
*(here->BJT2colColPtr) += m * (gcpr); |
|||
*(here->BJT2baseBasePtr) += m * ((gx) + (xcbx) * (s->real)); |
|||
*(here->BJT2baseBasePtr + 1) += m * ((xcbx) * (s->imag)); |
|||
*(here->BJT2emitEmitPtr) += m * (gepr); |
|||
*(here->BJT2colPrimeColPrimePtr) += m * ((gmu+go+gcpr) |
|||
+ (xcmu+xccs+xcbx) * (s->real)); |
|||
*(here->BJT2colPrimeColPrimePtr + 1) += m * ((xcmu+xccs+xcbx) |
|||
* (s->imag)); |
|||
*(here->BJT2basePrimeBasePrimePtr) += m * ((gx+gpi+gmu) |
|||
+ (xcpi+xcmu+xcmcb) * (s->real)); |
|||
*(here->BJT2basePrimeBasePrimePtr + 1) += m * ((xcpi+xcmu+xcmcb) |
|||
* (s->imag)); |
|||
*(here->BJT2emitPrimeEmitPrimePtr) += m * ((gpi+gepr+gm+go) |
|||
+ (xcpi+xgm) * (s->real)); |
|||
*(here->BJT2emitPrimeEmitPrimePtr + 1) += m * ((xcpi+xgm) |
|||
* (s->imag)); |
|||
*(here->BJT2colColPrimePtr) += m *(-gcpr); |
|||
*(here->BJT2baseBasePrimePtr) += m * (-gx); |
|||
*(here->BJT2emitEmitPrimePtr) += m * (-gepr); |
|||
*(here->BJT2colPrimeColPtr) += m * (-gcpr); |
|||
*(here->BJT2colPrimeBasePrimePtr) += m * ((-gmu+gm) |
|||
+ (-xcmu+xgm) * (s->real)); |
|||
*(here->BJT2colPrimeBasePrimePtr + 1) += m * ((-xcmu+xgm) |
|||
* (s->imag)); |
|||
*(here->BJT2colPrimeEmitPrimePtr) += m *((-gm-go) |
|||
+ (-xgm) * (s->real)); |
|||
*(here->BJT2colPrimeEmitPrimePtr + 1) += m * ((-xgm) * |
|||
(s->imag)); |
|||
*(here->BJT2basePrimeBasePtr) += m * (-gx); |
|||
*(here->BJT2basePrimeColPrimePtr) += m * ((-gmu) |
|||
+ (-xcmu-xcmcb) * (s->real)); |
|||
*(here->BJT2basePrimeColPrimePtr + 1) += m * ((-xcmu-xcmcb) |
|||
* (s->imag)); |
|||
*(here->BJT2basePrimeEmitPrimePtr) += m * ((-gpi) |
|||
+ (-xcpi) * (s->real)); |
|||
*(here->BJT2basePrimeEmitPrimePtr + 1) += m * ((-xcpi) |
|||
* (s->imag)); |
|||
*(here->BJT2emitPrimeEmitPtr) += m * (-gepr); |
|||
*(here->BJT2emitPrimeColPrimePtr) += m * ((-go) |
|||
+ (xcmcb) * (s->real)); |
|||
*(here->BJT2emitPrimeColPrimePtr + 1) += m * ((xcmcb) |
|||
* (s->imag)); |
|||
*(here->BJT2emitPrimeBasePrimePtr) += m * ((-gpi-gm) |
|||
+ (-xcpi-xgm-xcmcb) * (s->real)); |
|||
*(here->BJT2emitPrimeBasePrimePtr + 1) += m * ((-xcpi-xgm-xcmcb) |
|||
* (s->imag)); |
|||
*(here->BJT2substSubstPtr) += m * ((xccs) * (s->real)); |
|||
*(here->BJT2substSubstPtr + 1) += m * ((xccs) * (s->imag)); |
|||
/*DW survived from bjt |
|||
*(here->BJT2colPrimeSubstPtr) += (-xccs) * (s->real); |
|||
*(here->BJT2colPrimeSubstPtr + 1) += (-xccs) * (s->imag); |
|||
*(here->BJT2substColPrimePtr) += (-xccs) * (s->real); |
|||
*(here->BJT2substColPrimePtr + 1) += (-xccs) * (s->imag); |
|||
*/ |
|||
*(here->BJT2baseColPrimePtr) += m * ((-xcbx) * (s->real)); |
|||
*(here->BJT2baseColPrimePtr + 1) += m * ((-xcbx) * (s->imag)); |
|||
*(here->BJT2colPrimeBasePtr) += m * ((-xcbx) * (s->real)); |
|||
*(here->BJT2colPrimeBasePtr + 1) += m * ((-xcbx) * (s->imag)); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,712 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
|
|||
This function is obsolete (was used by an old sensitivity analysis) |
|||
**********/ |
|||
|
|||
/* actually load the current ac sensitivity |
|||
* information into the array previously provided |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2sAcLoad(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
|
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
double SaveState[25]; |
|||
int error; |
|||
int flag; |
|||
double vbeOp; |
|||
double vbcOp; |
|||
double A0; |
|||
double DELA = 0.0; |
|||
double Apert; |
|||
double DELAinv; |
|||
double vte = 0.0; |
|||
double gcpr; |
|||
double gepr; |
|||
double gpi; |
|||
double gmu; |
|||
double go; |
|||
double xgm; |
|||
double td; |
|||
double arg; |
|||
double gm; |
|||
double gx; |
|||
double xcpi; |
|||
double xcmu; |
|||
double xcbx; |
|||
double xccs; |
|||
double xcmcb; |
|||
double cx,icx; |
|||
double cbx,icbx; |
|||
double ccs,iccs; |
|||
double cbc,icbc; |
|||
double cbe,icbe; |
|||
double cce,icce; |
|||
double cb,icb; |
|||
double cbprm,icbprm; |
|||
double cc,icc; |
|||
double ccprm,iccprm; |
|||
double ce,ice; |
|||
double ceprm,iceprm; |
|||
double cs,ics; |
|||
double vcpr,ivcpr; |
|||
double vepr,ivepr; |
|||
double vx,ivx; |
|||
double vbx,ivbx; |
|||
double vcs,ivcs; |
|||
double vbc,ivbc; |
|||
double vbe,ivbe; |
|||
double vce,ivce; |
|||
double cb0,icb0; |
|||
double cbprm0,icbprm0; |
|||
double cc0,icc0; |
|||
double ccprm0,iccprm0; |
|||
double ce0,ice0; |
|||
double ceprm0,iceprm0; |
|||
double cs0,ics0; |
|||
double DvDp = 0.0; |
|||
int iparmno,i; |
|||
SENstruct *info; |
|||
|
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senacload \n"); |
|||
printf("BJT2senacload \n"); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
info = ckt->CKTsenInfo; |
|||
info->SENstatus = PERTURBATION; |
|||
|
|||
/* loop through all the models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
|
|||
|
|||
/* save the unperturbed values in the state vector */ |
|||
for(i=0; i <= 20; i++) { |
|||
*(SaveState + i) = *(ckt->CKTstate0 + here->BJT2state + i); |
|||
} |
|||
|
|||
vcpr = *(ckt->CKTrhsOld + here->BJT2colNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ; |
|||
ivcpr = *(ckt->CKTirhsOld + here->BJT2colNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ; |
|||
vepr = *(ckt->CKTrhsOld + here->BJT2emitNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ; |
|||
ivepr = *(ckt->CKTirhsOld + here->BJT2emitNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ; |
|||
vx = *(ckt->CKTrhsOld + here->BJT2baseNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2basePrimeNode) ;/* vb_bprm */ |
|||
ivx = *(ckt->CKTirhsOld + here->BJT2baseNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2basePrimeNode) ;/* ivb_bprm */ |
|||
vcs = *(ckt->CKTrhsOld + here->BJT2colPrimeNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2substNode) ; |
|||
ivcs = *(ckt->CKTirhsOld + here->BJT2colPrimeNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2substNode) ; |
|||
vbc = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ;/* vbprm_cprm */ |
|||
ivbc = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ;/* ivbprm_cprm */ |
|||
vbe = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ;/* vbprm_eprm */ |
|||
ivbe = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ;/* ivbprm_eprm */ |
|||
vce = vbe - vbc ; |
|||
ivce = ivbe - ivbc ; |
|||
vbx = vx + vbc ; |
|||
ivbx = ivx + ivbc ; |
|||
|
|||
|
|||
|
|||
vbeOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTrhsOp + here->BJT2emitPrimeNode)); |
|||
vbcOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) |
|||
- *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("\n without perturbation\n"); |
|||
#endif /* SENSDEBUG */ |
|||
/* without perturbation */ |
|||
A0 = here->BJT2area; |
|||
here->BJT2senPertFlag = ON; |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; |
|||
/* info->SENacpertflag == 1 only for first frequency */ |
|||
|
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the unperturbed values of small signal parameters */ |
|||
|
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
|
|||
*(here->BJT2senGpi)= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
*(here->BJT2senGmu)= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
*(here->BJT2senGm)= *(ckt->CKTstate0 + here->BJT2gm); |
|||
*(here->BJT2senGo)= *(ckt->CKTstate0 + here->BJT2go); |
|||
*(here->BJT2senGx)= *(ckt->CKTstate0 + here->BJT2gx); |
|||
*(here->BJT2senCpi)= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(here->BJT2senCmu)= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
*(here->BJT2senCbx)= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(here->BJT2senCsub)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
*(here->BJT2senCmcb)= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
} |
|||
gcpr = here->BJT2tCollectorConduct * A0; |
|||
gepr = here->BJT2tEmitterConduct * A0; |
|||
gpi= *(here->BJT2senGpi); |
|||
gmu= *(here->BJT2senGmu); |
|||
gm= *(here->BJT2senGm); |
|||
go= *(here->BJT2senGo); |
|||
gx= *(here->BJT2senGx); |
|||
xgm=0; |
|||
td=model->BJT2excessPhase; |
|||
if(td != 0) { |
|||
arg = td*ckt->CKTomega; |
|||
gm = gm+go; |
|||
xgm = -gm * sin(arg); |
|||
gm = gm * cos(arg)-go; |
|||
} |
|||
xcpi= *(here->BJT2senCpi) * ckt->CKTomega; |
|||
xcmu= *(here->BJT2senCmu) * ckt->CKTomega; |
|||
xcbx= *(here->BJT2senCbx) * ckt->CKTomega; |
|||
xccs= *(here->BJT2senCsub) * ckt->CKTomega; |
|||
xcmcb= *(here->BJT2senCmcb) * ckt->CKTomega; |
|||
|
|||
|
|||
cx=gx * vx ; |
|||
icx=gx * ivx; |
|||
cbx=( -xcbx * ivbx) ; |
|||
icbx= xcbx * vbx ; |
|||
ccs=( -xccs * ivcs) ; |
|||
iccs= xccs * vcs ; |
|||
cbc=(gmu * vbc -xcmu * ivbc) ; |
|||
icbc=xcmu * vbc + gmu * ivbc ; |
|||
cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; |
|||
icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; |
|||
cce= go * vce + gm * vbe - xgm * ivbe; |
|||
icce=go * ivce + gm * ivbe + xgm * vbe ; |
|||
|
|||
cc0=gcpr * vcpr ; |
|||
icc0=gcpr * ivcpr ; |
|||
ce0=gepr * vepr; |
|||
ice0=gepr * ivepr ; |
|||
cb0 = cx + cbx; |
|||
icb0 = icx + icbx; |
|||
if(here->BJT2baseNode != here->BJT2basePrimeNode){ |
|||
cbprm0 = (- cx + cbe + cbc); |
|||
icbprm0 = (- icx + icbe + icbc); |
|||
} |
|||
else{ |
|||
cbprm0 = ( cbx + cbe + cbc); |
|||
icbprm0 = (icbx + icbe + icbc); |
|||
} |
|||
ccprm0 = (- cbx - cc0 + ccs + cce - cbc); |
|||
iccprm0 = (- icbx - icc0 + iccs + icce - icbc); |
|||
ceprm0 = (- cbe - cce - ce0); |
|||
iceprm0 = (- icbe - icce - ice0); |
|||
cs0 = (- ccs) ; |
|||
ics0 = (- iccs) ; |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n", |
|||
gepr,gcpr,gmu,gpi); |
|||
printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n", |
|||
gm,go,gx,xcpi); |
|||
printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n" |
|||
,xcmu,xcbx,xccs,xcmcb); |
|||
printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n", |
|||
vepr,ivepr,vcpr,ivcpr); |
|||
printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n", |
|||
vbx,ivbx,vx,ivx); |
|||
printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n", |
|||
vbc,ivbc,vbe,ivbe); |
|||
printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n", |
|||
vce,ivce,vcs,ivcs); |
|||
printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n", |
|||
cce,icce,cbe,icbe); |
|||
printf("cbc0 = %.7e + j%.7e\n", |
|||
cbc,icbc); |
|||
printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n", |
|||
cc0,icc0,ce0,ice0); |
|||
printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n", |
|||
cb0,icb0,cs0,ics0); |
|||
printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n", |
|||
cbprm0,icbprm0,ceprm0,iceprm0); |
|||
printf("ccprm0 = %.7e + j%.7e \n", |
|||
ccprm0,iccprm0); |
|||
printf("\nPerturbation of Area\n"); |
|||
#endif /* SENSDEBUG */ |
|||
/* Perturbation of Area */ |
|||
if(here->BJT2senParmNo == 0){ |
|||
flag = 0; |
|||
goto next1; |
|||
} |
|||
|
|||
DELA = info->SENpertfac * A0; |
|||
Apert = A0 + DELA; |
|||
DELAinv = 1.0/DELA; |
|||
here->BJT2area = Apert; |
|||
|
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; |
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the small signal parameters |
|||
* corresponding to perturbed area |
|||
*/ |
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
|
|||
*(here->BJT2senGpi + 1)= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
*(here->BJT2senGmu + 1)= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
*(here->BJT2senGm + 1)= *(ckt->CKTstate0 + here->BJT2gm); |
|||
*(here->BJT2senGo + 1)= *(ckt->CKTstate0 + here->BJT2go); |
|||
*(here->BJT2senGx + 1)= *(ckt->CKTstate0 + here->BJT2gx); |
|||
*(here->BJT2senCpi + 1)= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(here->BJT2senCmu + 1)= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
*(here->BJT2senCbx + 1)= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(here->BJT2senCsub + 1)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
*(here->BJT2senCmcb + 1)= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
} |
|||
|
|||
|
|||
flag = 0; |
|||
goto load; |
|||
|
|||
|
|||
|
|||
pertvbx: /* Perturbation of vbx */ |
|||
#ifdef SENSDEBUG |
|||
printf("\nPerturbation of vbx\n"); |
|||
#endif /* SENSDEBUG */ |
|||
here->BJT2area = A0; |
|||
A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2baseNode) |
|||
- *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); |
|||
DELA = info->SENpertfac * A0 + 1e-8; |
|||
Apert = A0 + DELA; |
|||
DELAinv = model->BJT2type * 1.0/DELA; |
|||
*(ckt->CKTrhsOp + here->BJT2baseNode) += DELA; |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; |
|||
|
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the small signal parameters |
|||
* corresponding to perturbed vbx |
|||
*/ |
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
|
|||
*(here->BJT2senGpi + 2)= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
*(here->BJT2senGmu + 2)= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
*(here->BJT2senGm + 2)= *(ckt->CKTstate0 + here->BJT2gm); |
|||
*(here->BJT2senGo + 2)= *(ckt->CKTstate0 + here->BJT2go); |
|||
*(here->BJT2senGx + 2)= *(ckt->CKTstate0 + here->BJT2gx); |
|||
*(here->BJT2senCpi + 2)= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(here->BJT2senCmu + 2)= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
*(here->BJT2senCbx + 2)= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(here->BJT2senCsub + 2)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
*(here->BJT2senCmcb + 2)= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
} |
|||
|
|||
|
|||
flag = 1; |
|||
goto load; |
|||
|
|||
|
|||
pertvbe: /* Perturbation of vbe */ |
|||
#ifdef SENSDEBUG |
|||
printf("\nPerturbation of vbe\n"); |
|||
#endif /* SENSDEBUG */ |
|||
if (*(here->BJT2senCbx) != 0){ |
|||
*(ckt->CKTrhsOp + here ->BJT2baseNode) -= DELA; |
|||
} |
|||
vte=model->BJT2leakBEemissionCoeff*CONSTvt0; |
|||
A0 = vbeOp; |
|||
DELA = info->SENpertfac * vte ; |
|||
Apert = A0 + DELA; |
|||
DELAinv = 1.0/DELA; |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = Apert; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; |
|||
|
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the small signal parameters |
|||
* corresponding to perturbed vbe |
|||
*/ |
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
|
|||
*(here->BJT2senGpi + 3)= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
*(here->BJT2senGmu + 3)= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
*(here->BJT2senGm + 3)= *(ckt->CKTstate0 + here->BJT2gm); |
|||
*(here->BJT2senGo + 3)= *(ckt->CKTstate0 + here->BJT2go); |
|||
*(here->BJT2senGx + 3)= *(ckt->CKTstate0 + here->BJT2gx); |
|||
*(here->BJT2senCpi + 3)= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(here->BJT2senCmu + 3)= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
*(here->BJT2senCbx + 3)= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(here->BJT2senCsub + 3)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
*(here->BJT2senCmcb + 3)= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
} |
|||
|
|||
|
|||
flag = 2; |
|||
goto load; |
|||
|
|||
|
|||
pertvbc: /* Perturbation of vbc */ |
|||
#ifdef SENSDEBUG |
|||
printf("\nPerturbation of vbc\n"); |
|||
#endif /* SENSDEBUG */ |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = A0; |
|||
|
|||
A0 = vbcOp; |
|||
DELA = info->SENpertfac * vte ; |
|||
Apert = A0 + DELA; |
|||
DELAinv = 1.0/DELA; |
|||
|
|||
|
|||
*(ckt->CKTstate0 + here->BJT2vbc) = Apert; |
|||
|
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; |
|||
|
|||
|
|||
|
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the small signal parameters |
|||
* corresponding to perturbed vbc |
|||
*/ |
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
*(here->BJT2senGpi + 4)= *(ckt->CKTstate0 + here->BJT2gpi); |
|||
*(here->BJT2senGmu + 4)= *(ckt->CKTstate0 + here->BJT2gmu); |
|||
*(here->BJT2senGm + 4)= *(ckt->CKTstate0 + here->BJT2gm); |
|||
*(here->BJT2senGo + 4)= *(ckt->CKTstate0 + here->BJT2go); |
|||
*(here->BJT2senGx + 4)= *(ckt->CKTstate0 + here->BJT2gx); |
|||
*(here->BJT2senCpi + 4)= *(ckt->CKTstate0 + here->BJT2cqbe); |
|||
*(here->BJT2senCmu + 4)= *(ckt->CKTstate0 + here->BJT2cqbc); |
|||
*(here->BJT2senCbx + 4)= *(ckt->CKTstate0 + here->BJT2cqbx); |
|||
*(here->BJT2senCsub + 4)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
*(here->BJT2senCmcb + 4)= *(ckt->CKTstate0 + here->BJT2cexbc); |
|||
|
|||
} |
|||
|
|||
|
|||
flag = 3; |
|||
goto load; |
|||
|
|||
|
|||
|
|||
pertvcs: /* Perturbation of vcs */ |
|||
#ifdef SENSDEBUG |
|||
printf("\nPerturbation of vcs\n"); |
|||
#endif /* SENSDEBUG */ |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = A0; |
|||
A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2substNode) |
|||
- *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); |
|||
DELA = info->SENpertfac * A0 + 1e-8; |
|||
Apert = A0 + DELA; |
|||
DELAinv = model->BJT2type * 1.0/DELA; |
|||
*(ckt->CKTrhsOp + here->BJT2substNode) += DELA; |
|||
*(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; |
|||
*(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; |
|||
|
|||
if(info->SENacpertflag == 1){ |
|||
|
|||
/* store the small signal parameters |
|||
* corresponding to perturbed vcs |
|||
*/ |
|||
if ((error = BJT2load((GENmodel*)model,ckt)) != 0) return(error); |
|||
*(here->BJT2senCsub + 5)= *(ckt->CKTstate0 + here->BJT2cqsub); |
|||
|
|||
} |
|||
|
|||
|
|||
flag = 4; |
|||
|
|||
*(ckt->CKTrhsOp + here->BJT2substNode) -= DELA; |
|||
xccs= *(here->BJT2senCsub + 5) * ckt->CKTomega; |
|||
|
|||
ccs=( -xccs * ivcs) ; |
|||
iccs= xccs * vcs ; |
|||
cs = -ccs; |
|||
ics = -iccs; |
|||
ccprm = ccprm0 + cs0 - cs; |
|||
iccprm = iccprm0 + ics0 - ics; |
|||
cbprm = cbprm0; |
|||
icbprm = icbprm0; |
|||
ceprm = ceprm0; |
|||
iceprm = iceprm0; |
|||
cc = cc0; |
|||
icc = icc0; |
|||
ce = ce0; |
|||
ice = ice0; |
|||
cb = cb0; |
|||
icb = icb0; |
|||
goto next2; |
|||
|
|||
load: |
|||
gcpr=here->BJT2tCollectorConduct * here->BJT2area; |
|||
gepr=here->BJT2tEmitterConduct * here->BJT2area; |
|||
gpi= *(here->BJT2senGpi + flag+1); |
|||
gmu= *(here->BJT2senGmu + flag+1); |
|||
gm= *(here->BJT2senGm + flag+1); |
|||
go= *(here->BJT2senGo + flag+1); |
|||
gx= *(here->BJT2senGx + flag+1); |
|||
xgm=0; |
|||
td=model->BJT2excessPhase; |
|||
if(td != 0) { |
|||
arg = td*ckt->CKTomega; |
|||
gm = gm+go; |
|||
xgm = -gm * sin(arg); |
|||
gm = gm * cos(arg)-go; |
|||
} |
|||
xcpi= *(here->BJT2senCpi + flag+1) * ckt->CKTomega; |
|||
xcmu= *(here->BJT2senCmu + flag+1) * ckt->CKTomega; |
|||
xcbx= *(here->BJT2senCbx + flag+1) * ckt->CKTomega; |
|||
xccs= *(here->BJT2senCsub + flag+1) * ckt->CKTomega; |
|||
xcmcb= *(here->BJT2senCmcb + flag+1) * ckt->CKTomega; |
|||
|
|||
|
|||
cc=gcpr * vcpr ; |
|||
icc=gcpr * ivcpr ; |
|||
ce=gepr * vepr; |
|||
ice=gepr * ivepr ; |
|||
cx=gx * vx ; |
|||
icx=gx * ivx; |
|||
cbx=( -xcbx * ivbx) ; |
|||
icbx= xcbx * vbx ; |
|||
ccs=( -xccs * ivcs) ; |
|||
iccs= xccs * vcs ; |
|||
cbc=(gmu * vbc -xcmu * ivbc) ; |
|||
icbc=xcmu * vbc + gmu * ivbc ; |
|||
cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; |
|||
icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; |
|||
cce= go * vce + gm * vbe - xgm * ivbe; |
|||
icce=go * ivce + gm * ivbe + xgm * vbe ; |
|||
|
|||
|
|||
cb= cx + cbx; |
|||
icb= icx + icbx; |
|||
if(here->BJT2baseNode != here->BJT2basePrimeNode){ |
|||
cbprm=(- cx + cbe + cbc); |
|||
icbprm=(- icx + icbe + icbc); |
|||
} |
|||
else{ |
|||
cbprm=( cbx + cbe + cbc); |
|||
icbprm=(icbx + icbe + icbc); |
|||
} |
|||
ccprm=(- cbx - cc + ccs + cce - cbc); |
|||
iccprm=(- icbx - icc + iccs + icce - icbc); |
|||
ceprm=(- cbe - cce - ce); |
|||
iceprm=(- icbe - icce - ice); |
|||
cs= (- ccs) ; |
|||
ics= (- iccs) ; |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("A0 = %.7e , Apert = %.7e , DELA = %.7e\n" |
|||
,A0,Apert,DELA); |
|||
printf("gepr = %.7e , gcpr = %.7e , gmu = %.7e, gpi = %.7e\n" |
|||
,gepr,gcpr,gmu,gpi); |
|||
printf("gm = %.7e , go = %.7e , gx = %.7e, xcpi = %.7e\n" |
|||
,gm,go,gx,xcpi); |
|||
printf("xcmu = %.7e , xcbx = %.7e , xccs = %.7e, xcmcb = %.7e\n" |
|||
,xcmu,xcbx,xccs,xcmcb); |
|||
|
|||
printf("cx = %.7e + j%.7e , cbx = %.7e + j%.7e\n" |
|||
,cx,icx,cbx,icbx); |
|||
printf("ccs %.7e + j%.7e , cbc = %.7e + j%.7e" |
|||
,ccs,iccs,cbc,icbc); |
|||
printf("cbe %.7e + j%.7e , cce = %.7e + j%.7e\n" |
|||
,cbe,icbe,cce,icce); |
|||
|
|||
printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,", |
|||
,cc,icc,ce,ice); |
|||
printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e", |
|||
ccprm,iccprm,ceprm,iceprm); |
|||
printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ", |
|||
cb,icb,cbprm,icbprm) |
|||
printf("cs = %.7e + j%.7e\n", |
|||
cs,ics); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
|
|||
/* load the RHS matrix */ |
|||
next2: |
|||
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ |
|||
if( (!flag) && (iparmno != here->BJT2senParmNo) ) continue; |
|||
switch(flag){ |
|||
|
|||
case 0: |
|||
/* area : so no DC sensitivity term involved */ |
|||
DvDp = 1.0; |
|||
|
|||
break; |
|||
/* calculate the DC sensitivities of operating points */ |
|||
case 1: |
|||
DvDp = model->BJT2type * |
|||
(info->SEN_Sap[here->BJT2baseNode][iparmno] |
|||
- info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); |
|||
break; |
|||
case 2: |
|||
DvDp = model->BJT2type * |
|||
(info->SEN_Sap[here->BJT2basePrimeNode][iparmno] |
|||
- info->SEN_Sap[here->BJT2emitPrimeNode][iparmno]); |
|||
break; |
|||
case 3: |
|||
DvDp = model->BJT2type * |
|||
(info->SEN_Sap[here->BJT2basePrimeNode][iparmno] |
|||
- info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); |
|||
break; |
|||
case 4: |
|||
DvDp = model->BJT2type * |
|||
(info->SEN_Sap[here->BJT2substNode][iparmno] |
|||
- info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); |
|||
break; |
|||
} |
|||
#ifdef SENSDEBUG |
|||
printf("before loading\n"); |
|||
printf("BJT2type = %d\n",model->BJT2type); |
|||
printf("DvDp = %.7e , flag = %d , iparmno = %d,senparmno = %d\n" |
|||
,DvDp,flag,iparmno,here->BJT2senParmNo); |
|||
printf("senb = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); |
|||
printf("senbrm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); |
|||
printf("senc = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2colNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2colNode] + iparmno)); |
|||
printf("sencprm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); |
|||
printf("sene = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); |
|||
printf("seneprm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); |
|||
printf("sens = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2substNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2substNode] + iparmno)); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
|
|||
if(here->BJT2baseNode != here->BJT2basePrimeNode){ |
|||
*(info->SEN_RHS[here->BJT2baseNode] + iparmno) -= |
|||
( cb - cb0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2baseNode] + iparmno) -= |
|||
( icb - icb0) * DELAinv * DvDp; |
|||
} |
|||
|
|||
*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno) -= |
|||
( cbprm - cbprm0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno) -= |
|||
( icbprm - icbprm0) * DELAinv * DvDp; |
|||
|
|||
if(here->BJT2colNode != here->BJT2colPrimeNode){ |
|||
*(info->SEN_RHS[here->BJT2colNode] + iparmno) -= |
|||
( cc - cc0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2colNode] + iparmno) -= |
|||
( icc - icc0) * DELAinv * DvDp; |
|||
} |
|||
|
|||
*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno) -= |
|||
( ccprm - ccprm0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno) -= |
|||
( iccprm - iccprm0) * DELAinv * DvDp; |
|||
|
|||
if(here->BJT2emitNode != here->BJT2emitPrimeNode){ |
|||
*(info->SEN_RHS[here->BJT2emitNode] + iparmno) -= |
|||
( ce - ce0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2emitNode] + iparmno) -= |
|||
( ice - ice0) * DELAinv * DvDp; |
|||
} |
|||
|
|||
*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno) -= |
|||
( ceprm - ceprm0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno) -= |
|||
( iceprm - iceprm0) * DELAinv * DvDp; |
|||
*(info->SEN_RHS[here->BJT2substNode] + iparmno) -= |
|||
( cs - cs0) * DELAinv * DvDp; |
|||
*(info->SEN_iRHS[here->BJT2substNode] + iparmno) -= |
|||
( ics - ics0) * DELAinv * DvDp; |
|||
#ifdef SENSDEBUG |
|||
printf("after loading\n"); |
|||
|
|||
printf("senb = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); |
|||
printf("senbrm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); |
|||
printf("senc = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2colNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2colNode] + iparmno)); |
|||
printf("sencprm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); |
|||
printf("sene = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); |
|||
printf("seneprm = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); |
|||
printf("sens = %.7e + j%.7e\n " |
|||
,*(info->SEN_RHS[here->BJT2substNode] + iparmno), |
|||
*(info->SEN_iRHS[here->BJT2substNode] + iparmno)); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
} |
|||
|
|||
|
|||
next1: |
|||
switch(flag){ |
|||
case 0: |
|||
if (*(here->BJT2senCbx) == 0){ |
|||
here->BJT2area = A0; |
|||
goto pertvbe ; |
|||
} |
|||
else{ |
|||
goto pertvbx; |
|||
} |
|||
case 1: |
|||
goto pertvbe ; |
|||
case 2: |
|||
goto pertvbc ; |
|||
case 3: |
|||
goto pertvcs ; |
|||
case 4: |
|||
break; |
|||
} |
|||
|
|||
/* put the unperturbed values back into the state vector */ |
|||
for(i=0; i <= 20; i++) { |
|||
*(ckt->CKTstate0 + here->BJT2state + i) = *(SaveState + i); |
|||
} |
|||
here->BJT2senPertFlag = OFF; |
|||
} |
|||
|
|||
} |
|||
info->SENstatus = NORMAL; |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senacload end\n"); |
|||
#endif /* SENSDEBUG */ |
|||
return(OK); |
|||
} |
|||
|
|||
@ -1,348 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
/* |
|||
* This routine should only be called when circuit topology |
|||
* changes, since its computations do not depend on most |
|||
* device or model parameters, only on topology (as |
|||
* affected by emitter, collector, and base resistances) |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
int |
|||
BJT2setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) |
|||
/* load the BJT2 structure with those pointers needed later |
|||
* for fast matrix loading |
|||
*/ |
|||
|
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
int error; |
|||
CKTnode *tmp; |
|||
|
|||
/* loop through all the diode models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
if(model->BJT2type != NPN && model->BJT2type != PNP) { |
|||
model->BJT2type = NPN; |
|||
} |
|||
#ifndef GEOMETRY_COMPAT |
|||
if(!model->BJT2subsGiven || |
|||
(model->BJT2subs != VERTICAL && model->BJT2subs != LATERAL)) { |
|||
model->BJT2subs = VERTICAL; |
|||
} |
|||
#else |
|||
if(!model->BJT2subsGiven || |
|||
(model->BJT2subs != VERTICAL && model->BJT2subs != LATERAL)) { |
|||
if (model->BJT2type = NPN) |
|||
model->BJT2subs = VERTICAL; /* Vertical for NPN */ |
|||
else |
|||
model->BJT2subs = LATERAL; /* Lateral for PNP */ |
|||
} |
|||
#endif |
|||
if(!model->BJT2satCurGiven) { |
|||
model->BJT2satCur = 1e-16; |
|||
} |
|||
if(!model->BJT2subSatCurGiven) { |
|||
model->BJT2subSatCur = 1e-16; |
|||
} |
|||
if(!model->BJT2betaFGiven) { |
|||
model->BJT2betaF = 100; |
|||
} |
|||
if(!model->BJT2emissionCoeffFGiven) { |
|||
model->BJT2emissionCoeffF = 1; |
|||
} |
|||
if(!model->BJT2leakBEemissionCoeffGiven) { |
|||
model->BJT2leakBEemissionCoeff = 1.5; |
|||
} |
|||
if(!model->BJT2betaRGiven) { |
|||
model->BJT2betaR = 1; |
|||
} |
|||
if(!model->BJT2emissionCoeffRGiven) { |
|||
model->BJT2emissionCoeffR = 1; |
|||
} |
|||
if(!model->BJT2leakBCemissionCoeffGiven) { |
|||
model->BJT2leakBCemissionCoeff = 2; |
|||
} |
|||
if(!model->BJT2baseResistGiven) { |
|||
model->BJT2baseResist = 0; |
|||
} |
|||
if(!model->BJT2emitterResistGiven) { |
|||
model->BJT2emitterResist = 0; |
|||
} |
|||
if(!model->BJT2collectorResistGiven) { |
|||
model->BJT2collectorResist = 0; |
|||
} |
|||
if(!model->BJT2depletionCapBEGiven) { |
|||
model->BJT2depletionCapBE = 0; |
|||
} |
|||
if(!model->BJT2potentialBEGiven) { |
|||
model->BJT2potentialBE = .75; |
|||
} |
|||
if(!model->BJT2junctionExpBEGiven) { |
|||
model->BJT2junctionExpBE = .33; |
|||
} |
|||
if(!model->BJT2transitTimeFGiven) { |
|||
model->BJT2transitTimeF = 0; |
|||
} |
|||
if(!model->BJT2transitTimeBiasCoeffFGiven) { |
|||
model->BJT2transitTimeBiasCoeffF = 0; |
|||
} |
|||
if(!model->BJT2transitTimeHighCurrentFGiven) { |
|||
model->BJT2transitTimeHighCurrentF = 0; |
|||
} |
|||
if(!model->BJT2excessPhaseGiven) { |
|||
model->BJT2excessPhase = 0; |
|||
} |
|||
if(!model->BJT2depletionCapBCGiven) { |
|||
model->BJT2depletionCapBC = 0; |
|||
} |
|||
if(!model->BJT2potentialBCGiven) { |
|||
model->BJT2potentialBC = .75; |
|||
} |
|||
if(!model->BJT2junctionExpBCGiven) { |
|||
model->BJT2junctionExpBC = .33; |
|||
} |
|||
if(!model->BJT2baseFractionBCcapGiven) { |
|||
model->BJT2baseFractionBCcap = 1; |
|||
} |
|||
if(!model->BJT2transitTimeRGiven) { |
|||
model->BJT2transitTimeR = 0; |
|||
} |
|||
if(!model->BJT2capSubGiven) { |
|||
model->BJT2capSub = 0; |
|||
} |
|||
if(!model->BJT2potentialSubstrateGiven) { |
|||
model->BJT2potentialSubstrate = .75; |
|||
} |
|||
if(!model->BJT2exponentialSubstrateGiven) { |
|||
model->BJT2exponentialSubstrate = 0; |
|||
} |
|||
if(!model->BJT2betaExpGiven) { |
|||
model->BJT2betaExp = 0; |
|||
} |
|||
if(!model->BJT2energyGapGiven) { |
|||
model->BJT2energyGap = 1.11; |
|||
} |
|||
if(!model->BJT2tempExpISGiven) { |
|||
model->BJT2tempExpIS = 3; |
|||
} |
|||
if(!model->BJT2reTempCoeff1Given) { |
|||
model->BJT2reTempCoeff1 = 0.0; |
|||
} |
|||
if(!model->BJT2reTempCoeff2Given) { |
|||
model->BJT2reTempCoeff2 = 0.0; |
|||
} |
|||
if(!model->BJT2rcTempCoeff1Given) { |
|||
model->BJT2rcTempCoeff1 = 0.0; |
|||
} |
|||
if(!model->BJT2rcTempCoeff2Given) { |
|||
model->BJT2rcTempCoeff2 = 0.0; |
|||
} |
|||
if(!model->BJT2rbTempCoeff1Given) { |
|||
model->BJT2rbTempCoeff1 = 0.0; |
|||
} |
|||
if(!model->BJT2rbTempCoeff2Given) { |
|||
model->BJT2rbTempCoeff2 = 0.0; |
|||
} |
|||
if(!model->BJT2rbmTempCoeff1Given) { |
|||
model->BJT2rbmTempCoeff1 = 0.0; |
|||
} |
|||
if(!model->BJT2rbmTempCoeff2Given) { |
|||
model->BJT2rbmTempCoeff2 = 0.0; |
|||
} |
|||
if(!model->BJT2fNcoefGiven) { |
|||
model->BJT2fNcoef = 0; |
|||
} |
|||
if(!model->BJT2fNexpGiven) { |
|||
model->BJT2fNexp = 1; |
|||
} |
|||
|
|||
/* |
|||
* COMPATABILITY WARNING! |
|||
* special note: for backward compatability to much older models, spice 2G |
|||
* implemented a special case which checked if B-E leakage saturation |
|||
* current was >1, then it was instead a the B-E leakage saturation current |
|||
* divided by IS, and multiplied it by IS at this point. This was not |
|||
* handled correctly in the 2G code, and there is some question on its |
|||
* reasonability, since it is also undocumented, so it has been left out |
|||
* here. It could easily be added with 1 line. (The same applies to the B-C |
|||
* leakage saturation current). TQ 6/29/84 |
|||
*/ |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
CKTnode *tmpNode; |
|||
IFuid tmpName; |
|||
|
|||
if (here->BJT2owner != ARCHme) |
|||
goto matrixpointers; |
|||
|
|||
|
|||
if(!here->BJT2areaGiven) { |
|||
here->BJT2area = 1; |
|||
} |
|||
if(!here->BJT2areabGiven) { |
|||
here->BJT2areab = here->BJT2area; |
|||
} |
|||
if(!here->BJT2areacGiven) { |
|||
here->BJT2areac = here->BJT2area; |
|||
} |
|||
|
|||
if(!here->BJT2mGiven) { |
|||
here->BJT2m = 1.0; |
|||
} |
|||
|
|||
here->BJT2state = *states; |
|||
*states += BJT2numStates; |
|||
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ |
|||
*states += 8 * (ckt->CKTsenInfo->SENparms); |
|||
} |
|||
|
|||
matrixpointers: |
|||
if(model->BJT2collectorResist == 0) { |
|||
here->BJT2colPrimeNode = here->BJT2colNode; |
|||
} else if(here->BJT2colPrimeNode == 0) { |
|||
error = CKTmkVolt(ckt,&tmp,here->BJT2name,"collector"); |
|||
if(error) return(error); |
|||
here->BJT2colPrimeNode = tmp->number; |
|||
if (ckt->CKTcopyNodesets) { |
|||
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { |
|||
if (tmpNode->nsGiven) { |
|||
tmp->nodeset=tmpNode->nodeset; |
|||
tmp->nsGiven=tmpNode->nsGiven; |
|||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); |
|||
fprintf(stderr, " to %s\n", tmp->name); |
|||
fprintf(stderr, " value %g\n", |
|||
tmp->nodeset);*/ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if(model->BJT2baseResist == 0) { |
|||
here->BJT2basePrimeNode = here->BJT2baseNode; |
|||
} else if(here->BJT2basePrimeNode == 0){ |
|||
error = CKTmkVolt(ckt,&tmp,here->BJT2name, "base"); |
|||
if(error) return(error); |
|||
here->BJT2basePrimeNode = tmp->number; |
|||
if (ckt->CKTcopyNodesets) { |
|||
if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { |
|||
if (tmpNode->nsGiven) { |
|||
tmp->nodeset=tmpNode->nodeset; |
|||
tmp->nsGiven=tmpNode->nsGiven; |
|||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); |
|||
fprintf(stderr, " to %s\n", tmp->name); |
|||
fprintf(stderr, " value %g\n", |
|||
tmp->nodeset);*/ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
if(model->BJT2emitterResist == 0) { |
|||
here->BJT2emitPrimeNode = here->BJT2emitNode; |
|||
} else if(here->BJT2emitPrimeNode == 0) { |
|||
error = CKTmkVolt(ckt,&tmp,here->BJT2name, "emitter"); |
|||
if(error) return(error); |
|||
here->BJT2emitPrimeNode = tmp->number; |
|||
if (ckt->CKTcopyNodesets) { |
|||
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { |
|||
if (tmpNode->nsGiven) { |
|||
tmp->nodeset=tmpNode->nodeset; |
|||
tmp->nsGiven=tmpNode->nsGiven; |
|||
/* fprintf(stderr, "Nodeset copied from %s\n", tmpName); |
|||
fprintf(stderr, " to %s\n", tmp->name); |
|||
fprintf(stderr, " value %g\n", |
|||
tmp->nodeset);*/ |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* 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(BJT2colColPrimePtr,BJT2colNode,BJT2colPrimeNode) |
|||
TSTALLOC(BJT2baseBasePrimePtr,BJT2baseNode,BJT2basePrimeNode) |
|||
TSTALLOC(BJT2emitEmitPrimePtr,BJT2emitNode,BJT2emitPrimeNode) |
|||
TSTALLOC(BJT2colPrimeColPtr,BJT2colPrimeNode,BJT2colNode) |
|||
TSTALLOC(BJT2colPrimeBasePrimePtr,BJT2colPrimeNode,BJT2basePrimeNode) |
|||
TSTALLOC(BJT2colPrimeEmitPrimePtr,BJT2colPrimeNode,BJT2emitPrimeNode) |
|||
TSTALLOC(BJT2basePrimeBasePtr,BJT2basePrimeNode,BJT2baseNode) |
|||
TSTALLOC(BJT2basePrimeColPrimePtr,BJT2basePrimeNode,BJT2colPrimeNode) |
|||
TSTALLOC(BJT2basePrimeEmitPrimePtr,BJT2basePrimeNode,BJT2emitPrimeNode) |
|||
TSTALLOC(BJT2emitPrimeEmitPtr,BJT2emitPrimeNode,BJT2emitNode) |
|||
TSTALLOC(BJT2emitPrimeColPrimePtr,BJT2emitPrimeNode,BJT2colPrimeNode) |
|||
TSTALLOC(BJT2emitPrimeBasePrimePtr,BJT2emitPrimeNode,BJT2basePrimeNode) |
|||
TSTALLOC(BJT2colColPtr,BJT2colNode,BJT2colNode) |
|||
TSTALLOC(BJT2baseBasePtr,BJT2baseNode,BJT2baseNode) |
|||
TSTALLOC(BJT2emitEmitPtr,BJT2emitNode,BJT2emitNode) |
|||
TSTALLOC(BJT2colPrimeColPrimePtr,BJT2colPrimeNode,BJT2colPrimeNode) |
|||
TSTALLOC(BJT2basePrimeBasePrimePtr,BJT2basePrimeNode,BJT2basePrimeNode) |
|||
TSTALLOC(BJT2emitPrimeEmitPrimePtr,BJT2emitPrimeNode,BJT2emitPrimeNode) |
|||
TSTALLOC(BJT2substSubstPtr,BJT2substNode,BJT2substNode) |
|||
if (model -> BJT2subs == LATERAL) { |
|||
here -> BJT2substConNode = here -> BJT2basePrimeNode; |
|||
here -> BJT2substConSubstConPtr = |
|||
here -> BJT2basePrimeBasePrimePtr; |
|||
} else { |
|||
here -> BJT2substConNode = here -> BJT2colPrimeNode; |
|||
here -> BJT2substConSubstConPtr = here -> BJT2colPrimeColPrimePtr; |
|||
}; |
|||
TSTALLOC(BJT2substConSubstPtr,BJT2substConNode,BJT2substNode) |
|||
TSTALLOC(BJT2substSubstConPtr,BJT2substNode,BJT2substConNode) |
|||
TSTALLOC(BJT2baseColPrimePtr,BJT2baseNode,BJT2colPrimeNode) |
|||
TSTALLOC(BJT2colPrimeBasePtr,BJT2colPrimeNode,BJT2baseNode) |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
|
|||
int |
|||
BJT2unsetup(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2model *model; |
|||
BJT2instance *here; |
|||
|
|||
for (model = (BJT2model *)inModel; model != NULL; |
|||
model = model->BJT2nextModel) |
|||
{ |
|||
for (here = model->BJT2instances; here != NULL; |
|||
here=here->BJT2nextInstance) |
|||
{ |
|||
if (here->BJT2colPrimeNode |
|||
&& here->BJT2colPrimeNode != here->BJT2colNode) |
|||
{ |
|||
CKTdltNNum(ckt, here->BJT2colPrimeNode); |
|||
here->BJT2colPrimeNode = 0; |
|||
} |
|||
if (here->BJT2basePrimeNode |
|||
&& here->BJT2basePrimeNode != here->BJT2baseNode) |
|||
{ |
|||
CKTdltNNum(ckt, here->BJT2basePrimeNode); |
|||
here->BJT2basePrimeNode = 0; |
|||
} |
|||
if (here->BJT2emitPrimeNode |
|||
&& here->BJT2emitPrimeNode != here->BJT2emitNode) |
|||
{ |
|||
CKTdltNNum(ckt, here->BJT2emitPrimeNode); |
|||
here->BJT2emitPrimeNode = 0; |
|||
} |
|||
} |
|||
} |
|||
return OK; |
|||
} |
|||
@ -1,332 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
|
|||
This function is obsolete (was used by an old sensitivity analysis) |
|||
**********/ |
|||
|
|||
/* actually load the current sensitivity |
|||
* information into the array previously provided |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2sLoad(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
double SaveState0[27]; |
|||
int i; |
|||
int iparmno; |
|||
int error; |
|||
double A0; |
|||
double DELA; |
|||
double Apert; |
|||
double DELAinv; |
|||
double cb0; |
|||
double cb; |
|||
double cc0; |
|||
double cc; |
|||
double cx0; |
|||
double ccpr0; |
|||
double cepr0; |
|||
double DcbDp; |
|||
double DccDp; |
|||
double DceDp; |
|||
double DccprDp; |
|||
double DceprDp; |
|||
double DcxDp; |
|||
double DbprmDp; |
|||
double DcprmDp; |
|||
double DeprmDp; |
|||
double gx; |
|||
double gx0; |
|||
double tag0; |
|||
double tag1; |
|||
double qbe0; |
|||
double qbe; |
|||
double qbc0; |
|||
double qbc; |
|||
double qcs0; |
|||
double qcs; |
|||
double qbx0; |
|||
double qbx; |
|||
double DqbeDp = 0.0; |
|||
double DqbcDp = 0.0; |
|||
double DqcsDp = 0.0; |
|||
double DqbxDp = 0.0; |
|||
double Osxpbe; |
|||
double Osxpbc; |
|||
double Osxpcs; |
|||
double Osxpbx; |
|||
SENstruct *info; |
|||
|
|||
tag0 = ckt->CKTag[0]; |
|||
tag1 = ckt->CKTag[1]; |
|||
if(ckt->CKTorder == 1){ |
|||
tag1 = 0; |
|||
} |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senload \n"); |
|||
printf("CKTtime = %.5e\n",ckt->CKTtime); |
|||
printf("CKTorder = %.5e\n",ckt->CKTorder); |
|||
printf("tag0=%.7e,tag1=%.7e\n",tag0,tag1); |
|||
#endif /* SENSDEBUG */ |
|||
info = ckt->CKTsenInfo; |
|||
|
|||
info->SENstatus = PERTURBATION; |
|||
|
|||
/* loop through all the models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("base = %d , baseprm = %d ,col = %d, colprm = %d\n", |
|||
here->BJT2baseNode ,here->BJT2basePrimeNode, |
|||
here->BJT2colNode,here->BJT2colPrimeNode); |
|||
printf("emit = %d , emitprm = %d ,subst = %d, senparmno = %d\n", |
|||
here->BJT2emitNode ,here->BJT2emitPrimeNode, |
|||
here->BJT2substNode,here->BJT2senParmNo); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
|
|||
/* save the unperturbed values in the state vector */ |
|||
for(i=0; i <= 20; i++){ |
|||
*(SaveState0 + i) = *(ckt->CKTstate0 + here->BJT2state + i); |
|||
} |
|||
*(SaveState0 + 21) = *(ckt->CKTstate1 + here->BJT2cexbc); |
|||
*(SaveState0 + 22) = *(ckt->CKTstate2 + here->BJT2cexbc); |
|||
*(SaveState0 + 23) = here->BJT2capbe; |
|||
*(SaveState0 + 24) = here->BJT2capbc; |
|||
*(SaveState0 + 25) = here->BJT2capsub; |
|||
*(SaveState0 + 26) = here->BJT2capbx; |
|||
|
|||
if(here->BJT2senParmNo == 0) goto next; |
|||
|
|||
cx0 = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cb); |
|||
ccpr0 = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cc); |
|||
cepr0 = -cx0 - ccpr0; |
|||
|
|||
here->BJT2senPertFlag = ON; |
|||
error = BJT2load((GENmodel*)model,ckt); |
|||
if(error) return(error); |
|||
|
|||
cb0 = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cb); |
|||
cc0 = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cc); |
|||
gx0 = *(ckt->CKTstate0 + here->BJT2gx); |
|||
|
|||
qbe0 = *(ckt->CKTstate0 + here->BJT2qbe); |
|||
qbc0 = *(ckt->CKTstate0 + here->BJT2qbc); |
|||
qcs0 = *(ckt->CKTstate0 + here->BJT2qsub); |
|||
qbx0 = *(ckt->CKTstate0 + here->BJT2qbx); |
|||
|
|||
/* perturbation of area */ |
|||
|
|||
A0 = here->BJT2area; |
|||
DELA = info->SENpertfac * A0; |
|||
Apert = A0 + DELA; |
|||
DELAinv = 1.0/DELA; |
|||
here->BJT2senPertFlag = ON; |
|||
here->BJT2area = Apert; |
|||
error = BJT2load((GENmodel*)model,ckt); |
|||
if(error) return(error); |
|||
here->BJT2area = A0; |
|||
here->BJT2senPertFlag = OFF; |
|||
|
|||
|
|||
cb = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cb); |
|||
cc = model->BJT2type * *(ckt->CKTstate0 + here->BJT2cc); |
|||
gx = *(ckt->CKTstate0 + here->BJT2gx); |
|||
|
|||
qbe = *(ckt->CKTstate0 + here->BJT2qbe); |
|||
qbc = *(ckt->CKTstate0 + here->BJT2qbc); |
|||
qcs = *(ckt->CKTstate0 + here->BJT2qsub); |
|||
qbx = *(ckt->CKTstate0 + here->BJT2qbx); |
|||
|
|||
/* compute the gradients of currents */ |
|||
DcbDp = (cb - cb0) * DELAinv; |
|||
DccDp = (cc - cc0) * DELAinv; |
|||
DceDp = DcbDp + DccDp; |
|||
|
|||
DccprDp = 0; |
|||
DceprDp = 0; |
|||
DcxDp = 0; |
|||
if(here->BJT2colNode != here->BJT2colPrimeNode) |
|||
DccprDp = ccpr0 * info->SENpertfac * DELAinv; |
|||
if(here->BJT2emitNode != here->BJT2emitPrimeNode) |
|||
DceprDp = cepr0 * info->SENpertfac * DELAinv; |
|||
if(here->BJT2baseNode != here->BJT2basePrimeNode){ |
|||
if(gx0) DcxDp = cx0 * DELAinv * (gx-gx0)/gx0; |
|||
} |
|||
DbprmDp = DcbDp - DcxDp; |
|||
DcprmDp = DccDp - DccprDp; |
|||
DeprmDp = - DceDp - DceprDp; |
|||
|
|||
DqbeDp = (qbe - qbe0)*DELAinv; |
|||
DqbcDp = (qbc - qbc0)*DELAinv; |
|||
DqcsDp = (qcs - qcs0)*DELAinv; |
|||
DqbxDp = (qbx - qbx0)*DELAinv; |
|||
|
|||
*(here->BJT2dphibedp) = DqbeDp; |
|||
*(here->BJT2dphibcdp) = DqbcDp; |
|||
*(here->BJT2dphisubdp) = DqcsDp; |
|||
*(here->BJT2dphibxdp) = DqbxDp; |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("cb0 = %.7e ,cb = %.7e,\n",cb0,cb); |
|||
printf("cc0 = %.7e ,cc = %.7e,\n",cc0,cc); |
|||
printf("ccpr0 = %.7e \n",ccpr0); |
|||
printf("cepr0 = %.7e \n",cepr0); |
|||
printf("cx0 = %.7e \n",cx0); |
|||
printf("qbe0 = %.7e ,qbe = %.7e,\n",qbe0,qbe); |
|||
printf("qbc0 = %.7e ,qbc = %.7e,\n",qbc0,qbc); |
|||
printf("qcs0 = %.7e ,qcs = %.7e,\n",qcs0,qcs); |
|||
printf("qbx0 = %.7e ,qbx = %.7e,\n",qbx0,qbx); |
|||
printf("\n"); |
|||
|
|||
#endif /* SENSDEBUG */ |
|||
|
|||
if((info->SENmode == TRANSEN) && |
|||
(ckt->CKTmode & MODEINITTRAN)) |
|||
goto restore; |
|||
|
|||
/* load the RHS matrix */ |
|||
|
|||
*(info->SEN_RHS[here->BJT2baseNode] + here->BJT2senParmNo) |
|||
-= DcxDp; |
|||
*(info->SEN_RHS[here->BJT2basePrimeNode] + here->BJT2senParmNo) |
|||
-= DbprmDp; |
|||
*(info->SEN_RHS[here->BJT2colNode] + here->BJT2senParmNo) |
|||
-= DccprDp; |
|||
*(info->SEN_RHS[here->BJT2colPrimeNode] + here->BJT2senParmNo) |
|||
-= DcprmDp; |
|||
*(info->SEN_RHS[here->BJT2emitNode] + here->BJT2senParmNo) |
|||
-= DceprDp; |
|||
*(info->SEN_RHS[here->BJT2emitPrimeNode] + here->BJT2senParmNo) |
|||
-= DeprmDp; |
|||
#ifdef SENSDEBUG |
|||
printf("after loading\n"); |
|||
printf("DcxDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2baseNode] + here->BJT2senParmNo)); |
|||
printf("DcbprmDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2basePrimeNode] + |
|||
here->BJT2senParmNo)); |
|||
printf("DccprDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2colNode] + here->BJT2senParmNo)); |
|||
printf("DcprmDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2colPrimeNode] + |
|||
here->BJT2senParmNo)); |
|||
printf("DceprDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2emitNode] + |
|||
here->BJT2senParmNo)); |
|||
printf("DceprmDp=%.7e\n", |
|||
*(info->SEN_RHS[here->BJT2emitPrimeNode] + |
|||
here->BJT2senParmNo)); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
next: |
|||
if((info->SENmode == DCSEN)||(ckt->CKTmode&MODETRANOP))goto restore; |
|||
if((info->SENmode == TRANSEN) && |
|||
(ckt->CKTmode & MODEINITTRAN)) |
|||
goto restore; |
|||
|
|||
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ |
|||
Osxpbe = tag0 * *(ckt->CKTstate1 + here->BJT2sensxpbe + |
|||
8*(iparmno - 1)) |
|||
+ tag1 * *(ckt->CKTstate1 + here->BJT2sensxpbe + |
|||
8*(iparmno - 1) + 1); |
|||
|
|||
Osxpbc = tag0 * *(ckt->CKTstate1 + here->BJT2sensxpbc + |
|||
8*(iparmno - 1)) |
|||
+ tag1 * *(ckt->CKTstate1 + here->BJT2sensxpbc + |
|||
8*(iparmno - 1) + 1); |
|||
|
|||
Osxpcs = tag0 * *(ckt->CKTstate1 + here->BJT2sensxpsub + |
|||
8*(iparmno - 1)) |
|||
+ tag1 * *(ckt->CKTstate1 + here->BJT2sensxpsub + |
|||
8*(iparmno - 1) + 1); |
|||
|
|||
Osxpbx = tag0 * *(ckt->CKTstate1 + here->BJT2sensxpbx + |
|||
8*(iparmno - 1)) |
|||
+ tag1 * *(ckt->CKTstate1 + here->BJT2sensxpbx + |
|||
8*(iparmno - 1) + 1); |
|||
#ifdef SENSDEBUG |
|||
printf("iparmno=%d\n",iparmno); |
|||
printf("Osxpbe=%.7e,Osxpbc=%.7e\n",Osxpbe,Osxpbc); |
|||
printf("Osxpcs=%.7e,Osxpbx=%.7e\n",Osxpcs,Osxpbx); |
|||
printf("sxpbe=%.7e,sdbe=%.7e\n", |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbe + 8*(iparmno - 1)) |
|||
,*(ckt->CKTstate1 + here->BJT2sensxpbe + |
|||
8*(iparmno - 1) + 1)); |
|||
printf("sxpbc=%.7e,sdbc=%.7e\n", |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbc + 8*(iparmno - 1)) |
|||
,*(ckt->CKTstate1 + here->BJT2sensxpbc + |
|||
8*(iparmno - 1) + 1)); |
|||
printf("\n"); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
if(iparmno == here->BJT2senParmNo){ |
|||
Osxpbe = Osxpbe - tag0 * DqbeDp; |
|||
Osxpbc = Osxpbc - tag0 * DqbcDp; |
|||
Osxpcs = Osxpcs - tag0 * DqcsDp; |
|||
Osxpbx = Osxpbx - tag0 * DqbxDp; |
|||
} |
|||
|
|||
#ifdef SENSDEBUG |
|||
|
|||
printf("Osxpbe=%.7e,Osxpbc=%.7e\n",Osxpbe,Osxpbc); |
|||
printf("Osxpcs=%.7e,Osxpbx=%.7e\n",Osxpcs,Osxpbx); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
*(info->SEN_RHS[here->BJT2baseNode] + iparmno) |
|||
+= model->BJT2type * Osxpbx; |
|||
|
|||
*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno) |
|||
+= model->BJT2type * (Osxpbe + Osxpbc); |
|||
|
|||
*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno) |
|||
-= model->BJT2type * (Osxpbc + Osxpcs + Osxpbx ); |
|||
|
|||
*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno) |
|||
-= model->BJT2type * Osxpbe; |
|||
|
|||
*(info->SEN_RHS[here->BJT2substNode] + iparmno) |
|||
+= model->BJT2type * Osxpcs; |
|||
|
|||
} |
|||
|
|||
|
|||
/* put the unperturbed values back into the state vector */ |
|||
restore: |
|||
for(i=0; i <= 20; i++){ |
|||
*(ckt->CKTstate0 + here->BJT2state + i) = *(SaveState0 + i); |
|||
} |
|||
*(ckt->CKTstate1 + here->BJT2cexbc) = *(SaveState0 + 21); |
|||
*(ckt->CKTstate1 + here->BJT2cexbc) = *(SaveState0 + 21); |
|||
here->BJT2capbe = *(SaveState0 + 23) ; |
|||
here->BJT2capbc = *(SaveState0 + 24) ; |
|||
here->BJT2capsub = *(SaveState0 + 25) ; |
|||
here->BJT2capbx = *(SaveState0 + 26) ; |
|||
|
|||
} |
|||
} |
|||
info->SENstatus = NORMAL; |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senload end\n"); |
|||
#endif /* SENSDEBUG */ |
|||
return(OK); |
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
|
|||
This function is obsolete (was used by an old sensitivity analysis) |
|||
**********/ |
|||
|
|||
/* Pretty print the sensitivity info for all |
|||
* the bjt2s in the circuit. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
void |
|||
BJT2sPrint(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
|
|||
printf("BJT2S-----------------\n"); |
|||
/* loop through all the BJT2 models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
printf("Model name:%s\n",model->BJT2modName); |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
ckt->CKTsenInfo->SEN_parmVal[here->BJT2senParmNo] = here->BJT2area; |
|||
|
|||
printf(" Instance name:%s\n",here->BJT2name); |
|||
printf(" Collector, Base , Emitter nodes: %s, %s ,%s\n", |
|||
CKTnodName(ckt,here->BJT2colNode),CKTnodName(ckt,here->BJT2baseNode), |
|||
CKTnodName(ckt,here->BJT2emitNode)); |
|||
|
|||
printf(" Area: %g ",here->BJT2area); |
|||
printf(here->BJT2areaGiven ? "(specified)\n" : "(default)\n"); |
|||
printf(" BJT2senParmNo:%d\n",here->BJT2senParmNo); |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,52 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
|
|||
This function is obsolete (was used by an old sensitivity analysis) |
|||
**********/ |
|||
|
|||
/* loop through all the devices and |
|||
* allocate parameter #s to design parameters |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2sSetup(SENstruct *info, GENmodel *inModel) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
|
|||
#ifdef STEPDEBUG |
|||
printf(" BJT2sensetup \n"); |
|||
#endif /* STEPDEBUG */ |
|||
|
|||
/* loop through all the diode models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
if(here->BJT2senParmNo){ |
|||
here->BJT2senParmNo = ++(info->SENparms); |
|||
here->BJT2senPertFlag = OFF; |
|||
} |
|||
if((here->BJT2sens = TMALLOC(double, 55)) == |
|||
NULL) return(E_NOMEM); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
|
|||
@ -1,156 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
|
|||
This function is obsolete (was used by an old sensitivity analysis) |
|||
**********/ |
|||
|
|||
/* update the charge sensitivities and their derivatives */ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2sUpdate(GENmodel *inModel, CKTcircuit *ckt) |
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
int iparmno; |
|||
double sb; |
|||
double sbprm; |
|||
double scprm; |
|||
double seprm; |
|||
double ss; |
|||
double sxpbe; |
|||
double sxpbc; |
|||
double sxpcs; |
|||
double sxpbx; |
|||
double dummy1; |
|||
double dummy2; |
|||
SENstruct *info; |
|||
|
|||
info = ckt->CKTsenInfo; |
|||
if(ckt->CKTtime == 0) return(OK); |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senUpdate\n"); |
|||
printf("CKTtime = %.5e\n",ckt->CKTtime); |
|||
#endif /* SENSDEBUG */ |
|||
/* loop through all the BJT2 models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
sxpbe = 0; |
|||
sxpbc = 0; |
|||
sxpcs = 0; |
|||
sxpbx = 0; |
|||
#ifdef SENSDEBUG |
|||
printf("senupdate Instance name: %s\n",here->BJT2name); |
|||
printf("iparmno = %d,CKTag[0] = %.2e,CKTag[1] = %.2e\n", |
|||
iparmno,ckt->CKTag[0],ckt->CKTag[1]); |
|||
|
|||
printf("capbe = %.7e\n",here->BJT2capbe); |
|||
printf("capbc = %.7e\n",here->BJT2capbc); |
|||
printf("capcs = %.7e\n",here->BJT2capsub); |
|||
printf("capbx = %.7e\n",here->BJT2capbx); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ |
|||
sb = *(info->SEN_Sap[here->BJT2baseNode] + iparmno); |
|||
sbprm = *(info->SEN_Sap[here->BJT2basePrimeNode] + iparmno); |
|||
scprm = *(info->SEN_Sap[here->BJT2colPrimeNode] + iparmno); |
|||
seprm = *(info->SEN_Sap[here->BJT2emitPrimeNode] + iparmno); |
|||
ss = *(info->SEN_Sap[here->BJT2substNode] + iparmno); |
|||
#ifdef SENSDEBUG |
|||
printf("iparmno = %d \n",iparmno); |
|||
printf("sb = %.7e,sbprm = %.7e,scprm=%.7e\n",sb,sbprm,scprm); |
|||
printf("seprm = %.7e,ss = %.7e\n",seprm,ss); |
|||
#endif /* SENSDEBUG */ |
|||
|
|||
sxpbe = model ->BJT2type * (sbprm - seprm)*here->BJT2capbe; |
|||
|
|||
sxpbc = model ->BJT2type * (sbprm - scprm)*here->BJT2capbc ; |
|||
|
|||
sxpcs = model ->BJT2type * (ss - scprm)*here->BJT2capsub ; |
|||
|
|||
sxpbx = model ->BJT2type * (sb - scprm)*here->BJT2capbx ; |
|||
if(iparmno == here->BJT2senParmNo){ |
|||
sxpbe += *(here->BJT2dphibedp); |
|||
sxpbc += *(here->BJT2dphibcdp); |
|||
sxpcs += *(here->BJT2dphisubdp); |
|||
sxpbx += *(here->BJT2dphibxdp); |
|||
} |
|||
|
|||
|
|||
*(ckt->CKTstate0 + here->BJT2sensxpbe + 8 * (iparmno - 1)) = |
|||
sxpbe; |
|||
NIintegrate(ckt,&dummy1,&dummy2,here->BJT2capbe, |
|||
here->BJT2sensxpbe + 8*(iparmno -1)); |
|||
*(ckt->CKTstate0 + here->BJT2sensxpbc + 8 * (iparmno - 1)) = |
|||
sxpbc; |
|||
NIintegrate(ckt,&dummy1,&dummy2,here->BJT2capbc, |
|||
here->BJT2sensxpbc + 8*(iparmno -1)); |
|||
*(ckt->CKTstate0 + here->BJT2sensxpsub + 8 * (iparmno - 1)) = |
|||
sxpcs; |
|||
NIintegrate(ckt,&dummy1,&dummy2,here->BJT2capsub, |
|||
here->BJT2sensxpsub + 8*(iparmno -1)); |
|||
*(ckt->CKTstate0 + here->BJT2sensxpbx + 8 * (iparmno - 1)) = |
|||
sxpbx; |
|||
NIintegrate(ckt,&dummy1,&dummy2,here->BJT2capbx, |
|||
here->BJT2sensxpbx + 8*(iparmno -1)); |
|||
|
|||
#ifdef SENSDEBUG |
|||
printf("after loading\n"); |
|||
printf("sxpbe = %.7e,sdotxpbe = %.7e\n", |
|||
sxpbe,*(ckt->CKTstate0 + here->BJT2sensxpbe + 8 * |
|||
(iparmno - 1) + 1)); |
|||
printf("sxpbc = %.7e,sdotxpbc = %.7e\n", |
|||
sxpbc,*(ckt->CKTstate0 + here->BJT2sensxpbc + 8 * |
|||
(iparmno - 1) + 1)); |
|||
printf("sxpcs = %.7e,sdotxpsc = %.7e\n", |
|||
sxpcs,*(ckt->CKTstate0 + here->BJT2sensxpsub + 8 * |
|||
(iparmno - 1) + 1)); |
|||
printf("sxpbx = %.7e,sdotxpbx = %.7e\n", |
|||
sxpbx,*(ckt->CKTstate0 + here->BJT2sensxpbx + 8 * |
|||
(iparmno - 1) + 1)); |
|||
printf("\n"); |
|||
#endif /* SENSDEBUG */ |
|||
if(ckt->CKTmode & MODEINITTRAN) { |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbe + 8 * (iparmno - 1)) = |
|||
sxpbe; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbc + 8 * (iparmno - 1)) = |
|||
sxpbc; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpsub + 8 * (iparmno - 1)) = |
|||
sxpcs; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbx + 8 * (iparmno - 1)) = |
|||
sxpbx; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbe + 8 * (iparmno - 1) + |
|||
1) = 0; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbc + 8 * (iparmno - 1) + |
|||
1) = 0; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpsub + 8 * (iparmno - 1) + |
|||
1) = 0; |
|||
*(ckt->CKTstate1 + here->BJT2sensxpbx + 8 * (iparmno - 1) + |
|||
1) = 0; |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
#ifdef SENSDEBUG |
|||
printf("BJT2senUpdate end\n"); |
|||
#endif /* SENSDEBUG */ |
|||
return(OK); |
|||
} |
|||
|
|||
@ -1,231 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "smpdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "const.h" |
|||
#include "sperror.h" |
|||
#include "ifsim.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
/* ARGSUSED */ |
|||
int |
|||
BJT2temp(GENmodel *inModel, CKTcircuit *ckt) |
|||
/* |
|||
* Pre-compute many useful parameters |
|||
*/ |
|||
|
|||
{ |
|||
BJT2model *model = (BJT2model *)inModel; |
|||
BJT2instance *here; |
|||
double xfc; |
|||
double vt; |
|||
double ratlog; |
|||
double ratio1; |
|||
double factlog; |
|||
double bfactor; |
|||
double factor; |
|||
double fact1,fact2; |
|||
double pbo,pbfact; |
|||
double gmaold,gmanew; |
|||
double egfet; |
|||
double arg; |
|||
double dtemp; |
|||
|
|||
/* loop through all the bipolar models */ |
|||
for( ; model != NULL; model = model->BJT2nextModel ) { |
|||
|
|||
if(!model->BJT2tnomGiven) model->BJT2tnom = ckt->CKTnomTemp; |
|||
fact1 = model->BJT2tnom/REFTEMP; |
|||
|
|||
if(!model->BJT2leakBEcurrentGiven) { |
|||
if(model->BJT2c2Given) { |
|||
model->BJT2leakBEcurrent = model->BJT2c2 * model->BJT2satCur; |
|||
} else { |
|||
model->BJT2leakBEcurrent = 0; |
|||
} |
|||
} |
|||
if(!model->BJT2leakBCcurrentGiven) { |
|||
if(model->BJT2c4Given) { |
|||
model->BJT2leakBCcurrent = model->BJT2c4 * model->BJT2satCur; |
|||
} else { |
|||
model->BJT2leakBCcurrent = 0; |
|||
} |
|||
} |
|||
if(!model->BJT2minBaseResistGiven) { |
|||
model->BJT2minBaseResist = model->BJT2baseResist; |
|||
} |
|||
|
|||
/* |
|||
* COMPATABILITY WARNING! |
|||
* special note: for backward compatability to much older models, spice 2G |
|||
* implemented a special case which checked if B-E leakage saturation |
|||
* current was >1, then it was instead a the B-E leakage saturation current |
|||
* divided by IS, and multiplied it by IS at this point. This was not |
|||
* handled correctly in the 2G code, and there is some question on its |
|||
* reasonability, since it is also undocumented, so it has been left out |
|||
* here. It could easily be added with 1 line. (The same applies to the B-C |
|||
* leakage saturation current). TQ 6/29/84 |
|||
*/ |
|||
|
|||
if(model->BJT2earlyVoltFGiven && model->BJT2earlyVoltF != 0) { |
|||
model->BJT2invEarlyVoltF = 1/model->BJT2earlyVoltF; |
|||
} else { |
|||
model->BJT2invEarlyVoltF = 0; |
|||
} |
|||
if(model->BJT2rollOffFGiven && model->BJT2rollOffF != 0) { |
|||
model->BJT2invRollOffF = 1/model->BJT2rollOffF; |
|||
} else { |
|||
model->BJT2invRollOffF = 0; |
|||
} |
|||
if(model->BJT2earlyVoltRGiven && model->BJT2earlyVoltR != 0) { |
|||
model->BJT2invEarlyVoltR = 1/model->BJT2earlyVoltR; |
|||
} else { |
|||
model->BJT2invEarlyVoltR = 0; |
|||
} |
|||
if(model->BJT2rollOffRGiven && model->BJT2rollOffR != 0) { |
|||
model->BJT2invRollOffR = 1/model->BJT2rollOffR; |
|||
} else { |
|||
model->BJT2invRollOffR = 0; |
|||
} |
|||
if(model->BJT2collectorResistGiven && model->BJT2collectorResist != 0) { |
|||
model->BJT2collectorConduct = 1/model->BJT2collectorResist; |
|||
} else { |
|||
model->BJT2collectorConduct = 0; |
|||
} |
|||
if(model->BJT2emitterResistGiven && model->BJT2emitterResist != 0) { |
|||
model->BJT2emitterConduct = 1/model->BJT2emitterResist; |
|||
} else { |
|||
model->BJT2emitterConduct = 0; |
|||
} |
|||
if(model->BJT2transitTimeFVBCGiven && model->BJT2transitTimeFVBC != 0) { |
|||
model->BJT2transitTimeVBCFactor =1/ (model->BJT2transitTimeFVBC*1.44); |
|||
} else { |
|||
model->BJT2transitTimeVBCFactor = 0; |
|||
} |
|||
model->BJT2excessPhaseFactor = (model->BJT2excessPhase/ |
|||
(180.0/M_PI)) * model->BJT2transitTimeF; |
|||
if(model->BJT2depletionCapCoeffGiven) { |
|||
if(model->BJT2depletionCapCoeff>.9999) { |
|||
model->BJT2depletionCapCoeff=.9999; |
|||
SPfrontEnd->IFerror (ERR_WARNING, |
|||
"BJT2 model %s, parameter fc limited to 0.9999", |
|||
&(model->BJT2modName)); |
|||
} |
|||
} else { |
|||
model->BJT2depletionCapCoeff=.5; |
|||
} |
|||
xfc = log(1-model->BJT2depletionCapCoeff); |
|||
model->BJT2f2 = exp((1 + model->BJT2junctionExpBE) * xfc); |
|||
model->BJT2f3 = 1 - model->BJT2depletionCapCoeff * |
|||
(1 + model->BJT2junctionExpBE); |
|||
model->BJT2f6 = exp((1+model->BJT2junctionExpBC)*xfc); |
|||
model->BJT2f7 = 1 - model->BJT2depletionCapCoeff * |
|||
(1 + model->BJT2junctionExpBC); |
|||
|
|||
/* loop through all the instances of the model */ |
|||
for (here = model->BJT2instances; here != NULL ; |
|||
here=here->BJT2nextInstance) { |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
if(!here->BJT2dtempGiven) |
|||
here->BJT2dtemp = 0.0; |
|||
|
|||
if(!here->BJT2tempGiven) |
|||
here->BJT2temp = ckt->CKTtemp + here->BJT2dtemp; |
|||
|
|||
vt = here->BJT2temp * CONSTKoverQ; |
|||
fact2 = here->BJT2temp/REFTEMP; |
|||
egfet = 1.16-(7.02e-4*here->BJT2temp*here->BJT2temp)/ |
|||
(here->BJT2temp+1108); |
|||
arg = -egfet/(2*CONSTboltz*here->BJT2temp)+ |
|||
1.1150877/(CONSTboltz*(REFTEMP+REFTEMP)); |
|||
pbfact = -2*vt*(1.5*log(fact2)+CHARGE*arg); |
|||
|
|||
ratlog = log(here->BJT2temp/model->BJT2tnom); |
|||
ratio1 = here->BJT2temp/model->BJT2tnom -1; |
|||
factlog = ratio1 * model->BJT2energyGap/vt + |
|||
model->BJT2tempExpIS*ratlog; |
|||
factor = exp(factlog); |
|||
here->BJT2tSatCur = model->BJT2satCur * factor; |
|||
here->BJT2tSubSatCur = model->BJT2subSatCur * factor; |
|||
bfactor = exp(ratlog*model->BJT2betaExp); |
|||
here->BJT2tBetaF = model->BJT2betaF * bfactor; |
|||
here->BJT2tBetaR = model->BJT2betaR * bfactor; |
|||
here->BJT2tBEleakCur = model->BJT2leakBEcurrent * |
|||
exp(factlog/model->BJT2leakBEemissionCoeff)/bfactor; |
|||
here->BJT2tBCleakCur = model->BJT2leakBCcurrent * |
|||
exp(factlog/model->BJT2leakBCemissionCoeff)/bfactor; |
|||
|
|||
dtemp = here->BJT2temp - model->BJT2tnom; |
|||
if(model->BJT2emitterResistGiven && model->BJT2emitterResist != 0) { |
|||
factor = 1.0 + (model->BJT2reTempCoeff1)*dtemp + |
|||
(model->BJT2reTempCoeff2)*dtemp*dtemp; |
|||
here -> BJT2tEmitterConduct = 1/(model->BJT2emitterResist * factor); |
|||
} else { |
|||
here -> BJT2tEmitterConduct = 0; |
|||
} |
|||
if(model->BJT2collectorResistGiven && model->BJT2collectorResist != 0) { |
|||
factor = 1.0 + (model->BJT2rcTempCoeff1)*dtemp + |
|||
(model->BJT2rcTempCoeff2)*dtemp*dtemp; |
|||
here -> BJT2tCollectorConduct = 1/(model->BJT2collectorResist * factor); |
|||
} else { |
|||
here -> BJT2tCollectorConduct = 0; |
|||
} |
|||
factor = 1.0 + (model->BJT2rbTempCoeff1)*dtemp + |
|||
(model->BJT2rbTempCoeff2)*dtemp*dtemp; |
|||
here -> BJT2tBaseResist = model->BJT2baseResist * factor; |
|||
factor = 1.0 + (model->BJT2rbmTempCoeff1)*dtemp + |
|||
(model->BJT2rbmTempCoeff2)*dtemp*dtemp; |
|||
here -> BJT2tMinBaseResist = model->BJT2minBaseResist * factor; |
|||
|
|||
pbo = (model->BJT2potentialBE-pbfact)/fact1; |
|||
gmaold = (model->BJT2potentialBE-pbo)/pbo; |
|||
here->BJT2tBEcap = model->BJT2depletionCapBE/ |
|||
(1+model->BJT2junctionExpBE* |
|||
(4e-4*(model->BJT2tnom-REFTEMP)-gmaold)); |
|||
here->BJT2tBEpot = fact2 * pbo+pbfact; |
|||
gmanew = (here->BJT2tBEpot-pbo)/pbo; |
|||
here->BJT2tBEcap *= 1+model->BJT2junctionExpBE* |
|||
(4e-4*(here->BJT2temp-REFTEMP)-gmanew); |
|||
|
|||
pbo = (model->BJT2potentialBC-pbfact)/fact1; |
|||
gmaold = (model->BJT2potentialBC-pbo)/pbo; |
|||
here->BJT2tBCcap = model->BJT2depletionCapBC/ |
|||
(1+model->BJT2junctionExpBC* |
|||
(4e-4*(model->BJT2tnom-REFTEMP)-gmaold)); |
|||
here->BJT2tBCpot = fact2 * pbo+pbfact; |
|||
gmanew = (here->BJT2tBCpot-pbo)/pbo; |
|||
here->BJT2tBCcap *= 1+model->BJT2junctionExpBC* |
|||
(4e-4*(here->BJT2temp-REFTEMP)-gmanew); |
|||
pbo = (model->BJT2potentialSubstrate-pbfact)/fact1; |
|||
gmaold = (model->BJT2potentialSubstrate-pbo)/pbo; |
|||
here->BJT2tSubcap = model->BJT2capSub/ |
|||
(1+model->BJT2exponentialSubstrate* |
|||
(4e-4*(model->BJT2tnom-REFTEMP)-gmaold)); |
|||
here->BJT2tSubpot = fact2 * pbo+pbfact; |
|||
gmanew = (here->BJT2tSubpot-pbo)/pbo; |
|||
here->BJT2tSubcap *= 1+model->BJT2exponentialSubstrate* |
|||
(4e-4*(here->BJT2temp-REFTEMP)-gmanew); |
|||
here->BJT2tDepCap = model->BJT2depletionCapCoeff * here->BJT2tBEpot; |
|||
here->BJT2tf1 = here->BJT2tBEpot * (1 - exp((1 - |
|||
model->BJT2junctionExpBE) * xfc)) / |
|||
(1 - model->BJT2junctionExpBE); |
|||
here->BJT2tf4 = model->BJT2depletionCapCoeff * here->BJT2tBCpot; |
|||
here->BJT2tf5 = here->BJT2tBCpot * (1 - exp((1 - |
|||
model->BJT2junctionExpBC) * xfc)) / |
|||
(1 - model->BJT2junctionExpBC); |
|||
here->BJT2tVcrit = vt * |
|||
log(vt / (CONSTroot2*here->BJT2tSatCur*here->BJT2area)); |
|||
here->BJT2tSubVcrit = vt * |
|||
log(vt / (CONSTroot2*here->BJT2tSubSatCur*here->BJT2area)); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
/********** |
|||
Copyright 1990 Regents of the University of California. All rights reserved. |
|||
Author: 1985 Thomas L. Quarles |
|||
Modified: Alan Gillespie |
|||
**********/ |
|||
/* |
|||
*/ |
|||
|
|||
/* |
|||
* This routine performs truncation error calculations for |
|||
* BJT2s in the circuit. |
|||
*/ |
|||
|
|||
#include "ngspice.h" |
|||
#include "cktdefs.h" |
|||
#include "bjt2defs.h" |
|||
#include "sperror.h" |
|||
#include "suffix.h" |
|||
|
|||
|
|||
int |
|||
BJT2trunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) |
|||
|
|||
{ |
|||
BJT2model *model = (BJT2model*)inModel; |
|||
BJT2instance *here; |
|||
|
|||
for( ; model != NULL; model = model->BJT2nextModel) { |
|||
for(here=model->BJT2instances;here!=NULL;here = here->BJT2nextInstance){ |
|||
if (here->BJT2owner != ARCHme) continue; |
|||
|
|||
CKTterr(here->BJT2qbe,ckt,timeStep); |
|||
CKTterr(here->BJT2qbc,ckt,timeStep); |
|||
CKTterr(here->BJT2qsub,ckt,timeStep); |
|||
} |
|||
} |
|||
return(OK); |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue