merged to bjt model
This commit is contained in:
parent
0b6a557334
commit
33fdd85ee2
|
|
@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue