Dietmar's bjt2 code (temperature correction of resistors).

This commit is contained in:
pnenzi 2003-09-25 12:27:23 +00:00
parent 100aa8388d
commit a0514cfc30
31 changed files with 7639 additions and 7591 deletions

View File

@ -29,7 +29,12 @@ libbjt2_a_SOURCES = \
bjt2noise.c \
bjt2param.c \
bjt2pzld.c \
bjt2sacl.c \
bjt2setup.c \
bjt2sload.c \
bjt2sprt.c \
bjt2sset.c \
bjt2supd.c \
bjt2temp.c \
bjt2trun.c

View File

@ -1,156 +1,164 @@
/**********
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
*/
#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, "Area factor"),
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")
};
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"),
/*IOP("c2", BJT2_MOD_C2, IF_REAL, "Obsolete parameter name"),*/
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"),
/*IOP("c4", BJT2_MOD_C4, IF_REAL, "Obsolete parameter name"),*/
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("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);
/**********
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
*/
#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, "Area factor"),
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")
};
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"),
/*IOP("c2", BJT2_MOD_C2, IF_REAL, "Obsolete parameter name"),*/
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"),
/*IOP("c4", BJT2_MOD_C4, IF_REAL, "Obsolete parameter name"),*/
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);

View File

@ -1,105 +1,102 @@
/**********
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(inModel,ckt)
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;
for( ; model != NULL; model = model->BJT2nextModel) {
for( here = model->BJT2instances; here!= NULL;
here = here->BJT2nextInstance) {
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;
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) += (gcpr);
*(here->BJT2baseBasePtr) += (gx);
*(here->BJT2baseBasePtr + 1) += (xcbx);
*(here->BJT2emitEmitPtr) += (gepr);
*(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr);
*(here->BJT2colPrimeColPrimePtr + 1) += (xcmu+xcbx);
*(here->BJT2substConSubstConPtr + 1) += (xcsub);
*(here->BJT2basePrimeBasePrimePtr) += (gx+gpi+gmu);
*(here->BJT2basePrimeBasePrimePtr + 1) += (xcpi+xcmu+xcmcb);
*(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go);
*(here->BJT2emitPrimeEmitPrimePtr + 1) += (xcpi+xgm);
*(here->BJT2colColPrimePtr) += (-gcpr);
*(here->BJT2baseBasePrimePtr) += (-gx);
*(here->BJT2emitEmitPrimePtr) += (-gepr);
*(here->BJT2colPrimeColPtr) += (-gcpr);
*(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm);
*(here->BJT2colPrimeBasePrimePtr + 1) += (-xcmu+xgm);
*(here->BJT2colPrimeEmitPrimePtr) += (-gm-go);
*(here->BJT2colPrimeEmitPrimePtr + 1) += (-xgm);
*(here->BJT2basePrimeBasePtr) += (-gx);
*(here->BJT2basePrimeColPrimePtr) += (-gmu);
*(here->BJT2basePrimeColPrimePtr + 1) += (-xcmu-xcmcb);
*(here->BJT2basePrimeEmitPrimePtr) += (-gpi);
*(here->BJT2basePrimeEmitPrimePtr + 1) += (-xcpi);
*(here->BJT2emitPrimeEmitPtr) += (-gepr);
*(here->BJT2emitPrimeColPrimePtr) += (-go);
*(here->BJT2emitPrimeColPrimePtr + 1) += (xcmcb);
*(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm);
*(here->BJT2emitPrimeBasePrimePtr + 1) += (-xcpi-xgm-xcmcb);
*(here->BJT2substSubstPtr + 1) += (xcsub);
*(here->BJT2substConSubstPtr + 1) += (-xcsub);
*(here->BJT2substSubstConPtr + 1) += (-xcsub);
*(here->BJT2baseColPrimePtr + 1) += (-xcbx);
*(here->BJT2colPrimeBasePtr + 1) += (-xcbx);
}
}
return(OK);
}
/**********
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;
for( ; model != NULL; model = model->BJT2nextModel) {
for( here = model->BJT2instances; here!= NULL;
here = here->BJT2nextInstance) {
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) += (gcpr);
*(here->BJT2baseBasePtr) += (gx);
*(here->BJT2baseBasePtr + 1) += (xcbx);
*(here->BJT2emitEmitPtr) += (gepr);
*(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr);
*(here->BJT2colPrimeColPrimePtr + 1) += (xcmu+xcbx);
*(here->BJT2substConSubstConPtr + 1) += (xcsub);
*(here->BJT2basePrimeBasePrimePtr) += (gx+gpi+gmu);
*(here->BJT2basePrimeBasePrimePtr + 1) += (xcpi+xcmu+xcmcb);
*(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go);
*(here->BJT2emitPrimeEmitPrimePtr + 1) += (xcpi+xgm);
*(here->BJT2colColPrimePtr) += (-gcpr);
*(here->BJT2baseBasePrimePtr) += (-gx);
*(here->BJT2emitEmitPrimePtr) += (-gepr);
*(here->BJT2colPrimeColPtr) += (-gcpr);
*(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm);
*(here->BJT2colPrimeBasePrimePtr + 1) += (-xcmu+xgm);
*(here->BJT2colPrimeEmitPrimePtr) += (-gm-go);
*(here->BJT2colPrimeEmitPrimePtr + 1) += (-xgm);
*(here->BJT2basePrimeBasePtr) += (-gx);
*(here->BJT2basePrimeColPrimePtr) += (-gmu);
*(here->BJT2basePrimeColPrimePtr + 1) += (-xcmu-xcmcb);
*(here->BJT2basePrimeEmitPrimePtr) += (-gpi);
*(here->BJT2basePrimeEmitPrimePtr + 1) += (-xcpi);
*(here->BJT2emitPrimeEmitPtr) += (-gepr);
*(here->BJT2emitPrimeColPrimePtr) += (-go);
*(here->BJT2emitPrimeColPrimePtr + 1) += (xcmcb);
*(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm);
*(here->BJT2emitPrimeBasePrimePtr + 1) += (-xcpi-xgm-xcmcb);
*(here->BJT2substSubstPtr + 1) += (xcsub);
*(here->BJT2substConSubstPtr + 1) += (-xcsub);
*(here->BJT2substSubstConPtr + 1) += (-xcsub);
*(here->BJT2baseColPrimePtr + 1) += (-xcbx);
*(here->BJT2colPrimeBasePtr + 1) += (-xcbx);
}
}
return(OK);
}

View File

@ -1,293 +1,289 @@
/**********
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(ckt,instPtr,which,value,select)
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_AREA:
value->rValue = here->BJT2area;
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);
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);
}
};
return(OK);
case BJT2_QUEST_GPI:
value->rValue = *(ckt->CKTstate0 + here->BJT2gpi);
return(OK);
case BJT2_QUEST_GMU:
value->rValue = *(ckt->CKTstate0 + here->BJT2gmu);
return(OK);
case BJT2_QUEST_GM:
value->rValue = *(ckt->CKTstate0 + here->BJT2gm);
return(OK);
case BJT2_QUEST_GO:
value->rValue = *(ckt->CKTstate0 + here->BJT2go);
return(OK);
case BJT2_QUEST_QBE:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbe);
return(OK);
case BJT2_QUEST_CQBE:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbe);
return(OK);
case BJT2_QUEST_QBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbc);
return(OK);
case BJT2_QUEST_CQBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbc);
return(OK);
case BJT2_QUEST_QSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2qsub);
return(OK);
case BJT2_QUEST_CQSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqsub);
return(OK);
case BJT2_QUEST_QBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbx);
return(OK);
case BJT2_QUEST_CQBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbx);
return(OK);
case BJT2_QUEST_GX:
value->rValue = *(ckt->CKTstate0 + here->BJT2gx);
return(OK);
case BJT2_QUEST_CEXBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2cexbc);
return(OK);
case BJT2_QUEST_GEQCB:
value->rValue = *(ckt->CKTstate0 + here->BJT2geqcb);
return(OK);
case BJT2_QUEST_GCSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2gcsub);
return(OK);
case BJT2_QUEST_GDSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2gdsub);
return(OK);
case BJT2_QUEST_GEQBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2geqbx);
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 = MALLOC(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)));
}
return(OK);
case BJT2_QUEST_CE :
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = MALLOC(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);
}
}
}
return(OK);
case BJT2_QUEST_POWER :
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = MALLOC(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));
}
}
return(OK);
case BJT2_QUEST_CPI:
value->rValue = here->BJT2capbe;
return(OK);
case BJT2_QUEST_CMU:
value->rValue = here->BJT2capbc;
return(OK);
case BJT2_QUEST_CBX:
value->rValue = here->BJT2capbx;
return(OK);
case BJT2_QUEST_CSUB:
value->rValue = here->BJT2capsub;
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}
/**********
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_AREA:
value->rValue = here->BJT2area;
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);
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);
}
};
return(OK);
case BJT2_QUEST_GPI:
value->rValue = *(ckt->CKTstate0 + here->BJT2gpi);
return(OK);
case BJT2_QUEST_GMU:
value->rValue = *(ckt->CKTstate0 + here->BJT2gmu);
return(OK);
case BJT2_QUEST_GM:
value->rValue = *(ckt->CKTstate0 + here->BJT2gm);
return(OK);
case BJT2_QUEST_GO:
value->rValue = *(ckt->CKTstate0 + here->BJT2go);
return(OK);
case BJT2_QUEST_QBE:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbe);
return(OK);
case BJT2_QUEST_CQBE:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbe);
return(OK);
case BJT2_QUEST_QBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbc);
return(OK);
case BJT2_QUEST_CQBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbc);
return(OK);
case BJT2_QUEST_QSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2qsub);
return(OK);
case BJT2_QUEST_CQSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqsub);
return(OK);
case BJT2_QUEST_QBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2qbx);
return(OK);
case BJT2_QUEST_CQBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2cqbx);
return(OK);
case BJT2_QUEST_GX:
value->rValue = *(ckt->CKTstate0 + here->BJT2gx);
return(OK);
case BJT2_QUEST_CEXBC:
value->rValue = *(ckt->CKTstate0 + here->BJT2cexbc);
return(OK);
case BJT2_QUEST_GEQCB:
value->rValue = *(ckt->CKTstate0 + here->BJT2geqcb);
return(OK);
case BJT2_QUEST_GCSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2gcsub);
return(OK);
case BJT2_QUEST_GDSUB:
value->rValue = *(ckt->CKTstate0 + here->BJT2gdsub);
return(OK);
case BJT2_QUEST_GEQBX:
value->rValue = *(ckt->CKTstate0 + here->BJT2geqbx);
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 = MALLOC(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)));
}
return(OK);
case BJT2_QUEST_CE :
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = MALLOC(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);
}
}
}
return(OK);
case BJT2_QUEST_POWER :
if (ckt->CKTcurrentAnalysis & DOING_AC) {
errMsg = MALLOC(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));
}
}
return(OK);
case BJT2_QUEST_CPI:
value->rValue = here->BJT2capbe;
return(OK);
case BJT2_QUEST_CMU:
value->rValue = here->BJT2capbc;
return(OK);
case BJT2_QUEST_CBX:
value->rValue = here->BJT2capbx;
return(OK);
case BJT2_QUEST_CSUB:
value->rValue = here->BJT2capsub;
return(OK);
default:
return(E_BADPARM);
}
/* NOTREACHED */
}

