diff --git a/src/spicelib/devices/hicum2/Makefile.am b/src/spicelib/devices/hicum2/Makefile.am new file mode 100644 index 000000000..26a9ff34c --- /dev/null +++ b/src/spicelib/devices/hicum2/Makefile.am @@ -0,0 +1,32 @@ +## Process this file with automake to produce Makefile.in + +noinst_LTLIBRARIES = libhicum.la + +libhicum_la_SOURCES = \ + hicum.c \ + hicumacld.c \ + hicumask.c \ + hicumconv.c \ + hicumdefs.h \ + hicumext.h \ + hicumgetic.c \ + hicuminit.c \ + hicuminit.h \ + hicumitf.h \ + hicumload.c \ + hicummask.c \ + hicummpar.c \ + hicumnoise.c \ + hicumparam.c \ + hicumpzld.c \ + hicumsetup.c \ + hicumsoachk.c \ + hicumtemp.c \ + hicumtrunc.c + + + +AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include +AM_CFLAGS = $(STATIC) + +MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/devices/hicum2/hicum.c b/src/spicelib/devices/hicum2/hicum.c new file mode 100644 index 000000000..8b5c68556 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicum.c @@ -0,0 +1,259 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This file defines the HICUM data structures that are + * available to the next level(s) up the calling hierarchy + */ + +#include "ngspice/ngspice.h" +#include "ngspice/devdefs.h" +#include "hicumdefs.h" +#include "ngspice/suffix.h" + +IFparm HICUMpTable[] = { /* parameters */ + IOPU("area", HICUM_AREA, IF_REAL, "Area factor"), + IOPU("off", HICUM_OFF, IF_FLAG, "Device initially off"), + IP("ic", HICUM_IC, IF_REALVEC, "Initial condition vector"), + IOPAU("icvbe", HICUM_IC_VBE, IF_REAL, "Initial B-E voltage"), + IOPAU("icvce", HICUM_IC_VCE, IF_REAL, "Initial C-E voltage"), + IOPU("temp", HICUM_TEMP, IF_REAL, "Instance temperature"), + IOPU("dtemp", HICUM_DTEMP, IF_REAL, "Instance delta temperature"), + IOPU("m", HICUM_M, IF_REAL, "Multiplier"), + + OPU("collnode", HICUM_QUEST_COLLNODE, IF_INTEGER, "Number of collector node"), + OPU("basenode", HICUM_QUEST_BASENODE, IF_INTEGER, "Number of base node"), + OPU("emitnode", HICUM_QUEST_EMITNODE, IF_INTEGER, "Number of emitter node"), + OPU("subsnode", HICUM_QUEST_SUBSNODE, IF_INTEGER, "Number of substrate node"), + OPU("collCInode", HICUM_QUEST_COLLCINODE, IF_INTEGER, "Internal collector node"), + OPU("baseBPnode", HICUM_QUEST_BASEBPNODE, IF_INTEGER, "Internal base node"), + OPU("baseBInode", HICUM_QUEST_BASEBINODE, IF_INTEGER, "Internal base node"), + OPU("emitEInode", HICUM_QUEST_EMITEINODE, IF_INTEGER, "Internal emitter node"), + OPU("subsSInode", HICUM_QUEST_SUBSSINODE, IF_INTEGER, "Internal substrate node"), +// OPU("xfnode", HICUM_QUEST_XFNODE, IF_INTEGER, "Internal phase node xf"), +// OPU("xf1node", HICUM_QUEST_XF1NODE, IF_INTEGER, "Internal phase node xf1"), +// OPU("xf2node", HICUM_QUEST_XF2NODE, IF_INTEGER, "Internal phase node xf2"), + OP("vbe", HICUM_QUEST_VBE, IF_REAL, "B-E voltage"), + OP("vbc", HICUM_QUEST_VBC, IF_REAL, "B-C voltage"), + OP("ic", HICUM_QUEST_CC, IF_REAL, "Collector current"), + OP("ib", HICUM_QUEST_CB, IF_REAL, "Base current"), + OP("ie", HICUM_QUEST_CE, IF_REAL, "Emitter current"), + OP("is", HICUM_QUEST_CS, IF_REAL, "Substrate current"), + OP("gm", HICUM_QUEST_GM, IF_REAL, "Small signal transconductance dIc/dVbe"), + OP("go", HICUM_QUEST_GO, IF_REAL, "Small signal output conductance dIc/dVbc"), + OP("gpi", HICUM_QUEST_GPI, IF_REAL, "Small signal input conductance dIb/dVbe"), + OP("gmu", HICUM_QUEST_GMU, IF_REAL, "Small signal conductance dIb/dVbc"), + OP("gx", HICUM_QUEST_GX, IF_REAL, "Conductance from base to internal base"), + OP("cbe", HICUM_QUEST_CJBE, IF_REAL, "Internal base to emitter capacitance"), + OP("cbex", HICUM_QUEST_CBEX, IF_REAL, "External base to emitter capacitance"), + OP("cbep", HICUM_QUEST_CBEP, IF_REAL, "Parasitic Base to emitter capacitance"), + OP("cbc", HICUM_QUEST_CJBC, IF_REAL, "Internal base to collector capacitance"), + OP("cbcp", HICUM_QUEST_CBCXII,IF_REAL, "Parasitic Base to collector capacitance"), + OPU("geqcb", HICUM_QUEST_GEQCB, IF_REAL, "Internal C-B-base cap. equiv. cond."), + OPU("qbe", HICUM_QUEST_QBE, IF_REAL, "Charge storage B-E junction"), + OPU("cqbe", HICUM_QUEST_CQBE, IF_REAL, "Cap. due to charge storage in B-E jct."), + OPU("qbc", HICUM_QUEST_QBC, IF_REAL, "Charge storage B-C junction"), + OPU("cqbc", HICUM_QUEST_CQBC, IF_REAL, "Cap. due to charge storage in B-C jct."), + OPU("qbx", HICUM_QUEST_QBX, IF_REAL, "Charge storage B-X junction"), + OPU("cqbx", HICUM_QUEST_CQBX, IF_REAL, "Cap. due to charge storage in B-X jct."), + OP("p", HICUM_QUEST_POWER, IF_REAL, "Power dissipation") +}; + +IFparm HICUMmPTable[] = { /* model parameters */ +//Circuit simulator specific parameters + IOP("type", HICUM_MOD_TYPE, IF_STRING, "For transistor type NPN(+1) or PNP (-1)"), + IOPU("npn", HICUM_MOD_NPN, IF_FLAG, "NPN type device"), + IOPU("pnp", HICUM_MOD_PNP, IF_FLAG, "PNP type device"), + IOP("tnom", HICUM_MOD_TNOM, IF_REAL, "Temperature at which parameters are specified"), + +//Transfer current + IOP("c10", HICUM_MOD_C10 , IF_REAL, "GICCR constant"), + IOP("qp0", HICUM_MOD_QP0 , IF_REAL, "Zero-bias hole charge"), + IOP("ich", HICUM_MOD_ICH , IF_REAL, "High-current correction for 2D and 3D effects"), //`0' signifies infinity + IOP("hf0", HICUM_MOD_HF0 , IF_REAL, "Weight factor for the low current minority charge"), + IOP("hfe", HICUM_MOD_HFE , IF_REAL, "Emitter minority charge weighting factor in HBTs"), + IOP("hfc", HICUM_MOD_HFC , IF_REAL, "Collector minority charge weighting factor in HBTs"), + IOP("hjei", HICUM_MOD_HJEI , IF_REAL, "B-E depletion charge weighting factor in HBTs"), + IOP("ahjei", HICUM_MOD_AHJEI, IF_REAL, "Parameter describing the slope of hjEi(VBE)"), + IOP("rhjei", HICUM_MOD_RHJEI, IF_REAL, "Smoothing parameter for hjEi(VBE) at high voltage"), + IOP("hjci", HICUM_MOD_HJCI , IF_REAL, "B-C depletion charge weighting factor in HBTs"), + +//Base-Emitter diode currents + IOP("ibeis", HICUM_MOD_IBEIS, IF_REAL, "Internal B-E saturation current"), + IOP("mbei", HICUM_MOD_MBEI , IF_REAL, "Internal B-E current ideality factor"), + IOP("ireis", HICUM_MOD_IREIS, IF_REAL, "Internal B-E recombination saturation current"), + IOP("mrei", HICUM_MOD_MREI , IF_REAL, "Internal B-E recombination current ideality factor"), + IOP("ibeps", HICUM_MOD_IBEPS, IF_REAL, "Peripheral B-E saturation current"), + IOP("mbep", HICUM_MOD_MBEP , IF_REAL, "Peripheral B-E current ideality factor"), + IOP("ireps", HICUM_MOD_IREPS, IF_REAL, "Peripheral B-E recombination saturation current"), + IOP("mrep", HICUM_MOD_MREP , IF_REAL, "Peripheral B-E recombination current ideality factor"), + IOP("mcf", HICUM_MOD_MCF , IF_REAL, "Non-ideality factor for III-V HBTs"), + +//Transit time for excess recombination current at b-c barrier + IOP("tbhrec", HICUM_MOD_TBHREC, IF_REAL, "Base current recombination time constant at B-C barrier for high forward injection"), + +//Base-Collector diode currents + IOP("ibcis", HICUM_MOD_IBCIS, IF_REAL, "Internal B-C saturation current"), + IOP("mbci", HICUM_MOD_MBCI , IF_REAL, "Internal B-C current ideality factor"), + IOP("ibcxs", HICUM_MOD_IBCXS, IF_REAL, "External B-C saturation current"), + IOP("mbcx", HICUM_MOD_MBCX , IF_REAL, "External B-C current ideality factor"), + +//Base-Emitter tunneling current + IOP("ibets", HICUM_MOD_IBETS, IF_REAL, "B-E tunneling saturation current"), + IOP("abet", HICUM_MOD_ABET, IF_REAL, "Exponent factor for tunneling current"), + IOP("tunode",HICUM_MOD_TUNODE, IF_INTEGER, "Specifies the base node connection for the tunneling current"), // =1 signifies perimeter node + +//Base-Collector avalanche current + IOP("favl", HICUM_MOD_FAVL , IF_REAL, "Avalanche current factor"), + IOP("qavl", HICUM_MOD_QAVL , IF_REAL, "Exponent factor for avalanche current"), + IOP("alfav", HICUM_MOD_ALFAV, IF_REAL, "Relative TC for FAVL"), + IOP("alqav", HICUM_MOD_ALQAV, IF_REAL, "Relative TC for QAVL"), + +//Series resistances + IOP("rbi0", HICUM_MOD_RBI0 , IF_REAL, "Zero bias internal base resistance"), + IOP("rbx", HICUM_MOD_RBX , IF_REAL, "External base series resistance"), + IOP("fgeo", HICUM_MOD_FGEO , IF_REAL, "Factor for geometry dependence of emitter current crowding"), + IOP("fdqr0", HICUM_MOD_FDQR0, IF_REAL, "Correction factor for modulation by B-E and B-C space charge layer"), + IOP("fcrbi", HICUM_MOD_FCRBI, IF_REAL, "Ratio of HF shunt to total internal capacitance (lateral NQS effect)"), + IOP("fqi", HICUM_MOD_FQI , IF_REAL, "Ration of internal to total minority charge"), + IOP("re", HICUM_MOD_RE , IF_REAL, "Emitter series resistance"), + IOP("rcx", HICUM_MOD_RCX , IF_REAL, "External collector series resistance"), + +//Substrate transistor + IOP("itss", HICUM_MOD_ITSS, IF_REAL, "Substrate transistor transfer saturation current"), + IOP("msf", HICUM_MOD_MSF , IF_REAL, "Forward ideality factor of substrate transfer current"), + IOP("iscs", HICUM_MOD_ISCS, IF_REAL, "C-S diode saturation current"), + IOP("msc", HICUM_MOD_MSC , IF_REAL, "Ideality factor of C-S diode current"), + IOP("tsf", HICUM_MOD_TSF , IF_REAL, "Transit time for forward operation of substrate transistor"), + +//Intra-device substrate coupling + IOP("rsu", HICUM_MOD_RSU, IF_REAL, "Substrate series resistance"), + IOP("csu", HICUM_MOD_CSU, IF_REAL, "Substrate shunt capacitance"), + +//Depletion Capacitances + IOP("cjei0", HICUM_MOD_CJEI0 , IF_REAL, "Internal B-E zero-bias depletion capacitance"), + IOP("vdei", HICUM_MOD_VDEI , IF_REAL, "Internal B-E built-in potential"), + IOP("zei", HICUM_MOD_ZEI , IF_REAL, "Internal B-E grading coefficient"), + IOP("ajei", HICUM_MOD_AJEI , IF_REAL, "Ratio of maximum to zero-bias value of internal B-E capacitance"), + IOP("cjep0", HICUM_MOD_CJEP0 , IF_REAL, "Peripheral B-E zero-bias depletion capacitance"), + IOP("vdep", HICUM_MOD_VDEP , IF_REAL, "Peripheral B-E built-in potential"), + IOP("zep", HICUM_MOD_ZEP , IF_REAL, "Peripheral B-E grading coefficient"), + IOP("ajep", HICUM_MOD_AJEP , IF_REAL, "Ratio of maximum to zero-bias value of peripheral B-E capacitance"), + IOP("cjci0", HICUM_MOD_CJCI0 , IF_REAL, "Internal B-C zero-bias depletion capacitance"), + IOP("vdci", HICUM_MOD_VDCI , IF_REAL, "Internal B-C built-in potential"), + IOP("zci", HICUM_MOD_ZCI , IF_REAL, "Internal B-C grading coefficient"), + IOP("vptci", HICUM_MOD_VPTCI , IF_REAL, "Internal B-C punch-through voltage"), + IOP("cjcx0", HICUM_MOD_CJCX0 , IF_REAL, "External B-C zero-bias depletion capacitance"), + IOP("vdcx", HICUM_MOD_VDCX , IF_REAL, "External B-C built-in potential"), + IOP("zcx", HICUM_MOD_ZCX , IF_REAL, "External B-C grading coefficient"), + IOP("vptcx", HICUM_MOD_VPTCX , IF_REAL, "External B-C punch-through voltage"), + IOP("fbcpar", HICUM_MOD_FBCPAR, IF_REAL, "Partitioning factor of parasitic B-C cap"), + IOP("fbepar", HICUM_MOD_FBEPAR, IF_REAL, "Partitioning factor of parasitic B-E cap"), + IOP("cjs0", HICUM_MOD_CJS0 , IF_REAL, "C-S zero-bias depletion capacitance"), + IOP("vds", HICUM_MOD_VDS , IF_REAL, "C-S built-in potential"), + IOP("zs", HICUM_MOD_ZS , IF_REAL, "C-S grading coefficient"), + IOP("vpts", HICUM_MOD_VPTS , IF_REAL, "C-S punch-through voltage"), + IOP("cscp0", HICUM_MOD_CSCP0 , IF_REAL, "Perimeter S-C zero-bias depletion capacitance"), + IOP("vdsp", HICUM_MOD_VDSP , IF_REAL, "Perimeter S-C built-in potential"), + IOP("zsp", HICUM_MOD_ZSP , IF_REAL, "Perimeter S-C grading coefficient"), + IOP("vptsp", HICUM_MOD_VPTSP , IF_REAL, "Perimeter S-C punch-through voltage"), + +//Diffusion Capacitances + IOP("t0", HICUM_MOD_T0 , IF_REAL, "Low current forward transit time at VBC=0V"), + IOP("dt0h", HICUM_MOD_DT0H , IF_REAL, "Time constant for base and B-C space charge layer width modulation"), + IOP("tbvl", HICUM_MOD_TBVL , IF_REAL, "Time constant for modeling carrier jam at low VCE"), + IOP("tef0", HICUM_MOD_TEF0 , IF_REAL, "Neutral emitter storage time"), + IOP("gtfe", HICUM_MOD_GTFE , IF_REAL, "Exponent factor for current dependence of neutral emitter storage time"), + IOP("thcs", HICUM_MOD_THCS , IF_REAL, "Saturation time constant at high current densities"), + IOP("ahc", HICUM_MOD_AHC , IF_REAL, "Smoothing factor for current dependence of base and collector transit time"), + IOP("fthc", HICUM_MOD_FTHC , IF_REAL, "Partitioning factor for base and collector portion"), + IOP("rci0", HICUM_MOD_RCI0 , IF_REAL, "Internal collector resistance at low electric field"), + IOP("vlim", HICUM_MOD_VLIM , IF_REAL, "Voltage separating ohmic and saturation velocity regime"), + IOP("vces", HICUM_MOD_VCES , IF_REAL, "Internal C-E saturation voltage"), + IOP("vpt", HICUM_MOD_VPT , IF_REAL, "Collector punch-through voltage"), // `0' signifies infinity + IOP("aick", HICUM_MOD_AICK , IF_REAL, "Smoothing term for ICK"), + IOP("delck", HICUM_MOD_DELCK, IF_REAL, "Fitting factor for critical current"), + IOP("tr", HICUM_MOD_TR , IF_REAL, "Storage time for inverse operation"), + IOP("vcbar", HICUM_MOD_VCBAR, IF_REAL, "Barrier voltage"), + IOP("icbar", HICUM_MOD_ICBAR, IF_REAL, "Normalization parameter"), + IOP("acbar", HICUM_MOD_ACBAR, IF_REAL, "Smoothing parameter for barrier voltage"), + +//Isolation Capacitances + IOP("cbepar", HICUM_MOD_CBEPAR, IF_REAL, "Total parasitic B-E capacitance"), + IOP("cbcpar", HICUM_MOD_CBCPAR, IF_REAL, "Total parasitic B-C capacitance"), + +//Non-quasi-static Effect + IOP("alqf", HICUM_MOD_ALQF, IF_REAL, "Factor for additional delay time of minority charge"), + IOP("alit", HICUM_MOD_ALIT, IF_REAL, "Factor for additional delay time of transfer current"), + IOP("flnqs", HICUM_MOD_FLNQS, IF_INTEGER, "Flag for turning on and off of vertical NQS effect"), + +//Noise + IOP("kf", HICUM_MOD_KF , IF_REAL, "Flicker noise coefficient"), + IOP("af", HICUM_MOD_AF , IF_REAL, "Flicker noise exponent factor"), + IOP("cfbe", HICUM_MOD_CFBE , IF_INTEGER, "Flag for determining where to tag the flicker noise source"), + IOP("flcono", HICUM_MOD_FLCONO, IF_INTEGER, "Flag for turning on and off of correlated noise implementation"), + IOP("kfre", HICUM_MOD_KFRE , IF_REAL, "Emitter resistance flicker noise coefficient"), + IOP("afre", HICUM_MOD_AFRE , IF_REAL, "Emitter resistance flicker noise exponent factor"), + +//Lateral Geometry Scaling (at high current densities) + IOP("latb", HICUM_MOD_LATB, IF_REAL, "Scaling factor for collector minority charge in direction of emitter width"), + IOP("latl", HICUM_MOD_LATL, IF_REAL, "Scaling factor for collector minority charge in direction of emitter length"), + +//Temperature dependence + IOP("vgb", HICUM_MOD_VGB , IF_REAL, "Bandgap voltage extrapolated to 0 K"), + IOP("alt0", HICUM_MOD_ALT0 , IF_REAL, "First order relative TC of parameter T0"), + IOP("kt0", HICUM_MOD_KT0 , IF_REAL, "Second order relative TC of parameter T0"), + IOP("zetaci", HICUM_MOD_ZETACI , IF_REAL, "Temperature exponent for RCI0"), + IOP("alvs", HICUM_MOD_ALVS , IF_REAL, "Relative TC of saturation drift velocity"), + IOP("alces", HICUM_MOD_ALCES , IF_REAL, "Relative TC of VCES"), + IOP("zetarbi", HICUM_MOD_ZETARBI , IF_REAL, "Temperature exponent of internal base resistance"), + IOP("zetarbx", HICUM_MOD_ZETARBX , IF_REAL, "Temperature exponent of external base resistance"), + IOP("zetarcx", HICUM_MOD_ZETARCX , IF_REAL, "Temperature exponent of external collector resistance"), + IOP("zetare", HICUM_MOD_ZETARE , IF_REAL, "Temperature exponent of emitter resistance"), + IOP("zetacx", HICUM_MOD_ZETACX , IF_REAL, "Temperature exponent of mobility in substrate transistor transit time"), + IOP("vge", HICUM_MOD_VGE , IF_REAL, "Effective emitter bandgap voltage"), + IOP("vgc", HICUM_MOD_VGC , IF_REAL, "Effective collector bandgap voltage"), + IOP("vgs", HICUM_MOD_VGS , IF_REAL, "Effective substrate bandgap voltage"), + IOP("f1vg", HICUM_MOD_F1VG , IF_REAL, "Coefficient K1 in T-dependent band-gap equation"), + IOP("f2vg", HICUM_MOD_F2VG , IF_REAL, "Coefficient K2 in T-dependent band-gap equation"), + IOP("zetact", HICUM_MOD_ZETACT , IF_REAL, "Exponent coefficient in transfer current temperature dependence"), + IOP("zetabet", HICUM_MOD_ZETABET , IF_REAL, "Exponent coefficient in B-E junction current temperature dependence"), + IOP("alb", HICUM_MOD_ALB , IF_REAL, "Relative TC of forward current gain for V2.1 model"), + IOP("dvgbe", HICUM_MOD_DVGBE , IF_REAL, "Bandgap difference between B and B-E junction used for hjEi0 and hf0"), + IOP("zetahjei", HICUM_MOD_ZETAHJEI, IF_REAL, "Temperature coefficient for ahjEi"), + IOP("zetavgbe", HICUM_MOD_ZETAVGBE, IF_REAL, "Temperature coefficient for hjEi0"), + +//Self-Heating + IOP("flsh", HICUM_MOD_FLSH , IF_INTEGER, "Flag for turning on and off self-heating effect"), + IOP("rth", HICUM_MOD_RTH , IF_REAL, "Thermal resistance"), + IOP("zetarth", HICUM_MOD_ZETARTH, IF_REAL, "Temperature coefficient for Rth"), + IOP("alrth", HICUM_MOD_ALRTH , IF_REAL, "First order relative TC of parameter Rth"), + IOP("cth", HICUM_MOD_CTH , IF_REAL, "Thermal capacitance"), + +//Compatibility with V2.1 + IOP("flcomp", HICUM_MOD_FLCOMP, IF_REAL, "Flag for compatibility with v2.1 model (0=v2.1)"), + + IOP("vbe_max", HICUM_MOD_VBE_MAX, IF_REAL, "maximum voltage B-E junction"), + IOP("vbc_max", HICUM_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"), + IOP("vce_max", HICUM_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch") + +}; + +char *HICUMnames[] = { + "collector", + "base", + "emitter", + "substrate", + "temp" +}; + + +int HICUMnSize = NUMELEMS(HICUMnames); +int HICUMpTSize = NUMELEMS(HICUMpTable); +int HICUMmPTSize = NUMELEMS(HICUMmPTable); +int HICUMiSize = sizeof(HICUMinstance); +int HICUMmSize = sizeof(HICUMmodel); diff --git a/src/spicelib/devices/hicum2/hicumacld.c b/src/spicelib/devices/hicum2/hicumacld.c new file mode 100644 index 000000000..da5e55089 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumacld.c @@ -0,0 +1,320 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * Function to load the COMPLEX circuit matrix using the + * small signal parameters saved during a previous DC operating + * point analysis. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +int +HICUMacLoad(GENmodel *inModel, CKTcircuit *ckt) +{ + HICUMinstance *here; + HICUMmodel *model = (HICUMmodel*)inModel; + double Ibpei_Vbpei; + double Ibiei_Vbiei; + double Ibici_Vbici; + double Ibpci_Vbpci; + double Isici_Vsici; + double Iciei_Vbiei; + double Iciei_Vbici; + double Ibbp_Vbbp; + double Isis_Vsis; + double Ieie_Veie; + double Ibpbi_Vbpbi, Ibpbi_Vciei, Ibpbi_Vbiei; + double Ibpsi_Vbpci, Ibpsi_Vsici; + double Icic_Vcic; + + double XQrbi_Vbpbi; +// double XQrbi_Vbiei; +// double XQrbi_Vbici; + double XQdeix_Vbiei; + double XQjei_Vbiei; + double XQdci_Vbici; + double XQjci_Vbici; + double XQjep_Vbpei; + double Xqjcx0_t_i_Vbci; + double Xqjcx0_t_ii_Vbpci; + double XQdsu_Vbpci; +// double XQdsu_Vsici; + double XQjs_Vsici; + double XQscp_Vsc; + double XQbepar1_Vbe; + double XQbepar2_Vbpe; + double XQbcpar1_Vbci; + double XQbcpar2_Vbpci; + double XQsu_Vsis; + + /* loop through all the models */ + for( ; model != NULL; model = HICUMnextModel(model)) { + + /* loop through all the instances of the model */ + for( here = HICUMinstances(model); here!= NULL; + here = HICUMnextInstance(here)) { + + Ibbp_Vbbp = 1/here->HICUMrbx_t; + Icic_Vcic = 1/here->HICUMrcx_t; + Ieie_Veie = 1/here->HICUMre_t; + Isis_Vsis = 1/model->HICUMrsu; + + Ibiei_Vbiei = *(ckt->CKTstate0 + here->HICUMibiei_Vbiei); + Ibpei_Vbpei = *(ckt->CKTstate0 + here->HICUMibpei_Vbpei); + Iciei_Vbiei = *(ckt->CKTstate0 + here->HICUMiciei_Vbiei); + Iciei_Vbici = *(ckt->CKTstate0 + here->HICUMiciei_Vbici); + Ibici_Vbici = *(ckt->CKTstate0 + here->HICUMibici_Vbici); + Ibpbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi); + Ibpbi_Vbiei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei); + Ibpbi_Vciei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbici); + Isici_Vsici = *(ckt->CKTstate0 + here->HICUMisici_Vsici); + Ibpsi_Vbpci = *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci); + Ibpsi_Vsici = *(ckt->CKTstate0 + here->HICUMibpsi_Vsici); + Ibpci_Vbpci = *(ckt->CKTstate0 + here->HICUMibpci_Vbpci); + +/* +c The real part +*/ +/* +c Stamp element: Ibiei +*/ + *(here->HICUMbaseBIBaseBIPtr) += Ibiei_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += -Ibiei_Vbiei; + *(here->HICUMemitEIBaseBIPtr) += -Ibiei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Ibiei_Vbiei; +/* +c Stamp element: Ibpei +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpei_Vbpei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpei_Vbpei; + *(here->HICUMemitEIBaseBPPtr) += -Ibpei_Vbpei; + *(here->HICUMemitEIEmitEIPtr) += Ibpei_Vbpei; + +/* +c Stamp element: Iciei +*/ + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbiei; + *(here->HICUMcollCIEmitEIPtr) += -Iciei_Vbiei; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Iciei_Vbiei; + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbici; + *(here->HICUMcollCICollCIPtr) += -Iciei_Vbici; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbici; + *(here->HICUMemitEICollCIPtr) += Iciei_Vbici; +/* +c Stamp element: Ibici +*/ + *(here->HICUMbaseBIBaseBIPtr) += Ibici_Vbici; + *(here->HICUMbaseBICollCIPtr) += -Ibici_Vbici; + *(here->HICUMcollCIBaseBIPtr) += -Ibici_Vbici; + *(here->HICUMcollCICollCIPtr) += Ibici_Vbici; +/* +c Stamp element: Ibpci +*/ + *(here->HICUMbaseBPCollCIPtr) += Ibpci_Vbpci; + *(here->HICUMbaseBPBaseBPPtr) += -Ibpci_Vbpci; + *(here->HICUMcollCIBaseBPPtr) += -Ibpci_Vbpci; + *(here->HICUMcollCICollCIPtr) += Ibpci_Vbpci; +/* +c Stamp element: Rcx +*/ + *(here->HICUMcollCollPtr) += Icic_Vcic; + *(here->HICUMcollCICollPtr) += -Icic_Vcic; + *(here->HICUMcollCollCIPtr) += -Icic_Vcic; + *(here->HICUMcollCICollCIPtr) += Icic_Vcic; +/* +c Stamp element: Rbx +*/ + *(here->HICUMbaseBasePtr) += Ibbp_Vbbp; + *(here->HICUMbaseBPBasePtr) += -Ibbp_Vbbp; + *(here->HICUMbaseBaseBPPtr) += -Ibbp_Vbbp; + *(here->HICUMbaseBPBaseBPPtr) += Ibbp_Vbbp; +/* +c Stamp element: Ibpbi +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBPCollCIPtr) += Ibpbi_Vciei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vciei; + *(here->HICUMbaseBIBaseBPPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBICollCIPtr) += -Ibpbi_Vciei; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vciei; +/* +c Stamp element: Re +*/ + *(here->HICUMemitEmitPtr) += Ieie_Veie; + *(here->HICUMemitEIEmitPtr) += -Ieie_Veie; + *(here->HICUMemitEmitEIPtr) += -Ieie_Veie; + *(here->HICUMemitEIEmitEIPtr) += Ieie_Veie; +/* +c Stamp element: Isici +*/ + *(here->HICUMsubsSISubsSIPtr) += Isici_Vsici; + *(here->HICUMsubsSICollCIPtr) += -Isici_Vsici; + *(here->HICUMcollCISubsSIPtr) += -Isici_Vsici; + *(here->HICUMcollCICollCIPtr) += Isici_Vsici; +/* +c Stamp element: Ibpsi +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpsi_Vbpci; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vbpci; + *(here->HICUMbaseBPSubsSIPtr) += Ibpsi_Vsici; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vsici; + *(here->HICUMsubsSIBaseBPPtr) += -Ibpsi_Vbpci; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vbpci; + *(here->HICUMsubsSISubsSIPtr) += -Ibpsi_Vsici; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vsici; +/* +c Stamp element: Rs +*/ + *(here->HICUMsubsSubsPtr) += Isis_Vsis; + *(here->HICUMsubsSISubsPtr) += -Isis_Vsis; + *(here->HICUMsubsSubsSIPtr) += -Isis_Vsis; + *(here->HICUMsubsSISubsSIPtr) += Isis_Vsis; +/* +c The complex part +*/ +//todo: Complete with partial dervatives e.g. Qjs_Vsici, Qrbi_Vbici + + XQrbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMcqrbi) * ckt->CKTomega; + XQdeix_Vbiei = *(ckt->CKTstate0 + here->HICUMcqdeix) * ckt->CKTomega; + XQjei_Vbiei = *(ckt->CKTstate0 + here->HICUMcqjei) * ckt->CKTomega; + XQdci_Vbici = *(ckt->CKTstate0 + here->HICUMcqdci) * ckt->CKTomega; + XQjci_Vbici = *(ckt->CKTstate0 + here->HICUMcqjci) * ckt->CKTomega; + XQjep_Vbpei = *(ckt->CKTstate0 + here->HICUMcqjep) * ckt->CKTomega; + Xqjcx0_t_i_Vbci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i) * ckt->CKTomega; + Xqjcx0_t_ii_Vbpci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) * ckt->CKTomega; + XQdsu_Vbpci = *(ckt->CKTstate0 + here->HICUMcqdsu) * ckt->CKTomega; + XQjs_Vsici = *(ckt->CKTstate0 + here->HICUMcqjs) * ckt->CKTomega; + XQscp_Vsc = *(ckt->CKTstate0 + here->HICUMcqscp) * ckt->CKTomega; + XQbepar1_Vbe = *(ckt->CKTstate0 + here->HICUMcqbepar1) * ckt->CKTomega; + XQbepar2_Vbpe = *(ckt->CKTstate0 + here->HICUMcqbepar2) * ckt->CKTomega; + XQbcpar1_Vbci = *(ckt->CKTstate0 + here->HICUMcqbcpar1) * ckt->CKTomega; + XQbcpar2_Vbpci = *(ckt->CKTstate0 + here->HICUMcqbcpar2) * ckt->CKTomega; + XQsu_Vsis = *(ckt->CKTstate0 + here->HICUMcqsu) * ckt->CKTomega; +/* +c Stamp element: Qbepar1 +*/ + *(here->HICUMbaseBasePtr + 1) += XQbepar1_Vbe; + *(here->HICUMbaseEmitPtr + 1) += -XQbepar1_Vbe; + *(here->HICUMemitBasePtr + 1) += -XQbepar1_Vbe; + *(here->HICUMemitEmitPtr + 1) += XQbepar1_Vbe; +/* +c Stamp element: Qbepar2 +*/ + *(here->HICUMbaseBPBaseBPPtr + 1) += XQbepar2_Vbpe; + *(here->HICUMemitBaseBPPtr + 1) += -XQbepar2_Vbpe; + *(here->HICUMemitEmitPtr + 1) += -XQbepar2_Vbpe; + *(here->HICUMbaseBPEmitPtr + 1) += XQbepar2_Vbpe; +/* +c Stamp element: Qdeix, Qjei +*/ + *(here->HICUMbaseBIBaseBIPtr + 1) += XQdeix_Vbiei; + *(here->HICUMbaseBIEmitEIPtr + 1) += -XQdeix_Vbiei; + *(here->HICUMemitEIBaseBIPtr + 1) += -XQdeix_Vbiei; + *(here->HICUMemitEIEmitEIPtr + 1) += XQdeix_Vbiei; + *(here->HICUMbaseBIBaseBIPtr + 1) += XQjei_Vbiei; + *(here->HICUMbaseBIEmitEIPtr + 1) += -XQjei_Vbiei; + *(here->HICUMemitEIBaseBIPtr + 1) += -XQjei_Vbiei; + *(here->HICUMemitEIEmitEIPtr + 1) += XQjei_Vbiei; +/* +c Stamp element: Qjep +*/ + *(here->HICUMbaseBPBaseBPPtr + 1) += XQjep_Vbpei; + *(here->HICUMbaseBPEmitEIPtr + 1) += -XQjep_Vbpei; + *(here->HICUMemitEIBaseBPPtr + 1) += -XQjep_Vbpei; + *(here->HICUMemitEIEmitEIPtr + 1) += XQjep_Vbpei; + +/* +c Stamp element: Qdci, Qjci +*/ + *(here->HICUMbaseBIBaseBIPtr + 1) += XQdci_Vbici; + *(here->HICUMbaseBICollCIPtr + 1) += -XQdci_Vbici; + *(here->HICUMcollCIBaseBIPtr + 1) += -XQdci_Vbici; + *(here->HICUMcollCICollCIPtr + 1) += XQdci_Vbici; + *(here->HICUMbaseBIBaseBIPtr + 1) += XQjci_Vbici; + *(here->HICUMbaseBICollCIPtr + 1) += -XQjci_Vbici; + *(here->HICUMcollCIBaseBIPtr + 1) += -XQjci_Vbici; + *(here->HICUMcollCICollCIPtr + 1) += XQjci_Vbici; +/* +c Stamp element: Qbcpar1, qjcx0_i +*/ + *(here->HICUMbaseBasePtr + 1) += XQbcpar1_Vbci; + *(here->HICUMbaseCollCIPtr + 1) += -XQbcpar1_Vbci; + *(here->HICUMcollCIBasePtr + 1) += -XQbcpar1_Vbci; + *(here->HICUMcollCICollCIPtr + 1) += XQbcpar1_Vbci; + *(here->HICUMbaseBasePtr + 1) += Xqjcx0_t_i_Vbci; + *(here->HICUMbaseCollCIPtr + 1) += -Xqjcx0_t_i_Vbci; + *(here->HICUMcollCIBasePtr + 1) += -Xqjcx0_t_i_Vbci; + *(here->HICUMcollCICollCIPtr + 1) += Xqjcx0_t_i_Vbci; +/* +c Stamp element: Qbcpar2, qjcx0_ii, Qdsu +*/ + *(here->HICUMbaseBPBaseBPPtr + 1) += XQbcpar2_Vbpci; + *(here->HICUMcollCICollCIPtr + 1) += XQbcpar2_Vbpci; + *(here->HICUMbaseBPCollCIPtr + 1) += -XQbcpar2_Vbpci; + *(here->HICUMcollCIBaseBPPtr + 1) += -XQbcpar2_Vbpci; + *(here->HICUMbaseBPCollCIPtr + 1) += Xqjcx0_t_ii_Vbpci; + *(here->HICUMbaseBPBaseBPPtr + 1) += -Xqjcx0_t_ii_Vbpci; + *(here->HICUMcollCIBaseBPPtr + 1) += -Xqjcx0_t_ii_Vbpci; + *(here->HICUMcollCICollCIPtr + 1) += Xqjcx0_t_ii_Vbpci; + *(here->HICUMbaseBPCollCIPtr + 1) += XQdsu_Vbpci; + *(here->HICUMbaseBPBaseBPPtr + 1) += -XQdsu_Vbpci; + *(here->HICUMcollCIBaseBPPtr + 1) += -XQdsu_Vbpci; + *(here->HICUMcollCICollCIPtr + 1) += XQdsu_Vbpci; +/* +c Stamp element: Qrbi +*/ + *(here->HICUMbaseBPBaseBPPtr + 1) += XQrbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr + 1) += -XQrbi_Vbpbi; + *(here->HICUMbaseBIBaseBPPtr + 1) += -XQrbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr + 1) += XQrbi_Vbpbi; +//todo: +// *(here->HICUMbaseBPBaseBIPtr + 1) += XQrbi_Vbiei; +// *(here->HICUMbaseBPEmitEIPtr + 1) += -XQrbi_Vbiei; +// *(here->HICUMbaseBIBaseBIPtr + 1) += -XQrbi_Vbiei; +// *(here->HICUMbaseBIEmitEIPtr + 1) += XQrbi_Vbiei; +// *(here->HICUMbaseBPCollCIPtr + 1) += XQrbi_Vbici; +// *(here->HICUMbaseBPEmitEIPtr + 1) += -XQrbi_Vbici; +// *(here->HICUMbaseBICollCIPtr + 1) += -XQrbi_Vbici; +// *(here->HICUMbaseBIEmitEIPtr + 1) += XQrbi_Vbici; +/* +c Stamp element: Cscp +*/ + *(here->HICUMsubsSubsPtr + 1) += XQscp_Vsc; + *(here->HICUMcollSubsPtr + 1) += -XQscp_Vsc; + *(here->HICUMcollCollPtr + 1) += -XQscp_Vsc; + *(here->HICUMsubsCollPtr + 1) += XQscp_Vsc; +/* +c Stamp element: Cjs +*/ + *(here->HICUMsubsSISubsSIPtr + 1) += XQjs_Vsici; + *(here->HICUMsubsSICollCIPtr + 1) += -XQjs_Vsici; + *(here->HICUMcollCISubsSIPtr + 1) += -XQjs_Vsici; + *(here->HICUMcollCICollCIPtr + 1) += XQjs_Vsici; +/* +c Stamp element: Csu +*/ + *(here->HICUMsubsSubsPtr + 1) += XQsu_Vsis; + *(here->HICUMsubsSISubsPtr + 1) += -XQsu_Vsis; + *(here->HICUMsubsSubsSIPtr + 1) += -XQsu_Vsis; + *(here->HICUMsubsSISubsSIPtr + 1) += XQsu_Vsis; + + } + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicumask.c b/src/spicelib/devices/hicum2/hicumask.c new file mode 100644 index 000000000..f06e14a4f --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumask.c @@ -0,0 +1,155 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Mathew Lew and Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine gives access to the internal device + * parameters for HICUMs + */ + +#include "ngspice/ngspice.h" +#include "ngspice/const.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/ifsim.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +/*ARGSUSED*/ +int +HICUMask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalue *select) +{ + HICUMinstance *here = (HICUMinstance*)instPtr; + + NG_IGNORE(select); + + switch(which) { + case HICUM_AREA: + value->rValue = here->HICUMarea; + return(OK); + case HICUM_OFF: + value->iValue = here->HICUMoff; + return(OK); + case HICUM_IC_VBE: + value->rValue = here->HICUMicVBE; + return(OK); + case HICUM_IC_VCE: + value->rValue = here->HICUMicVCE; + return(OK); + case HICUM_TEMP: + value->rValue = here->HICUMtemp - CONSTCtoK; + return(OK); + case HICUM_M: + value->rValue = here->HICUMm; + return(OK); + case HICUM_QUEST_COLLNODE: + value->iValue = here->HICUMcollNode; + return(OK); + case HICUM_QUEST_BASENODE: + value->iValue = here->HICUMbaseNode; + return(OK); + case HICUM_QUEST_EMITNODE: + value->iValue = here->HICUMemitNode; + return(OK); + case HICUM_QUEST_SUBSNODE: + value->iValue = here->HICUMsubsNode; + return(OK); + case HICUM_QUEST_COLLCINODE: + value->iValue = here->HICUMcollCINode; + return(OK); + case HICUM_QUEST_BASEBPNODE: + value->iValue = here->HICUMbaseBPNode; + return(OK); + case HICUM_QUEST_BASEBINODE: + value->iValue = here->HICUMbaseBINode; + return(OK); + case HICUM_QUEST_EMITEINODE: + value->iValue = here->HICUMemitEINode; + return(OK); + case HICUM_QUEST_SUBSSINODE: + value->iValue = here->HICUMsubsSINode; + return(OK); + case HICUM_QUEST_VBE: + value->rValue = *(ckt->CKTstate0 + here->HICUMvbiei); + return(OK); + case HICUM_QUEST_VBC: + value->rValue = *(ckt->CKTstate0 + here->HICUMvbici); + return(OK); + case HICUM_QUEST_CC: + value->rValue = *(ckt->CKTstate0 + here->HICUMiciei) - + *(ckt->CKTstate0 + here->HICUMibici); + return(OK); + case HICUM_QUEST_CB: + value->rValue = *(ckt->CKTstate0 + here->HICUMibiei) + + *(ckt->CKTstate0 + here->HICUMibici) + + *(ckt->CKTstate0 + here->HICUMibpci) + + *(ckt->CKTstate0 + here->HICUMibpsi); + return(OK); + case HICUM_QUEST_CE: + value->rValue = - *(ckt->CKTstate0 + here->HICUMibiei) - + *(ckt->CKTstate0 + here->HICUMibpei) - + *(ckt->CKTstate0 + here->HICUMiciei); + return(OK); + case HICUM_QUEST_CS: + value->rValue = *(ckt->CKTstate0 + here->HICUMisici) - + *(ckt->CKTstate0 + here->HICUMibpsi); + return(OK); + case HICUM_QUEST_GM: + value->rValue = *(ckt->CKTstate0 + here->HICUMiciei_Vbiei); + return(OK); + case HICUM_QUEST_GO: + value->rValue = *(ckt->CKTstate0 + here->HICUMiciei_Vbici); + return(OK); + case HICUM_QUEST_GPI: + value->rValue = *(ckt->CKTstate0 + here->HICUMibiei_Vbiei); + return(OK); + case HICUM_QUEST_GMU: + value->rValue = *(ckt->CKTstate0 + here->HICUMibici_Vbici); + return(OK); + case HICUM_QUEST_GX: + value->rValue = *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi); + return(OK); + case HICUM_QUEST_CJBE: + value->rValue = here->HICUMcapjei; + return(OK); + case HICUM_QUEST_CDBE: + value->rValue = here->HICUMcapdeix; + return(OK); + case HICUM_QUEST_CBEP: + value->rValue = here->HICUMcapjep; + return(OK); + case HICUM_QUEST_CJBC: + value->rValue = here->HICUMcapjci; + return(OK); + case HICUM_QUEST_CBCXI: + value->rValue = here->HICUMcapjcx_t_i; + return(OK); + case HICUM_QUEST_CBCXII: + value->rValue = here->HICUMcapjcx_t_ii; + return(OK); + case HICUM_QUEST_CSCP: + value->rValue = here->HICUMcapscp; + return(OK); + case HICUM_QUEST_QBE: + value->rValue = *(ckt->CKTstate0 + here->HICUMqjei); + return(OK); + case HICUM_QUEST_QBC: + value->rValue = *(ckt->CKTstate0 + here->HICUMqjci); + return(OK); + case HICUM_QUEST_POWER: + value->rValue = fabs(*(ckt->CKTstate0 + here->HICUMiciei)) * fabs(*(ckt->CKTstate0 + here->HICUMvbiei) - *(ckt->CKTstate0 + here->HICUMvbici)) + + fabs(*(ckt->CKTstate0 + here->HICUMibiei) * *(ckt->CKTstate0 + here->HICUMvbiei)) + + fabs(*(ckt->CKTstate0 + here->HICUMibpei) * *(ckt->CKTstate0 + here->HICUMvbpei)) + + fabs(*(ckt->CKTstate0 + here->HICUMibici) * *(ckt->CKTstate0 + here->HICUMvbici)) + + fabs(*(ckt->CKTstate0 + here->HICUMibpci) * *(ckt->CKTstate0 + here->HICUMvbpci)) + + fabs(*(ckt->CKTstate0 + here->HICUMibpsi) * *(ckt->CKTstate0 + here->HICUMvsici)); + return(OK); + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/hicum2/hicumconv.c b/src/spicelib/devices/hicum2/hicumconv.c new file mode 100644 index 000000000..949d2d68d --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumconv.c @@ -0,0 +1,166 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine performs the device convergence test for + * HICUMs in the circuit. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +int +HICUMconvTest(GENmodel *inModel, CKTcircuit *ckt) +{ + HICUMinstance *here; + HICUMmodel *model = (HICUMmodel *) inModel; + double tol; + double delvbiei; + double delvbici; + double delvbpei; + double delvbpbi; + double delvbpci; + double delvsici; + + double ibieihat; + double ibicihat; + double icieihat; + double ibpeihat; + double ibpbihat; + double ibpcihat; + double ibpsihat; + double isicihat; + + double Vbiei, Vbici, Vciei, Vbpei, Vbpbi, Vbpci, Vbci, Vsici; + double Ibiei, Ibici, Iciei, Ibpei, Ibpbi, Ibpci, Ibpsi, Isici; + + for( ; model != NULL; model = HICUMnextModel(model)) { + for(here=HICUMinstances(model);here!=NULL;here = HICUMnextInstance(here)) { + + Vbci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vbiei= model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBINode)- + *(ckt->CKTrhsOld+here->HICUMemitEINode)); + Vbici = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBINode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vbpei = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMemitEINode)); + Vbpbi = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMbaseBINode)); + Vbpci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vsici = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsSINode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vciei = Vbiei - Vbici; + + delvbiei = Vbiei - *(ckt->CKTstate0 + here->HICUMvbiei); + delvbici = Vbici - *(ckt->CKTstate0 + here->HICUMvbici); + delvbpei = Vbpei - *(ckt->CKTstate0 + here->HICUMvbpei); + delvbpbi = Vbpbi - *(ckt->CKTstate0 + here->HICUMvbpbi); + delvbpci = Vbpci - *(ckt->CKTstate0 + here->HICUMvbpci); + delvsici = Vsici - *(ckt->CKTstate0 + here->HICUMvsici); + + ibieihat = *(ckt->CKTstate0 + here->HICUMibiei) + + *(ckt->CKTstate0 + here->HICUMibiei_Vbiei)*delvbiei; + ibicihat = *(ckt->CKTstate0 + here->HICUMibici) + + *(ckt->CKTstate0 + here->HICUMibici_Vbici)*delvbici; + icieihat = *(ckt->CKTstate0 + here->HICUMiciei) + + *(ckt->CKTstate0 + here->HICUMiciei_Vbiei)*delvbiei + + *(ckt->CKTstate0 + here->HICUMiciei_Vbici)*delvbici; + ibpeihat = *(ckt->CKTstate0 + here->HICUMibpei) + + *(ckt->CKTstate0 + here->HICUMibpei_Vbpei)*delvbpei; + ibpbihat = *(ckt->CKTstate0 + here->HICUMibpbi) + + *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei)*delvbiei + + *(ckt->CKTstate0 + here->HICUMibpbi_Vbici)*delvbici; + ibpcihat = *(ckt->CKTstate0 + here->HICUMibpci) + + *(ckt->CKTstate0 + here->HICUMibpci_Vbpci)*delvbici; + ibpsihat = *(ckt->CKTstate0 + here->HICUMibpsi) + + *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci)*delvbpci + + *(ckt->CKTstate0 + here->HICUMibpsi_Vsici)*delvsici; + isicihat = *(ckt->CKTstate0 + here->HICUMisici) + + *(ckt->CKTstate0 + here->HICUMisici_Vsici)*delvsici; + + Ibiei = *(ckt->CKTstate0 + here->HICUMibiei); + Ibici = *(ckt->CKTstate0 + here->HICUMibici); + Iciei = *(ckt->CKTstate0 + here->HICUMiciei); + Ibpei = *(ckt->CKTstate0 + here->HICUMibpei); + Ibpbi = *(ckt->CKTstate0 + here->HICUMibpbi); + Ibpci = *(ckt->CKTstate0 + here->HICUMibpci); + Ibpsi = *(ckt->CKTstate0 + here->HICUMibpsi); + Isici = *(ckt->CKTstate0 + here->HICUMisici); + /* + * check convergence + */ + tol=ckt->CKTreltol*MAX(fabs(ibieihat),fabs(Ibiei))+ckt->CKTabstol; + if (fabs(ibieihat-Ibiei) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibicihat),fabs(Ibici))+ckt->CKTabstol; + if (fabs(ibicihat-Ibici) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(icieihat),fabs(Iciei))+ckt->CKTabstol; + if (fabs(icieihat-Iciei) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibpeihat),fabs(Ibpei))+ckt->CKTabstol; + if (fabs(ibpeihat-Ibpei) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibpbihat),fabs(Ibpbi))+ckt->CKTabstol; + if (fabs(ibpbihat-Ibpbi) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibpcihat),fabs(Ibpci))+ckt->CKTabstol; + if (fabs(ibpcihat-Ibpci) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(ibpsihat),fabs(Ibpsi))+ckt->CKTabstol; + if (fabs(ibpsihat-Ibpsi) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } else { + tol=ckt->CKTreltol*MAX(fabs(isicihat),fabs(Isici))+ckt->CKTabstol; + if (fabs(isicihat-Isici) > tol) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + return(OK); /* no reason to continue - we've failed... */ + } + } + } + } + } + } + } + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicumdefs.h b/src/spicelib/devices/hicum2/hicumdefs.h new file mode 100644 index 000000000..48ab4194b --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumdefs.h @@ -0,0 +1,994 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +#ifndef HICUM +#define HICUM + +#include "ngspice/cktdefs.h" +#include "ngspice/ifsim.h" +#include "ngspice/gendefs.h" +#include "ngspice/complex.h" +#include "ngspice/noisedef.h" + +/* structures to describe Bipolar Junction Transistors */ + +/* indices to array of HICUM noise sources */ + +enum { + HICUMRCNOIZ = 0, + HICUMRBNOIZ, + HICUMRBINOIZ, + HICUMRENOIZ, + HICUMRSNOIZ, + HICUMICNOIZ, + HICUMIBCNOIZ, + HICUMIBEPNOIZ, + HICUMIBCXNOIZ, + HICUMITSNOIZ, + HICUMFLBENOIZ, + HICUMFLRENOIZ, + HICUMTOTNOIZ, + /* finally, the number of noise sources */ + HICUMNSRCS +}; + +/* data needed to describe a single instance */ + +typedef struct sHICUMinstance { + + struct GENinstance gen; + +#define HICUMmodPtr(inst) ((struct sHICUMmodel *)((inst)->gen.GENmodPtr)) +#define HICUMnextInstance(inst) ((struct sHICUMinstance *)((inst)->gen.GENnextInstance)) +#define HICUMname gen.GENname +#define HICUMstate gen.GENstate + + const int HICUMcollNode; /* number of collector node of hicum */ + const int HICUMbaseNode; /* number of base node of hicum */ + const int HICUMemitNode; /* number of emitter node of hicum */ + const int HICUMsubsNode; /* number of substrate node of hicum */ + const int HICUMtempNode; /* number of the temperature node of the hicum */ + int HICUMcollCINode; /* number of internal collector node of hicum */ + int HICUMbaseBINode; /* number of internal base node of hicum */ + int HICUMemitEINode; /* number of internal emitter node of hicum */ + int HICUMbaseBPNode; /* number of internal base node of hicum */ + int HICUMsubsSINode; /* number of internal substrate node */ + int HICUMxfNode; /* number of internal excess phase node */ + int HICUMxf1Node; /* number of internal excess phase node */ + int HICUMxf2Node; /* number of internal excess phase node */ + + double HICUMarea; /* area factor for the hicum */ + double HICUMicVBE; /* initial condition voltage B-E */ + double HICUMicVCE; /* initial condition voltage C-E */ + double HICUMtemp; /* instance temperature */ + double HICUMdtemp; /* instance delta temperature */ + double HICUMm; /* multiply factor for the hicum */ + + double HICUMmg; + double HICUMvt0; + double HICUMvt; + double HICUMdT; + double HICUMqtt0; + double HICUMln_qtt0; + double HICUMibeis_t; + double HICUMireis_t; + double HICUMibeps_t; + double HICUMireps_t; + double HICUMibcis_t; + double HICUMibcxs_t; + double HICUMitss_t; + double HICUMiscs_t; + double HICUMqp0_t; + double HICUMvlim_t; + double HICUMtef0_t; + double HICUMc10_t; + double HICUMrci0_t; + double HICUMvces_t; + double HICUMt0_t; + double HICUMthcs_t; + double HICUMfavl_t; + double HICUMqavl_t; + double HICUMrbi0_t; + double HICUMibets_t; + double HICUMabet_t; + double HICUMcjcx01_t; + double HICUMcjcx02_t; + double HICUMrcx_t; + double HICUMrbx_t; + double HICUMre_t; + double HICUMtsf_t; + double HICUMcscp0_t; + double HICUMvdsp_t; + double HICUMvptsp_t; + double HICUMahjei_t; + double HICUMhjei0_t; + double HICUMhf0_t; + double HICUMhfc_t; + double HICUMhfe_t; + double HICUMrth_t; + + double HICUMvdei_t; + double HICUMajei_t; + double HICUMcjci0_t; + double HICUMvdci_t; + double HICUMvptci_t; + double HICUMvdep_t; + double HICUMajep_t; + double HICUMcjep0_t; + double HICUMcjei0_t; + double HICUMvdcx_t; + double HICUMvptcx_t; + double HICUMcjs0_t; + double HICUMvds_t; + double HICUMvpts_t; + + double *HICUMcollCollPtr; /* pointer to sparse matrix at + * (collector,collector) */ + double *HICUMbaseBasePtr; /* pointer to sparse matrix at + * (base,base) */ + double *HICUMemitEmitPtr; /* pointer to sparse matrix at + * (emitter,emitter) */ + double *HICUMsubsSubsPtr; /* pointer to sparse matrix at + * (substrate,substrate) */ + double *HICUMcollCICollCIPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *HICUMbaseBIBaseBIPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *HICUMbaseBPBaseBPPtr; /* pointer to sparse matrix at + * (collector prime,collector prime) */ + double *HICUMemitEIEmitEIPtr; /* pointer to sparse matrix at + * (emitter prime,emitter prime) */ + double *HICUMsubsSISubsSIPtr; /* pointer to sparse matrix at + * (substrate prime, substrate prime) */ + + double *HICUMbaseEmitPtr; /* pointer to sparse matrix at + * (base,emit) */ + double *HICUMemitBasePtr; /* pointer to sparse matrix at + * (emit,base) */ + double *HICUMcollCollCIPtr; /* pointer to sparse matrix at + * (collector,collector prime) */ + double *HICUMbaseBaseBPPtr; /* pointer to sparse matrix at + * (base,base prime) */ + double *HICUMemitEmitEIPtr; /* pointer to sparse matrix at + * (emitter,emitter prime) */ + double *HICUMsubsSubsSIPtr; /* pointer to sparse matrix at + * (substrate, Substrate connection) */ + double *HICUMcollCIBaseBIPtr; /* pointer to sparse matrix at + * (collector prime,base) */ + double *HICUMcollCIEmitEIPtr; /* pointer to sparse matrix at + * (collector prime,emitter prime) */ + double *HICUMbaseBPBaseBIPtr; /* pointer to sparse matrix at + * (base prime,emitter prime) */ + double *HICUMbaseBPEmitEIPtr; /* pointer to sparse matrix at + * (base prime,emitter prime) */ + double *HICUMbaseBPSubsSIPtr; /* pointer to sparse matrix at + * (base prime,emitter prime) */ + double *HICUMbaseBIEmitEIPtr; /* pointer to sparse matrix at + * (base prime,emitter prime) */ + + double *HICUMcollCICollPtr; /* pointer to sparse matrix at + * (collector prime,collector) */ + double *HICUMbaseBPBasePtr; /* pointer to sparse matrix at + * (base prime,base ) */ + double *HICUMemitEIEmitPtr; /* pointer to sparse matrix at + * (emitter prime,emitter) */ + double *HICUMsubsSISubsPtr; /* pointer to sparse matrix at + * (Substrate connection, substrate) */ + double *HICUMbaseBPCollCIPtr; /* pointer to sparse matrix at + * (base,collector prime) */ + double *HICUMcollCIBaseBPPtr; /* pointer to sparse matrix at + * (collector prime,base) */ + + double *HICUMbaseBICollCIPtr; /* pointer to sparse matrix at + * (base,collector prime) */ + double *HICUMemitEICollCIPtr; /* pointer to sparse matrix at + * (emitter prime,collector prime) */ + double *HICUMsubsSICollCIPtr; /* pointer to sparse matrix at + * (substrate,collector prime) */ + double *HICUMcollCISubsSIPtr; /* pointer to sparse matrix at + * (collector prime,substrate) */ + double *HICUMbaseBIBaseBPPtr; /* pointer to sparse matrix at + * (base prime,emitter prime) */ + double *HICUMemitEIBaseBPPtr; /* pointer to sparse matrix at + * (emitter prime,base prime) */ + double *HICUMsubsSIBaseBPPtr; /* pointer to sparse matrix at + * (substrate,base) */ + double *HICUMsubsSIBaseBIPtr; /* pointer to sparse matrix at + * (substrate,base) */ + double *HICUMemitEIBaseBIPtr; /* pointer to sparse matrix at + * (emitter prime,base prime) */ + + double *HICUMcollCIBasePtr; + double *HICUMbaseCollCIPtr; + + double *HICUMbaseBPEmitPtr; + double *HICUMemitBaseBPPtr; + + double *HICUMsubsCollPtr; + double *HICUMcollSubsPtr; + + double *HICUMxfXfPtr; + double *HICUMxf1Xf1Ptr; + double *HICUMxf2Xf2Ptr; + + /* self heating */ + double *HICUMcollTempPtr; + double *HICUMbaseTempPtr; + double *HICUMemitTempPtr; + + double *HICUMcollCItempPtr; + double *HICUMbaseBItempPtr; + double *HICUMbaseBPtempPtr; + double *HICUMemitEItempPtr; + double *HICUMsubsSItempPtr; + + double *HICUMtempCollCIPtr; + double *HICUMtempBaseBIPtr; + double *HICUMtempBaseBPPtr; + double *HICUMtempEmitEIPtr; + double *HICUMtempSubsSIPtr; + double *HICUMtempTempPtr; + + unsigned HICUMareaGiven :1; /* flag to indicate area was specified */ + unsigned HICUMoff :1; /* 'off' flag for hicum */ + unsigned HICUMicVBEGiven :1; /* flag to indicate VBE init. cond. given */ + unsigned HICUMicVCEGiven :1; /* flag to indicate VCE init. cond. given */ + unsigned HICUMtempGiven :1; /* temperature given for hicum instance*/ + unsigned HICUMdtempGiven :1; /* delta temperature given for hicum instance*/ + unsigned HICUMmGiven :1; /* flag to indicate multiplier was specified */ + + double HICUMcaprbi; + double HICUMcapdeix; + double HICUMcapjei; + double HICUMcapdci; + double HICUMcapjci; + double HICUMcapjep; + double HICUMcapjcx_t_i; + double HICUMcapjcx_t_ii; + double HICUMcapdsu; + double HICUMcapjs; + double HICUMcapscp; + double HICUMcapsu; + double HICUMcapcth; + + double HICUMtVcrit; + double HICUMbetadc; + +#ifndef NONOISE + double HICUMnVar[NSTATVARS][HICUMNSRCS]; +#else /*NONOISE*/ + double **HICUMnVar; +#endif /*NONOISE*/ +/* the above to avoid allocating memory when it is not needed */ + +} HICUMinstance; + +/* entries in the state vector for hicum: */ + +#define HICUMvbiei HICUMstate +#define HICUMvbici HICUMstate+1 +#define HICUMvbpei HICUMstate+2 +#define HICUMvbpbi HICUMstate+3 +#define HICUMvbpci HICUMstate+4 +#define HICUMvsici HICUMstate+5 + +#define HICUMibiei HICUMstate+6 +#define HICUMibiei_Vbiei HICUMstate+7 + +#define HICUMibpei HICUMstate+8 +#define HICUMibpei_Vbpei HICUMstate+9 + +#define HICUMiciei HICUMstate+10 +#define HICUMiciei_Vbiei HICUMstate+11 +#define HICUMiciei_Vbici HICUMstate+12 + +#define HICUMibici HICUMstate+13 +#define HICUMibici_Vbici HICUMstate+14 + +#define HICUMibpbi HICUMstate+15 +#define HICUMibpbi_Vbpbi HICUMstate+16 +#define HICUMibpbi_Vbiei HICUMstate+17 +#define HICUMibpbi_Vbici HICUMstate+18 + +#define HICUMibpci HICUMstate+19 +#define HICUMibpci_Vbpci HICUMstate+20 + +#define HICUMisici HICUMstate+21 +#define HICUMisici_Vsici HICUMstate+22 + +#define HICUMibpsi HICUMstate+23 +#define HICUMibpsi_Vbpci HICUMstate+24 +#define HICUMibpsi_Vsici HICUMstate+25 + +#define HICUMisis_Vsis HICUMstate+26 + +#define HICUMieie HICUMstate+27 // needed for re-flicker noise + +#define HICUMqrbi HICUMstate+28 +#define HICUMcqrbi HICUMstate+29 + +#define HICUMqjei HICUMstate+30 +#define HICUMcqjei HICUMstate+31 + +#define HICUMqdeix HICUMstate+32 +#define HICUMcqdeix HICUMstate+33 + +#define HICUMqjci HICUMstate+34 +#define HICUMcqjci HICUMstate+35 + +#define HICUMqdci HICUMstate+36 +#define HICUMcqdci HICUMstate+37 + +#define HICUMqjep HICUMstate+38 +#define HICUMcqjep HICUMstate+39 + +#define HICUMqjcx0_i HICUMstate+40 +#define HICUMcqcx0_t_i HICUMstate+41 + +#define HICUMqjcx0_ii HICUMstate+42 +#define HICUMcqcx0_t_ii HICUMstate+43 + +#define HICUMqdsu HICUMstate+44 +#define HICUMcqdsu HICUMstate+45 + +#define HICUMqjs HICUMstate+46 +#define HICUMcqjs HICUMstate+47 + +#define HICUMqscp HICUMstate+48 +#define HICUMcqscp HICUMstate+49 + +#define HICUMqbepar1 HICUMstate+50 +#define HICUMcqbepar1 HICUMstate+51 +#define HICUMgqbepar1 HICUMstate+52 + +#define HICUMqbepar2 HICUMstate+53 +#define HICUMcqbepar2 HICUMstate+54 +#define HICUMgqbepar2 HICUMstate+55 + +#define HICUMqbcpar1 HICUMstate+56 +#define HICUMcqbcpar1 HICUMstate+57 +#define HICUMgqbcpar1 HICUMstate+58 + +#define HICUMqbcpar2 HICUMstate+59 +#define HICUMcqbcpar2 HICUMstate+60 +#define HICUMgqbcpar2 HICUMstate+61 + +#define HICUMqsu HICUMstate+62 +#define HICUMcqsu HICUMstate+63 +#define HICUMgqsu HICUMstate+64 + +#define HICUMqcth HICUMstate+65 /* thermal capacitor charge */ +#define HICUMcqcth HICUMstate+66 /* thermal capacitor current */ + +#define HICUMvrth HICUMstate+67 +#define HICUMicth_Vrth HICUMstate+68 + +//#define HICUMvbxf HICUMstate+73 +//#define HICUMvbxf1 HICUMstate+74 +//#define HICUMvbxf2 HICUMstate+75 +#define HICUMnumStates 69 + +/* per model data */ +typedef struct sHICUMmodel { /* model structure for a hicum */ + + struct GENmodel gen; + +#define HICUMmodType gen.GENmodType +#define HICUMnextModel(inst) ((struct sHICUMmodel *)((inst)->gen.GENnextModel)) +#define HICUMinstances(inst) ((HICUMinstance *)((inst)->gen.GENinstances)) +#define HICUMmodName gen.GENmodName + +//Circuit simulator specific parameters + int HICUMtype; + double HICUMtnom; + +//Transfer current + double HICUMc10; + double HICUMqp0; + double HICUMich; + double HICUMhf0; + double HICUMhfe; + double HICUMhfc; + double HICUMhjei; + double HICUMahjei; + double HICUMrhjei; + double HICUMhjci; + +//Base-Emitter diode; + double HICUMibeis; + double HICUMmbei; + double HICUMireis; + double HICUMmrei; + double HICUMibeps; + double HICUMmbep; + double HICUMireps; + double HICUMmrep; + double HICUMmcf; + +//Transit time for excess recombination current at b-c barrier + double HICUMtbhrec; + +//Base-Collector diode currents + double HICUMibcis; + double HICUMmbci; + double HICUMibcxs; + double HICUMmbcx; + +//Base-Emitter tunneling current + double HICUMibets; + double HICUMabet; + int HICUMtunode; + +//Base-Collector avalanche current + double HICUMfavl; + double HICUMqavl; + double HICUMalfav; + double HICUMalqav; + +//Series resistances + double HICUMrbi0; + double HICUMrbx; + double HICUMfgeo; + double HICUMfdqr0; + double HICUMfcrbi; + double HICUMfqi; + double HICUMre; + double HICUMrcx; + +//Substrate transistor + double HICUMitss; + double HICUMmsf; + double HICUMiscs; + double HICUMmsc; + double HICUMtsf; + +//Intra-device substrate coupling + double HICUMrsu; + double HICUMcsu; + +//Depletion Capacitances + double HICUMcjei0; + double HICUMvdei; + double HICUMzei; + double HICUMajei; + double HICUMcjep0; + double HICUMvdep; + double HICUMzep; + double HICUMajep; + double HICUMcjci0; + double HICUMvdci; + double HICUMzci; + double HICUMvptci; + double HICUMcjcx0; + double HICUMvdcx; + double HICUMzcx; + double HICUMvptcx; + double HICUMfbcpar; + double HICUMfbepar; + double HICUMcjs0; + double HICUMvds; + double HICUMzs; + double HICUMvpts; + double HICUMcscp0; + double HICUMvdsp; + double HICUMzsp; + double HICUMvptsp; + +//Diffusion Capacitances + double HICUMt0; + double HICUMdt0h; + double HICUMtbvl; + double HICUMtef0; + double HICUMgtfe; + double HICUMthcs; + double HICUMahc; + double HICUMfthc; + double HICUMrci0; + double HICUMvlim; + double HICUMvces; + double HICUMvpt; + double HICUMaick; + double HICUMdelck; + double HICUMtr; + double HICUMvcbar; + double HICUMicbar; + double HICUMacbar; + +//Isolation Capacitances + double HICUMcbepar; + double HICUMcbcpar; + +//Non-quasi-static Effect + double HICUMalqf; + double HICUMalit; + int HICUMflnqs; + +//Noise + double HICUMkf; + double HICUMaf; + int HICUMcfbe; + int HICUMflcono; + double HICUMkfre; + double HICUMafre; + +//Lateral Geometry Scaling (at high current densities) + double HICUMlatb; + double HICUMlatl; + +//Temperature dependence + double HICUMvgb; + double HICUMalt0; + double HICUMkt0; + double HICUMzetaci; + double HICUMalvs; + double HICUMalces; + double HICUMzetarbi; + double HICUMzetarbx; + double HICUMzetarcx; + double HICUMzetare; + double HICUMzetacx; + double HICUMvge; + double HICUMvgc; + double HICUMvgs; + double HICUMf1vg; + double HICUMf2vg; + double HICUMzetact; + double HICUMzetabet; + double HICUMalb; + double HICUMdvgbe; + double HICUMzetahjei; + double HICUMzetavgbe; + +//Self-Heating + int HICUMflsh; + double HICUMrth; + double HICUMzetarth; + double HICUMalrth; + double HICUMcth; + +//Compatibility with V2.1 + double HICUMflcomp; + +//SOA check parameters + double HICUMvbeMax; /* maximum voltage over B-E junction */ + double HICUMvbcMax; /* maximum voltage over B-C junction */ + double HICUMvceMax; /* maximum voltage over C-E branch */ + +//Circuit simulator specific parameters + unsigned HICUMtypeGiven : 1; + unsigned HICUMtnomGiven : 1; + +//Transfer current + unsigned HICUMc10Given : 1; + unsigned HICUMqp0Given : 1; + unsigned HICUMichGiven : 1; + unsigned HICUMhf0Given : 1; + unsigned HICUMhfeGiven : 1; + unsigned HICUMhfcGiven : 1; + unsigned HICUMhjeiGiven : 1; + unsigned HICUMahjeiGiven : 1; + unsigned HICUMrhjeiGiven : 1; + unsigned HICUMhjciGiven : 1; + +//Base-Emitter diodeGiven : 1; + unsigned HICUMibeisGiven : 1; + unsigned HICUMmbeiGiven : 1; + unsigned HICUMireisGiven : 1; + unsigned HICUMmreiGiven : 1; + unsigned HICUMibepsGiven : 1; + unsigned HICUMmbepGiven : 1; + unsigned HICUMirepsGiven : 1; + unsigned HICUMmrepGiven : 1; + unsigned HICUMmcfGiven : 1; + +//Transit time for excess recombination current at b-c barrier + unsigned HICUMtbhrecGiven : 1; + +//Base-Collector diode currents + unsigned HICUMibcisGiven : 1; + unsigned HICUMmbciGiven : 1; + unsigned HICUMibcxsGiven : 1; + unsigned HICUMmbcxGiven : 1; + +//Base-Emitter tunneling current + unsigned HICUMibetsGiven : 1; + unsigned HICUMabetGiven : 1; + unsigned HICUMtunodeGiven : 1; + +//Base-Collector avalanche current + unsigned HICUMfavlGiven : 1; + unsigned HICUMqavlGiven : 1; + unsigned HICUMalfavGiven : 1; + unsigned HICUMalqavGiven : 1; + +//Series resistances + unsigned HICUMrbi0Given : 1; + unsigned HICUMrbxGiven : 1; + unsigned HICUMfgeoGiven : 1; + unsigned HICUMfdqr0Given : 1; + unsigned HICUMfcrbiGiven : 1; + unsigned HICUMfqiGiven : 1; + unsigned HICUMreGiven : 1; + unsigned HICUMrcxGiven : 1; + +//Substrate transistor + unsigned HICUMitssGiven : 1; + unsigned HICUMmsfGiven : 1; + unsigned HICUMiscsGiven : 1; + unsigned HICUMmscGiven : 1; + unsigned HICUMtsfGiven : 1; + +//Intra-device substrate coupling + unsigned HICUMrsuGiven : 1; + unsigned HICUMcsuGiven : 1; + +//Depletion Capacitances + unsigned HICUMcjei0Given : 1; + unsigned HICUMvdeiGiven : 1; + unsigned HICUMzeiGiven : 1; + unsigned HICUMajeiGiven : 1; + unsigned HICUMcjep0Given : 1; + unsigned HICUMvdepGiven : 1; + unsigned HICUMzepGiven : 1; + unsigned HICUMajepGiven : 1; + unsigned HICUMcjci0Given : 1; + unsigned HICUMvdciGiven : 1; + unsigned HICUMzciGiven : 1; + unsigned HICUMvptciGiven : 1; + unsigned HICUMcjcx0Given : 1; + unsigned HICUMvdcxGiven : 1; + unsigned HICUMzcxGiven : 1; + unsigned HICUMvptcxGiven : 1; + unsigned HICUMfbcparGiven : 1; + unsigned HICUMfbeparGiven : 1; + unsigned HICUMcjs0Given : 1; + unsigned HICUMvdsGiven : 1; + unsigned HICUMzsGiven : 1; + unsigned HICUMvptsGiven : 1; + unsigned HICUMcscp0Given : 1; + unsigned HICUMvdspGiven : 1; + unsigned HICUMzspGiven : 1; + unsigned HICUMvptspGiven : 1; + +//Diffusion Capacitances + unsigned HICUMt0Given : 1; + unsigned HICUMdt0hGiven : 1; + unsigned HICUMtbvlGiven : 1; + unsigned HICUMtef0Given : 1; + unsigned HICUMgtfeGiven : 1; + unsigned HICUMthcsGiven : 1; + unsigned HICUMahcGiven : 1; + unsigned HICUMfthcGiven : 1; + unsigned HICUMrci0Given : 1; + unsigned HICUMvlimGiven : 1; + unsigned HICUMvcesGiven : 1; + unsigned HICUMvptGiven : 1; + unsigned HICUMaickGiven : 1; + unsigned HICUMdelckGiven : 1; + unsigned HICUMtrGiven : 1; + unsigned HICUMvcbarGiven : 1; + unsigned HICUMicbarGiven : 1; + unsigned HICUMacbarGiven : 1; + +//Isolation Capacitances + unsigned HICUMcbeparGiven : 1; + unsigned HICUMcbcparGiven : 1; + +//Non-quasi-static Effect + unsigned HICUMalqfGiven : 1; + unsigned HICUMalitGiven : 1; + unsigned HICUMflnqsGiven : 1; + +//Noise + unsigned HICUMkfGiven : 1; + unsigned HICUMafGiven : 1; + unsigned HICUMcfbeGiven : 1; + unsigned HICUMflconoGiven : 1; + unsigned HICUMkfreGiven : 1; + unsigned HICUMafreGiven : 1; + +//Lateral Geometry Scaling (at high current densities) + unsigned HICUMlatbGiven : 1; + unsigned HICUMlatlGiven : 1; + +//Temperature dependence + unsigned HICUMvgbGiven : 1; + unsigned HICUMalt0Given : 1; + unsigned HICUMkt0Given : 1; + unsigned HICUMzetaciGiven : 1; + unsigned HICUMalvsGiven : 1; + unsigned HICUMalcesGiven : 1; + unsigned HICUMzetarbiGiven : 1; + unsigned HICUMzetarbxGiven : 1; + unsigned HICUMzetarcxGiven : 1; + unsigned HICUMzetareGiven : 1; + unsigned HICUMzetacxGiven : 1; + unsigned HICUMvgeGiven : 1; + unsigned HICUMvgcGiven : 1; + unsigned HICUMvgsGiven : 1; + unsigned HICUMf1vgGiven : 1; + unsigned HICUMf2vgGiven : 1; + unsigned HICUMzetactGiven : 1; + unsigned HICUMzetabetGiven : 1; + unsigned HICUMalbGiven : 1; + unsigned HICUMdvgbeGiven : 1; + unsigned HICUMzetahjeiGiven : 1; + unsigned HICUMzetavgbeGiven : 1; + +//Self-Heating + unsigned HICUMflshGiven : 1; + unsigned HICUMrthGiven : 1; + unsigned HICUMzetarthGiven : 1; + unsigned HICUMalrthGiven : 1; + unsigned HICUMcthGiven : 1; + +//Compatibility with V2.1 + unsigned HICUMflcompGiven : 1; + + unsigned HICUMvbeMaxGiven : 1; + unsigned HICUMvbcMaxGiven : 1; + unsigned HICUMvceMaxGiven : 1; +} HICUMmodel; + +#ifndef NPN +#define NPN 1 +#define PNP -1 +#endif /*NPN*/ + +/* device parameters */ +enum { + HICUM_AREA = 1, + HICUM_OFF, + HICUM_IC, + HICUM_IC_VBE, + HICUM_IC_VCE, + HICUM_TEMP, + HICUM_DTEMP, + HICUM_M, +}; + +/* model parameters */ +enum { +//Circuit simulator specific parameters + HICUM_MOD_NPN = 101, + HICUM_MOD_PNP, + HICUM_MOD_TNOM, + +//Transfer current + HICUM_MOD_C10, + HICUM_MOD_QP0, + HICUM_MOD_ICH, + HICUM_MOD_HF0, + HICUM_MOD_HFE, + HICUM_MOD_HFC, + HICUM_MOD_HJEI, + HICUM_MOD_AHJEI, + HICUM_MOD_RHJEI, + HICUM_MOD_HJCI, + +//Base-Emitter diode, + HICUM_MOD_IBEIS, + HICUM_MOD_MBEI, + HICUM_MOD_IREIS, + HICUM_MOD_MREI, + HICUM_MOD_IBEPS, + HICUM_MOD_MBEP, + HICUM_MOD_IREPS, + HICUM_MOD_MREP, + HICUM_MOD_MCF, + +//Transit time for excess recombination current at b-c barrier + HICUM_MOD_TBHREC, + +//Base-Collector diode currents + HICUM_MOD_IBCIS, + HICUM_MOD_MBCI, + HICUM_MOD_IBCXS, + HICUM_MOD_MBCX, + +//Base-Emitter tunneling current + HICUM_MOD_IBETS, + HICUM_MOD_ABET, + HICUM_MOD_TUNODE, + +//Base-Collector avalanche current + HICUM_MOD_FAVL, + HICUM_MOD_QAVL, + HICUM_MOD_ALFAV, + HICUM_MOD_ALQAV, + +//Series resistances + HICUM_MOD_RBI0, + HICUM_MOD_RBX, + HICUM_MOD_FGEO, + HICUM_MOD_FDQR0, + HICUM_MOD_FCRBI, + HICUM_MOD_FQI, + HICUM_MOD_RE, + HICUM_MOD_RCX, + +//Substrate transistor + HICUM_MOD_ITSS, + HICUM_MOD_MSF, + HICUM_MOD_ISCS, + HICUM_MOD_MSC, + HICUM_MOD_TSF, + +//Intra-device substrate coupling + HICUM_MOD_RSU, + HICUM_MOD_CSU, + +//Depletion Capacitances + HICUM_MOD_CJEI0, + HICUM_MOD_VDEI, + HICUM_MOD_ZEI, + HICUM_MOD_AJEI, + HICUM_MOD_CJEP0, + HICUM_MOD_VDEP, + HICUM_MOD_ZEP, + HICUM_MOD_AJEP, + HICUM_MOD_CJCI0, + HICUM_MOD_VDCI, + HICUM_MOD_ZCI, + HICUM_MOD_VPTCI, + HICUM_MOD_CJCX0, + HICUM_MOD_VDCX, + HICUM_MOD_ZCX, + HICUM_MOD_VPTCX, + HICUM_MOD_FBCPAR, + HICUM_MOD_FBEPAR, + HICUM_MOD_CJS0, + HICUM_MOD_VDS, + HICUM_MOD_ZS, + HICUM_MOD_VPTS, + HICUM_MOD_CSCP0, + HICUM_MOD_VDSP, + HICUM_MOD_ZSP, + HICUM_MOD_VPTSP, + +//Diffusion Capacitances + HICUM_MOD_T0, + HICUM_MOD_DT0H, + HICUM_MOD_TBVL, + HICUM_MOD_TEF0, + HICUM_MOD_GTFE, + HICUM_MOD_THCS, + HICUM_MOD_AHC, + HICUM_MOD_FTHC, + HICUM_MOD_RCI0, + HICUM_MOD_VLIM, + HICUM_MOD_VCES, + HICUM_MOD_VPT, + HICUM_MOD_AICK, + HICUM_MOD_DELCK, + HICUM_MOD_TR, + HICUM_MOD_VCBAR, + HICUM_MOD_ICBAR, + HICUM_MOD_ACBAR, + +//Isolation Capacitances + HICUM_MOD_CBEPAR, + HICUM_MOD_CBCPAR, + +//Non-quasi-static Effect + HICUM_MOD_ALQF, + HICUM_MOD_ALIT, + HICUM_MOD_FLNQS, + +//Noise + HICUM_MOD_KF, + HICUM_MOD_AF, + HICUM_MOD_CFBE, + HICUM_MOD_FLCONO, + + HICUM_MOD_KFRE, + HICUM_MOD_AFRE, + +//Lateral Geometry Scaling (at high current densities) + HICUM_MOD_LATB, + HICUM_MOD_LATL, + +//Temperature dependence + HICUM_MOD_VGB, + HICUM_MOD_ALT0, + HICUM_MOD_KT0, + HICUM_MOD_ZETACI, + HICUM_MOD_ALVS, + HICUM_MOD_ALCES, + HICUM_MOD_ZETARBI, + HICUM_MOD_ZETARBX, + HICUM_MOD_ZETARCX, + HICUM_MOD_ZETARE, + HICUM_MOD_ZETACX, + HICUM_MOD_VGE, + HICUM_MOD_VGC, + HICUM_MOD_VGS, + HICUM_MOD_F1VG, + HICUM_MOD_F2VG, + HICUM_MOD_ZETACT, + HICUM_MOD_ZETABET, + HICUM_MOD_ALB, + HICUM_MOD_DVGBE, + HICUM_MOD_ZETAHJEI, + HICUM_MOD_ZETAVGBE, + +//Self-Heating + HICUM_MOD_FLSH, + HICUM_MOD_RTH, + HICUM_MOD_ZETARTH, + HICUM_MOD_ALRTH, + HICUM_MOD_CTH, + +//Compatibility with V2.1 + HICUM_MOD_FLCOMP, + + HICUM_MOD_VBE_MAX, + HICUM_MOD_VBC_MAX, + HICUM_MOD_VCE_MAX, +}; + +/* device questions */ +enum { + HICUM_QUEST_FT = 251, + HICUM_QUEST_COLLNODE, + HICUM_QUEST_BASENODE, + HICUM_QUEST_EMITNODE, + HICUM_QUEST_SUBSNODE, + HICUM_QUEST_COLLCINODE, + HICUM_QUEST_BASEBPNODE, + HICUM_QUEST_BASEBINODE, + HICUM_QUEST_EMITEINODE, + HICUM_QUEST_SUBSSINODE, +// HICUM_QUEST_XFNODE, +// HICUM_QUEST_XF1NODE, +// HICUM_QUEST_XF2NODE, + HICUM_QUEST_VBE, + HICUM_QUEST_VBC, + HICUM_QUEST_CC, + HICUM_QUEST_CB, + HICUM_QUEST_CE, + HICUM_QUEST_CS, + HICUM_QUEST_GM, + HICUM_QUEST_GO, + HICUM_QUEST_GPI, + HICUM_QUEST_GMU, + HICUM_QUEST_GX, + HICUM_QUEST_QBE, + HICUM_QUEST_CQBE, + HICUM_QUEST_QBC, + HICUM_QUEST_CQBC, + HICUM_QUEST_QBX, + HICUM_QUEST_CQBX, + HICUM_QUEST_QBCP, + HICUM_QUEST_CQBCP, + HICUM_QUEST_CEXBC, + HICUM_QUEST_GEQCB, + HICUM_QUEST_GCSUB, + HICUM_QUEST_GDSUB, + HICUM_QUEST_GEQBX, + HICUM_QUEST_CJBE, + HICUM_QUEST_CBEX, + HICUM_QUEST_CDBE, + HICUM_QUEST_CBEP, + HICUM_QUEST_CJBC, + HICUM_QUEST_CBCXI, + HICUM_QUEST_CBCXII, + HICUM_QUEST_CSCP, + HICUM_QUEST_POWER, +}; + +/* model questions */ +enum { + HICUM_MOD_COLLCONDUCT = 301, + HICUM_MOD_BASECONDUCT, + HICUM_MOD_EMITTERCONDUCT, + HICUM_MOD_SUBSTRATECONDUCT, + HICUM_MOD_TYPE, +}; + +#include "hicumext.h" +#endif /*HICUM*/ diff --git a/src/spicelib/devices/hicum2/hicumext.h b/src/spicelib/devices/hicum2/hicumext.h new file mode 100644 index 000000000..18d9cd38f --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumext.h @@ -0,0 +1,28 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ +#ifndef __HICUMEXT_H +#define __HICUMEXT_H + + +extern int HICUMacLoad(GENmodel *,CKTcircuit*); +extern int HICUMask(CKTcircuit *,GENinstance*,int,IFvalue*,IFvalue*); +extern int HICUMconvTest(GENmodel*,CKTcircuit*); +extern int HICUMdelete(GENinstance*); +extern int HICUMgetic(GENmodel*,CKTcircuit*); +extern int HICUMload(GENmodel*,CKTcircuit*); +extern int HICUMmAsk(CKTcircuit*,GENmodel*,int,IFvalue*); +extern int HICUMmParam(int,IFvalue*,GENmodel*); +extern int HICUMparam(int,IFvalue*,GENinstance*,IFvalue*); +extern int HICUMpzLoad(GENmodel*, CKTcircuit*, SPcomplex*); +extern int HICUMsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); +extern int HICUMunsetup(GENmodel*,CKTcircuit*); +extern int HICUMtemp(GENmodel*,CKTcircuit*); +extern int HICUMtrunc(GENmodel*,CKTcircuit*,double*); +extern int HICUMnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int HICUMsoaCheck(CKTcircuit *, GENmodel *); + +#endif diff --git a/src/spicelib/devices/hicum2/hicumgetic.c b/src/spicelib/devices/hicum2/hicumgetic.c new file mode 100644 index 000000000..2cfef2468 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumgetic.c @@ -0,0 +1,47 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine gets the device initial conditions for the HICUMs + * from the RHS vector + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +HICUMgetic(GENmodel *inModel, CKTcircuit *ckt) +{ + + HICUMmodel *model = (HICUMmodel*)inModel; + HICUMinstance *here; + /* + * grab initial conditions out of rhs array. User specified, so use + * external nodes to get values + */ + + for( ; model ; model = HICUMnextModel(model)) { + for(here = HICUMinstances(model); here ; here = HICUMnextInstance(here)) { + + if(!here->HICUMicVBEGiven) { + here->HICUMicVBE = + *(ckt->CKTrhs + here->HICUMbaseNode) - + *(ckt->CKTrhs + here->HICUMemitNode); + } + if(!here->HICUMicVCEGiven) { + here->HICUMicVCE = + *(ckt->CKTrhs + here->HICUMcollNode) - + *(ckt->CKTrhs + here->HICUMemitNode); + } + } + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicuminit.c b/src/spicelib/devices/hicum2/hicuminit.c new file mode 100644 index 000000000..73b5e46e1 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicuminit.c @@ -0,0 +1,81 @@ +/* + * hicuminit.c + */ + + +#include "ngspice/config.h" + +#include "ngspice/devdefs.h" + +#include "hicumitf.h" +#include "hicumext.h" +#include "hicuminit.h" + + +SPICEdev HICUMinfo = { + .DEVpublic = { + .name = "hicum2", + .description = "High Current Model for BJT", + .terms = &HICUMnSize, + .numNames = &HICUMnSize, + .termNames = HICUMnames, + .numInstanceParms = &HICUMpTSize, + .instanceParms = HICUMpTable, + .numModelParms = &HICUMmPTSize, + .modelParms = HICUMmPTable, + .flags = DEV_DEFAULT, + +#ifdef XSPICE + .cm_func = NULL, + .num_conn = 0, + .conn = NULL, + .num_param = 0, + .param = NULL, + .num_inst_var = 0, + .inst_var = NULL, +#endif + }, + + .DEVparam = HICUMparam, + .DEVmodParam = HICUMmParam, + .DEVload = HICUMload, + .DEVsetup = HICUMsetup, + .DEVunsetup = HICUMunsetup, + .DEVpzSetup = HICUMsetup, + .DEVtemperature = HICUMtemp, + .DEVtrunc = HICUMtrunc, + .DEVfindBranch = NULL, + .DEVacLoad = HICUMacLoad, + .DEVaccept = NULL, + .DEVdestroy = NULL, + .DEVmodDelete = NULL, + .DEVdelete = NULL, + .DEVsetic = HICUMgetic, + .DEVask = HICUMask, + .DEVmodAsk = HICUMmAsk, + .DEVpzLoad = HICUMpzLoad, + .DEVconvTest = HICUMconvTest, + .DEVsenSetup = NULL, + .DEVsenLoad = NULL, + .DEVsenUpdate = NULL, + .DEVsenAcLoad = NULL, + .DEVsenPrint = NULL, + .DEVsenTrunc = NULL, + .DEVdisto = NULL, + .DEVnoise = HICUMnoise, + .DEVsoaCheck = HICUMsoaCheck, + .DEVinstSize = &HICUMiSize, + .DEVmodSize = &HICUMmSize, + +#ifdef CIDER + .DEVdump = NULL, + .DEVacct = NULL, +#endif +}; + + +SPICEdev * +get_hicum_info(void) +{ + return &HICUMinfo; +} diff --git a/src/spicelib/devices/hicum2/hicuminit.h b/src/spicelib/devices/hicum2/hicuminit.h new file mode 100644 index 000000000..ca8ab5ebf --- /dev/null +++ b/src/spicelib/devices/hicum2/hicuminit.h @@ -0,0 +1,13 @@ +#ifndef _HICUMINIT_H +#define _HICUMINIT_H + +extern IFparm HICUMpTable[ ]; +extern IFparm HICUMmPTable[ ]; +extern char *HICUMnames[ ]; +extern int HICUMpTSize; +extern int HICUMmPTSize; +extern int HICUMnSize; +extern int HICUMiSize; +extern int HICUMmSize; + +#endif diff --git a/src/spicelib/devices/hicum2/hicumitf.h b/src/spicelib/devices/hicum2/hicumitf.h new file mode 100644 index 000000000..e67b2d8d7 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumitf.h @@ -0,0 +1,12 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ +#ifndef DEV_HICUM +#define DEV_HICUM + +extern SPICEdev *get_hicum_info(void); + +#endif diff --git a/src/spicelib/devices/hicum2/hicumload.c b/src/spicelib/devices/hicum2/hicumload.c new file mode 100644 index 000000000..497c67cfd --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumload.c @@ -0,0 +1,2290 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This is the function called each iteration to evaluate the + * HICUMs in the circuit and load them into the matrix as appropriate + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/const.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/devdefs.h" + +#define VPT_thresh 1.0e2 +#define Dexp_lim 80.0 +#define Cexp_lim 80.0 +#define DFa_fj 1.921812 +#define RTOLC 1.0e-5 +#define l_itmax 100 +#define LN_EXP_LIMIT 11.0 +#define MIN_R 0.001 + +void QJMODF(double , double , double , double , double , double , double *, double *); +void QJMOD(double ,double , double , double , double , double , double , double *, double *); +void HICJQ(double , double , double , double , double , double , double *, double *); +void HICFCI(double , double , double , double *, double *); +void HICFCT(double , double , double *, double *); +void HICQFC(HICUMinstance *here, HICUMmodel *model, double , double , double , double *, double *, double *, double *); +void HICQFF(HICUMinstance *here, HICUMmodel *model, double , double , double *, double *, double *, double *, double *); +void HICDIO(double , double , double , double , double , double *, double *); + +double FFdVc, FFdVc_ditf; + +/* HICUMlimitlog(deltemp, deltemp_old, LIM_TOL, check) + * Logarithmic damping the per-iteration change of deltemp beyond LIM_TOL. + */ +static double +HICUMlimitlog( + double deltemp, + double deltemp_old, + double LIM_TOL, + int *check) +{ + *check = 0; + if (isnan (deltemp) || isnan (deltemp_old)) + { + fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n"); + fprintf(stderr, "New prediction returns to 0.0!\n"); + deltemp = 0.0; + *check = 1; + } + /* Logarithmic damping of deltemp beyond LIM_TOL */ + if (deltemp > deltemp_old + LIM_TOL) { + deltemp = deltemp_old + LIM_TOL + log10((deltemp-deltemp_old)/LIM_TOL); + *check = 1; + } + else if (deltemp < deltemp_old - LIM_TOL) { + deltemp = deltemp_old - LIM_TOL - log10((deltemp_old-deltemp)/LIM_TOL); + *check = 1; + } + return deltemp; +} + + +//////////////Explicit Capacitance and Charge Expression/////////////// + +// DEPLETION CHARGE CALCULATION +// Hyperbolic smoothing used; no punch-through +// INPUT: +// c_0 : zero-bias capacitance +// u_d : built-in voltage +// z : exponent coefficient +// a_j : control parameter for C peak value at high forward bias +// U_cap : voltage across junction +// OUTPUT: +// Qz : depletion Charge +// C : depletion capacitance +void QJMODF(double vt, double c_0, double u_d, double z, double a_j, double U_cap, double *C, double *Qz) +{ +double DFV_f,DFv_e,DFs_q,DFs_q2,DFv_j,DFdvj_dv,DFb,DFC_j1,DFQ_j; + if(c_0 > 0.0) { + DFV_f = u_d*(1.0-exp(-log(a_j)/z)); + DFv_e = (DFV_f-U_cap)/vt; + DFs_q = sqrt(DFv_e*DFv_e+DFa_fj); + DFs_q2 = (DFv_e+DFs_q)*0.5; + DFv_j = DFV_f-vt*DFs_q2; + DFdvj_dv = DFs_q2/DFs_q; + DFb = log(1.0-DFv_j/u_d); + DFC_j1 = c_0*exp(-z*DFb)*DFdvj_dv; + *C = DFC_j1+a_j*c_0*(1.0-DFdvj_dv); + DFQ_j = c_0*u_d*(1.0-exp(DFb*(1.0-z)))/(1.0-z); + *Qz = DFQ_j+a_j*c_0*(U_cap-DFv_j); + } else { + *C = 0.0; + *Qz = 0.0; + } +} + +//////////////Explicit Capacitance and Charge Expression/////////////// + + +// DEPLETION CHARGE CALCULATION CONSIDERING PUNCH THROUGH +// smoothing of reverse bias region (punch-through) +// and limiting to a_j=Cj,max/Cj0 for forward bias. +// Important for base-collector and collector-substrate junction +// INPUT: +// c_0 : zero-bias capacitance +// u_d : built-in voltage +// z : exponent coefficient +// a_j : control parameter for C peak value at high forward bias +// v_pt : punch-through voltage (defined as qNw^2/2e) +// U_cap : voltage across junction +// OUTPUT: +// Qz : depletion charge +// C : depletion capacitance +void QJMOD(double vt,double c_0, double u_d, double z, double a_j, double v_pt, double U_cap, double *C, double *Qz) +{ +double Dz_r,Dv_p,DV_f,DC_max,DC_c,Dv_e,De,De_1,Dv_j1,Da,Dv_r,De_2,Dv_j2,Dv_j4,DCln1,DCln2,Dz1,Dzr1,DC_j1,DC_j2,DC_j3,DQ_j1,DQ_j2,DQ_j3; + if(c_0 > 0.0) { + Dz_r = z/4.0; + Dv_p = v_pt-u_d; + DV_f = u_d*(1.0-exp(-log(a_j)/z)); + DC_max = a_j*c_0; + DC_c = c_0*exp((Dz_r-z)*log(v_pt/u_d)); + Dv_e = (DV_f-U_cap)/vt; + if(Dv_e < Cexp_lim) { + De = exp(Dv_e); + De_1 = De/(1.0+De); + Dv_j1 = DV_f-vt*log(1.0+De); + } else { + De_1 = 1.0; + Dv_j1 = U_cap; + } + Da = 0.1*Dv_p+4.0*vt; + Dv_r = (Dv_p+Dv_j1)/Da; + if(Dv_r < Cexp_lim) { + De = exp(Dv_r); + De_2 = De/(1.0+De); + Dv_j2 = -Dv_p+Da*(log(1.0+De)-exp(-(Dv_p+DV_f)/Da)); + } else { + De_2 = 1.0; + Dv_j2 = Dv_j1; + } + Dv_j4 = U_cap-Dv_j1; + DCln1 = log(1.0-Dv_j1/u_d); + DCln2 = log(1.0-Dv_j2/u_d); + Dz1 = 1.0-z; + Dzr1 = 1.0-Dz_r; + DC_j1 = c_0*exp(DCln2*(-z))*De_1*De_2; + DC_j2 = DC_c*exp(DCln1*(-Dz_r))*(1.0-De_2); + DC_j3 = DC_max*(1.0-De_1); + *C = DC_j1+DC_j2+DC_j3; + DQ_j1 = c_0*(1.0-exp(DCln2*Dz1))/Dz1; + DQ_j2 = DC_c*(1.0-exp(DCln1*Dzr1))/Dzr1; + DQ_j3 = DC_c*(1.0-exp(DCln2*Dzr1))/Dzr1; + *Qz = (DQ_j1+DQ_j2-DQ_j3)*u_d+DC_max*Dv_j4; + } else { + *C = 0.0; + *Qz = 0.0; + } +} + +// DEPLETION CHARGE & CAPACITANCE CALCULATION SELECTOR +// Dependent on junction punch-through voltage +// Important for collector related junctions +void HICJQ(double vt, double c_0, double u_d, double z, double v_pt, double U_cap, double *C, double *Qz) +{ + if(v_pt < VPT_thresh) { + QJMOD(vt,c_0,u_d,z,2.4,v_pt,U_cap,C,Qz); + } else { + QJMODF(vt,c_0,u_d,z,2.4,U_cap,C,Qz); + } +} + +// A CALCULATION NEEDED FOR COLLECTOR MINORITY CHARGE FORMULATION +// INPUT: +// zb,zl : zeta_b and zeta_l (model parameters, TED 10/96) +// w : normalized injection width +// OUTPUT: +// hicfcio : function of equation (2.1.17-10) +void HICFCI(double zb, double zl, double w, double *hicfcio, double *dhicfcio_dw) +{ +double z,lnzb,x,a,a2,a3,r; + z = zb*w; + lnzb = log(1+zb*w); + if(z > 1.0e-6) { + x = 1.0+z; + a = x*x; + a2 = 0.250*(a*(2.0*lnzb-1.0)+1.0); + a3 = (a*x*(3.0*lnzb-1.0)+1.0)/9.0; + r = zl/zb; + *hicfcio = ((1.0-r)*a2+r*a3)/zb; + *dhicfcio_dw = ((1.0-r)*x+r*a)*lnzb; + } else { + a = z*z; + a2 = 3.0+z-0.25*a+0.10*z*a; + a3 = 2.0*z+0.75*a-0.20*a*z; + *hicfcio = (zb*a2+zl*a3)*w*w/6.0; + *dhicfcio_dw = (1+zl*w)*(1+z)*lnzb; + } +} + +// NEEDED TO CALCULATE WEIGHTED ICCR COLLECTOR MINORITY CHARGE +// INPUT: +// z : zeta_b or zeta_l +// w : normalized injection width +// OUTPUT: +// hicfcto : output +// dhicfcto_dw : derivative of output wrt w +void HICFCT(double z, double w, double *hicfcto, double *dhicfcto_dw) +{ +double a,lnz; + a = z*w; + lnz = log(1+z*w); + if (a > 1.0e-6) { + *hicfcto = (a - lnz)/z; + *dhicfcto_dw = a / (1.0 + a); + } else { + *hicfcto = 0.5 * a * w; + *dhicfcto_dw = a; + } +} + +// COLLECTOR CURRENT SPREADING CALCULATION +// collector minority charge incl. 2D/3D current spreading (TED 10/96) +// INPUT: +// Ix : forward transport current component (itf) +// I_CK : critical current +// FFT_pcS : dependent on fthc and thcs (parameters) +// IMPLICIT INPUT: +// ahc, latl, latb : model parameters +// vt : thermal voltage +// OUTPUT: +// Q_fC, Q_CT: actual and ICCR (weighted) hole charge +// T_fC, T_cT: actual and ICCR (weighted) transit time +// Derivative dfCT_ditf not properly implemented yet +void HICQFC(HICUMinstance *here, HICUMmodel *model, double Ix, double I_CK, double FFT_pcS, double *Q_fC, double *Q_CT, double *T_fC, double *T_cT) +{ +double FCa,FCrt,FCa_ck,FCdaick_ditf,FCz,FCxl,FCxb,FCln,FCa1,FCd_a,FCw,FCdw_daick,FCda1_dw; +double FCf3,FCdf2_dw,FCdf3_dw,FCd_f,FCz_1,FCf2,FCdfCT_dw,FCdf1_dw,FCw2,FCf1,FCf_ci,FCdfc_dw,FCdw_ditf,FCdfc_ditf,FCf_CT,FCdfCT_ditf; + + *Q_fC = FFT_pcS*Ix; + FCa = 1.0-I_CK/Ix; + FCrt = sqrt(FCa*FCa+model->HICUMahc); + FCa_ck = 1.0-(FCa+FCrt)/(1.0+sqrt(1.0+model->HICUMahc)); + FCdaick_ditf = (FCa_ck-1.0)*(1-FCa)/(FCrt*Ix); + if(model->HICUMlatb > model->HICUMlatl) { + FCz = model->HICUMlatb-model->HICUMlatl; + FCxl = 1.0+model->HICUMlatl; + FCxb = 1.0+model->HICUMlatb; + if(model->HICUMlatb > 0.01) { + FCln = log(FCxb/FCxl); + FCa1 = exp((FCa_ck-1.0)*FCln); + FCd_a = 1.0/(model->HICUMlatl-FCa1*model->HICUMlatb); + FCw = (FCa1-1.0)*FCd_a; + FCdw_daick = -FCz*FCa1*FCln*FCd_a*FCd_a; + FCa1 = log((1.0+model->HICUMlatb*FCw)/(1.0+model->HICUMlatl*FCw)); + FCda1_dw = model->HICUMlatb/(1.0+model->HICUMlatb*FCw) - model->HICUMlatl/(1.0+model->HICUMlatl*FCw); + } else { + FCf1 = 1.0-FCa_ck; + FCd_a = 1.0/(1.0+FCa_ck*model->HICUMlatb); + FCw = FCf1*FCd_a; + FCdw_daick = -1.0*FCd_a*FCd_a*FCxb*FCd_a; + FCa1 = FCz*FCw; + FCda1_dw = FCz; + } + FCf_CT = 2.0/FCz; + FCw2 = FCw*FCw; + FCf1 = model->HICUMlatb*model->HICUMlatl*FCw*FCw2/3.0+(model->HICUMlatb+model->HICUMlatl)*FCw2/2.0+FCw; + FCdf1_dw = model->HICUMlatb*model->HICUMlatl*FCw2 + (model->HICUMlatb+model->HICUMlatl)*FCw + 1.0; + HICFCI(model->HICUMlatb,model->HICUMlatl,FCw,&FCf2,&FCdf2_dw); + HICFCI(model->HICUMlatl,model->HICUMlatb,FCw,&FCf3,&FCdf3_dw); + FCf_ci = FCf_CT*(FCa1*FCf1-FCf2+FCf3); + FCdfc_dw = FCf_CT*(FCa1*FCdf1_dw+FCda1_dw*FCf1-FCdf2_dw+FCdf3_dw); + FCdw_ditf = FCdw_daick*FCdaick_ditf; + FCdfc_ditf = FCdfc_dw*FCdw_ditf; + if(model->HICUMflcomp == 0.0 || model->HICUMflcomp == 2.1) { + HICFCT(model->HICUMlatb,FCw,&FCf2,&FCdf2_dw); + HICFCT(model->HICUMlatl,FCw,&FCf3,&FCdf3_dw); + FCf_CT = FCf_CT*(FCf2-FCf3); + FCdfCT_dw = FCf_CT*(FCdf2_dw-FCdf3_dw); + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf; + } else { + FCf_CT = FCf_ci; + FCdfCT_ditf = FCdfc_ditf; + } + } else { + if(model->HICUMlatb > 0.01) { + FCd_a = 1.0/(1.0+FCa_ck*model->HICUMlatb); + FCw = (1.0-FCa_ck)*FCd_a; + FCdw_daick = -(1.0+model->HICUMlatb)*FCd_a*FCd_a; + } else { + FCw = 1.0-FCa_ck-FCa_ck*model->HICUMlatb; + FCdw_daick = -(1.0+model->HICUMlatb); + } + FCw2 = FCw*FCw; + FCz = model->HICUMlatb*FCw; + FCz_1 = 1.0+FCz; + FCd_f = 1.0/(FCz_1); + FCf_ci = FCw2*(1.0+FCz/3.0)*FCd_f; + FCdfc_dw = 2.0*FCw*(FCz_1+FCz*FCz/3.0)*FCd_f*FCd_f; + FCdw_ditf = FCdw_daick*FCdaick_ditf; + FCdfc_ditf = FCdfc_dw*FCdw_ditf; + if(model->HICUMflcomp == 0.0 || model->HICUMflcomp == 2.1) { + if (FCz > 0.001) { + FCf_CT = 2.0*(FCz_1*log(FCz_1)-FCz)/(model->HICUMlatb*model->HICUMlatb*FCz_1); + FCdfCT_dw = 2.0*FCw*FCd_f*FCd_f; + } else { + FCf_CT = FCw2*(1.0-FCz/3.0)*FCd_f; + FCdfCT_dw = 2.0*FCw*(1.0-FCz*FCz/3.0)*FCd_f*FCd_f; + } + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf; + } else { + FCf_CT = FCf_ci; + FCdfCT_ditf = FCdfc_ditf; + } + } + *Q_CT = *Q_fC*FCf_CT*exp((FFdVc-model->HICUMvcbar)/here->HICUMvt); + *Q_fC = *Q_fC*FCf_ci*exp((FFdVc-model->HICUMvcbar)/here->HICUMvt); + *T_fC = FFT_pcS*exp((FFdVc-model->HICUMvcbar)/here->HICUMvt)*(FCf_ci+Ix*FCdfc_ditf)+ *Q_fC/here->HICUMvt*FFdVc_ditf; + *T_cT = FFT_pcS*exp((FFdVc-model->HICUMvcbar)/here->HICUMvt)*(FCf_CT+Ix*FCdfCT_ditf)+ *Q_CT/here->HICUMvt*FFdVc_ditf; +} + +// TRANSIT-TIME AND STORED MINORITY CHARGE +// INPUT: +// itf : forward transport current +// I_CK : critical current +// T_f : transit time +// Q_f : minority charge / for low current +// IMPLICIT INPUT: +// tef0, gtfe, fthc, thcs, ahc, latl, latb : model parameters +// OUTPUT: +// T_f : transit time +// Q_f : minority charge / transient analysis +// T_fT : transit time +// Q_fT : minority charge / ICCR (transfer current) +// Q_bf : excess base charge +void HICQFF(HICUMinstance *here, HICUMmodel *model, double itf, double I_CK, double *T_f, double *Q_f, double *T_fT, double *Q_fT, double *Q_bf) +{ +double FFitf_ick,FFdTef,FFdQef,FFib,FFfcbar,FFdib_ditf,FFdQbfb,FFdTbfb,FFic,FFw,FFdQfhc,FFdTfhc,FFdQcfc,FFdTcfc,FFdQcfcT,FFdTcfcT,FFdQbfc,FFdTbfc; + + if(itf < 1.0e-6*I_CK) { + *Q_fT = *Q_f; + *T_fT = *T_f; + *Q_bf = 0; + } else { + FFitf_ick = itf/I_CK; + FFdTef = here->HICUMtef0_t*exp(model->HICUMgtfe*log(FFitf_ick)); + FFdQef = FFdTef*itf/(1+model->HICUMgtfe); + if (model->HICUMicbar<0.05*(model->HICUMvlim/model->HICUMrci0)) { + FFdVc = 0; + FFdVc_ditf = 0; + } else { + FFib = (itf-I_CK)/model->HICUMicbar; + if (FFib < -1.0e10) { + FFib = -1.0e10; + } + FFfcbar = (FFib+sqrt(FFib*FFib+model->HICUMacbar))/2.0; + FFdib_ditf = FFfcbar/sqrt(FFib*FFib+model->HICUMacbar)/model->HICUMicbar; + FFdVc = model->HICUMvcbar*exp(-1.0/FFfcbar); + FFdVc_ditf = FFdVc/(FFfcbar*FFfcbar)*FFdib_ditf; + } + FFdQbfb = (1-model->HICUMfthc)*here->HICUMthcs_t*itf*(exp(FFdVc/here->HICUMvt)-1); + FFdTbfb = FFdQbfb/itf+(1-model->HICUMfthc)*here->HICUMthcs_t*itf*exp(FFdVc/here->HICUMvt)/here->HICUMvt*FFdVc_ditf; + FFic = 1-1.0/FFitf_ick; + FFw = (FFic+sqrt(FFic*FFic+model->HICUMahc))/(1+sqrt(1+model->HICUMahc)); + FFdQfhc = here->HICUMthcs_t*itf*FFw*FFw*exp((FFdVc-model->HICUMvcbar)/here->HICUMvt); + FFdTfhc = FFdQfhc*(1.0/itf*(1.0+2.0/(FFitf_ick*sqrt(FFic*FFic+model->HICUMahc)))+1.0/here->HICUMvt*FFdVc_ditf); + if(model->HICUMlatb <= 0.0 && model->HICUMlatl <= 0.0) { + FFdQcfc = model->HICUMfthc*FFdQfhc; + FFdTcfc = model->HICUMfthc*FFdTfhc; + FFdQcfcT = FFdQcfc; + FFdTcfcT = FFdTcfc; + } else { + HICQFC(here,model,itf,I_CK,model->HICUMfthc*here->HICUMthcs_t,&FFdQcfc,&FFdQcfcT,&FFdTcfc,&FFdTcfcT); + } + FFdQbfc = (1-model->HICUMfthc)*FFdQfhc; + FFdTbfc = (1-model->HICUMfthc)*FFdTfhc; + *Q_fT = here->HICUMhf0_t* *Q_f+FFdQbfb+FFdQbfc+here->HICUMhfe_t*FFdQef+here->HICUMhfc_t*FFdQcfcT; + *T_fT = here->HICUMhf0_t*(*T_f)+FFdTbfb+FFdTbfc+here->HICUMhfe_t*FFdTef+here->HICUMhfc_t*FFdTcfcT; + *Q_f = *Q_f+(FFdQbfb+FFdQbfc)+FFdQef+FFdQcfc; + *T_f = *T_f+(FFdTbfb+FFdTbfc)+FFdTef+FFdTcfc; + *Q_bf = FFdQbfb+FFdQbfc; + } +} + + +// IDEAL DIODE (WITHOUT CAPACITANCE): +// conductance calculation not required +// INPUT: +// IS, IST : saturation currents (model parameter related) +// UM1 : ideality factor +// U : branch voltage +// IMPLICIT INPUT: +// vt : thermal voltage +// OUTPUT: +// Iz : diode current +void HICDIO(double vt, double IS, double IST, double UM1, double U, double *Iz, double *Gz) +{ +double DIOY, le, vtn; + vtn = UM1*vt; + DIOY = U/vtn; + if (IS > 0.0) { + if (DIOY > Dexp_lim) { + le = (1 + (DIOY - Dexp_lim)); + DIOY = Dexp_lim; + le = le*exp(DIOY); + *Iz = IST*(le-1.0); + *Gz = IST*exp(Dexp_lim)/vtn; + } else { + le = exp(DIOY); + *Iz = IST*(le-1.0); + *Gz = IST*le/vtn; + } + if(DIOY <= -14.0) { + *Iz = -IST; + *Gz = 0.0; + } + } else { + *Iz = 0.0; + *Gz = 0.0; + } +} + + +int hicum_thermal_update(HICUMmodel *, HICUMinstance *); + + +int +HICUMload(GENmodel *inModel, CKTcircuit *ckt) + /* actually load the current resistance value into the + * sparse matrix previously provided + */ +{ + HICUMmodel *model = (HICUMmodel*)inModel; + HICUMinstance *here; + + //Declaration of variables + + double cbcpar1,cbcpar2,cbepar2,cbepar1,Oich,Otbhrec; + + //Charges, capacitances and currents + double Qjci,Qjei,Qjep; + double Qdei,Qdci,Qrbi; + double it,ibei,irei,ibci,ibep,irep,ibh_rec; + double ibet,iavl; + double ijbcx,ijsc,Qjs,Qscp,HSUM,HSI_Tsu,Qdsu; + + //Base resistance and self-heating power + double rbi,pterm; + + //Model initialization + double C_1; + + //Model evaluation + double Crbi,Cjci,Cjcit,cc,Cjei,Cjep,CjCx_i,CjCx_ii,Cjs,Cscp; + double itf,itr,Tf,Tr,VT_f,i_0f,i_0r,a_bpt,Q_0,Q_p,Q_bpt; + double Orci0_t,b_q,I_Tf1,T_f0,Q_fT,T_fT,Q_bf; + double a_h,Q_pT,d_Q; + double Qf,Cdei,Qr,Cdci; + double ick,vc,cjcx01,cjcx02; + int l_it; + + //NQS +// double Ixf1,Ixf2,Qxf1,Qxf2; + double Itxf, Qdeix; +// double Vxf, Ixf, Qxf; + + double hjei_vbe; + + double Vbiei, Vbici, Vciei, Vbpei, Vbpbi, Vbpci, Vsici, Vbci, Vsc; + + double qjcx0_t_i, qjcx0_t_ii; + + //end of variables + + int iret; + +#ifndef PREDICTOR + double xfact; +#endif + double delvbiei=0.0, delvbici=0.0, delvbpei=0.0, delvbpbi=0.0, delvbpci=0.0, delvsici=0.0; + double ibieihat; + double ibpeihat; + double icieihat; + double ibicihat; + double ibpcihat; + double ibpbihat; + double isicihat; + double ibpsihat; + double ceq, geq=0.0, rhs_current; + int icheck=1; + int ichk1, ichk2, ichk3, ichk4, ichk5; + int error; + double Vbe, Vcic, Vbbp, Veie, Vsis, Vbpe; +// double Vbxf, Vbxf1, Vbxf2; + + double Ibiei, Ibiei_Vbiei; + double Ibici, Ibici_Vbici; + double Ibpei, Ibpei_Vbpei; + double Ibpci, Ibpci_Vbpci; + double Isici, Isici_Vsici; + double Isc, Isc_Vsc; + double Iciei, Iciei_Vbiei, Iciei_Vbici; + double Ibbp_Vbbp; + double Isis_Vsis; + double Ieie, Ieie_Veie; + double Ibpbi, Ibpbi_Vbpbi, Ibpbi_Vbici, Ibpbi_Vbiei; + double Ibpsi, Ibpsi_Vbpci, Ibpsi_Vsici; + double Icic_Vcic; + double Ibci, Ibci_Vbci; +// double Icxf, Icxf1, Icxf2, Ibxf, Ibxf1, Ibxf2; + double hjei_vbe_Vbiei, ibet_Vbpei, ibet_Vbiei, czz_Vbiei, czz_Vbpei; + double irei_Vbiei, irep_Vbpei, iavl_Vbici, itf_Vbiei, itr_Vbici, rbi_Vbiei, rbi_Vbici; + + double Qbepar1; + double Qbepar2; + double Qbcpar1; + double Qbcpar2; + double Qsu; + double Qcth; + + double Qrbi_Vbpbi; + double Qrbi_Vbiei; + double Qrbi_Vbici; + double Qdeix_Vbiei; + double Qjei_Vbiei; + double Qdci_Vbici; + double Qjci_Vbici; + double Qjep_Vbpei; + double qjcx0_t_i_Vbci; + double qjcx0_t_ii_Vbpci; + double Qdsu_Vbpci; + double Qjs_Vsici; + double Qscp_Vsc; + double Qbepar1_Vbe; + double Qbepar2_Vbpe; + double Qbcpar1_Vbci; + double Qbcpar2_Vbpci; + double Qsu_Vsis; + + double cqbepar1, gqbepar1; + double cqbepar2, gqbepar2; + double cqbcpar1, gqbcpar1; + double cqbcpar2, gqbcpar2; + double cqsu, gqsu; + + double Ith, Vrth, Icth, Icth_Vrth, delvrth; + + double Irth_Vrth; + double Iciei_Vrth; + double Ibiei_Vrth; + double Ibici_Vrth; + double Ibpei_Vrth; + double Ibpci_Vrth; + double Isici_Vrth; + double Ibpbi_Vrth; + double Ieie_Vrth; + double Icic_Vrth; + double Ibbp_Vrth; + + double Ith_Vrth; + double Ith_Vciei; + double Ith_Vbiei; + double Ith_Vbici; + double Ith_Vbpei; + double Ith_Vbpci; + double Ith_Vsici; + double Ith_Vbpbi; + double Ith_Veie; + double Ith_Vcic; + double Ith_Vbbp; + + /* loop through all the models */ + for( ; model != NULL; model = HICUMnextModel(model)) { + +// Model_initialization + + //Depletion capacitance splitting at b-c junction + //Capacitances at peripheral and external base node + C_1 = (1.0-model->HICUMfbcpar)*(model->HICUMcjcx0+model->HICUMcbcpar); + if (C_1 >= model->HICUMcbcpar) { + cbcpar1 = model->HICUMcbcpar; + cbcpar2 = 0.0; + cjcx01 = C_1-model->HICUMcbcpar; + cjcx02 = model->HICUMcjcx0-cjcx01; + } else { + cbcpar1 = C_1; + cbcpar2 = model->HICUMcbcpar-cbcpar1; + cjcx01 = 0.0; + cjcx02 = model->HICUMcjcx0; + } + + //Parasitic b-e capacitance partitioning: No temperature dependence + cbepar2 = model->HICUMfbepar*model->HICUMcbepar; + cbepar1 = model->HICUMcbepar-cbepar2; + + //Avoid divide-by-zero and define infinity other way + //High current correction for 2D and 3D effects + if (model->HICUMich != 0.0) { + Oich = 1.0/model->HICUMich; + } else { + Oich = 0.0; + } + + //Base current recombination time constant at b-c barrier + if (model->HICUMtbhrec != 0.0) { + Otbhrec = 1.0/model->HICUMtbhrec; + } else { + Otbhrec = 0.0; + } + +// end of Model_initialization + + /* loop through all the instances of the model */ + for (here = HICUMinstances(model); here != NULL ; + here=HICUMnextInstance(here)) { + + gqbepar1 = 0.0; + gqbepar2 = 0.0; + gqbcpar1 = 0.0; + gqbcpar2 = 0.0; + gqsu = 0.0; + Icth = 0.0, Icth_Vrth = 0.0; + +// SCALE = here->HICUMarea * here->HICUMm; + + /* + * initialization + */ + icheck=1; + if(ckt->CKTmode & MODEINITSMSIG) { + Vbiei = *(ckt->CKTstate0 + here->HICUMvbiei); + Vbici = *(ckt->CKTstate0 + here->HICUMvbici); + Vciei = Vbiei - Vbici; + Vbpei = *(ckt->CKTstate0 + here->HICUMvbpei); + Vbpci = *(ckt->CKTstate0 + here->HICUMvbpci); + Vbci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vsici = *(ckt->CKTstate0 + here->HICUMvsici); + Vsc = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsNode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + + Vbpbi = *(ckt->CKTstate0 + here->HICUMvbpbi); + Vbe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vcic = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMcollCINode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + Vbbp = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)); + Vbpe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Veie = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMemitEINode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vsis = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsSINode)- + *(ckt->CKTrhsOld+here->HICUMsubsNode)); +// Vbxf = *(ckt->CKTstate0 + here->HICUMvbxf); +// Vbxf1 = *(ckt->CKTstate0 + here->HICUMvbxf1); +// Vbxf2 = *(ckt->CKTstate0 + here->HICUMvbxf2); + if (model->HICUMflsh) + Vrth = *(ckt->CKTstate0 + here->HICUMvrth); + } else if(ckt->CKTmode & MODEINITTRAN) { + Vbiei = *(ckt->CKTstate1 + here->HICUMvbiei); + Vbici = *(ckt->CKTstate1 + here->HICUMvbici); + Vciei = Vbiei - Vbici; + Vbpei = *(ckt->CKTstate1 + here->HICUMvbpei); + Vbpci = *(ckt->CKTstate1 + here->HICUMvbpci); + Vbci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vsici = *(ckt->CKTstate1 + here->HICUMvsici); + Vsc = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsNode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + + Vbpbi = *(ckt->CKTstate1 + here->HICUMvbpbi); + Vbe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vcic = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMcollCINode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + Vbbp = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)); + Vbpe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Veie = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMemitEINode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vsis = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsSINode)- + *(ckt->CKTrhsOld+here->HICUMsubsNode)); +// Vbxf = *(ckt->CKTstate1 + here->HICUMvbxf); +// Vbxf1 = *(ckt->CKTstate1 + here->HICUMvbxf1); +// Vbxf2 = *(ckt->CKTstate1 + here->HICUMvbxf2); + if (model->HICUMflsh) + Vrth = *(ckt->CKTstate1 + here->HICUMvrth); + } else if((ckt->CKTmode & MODEINITJCT) && + (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ + Vbe=Vbiei=model->HICUMtype*here->HICUMicVBE; + Vciei=model->HICUMtype*here->HICUMicVCE; + Vbci=Vbici=Vbpci=Vbiei-Vciei; + Vbpei=0.0; + Vsc=Vsici=0.0; + Vbpbi=Vbbp=Vbpe=0.0; + Vcic=Veie=Vsis=0.0; + Vrth=0.0,Icth=0.0,Icth_Vrth=0.0; +// Vbxf=Vbxf1=Vbxf2=0.0; + } else if((ckt->CKTmode & MODEINITJCT) && (here->HICUMoff==0)) { + Vbe=Vbiei=model->HICUMtype*here->HICUMtVcrit; + Vciei=0.0; + Vbci=Vbici=Vbpci=0.0; + Vbpei=0.0; + Vsc=Vsici=0.0; + Vbpbi=Vbbp=Vbpe=0.0; + Vcic=Veie=Vsis=0.0; + Vrth=0.0,Icth=0.0,Icth_Vrth=0.0; +// Vbxf=Vbxf1=Vbxf2=0.0; + } else if((ckt->CKTmode & MODEINITJCT) || + ( (ckt->CKTmode & MODEINITFIX) && (here->HICUMoff!=0))) { + Vbe=0.0; + Vbiei=Vbe; + Vciei=0.0; + Vbci=Vbici=Vbpci=0.0; + Vbpei=0.0; + Vsc=Vsici=0.0; + Vbpbi=Vbbp=Vbpe=0.0; + Vcic=Veie=Vsis=0.0; + Vrth=0.0,Icth=0.0,Icth_Vrth=0.0; +// Vbxf=Vbxf1=Vbxf2=0.0; + } else { +#ifndef PREDICTOR + if(ckt->CKTmode & MODEINITPRED) { + xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; + Vbiei = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbiei)- + xfact * *(ckt->CKTstate2 + here->HICUMvbiei); + Vbici = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbici)- + xfact * *(ckt->CKTstate2 + here->HICUMvbici); + Vciei = Vbiei - Vbici; + Vbpei = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpei)- + xfact * *(ckt->CKTstate2 + here->HICUMvbpei); + Vbpci = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpci)- + xfact * *(ckt->CKTstate2 + here->HICUMvbpci); + Vsici = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvsici)- + xfact * *(ckt->CKTstate2 + here->HICUMvsici); + Vbpbi = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpbi)- + xfact * *(ckt->CKTstate2 + here->HICUMvbpbi); +// Vbxf = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbxf)- +// xfact * *(ckt->CKTstate2 + here->HICUMvbxf); +// Vbxf1 = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbxf1)- +// xfact * *(ckt->CKTstate2 + here->HICUMvbxf1); +// Vbxf2 = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbxf2)- +// xfact * *(ckt->CKTstate2 + here->HICUMvbxf2); + if (model->HICUMflsh) { + Vrth = (1.0 + xfact)* (*(ckt->CKTstate1 + here->HICUMvrth)) + - ( xfact * (*(ckt->CKTstate2 + here->HICUMvrth))); + } + *(ckt->CKTstate0 + here->HICUMvbiei) = + *(ckt->CKTstate1 + here->HICUMvbiei); + *(ckt->CKTstate0 + here->HICUMvbpei) = + *(ckt->CKTstate1 + here->HICUMvbpei); + *(ckt->CKTstate0 + here->HICUMvbici) = + *(ckt->CKTstate1 + here->HICUMvbici); + *(ckt->CKTstate0 + here->HICUMvbpei) = + *(ckt->CKTstate1 + here->HICUMvbpei); + *(ckt->CKTstate0 + here->HICUMvbpbi) = + *(ckt->CKTstate1 + here->HICUMvbpbi); + *(ckt->CKTstate0 + here->HICUMvsici) = + *(ckt->CKTstate1 + here->HICUMvsici); +// *(ckt->CKTstate0 + here->HICUMvbxf) = +// *(ckt->CKTstate1 + here->HICUMvbxf); +// *(ckt->CKTstate0 + here->HICUMvbxf1) = +// *(ckt->CKTstate1 + here->HICUMvbxf1); +// *(ckt->CKTstate0 + here->HICUMvbxf2) = +// *(ckt->CKTstate1 + here->HICUMvbxf2); + if (model->HICUMflsh) { + *(ckt->CKTstate0 + here->HICUMvrth) = + *(ckt->CKTstate1 + here->HICUMvrth); + } + *(ckt->CKTstate0 + here->HICUMibiei) = + *(ckt->CKTstate1 + here->HICUMibiei); + *(ckt->CKTstate0 + here->HICUMibiei_Vbiei) = + *(ckt->CKTstate1 + here->HICUMibiei_Vbiei); + *(ckt->CKTstate0 + here->HICUMibpei) = + *(ckt->CKTstate1 + here->HICUMibpei); + *(ckt->CKTstate0 + here->HICUMibpei_Vbpei) = + *(ckt->CKTstate1 + here->HICUMibpei_Vbpei); + *(ckt->CKTstate0 + here->HICUMiciei) = + *(ckt->CKTstate1 + here->HICUMiciei); + *(ckt->CKTstate0 + here->HICUMiciei_Vbiei) = + *(ckt->CKTstate1 + here->HICUMiciei_Vbiei); + *(ckt->CKTstate0 + here->HICUMiciei_Vbici) = + *(ckt->CKTstate1 + here->HICUMiciei_Vbici); + *(ckt->CKTstate0 + here->HICUMibici) = + *(ckt->CKTstate1 + here->HICUMibici); + *(ckt->CKTstate0 + here->HICUMibici_Vbici) = + *(ckt->CKTstate1 + here->HICUMibici_Vbici); + *(ckt->CKTstate0 + here->HICUMibpei) = + *(ckt->CKTstate1 + here->HICUMibpei); + *(ckt->CKTstate0 + here->HICUMibpbi) = + *(ckt->CKTstate1 + here->HICUMibpbi); + *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi) = + *(ckt->CKTstate1 + here->HICUMibpbi_Vbpbi); + *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei) = + *(ckt->CKTstate1 + here->HICUMibpbi_Vbiei); + *(ckt->CKTstate0 + here->HICUMibpbi_Vbici) = + *(ckt->CKTstate1 + here->HICUMibpbi_Vbici); + *(ckt->CKTstate0 + here->HICUMisici) = + *(ckt->CKTstate1 + here->HICUMisici); + *(ckt->CKTstate0 + here->HICUMisici_Vsici) = + *(ckt->CKTstate1 + here->HICUMisici_Vsici); + *(ckt->CKTstate0 + here->HICUMibpsi) = + *(ckt->CKTstate1 + here->HICUMibpsi); + *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci) = + *(ckt->CKTstate1 + here->HICUMibpsi_Vbpci); + *(ckt->CKTstate0 + here->HICUMibpsi_Vsici) = + *(ckt->CKTstate1 + here->HICUMibpsi_Vsici); + *(ckt->CKTstate0 + here->HICUMgqbepar1) = + *(ckt->CKTstate1 + here->HICUMgqbepar1); + *(ckt->CKTstate0 + here->HICUMgqbepar2) = + *(ckt->CKTstate1 + here->HICUMgqbepar2); + *(ckt->CKTstate0 + here->HICUMieie) = + *(ckt->CKTstate1 + here->HICUMieie); + *(ckt->CKTstate0 + here->HICUMisis_Vsis) = + *(ckt->CKTstate1 + here->HICUMisis_Vsis); + if (model->HICUMflsh) + *(ckt->CKTstate0 + here->HICUMqcth) = + *(ckt->CKTstate1 + here->HICUMqcth); + } else { +#endif /* PREDICTOR */ + /* + * compute new nonlinear branch voltages + */ + Vbiei = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBINode)- + *(ckt->CKTrhsOld+here->HICUMemitEINode)); + Vbici = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBINode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vbpei = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMemitEINode)); + Vbpbi = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMbaseBINode)); + Vbpci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vsici = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsSINode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); +// Vbxf = *(ckt->CKTrhsOld + here->HICUMxfNode); +// Vbxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node); +// Vbxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node); + Vciei = Vbiei - Vbici; + if (model->HICUMflsh) + Vrth = *(ckt->CKTrhsOld + here->HICUMtempNode); +#ifndef PREDICTOR + } +#endif /* PREDICTOR */ + delvbiei = Vbiei - *(ckt->CKTstate0 + here->HICUMvbiei); + delvbici = Vbici - *(ckt->CKTstate0 + here->HICUMvbici); + delvbpei = Vbpei - *(ckt->CKTstate0 + here->HICUMvbpei); + delvbpbi = Vbpbi - *(ckt->CKTstate0 + here->HICUMvbpbi); + delvbpci = Vbpci - *(ckt->CKTstate0 + here->HICUMvbpci); + delvsici = Vsici - *(ckt->CKTstate0 + here->HICUMvsici); + if (model->HICUMflsh) + delvrth = Vrth - *(ckt->CKTstate0 + here->HICUMvrth); + Vbe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vsc = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsNode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + Vcic = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMcollCINode)- + *(ckt->CKTrhsOld+here->HICUMcollNode)); + Vbci = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMcollCINode)); + Vbbp = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseNode)- + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)); + Vbpe = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMbaseBPNode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Veie = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMemitEINode)- + *(ckt->CKTrhsOld+here->HICUMemitNode)); + Vsis = model->HICUMtype*( + *(ckt->CKTrhsOld+here->HICUMsubsSINode)- + *(ckt->CKTrhsOld+here->HICUMsubsNode)); +// Vbxf = *(ckt->CKTrhsOld + here->HICUMxfNode); +// Vbxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node); +// Vbxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node); + if (model->HICUMflsh) + Vrth = *(ckt->CKTrhsOld + here->HICUMtempNode); + ibieihat = *(ckt->CKTstate0 + here->HICUMibiei) + + *(ckt->CKTstate0 + here->HICUMibiei_Vbiei)*delvbiei; + ibicihat = *(ckt->CKTstate0 + here->HICUMibici) + + *(ckt->CKTstate0 + here->HICUMibici_Vbici)*delvbici; + ibpeihat = *(ckt->CKTstate0 + here->HICUMibpei) + + *(ckt->CKTstate0 + here->HICUMibpei_Vbpei)*delvbpei; + ibpcihat = *(ckt->CKTstate0 + here->HICUMibpci) + + *(ckt->CKTstate0 + here->HICUMibpci_Vbpci)*delvbpci; + icieihat = *(ckt->CKTstate0 + here->HICUMiciei) + + *(ckt->CKTstate0 + here->HICUMiciei_Vbiei)*delvbiei + + *(ckt->CKTstate0 + here->HICUMiciei_Vbici)*delvbici; + ibpbihat = *(ckt->CKTstate0 + here->HICUMibpbi) + + *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi)*delvbpbi + + *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei)*delvbiei + + *(ckt->CKTstate0 + here->HICUMibpbi_Vbici)*delvbici; + isicihat = *(ckt->CKTstate0 + here->HICUMisici) + + *(ckt->CKTstate0 + here->HICUMisici_Vsici)*delvsici; + ibpsihat = *(ckt->CKTstate0 + here->HICUMibpsi) + + *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci)*delvbpci + + *(ckt->CKTstate0 + here->HICUMibpsi_Vsici)*delvsici; + /* + * 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. + * ... no bypass in case of selfheating + */ + if( (ckt->CKTbypass) && (!(ckt->CKTmode & MODEINITPRED)) && !model->HICUMflsh && + (fabs(delvbiei) < (ckt->CKTreltol*MAX(fabs(Vbiei), + fabs(*(ckt->CKTstate0 + here->HICUMvbiei)))+ + ckt->CKTvoltTol)) ) + if( (fabs(delvbici) < ckt->CKTreltol*MAX(fabs(Vbici), + fabs(*(ckt->CKTstate0 + here->HICUMvbici)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvbpei) < ckt->CKTreltol*MAX(fabs(Vbpei), + fabs(*(ckt->CKTstate0 + here->HICUMvbpei)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvbpbi) < ckt->CKTreltol*MAX(fabs(Vbpbi), + fabs(*(ckt->CKTstate0 + here->HICUMvbpbi)))+ + ckt->CKTvoltTol) ) + if( (fabs(delvsici) < ckt->CKTreltol*MAX(fabs(Vsici), + fabs(*(ckt->CKTstate0 + here->HICUMvsici)))+ + ckt->CKTvoltTol) ) + if( (fabs(ibieihat-*(ckt->CKTstate0 + here->HICUMibiei)) < + ckt->CKTreltol* MAX(fabs(ibieihat), + fabs(*(ckt->CKTstate0 + here->HICUMibiei)))+ + ckt->CKTabstol) ) + if( (fabs(ibpeihat-*(ckt->CKTstate0 + here->HICUMibpei)) < + ckt->CKTreltol* MAX(fabs(ibpeihat), + fabs(*(ckt->CKTstate0 + here->HICUMibpei)))+ + ckt->CKTabstol) ) + if( (fabs(icieihat-*(ckt->CKTstate0 + here->HICUMiciei)) < + ckt->CKTreltol* MAX(fabs(icieihat), + fabs(*(ckt->CKTstate0 + here->HICUMiciei)))+ + ckt->CKTabstol) ) + if( (fabs(ibicihat-*(ckt->CKTstate0 + here->HICUMibici)) < + ckt->CKTreltol* MAX(fabs(ibicihat), + fabs(*(ckt->CKTstate0 + here->HICUMibici)))+ + ckt->CKTabstol) ) + if( (fabs(ibpcihat-*(ckt->CKTstate0 + here->HICUMibpei)) < + ckt->CKTreltol* MAX(fabs(ibpcihat), + fabs(*(ckt->CKTstate0 + here->HICUMibpei)))+ + ckt->CKTabstol) ) + if( (fabs(ibpbihat-*(ckt->CKTstate0 + here->HICUMibpbi)) < + ckt->CKTreltol* MAX(fabs(ibpbihat), + fabs(*(ckt->CKTstate0 + here->HICUMibpbi)))+ + ckt->CKTabstol) ) + if( (fabs(isicihat-*(ckt->CKTstate0 + here->HICUMisici)) < + ckt->CKTreltol* MAX(fabs(isicihat), + fabs(*(ckt->CKTstate0 + here->HICUMisici)))+ + ckt->CKTabstol) ) + if( (fabs(ibpsihat-*(ckt->CKTstate0 + here->HICUMibpsi)) < + ckt->CKTreltol* MAX(fabs(ibpsihat), + fabs(*(ckt->CKTstate0 + here->HICUMibpsi)))+ + ckt->CKTabstol) ) { + /* + * bypassing.... + */ + Vbiei = *(ckt->CKTstate0 + here->HICUMvbiei); + Vbici = *(ckt->CKTstate0 + here->HICUMvbici); + Vbpei = *(ckt->CKTstate0 + here->HICUMvbpei); + Vbpbi = *(ckt->CKTstate0 + here->HICUMvbpbi); + Vbpci = *(ckt->CKTstate0 + here->HICUMvbpci); + Vsici = *(ckt->CKTstate0 + here->HICUMvsici); + + Ibiei = *(ckt->CKTstate0 + here->HICUMibiei); + Ibiei_Vbiei = *(ckt->CKTstate0 + here->HICUMibiei_Vbiei); + + Ibpei = *(ckt->CKTstate0 + here->HICUMibpei); + Ibpei_Vbpei = *(ckt->CKTstate0 + here->HICUMibpei_Vbpei); + + Iciei = *(ckt->CKTstate0 + here->HICUMiciei); + Iciei_Vbiei = *(ckt->CKTstate0 + here->HICUMiciei_Vbiei); + Iciei_Vbici = *(ckt->CKTstate0 + here->HICUMiciei_Vbici); + + Ibici = *(ckt->CKTstate0 + here->HICUMibici); + Ibici_Vbici = *(ckt->CKTstate0 + here->HICUMibici_Vbici); + + Ibpbi = *(ckt->CKTstate0 + here->HICUMibpbi); + Ibpbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi); + Ibpbi_Vbiei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei); + Ibpbi_Vbici = *(ckt->CKTstate0 + here->HICUMibpbi_Vbici); + + Isici = *(ckt->CKTstate0 + here->HICUMisici); + Isici_Vsici = *(ckt->CKTstate0 + here->HICUMisici_Vsici); + + Ibpsi = *(ckt->CKTstate0 + here->HICUMibpsi); + Ibpsi_Vbpci = *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci); + Ibpsi_Vsici = *(ckt->CKTstate0 + here->HICUMibpsi_Vsici); + + Ibpci = *(ckt->CKTstate0 + here->HICUMibpci); + Ibpci_Vbpci = *(ckt->CKTstate0 + here->HICUMibpci_Vbpci); + + Ieie = *(ckt->CKTstate0 + here->HICUMieie); + + Isis_Vsis = *(ckt->CKTstate0 + here->HICUMisis_Vsis); + + gqbepar1 = *(ckt->CKTstate0 + here->HICUMgqbepar1); + gqbepar2 = *(ckt->CKTstate0 + here->HICUMgqbepar2); + gqbcpar1 = *(ckt->CKTstate0 + here->HICUMgqbcpar1); + gqbcpar2 = *(ckt->CKTstate0 + here->HICUMgqbcpar2); + goto load; + } + /* + * limit nonlinear branch voltages + */ + ichk1 = 1, ichk2 = 1, ichk3 = 1, ichk4 = 1, ichk5 = 0; + Vbiei = DEVpnjlim(Vbiei,*(ckt->CKTstate0 + here->HICUMvbiei),here->HICUMvt, + here->HICUMtVcrit,&icheck); + Vbici = DEVpnjlim(Vbici,*(ckt->CKTstate0 + here->HICUMvbici),here->HICUMvt, + here->HICUMtVcrit,&ichk1); + Vbpei = DEVpnjlim(Vbpei,*(ckt->CKTstate0 + here->HICUMvbpei),here->HICUMvt, + here->HICUMtVcrit,&ichk2); + Vbpci = DEVpnjlim(Vbpci,*(ckt->CKTstate0 + here->HICUMvbpci),here->HICUMvt, + here->HICUMtVcrit,&ichk3); + Vsici = DEVpnjlim(Vsici,*(ckt->CKTstate0 + here->HICUMvsici),here->HICUMvt, + here->HICUMtVcrit,&ichk4); + if (model->HICUMflsh) { + ichk5 = 1; + Vrth = HICUMlimitlog(Vrth, + *(ckt->CKTstate0 + here->HICUMvrth),100,&ichk4); + } + if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1) || (ichk5 == 1)) icheck=1; + } + /* + * determine dc current and derivatives + */ +//todo: check for double multiplication on pnp's + Vbiei = model->HICUMtype*Vbiei; + Vbici = model->HICUMtype*Vbici; + Vciei = model->HICUMtype*Vciei; + Vbpei = model->HICUMtype*Vbpei; + Vbpci = model->HICUMtype*Vbpci; + Vbci = model->HICUMtype*Vbci; + Vsici = model->HICUMtype*Vsici; + Vsc = model->HICUMtype*Vsc; + if (model->HICUMflsh!=0 && model->HICUMrth >= MIN_R) { // Thermal_update_with_self_heating + + here->HICUMtemp = here->HICUMtemp+Vrth; + + iret = hicum_thermal_update(model, here); + } + // Model_evaluation + + //Intrinsic transistor + //Internal base currents across b-e junction + HICDIO(here->HICUMvt,model->HICUMibeis,here->HICUMibeis_t,model->HICUMmbei,Vbiei,&ibei,&Ibiei_Vbiei); + HICDIO(here->HICUMvt,model->HICUMireis,here->HICUMireis_t,model->HICUMmrei,Vbiei,&irei,&irei_Vbiei); + + //HICCR: begin + + //Inverse of low-field internal collector resistance: needed in HICICK + Orci0_t = 1.0/here->HICUMrci0_t; + + //Initialization + //Transfer current, minority charges and transit times + + Tr = model->HICUMtr; + VT_f = model->HICUMmcf*here->HICUMvt; + i_0f = here->HICUMc10_t * exp(Vbiei/VT_f); + i_0r = here->HICUMc10_t * exp(Vbici/here->HICUMvt); + + //Internal b-e and b-c junction capacitances and charges + //QJMODF(here->HICUMvt,cjei0_t,vdei_t,model->HICUMzei,ajei_t,V(br_biei),Qjei) + //Cjei = ddx(Qjei,V(bi)); + QJMODF(here->HICUMvt,here->HICUMcjei0_t,here->HICUMvdei_t,model->HICUMzei,here->HICUMajei_t,Vbiei,&Cjei,&Qjei); +//todo: hjei_vbe_Vbiei + if (model->HICUMahjei == 0.0) { + hjei_vbe = model->HICUMhjei; + hjei_vbe_Vbiei = 0.0; + } else { + double vj, vj_z; + //vendhjei = vdei_t*(1.0-exp(-log(ajei_t)/z_h)); + vj = (here->HICUMvdei_t-Vbiei)/(model->HICUMrhjei*here->HICUMvt); + vj = here->HICUMvdei_t-model->HICUMrhjei*here->HICUMvt*(vj+sqrt(vj*vj+DFa_fj))*0.5; + vj = (vj-here->HICUMvt)/here->HICUMvt; + vj = here->HICUMvt*(1.0+(vj+sqrt(vj*vj+DFa_fj))*0.5); + vj_z = (1.0-exp(model->HICUMzei*log(1.0-vj/here->HICUMvdei_t)))*here->HICUMahjei_t; + hjei_vbe = here->HICUMhjei0_t*(exp(vj_z)-1.0)/vj_z; + hjei_vbe_Vbiei = 0.0; + } + + //HICJQ(here->HICUMvt,cjci0_t,vdci_t,model->HICUMzci,vptci_t,V(br_bici),Qjci); + //Cjci = ddx(Qjci,V(bi)); + HICJQ(here->HICUMvt,here->HICUMcjci0_t,here->HICUMvdci_t,model->HICUMzci,here->HICUMvptci_t,Vbici,&Cjci,&Qjci); + + //Hole charge at low bias + a_bpt = 0.05; + Q_0 = here->HICUMqp0_t + hjei_vbe*Qjei + model->HICUMhjci*Qjci; + Q_bpt = a_bpt*here->HICUMqp0_t; + b_q = Q_0/Q_bpt-1; + Q_0 = Q_bpt*(1+(b_q +sqrt(b_q*b_q+1.921812))/2); + + //Transit time calculation at low current density + if(here->HICUMcjci0_t > 0.0) { // CJMODF + double cV_f,cv_e,cs_q,cs_q2,cv_j,cdvj_dv; + cV_f = here->HICUMvdci_t*(1.0-exp(-log(2.4)/model->HICUMzci)); + cv_e = (cV_f-Vbici)/here->HICUMvt; + cs_q = sqrt(cv_e*cv_e+1.921812); + cs_q2 = (cv_e+cs_q)*0.5; + cv_j = cV_f-here->HICUMvt*cs_q2; + cdvj_dv = cs_q2/cs_q; + Cjcit = here->HICUMcjci0_t*exp(-model->HICUMzci*log(1.0-cv_j/here->HICUMvdci_t))*cdvj_dv+2.4*here->HICUMcjci0_t*(1.0-cdvj_dv); + } else { + Cjcit = 0.0; + } + if(Cjcit > 0.0) { + cc = here->HICUMcjci0_t/Cjcit; + } else { + cc = 1.0; + } + T_f0 = here->HICUMt0_t+model->HICUMdt0h*(cc-1.0)+model->HICUMtbvl*(1/cc-1.0); + + //Effective collector voltage + vc = Vciei-here->HICUMvces_t; + + //Critical current for onset of high-current effects + { // HICICK + double Ovpt,a,d1,vceff,a1,a11,Odelck,ick1,ick2,ICKa; + Ovpt = 1.0/model->HICUMvpt; + a = vc/here->HICUMvt; + d1 = a-1; + vceff = (1.0+((d1+sqrt(d1*d1+1.921812))/2))*here->HICUMvt; + // a = vceff/vlim_t; + // ick = vceff*Orci0_t/sqrt(1.0+a*a); + // ICKa = (vceff-vlim_t)*Ovpt; + // ick = ick*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+1.0e-3))); + + a1 = vceff/here->HICUMvlim_t; + a11 = vceff*Orci0_t; + Odelck = 1/model->HICUMdelck; + ick1 = exp(Odelck*log(1+exp(model->HICUMdelck*log(a1)))); + ick2 = a11/ick1; + ICKa = (vceff-here->HICUMvlim_t)*Ovpt; + ick = ick2*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+model->HICUMaick))); + + } + + //Initial formulation of forward and reverse component of transfer current + Q_p = Q_0; + if (T_f0 > 0.0 || Tr > 0.0) { + double A; + A = 0.5*Q_0; + Q_p = A+sqrt(A*A+T_f0*i_0f+Tr*i_0r); + } + I_Tf1 =i_0f/Q_p; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_p; + + //Initial formulation of forward transit time, diffusion, GICCR and excess b-c charge + Q_bf = 0.0; + Tf = T_f0; + Qf = T_f0*itf; + HICQFF(here, model, itf,ick,&Tf,&Qf,&T_fT,&Q_fT,&Q_bf); + + //Initial formulation of reverse diffusion charge + Qr = Tr*itr; + + //Preparation for iteration to get total hole charge and related variables + l_it = 0; + if(Qf > RTOLC*Q_p || a_h > RTOLC) { + //Iteration for Q_pT is required for improved initial solution + Qf = sqrt(T_f0*itf*Q_fT); + Q_pT = Q_0+Qf+Qr; + d_Q = Q_pT; + while (fabs(d_Q) >= RTOLC*fabs(Q_pT) && l_it <= l_itmax) { + double a; +// d_Q0 = d_Q; + I_Tf1 = i_0f/Q_pT; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_pT; + Tf = T_f0; + Qf = T_f0*itf; + HICQFF(here, model, itf,ick,&Tf,&Qf,&T_fT,&Q_fT,&Q_bf); + Qr = Tr*itr; + if(Oich == 0.0) { + a = 1.0+(T_fT*itf+Qr)/Q_pT; + } else { + a = 1.0+(T_fT*I_Tf1*(1.0+2.0*a_h)+Qr)/Q_pT; + } + d_Q = -(Q_pT-(Q_0+Q_fT+Qr))/a; + //Limit maximum change of Q_pT + a = fabs(0.3*Q_pT); + if(fabs(d_Q) > a) { + if (d_Q>=0) { + d_Q = a; + } else { + d_Q = -a; + } + } + Q_pT = Q_pT+d_Q; + l_it = l_it+1; + } //while + + I_Tf1 = i_0f/Q_pT; + a_h = Oich*I_Tf1; + itf = I_Tf1*(1.0+a_h); + itr = i_0r/Q_pT; + + //Final transit times, charges and transport current components + Tf = T_f0; + Qf = T_f0*itf; + HICQFF(here, model, itf,ick,&Tf,&Qf,&T_fT,&Q_fT,&Q_bf); + Qr = Tr*itr; + + } //if + itf_Vbiei = itf/VT_f; + itr_Vbici = itr/here->HICUMvt; + + //NQS effect implemented with LCR networks + //Once the delay in ITF is considered, IT_NQS is calculated afterwards + + it = itf-itr; + + //Diffusion charges for further use + Qdei = Qf; + Qdci = Qr; + + + //High-frequency emitter current crowding (lateral NQS) + Cdei = T_f0*itf/here->HICUMvt; + Cdci = model->HICUMtr*itr/here->HICUMvt; + Crbi = model->HICUMfcrbi*(Cjei+Cjci+Cdei+Cdci); + Qrbi = Crbi*Vbpbi; + + // Qrbi = model->HICUMfcrbi*(Qjei+Qjci+Qdei+Qdci); + + //HICCR: } + + //Internal base current across b-c junction + HICDIO(here->HICUMvt,model->HICUMibcis,here->HICUMibcis_t,model->HICUMmbci,Vbici,&ibci,&Ibici_Vbici); + + //Avalanche current + if((Vbici < 0.0) && (here->HICUMfavl_t > 0.0) && (here->HICUMcjci0_t > 0.0)) { // HICAVL + double v_bord,v_q,U0,av,avl,avl_Vbici; + v_bord = here->HICUMvdci_t-Vbici; + v_q = here->HICUMqavl_t/Cjci; + U0 = here->HICUMqavl_t/here->HICUMcjci0_t; + if(v_bord > U0) { + av = here->HICUMfavl_t*exp(-v_q/U0); + avl = av*(U0+(1.0+v_q/U0)*(v_bord-U0)); + avl_Vbici = (-here->HICUMcjci0_t/Cjci-1)*here->HICUMfavl_t*exp(-here->HICUMcjci0_t/Cjci); + } else { + avl = here->HICUMfavl_t*v_bord*exp(-v_q/v_bord); + avl_Vbici = -(v_q*here->HICUMfavl_t*exp(-v_q/v_bord)/v_bord) - here->HICUMfavl_t*exp(-v_q/v_bord); + } + iavl = itf*avl; + iavl_Vbici = itf*avl_Vbici; + } else { + iavl = 0.0; + iavl_Vbici = 0.0; + } + + //Excess base current from recombination at the b-c barrier + ibh_rec = Q_bf*Otbhrec; + +//todo: Qf derivatives to Vbiei, Vbici + //Internal base resistance = f(Vbiei, Vbici) + if(here->HICUMrbi0_t > 0.0) { // HICRBI + double Qz_nom,f_QR,ETA,Qz0,fQz,ETA_Vbiei,ETA_Vbici, fQz_Vbiei,fQz_Vbici; + // Consideration of conductivity modulation + // To avoid convergence problem hyperbolic smoothing used + f_QR = (1+model->HICUMfdqr0)*here->HICUMqp0_t; + Qz0 = Qjei+Qjci+Qf; + Qz_nom = 1+Qz0/f_QR; + fQz = 0.5*(Qz_nom+sqrt(Qz_nom*Qz_nom+0.01)); + fQz_Vbiei=Cjei/f_QR; + fQz_Vbici=Cjci/f_QR; + rbi = here->HICUMrbi0_t/fQz; + rbi_Vbiei=-here->HICUMrbi0_t*fQz_Vbiei/(fQz*fQz); + rbi_Vbici=-here->HICUMrbi0_t*fQz_Vbici/(fQz*fQz); + // Consideration of emitter current crowding + if( ibei > 0.0) { + ETA = rbi*ibei*model->HICUMfgeo/here->HICUMvt; + ETA_Vbiei = (rbi*Ibiei_Vbiei+rbi_Vbiei*ibei)*model->HICUMfgeo/here->HICUMvt; + ETA_Vbici = rbi_Vbici*ibei*model->HICUMfgeo/here->HICUMvt; + if(ETA < 1.0e-6) { + rbi = rbi*(1.0-0.5*ETA); + rbi_Vbiei = rbi_Vbiei-0.5*(rbi*ETA_Vbiei+rbi_Vbiei*ETA); + rbi_Vbici = rbi_Vbici-0.5*(rbi*ETA_Vbici+rbi_Vbici*ETA); + } else { + rbi = rbi*log(1.0+ETA)/ETA; + rbi_Vbiei=log(ETA+1)*rbi_Vbiei/ETA - rbi*ETA_Vbiei*log(ETA+1)/ETA/ETA + rbi*ETA_Vbiei/(ETA*(ETA+1)); + rbi_Vbici=log(ETA+1)*rbi_Vbici/ETA - rbi*ETA_Vbici*log(ETA+1)/ETA/ETA + rbi*ETA_Vbici/(ETA*(ETA+1)); + } + } + // Consideration of peripheral charge + if(Qf > 0.0) { + rbi = rbi*(Qjei+Qf*model->HICUMfqi)/(Qjei+Qf); + rbi_Vbiei = (Qjei+Qf*model->HICUMfqi)*rbi_Vbiei/(Qjei+Qf) + rbi*Cjei/(Qjei+Qf) - (Qjei+Qf*model->HICUMfqi)*rbi*Cjei/(Qjei+Qf)/(Qjei+Qf); + rbi_Vbici = rbi_Vbici*(Qjei+Qf*model->HICUMfqi)/(Qjei+Qf); + } + } else { + rbi = 0.0; + rbi_Vbiei = 0.0; + rbi_Vbici = 0.0; + } + + //Base currents across peripheral b-e junction + HICDIO(here->HICUMvt,model->HICUMibeps,here->HICUMibeps_t,model->HICUMmbep,Vbpei,&ibep,&Ibpei_Vbpei); + HICDIO(here->HICUMvt,model->HICUMireps,here->HICUMireps_t,model->HICUMmrep,Vbpei,&irep,&irep_Vbpei); + + //Peripheral b-e junction capacitance and charge + QJMODF(here->HICUMvt,here->HICUMcjep0_t,here->HICUMvdep_t,model->HICUMzep,here->HICUMajep_t,Vbpei,&Cjep,&Qjep); + + //Tunneling current + if (model->HICUMibets > 0 && (Vbpei <0.0 || Vbiei < 0.0)) { // HICTUN + double pocce,czz; + if(model->HICUMtunode==1 && here->HICUMcjep0_t > 0.0 && here->HICUMvdep_t >0.0) { + pocce = exp((1-1/model->HICUMzep)*log(Cjep/here->HICUMcjep0_t)); + czz = -(Vbpei/here->HICUMvdep_t)*here->HICUMibets_t*pocce; + czz_Vbpei = -(1/here->HICUMvdep_t)*here->HICUMibets_t*pocce; + ibet = czz*exp(-here->HICUMabet_t/pocce); + ibet_Vbpei = czz_Vbpei*exp(-here->HICUMabet_t/pocce); + } else if (model->HICUMtunode==0 && here->HICUMcjei0_t > 0.0 && here->HICUMvdei_t >0.0) { + pocce = exp((1-1/model->HICUMzei)*log(Cjei/here->HICUMcjei0_t)); + czz = -(Vbiei/here->HICUMvdei_t)*here->HICUMibets_t*pocce; + czz_Vbiei = -(1/here->HICUMvdei_t)*here->HICUMibets_t*pocce; + ibet = czz*exp(-here->HICUMabet_t/pocce); + ibet_Vbiei = czz_Vbiei*exp(-here->HICUMabet_t/pocce); + } else { + ibet = 0.0; + ibet_Vbpei = 0.0; + ibet_Vbiei = 0.0; + } + } else { + ibet = 0.0; + ibet_Vbpei = 0.0; + ibet_Vbiei = 0.0; + } + + + //Base currents across peripheral b-c junction (bp,ci) + HICDIO(here->HICUMvt,model->HICUMibcxs,here->HICUMibcxs_t,model->HICUMmbcx,Vbpci,&ijbcx,&Ibpci_Vbpci); + + //Depletion capacitance and charge at external b-c junction (b,ci) + HICJQ(here->HICUMvt,here->HICUMcjcx01_t,here->HICUMvdcx_t,model->HICUMzcx,here->HICUMvptcx_t,Vbci,&CjCx_i,&qjcx0_t_i); + + //Depletion capacitance and charge at peripheral b-c junction (bp,ci) + HICJQ(here->HICUMvt,here->HICUMcjcx02_t,here->HICUMvdcx_t,model->HICUMzcx,here->HICUMvptcx_t,Vbpci,&CjCx_ii,&qjcx0_t_ii); + + //Depletion substrate capacitance and charge at inner s-c junction (si,ci) + HICJQ(here->HICUMvt,here->HICUMcjs0_t,here->HICUMvds_t,model->HICUMzs,here->HICUMvpts_t,Vsici,&Cjs,&Qjs); + /* Peripheral substrate capacitance and charge at s-c junction (s,c) + * Bias dependent only if model->HICUMvdsp > 0 + */ + if (model->HICUMvdsp > 0) { + HICJQ(here->HICUMvt,here->HICUMcscp0_t,here->HICUMvdsp_t,model->HICUMzsp,here->HICUMvptsp_t,Vsc,&Cscp,&Qscp); + } else { + // Constant, temperature independent capacitance + Cscp = model->HICUMcscp0; + Qscp = model->HICUMcscp0*Vsc; + } + + //Parasitic substrate transistor transfer current and diffusion charge + if(model->HICUMitss > 0.0) { // Sub_Transfer + double HSa,HSb; + HSUM = model->HICUMmsf*here->HICUMvt; + HSa = exp(Vbpci/HSUM); + HSb = exp(Vsici/HSUM); + HSI_Tsu = here->HICUMitss_t*(HSa-HSb); + Ibpsi_Vbpci = here->HICUMitss_t*HSa/HSUM; + Ibpsi_Vsici = -here->HICUMitss_t*HSb/HSUM; + if(model->HICUMtsf > 0.0) { + Qdsu = here->HICUMtsf_t*here->HICUMitss_t*HSa; + Qdsu_Vbpci = here->HICUMtsf_t*here->HICUMitss_t*HSa/HSUM; + } else { + Qdsu = 0.0; + Qdsu_Vbpci = 0.0; + } + } else { + HSI_Tsu = 0.0; + Ibpsi_Vbpci = 0.0; + Ibpsi_Vsici = 0.0; + Qdsu = 0.0; + Qdsu_Vbpci = 0.0; + } + + // Current gain computation for correlated noise implementation + if (ibei > 0.0) { + here->HICUMbetadc=it/ibei; + } else { + here->HICUMbetadc=0.0; + } + Ieie = Veie/here->HICUMre_t; // only needed for re flicker noise + + //Diode current for s-c junction (si,ci) + HICDIO(here->HICUMvt,model->HICUMiscs,here->HICUMiscs_t,model->HICUMmsc,Vsici,&ijsc,&Isici_Vsici); + + //Self-heating calculation + if (model->HICUMflsh == 1 && model->HICUMrth >= MIN_R) { + pterm = Vciei*it + (here->HICUMvdci_t-Vbici)*iavl; + } else if (model->HICUMflsh == 2 && model->HICUMrth >= MIN_R) { + pterm = Vciei*it + (here->HICUMvdci_t-Vbici)*iavl + ibei*Vbiei + ibci*Vbici + ibep*Vbpei + ijbcx*Vbpci + ijsc*Vsici; + if (rbi >= MIN_R) { + pterm = pterm + Vbpbi*Vbpbi/rbi; + } + if (here->HICUMre_t >= MIN_R) { + pterm = pterm + Veie*Veie/here->HICUMre_t; + } + if (here->HICUMrcx_t >= MIN_R) { + pterm = pterm + Vcic*Vcic/here->HICUMrcx_t; + } + if (here->HICUMrbx_t >= MIN_R) { + pterm = pterm + Vbbp*Vbbp/here->HICUMrbx_t; + } + } + + Itxf = itf; + Qdeix = Qdei; + + // Excess Phase calculation + +// if ((model->HICUMflnqs != 0 || model->HICUMflcomp == 0.0 || model->HICUMflcomp == 2.1) && Tf != 0 && (model->HICUMalit > 0 || model->HICUMalqf > 0)) { +// double Vxf1, Vxf2, fact; +// Vxf1 = Vbxf1; +// Vxf2 = Vbxf2; +// +// Ixf1 = (Vxf2-itf)/Tf*model->HICUMt0; +// Ixf2 = (Vxf2-Vxf1)/Tf*model->HICUMt0; +// Qxf1 = model->HICUMalit*Vxf1*model->HICUMt0; +// Qxf2 = model->HICUMalit*Vxf2/3*model->HICUMt0; +// Itxf = Vxf2; +// +// Vxf = Vbxf; //for RC nw +// fact = model->HICUMt0/Tf; //for RC nw +// Ixf = (Vxf - Qdei)*fact; //for RC nw +// Qxf = model->HICUMalqf*Vxf*model->HICUMt0; //for RC nw +// Qdeix = Vxf; //for RC nw +// } else { +// Ixf1 = Vbxf1; +// Ixf2 = Vbxf2; +// Qxf1 = 0; +// Qxf2 = 0; +// +// Ixf = Vbxf; +// Qxf = 0; +// } + + // end of Model_evaluation + + // Load_sources + +// Ibci += ddt(model->HICUMtype*qjcx0_t_i); +// Ibci += ddt(cbcpar1*Vbci); + +// Ibpci += ddt(cbcpar2*Vbpci); + +// Ibpbi += ddt(Qrbi); + + Ibpei = model->HICUMtype*ibep; + Ibpei += model->HICUMtype*irep; + Ibpei_Vbpei += model->HICUMtype*irep_Vbpei; +// Ibpei += ddt(model->HICUMtype*Qjep); + + Ibiei = model->HICUMtype*ibei; + Ibiei += model->HICUMtype*irei; + Ibiei_Vbiei += model->HICUMtype*irei_Vbiei; + Ibiei += model->HICUMtype*ibh_rec; +// Ibiei += ddt(model->HICUMtype*(Qdeix+Qjei)); + if (model->HICUMtunode==1.0) { + Ibpei += -model->HICUMtype*ibet; + Ibpei_Vbpei += -model->HICUMtype*ibet_Vbpei; + } else { + Ibiei += -model->HICUMtype*ibet; + Ibiei_Vbiei += -model->HICUMtype*ibet_Vbiei; + } + + Ibpsi = model->HICUMtype*HSI_Tsu; + + Ibpci = model->HICUMtype*ijbcx; +// Ibpci += ddt(model->HICUMtype*(qjcx0_t_ii+Qdsu)); + +// Ibe += ddt(cbepar1*Vbe); +// Ibpe += ddt(cbepar2*Vbpe); + + Ibici = model->HICUMtype*(ibci - iavl); + Ibici_Vbici = model->HICUMtype*(Ibici_Vbici - iavl_Vbici); +// Ibici += ddt(model->HICUMtype*(Qdci+Qjci)); + + Isici = model->HICUMtype*ijsc; +// Isici += ddt(model->HICUMtype*Qjs); + +// Isc += ddt(model->HICUMtype*Qscp); + + Iciei = model->HICUMtype*(Itxf - itr); + Iciei_Vbiei = model->HICUMtype*itf_Vbiei; + Iciei_Vbici = -model->HICUMtype*itr_Vbici; + +//printf("Vbiei: %f Vbici: %f Vciei: %f Vbpei: %f Vbpci: %f Vbci: %f Vsici: %f\n", Vbiei, Vbici, Vciei, Vbpei, Vbpci, Vbci, Vsici); +//printf("Ibiei: %g Ibici: %g Ibpei: %g Iciei: %g\n",Ibiei,Ibici,Ibpei,Iciei); +// Isis += ddt(model->HICUMcsu*Vsis); + + // Following code is an intermediate solution (if branch contribution is not supported): + // ****************************************** + //if(model->HICUMflsh == 0 || model->HICUMrth < MIN_R) { + // I[br_sht] <+ Vrth]/MIN_R; + //} else { + // I[br_sht] <+ Vrth]/rth_t-pterm; + // I[br_sht] <+ ddt(model->HICUMcth*Vrth]); + //} + + // ****************************************** + + // For simulators having no problem with Vrth) <+ 0.0 + // with external thermal node, following code may be used. + // Note that external thermal node should remain accessible + // even without self-heating. + // ******************************************** + Ith_Vbiei = 0.0; + Ith_Vbici = 0.0; + Ith_Vbpbi = 0.0; + Ith_Vbpci = 0.0; + Ith_Vbpei = 0.0; + Ith_Vciei = 0.0; + Ith_Vsici = 0.0; + Ith_Vcic = 0.0; + Ith_Vbbp = 0.0; + Ith_Veie = 0.0; + Ith_Vrth = 0.0; + if(model->HICUMflsh == 0 || model->HICUMrth < MIN_R) { + Ith = 0.0; + } else { + Ith = Vrth/here->HICUMrth_t-pterm; + if (model->HICUMflsh == 1 && model->HICUMrth >= MIN_R) { + Ith_Vciei = -it; + Ith_Vbici = iavl; + } else if (model->HICUMflsh == 2 && model->HICUMrth >= MIN_R) { + Ith_Vciei = -it; + Ith_Vbiei = -ibei; + Ith_Vbici = -ibci+iavl; + Ith_Vbpei = -ibep; + Ith_Vbpci = -ijbcx; + Ith_Vsici = -ijsc; + if (rbi >= MIN_R) { + Ith_Vbpbi = -Vbpbi*Vbpbi/rbi; + } + if (here->HICUMre_t >= MIN_R) { + Ith_Veie = -Veie*Veie/here->HICUMre_t; + } + if (here->HICUMrcx_t >= MIN_R) { + Ith_Vcic = -Vcic*Vcic/here->HICUMrcx_t; + } + if (here->HICUMrbx_t >= MIN_R) { + Ith_Vbbp = -Vbbp*Vbbp/here->HICUMrbx_t; + } + } +// Ith += ddt(model->HICUMcth*Vrth); + } + // ******************************************** + +// // NQS effect +// Ibxf1 = Ixf1; +//// Icxf1 += ddt(Qxf1); +// Ibxf2 = Ixf2; +//// Icxf2 += ddt(Qxf2); +// +// Ibxf = Ixf; //for RC nw +//// Icxf += ddt(Qxf); //for RC nw + + // end of Load_sources + + if (rbi >= MIN_R) { + Ibpbi_Vbpbi = 1 / rbi; + Ibpbi = Vbpbi / rbi; + } else { + Ibpbi_Vbpbi = 1 / MIN_R; + Ibpbi = Vbpbi / MIN_R; + } + Ibpbi_Vbiei = -Vbpbi * rbi_Vbiei / (rbi*rbi); + Ibpbi_Vbici = -Vbpbi * rbi_Vbici / (rbi*rbi); + + Ibbp_Vbbp = 1/here->HICUMrbx_t; + Icic_Vcic = 1/here->HICUMrcx_t; + Ieie_Veie = 1/here->HICUMre_t; + Isis_Vsis = 1/model->HICUMrsu; + + Qrbi_Vbpbi = Crbi; + Qrbi_Vbiei = 0.0; + Qrbi_Vbici = 0.0; + Qdeix_Vbiei = Cdei; + Qjei_Vbiei = Cjei; + Qdci_Vbici = Cdci; + Qjci_Vbici = Cjci; + Qjep_Vbpei = Cjep; + qjcx0_t_i_Vbci = CjCx_i; + qjcx0_t_ii_Vbpci = CjCx_ii; + Qjs_Vsici = Cjs; + Qscp_Vsc = Cscp; + Qbepar1_Vbe = cbepar1; + Qbepar2_Vbpe = cbepar2; + Qbcpar1_Vbci = cbcpar1; + Qbcpar2_Vbpci = cbcpar2; + Qsu_Vsis = model->HICUMcsu; + +//todo: all the derivatives have to be known dI/dT + Ibbp_Vrth = 0.0; + Ieie_Vrth = 0.0; + Icic_Vrth = 0.0; + Irth_Vrth = 0.0; + Ibici_Vrth = 0.0; + Ibpei_Vrth = 0.0; + Ibiei_Vrth = 0.0; + Ibpci_Vrth = 0.0; + Ibpbi_Vrth = 0.0; + Iciei_Vrth = 0.0; + Isici_Vrth = 0.0; + +//todo: what about dQ/dT ? + + Ibiei += ckt->CKTgmin*Vbiei; + Ibiei_Vbiei += ckt->CKTgmin; + Ibici += ckt->CKTgmin*Vbici; + Ibici_Vbici += ckt->CKTgmin; + Iciei += ckt->CKTgmin*Vciei; + Iciei_Vbiei += ckt->CKTgmin; + Iciei_Vbici += ckt->CKTgmin; + Ibpei += ckt->CKTgmin*Vbpei; + Ibpei_Vbpei += ckt->CKTgmin; + Ibpbi += ckt->CKTgmin*Vbpbi; + Ibpbi_Vbiei += ckt->CKTgmin; + Ibpbi_Vbici += ckt->CKTgmin; + Ibpci += ckt->CKTgmin*Vbpci; + Ibpci_Vbpci += ckt->CKTgmin; + Isici += ckt->CKTgmin*Vsici; + Isici_Vsici += ckt->CKTgmin; + + if( (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) || + (ckt->CKTmode & MODEINITSMSIG)) { + /* + * charge storage elements + */ + Qbepar1=cbepar1*Vbe; + Qbepar2=cbepar2*Vbpe; + Qbcpar1=cbcpar1*Vbci; + Qbcpar2=cbcpar2*Vbpci; + Qsu=model->HICUMcsu*Vsis; + Qcth=model->HICUMcth*Vrth; + + *(ckt->CKTstate0 + here->HICUMqrbi) = Qrbi; + *(ckt->CKTstate0 + here->HICUMqdeix) = Qdeix; + *(ckt->CKTstate0 + here->HICUMqjei) = Qjei; + *(ckt->CKTstate0 + here->HICUMqdci) = Qdci; + *(ckt->CKTstate0 + here->HICUMqjci) = Qjci; + *(ckt->CKTstate0 + here->HICUMqjep) = Qjep; + *(ckt->CKTstate0 + here->HICUMqjcx0_i) = qjcx0_t_i; + *(ckt->CKTstate0 + here->HICUMqjcx0_ii) = qjcx0_t_ii; + *(ckt->CKTstate0 + here->HICUMqdsu) = Qdsu; + *(ckt->CKTstate0 + here->HICUMqjs) = Qjs; + *(ckt->CKTstate0 + here->HICUMqscp) = Qscp; + *(ckt->CKTstate0 + here->HICUMqbepar1) = Qbepar1; + *(ckt->CKTstate0 + here->HICUMqbepar2) = Qbepar2; + *(ckt->CKTstate0 + here->HICUMqbcpar1) = Qbcpar1; + *(ckt->CKTstate0 + here->HICUMqbcpar2) = Qbcpar2; + *(ckt->CKTstate0 + here->HICUMqsu) = Qsu; + if (model->HICUMflsh) + *(ckt->CKTstate0 + here->HICUMqcth) = Qcth; + + here->HICUMcaprbi = Qrbi_Vbpbi; + here->HICUMcapdeix = Cdei; + here->HICUMcapjei = Cjei; + here->HICUMcapdci = Cdci; + here->HICUMcapjci = Cjci; + here->HICUMcapjep = Cjep; + here->HICUMcapjcx_t_i = CjCx_i; + here->HICUMcapjcx_t_ii = CjCx_ii; + here->HICUMcapdsu = Qdsu_Vbpci; + here->HICUMcapjs = Cjs; + here->HICUMcapscp = Cscp; + here->HICUMcapsu = model->HICUMcsu; + here->HICUMcapcth = model->HICUMcth; + + /* + * store small-signal parameters + */ + if ( (!(ckt->CKTmode & MODETRANOP))|| + (!(ckt->CKTmode & MODEUIC)) ) { + if(ckt->CKTmode & MODEINITSMSIG) { + *(ckt->CKTstate0 + here->HICUMcqrbi) = Qrbi_Vbpbi; + *(ckt->CKTstate0 + here->HICUMcqdeix) = Qdeix_Vbiei; + *(ckt->CKTstate0 + here->HICUMcqjei) = Qjei_Vbiei; + *(ckt->CKTstate0 + here->HICUMcqdci) = Qdci_Vbici; + *(ckt->CKTstate0 + here->HICUMcqjci) = Qjci_Vbici; + *(ckt->CKTstate0 + here->HICUMcqjep) = Qjep_Vbpei; + *(ckt->CKTstate0 + here->HICUMcqcx0_t_i) = qjcx0_t_i_Vbci; + *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) = qjcx0_t_ii_Vbpci; + *(ckt->CKTstate0 + here->HICUMcqdsu) = Qdsu_Vbpci; + *(ckt->CKTstate0 + here->HICUMcqjs) = Qjs_Vsici; + *(ckt->CKTstate0 + here->HICUMcqscp) = Qscp_Vsc; + *(ckt->CKTstate0 + here->HICUMcqbepar1) = Qbepar1_Vbe; + *(ckt->CKTstate0 + here->HICUMcqbepar2) = Qbepar2_Vbpe; + *(ckt->CKTstate0 + here->HICUMcqbcpar1) = Qbcpar1_Vbci; + *(ckt->CKTstate0 + here->HICUMcqbcpar2) = Qbcpar2_Vbpci; + *(ckt->CKTstate0 + here->HICUMcqsu) = Qsu_Vsis; + if (model->HICUMflsh) + *(ckt->CKTstate0 + here->HICUMcqcth) = model->HICUMcth; + continue; /* go to 1000 */ + } + /* + * transient analysis + */ + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HICUMqrbi) = + *(ckt->CKTstate0 + here->HICUMqrbi) ; + *(ckt->CKTstate1 + here->HICUMqjei) = + *(ckt->CKTstate0 + here->HICUMqjei) ; + *(ckt->CKTstate1 + here->HICUMqdeix) = + *(ckt->CKTstate0 + here->HICUMqdeix) ; + *(ckt->CKTstate1 + here->HICUMqjci) = + *(ckt->CKTstate0 + here->HICUMqjci) ; + *(ckt->CKTstate1 + here->HICUMqdci) = + *(ckt->CKTstate0 + here->HICUMqdci) ; + *(ckt->CKTstate1 + here->HICUMqjep) = + *(ckt->CKTstate0 + here->HICUMqjep) ; + *(ckt->CKTstate1 + here->HICUMqjcx0_i) = + *(ckt->CKTstate0 + here->HICUMqjcx0_i) ; + *(ckt->CKTstate1 + here->HICUMqjcx0_ii) = + *(ckt->CKTstate0 + here->HICUMqjcx0_ii) ; + *(ckt->CKTstate1 + here->HICUMqdsu) = + *(ckt->CKTstate0 + here->HICUMqdsu) ; + *(ckt->CKTstate1 + here->HICUMqjs) = + *(ckt->CKTstate0 + here->HICUMqjs) ; + *(ckt->CKTstate1 + here->HICUMqscp) = + *(ckt->CKTstate0 + here->HICUMqscp) ; + *(ckt->CKTstate1 + here->HICUMqbepar1) = + *(ckt->CKTstate0 + here->HICUMqbepar1) ; + *(ckt->CKTstate1 + here->HICUMqbepar2) = + *(ckt->CKTstate0 + here->HICUMqbepar2) ; + *(ckt->CKTstate1 + here->HICUMqbcpar1) = + *(ckt->CKTstate0 + here->HICUMqbcpar1) ; + *(ckt->CKTstate1 + here->HICUMqbcpar2) = + *(ckt->CKTstate0 + here->HICUMqbcpar2) ; + *(ckt->CKTstate1 + here->HICUMqsu) = + *(ckt->CKTstate0 + here->HICUMqsu) ; + if (model->HICUMflsh) + *(ckt->CKTstate1 + here->HICUMqcth) = + *(ckt->CKTstate0 + here->HICUMqcth) ; + } + error = NIintegrate(ckt,&geq,&ceq,Qrbi_Vbpbi,here->HICUMqrbi); + if(error) return(error); + Ibpbi_Vbpbi += geq; + Ibpbi += *(ckt->CKTstate0 + here->HICUMcqrbi); + + error = NIintegrate(ckt,&geq,&ceq,Cjei,here->HICUMqjei); + if(error) return(error); + Ibiei_Vbiei += geq; + Ibiei += *(ckt->CKTstate0 + here->HICUMcqjep); + + error = NIintegrate(ckt,&geq,&ceq,Cdei,here->HICUMqdeix); + if(error) return(error); + Ibiei_Vbiei += geq; + Ibiei += *(ckt->CKTstate0 + here->HICUMcqdeix); + + error = NIintegrate(ckt,&geq,&ceq,Cjci,here->HICUMqjci); + if(error) return(error); + Ibici_Vbici += geq; + Ibici += *(ckt->CKTstate0 + here->HICUMcqjci); + + error = NIintegrate(ckt,&geq,&ceq,Cdci,here->HICUMqdci); + if(error) return(error); + Ibici_Vbici += geq; + Ibici += *(ckt->CKTstate0 + here->HICUMcqdci); + + error = NIintegrate(ckt,&geq,&ceq,Cjep,here->HICUMqjep); + if(error) return(error); + Ibpei_Vbpei += geq; + Ibpei += *(ckt->CKTstate0 + here->HICUMcqjep); + + error = NIintegrate(ckt,&geq,&ceq,CjCx_ii,here->HICUMqjcx0_ii); + if(error) return(error); + Ibpci_Vbpci += geq; + Ibpci += *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii); + + error = NIintegrate(ckt,&geq,&ceq,Qdsu_Vbpci,here->HICUMqdsu); + if(error) return(error); + Ibpci_Vbpci += geq; + Ibpci += *(ckt->CKTstate0 + here->HICUMcqdsu); + + error = NIintegrate(ckt,&geq,&ceq,Cjs,here->HICUMqjs); + if(error) return(error); + Isici_Vsici += geq; + Isici += *(ckt->CKTstate0 + here->HICUMcqjs); + + error = NIintegrate(ckt,&geq,&ceq,CjCx_i,here->HICUMqjcx0_i); + if(error) return(error); + Ibci_Vbci = geq; + Ibci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i); + + error = NIintegrate(ckt,&geq,&ceq,Cscp,here->HICUMqscp); + if(error) return(error); + Isc_Vsc = geq; + Isc = *(ckt->CKTstate0 + here->HICUMcqscp); + + if (model->HICUMflsh) + { + error = NIintegrate(ckt,&geq,&ceq,model->HICUMcth,here->HICUMqcth); + if(error) return(error); + Icth_Vrth = geq; + Icth = *(ckt->CKTstate0 + here->HICUMcqcth); + } + + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HICUMcqrbi) = + *(ckt->CKTstate0 + here->HICUMcqrbi); + *(ckt->CKTstate1 + here->HICUMcqjei) = + *(ckt->CKTstate0 + here->HICUMcqjei); + *(ckt->CKTstate1 + here->HICUMcqdeix) = + *(ckt->CKTstate0 + here->HICUMcqdeix); + *(ckt->CKTstate1 + here->HICUMcqjci) = + *(ckt->CKTstate0 + here->HICUMcqjci); + *(ckt->CKTstate1 + here->HICUMcqdci) = + *(ckt->CKTstate0 + here->HICUMcqdci); + *(ckt->CKTstate1 + here->HICUMcqjep) = + *(ckt->CKTstate0 + here->HICUMcqjep); + *(ckt->CKTstate1 + here->HICUMcqcx0_t_i) = + *(ckt->CKTstate0 + here->HICUMcqcx0_t_i); + *(ckt->CKTstate1 + here->HICUMcqcx0_t_ii) = + *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii); + *(ckt->CKTstate1 + here->HICUMcqdsu) = + *(ckt->CKTstate0 + here->HICUMcqdsu); + *(ckt->CKTstate1 + here->HICUMcqjs) = + *(ckt->CKTstate0 + here->HICUMcqjs); + *(ckt->CKTstate1 + here->HICUMcqscp) = + *(ckt->CKTstate0 + here->HICUMcqscp); + if (model->HICUMflsh) + *(ckt->CKTstate1 + here->HICUMcqcth) = + *(ckt->CKTstate0 + here->HICUMcqcth); + } + } + } + + /* + * check convergence + */ + if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->HICUMoff))) { + if (icheck == 1) { + ckt->CKTnoncon++; + ckt->CKTtroubleElt = (GENinstance *) here; + } + } + + /* + * charge storage for outer junctions + */ + if(ckt->CKTmode & (MODETRAN | MODEAC)) { + error = NIintegrate(ckt,&gqbepar1,&cqbepar1,cbepar1,here->HICUMqbepar1); + if(error) return(error); + error = NIintegrate(ckt,&gqbepar2,&cqbepar2,cbepar2,here->HICUMqbepar2); + if(error) return(error); + error = NIintegrate(ckt,&gqbcpar1,&cqbcpar1,cbcpar1,here->HICUMqbcpar1); + if(error) return(error); + error = NIintegrate(ckt,&gqbcpar2,&cqbcpar2,cbcpar2,here->HICUMqbcpar2); + if(error) return(error); + error = NIintegrate(ckt,&gqsu,&cqsu,model->HICUMcsu,here->HICUMqsu); + if(error) return(error); +//tocheck: Currents and conductances must used in stamping below + if(ckt->CKTmode & MODEINITTRAN) { + *(ckt->CKTstate1 + here->HICUMcqbepar1) = + *(ckt->CKTstate0 + here->HICUMcqbepar1); + *(ckt->CKTstate1 + here->HICUMcqbepar2) = + *(ckt->CKTstate0 + here->HICUMcqbepar2); + *(ckt->CKTstate1 + here->HICUMcqbcpar1) = + *(ckt->CKTstate0 + here->HICUMcqbcpar1); + *(ckt->CKTstate1 + here->HICUMcqbcpar2) = + *(ckt->CKTstate0 + here->HICUMcqbcpar2); + *(ckt->CKTstate1 + here->HICUMcqsu) = + *(ckt->CKTstate0 + here->HICUMcqsu); + } + } + + *(ckt->CKTstate0 + here->HICUMvbiei) = Vbiei; + *(ckt->CKTstate0 + here->HICUMvbici) = Vbici; + *(ckt->CKTstate0 + here->HICUMvbpei) = Vbpei; + *(ckt->CKTstate0 + here->HICUMvbpbi) = Vbpbi; + *(ckt->CKTstate0 + here->HICUMvbpci) = Vbpci; + *(ckt->CKTstate0 + here->HICUMvsici) = Vsici; + + *(ckt->CKTstate0 + here->HICUMibiei) = Ibiei; + *(ckt->CKTstate0 + here->HICUMibiei_Vbiei) = Ibiei_Vbiei; + + *(ckt->CKTstate0 + here->HICUMibpei) = Ibpei; + *(ckt->CKTstate0 + here->HICUMibpei_Vbpei) = Ibpei_Vbpei; + + *(ckt->CKTstate0 + here->HICUMiciei) = Iciei; + *(ckt->CKTstate0 + here->HICUMiciei_Vbiei) = Iciei_Vbiei; + *(ckt->CKTstate0 + here->HICUMiciei_Vbici) = Iciei_Vbici; + + *(ckt->CKTstate0 + here->HICUMibici) = Ibici; + *(ckt->CKTstate0 + here->HICUMibici_Vbici) = Ibici_Vbici; + + *(ckt->CKTstate0 + here->HICUMibpbi) = Ibpbi; + *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi) = Ibpbi_Vbpbi; + *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei) = Ibpbi_Vbiei; + *(ckt->CKTstate0 + here->HICUMibpbi_Vbici) = Ibpbi_Vbici; + + *(ckt->CKTstate0 + here->HICUMibpci) = Ibpci; + *(ckt->CKTstate0 + here->HICUMibpci_Vbpci) = Ibpci_Vbpci; + + *(ckt->CKTstate0 + here->HICUMisici) = Isici; + *(ckt->CKTstate0 + here->HICUMisici_Vsici) = Isici_Vsici; + + *(ckt->CKTstate0 + here->HICUMibpsi) = Ibpsi; + *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci) = Ibpsi_Vbpci; + *(ckt->CKTstate0 + here->HICUMibpsi_Vsici) = Ibpsi_Vsici; + + *(ckt->CKTstate0 + here->HICUMisis_Vsis) = Isis_Vsis; + + *(ckt->CKTstate0 + here->HICUMieie) = Ieie; + + *(ckt->CKTstate0 + here->HICUMcqcth) = Icth; + *(ckt->CKTstate0 + here->HICUMicth_Vrth) = Icth_Vrth; + + *(ckt->CKTstate0 + here->HICUMgqbepar1) = gqbepar1; + *(ckt->CKTstate0 + here->HICUMgqbepar2) = gqbepar2; + + *(ckt->CKTstate0 + here->HICUMgqbcpar1) = gqbcpar1; + *(ckt->CKTstate0 + here->HICUMgqbcpar2) = gqbcpar2; + + *(ckt->CKTstate0 + here->HICUMgqsu) = gqsu; + +load: + /* + * load current excitation vector and matrix + */ +/* +c Branch: be, Stamp element: Cbepar1 +*/ + rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbepar1) - Vbe * gqbepar1); + *(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current; + *(here->HICUMbaseBasePtr) += gqbepar1; + *(here->HICUMemitEmitPtr) += gqbepar1; + *(ckt->CKTrhs + here->HICUMemitNode) += rhs_current; + *(here->HICUMbaseEmitPtr) += -gqbepar1; + *(here->HICUMemitBasePtr) += -gqbepar1; +/* +c Branch: bpe, Stamp element: Cbepar2 +*/ + rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbepar2) - Vbpe * gqbepar2); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPBaseBPPtr) += gqbepar2; + *(here->HICUMbaseBPEmitPtr) += gqbepar2; + *(ckt->CKTrhs + here->HICUMemitNode) += rhs_current; + *(here->HICUMemitBaseBPPtr) += -gqbepar2; + *(here->HICUMemitEmitPtr) += -gqbepar2; +/* +c Branch: bci, Stamp element: Cbcpar1 +*/ + rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbcpar1) - Vbci * gqbcpar1); + *(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current; + *(here->HICUMbaseBasePtr) += gqbcpar1; + *(here->HICUMcollCICollCIPtr) += gqbcpar1; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMbaseCollCIPtr) += -gqbcpar1; + *(here->HICUMcollCIBasePtr) += -gqbcpar1; +/* +c Branch: bpci, Stamp element: Cbcpar2 +*/ + rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbcpar2) - Vbpci * gqbcpar2); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPBaseBPPtr) += gqbcpar2; + *(here->HICUMcollCICollCIPtr) += gqbcpar2; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMbaseBPCollCIPtr) += -gqbcpar2; + *(here->HICUMcollCIBaseBPPtr) += -gqbcpar2; +/* +c Branch: ssi, Stamp element: Csu +*/ + rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqsu) - Vsis * gqsu); + *(ckt->CKTrhs + here->HICUMsubsNode) += -rhs_current; + *(here->HICUMsubsSubsPtr) += gqsu; + *(here->HICUMsubsSISubsSIPtr) += gqsu; + *(ckt->CKTrhs + here->HICUMsubsSINode) += rhs_current; + *(here->HICUMsubsSubsSIPtr) += -gqsu; + *(here->HICUMsubsSISubsPtr) += -gqsu; +/* +c Branch: biei, Stamp element: Ijbei +*/ + rhs_current = model->HICUMtype * (Ibiei - Ibiei_Vbiei*Vbiei); + *(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current; + *(here->HICUMbaseBIBaseBIPtr) += Ibiei_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += -Ibiei_Vbiei; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEIBaseBIPtr) += -Ibiei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Ibiei_Vbiei; +/* +c Branch: bpei, Stamp element: Ijbep +*/ + rhs_current = model->HICUMtype * (Ibpei - Ibpei_Vbpei*Vbpei); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPBaseBPPtr) += Ibpei_Vbpei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpei_Vbpei; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEIBaseBPPtr) += -Ibpei_Vbpei; + *(here->HICUMemitEIEmitEIPtr) += Ibpei_Vbpei; + +/* +c Branch: bici, Stamp element: Ijbci +*/ + rhs_current = model->HICUMtype * (Ibici - Ibici_Vbici*Vbici); + *(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current; + *(here->HICUMbaseBIBaseBIPtr) += Ibici_Vbici; + *(here->HICUMbaseBICollCIPtr) += -Ibici_Vbici; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCIBaseBIPtr) += -Ibici_Vbici; + *(here->HICUMcollCICollCIPtr) += Ibici_Vbici; +/* +c Branch: ciei, Stamp element: It +*/ + rhs_current = model->HICUMtype * (Iciei - Iciei_Vbiei*Vbiei - Iciei_Vbici*Vbici); + *(ckt->CKTrhs + here->HICUMcollCINode) += -rhs_current; + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbiei; + *(here->HICUMcollCIEmitEIPtr) += -Iciei_Vbiei; + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbici; + *(here->HICUMcollCICollCIPtr) += -Iciei_Vbici; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Iciei_Vbiei; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbici; + *(here->HICUMemitEICollCIPtr) += Iciei_Vbici; +/* +c Branch: bci, Stamp element: Qbcx +*/ + rhs_current = model->HICUMtype * (Ibci - Ibci_Vbci*Vbci); + *(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current; + *(here->HICUMbaseBasePtr) += Ibci_Vbci; + *(here->HICUMbaseCollCIPtr) += -Ibci_Vbci; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCIBasePtr) += -Ibci_Vbci; + *(here->HICUMcollCICollCIPtr) += Ibci_Vbci; +/* +c Branch: bpci, Stamp element: Ijbcx +*/ + rhs_current = model->HICUMtype * (Ibpci - Ibpci_Vbpci*Vbpci); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPCollCIPtr) += Ibpci_Vbpci; + *(here->HICUMbaseBPBaseBPPtr) += -Ibpci_Vbpci; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCIBaseBPPtr) += -Ibpci_Vbpci; + *(here->HICUMcollCICollCIPtr) += Ibpci_Vbpci; +/* +c Branch: cic, Stamp element: Rcx +*/ + *(here->HICUMcollCollPtr) += Icic_Vcic; + *(here->HICUMcollCICollCIPtr) += Icic_Vcic; + *(here->HICUMcollCICollPtr) += -Icic_Vcic; + *(here->HICUMcollCollCIPtr) += -Icic_Vcic; + +/* +c Branch: bbp, Stamp element: Rbx +*/ + *(here->HICUMbaseBasePtr) += Ibbp_Vbbp; + *(here->HICUMbaseBPBaseBPPtr) += Ibbp_Vbbp; + *(here->HICUMbaseBPBasePtr) += -Ibbp_Vbbp; + *(here->HICUMbaseBaseBPPtr) += -Ibbp_Vbbp; +/* +c Branch: eie, Stamp element: Re +*/ + *(here->HICUMemitEmitPtr) += Ieie_Veie; + *(here->HICUMemitEIEmitEIPtr) += Ieie_Veie; + *(here->HICUMemitEIEmitPtr) += -Ieie_Veie; + *(here->HICUMemitEmitEIPtr) += -Ieie_Veie; +/* +c Branch: bpbi, Stamp element: Rbi, Crbi +*/ + rhs_current = model->HICUMtype * (Ibpbi - Ibpbi_Vbpbi*Vbpbi - Ibpbi_Vbiei*Vbiei - Ibpbi_Vbici*Vbici); +//printf("Ibpbi_Vbpbi: %g Vbpbi: %f Ibpbi_Vbiei: %g Vbiei: %f Ibpbi_Vbici: %g Vbici: %f\n", Ibpbi_Vbpbi, Vbpbi, Ibpbi_Vbiei, Vbiei, Ibpbi_Vbici, Vbici); +//printf("Ibpbi: %g RHS: %g\n", Ibpbi, rhs_current); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPBaseBPPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBPCollCIPtr) += Ibpbi_Vbici; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vbici; + *(ckt->CKTrhs + here->HICUMbaseBINode) += rhs_current; + *(here->HICUMbaseBIBaseBPPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBICollCIPtr) += -Ibpbi_Vbici; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vbici; +/* +c Branch: sc, Stamp element: Cscp +*/ + rhs_current = model->HICUMtype * (Isc - Isc_Vsc*Vsc); + *(ckt->CKTrhs + here->HICUMsubsNode) += -rhs_current; + *(here->HICUMsubsSubsPtr) += Isc_Vsc; + *(here->HICUMsubsCollPtr) += Isc_Vsc; + *(ckt->CKTrhs + here->HICUMcollNode) += rhs_current; + *(here->HICUMcollSubsPtr) += -Isc_Vsc; + *(here->HICUMcollCollPtr) += -Isc_Vsc; +/* +c Branch: sici, Stamp element: Ijsc +*/ + rhs_current = model->HICUMtype * (Isici - Isici_Vsici*Vsici); + *(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current; + *(here->HICUMsubsSISubsSIPtr) += Isici_Vsici; + *(here->HICUMsubsSICollCIPtr) += -Isici_Vsici; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCISubsSIPtr) += -Isici_Vsici; + *(here->HICUMcollCICollCIPtr) += Isici_Vsici; +/* +c Branch: bpsi, Stamp element: Its +*/ + rhs_current = model->HICUMtype * (Ibpsi - Ibpsi_Vbpci*Vbpci - Ibpsi_Vsici*Vsici); + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPBaseBPPtr) += Ibpsi_Vbpci; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vbpci; + *(here->HICUMbaseBPSubsSIPtr) += Ibpsi_Vsici; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vsici; + *(ckt->CKTrhs + here->HICUMsubsSINode) += rhs_current; + *(here->HICUMsubsSIBaseBPPtr) += -Ibpsi_Vbpci; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vbpci; + *(here->HICUMsubsSISubsSIPtr) += -Ibpsi_Vsici; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vsici; +/* +c Branch: sis, Stamp element: Rsu +*/ + *(here->HICUMsubsSubsPtr) += Isis_Vsis; + *(here->HICUMsubsSISubsSIPtr) += Isis_Vsis; + *(here->HICUMsubsSISubsPtr) += -Isis_Vsis; + *(here->HICUMsubsSubsSIPtr) += -Isis_Vsis; + + if (model->HICUMflsh) { +/* +c Stamp element: Ibiei +*/ + rhs_current = -Ibiei_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current; + *(here->HICUMbaseBItempPtr) += Ibiei_Vrth; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEItempPtr) += -Ibiei_Vrth; +/* +c Stamp element: Ibici +*/ + rhs_current = -Ibici_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current; + *(here->HICUMbaseBItempPtr) += Ibici_Vrth; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCItempPtr) += -Ibici_Vrth; +/* +c Stamp element: Iciei +*/ + rhs_current = -Iciei_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMcollCINode) += -rhs_current; + *(here->HICUMcollCItempPtr) += Iciei_Vrth; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEItempPtr) += -Iciei_Vrth; +/* +c Stamp element: Ibpei +*/ + rhs_current = -Ibpei_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPtempPtr) += Ibpei_Vrth; + *(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current; + *(here->HICUMemitEItempPtr) += -Ibpei_Vrth; +/* +c Stamp element: Ibpci +*/ + rhs_current = -Ibpci_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPtempPtr) += Ibpci_Vrth; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCItempPtr) += -Ibpci_Vrth; +/* +c Stamp element: Isici +*/ + rhs_current = -Isici_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current; + *(here->HICUMsubsSItempPtr) += Isici_Vrth; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCItempPtr) += -Isici_Vrth; +/* +c Stamp element: Rbi +*/ + rhs_current = -Ibpbi_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current; + *(here->HICUMbaseBPtempPtr) += Ibpbi_Vrth; + *(ckt->CKTrhs + here->HICUMbaseBINode) += rhs_current; + *(here->HICUMbaseBItempPtr) += -Ibpbi_Vrth; +/* +c Stamp element: Isici +*/ + rhs_current = -Isici_Vrth*Vrth; + *(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current; + *(here->HICUMsubsSItempPtr) += Isici_Vrth; + *(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current; + *(here->HICUMcollCItempPtr) += -Isici_Vrth; +/* +c Stamp element: Rcx +*/ + *(here->HICUMcollTempPtr) += Icic_Vrth; +/* +c Stamp element: Rbx +*/ + *(here->HICUMbaseTempPtr) += Ibbp_Vrth; +/* +c Stamp element: Re +*/ + *(here->HICUMemitTempPtr) += Ieie_Vrth; +/* +c Stamp element: Rth +*/ + *(here->HICUMtempTempPtr) += Irth_Vrth; +/* +c Stamp element: Cth +*/ + *(here->HICUMtempTempPtr) += Icth_Vrth; +/* +c Stamp element: Ith +*/ + rhs_current = Ith + Icth - Icth_Vrth*Vrth + + Ith_Vbiei*Vbiei + Ith_Vbici*Vbici + Ith_Vciei*Vciei + + Ith_Vbpei*Vbpei + Ith_Vbpci*Vbpci + Ith_Vsici*Vsici + + Ith_Vbpbi*Vbpbi + + Ith_Vcic*Vcic + Ith_Vbbp*Vbbp + Ith_Veie*Veie; + + *(ckt->CKTrhs + here->HICUMtempNode) -= rhs_current; + + *(here->HICUMtempTempPtr) += -Ith_Vrth; + + *(here->HICUMtempBaseBIPtr) += -Ith_Vbiei; + *(here->HICUMtempEmitEIPtr) += +Ith_Vbiei; + + *(here->HICUMtempBaseBIPtr) += -Ith_Vbici; + *(here->HICUMtempCollCIPtr) += +Ith_Vbici; + + *(here->HICUMtempCollCIPtr) += -Ith_Vciei; + *(here->HICUMtempEmitEIPtr) += +Ith_Vciei; + + *(here->HICUMtempBaseBPPtr) += -Ith_Vbpei; + *(here->HICUMtempEmitEIPtr) += +Ith_Vbpei; + + *(here->HICUMtempBaseBPPtr) += -Ith_Vbpci; + *(here->HICUMtempCollCIPtr) += +Ith_Vbpci; + + *(here->HICUMtempSubsSIPtr) += -Ith_Vsici; + *(here->HICUMtempCollCIPtr) += +Ith_Vsici; + + *(here->HICUMtempBaseBPPtr) += -Ith_Vbpbi; + *(here->HICUMtempBaseBIPtr) += +Ith_Vbpbi; + + *(here->HICUMtempCollCIPtr) += +Ith_Vcic; + *(here->HICUMtempBaseBPPtr) += +Ith_Vbbp; + *(here->HICUMtempEmitEIPtr) += +Ith_Veie; + } + } + + } + return(OK); +} + diff --git a/src/spicelib/devices/hicum2/hicummask.c b/src/spicelib/devices/hicum2/hicummask.c new file mode 100644 index 000000000..b6269c067 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicummask.c @@ -0,0 +1,488 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Mathew Lew and Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/const.h" +#include "ngspice/ifsim.h" +#include "ngspice/cktdefs.h" +#include "ngspice/devdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +#define MIN_R 0.001 + +/*ARGSUSED*/ +int +HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) +{ + HICUMmodel *here = (HICUMmodel*)instPtr; + + NG_IGNORE(ckt); + + switch(which) { + +//Circuit simulator specific parameters + case HICUM_MOD_TYPE: + if (here->HICUMtype == NPN) + value->sValue = "npn"; + else + value->sValue = "pnp"; + return(OK); + case HICUM_MOD_TNOM: + value->rValue = here->HICUMtnom; + return(OK); + +//Transfer current + case HICUM_MOD_C10: + value->rValue = here->HICUMc10; + return(OK); + case HICUM_MOD_QP0: + value->rValue = here->HICUMqp0; + return(OK); + case HICUM_MOD_ICH: + value->rValue = here->HICUMich; + return(OK); + case HICUM_MOD_HF0: + value->rValue = here->HICUMhf0; + return(OK); + case HICUM_MOD_HFE: + value->rValue = here->HICUMhfe; + return(OK); + case HICUM_MOD_HFC: + value->rValue = here->HICUMhfc; + return(OK); + case HICUM_MOD_HJEI: + value->rValue = here->HICUMhjei; + return(OK); + case HICUM_MOD_AHJEI: + value->rValue = here->HICUMahjei; + return(OK); + case HICUM_MOD_RHJEI: + value->rValue = here->HICUMrhjei; + return(OK); + case HICUM_MOD_HJCI: + value->rValue = here->HICUMhjci; + return(OK); + +//Base-Emitter diode: + case HICUM_MOD_IBEIS: + value->rValue = here->HICUMibeis; + return(OK); + case HICUM_MOD_MBEI: + value->rValue = here->HICUMmbei; + return(OK); + case HICUM_MOD_IREIS: + value->rValue = here->HICUMireis; + return(OK); + case HICUM_MOD_MREI: + value->rValue = here->HICUMmrei; + return(OK); + case HICUM_MOD_IBEPS: + value->rValue = here->HICUMibeps; + return(OK); + case HICUM_MOD_MBEP: + value->rValue = here->HICUMmbep; + return(OK); + case HICUM_MOD_IREPS: + value->rValue = here->HICUMireps; + return(OK); + case HICUM_MOD_MREP: + value->rValue = here->HICUMmrep; + return(OK); + case HICUM_MOD_MCF: + value->rValue = here->HICUMmcf; + return(OK); + +//Transit time for excess recombination current at b-c barrier + case HICUM_MOD_TBHREC: + value->rValue = here->HICUMtbhrec; + return(OK); + +//Base-Collector diode currents + case HICUM_MOD_IBCIS: + value->rValue = here->HICUMibcis; + return(OK); + case HICUM_MOD_MBCI: + value->rValue = here->HICUMmbci; + return(OK); + case HICUM_MOD_IBCXS: + value->rValue = here->HICUMibcxs; + return(OK); + case HICUM_MOD_MBCX: + value->rValue = here->HICUMmbcx; + return(OK); + +//Base-Emitter tunneling current + case HICUM_MOD_IBETS: + value->rValue = here->HICUMibets; + return(OK); + case HICUM_MOD_ABET: + value->rValue = here->HICUMabet; + return(OK); + case HICUM_MOD_TUNODE: + value->rValue = here->HICUMtunode = value->iValue; + return(OK); + +//Base-Collector avalanche current + case HICUM_MOD_FAVL: + value->rValue = here->HICUMfavl; + return(OK); + case HICUM_MOD_QAVL: + value->rValue = here->HICUMqavl; + return(OK); + case HICUM_MOD_ALFAV: + value->rValue = here->HICUMalfav; + return(OK); + case HICUM_MOD_ALQAV: + value->rValue = here->HICUMalqav; + return(OK); + +//Series resistances + case HICUM_MOD_RBI0: + value->rValue = here->HICUMrbi0; + if (here->HICUMrbi0 < MIN_R) here->HICUMrbi0 = MIN_R; + return(OK); + case HICUM_MOD_RBX: + value->rValue = here->HICUMrbx; + if (here->HICUMrbx < MIN_R) here->HICUMrbx = MIN_R; + return(OK); + case HICUM_MOD_FGEO: + value->rValue = here->HICUMfgeo; + return(OK); + case HICUM_MOD_FDQR0: + value->rValue = here->HICUMfdqr0; + return(OK); + case HICUM_MOD_FCRBI: + value->rValue = here->HICUMfcrbi; + return(OK); + case HICUM_MOD_FQI: + value->rValue = here->HICUMfqi; + return(OK); + case HICUM_MOD_RE: + value->rValue = here->HICUMre; + if (here->HICUMre < MIN_R) here->HICUMre = MIN_R; + return(OK); + case HICUM_MOD_RCX: + value->rValue = here->HICUMrcx; + if (here->HICUMrcx < MIN_R) here->HICUMrcx = MIN_R; + return(OK); + +//Substrate transistor + case HICUM_MOD_ITSS: + value->rValue = here->HICUMitss; + return(OK); + case HICUM_MOD_MSF: + value->rValue = here->HICUMmsf; + return(OK); + case HICUM_MOD_ISCS: + value->rValue = here->HICUMiscs; + return(OK); + case HICUM_MOD_MSC: + value->rValue = here->HICUMmsc; + return(OK); + case HICUM_MOD_TSF: + value->rValue = here->HICUMtsf; + return(OK); + +//Intra-device substrate coupling + case HICUM_MOD_RSU: + value->rValue = here->HICUMrsu; + if (here->HICUMrsu < MIN_R) here->HICUMrsu = MIN_R; + return(OK); + case HICUM_MOD_CSU: + +//Depletion Capacitances + case HICUM_MOD_CJEI0: + value->rValue = here->HICUMcjei0; + return(OK); + case HICUM_MOD_VDEI: + value->rValue = here->HICUMvdei; + return(OK); + case HICUM_MOD_ZEI: + value->rValue = here->HICUMzei; + return(OK); + case HICUM_MOD_AJEI: + value->rValue = here->HICUMajei; + return(OK); + case HICUM_MOD_CJEP0: + value->rValue = here->HICUMcjep0; + return(OK); + case HICUM_MOD_VDEP: + value->rValue = here->HICUMvdep; + return(OK); + case HICUM_MOD_ZEP: + value->rValue = here->HICUMzep; + return(OK); + case HICUM_MOD_AJEP: + value->rValue = here->HICUMajep; + return(OK); + case HICUM_MOD_CJCI0: + value->rValue = here->HICUMcjci0; + return(OK); + case HICUM_MOD_VDCI: + value->rValue = here->HICUMvdci; + return(OK); + case HICUM_MOD_ZCI: + value->rValue = here->HICUMzci; + return(OK); + case HICUM_MOD_VPTCI: + value->rValue = here->HICUMvptci; + return(OK); + case HICUM_MOD_CJCX0: + value->rValue = here->HICUMcjcx0; + return(OK); + case HICUM_MOD_VDCX: + value->rValue = here->HICUMvdcx; + return(OK); + case HICUM_MOD_ZCX: + value->rValue = here->HICUMzcx; + return(OK); + case HICUM_MOD_VPTCX: + value->rValue = here->HICUMvptcx; + return(OK); + case HICUM_MOD_FBCPAR: + value->rValue = here->HICUMfbcpar; + return(OK); + case HICUM_MOD_FBEPAR: + value->rValue = here->HICUMfbepar; + return(OK); + case HICUM_MOD_CJS0: + value->rValue = here->HICUMcjs0; + return(OK); + case HICUM_MOD_VDS: + value->rValue = here->HICUMvds; + return(OK); + case HICUM_MOD_ZS: + value->rValue = here->HICUMzs; + return(OK); + case HICUM_MOD_VPTS: + value->rValue = here->HICUMvpts; + return(OK); + case HICUM_MOD_CSCP0: + value->rValue = here->HICUMcscp0; + return(OK); + case HICUM_MOD_VDSP: + value->rValue = here->HICUMvdsp; + return(OK); + case HICUM_MOD_ZSP: + value->rValue = here->HICUMzsp; + return(OK); + case HICUM_MOD_VPTSP: + value->rValue = here->HICUMvptsp; + return(OK); + +//Diffusion Capacitances + case HICUM_MOD_T0: + value->rValue = here->HICUMt0; + return(OK); + case HICUM_MOD_DT0H: + value->rValue = here->HICUMdt0h; + return(OK); + case HICUM_MOD_TBVL: + value->rValue = here->HICUMtbvl; + return(OK); + case HICUM_MOD_TEF0: + value->rValue = here->HICUMtef0; + return(OK); + case HICUM_MOD_GTFE: + value->rValue = here->HICUMgtfe; + return(OK); + case HICUM_MOD_THCS: + value->rValue = here->HICUMthcs; + return(OK); + case HICUM_MOD_AHC: + value->rValue = here->HICUMahc; + return(OK); + case HICUM_MOD_FTHC: + value->rValue = here->HICUMfthc; + return(OK); + case HICUM_MOD_RCI0: + value->rValue = here->HICUMrci0; + return(OK); + case HICUM_MOD_VLIM: + value->rValue = here->HICUMvlim; + return(OK); + case HICUM_MOD_VCES: + value->rValue = here->HICUMvces; + return(OK); + case HICUM_MOD_VPT: + value->rValue = here->HICUMvpt; + return(OK); + case HICUM_MOD_AICK: + value->rValue = here->HICUMaick; + return(OK); + case HICUM_MOD_DELCK: + value->rValue = here->HICUMdelck; + return(OK); + case HICUM_MOD_TR: + value->rValue = here->HICUMtr; + return(OK); + case HICUM_MOD_VCBAR: + value->rValue = here->HICUMvcbar; + return(OK); + case HICUM_MOD_ICBAR: + value->rValue = here->HICUMicbar; + return(OK); + case HICUM_MOD_ACBAR: + value->rValue = here->HICUMacbar; + return(OK); + +//Isolation Capacitances + case HICUM_MOD_CBEPAR: + value->rValue = here->HICUMcbepar; + return(OK); + case HICUM_MOD_CBCPAR: + value->rValue = here->HICUMcbcpar; + return(OK); + +//Non-quasi-static Effect + case HICUM_MOD_ALQF: + value->rValue = here->HICUMalqf; + return(OK); + case HICUM_MOD_ALIT: + value->rValue = here->HICUMalit; + return(OK); + case HICUM_MOD_FLNQS: + value->iValue = here->HICUMflnqs; + return(OK); + +//Noise + case HICUM_MOD_KF: + value->rValue = here->HICUMkf; + return(OK); + case HICUM_MOD_AF: + value->rValue = here->HICUMaf; + return(OK); + case HICUM_MOD_CFBE: + value->rValue = here->HICUMcfbe; + return(OK); + case HICUM_MOD_FLCONO: + value->iValue = here->HICUMflcono; + return(OK); + case HICUM_MOD_KFRE: + value->rValue = here->HICUMkfre; + return(OK); + case HICUM_MOD_AFRE: + value->rValue = here->HICUMafre; + return(OK); + +//Lateral Geometry Scaling (at high current densities) + case HICUM_MOD_LATB: + value->rValue = here->HICUMlatb; + return(OK); + case HICUM_MOD_LATL: + value->rValue = here->HICUMlatl; + return(OK); + +//Temperature dependence + case HICUM_MOD_VGB: + value->rValue = here->HICUMvgb; + return(OK); + case HICUM_MOD_ALT0: + value->rValue = here->HICUMalt0; + return(OK); + case HICUM_MOD_KT0: + value->rValue = here->HICUMkt0; + return(OK); + case HICUM_MOD_ZETACI: + value->rValue = here->HICUMzetaci; + return(OK); + case HICUM_MOD_ALVS: + value->rValue = here->HICUMalvs; + return(OK); + case HICUM_MOD_ALCES: + value->rValue = here->HICUMalces; + return(OK); + case HICUM_MOD_ZETARBI: + value->rValue = here->HICUMzetarbi; + return(OK); + case HICUM_MOD_ZETARBX: + value->rValue = here->HICUMzetarbx; + return(OK); + case HICUM_MOD_ZETARCX: + value->rValue = here->HICUMzetarcx; + return(OK); + case HICUM_MOD_ZETARE: + value->rValue = here->HICUMzetare; + return(OK); + case HICUM_MOD_ZETACX: + value->rValue = here->HICUMzetacx; + return(OK); + case HICUM_MOD_VGE: + value->rValue = here->HICUMvge; + return(OK); + case HICUM_MOD_VGC: + value->rValue = here->HICUMvgc; + return(OK); + case HICUM_MOD_VGS: + value->rValue = here->HICUMvgs; + return(OK); + case HICUM_MOD_F1VG: + value->rValue = here->HICUMf1vg; + return(OK); + case HICUM_MOD_F2VG: + value->rValue = here->HICUMf2vg; + return(OK); + case HICUM_MOD_ZETACT: + value->rValue = here->HICUMzetact; + return(OK); + case HICUM_MOD_ZETABET: + value->rValue = here->HICUMzetabet; + return(OK); + case HICUM_MOD_ALB: + value->rValue = here->HICUMalb; + return(OK); + case HICUM_MOD_DVGBE: + value->rValue = here->HICUMdvgbe; + return(OK); + case HICUM_MOD_ZETAHJEI: + value->rValue = here->HICUMzetahjei; + return(OK); + case HICUM_MOD_ZETAVGBE: + value->rValue = here->HICUMzetavgbe; + return(OK); + +//Self-Heating + case HICUM_MOD_FLSH: + value->iValue = here->HICUMflsh; + return(OK); + case HICUM_MOD_RTH: + value->rValue = here->HICUMrth; + return(OK); + case HICUM_MOD_ZETARTH: + value->rValue = here->HICUMzetarth; + return(OK); + case HICUM_MOD_ALRTH: + value->rValue = here->HICUMalrth; + return(OK); + case HICUM_MOD_CTH: + value->rValue = here->HICUMcth; + return(OK); + +//Compatibility with V2.1 + case HICUM_MOD_FLCOMP: + value->rValue = here->HICUMflcomp; + return(OK); + +//SOA-check + case HICUM_MOD_VBE_MAX: + value->rValue = here->HICUMvbeMax; + return(OK); + case HICUM_MOD_VBC_MAX: + value->rValue = here->HICUMvbcMax; + return(OK); + case HICUM_MOD_VCE_MAX: + value->rValue = here->HICUMvceMax; + return(OK); + + default: + return(E_BADPARM); + } + /* NOTREACHED */ +} + diff --git a/src/spicelib/devices/hicum2/hicummpar.c b/src/spicelib/devices/hicum2/hicummpar.c new file mode 100644 index 000000000..6896f5438 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicummpar.c @@ -0,0 +1,626 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine sets model parameters for + * HICUMs in the circuit. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/const.h" +#include "ngspice/ifsim.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +#define MIN_R 0.001 + +int +HICUMmParam(int param, IFvalue *value, GENmodel *inModel) +{ + HICUMmodel *model = (HICUMmodel*)inModel; + + switch(param) { + +//Circuit simulator specific parameters + + case HICUM_MOD_NPN: + if(value->iValue) { + model->HICUMtype = NPN; + } + break; + case HICUM_MOD_PNP: + if(value->iValue) { + model->HICUMtype = PNP; + } + break; + + case HICUM_MOD_TNOM: + model->HICUMtnom = value->rValue+CONSTCtoK; + model->HICUMtnomGiven = TRUE; + break; + +//Transfer current + case HICUM_MOD_C10: + model->HICUMc10 = value->rValue; + model->HICUMc10Given = TRUE; + break; + case HICUM_MOD_QP0: + model->HICUMqp0 = value->rValue; + model->HICUMqp0Given = TRUE; + break; + case HICUM_MOD_ICH: + model->HICUMich = value->rValue; + model->HICUMichGiven = TRUE; + break; + case HICUM_MOD_HF0: + model->HICUMhf0 = value->rValue; + model->HICUMhf0Given = TRUE; + break; + case HICUM_MOD_HFE: + model->HICUMhfe = value->rValue; + model->HICUMhfeGiven = TRUE; + break; + case HICUM_MOD_HFC: + model->HICUMhfc = value->rValue; + model->HICUMhfcGiven = TRUE; + break; + case HICUM_MOD_HJEI: + model->HICUMhjei = value->rValue; + model->HICUMhjeiGiven = TRUE; + break; + case HICUM_MOD_AHJEI: + model->HICUMahjei = value->rValue; + model->HICUMahjeiGiven = TRUE; + break; + case HICUM_MOD_RHJEI: + model->HICUMrhjei = value->rValue; + model->HICUMrhjeiGiven = TRUE; + break; + case HICUM_MOD_HJCI: + model->HICUMhjci = value->rValue; + model->HICUMhjciGiven = TRUE; + break; + +//Base-Emitter diode: + case HICUM_MOD_IBEIS: + model->HICUMibeis = value->rValue; + model->HICUMibeisGiven = TRUE; + break; + case HICUM_MOD_MBEI: + model->HICUMmbei = value->rValue; + model->HICUMmbeiGiven = TRUE; + break; + case HICUM_MOD_IREIS: + model->HICUMireis = value->rValue; + model->HICUMireisGiven = TRUE; + break; + case HICUM_MOD_MREI: + model->HICUMmrei = value->rValue; + model->HICUMmreiGiven = TRUE; + break; + case HICUM_MOD_IBEPS: + model->HICUMibeps = value->rValue; + model->HICUMibepsGiven = TRUE; + break; + case HICUM_MOD_MBEP: + model->HICUMmbep = value->rValue; + model->HICUMmbepGiven = TRUE; + break; + case HICUM_MOD_IREPS: + model->HICUMireps = value->rValue; + model->HICUMirepsGiven = TRUE; + break; + case HICUM_MOD_MREP: + model->HICUMmrep = value->rValue; + model->HICUMmrepGiven = TRUE; + break; + case HICUM_MOD_MCF: + model->HICUMmcf = value->rValue; + model->HICUMmcfGiven = TRUE; + break; + +//Transit time for excess recombination current at b-c barrier + case HICUM_MOD_TBHREC: + model->HICUMtbhrec = value->rValue; + model->HICUMtbhrecGiven = TRUE; + break; + +//Base-Collector diode currents + case HICUM_MOD_IBCIS: + model->HICUMibcis = value->rValue; + model->HICUMibcisGiven = TRUE; + break; + case HICUM_MOD_MBCI: + model->HICUMmbci = value->rValue; + model->HICUMmbciGiven = TRUE; + break; + case HICUM_MOD_IBCXS: + model->HICUMibcxs = value->rValue; + model->HICUMibcxsGiven = TRUE; + break; + case HICUM_MOD_MBCX: + model->HICUMmbcx = value->rValue; + model->HICUMmbcxGiven = TRUE; + break; + +//Base-Emitter tunneling current + case HICUM_MOD_IBETS: + model->HICUMibets = value->rValue; + model->HICUMibetsGiven = TRUE; + break; + case HICUM_MOD_ABET: + model->HICUMabet = value->rValue; + model->HICUMabetGiven = TRUE; + break; + case HICUM_MOD_TUNODE: + model->HICUMtunode = value->iValue; + model->HICUMtunodeGiven = TRUE; + break; + +//Base-Collector avalanche current + case HICUM_MOD_FAVL: + model->HICUMfavl = value->rValue; + model->HICUMfavlGiven = TRUE; + break; + case HICUM_MOD_QAVL: + model->HICUMqavl = value->rValue; + model->HICUMqavlGiven = TRUE; + break; + case HICUM_MOD_ALFAV: + model->HICUMalfav = value->rValue; + model->HICUMalfavGiven = TRUE; + break; + case HICUM_MOD_ALQAV: + model->HICUMalqav = value->rValue; + model->HICUMalqavGiven = TRUE; + break; + +//Series resistances + case HICUM_MOD_RBI0: + model->HICUMrbi0 = value->rValue; + if (model->HICUMrbi0 < MIN_R) model->HICUMrbi0 = MIN_R; + model->HICUMrbi0Given = TRUE; + break; + case HICUM_MOD_RBX: + model->HICUMrbx = value->rValue; + if (model->HICUMrbx < MIN_R) model->HICUMrbx = MIN_R; + model->HICUMrbxGiven = TRUE; + break; + case HICUM_MOD_FGEO: + model->HICUMfgeo = value->rValue; + model->HICUMfgeoGiven = TRUE; + break; + case HICUM_MOD_FDQR0: + model->HICUMfdqr0 = value->rValue; + model->HICUMfdqr0Given = TRUE; + break; + case HICUM_MOD_FCRBI: + model->HICUMfcrbi = value->rValue; + model->HICUMfcrbiGiven = TRUE; + break; + case HICUM_MOD_FQI: + model->HICUMfqi = value->rValue; + model->HICUMfqiGiven = TRUE; + break; + case HICUM_MOD_RE: + model->HICUMre = value->rValue; + if (model->HICUMre < MIN_R) model->HICUMre = MIN_R; + model->HICUMreGiven = TRUE; + break; + case HICUM_MOD_RCX: + model->HICUMrcx = value->rValue; + if (model->HICUMrcx < MIN_R) model->HICUMrcx = MIN_R; + model->HICUMrcxGiven = TRUE; + break; + +//Substrate transistor + case HICUM_MOD_ITSS: + model->HICUMitss = value->rValue; + model->HICUMitssGiven = TRUE; + break; + case HICUM_MOD_MSF: + model->HICUMmsf = value->rValue; + model->HICUMmsfGiven = TRUE; + break; + case HICUM_MOD_ISCS: + model->HICUMiscs = value->rValue; + model->HICUMiscsGiven = TRUE; + break; + case HICUM_MOD_MSC: + model->HICUMmsc = value->rValue; + model->HICUMmscGiven = TRUE; + break; + case HICUM_MOD_TSF: + model->HICUMtsf = value->rValue; + model->HICUMtsfGiven = TRUE; + break; + +//Intra-device substrate coupling + case HICUM_MOD_RSU: + model->HICUMrsu = value->rValue; + if (model->HICUMrsu < MIN_R) model->HICUMrsu = MIN_R; + model->HICUMrsuGiven = TRUE; + break; + case HICUM_MOD_CSU: + +//Depletion Capacitances + case HICUM_MOD_CJEI0: + model->HICUMcjei0 = value->rValue; + model->HICUMcjei0Given = TRUE; + break; + case HICUM_MOD_VDEI: + model->HICUMvdei = value->rValue; + model->HICUMvdeiGiven = TRUE; + break; + case HICUM_MOD_ZEI: + model->HICUMzei = value->rValue; + model->HICUMzeiGiven = TRUE; + break; + case HICUM_MOD_AJEI: + model->HICUMajei = value->rValue; + model->HICUMajeiGiven = TRUE; + break; + case HICUM_MOD_CJEP0: + model->HICUMcjep0 = value->rValue; + model->HICUMcjep0Given = TRUE; + break; + case HICUM_MOD_VDEP: + model->HICUMvdep = value->rValue; + model->HICUMvdepGiven = TRUE; + break; + case HICUM_MOD_ZEP: + model->HICUMzep = value->rValue; + model->HICUMzepGiven = TRUE; + break; + case HICUM_MOD_AJEP: + model->HICUMajep = value->rValue; + model->HICUMajepGiven = TRUE; + break; + case HICUM_MOD_CJCI0: + model->HICUMcjci0 = value->rValue; + model->HICUMcjci0Given = TRUE; + break; + case HICUM_MOD_VDCI: + model->HICUMvdci = value->rValue; + model->HICUMvdciGiven = TRUE; + break; + case HICUM_MOD_ZCI: + model->HICUMzci = value->rValue; + model->HICUMzciGiven = TRUE; + break; + case HICUM_MOD_VPTCI: + model->HICUMvptci = value->rValue; + model->HICUMvptciGiven = TRUE; + break; + case HICUM_MOD_CJCX0: + model->HICUMcjcx0 = value->rValue; + model->HICUMcjcx0Given = TRUE; + break; + case HICUM_MOD_VDCX: + model->HICUMvdcx = value->rValue; + model->HICUMvdcxGiven = TRUE; + break; + case HICUM_MOD_ZCX: + model->HICUMzcx = value->rValue; + model->HICUMzcxGiven = TRUE; + break; + case HICUM_MOD_VPTCX: + model->HICUMvptcx = value->rValue; + model->HICUMvptcxGiven = TRUE; + break; + case HICUM_MOD_FBCPAR: + model->HICUMfbcpar = value->rValue; + model->HICUMfbcparGiven = TRUE; + break; + case HICUM_MOD_FBEPAR: + model->HICUMfbepar = value->rValue; + model->HICUMfbeparGiven = TRUE; + break; + case HICUM_MOD_CJS0: + model->HICUMcjs0 = value->rValue; + model->HICUMcjs0Given = TRUE; + break; + case HICUM_MOD_VDS: + model->HICUMvds = value->rValue; + model->HICUMvdsGiven = TRUE; + break; + case HICUM_MOD_ZS: + model->HICUMzs = value->rValue; + model->HICUMzsGiven = TRUE; + break; + case HICUM_MOD_VPTS: + model->HICUMvpts = value->rValue; + model->HICUMvptsGiven = TRUE; + break; + case HICUM_MOD_CSCP0: + model->HICUMcscp0 = value->rValue; + model->HICUMcscp0Given = TRUE; + break; + case HICUM_MOD_VDSP: + model->HICUMvdsp = value->rValue; + model->HICUMvdspGiven = TRUE; + break; + case HICUM_MOD_ZSP: + model->HICUMzsp = value->rValue; + model->HICUMzspGiven = TRUE; + break; + case HICUM_MOD_VPTSP: + model->HICUMvptsp = value->rValue; + model->HICUMvptspGiven = TRUE; + break; + +//Diffusion Capacitances + case HICUM_MOD_T0: + model->HICUMt0 = value->rValue; + model->HICUMt0Given = TRUE; + break; + case HICUM_MOD_DT0H: + model->HICUMdt0h = value->rValue; + model->HICUMdt0hGiven = TRUE; + break; + case HICUM_MOD_TBVL: + model->HICUMtbvl = value->rValue; + model->HICUMtbvlGiven = TRUE; + break; + case HICUM_MOD_TEF0: + model->HICUMtef0 = value->rValue; + model->HICUMtef0Given = TRUE; + break; + case HICUM_MOD_GTFE: + model->HICUMgtfe = value->rValue; + model->HICUMgtfeGiven = TRUE; + break; + case HICUM_MOD_THCS: + model->HICUMthcs = value->rValue; + model->HICUMthcsGiven = TRUE; + break; + case HICUM_MOD_AHC: + model->HICUMahc = value->rValue; + model->HICUMahcGiven = TRUE; + break; + case HICUM_MOD_FTHC: + model->HICUMfthc = value->rValue; + model->HICUMfthcGiven = TRUE; + break; + case HICUM_MOD_RCI0: + model->HICUMrci0 = value->rValue; + model->HICUMrci0Given = TRUE; + break; + case HICUM_MOD_VLIM: + model->HICUMvlim = value->rValue; + model->HICUMvlimGiven = TRUE; + break; + case HICUM_MOD_VCES: + model->HICUMvces = value->rValue; + model->HICUMvcesGiven = TRUE; + break; + case HICUM_MOD_VPT: + model->HICUMvpt = value->rValue; + model->HICUMvptGiven = TRUE; + break; + case HICUM_MOD_AICK: + model->HICUMaick = value->rValue; + model->HICUMaickGiven = TRUE; + break; + case HICUM_MOD_DELCK: + model->HICUMdelck = value->rValue; + model->HICUMdelckGiven = TRUE; + break; + case HICUM_MOD_TR: + model->HICUMtr = value->rValue; + model->HICUMtrGiven = TRUE; + break; + case HICUM_MOD_VCBAR: + model->HICUMvcbar = value->rValue; + model->HICUMvcbarGiven = TRUE; + break; + case HICUM_MOD_ICBAR: + model->HICUMicbar = value->rValue; + model->HICUMicbarGiven = TRUE; + break; + case HICUM_MOD_ACBAR: + model->HICUMacbar = value->rValue; + model->HICUMacbarGiven = TRUE; + break; + +//Isolation Capacitances + case HICUM_MOD_CBEPAR: + model->HICUMcbepar = value->rValue; + model->HICUMcbeparGiven = TRUE; + break; + case HICUM_MOD_CBCPAR: + model->HICUMcbcpar = value->rValue; + model->HICUMcbcparGiven = TRUE; + break; + +//Non-quasi-static Effect + case HICUM_MOD_ALQF: + model->HICUMalqf = value->rValue; + model->HICUMalqfGiven = TRUE; + break; + case HICUM_MOD_ALIT: + model->HICUMalit = value->rValue; + model->HICUMalitGiven = TRUE; + break; + case HICUM_MOD_FLNQS: + model->HICUMflnqs = value->iValue; + model->HICUMflnqsGiven = TRUE; + break; + +//Noise + case HICUM_MOD_KF: + model->HICUMkf = value->rValue; + model->HICUMkfGiven = TRUE; + break; + case HICUM_MOD_AF: + model->HICUMaf = value->rValue; + model->HICUMafGiven = TRUE; + break; + case HICUM_MOD_CFBE: + model->HICUMcfbe = value->iValue; + model->HICUMcfbeGiven = TRUE; + break; + case HICUM_MOD_FLCONO: + model->HICUMflcono = value->iValue; + model->HICUMflconoGiven = TRUE; + break; + case HICUM_MOD_KFRE: + model->HICUMkfre = value->rValue; + model->HICUMkfreGiven = TRUE; + break; + case HICUM_MOD_AFRE: + model->HICUMafre = value->rValue; + model->HICUMafreGiven = TRUE; + break; + +//Lateral Geometry Scaling (at high current densities) + case HICUM_MOD_LATB: + model->HICUMlatb = value->rValue; + model->HICUMlatbGiven = TRUE; + break; + case HICUM_MOD_LATL: + model->HICUMlatl = value->rValue; + model->HICUMlatlGiven = TRUE; + break; + +//Temperature dependence + case HICUM_MOD_VGB: + model->HICUMvgb = value->rValue; + model->HICUMvgbGiven = TRUE; + break; + case HICUM_MOD_ALT0: + model->HICUMalt0 = value->rValue; + model->HICUMalt0Given = TRUE; + break; + case HICUM_MOD_KT0: + model->HICUMkt0 = value->rValue; + model->HICUMkt0Given = TRUE; + break; + case HICUM_MOD_ZETACI: + model->HICUMzetaci = value->rValue; + model->HICUMzetaciGiven = TRUE; + break; + case HICUM_MOD_ALVS: + model->HICUMalvs = value->rValue; + model->HICUMalvsGiven = TRUE; + break; + case HICUM_MOD_ALCES: + model->HICUMalces = value->rValue; + model->HICUMalcesGiven = TRUE; + break; + case HICUM_MOD_ZETARBI: + model->HICUMzetarbi = value->rValue; + model->HICUMzetarbiGiven = TRUE; + break; + case HICUM_MOD_ZETARBX: + model->HICUMzetarbx = value->rValue; + model->HICUMzetarbxGiven = TRUE; + break; + case HICUM_MOD_ZETARCX: + model->HICUMzetarcx = value->rValue; + model->HICUMzetarcxGiven = TRUE; + break; + case HICUM_MOD_ZETARE: + model->HICUMzetare = value->rValue; + model->HICUMzetareGiven = TRUE; + break; + case HICUM_MOD_ZETACX: + model->HICUMzetacx = value->rValue; + model->HICUMzetacxGiven = TRUE; + break; + case HICUM_MOD_VGE: + model->HICUMvge = value->rValue; + model->HICUMvgeGiven = TRUE; + break; + case HICUM_MOD_VGC: + model->HICUMvgc = value->rValue; + model->HICUMvgcGiven = TRUE; + break; + case HICUM_MOD_VGS: + model->HICUMvgs = value->rValue; + model->HICUMvgsGiven = TRUE; + break; + case HICUM_MOD_F1VG: + model->HICUMf1vg = value->rValue; + model->HICUMf1vgGiven = TRUE; + break; + case HICUM_MOD_F2VG: + model->HICUMf2vg = value->rValue; + model->HICUMf2vgGiven = TRUE; + break; + case HICUM_MOD_ZETACT: + model->HICUMzetact = value->rValue; + model->HICUMzetactGiven = TRUE; + break; + case HICUM_MOD_ZETABET: + model->HICUMzetabet = value->rValue; + model->HICUMzetabetGiven = TRUE; + break; + case HICUM_MOD_ALB: + model->HICUMalb = value->rValue; + model->HICUMalbGiven = TRUE; + break; + case HICUM_MOD_DVGBE: + model->HICUMdvgbe = value->rValue; + model->HICUMdvgbeGiven = TRUE; + break; + case HICUM_MOD_ZETAHJEI: + model->HICUMzetahjei = value->rValue; + model->HICUMzetahjeiGiven = TRUE; + break; + case HICUM_MOD_ZETAVGBE: + model->HICUMzetavgbe = value->rValue; + model->HICUMzetavgbeGiven = TRUE; + break; + +//Self-Heating + case HICUM_MOD_FLSH: + model->HICUMflsh = value->iValue; + model->HICUMflshGiven = TRUE; + break; + case HICUM_MOD_RTH: + model->HICUMrth = value->rValue; + model->HICUMrthGiven = TRUE; + break; + case HICUM_MOD_ZETARTH: + model->HICUMzetarth = value->rValue; + model->HICUMzetarthGiven = TRUE; + break; + case HICUM_MOD_ALRTH: + model->HICUMalrth = value->rValue; + model->HICUMalrthGiven = TRUE; + break; + case HICUM_MOD_CTH: + model->HICUMcth = value->rValue; + model->HICUMcthGiven = TRUE; + break; + +//Compatibility with V2.1 + case HICUM_MOD_FLCOMP: + model->HICUMflcomp = value->rValue; + model->HICUMflcompGiven = TRUE; + break; + +//SOA-check + case HICUM_MOD_VBE_MAX: + model->HICUMvbeMax = value->rValue; + model->HICUMvbeMaxGiven = TRUE; + break; + case HICUM_MOD_VBC_MAX: + model->HICUMvbcMax = value->rValue; + model->HICUMvbcMaxGiven = TRUE; + break; + case HICUM_MOD_VCE_MAX: + model->HICUMvceMax = value->rValue; + model->HICUMvceMaxGiven = TRUE; + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicumnoise.c b/src/spicelib/devices/hicum2/hicumnoise.c new file mode 100644 index 000000000..8e228b67a --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumnoise.c @@ -0,0 +1,252 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1987 Gary W. Ng +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "hicumdefs.h" +#include "ngspice/cktdefs.h" +#include "ngspice/iferrmsg.h" +#include "ngspice/noisedef.h" +#include "ngspice/suffix.h" + +/* + * HICUMnoise (mode, operation, firstModel, ckt, data, OnDens) + * + * This routine names and evaluates all of the noise sources + * associated with HICUM'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 HICUM's is summed with the variable "OnDens". + */ + + +int +HICUMnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, Ndata *data, double *OnDens) +{ + NOISEAN *job = (NOISEAN *) ckt->CKTcurJob; + + HICUMmodel *firstModel = (HICUMmodel *) genmodel; + HICUMmodel *model; + HICUMinstance *inst; + double tempOnoise; + double tempInoise; + double noizDens[HICUMNSRCS]; + double lnNdens[HICUMNSRCS]; + int i; + + double Ibbp_Vbbp; + double Icic_Vcic; + double Ieie_Veie; + double Isis_Vsis; + + /* define the names of the noise sources */ + + static char *HICUMnNames[HICUMNSRCS] = { + /* Note that we have to keep the order consistent with the + strchr definitions in HICUMdefs.h */ + "_rc", /* noise due to rc */ + "_rb", /* noise due to rb */ + "_rbi", /* noise due to rbi */ + "_re", /* noise due to re */ + "_rs", /* noise due to rs */ + "_ic", /* noise due to ic */ + "_ibc", /* noise due to ib */ + "_ibep", /* noise due to ibep */ + "_its", /* noise due to iccp */ + "_1overfbe", /* flicker (1/f) noise ibe */ + "_1overfbep", /* flicker (1/f) noise re */ + "" /* total transistor noise */ + }; + + for (model=firstModel; model != NULL; model=HICUMnextModel(model)) { + for (inst=HICUMinstances(model); inst != NULL; + inst=HICUMnextInstance(inst)) { + + Ibbp_Vbbp = 1/inst->HICUMrbx_t; + Icic_Vcic = 1/inst->HICUMrcx_t; + Ieie_Veie = 1/inst->HICUMre_t; + Isis_Vsis = 1/model->HICUMrsu; + + switch (operation) { + + case N_OPEN: + + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ + + if (job->NStpsSm != 0) { + switch (mode) { + + case N_DENS: + for (i=0; i < HICUMNSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_%s%s", inst->HICUMname, HICUMnNames[i]); + } + break; + + case INT_NOIZ: + for (i=0; i < HICUMNSRCS; i++) { + NOISE_ADD_OUTVAR(ckt, data, "onoise_total_%s%s", inst->HICUMname, HICUMnNames[i]); + NOISE_ADD_OUTVAR(ckt, data, "inoise_total_%s%s", inst->HICUMname, HICUMnNames[i]); + } + break; + } + } + break; + + case N_CALC: + switch (mode) { + + case N_DENS: + NevalSrc(&noizDens[HICUMRCNOIZ],&lnNdens[HICUMRCNOIZ], + ckt,THERMNOISE,inst->HICUMcollCINode,inst->HICUMcollNode, + Icic_Vcic); + + NevalSrc(&noizDens[HICUMRBNOIZ],&lnNdens[HICUMRBNOIZ], + ckt,THERMNOISE,inst->HICUMbaseBPNode,inst->HICUMbaseNode, + Ibbp_Vbbp); + + NevalSrc(&noizDens[HICUMRBINOIZ],&lnNdens[HICUMRBINOIZ], + ckt,THERMNOISE,inst->HICUMbaseBPNode,inst->HICUMbaseBINode, + *(ckt->CKTstate0 + inst->HICUMibpbi_Vbpbi)); + + NevalSrc(&noizDens[HICUMRENOIZ],&lnNdens[HICUMRENOIZ], + ckt,THERMNOISE,inst->HICUMemitEINode,inst->HICUMemitNode, + Ieie_Veie); + + NevalSrc(&noizDens[HICUMRSNOIZ],&lnNdens[HICUMRSNOIZ], + ckt,THERMNOISE,inst->HICUMsubsSINode,inst->HICUMsubsNode, + Isis_Vsis); + + + NevalSrc(&noizDens[HICUMICNOIZ],&lnNdens[HICUMICNOIZ], + ckt,SHOTNOISE,inst->HICUMcollCINode,inst->HICUMemitEINode, + *(ckt->CKTstate0 + inst->HICUMiciei)); + + NevalSrc(&noizDens[HICUMIBCNOIZ],&lnNdens[HICUMIBCNOIZ], + ckt,SHOTNOISE,inst->HICUMbaseBINode,inst->HICUMcollCINode, + *(ckt->CKTstate0 + inst->HICUMibici)); + + NevalSrc(&noizDens[HICUMIBEPNOIZ],&lnNdens[HICUMIBEPNOIZ], + ckt,SHOTNOISE,inst->HICUMbaseBPNode,inst->HICUMemitEINode, + *(ckt->CKTstate0 + inst->HICUMibpei)); + + NevalSrc(&noizDens[HICUMIBCXNOIZ],&lnNdens[HICUMIBCXNOIZ], + ckt,SHOTNOISE,inst->HICUMbaseBPNode,inst->HICUMcollCINode, + *(ckt->CKTstate0 + inst->HICUMibpci)); + + NevalSrc(&noizDens[HICUMITSNOIZ],&lnNdens[HICUMITSNOIZ], + ckt,SHOTNOISE,inst->HICUMsubsSINode,inst->HICUMcollCINode, + *(ckt->CKTstate0 + inst->HICUMisici)); + + + NevalSrc(&noizDens[HICUMFLBENOIZ], NULL, ckt, + N_GAIN,inst->HICUMbaseBINode, inst->HICUMemitEINode, + (double)0.0); + noizDens[HICUMFLBENOIZ] *= inst->HICUMm * model->HICUMkf * + exp(model->HICUMaf * + log(MAX(fabs((*(ckt->CKTstate0 + inst->HICUMibiei)+*(ckt->CKTstate0 + inst->HICUMibpei))/inst->HICUMm),N_MINLOG))) / + data->freq; + lnNdens[HICUMFLBENOIZ] = + log(MAX(noizDens[HICUMFLBENOIZ],N_MINLOG)); + + NevalSrc(&noizDens[HICUMFLRENOIZ], NULL, ckt, + N_GAIN,inst->HICUMemitNode, inst->HICUMemitEINode, + (double)0.0); + noizDens[HICUMFLRENOIZ] *= inst->HICUMm * model->HICUMkfre * + exp(model->HICUMafre * + log(MAX(fabs(*(ckt->CKTstate0 + inst->HICUMieie)/inst->HICUMm),N_MINLOG))) / + data->freq; + lnNdens[HICUMFLRENOIZ] = + log(MAX(noizDens[HICUMFLRENOIZ],N_MINLOG)); + + + noizDens[HICUMTOTNOIZ] = noizDens[HICUMRCNOIZ] + + noizDens[HICUMRBNOIZ] + + noizDens[HICUMRBINOIZ] + + noizDens[HICUMRENOIZ] + + noizDens[HICUMRSNOIZ] + + noizDens[HICUMICNOIZ] + + noizDens[HICUMIBCNOIZ] + + noizDens[HICUMIBEPNOIZ] + + noizDens[HICUMIBCXNOIZ] + + noizDens[HICUMITSNOIZ] + + noizDens[HICUMFLBENOIZ] + + noizDens[HICUMFLRENOIZ]; + + + lnNdens[HICUMTOTNOIZ] = + log(noizDens[HICUMTOTNOIZ]); + + *OnDens += noizDens[HICUMTOTNOIZ]; + + if (data->delFreq == 0.0) { + + /* if we haven't done any previous integration, we need to */ + /* initialize our "history" variables */ + + for (i=0; i < HICUMNSRCS; i++) { + inst->HICUMnVar[LNLSTDENS][i] = lnNdens[i]; + } + + /* clear out our integration variables if it's the first pass */ + + if (data->freq == job->NstartFreq) { + for (i=0; i < HICUMNSRCS; i++) { + inst->HICUMnVar[OUTNOIZ][i] = 0.0; + inst->HICUMnVar[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 < HICUMNSRCS; i++) { + if (i != HICUMTOTNOIZ) { + tempOnoise = Nintegrate(noizDens[i], lnNdens[i], + inst->HICUMnVar[LNLSTDENS][i], data); + tempInoise = Nintegrate(noizDens[i] * data->GainSqInv , + lnNdens[i] + data->lnGainInv, + inst->HICUMnVar[LNLSTDENS][i] + data->lnGainInv, + data); + inst->HICUMnVar[LNLSTDENS][i] = lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (job->NStpsSm != 0) { + inst->HICUMnVar[OUTNOIZ][i] += tempOnoise; + inst->HICUMnVar[OUTNOIZ][HICUMTOTNOIZ] += tempOnoise; + inst->HICUMnVar[INNOIZ][i] += tempInoise; + inst->HICUMnVar[INNOIZ][HICUMTOTNOIZ] += tempInoise; + } + } + } + } + if (data->prtSummary) { + for (i=0; i < HICUMNSRCS; i++) { /* print a summary report */ + data->outpVector[data->outNumber++] = noizDens[i]; + } + } + break; + + case INT_NOIZ: /* already calculated, just output */ + if (job->NStpsSm != 0) { + for (i=0; i < HICUMNSRCS; i++) { + data->outpVector[data->outNumber++] = inst->HICUMnVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] = inst->HICUMnVar[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/hicum2/hicumparam.c b/src/spicelib/devices/hicum2/hicumparam.c new file mode 100644 index 000000000..2b1a17dda --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumparam.c @@ -0,0 +1,74 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine sets instance parameters for + * HICUMs in the circuit. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/const.h" +#include "ngspice/ifsim.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +/* ARGSUSED */ +int +HICUMparam(int param, IFvalue *value, GENinstance *instPtr, IFvalue *select) +{ + HICUMinstance *here = (HICUMinstance*)instPtr; + + NG_IGNORE(select); + + switch(param) { + case HICUM_AREA: + here->HICUMarea = value->rValue; + here->HICUMareaGiven = TRUE; + break; + case HICUM_OFF: + here->HICUMoff = (value->iValue != 0); + break; + case HICUM_IC_VBE: + here->HICUMicVBE = value->rValue; + here->HICUMicVBEGiven = TRUE; + break; + case HICUM_IC_VCE: + here->HICUMicVCE = value->rValue; + here->HICUMicVCEGiven = TRUE; + break; + case HICUM_TEMP: + here->HICUMtemp = value->rValue+CONSTCtoK; + here->HICUMtempGiven = TRUE; + break; + case HICUM_DTEMP: + here->HICUMdtemp = value->rValue; + here->HICUMdtempGiven = TRUE; + break; + case HICUM_M: + here->HICUMm = value->rValue; + here->HICUMmGiven = TRUE; + break; + case HICUM_IC : + switch(value->v.numValue) { + case 2: + here->HICUMicVCE = *(value->v.vec.rVec+1); + here->HICUMicVCEGiven = TRUE; + case 1: + here->HICUMicVBE = *(value->v.vec.rVec); + here->HICUMicVBEGiven = TRUE; + break; + default: + return(E_BADPARM); + } + break; + default: + return(E_BADPARM); + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicumpzld.c b/src/spicelib/devices/hicum2/hicumpzld.c new file mode 100644 index 000000000..fc6c38082 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumpzld.c @@ -0,0 +1,392 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * Function to load the COMPLEX circuit matrix using the + * small signal parameters saved during a previous DC operating + * point analysis. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + +int +HICUMpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) +{ + HICUMinstance *here; + HICUMmodel *model = (HICUMmodel*)inModel; + double Ibpei_Vbpei; + double Ibiei_Vbiei; + double Ibici_Vbici; + double Ibpci_Vbpci; + double Isici_Vsici; + double Iciei_Vbiei; + double Iciei_Vbici; + double Ibbp_Vbbp; + double Isis_Vsis; + double Ieie_Veie; + double Ibpbi_Vbpbi, Ibpbi_Vciei, Ibpbi_Vbiei; + double Ibpsi_Vbpci, Ibpsi_Vsici; + double Icic_Vcic; + + double XQrbi_Vbpbi; +// double XQrbi_Vbiei; +// double XQrbi_Vbici; + double XQdeix_Vbiei; + double XQjei_Vbiei; + double XQdci_Vbici; + double XQjci_Vbici; + double XQjep_Vbpei; + double Xqjcx0_t_i_Vbci; + double Xqjcx0_t_ii_Vbpci; + double XQdsu_Vbpci; +// double XQdsu_Vsici; + double XQjs_Vsici; + double XQscp_Vsc; + double XQbepar1_Vbe; + double XQbepar2_Vbpe; + double XQbcpar1_Vbci; + double XQbcpar2_Vbpci; + double XQsu_Vsis; + + /* loop through all the models */ + for( ; model != NULL; model = HICUMnextModel(model)) { + + /* loop through all the instances of the model */ + for( here = HICUMinstances(model); here!= NULL; + here = HICUMnextInstance(here)) { + + Ibbp_Vbbp = 1/here->HICUMrbx_t; + Icic_Vcic = 1/here->HICUMrcx_t; + Ieie_Veie = 1/here->HICUMre_t; + Isis_Vsis = 1/model->HICUMrsu; + + Ibiei_Vbiei = *(ckt->CKTstate0 + here->HICUMibiei_Vbiei); + Ibpei_Vbpei = *(ckt->CKTstate0 + here->HICUMibpei_Vbpei); + Iciei_Vbiei = *(ckt->CKTstate0 + here->HICUMiciei_Vbiei); + Iciei_Vbici = *(ckt->CKTstate0 + here->HICUMiciei_Vbici); + Ibici_Vbici = *(ckt->CKTstate0 + here->HICUMibici_Vbici); + Ibpbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi); + Ibpbi_Vbiei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei); + Ibpbi_Vciei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbici); + Isici_Vsici = *(ckt->CKTstate0 + here->HICUMisici_Vsici); + Ibpsi_Vbpci = *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci); + Ibpsi_Vsici = *(ckt->CKTstate0 + here->HICUMibpsi_Vsici); + Ibpci_Vbpci = *(ckt->CKTstate0 + here->HICUMibpci_Vbpci); + +/* +c The real part +*/ +/* +c Stamp element: Ibiei +*/ + *(here->HICUMbaseBIBaseBIPtr) += Ibiei_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += -Ibiei_Vbiei; + *(here->HICUMemitEIBaseBIPtr) += -Ibiei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Ibiei_Vbiei; +/* +c Stamp element: Ibpei +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpei_Vbpei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpei_Vbpei; + *(here->HICUMemitEIBaseBPPtr) += -Ibpei_Vbpei; + *(here->HICUMemitEIEmitEIPtr) += Ibpei_Vbpei; + +/* +c Stamp element: Iciei +*/ + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbiei; + *(here->HICUMcollCIEmitEIPtr) += -Iciei_Vbiei; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbiei; + *(here->HICUMemitEIEmitEIPtr) += Iciei_Vbiei; + + *(here->HICUMcollCIBaseBIPtr) += Iciei_Vbici; + *(here->HICUMcollCICollCIPtr) += -Iciei_Vbici; + *(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbici; + *(here->HICUMemitEICollCIPtr) += Iciei_Vbici; +/* +c Stamp element: Ibici +*/ + *(here->HICUMbaseBIBaseBIPtr) += Ibici_Vbici; + *(here->HICUMbaseBICollCIPtr) += -Ibici_Vbici; + *(here->HICUMcollCIBaseBIPtr) += -Ibici_Vbici; + *(here->HICUMcollCICollCIPtr) += Ibici_Vbici; +/* +c Stamp element: Ibpci +*/ + *(here->HICUMbaseBPCollCIPtr) += Ibpci_Vbpci; + *(here->HICUMbaseBPBaseBPPtr) += -Ibpci_Vbpci; + *(here->HICUMcollCIBaseBPPtr) += -Ibpci_Vbpci; + *(here->HICUMcollCICollCIPtr) += Ibpci_Vbpci; +/* +c Stamp element: Rcx +*/ + *(here->HICUMcollCollPtr) += Icic_Vcic; + *(here->HICUMcollCICollPtr) += -Icic_Vcic; + *(here->HICUMcollCollCIPtr) += -Icic_Vcic; + *(here->HICUMcollCICollCIPtr) += Icic_Vcic; +/* +c Stamp element: Rbx +*/ + *(here->HICUMbaseBasePtr) += Ibbp_Vbbp; + *(here->HICUMbaseBPBasePtr) += -Ibbp_Vbbp; + *(here->HICUMbaseBaseBPPtr) += -Ibbp_Vbbp; + *(here->HICUMbaseBPBaseBPPtr) += Ibbp_Vbbp; +/* +c Stamp element: Ibpbi +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBPBaseBIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBPCollCIPtr) += Ibpbi_Vciei; + *(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vciei; + *(here->HICUMbaseBIBaseBPPtr) += -Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += Ibpbi_Vbpbi; + *(here->HICUMbaseBIBaseBIPtr) += -Ibpbi_Vbiei; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vbiei; + *(here->HICUMbaseBICollCIPtr) += -Ibpbi_Vciei; + *(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vciei; +/* +c Stamp element: Re +*/ + *(here->HICUMemitEmitPtr) += Ieie_Veie; + *(here->HICUMemitEIEmitPtr) += -Ieie_Veie; + *(here->HICUMemitEmitEIPtr) += -Ieie_Veie; + *(here->HICUMemitEIEmitEIPtr) += Ieie_Veie; +/* +c Stamp element: Isici +*/ + *(here->HICUMsubsSISubsSIPtr) += Isici_Vsici; + *(here->HICUMsubsSICollCIPtr) += -Isici_Vsici; + *(here->HICUMcollCISubsSIPtr) += -Isici_Vsici; + *(here->HICUMcollCICollCIPtr) += Isici_Vsici; +/* +c Stamp element: Ibpsi +*/ + *(here->HICUMbaseBPBaseBPPtr) += Ibpsi_Vbpci; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vbpci; + *(here->HICUMbaseBPSubsSIPtr) += Ibpsi_Vsici; + *(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vsici; + *(here->HICUMsubsSIBaseBPPtr) += -Ibpsi_Vbpci; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vbpci; + *(here->HICUMsubsSISubsSIPtr) += -Ibpsi_Vsici; + *(here->HICUMsubsSICollCIPtr) += Ibpsi_Vsici; +/* +c Stamp element: Rs +*/ + *(here->HICUMsubsSubsPtr) += Isis_Vsis; + *(here->HICUMsubsSISubsPtr) += -Isis_Vsis; + *(here->HICUMsubsSubsSIPtr) += -Isis_Vsis; + *(here->HICUMsubsSISubsSIPtr) += Isis_Vsis; +/* +c The complex part +*/ +//todo: Complete with partial dervatives e.g. Qjs_Vsici, Qrbi_Vbici + + XQrbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMcqrbi) * ckt->CKTomega; + XQdeix_Vbiei = *(ckt->CKTstate0 + here->HICUMcqdeix) * ckt->CKTomega; + XQjei_Vbiei = *(ckt->CKTstate0 + here->HICUMcqjei) * ckt->CKTomega; + XQdci_Vbici = *(ckt->CKTstate0 + here->HICUMcqdci) * ckt->CKTomega; + XQjci_Vbici = *(ckt->CKTstate0 + here->HICUMcqjci) * ckt->CKTomega; + XQjep_Vbpei = *(ckt->CKTstate0 + here->HICUMcqjep) * ckt->CKTomega; + Xqjcx0_t_i_Vbci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i) * ckt->CKTomega; + Xqjcx0_t_ii_Vbpci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) * ckt->CKTomega; + XQdsu_Vbpci = *(ckt->CKTstate0 + here->HICUMcqdsu) * ckt->CKTomega; + XQjs_Vsici = *(ckt->CKTstate0 + here->HICUMcqjs) * ckt->CKTomega; + XQscp_Vsc = *(ckt->CKTstate0 + here->HICUMcqscp) * ckt->CKTomega; + XQbepar1_Vbe = *(ckt->CKTstate0 + here->HICUMcqbepar1) * ckt->CKTomega; + XQbepar2_Vbpe = *(ckt->CKTstate0 + here->HICUMcqbepar2) * ckt->CKTomega; + XQbcpar1_Vbci = *(ckt->CKTstate0 + here->HICUMcqbcpar1) * ckt->CKTomega; + XQbcpar2_Vbpci = *(ckt->CKTstate0 + here->HICUMcqbcpar2) * ckt->CKTomega; + XQsu_Vsis = *(ckt->CKTstate0 + here->HICUMcqsu) * ckt->CKTomega; +/* +c Stamp element: Qbepar1 +*/ + *(here->HICUMbaseBasePtr) += XQbepar1_Vbe * (s->real); + *(here->HICUMbaseEmitPtr) += -XQbepar1_Vbe * (s->real); + *(here->HICUMemitBasePtr) += -XQbepar1_Vbe * (s->real); + *(here->HICUMemitEmitPtr) += XQbepar1_Vbe * (s->real); + *(here->HICUMbaseBasePtr + 1) += XQbepar1_Vbe * (s->imag); + *(here->HICUMbaseEmitPtr + 1) += -XQbepar1_Vbe * (s->imag); + *(here->HICUMemitBasePtr + 1) += -XQbepar1_Vbe * (s->imag); + *(here->HICUMemitEmitPtr + 1) += XQbepar1_Vbe * (s->imag); +/* +c Stamp element: Qbepar2 +*/ + *(here->HICUMbaseBPBaseBPPtr) += XQbepar2_Vbpe * (s->real); + *(here->HICUMemitBaseBPPtr) += -XQbepar2_Vbpe * (s->real); + *(here->HICUMemitEmitPtr) += -XQbepar2_Vbpe * (s->real); + *(here->HICUMbaseBPEmitPtr) += XQbepar2_Vbpe * (s->real); + *(here->HICUMbaseBPBaseBPPtr + 1) += XQbepar2_Vbpe * (s->imag); + *(here->HICUMemitBaseBPPtr + 1) += -XQbepar2_Vbpe * (s->imag); + *(here->HICUMemitEmitPtr + 1) += -XQbepar2_Vbpe * (s->imag); + *(here->HICUMbaseBPEmitPtr + 1) += XQbepar2_Vbpe * (s->imag); +/* +c Stamp element: Qdeix, Qjei +*/ + *(here->HICUMbaseBIBaseBIPtr) += XQdeix_Vbiei * (s->real); + *(here->HICUMbaseBIEmitEIPtr) += -XQdeix_Vbiei * (s->real); + *(here->HICUMemitEIBaseBIPtr) += -XQdeix_Vbiei * (s->real); + *(here->HICUMemitEIEmitEIPtr) += XQdeix_Vbiei * (s->real); + *(here->HICUMbaseBIBaseBIPtr + 1) += XQdeix_Vbiei * (s->imag); + *(here->HICUMbaseBIEmitEIPtr + 1) += -XQdeix_Vbiei * (s->imag); + *(here->HICUMemitEIBaseBIPtr + 1) += -XQdeix_Vbiei * (s->imag); + *(here->HICUMemitEIEmitEIPtr + 1) += XQdeix_Vbiei * (s->imag); + *(here->HICUMbaseBIBaseBIPtr) += XQjei_Vbiei * (s->real); + *(here->HICUMbaseBIEmitEIPtr) += -XQjei_Vbiei * (s->real); + *(here->HICUMemitEIBaseBIPtr) += -XQjei_Vbiei * (s->real); + *(here->HICUMemitEIEmitEIPtr) += XQjei_Vbiei * (s->real); + *(here->HICUMbaseBIBaseBIPtr + 1) += XQjei_Vbiei * (s->imag); + *(here->HICUMbaseBIEmitEIPtr + 1) += -XQjei_Vbiei * (s->imag); + *(here->HICUMemitEIBaseBIPtr + 1) += -XQjei_Vbiei * (s->imag); + *(here->HICUMemitEIEmitEIPtr + 1) += XQjei_Vbiei * (s->imag); +/* +c Stamp element: Qjep +*/ + *(here->HICUMbaseBPBaseBPPtr) += XQjep_Vbpei * (s->real); + *(here->HICUMbaseBPEmitEIPtr) += -XQjep_Vbpei * (s->real); + *(here->HICUMemitEIBaseBPPtr) += -XQjep_Vbpei * (s->real); + *(here->HICUMemitEIEmitEIPtr) += XQjep_Vbpei * (s->real); + *(here->HICUMbaseBPBaseBPPtr + 1) += XQjep_Vbpei * (s->imag); + *(here->HICUMbaseBPEmitEIPtr + 1) += -XQjep_Vbpei * (s->imag); + *(here->HICUMemitEIBaseBPPtr + 1) += -XQjep_Vbpei * (s->imag); + *(here->HICUMemitEIEmitEIPtr + 1) += XQjep_Vbpei * (s->imag); +/* +c Stamp element: Qdci, Qjci +*/ + *(here->HICUMbaseBIBaseBIPtr) += XQdci_Vbici * (s->real); + *(here->HICUMbaseBICollCIPtr) += -XQdci_Vbici * (s->real); + *(here->HICUMcollCIBaseBIPtr) += -XQdci_Vbici * (s->real); + *(here->HICUMcollCICollCIPtr) += XQdci_Vbici * (s->real); + *(here->HICUMbaseBIBaseBIPtr + 1) += XQdci_Vbici * (s->imag); + *(here->HICUMbaseBICollCIPtr + 1) += -XQdci_Vbici * (s->imag); + *(here->HICUMcollCIBaseBIPtr + 1) += -XQdci_Vbici * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQdci_Vbici * (s->imag); + *(here->HICUMbaseBIBaseBIPtr) += XQjci_Vbici * (s->real); + *(here->HICUMbaseBICollCIPtr) += -XQjci_Vbici * (s->real); + *(here->HICUMcollCIBaseBIPtr) += -XQjci_Vbici * (s->real); + *(here->HICUMcollCICollCIPtr) += XQjci_Vbici * (s->real); + *(here->HICUMbaseBIBaseBIPtr + 1) += XQjci_Vbici * (s->imag); + *(here->HICUMbaseBICollCIPtr + 1) += -XQjci_Vbici * (s->imag); + *(here->HICUMcollCIBaseBIPtr + 1) += -XQjci_Vbici * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQjci_Vbici * (s->imag); +/* +c Stamp element: Qbcpar1, qjcx0_i +*/ + *(here->HICUMbaseBasePtr) += XQbcpar1_Vbci * (s->real); + *(here->HICUMbaseCollCIPtr) += -XQbcpar1_Vbci * (s->real); + *(here->HICUMcollCIBasePtr) += -XQbcpar1_Vbci * (s->real); + *(here->HICUMcollCICollCIPtr) += XQbcpar1_Vbci * (s->real); + *(here->HICUMbaseBasePtr + 1) += XQbcpar1_Vbci * (s->imag); + *(here->HICUMbaseCollCIPtr + 1) += -XQbcpar1_Vbci * (s->imag); + *(here->HICUMcollCIBasePtr + 1) += -XQbcpar1_Vbci * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQbcpar1_Vbci * (s->imag); + *(here->HICUMbaseBasePtr) += Xqjcx0_t_i_Vbci * (s->real); + *(here->HICUMbaseCollCIPtr) += -Xqjcx0_t_i_Vbci * (s->real); + *(here->HICUMcollCIBasePtr) += -Xqjcx0_t_i_Vbci * (s->real); + *(here->HICUMcollCICollCIPtr) += Xqjcx0_t_i_Vbci * (s->real); + *(here->HICUMbaseBasePtr + 1) += Xqjcx0_t_i_Vbci * (s->imag); + *(here->HICUMbaseCollCIPtr + 1) += -Xqjcx0_t_i_Vbci * (s->imag); + *(here->HICUMcollCIBasePtr + 1) += -Xqjcx0_t_i_Vbci * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += Xqjcx0_t_i_Vbci * (s->imag); +/* +c Stamp element: Qbcpar2, qjcx0_ii, Qdsu +*/ + *(here->HICUMbaseBPBaseBPPtr) += XQbcpar2_Vbpci * (s->real); + *(here->HICUMcollCICollCIPtr) += XQbcpar2_Vbpci * (s->real); + *(here->HICUMbaseBPCollCIPtr) += -XQbcpar2_Vbpci * (s->real); + *(here->HICUMcollCIBaseBPPtr) += -XQbcpar2_Vbpci * (s->real); + *(here->HICUMbaseBPBaseBPPtr + 1) += XQbcpar2_Vbpci * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQbcpar2_Vbpci * (s->imag); + *(here->HICUMbaseBPCollCIPtr + 1) += -XQbcpar2_Vbpci * (s->imag); + *(here->HICUMcollCIBaseBPPtr + 1) += -XQbcpar2_Vbpci * (s->imag); + *(here->HICUMbaseBPCollCIPtr) += Xqjcx0_t_ii_Vbpci * (s->real); + *(here->HICUMbaseBPBaseBPPtr) += -Xqjcx0_t_ii_Vbpci * (s->real); + *(here->HICUMcollCIBaseBPPtr) += -Xqjcx0_t_ii_Vbpci * (s->real); + *(here->HICUMcollCICollCIPtr) += Xqjcx0_t_ii_Vbpci * (s->real); + *(here->HICUMbaseBPCollCIPtr + 1) += Xqjcx0_t_ii_Vbpci * (s->imag); + *(here->HICUMbaseBPBaseBPPtr + 1) += -Xqjcx0_t_ii_Vbpci * (s->imag); + *(here->HICUMcollCIBaseBPPtr + 1) += -Xqjcx0_t_ii_Vbpci * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += Xqjcx0_t_ii_Vbpci * (s->imag); + *(here->HICUMbaseBPCollCIPtr) += XQdsu_Vbpci * (s->real); + *(here->HICUMbaseBPBaseBPPtr) += -XQdsu_Vbpci * (s->real); + *(here->HICUMcollCIBaseBPPtr) += -XQdsu_Vbpci * (s->real); + *(here->HICUMcollCICollCIPtr) += XQdsu_Vbpci * (s->real); + *(here->HICUMbaseBPCollCIPtr + 1) += XQdsu_Vbpci * (s->imag); + *(here->HICUMbaseBPBaseBPPtr + 1) += -XQdsu_Vbpci * (s->imag); + *(here->HICUMcollCIBaseBPPtr + 1) += -XQdsu_Vbpci * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQdsu_Vbpci * (s->imag); +/* +c Stamp element: Qrbi +*/ + *(here->HICUMbaseBPBaseBPPtr) += XQrbi_Vbpbi * (s->real); + *(here->HICUMbaseBPBaseBIPtr) += -XQrbi_Vbpbi * (s->real); + *(here->HICUMbaseBIBaseBPPtr) += -XQrbi_Vbpbi * (s->real); + *(here->HICUMbaseBIBaseBIPtr) += XQrbi_Vbpbi * (s->real); + *(here->HICUMbaseBPBaseBPPtr + 1) += XQrbi_Vbpbi * (s->imag); + *(here->HICUMbaseBPBaseBIPtr + 1) += -XQrbi_Vbpbi * (s->imag); + *(here->HICUMbaseBIBaseBPPtr + 1) += -XQrbi_Vbpbi * (s->imag); + *(here->HICUMbaseBIBaseBIPtr + 1) += XQrbi_Vbpbi * (s->imag); +//todo: +// *(here->HICUMbaseBPBaseBIPtr) += XQrbi_Vbiei * (s->real); +// *(here->HICUMbaseBPEmitEIPtr) += -XQrbi_Vbiei * (s->real); +// *(here->HICUMbaseBIBaseBIPtr) += -XQrbi_Vbiei * (s->real); +// *(here->HICUMbaseBIEmitEIPtr) += XQrbi_Vbiei * (s->real); +// *(here->HICUMbaseBPBaseBIPtr + 1) += XQrbi_Vbiei * (s->imag); +// *(here->HICUMbaseBPEmitEIPtr + 1) += -XQrbi_Vbiei * (s->imag); +// *(here->HICUMbaseBIBaseBIPtr + 1) += -XQrbi_Vbiei * (s->imag); +// *(here->HICUMbaseBIEmitEIPtr + 1) += XQrbi_Vbiei * (s->imag); +// *(here->HICUMbaseBPCollCIPtr) += XQrbi_Vbici * (s->real); +// *(here->HICUMbaseBPEmitEIPtr) += -XQrbi_Vbici * (s->real); +// *(here->HICUMbaseBICollCIPtr) += -XQrbi_Vbici * (s->real); +// *(here->HICUMbaseBIEmitEIPtr) += XQrbi_Vbici * (s->real); +// *(here->HICUMbaseBPCollCIPtr + 1) += XQrbi_Vbici * (s->imag); +// *(here->HICUMbaseBPEmitEIPtr + 1) += -XQrbi_Vbici * (s->imag); +// *(here->HICUMbaseBICollCIPtr + 1) += -XQrbi_Vbici * (s->imag); +// *(here->HICUMbaseBIEmitEIPtr + 1) += XQrbi_Vbici * (s->imag); +/* +c Stamp element: Cscp +*/ + *(here->HICUMsubsSubsPtr) += XQscp_Vsc * (s->real); + *(here->HICUMcollSubsPtr) += -XQscp_Vsc * (s->real); + *(here->HICUMcollCollPtr) += -XQscp_Vsc * (s->real); + *(here->HICUMsubsCollPtr) += XQscp_Vsc * (s->real); + *(here->HICUMsubsSubsPtr + 1) += XQscp_Vsc * (s->imag); + *(here->HICUMcollSubsPtr + 1) += -XQscp_Vsc * (s->imag); + *(here->HICUMcollCollPtr + 1) += -XQscp_Vsc * (s->imag); + *(here->HICUMsubsCollPtr + 1) += XQscp_Vsc * (s->imag); +/* +c Stamp element: Cjs +*/ + *(here->HICUMsubsSISubsSIPtr) += XQjs_Vsici * (s->real); + *(here->HICUMsubsSICollCIPtr) += -XQjs_Vsici * (s->real); + *(here->HICUMcollCISubsSIPtr) += -XQjs_Vsici * (s->real); + *(here->HICUMcollCICollCIPtr) += XQjs_Vsici * (s->real); + *(here->HICUMsubsSISubsSIPtr + 1) += XQjs_Vsici * (s->imag); + *(here->HICUMsubsSICollCIPtr + 1) += -XQjs_Vsici * (s->imag); + *(here->HICUMcollCISubsSIPtr + 1) += -XQjs_Vsici * (s->imag); + *(here->HICUMcollCICollCIPtr + 1) += XQjs_Vsici * (s->imag); +/* +c Stamp element: Csu +*/ + *(here->HICUMsubsSubsPtr) += XQsu_Vsis * (s->real); + *(here->HICUMsubsSISubsPtr) += -XQsu_Vsis * (s->real); + *(here->HICUMsubsSubsSIPtr) += -XQsu_Vsis * (s->real); + *(here->HICUMsubsSISubsSIPtr) += XQsu_Vsis * (s->real); + *(here->HICUMsubsSubsPtr + 1) += XQsu_Vsis * (s->imag); + *(here->HICUMsubsSISubsPtr + 1) += -XQsu_Vsis * (s->imag); + *(here->HICUMsubsSubsSIPtr + 1) += -XQsu_Vsis * (s->imag); + *(here->HICUMsubsSISubsSIPtr + 1) += XQsu_Vsis * (s->imag); + + } + } + return(OK); +} diff --git a/src/spicelib/devices/hicum2/hicumsetup.c b/src/spicelib/devices/hicum2/hicumsetup.c new file mode 100644 index 000000000..a0d3cd7d2 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumsetup.c @@ -0,0 +1,708 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * 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/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/smpdefs.h" +#include "hicumdefs.h" +#include "ngspice/const.h" +#include "ngspice/sperror.h" +#include "ngspice/ifsim.h" +#include "ngspice/suffix.h" + +#define MIN_R 0.001 + +int +HICUMsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) + /* load the HICUM structure with those pointers needed later + * for fast matrix loading + */ +{ + HICUMmodel *model = (HICUMmodel*)inModel; + HICUMinstance *here; + int error; + CKTnode *tmp; + + /* loop through all the transistor models */ + for( ; model != NULL; model = HICUMnextModel(model)) { + +//Circuit simulator specific parameters + if(model->HICUMtype != NPN && model->HICUMtype != PNP) { + model->HICUMtype = NPN; + } + if(!model->HICUMtnomGiven) { + model->HICUMtnom = 27.0; + } +//Transfer current + if(!model->HICUMc10Given) { + model->HICUMc10 = 2e-30; + } + if(!model->HICUMqp0Given) { + model->HICUMqp0 = 2e-14; + } + if(!model->HICUMichGiven) { + model->HICUMich = 0.0; + } + if(!model->HICUMhf0Given) { + model->HICUMhf0 = 1.0; + } + if(!model->HICUMhfeGiven) { + model->HICUMhfe = 1.0; + } + if(!model->HICUMhfcGiven) { + model->HICUMhfc = 1.0; + } + if(!model->HICUMhjeiGiven) { + model->HICUMhjei = 1.0; + } + if(!model->HICUMahjeiGiven) { + model->HICUMahjei = 0.0; + } + if(!model->HICUMrhjeiGiven) { + model->HICUMrhjei = 1.0; + } + if(!model->HICUMhjciGiven) { + model->HICUMhjci = 1.0; + } +//Base-Emitter diode; + if(!model->HICUMibeisGiven) { + model->HICUMibeis = 1e-18; + } + if(!model->HICUMmbeiGiven) { + model->HICUMmbei = 1.0; + } + if(!model->HICUMireisGiven) { + model->HICUMireis = 0.0; + } + if(!model->HICUMmreiGiven) { + model->HICUMmrei = 2.0; + } + if(!model->HICUMibepsGiven) { + model->HICUMibeps = 0.0; + } + if(!model->HICUMmbepGiven) { + model->HICUMmbep = 1.0; + } + if(!model->HICUMirepsGiven) { + model->HICUMireps = 0.0; + } + if(!model->HICUMmrepGiven) { + model->HICUMmrep = 2.0; + } + if(!model->HICUMmcfGiven) { + model->HICUMmcf = 1.0; + } +//Transit time for excess recombination current at b-c barrier + if(!model->HICUMtbhrecGiven) { + model->HICUMtbhrec = 0.0; + } +//Base-Collector diode currents + if(!model->HICUMibcisGiven) { + model->HICUMibcis = 1e-16; + } + if(!model->HICUMmbciGiven) { + model->HICUMmbci = 1.0; + } + if(!model->HICUMibcxsGiven) { + model->HICUMibcxs = 0.0; + } + if(!model->HICUMmbcxGiven) { + model->HICUMmbcx = 1.0; + } +//Base-Emitter tunneling current + if(!model->HICUMibetsGiven) { + model->HICUMibets = 0.0; + } + if(!model->HICUMabetGiven) { + model->HICUMabet = 40.0; + } + if(!model->HICUMtunodeGiven) { + model->HICUMtunode = 1; + } +//Base-Collector avalanche current + if(!model->HICUMfavlGiven) { + model->HICUMfavl = 0.0; + } + if(!model->HICUMqavlGiven) { + model->HICUMqavl = 0.0; + } + if(!model->HICUMalfavGiven) { + model->HICUMalfav = 0.0; + } + if(!model->HICUMalqavGiven) { + model->HICUMalqav = 0.0; + } +//Series resistances + if(!model->HICUMrbi0Given) { + model->HICUMrbi0 = MIN_R; + } + if(!model->HICUMrbxGiven) { + model->HICUMrbx = MIN_R; + } + if(!model->HICUMfgeoGiven) { + model->HICUMfgeo = 0.6557; + } + if(!model->HICUMfdqr0Given) { + model->HICUMfdqr0 = 0.0; + } + if(!model->HICUMfcrbiGiven) { + model->HICUMfcrbi = 0.0; + } + if(!model->HICUMfqiGiven) { + model->HICUMfqi = 1.0; + } + if(!model->HICUMreGiven) { + model->HICUMre = MIN_R; + } + if(!model->HICUMrcxGiven) { + model->HICUMrcx = MIN_R; + } +//Substrate transistor + if(!model->HICUMitssGiven) { + model->HICUMitss = 0.0; + } + if(!model->HICUMmsfGiven) { + model->HICUMmsf = 1.0; + } + if(!model->HICUMiscsGiven) { + model->HICUMiscs = 0.0; + } + if(!model->HICUMmscGiven) { + model->HICUMmsc = 1.0; + } + if(!model->HICUMtsfGiven) { + model->HICUMtsf = 0.0; + } +//Intra-device substrate coupling + if(!model->HICUMrsuGiven) { + model->HICUMrsu = MIN_R; + } + if(!model->HICUMcsuGiven) { + model->HICUMcsu = 0.0; + } +//Depletion Capacitances + if(!model->HICUMcjei0Given) { + model->HICUMcjei0 = 1.0e-20; + } + if(!model->HICUMvdeiGiven) { + model->HICUMvdei = 0.9; + } + if(!model->HICUMzeiGiven) { + model->HICUMzei = 0.5; + } + if(!model->HICUMajeiGiven) { + model->HICUMajei = 2.5; + } + if(!model->HICUMcjep0Given) { + model->HICUMcjep0 = 1.0e-20; + } + if(!model->HICUMvdepGiven) { + model->HICUMvdep = 0.9; + } + if(!model->HICUMzepGiven) { + model->HICUMzep = 0.5; + } + if(!model->HICUMajepGiven) { + model->HICUMajep = 2.5; + } + if(!model->HICUMcjci0Given) { + model->HICUMcjci0 = 1.0e-20; + } + if(!model->HICUMvdciGiven) { + model->HICUMvdci = 0.7; + } + if(!model->HICUMzciGiven) { + model->HICUMzci = 0.4; + } + if(!model->HICUMvptciGiven) { + model->HICUMvptci = 100.0; + } + if(!model->HICUMcjcx0Given) { + model->HICUMcjcx0 = 1.0e-20; + } + if(!model->HICUMvdcxGiven) { + model->HICUMvdcx = 0.7; + } + if(!model->HICUMzcxGiven) { + model->HICUMzcx = 0.4; + } + if(!model->HICUMvptcxGiven) { + model->HICUMvptcx = 100.0; + } + if(!model->HICUMfbcparGiven) { + model->HICUMfbcpar = 0.0; + } + if(!model->HICUMfbeparGiven) { + model->HICUMfbepar = 1.0; + } + if(!model->HICUMcjs0Given) { + model->HICUMcjs0 = 0.0; + } + if(!model->HICUMvdsGiven) { + model->HICUMvds = 0.6; + } + if(!model->HICUMzsGiven) { + model->HICUMzs = 0.5; + } + if(!model->HICUMvptsGiven) { + model->HICUMvpts = 100.0; + } + if(!model->HICUMcscp0Given) { + model->HICUMcscp0 = 0.0; + } + if(!model->HICUMvdspGiven) { + model->HICUMvdsp = 0.6; + } + if(!model->HICUMzspGiven) { + model->HICUMzsp = 0.5; + } + if(!model->HICUMvptspGiven) { + model->HICUMvptsp = 100.0; + } +//Diffusion Capacitances + if(!model->HICUMt0Given) { + model->HICUMt0 = 0.0; + } + if(!model->HICUMdt0hGiven) { + model->HICUMdt0h = 0.0; + } + if(!model->HICUMtbvlGiven) { + model->HICUMtbvl = 0.0; + } + if(!model->HICUMtef0Given) { + model->HICUMtef0 = 0.0; + } + if(!model->HICUMgtfeGiven) { + model->HICUMgtfe = 1.0; + } + if(!model->HICUMthcsGiven) { + model->HICUMthcs = 0.0; + } + if(!model->HICUMahcGiven) { + model->HICUMahc = 0.1; + } + if(!model->HICUMfthcGiven) { + model->HICUMfthc = 0.0; + } + if(!model->HICUMrci0Given) { + model->HICUMrci0 = 150; + } + if(!model->HICUMvlimGiven) { + model->HICUMvlim = 0.5; + } + if(!model->HICUMvcesGiven) { + model->HICUMvces = 0.1; + } + if(!model->HICUMvptGiven) { + model->HICUMvpt = 100.0; + } + if(!model->HICUMaickGiven) { + model->HICUMaick = 1.0e-03; + } + if(!model->HICUMdelckGiven) { + model->HICUMdelck = 2.0; + } + if(!model->HICUMtrGiven) { + model->HICUMtr = 0.0; + } + if(!model->HICUMvcbarGiven) { + model->HICUMvcbar = 0.0; + } + if(!model->HICUMicbarGiven) { + model->HICUMicbar = 0.0; + } + if(!model->HICUMacbarGiven) { + model->HICUMacbar = 0.01; + } +//Isolation Capacitances + if(!model->HICUMcbeparGiven) { + model->HICUMcbepar = 0.0; + } + if(!model->HICUMcbcparGiven) { + model->HICUMcbcpar = 0.0; + } +//Non-quasi-static Effect + if(!model->HICUMalqfGiven) { + model->HICUMalqf = 0.167; + } + if(!model->HICUMalitGiven) { + model->HICUMalit = 0.333; + } + if(!model->HICUMflnqsGiven) { + model->HICUMflnqs = 0; + } +//Noise + if(!model->HICUMkfGiven) { + model->HICUMkf = 0.0; + } + if(!model->HICUMafGiven) { + model->HICUMaf = 2.0; + } + if(!model->HICUMcfbeGiven) { + model->HICUMcfbe = -1; + } + if(!model->HICUMflconoGiven) { + model->HICUMflcono = 0; + } + if(!model->HICUMkfreGiven) { + model->HICUMkfre = 0.0; + } + if(!model->HICUMafreGiven) { + model->HICUMafre = 2.0; + } +//Lateral Geometry Scaling (at high current densities) + if(!model->HICUMlatbGiven) { + model->HICUMlatb = 0.0; + } + if(!model->HICUMlatlGiven) { + model->HICUMlatl = 0.0; + } +//Temperature dependence + if(!model->HICUMvgbGiven) { + model->HICUMvgb = 1.17; + } + if(!model->HICUMalt0Given) { + model->HICUMalt0 = 0.0; + } + if(!model->HICUMkt0Given) { + model->HICUMkt0 = 0.0; + } + if(!model->HICUMzetaciGiven) { + model->HICUMzetaci = 0.0; + } + if(!model->HICUMalvsGiven) { + model->HICUMalvs = 0.0; + } + if(!model->HICUMalcesGiven) { + model->HICUMalces = 0.0; + } + if(!model->HICUMzetarbiGiven) { + model->HICUMzetarbi = 0.0; + } + if(!model->HICUMzetarbxGiven) { + model->HICUMzetarbx = 0.0; + } + if(!model->HICUMzetarcxGiven) { + model->HICUMzetarcx = 0.0; + } + if(!model->HICUMzetareGiven) { + model->HICUMzetare = 0.0; + } + if(!model->HICUMzetacxGiven) { + model->HICUMzetacx = 1.0; + } + if(!model->HICUMvgeGiven) { + model->HICUMvge = 1.17; + } + if(!model->HICUMvgcGiven) { + model->HICUMvgc = 1.17; + } + if(!model->HICUMvgsGiven) { + model->HICUMvgs = 1.17; + } + if(!model->HICUMf1vgGiven) { + model->HICUMf1vg = -1.02377e-4; + } + if(!model->HICUMf2vgGiven) { + model->HICUMf2vg = 4.3215e-4; + } + if(!model->HICUMzetactGiven) { + model->HICUMzetact = 3.0; + } + if(!model->HICUMzetabetGiven) { + model->HICUMzetabet = 3.5; + } + if(!model->HICUMalbGiven) { + model->HICUMalb = 0.0; + } + if(!model->HICUMdvgbeGiven) { + model->HICUMdvgbe = 0.0; + } + if(!model->HICUMzetahjeiGiven) { + model->HICUMzetahjei = 1.0; + } + if(!model->HICUMzetavgbeGiven) { + model->HICUMzetavgbe = 1.0; + } +//Self-Heating + if(!model->HICUMflshGiven) { + model->HICUMflsh = 0; + } + if(!model->HICUMrthGiven) { + model->HICUMrth = 0.0; + } + if(!model->HICUMzetarthGiven) { + model->HICUMzetarth = 0.0; + } + if(!model->HICUMalrthGiven) { + model->HICUMalrth = 0.0; + } + if(!model->HICUMcthGiven) { + model->HICUMcth = 0.0; + } +//Compatibility with V2.1 + if(!model->HICUMflcompGiven) { + model->HICUMflcomp = 0.0; + } + + if(!model->HICUMvbeMaxGiven) { + model->HICUMvbeMax = 1e99; + } + if(!model->HICUMvbcMaxGiven) { + model->HICUMvbcMax = 1e99; + } + if(!model->HICUMvceMaxGiven) { + model->HICUMvceMax = 1e99; + } + + /* loop through all the instances of the model */ + for (here = HICUMinstances(model); here != NULL ; + here=HICUMnextInstance(here)) { + CKTnode *tmpNode; + IFuid tmpName; + + if(!here->HICUMareaGiven) { + here->HICUMarea = 1.0; + } + if(!here->HICUMmGiven) { + here->HICUMm = 1.0; + } + if(!here->HICUMdtempGiven) { + here->HICUMdtemp = 0.0; + } + + here->HICUMstate = *states; + *states += HICUMnumStates; + + if(model->HICUMrcx == 0) { + here->HICUMcollCINode = here->HICUMcollNode; + } else if(here->HICUMcollCINode == 0) { + error = CKTmkVolt(ckt,&tmp,here->HICUMname,"collCI"); + if(error) return(error); + here->HICUMcollCINode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + if(model->HICUMrbx == 0) { + here->HICUMbaseBPNode = here->HICUMbaseNode; + } else if(here->HICUMbaseBPNode == 0){ + error = CKTmkVolt(ckt,&tmp,here->HICUMname, "baseBP"); + if(error) return(error); + here->HICUMbaseBPNode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + if(model->HICUMre == 0) { + here->HICUMemitEINode = here->HICUMemitNode; + } else if(here->HICUMemitEINode == 0) { + error = CKTmkVolt(ckt,&tmp,here->HICUMname, "emitEI"); + if(error) return(error); + here->HICUMemitEINode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + if(model->HICUMrsu == 0) { + here->HICUMsubsSINode = here->HICUMsubsNode; + } else if(here->HICUMsubsSINode == 0) { + error = CKTmkVolt(ckt,&tmp,here->HICUMname, "subsSI"); + if(error) return(error); + here->HICUMsubsSINode = tmp->number; + if (ckt->CKTcopyNodesets) { + if (CKTinst2Node(ckt,here,4,&tmpNode,&tmpName)==OK) { + if (tmpNode->nsGiven) { + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; + } + } + } + } + + if(here->HICUMbaseBINode == 0) { + error = CKTmkVolt(ckt, &tmp, here->HICUMname, "baseBI"); + if(error) return(error); + here->HICUMbaseBINode = tmp->number; + } + +// if(here->HICUMxfNode == 0) { +// error = CKTmkVolt(ckt, &tmp, here->HICUMname, "xf"); +// if(error) return(error); +// here->HICUMxfNode = tmp->number; +// } +// +// if(here->HICUMxf1Node == 0) { +// error = CKTmkVolt(ckt, &tmp, here->HICUMname, "xf1"); +// if(error) return(error); +// here->HICUMxf1Node = tmp->number; +// } +// +// if(here->HICUMxf2Node == 0) { +// error = CKTmkVolt(ckt, &tmp, here->HICUMname, "xf2"); +// if(error) return(error); +// here->HICUMxf2Node = tmp->number; +// } + + if((model->HICUMrthGiven) && (model->HICUMcth < 1e-12)) + model->HICUMcth = 1e-12; + +/* macro to make elements with built in test for out of memory */ +#define TSTALLOC(ptr,first,second) \ +do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ + return(E_NOMEM);\ +} } while(0) + TSTALLOC(HICUMcollCollPtr,HICUMcollNode,HICUMcollNode); + TSTALLOC(HICUMbaseBasePtr,HICUMbaseNode,HICUMbaseNode); + TSTALLOC(HICUMemitEmitPtr,HICUMemitNode,HICUMemitNode); + TSTALLOC(HICUMsubsSubsPtr,HICUMsubsNode,HICUMsubsNode); + + TSTALLOC(HICUMcollCICollCIPtr,HICUMcollCINode,HICUMcollCINode); + TSTALLOC(HICUMbaseBIBaseBIPtr,HICUMbaseBINode,HICUMbaseBINode); + TSTALLOC(HICUMemitEIEmitEIPtr,HICUMemitEINode,HICUMemitEINode); + TSTALLOC(HICUMbaseBPBaseBPPtr,HICUMbaseBPNode,HICUMbaseBPNode); + TSTALLOC(HICUMsubsSISubsSIPtr,HICUMsubsSINode,HICUMsubsSINode); + + TSTALLOC(HICUMbaseEmitPtr,HICUMbaseNode,HICUMemitNode); //b-e + TSTALLOC(HICUMemitBasePtr,HICUMemitNode,HICUMbaseNode); //e-b + + TSTALLOC(HICUMbaseBaseBPPtr,HICUMbaseNode,HICUMbaseBPNode); //b-bp + TSTALLOC(HICUMbaseBPBasePtr,HICUMbaseBPNode,HICUMbaseNode); //bp-b + TSTALLOC(HICUMemitEmitEIPtr,HICUMemitNode,HICUMemitEINode); //e-ei + TSTALLOC(HICUMemitEIEmitPtr,HICUMemitEINode,HICUMemitNode); //ei-e + + TSTALLOC(HICUMsubsSubsSIPtr,HICUMsubsNode,HICUMsubsSINode); //s-si + TSTALLOC(HICUMsubsSISubsPtr,HICUMsubsSINode,HICUMsubsNode); //si-s + + TSTALLOC(HICUMcollCIBasePtr,HICUMcollCINode,HICUMbaseNode); //b-ci + TSTALLOC(HICUMbaseCollCIPtr,HICUMbaseNode,HICUMcollCINode); //ci-b + + TSTALLOC(HICUMcollCIEmitEIPtr,HICUMcollCINode,HICUMemitEINode); //ci-ei + TSTALLOC(HICUMemitEICollCIPtr,HICUMemitEINode,HICUMcollCINode); //ei-ci + + TSTALLOC(HICUMbaseBPBaseBIPtr,HICUMbaseBPNode,HICUMbaseBINode); //bp-bi + TSTALLOC(HICUMbaseBIBaseBPPtr,HICUMbaseBINode,HICUMbaseBPNode); //bi-bp + + TSTALLOC(HICUMbaseBPEmitEIPtr,HICUMbaseBPNode,HICUMemitEINode); //bp-ei + TSTALLOC(HICUMemitEIBaseBPPtr,HICUMemitEINode,HICUMbaseBPNode); //ei-bp + + TSTALLOC(HICUMbaseBPEmitPtr,HICUMbaseBPNode,HICUMemitNode); //bp-e + TSTALLOC(HICUMemitBaseBPPtr,HICUMemitNode,HICUMbaseBPNode); //e-bp + + TSTALLOC(HICUMbaseBPSubsSIPtr,HICUMbaseBPNode,HICUMsubsSINode); //bp-si + TSTALLOC(HICUMsubsSIBaseBPPtr,HICUMsubsSINode,HICUMbaseBPNode); //si-bp + + TSTALLOC(HICUMbaseBIEmitEIPtr,HICUMbaseBINode,HICUMemitEINode); //ei-bi + TSTALLOC(HICUMemitEIBaseBIPtr,HICUMemitEINode,HICUMbaseBINode); //bi-ei + + TSTALLOC(HICUMbaseBICollCIPtr,HICUMbaseBINode,HICUMcollCINode); //ci-bi + TSTALLOC(HICUMcollCIBaseBIPtr,HICUMcollCINode,HICUMbaseBINode); //bi-ci + + TSTALLOC(HICUMbaseBPCollCIPtr,HICUMbaseBPNode,HICUMcollCINode); //bp-ci + TSTALLOC(HICUMcollCIBaseBPPtr,HICUMcollCINode,HICUMbaseBPNode); //ci-bp + + TSTALLOC(HICUMsubsSICollCIPtr,HICUMsubsSINode,HICUMcollCINode); //si-ci + TSTALLOC(HICUMcollCISubsSIPtr,HICUMcollCINode,HICUMsubsSINode); //ci-si + + TSTALLOC(HICUMcollCICollPtr,HICUMcollCINode,HICUMcollNode); //ci-c + TSTALLOC(HICUMcollCollCIPtr,HICUMcollNode,HICUMcollCINode); //c-ci + + TSTALLOC(HICUMsubsCollPtr,HICUMsubsNode,HICUMcollNode); //s-c + TSTALLOC(HICUMcollSubsPtr,HICUMcollNode,HICUMsubsNode); //c-s + +// TSTALLOC(HICUMxfXfPtr,HICUMxfNode,HICUMxfNode); +// TSTALLOC(HICUMxf1Xf1Ptr,HICUMxf1Node,HICUMxf1Node); +// TSTALLOC(HICUMxf2Xf2Ptr,HICUMxf2Node,HICUMxf2Node); + + if (model->HICUMflsh) { + TSTALLOC(HICUMcollTempPtr,HICUMcollNode,HICUMtempNode); + TSTALLOC(HICUMbaseTempPtr,HICUMbaseNode,HICUMtempNode); + TSTALLOC(HICUMemitTempPtr,HICUMemitNode,HICUMtempNode); + + TSTALLOC(HICUMcollCItempPtr,HICUMcollCINode,HICUMtempNode); + TSTALLOC(HICUMbaseBItempPtr,HICUMbaseBINode,HICUMtempNode); + TSTALLOC(HICUMbaseBPtempPtr,HICUMbaseBPNode,HICUMtempNode); + TSTALLOC(HICUMemitEItempPtr,HICUMemitEINode,HICUMtempNode); + TSTALLOC(HICUMsubsSItempPtr,HICUMsubsSINode,HICUMtempNode); + + TSTALLOC(HICUMtempCollCIPtr,HICUMtempNode,HICUMcollCINode); + TSTALLOC(HICUMtempBaseBIPtr,HICUMtempNode,HICUMbaseBINode); + TSTALLOC(HICUMtempBaseBPPtr,HICUMtempNode,HICUMbaseBPNode); + TSTALLOC(HICUMtempEmitEIPtr,HICUMtempNode,HICUMemitEINode); + TSTALLOC(HICUMtempSubsSIPtr,HICUMtempNode,HICUMsubsSINode); + + TSTALLOC(HICUMtempTempPtr,HICUMtempNode,HICUMtempNode); + } + + } + } + return(OK); +} + +int +HICUMunsetup( + GENmodel *inModel, + CKTcircuit *ckt) +{ + HICUMmodel *model; + HICUMinstance *here; + + for (model = (HICUMmodel *)inModel; model != NULL; + model = HICUMnextModel(model)) + { + for (here = HICUMinstances(model); here != NULL; + here=HICUMnextInstance(here)) + { + if (here->HICUMbaseBINode > 0) + CKTdltNNum(ckt, here->HICUMbaseBINode); + here->HICUMbaseBINode = 0; + + if (here->HICUMsubsSINode > 0 + && here->HICUMsubsSINode != here->HICUMsubsNode) + CKTdltNNum(ckt, here->HICUMsubsSINode); + here->HICUMsubsSINode = 0; + + if (here->HICUMemitEINode > 0 + && here->HICUMemitEINode != here->HICUMemitNode) + CKTdltNNum(ckt, here->HICUMemitEINode); + here->HICUMemitEINode = 0; + + if (here->HICUMbaseBPNode > 0 + && here->HICUMbaseBPNode != here->HICUMbaseNode) + CKTdltNNum(ckt, here->HICUMbaseBPNode); + here->HICUMbaseBPNode = 0; + + if (here->HICUMcollCINode > 0 + && here->HICUMcollCINode != here->HICUMcollNode) + CKTdltNNum(ckt, here->HICUMcollCINode); + here->HICUMcollCINode = 0; + } + } + return OK; +} diff --git a/src/spicelib/devices/hicum2/hicumsoachk.c b/src/spicelib/devices/hicum2/hicumsoachk.c new file mode 100644 index 000000000..9c06bf5f1 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumsoachk.c @@ -0,0 +1,72 @@ +/********** +Copyright 2013 Dietmar Warning. All rights reserved. +Author: 2013 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +HICUMsoaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + HICUMmodel *model = (HICUMmodel *) inModel; + HICUMinstance *here; + double vbe, vbc, vce; /* actual bjt voltages */ + int maxwarns; + static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0; + + if (!ckt) { + warns_vbe = 0; + warns_vbc = 0; + warns_vce = 0; + return OK; + } + + maxwarns = ckt->CKTsoaMaxWarns; + + for (; model; model = HICUMnextModel(model)) { + + for (here = HICUMinstances(model); here; here=HICUMnextInstance(here)) { + + vbe = fabs(ckt->CKTrhsOld [here->HICUMbaseNode] - + ckt->CKTrhsOld [here->HICUMemitNode]); + vbc = fabs(ckt->CKTrhsOld [here->HICUMbaseNode] - + ckt->CKTrhsOld [here->HICUMcollNode]); + vce = fabs(ckt->CKTrhsOld [here->HICUMcollNode] - + ckt->CKTrhsOld [here->HICUMemitNode]); + + if (vbe > model->HICUMvbeMax) + if (warns_vbe < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbe|=%g has exceeded Vbe_max=%g\n", + vbe, model->HICUMvbeMax); + warns_vbe++; + } + + if (vbc > model->HICUMvbcMax) + if (warns_vbc < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbc|=%g has exceeded Vbc_max=%g\n", + vbc, model->HICUMvbcMax); + warns_vbc++; + } + + if (vce > model->HICUMvceMax) + if (warns_vce < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vce|=%g has exceeded Vce_max=%g\n", + vce, model->HICUMvceMax); + warns_vce++; + } + + } + } + + return OK; +} diff --git a/src/spicelib/devices/hicum2/hicumtemp.c b/src/spicelib/devices/hicum2/hicumtemp.c new file mode 100644 index 000000000..b04d76a19 --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumtemp.c @@ -0,0 +1,352 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/smpdefs.h" +#include "hicumdefs.h" +#include "ngspice/const.h" +#include "ngspice/sperror.h" +#include "ngspice/ifsim.h" +#include "ngspice/suffix.h" + +#define TMAX 326.85 +#define TMIN -100.0 +#define LN_EXP_LIMIT 11.0 + +void TMPHICJ(double , double , double , double , double , + double , double , double , double , double , double , + double *, double *, double *); + +// TEMPERATURE UPDATE OF JUNCTION CAPACITANCE RELATED PARAMETERS +// INPUT: +// mostly model parameters +// x : zero bias junction capacitance +// y : junction built-in potential +// z : grading co-efficient +// w : ratio of maximum to zero-bias value of capacitance or punch-through voltage +// is_al : condition factor to check what "w" stands for +// vgeff : band-gap voltage +// IMPLICIT INPUT: +// vt : thermal voltage +// vt0,qtt0,ln_qtt0,mg : other model variables +// OUTPUT: +// c_j_t : temperature update of "c_j" +// vd_t : temperature update of "vd0" +// w_t : temperature update of "w" +void TMPHICJ(double vt, double vt0, double qtt0, double ln_qtt0, double mg, + double c_j, double vd0, double z, double w, double is_al, double vgeff, + double *c_j_t, double *vd_t, double *w_t) +{ +double vdj0,vdjt,vdt; + +if (c_j > 0.0) { + vdj0 = 2*vt0*log(exp(vd0*0.5/vt0)-exp(-0.5*vd0/vt0)); + vdjt = vdj0*qtt0+vgeff*(1-qtt0)-mg*vt*ln_qtt0; + vdt = vdjt+2*vt*log(0.5*(1+sqrt(1+4*exp(-vdjt/vt)))); + *vd_t = vdt; + *c_j_t = c_j*exp(z*log(vd0/(*vd_t))); + if (is_al == 1) { + *w_t = w*(*vd_t)/vd0; + } else { + *w_t = w; + } + } else { + *c_j_t = c_j; + *vd_t = vd0; + *w_t = w; + } +} + +int iret, hicum_thermal_update(HICUMmodel *, HICUMinstance *); + +int +HICUMtemp(GENmodel *inModel, CKTcircuit *ckt) + /* Pre-compute many useful parameters + */ +{ + HICUMmodel *model = (HICUMmodel *)inModel; + HICUMinstance *here; + + /* loop through all the bipolar models */ + for( ; model != NULL; model = HICUMnextModel(model)) { + + /* loop through all the instances of the model */ + for (here = HICUMinstances(model); here != NULL ; + here=HICUMnextInstance(here)) { + + if(!here->HICUMtempGiven) here->HICUMtemp = ckt->CKTtemp; + + if(here->HICUMdtempGiven) here->HICUMtemp = here->HICUMtemp + here->HICUMdtemp; + + iret = hicum_thermal_update(model, here); + + } + } + return(OK); +} + +int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance) +{ + HICUMmodel *model = (HICUMmodel *)inModel; + HICUMinstance *here = (HICUMinstance *)inInstance; + + double k10,k20,avs,vgb_t0,vge_t0,vgbe_t0,vgbe0,vgbc0,vgsc0; + double zetabci,zetabcxt,zetasct; + double k1,k2,dvg0,vge_t,vgb_t,vgbe_t,cratio_t,a; + double Tnom, dT, zetatef, cjcx01, cjcx02, C_1; + double cjci0_t, vdci_t, vptci_t, cjep0_t, vdep_t, ajep_t, vdcx_t, vptcx_t, cscp0_t, vdsp_t, vptsp_t, cjs0_t, vds_t, vpts_t; + + Tnom = model->HICUMtnom; + k10 = model->HICUMf1vg*Tnom*log(Tnom); + k20 = model->HICUMf2vg*Tnom; + avs = model->HICUMalvs*Tnom; + vgb_t0 = model->HICUMvgb+k10+k20; + vge_t0 = model->HICUMvge+k10+k20; + vgbe_t0 = (vgb_t0+vge_t0)/2; + + vgbe0 = (model->HICUMvgb+model->HICUMvge)/2; + vgbc0 = (model->HICUMvgb+model->HICUMvgc)/2; + vgsc0 = (model->HICUMvgs+model->HICUMvgc)/2; + + here->HICUMmg = 3-model->HICUMf1vg/CONSTKoverQ; + zetabci = here->HICUMmg+1-model->HICUMzetaci; + zetabcxt= here->HICUMmg+1-model->HICUMzetacx; + zetasct = here->HICUMmg-1.5; + + // Limit temperature to avoid FPEs in equations + if(here->HICUMtemp < TMIN + CONSTCtoK) { + here->HICUMtemp = TMIN + CONSTCtoK; + } else { + if (here->HICUMtemp > TMAX + CONSTCtoK) { + here->HICUMtemp = TMAX + CONSTCtoK; + } + } + here->HICUMvt0 = Tnom * CONSTKoverQ; + here->HICUMvt = here->HICUMtemp * CONSTKoverQ; + dT = here->HICUMtemp-Tnom; + here->HICUMqtt0 = here->HICUMtemp/Tnom; + here->HICUMln_qtt0 = log(here->HICUMqtt0); + k1 = model->HICUMf1vg*here->HICUMtemp*log(here->HICUMtemp); + k2 = model->HICUMf2vg*here->HICUMtemp; + vgb_t = model->HICUMvgb+k1+k2; + vge_t = model->HICUMvge+k1+k2; + vgbe_t = (vgb_t+vge_t)/2; + + here->HICUMtVcrit = here->HICUMvt * + log(here->HICUMvt / (CONSTroot2*model->HICUMibeis*here->HICUMarea*here->HICUMm)); + + //Internal b-e junction capacitance + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcjei0,model->HICUMvdei,model->HICUMzei,model->HICUMajei,1,vgbe0,&here->HICUMcjei0_t,&here->HICUMvdei_t,&here->HICUMajei_t); + + if (model->HICUMflcomp == 0.0 || model->HICUMflcomp == 2.1) { + double V_gT, r_VgVT, k; + V_gT = 3.0*here->HICUMvt*here->HICUMln_qtt0 + model->HICUMvgb*(here->HICUMqtt0-1.0); + r_VgVT = V_gT/here->HICUMvt; + //Internal b-e diode saturation currents + a = model->HICUMmcf*r_VgVT/model->HICUMmbei - model->HICUMalb*dT; + here->HICUMibeis_t = model->HICUMibeis*exp(a); + a = model->HICUMmcf*r_VgVT/model->HICUMmrei - model->HICUMalb*dT; + here->HICUMireis_t = model->HICUMireis*exp(a); + a = model->HICUMmcf*r_VgVT/model->HICUMmbep - model->HICUMalb*dT; + //Peripheral b-e diode saturation currents + here->HICUMibeps_t = model->HICUMibeps*exp(a); + a = model->HICUMmcf*r_VgVT/model->HICUMmrep - model->HICUMalb*dT; + here->HICUMireps_t = model->HICUMireps*exp(a); + //Internal b-c diode saturation current + a = r_VgVT/model->HICUMmbci; + here->HICUMibcis_t = model->HICUMibcis*exp(a); + //External b-c diode saturation currents + a = r_VgVT/model->HICUMmbcx; + here->HICUMibcxs_t = model->HICUMibcxs*exp(a); + //Saturation transfer current for substrate transistor + a = r_VgVT/model->HICUMmsf; + here->HICUMitss_t = model->HICUMitss*exp(a); + //Saturation current for c-s diode + a = r_VgVT/model->HICUMmsc; + here->HICUMiscs_t = model->HICUMiscs*exp(a); + //Zero bias hole charge + a = here->HICUMvdei_t/model->HICUMvdei; + here->HICUMqp0_t = model->HICUMqp0*(1.0+0.5*model->HICUMzei*(1.0-a)); + //Voltage separating ohmic and saturation velocity regime + a = model->HICUMvlim*(1.0-model->HICUMalvs*dT)*exp(model->HICUMzetaci*here->HICUMln_qtt0); + k = (a-here->HICUMvt)/here->HICUMvt; + if (k < LN_EXP_LIMIT) { + here->HICUMvlim_t = here->HICUMvt + here->HICUMvt*log(1.0+exp(k)); + } else { + here->HICUMvlim_t = a; + } + //Neutral emitter storage time + a = 1.0+model->HICUMalb*dT; + k = 0.5*(a+sqrt(a*a+0.01)); + here->HICUMtef0_t = model->HICUMtef0*here->HICUMqtt0/k; + } else { + //Internal b-e diode saturation currents + here->HICUMibeis_t = model->HICUMibeis*exp(model->HICUMzetabet*here->HICUMln_qtt0+model->HICUMvge/here->HICUMvt*(here->HICUMqtt0-1)); + if (model->HICUMflcomp>=2.3) { + here->HICUMireis_t = model->HICUMireis*exp(here->HICUMmg/model->HICUMmrei*here->HICUMln_qtt0+vgbe0/(model->HICUMmrei*here->HICUMvt)*(here->HICUMqtt0-1)); + } else { + here->HICUMireis_t = model->HICUMireis*exp(0.5*here->HICUMmg*here->HICUMln_qtt0+0.5*vgbe0/here->HICUMvt*(here->HICUMqtt0-1)); + } + //Peripheral b-e diode saturation currents + here->HICUMibeps_t = model->HICUMibeps*exp(model->HICUMzetabet*here->HICUMln_qtt0+model->HICUMvge/here->HICUMvt*(here->HICUMqtt0-1)); + if (model->HICUMflcomp>=2.3) { + here->HICUMireps_t = model->HICUMireps*exp(here->HICUMmg/model->HICUMmrep*here->HICUMln_qtt0+vgbe0/(model->HICUMmrep*here->HICUMvt)*(here->HICUMqtt0-1)); + } else { + here->HICUMireps_t = model->HICUMireps*exp(0.5*here->HICUMmg*here->HICUMln_qtt0+0.5*vgbe0/here->HICUMvt*(here->HICUMqtt0-1)); + } + //Internal b-c diode saturation currents + here->HICUMibcis_t = model->HICUMibcis*exp(zetabci*here->HICUMln_qtt0+model->HICUMvgc/here->HICUMvt*(here->HICUMqtt0-1)); + //External b-c diode saturation currents + here->HICUMibcxs_t = model->HICUMibcxs*exp(zetabcxt*here->HICUMln_qtt0+model->HICUMvgc/here->HICUMvt*(here->HICUMqtt0-1)); + //Saturation transfer current for substrate transistor + here->HICUMitss_t = model->HICUMitss*exp(zetasct*here->HICUMln_qtt0+model->HICUMvgc/here->HICUMvt*(here->HICUMqtt0-1)); + //Saturation current for c-s diode + here->HICUMiscs_t = model->HICUMiscs*exp(zetasct*here->HICUMln_qtt0+model->HICUMvgs/here->HICUMvt*(here->HICUMqtt0-1)); + //Zero bias hole charge + a = exp(model->HICUMzei*log(here->HICUMvdei_t/model->HICUMvdei)); + here->HICUMqp0_t = model->HICUMqp0*(2.0-a); + //Voltage separating ohmic and saturation velocity regime + here->HICUMvlim_t = model->HICUMvlim*exp((model->HICUMzetaci-avs)*here->HICUMln_qtt0); + //Neutral emitter storage time + if (model->HICUMflcomp >= 2.3) { + here->HICUMtef0_t = model->HICUMtef0; + } else { + zetatef = model->HICUMzetabet-model->HICUMzetact-0.5; + dvg0 = model->HICUMvgb-model->HICUMvge; + here->HICUMtef0_t = model->HICUMtef0*exp(zetatef*here->HICUMln_qtt0-dvg0/here->HICUMvt*(here->HICUMqtt0-1)); + } + } + + //GICCR prefactor + here->HICUMc10_t = model->HICUMc10*exp(model->HICUMzetact*here->HICUMln_qtt0+model->HICUMvgb/here->HICUMvt*(here->HICUMqtt0-1)); + + // Low-field internal collector resistance + here->HICUMrci0_t = model->HICUMrci0*exp(model->HICUMzetaci*here->HICUMln_qtt0); + + //Voltage separating ohmic and saturation velocity regime + //vlim_t = model->HICUMvlim*exp((model->HICUMzetaci-avs)*here->HICUMln_qtt0); + + //Internal c-e saturation voltage + here->HICUMvces_t = model->HICUMvces*(1+model->HICUMalces*dT); + + + //Internal b-c diode saturation current + //ibcis_t = model->HICUMibcis*exp(zetabci*here->HICUMln_qtt0+model->HICUMvgc/here->HICUMvt*(here->HICUMqtt0-1)); + + //Internal b-c junction capacitance + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcjci0,model->HICUMvdci,model->HICUMzci,model->HICUMvptci,0,vgbc0,&cjci0_t,&vdci_t,&vptci_t); + here->HICUMcjci0_t = cjci0_t; + here->HICUMvdci_t = vdci_t; + here->HICUMvptci_t = vptci_t; + + //Low-current forward transit time + here->HICUMt0_t = model->HICUMt0*(1+model->HICUMalt0*dT+model->HICUMkt0*dT*dT); + + //Saturation time constant at high current densities + here->HICUMthcs_t = model->HICUMthcs*exp((model->HICUMzetaci-1)*here->HICUMln_qtt0); + + //Avalanche current factors + here->HICUMfavl_t = model->HICUMfavl*exp(model->HICUMalfav*dT); + here->HICUMqavl_t = model->HICUMqavl*exp(model->HICUMalqav*dT); + + //Zero bias internal base resistance + here->HICUMrbi0_t = model->HICUMrbi0*exp(model->HICUMzetarbi*here->HICUMln_qtt0); + + //Peripheral b-e junction capacitance + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcjep0,model->HICUMvdep,model->HICUMzep,model->HICUMajep,1,vgbe0,&cjep0_t,&vdep_t,&ajep_t); + here->HICUMcjep0_t = cjep0_t; + here->HICUMvdep_t = vdep_t; + here->HICUMajep_t = ajep_t; + + //Tunneling current factors + if (model->HICUMibets > 0) { // HICTUN_T + double a_eg,ab,aa; + ab = 1.0; + aa = 1.0; + a_eg=vgbe_t0/vgbe_t; + if(model->HICUMtunode==1 && model->HICUMcjep0 > 0.0 && model->HICUMvdep >0.0) { + ab = (here->HICUMcjep0_t/model->HICUMcjep0)*sqrt(a_eg)*vdep_t*vdep_t/(model->HICUMvdep*model->HICUMvdep); + aa = (model->HICUMvdep/vdep_t)*(model->HICUMcjep0/here->HICUMcjep0_t)*pow(a_eg,-1.5); + } else if (model->HICUMtunode==0 && model->HICUMcjei0 > 0.0 && model->HICUMvdei >0.0) { + ab = (here->HICUMcjei0_t/model->HICUMcjei0)*sqrt(a_eg)*here->HICUMvdei_t*here->HICUMvdei_t/(model->HICUMvdei*model->HICUMvdei); + aa = (model->HICUMvdei/here->HICUMvdei_t)*(model->HICUMcjei0/here->HICUMcjei0_t)*pow(a_eg,-1.5); + } + here->HICUMibets_t = model->HICUMibets*ab; + here->HICUMabet_t = model->HICUMabet*aa; + } else { + here->HICUMibets_t = 0; + here->HICUMabet_t = 1; + } + + //Depletion capacitance splitting at b-c junction + //Capacitances at peripheral and external base node + C_1 = (1.0-model->HICUMfbcpar)*(model->HICUMcjcx0+model->HICUMcbcpar); + if (C_1 >= model->HICUMcbcpar) { + cjcx01 = C_1-model->HICUMcbcpar; + cjcx02 = model->HICUMcjcx0-cjcx01; + } else { + cjcx01 = 0.0; + cjcx02 = model->HICUMcjcx0; + } + + //Temperature mapping for tunneling current is done inside HICTUN + + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,1.0,model->HICUMvdcx,model->HICUMzcx,model->HICUMvptcx,0,vgbc0,&cratio_t,&vdcx_t,&vptcx_t); + here->HICUMcjcx01_t=cratio_t*cjcx01; + here->HICUMcjcx02_t=cratio_t*cjcx02; + here->HICUMvdcx_t = vdcx_t; + here->HICUMvptcx_t = vptcx_t; + + //External b-c diode saturation currents + //ibcxs_t = model->HICUMibcxs*exp(zetabcxt*here->HICUMln_qtt0+model->HICUMvgc/here->HICUMvt*(qtt0-1)); + + //Constant external series resistances + here->HICUMrcx_t = model->HICUMrcx*exp(model->HICUMzetarcx*here->HICUMln_qtt0); + here->HICUMrbx_t = model->HICUMrbx*exp(model->HICUMzetarbx*here->HICUMln_qtt0); + here->HICUMre_t = model->HICUMre*exp(model->HICUMzetare*here->HICUMln_qtt0); + + //Forward transit time in substrate transistor + here->HICUMtsf_t = model->HICUMtsf*exp((model->HICUMzetacx-1.0)*here->HICUMln_qtt0); + + //Capacitance for c-s junction + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcjs0,model->HICUMvds,model->HICUMzs,model->HICUMvpts,0,vgsc0,&cjs0_t,&vds_t,&vpts_t); + here->HICUMcjs0_t = cjs0_t; + here->HICUMvds_t = vds_t; + here->HICUMvpts_t = vpts_t; + /*Peripheral s-c capacitance + * Note, thermal update only required for model->HICUMvds > 0 + * Save computional effort otherwise + */ + if (model->HICUMvdsp > 0) { + TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcscp0,model->HICUMvdsp,model->HICUMzsp,model->HICUMvptsp,0,vgsc0,&cscp0_t,&vdsp_t,&vptsp_t); + here->HICUMcscp0_t = cscp0_t; + here->HICUMvdsp_t = vdsp_t; + here->HICUMvptsp_t = vptsp_t; + } else { + // Avoid uninitialized variables + here->HICUMcscp0_t = model->HICUMcscp0; + here->HICUMvdsp_t = model->HICUMvdsp; + here->HICUMvptsp_t = model->HICUMvptsp; + } + + here->HICUMahjei_t = model->HICUMahjei*exp(model->HICUMzetahjei*here->HICUMln_qtt0); + here->HICUMhjei0_t = model->HICUMhjei*exp(model->HICUMdvgbe/here->HICUMvt*(exp(model->HICUMzetavgbe*log(here->HICUMqtt0))-1)); + here->HICUMhf0_t = model->HICUMhf0*exp(model->HICUMdvgbe/here->HICUMvt*(here->HICUMqtt0-1)); + if (model->HICUMflcomp >= 2.3) { + here->HICUMhfe_t = model->HICUMhfe*exp((model->HICUMvgb-model->HICUMvge)/here->HICUMvt*(here->HICUMqtt0-1)); + here->HICUMhfc_t = model->HICUMhfc*exp((model->HICUMvgb-model->HICUMvgc)/here->HICUMvt*(here->HICUMqtt0-1)); + } else { + here->HICUMhfe_t = model->HICUMhfe; + here->HICUMhfc_t = model->HICUMhfc; + } + + here->HICUMrth_t = model->HICUMrth*exp(model->HICUMzetarth*here->HICUMln_qtt0)*(1+model->HICUMalrth*dT); + + return(0); +} + diff --git a/src/spicelib/devices/hicum2/hicumtrunc.c b/src/spicelib/devices/hicum2/hicumtrunc.c new file mode 100644 index 000000000..b6673a5fb --- /dev/null +++ b/src/spicelib/devices/hicum2/hicumtrunc.c @@ -0,0 +1,44 @@ +/********** +Copyright 1990 Regents of the University of California. All rights reserved. +Author: 1985 Thomas L. Quarles +Model Author: 1990 Michael Schröter TU Dresden +Spice3 Implementation: 2019 Dietmar Warning +**********/ + +/* + * This routine performs truncation error calculations for + * HICUMs in the circuit. + */ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "hicumdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" + + +int +HICUMtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) +{ + HICUMmodel *model = (HICUMmodel*)inModel; + HICUMinstance *here; + + for( ; model != NULL; model = HICUMnextModel(model)) { + for(here=HICUMinstances(model);here!=NULL; + here = HICUMnextInstance(here)){ + + CKTterr(here->HICUMqrbi, ckt, timeStep); + CKTterr(here->HICUMqjei, ckt, timeStep); + CKTterr(here->HICUMqdeix, ckt, timeStep); + CKTterr(here->HICUMqjci, ckt, timeStep); + CKTterr(here->HICUMqdci, ckt, timeStep); + CKTterr(here->HICUMqjep, ckt, timeStep); + CKTterr(here->HICUMqjcx0_i, ckt, timeStep); + CKTterr(here->HICUMqjcx0_ii, ckt, timeStep); + CKTterr(here->HICUMqdsu, ckt, timeStep); + CKTterr(here->HICUMqjs, ckt, timeStep); + CKTterr(here->HICUMqscp, ckt, timeStep); + } + } + return(OK); +}