From a0514cfc309e1fdc2880a5d245a1a7f9716e6dec Mon Sep 17 00:00:00 2001 From: pnenzi Date: Thu, 25 Sep 2003 12:27:23 +0000 Subject: [PATCH] Dietmar's bjt2 code (temperature correction of resistors). --- src/spicelib/devices/bjt2/Makefile.am | 5 + src/spicelib/devices/bjt2/bjt2.c | 320 +-- src/spicelib/devices/bjt2/bjt2acld.c | 207 +- src/spicelib/devices/bjt2/bjt2ask.c | 582 ++-- src/spicelib/devices/bjt2/bjt2conv.c | 151 +- src/spicelib/devices/bjt2/bjt2defs.h | 1120 ++++---- src/spicelib/devices/bjt2/bjt2del.c | 82 +- src/spicelib/devices/bjt2/bjt2dest.c | 95 +- src/spicelib/devices/bjt2/bjt2disto.c | 3679 ++++++++++++------------- src/spicelib/devices/bjt2/bjt2dset.c | 1418 +++++----- src/spicelib/devices/bjt2/bjt2dset.h | 12 +- src/spicelib/devices/bjt2/bjt2ext.h | 70 +- src/spicelib/devices/bjt2/bjt2getic.c | 97 +- src/spicelib/devices/bjt2/bjt2init.c | 168 +- src/spicelib/devices/bjt2/bjt2init.h | 26 +- src/spicelib/devices/bjt2/bjt2itf.h | 22 +- src/spicelib/devices/bjt2/bjt2load.c | 1593 ++++++----- src/spicelib/devices/bjt2/bjt2mask.c | 438 +-- src/spicelib/devices/bjt2/bjt2mdel.c | 89 +- src/spicelib/devices/bjt2/bjt2mpar.c | 479 ++-- src/spicelib/devices/bjt2/bjt2noise.c | 457 ++- src/spicelib/devices/bjt2/bjt2param.c | 140 +- src/spicelib/devices/bjt2/bjt2pzld.c | 257 +- src/spicelib/devices/bjt2/bjt2sacl.c | 1423 +++++----- src/spicelib/devices/bjt2/bjt2setup.c | 626 +++-- src/spicelib/devices/bjt2/bjt2sload.c | 660 +++-- src/spicelib/devices/bjt2/bjt2sprt.c | 103 +- src/spicelib/devices/bjt2/bjt2sset.c | 100 +- src/spicelib/devices/bjt2/bjt2supd.c | 310 ++- src/spicelib/devices/bjt2/bjt2temp.c | 426 +-- src/spicelib/devices/bjt2/bjt2trun.c | 75 +- 31 files changed, 7639 insertions(+), 7591 deletions(-) diff --git a/src/spicelib/devices/bjt2/Makefile.am b/src/spicelib/devices/bjt2/Makefile.am index 36698bc1a..d128231db 100644 --- a/src/spicelib/devices/bjt2/Makefile.am +++ b/src/spicelib/devices/bjt2/Makefile.am @@ -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 diff --git a/src/spicelib/devices/bjt2/bjt2.c b/src/spicelib/devices/bjt2/bjt2.c index 6b4d6f3d7..407db82a3 100644 --- a/src/spicelib/devices/bjt2/bjt2.c +++ b/src/spicelib/devices/bjt2/bjt2.c @@ -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); diff --git a/src/spicelib/devices/bjt2/bjt2acld.c b/src/spicelib/devices/bjt2/bjt2acld.c index 9d8ee9d6b..8d03540fb 100644 --- a/src/spicelib/devices/bjt2/bjt2acld.c +++ b/src/spicelib/devices/bjt2/bjt2acld.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2ask.c b/src/spicelib/devices/bjt2/bjt2ask.c index f72bdbac7..eae103368 100644 --- a/src/spicelib/devices/bjt2/bjt2ask.c +++ b/src/spicelib/devices/bjt2/bjt2ask.c @@ -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 */ +} + diff --git a/src/spicelib/devices/bjt2/bjt2conv.c b/src/spicelib/devices/bjt2/bjt2conv.c index 5a0afa470..b62f8dbfd 100644 --- a/src/spicelib/devices/bjt2/bjt2conv.c +++ b/src/spicelib/devices/bjt2/bjt2conv.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2defs.h b/src/spicelib/devices/bjt2/bjt2defs.h index c76c71444..289c6f2f5 100644 --- a/src/spicelib/devices/bjt2/bjt2defs.h +++ b/src/spicelib/devices/bjt2/bjt2defs.h @@ -1,546 +1,574 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1985 Thomas L. Quarles -Modified: Alan Gillespie -**********/ - -#ifndef BJT2 -#define BJT2 - -#include "cktdefs.h" -#include "ifsim.h" -#include "gendefs.h" -#include "complex.h" -#include "noisedef.h" - -/* structures to describe Bipolar Junction Transistors */ - -/* data needed to describe a single instance */ - -typedef struct sBJT2instance { - struct sBJT2model *BJT2modPtr; /* backpointer to model */ - struct sBJT2instance *BJT2nextInstance; /* pointer to next instance of - * current model*/ - IFuid BJT2name; /* pointer to character string naming this instance */ - int BJT2owner; /* number of owner process */ - int BJT2state; /* pointer to start of state vector for bjt2 */ - - int BJT2colNode; /* number of collector node of bjt2 */ - int BJT2baseNode; /* number of base node of bjt2 */ - int BJT2emitNode; /* number of emitter node of bjt2 */ - int BJT2substNode; /* number of substrate node of bjt2 */ - int BJT2colPrimeNode; /* number of internal collector node of bjt2 */ - int BJT2basePrimeNode; /* number of internal base node of bjt2 */ - int BJT2emitPrimeNode; /* number of internal emitter node of bjt2 */ - int BJT2substConNode; /* number of node which substrate is connected to */ - /* Substrate connection is either base prime * - * or collector prime depending on whether * - * the device is VERTICAL or LATERAL */ - double BJT2area; /* area factor for the bjt2 */ - double BJT2icVBE; /* initial condition voltage B-E*/ - double BJT2icVCE; /* initial condition voltage C-E*/ - double BJT2temp; /* instance temperature */ - double BJT2tSatCur; /* temperature adjusted saturation current */ - double BJT2tSubSatCur; /* temperature adjusted subst. saturation current */ - double BJT2tBetaF; /* temperature adjusted forward beta */ - double BJT2tBetaR; /* temperature adjusted reverse beta */ - double BJT2tBEleakCur; /* temperature adjusted B-E leakage current */ - double BJT2tBCleakCur; /* temperature adjusted B-C leakage current */ - double BJT2tBEcap; /* temperature adjusted B-E capacitance */ - double BJT2tBEpot; /* temperature adjusted B-E potential */ - double BJT2tBCcap; /* temperature adjusted B-C capacitance */ - double BJT2tBCpot; /* temperature adjusted B-C potential */ - double BJT2tSubcap; /* temperature adjusted Substrate capacitance */ - double BJT2tSubpot; /* temperature adjusted Substrate potential */ - double BJT2tDepCap; /* temperature adjusted join point in diode curve */ - double BJT2tf1; /* temperature adjusted polynomial coefficient */ - double BJT2tf4; /* temperature adjusted polynomial coefficient */ - double BJT2tf5; /* temperature adjusted polynomial coefficient */ - double BJT2tVcrit; /* temperature adjusted critical voltage */ - double BJT2tSubVcrit; /* temperature adjusted substrate critical voltage */ - - double *BJT2colColPrimePtr; /* pointer to sparse matrix at - * (collector,collector prime) */ - double *BJT2baseBasePrimePtr; /* pointer to sparse matrix at - * (base,base prime) */ - double *BJT2emitEmitPrimePtr; /* pointer to sparse matrix at - * (emitter,emitter prime) */ - double *BJT2colPrimeColPtr; /* pointer to sparse matrix at - * (collector prime,collector) */ - double *BJT2colPrimeBasePrimePtr; /* pointer to sparse matrix at - * (collector prime,base prime) */ - double *BJT2colPrimeEmitPrimePtr; /* pointer to sparse matrix at - * (collector prime,emitter prime) */ - double *BJT2basePrimeBasePtr; /* pointer to sparse matrix at - * (base prime,base ) */ - double *BJT2basePrimeColPrimePtr; /* pointer to sparse matrix at - * (base prime,collector prime) */ - double *BJT2basePrimeEmitPrimePtr; /* pointer to sparse matrix at - * (base primt,emitter prime) */ - double *BJT2emitPrimeEmitPtr; /* pointer to sparse matrix at - * (emitter prime,emitter) */ - double *BJT2emitPrimeColPrimePtr; /* pointer to sparse matrix at - * (emitter prime,collector prime) */ - double *BJT2emitPrimeBasePrimePtr; /* pointer to sparse matrix at - * (emitter prime,base prime) */ - double *BJT2colColPtr; /* pointer to sparse matrix at - * (collector,collector) */ - double *BJT2baseBasePtr; /* pointer to sparse matrix at - * (base,base) */ - double *BJT2emitEmitPtr; /* pointer to sparse matrix at - * (emitter,emitter) */ - double *BJT2colPrimeColPrimePtr; /* pointer to sparse matrix at - * (collector prime,collector prime) */ - double *BJT2basePrimeBasePrimePtr; /* pointer to sparse matrix at - * (base prime,base prime) */ - double *BJT2emitPrimeEmitPrimePtr; /* pointer to sparse matrix at - * (emitter prime,emitter prime) */ - double *BJT2substSubstPtr; /* pointer to sparse matrix at - * (substrate,substrate) */ - double *BJT2substConSubstPtr; /* pointer to sparse matrix at - * (Substrate connection, substrate) */ - double *BJT2substSubstConPtr; /* pointer to sparse matrix at - * (substrate, Substrate connection) */ - double *BJT2substConSubstConPtr; /* pointer to sparse matrix at - * (Substrate connection, Substrate connection) */ - /* Substrate connection is either base prime * - * or collector prime depending on whether * - * the device is VERTICAL or LATERAL */ - double *BJT2baseColPrimePtr; /* pointer to sparse matrix at - * (base,collector prime) */ - double *BJT2colPrimeBasePtr; /* pointer to sparse matrix at - * (collector prime,base) */ - - unsigned BJT2off :1; /* 'off' flag for bjt2 */ - unsigned BJT2tempGiven :1; /* temperature given for bjt2 instance*/ - unsigned BJT2areaGiven :1; /* flag to indicate area was specified */ - unsigned BJT2icVBEGiven :1; /* flag to indicate VBE init. cond. given */ - unsigned BJT2icVCEGiven :1; /* flag to indicate VCE init. cond. given */ - unsigned BJT2senPertFlag :1; /* indictes whether the the parameter of - the particular instance is to be perturbed */ - - int BJT2senParmNo; /* parameter # for sensitivity use; - set equal to 0 if not a design parameter*/ - double BJT2capbe; - double BJT2capbc; - double BJT2capsub; - double BJT2capbx; - double *BJT2sens; - -#define BJT2senGpi BJT2sens /* stores the perturbed values of gpi */ -#define BJT2senGmu BJT2sens+5 /* stores the perturbed values of gmu */ -#define BJT2senGm BJT2sens+10 /* stores the perturbed values of gm */ -#define BJT2senGo BJT2sens+15 /* stores the perturbed values of go */ -#define BJT2senGx BJT2sens+20 /* stores the perturbed values of gx */ -#define BJT2senCpi BJT2sens+25 /* stores the perturbed values of cpi */ -#define BJT2senCmu BJT2sens+30 /* stores the perturbed values of cmu */ -#define BJT2senCbx BJT2sens+35 /* stores the perturbed values of cbx */ -#define BJT2senCmcb BJT2sens+40 /* stores the perturbed values of cmcb */ -#define BJT2senCsub BJT2sens+45 /* stores the perturbed values of csub */ -#define BJT2dphibedp BJT2sens+51 -#define BJT2dphibcdp BJT2sens+52 -#define BJT2dphisubdp BJT2sens+53 -#define BJT2dphibxdp BJT2sens+54 - -/* - * distortion stuff - * the following naming convention is used: - * x = vbe - * y = vbc - * z = vbb - * w = vbed (vbe delayed for the linear gm delay) - * therefore ic_xyz stands for the coefficient of the vbe*vbc*vbb - * term in the multidimensional Taylor expansion for ic; and ibb_x2y - * for the coeff. of the vbe*vbe*vbc term in the ibb expansion. - */ - -#define BJT2NDCOEFFS 65 - -#ifndef NODISTO - double BJT2dCoeffs[BJT2NDCOEFFS]; -#else /* NODISTO */ - double *BJT2dCoeffs; -#endif /* NODISTO */ - -#ifndef CONFIG - -#define ic_x BJT2dCoeffs[0] -#define ic_y BJT2dCoeffs[1] -#define ic_xd BJT2dCoeffs[2] -#define ic_x2 BJT2dCoeffs[3] -#define ic_y2 BJT2dCoeffs[4] -#define ic_w2 BJT2dCoeffs[5] -#define ic_xy BJT2dCoeffs[6] -#define ic_yw BJT2dCoeffs[7] -#define ic_xw BJT2dCoeffs[8] -#define ic_x3 BJT2dCoeffs[9] -#define ic_y3 BJT2dCoeffs[10] -#define ic_w3 BJT2dCoeffs[11] -#define ic_x2w BJT2dCoeffs[12] -#define ic_x2y BJT2dCoeffs[13] -#define ic_y2w BJT2dCoeffs[14] -#define ic_xy2 BJT2dCoeffs[15] -#define ic_xw2 BJT2dCoeffs[16] -#define ic_yw2 BJT2dCoeffs[17] -#define ic_xyw BJT2dCoeffs[18] - -#define ib_x BJT2dCoeffs[19] -#define ib_y BJT2dCoeffs[20] -#define ib_x2 BJT2dCoeffs[21] -#define ib_y2 BJT2dCoeffs[22] -#define ib_xy BJT2dCoeffs[23] -#define ib_x3 BJT2dCoeffs[24] -#define ib_y3 BJT2dCoeffs[25] -#define ib_x2y BJT2dCoeffs[26] -#define ib_xy2 BJT2dCoeffs[27] - -#define ibb_x BJT2dCoeffs[28] -#define ibb_y BJT2dCoeffs[29] -#define ibb_z BJT2dCoeffs[30] -#define ibb_x2 BJT2dCoeffs[31] -#define ibb_y2 BJT2dCoeffs[32] -#define ibb_z2 BJT2dCoeffs[33] -#define ibb_xy BJT2dCoeffs[34] -#define ibb_yz BJT2dCoeffs[35] -#define ibb_xz BJT2dCoeffs[36] -#define ibb_x3 BJT2dCoeffs[37] -#define ibb_y3 BJT2dCoeffs[38] -#define ibb_z3 BJT2dCoeffs[39] -#define ibb_x2z BJT2dCoeffs[40] -#define ibb_x2y BJT2dCoeffs[41] -#define ibb_y2z BJT2dCoeffs[42] -#define ibb_xy2 BJT2dCoeffs[43] -#define ibb_xz2 BJT2dCoeffs[44] -#define ibb_yz2 BJT2dCoeffs[45] -#define ibb_xyz BJT2dCoeffs[46] - -#define qbe_x BJT2dCoeffs[47] -#define qbe_y BJT2dCoeffs[48] -#define qbe_x2 BJT2dCoeffs[49] -#define qbe_y2 BJT2dCoeffs[50] -#define qbe_xy BJT2dCoeffs[51] -#define qbe_x3 BJT2dCoeffs[52] -#define qbe_y3 BJT2dCoeffs[53] -#define qbe_x2y BJT2dCoeffs[54] -#define qbe_xy2 BJT2dCoeffs[55] - -#define capbc1 BJT2dCoeffs[56] -#define capbc2 BJT2dCoeffs[57] -#define capbc3 BJT2dCoeffs[58] - -#define capbx1 BJT2dCoeffs[59] -#define capbx2 BJT2dCoeffs[60] -#define capbx3 BJT2dCoeffs[61] - -#define capsc1 BJT2dCoeffs[62] -#define capsc2 BJT2dCoeffs[63] -#define capsc3 BJT2dCoeffs[64] - -#endif - -/* indices to array of BJT2 noise sources */ - -#define BJT2RCNOIZ 0 -#define BJT2RBNOIZ 1 -#define BJT2_RE_NOISE 2 -#define BJT2ICNOIZ 3 -#define BJT2IBNOIZ 4 -#define BJT2FLNOIZ 5 -#define BJT2TOTNOIZ 6 - -#define BJT2NSRCS 7 /* the number of BJT2 noise sources */ - -#ifndef NONOISE - double BJT2nVar[NSTATVARS][BJT2NSRCS]; -#else /*NONOISE*/ - double **BJT2nVar; -#endif /*NONOISE*/ -/* the above to avoid allocating memory when it is not needed */ - -} BJT2instance ; - -/* entries in the state vector for bjt2: */ -#define BJT2vbe BJT2state -#define BJT2vbc BJT2state+1 -#define BJT2cc BJT2state+2 -#define BJT2cb BJT2state+3 -#define BJT2gpi BJT2state+4 -#define BJT2gmu BJT2state+5 -#define BJT2gm BJT2state+6 -#define BJT2go BJT2state+7 -#define BJT2qbe BJT2state+8 -#define BJT2cqbe BJT2state+9 -#define BJT2qbc BJT2state+10 -#define BJT2cqbc BJT2state+11 -#define BJT2qsub BJT2state+12 -#define BJT2cqsub BJT2state+13 -#define BJT2qbx BJT2state+14 -#define BJT2cqbx BJT2state+15 -#define BJT2gx BJT2state+16 -#define BJT2cexbc BJT2state+17 -#define BJT2geqcb BJT2state+18 -#define BJT2gcsub BJT2state+19 -#define BJT2geqbx BJT2state+20 -#define BJT2vsub BJT2state+21 -#define BJT2cdsub BJT2state+22 -#define BJT2gdsub BJT2state+23 -#define BJT2numStates 24 - -#define BJT2sensxpbe BJT2state+24 /* charge sensitivities and their - derivatives. +25 for the derivatives - - pointer to the beginning of the array */ -#define BJT2sensxpbc BJT2state+26 -#define BJT2sensxpsub BJT2state+28 -#define BJT2sensxpbx BJT2state+30 - -#define BJT2numSenStates 8 - - -/* per model data */ -typedef struct sBJT2model { /* model structure for a bjt2 */ - int BJT2modType; /* type index of this device type */ - struct sBJT2model *BJT2nextModel; /* pointer to next possible model in - * linked list */ - BJT2instance * BJT2instances; /* pointer to list of instances - * that have this model */ - IFuid BJT2modName; /* pointer to character string naming this model */ - int BJT2type; - - - int BJT2subs; - double BJT2tnom; /* nominal temperature */ - double BJT2satCur; /* input - don't use */ - double BJT2subSatCur; /* input - don't use */ - double BJT2betaF; /* input - don't use */ - double BJT2emissionCoeffF; - double BJT2earlyVoltF; - double BJT2rollOffF; - double BJT2leakBEcurrent; /* input - don't use */ - double BJT2c2; - double BJT2leakBEemissionCoeff; - double BJT2betaR; /* input - don't use */ - double BJT2emissionCoeffR; - double BJT2earlyVoltR; - double BJT2rollOffR; - double BJT2leakBCcurrent; /* input - don't use */ - double BJT2c4; - double BJT2leakBCemissionCoeff; - double BJT2baseResist; - double BJT2baseCurrentHalfResist; - double BJT2minBaseResist; - double BJT2emitterResist; - double BJT2collectorResist; - double BJT2depletionCapBE; /* input - don't use */ - double BJT2potentialBE; /* input - don't use */ - double BJT2junctionExpBE; - double BJT2transitTimeF; - double BJT2transitTimeBiasCoeffF; - double BJT2transitTimeFVBC; - double BJT2transitTimeHighCurrentF; - double BJT2excessPhase; - double BJT2depletionCapBC; /* input - don't use */ - double BJT2potentialBC; /* input - don't use */ - double BJT2junctionExpBC; - double BJT2baseFractionBCcap; - double BJT2transitTimeR; - double BJT2capSub; - double BJT2potentialSubstrate; - double BJT2exponentialSubstrate; - double BJT2betaExp; - double BJT2energyGap; - double BJT2tempExpIS; - double BJT2depletionCapCoeff; - double BJT2fNcoef; - double BJT2fNexp; - - double BJT2invEarlyVoltF; /* inverse of BJT2earlyVoltF */ - double BJT2invEarlyVoltR; /* inverse of BJT2earlyVoltR */ - double BJT2invRollOffF; /* inverse of BJT2rollOffF */ - double BJT2invRollOffR; /* inverse of BJT2rollOffR */ - double BJT2collectorConduct; /* collector conductance */ - double BJT2emitterConduct; /* emitter conductance */ - double BJT2transitTimeVBCFactor; /* */ - double BJT2excessPhaseFactor; - double BJT2f2; - double BJT2f3; - double BJT2f6; - double BJT2f7; - - unsigned BJT2subsGiven : 1; - unsigned BJT2tnomGiven : 1; - unsigned BJT2satCurGiven : 1; - unsigned BJT2subSatCurGiven : 1; - unsigned BJT2betaFGiven : 1; - unsigned BJT2emissionCoeffFGiven : 1; - unsigned BJT2earlyVoltFGiven : 1; - unsigned BJT2rollOffFGiven : 1; - unsigned BJT2leakBEcurrentGiven : 1; - unsigned BJT2c2Given : 1; - unsigned BJT2leakBEemissionCoeffGiven : 1; - unsigned BJT2betaRGiven : 1; - unsigned BJT2emissionCoeffRGiven : 1; - unsigned BJT2earlyVoltRGiven : 1; - unsigned BJT2rollOffRGiven : 1; - unsigned BJT2leakBCcurrentGiven : 1; - unsigned BJT2c4Given : 1; - unsigned BJT2leakBCemissionCoeffGiven : 1; - unsigned BJT2baseResistGiven : 1; - unsigned BJT2baseCurrentHalfResistGiven : 1; - unsigned BJT2minBaseResistGiven : 1; - unsigned BJT2emitterResistGiven : 1; - unsigned BJT2collectorResistGiven : 1; - unsigned BJT2depletionCapBEGiven : 1; - unsigned BJT2potentialBEGiven : 1; - unsigned BJT2junctionExpBEGiven : 1; - unsigned BJT2transitTimeFGiven : 1; - unsigned BJT2transitTimeBiasCoeffFGiven : 1; - unsigned BJT2transitTimeFVBCGiven : 1; - unsigned BJT2transitTimeHighCurrentFGiven : 1; - unsigned BJT2excessPhaseGiven : 1; - unsigned BJT2depletionCapBCGiven : 1; - unsigned BJT2potentialBCGiven : 1; - unsigned BJT2junctionExpBCGiven : 1; - unsigned BJT2baseFractionBCcapGiven : 1; - unsigned BJT2transitTimeRGiven : 1; - unsigned BJT2capSubGiven : 1; - unsigned BJT2potentialSubstrateGiven : 1; - unsigned BJT2exponentialSubstrateGiven : 1; - unsigned BJT2betaExpGiven : 1; - unsigned BJT2energyGapGiven : 1; - unsigned BJT2tempExpISGiven : 1; - unsigned BJT2depletionCapCoeffGiven : 1; - unsigned BJT2fNcoefGiven : 1; - unsigned BJT2fNexpGiven :1; -} BJT2model; - -#ifndef NPN -#define NPN 1 -#define PNP -1 -#endif /*NPN*/ - - -#ifndef VERTICAL -#define VERTICAL 1 -#define LATERAL -1 -#endif /* VERTICAL */ - - -/* device parameters */ -#define BJT2_AREA 1 -#define BJT2_OFF 2 -#define BJT2_IC_VBE 3 -#define BJT2_IC_VCE 4 -#define BJT2_IC 5 -#define BJT2_AREA_SENS 6 -#define BJT2_TEMP 7 - -/* model parameters */ -#define BJT2_MOD_NPN 101 -#define BJT2_MOD_PNP 102 -#define BJT2_MOD_IS 103 -#define BJT2_MOD_ISS 146 -#define BJT2_MOD_BF 104 -#define BJT2_MOD_NF 105 -#define BJT2_MOD_VAF 106 -#define BJT2_MOD_IKF 107 -#define BJT2_MOD_ISE 108 -#define BJT2_MOD_C2 109 -#define BJT2_MOD_NE 110 -#define BJT2_MOD_BR 111 -#define BJT2_MOD_NR 112 -#define BJT2_MOD_VAR 113 -#define BJT2_MOD_IKR 114 -#define BJT2_MOD_ISC 115 -#define BJT2_MOD_C4 116 -#define BJT2_MOD_NC 117 -#define BJT2_MOD_RB 118 -#define BJT2_MOD_IRB 119 -#define BJT2_MOD_RBM 120 -#define BJT2_MOD_RE 121 -#define BJT2_MOD_RC 122 -#define BJT2_MOD_CJE 123 -#define BJT2_MOD_VJE 124 -#define BJT2_MOD_MJE 125 -#define BJT2_MOD_TF 126 -#define BJT2_MOD_XTF 127 -#define BJT2_MOD_VTF 128 -#define BJT2_MOD_ITF 129 -#define BJT2_MOD_PTF 130 -#define BJT2_MOD_CJC 131 -#define BJT2_MOD_VJC 132 -#define BJT2_MOD_MJC 133 -#define BJT2_MOD_XCJC 134 -#define BJT2_MOD_TR 135 -#define BJT2_MOD_CJS 136 -#define BJT2_MOD_VJS 137 -#define BJT2_MOD_MJS 138 -#define BJT2_MOD_XTB 139 -#define BJT2_MOD_EG 140 -#define BJT2_MOD_XTI 141 -#define BJT2_MOD_FC 142 -#define BJT2_MOD_TNOM 143 -#define BJT2_MOD_AF 144 -#define BJT2_MOD_KF 145 -#define BJT2_MOD_SUBS 147 - - -/* device questions */ -#define BJT2_QUEST_FT 201 -#define BJT2_QUEST_COLNODE 202 -#define BJT2_QUEST_BASENODE 203 -#define BJT2_QUEST_EMITNODE 204 -#define BJT2_QUEST_SUBSTNODE 205 -#define BJT2_QUEST_COLPRIMENODE 206 -#define BJT2_QUEST_BASEPRIMENODE 207 -#define BJT2_QUEST_EMITPRIMENODE 208 -#define BJT2_QUEST_VBE 209 -#define BJT2_QUEST_VBC 210 -#define BJT2_QUEST_CC 211 -#define BJT2_QUEST_CB 212 -#define BJT2_QUEST_GPI 213 -#define BJT2_QUEST_GMU 214 -#define BJT2_QUEST_GM 215 -#define BJT2_QUEST_GO 216 -#define BJT2_QUEST_QBE 217 -#define BJT2_QUEST_CQBE 218 -#define BJT2_QUEST_QBC 219 -#define BJT2_QUEST_CQBC 220 -#define BJT2_QUEST_QSUB 221 -#define BJT2_QUEST_CQSUB 222 -#define BJT2_QUEST_QBX 223 -#define BJT2_QUEST_CQBX 224 -#define BJT2_QUEST_GX 225 -#define BJT2_QUEST_CEXBC 226 -#define BJT2_QUEST_GEQCB 227 -#define BJT2_QUEST_GCSUB 228 -#define BJT2_QUEST_GDSUB 243 -#define BJT2_QUEST_GEQBX 229 -#define BJT2_QUEST_SENS_REAL 230 -#define BJT2_QUEST_SENS_IMAG 231 -#define BJT2_QUEST_SENS_MAG 232 -#define BJT2_QUEST_SENS_PH 233 -#define BJT2_QUEST_SENS_CPLX 234 -#define BJT2_QUEST_SENS_DC 235 -#define BJT2_QUEST_CE 236 -#define BJT2_QUEST_CS 237 -#define BJT2_QUEST_POWER 238 - -#define BJT2_QUEST_CPI 239 -#define BJT2_QUEST_CMU 240 -#define BJT2_QUEST_CBX 241 -#define BJT2_QUEST_CSUB 242 - -/* model questions */ -#define BJT2_MOD_INVEARLYF 301 -#define BJT2_MOD_INVEARLYR 302 -#define BJT2_MOD_INVROLLOFFF 303 -#define BJT2_MOD_INVROLLOFFR 304 -#define BJT2_MOD_COLCONDUCT 305 -#define BJT2_MOD_EMITTERCONDUCT 306 -#define BJT2_MOD_TRANSVBCFACT 307 -#define BJT2_MOD_EXCESSPHASEFACTOR 308 -#define BJT2_MOD_TYPE 309 -#define BJT2_MOD_QUEST_SUBS 310 - -#include "bjt2ext.h" -#endif /*BJT2*/ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +#ifndef BJT2 +#define BJT2 + +#include "cktdefs.h" +#include "ifsim.h" +#include "gendefs.h" +#include "complex.h" +#include "noisedef.h" + +/* structures to describe Bipolar Junction Transistors */ + +/* data needed to describe a single instance */ + +typedef struct sBJT2instance { + struct sBJT2model *BJT2modPtr; /* backpointer to model */ + struct sBJT2instance *BJT2nextInstance; /* pointer to next instance of + * current model*/ + IFuid BJT2name; /* pointer to character string naming this instance */ + int BJT2owner; /* number of owner process */ + int BJT2state; /* pointer to start of state vector for bjt2 */ + + int BJT2colNode; /* number of collector node of bjt2 */ + int BJT2baseNode; /* number of base node of bjt2 */ + int BJT2emitNode; /* number of emitter node of bjt2 */ + int BJT2substNode; /* number of substrate node of bjt2 */ + int BJT2colPrimeNode; /* number of internal collector node of bjt2 */ + int BJT2basePrimeNode; /* number of internal base node of bjt2 */ + int BJT2emitPrimeNode; /* number of internal emitter node of bjt2 */ + int BJT2substConNode; /* number of node which substrate is connected to */ + /* Substrate connection is either base prime * + * or collector prime depending on whether * + * the device is VERTICAL or LATERAL */ + double BJT2area; /* area factor for the bjt2 */ + double BJT2icVBE; /* initial condition voltage B-E*/ + double BJT2icVCE; /* initial condition voltage C-E*/ + double BJT2temp; /* instance temperature */ + double BJT2tSatCur; /* temperature adjusted saturation current */ + double BJT2tSubSatCur; /* temperature adjusted subst. saturation current */ + double BJT2tEmitterConduct; /* emitter conductance */ + double BJT2tCollectorConduct; /* collector conductance */ + double BJT2tBaseResist; /* temperature adjusted base resistance */ + double BJT2tMinBaseResist; /* temperature adjusted base resistance */ + double BJT2tBetaF; /* temperature adjusted forward beta */ + double BJT2tBetaR; /* temperature adjusted reverse beta */ + double BJT2tBEleakCur; /* temperature adjusted B-E leakage current */ + double BJT2tBCleakCur; /* temperature adjusted B-C leakage current */ + double BJT2tBEcap; /* temperature adjusted B-E capacitance */ + double BJT2tBEpot; /* temperature adjusted B-E potential */ + double BJT2tBCcap; /* temperature adjusted B-C capacitance */ + double BJT2tBCpot; /* temperature adjusted B-C potential */ + double BJT2tSubcap; /* temperature adjusted Substrate capacitance */ + double BJT2tSubpot; /* temperature adjusted Substrate potential */ + double BJT2tDepCap; /* temperature adjusted join point in diode curve */ + double BJT2tf1; /* temperature adjusted polynomial coefficient */ + double BJT2tf4; /* temperature adjusted polynomial coefficient */ + double BJT2tf5; /* temperature adjusted polynomial coefficient */ + double BJT2tVcrit; /* temperature adjusted critical voltage */ + double BJT2tSubVcrit; /* temperature adjusted substrate critical voltage */ + + double *BJT2colColPrimePtr; /* pointer to sparse matrix at + * (collector,collector prime) */ + double *BJT2baseBasePrimePtr; /* pointer to sparse matrix at + * (base,base prime) */ + double *BJT2emitEmitPrimePtr; /* pointer to sparse matrix at + * (emitter,emitter prime) */ + double *BJT2colPrimeColPtr; /* pointer to sparse matrix at + * (collector prime,collector) */ + double *BJT2colPrimeBasePrimePtr; /* pointer to sparse matrix at + * (collector prime,base prime) */ + double *BJT2colPrimeEmitPrimePtr; /* pointer to sparse matrix at + * (collector prime,emitter prime) */ + double *BJT2basePrimeBasePtr; /* pointer to sparse matrix at + * (base prime,base ) */ + double *BJT2basePrimeColPrimePtr; /* pointer to sparse matrix at + * (base prime,collector prime) */ + double *BJT2basePrimeEmitPrimePtr; /* pointer to sparse matrix at + * (base primt,emitter prime) */ + double *BJT2emitPrimeEmitPtr; /* pointer to sparse matrix at + * (emitter prime,emitter) */ + double *BJT2emitPrimeColPrimePtr; /* pointer to sparse matrix at + * (emitter prime,collector prime) */ + double *BJT2emitPrimeBasePrimePtr; /* pointer to sparse matrix at + * (emitter prime,base prime) */ + double *BJT2colColPtr; /* pointer to sparse matrix at + * (collector,collector) */ + double *BJT2baseBasePtr; /* pointer to sparse matrix at + * (base,base) */ + double *BJT2emitEmitPtr; /* pointer to sparse matrix at + * (emitter,emitter) */ + double *BJT2colPrimeColPrimePtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *BJT2basePrimeBasePrimePtr; /* pointer to sparse matrix at + * (base prime,base prime) */ + double *BJT2emitPrimeEmitPrimePtr; /* pointer to sparse matrix at + * (emitter prime,emitter prime) */ + double *BJT2substSubstPtr; /* pointer to sparse matrix at + * (substrate,substrate) */ + double *BJT2substConSubstPtr; /* pointer to sparse matrix at + * (Substrate connection, substrate) */ + double *BJT2substSubstConPtr; /* pointer to sparse matrix at + * (substrate, Substrate connection) */ + double *BJT2substConSubstConPtr; /* pointer to sparse matrix at + * (Substrate connection, Substrate connection) */ + /* Substrate connection is either base prime * + * or collector prime depending on whether * + * the device is VERTICAL or LATERAL */ + double *BJT2baseColPrimePtr; /* pointer to sparse matrix at + * (base,collector prime) */ + double *BJT2colPrimeBasePtr; /* pointer to sparse matrix at + * (collector prime,base) */ + + unsigned BJT2off :1; /* 'off' flag for bjt2 */ + unsigned BJT2tempGiven :1; /* temperature given for bjt2 instance*/ + unsigned BJT2areaGiven :1; /* flag to indicate area was specified */ + unsigned BJT2icVBEGiven :1; /* flag to indicate VBE init. cond. given */ + unsigned BJT2icVCEGiven :1; /* flag to indicate VCE init. cond. given */ + unsigned BJT2senPertFlag :1; /* indictes whether the the parameter of + the particular instance is to be perturbed */ + + int BJT2senParmNo; /* parameter # for sensitivity use; + set equal to 0 if not a design parameter*/ + double BJT2capbe; + double BJT2capbc; + double BJT2capsub; + double BJT2capbx; + double *BJT2sens; + +#define BJT2senGpi BJT2sens /* stores the perturbed values of gpi */ +#define BJT2senGmu BJT2sens+5 /* stores the perturbed values of gmu */ +#define BJT2senGm BJT2sens+10 /* stores the perturbed values of gm */ +#define BJT2senGo BJT2sens+15 /* stores the perturbed values of go */ +#define BJT2senGx BJT2sens+20 /* stores the perturbed values of gx */ +#define BJT2senCpi BJT2sens+25 /* stores the perturbed values of cpi */ +#define BJT2senCmu BJT2sens+30 /* stores the perturbed values of cmu */ +#define BJT2senCbx BJT2sens+35 /* stores the perturbed values of cbx */ +#define BJT2senCmcb BJT2sens+40 /* stores the perturbed values of cmcb */ +#define BJT2senCsub BJT2sens+45 /* stores the perturbed values of csub */ +#define BJT2dphibedp BJT2sens+51 +#define BJT2dphibcdp BJT2sens+52 +#define BJT2dphisubdp BJT2sens+53 +#define BJT2dphibxdp BJT2sens+54 + +/* + * distortion stuff + * the following naming convention is used: + * x = vbe + * y = vbc + * z = vbb + * w = vbed (vbe delayed for the linear gm delay) + * therefore ic_xyz stands for the coefficient of the vbe*vbc*vbb + * term in the multidimensional Taylor expansion for ic; and ibb_x2y + * for the coeff. of the vbe*vbe*vbc term in the ibb expansion. + */ + +#define BJT2NDCOEFFS 65 + +#ifndef NODISTO + double BJT2dCoeffs[BJT2NDCOEFFS]; +#else /* NODISTO */ + double *BJT2dCoeffs; +#endif /* NODISTO */ + +#ifndef CONFIG + +#define ic_x BJT2dCoeffs[0] +#define ic_y BJT2dCoeffs[1] +#define ic_xd BJT2dCoeffs[2] +#define ic_x2 BJT2dCoeffs[3] +#define ic_y2 BJT2dCoeffs[4] +#define ic_w2 BJT2dCoeffs[5] +#define ic_xy BJT2dCoeffs[6] +#define ic_yw BJT2dCoeffs[7] +#define ic_xw BJT2dCoeffs[8] +#define ic_x3 BJT2dCoeffs[9] +#define ic_y3 BJT2dCoeffs[10] +#define ic_w3 BJT2dCoeffs[11] +#define ic_x2w BJT2dCoeffs[12] +#define ic_x2y BJT2dCoeffs[13] +#define ic_y2w BJT2dCoeffs[14] +#define ic_xy2 BJT2dCoeffs[15] +#define ic_xw2 BJT2dCoeffs[16] +#define ic_yw2 BJT2dCoeffs[17] +#define ic_xyw BJT2dCoeffs[18] + +#define ib_x BJT2dCoeffs[19] +#define ib_y BJT2dCoeffs[20] +#define ib_x2 BJT2dCoeffs[21] +#define ib_y2 BJT2dCoeffs[22] +#define ib_xy BJT2dCoeffs[23] +#define ib_x3 BJT2dCoeffs[24] +#define ib_y3 BJT2dCoeffs[25] +#define ib_x2y BJT2dCoeffs[26] +#define ib_xy2 BJT2dCoeffs[27] + +#define ibb_x BJT2dCoeffs[28] +#define ibb_y BJT2dCoeffs[29] +#define ibb_z BJT2dCoeffs[30] +#define ibb_x2 BJT2dCoeffs[31] +#define ibb_y2 BJT2dCoeffs[32] +#define ibb_z2 BJT2dCoeffs[33] +#define ibb_xy BJT2dCoeffs[34] +#define ibb_yz BJT2dCoeffs[35] +#define ibb_xz BJT2dCoeffs[36] +#define ibb_x3 BJT2dCoeffs[37] +#define ibb_y3 BJT2dCoeffs[38] +#define ibb_z3 BJT2dCoeffs[39] +#define ibb_x2z BJT2dCoeffs[40] +#define ibb_x2y BJT2dCoeffs[41] +#define ibb_y2z BJT2dCoeffs[42] +#define ibb_xy2 BJT2dCoeffs[43] +#define ibb_xz2 BJT2dCoeffs[44] +#define ibb_yz2 BJT2dCoeffs[45] +#define ibb_xyz BJT2dCoeffs[46] + +#define qbe_x BJT2dCoeffs[47] +#define qbe_y BJT2dCoeffs[48] +#define qbe_x2 BJT2dCoeffs[49] +#define qbe_y2 BJT2dCoeffs[50] +#define qbe_xy BJT2dCoeffs[51] +#define qbe_x3 BJT2dCoeffs[52] +#define qbe_y3 BJT2dCoeffs[53] +#define qbe_x2y BJT2dCoeffs[54] +#define qbe_xy2 BJT2dCoeffs[55] + +#define capbc1 BJT2dCoeffs[56] +#define capbc2 BJT2dCoeffs[57] +#define capbc3 BJT2dCoeffs[58] + +#define capbx1 BJT2dCoeffs[59] +#define capbx2 BJT2dCoeffs[60] +#define capbx3 BJT2dCoeffs[61] + +#define capsc1 BJT2dCoeffs[62] +#define capsc2 BJT2dCoeffs[63] +#define capsc3 BJT2dCoeffs[64] + +#endif + +/* indices to array of BJT2 noise sources */ + +#define BJT2RCNOIZ 0 +#define BJT2RBNOIZ 1 +#define BJT2_RE_NOISE 2 +#define BJT2ICNOIZ 3 +#define BJT2IBNOIZ 4 +#define BJT2FLNOIZ 5 +#define BJT2TOTNOIZ 6 + +#define BJT2NSRCS 7 /* the number of BJT2 noise sources */ + +#ifndef NONOISE + double BJT2nVar[NSTATVARS][BJT2NSRCS]; +#else /*NONOISE*/ + double **BJT2nVar; +#endif /*NONOISE*/ +/* the above to avoid allocating memory when it is not needed */ + +} BJT2instance ; + +/* entries in the state vector for bjt2: */ +#define BJT2vbe BJT2state +#define BJT2vbc BJT2state+1 +#define BJT2cc BJT2state+2 +#define BJT2cb BJT2state+3 +#define BJT2gpi BJT2state+4 +#define BJT2gmu BJT2state+5 +#define BJT2gm BJT2state+6 +#define BJT2go BJT2state+7 +#define BJT2qbe BJT2state+8 +#define BJT2cqbe BJT2state+9 +#define BJT2qbc BJT2state+10 +#define BJT2cqbc BJT2state+11 +#define BJT2qsub BJT2state+12 +#define BJT2cqsub BJT2state+13 +#define BJT2qbx BJT2state+14 +#define BJT2cqbx BJT2state+15 +#define BJT2gx BJT2state+16 +#define BJT2cexbc BJT2state+17 +#define BJT2geqcb BJT2state+18 +#define BJT2gcsub BJT2state+19 +#define BJT2geqbx BJT2state+20 +#define BJT2vsub BJT2state+21 +#define BJT2cdsub BJT2state+22 +#define BJT2gdsub BJT2state+23 +#define BJT2numStates 24 + +#define BJT2sensxpbe BJT2state+24 /* charge sensitivities and their + derivatives. +25 for the derivatives - + pointer to the beginning of the array */ +#define BJT2sensxpbc BJT2state+26 +#define BJT2sensxpsub BJT2state+28 +#define BJT2sensxpbx BJT2state+30 + +#define BJT2numSenStates 8 + + +/* per model data */ +typedef struct sBJT2model { /* model structure for a bjt2 */ + int BJT2modType; /* type index of this device type */ + struct sBJT2model *BJT2nextModel; /* pointer to next possible model in + * linked list */ + BJT2instance * BJT2instances; /* pointer to list of instances + * that have this model */ + IFuid BJT2modName; /* pointer to character string naming this model */ + int BJT2type; + + + int BJT2subs; + double BJT2tnom; /* nominal temperature */ + double BJT2satCur; /* input - don't use */ + double BJT2subSatCur; /* input - don't use */ + double BJT2betaF; /* input - don't use */ + double BJT2emissionCoeffF; + double BJT2earlyVoltF; + double BJT2rollOffF; + double BJT2leakBEcurrent; /* input - don't use */ + double BJT2c2; + double BJT2leakBEemissionCoeff; + double BJT2betaR; /* input - don't use */ + double BJT2emissionCoeffR; + double BJT2earlyVoltR; + double BJT2rollOffR; + double BJT2leakBCcurrent; /* input - don't use */ + double BJT2c4; + double BJT2leakBCemissionCoeff; + double BJT2baseResist; + double BJT2baseCurrentHalfResist; + double BJT2minBaseResist; + double BJT2emitterResist; + double BJT2collectorResist; + double BJT2depletionCapBE; /* input - don't use */ + double BJT2potentialBE; /* input - don't use */ + double BJT2junctionExpBE; + double BJT2transitTimeF; + double BJT2transitTimeBiasCoeffF; + double BJT2transitTimeFVBC; + double BJT2transitTimeHighCurrentF; + double BJT2excessPhase; + double BJT2depletionCapBC; /* input - don't use */ + double BJT2potentialBC; /* input - don't use */ + double BJT2junctionExpBC; + double BJT2baseFractionBCcap; + double BJT2transitTimeR; + double BJT2capSub; + double BJT2potentialSubstrate; + double BJT2exponentialSubstrate; + double BJT2betaExp; + double BJT2energyGap; + double BJT2tempExpIS; + double BJT2reTempCoeff1; + double BJT2reTempCoeff2; + double BJT2rcTempCoeff1; + double BJT2rcTempCoeff2; + double BJT2rbTempCoeff1; + double BJT2rbTempCoeff2; + double BJT2rbmTempCoeff1; + double BJT2rbmTempCoeff2; + double BJT2depletionCapCoeff; + double BJT2fNcoef; + double BJT2fNexp; + + double BJT2invEarlyVoltF; /* inverse of BJT2earlyVoltF */ + double BJT2invEarlyVoltR; /* inverse of BJT2earlyVoltR */ + double BJT2invRollOffF; /* inverse of BJT2rollOffF */ + double BJT2invRollOffR; /* inverse of BJT2rollOffR */ + double BJT2collectorConduct; /* collector conductance */ + double BJT2emitterConduct; /* emitter conductance */ + double BJT2transitTimeVBCFactor; /* */ + double BJT2excessPhaseFactor; + double BJT2f2; + double BJT2f3; + double BJT2f6; + double BJT2f7; + + unsigned BJT2subsGiven : 1; + unsigned BJT2tnomGiven : 1; + unsigned BJT2satCurGiven : 1; + unsigned BJT2subSatCurGiven : 1; + unsigned BJT2betaFGiven : 1; + unsigned BJT2emissionCoeffFGiven : 1; + unsigned BJT2earlyVoltFGiven : 1; + unsigned BJT2rollOffFGiven : 1; + unsigned BJT2leakBEcurrentGiven : 1; + unsigned BJT2c2Given : 1; + unsigned BJT2leakBEemissionCoeffGiven : 1; + unsigned BJT2betaRGiven : 1; + unsigned BJT2emissionCoeffRGiven : 1; + unsigned BJT2earlyVoltRGiven : 1; + unsigned BJT2rollOffRGiven : 1; + unsigned BJT2leakBCcurrentGiven : 1; + unsigned BJT2c4Given : 1; + unsigned BJT2leakBCemissionCoeffGiven : 1; + unsigned BJT2baseResistGiven : 1; + unsigned BJT2baseCurrentHalfResistGiven : 1; + unsigned BJT2minBaseResistGiven : 1; + unsigned BJT2emitterResistGiven : 1; + unsigned BJT2collectorResistGiven : 1; + unsigned BJT2depletionCapBEGiven : 1; + unsigned BJT2potentialBEGiven : 1; + unsigned BJT2junctionExpBEGiven : 1; + unsigned BJT2transitTimeFGiven : 1; + unsigned BJT2transitTimeBiasCoeffFGiven : 1; + unsigned BJT2transitTimeFVBCGiven : 1; + unsigned BJT2transitTimeHighCurrentFGiven : 1; + unsigned BJT2excessPhaseGiven : 1; + unsigned BJT2depletionCapBCGiven : 1; + unsigned BJT2potentialBCGiven : 1; + unsigned BJT2junctionExpBCGiven : 1; + unsigned BJT2baseFractionBCcapGiven : 1; + unsigned BJT2transitTimeRGiven : 1; + unsigned BJT2capSubGiven : 1; + unsigned BJT2potentialSubstrateGiven : 1; + unsigned BJT2exponentialSubstrateGiven : 1; + unsigned BJT2betaExpGiven : 1; + unsigned BJT2energyGapGiven : 1; + unsigned BJT2tempExpISGiven : 1; + unsigned BJT2reTempCoeff1Given : 1; + unsigned BJT2reTempCoeff2Given : 1; + unsigned BJT2rcTempCoeff1Given : 1; + unsigned BJT2rcTempCoeff2Given : 1; + unsigned BJT2rbTempCoeff1Given : 1; + unsigned BJT2rbTempCoeff2Given : 1; + unsigned BJT2rbmTempCoeff1Given : 1; + unsigned BJT2rbmTempCoeff2Given : 1; + unsigned BJT2depletionCapCoeffGiven : 1; + unsigned BJT2fNcoefGiven : 1; + unsigned BJT2fNexpGiven :1; +} BJT2model; + +#ifndef NPN +#define NPN 1 +#define PNP -1 +#endif /*NPN*/ + + +#ifndef VERTICAL +#define VERTICAL 1 +#define LATERAL -1 +#endif /* VERTICAL */ + + +/* device parameters */ +#define BJT2_AREA 1 +#define BJT2_OFF 2 +#define BJT2_IC_VBE 3 +#define BJT2_IC_VCE 4 +#define BJT2_IC 5 +#define BJT2_AREA_SENS 6 +#define BJT2_TEMP 7 + +/* model parameters */ +#define BJT2_MOD_NPN 101 +#define BJT2_MOD_PNP 102 +#define BJT2_MOD_IS 103 +#define BJT2_MOD_ISS 146 +#define BJT2_MOD_BF 104 +#define BJT2_MOD_NF 105 +#define BJT2_MOD_VAF 106 +#define BJT2_MOD_IKF 107 +#define BJT2_MOD_ISE 108 +#define BJT2_MOD_C2 109 +#define BJT2_MOD_NE 110 +#define BJT2_MOD_BR 111 +#define BJT2_MOD_NR 112 +#define BJT2_MOD_VAR 113 +#define BJT2_MOD_IKR 114 +#define BJT2_MOD_ISC 115 +#define BJT2_MOD_C4 116 +#define BJT2_MOD_NC 117 +#define BJT2_MOD_RB 118 +#define BJT2_MOD_IRB 119 +#define BJT2_MOD_RBM 120 +#define BJT2_MOD_RE 121 +#define BJT2_MOD_RC 122 +#define BJT2_MOD_CJE 123 +#define BJT2_MOD_VJE 124 +#define BJT2_MOD_MJE 125 +#define BJT2_MOD_TF 126 +#define BJT2_MOD_XTF 127 +#define BJT2_MOD_VTF 128 +#define BJT2_MOD_ITF 129 +#define BJT2_MOD_PTF 130 +#define BJT2_MOD_CJC 131 +#define BJT2_MOD_VJC 132 +#define BJT2_MOD_MJC 133 +#define BJT2_MOD_XCJC 134 +#define BJT2_MOD_TR 135 +#define BJT2_MOD_CJS 136 +#define BJT2_MOD_VJS 137 +#define BJT2_MOD_MJS 138 +#define BJT2_MOD_XTB 139 +#define BJT2_MOD_EG 140 +#define BJT2_MOD_XTI 141 +#define BJT2_MOD_FC 142 +#define BJT2_MOD_TNOM 143 +#define BJT2_MOD_AF 144 +#define BJT2_MOD_KF 145 +#define BJT2_MOD_SUBS 147 +#define BJT2_MOD_TRE1 148 +#define BJT2_MOD_TRE2 149 +#define BJT2_MOD_TRC1 150 +#define BJT2_MOD_TRC2 151 +#define BJT2_MOD_TRB1 152 +#define BJT2_MOD_TRB2 153 +#define BJT2_MOD_TRBM1 154 +#define BJT2_MOD_TRBM2 155 + + +/* device questions */ +#define BJT2_QUEST_FT 201 +#define BJT2_QUEST_COLNODE 202 +#define BJT2_QUEST_BASENODE 203 +#define BJT2_QUEST_EMITNODE 204 +#define BJT2_QUEST_SUBSTNODE 205 +#define BJT2_QUEST_COLPRIMENODE 206 +#define BJT2_QUEST_BASEPRIMENODE 207 +#define BJT2_QUEST_EMITPRIMENODE 208 +#define BJT2_QUEST_VBE 209 +#define BJT2_QUEST_VBC 210 +#define BJT2_QUEST_CC 211 +#define BJT2_QUEST_CB 212 +#define BJT2_QUEST_GPI 213 +#define BJT2_QUEST_GMU 214 +#define BJT2_QUEST_GM 215 +#define BJT2_QUEST_GO 216 +#define BJT2_QUEST_QBE 217 +#define BJT2_QUEST_CQBE 218 +#define BJT2_QUEST_QBC 219 +#define BJT2_QUEST_CQBC 220 +#define BJT2_QUEST_QSUB 221 +#define BJT2_QUEST_CQSUB 222 +#define BJT2_QUEST_QBX 223 +#define BJT2_QUEST_CQBX 224 +#define BJT2_QUEST_GX 225 +#define BJT2_QUEST_CEXBC 226 +#define BJT2_QUEST_GEQCB 227 +#define BJT2_QUEST_GCSUB 228 +#define BJT2_QUEST_GDSUB 243 +#define BJT2_QUEST_GEQBX 229 +#define BJT2_QUEST_SENS_REAL 230 +#define BJT2_QUEST_SENS_IMAG 231 +#define BJT2_QUEST_SENS_MAG 232 +#define BJT2_QUEST_SENS_PH 233 +#define BJT2_QUEST_SENS_CPLX 234 +#define BJT2_QUEST_SENS_DC 235 +#define BJT2_QUEST_CE 236 +#define BJT2_QUEST_CS 237 +#define BJT2_QUEST_POWER 238 + +#define BJT2_QUEST_CPI 239 +#define BJT2_QUEST_CMU 240 +#define BJT2_QUEST_CBX 241 +#define BJT2_QUEST_CSUB 242 + +/* model questions */ +#define BJT2_MOD_INVEARLYF 301 +#define BJT2_MOD_INVEARLYR 302 +#define BJT2_MOD_INVROLLOFFF 303 +#define BJT2_MOD_INVROLLOFFR 304 +#define BJT2_MOD_COLCONDUCT 305 +#define BJT2_MOD_EMITTERCONDUCT 306 +#define BJT2_MOD_TRANSVBCFACT 307 +#define BJT2_MOD_EXCESSPHASEFACTOR 308 +#define BJT2_MOD_TYPE 309 +#define BJT2_MOD_QUEST_SUBS 310 + +#include "bjt2ext.h" +#endif /*BJT2*/ diff --git a/src/spicelib/devices/bjt2/bjt2del.c b/src/spicelib/devices/bjt2/bjt2del.c index bf28ed671..d2b2a7a3f 100644 --- a/src/spicelib/devices/bjt2/bjt2del.c +++ b/src/spicelib/devices/bjt2/bjt2del.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2dest.c b/src/spicelib/devices/bjt2/bjt2dest.c index 4edc8b332..390301f00 100644 --- a/src/spicelib/devices/bjt2/bjt2dest.c +++ b/src/spicelib/devices/bjt2/bjt2dest.c @@ -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; +} diff --git a/src/spicelib/devices/bjt2/bjt2disto.c b/src/spicelib/devices/bjt2/bjt2disto.c index 5ba2159b0..fb3f11f5b 100644 --- a/src/spicelib/devices/bjt2/bjt2disto.c +++ b/src/spicelib/devices/bjt2/bjt2disto.c @@ -1,1841 +1,1838 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1988 Jaijeet S Roychowdhury -Modified: Alan Gillespie -**********/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "bjt2defs.h" -#include "sperror.h" -#include "distodef.h" -#include "suffix.h" -#include "bjt2dset.h" - -int -BJT2disto(mode,genmodel,ckt) - int mode; - GENmodel *genmodel; - CKTcircuit *ckt; -/* assuming here that ckt->CKTomega has been initialised to - * the correct value - */ -{ - BJT2model *model = (BJT2model *) genmodel; - DISTOAN* job = (DISTOAN*) ckt->CKTcurJob; - double td; - DpassStr pass; - double r1h1x,i1h1x; - double r1h1y,i1h1y; - double r1h1z, i1h1z; - double r1h2x, i1h2x; - double r1h2y, i1h2y; - double r1h2z, i1h2z; - double r1hm2x,i1hm2x; - double r1hm2y,i1hm2y; - double r1hm2z, i1hm2z; - double r2h11x,i2h11x; - double r2h11y,i2h11y; - double r2h11z, i2h11z; - double r2h1m2x,i2h1m2x; - double r2h1m2y,i2h1m2y; - double r2h1m2z, i2h1m2z; - double temp, itemp; - register BJT2instance *here; -#ifdef DISTODEBUG - double time; -#endif - -if (mode == D_SETUP) - - return(BJT2dSetup((GENmodel *)model,ckt)); - - -if ((mode == D_TWOF1) || (mode == D_THRF1) || - (mode == D_F1PF2) || (mode == D_F1MF2) || - (mode == D_2F1MF2)) { - - /* loop through all the BJT2 models */ -for( ; model != NULL; model = model->BJT2nextModel ) { - td = model->BJT2excessPhaseFactor; - - /* loop through all the instances of the model */ - for (here = model->BJT2instances; here != NULL ; - here=here->BJT2nextInstance) { - - - - /* getting Volterra kernels */ - /* until further notice x = vbe, y = vbc, z= vbed */ - - r1h1x = *(job->r1H1ptr + (here->BJT2basePrimeNode)) - - *(job->r1H1ptr + (here->BJT2emitPrimeNode)); - i1h1x = *(job->i1H1ptr + (here->BJT2basePrimeNode)) - - *(job->i1H1ptr + (here->BJT2emitPrimeNode)); - - r1h1y = *(job->r1H1ptr + (here->BJT2basePrimeNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1y = *(job->i1H1ptr + (here->BJT2basePrimeNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - - if (td != 0) { - - temp = job->Domega1 * td; - - /* multiplying r1h1x by exp(-j omega td) */ - r1h1z = r1h1x*cos(temp) + i1h1x*sin(temp); - i1h1z = i1h1x*cos(temp) - r1h1x*sin(temp); - } - else { - r1h1z = r1h1x; - i1h1z = i1h1x; - } - - if ((mode == D_F1MF2) || - (mode == D_2F1MF2)) { - - r1hm2x = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - - *(job->r1H2ptr + (here->BJT2emitPrimeNode)); - i1hm2x = -(*(job->i1H2ptr + (here->BJT2basePrimeNode)) - - *(job->i1H2ptr + (here->BJT2emitPrimeNode))); - - r1hm2y = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - - *(job->r1H2ptr + (here->BJT2colPrimeNode)); - i1hm2y = -(*(job->i1H2ptr + (here->BJT2basePrimeNode)) - - *(job->i1H2ptr + (here->BJT2colPrimeNode))); - - if (td != 0) { - - temp = -job->Domega2 * td; - r1hm2z = r1hm2x*cos(temp) + i1hm2x*sin(temp); - i1hm2z = i1hm2x*cos(temp) - r1hm2x*sin(temp); - } - else { - r1hm2z = r1hm2x; - i1hm2z = i1hm2x; - } - } - if ((mode == D_THRF1) || (mode == D_2F1MF2)){ - - - r2h11x = *(job->r2H11ptr + (here->BJT2basePrimeNode)) - - *(job->r2H11ptr + (here->BJT2emitPrimeNode)); - i2h11x = *(job->i2H11ptr + (here->BJT2basePrimeNode)) - - *(job->i2H11ptr + (here->BJT2emitPrimeNode)); - - r2h11y = *(job->r2H11ptr + (here->BJT2basePrimeNode)) - - *(job->r2H11ptr + (here->BJT2colPrimeNode)); - i2h11y = *(job->i2H11ptr + (here->BJT2basePrimeNode)) - - *(job->i2H11ptr + (here->BJT2colPrimeNode)); - - if (td != 0) { - temp = 2*job->Domega1* td ; - r2h11z = r2h11x*cos(temp) + i2h11x*sin(temp); - i2h11z = i2h11x*cos(temp) - r2h11x*sin(temp); - } - else { - r2h11z = r2h11x; - i2h11z = i2h11x; - } - } - - if ((mode == D_2F1MF2)){ - - r2h1m2x = *(job->r2H1m2ptr + (here->BJT2basePrimeNode)) - - *(job->r2H1m2ptr + (here->BJT2emitPrimeNode)); - i2h1m2x = *(job->i2H1m2ptr + (here->BJT2basePrimeNode)) - - *(job->i2H1m2ptr + (here->BJT2emitPrimeNode)); - - r2h1m2y = *(job->r2H1m2ptr + (here->BJT2basePrimeNode)) - - *(job->r2H1m2ptr + (here->BJT2colPrimeNode)); - i2h1m2y = *(job->i2H1m2ptr + (here->BJT2basePrimeNode)) - - *(job->i2H1m2ptr + (here->BJT2colPrimeNode)); - - if (td != 0) { - - temp = (job->Domega1 - job->Domega2) * td; - r2h1m2z = r2h1m2x*cos(temp) - + i2h1m2x*sin(temp); - i2h1m2z = i2h1m2x*cos(temp) - - r2h1m2x*sin(temp); - } - else { - r2h1m2z = r2h1m2x; - i2h1m2z = i2h1m2x; - } - } - if ((mode == D_F1PF2)){ - - r1h2x = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - - *(job->r1H2ptr + (here->BJT2emitPrimeNode)); - i1h2x = *(job->i1H2ptr + (here->BJT2basePrimeNode)) - - *(job->i1H2ptr + (here->BJT2emitPrimeNode)); - - r1h2y = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - - *(job->r1H2ptr + (here->BJT2colPrimeNode)); - i1h2y = *(job->i1H2ptr + (here->BJT2basePrimeNode)) - - *(job->i1H2ptr + (here->BJT2colPrimeNode)); - - - if (td != 0) { - temp = job->Domega2 * td; - r1h2z = r1h2x*cos(temp) + i1h2x*sin(temp); - i1h2z = i1h2x*cos(temp) - r1h2x*sin(temp); - } - else { - r1h2z = r1h2x; - i1h2z = i1h2x; - } - } - /* loading starts here */ - - switch (mode) { - case D_TWOF1: - - - /* ic term */ - -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = DFn2F1( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z); - - itemp = DFi2F1( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for DFn2F1: %g seconds \n", time); -#endif - - *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* finish ic term */ - /* loading ib term */ - /* x and y still the same */ - temp = DFn2F1( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0); - - itemp = DFi2F1( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* ib term over */ - /* loading ibb term */ - /* now x = vbe, y = vbc, z = vbb */ - if ( !((model->BJT2minBaseResist == 0.0) && - (model->BJT2baseResist == model->BJT2minBaseResist))) { - - r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - - *(job->r1H1ptr + (here->BJT2basePrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - - *(job->i1H1ptr + (here->BJT2basePrimeNode)); - - temp = DFn2F1( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z); - - itemp = DFi2F1( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z); - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; - } - - /* ibb term over */ - /* loading qbe term */ - /* x = vbe, y = vbc, z not used */ - /* (have to multiply by j omega for charge storage - * elements to get the current) - */ - - temp = - ckt->CKTomega* - DFi2F1( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0); - - itemp = ckt->CKTomega* - DFn2F1( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* qbe term over */ - /* loading qbx term */ - /* z = vbx= vb - vcPrime */ - - r1h1z = r1h1z + r1h1y; - i1h1z = i1h1z + i1h1y; -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = - ckt->CKTomega * - D1i2F1(here->capbx2, - r1h1z, - i1h1z); - itemp = ckt->CKTomega * - D1n2F1(here->capbx2, - r1h1z, - i1h1z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for D1n2F1: %g seconds \n", time); -#endif - - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbx term over */ - - /* loading qbc term */ - - temp = - ckt->CKTomega * - D1i2F1(here->capbc2, - r1h1y, - i1h1y); - itemp = ckt->CKTomega * - D1n2F1(here->capbc2, - r1h1y, - i1h1y); - - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbc term over */ - - - /* loading qsc term */ - /* z = vsc */ - - - - r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - - temp = - ckt->CKTomega * - D1i2F1(here->capsc2, - r1h1z, - i1h1z); - itemp = ckt->CKTomega * - D1n2F1(here->capsc2, - r1h1z, - i1h1z); - - - *(ckt->CKTrhs + here->BJT2substNode) -= temp; - *(ckt->CKTirhs + here->BJT2substNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qsc term over */ - - - break; - - case D_THRF1: - /* ic term */ - -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = DFn3F1( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - here->ic_x3, - here->ic_y3, - here->ic_w3, - here->ic_x2y, - here->ic_x2w, - here->ic_xy2, - here->ic_y2w, - here->ic_xw2, - here->ic_yw2, - here->ic_xyw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - r2h11z, - i2h11z); - - itemp = DFi3F1( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - here->ic_x3, - here->ic_y3, - here->ic_w3, - here->ic_x2y, - here->ic_x2w, - here->ic_xy2, - here->ic_y2w, - here->ic_xw2, - here->ic_yw2, - here->ic_xyw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - r2h11z, - i2h11z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for DFn3F1: %g seconds \n", time); -#endif - - *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* finish ic term */ - /* loading ib term */ - /* x and y still the same */ - temp = DFn3F1( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - here->ib_x3, - here->ib_y3, - 0.0, - here->ib_x2y, - 0.0, - here->ib_xy2, - 0.0, - 0.0, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - 0.0, - 0.0); - - itemp = DFi3F1( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - here->ib_x3, - here->ib_y3, - 0.0, - here->ib_x2y, - 0.0, - here->ib_xy2, - 0.0, - 0.0, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* ib term over */ - /* loading ibb term */ - if ( !((model->BJT2minBaseResist == 0.0) && - (model->BJT2baseResist == model->BJT2minBaseResist))) { - - /* now x = vbe, y = vbc, z = vbb */ - r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - - *(job->r1H1ptr + (here->BJT2basePrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - - *(job->i1H1ptr + (here->BJT2basePrimeNode)); - - r2h11z = *(job->r2H11ptr + (here->BJT2baseNode)) - - *(job->r2H11ptr + (here->BJT2basePrimeNode)); - i2h11z = *(job->i2H11ptr + (here->BJT2baseNode)) - - *(job->i2H11ptr + (here->BJT2basePrimeNode)); - - temp = DFn3F1( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - here->ibb_x3, - here->ibb_y3, - here->ibb_z3, - here->ibb_x2y, - here->ibb_x2z, - here->ibb_xy2, - here->ibb_y2z, - here->ibb_xz2, - here->ibb_yz2, - here->ibb_xyz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - r2h11z, - i2h11z); - - itemp = DFi3F1( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - here->ibb_x3, - here->ibb_y3, - here->ibb_z3, - here->ibb_x2y, - here->ibb_x2z, - here->ibb_xy2, - here->ibb_y2z, - here->ibb_xz2, - here->ibb_yz2, - here->ibb_xyz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - r2h11z, - i2h11z); - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; - - } - /* ibb term over */ - /* loading qbe term */ - /* x = vbe, y = vbc, z not used */ - /* (have to multiply by j omega for charge storage - * elements to get the current) - */ - - temp = - ckt->CKTomega* - DFi3F1( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - here->qbe_x3, - here->qbe_y3, - 0.0, - here->qbe_x2y, - 0.0, - here->qbe_xy2, - 0.0, - 0.0, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - 0.0, - 0.0); - - itemp = ckt->CKTomega* - DFn3F1( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - here->qbe_x3, - here->qbe_y3, - 0.0, - here->qbe_x2y, - 0.0, - here->qbe_xy2, - 0.0, - 0.0, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r2h11x, - i2h11x, - r2h11y, - i2h11y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* qbe term over */ - /* loading qbx term */ - /* z = vbx= vb - vcPrime */ - - r1h1z = r1h1z + r1h1y; - i1h1z = i1h1z + i1h1y; - r2h11z = r2h11z + r2h11y; - i2h11z = i2h11z + i2h11y; -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = - ckt->CKTomega * - D1i3F1(here->capbx2, - here->capbx3, - r1h1z, - i1h1z, - r2h11z, - i2h11z); - itemp = ckt->CKTomega * - D1n3F1(here->capbx2, - here->capbx3, - r1h1z, - i1h1z, - r2h11z, - i2h11z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for D1n3F1: %g seconds \n", time); -#endif - - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbx term over */ - - /* loading qbc term */ - - temp = - ckt->CKTomega * - D1i3F1(here->capbc2, - here->capbc3, - r1h1y, - i1h1y, - r2h11y, - i2h11y); - itemp = ckt->CKTomega * - D1n3F1(here->capbc2, - here->capbc3, - r1h1y, - i1h1y, - r2h11y, - i2h11y); - - - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbc term over */ - - - /* loading qsc term */ - /* z = vsc */ - - - - r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - - r2h11z = *(job->r2H11ptr + (here->BJT2substNode)) - - *(job->r2H11ptr + (here->BJT2colPrimeNode)); - i2h11z = *(job->i2H11ptr + (here->BJT2substNode)) - - *(job->i2H11ptr + (here->BJT2colPrimeNode)); - - temp = - ckt->CKTomega * - D1i3F1(here->capsc2, - here->capsc3, - r1h1z, - i1h1z, - r2h11z, - i2h11z); - - itemp = ckt->CKTomega * - D1n3F1(here->capsc2, - here->capsc3, - r1h1z, - i1h1z, - r2h11z, - i2h11z); - - - *(ckt->CKTrhs + here->BJT2substNode) -= temp; - *(ckt->CKTirhs + here->BJT2substNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qsc term over */ - - - break; - case D_F1PF2: - /* ic term */ - - temp = DFnF12( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - r1h2z, - i1h2z); - - itemp = DFiF12( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - r1h2z, - i1h2z); - - *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* finish ic term */ - /* loading ib term */ - /* x and y still the same */ -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = DFnF12( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - 0.0, - 0.0); - - itemp = DFiF12( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - 0.0, - 0.0); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for DFnF12: %g seconds \n", time); -#endif - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* ib term over */ - /* loading ibb term */ - if ( !((model->BJT2minBaseResist == 0.0) && - (model->BJT2baseResist == model->BJT2minBaseResist))) { - - /* now x = vbe, y = vbc, z = vbb */ - r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - - *(job->r1H1ptr + (here->BJT2basePrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - - *(job->i1H1ptr + (here->BJT2basePrimeNode)); - - r1h2z = *(job->r1H2ptr + (here->BJT2baseNode)) - - *(job->r1H2ptr + (here->BJT2basePrimeNode)); - i1h2z = *(job->i1H2ptr + (here->BJT2baseNode)) - - *(job->i1H2ptr + (here->BJT2basePrimeNode)); - - temp = DFnF12( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - r1h2z, - i1h2z); - - itemp = DFiF12( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - r1h2z, - i1h2z); - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; - - } - /* ibb term over */ - /* loading qbe term */ - /* x = vbe, y = vbc, z not used */ - /* (have to multiply by j omega for charge storage - * elements - to get the current) - */ - - temp = - ckt->CKTomega* - DFiF12( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - 0.0, - 0.0); - - itemp = ckt->CKTomega* - DFnF12( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1h2x, - i1h2x, - r1h2y, - i1h2y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* qbe term over */ - /* loading qbx term */ - /* z = vbx= vb - vcPrime */ - - r1h1z = r1h1z + r1h1y; - i1h1z = i1h1z + i1h1y; - r1h2z = r1h2z + r1h2y; - i1h2z = i1h2z + i1h2y; -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = - ckt->CKTomega * - D1iF12(here->capbx2, - r1h1z, - i1h1z, - r1h2z, - i1h2z); - itemp = ckt->CKTomega * - D1nF12(here->capbx2, - r1h1z, - i1h1z, - r1h2z, - i1h2z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for D1nF12: %g seconds \n", time); -#endif - - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbx term over */ - - /* loading qbc term */ - - temp = - ckt->CKTomega * - D1iF12(here->capbc2, - r1h1y, - i1h1y, - r1h2y, - i1h2y); - itemp = ckt->CKTomega * - D1nF12(here->capbc2, - r1h1y, - i1h1y, - r1h2y, - i1h2y); - - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbc term over */ - - - /* loading qsc term */ - /* z = vsc */ - - - - r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - r1h2z = *(job->r1H2ptr + (here->BJT2substNode)) - - *(job->r1H2ptr + (here->BJT2colPrimeNode)); - i1h2z = *(job->i1H2ptr + (here->BJT2substNode)) - - *(job->i1H2ptr + (here->BJT2colPrimeNode)); - - temp = - ckt->CKTomega * - D1iF12(here->capsc2, - r1h1z, - i1h1z, - r1h2z, - i1h2z); - itemp = ckt->CKTomega * - D1nF12(here->capsc2, - r1h1z, - i1h1z, - r1h2z, - i1h2z); - - - *(ckt->CKTrhs + here->BJT2substNode) -= temp; - *(ckt->CKTirhs + here->BJT2substNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qsc term over */ - - - break; - case D_F1MF2: - /* ic term */ - - temp = DFnF12( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - r1hm2z, - i1hm2z); - - itemp = DFiF12( here->ic_x2, - here->ic_y2, - here->ic_w2, - here->ic_xy, - here->ic_yw, - here->ic_xw, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - r1hm2z, - i1hm2z); - - *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* finish ic term */ - /* loading ib term */ - /* x and y still the same */ - temp = DFnF12( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - 0.0, - 0.0); - - itemp = DFiF12( here->ib_x2, - here->ib_y2, - 0.0, - here->ib_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* ib term over */ - /* loading ibb term */ - if ( !((model->BJT2minBaseResist == 0.0) && - (model->BJT2baseResist == model->BJT2minBaseResist))) { - - /* now x = vbe, y = vbc, z = vbb */ - r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - - *(job->r1H1ptr + (here->BJT2basePrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - - *(job->i1H1ptr + (here->BJT2basePrimeNode)); - - r1hm2z = *(job->r1H2ptr + (here->BJT2baseNode)) - - *(job->r1H2ptr + (here->BJT2basePrimeNode)); - i1hm2z = *(job->i1H2ptr + (here->BJT2baseNode)) - - *(job->i1H2ptr + (here->BJT2basePrimeNode)); - - temp = DFnF12( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - r1hm2z, - i1hm2z); - - itemp = DFiF12( here->ibb_x2, - here->ibb_y2, - here->ibb_z2, - here->ibb_xy, - here->ibb_yz, - here->ibb_xz, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - r1h1z, - i1h1z, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - r1hm2z, - i1hm2z); - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; - } - - /* ibb term over */ - /* loading qbe term */ - /* x = vbe, y = vbc, z not used */ - /* (have to multiply by j omega for charge storage - * elements - to get the current) - */ - - temp = - ckt->CKTomega* - DFiF12( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - 0.0, - 0.0); - - itemp = ckt->CKTomega* - DFnF12( here->qbe_x2, - here->qbe_y2, - 0.0, - here->qbe_xy, - 0.0, - 0.0, - r1h1x, - i1h1x, - r1h1y, - i1h1y, - 0.0, - 0.0, - r1hm2x, - i1hm2x, - r1hm2y, - i1hm2y, - 0.0, - 0.0); - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* qbe term over */ - /* loading qbx term */ - /* z = vbx= vb - vcPrime */ - - r1h1z = r1h1z + r1h1y; - i1h1z = i1h1z + i1h1y; - r1hm2z = r1hm2z + r1hm2y; - i1hm2z = i1hm2z + i1hm2y; - temp = - ckt->CKTomega * - D1iF12(here->capbx2, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z); - itemp = ckt->CKTomega * - D1nF12(here->capbx2, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z); - - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbx term over */ - - /* loading qbc term */ - - temp = - ckt->CKTomega * - D1iF12(here->capbc2, - r1h1y, - i1h1y, - r1hm2y, - i1hm2y); - itemp = ckt->CKTomega * - D1nF12(here->capbc2, - r1h1y, - i1h1y, - r1hm2y, - i1hm2y); - - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbc term over */ - - - /* loading qsc term */ - /* z = vsc */ - - - - r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - r1hm2z = *(job->r1H2ptr + (here->BJT2substNode)) - - *(job->r1H2ptr + (here->BJT2colPrimeNode)); - i1hm2z = *(job->i1H2ptr + (here->BJT2substNode)) - - *(job->i1H2ptr + (here->BJT2colPrimeNode)); - - temp = - ckt->CKTomega * - D1iF12(here->capsc2, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z); - itemp = ckt->CKTomega * - D1nF12(here->capsc2, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z); - - - *(ckt->CKTrhs + here->BJT2substNode) -= temp; - *(ckt->CKTirhs + here->BJT2substNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qsc term over */ - - - break; - case D_2F1MF2: - /* ic term */ - - { - pass.cxx = here->ic_x2; - pass.cyy = here->ic_y2; - pass.czz = here->ic_w2; - pass.cxy = here->ic_xy; - pass.cyz = here->ic_yw; - pass.cxz = here->ic_xw; - pass.cxxx = here->ic_x3; - pass.cyyy = here->ic_y3; - pass.czzz = here->ic_w3; - pass.cxxy = here->ic_x2y; - pass.cxxz = here->ic_x2w; - pass.cxyy = here->ic_xy2; - pass.cyyz = here->ic_y2w; - pass.cxzz = here->ic_xw2; - pass.cyzz = here->ic_yw2; - pass.cxyz = here->ic_xyw; - pass.r1h1x = r1h1x; - pass.i1h1x = i1h1x; - pass.r1h1y = r1h1y; - pass.i1h1y = i1h1y; - pass.r1h1z = r1h1z; - pass.i1h1z = i1h1z; - pass.r1h2x = r1hm2x; - pass.i1h2x = i1hm2x; - pass.r1h2y = r1hm2y; - pass.i1h2y = i1hm2y; - pass.r1h2z = r1hm2z; - pass.i1h2z = i1hm2z; - pass.r2h11x = r2h11x; - pass.i2h11x = i2h11x; - pass.r2h11y = r2h11y; - pass.i2h11y = i2h11y; - pass.r2h11z = r2h11z; - pass.i2h11z = i2h11z; - pass.h2f1f2x = r2h1m2x; - pass.ih2f1f2x = i2h1m2x; - pass.h2f1f2y = r2h1m2y; - pass.ih2f1f2y = i2h1m2y; - pass.h2f1f2z = r2h1m2z; - pass.ih2f1f2z = i2h1m2z; -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = DFn2F12(&pass); - - - itemp = DFi2F12(&pass); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for DFn2F12: %g seconds \n", time); -#endif - } - - *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* finish ic term */ - /* loading ib term */ - /* x and y still the same */ - { - pass.cxx = here->ib_x2; - pass.cyy = here->ib_y2; - pass.czz = 0.0; - pass.cxy = here->ib_xy; - pass.cyz = 0.0; - pass.cxz = 0.0; - pass.cxxx = here->ib_x3; - pass.cyyy = here->ib_y3; - pass.czzz = 0.0; - pass.cxxy = here->ib_x2y; - pass.cxxz = 0.0; - pass.cxyy = here->ib_xy2; - pass.cyyz = 0.0; - pass.cxzz = 0.0; - pass.cyzz = 0.0; - pass.cxyz = 0.0; - pass.r1h1x = r1h1x; - pass.i1h1x = i1h1x; - pass.r1h1y = r1h1y; - pass.i1h1y = i1h1y; - pass.r1h1z = 0.0; - pass.i1h1z = 0.0; - pass.r1h2x = r1hm2x; - pass.i1h2x = i1hm2x; - pass.r1h2y = r1hm2y; - pass.i1h2y = i1hm2y; - pass.r1h2z = 0.0; - pass.i1h2z = 0.0; - pass.r2h11x = r2h11x; - pass.i2h11x = i2h11x; - pass.r2h11y = r2h11y; - pass.i2h11y = i2h11y; - pass.r2h11z = 0.0; - pass.i2h11z = 0.0; - pass.h2f1f2x = r2h1m2x; - pass.ih2f1f2x = i2h1m2x; - pass.h2f1f2y = r2h1m2y; - pass.ih2f1f2y = i2h1m2y; - pass.h2f1f2z = 0.0; - pass.ih2f1f2z = 0.0; - temp = DFn2F12(&pass); - - itemp = DFi2F12(&pass); - } - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* ib term over */ - /* loading ibb term */ - if ( !((model->BJT2minBaseResist == 0.0) && - (model->BJT2baseResist == model->BJT2minBaseResist))) { - - /* now x = vbe, y = vbc, z = vbb */ - r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - - *(job->r1H1ptr + (here->BJT2basePrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - - *(job->i1H1ptr + (here->BJT2basePrimeNode)); - - r1hm2z = *(job->r1H2ptr + (here->BJT2baseNode)) - - *(job->r1H2ptr + (here->BJT2basePrimeNode)); - i1hm2z = -(*(job->i1H2ptr + (here->BJT2baseNode)) - - *(job->i1H2ptr + (here->BJT2basePrimeNode))); - - r2h11z = *(job->r2H11ptr + (here->BJT2baseNode)) - - *(job->r2H11ptr + (here->BJT2basePrimeNode)); - i2h11z = *(job->i2H11ptr + (here->BJT2baseNode)) - - *(job->i2H11ptr + (here->BJT2basePrimeNode)); - - r2h1m2z = *(job->r2H1m2ptr + (here->BJT2baseNode)) - - *(job->r2H1m2ptr + (here->BJT2basePrimeNode)); - i2h1m2z = *(job->i2H1m2ptr + (here->BJT2baseNode)) - - *(job->i2H1m2ptr + (here->BJT2basePrimeNode)); - - { - pass.cxx = here->ibb_x2; - pass.cyy = here->ibb_y2; - pass.czz = here->ibb_z2; - pass.cxy = here->ibb_xy; - pass.cyz = here->ibb_yz; - pass.cxz = here->ibb_xz; - pass.cxxx = here->ibb_x3; - pass.cyyy = here->ibb_y3; - pass.czzz = here->ibb_z3; - pass.cxxy = here->ibb_x2y; - pass.cxxz = here->ibb_x2z; - pass.cxyy = here->ibb_xy2; - pass.cyyz = here->ibb_y2z; - pass.cxzz = here->ibb_xz2; - pass.cyzz = here->ibb_yz2; - pass.cxyz = here->ibb_xyz; - pass.r1h1x = r1h1x; - pass.i1h1x = i1h1x; - pass.r1h1y = r1h1y; - pass.i1h1y = i1h1y; - pass.r1h1z = r1h1z; - pass.i1h1z = i1h1z; - pass.r1h2x = r1hm2x; - pass.i1h2x = i1hm2x; - pass.r1h2y = r1hm2y; - pass.i1h2y = i1hm2y; - pass.r1h2z = r1hm2z; - pass.i1h2z = i1hm2z; - pass.r2h11x = r2h11x; - pass.i2h11x = i2h11x; - pass.r2h11y = r2h11y; - pass.i2h11y = i2h11y; - pass.r2h11z = r2h11z; - pass.i2h11z = i2h11z; - pass.h2f1f2x = r2h1m2x; - pass.ih2f1f2x = i2h1m2x; - pass.h2f1f2y = r2h1m2y; - pass.ih2f1f2y = i2h1m2y; - pass.h2f1f2z = r2h1m2z; - pass.ih2f1f2z = i2h1m2z; - temp = DFn2F12(&pass); - - itemp = DFi2F12(&pass); - } - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; - - } - /* ibb term over */ - /* loading qbe term */ - /* x = vbe, y = vbc, z not used */ - /* (have to multiply by j omega for charge storage - * elements to get the current) - */ - - { - pass.cxx = here->qbe_x2; - pass.cyy = here->qbe_y2; - pass.czz = 0.0; - pass.cxy = here->qbe_xy; - pass.cyz = 0.0; - pass.cxz = 0.0; - pass.cxxx = here->qbe_x3; - pass.cyyy = here->qbe_y3; - pass.czzz = 0.0; - pass.cxxy = here->qbe_x2y; - pass.cxxz = 0.0; - pass.cxyy = here->qbe_xy2; - pass.cyyz = 0.0; - pass.cxzz = 0.0; - pass.cyzz = 0.0; - pass.cxyz = 0.0; - pass.r1h1x = r1h1x; - pass.i1h1x = i1h1x; - pass.r1h1y = r1h1y; - pass.i1h1y = i1h1y; - pass.r1h1z = 0.0; - pass.i1h1z = 0.0; - pass.r1h2x = r1hm2x; - pass.i1h2x = i1hm2x; - pass.r1h2y = r1hm2y; - pass.i1h2y = i1hm2y; - pass.r1h2z = 0.0; - pass.i1h2z = 0.0; - pass.r2h11x = r2h11x; - pass.i2h11x = i2h11x; - pass.r2h11y = r2h11y; - pass.i2h11y = i2h11y; - pass.r2h11z = 0.0; - pass.i2h11z = 0.0; - pass.h2f1f2x = r2h1m2x; - pass.ih2f1f2x = i2h1m2x; - pass.h2f1f2y = r2h1m2y; - pass.ih2f1f2y = i2h1m2y; - pass.h2f1f2z = 0.0; - pass.ih2f1f2z = 0.0; - temp = - ckt->CKTomega* - DFi2F12(&pass); - - itemp = ckt->CKTomega* - DFn2F12(&pass); - } - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; - - /* qbe term over */ - /* loading qbx term */ - /* z = vbx= vb - vcPrime */ - - r1h1z = r1h1z + r1h1y; - i1h1z = i1h1z + i1h1y; - r1hm2z = r1hm2z + r1hm2y; - i1hm2z = i1hm2z + i1hm2y; - r2h11z = r2h11z + r2h11y; - i2h11z = i2h11z + i2h11y; - r2h1m2z = r2h1m2z + r2h1m2y; - i2h1m2z = i2h1m2z + i2h1m2y; -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))(); -#endif - temp = - ckt->CKTomega * - D1i2F12(here->capbx2, - here->capbx3, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z, - r2h11z, - i2h11z, - r2h1m2z, - i2h1m2z); - itemp = ckt->CKTomega * - D1n2F12(here->capbx2, - here->capbx3, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z, - r2h11z, - i2h11z, - r2h1m2z, - i2h1m2z); -#ifdef D_DBG_SMALLTIMES -time = (*(SPfrontEnd->IFseconds))() - time; -printf("Time for D1n2F12: %g seconds \n", time); -#endif - - - *(ckt->CKTrhs + here->BJT2baseNode) -= temp; - *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbx term over */ - - /* loading qbc term */ - - temp = - ckt->CKTomega * - D1i2F12(here->capbc2, - here->capbc3, - r1h1y, - i1h1y, - r1hm2y, - i1hm2y, - r2h11y, - i2h11y, - r2h1m2y, - i2h1m2y); - itemp = ckt->CKTomega * - D1n2F12(here->capbc2, - here->capbc3, - r1h1y, - i1h1y, - r1hm2y, - i1hm2y, - r2h11y, - i2h11y, - r2h1m2y, - i2h1m2y); - - - - - *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; - *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qbc term over */ - - - /* loading qsc term */ - /* z = vsc */ - - - - r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - - *(job->r1H1ptr + (here->BJT2colPrimeNode)); - i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - - *(job->i1H1ptr + (here->BJT2colPrimeNode)); - - r1hm2z = *(job->r1H2ptr + (here->BJT2substNode)) - - *(job->r1H2ptr + (here->BJT2colPrimeNode)); - i1hm2z = -(*(job->i1H2ptr + (here->BJT2substNode)) - - *(job->i1H2ptr + (here->BJT2colPrimeNode))); - - r2h11z = *(job->r2H11ptr + (here->BJT2substNode)) - - *(job->r2H11ptr + (here->BJT2colPrimeNode)); - i2h11z = *(job->i2H11ptr + (here->BJT2substNode)) - - *(job->i2H11ptr + (here->BJT2colPrimeNode)); - - r2h1m2z = *(job->r2H1m2ptr + (here->BJT2substNode)) - - *(job->r2H1m2ptr + (here->BJT2colPrimeNode)); - i2h1m2z = *(job->i2H1m2ptr + (here->BJT2substNode)) - - *(job->i2H1m2ptr + (here->BJT2colPrimeNode)); - - temp = - ckt->CKTomega * - D1i2F12(here->capsc2, - here->capsc3, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z, - r2h11z, - i2h11z, - r2h1m2z, - i2h1m2z); - - itemp = ckt->CKTomega * - D1n2F12(here->capsc2, - here->capsc3, - r1h1z, - i1h1z, - r1hm2z, - i1hm2z, - r2h11z, - i2h11z, - r2h1m2z, - i2h1m2z); - - - *(ckt->CKTrhs + here->BJT2substNode) -= temp; - *(ckt->CKTirhs + here->BJT2substNode) -= itemp; - *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; - *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; - - /* qsc term over */ - - - break; - default: -; - ; - } - } -} -return(OK); -} - else - return(E_BADPARM); -} +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include "bjt2defs.h" +#include "sperror.h" +#include "distodef.h" +#include "suffix.h" +#include "bjt2dset.h" + +int +BJT2disto(int mode, GENmodel *genmodel, CKTcircuit *ckt) +/* assuming here that ckt->CKTomega has been initialised to + * the correct value + */ +{ + BJT2model *model = (BJT2model *) genmodel; + DISTOAN* job = (DISTOAN*) ckt->CKTcurJob; + double td; + DpassStr pass; + double r1h1x,i1h1x; + double r1h1y,i1h1y; + double r1h1z, i1h1z; + double r1h2x, i1h2x; + double r1h2y, i1h2y; + double r1h2z, i1h2z; + double r1hm2x,i1hm2x; + double r1hm2y,i1hm2y; + double r1hm2z, i1hm2z; + double r2h11x,i2h11x; + double r2h11y,i2h11y; + double r2h11z, i2h11z; + double r2h1m2x,i2h1m2x; + double r2h1m2y,i2h1m2y; + double r2h1m2z, i2h1m2z; + double temp, itemp; + register BJT2instance *here; +#ifdef DISTODEBUG + double time; +#endif + +if (mode == D_SETUP) + + return(BJT2dSetup((GENmodel *)model,ckt)); + + +if ((mode == D_TWOF1) || (mode == D_THRF1) || + (mode == D_F1PF2) || (mode == D_F1MF2) || + (mode == D_2F1MF2)) { + + /* loop through all the BJT2 models */ +for( ; model != NULL; model = model->BJT2nextModel ) { + td = model->BJT2excessPhaseFactor; + + /* loop through all the instances of the model */ + for (here = model->BJT2instances; here != NULL ; + here=here->BJT2nextInstance) { + + + + /* getting Volterra kernels */ + /* until further notice x = vbe, y = vbc, z= vbed */ + + r1h1x = *(job->r1H1ptr + (here->BJT2basePrimeNode)) - + *(job->r1H1ptr + (here->BJT2emitPrimeNode)); + i1h1x = *(job->i1H1ptr + (here->BJT2basePrimeNode)) - + *(job->i1H1ptr + (here->BJT2emitPrimeNode)); + + r1h1y = *(job->r1H1ptr + (here->BJT2basePrimeNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1y = *(job->i1H1ptr + (here->BJT2basePrimeNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + + if (td != 0) { + + temp = job->Domega1 * td; + + /* multiplying r1h1x by exp(-j omega td) */ + r1h1z = r1h1x*cos(temp) + i1h1x*sin(temp); + i1h1z = i1h1x*cos(temp) - r1h1x*sin(temp); + } + else { + r1h1z = r1h1x; + i1h1z = i1h1x; + } + + if ((mode == D_F1MF2) || + (mode == D_2F1MF2)) { + + r1hm2x = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - + *(job->r1H2ptr + (here->BJT2emitPrimeNode)); + i1hm2x = -(*(job->i1H2ptr + (here->BJT2basePrimeNode)) - + *(job->i1H2ptr + (here->BJT2emitPrimeNode))); + + r1hm2y = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - + *(job->r1H2ptr + (here->BJT2colPrimeNode)); + i1hm2y = -(*(job->i1H2ptr + (here->BJT2basePrimeNode)) - + *(job->i1H2ptr + (here->BJT2colPrimeNode))); + + if (td != 0) { + + temp = -job->Domega2 * td; + r1hm2z = r1hm2x*cos(temp) + i1hm2x*sin(temp); + i1hm2z = i1hm2x*cos(temp) - r1hm2x*sin(temp); + } + else { + r1hm2z = r1hm2x; + i1hm2z = i1hm2x; + } + } + if ((mode == D_THRF1) || (mode == D_2F1MF2)){ + + + r2h11x = *(job->r2H11ptr + (here->BJT2basePrimeNode)) - + *(job->r2H11ptr + (here->BJT2emitPrimeNode)); + i2h11x = *(job->i2H11ptr + (here->BJT2basePrimeNode)) - + *(job->i2H11ptr + (here->BJT2emitPrimeNode)); + + r2h11y = *(job->r2H11ptr + (here->BJT2basePrimeNode)) - + *(job->r2H11ptr + (here->BJT2colPrimeNode)); + i2h11y = *(job->i2H11ptr + (here->BJT2basePrimeNode)) - + *(job->i2H11ptr + (here->BJT2colPrimeNode)); + + if (td != 0) { + temp = 2*job->Domega1* td ; + r2h11z = r2h11x*cos(temp) + i2h11x*sin(temp); + i2h11z = i2h11x*cos(temp) - r2h11x*sin(temp); + } + else { + r2h11z = r2h11x; + i2h11z = i2h11x; + } + } + + if ((mode == D_2F1MF2)){ + + r2h1m2x = *(job->r2H1m2ptr + (here->BJT2basePrimeNode)) - + *(job->r2H1m2ptr + (here->BJT2emitPrimeNode)); + i2h1m2x = *(job->i2H1m2ptr + (here->BJT2basePrimeNode)) + - *(job->i2H1m2ptr + (here->BJT2emitPrimeNode)); + + r2h1m2y = *(job->r2H1m2ptr + (here->BJT2basePrimeNode)) - + *(job->r2H1m2ptr + (here->BJT2colPrimeNode)); + i2h1m2y = *(job->i2H1m2ptr + (here->BJT2basePrimeNode)) + - *(job->i2H1m2ptr + (here->BJT2colPrimeNode)); + + if (td != 0) { + + temp = (job->Domega1 - job->Domega2) * td; + r2h1m2z = r2h1m2x*cos(temp) + + i2h1m2x*sin(temp); + i2h1m2z = i2h1m2x*cos(temp) + - r2h1m2x*sin(temp); + } + else { + r2h1m2z = r2h1m2x; + i2h1m2z = i2h1m2x; + } + } + if ((mode == D_F1PF2)){ + + r1h2x = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - + *(job->r1H2ptr + (here->BJT2emitPrimeNode)); + i1h2x = *(job->i1H2ptr + (here->BJT2basePrimeNode)) - + *(job->i1H2ptr + (here->BJT2emitPrimeNode)); + + r1h2y = *(job->r1H2ptr + (here->BJT2basePrimeNode)) - + *(job->r1H2ptr + (here->BJT2colPrimeNode)); + i1h2y = *(job->i1H2ptr + (here->BJT2basePrimeNode)) - + *(job->i1H2ptr + (here->BJT2colPrimeNode)); + + + if (td != 0) { + temp = job->Domega2 * td; + r1h2z = r1h2x*cos(temp) + i1h2x*sin(temp); + i1h2z = i1h2x*cos(temp) - r1h2x*sin(temp); + } + else { + r1h2z = r1h2x; + i1h2z = i1h2x; + } + } + /* loading starts here */ + + switch (mode) { + case D_TWOF1: + + + /* ic term */ + +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = DFn2F1( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); + + itemp = DFi2F1( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for DFn2F1: %g seconds \n", time); +#endif + + *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* finish ic term */ + /* loading ib term */ + /* x and y still the same */ + temp = DFn2F1( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0); + + itemp = DFi2F1( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* ib term over */ + /* loading ibb term */ + /* now x = vbe, y = vbc, z = vbb */ + if ( !((model->BJT2minBaseResist == 0.0) && + (model->BJT2baseResist == model->BJT2minBaseResist))) { + + r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - + *(job->r1H1ptr + (here->BJT2basePrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - + *(job->i1H1ptr + (here->BJT2basePrimeNode)); + + temp = DFn2F1( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); + + itemp = DFi2F1( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z); + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; + } + + /* ibb term over */ + /* loading qbe term */ + /* x = vbe, y = vbc, z not used */ + /* (have to multiply by j omega for charge storage + * elements to get the current) + */ + + temp = - ckt->CKTomega* + DFi2F1( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0); + + itemp = ckt->CKTomega* + DFn2F1( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* qbe term over */ + /* loading qbx term */ + /* z = vbx= vb - vcPrime */ + + r1h1z = r1h1z + r1h1y; + i1h1z = i1h1z + i1h1y; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = - ckt->CKTomega * + D1i2F1(here->capbx2, + r1h1z, + i1h1z); + itemp = ckt->CKTomega * + D1n2F1(here->capbx2, + r1h1z, + i1h1z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for D1n2F1: %g seconds \n", time); +#endif + + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbx term over */ + + /* loading qbc term */ + + temp = - ckt->CKTomega * + D1i2F1(here->capbc2, + r1h1y, + i1h1y); + itemp = ckt->CKTomega * + D1n2F1(here->capbc2, + r1h1y, + i1h1y); + + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbc term over */ + + + /* loading qsc term */ + /* z = vsc */ + + + + r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + + temp = - ckt->CKTomega * + D1i2F1(here->capsc2, + r1h1z, + i1h1z); + itemp = ckt->CKTomega * + D1n2F1(here->capsc2, + r1h1z, + i1h1z); + + + *(ckt->CKTrhs + here->BJT2substNode) -= temp; + *(ckt->CKTirhs + here->BJT2substNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qsc term over */ + + + break; + + case D_THRF1: + /* ic term */ + +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = DFn3F1( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + here->ic_x3, + here->ic_y3, + here->ic_w3, + here->ic_x2y, + here->ic_x2w, + here->ic_xy2, + here->ic_y2w, + here->ic_xw2, + here->ic_yw2, + here->ic_xyw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); + + itemp = DFi3F1( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + here->ic_x3, + here->ic_y3, + here->ic_w3, + here->ic_x2y, + here->ic_x2w, + here->ic_xy2, + here->ic_y2w, + here->ic_xw2, + here->ic_yw2, + here->ic_xyw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for DFn3F1: %g seconds \n", time); +#endif + + *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* finish ic term */ + /* loading ib term */ + /* x and y still the same */ + temp = DFn3F1( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + here->ib_x3, + here->ib_y3, + 0.0, + here->ib_x2y, + 0.0, + here->ib_xy2, + 0.0, + 0.0, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + 0.0, + 0.0); + + itemp = DFi3F1( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + here->ib_x3, + here->ib_y3, + 0.0, + here->ib_x2y, + 0.0, + here->ib_xy2, + 0.0, + 0.0, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* ib term over */ + /* loading ibb term */ + if ( !((model->BJT2minBaseResist == 0.0) && + (model->BJT2baseResist == model->BJT2minBaseResist))) { + + /* now x = vbe, y = vbc, z = vbb */ + r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - + *(job->r1H1ptr + (here->BJT2basePrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - + *(job->i1H1ptr + (here->BJT2basePrimeNode)); + + r2h11z = *(job->r2H11ptr + (here->BJT2baseNode)) - + *(job->r2H11ptr + (here->BJT2basePrimeNode)); + i2h11z = *(job->i2H11ptr + (here->BJT2baseNode)) - + *(job->i2H11ptr + (here->BJT2basePrimeNode)); + + temp = DFn3F1( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + here->ibb_x3, + here->ibb_y3, + here->ibb_z3, + here->ibb_x2y, + here->ibb_x2z, + here->ibb_xy2, + here->ibb_y2z, + here->ibb_xz2, + here->ibb_yz2, + here->ibb_xyz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); + + itemp = DFi3F1( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + here->ibb_x3, + here->ibb_y3, + here->ibb_z3, + here->ibb_x2y, + here->ibb_x2z, + here->ibb_xy2, + here->ibb_y2z, + here->ibb_xz2, + here->ibb_yz2, + here->ibb_xyz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + r2h11z, + i2h11z); + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; + + } + /* ibb term over */ + /* loading qbe term */ + /* x = vbe, y = vbc, z not used */ + /* (have to multiply by j omega for charge storage + * elements to get the current) + */ + + temp = - ckt->CKTomega* + DFi3F1( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + here->qbe_x3, + here->qbe_y3, + 0.0, + here->qbe_x2y, + 0.0, + here->qbe_xy2, + 0.0, + 0.0, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + 0.0, + 0.0); + + itemp = ckt->CKTomega* + DFn3F1( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + here->qbe_x3, + here->qbe_y3, + 0.0, + here->qbe_x2y, + 0.0, + here->qbe_xy2, + 0.0, + 0.0, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r2h11x, + i2h11x, + r2h11y, + i2h11y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* qbe term over */ + /* loading qbx term */ + /* z = vbx= vb - vcPrime */ + + r1h1z = r1h1z + r1h1y; + i1h1z = i1h1z + i1h1y; + r2h11z = r2h11z + r2h11y; + i2h11z = i2h11z + i2h11y; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = - ckt->CKTomega * + D1i3F1(here->capbx2, + here->capbx3, + r1h1z, + i1h1z, + r2h11z, + i2h11z); + itemp = ckt->CKTomega * + D1n3F1(here->capbx2, + here->capbx3, + r1h1z, + i1h1z, + r2h11z, + i2h11z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for D1n3F1: %g seconds \n", time); +#endif + + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbx term over */ + + /* loading qbc term */ + + temp = - ckt->CKTomega * + D1i3F1(here->capbc2, + here->capbc3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + itemp = ckt->CKTomega * + D1n3F1(here->capbc2, + here->capbc3, + r1h1y, + i1h1y, + r2h11y, + i2h11y); + + + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbc term over */ + + + /* loading qsc term */ + /* z = vsc */ + + + + r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + + r2h11z = *(job->r2H11ptr + (here->BJT2substNode)) - + *(job->r2H11ptr + (here->BJT2colPrimeNode)); + i2h11z = *(job->i2H11ptr + (here->BJT2substNode)) - + *(job->i2H11ptr + (here->BJT2colPrimeNode)); + + temp = - ckt->CKTomega * + D1i3F1(here->capsc2, + here->capsc3, + r1h1z, + i1h1z, + r2h11z, + i2h11z); + + itemp = ckt->CKTomega * + D1n3F1(here->capsc2, + here->capsc3, + r1h1z, + i1h1z, + r2h11z, + i2h11z); + + + *(ckt->CKTrhs + here->BJT2substNode) -= temp; + *(ckt->CKTirhs + here->BJT2substNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qsc term over */ + + + break; + case D_F1PF2: + /* ic term */ + + temp = DFnF12( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + itemp = DFiF12( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* finish ic term */ + /* loading ib term */ + /* x and y still the same */ +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = DFnF12( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + 0.0, + 0.0); + + itemp = DFiF12( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + 0.0, + 0.0); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for DFnF12: %g seconds \n", time); +#endif + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* ib term over */ + /* loading ibb term */ + if ( !((model->BJT2minBaseResist == 0.0) && + (model->BJT2baseResist == model->BJT2minBaseResist))) { + + /* now x = vbe, y = vbc, z = vbb */ + r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - + *(job->r1H1ptr + (here->BJT2basePrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - + *(job->i1H1ptr + (here->BJT2basePrimeNode)); + + r1h2z = *(job->r1H2ptr + (here->BJT2baseNode)) - + *(job->r1H2ptr + (here->BJT2basePrimeNode)); + i1h2z = *(job->i1H2ptr + (here->BJT2baseNode)) - + *(job->i1H2ptr + (here->BJT2basePrimeNode)); + + temp = DFnF12( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + itemp = DFiF12( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + r1h2z, + i1h2z); + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; + + } + /* ibb term over */ + /* loading qbe term */ + /* x = vbe, y = vbc, z not used */ + /* (have to multiply by j omega for charge storage + * elements - to get the current) + */ + + temp = - ckt->CKTomega* + DFiF12( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + 0.0, + 0.0); + + itemp = ckt->CKTomega* + DFnF12( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1h2x, + i1h2x, + r1h2y, + i1h2y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* qbe term over */ + /* loading qbx term */ + /* z = vbx= vb - vcPrime */ + + r1h1z = r1h1z + r1h1y; + i1h1z = i1h1z + i1h1y; + r1h2z = r1h2z + r1h2y; + i1h2z = i1h2z + i1h2y; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = - ckt->CKTomega * + D1iF12(here->capbx2, + r1h1z, + i1h1z, + r1h2z, + i1h2z); + itemp = ckt->CKTomega * + D1nF12(here->capbx2, + r1h1z, + i1h1z, + r1h2z, + i1h2z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for D1nF12: %g seconds \n", time); +#endif + + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbx term over */ + + /* loading qbc term */ + + temp = - ckt->CKTomega * + D1iF12(here->capbc2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + itemp = ckt->CKTomega * + D1nF12(here->capbc2, + r1h1y, + i1h1y, + r1h2y, + i1h2y); + + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbc term over */ + + + /* loading qsc term */ + /* z = vsc */ + + + + r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + r1h2z = *(job->r1H2ptr + (here->BJT2substNode)) - + *(job->r1H2ptr + (here->BJT2colPrimeNode)); + i1h2z = *(job->i1H2ptr + (here->BJT2substNode)) - + *(job->i1H2ptr + (here->BJT2colPrimeNode)); + + temp = - ckt->CKTomega * + D1iF12(here->capsc2, + r1h1z, + i1h1z, + r1h2z, + i1h2z); + itemp = ckt->CKTomega * + D1nF12(here->capsc2, + r1h1z, + i1h1z, + r1h2z, + i1h2z); + + + *(ckt->CKTrhs + here->BJT2substNode) -= temp; + *(ckt->CKTirhs + here->BJT2substNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qsc term over */ + + + break; + case D_F1MF2: + /* ic term */ + + temp = DFnF12( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + itemp = DFiF12( here->ic_x2, + here->ic_y2, + here->ic_w2, + here->ic_xy, + here->ic_yw, + here->ic_xw, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* finish ic term */ + /* loading ib term */ + /* x and y still the same */ + temp = DFnF12( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + 0.0, + 0.0); + + itemp = DFiF12( here->ib_x2, + here->ib_y2, + 0.0, + here->ib_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* ib term over */ + /* loading ibb term */ + if ( !((model->BJT2minBaseResist == 0.0) && + (model->BJT2baseResist == model->BJT2minBaseResist))) { + + /* now x = vbe, y = vbc, z = vbb */ + r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - + *(job->r1H1ptr + (here->BJT2basePrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - + *(job->i1H1ptr + (here->BJT2basePrimeNode)); + + r1hm2z = *(job->r1H2ptr + (here->BJT2baseNode)) - + *(job->r1H2ptr + (here->BJT2basePrimeNode)); + i1hm2z = *(job->i1H2ptr + (here->BJT2baseNode)) - + *(job->i1H2ptr + (here->BJT2basePrimeNode)); + + temp = DFnF12( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + itemp = DFiF12( here->ibb_x2, + here->ibb_y2, + here->ibb_z2, + here->ibb_xy, + here->ibb_yz, + here->ibb_xz, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + r1h1z, + i1h1z, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + r1hm2z, + i1hm2z); + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; + } + + /* ibb term over */ + /* loading qbe term */ + /* x = vbe, y = vbc, z not used */ + /* (have to multiply by j omega for charge storage + * elements - to get the current) + */ + + temp = - ckt->CKTomega* + DFiF12( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + 0.0, + 0.0); + + itemp = ckt->CKTomega* + DFnF12( here->qbe_x2, + here->qbe_y2, + 0.0, + here->qbe_xy, + 0.0, + 0.0, + r1h1x, + i1h1x, + r1h1y, + i1h1y, + 0.0, + 0.0, + r1hm2x, + i1hm2x, + r1hm2y, + i1hm2y, + 0.0, + 0.0); + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* qbe term over */ + /* loading qbx term */ + /* z = vbx= vb - vcPrime */ + + r1h1z = r1h1z + r1h1y; + i1h1z = i1h1z + i1h1y; + r1hm2z = r1hm2z + r1hm2y; + i1hm2z = i1hm2z + i1hm2y; + temp = - ckt->CKTomega * + D1iF12(here->capbx2, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z); + itemp = ckt->CKTomega * + D1nF12(here->capbx2, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z); + + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbx term over */ + + /* loading qbc term */ + + temp = - ckt->CKTomega * + D1iF12(here->capbc2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + itemp = ckt->CKTomega * + D1nF12(here->capbc2, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y); + + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbc term over */ + + + /* loading qsc term */ + /* z = vsc */ + + + + r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + r1hm2z = *(job->r1H2ptr + (here->BJT2substNode)) - + *(job->r1H2ptr + (here->BJT2colPrimeNode)); + i1hm2z = *(job->i1H2ptr + (here->BJT2substNode)) - + *(job->i1H2ptr + (here->BJT2colPrimeNode)); + + temp = - ckt->CKTomega * + D1iF12(here->capsc2, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z); + itemp = ckt->CKTomega * + D1nF12(here->capsc2, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z); + + + *(ckt->CKTrhs + here->BJT2substNode) -= temp; + *(ckt->CKTirhs + here->BJT2substNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qsc term over */ + + + break; + case D_2F1MF2: + /* ic term */ + + { + pass.cxx = here->ic_x2; + pass.cyy = here->ic_y2; + pass.czz = here->ic_w2; + pass.cxy = here->ic_xy; + pass.cyz = here->ic_yw; + pass.cxz = here->ic_xw; + pass.cxxx = here->ic_x3; + pass.cyyy = here->ic_y3; + pass.czzz = here->ic_w3; + pass.cxxy = here->ic_x2y; + pass.cxxz = here->ic_x2w; + pass.cxyy = here->ic_xy2; + pass.cyyz = here->ic_y2w; + pass.cxzz = here->ic_xw2; + pass.cyzz = here->ic_yw2; + pass.cxyz = here->ic_xyw; + pass.r1h1x = r1h1x; + pass.i1h1x = i1h1x; + pass.r1h1y = r1h1y; + pass.i1h1y = i1h1y; + pass.r1h1z = r1h1z; + pass.i1h1z = i1h1z; + pass.r1h2x = r1hm2x; + pass.i1h2x = i1hm2x; + pass.r1h2y = r1hm2y; + pass.i1h2y = i1hm2y; + pass.r1h2z = r1hm2z; + pass.i1h2z = i1hm2z; + pass.r2h11x = r2h11x; + pass.i2h11x = i2h11x; + pass.r2h11y = r2h11y; + pass.i2h11y = i2h11y; + pass.r2h11z = r2h11z; + pass.i2h11z = i2h11z; + pass.h2f1f2x = r2h1m2x; + pass.ih2f1f2x = i2h1m2x; + pass.h2f1f2y = r2h1m2y; + pass.ih2f1f2y = i2h1m2y; + pass.h2f1f2z = r2h1m2z; + pass.ih2f1f2z = i2h1m2z; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = DFn2F12(&pass); + + + itemp = DFi2F12(&pass); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for DFn2F12: %g seconds \n", time); +#endif + } + + *(ckt->CKTrhs + here->BJT2colPrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* finish ic term */ + /* loading ib term */ + /* x and y still the same */ + { + pass.cxx = here->ib_x2; + pass.cyy = here->ib_y2; + pass.czz = 0.0; + pass.cxy = here->ib_xy; + pass.cyz = 0.0; + pass.cxz = 0.0; + pass.cxxx = here->ib_x3; + pass.cyyy = here->ib_y3; + pass.czzz = 0.0; + pass.cxxy = here->ib_x2y; + pass.cxxz = 0.0; + pass.cxyy = here->ib_xy2; + pass.cyyz = 0.0; + pass.cxzz = 0.0; + pass.cyzz = 0.0; + pass.cxyz = 0.0; + pass.r1h1x = r1h1x; + pass.i1h1x = i1h1x; + pass.r1h1y = r1h1y; + pass.i1h1y = i1h1y; + pass.r1h1z = 0.0; + pass.i1h1z = 0.0; + pass.r1h2x = r1hm2x; + pass.i1h2x = i1hm2x; + pass.r1h2y = r1hm2y; + pass.i1h2y = i1hm2y; + pass.r1h2z = 0.0; + pass.i1h2z = 0.0; + pass.r2h11x = r2h11x; + pass.i2h11x = i2h11x; + pass.r2h11y = r2h11y; + pass.i2h11y = i2h11y; + pass.r2h11z = 0.0; + pass.i2h11z = 0.0; + pass.h2f1f2x = r2h1m2x; + pass.ih2f1f2x = i2h1m2x; + pass.h2f1f2y = r2h1m2y; + pass.ih2f1f2y = i2h1m2y; + pass.h2f1f2z = 0.0; + pass.ih2f1f2z = 0.0; + temp = DFn2F12(&pass); + + itemp = DFi2F12(&pass); + } + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* ib term over */ + /* loading ibb term */ + if ( !((model->BJT2minBaseResist == 0.0) && + (model->BJT2baseResist == model->BJT2minBaseResist))) { + + /* now x = vbe, y = vbc, z = vbb */ + r1h1z = *(job->r1H1ptr + (here->BJT2baseNode)) - + *(job->r1H1ptr + (here->BJT2basePrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2baseNode)) - + *(job->i1H1ptr + (here->BJT2basePrimeNode)); + + r1hm2z = *(job->r1H2ptr + (here->BJT2baseNode)) - + *(job->r1H2ptr + (here->BJT2basePrimeNode)); + i1hm2z = -(*(job->i1H2ptr + (here->BJT2baseNode)) - + *(job->i1H2ptr + (here->BJT2basePrimeNode))); + + r2h11z = *(job->r2H11ptr + (here->BJT2baseNode)) - + *(job->r2H11ptr + (here->BJT2basePrimeNode)); + i2h11z = *(job->i2H11ptr + (here->BJT2baseNode)) - + *(job->i2H11ptr + (here->BJT2basePrimeNode)); + + r2h1m2z = *(job->r2H1m2ptr + (here->BJT2baseNode)) - + *(job->r2H1m2ptr + (here->BJT2basePrimeNode)); + i2h1m2z = *(job->i2H1m2ptr + (here->BJT2baseNode)) - + *(job->i2H1m2ptr + (here->BJT2basePrimeNode)); + + { + pass.cxx = here->ibb_x2; + pass.cyy = here->ibb_y2; + pass.czz = here->ibb_z2; + pass.cxy = here->ibb_xy; + pass.cyz = here->ibb_yz; + pass.cxz = here->ibb_xz; + pass.cxxx = here->ibb_x3; + pass.cyyy = here->ibb_y3; + pass.czzz = here->ibb_z3; + pass.cxxy = here->ibb_x2y; + pass.cxxz = here->ibb_x2z; + pass.cxyy = here->ibb_xy2; + pass.cyyz = here->ibb_y2z; + pass.cxzz = here->ibb_xz2; + pass.cyzz = here->ibb_yz2; + pass.cxyz = here->ibb_xyz; + pass.r1h1x = r1h1x; + pass.i1h1x = i1h1x; + pass.r1h1y = r1h1y; + pass.i1h1y = i1h1y; + pass.r1h1z = r1h1z; + pass.i1h1z = i1h1z; + pass.r1h2x = r1hm2x; + pass.i1h2x = i1hm2x; + pass.r1h2y = r1hm2y; + pass.i1h2y = i1hm2y; + pass.r1h2z = r1hm2z; + pass.i1h2z = i1hm2z; + pass.r2h11x = r2h11x; + pass.i2h11x = i2h11x; + pass.r2h11y = r2h11y; + pass.i2h11y = i2h11y; + pass.r2h11z = r2h11z; + pass.i2h11z = i2h11z; + pass.h2f1f2x = r2h1m2x; + pass.ih2f1f2x = i2h1m2x; + pass.h2f1f2y = r2h1m2y; + pass.ih2f1f2y = i2h1m2y; + pass.h2f1f2z = r2h1m2z; + pass.ih2f1f2z = i2h1m2z; + temp = DFn2F12(&pass); + + itemp = DFi2F12(&pass); + } + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) += itemp; + + } + /* ibb term over */ + /* loading qbe term */ + /* x = vbe, y = vbc, z not used */ + /* (have to multiply by j omega for charge storage + * elements to get the current) + */ + + { + pass.cxx = here->qbe_x2; + pass.cyy = here->qbe_y2; + pass.czz = 0.0; + pass.cxy = here->qbe_xy; + pass.cyz = 0.0; + pass.cxz = 0.0; + pass.cxxx = here->qbe_x3; + pass.cyyy = here->qbe_y3; + pass.czzz = 0.0; + pass.cxxy = here->qbe_x2y; + pass.cxxz = 0.0; + pass.cxyy = here->qbe_xy2; + pass.cyyz = 0.0; + pass.cxzz = 0.0; + pass.cyzz = 0.0; + pass.cxyz = 0.0; + pass.r1h1x = r1h1x; + pass.i1h1x = i1h1x; + pass.r1h1y = r1h1y; + pass.i1h1y = i1h1y; + pass.r1h1z = 0.0; + pass.i1h1z = 0.0; + pass.r1h2x = r1hm2x; + pass.i1h2x = i1hm2x; + pass.r1h2y = r1hm2y; + pass.i1h2y = i1hm2y; + pass.r1h2z = 0.0; + pass.i1h2z = 0.0; + pass.r2h11x = r2h11x; + pass.i2h11x = i2h11x; + pass.r2h11y = r2h11y; + pass.i2h11y = i2h11y; + pass.r2h11z = 0.0; + pass.i2h11z = 0.0; + pass.h2f1f2x = r2h1m2x; + pass.ih2f1f2x = i2h1m2x; + pass.h2f1f2y = r2h1m2y; + pass.ih2f1f2y = i2h1m2y; + pass.h2f1f2z = 0.0; + pass.ih2f1f2z = 0.0; + temp = - ckt->CKTomega* + DFi2F12(&pass); + + itemp = ckt->CKTomega* + DFn2F12(&pass); + } + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2emitPrimeNode) += itemp; + + /* qbe term over */ + /* loading qbx term */ + /* z = vbx= vb - vcPrime */ + + r1h1z = r1h1z + r1h1y; + i1h1z = i1h1z + i1h1y; + r1hm2z = r1hm2z + r1hm2y; + i1hm2z = i1hm2z + i1hm2y; + r2h11z = r2h11z + r2h11y; + i2h11z = i2h11z + i2h11y; + r2h1m2z = r2h1m2z + r2h1m2y; + i2h1m2z = i2h1m2z + i2h1m2y; +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))(); +#endif + temp = - ckt->CKTomega * + D1i2F12(here->capbx2, + here->capbx3, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z, + r2h11z, + i2h11z, + r2h1m2z, + i2h1m2z); + itemp = ckt->CKTomega * + D1n2F12(here->capbx2, + here->capbx3, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z, + r2h11z, + i2h11z, + r2h1m2z, + i2h1m2z); +#ifdef D_DBG_SMALLTIMES +time = (*(SPfrontEnd->IFseconds))() - time; +printf("Time for D1n2F12: %g seconds \n", time); +#endif + + + *(ckt->CKTrhs + here->BJT2baseNode) -= temp; + *(ckt->CKTirhs + here->BJT2baseNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbx term over */ + + /* loading qbc term */ + + temp = - ckt->CKTomega * + D1i2F12(here->capbc2, + here->capbc3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + itemp = ckt->CKTomega * + D1n2F12(here->capbc2, + here->capbc3, + r1h1y, + i1h1y, + r1hm2y, + i1hm2y, + r2h11y, + i2h11y, + r2h1m2y, + i2h1m2y); + + + + + *(ckt->CKTrhs + here->BJT2basePrimeNode) -= temp; + *(ckt->CKTirhs + here->BJT2basePrimeNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qbc term over */ + + + /* loading qsc term */ + /* z = vsc */ + + + + r1h1z = *(job->r1H1ptr + (here->BJT2substNode)) - + *(job->r1H1ptr + (here->BJT2colPrimeNode)); + i1h1z = *(job->i1H1ptr + (here->BJT2substNode)) - + *(job->i1H1ptr + (here->BJT2colPrimeNode)); + + r1hm2z = *(job->r1H2ptr + (here->BJT2substNode)) - + *(job->r1H2ptr + (here->BJT2colPrimeNode)); + i1hm2z = -(*(job->i1H2ptr + (here->BJT2substNode)) - + *(job->i1H2ptr + (here->BJT2colPrimeNode))); + + r2h11z = *(job->r2H11ptr + (here->BJT2substNode)) - + *(job->r2H11ptr + (here->BJT2colPrimeNode)); + i2h11z = *(job->i2H11ptr + (here->BJT2substNode)) - + *(job->i2H11ptr + (here->BJT2colPrimeNode)); + + r2h1m2z = *(job->r2H1m2ptr + (here->BJT2substNode)) - + *(job->r2H1m2ptr + (here->BJT2colPrimeNode)); + i2h1m2z = *(job->i2H1m2ptr + (here->BJT2substNode)) - + *(job->i2H1m2ptr + (here->BJT2colPrimeNode)); + + temp = - ckt->CKTomega * + D1i2F12(here->capsc2, + here->capsc3, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z, + r2h11z, + i2h11z, + r2h1m2z, + i2h1m2z); + + itemp = ckt->CKTomega * + D1n2F12(here->capsc2, + here->capsc3, + r1h1z, + i1h1z, + r1hm2z, + i1hm2z, + r2h11z, + i2h11z, + r2h1m2z, + i2h1m2z); + + + *(ckt->CKTrhs + here->BJT2substNode) -= temp; + *(ckt->CKTirhs + here->BJT2substNode) -= itemp; + *(ckt->CKTrhs + here->BJT2colPrimeNode) += temp; + *(ckt->CKTirhs + here->BJT2colPrimeNode) += itemp; + + /* qsc term over */ + + + break; + default: +; + ; + } + } +} +return(OK); +} + else + return(E_BADPARM); +} diff --git a/src/spicelib/devices/bjt2/bjt2dset.c b/src/spicelib/devices/bjt2/bjt2dset.c index fcd78efb2..7f3b7360c 100644 --- a/src/spicelib/devices/bjt2/bjt2dset.c +++ b/src/spicelib/devices/bjt2/bjt2dset.c @@ -1,710 +1,708 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1988 Jaijeet S Roychowdhury -Modified: Alan Gillespie -**********/ - -#include "ngspice.h" -#include "cktdefs.h" -#include "bjt2defs.h" -#include "const.h" -#include "distodef.h" -#include "sperror.h" -#include "devdefs.h" -#include "suffix.h" - -/* - * This function initialises the Taylor coeffs for the - * BJT2's in the circuit - */ - -int -BJT2dSetup(inModel,ckt) - GENmodel *inModel; - CKTcircuit *ckt; - /* actually load the current resistance value into the - * sparse matrix previously provided - */ -{ - BJT2model *model = (BJT2model*)inModel; - BJT2instance *here; - double arg; - double c2; - double c4; - double lcapbe1,lcapbe2,lcapbe3; - double lcapbx1,lcapbx2,lcapbx3; - double cb; - double cbc; - double cbcn; - double cbe; - double cben; - double cdis; - double csat; - double ctot; - double czbc; - double czbcf2; - double czbe; - double czbef2; - double czbx; - double czbxf2; - double czcs; - double evbc; - double evbcn; - double evbe; - double evben; - double f1; - double f2; - double f3; - double fcpc; - double fcpe; - double gbb1; - double gbc; - double gbcn; - double gbe; - double gbe2,gbe3; - double gbc2,gbc3; - double gben2,gben3; - double gbcn2,gbcn3; - double gben; - double gbb2, gbb3; - double oik; - double oikr; - double ovtf; - double pc; - double pe; - double ps; - double q1; - double q2; - double qb; - double rbpi; - double rbpr; - double sarg; - double sqarg; - double tf; - double tr; - double vbc; - double vbe; - double vbx; - double vsc; - double vt; - double vtc; - double vte; - double vtn; - double xjrb; - double xjtf; - double xmc; - double xme; - double xms; - double xtf; - double vbed; - double vbb; - -double lcapbc1 = 0.0; -double lcapbc2 = 0.0; -double lcapbc3 = 0.0; - -double lcapsc1 = 0.0; -double lcapsc2 = 0.0; -double lcapsc3 = 0.0; -double ic; -double dummy; -Dderivs d_p, d_q, d_r; -Dderivs d_dummy, d_q1, d_qb, d_dummy2; -Dderivs d_arg, d_sqarg, d_ic, d_q2; -Dderivs d_z, d_tanz, d_vbb, d_ibb, d_rbb; -Dderivs d_ib, d_cbe, d_tff, d_qbe; - -d_p.value = 0.0; -d_p.d1_p = 1.0; -d_p.d1_q = 0.0; -d_p.d1_r = 0.0; -d_p.d2_p2 = 0.0; -d_p.d2_q2 = 0.0; -d_p.d2_r2 = 0.0; -d_p.d2_pq = 0.0; -d_p.d2_qr = 0.0; -d_p.d2_pr = 0.0; -d_p.d3_p3 = 0.0; -d_p.d3_q3 = 0.0; -d_p.d3_r3 = 0.0; -d_p.d3_p2q = 0.0; -d_p.d3_p2r = 0.0; -d_p.d3_pq2 = 0.0; -d_p.d3_q2r = 0.0; -d_p.d3_pr2 = 0.0; -d_p.d3_qr2 = 0.0; -d_p.d3_pqr = 0.0; - -EqualDeriv(&d_q, &d_p); -d_q.d1_q = 1.0; -d_q.d1_p = 0.0; - -EqualDeriv(&d_r, &d_p); -d_r.d1_r = 1.0; -d_r.d1_p = 0.0; - - -/* loop through all the models */ -for( ; model != NULL; model = model->BJT2nextModel ) { - - /* loop through all the instances of the model */ - for (here = model->BJT2instances; here != NULL ; - here=here->BJT2nextInstance) { - - vt = here->BJT2temp * CONSTKoverQ; - - - /* - * dc model paramters - */ - csat=here->BJT2tSatCur*here->BJT2area; - rbpr=model->BJT2minBaseResist/here->BJT2area; - rbpi=model->BJT2baseResist/here->BJT2area-rbpr; - oik=model->BJT2invRollOffF/here->BJT2area; - c2=here->BJT2tBEleakCur*here->BJT2area; - vte=model->BJT2leakBEemissionCoeff*vt; - oikr=model->BJT2invRollOffR/here->BJT2area; - c4=here->BJT2tBCleakCur*here->BJT2area; - vtc=model->BJT2leakBCemissionCoeff*vt; - xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area; - - - /* - * initialization - */ - vbe= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2basePrimeNode) - - *(ckt->CKTrhsOld + here->BJT2emitPrimeNode)); - vbc= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2baseNode) - - *(ckt->CKTrhsOld + here->BJT2colPrimeNode)); - vbx=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsc=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - - vbb=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode) - - *(ckt->CKTrhsOld+here->BJT2basePrimeNode)); - - - vbed = vbe; /* this is just a dummy variable - * it is the delayed vbe to be - * used in the delayed gm generator - */ - - - /* ic = f1(vbe,vbc,vbed) + f2(vbc) + f3(vbc) - * - * we shall calculate the taylor coeffs of - * ic wrt vbe, vbed, and vbc and store them away. - * the equations f1 f2 and f3 are given elsewhere; - * we shall start off with f1, compute - * derivs. upto third order and then do f2 and - * f3 and add their derivatives. - * - * Since f1 above is a function of three variables, it - * will be convenient to use derivative structures - * to compute the derivatives of f1. For this - * computation, p=vbe, q=vbc, r=vbed. - * - * ib = f1(vbe) + f2(vbc) (not the same f's as - * above, in case you are - * wondering!) - * the gbe's gbc's gben's and gbcn's are - * convenient subsidiary variables. - * - * irb = f(vbe, vbc, vbb) - the vbe & vbc - * dependencies arise from the - * qb term. - * qbe = f1(vbe,vbc) + f2(vbe) - * - * derivative structures will be used again in the - * above two equations. p=vbe, q=vbc, r=vbb. - * - * qbc = f(vbc) ; qbx = f(vbx) - * - * qss = f(vsc) - */ - /* - * determine dc current and derivitives - */ -next1: vtn=vt*model->BJT2emissionCoeffF; - if(vbe > -5*vtn){ - evbe=exp(vbe/vtn); - cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; - gbe=csat*evbe/vtn+ckt->CKTgmin; - gbe2 = csat*evbe/vtn/vtn; - gbe3 = gbe2/vtn; - - /* note - these are actually derivs, not Taylor - * coeffs. - not divided by 2! and 3! - */ - if (c2 == 0) { - cben=0; - gben=gben2=gben3=0; - } else { - evben=exp(vbe/vte); - cben=c2*(evben-1); - gben=c2*evben/vte; - gben2=gben/vte; - gben3=gben2/vte; - } - } else { - gbe = -csat/vbe+ckt->CKTgmin; - gbe2=gbe3=gben2=gben3=0; - cbe=gbe*vbe; - gben = -c2/vbe; - cben=gben*vbe; - } - vtn=vt*model->BJT2emissionCoeffR; - if(vbc > -5*vtn) { - evbc=exp(vbc/vtn); - cbc=csat*(evbc-1)+ckt->CKTgmin*vbc; - gbc=csat*evbc/vtn+ckt->CKTgmin; - gbc2=csat*evbc/vtn/vtn; - gbc3=gbc2/vtn; - if (c4 == 0) { - cbcn=0; - gbcn=0; - gbcn2=gbcn3=0; - } else { - evbcn=exp(vbc/vtc); - cbcn=c4*(evbcn-1); - gbcn=c4*evbcn/vtc; - gbcn2=gbcn/vtc; - gbcn3=gbcn2/vtc; - } - } else { - gbc = -csat/vbc+ckt->CKTgmin; - gbc2=gbc3=0; - cbc = gbc*vbc; - gbcn = -c4/vbc; - gbcn2=gbcn3=0; - cbcn=gbcn*vbc; - } - /* - * determine base charge terms - */ - /* q1 is a function of 2 variables p=vbe and q=vbc. r= - * anything - */ - q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); - dummy = (1-model->BJT2invEarlyVoltF*vbc- - model->BJT2invEarlyVoltR*vbe); - EqualDeriv(&d_dummy, &d_p); - d_dummy.value = dummy; - d_dummy.d1_p = - model->BJT2invEarlyVoltR; - d_dummy.d1_q = - model->BJT2invEarlyVoltF; - /* q1 = 1/dummy */ - InvDeriv(&d_q1, &d_dummy); /* now q1 and its derivatives are - set up */ - if(oik == 0 && oikr == 0) { - qb=q1; - EqualDeriv(&d_qb, &d_q1); - } else { - q2=oik*cbe+oikr*cbc; - EqualDeriv(&d_q2, &d_p); - d_q2.value = q2; - d_q2.d1_p = oik*gbe; - d_q2.d1_q = oikr*gbc; - d_q2.d2_p2 = oik*gbe2; - d_q2.d2_q2 = oikr*gbc2; - d_q2.d3_p3 = oik*gbe3; - d_q2.d3_q3 = oikr*gbc3; - arg=MAX(0,1+4*q2); - if (arg == 0.) - { - EqualDeriv(&d_arg,&d_p); - d_arg.d1_p = 0.0; - } - else - { - TimesDeriv(&d_arg,&d_q2,4.0); - d_arg.value += 1.; - } - sqarg=1; - EqualDeriv(&d_sqarg,&d_p); - d_sqarg.value = 1.0; - d_sqarg.d1_p = 0.0; - if(arg != 0){ - sqarg=sqrt(arg); - SqrtDeriv(&d_sqarg, &d_arg); - } - - qb=q1*(1+sqarg)/2; - dummy = 1 + sqarg; - EqualDeriv(&d_dummy, &d_sqarg); - d_dummy.value += 1.0; - MultDeriv(&d_qb, &d_q1, &d_dummy); - TimesDeriv(&d_qb, &d_qb, 0.5); - } - -ic = (cbe - cbc)/qb; -/* cbe is a fn of vbed only; cbc of vbc; and qb of vbe and vbc */ -/* p=vbe, q=vbc, r=vbed; now dummy = cbe - cbc */ -EqualDeriv(&d_dummy, &d_p); -d_dummy.d1_p = 0.0; -d_dummy.value = cbe-cbc; -d_dummy.d1_r = gbe; -d_dummy.d2_r2 = gbe2; -d_dummy.d3_r3 = gbe3; -d_dummy.d1_q = -gbc; -d_dummy.d2_q2 = -gbc2; -d_dummy.d3_q3 = -gbc3; - -DivDeriv(&d_ic, &d_dummy, &d_qb); - - -d_ic.value -= cbc/here->BJT2tBetaR + cbcn; -d_ic.d1_q -= gbc/here->BJT2tBetaR + gbcn; -d_ic.d2_q2 -= gbc2/here->BJT2tBetaR + gbcn2; -d_ic.d3_q3 -= gbc3/here->BJT2tBetaR + gbcn3; - -/* check this point: where is the f2(vbe) contribution to ic ? */ - - /* ic derivatives all set up now */ - /* base spread resistance */ - - if ( !((rbpr == 0.0) && (rbpi == 0.0))) - { - cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; - /* we are calculating derivatives w.r.t cb itself */ - /* - gx=rbpr+rbpi/qb; - */ - - if (cb != 0.0) { - if((xjrb != 0.0) && (rbpi != 0.0)) { - /* p = ib, q, r = anything */ - dummy=MAX(cb/xjrb,1e-9); - EqualDeriv(&d_dummy, &d_p); - d_dummy.value = dummy; - d_dummy.d1_p = 1/xjrb; - SqrtDeriv(&d_dummy, &d_dummy); - TimesDeriv(&d_dummy, &d_dummy, 2.4317); - - /* - dummy2=(-1+sqrt(1+14.59025*MAX(cb/xjrb,1e-9))); - */ - EqualDeriv(&d_dummy2, &d_p); - d_dummy2.value = 1+14.59025*MAX(cb/xjrb,1e-9); - d_dummy2.d1_p = 14.59025/xjrb; - SqrtDeriv(&d_dummy2, &d_dummy2); - d_dummy2.value -= 1.0; - - DivDeriv(&d_z, &d_dummy2, &d_dummy); - TanDeriv(&d_tanz, &d_z); - - /*now using dummy = tanz - z and dummy2 = z*tanz*tanz */ - TimesDeriv(&d_dummy, &d_z, -1.0); - PlusDeriv(&d_dummy, &d_dummy, &d_tanz); - - MultDeriv(&d_dummy2, &d_tanz, &d_tanz); - MultDeriv(&d_dummy2, &d_dummy2, &d_z); - - DivDeriv(&d_rbb , &d_dummy, &d_dummy2); - TimesDeriv(&d_rbb,&d_rbb, 3.0*rbpi); - d_rbb.value += rbpr; - - MultDeriv(&d_vbb, &d_rbb, &d_p); - - /* power series inversion to get the conductance derivatives */ - - if (d_vbb.d1_p != 0) { - gbb1 = 1/d_vbb.d1_p; - gbb2 = -(d_vbb.d2_p2*0.5)*gbb1*gbb1; - gbb3 = gbb1*gbb1*gbb1*gbb1*(-(d_vbb.d3_p3/6.0) - + 2*(d_vbb.d2_p2*0.5)*(d_vbb.d2_p2*0.5)*gbb1); - } - else - printf("\nd_vbb.d1_p = 0 in base spread resistance calculations\n"); - - -/* r = vbb */ -EqualDeriv(&d_ibb, &d_r); -d_ibb.value = cb; -d_ibb.d1_r = gbb1; -d_ibb.d2_r2 = 2*gbb2; -d_ibb.d3_r3 = 6.0*gbb3; - } - else - { - /* - rbb = rbpr + rbpi/qb; - ibb = vbb /rbb; = f(vbe, vbc, vbb) - */ - - EqualDeriv(&d_rbb,&d_p); - d_rbb.d1_p = 0.0; - if (rbpi != 0.0) { - InvDeriv(&d_rbb, &d_qb); - TimesDeriv(&d_rbb, &d_rbb,rbpi); - } - d_rbb.value += rbpr; - - EqualDeriv(&d_ibb,&d_r); - d_ibb.value = vbb; - DivDeriv(&d_ibb,&d_ibb,&d_rbb); - - } - } - else - { - EqualDeriv(&d_ibb,&d_r); - if (rbpr != 0.0) - d_ibb.d1_r = 1/rbpr; - } - } - else - { - EqualDeriv(&d_ibb,&d_p); - d_ibb.d1_p = 0.0; - } - - /* formulae for base spread resistance over! */ - - /* ib term */ - - EqualDeriv(&d_ib, &d_p); - d_ib.d1_p = 0.0; - d_ib.value = cb; - d_ib.d1_p = gbe/here->BJT2tBetaF + gben; - d_ib.d2_p2 = gbe2/here->BJT2tBetaF + gben2; - d_ib.d3_p3 = gbe3/here->BJT2tBetaF + gben3; - - d_ib.d1_q = gbc/here->BJT2tBetaR + gbcn; - d_ib.d2_q2 = gbc2/here->BJT2tBetaR + gbcn2; - d_ib.d3_q3 = gbc3/here->BJT2tBetaR + gbcn3; - - /* ib term over */ - /* - * charge storage elements - */ - tf=model->BJT2transitTimeF; - tr=model->BJT2transitTimeR; - czbe=here->BJT2tBEcap*here->BJT2area; - pe=here->BJT2tBEpot; - xme=model->BJT2junctionExpBE; - cdis=model->BJT2baseFractionBCcap; - ctot=here->BJT2tBCcap*here->BJT2area; - czbc=ctot*cdis; - czbx=ctot-czbc; - pc=here->BJT2tBCpot; - xmc=model->BJT2junctionExpBC; - fcpe=here->BJT2tDepCap; - czcs=model->BJT2capSub*here->BJT2area; /* PN */ - ps=model->BJT2potentialSubstrate; - xms=model->BJT2exponentialSubstrate; - xtf=model->BJT2transitTimeBiasCoeffF; - ovtf=model->BJT2transitTimeVBCFactor; - xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area; - if(tf != 0 && vbe >0) { - EqualDeriv(&d_cbe, &d_p); - d_cbe.value = cbe; - d_cbe.d1_p = gbe; - d_cbe.d2_p2 = gbe2; - d_cbe.d3_p3 = gbe3; - if(xtf != 0){ - if(ovtf != 0) { - /* dummy = exp ( vbc*ovtf) */ - EqualDeriv(&d_dummy, &d_q); - d_dummy.value = vbc*ovtf; - d_dummy.d1_q = ovtf; - ExpDeriv(&d_dummy, &d_dummy); - } - else - { - EqualDeriv(&d_dummy,&d_p); - d_dummy.value = 1.0; - d_dummy.d1_p = 0.0; - } - if(xjtf != 0) { - EqualDeriv(&d_dummy2, &d_cbe); - d_dummy2.value += xjtf; - DivDeriv(&d_dummy2, &d_cbe, &d_dummy2); - MultDeriv (&d_dummy2, &d_dummy2, &d_dummy2); - } - else - { - EqualDeriv(&d_dummy2,&d_p); - d_dummy2.value = 1.0; - d_dummy2.d1_p = 0.0; - } - - MultDeriv(&d_tff, &d_dummy, &d_dummy2); - TimesDeriv(&d_tff, &d_tff, tf*xtf); - d_tff.value += tf; - } - else - { - EqualDeriv(&d_tff,&d_p); - d_tff.value = tf; - d_tff.d1_p = 0.0; - } - - - - - /* qbe = tff/qb*cbe */ - -/* - dummy = tff/qb; - */ - /* these are the cbe coeffs */ -DivDeriv(&d_dummy, &d_tff, &d_qb); -MultDeriv(&d_qbe, &d_dummy, &d_cbe); - - } - else - { - EqualDeriv(&d_qbe, &d_p); - d_qbe.value = 0.0; - d_qbe.d1_p = 0.0; - } - if (vbe < fcpe) { - arg=1-vbe/pe; - sarg=exp(-xme*log(arg)); - lcapbe1 = czbe*sarg; - lcapbe2 = - 0.5*czbe*xme*sarg/(arg*pe); - lcapbe3 = - czbe*xme*(xme+1)*sarg/(arg*arg*pe*pe*6); - } else { - f1=here->BJT2tf1; - f2=model->BJT2f2; - f3=model->BJT2f3; - czbef2=czbe/f2; - lcapbe1 = czbef2*(f3+xme*vbe/pe); - lcapbe2 = 0.5*xme*czbef2/pe; - lcapbe3 = 0.0; - } - d_qbe.d1_p += lcapbe1; - d_qbe.d2_p2 += lcapbe2*2.; - d_qbe.d3_p3 += lcapbe3*6.; - - - fcpc=here->BJT2tf4; - f1=here->BJT2tf5; - f2=model->BJT2f6; - f3=model->BJT2f7; - if (vbc < fcpc) { - arg=1-vbc/pc; - sarg=exp(-xmc*log(arg)); - lcapbc1 = czbc*sarg; - lcapbc2 = - 0.5*czbc*xmc*sarg/(arg*pc); - lcapbc3 = - czbc*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); - } else { - czbcf2=czbc/f2; - lcapbc1 = czbcf2*(f3+xmc*vbc/pc); - lcapbc2 = 0.5*xmc*czbcf2/pc; - lcapbc3 = 0; - } - if(vbx < fcpc) { - arg=1-vbx/pc; - sarg=exp(-xmc*log(arg)); - lcapbx1 = czbx*sarg; - lcapbx2 = - 0.5*czbx*xmc*sarg/(arg*pc); - lcapbx3 = - czbx*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); - } else { - czbxf2=czbx/f2; - lcapbx1 = czbxf2*(f3+xmc*vbx/pc); - lcapbx2 = 0.5*xmc*czbxf2/pc; - lcapbx3 = 0; - } - if(vsc < 0){ - arg=1-vsc/ps; - sarg=exp(-xms*log(arg)); - lcapsc1 = czcs*sarg; - lcapsc2 = - 0.5*czcs*xms*sarg/(arg*ps); - lcapsc3 = - czcs*xms*(xms+1)*sarg/(arg*arg*ps*ps*6); - } else { - lcapsc1 = czcs*(1+xms*vsc/ps); - lcapsc2 = czcs*0.5*xms/ps; - lcapsc3 = 0; - } - - /* - * store small-signal parameters - */ -here->ic_x = d_ic.d1_p; -here->ic_y = d_ic.d1_q; -here->ic_xd = d_ic.d1_r; -here->ic_x2 = 0.5*model->BJT2type*d_ic.d2_p2; -here->ic_y2 = 0.5*model->BJT2type*d_ic.d2_q2; -here->ic_w2 = 0.5*model->BJT2type*d_ic.d2_r2; -here->ic_xy = model->BJT2type*d_ic.d2_pq; -here->ic_yw = model->BJT2type*d_ic.d2_qr; -here->ic_xw = model->BJT2type*d_ic.d2_pr; -here->ic_x3 = d_ic.d3_p3/6.; -here->ic_y3 = d_ic.d3_q3/6.; -here->ic_w3 = d_ic.d3_r3/6.; -here->ic_x2w = 0.5*d_ic.d3_p2r; -here->ic_x2y = 0.5*d_ic.d3_p2q; -here->ic_y2w = 0.5*d_ic.d3_q2r; -here->ic_xy2 = 0.5*d_ic.d3_pq2; -here->ic_xw2 = 0.5*d_ic.d3_pr2; -here->ic_yw2 = 0.5*d_ic.d3_qr2; -here->ic_xyw = d_ic.d3_pqr; - -here->ib_x = d_ib.d1_p; -here->ib_y = d_ib.d1_q; -here->ib_x2 = 0.5*model->BJT2type*d_ib.d2_p2; -here->ib_y2 = 0.5*model->BJT2type*d_ib.d2_q2; -here->ib_xy = model->BJT2type*d_ib.d2_pq; -here->ib_x3 = d_ib.d3_p3/6.; -here->ib_y3 = d_ib.d3_q3/6.; -here->ib_x2y = 0.5*d_ib.d3_p2q; -here->ib_xy2 = 0.5*d_ib.d3_pq2; - -here->ibb_x = d_ibb.d1_p; -here->ibb_y = d_ibb.d1_q; -here->ibb_z = d_ibb.d1_r; -here->ibb_x2 = 0.5*model->BJT2type*d_ibb.d2_p2; -here->ibb_y2 = 0.5*model->BJT2type*d_ibb.d2_q2; -here->ibb_z2 = 0.5*model->BJT2type*d_ibb.d2_r2; -here->ibb_xy = model->BJT2type*d_ibb.d2_pq; -here->ibb_yz = model->BJT2type*d_ibb.d2_qr; -here->ibb_xz = model->BJT2type*d_ibb.d2_pr; -here->ibb_x3 = d_ibb.d3_p3/6.; -here->ibb_y3 = d_ibb.d3_q3/6.; -here->ibb_z3 = d_ibb.d3_r3/6.; -here->ibb_x2z = 0.5*d_ibb.d3_p2r; -here->ibb_x2y = 0.5*d_ibb.d3_p2q; -here->ibb_y2z = 0.5*d_ibb.d3_q2r; -here->ibb_xy2 = 0.5*d_ibb.d3_pq2; -here->ibb_xz2 = 0.5*d_ibb.d3_pr2; -here->ibb_yz2 = 0.5*d_ibb.d3_qr2; -here->ibb_xyz = d_ibb.d3_pqr; - -here->qbe_x = d_qbe.d1_p; -here->qbe_y = d_qbe.d1_q; -here->qbe_x2 = 0.5*model->BJT2type*d_qbe.d2_p2; -here->qbe_y2 = 0.5*model->BJT2type*d_qbe.d2_q2; -here->qbe_xy = model->BJT2type*d_qbe.d2_pq; -here->qbe_x3 = d_qbe.d3_p3/6.; -here->qbe_y3 = d_qbe.d3_q3/6.; -here->qbe_x2y = 0.5*d_qbe.d3_p2q; -here->qbe_xy2 = 0.5*d_qbe.d3_pq2; - -here->capbc1 = lcapbc1; -here->capbc2 = lcapbc2; -here->capbc3 = lcapbc3; - -here->capbx1 = lcapbx1; -here->capbx2 = lcapbx2; -here->capbx3 = lcapbx3; - -here->capsc1 = lcapsc1; -here->capsc2 = lcapsc2; -here->capsc3 = lcapsc3; - } - } - return(OK); - } +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1988 Jaijeet S Roychowdhury +Modified: Alan Gillespie +**********/ + +#include "ngspice.h" +#include "cktdefs.h" +#include "bjt2defs.h" +#include "const.h" +#include "distodef.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +/* + * This function initialises the Taylor coeffs for the + * BJT2's in the circuit + */ + +int +BJT2dSetup(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current resistance value into the + * sparse matrix previously provided + */ +{ + BJT2model *model = (BJT2model*)inModel; + BJT2instance *here; + double arg; + double c2; + double c4; + double lcapbe1,lcapbe2,lcapbe3; + double lcapbx1,lcapbx2,lcapbx3; + double cb; + double cbc; + double cbcn; + double cbe; + double cben; + double cdis; + double csat; + double ctot; + double czbc; + double czbcf2; + double czbe; + double czbef2; + double czbx; + double czbxf2; + double czcs; + double evbc; + double evbcn; + double evbe; + double evben; + double f1; + double f2; + double f3; + double fcpc; + double fcpe; + double gbb1; + double gbc; + double gbcn; + double gbe; + double gbe2,gbe3; + double gbc2,gbc3; + double gben2,gben3; + double gbcn2,gbcn3; + double gben; + double gbb2, gbb3; + double oik; + double oikr; + double ovtf; + double pc; + double pe; + double ps; + double q1; + double q2; + double qb; + double rbpi; + double rbpr; + double sarg; + double sqarg; + double tf; + double tr; + double vbc; + double vbe; + double vbx; + double vsc; + double vt; + double vtc; + double vte; + double vtn; + double xjrb; + double xjtf; + double xmc; + double xme; + double xms; + double xtf; + double vbed; + double vbb; + +double lcapbc1 = 0.0; +double lcapbc2 = 0.0; +double lcapbc3 = 0.0; + +double lcapsc1 = 0.0; +double lcapsc2 = 0.0; +double lcapsc3 = 0.0; +double ic; +double dummy; +Dderivs d_p, d_q, d_r; +Dderivs d_dummy, d_q1, d_qb, d_dummy2; +Dderivs d_arg, d_sqarg, d_ic, d_q2; +Dderivs d_z, d_tanz, d_vbb, d_ibb, d_rbb; +Dderivs d_ib, d_cbe, d_tff, d_qbe; + +d_p.value = 0.0; +d_p.d1_p = 1.0; +d_p.d1_q = 0.0; +d_p.d1_r = 0.0; +d_p.d2_p2 = 0.0; +d_p.d2_q2 = 0.0; +d_p.d2_r2 = 0.0; +d_p.d2_pq = 0.0; +d_p.d2_qr = 0.0; +d_p.d2_pr = 0.0; +d_p.d3_p3 = 0.0; +d_p.d3_q3 = 0.0; +d_p.d3_r3 = 0.0; +d_p.d3_p2q = 0.0; +d_p.d3_p2r = 0.0; +d_p.d3_pq2 = 0.0; +d_p.d3_q2r = 0.0; +d_p.d3_pr2 = 0.0; +d_p.d3_qr2 = 0.0; +d_p.d3_pqr = 0.0; + +EqualDeriv(&d_q, &d_p); +d_q.d1_q = 1.0; +d_q.d1_p = 0.0; + +EqualDeriv(&d_r, &d_p); +d_r.d1_r = 1.0; +d_r.d1_p = 0.0; + + +/* loop through all the models */ +for( ; model != NULL; model = model->BJT2nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->BJT2instances; here != NULL ; + here=here->BJT2nextInstance) { + + vt = here->BJT2temp * CONSTKoverQ; + + + /* + * dc model paramters + */ + csat=here->BJT2tSatCur*here->BJT2area; + rbpr=model->BJT2minBaseResist/here->BJT2area; + rbpi=model->BJT2baseResist/here->BJT2area-rbpr; + oik=model->BJT2invRollOffF/here->BJT2area; + c2=here->BJT2tBEleakCur*here->BJT2area; + vte=model->BJT2leakBEemissionCoeff*vt; + oikr=model->BJT2invRollOffR/here->BJT2area; + c4=here->BJT2tBCleakCur*here->BJT2area; + vtc=model->BJT2leakBCemissionCoeff*vt; + xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area; + + + /* + * initialization + */ + vbe= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2basePrimeNode) - + *(ckt->CKTrhsOld + here->BJT2emitPrimeNode)); + vbc= model->BJT2type*(*(ckt->CKTrhsOld + here->BJT2baseNode) - + *(ckt->CKTrhsOld + here->BJT2colPrimeNode)); + vbx=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsc=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + + vbb=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode) - + *(ckt->CKTrhsOld+here->BJT2basePrimeNode)); + + + vbed = vbe; /* this is just a dummy variable + * it is the delayed vbe to be + * used in the delayed gm generator + */ + + + /* ic = f1(vbe,vbc,vbed) + f2(vbc) + f3(vbc) + * + * we shall calculate the taylor coeffs of + * ic wrt vbe, vbed, and vbc and store them away. + * the equations f1 f2 and f3 are given elsewhere; + * we shall start off with f1, compute + * derivs. upto third order and then do f2 and + * f3 and add their derivatives. + * + * Since f1 above is a function of three variables, it + * will be convenient to use derivative structures + * to compute the derivatives of f1. For this + * computation, p=vbe, q=vbc, r=vbed. + * + * ib = f1(vbe) + f2(vbc) (not the same f's as + * above, in case you are + * wondering!) + * the gbe's gbc's gben's and gbcn's are + * convenient subsidiary variables. + * + * irb = f(vbe, vbc, vbb) - the vbe & vbc + * dependencies arise from the + * qb term. + * qbe = f1(vbe,vbc) + f2(vbe) + * + * derivative structures will be used again in the + * above two equations. p=vbe, q=vbc, r=vbb. + * + * qbc = f(vbc) ; qbx = f(vbx) + * + * qss = f(vsc) + */ + /* + * determine dc current and derivitives + */ +next1: vtn=vt*model->BJT2emissionCoeffF; + if(vbe > -5*vtn){ + evbe=exp(vbe/vtn); + cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; + gbe=csat*evbe/vtn+ckt->CKTgmin; + gbe2 = csat*evbe/vtn/vtn; + gbe3 = gbe2/vtn; + + /* note - these are actually derivs, not Taylor + * coeffs. - not divided by 2! and 3! + */ + if (c2 == 0) { + cben=0; + gben=gben2=gben3=0; + } else { + evben=exp(vbe/vte); + cben=c2*(evben-1); + gben=c2*evben/vte; + gben2=gben/vte; + gben3=gben2/vte; + } + } else { + gbe = -csat/vbe+ckt->CKTgmin; + gbe2=gbe3=gben2=gben3=0; + cbe=gbe*vbe; + gben = -c2/vbe; + cben=gben*vbe; + } + vtn=vt*model->BJT2emissionCoeffR; + if(vbc > -5*vtn) { + evbc=exp(vbc/vtn); + cbc=csat*(evbc-1)+ckt->CKTgmin*vbc; + gbc=csat*evbc/vtn+ckt->CKTgmin; + gbc2=csat*evbc/vtn/vtn; + gbc3=gbc2/vtn; + if (c4 == 0) { + cbcn=0; + gbcn=0; + gbcn2=gbcn3=0; + } else { + evbcn=exp(vbc/vtc); + cbcn=c4*(evbcn-1); + gbcn=c4*evbcn/vtc; + gbcn2=gbcn/vtc; + gbcn3=gbcn2/vtc; + } + } else { + gbc = -csat/vbc+ckt->CKTgmin; + gbc2=gbc3=0; + cbc = gbc*vbc; + gbcn = -c4/vbc; + gbcn2=gbcn3=0; + cbcn=gbcn*vbc; + } + /* + * determine base charge terms + */ + /* q1 is a function of 2 variables p=vbe and q=vbc. r= + * anything + */ + q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); + dummy = (1-model->BJT2invEarlyVoltF*vbc- + model->BJT2invEarlyVoltR*vbe); + EqualDeriv(&d_dummy, &d_p); + d_dummy.value = dummy; + d_dummy.d1_p = - model->BJT2invEarlyVoltR; + d_dummy.d1_q = - model->BJT2invEarlyVoltF; + /* q1 = 1/dummy */ + InvDeriv(&d_q1, &d_dummy); /* now q1 and its derivatives are + set up */ + if(oik == 0 && oikr == 0) { + qb=q1; + EqualDeriv(&d_qb, &d_q1); + } else { + q2=oik*cbe+oikr*cbc; + EqualDeriv(&d_q2, &d_p); + d_q2.value = q2; + d_q2.d1_p = oik*gbe; + d_q2.d1_q = oikr*gbc; + d_q2.d2_p2 = oik*gbe2; + d_q2.d2_q2 = oikr*gbc2; + d_q2.d3_p3 = oik*gbe3; + d_q2.d3_q3 = oikr*gbc3; + arg=MAX(0,1+4*q2); + if (arg == 0.) + { + EqualDeriv(&d_arg,&d_p); + d_arg.d1_p = 0.0; + } + else + { + TimesDeriv(&d_arg,&d_q2,4.0); + d_arg.value += 1.; + } + sqarg=1; + EqualDeriv(&d_sqarg,&d_p); + d_sqarg.value = 1.0; + d_sqarg.d1_p = 0.0; + if(arg != 0){ + sqarg=sqrt(arg); + SqrtDeriv(&d_sqarg, &d_arg); + } + + qb=q1*(1+sqarg)/2; + dummy = 1 + sqarg; + EqualDeriv(&d_dummy, &d_sqarg); + d_dummy.value += 1.0; + MultDeriv(&d_qb, &d_q1, &d_dummy); + TimesDeriv(&d_qb, &d_qb, 0.5); + } + +ic = (cbe - cbc)/qb; +/* cbe is a fn of vbed only; cbc of vbc; and qb of vbe and vbc */ +/* p=vbe, q=vbc, r=vbed; now dummy = cbe - cbc */ +EqualDeriv(&d_dummy, &d_p); +d_dummy.d1_p = 0.0; +d_dummy.value = cbe-cbc; +d_dummy.d1_r = gbe; +d_dummy.d2_r2 = gbe2; +d_dummy.d3_r3 = gbe3; +d_dummy.d1_q = -gbc; +d_dummy.d2_q2 = -gbc2; +d_dummy.d3_q3 = -gbc3; + +DivDeriv(&d_ic, &d_dummy, &d_qb); + + +d_ic.value -= cbc/here->BJT2tBetaR + cbcn; +d_ic.d1_q -= gbc/here->BJT2tBetaR + gbcn; +d_ic.d2_q2 -= gbc2/here->BJT2tBetaR + gbcn2; +d_ic.d3_q3 -= gbc3/here->BJT2tBetaR + gbcn3; + +/* check this point: where is the f2(vbe) contribution to ic ? */ + + /* ic derivatives all set up now */ + /* base spread resistance */ + + if ( !((rbpr == 0.0) && (rbpi == 0.0))) + { + cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; + /* we are calculating derivatives w.r.t cb itself */ + /* + gx=rbpr+rbpi/qb; + */ + + if (cb != 0.0) { + if((xjrb != 0.0) && (rbpi != 0.0)) { + /* p = ib, q, r = anything */ + dummy=MAX(cb/xjrb,1e-9); + EqualDeriv(&d_dummy, &d_p); + d_dummy.value = dummy; + d_dummy.d1_p = 1/xjrb; + SqrtDeriv(&d_dummy, &d_dummy); + TimesDeriv(&d_dummy, &d_dummy, 2.4317); + + /* + dummy2=(-1+sqrt(1+14.59025*MAX(cb/xjrb,1e-9))); + */ + EqualDeriv(&d_dummy2, &d_p); + d_dummy2.value = 1+14.59025*MAX(cb/xjrb,1e-9); + d_dummy2.d1_p = 14.59025/xjrb; + SqrtDeriv(&d_dummy2, &d_dummy2); + d_dummy2.value -= 1.0; + + DivDeriv(&d_z, &d_dummy2, &d_dummy); + TanDeriv(&d_tanz, &d_z); + + /*now using dummy = tanz - z and dummy2 = z*tanz*tanz */ + TimesDeriv(&d_dummy, &d_z, -1.0); + PlusDeriv(&d_dummy, &d_dummy, &d_tanz); + + MultDeriv(&d_dummy2, &d_tanz, &d_tanz); + MultDeriv(&d_dummy2, &d_dummy2, &d_z); + + DivDeriv(&d_rbb , &d_dummy, &d_dummy2); + TimesDeriv(&d_rbb,&d_rbb, 3.0*rbpi); + d_rbb.value += rbpr; + + MultDeriv(&d_vbb, &d_rbb, &d_p); + + /* power series inversion to get the conductance derivatives */ + + if (d_vbb.d1_p != 0) { + gbb1 = 1/d_vbb.d1_p; + gbb2 = -(d_vbb.d2_p2*0.5)*gbb1*gbb1; + gbb3 = gbb1*gbb1*gbb1*gbb1*(-(d_vbb.d3_p3/6.0) + + 2*(d_vbb.d2_p2*0.5)*(d_vbb.d2_p2*0.5)*gbb1); + } + else + printf("\nd_vbb.d1_p = 0 in base spread resistance calculations\n"); + + +/* r = vbb */ +EqualDeriv(&d_ibb, &d_r); +d_ibb.value = cb; +d_ibb.d1_r = gbb1; +d_ibb.d2_r2 = 2*gbb2; +d_ibb.d3_r3 = 6.0*gbb3; + } + else + { + /* + rbb = rbpr + rbpi/qb; + ibb = vbb /rbb; = f(vbe, vbc, vbb) + */ + + EqualDeriv(&d_rbb,&d_p); + d_rbb.d1_p = 0.0; + if (rbpi != 0.0) { + InvDeriv(&d_rbb, &d_qb); + TimesDeriv(&d_rbb, &d_rbb,rbpi); + } + d_rbb.value += rbpr; + + EqualDeriv(&d_ibb,&d_r); + d_ibb.value = vbb; + DivDeriv(&d_ibb,&d_ibb,&d_rbb); + + } + } + else + { + EqualDeriv(&d_ibb,&d_r); + if (rbpr != 0.0) + d_ibb.d1_r = 1/rbpr; + } + } + else + { + EqualDeriv(&d_ibb,&d_p); + d_ibb.d1_p = 0.0; + } + + /* formulae for base spread resistance over! */ + + /* ib term */ + + EqualDeriv(&d_ib, &d_p); + d_ib.d1_p = 0.0; + d_ib.value = cb; + d_ib.d1_p = gbe/here->BJT2tBetaF + gben; + d_ib.d2_p2 = gbe2/here->BJT2tBetaF + gben2; + d_ib.d3_p3 = gbe3/here->BJT2tBetaF + gben3; + + d_ib.d1_q = gbc/here->BJT2tBetaR + gbcn; + d_ib.d2_q2 = gbc2/here->BJT2tBetaR + gbcn2; + d_ib.d3_q3 = gbc3/here->BJT2tBetaR + gbcn3; + + /* ib term over */ + /* + * charge storage elements + */ + tf=model->BJT2transitTimeF; + tr=model->BJT2transitTimeR; + czbe=here->BJT2tBEcap*here->BJT2area; + pe=here->BJT2tBEpot; + xme=model->BJT2junctionExpBE; + cdis=model->BJT2baseFractionBCcap; + ctot=here->BJT2tBCcap*here->BJT2area; + czbc=ctot*cdis; + czbx=ctot-czbc; + pc=here->BJT2tBCpot; + xmc=model->BJT2junctionExpBC; + fcpe=here->BJT2tDepCap; + czcs=model->BJT2capSub*here->BJT2area; /* PN */ + ps=model->BJT2potentialSubstrate; + xms=model->BJT2exponentialSubstrate; + xtf=model->BJT2transitTimeBiasCoeffF; + ovtf=model->BJT2transitTimeVBCFactor; + xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area; + if(tf != 0 && vbe >0) { + EqualDeriv(&d_cbe, &d_p); + d_cbe.value = cbe; + d_cbe.d1_p = gbe; + d_cbe.d2_p2 = gbe2; + d_cbe.d3_p3 = gbe3; + if(xtf != 0){ + if(ovtf != 0) { + /* dummy = exp ( vbc*ovtf) */ + EqualDeriv(&d_dummy, &d_q); + d_dummy.value = vbc*ovtf; + d_dummy.d1_q = ovtf; + ExpDeriv(&d_dummy, &d_dummy); + } + else + { + EqualDeriv(&d_dummy,&d_p); + d_dummy.value = 1.0; + d_dummy.d1_p = 0.0; + } + if(xjtf != 0) { + EqualDeriv(&d_dummy2, &d_cbe); + d_dummy2.value += xjtf; + DivDeriv(&d_dummy2, &d_cbe, &d_dummy2); + MultDeriv (&d_dummy2, &d_dummy2, &d_dummy2); + } + else + { + EqualDeriv(&d_dummy2,&d_p); + d_dummy2.value = 1.0; + d_dummy2.d1_p = 0.0; + } + + MultDeriv(&d_tff, &d_dummy, &d_dummy2); + TimesDeriv(&d_tff, &d_tff, tf*xtf); + d_tff.value += tf; + } + else + { + EqualDeriv(&d_tff,&d_p); + d_tff.value = tf; + d_tff.d1_p = 0.0; + } + + + + + /* qbe = tff/qb*cbe */ + +/* + dummy = tff/qb; + */ + /* these are the cbe coeffs */ +DivDeriv(&d_dummy, &d_tff, &d_qb); +MultDeriv(&d_qbe, &d_dummy, &d_cbe); + + } + else + { + EqualDeriv(&d_qbe, &d_p); + d_qbe.value = 0.0; + d_qbe.d1_p = 0.0; + } + if (vbe < fcpe) { + arg=1-vbe/pe; + sarg=exp(-xme*log(arg)); + lcapbe1 = czbe*sarg; + lcapbe2 = + 0.5*czbe*xme*sarg/(arg*pe); + lcapbe3 = + czbe*xme*(xme+1)*sarg/(arg*arg*pe*pe*6); + } else { + f1=here->BJT2tf1; + f2=model->BJT2f2; + f3=model->BJT2f3; + czbef2=czbe/f2; + lcapbe1 = czbef2*(f3+xme*vbe/pe); + lcapbe2 = 0.5*xme*czbef2/pe; + lcapbe3 = 0.0; + } + d_qbe.d1_p += lcapbe1; + d_qbe.d2_p2 += lcapbe2*2.; + d_qbe.d3_p3 += lcapbe3*6.; + + + fcpc=here->BJT2tf4; + f1=here->BJT2tf5; + f2=model->BJT2f6; + f3=model->BJT2f7; + if (vbc < fcpc) { + arg=1-vbc/pc; + sarg=exp(-xmc*log(arg)); + lcapbc1 = czbc*sarg; + lcapbc2 = + 0.5*czbc*xmc*sarg/(arg*pc); + lcapbc3 = + czbc*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); + } else { + czbcf2=czbc/f2; + lcapbc1 = czbcf2*(f3+xmc*vbc/pc); + lcapbc2 = 0.5*xmc*czbcf2/pc; + lcapbc3 = 0; + } + if(vbx < fcpc) { + arg=1-vbx/pc; + sarg=exp(-xmc*log(arg)); + lcapbx1 = czbx*sarg; + lcapbx2 = + 0.5*czbx*xmc*sarg/(arg*pc); + lcapbx3 = + czbx*xmc*(xmc+1)*sarg/(arg*arg*pc*pc*6); + } else { + czbxf2=czbx/f2; + lcapbx1 = czbxf2*(f3+xmc*vbx/pc); + lcapbx2 = 0.5*xmc*czbxf2/pc; + lcapbx3 = 0; + } + if(vsc < 0){ + arg=1-vsc/ps; + sarg=exp(-xms*log(arg)); + lcapsc1 = czcs*sarg; + lcapsc2 = + 0.5*czcs*xms*sarg/(arg*ps); + lcapsc3 = + czcs*xms*(xms+1)*sarg/(arg*arg*ps*ps*6); + } else { + lcapsc1 = czcs*(1+xms*vsc/ps); + lcapsc2 = czcs*0.5*xms/ps; + lcapsc3 = 0; + } + + /* + * store small-signal parameters + */ +here->ic_x = d_ic.d1_p; +here->ic_y = d_ic.d1_q; +here->ic_xd = d_ic.d1_r; +here->ic_x2 = 0.5*model->BJT2type*d_ic.d2_p2; +here->ic_y2 = 0.5*model->BJT2type*d_ic.d2_q2; +here->ic_w2 = 0.5*model->BJT2type*d_ic.d2_r2; +here->ic_xy = model->BJT2type*d_ic.d2_pq; +here->ic_yw = model->BJT2type*d_ic.d2_qr; +here->ic_xw = model->BJT2type*d_ic.d2_pr; +here->ic_x3 = d_ic.d3_p3/6.; +here->ic_y3 = d_ic.d3_q3/6.; +here->ic_w3 = d_ic.d3_r3/6.; +here->ic_x2w = 0.5*d_ic.d3_p2r; +here->ic_x2y = 0.5*d_ic.d3_p2q; +here->ic_y2w = 0.5*d_ic.d3_q2r; +here->ic_xy2 = 0.5*d_ic.d3_pq2; +here->ic_xw2 = 0.5*d_ic.d3_pr2; +here->ic_yw2 = 0.5*d_ic.d3_qr2; +here->ic_xyw = d_ic.d3_pqr; + +here->ib_x = d_ib.d1_p; +here->ib_y = d_ib.d1_q; +here->ib_x2 = 0.5*model->BJT2type*d_ib.d2_p2; +here->ib_y2 = 0.5*model->BJT2type*d_ib.d2_q2; +here->ib_xy = model->BJT2type*d_ib.d2_pq; +here->ib_x3 = d_ib.d3_p3/6.; +here->ib_y3 = d_ib.d3_q3/6.; +here->ib_x2y = 0.5*d_ib.d3_p2q; +here->ib_xy2 = 0.5*d_ib.d3_pq2; + +here->ibb_x = d_ibb.d1_p; +here->ibb_y = d_ibb.d1_q; +here->ibb_z = d_ibb.d1_r; +here->ibb_x2 = 0.5*model->BJT2type*d_ibb.d2_p2; +here->ibb_y2 = 0.5*model->BJT2type*d_ibb.d2_q2; +here->ibb_z2 = 0.5*model->BJT2type*d_ibb.d2_r2; +here->ibb_xy = model->BJT2type*d_ibb.d2_pq; +here->ibb_yz = model->BJT2type*d_ibb.d2_qr; +here->ibb_xz = model->BJT2type*d_ibb.d2_pr; +here->ibb_x3 = d_ibb.d3_p3/6.; +here->ibb_y3 = d_ibb.d3_q3/6.; +here->ibb_z3 = d_ibb.d3_r3/6.; +here->ibb_x2z = 0.5*d_ibb.d3_p2r; +here->ibb_x2y = 0.5*d_ibb.d3_p2q; +here->ibb_y2z = 0.5*d_ibb.d3_q2r; +here->ibb_xy2 = 0.5*d_ibb.d3_pq2; +here->ibb_xz2 = 0.5*d_ibb.d3_pr2; +here->ibb_yz2 = 0.5*d_ibb.d3_qr2; +here->ibb_xyz = d_ibb.d3_pqr; + +here->qbe_x = d_qbe.d1_p; +here->qbe_y = d_qbe.d1_q; +here->qbe_x2 = 0.5*model->BJT2type*d_qbe.d2_p2; +here->qbe_y2 = 0.5*model->BJT2type*d_qbe.d2_q2; +here->qbe_xy = model->BJT2type*d_qbe.d2_pq; +here->qbe_x3 = d_qbe.d3_p3/6.; +here->qbe_y3 = d_qbe.d3_q3/6.; +here->qbe_x2y = 0.5*d_qbe.d3_p2q; +here->qbe_xy2 = 0.5*d_qbe.d3_pq2; + +here->capbc1 = lcapbc1; +here->capbc2 = lcapbc2; +here->capbc3 = lcapbc3; + +here->capbx1 = lcapbx1; +here->capbx2 = lcapbx2; +here->capbx3 = lcapbx3; + +here->capsc1 = lcapsc1; +here->capsc2 = lcapsc2; +here->capsc3 = lcapsc3; + } + } + return(OK); + } diff --git a/src/spicelib/devices/bjt2/bjt2dset.h b/src/spicelib/devices/bjt2/bjt2dset.h index 5a2dd5b16..c1d70b3fe 100644 --- a/src/spicelib/devices/bjt2/bjt2dset.h +++ b/src/spicelib/devices/bjt2/bjt2dset.h @@ -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 diff --git a/src/spicelib/devices/bjt2/bjt2ext.h b/src/spicelib/devices/bjt2/bjt2ext.h index 44d13ed34..c9993eb1d 100644 --- a/src/spicelib/devices/bjt2/bjt2ext.h +++ b/src/spicelib/devices/bjt2/bjt2ext.h @@ -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 diff --git a/src/spicelib/devices/bjt2/bjt2getic.c b/src/spicelib/devices/bjt2/bjt2getic.c index 07ba95c50..8906be02a 100644 --- a/src/spicelib/devices/bjt2/bjt2getic.c +++ b/src/spicelib/devices/bjt2/bjt2getic.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2init.c b/src/spicelib/devices/bjt2/bjt2init.c index 1cd29d532..a21cf7bb5 100644 --- a/src/spicelib/devices/bjt2/bjt2init.c +++ b/src/spicelib/devices/bjt2/bjt2init.c @@ -1,84 +1,84 @@ -#include - -#include - -#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 + +#include + +#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; +} diff --git a/src/spicelib/devices/bjt2/bjt2init.h b/src/spicelib/devices/bjt2/bjt2init.h index 41c7aca79..48c9b149a 100644 --- a/src/spicelib/devices/bjt2/bjt2init.h +++ b/src/spicelib/devices/bjt2/bjt2init.h @@ -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 diff --git a/src/spicelib/devices/bjt2/bjt2itf.h b/src/spicelib/devices/bjt2/bjt2itf.h index 227968b68..7940a6c1f 100644 --- a/src/spicelib/devices/bjt2/bjt2itf.h +++ b/src/spicelib/devices/bjt2/bjt2itf.h @@ -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 \ No newline at end of file +/********** +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 diff --git a/src/spicelib/devices/bjt2/bjt2load.c b/src/spicelib/devices/bjt2/bjt2load.c index 40ce5569d..3d260fd73 100644 --- a/src/spicelib/devices/bjt2/bjt2load.c +++ b/src/spicelib/devices/bjt2/bjt2load.c @@ -1,798 +1,795 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1985 Thomas L. Quarles -Modified: Alan Gillespie -**********/ - -/* - * This is the function called each iteration to evaluate the - * BJT2s in the circuit and load them into the matrix as appropriate - */ - -#include "ngspice.h" -#include "cktdefs.h" -#include "bjt2defs.h" -#include "const.h" -#include "trandefs.h" -#include "sperror.h" -#include "devdefs.h" -#include "suffix.h" - -int -BJT2load(inModel,ckt) - - GENmodel *inModel; - CKTcircuit *ckt; - /* actually load the current resistance value into the - * sparse matrix previously provided - */ -{ - BJT2model *model = (BJT2model*)inModel; - BJT2instance *here; - double arg1; - double arg2; - double arg3; - double arg; - double argtf; - double c2; - double c4; - double capbc; - double capbe; - double capbx=0; - double capsub=0; - double cb; - double cbc; - double cbcn; - double cbe; - double cben; - double cbhat; - double cc; - double cchat; - double cdis; - double ceq; - double ceqbc; - double ceqbe; - double ceqbx; - double geqsub; - double ceqsub; - double cex; - double csat; - double csubsat; - double ctot; - double czbc; - double czbcf2; - double czbe; - double czbef2; - double czbx; - double czbxf2; - double czsub; - double delvbc; - double delvbe; - double denom; - double dqbdvc; - double dqbdve; - double evbc; - double evbcn; - double evbe; - double evben; - double f1; - double f2; - double f3; - double fcpc; - double fcpe; - double gbc; - double gbcn; - double gbe; - double gben; - double gcsub; - double gcpr; - double gepr; - double geq; - double geqbx; - double geqcb; - double gex; - double gm; - double gmu; - double go; - double gpi; - double gx; - double oik; - double oikr; - double ovtf; - double pc; - double pe; - double ps; - double q1; - double q2; - double qb; - double rbpi; - double rbpr; - double sarg; - double sqarg; - double td; - double temp; - double tf; - double tol; - double tr; - double vbc; - double vbe; - double vbx; - double vce; - double vsub; - double vt; - double vtc; - double vte; - double vtn; - double xfact; - double xjrb; - double xjtf; - double xmc; - double xme; - double xms; - double xtf; - double evsub; - double gdsub; - double cdsub; - int icheck; - int ichk1; - int error; - int SenCond=0; - /* loop through all the models */ - for( ; model != NULL; model = model->BJT2nextModel ) { - - /* loop through all the instances of the model */ - for (here = model->BJT2instances; here != NULL ; - here=here->BJT2nextInstance) { - - vt = here->BJT2temp * CONSTKoverQ; - - if(ckt->CKTsenInfo){ -#ifdef SENSDEBUG - printf("BJT2load \n"); -#endif /* SENSDEBUG */ - - if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& - (here->BJT2senPertFlag == OFF)) continue; - SenCond = here->BJT2senPertFlag; - } - - - gcsub=0; - ceqsub=0; - geqbx=0; - ceqbx=0; - geqcb=0; - /* - * dc model paramters - */ - csat=here->BJT2tSatCur*here->BJT2area; - csubsat=here->BJT2tSubSatCur*here->BJT2area; - rbpr=model->BJT2minBaseResist/here->BJT2area; - rbpi=model->BJT2baseResist/here->BJT2area-rbpr; - gcpr=model->BJT2collectorConduct*here->BJT2area; - gepr=model->BJT2emitterConduct*here->BJT2area; - oik=model->BJT2invRollOffF/here->BJT2area; - c2=here->BJT2tBEleakCur*here->BJT2area; - vte=model->BJT2leakBEemissionCoeff*vt; - oikr=model->BJT2invRollOffR/here->BJT2area; - c4=here->BJT2tBCleakCur*here->BJT2area; - vtc=model->BJT2leakBCemissionCoeff*vt; - td=model->BJT2excessPhaseFactor; - xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area; - - if(SenCond){ -#ifdef SENSDEBUG - printf("BJT2senPertFlag = ON \n"); -#endif /* SENSDEBUG */ - - if((ckt->CKTsenInfo->SENmode == TRANSEN)&& - (ckt->CKTmode & MODEINITTRAN)) { - vbe = *(ckt->CKTstate1 + here->BJT2vbe); - vbc = *(ckt->CKTstate1 + here->BJT2vbc); - vbx=model->BJT2type*( - *(ckt->CKTrhsOp+here->BJT2baseNode)- - *(ckt->CKTrhsOp+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOp+here->BJT2substNode)- - *(ckt->CKTrhsOp+here->BJT2substConNode)); - } - else{ - vbe = *(ckt->CKTstate0 + here->BJT2vbe); - vbc = *(ckt->CKTstate0 + here->BJT2vbc); - if((ckt->CKTsenInfo->SENmode == DCSEN)|| - (ckt->CKTsenInfo->SENmode == TRANSEN)){ - vbx=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2substConNode)); - } - if(ckt->CKTsenInfo->SENmode == ACSEN){ - vbx=model->BJT2type*( - *(ckt->CKTrhsOp+here->BJT2baseNode)- - *(ckt->CKTrhsOp+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOp+here->BJT2substNode)- - *(ckt->CKTrhsOp+here->BJT2substConNode)); - } - } - goto next1; - } - - /* - * initialization - */ - icheck=1; - if(ckt->CKTmode & MODEINITSMSIG) { - vbe= *(ckt->CKTstate0 + here->BJT2vbe); - vbc= *(ckt->CKTstate0 + here->BJT2vbc); - vbx=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2substConNode)); - } else if(ckt->CKTmode & MODEINITTRAN) { - vbe = *(ckt->CKTstate1 + here->BJT2vbe); - vbc = *(ckt->CKTstate1 + here->BJT2vbc); - vbx=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2substConNode)); - if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { - vbx=model->BJT2type*(here->BJT2icVBE-here->BJT2icVCE); - vsub=0; - } - } else if((ckt->CKTmode & MODEINITJCT) && - (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ - vbe=model->BJT2type*here->BJT2icVBE; - vce=model->BJT2type*here->BJT2icVCE; - vbc=vbe-vce; - vbx=vbc; - vsub=0; - } else if((ckt->CKTmode & MODEINITJCT) && (here->BJT2off==0)) { - vbe=here->BJT2tVcrit; - vbc=0; - /* ERROR: need to initialize VCS, VBX here */ - vsub=vbx=0; - } else if((ckt->CKTmode & MODEINITJCT) || - ( (ckt->CKTmode & MODEINITFIX) && (here->BJT2off!=0))) { - vbe=0; - vbc=0; - /* ERROR: need to initialize VCS, VBX here */ - vsub=vbx=0; - } else { -#ifndef PREDICTOR - if(ckt->CKTmode & MODEINITPRED) { - xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; - *(ckt->CKTstate0 + here->BJT2vbe) = - *(ckt->CKTstate1 + here->BJT2vbe); - vbe = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbe)- - xfact* *(ckt->CKTstate2 + here->BJT2vbe); - *(ckt->CKTstate0 + here->BJT2vbc) = - *(ckt->CKTstate1 + here->BJT2vbc); - vbc = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbc)- - xfact* *(ckt->CKTstate2 + here->BJT2vbc); - *(ckt->CKTstate0 + here->BJT2cc) = - *(ckt->CKTstate1 + here->BJT2cc); - *(ckt->CKTstate0 + here->BJT2cb) = - *(ckt->CKTstate1 + here->BJT2cb); - *(ckt->CKTstate0 + here->BJT2gpi) = - *(ckt->CKTstate1 + here->BJT2gpi); - *(ckt->CKTstate0 + here->BJT2gmu) = - *(ckt->CKTstate1 + here->BJT2gmu); - *(ckt->CKTstate0 + here->BJT2gm) = - *(ckt->CKTstate1 + here->BJT2gm); - *(ckt->CKTstate0 + here->BJT2go) = - *(ckt->CKTstate1 + here->BJT2go); - *(ckt->CKTstate0 + here->BJT2gx) = - *(ckt->CKTstate1 + here->BJT2gx); - *(ckt->CKTstate0 + here->BJT2vsub) = - *(ckt->CKTstate1 + here->BJT2vsub); - vsub = (1+xfact)**(ckt->CKTstate1 + here->BJT2vsub)- - xfact* *(ckt->CKTstate2 + here->BJT2vsub); - } else { -#endif /* PREDICTOR */ - /* - * compute new nonlinear branch voltages - */ - vbe=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2basePrimeNode)- - *(ckt->CKTrhsOld+here->BJT2emitPrimeNode)); - vbc=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2basePrimeNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2substConNode)); -#ifndef PREDICTOR - } -#endif /* PREDICTOR */ - delvbe=vbe- *(ckt->CKTstate0 + here->BJT2vbe); - delvbc=vbc- *(ckt->CKTstate0 + here->BJT2vbc); - vbx=model->BJT2type*( - *(ckt->CKTrhsOld+here->BJT2baseNode)- - *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); - vsub=model->BJT2type*model->BJT2subs*( - *(ckt->CKTrhsOld+here->BJT2substNode)- - *(ckt->CKTrhsOld+here->BJT2substConNode)); - cchat= *(ckt->CKTstate0 + here->BJT2cc)+(*(ckt->CKTstate0 + - here->BJT2gm)+ *(ckt->CKTstate0 + here->BJT2go))*delvbe- - (*(ckt->CKTstate0 + here->BJT2go)+*(ckt->CKTstate0 + - here->BJT2gmu))*delvbc; - cbhat= *(ckt->CKTstate0 + here->BJT2cb)+ *(ckt->CKTstate0 + - here->BJT2gpi)*delvbe+ *(ckt->CKTstate0 + here->BJT2gmu)* - delvbc; - - /* - * bypass if solution has not changed - */ - /* the following collections of if's would be just one - * if the average compiler could handle it, but many - * find the expression too complicated, thus the split. - */ - if( (ckt->CKTbypass) && - (!(ckt->CKTmode & MODEINITPRED)) && - (fabs(delvbe) < (ckt->CKTreltol*MAX(fabs(vbe), - fabs(*(ckt->CKTstate0 + here->BJT2vbe)))+ - ckt->CKTvoltTol)) ) - if( (fabs(delvbc) < ckt->CKTreltol*MAX(fabs(vbc), - fabs(*(ckt->CKTstate0 + here->BJT2vbc)))+ - ckt->CKTvoltTol) ) - if( (fabs(cchat-*(ckt->CKTstate0 + here->BJT2cc)) < - ckt->CKTreltol* MAX(fabs(cchat), - fabs(*(ckt->CKTstate0 + here->BJT2cc)))+ - ckt->CKTabstol) ) - if( (fabs(cbhat-*(ckt->CKTstate0 + here->BJT2cb)) < - ckt->CKTreltol* MAX(fabs(cbhat), - fabs(*(ckt->CKTstate0 + here->BJT2cb)))+ - ckt->CKTabstol) ) { - /* - * bypassing.... - */ - vbe = *(ckt->CKTstate0 + here->BJT2vbe); - vbc = *(ckt->CKTstate0 + here->BJT2vbc); - cc = *(ckt->CKTstate0 + here->BJT2cc); - cb = *(ckt->CKTstate0 + here->BJT2cb); - gpi = *(ckt->CKTstate0 + here->BJT2gpi); - gmu = *(ckt->CKTstate0 + here->BJT2gmu); - gm = *(ckt->CKTstate0 + here->BJT2gm); - go = *(ckt->CKTstate0 + here->BJT2go); - gx = *(ckt->CKTstate0 + here->BJT2gx); - geqcb = *(ckt->CKTstate0 + here->BJT2geqcb); - gcsub = *(ckt->CKTstate0 + here->BJT2gcsub); - geqbx = *(ckt->CKTstate0 + here->BJT2geqbx); - vsub = *(ckt->CKTstate0 + here->BJT2vsub); - gdsub = *(ckt->CKTstate0 + here->BJT2gdsub); - cdsub = *(ckt->CKTstate0 + here->BJT2cdsub); - goto load; - } - - /* - * limit nonlinear branch voltages - */ - ichk1=1; - vbe = DEVpnjlim(vbe,*(ckt->CKTstate0 + here->BJT2vbe),vt, - here->BJT2tVcrit,&icheck); - vbc = DEVpnjlim(vbc,*(ckt->CKTstate0 + here->BJT2vbc),vt, - here->BJT2tVcrit,&ichk1); - if (ichk1 == 1) icheck=1; - vsub = DEVpnjlim(vsub,*(ckt->CKTstate0 + here->BJT2vsub),vt, - here->BJT2tSubVcrit,&ichk1); - if (ichk1 == 1) icheck=1; - } - /* - * determine dc current and derivitives - */ -next1: vtn=vt*model->BJT2emissionCoeffF; - if(vbe >= -3*vtn){ - evbe=exp(vbe/vtn); - cbe=csat*(evbe-1); - gbe=csat*evbe/vtn; - } else { - arg=3*vtn/(vbe*CONSTe); - arg = arg * arg * arg; - cbe = -csat*(1+arg); - gbe = csat*3*arg/vbe; - } - if (c2 == 0) { - cben=0; - gben=0; - } else { - if(vbe >= -3*vte){ - evben=exp(vbe/vte); - cben=c2*(evben-1); - gben=c2*evben/vte; - } else { - arg=3*vte/(vbe*CONSTe); - arg = arg * arg * arg; - cben = -c2*(1+arg); - gben = c2*3*arg/vbe; - } - } - gben+=ckt->CKTgmin; - cben+=ckt->CKTgmin*vbe; - vtn=vt*model->BJT2emissionCoeffR; - if(vbc >= -3*vtn) { - evbc=exp(vbc/vtn); - cbc=csat*(evbc-1); - gbc=csat*evbc/vtn; - } else { - arg=3*vtn/(vbc*CONSTe); - arg = arg * arg * arg; - cbc = -csat*(1+arg); - gbc = csat*3*arg/vbc; - } - if (c4 == 0) { - cbcn=0; - gbcn=0; - } else { - if(vbc >= -3*vtc) { - evbcn=exp(vbc/vtc); - cbcn=c4*(evbcn-1); - gbcn=c4*evbcn/vtc; - } else { - arg=3*vtc/(vbc*CONSTe); - arg = arg * arg * arg; - cbcn = -c4*(1+arg); - gbcn = c4*3*arg/vbc; - } - } - gbcn+=ckt->CKTgmin; - cbcn+=ckt->CKTgmin*vbc; - if(vsub <= -3*vt) { - arg=3*vte/(vsub*CONSTe); - arg = arg * arg * arg; - gdsub = csubsat*3*arg/vsub+ckt->CKTgmin; - cdsub = -csubsat*(1+arg)+ckt->CKTgmin*vsub; - } else { - evsub = exp(MIN(MAX_EXP_ARG,vsub/vt)); - gdsub = csubsat*evsub/vt + ckt->CKTgmin; - cdsub = csubsat*(evsub-1) + ckt->CKTgmin*vsub; - } - /* - * determine base charge terms - */ - q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); - if(oik == 0 && oikr == 0) { - qb=q1; - dqbdve=q1*qb*model->BJT2invEarlyVoltR; - dqbdvc=q1*qb*model->BJT2invEarlyVoltF; - } else { - q2=oik*cbe+oikr*cbc; - arg=MAX(0,1+4*q2); - sqarg=1; - if(arg != 0) sqarg=sqrt(arg); - qb=q1*(1+sqarg)/2; - dqbdve=q1*(qb*model->BJT2invEarlyVoltR+oik*gbe/sqarg); - dqbdvc=q1*(qb*model->BJT2invEarlyVoltF+oikr*gbc/sqarg); - } - /* - * weil's approx. for excess phase applied with backward- - * euler integration - */ - cc=0; - cex=cbe; - gex=gbe; - if(ckt->CKTmode & (MODETRAN | MODEAC) && td != 0) { - arg1=ckt->CKTdelta/td; - arg2=3*arg1; - arg1=arg2*arg1; - denom=1+arg1+arg2; - arg3=arg1/denom; - if(ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->BJT2cexbc)=cbe/qb; - *(ckt->CKTstate2 + here->BJT2cexbc)= - *(ckt->CKTstate1 + here->BJT2cexbc); - } - cc=(*(ckt->CKTstate1 + here->BJT2cexbc)*(1+ckt->CKTdelta/ - ckt->CKTdeltaOld[1]+arg2)- - *(ckt->CKTstate2 + here->BJT2cexbc)*ckt->CKTdelta/ - ckt->CKTdeltaOld[1])/denom; - cex=cbe*arg3; - gex=gbe*arg3; - *(ckt->CKTstate0 + here->BJT2cexbc)=cc+cex/qb; - } - /* - * determine dc incremental conductances - */ - cc=cc+(cex-cbc)/qb-cbc/here->BJT2tBetaR-cbcn; - cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; - gx=rbpr+rbpi/qb; - if(xjrb != 0) { - arg1=MAX(cb/xjrb,1e-9); - arg2=(-1+sqrt(1+14.59025*arg1))/2.4317/sqrt(arg1); - arg1=tan(arg2); - gx=rbpr+3*rbpi*(arg1-arg2)/arg2/arg1/arg1; - } - if(gx != 0) gx=1/gx; - gpi=gbe/here->BJT2tBetaF+gben; - gmu=gbc/here->BJT2tBetaR+gbcn; - go=(gbc+(cex-cbc)*dqbdvc/qb)/qb; - gm=(gex-(cex-cbc)*dqbdve/qb)/qb-go; - if( (ckt->CKTmode & (MODETRAN | MODEAC)) || - ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || - (ckt->CKTmode & MODEINITSMSIG)) { - /* - * charge storage elements - */ - tf=model->BJT2transitTimeF; - tr=model->BJT2transitTimeR; - czbe=here->BJT2tBEcap*here->BJT2area; - pe=here->BJT2tBEpot; - xme=model->BJT2junctionExpBE; - cdis=model->BJT2baseFractionBCcap; - ctot=here->BJT2tBCcap*here->BJT2area; - czbc=ctot*cdis; - czbx=ctot-czbc; - pc=here->BJT2tBCpot; - xmc=model->BJT2junctionExpBC; - fcpe=here->BJT2tDepCap; - czsub=here->BJT2tSubcap*here->BJT2area; - ps=here->BJT2tSubpot; - xms=model->BJT2exponentialSubstrate; - xtf=model->BJT2transitTimeBiasCoeffF; - ovtf=model->BJT2transitTimeVBCFactor; - xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area; - if(tf != 0 && vbe >0) { - argtf=0; - arg2=0; - arg3=0; - if(xtf != 0){ - argtf=xtf; - if(ovtf != 0) { - argtf=argtf*exp(vbc*ovtf); - } - arg2=argtf; - if(xjtf != 0) { - temp=cbe/(cbe+xjtf); - argtf=argtf*temp*temp; - arg2=argtf*(3-temp-temp); - } - arg3=cbe*argtf*ovtf; - } - cbe=cbe*(1+argtf)/qb; - gbe=(gbe*(1+arg2)-cbe*dqbdve)/qb; - geqcb=tf*(arg3-cbe*dqbdvc)/qb; - } - if (vbe < fcpe) { - arg=1-vbe/pe; - sarg=exp(-xme*log(arg)); - *(ckt->CKTstate0 + here->BJT2qbe)=tf*cbe+pe*czbe* - (1-arg*sarg)/(1-xme); - capbe=tf*gbe+czbe*sarg; - } else { - f1=here->BJT2tf1; - f2=model->BJT2f2; - f3=model->BJT2f3; - czbef2=czbe/f2; - *(ckt->CKTstate0 + here->BJT2qbe) = tf*cbe+czbe*f1+czbef2* - (f3*(vbe-fcpe) +(xme/(pe+pe))*(vbe*vbe-fcpe*fcpe)); - capbe=tf*gbe+czbef2*(f3+xme*vbe/pe); - } - fcpc=here->BJT2tf4; - f1=here->BJT2tf5; - f2=model->BJT2f6; - f3=model->BJT2f7; - if (vbc < fcpc) { - arg=1-vbc/pc; - sarg=exp(-xmc*log(arg)); - *(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+pc*czbc*( - 1-arg*sarg)/(1-xmc); - capbc=tr*gbc+czbc*sarg; - } else { - czbcf2=czbc/f2; - *(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+czbc*f1+czbcf2* - (f3*(vbc-fcpc) +(xmc/(pc+pc))*(vbc*vbc-fcpc*fcpc)); - capbc=tr*gbc+czbcf2*(f3+xmc*vbc/pc); - } - if(vbx < fcpc) { - arg=1-vbx/pc; - sarg=exp(-xmc*log(arg)); - *(ckt->CKTstate0 + here->BJT2qbx)= - pc*czbx* (1-arg*sarg)/(1-xmc); - capbx=czbx*sarg; - } else { - czbxf2=czbx/f2; - *(ckt->CKTstate0 + here->BJT2qbx)=czbx*f1+czbxf2* - (f3*(vbx-fcpc)+(xmc/(pc+pc))*(vbx*vbx-fcpc*fcpc)); - capbx=czbxf2*(f3+xmc*vbx/pc); - } - if(vsub < 0){ - arg=1-vsub/ps; - sarg=exp(-xms*log(arg)); - *(ckt->CKTstate0 + here->BJT2qsub) = ps*czsub*(1-arg*sarg)/ - (1-xms); - capsub=czsub*sarg; - } else { - *(ckt->CKTstate0 + here->BJT2qsub) = vsub*czsub*(1+xms*vsub/ - (2*ps)); - capsub=czsub*(1+xms*vsub/ps); - } - here->BJT2capbe = capbe; - here->BJT2capbc = capbc; - here->BJT2capsub = capsub; - here->BJT2capbx = capbx; - - /* - * store small-signal parameters - */ - if ( (!(ckt->CKTmode & MODETRANOP))|| - (!(ckt->CKTmode & MODEUIC)) ) { - if(ckt->CKTmode & MODEINITSMSIG) { - *(ckt->CKTstate0 + here->BJT2cqbe) = capbe; - *(ckt->CKTstate0 + here->BJT2cqbc) = capbc; - *(ckt->CKTstate0 + here->BJT2cqsub) = capsub; - *(ckt->CKTstate0 + here->BJT2cqbx) = capbx; - *(ckt->CKTstate0 + here->BJT2cexbc) = geqcb; - if(SenCond){ - *(ckt->CKTstate0 + here->BJT2cc) = cc; - *(ckt->CKTstate0 + here->BJT2cb) = cb; - *(ckt->CKTstate0 + here->BJT2gpi) = gpi; - *(ckt->CKTstate0 + here->BJT2gmu) = gmu; - *(ckt->CKTstate0 + here->BJT2gm) = gm; - *(ckt->CKTstate0 + here->BJT2go) = go; - *(ckt->CKTstate0 + here->BJT2gx) = gx; - *(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; - *(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; - } -#ifdef SENSDEBUG - printf("storing small signal parameters for op\n"); - printf("capbe = %.7e ,capbc = %.7e\n",capbe,capbc); - printf("capsub = %.7e ,capbx = %.7e\n",capsub,capbx); - printf("geqcb = %.7e ,gpi = %.7e\n",geqcb,gpi); - printf("gmu = %.7e ,gm = %.7e\n",gmu,gm); - printf("go = %.7e ,gx = %.7e\n",go,gx); - printf("gcsub = %.7e ,geqbx = %.7e\n",gcsub,geqbx); - printf("cc = %.7e ,cb = %.7e\n",cc,cb); -#endif /* SENSDEBUG */ - continue; /* go to 1000 */ - } - /* - * transient analysis - */ - if(SenCond && ckt->CKTsenInfo->SENmode == TRANSEN){ - *(ckt->CKTstate0 + here->BJT2cc) = cc; - *(ckt->CKTstate0 + here->BJT2cb) = cb; - *(ckt->CKTstate0 + here->BJT2gx) = gx; - continue; - } - - if(ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->BJT2qbe) = - *(ckt->CKTstate0 + here->BJT2qbe) ; - *(ckt->CKTstate1 + here->BJT2qbc) = - *(ckt->CKTstate0 + here->BJT2qbc) ; - *(ckt->CKTstate1 + here->BJT2qbx) = - *(ckt->CKTstate0 + here->BJT2qbx) ; - *(ckt->CKTstate1 + here->BJT2qsub) = - *(ckt->CKTstate0 + here->BJT2qsub) ; - } - error = NIintegrate(ckt,&geq,&ceq,capbe,here->BJT2qbe); - if(error) return(error); - geqcb=geqcb*ckt->CKTag[0]; - gpi=gpi+geq; - cb=cb+*(ckt->CKTstate0 + here->BJT2cqbe); - error = NIintegrate(ckt,&geq,&ceq,capbc,here->BJT2qbc); - if(error) return(error); - gmu=gmu+geq; - cb=cb+*(ckt->CKTstate0 + here->BJT2cqbc); - cc=cc-*(ckt->CKTstate0 + here->BJT2cqbc); - if(ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->BJT2cqbe) = - *(ckt->CKTstate0 + here->BJT2cqbe); - *(ckt->CKTstate1 + here->BJT2cqbc) = - *(ckt->CKTstate0 + here->BJT2cqbc); - } - } - } - - if(SenCond) goto next2; - - /* - * check convergence - */ - if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->BJT2off))) { - if (icheck == 1) { - ckt->CKTnoncon++; - ckt->CKTtroubleElt = (GENinstance *) here; - } - } - - /* - * charge storage for c-s and b-x junctions - */ - if(ckt->CKTmode & (MODETRAN | MODEAC)) { - error = NIintegrate(ckt,&gcsub,&ceq,capsub,here->BJT2qsub); - if(error) return(error); - error = NIintegrate(ckt,&geqbx,&ceq,capbx,here->BJT2qbx); - if(error) return(error); - if(ckt->CKTmode & MODEINITTRAN) { - *(ckt->CKTstate1 + here->BJT2cqbx) = - *(ckt->CKTstate0 + here->BJT2cqbx); - *(ckt->CKTstate1 + here->BJT2cqsub) = - *(ckt->CKTstate0 + here->BJT2cqsub); - } - } -next2: - *(ckt->CKTstate0 + here->BJT2vbe) = vbe; - *(ckt->CKTstate0 + here->BJT2vbc) = vbc; - *(ckt->CKTstate0 + here->BJT2cc) = cc; - *(ckt->CKTstate0 + here->BJT2cb) = cb; - *(ckt->CKTstate0 + here->BJT2gpi) = gpi; - *(ckt->CKTstate0 + here->BJT2gmu) = gmu; - *(ckt->CKTstate0 + here->BJT2gm) = gm; - *(ckt->CKTstate0 + here->BJT2go) = go; - *(ckt->CKTstate0 + here->BJT2gx) = gx; - *(ckt->CKTstate0 + here->BJT2geqcb) = geqcb; - *(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; - *(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; - *(ckt->CKTstate0 + here->BJT2vsub) = vsub; - *(ckt->CKTstate0 + here->BJT2gdsub) = gdsub; - *(ckt->CKTstate0 + here->BJT2cdsub) = cdsub; - - - /* Do not load the Jacobian and the rhs if - perturbation is being carried out */ - - if(SenCond)continue; -load: - /* - * load current excitation vector - */ - geqsub = gcsub + gdsub; - ceqsub=model->BJT2type * model->BJT2subs * - (*(ckt->CKTstate0 + here->BJT2cqsub) + cdsub - vsub*geqsub); -/* - ceqsub=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqsub) + - model->BJT2subs*cdsub - vsub*geqsub); -*/ - ceqbx=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqbx) - - vbx * geqbx); - ceqbe=model->BJT2type * (cc + cb - vbe * (gm + go + gpi) + vbc * - (go - geqcb)); - ceqbc=model->BJT2type * (-cc + vbe * (gm + go) - vbc * (gmu + go)); - - *(ckt->CKTrhs + here->BJT2baseNode) += (-ceqbx); - *(ckt->CKTrhs + here->BJT2colPrimeNode) += - (ceqbx+ceqbc); - *(ckt->CKTrhs + here->BJT2substConNode) += ceqsub; - *(ckt->CKTrhs + here->BJT2basePrimeNode) += - (-ceqbe-ceqbc); - *(ckt->CKTrhs + here->BJT2emitPrimeNode) += (ceqbe); - *(ckt->CKTrhs + here->BJT2substNode) += (-ceqsub); - - /* - * load y matrix - */ - *(here->BJT2colColPtr) += (gcpr); - *(here->BJT2baseBasePtr) += (gx+geqbx); - *(here->BJT2emitEmitPtr) += (gepr); - *(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr+geqbx); - *(here->BJT2substConSubstConPtr) += (geqsub); - *(here->BJT2basePrimeBasePrimePtr) += (gx +gpi+gmu+geqcb); - *(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go); - *(here->BJT2colColPrimePtr) += (-gcpr); - *(here->BJT2baseBasePrimePtr) += (-gx); - *(here->BJT2emitEmitPrimePtr) += (-gepr); - *(here->BJT2colPrimeColPtr) += (-gcpr); - *(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm); - *(here->BJT2colPrimeEmitPrimePtr) += (-gm-go); - *(here->BJT2basePrimeBasePtr) += (-gx); - *(here->BJT2basePrimeColPrimePtr) += (-gmu-geqcb); - *(here->BJT2basePrimeEmitPrimePtr) += (-gpi); - *(here->BJT2emitPrimeEmitPtr) += (-gepr); - *(here->BJT2emitPrimeColPrimePtr) += (-go+geqcb); - *(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm-geqcb); - *(here->BJT2substSubstPtr) += (geqsub); - *(here->BJT2substConSubstPtr) += (-geqsub); - *(here->BJT2substSubstConPtr) += (-geqsub); - *(here->BJT2baseColPrimePtr) += (-geqbx); - *(here->BJT2colPrimeBasePtr) += (-geqbx); - } - } - return(OK); -} +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +/* + * This is the function called each iteration to evaluate the + * BJT2s in the circuit and load them into the matrix as appropriate + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "bjt2defs.h" +#include "const.h" +#include "trandefs.h" +#include "sperror.h" +#include "devdefs.h" +#include "suffix.h" + +int +BJT2load(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current resistance value into the + * sparse matrix previously provided + */ +{ + BJT2model *model = (BJT2model*)inModel; + BJT2instance *here; + double arg1; + double arg2; + double arg3; + double arg; + double argtf; + double c2; + double c4; + double capbc; + double capbe; + double capbx=0; + double capsub=0; + double cb; + double cbc; + double cbcn; + double cbe; + double cben; + double cbhat; + double cc; + double cchat; + double cdis; + double ceq; + double ceqbc; + double ceqbe; + double ceqbx; + double geqsub; + double ceqsub; + double cex; + double csat; + double csubsat; + double ctot; + double czbc; + double czbcf2; + double czbe; + double czbef2; + double czbx; + double czbxf2; + double czsub; + double delvbc; + double delvbe; + double denom; + double dqbdvc; + double dqbdve; + double evbc; + double evbcn; + double evbe; + double evben; + double f1; + double f2; + double f3; + double fcpc; + double fcpe; + double gbc; + double gbcn; + double gbe; + double gben; + double gcsub; + double gcpr; + double gepr; + double geq; + double geqbx; + double geqcb; + double gex; + double gm; + double gmu; + double go; + double gpi; + double gx; + double oik; + double oikr; + double ovtf; + double pc; + double pe; + double ps; + double q1; + double q2; + double qb; + double rbpi; + double rbpr; + double sarg; + double sqarg; + double td; + double temp; + double tf; + double tol; + double tr; + double vbc; + double vbe; + double vbx; + double vce; + double vsub; + double vt; + double vtc; + double vte; + double vtn; + double xfact; + double xjrb; + double xjtf; + double xmc; + double xme; + double xms; + double xtf; + double evsub; + double gdsub; + double cdsub; + int icheck; + int ichk1; + int error; + int SenCond=0; + /* loop through all the models */ + for( ; model != NULL; model = model->BJT2nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->BJT2instances; here != NULL ; + here=here->BJT2nextInstance) { + + vt = here->BJT2temp * CONSTKoverQ; + + if(ckt->CKTsenInfo){ +#ifdef SENSDEBUG + printf("BJT2load \n"); +#endif /* SENSDEBUG */ + + if((ckt->CKTsenInfo->SENstatus == PERTURBATION)&& + (here->BJT2senPertFlag == OFF)) continue; + SenCond = here->BJT2senPertFlag; + } + + + gcsub=0; + ceqsub=0; + geqbx=0; + ceqbx=0; + geqcb=0; + /* + * dc model paramters + */ + csat=here->BJT2tSatCur*here->BJT2area; + csubsat=here->BJT2tSubSatCur*here->BJT2area; + rbpr=here->BJT2tMinBaseResist/here->BJT2area; + rbpi=here->BJT2tBaseResist/here->BJT2area-rbpr; + gcpr=here->BJT2tCollectorConduct*here->BJT2area; + gepr=here->BJT2tEmitterConduct*here->BJT2area; + oik=model->BJT2invRollOffF/here->BJT2area; + c2=here->BJT2tBEleakCur*here->BJT2area; + vte=model->BJT2leakBEemissionCoeff*vt; + oikr=model->BJT2invRollOffR/here->BJT2area; + c4=here->BJT2tBCleakCur*here->BJT2area; + vtc=model->BJT2leakBCemissionCoeff*vt; + td=model->BJT2excessPhaseFactor; + xjrb=model->BJT2baseCurrentHalfResist*here->BJT2area; + + if(SenCond){ +#ifdef SENSDEBUG + printf("BJT2senPertFlag = ON \n"); +#endif /* SENSDEBUG */ + + if((ckt->CKTsenInfo->SENmode == TRANSEN)&& + (ckt->CKTmode & MODEINITTRAN)) { + vbe = *(ckt->CKTstate1 + here->BJT2vbe); + vbc = *(ckt->CKTstate1 + here->BJT2vbc); + vbx=model->BJT2type*( + *(ckt->CKTrhsOp+here->BJT2baseNode)- + *(ckt->CKTrhsOp+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOp+here->BJT2substNode)- + *(ckt->CKTrhsOp+here->BJT2substConNode)); + } + else{ + vbe = *(ckt->CKTstate0 + here->BJT2vbe); + vbc = *(ckt->CKTstate0 + here->BJT2vbc); + if((ckt->CKTsenInfo->SENmode == DCSEN)|| + (ckt->CKTsenInfo->SENmode == TRANSEN)){ + vbx=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2substConNode)); + } + if(ckt->CKTsenInfo->SENmode == ACSEN){ + vbx=model->BJT2type*( + *(ckt->CKTrhsOp+here->BJT2baseNode)- + *(ckt->CKTrhsOp+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOp+here->BJT2substNode)- + *(ckt->CKTrhsOp+here->BJT2substConNode)); + } + } + goto next1; + } + + /* + * initialization + */ + icheck=1; + if(ckt->CKTmode & MODEINITSMSIG) { + vbe= *(ckt->CKTstate0 + here->BJT2vbe); + vbc= *(ckt->CKTstate0 + here->BJT2vbc); + vbx=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2substConNode)); + } else if(ckt->CKTmode & MODEINITTRAN) { + vbe = *(ckt->CKTstate1 + here->BJT2vbe); + vbc = *(ckt->CKTstate1 + here->BJT2vbc); + vbx=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2substConNode)); + if( (ckt->CKTmode & MODETRAN) && (ckt->CKTmode & MODEUIC) ) { + vbx=model->BJT2type*(here->BJT2icVBE-here->BJT2icVCE); + vsub=0; + } + } else if((ckt->CKTmode & MODEINITJCT) && + (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ + vbe=model->BJT2type*here->BJT2icVBE; + vce=model->BJT2type*here->BJT2icVCE; + vbc=vbe-vce; + vbx=vbc; + vsub=0; + } else if((ckt->CKTmode & MODEINITJCT) && (here->BJT2off==0)) { + vbe=here->BJT2tVcrit; + vbc=0; + /* ERROR: need to initialize VCS, VBX here */ + vsub=vbx=0; + } else if((ckt->CKTmode & MODEINITJCT) || + ( (ckt->CKTmode & MODEINITFIX) && (here->BJT2off!=0))) { + vbe=0; + vbc=0; + /* ERROR: need to initialize VCS, VBX here */ + vsub=vbx=0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->BJT2vbe) = + *(ckt->CKTstate1 + here->BJT2vbe); + vbe = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbe)- + xfact* *(ckt->CKTstate2 + here->BJT2vbe); + *(ckt->CKTstate0 + here->BJT2vbc) = + *(ckt->CKTstate1 + here->BJT2vbc); + vbc = (1+xfact)**(ckt->CKTstate1 + here->BJT2vbc)- + xfact* *(ckt->CKTstate2 + here->BJT2vbc); + *(ckt->CKTstate0 + here->BJT2cc) = + *(ckt->CKTstate1 + here->BJT2cc); + *(ckt->CKTstate0 + here->BJT2cb) = + *(ckt->CKTstate1 + here->BJT2cb); + *(ckt->CKTstate0 + here->BJT2gpi) = + *(ckt->CKTstate1 + here->BJT2gpi); + *(ckt->CKTstate0 + here->BJT2gmu) = + *(ckt->CKTstate1 + here->BJT2gmu); + *(ckt->CKTstate0 + here->BJT2gm) = + *(ckt->CKTstate1 + here->BJT2gm); + *(ckt->CKTstate0 + here->BJT2go) = + *(ckt->CKTstate1 + here->BJT2go); + *(ckt->CKTstate0 + here->BJT2gx) = + *(ckt->CKTstate1 + here->BJT2gx); + *(ckt->CKTstate0 + here->BJT2vsub) = + *(ckt->CKTstate1 + here->BJT2vsub); + vsub = (1+xfact)**(ckt->CKTstate1 + here->BJT2vsub)- + xfact* *(ckt->CKTstate2 + here->BJT2vsub); + } else { +#endif /* PREDICTOR */ + /* + * compute new nonlinear branch voltages + */ + vbe=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2basePrimeNode)- + *(ckt->CKTrhsOld+here->BJT2emitPrimeNode)); + vbc=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2basePrimeNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2substConNode)); +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvbe=vbe- *(ckt->CKTstate0 + here->BJT2vbe); + delvbc=vbc- *(ckt->CKTstate0 + here->BJT2vbc); + vbx=model->BJT2type*( + *(ckt->CKTrhsOld+here->BJT2baseNode)- + *(ckt->CKTrhsOld+here->BJT2colPrimeNode)); + vsub=model->BJT2type*model->BJT2subs*( + *(ckt->CKTrhsOld+here->BJT2substNode)- + *(ckt->CKTrhsOld+here->BJT2substConNode)); + cchat= *(ckt->CKTstate0 + here->BJT2cc)+(*(ckt->CKTstate0 + + here->BJT2gm)+ *(ckt->CKTstate0 + here->BJT2go))*delvbe- + (*(ckt->CKTstate0 + here->BJT2go)+*(ckt->CKTstate0 + + here->BJT2gmu))*delvbc; + cbhat= *(ckt->CKTstate0 + here->BJT2cb)+ *(ckt->CKTstate0 + + here->BJT2gpi)*delvbe+ *(ckt->CKTstate0 + here->BJT2gmu)* + delvbc; + + /* + * bypass if solution has not changed + */ + /* the following collections of if's would be just one + * if the average compiler could handle it, but many + * find the expression too complicated, thus the split. + */ + if( (ckt->CKTbypass) && + (!(ckt->CKTmode & MODEINITPRED)) && + (fabs(delvbe) < (ckt->CKTreltol*MAX(fabs(vbe), + fabs(*(ckt->CKTstate0 + here->BJT2vbe)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvbc) < ckt->CKTreltol*MAX(fabs(vbc), + fabs(*(ckt->CKTstate0 + here->BJT2vbc)))+ + ckt->CKTvoltTol) ) + if( (fabs(cchat-*(ckt->CKTstate0 + here->BJT2cc)) < + ckt->CKTreltol* MAX(fabs(cchat), + fabs(*(ckt->CKTstate0 + here->BJT2cc)))+ + ckt->CKTabstol) ) + if( (fabs(cbhat-*(ckt->CKTstate0 + here->BJT2cb)) < + ckt->CKTreltol* MAX(fabs(cbhat), + fabs(*(ckt->CKTstate0 + here->BJT2cb)))+ + ckt->CKTabstol) ) { + /* + * bypassing.... + */ + vbe = *(ckt->CKTstate0 + here->BJT2vbe); + vbc = *(ckt->CKTstate0 + here->BJT2vbc); + cc = *(ckt->CKTstate0 + here->BJT2cc); + cb = *(ckt->CKTstate0 + here->BJT2cb); + gpi = *(ckt->CKTstate0 + here->BJT2gpi); + gmu = *(ckt->CKTstate0 + here->BJT2gmu); + gm = *(ckt->CKTstate0 + here->BJT2gm); + go = *(ckt->CKTstate0 + here->BJT2go); + gx = *(ckt->CKTstate0 + here->BJT2gx); + geqcb = *(ckt->CKTstate0 + here->BJT2geqcb); + gcsub = *(ckt->CKTstate0 + here->BJT2gcsub); + geqbx = *(ckt->CKTstate0 + here->BJT2geqbx); + vsub = *(ckt->CKTstate0 + here->BJT2vsub); + gdsub = *(ckt->CKTstate0 + here->BJT2gdsub); + cdsub = *(ckt->CKTstate0 + here->BJT2cdsub); + goto load; + } + + /* + * limit nonlinear branch voltages + */ + ichk1=1; + vbe = DEVpnjlim(vbe,*(ckt->CKTstate0 + here->BJT2vbe),vt, + here->BJT2tVcrit,&icheck); + vbc = DEVpnjlim(vbc,*(ckt->CKTstate0 + here->BJT2vbc),vt, + here->BJT2tVcrit,&ichk1); + if (ichk1 == 1) icheck=1; + vsub = DEVpnjlim(vsub,*(ckt->CKTstate0 + here->BJT2vsub),vt, + here->BJT2tSubVcrit,&ichk1); + if (ichk1 == 1) icheck=1; + } + /* + * determine dc current and derivitives + */ +next1: vtn=vt*model->BJT2emissionCoeffF; + if(vbe >= -3*vtn){ + evbe=exp(vbe/vtn); + cbe=csat*(evbe-1); + gbe=csat*evbe/vtn; + } else { + arg=3*vtn/(vbe*CONSTe); + arg = arg * arg * arg; + cbe = -csat*(1+arg); + gbe = csat*3*arg/vbe; + } + if (c2 == 0) { + cben=0; + gben=0; + } else { + if(vbe >= -3*vte){ + evben=exp(vbe/vte); + cben=c2*(evben-1); + gben=c2*evben/vte; + } else { + arg=3*vte/(vbe*CONSTe); + arg = arg * arg * arg; + cben = -c2*(1+arg); + gben = c2*3*arg/vbe; + } + } + gben+=ckt->CKTgmin; + cben+=ckt->CKTgmin*vbe; + vtn=vt*model->BJT2emissionCoeffR; + if(vbc >= -3*vtn) { + evbc=exp(vbc/vtn); + cbc=csat*(evbc-1); + gbc=csat*evbc/vtn; + } else { + arg=3*vtn/(vbc*CONSTe); + arg = arg * arg * arg; + cbc = -csat*(1+arg); + gbc = csat*3*arg/vbc; + } + if (c4 == 0) { + cbcn=0; + gbcn=0; + } else { + if(vbc >= -3*vtc) { + evbcn=exp(vbc/vtc); + cbcn=c4*(evbcn-1); + gbcn=c4*evbcn/vtc; + } else { + arg=3*vtc/(vbc*CONSTe); + arg = arg * arg * arg; + cbcn = -c4*(1+arg); + gbcn = c4*3*arg/vbc; + } + } + gbcn+=ckt->CKTgmin; + cbcn+=ckt->CKTgmin*vbc; + if(vsub <= -3*vt) { + arg=3*vt/(vsub*CONSTe); + arg = arg * arg * arg; + gdsub = csubsat*3*arg/vsub+ckt->CKTgmin; + cdsub = -csubsat*(1+arg)+ckt->CKTgmin*vsub; + } else { + evsub = exp(MIN(MAX_EXP_ARG,vsub/vt)); + gdsub = csubsat*evsub/vt + ckt->CKTgmin; + cdsub = csubsat*(evsub-1) + ckt->CKTgmin*vsub; + } + /* + * determine base charge terms + */ + q1=1/(1-model->BJT2invEarlyVoltF*vbc-model->BJT2invEarlyVoltR*vbe); + if(oik == 0 && oikr == 0) { + qb=q1; + dqbdve=q1*qb*model->BJT2invEarlyVoltR; + dqbdvc=q1*qb*model->BJT2invEarlyVoltF; + } else { + q2=oik*cbe+oikr*cbc; + arg=MAX(0,1+4*q2); + sqarg=1; + if(arg != 0) sqarg=sqrt(arg); + qb=q1*(1+sqarg)/2; + dqbdve=q1*(qb*model->BJT2invEarlyVoltR+oik*gbe/sqarg); + dqbdvc=q1*(qb*model->BJT2invEarlyVoltF+oikr*gbc/sqarg); + } + /* + * weil's approx. for excess phase applied with backward- + * euler integration + */ + cc=0; + cex=cbe; + gex=gbe; + if(ckt->CKTmode & (MODETRAN | MODEAC) && td != 0) { + arg1=ckt->CKTdelta/td; + arg2=3*arg1; + arg1=arg2*arg1; + denom=1+arg1+arg2; + arg3=arg1/denom; + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->BJT2cexbc)=cbe/qb; + *(ckt->CKTstate2 + here->BJT2cexbc)= + *(ckt->CKTstate1 + here->BJT2cexbc); + } + cc=(*(ckt->CKTstate1 + here->BJT2cexbc)*(1+ckt->CKTdelta/ + ckt->CKTdeltaOld[1]+arg2)- + *(ckt->CKTstate2 + here->BJT2cexbc)*ckt->CKTdelta/ + ckt->CKTdeltaOld[1])/denom; + cex=cbe*arg3; + gex=gbe*arg3; + *(ckt->CKTstate0 + here->BJT2cexbc)=cc+cex/qb; + } + /* + * determine dc incremental conductances + */ + cc=cc+(cex-cbc)/qb-cbc/here->BJT2tBetaR-cbcn; + cb=cbe/here->BJT2tBetaF+cben+cbc/here->BJT2tBetaR+cbcn; + gx=rbpr+rbpi/qb; + if(xjrb != 0) { + arg1=MAX(cb/xjrb,1e-9); + arg2=(-1+sqrt(1+14.59025*arg1))/2.4317/sqrt(arg1); + arg1=tan(arg2); + gx=rbpr+3*rbpi*(arg1-arg2)/arg2/arg1/arg1; + } + if(gx != 0) gx=1/gx; + gpi=gbe/here->BJT2tBetaF+gben; + gmu=gbc/here->BJT2tBetaR+gbcn; + go=(gbc+(cex-cbc)*dqbdvc/qb)/qb; + gm=(gex-(cex-cbc)*dqbdve/qb)/qb-go; + if( (ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || + (ckt->CKTmode & MODEINITSMSIG)) { + /* + * charge storage elements + */ + tf=model->BJT2transitTimeF; + tr=model->BJT2transitTimeR; + czbe=here->BJT2tBEcap*here->BJT2area; + pe=here->BJT2tBEpot; + xme=model->BJT2junctionExpBE; + cdis=model->BJT2baseFractionBCcap; + ctot=here->BJT2tBCcap*here->BJT2area; + czbc=ctot*cdis; + czbx=ctot-czbc; + pc=here->BJT2tBCpot; + xmc=model->BJT2junctionExpBC; + fcpe=here->BJT2tDepCap; + czsub=here->BJT2tSubcap*here->BJT2area; + ps=here->BJT2tSubpot; + xms=model->BJT2exponentialSubstrate; + xtf=model->BJT2transitTimeBiasCoeffF; + ovtf=model->BJT2transitTimeVBCFactor; + xjtf=model->BJT2transitTimeHighCurrentF*here->BJT2area; + if(tf != 0 && vbe >0) { + argtf=0; + arg2=0; + arg3=0; + if(xtf != 0){ + argtf=xtf; + if(ovtf != 0) { + argtf=argtf*exp(vbc*ovtf); + } + arg2=argtf; + if(xjtf != 0) { + temp=cbe/(cbe+xjtf); + argtf=argtf*temp*temp; + arg2=argtf*(3-temp-temp); + } + arg3=cbe*argtf*ovtf; + } + cbe=cbe*(1+argtf)/qb; + gbe=(gbe*(1+arg2)-cbe*dqbdve)/qb; + geqcb=tf*(arg3-cbe*dqbdvc)/qb; + } + if (vbe < fcpe) { + arg=1-vbe/pe; + sarg=exp(-xme*log(arg)); + *(ckt->CKTstate0 + here->BJT2qbe)=tf*cbe+pe*czbe* + (1-arg*sarg)/(1-xme); + capbe=tf*gbe+czbe*sarg; + } else { + f1=here->BJT2tf1; + f2=model->BJT2f2; + f3=model->BJT2f3; + czbef2=czbe/f2; + *(ckt->CKTstate0 + here->BJT2qbe) = tf*cbe+czbe*f1+czbef2* + (f3*(vbe-fcpe) +(xme/(pe+pe))*(vbe*vbe-fcpe*fcpe)); + capbe=tf*gbe+czbef2*(f3+xme*vbe/pe); + } + fcpc=here->BJT2tf4; + f1=here->BJT2tf5; + f2=model->BJT2f6; + f3=model->BJT2f7; + if (vbc < fcpc) { + arg=1-vbc/pc; + sarg=exp(-xmc*log(arg)); + *(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+pc*czbc*( + 1-arg*sarg)/(1-xmc); + capbc=tr*gbc+czbc*sarg; + } else { + czbcf2=czbc/f2; + *(ckt->CKTstate0 + here->BJT2qbc) = tr*cbc+czbc*f1+czbcf2* + (f3*(vbc-fcpc) +(xmc/(pc+pc))*(vbc*vbc-fcpc*fcpc)); + capbc=tr*gbc+czbcf2*(f3+xmc*vbc/pc); + } + if(vbx < fcpc) { + arg=1-vbx/pc; + sarg=exp(-xmc*log(arg)); + *(ckt->CKTstate0 + here->BJT2qbx)= + pc*czbx* (1-arg*sarg)/(1-xmc); + capbx=czbx*sarg; + } else { + czbxf2=czbx/f2; + *(ckt->CKTstate0 + here->BJT2qbx)=czbx*f1+czbxf2* + (f3*(vbx-fcpc)+(xmc/(pc+pc))*(vbx*vbx-fcpc*fcpc)); + capbx=czbxf2*(f3+xmc*vbx/pc); + } + if(vsub < 0){ + arg=1-vsub/ps; + sarg=exp(-xms*log(arg)); + *(ckt->CKTstate0 + here->BJT2qsub) = ps*czsub*(1-arg*sarg)/ + (1-xms); + capsub=czsub*sarg; + } else { + *(ckt->CKTstate0 + here->BJT2qsub) = vsub*czsub*(1+xms*vsub/ + (2*ps)); + capsub=czsub*(1+xms*vsub/ps); + } + here->BJT2capbe = capbe; + here->BJT2capbc = capbc; + here->BJT2capsub = capsub; + here->BJT2capbx = capbx; + + /* + * store small-signal parameters + */ + if ( (!(ckt->CKTmode & MODETRANOP))|| + (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->BJT2cqbe) = capbe; + *(ckt->CKTstate0 + here->BJT2cqbc) = capbc; + *(ckt->CKTstate0 + here->BJT2cqsub) = capsub; + *(ckt->CKTstate0 + here->BJT2cqbx) = capbx; + *(ckt->CKTstate0 + here->BJT2cexbc) = geqcb; + if(SenCond){ + *(ckt->CKTstate0 + here->BJT2cc) = cc; + *(ckt->CKTstate0 + here->BJT2cb) = cb; + *(ckt->CKTstate0 + here->BJT2gpi) = gpi; + *(ckt->CKTstate0 + here->BJT2gmu) = gmu; + *(ckt->CKTstate0 + here->BJT2gm) = gm; + *(ckt->CKTstate0 + here->BJT2go) = go; + *(ckt->CKTstate0 + here->BJT2gx) = gx; + *(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; + *(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; + } +#ifdef SENSDEBUG + printf("storing small signal parameters for op\n"); + printf("capbe = %.7e ,capbc = %.7e\n",capbe,capbc); + printf("capsub = %.7e ,capbx = %.7e\n",capsub,capbx); + printf("geqcb = %.7e ,gpi = %.7e\n",geqcb,gpi); + printf("gmu = %.7e ,gm = %.7e\n",gmu,gm); + printf("go = %.7e ,gx = %.7e\n",go,gx); + printf("gcsub = %.7e ,geqbx = %.7e\n",gcsub,geqbx); + printf("cc = %.7e ,cb = %.7e\n",cc,cb); +#endif /* SENSDEBUG */ + continue; /* go to 1000 */ + } + /* + * transient analysis + */ + if(SenCond && ckt->CKTsenInfo->SENmode == TRANSEN){ + *(ckt->CKTstate0 + here->BJT2cc) = cc; + *(ckt->CKTstate0 + here->BJT2cb) = cb; + *(ckt->CKTstate0 + here->BJT2gx) = gx; + continue; + } + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->BJT2qbe) = + *(ckt->CKTstate0 + here->BJT2qbe) ; + *(ckt->CKTstate1 + here->BJT2qbc) = + *(ckt->CKTstate0 + here->BJT2qbc) ; + *(ckt->CKTstate1 + here->BJT2qbx) = + *(ckt->CKTstate0 + here->BJT2qbx) ; + *(ckt->CKTstate1 + here->BJT2qsub) = + *(ckt->CKTstate0 + here->BJT2qsub) ; + } + error = NIintegrate(ckt,&geq,&ceq,capbe,here->BJT2qbe); + if(error) return(error); + geqcb=geqcb*ckt->CKTag[0]; + gpi=gpi+geq; + cb=cb+*(ckt->CKTstate0 + here->BJT2cqbe); + error = NIintegrate(ckt,&geq,&ceq,capbc,here->BJT2qbc); + if(error) return(error); + gmu=gmu+geq; + cb=cb+*(ckt->CKTstate0 + here->BJT2cqbc); + cc=cc-*(ckt->CKTstate0 + here->BJT2cqbc); + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->BJT2cqbe) = + *(ckt->CKTstate0 + here->BJT2cqbe); + *(ckt->CKTstate1 + here->BJT2cqbc) = + *(ckt->CKTstate0 + here->BJT2cqbc); + } + } + } + + if(SenCond) goto next2; + + /* + * check convergence + */ + if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->BJT2off))) { + if (icheck == 1) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + } + } + + /* + * charge storage for c-s and b-x junctions + */ + if(ckt->CKTmode & (MODETRAN | MODEAC)) { + error = NIintegrate(ckt,&gcsub,&ceq,capsub,here->BJT2qsub); + if(error) return(error); + error = NIintegrate(ckt,&geqbx,&ceq,capbx,here->BJT2qbx); + if(error) return(error); + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->BJT2cqbx) = + *(ckt->CKTstate0 + here->BJT2cqbx); + *(ckt->CKTstate1 + here->BJT2cqsub) = + *(ckt->CKTstate0 + here->BJT2cqsub); + } + } +next2: + *(ckt->CKTstate0 + here->BJT2vbe) = vbe; + *(ckt->CKTstate0 + here->BJT2vbc) = vbc; + *(ckt->CKTstate0 + here->BJT2cc) = cc; + *(ckt->CKTstate0 + here->BJT2cb) = cb; + *(ckt->CKTstate0 + here->BJT2gpi) = gpi; + *(ckt->CKTstate0 + here->BJT2gmu) = gmu; + *(ckt->CKTstate0 + here->BJT2gm) = gm; + *(ckt->CKTstate0 + here->BJT2go) = go; + *(ckt->CKTstate0 + here->BJT2gx) = gx; + *(ckt->CKTstate0 + here->BJT2geqcb) = geqcb; + *(ckt->CKTstate0 + here->BJT2gcsub) = gcsub; + *(ckt->CKTstate0 + here->BJT2geqbx) = geqbx; + *(ckt->CKTstate0 + here->BJT2vsub) = vsub; + *(ckt->CKTstate0 + here->BJT2gdsub) = gdsub; + *(ckt->CKTstate0 + here->BJT2cdsub) = cdsub; + + + /* Do not load the Jacobian and the rhs if + perturbation is being carried out */ + + if(SenCond)continue; +load: + /* + * load current excitation vector + */ + geqsub = gcsub + gdsub; + ceqsub=model->BJT2type * model->BJT2subs * + (*(ckt->CKTstate0 + here->BJT2cqsub) + cdsub - vsub*geqsub); +/* + ceqsub=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqsub) + + model->BJT2subs*cdsub - vsub*geqsub); +*/ + ceqbx=model->BJT2type * (*(ckt->CKTstate0 + here->BJT2cqbx) - + vbx * geqbx); + ceqbe=model->BJT2type * (cc + cb - vbe * (gm + go + gpi) + vbc * + (go - geqcb)); + ceqbc=model->BJT2type * (-cc + vbe * (gm + go) - vbc * (gmu + go)); + + *(ckt->CKTrhs + here->BJT2baseNode) += (-ceqbx); + *(ckt->CKTrhs + here->BJT2colPrimeNode) += + (ceqbx+ceqbc); + *(ckt->CKTrhs + here->BJT2substConNode) += ceqsub; + *(ckt->CKTrhs + here->BJT2basePrimeNode) += + (-ceqbe-ceqbc); + *(ckt->CKTrhs + here->BJT2emitPrimeNode) += (ceqbe); + *(ckt->CKTrhs + here->BJT2substNode) += (-ceqsub); + + /* + * load y matrix + */ + *(here->BJT2colColPtr) += (gcpr); + *(here->BJT2baseBasePtr) += (gx+geqbx); + *(here->BJT2emitEmitPtr) += (gepr); + *(here->BJT2colPrimeColPrimePtr) += (gmu+go+gcpr+geqbx); + *(here->BJT2substConSubstConPtr) += (geqsub); + *(here->BJT2basePrimeBasePrimePtr) += (gx +gpi+gmu+geqcb); + *(here->BJT2emitPrimeEmitPrimePtr) += (gpi+gepr+gm+go); + *(here->BJT2colColPrimePtr) += (-gcpr); + *(here->BJT2baseBasePrimePtr) += (-gx); + *(here->BJT2emitEmitPrimePtr) += (-gepr); + *(here->BJT2colPrimeColPtr) += (-gcpr); + *(here->BJT2colPrimeBasePrimePtr) += (-gmu+gm); + *(here->BJT2colPrimeEmitPrimePtr) += (-gm-go); + *(here->BJT2basePrimeBasePtr) += (-gx); + *(here->BJT2basePrimeColPrimePtr) += (-gmu-geqcb); + *(here->BJT2basePrimeEmitPrimePtr) += (-gpi); + *(here->BJT2emitPrimeEmitPtr) += (-gepr); + *(here->BJT2emitPrimeColPrimePtr) += (-go+geqcb); + *(here->BJT2emitPrimeBasePrimePtr) += (-gpi-gm-geqcb); + *(here->BJT2substSubstPtr) += (geqsub); + *(here->BJT2substConSubstPtr) += (-geqsub); + *(here->BJT2substSubstConPtr) += (-geqsub); + *(here->BJT2baseColPrimePtr) += (-geqbx); + *(here->BJT2colPrimeBasePtr) += (-geqbx); + } + } + return(OK); +} diff --git a/src/spicelib/devices/bjt2/bjt2mask.c b/src/spicelib/devices/bjt2/bjt2mask.c index 1e232a5b2..4fda8339e 100644 --- a/src/spicelib/devices/bjt2/bjt2mask.c +++ b/src/spicelib/devices/bjt2/bjt2mask.c @@ -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 */ +} + diff --git a/src/spicelib/devices/bjt2/bjt2mdel.c b/src/spicelib/devices/bjt2/bjt2mdel.c index 554c740a4..30186d253 100644 --- a/src/spicelib/devices/bjt2/bjt2mdel.c +++ b/src/spicelib/devices/bjt2/bjt2mdel.c @@ -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); + +} diff --git a/src/spicelib/devices/bjt2/bjt2mpar.c b/src/spicelib/devices/bjt2/bjt2mpar.c index 4db2595e5..a6677479b 100644 --- a/src/spicelib/devices/bjt2/bjt2mpar.c +++ b/src/spicelib/devices/bjt2/bjt2mpar.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2noise.c b/src/spicelib/devices/bjt2/bjt2noise.c index bd90bd3b8..43614890b 100644 --- a/src/spicelib/devices/bjt2/bjt2noise.c +++ b/src/spicelib/devices/bjt2/bjt2noise.c @@ -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); +} + + diff --git a/src/spicelib/devices/bjt2/bjt2param.c b/src/spicelib/devices/bjt2/bjt2param.c index 83566fc62..34ceee8f6 100644 --- a/src/spicelib/devices/bjt2/bjt2param.c +++ b/src/spicelib/devices/bjt2/bjt2param.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2pzld.c b/src/spicelib/devices/bjt2/bjt2pzld.c index dc4db9d8f..933a8ad58 100644 --- a/src/spicelib/devices/bjt2/bjt2pzld.c +++ b/src/spicelib/devices/bjt2/bjt2pzld.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2sacl.c b/src/spicelib/devices/bjt2/bjt2sacl.c index 13c27ed34..957bbdaba 100644 --- a/src/spicelib/devices/bjt2/bjt2sacl.c +++ b/src/spicelib/devices/bjt2/bjt2sacl.c @@ -1,713 +1,710 @@ -/********** -Copyright 1990 Regents of the University of California. All rights reserved. -Author: 1985 Thomas L. Quarles -Modified: Alan Gillespie -**********/ - -/* actually load the current ac sensitivity - * information into the array previously provided - */ - -#include "ngspice.h" -#include "cktdefs.h" -#include "smpdefs.h" -#include "bjt2defs.h" -#include "const.h" -#include "sperror.h" -#include "ifsim.h" -#include "suffix.h" - - -int -BJT2sAcLoad(inModel,ckt) -GENmodel *inModel; -CKTcircuit *ckt; - -{ - - BJT2model *model = (BJT2model*)inModel; - BJT2instance *here; - double SaveState[25]; - int error; - int flag; - double vbeOp; - double vbcOp; - double A0; - double DELA; - double Apert; - double DELAinv; - double vte; - double gcpr; - double gepr; - double gpi; - double gmu; - double go; - double xgm; - double td; - double arg; - double gm; - double gx; - double xcpi; - double xcmu; - double xcbx; - double xccs; - double xcmcb; - double cx,icx; - double cbx,icbx; - double ccs,iccs; - double cbc,icbc; - double cbe,icbe; - double cce,icce; - double cb,icb; - double cbprm,icbprm; - double cc,icc; - double ccprm,iccprm; - double ce,ice; - double ceprm,iceprm; - double cs,ics; - double vcpr,ivcpr; - double vepr,ivepr; - double vx,ivx; - double vbx,ivbx; - double vcs,ivcs; - double vbc,ivbc; - double vbe,ivbe; - double vce,ivce; - double cb0,icb0; - double cbprm0,icbprm0; - double cc0,icc0; - double ccprm0,iccprm0; - double ce0,ice0; - double ceprm0,iceprm0; - double cs0,ics0; - double DvDp; - int iparmno,i; - SENstruct *info; - - -#ifdef SENSDEBUG - printf("BJT2senacload \n"); - printf("BJT2senacload \n"); -#endif /* SENSDEBUG */ - - info = ckt->CKTsenInfo; - info->SENstatus = PERTURBATION; - - /* loop through all the models */ - for( ; model != NULL; model = model->BJT2nextModel ) { - - /* loop through all the instances of the model */ - for (here = model->BJT2instances; here != NULL ; - here=here->BJT2nextInstance) { - - - /* save the unperturbed values in the state vector */ - for(i=0; i <= 20; i++) { - *(SaveState + i) = *(ckt->CKTstate0 + here->BJT2state + i); - } - - vcpr = *(ckt->CKTrhsOld + here->BJT2colNode) - - *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ; - ivcpr = *(ckt->CKTirhsOld + here->BJT2colNode) - - *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ; - vepr = *(ckt->CKTrhsOld + here->BJT2emitNode) - - *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ; - ivepr = *(ckt->CKTirhsOld + here->BJT2emitNode) - - *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ; - vx = *(ckt->CKTrhsOld + here->BJT2baseNode) - - *(ckt->CKTrhsOld + here->BJT2basePrimeNode) ;/* vb_bprm */ - ivx = *(ckt->CKTirhsOld + here->BJT2baseNode) - - *(ckt->CKTirhsOld + here->BJT2basePrimeNode) ;/* ivb_bprm */ - vcs = *(ckt->CKTrhsOld + here->BJT2colPrimeNode) - - *(ckt->CKTrhsOld + here->BJT2substNode) ; - ivcs = *(ckt->CKTirhsOld + here->BJT2colPrimeNode) - - *(ckt->CKTirhsOld + here->BJT2substNode) ; - vbc = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) - - *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ;/* vbprm_cprm */ - ivbc = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) - - *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ;/* ivbprm_cprm */ - vbe = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) - - *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ;/* vbprm_eprm */ - ivbe = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) - - *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ;/* ivbprm_eprm */ - vce = vbe - vbc ; - ivce = ivbe - ivbc ; - vbx = vx + vbc ; - ivbx = ivx + ivbc ; - - - - vbeOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) - - *(ckt->CKTrhsOp + here->BJT2emitPrimeNode)); - vbcOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) - - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); - -#ifdef SENSDEBUG - printf("\n without perturbation\n"); -#endif /* SENSDEBUG */ - /* without perturbation */ - A0 = here->BJT2area; - here->BJT2senPertFlag = ON; - *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; - *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; - /* info->SENacpertflag == 1 only for first frequency */ - - if(info->SENacpertflag == 1){ - - /* store the unperturbed values of small signal parameters */ - - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - - *(here->BJT2senGpi)= *(ckt->CKTstate0 + here->BJT2gpi); - *(here->BJT2senGmu)= *(ckt->CKTstate0 + here->BJT2gmu); - *(here->BJT2senGm)= *(ckt->CKTstate0 + here->BJT2gm); - *(here->BJT2senGo)= *(ckt->CKTstate0 + here->BJT2go); - *(here->BJT2senGx)= *(ckt->CKTstate0 + here->BJT2gx); - *(here->BJT2senCpi)= *(ckt->CKTstate0 + here->BJT2cqbe); - *(here->BJT2senCmu)= *(ckt->CKTstate0 + here->BJT2cqbc); - *(here->BJT2senCbx)= *(ckt->CKTstate0 + here->BJT2cqbx); - *(here->BJT2senCcs)= *(ckt->CKTstate0 + here->BJT2cqcs); - *(here->BJT2senCmcb)= *(ckt->CKTstate0 + here->BJT2cexbc); - } - gcpr = model->BJT2collectorConduct * A0; - gepr = model->BJT2emitterConduct * A0; - gpi= *(here->BJT2senGpi); - gmu= *(here->BJT2senGmu); - gm= *(here->BJT2senGm); - go= *(here->BJT2senGo); - gx= *(here->BJT2senGx); - xgm=0; - td=model->BJT2excessPhase; - if(td != 0) { - arg = td*ckt->CKTomega; - gm = gm+go; - xgm = -gm * sin(arg); - gm = gm * cos(arg)-go; - } - xcpi= *(here->BJT2senCpi) * ckt->CKTomega; - xcmu= *(here->BJT2senCmu) * ckt->CKTomega; - xcbx= *(here->BJT2senCbx) * ckt->CKTomega; - xccs= *(here->BJT2senCcs) * ckt->CKTomega; - xcmcb= *(here->BJT2senCmcb) * ckt->CKTomega; - - - cx=gx * vx ; - icx=gx * ivx; - cbx=( -xcbx * ivbx) ; - icbx= xcbx * vbx ; - ccs=( -xccs * ivcs) ; - iccs= xccs * vcs ; - cbc=(gmu * vbc -xcmu * ivbc) ; - icbc=xcmu * vbc + gmu * ivbc ; - cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; - icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; - cce= go * vce + gm * vbe - xgm * ivbe; - icce=go * ivce + gm * ivbe + xgm * vbe ; - - cc0=gcpr * vcpr ; - icc0=gcpr * ivcpr ; - ce0=gepr * vepr; - ice0=gepr * ivepr ; - cb0 = cx + cbx; - icb0 = icx + icbx; - if(here->BJT2baseNode != here->BJT2basePrimeNode){ - cbprm0 = (- cx + cbe + cbc); - icbprm0 = (- icx + icbe + icbc); - } - else{ - cbprm0 = ( cbx + cbe + cbc); - icbprm0 = (icbx + icbe + icbc); - } - ccprm0 = (- cbx - cc0 + ccs + cce - cbc); - iccprm0 = (- icbx - icc0 + iccs + icce - icbc); - ceprm0 = (- cbe - cce - ce0); - iceprm0 = (- icbe - icce - ice0); - cs0 = (- ccs) ; - ics0 = (- iccs) ; - -#ifdef SENSDEBUG - printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n", - gepr,gcpr,gmu,gpi); - printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n", - gm,go,gx,xcpi); - printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n" - ,xcmu,xcbx,xccs,xcmcb); - printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n", - vepr,ivepr,vcpr,ivcpr); - printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n", - vbx,ivbx,vx,ivx); - printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n", - vbc,ivbc,vbe,ivbe); - printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n", - vce,ivce,vcs,ivcs); - printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n", - cce,icce,cbe,icbe); - printf("cbc0 = %.7e + j%.7e\n", - cbc,icbc); - printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n", - cc0,icc0,ce0,ice0); - printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n", - cb0,icb0,cs0,ics0); - printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n", - cbprm0,icbprm0,ceprm0,iceprm0); - printf("ccprm0 = %.7e + j%.7e \n", - ccprm0,iccprm0); - printf("\nPerturbation of Area\n"); -#endif /* SENSDEBUG */ - /* Perturbation of Area */ - if(here->BJT2senParmNo == 0){ - flag = 0; - goto next1; - } - - DELA = info->SENpertfac * A0; - Apert = A0 + DELA; - DELAinv = 1.0/DELA; - here->BJT2area = Apert; - - *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; - *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; - if(info->SENacpertflag == 1){ - - /* store the small signal parameters - * corresponding to perturbed area - */ - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - - *(here->BJT2senGpi + 1)= *(ckt->CKTstate0 + here->BJT2gpi); - *(here->BJT2senGmu + 1)= *(ckt->CKTstate0 + here->BJT2gmu); - *(here->BJT2senGm + 1)= *(ckt->CKTstate0 + here->BJT2gm); - *(here->BJT2senGo + 1)= *(ckt->CKTstate0 + here->BJT2go); - *(here->BJT2senGx + 1)= *(ckt->CKTstate0 + here->BJT2gx); - *(here->BJT2senCpi + 1)= *(ckt->CKTstate0 + here->BJT2cqbe); - *(here->BJT2senCmu + 1)= *(ckt->CKTstate0 + here->BJT2cqbc); - *(here->BJT2senCbx + 1)= *(ckt->CKTstate0 + here->BJT2cqbx); - *(here->BJT2senCcs + 1)= *(ckt->CKTstate0 + here->BJT2cqcs); - *(here->BJT2senCmcb + 1)= *(ckt->CKTstate0 + here->BJT2cexbc); - } - - - flag = 0; - goto load; - - - -pertvbx: /* Perturbation of vbx */ -#ifdef SENSDEBUG - printf("\nPerturbation of vbx\n"); -#endif /* SENSDEBUG */ - here->BJT2area = A0; - A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2baseNode) - - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); - DELA = info->SENpertfac * A0 + 1e-8; - Apert = A0 + DELA; - DELAinv = model->BJT2type * 1.0/DELA; - *(ckt->CKTrhsOp + here->BJT2baseNode) += DELA; - *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; - *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; - - if(info->SENacpertflag == 1){ - - /* store the small signal parameters - * corresponding to perturbed vbx - */ - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - - *(here->BJT2senGpi + 2)= *(ckt->CKTstate0 + here->BJT2gpi); - *(here->BJT2senGmu + 2)= *(ckt->CKTstate0 + here->BJT2gmu); - *(here->BJT2senGm + 2)= *(ckt->CKTstate0 + here->BJT2gm); - *(here->BJT2senGo + 2)= *(ckt->CKTstate0 + here->BJT2go); - *(here->BJT2senGx + 2)= *(ckt->CKTstate0 + here->BJT2gx); - *(here->BJT2senCpi + 2)= *(ckt->CKTstate0 + here->BJT2cqbe); - *(here->BJT2senCmu + 2)= *(ckt->CKTstate0 + here->BJT2cqbc); - *(here->BJT2senCbx + 2)= *(ckt->CKTstate0 + here->BJT2cqbx); - *(here->BJT2senCcs + 2)= *(ckt->CKTstate0 + here->BJT2cqcs); - *(here->BJT2senCmcb + 2)= *(ckt->CKTstate0 + here->BJT2cexbc); - } - - - flag = 1; - goto load; - - -pertvbe: /* Perturbation of vbe */ -#ifdef SENSDEBUG - printf("\nPerturbation of vbe\n"); -#endif /* SENSDEBUG */ - if (*(here->BJT2senCbx) != 0){ - *(ckt->CKTrhsOp + here ->BJT2baseNode) -= DELA; - } - vte=model->BJT2leakBEemissionCoeff*CONSTvt0; - A0 = vbeOp; - DELA = info->SENpertfac * vte ; - Apert = A0 + DELA; - DELAinv = 1.0/DELA; - *(ckt->CKTstate0 + here->BJT2vbe) = Apert; - *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; - - if(info->SENacpertflag == 1){ - - /* store the small signal parameters - * corresponding to perturbed vbe - */ - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - - *(here->BJT2senGpi + 3)= *(ckt->CKTstate0 + here->BJT2gpi); - *(here->BJT2senGmu + 3)= *(ckt->CKTstate0 + here->BJT2gmu); - *(here->BJT2senGm + 3)= *(ckt->CKTstate0 + here->BJT2gm); - *(here->BJT2senGo + 3)= *(ckt->CKTstate0 + here->BJT2go); - *(here->BJT2senGx + 3)= *(ckt->CKTstate0 + here->BJT2gx); - *(here->BJT2senCpi + 3)= *(ckt->CKTstate0 + here->BJT2cqbe); - *(here->BJT2senCmu + 3)= *(ckt->CKTstate0 + here->BJT2cqbc); - *(here->BJT2senCbx + 3)= *(ckt->CKTstate0 + here->BJT2cqbx); - *(here->BJT2senCcs + 3)= *(ckt->CKTstate0 + here->BJT2cqcs); - *(here->BJT2senCmcb + 3)= *(ckt->CKTstate0 + here->BJT2cexbc); - } - - - flag = 2; - goto load; - - -pertvbc: /* Perturbation of vbc */ -#ifdef SENSDEBUG - printf("\nPerturbation of vbc\n"); -#endif /* SENSDEBUG */ - *(ckt->CKTstate0 + here->BJT2vbe) = A0; - - A0 = vbcOp; - DELA = info->SENpertfac * vte ; - Apert = A0 + DELA; - DELAinv = 1.0/DELA; - - - *(ckt->CKTstate0 + here->BJT2vbc) = Apert; - - *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; - - - - if(info->SENacpertflag == 1){ - - /* store the small signal parameters - * corresponding to perturbed vbc - */ - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - *(here->BJT2senGpi + 4)= *(ckt->CKTstate0 + here->BJT2gpi); - *(here->BJT2senGmu + 4)= *(ckt->CKTstate0 + here->BJT2gmu); - *(here->BJT2senGm + 4)= *(ckt->CKTstate0 + here->BJT2gm); - *(here->BJT2senGo + 4)= *(ckt->CKTstate0 + here->BJT2go); - *(here->BJT2senGx + 4)= *(ckt->CKTstate0 + here->BJT2gx); - *(here->BJT2senCpi + 4)= *(ckt->CKTstate0 + here->BJT2cqbe); - *(here->BJT2senCmu + 4)= *(ckt->CKTstate0 + here->BJT2cqbc); - *(here->BJT2senCbx + 4)= *(ckt->CKTstate0 + here->BJT2cqbx); - *(here->BJT2senCcs + 4)= *(ckt->CKTstate0 + here->BJT2cqcs); - *(here->BJT2senCmcb + 4)= *(ckt->CKTstate0 + here->BJT2cexbc); - - } - - - flag = 3; - goto load; - - - -pertvcs: /* Perturbation of vcs */ -#ifdef SENSDEBUG - printf("\nPerturbation of vcs\n"); -#endif /* SENSDEBUG */ - *(ckt->CKTstate0 + here->BJT2vbc) = A0; - A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2substNode) - - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); - DELA = info->SENpertfac * A0 + 1e-8; - Apert = A0 + DELA; - DELAinv = model->BJT2type * 1.0/DELA; - *(ckt->CKTrhsOp + here->BJT2substNode) += DELA; - *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; - *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; - - if(info->SENacpertflag == 1){ - - /* store the small signal parameters - * corresponding to perturbed vcs - */ - if(error = BJT2load((GENmodel*)model,ckt)) return(error); - *(here->BJT2senCcs + 5)= *(ckt->CKTstate0 + here->BJT2cqcs); - - } - - - flag = 4; - - *(ckt->CKTrhsOp + here->BJT2substNode) -= DELA; - xccs= *(here->BJT2senCcs + 5) * ckt->CKTomega; - - ccs=( -xccs * ivcs) ; - iccs= xccs * vcs ; - cs = -ccs; - ics = -iccs; - ccprm = ccprm0 + cs0 - cs; - iccprm = iccprm0 + ics0 - ics; - cbprm = cbprm0; - icbprm = icbprm0; - ceprm = ceprm0; - iceprm = iceprm0; - cc = cc0; - icc = icc0; - ce = ce0; - ice = ice0; - cb = cb0; - icb = icb0; - goto next2; - -load: - gcpr=model->BJT2collectorConduct * here->BJT2area; - gepr=model->BJT2emitterConduct * here->BJT2area; - gpi= *(here->BJT2senGpi + flag+1); - gmu= *(here->BJT2senGmu + flag+1); - gm= *(here->BJT2senGm + flag+1); - go= *(here->BJT2senGo + flag+1); - gx= *(here->BJT2senGx + flag+1); - xgm=0; - td=model->BJT2excessPhase; - if(td != 0) { - arg = td*ckt->CKTomega; - gm = gm+go; - xgm = -gm * sin(arg); - gm = gm * cos(arg)-go; - } - xcpi= *(here->BJT2senCpi + flag+1) * ckt->CKTomega; - xcmu= *(here->BJT2senCmu + flag+1) * ckt->CKTomega; - xcbx= *(here->BJT2senCbx + flag+1) * ckt->CKTomega; - xccs= *(here->BJT2senCcs + flag+1) * ckt->CKTomega; - xcmcb= *(here->BJT2senCmcb + flag+1) * ckt->CKTomega; - - - cc=gcpr * vcpr ; - icc=gcpr * ivcpr ; - ce=gepr * vepr; - ice=gepr * ivepr ; - cx=gx * vx ; - icx=gx * ivx; - cbx=( -xcbx * ivbx) ; - icbx= xcbx * vbx ; - ccs=( -xccs * ivcs) ; - iccs= xccs * vcs ; - cbc=(gmu * vbc -xcmu * ivbc) ; - icbc=xcmu * vbc + gmu * ivbc ; - cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; - icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; - cce= go * vce + gm * vbe - xgm * ivbe; - icce=go * ivce + gm * ivbe + xgm * vbe ; - - - cb= cx + cbx; - icb= icx + icbx; - if(here->BJT2baseNode != here->BJT2basePrimeNode){ - cbprm=(- cx + cbe + cbc); - icbprm=(- icx + icbe + icbc); - } - else{ - cbprm=( cbx + cbe + cbc); - icbprm=(icbx + icbe + icbc); - } - ccprm=(- cbx - cc + ccs + cce - cbc); - iccprm=(- icbx - icc + iccs + icce - icbc); - ceprm=(- cbe - cce - ce); - iceprm=(- icbe - icce - ice); - cs= (- ccs) ; - ics= (- iccs) ; - -#ifdef SENSDEBUG - printf("A0 = %.7e , Apert = %.7e , DELA = %.7e\n" - ,A0,Apert,DELA); - printf("gepr = %.7e , gcpr = %.7e , gmu = %.7e, gpi = %.7e\n" - ,gepr,gcpr,gmu,gpi); - printf("gm = %.7e , go = %.7e , gx = %.7e, xcpi = %.7e\n" - ,gm,go,gx,xcpi); - printf("xcmu = %.7e , xcbx = %.7e , xccs = %.7e, xcmcb = %.7e\n" - ,xcmu,xcbx,xccs,xcmcb); - - printf("cx = %.7e + j%.7e , cbx = %.7e + j%.7e\n" - ,cx,icx,cbx,icbx); - printf("ccs %.7e + j%.7e , cbc = %.7e + j%.7e" - ,ccs,iccs,cbc,icbc); - printf("cbe %.7e + j%.7e , cce = %.7e + j%.7e\n" - ,cbe,icbe,cce,icce); - - printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,", - ,cc,icc,ce,ice); - printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e", - ccprm,iccprm,ceprm,iceprm); - printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ", - cb,icb,cbprm,icbprm) - printf("cs = %.7e + j%.7e\n", - cs,ics); -#endif /* SENSDEBUG */ - - - /* load the RHS matrix */ -next2: - for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ - if( (!flag) && (iparmno != here->BJT2senParmNo) ) continue; - switch(flag){ - - case 0: - /* area : so no DC sensitivity term involved */ - DvDp = 1.0; - - break; - /* calculate the DC sensitivities of operating points */ - case 1: - DvDp = model->BJT2type * - (info->SEN_Sap[here->BJT2baseNode][iparmno] - - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); - break; - case 2: - DvDp = model->BJT2type * - (info->SEN_Sap[here->BJT2basePrimeNode][iparmno] - - info->SEN_Sap[here->BJT2emitPrimeNode][iparmno]); - break; - case 3: - DvDp = model->BJT2type * - (info->SEN_Sap[here->BJT2basePrimeNode][iparmno] - - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); - break; - case 4: - DvDp = model->BJT2type * - (info->SEN_Sap[here->BJT2substNode][iparmno] - - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); - break; - } -#ifdef SENSDEBUG - printf("before loading\n"); - printf("BJT2type = %d\n",model->BJT2type); - printf("DvDp = %.7e , flag = %d , iparmno = %d,senparmno = %d\n" - ,DvDp,flag,iparmno,here->BJT2senParmNo); - printf("senb = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), - *(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); - printf("senbrm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); - printf("senc = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2colNode] + iparmno), - *(info->SEN_iRHS[here->BJT2colNode] + iparmno)); - printf("sencprm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); - printf("sene = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), - *(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); - printf("seneprm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); - printf("sens = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2substNode] + iparmno), - *(info->SEN_iRHS[here->BJT2substNode] + iparmno)); -#endif /* SENSDEBUG */ - - - if(here->BJT2baseNode != here->BJT2basePrimeNode){ - *(info->SEN_RHS[here->BJT2baseNode] + iparmno) -= - ( cb - cb0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2baseNode] + iparmno) -= - ( icb - icb0) * DELAinv * DvDp; - } - - *(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno) -= - ( cbprm - cbprm0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno) -= - ( icbprm - icbprm0) * DELAinv * DvDp; - - if(here->BJT2colNode != here->BJT2colPrimeNode){ - *(info->SEN_RHS[here->BJT2colNode] + iparmno) -= - ( cc - cc0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2colNode] + iparmno) -= - ( icc - icc0) * DELAinv * DvDp; - } - - *(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno) -= - ( ccprm - ccprm0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno) -= - ( iccprm - iccprm0) * DELAinv * DvDp; - - if(here->BJT2emitNode != here->BJT2emitPrimeNode){ - *(info->SEN_RHS[here->BJT2emitNode] + iparmno) -= - ( ce - ce0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2emitNode] + iparmno) -= - ( ice - ice0) * DELAinv * DvDp; - } - - *(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno) -= - ( ceprm - ceprm0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno) -= - ( iceprm - iceprm0) * DELAinv * DvDp; - *(info->SEN_RHS[here->BJT2substNode] + iparmno) -= - ( cs - cs0) * DELAinv * DvDp; - *(info->SEN_iRHS[here->BJT2substNode] + iparmno) -= - ( ics - ics0) * DELAinv * DvDp; -#ifdef SENSDEBUG - printf("after loading\n"); - - printf("senb = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), - *(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); - printf("senbrm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); - printf("senc = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2colNode] + iparmno), - *(info->SEN_iRHS[here->BJT2colNode] + iparmno)); - printf("sencprm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); - printf("sene = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), - *(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); - printf("seneprm = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), - *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); - printf("sens = %.7e + j%.7e\n " - ,*(info->SEN_RHS[here->BJT2substNode] + iparmno), - *(info->SEN_iRHS[here->BJT2substNode] + iparmno)); -#endif /* SENSDEBUG */ - - } - - -next1: - switch(flag){ - case 0: - if (*(here->BJT2senCbx) == 0){ - here->BJT2area = A0; - goto pertvbe ; - } - else{ - goto pertvbx; - } - case 1: - goto pertvbe ; - case 2: - goto pertvbc ; - case 3: - goto pertvcs ; - case 4: - break; - } - - /* put the unperturbed values back into the state vector */ - for(i=0; i <= 20; i++) { - *(ckt->CKTstate0 + here->BJT2state + i) = *(SaveState + i); - } - here->BJT2senPertFlag = OFF; - } - - } - info->SENstatus = NORMAL; -#ifdef SENSDEBUG - printf("BJT2senacload end\n"); -#endif /* SENSDEBUG */ - return(OK); -} - +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Modified: Alan Gillespie +**********/ + +/* actually load the current ac sensitivity + * information into the array previously provided + */ + +#include "ngspice.h" +#include "cktdefs.h" +#include "smpdefs.h" +#include "bjt2defs.h" +#include "const.h" +#include "sperror.h" +#include "ifsim.h" +#include "suffix.h" + + +int +BJT2sAcLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + + BJT2model *model = (BJT2model*)inModel; + BJT2instance *here; + double SaveState[25]; + int error; + int flag; + double vbeOp; + double vbcOp; + double A0; + double DELA; + double Apert; + double DELAinv; + double vte; + double gcpr; + double gepr; + double gpi; + double gmu; + double go; + double xgm; + double td; + double arg; + double gm; + double gx; + double xcpi; + double xcmu; + double xcbx; + double xccs; + double xcmcb; + double cx,icx; + double cbx,icbx; + double ccs,iccs; + double cbc,icbc; + double cbe,icbe; + double cce,icce; + double cb,icb; + double cbprm,icbprm; + double cc,icc; + double ccprm,iccprm; + double ce,ice; + double ceprm,iceprm; + double cs,ics; + double vcpr,ivcpr; + double vepr,ivepr; + double vx,ivx; + double vbx,ivbx; + double vcs,ivcs; + double vbc,ivbc; + double vbe,ivbe; + double vce,ivce; + double cb0,icb0; + double cbprm0,icbprm0; + double cc0,icc0; + double ccprm0,iccprm0; + double ce0,ice0; + double ceprm0,iceprm0; + double cs0,ics0; + double DvDp; + int iparmno,i; + SENstruct *info; + + +#ifdef SENSDEBUG + printf("BJT2senacload \n"); + printf("BJT2senacload \n"); +#endif /* SENSDEBUG */ + + info = ckt->CKTsenInfo; + info->SENstatus = PERTURBATION; + + /* loop through all the models */ + for( ; model != NULL; model = model->BJT2nextModel ) { + + /* loop through all the instances of the model */ + for (here = model->BJT2instances; here != NULL ; + here=here->BJT2nextInstance) { + + + /* save the unperturbed values in the state vector */ + for(i=0; i <= 20; i++) { + *(SaveState + i) = *(ckt->CKTstate0 + here->BJT2state + i); + } + + vcpr = *(ckt->CKTrhsOld + here->BJT2colNode) + - *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ; + ivcpr = *(ckt->CKTirhsOld + here->BJT2colNode) + - *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ; + vepr = *(ckt->CKTrhsOld + here->BJT2emitNode) + - *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ; + ivepr = *(ckt->CKTirhsOld + here->BJT2emitNode) + - *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ; + vx = *(ckt->CKTrhsOld + here->BJT2baseNode) + - *(ckt->CKTrhsOld + here->BJT2basePrimeNode) ;/* vb_bprm */ + ivx = *(ckt->CKTirhsOld + here->BJT2baseNode) + - *(ckt->CKTirhsOld + here->BJT2basePrimeNode) ;/* ivb_bprm */ + vcs = *(ckt->CKTrhsOld + here->BJT2colPrimeNode) + - *(ckt->CKTrhsOld + here->BJT2substNode) ; + ivcs = *(ckt->CKTirhsOld + here->BJT2colPrimeNode) + - *(ckt->CKTirhsOld + here->BJT2substNode) ; + vbc = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) + - *(ckt->CKTrhsOld + here->BJT2colPrimeNode) ;/* vbprm_cprm */ + ivbc = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) + - *(ckt->CKTirhsOld + here->BJT2colPrimeNode) ;/* ivbprm_cprm */ + vbe = *(ckt->CKTrhsOld + here->BJT2basePrimeNode) + - *(ckt->CKTrhsOld + here->BJT2emitPrimeNode) ;/* vbprm_eprm */ + ivbe = *(ckt->CKTirhsOld + here->BJT2basePrimeNode) + - *(ckt->CKTirhsOld + here->BJT2emitPrimeNode) ;/* ivbprm_eprm */ + vce = vbe - vbc ; + ivce = ivbe - ivbc ; + vbx = vx + vbc ; + ivbx = ivx + ivbc ; + + + + vbeOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) + - *(ckt->CKTrhsOp + here->BJT2emitPrimeNode)); + vbcOp =model->BJT2type * ( *(ckt->CKTrhsOp + here->BJT2basePrimeNode) + - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); + +#ifdef SENSDEBUG + printf("\n without perturbation\n"); +#endif /* SENSDEBUG */ + /* without perturbation */ + A0 = here->BJT2area; + here->BJT2senPertFlag = ON; + *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; + *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; + /* info->SENacpertflag == 1 only for first frequency */ + + if(info->SENacpertflag == 1){ + + /* store the unperturbed values of small signal parameters */ + + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + + *(here->BJT2senGpi)= *(ckt->CKTstate0 + here->BJT2gpi); + *(here->BJT2senGmu)= *(ckt->CKTstate0 + here->BJT2gmu); + *(here->BJT2senGm)= *(ckt->CKTstate0 + here->BJT2gm); + *(here->BJT2senGo)= *(ckt->CKTstate0 + here->BJT2go); + *(here->BJT2senGx)= *(ckt->CKTstate0 + here->BJT2gx); + *(here->BJT2senCpi)= *(ckt->CKTstate0 + here->BJT2cqbe); + *(here->BJT2senCmu)= *(ckt->CKTstate0 + here->BJT2cqbc); + *(here->BJT2senCbx)= *(ckt->CKTstate0 + here->BJT2cqbx); + *(here->BJT2senCsub)= *(ckt->CKTstate0 + here->BJT2cqsub); + *(here->BJT2senCmcb)= *(ckt->CKTstate0 + here->BJT2cexbc); + } + gcpr = here->BJT2tCollectorConduct * A0; + gepr = here->BJT2tEmitterConduct * A0; + gpi= *(here->BJT2senGpi); + gmu= *(here->BJT2senGmu); + gm= *(here->BJT2senGm); + go= *(here->BJT2senGo); + gx= *(here->BJT2senGx); + xgm=0; + td=model->BJT2excessPhase; + if(td != 0) { + arg = td*ckt->CKTomega; + gm = gm+go; + xgm = -gm * sin(arg); + gm = gm * cos(arg)-go; + } + xcpi= *(here->BJT2senCpi) * ckt->CKTomega; + xcmu= *(here->BJT2senCmu) * ckt->CKTomega; + xcbx= *(here->BJT2senCbx) * ckt->CKTomega; + xccs= *(here->BJT2senCsub) * ckt->CKTomega; + xcmcb= *(here->BJT2senCmcb) * ckt->CKTomega; + + + cx=gx * vx ; + icx=gx * ivx; + cbx=( -xcbx * ivbx) ; + icbx= xcbx * vbx ; + ccs=( -xccs * ivcs) ; + iccs= xccs * vcs ; + cbc=(gmu * vbc -xcmu * ivbc) ; + icbc=xcmu * vbc + gmu * ivbc ; + cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; + icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; + cce= go * vce + gm * vbe - xgm * ivbe; + icce=go * ivce + gm * ivbe + xgm * vbe ; + + cc0=gcpr * vcpr ; + icc0=gcpr * ivcpr ; + ce0=gepr * vepr; + ice0=gepr * ivepr ; + cb0 = cx + cbx; + icb0 = icx + icbx; + if(here->BJT2baseNode != here->BJT2basePrimeNode){ + cbprm0 = (- cx + cbe + cbc); + icbprm0 = (- icx + icbe + icbc); + } + else{ + cbprm0 = ( cbx + cbe + cbc); + icbprm0 = (icbx + icbe + icbc); + } + ccprm0 = (- cbx - cc0 + ccs + cce - cbc); + iccprm0 = (- icbx - icc0 + iccs + icce - icbc); + ceprm0 = (- cbe - cce - ce0); + iceprm0 = (- icbe - icce - ice0); + cs0 = (- ccs) ; + ics0 = (- iccs) ; + +#ifdef SENSDEBUG + printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n", + gepr,gcpr,gmu,gpi); + printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n", + gm,go,gx,xcpi); + printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n" + ,xcmu,xcbx,xccs,xcmcb); + printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n", + vepr,ivepr,vcpr,ivcpr); + printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n", + vbx,ivbx,vx,ivx); + printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n", + vbc,ivbc,vbe,ivbe); + printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n", + vce,ivce,vcs,ivcs); + printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n", + cce,icce,cbe,icbe); + printf("cbc0 = %.7e + j%.7e\n", + cbc,icbc); + printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n", + cc0,icc0,ce0,ice0); + printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n", + cb0,icb0,cs0,ics0); + printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n", + cbprm0,icbprm0,ceprm0,iceprm0); + printf("ccprm0 = %.7e + j%.7e \n", + ccprm0,iccprm0); + printf("\nPerturbation of Area\n"); +#endif /* SENSDEBUG */ + /* Perturbation of Area */ + if(here->BJT2senParmNo == 0){ + flag = 0; + goto next1; + } + + DELA = info->SENpertfac * A0; + Apert = A0 + DELA; + DELAinv = 1.0/DELA; + here->BJT2area = Apert; + + *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; + *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; + if(info->SENacpertflag == 1){ + + /* store the small signal parameters + * corresponding to perturbed area + */ + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + + *(here->BJT2senGpi + 1)= *(ckt->CKTstate0 + here->BJT2gpi); + *(here->BJT2senGmu + 1)= *(ckt->CKTstate0 + here->BJT2gmu); + *(here->BJT2senGm + 1)= *(ckt->CKTstate0 + here->BJT2gm); + *(here->BJT2senGo + 1)= *(ckt->CKTstate0 + here->BJT2go); + *(here->BJT2senGx + 1)= *(ckt->CKTstate0 + here->BJT2gx); + *(here->BJT2senCpi + 1)= *(ckt->CKTstate0 + here->BJT2cqbe); + *(here->BJT2senCmu + 1)= *(ckt->CKTstate0 + here->BJT2cqbc); + *(here->BJT2senCbx + 1)= *(ckt->CKTstate0 + here->BJT2cqbx); + *(here->BJT2senCsub + 1)= *(ckt->CKTstate0 + here->BJT2cqsub); + *(here->BJT2senCmcb + 1)= *(ckt->CKTstate0 + here->BJT2cexbc); + } + + + flag = 0; + goto load; + + + +pertvbx: /* Perturbation of vbx */ +#ifdef SENSDEBUG + printf("\nPerturbation of vbx\n"); +#endif /* SENSDEBUG */ + here->BJT2area = A0; + A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2baseNode) + - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); + DELA = info->SENpertfac * A0 + 1e-8; + Apert = A0 + DELA; + DELAinv = model->BJT2type * 1.0/DELA; + *(ckt->CKTrhsOp + here->BJT2baseNode) += DELA; + *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; + *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; + + if(info->SENacpertflag == 1){ + + /* store the small signal parameters + * corresponding to perturbed vbx + */ + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + + *(here->BJT2senGpi + 2)= *(ckt->CKTstate0 + here->BJT2gpi); + *(here->BJT2senGmu + 2)= *(ckt->CKTstate0 + here->BJT2gmu); + *(here->BJT2senGm + 2)= *(ckt->CKTstate0 + here->BJT2gm); + *(here->BJT2senGo + 2)= *(ckt->CKTstate0 + here->BJT2go); + *(here->BJT2senGx + 2)= *(ckt->CKTstate0 + here->BJT2gx); + *(here->BJT2senCpi + 2)= *(ckt->CKTstate0 + here->BJT2cqbe); + *(here->BJT2senCmu + 2)= *(ckt->CKTstate0 + here->BJT2cqbc); + *(here->BJT2senCbx + 2)= *(ckt->CKTstate0 + here->BJT2cqbx); + *(here->BJT2senCsub + 2)= *(ckt->CKTstate0 + here->BJT2cqsub); + *(here->BJT2senCmcb + 2)= *(ckt->CKTstate0 + here->BJT2cexbc); + } + + + flag = 1; + goto load; + + +pertvbe: /* Perturbation of vbe */ +#ifdef SENSDEBUG + printf("\nPerturbation of vbe\n"); +#endif /* SENSDEBUG */ + if (*(here->BJT2senCbx) != 0){ + *(ckt->CKTrhsOp + here ->BJT2baseNode) -= DELA; + } + vte=model->BJT2leakBEemissionCoeff*CONSTvt0; + A0 = vbeOp; + DELA = info->SENpertfac * vte ; + Apert = A0 + DELA; + DELAinv = 1.0/DELA; + *(ckt->CKTstate0 + here->BJT2vbe) = Apert; + *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; + + if(info->SENacpertflag == 1){ + + /* store the small signal parameters + * corresponding to perturbed vbe + */ + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + + *(here->BJT2senGpi + 3)= *(ckt->CKTstate0 + here->BJT2gpi); + *(here->BJT2senGmu + 3)= *(ckt->CKTstate0 + here->BJT2gmu); + *(here->BJT2senGm + 3)= *(ckt->CKTstate0 + here->BJT2gm); + *(here->BJT2senGo + 3)= *(ckt->CKTstate0 + here->BJT2go); + *(here->BJT2senGx + 3)= *(ckt->CKTstate0 + here->BJT2gx); + *(here->BJT2senCpi + 3)= *(ckt->CKTstate0 + here->BJT2cqbe); + *(here->BJT2senCmu + 3)= *(ckt->CKTstate0 + here->BJT2cqbc); + *(here->BJT2senCbx + 3)= *(ckt->CKTstate0 + here->BJT2cqbx); + *(here->BJT2senCsub + 3)= *(ckt->CKTstate0 + here->BJT2cqsub); + *(here->BJT2senCmcb + 3)= *(ckt->CKTstate0 + here->BJT2cexbc); + } + + + flag = 2; + goto load; + + +pertvbc: /* Perturbation of vbc */ +#ifdef SENSDEBUG + printf("\nPerturbation of vbc\n"); +#endif /* SENSDEBUG */ + *(ckt->CKTstate0 + here->BJT2vbe) = A0; + + A0 = vbcOp; + DELA = info->SENpertfac * vte ; + Apert = A0 + DELA; + DELAinv = 1.0/DELA; + + + *(ckt->CKTstate0 + here->BJT2vbc) = Apert; + + *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; + + + + if(info->SENacpertflag == 1){ + + /* store the small signal parameters + * corresponding to perturbed vbc + */ + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + *(here->BJT2senGpi + 4)= *(ckt->CKTstate0 + here->BJT2gpi); + *(here->BJT2senGmu + 4)= *(ckt->CKTstate0 + here->BJT2gmu); + *(here->BJT2senGm + 4)= *(ckt->CKTstate0 + here->BJT2gm); + *(here->BJT2senGo + 4)= *(ckt->CKTstate0 + here->BJT2go); + *(here->BJT2senGx + 4)= *(ckt->CKTstate0 + here->BJT2gx); + *(here->BJT2senCpi + 4)= *(ckt->CKTstate0 + here->BJT2cqbe); + *(here->BJT2senCmu + 4)= *(ckt->CKTstate0 + here->BJT2cqbc); + *(here->BJT2senCbx + 4)= *(ckt->CKTstate0 + here->BJT2cqbx); + *(here->BJT2senCsub + 4)= *(ckt->CKTstate0 + here->BJT2cqsub); + *(here->BJT2senCmcb + 4)= *(ckt->CKTstate0 + here->BJT2cexbc); + + } + + + flag = 3; + goto load; + + + +pertvcs: /* Perturbation of vcs */ +#ifdef SENSDEBUG + printf("\nPerturbation of vcs\n"); +#endif /* SENSDEBUG */ + *(ckt->CKTstate0 + here->BJT2vbc) = A0; + A0 = model->BJT2type * (*(ckt->CKTrhsOp + here->BJT2substNode) + - *(ckt->CKTrhsOp + here->BJT2colPrimeNode)); + DELA = info->SENpertfac * A0 + 1e-8; + Apert = A0 + DELA; + DELAinv = model->BJT2type * 1.0/DELA; + *(ckt->CKTrhsOp + here->BJT2substNode) += DELA; + *(ckt->CKTstate0 + here->BJT2vbe) = vbeOp; + *(ckt->CKTstate0 + here->BJT2vbc) = vbcOp; + + if(info->SENacpertflag == 1){ + + /* store the small signal parameters + * corresponding to perturbed vcs + */ + if(error = BJT2load((GENmodel*)model,ckt)) return(error); + *(here->BJT2senCsub + 5)= *(ckt->CKTstate0 + here->BJT2cqsub); + + } + + + flag = 4; + + *(ckt->CKTrhsOp + here->BJT2substNode) -= DELA; + xccs= *(here->BJT2senCsub + 5) * ckt->CKTomega; + + ccs=( -xccs * ivcs) ; + iccs= xccs * vcs ; + cs = -ccs; + ics = -iccs; + ccprm = ccprm0 + cs0 - cs; + iccprm = iccprm0 + ics0 - ics; + cbprm = cbprm0; + icbprm = icbprm0; + ceprm = ceprm0; + iceprm = iceprm0; + cc = cc0; + icc = icc0; + ce = ce0; + ice = ice0; + cb = cb0; + icb = icb0; + goto next2; + +load: + gcpr=here->BJT2tCollectorConduct * here->BJT2area; + gepr=here->BJT2tEmitterConduct * here->BJT2area; + gpi= *(here->BJT2senGpi + flag+1); + gmu= *(here->BJT2senGmu + flag+1); + gm= *(here->BJT2senGm + flag+1); + go= *(here->BJT2senGo + flag+1); + gx= *(here->BJT2senGx + flag+1); + xgm=0; + td=model->BJT2excessPhase; + if(td != 0) { + arg = td*ckt->CKTomega; + gm = gm+go; + xgm = -gm * sin(arg); + gm = gm * cos(arg)-go; + } + xcpi= *(here->BJT2senCpi + flag+1) * ckt->CKTomega; + xcmu= *(here->BJT2senCmu + flag+1) * ckt->CKTomega; + xcbx= *(here->BJT2senCbx + flag+1) * ckt->CKTomega; + xccs= *(here->BJT2senCsub + flag+1) * ckt->CKTomega; + xcmcb= *(here->BJT2senCmcb + flag+1) * ckt->CKTomega; + + + cc=gcpr * vcpr ; + icc=gcpr * ivcpr ; + ce=gepr * vepr; + ice=gepr * ivepr ; + cx=gx * vx ; + icx=gx * ivx; + cbx=( -xcbx * ivbx) ; + icbx= xcbx * vbx ; + ccs=( -xccs * ivcs) ; + iccs= xccs * vcs ; + cbc=(gmu * vbc -xcmu * ivbc) ; + icbc=xcmu * vbc + gmu * ivbc ; + cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ; + icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc; + cce= go * vce + gm * vbe - xgm * ivbe; + icce=go * ivce + gm * ivbe + xgm * vbe ; + + + cb= cx + cbx; + icb= icx + icbx; + if(here->BJT2baseNode != here->BJT2basePrimeNode){ + cbprm=(- cx + cbe + cbc); + icbprm=(- icx + icbe + icbc); + } + else{ + cbprm=( cbx + cbe + cbc); + icbprm=(icbx + icbe + icbc); + } + ccprm=(- cbx - cc + ccs + cce - cbc); + iccprm=(- icbx - icc + iccs + icce - icbc); + ceprm=(- cbe - cce - ce); + iceprm=(- icbe - icce - ice); + cs= (- ccs) ; + ics= (- iccs) ; + +#ifdef SENSDEBUG + printf("A0 = %.7e , Apert = %.7e , DELA = %.7e\n" + ,A0,Apert,DELA); + printf("gepr = %.7e , gcpr = %.7e , gmu = %.7e, gpi = %.7e\n" + ,gepr,gcpr,gmu,gpi); + printf("gm = %.7e , go = %.7e , gx = %.7e, xcpi = %.7e\n" + ,gm,go,gx,xcpi); + printf("xcmu = %.7e , xcbx = %.7e , xccs = %.7e, xcmcb = %.7e\n" + ,xcmu,xcbx,xccs,xcmcb); + + printf("cx = %.7e + j%.7e , cbx = %.7e + j%.7e\n" + ,cx,icx,cbx,icbx); + printf("ccs %.7e + j%.7e , cbc = %.7e + j%.7e" + ,ccs,iccs,cbc,icbc); + printf("cbe %.7e + j%.7e , cce = %.7e + j%.7e\n" + ,cbe,icbe,cce,icce); + + printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,", + ,cc,icc,ce,ice); + printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e", + ccprm,iccprm,ceprm,iceprm); + printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ", + cb,icb,cbprm,icbprm) + printf("cs = %.7e + j%.7e\n", + cs,ics); +#endif /* SENSDEBUG */ + + + /* load the RHS matrix */ +next2: + for(iparmno = 1;iparmno<=info->SENparms;iparmno++){ + if( (!flag) && (iparmno != here->BJT2senParmNo) ) continue; + switch(flag){ + + case 0: + /* area : so no DC sensitivity term involved */ + DvDp = 1.0; + + break; + /* calculate the DC sensitivities of operating points */ + case 1: + DvDp = model->BJT2type * + (info->SEN_Sap[here->BJT2baseNode][iparmno] + - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); + break; + case 2: + DvDp = model->BJT2type * + (info->SEN_Sap[here->BJT2basePrimeNode][iparmno] + - info->SEN_Sap[here->BJT2emitPrimeNode][iparmno]); + break; + case 3: + DvDp = model->BJT2type * + (info->SEN_Sap[here->BJT2basePrimeNode][iparmno] + - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); + break; + case 4: + DvDp = model->BJT2type * + (info->SEN_Sap[here->BJT2substNode][iparmno] + - info->SEN_Sap[here->BJT2colPrimeNode][iparmno]); + break; + } +#ifdef SENSDEBUG + printf("before loading\n"); + printf("BJT2type = %d\n",model->BJT2type); + printf("DvDp = %.7e , flag = %d , iparmno = %d,senparmno = %d\n" + ,DvDp,flag,iparmno,here->BJT2senParmNo); + printf("senb = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), + *(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); + printf("senbrm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); + printf("senc = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2colNode] + iparmno), + *(info->SEN_iRHS[here->BJT2colNode] + iparmno)); + printf("sencprm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); + printf("sene = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), + *(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); + printf("seneprm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); + printf("sens = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2substNode] + iparmno), + *(info->SEN_iRHS[here->BJT2substNode] + iparmno)); +#endif /* SENSDEBUG */ + + + if(here->BJT2baseNode != here->BJT2basePrimeNode){ + *(info->SEN_RHS[here->BJT2baseNode] + iparmno) -= + ( cb - cb0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2baseNode] + iparmno) -= + ( icb - icb0) * DELAinv * DvDp; + } + + *(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno) -= + ( cbprm - cbprm0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno) -= + ( icbprm - icbprm0) * DELAinv * DvDp; + + if(here->BJT2colNode != here->BJT2colPrimeNode){ + *(info->SEN_RHS[here->BJT2colNode] + iparmno) -= + ( cc - cc0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2colNode] + iparmno) -= + ( icc - icc0) * DELAinv * DvDp; + } + + *(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno) -= + ( ccprm - ccprm0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno) -= + ( iccprm - iccprm0) * DELAinv * DvDp; + + if(here->BJT2emitNode != here->BJT2emitPrimeNode){ + *(info->SEN_RHS[here->BJT2emitNode] + iparmno) -= + ( ce - ce0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2emitNode] + iparmno) -= + ( ice - ice0) * DELAinv * DvDp; + } + + *(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno) -= + ( ceprm - ceprm0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno) -= + ( iceprm - iceprm0) * DELAinv * DvDp; + *(info->SEN_RHS[here->BJT2substNode] + iparmno) -= + ( cs - cs0) * DELAinv * DvDp; + *(info->SEN_iRHS[here->BJT2substNode] + iparmno) -= + ( ics - ics0) * DELAinv * DvDp; +#ifdef SENSDEBUG + printf("after loading\n"); + + printf("senb = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2baseNode] + iparmno), + *(info->SEN_iRHS[here->BJT2baseNode] + iparmno)); + printf("senbrm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2basePrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2basePrimeNode] + iparmno)); + printf("senc = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2colNode] + iparmno), + *(info->SEN_iRHS[here->BJT2colNode] + iparmno)); + printf("sencprm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2colPrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2colPrimeNode] + iparmno)); + printf("sene = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2emitNode] + iparmno), + *(info->SEN_iRHS[here->BJT2emitNode] + iparmno)); + printf("seneprm = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2emitPrimeNode] + iparmno), + *(info->SEN_iRHS[here->BJT2emitPrimeNode] + iparmno)); + printf("sens = %.7e + j%.7e\n " + ,*(info->SEN_RHS[here->BJT2substNode] + iparmno), + *(info->SEN_iRHS[here->BJT2substNode] + iparmno)); +#endif /* SENSDEBUG */ + + } + + +next1: + switch(flag){ + case 0: + if (*(here->BJT2senCbx) == 0){ + here->BJT2area = A0; + goto pertvbe ; + } + else{ + goto pertvbx; + } + case 1: + goto pertvbe ; + case 2: + goto pertvbc ; + case 3: + goto pertvcs ; + case 4: + break; + } + + /* put the unperturbed values back into the state vector */ + for(i=0; i <= 20; i++) { + *(ckt->CKTstate0 + here->BJT2state + i) = *(SaveState + i); + } + here->BJT2senPertFlag = OFF; + } + + } + info->SENstatus = NORMAL; +#ifdef SENSDEBUG + printf("BJT2senacload end\n"); +#endif /* SENSDEBUG */ + return(OK); +} + diff --git a/src/spicelib/devices/bjt2/bjt2setup.c b/src/spicelib/devices/bjt2/bjt2setup.c index ed2f973e7..a17481605 100644 --- a/src/spicelib/devices/bjt2/bjt2setup.c +++ b/src/spicelib/devices/bjt2/bjt2setup.c @@ -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; +} diff --git a/src/spicelib/devices/bjt2/bjt2sload.c b/src/spicelib/devices/bjt2/bjt2sload.c index 8905396c4..66550970c 100644 --- a/src/spicelib/devices/bjt2/bjt2sload.c +++ b/src/spicelib/devices/bjt2/bjt2sload.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2sprt.c b/src/spicelib/devices/bjt2/bjt2sprt.c index 8a85c732e..a0bdd7c97 100644 --- a/src/spicelib/devices/bjt2/bjt2sprt.c +++ b/src/spicelib/devices/bjt2/bjt2sprt.c @@ -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); + + } + } +} + diff --git a/src/spicelib/devices/bjt2/bjt2sset.c b/src/spicelib/devices/bjt2/bjt2sset.c index 79aac1433..b763f7685 100644 --- a/src/spicelib/devices/bjt2/bjt2sset.c +++ b/src/spicelib/devices/bjt2/bjt2sset.c @@ -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); +} + diff --git a/src/spicelib/devices/bjt2/bjt2supd.c b/src/spicelib/devices/bjt2/bjt2supd.c index 7df808353..1d4520380 100644 --- a/src/spicelib/devices/bjt2/bjt2supd.c +++ b/src/spicelib/devices/bjt2/bjt2supd.c @@ -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); +} + diff --git a/src/spicelib/devices/bjt2/bjt2temp.c b/src/spicelib/devices/bjt2/bjt2temp.c index c2cb5dbb4..ca8c06d8a 100644 --- a/src/spicelib/devices/bjt2/bjt2temp.c +++ b/src/spicelib/devices/bjt2/bjt2temp.c @@ -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); +} diff --git a/src/spicelib/devices/bjt2/bjt2trun.c b/src/spicelib/devices/bjt2/bjt2trun.c index a19dfb915..d2888cd1d 100644 --- a/src/spicelib/devices/bjt2/bjt2trun.c +++ b/src/spicelib/devices/bjt2/bjt2trun.c @@ -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); +}