View File

@ -1,77 +1,74 @@
/**********
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(inModel,ckt)
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){
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);
}
/**********
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){
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);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +1,39 @@
/**********
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(inModel,name,kill)
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);
}
/**********
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);
}

View File

@ -1,49 +1,46 @@
/**********
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(inModel)
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;
}
/**********
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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#ifndef __BJT2DSET_H
#define __BJT2DSET_H
int BJT2dSetup(GENmodel *inModel, CKTcircuit *ckt);
#endif
#ifndef __BJT2DSET_H
#define __BJT2DSET_H
int BJT2dSetup(GENmodel *inModel, CKTcircuit *ckt);
#endif

View File

@ -1,35 +1,35 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
#ifndef __BJ2TEXT_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
/**********
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

View File

@ -1,50 +1,47 @@
/**********
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(inModel,ckt)
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->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);
}
/**********
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->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);
}

View File

@ -1,84 +1,84 @@
#include <config.h>
#include <devdefs.h>
#include "bjt2itf.h"
#include "bjt2ext.h"
#include "bjt2init.h"
SPICEdev BJT2info = {
{
"BJT2",
"Bipolar Junction Transistor (AG)",
&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 : NULL, /* BJT2sSetup */
DEVsenLoad : NULL, /* BJT2sLoad */
DEVsenUpdate : NULL, /* BJT2sUpdate */
DEVsenAcLoad : NULL, /* BJT2sAcLoad */
DEVsenPrint : NULL, /* 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;
}
#include <config.h>
#include <devdefs.h>
#include "bjt2itf.h"
#include "bjt2ext.h"
#include "bjt2init.h"
SPICEdev BJT2info = {
{
"BJT2",
"Bipolar Junction Transistor (AG)",
&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;
}

View File

@ -1,13 +1,13 @@
#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
#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

View File

@ -1,11 +1,11 @@
/**********
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
/**********
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

File diff suppressed because it is too large Load Diff

View File

@ -1,209 +1,229 @@
/**********
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(ckt,instPtr,which,value)
CKTcircuit *ckt;
GENmodel *instPtr;
int which;
IFvalue *value;
{
BJT2model *here = (BJT2model*)instPtr;
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_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 */
}
/**********
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;
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 */
}

View File

@ -1,46 +1,43 @@
/**********
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(inModels,modname,kill)
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);
}
/**********
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);
}

View File

@ -1,225 +1,254 @@
/**********
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(param,value,inModel)
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_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);
}
/**********
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);
}

View File

@ -1,231 +1,226 @@
/**********
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".
*/
extern void NevalSrc();
extern double Nintegrate();
int
BJT2noise (mode, operation, genmodel, ckt, data, OnDens)
GENmodel *genmodel;
int mode;
int operation;
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 error;
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) {
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 = (IFuid *)
trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
break;
case INT_NOIZ:
for (i=0; i < BJT2NSRCS; i++) {
(void)sprintf(name,"onoise_total_%s%s",
inst->BJT2name,BJT2nNames[i]);
data->namelist = (IFuid *)
trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
(void)sprintf(name,"inoise_total_%s%s",
inst->BJT2name,BJT2nNames[i]);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
break;
}
}
break;
case N_CALC:
switch (mode) {
case N_DENS:
NevalSrc(&noizDens[BJT2RCNOIZ],&lnNdens[BJT2RCNOIZ],
ckt,THERMNOISE,inst->BJT2colPrimeNode,inst->BJT2colNode,
model->BJT2collectorConduct * inst->BJT2area);
NevalSrc(&noizDens[BJT2RBNOIZ],&lnNdens[BJT2RBNOIZ],
ckt,THERMNOISE,inst->BJT2basePrimeNode,inst->BJT2baseNode,
*(ckt->CKTstate0 + inst->BJT2gx));
NevalSrc(&noizDens[BJT2_RE_NOISE],&lnNdens[BJT2_RE_NOISE],
ckt,THERMNOISE,inst->BJT2emitPrimeNode,inst->BJT2emitNode,
model->BJT2emitterConduct * inst->BJT2area);
NevalSrc(&noizDens[BJT2ICNOIZ],&lnNdens[BJT2ICNOIZ],
ckt,SHOTNOISE,inst->BJT2colPrimeNode, inst->BJT2emitPrimeNode,
*(ckt->CKTstate0 + inst->BJT2cc));
NevalSrc(&noizDens[BJT2IBNOIZ],&lnNdens[BJT2IBNOIZ],
ckt,SHOTNOISE,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode,
*(ckt->CKTstate0 + inst->BJT2cb));
NevalSrc(&noizDens[BJT2FLNOIZ],(double*)NULL,ckt,
N_GAIN,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode,
(double)0.0);
noizDens[BJT2FLNOIZ] *= 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);
}
/**********
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".
*/
extern void NevalSrc();
extern double Nintegrate();
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 error;
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) {
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 = (IFuid *)
trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
break;
case INT_NOIZ:
for (i=0; i < BJT2NSRCS; i++) {
(void)sprintf(name,"onoise_total_%s%s",
inst->BJT2name,BJT2nNames[i]);
data->namelist = (IFuid *)
trealloc((char *)data->namelist,
(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
(void)sprintf(name,"inoise_total_%s%s",
inst->BJT2name,BJT2nNames[i]);
data->namelist = (IFuid *)trealloc((char *)data->namelist,(data->numPlots + 1)*sizeof(IFuid));
if (!data->namelist) return(E_NOMEM);
(*(SPfrontEnd->IFnewUid))(ckt,
&(data->namelist[data->numPlots++]),
(IFuid)NULL,name,UID_OTHER,(void **)NULL);
/* we've added one more plot */
}
break;
}
}
break;
case N_CALC:
switch (mode) {
case N_DENS:
NevalSrc(&noizDens[BJT2RCNOIZ],&lnNdens[BJT2RCNOIZ],
ckt,THERMNOISE,inst->BJT2colPrimeNode,inst->BJT2colNode,
model->BJT2collectorConduct * inst->BJT2area);
NevalSrc(&noizDens[BJT2RBNOIZ],&lnNdens[BJT2RBNOIZ],
ckt,THERMNOISE,inst->BJT2basePrimeNode,inst->BJT2baseNode,
*(ckt->CKTstate0 + inst->BJT2gx));
NevalSrc(&noizDens[BJT2_RE_NOISE],&lnNdens[BJT2_RE_NOISE],
ckt,THERMNOISE,inst->BJT2emitPrimeNode,inst->BJT2emitNode,
model->BJT2emitterConduct * inst->BJT2area);
NevalSrc(&noizDens[BJT2ICNOIZ],&lnNdens[BJT2ICNOIZ],
ckt,SHOTNOISE,inst->BJT2colPrimeNode, inst->BJT2emitPrimeNode,
*(ckt->CKTstate0 + inst->BJT2cc));
NevalSrc(&noizDens[BJT2IBNOIZ],&lnNdens[BJT2IBNOIZ],
ckt,SHOTNOISE,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode,
*(ckt->CKTstate0 + inst->BJT2cb));
NevalSrc(&noizDens[BJT2FLNOIZ],(double*)NULL,ckt,
N_GAIN,inst->BJT2basePrimeNode, inst->BJT2emitPrimeNode,
(double)0.0);
noizDens[BJT2FLNOIZ] *= 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);
}

View File

@ -1,72 +1,68 @@
/**********
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(param,value,instPtr,select)
int param;
IFvalue *value;
GENinstance *instPtr;
IFvalue *select;
{
BJT2instance *here = (BJT2instance*)instPtr;
switch(param) {
case BJT2_AREA:
here->BJT2area = value->rValue;
here->BJT2areaGiven = TRUE;
break;
case BJT2_TEMP:
here->BJT2temp = value->rValue+CONSTCtoK;
here->BJT2tempGiven = TRUE;
break;
case BJT2_OFF:
here->BJT2off = value->iValue;
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);
}
/**********
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;
switch(param) {
case BJT2_AREA:
here->BJT2area = value->rValue;
here->BJT2areaGiven = TRUE;
break;
case BJT2_TEMP:
here->BJT2temp = value->rValue+CONSTCtoK;
here->BJT2tempGiven = TRUE;
break;
case BJT2_OFF:
here->BJT2off = value->iValue;
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);
}

View File

@ -1,142 +1,115 @@
/**********
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(inModel,ckt,s)
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 xcsub;
double xcmcb;
for( ; model != NULL; model = model->BJT2nextModel) {
for( here = model->BJT2instances; here!= NULL;
here = here->BJT2nextInstance) {
gcpr=model->BJT2collectorResist * here->BJT2area;
gepr=model->BJT2emitterResist * 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);
xcsub= *(ckt->CKTstate0 + here->BJT2cqsub);
xcmcb= *(ckt->CKTstate0 + here->BJT2cexbc);
*(here->BJT2colColPtr) += (gcpr);
*(here->BJT2baseBasePtr) += (gx) + (xcbx) * (s->real);
*(here->BJT2baseBasePtr + 1) += (xcbx) * (s->imag);
*(here->BJT2emitEmitPtr) += (gepr);
*(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr)
+ (xcmu+xcbx) * (s->real);
*(here->BJT2colPrimeColPrimePtr + 1) += (xcmu+xcbx)
* (s->imag);
*(here->BJT2substConSubstPtr) += (-xcsub) * (s->real);
*(here->BJT2substConSubstPtr = 1) += (-xcsub) * (s->imag);
*(here->BJT2basePrimeBasePrimePtr) += (gx+gpi+gmu)
+ (xcpi+xcmu+xcmcb) * (s->real);
*(here->BJT2basePrimeBasePrimePtr + 1) += (xcpi+xcmu+xcmcb)
* (s->imag);
*(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go)
+ (xcpi+xgm) * (s->real);
*(here->BJT2emitPrimeEmitPrimePtr + 1) += (xcpi+xgm)
* (s->imag);
*(here->BJT2colColPrimePtr) += (-gcpr);
*(here->BJT2baseBasePrimePtr) += (-gx);
*(here->BJT2emitEmitPrimePtr) += (-gepr);
*(here->BJT2colPrimeColPtr) += (-gcpr);
*(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm)
+ (-xcmu+xgm) * (s->real);
*(here->BJT2colPrimeBasePrimePtr + 1) += (-xcmu+xgm)
* (s->imag);
*(here->BJT2colPrimeEmitPrimePtr) += (-gm-go)
+ (-xgm) * (s->real);
*(here->BJT2colPrimeEmitPrimePtr + 1) += (-xgm) *
(s->imag);
*(here->BJT2basePrimeBasePtr) += (-gx);
*(here->BJT2basePrimeColPrimePtr) += (-gmu)
+ (-xcmu-xcmcb) * (s->real);
*(here->BJT2basePrimeColPrimePtr + 1) += (-xcmu-xcmcb)
* (s->imag);
*(here->BJT2basePrimeEmitPrimePtr) += (-gpi)
+ (-xcpi) * (s->real);
*(here->BJT2basePrimeEmitPrimePtr + 1) += (-xcpi)
* (s->imag);
*(here->BJT2emitPrimeEmitPtr) += (-gepr);
*(here->BJT2emitPrimeColPrimePtr) += (-go)
+ (xcmcb) * (s->real);
*(here->BJT2emitPrimeColPrimePtr + 1) += (xcmcb)
* (s->imag);
*(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm)
+ (-xcpi-xgm-xcmcb) * (s->real);
*(here->BJT2emitPrimeBasePrimePtr + 1) += (-xcpi-xgm-xcmcb)
* (s->imag);
/*
* Paolo Nenzi 2002
*
* This is a very quick and dirty hack to make BJ2 compile.
* The code replacing the commented out one has been built using
* the one in bjt2acld.c
* DO NOT USE THIS DEVICE
*
* *(here->BJT2substSubstPtr) += (xccs) * (s->real);
* *(here->BJT2substSubstPtr + 1) += (xccs) * (s->imag);
* *(here->BJT2colPrimeSubstPtr) += (-xccs) * (s->real);
* *(here->BJT2colPrimeSubstPtr + 1) += (-xccs) * (s->imag);
* *(here->BJT2substColPrimePtr) += (-xccs) * (s->real);
* *(here->BJT2substColPrimePtr + 1) += (-xccs) * (s->imag);
*/
*(here->BJT2substSubstPtr) += (xcsub) * (s->real);
*(here->BJT2substSubstPtr + 1) += (xcsub) * (s->imag);
*(here->BJT2substConSubstPtr) += (-xcsub) * (s->real);
*(here->BJT2substConSubstPtr = 1) += (-xcsub) * (s->imag);
*(here->BJT2substSubstConPtr) += (-xcsub) * (s->real);
*(here->BJT2substSubstConPtr = 1) += (-xcsub) * (s->imag);
*(here->BJT2baseColPrimePtr) += (-xcbx) * (s->real);
*(here->BJT2baseColPrimePtr + 1) += (-xcbx) * (s->imag);
*(here->BJT2colPrimeBasePtr) += (-xcbx) * (s->real);
*(here->BJT2colPrimeBasePtr + 1) += (-xcbx) * (s->imag);
}
}
return(OK);
}
/**********
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;
for( ; model != NULL; model = model->BJT2nextModel) {
for( here = model->BJT2instances; here!= NULL;
here = here->BJT2nextInstance) {
gcpr=model->BJT2collectorResist * here->BJT2area;
gepr=model->BJT2emitterResist * 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) += (gcpr);
*(here->BJT2baseBasePtr) += (gx) + (xcbx) * (s->real);
*(here->BJT2baseBasePtr + 1) += (xcbx) * (s->imag);
*(here->BJT2emitEmitPtr) += (gepr);
*(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr)
+ (xcmu+xccs+xcbx) * (s->real);
*(here->BJT2colPrimeColPrimePtr + 1) += (xcmu+xccs+xcbx)
* (s->imag);
*(here->BJT2basePrimeBasePrimePtr) += (gx+gpi+gmu)
+ (xcpi+xcmu+xcmcb) * (s->real);
*(here->BJT2basePrimeBasePrimePtr + 1) += (xcpi+xcmu+xcmcb)
* (s->imag);
*(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go)
+ (xcpi+xgm) * (s->real);
*(here->BJT2emitPrimeEmitPrimePtr + 1) += (xcpi+xgm)
* (s->imag);
*(here->BJT2colColPrimePtr) += (-gcpr);
*(here->BJT2baseBasePrimePtr) += (-gx);
*(here->BJT2emitEmitPrimePtr) += (-gepr);
*(here->BJT2colPrimeColPtr) += (-gcpr);
*(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm)
+ (-xcmu+xgm) * (s->real);
*(here->BJT2colPrimeBasePrimePtr + 1) += (-xcmu+xgm)
* (s->imag);
*(here->BJT2colPrimeEmitPrimePtr) += (-gm-go)
+ (-xgm) * (s->real);
*(here->BJT2colPrimeEmitPrimePtr + 1) += (-xgm) *
(s->imag);
*(here->BJT2basePrimeBasePtr) += (-gx);
*(here->BJT2basePrimeColPrimePtr) += (-gmu)
+ (-xcmu-xcmcb) * (s->real);
*(here->BJT2basePrimeColPrimePtr + 1) += (-xcmu-xcmcb)
* (s->imag);
*(here->BJT2basePrimeEmitPrimePtr) += (-gpi)
+ (-xcpi) * (s->real);
*(here->BJT2basePrimeEmitPrimePtr + 1) += (-xcpi)
* (s->imag);
*(here->BJT2emitPrimeEmitPtr) += (-gepr);
*(here->BJT2emitPrimeColPrimePtr) += (-go)
+ (xcmcb) * (s->real);
*(here->BJT2emitPrimeColPrimePtr + 1) += (xcmcb)
* (s->imag);
*(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm)
+ (-xcpi-xgm-xcmcb) * (s->real);
*(here->BJT2emitPrimeBasePrimePtr + 1) += (-xcpi-xgm-xcmcb)
* (s->imag);
*(here->BJT2substSubstPtr) += (xccs) * (s->real);
*(here->BJT2substSubstPtr + 1) += (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) += (-xcbx) * (s->real);
*(here->BJT2baseColPrimePtr + 1) += (-xcbx) * (s->imag);
*(here->BJT2colPrimeBasePtr) += (-xcbx) * (s->real);
*(here->BJT2colPrimeBasePtr + 1) += (-xcbx) * (s->imag);
}
}
return(OK);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,304 +1,322 @@
/**********
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(matrix,inModel,ckt,states)
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;
}
if(!model->BJT2subsGiven ||
(model->BJT2subs != VERTICAL && model->BJT2subs != LATERAL)) {
model->BJT2subs = VERTICAL;
}
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->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->BJT2areaGiven) {
here->BJT2area = 1;
}
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);*/
}
}
}
}
here->BJT2state = *states;
*states += BJT2numStates;
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){
*states += 8 * (ckt->CKTsenInfo->SENparms);
}
/* 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(inModel,ckt)
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;
}
/**********
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;
}
if(!model->BJT2subsGiven ||
(model->BJT2subs != VERTICAL && model->BJT2subs != LATERAL)) {
model->BJT2subs = VERTICAL;
}
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->BJT2areaGiven) {
here->BJT2area = 1;
}
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);*/
}
}
}
}
here->BJT2state = *states;
*states += BJT2numStates;
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){
*states += 8 * (ckt->CKTsenInfo->SENparms);
}
/* 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;
}

View File

@ -1,331 +1,329 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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(inModel,ckt)
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;
double DqbcDp;
double DqcsDp;
double DqbxDp;
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) {
#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->BJT2capcs;
*(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->BJT2qcs);
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->BJT2qcs);
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->BJT2dphicsdp) = 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->BJT2sensxpcs +
8*(iparmno - 1))
+ tag1 * *(ckt->CKTstate1 + here->BJT2sensxpcs +
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->BJT2capcs = *(SaveState0 + 25) ;
here->BJT2capbx = *(SaveState0 + 26) ;
}
}
info->SENstatus = NORMAL;
#ifdef SENSDEBUG
printf("BJT2senload end\n");
#endif /* SENSDEBUG */
return(OK);
}
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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;
double DqbcDp;
double DqcsDp;
double DqbxDp;
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) {
#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);
}

View File

@ -1,53 +1,50 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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(inModel,ckt)
CKTcircuit *ckt;
GENmodel *inModel;
{
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) {
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);
}
}
}
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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) {
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);
}
}
}

View File

@ -1,51 +1,49 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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(info,inModel)
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->BJT2senParmNo){
here->BJT2senParmNo = ++(info->SENparms);
here->BJT2senPertFlag = OFF;
}
if((here->BJT2sens = (double *)MALLOC(55*sizeof(double))) ==
NULL) return(E_NOMEM);
}
}
return(OK);
}
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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->BJT2senParmNo){
here->BJT2senParmNo = ++(info->SENparms);
here->BJT2senPertFlag = OFF;
}
if((here->BJT2sens = (double *)MALLOC(55*sizeof(double))) ==
NULL) return(E_NOMEM);
}
}
return(OK);
}

View File

@ -1,156 +1,154 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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(inModel,ckt)
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) {
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->BJT2capcs);
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->BJT2capcs ;
sxpbx = model ->BJT2type * (sb - scprm)*here->BJT2capbx ;
if(iparmno == here->BJT2senParmNo){
sxpbe += *(here->BJT2dphibedp);
sxpbc += *(here->BJT2dphibcdp);
sxpcs += *(here->BJT2dphicsdp);
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->BJT2sensxpcs + 8 * (iparmno - 1)) =
sxpcs;
NIintegrate(ckt,&dummy1,&dummy2,here->BJT2capcs,
here->BJT2sensxpcs + 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->BJT2sensxpcs + 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->BJT2sensxpcs + 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->BJT2sensxpcs + 8 * (iparmno - 1) +
1) = 0;
*(ckt->CKTstate1 + here->BJT2sensxpbx + 8 * (iparmno - 1) +
1) = 0;
}
}
}
}
#ifdef SENSDEBUG
printf("BJT2senUpdate end\n");
#endif /* SENSDEBUG */
return(OK);
}
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
Modified: Alan Gillespie
**********/
/* 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) {
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);
}

View File

@ -1,202 +1,224 @@
/**********
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(inModel,ckt)
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;
/* 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->BJT2tempGiven) here->BJT2temp = ckt->CKTtemp;
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;
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);
}
/**********
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->BJT2tempGiven) here->BJT2temp = ckt->CKTtemp;
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);
}

View File

@ -1,39 +1,36 @@
/**********
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(inModel,ckt,timeStep)
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){
CKTterr(here->BJT2qbe,ckt,timeStep);
CKTterr(here->BJT2qbc,ckt,timeStep);
CKTterr(here->BJT2qsub,ckt,timeStep);
}
}
return(OK);
}
/**********
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){
CKTterr(here->BJT2qbe,ckt,timeStep);
CKTterr(here->BJT2qbc,ckt,timeStep);
CKTterr(here->BJT2qsub,ckt,timeStep);
}
}
return(OK);
}