diff --git a/src/spicelib/devices/bjt/bjt.c b/src/spicelib/devices/bjt/bjt.c index f0d668f7f..acff3f300 100644 --- a/src/spicelib/devices/bjt/bjt.c +++ b/src/spicelib/devices/bjt/bjt.c @@ -40,14 +40,14 @@ IFparm BJTpTable[] = { /* parameters */ "Internal emitter node"), OP("ic", BJT_QUEST_CC, IF_REAL, "Current at collector node"), OP("ib", BJT_QUEST_CB, IF_REAL, "Current at base node"), - OP("ie", BJT_QUEST_CE, IF_REAL, "Emitter current"), + OP("ie", BJT_QUEST_CE, IF_REAL, "Emitter current"), OPU("is", BJT_QUEST_CS, IF_REAL, "Substrate current"), OP("vbe", BJT_QUEST_VBE, IF_REAL, "B-E voltage"), OP("vbc", BJT_QUEST_VBC, IF_REAL, "B-C voltage"), OP("gm", BJT_QUEST_GM, IF_REAL, "Small signal transconductance"), OP("gpi", BJT_QUEST_GPI, IF_REAL, "Small signal input conductance - pi"), OP("gmu", BJT_QUEST_GMU, IF_REAL, "Small signal conductance - mu"), - OP("gx", BJT_QUEST_GX, IF_REAL, "Conductance from base to internal base"), + OP("gx", BJT_QUEST_GX, IF_REAL, "Conductance from base to internal base"), OP("go", BJT_QUEST_GO, IF_REAL, "Small signal output conductance"), OPU("geqcb",BJT_QUEST_GEQCB,IF_REAL, "d(Ibe)/d(Vbc)"), OPU("gccs", BJT_QUEST_GCCS, IF_REAL, "Internal C-S cap. equiv. cond."), @@ -58,22 +58,22 @@ IFparm BJTpTable[] = { /* parameters */ OP("cbx",BJT_QUEST_CBX, IF_REAL, "Base to collector capacitance"), OP("ccs",BJT_QUEST_CCS, IF_REAL, "Collector to substrate capacitance"), - OPU("cqbe",BJT_QUEST_CQBE, IF_REAL, "Cap. due to charge storage in B-E jct."), - OPU("cqbc",BJT_QUEST_CQBC, IF_REAL, "Cap. due to charge storage in B-C jct."), + OPU("cqbe", BJT_QUEST_CQBE, IF_REAL, "Cap. due to charge storage in B-E jct."), + OPU("cqbc", BJT_QUEST_CQBC, IF_REAL, "Cap. due to charge storage in B-C jct."), OPU("cqcs", BJT_QUEST_CQCS, IF_REAL, "Cap. due to charge storage in C-S jct."), OPU("cqbx", BJT_QUEST_CQBX, IF_REAL, "Cap. due to charge storage in B-X jct."), OPU("cexbc",BJT_QUEST_CEXBC,IF_REAL, "Total Capacitance in B-X junction"), OPU("qbe", BJT_QUEST_QBE, IF_REAL, "Charge storage B-E junction"), - OPU("qbc", BJT_QUEST_QBC, IF_REAL, "Charge storage B-C junction"), + OPU("qbc", BJT_QUEST_QBC, IF_REAL, "Charge storage B-C junction"), OPU("qcs", BJT_QUEST_QCS, IF_REAL, "Charge storage C-S junction"), OPU("qbx", BJT_QUEST_QBX, IF_REAL, "Charge storage B-X junction"), OPU("p", BJT_QUEST_POWER,IF_REAL, "Power dissipation"), OPU("sens_dc", BJT_QUEST_SENS_DC, IF_REAL, "dc sensitivity "), OPU("sens_real", BJT_QUEST_SENS_REAL, IF_REAL,"real part of ac sensitivity"), - OPU("sens_imag",BJT_QUEST_SENS_IMAG,IF_REAL, + OPU("sens_imag", BJT_QUEST_SENS_IMAG,IF_REAL, "dc sens. & imag part of ac sens."), - OPU("sens_mag", BJT_QUEST_SENS_MAG, IF_REAL, "sensitivity of ac magnitude"), + OPU("sens_mag", BJT_QUEST_SENS_MAG, IF_REAL, "sensitivity of ac magnitude"), OPU("sens_ph", BJT_QUEST_SENS_PH, IF_REAL, "sensitivity of ac phase"), OPU("sens_cplx", BJT_QUEST_SENS_CPLX, IF_COMPLEX, "ac sensitivity"), IOPU("temp", BJT_TEMP, IF_REAL, "instance temperature"), @@ -81,9 +81,9 @@ IFparm BJTpTable[] = { /* parameters */ }; IFparm BJTmPTable[] = { /* model parameters */ - OP("type", BJT_MOD_TYPE, IF_STRING, "NPN or PNP"), - IOPU("npn", BJT_MOD_NPN, IF_FLAG, "NPN type device"), - IOPU("pnp", BJT_MOD_PNP, IF_FLAG, "PNP type device"), + OP("type", BJT_MOD_TYPE, IF_STRING, "NPN or PNP"), + IOPU("npn", BJT_MOD_NPN, IF_FLAG, "NPN type device"), + IOPU("pnp", BJT_MOD_PNP, IF_FLAG, "PNP type device"), IOP("is", BJT_MOD_IS, IF_REAL, "Saturation Current"), IOP("bf", BJT_MOD_BF, IF_REAL, "Ideal forward beta"), IOP("nf", BJT_MOD_NF, IF_REAL, "Forward emission coefficient"), @@ -112,27 +112,27 @@ IFparm BJTmPTable[] = { /* model parameters */ IOP("re", BJT_MOD_RE, IF_REAL, "Emitter resistance"), IOP("rc", BJT_MOD_RC, IF_REAL, "Collector resistance"), IOPA("cje", BJT_MOD_CJE, IF_REAL,"Zero bias B-E depletion capacitance"), - IOPA("vje", BJT_MOD_VJE, IF_REAL, "B-E built in potential"), + IOPA("vje", BJT_MOD_VJE, IF_REAL, "B-E built in potential"), IOPR("pe", BJT_MOD_VJE, IF_REAL, "B-E built in potential"), - IOPA("mje", BJT_MOD_MJE, IF_REAL, "B-E junction grading coefficient"), + IOPA("mje", BJT_MOD_MJE, IF_REAL, "B-E junction grading coefficient"), IOPR("me", BJT_MOD_MJE, IF_REAL, "B-E junction grading coefficient"), IOPA("tf", BJT_MOD_TF, IF_REAL, "Ideal forward transit time"), - IOPA("xtf", BJT_MOD_XTF, IF_REAL, "Coefficient for bias dependence of TF"), - IOPA("vtf", BJT_MOD_VTF, IF_REAL, "Voltage giving VBC dependence of TF"), - IOPA("itf", BJT_MOD_ITF, IF_REAL, "High current dependence of TF"), - IOPA("ptf", BJT_MOD_PTF, IF_REAL, "Excess phase"), - IOPA("cjc", BJT_MOD_CJC, IF_REAL, "Zero bias B-C depletion capacitance"), - IOPA("vjc", BJT_MOD_VJC, IF_REAL, "B-C built in potential"), + IOPA("xtf", BJT_MOD_XTF, IF_REAL, "Coefficient for bias dependence of TF"), + IOPA("vtf", BJT_MOD_VTF, IF_REAL, "Voltage giving VBC dependence of TF"), + IOPA("itf", BJT_MOD_ITF, IF_REAL, "High current dependence of TF"), + IOPA("ptf", BJT_MOD_PTF, IF_REAL, "Excess phase"), + IOPA("cjc", BJT_MOD_CJC, IF_REAL, "Zero bias B-C depletion capacitance"), + IOPA("vjc", BJT_MOD_VJC, IF_REAL, "B-C built in potential"), IOPR("pc", BJT_MOD_VJC, IF_REAL, "B-C built in potential"), - IOPA("mjc", BJT_MOD_MJC, IF_REAL, "B-C junction grading coefficient"), + IOPA("mjc", BJT_MOD_MJC, IF_REAL, "B-C junction grading coefficient"), IOPR("mc", BJT_MOD_MJC, IF_REAL, "B-C junction grading coefficient"), IOPA("xcjc",BJT_MOD_XCJC, IF_REAL, "Fraction of B-C cap to internal base"), IOPA("tr", BJT_MOD_TR, IF_REAL, "Ideal reverse transit time"), IOPA("cjs", BJT_MOD_CJS, IF_REAL, "Zero bias C-S capacitance"), IOPA("ccs", BJT_MOD_CJS, IF_REAL, "Zero bias C-S capacitance"), - IOPA("vjs", BJT_MOD_VJS, IF_REAL, "Substrate junction built in potential"), + IOPA("vjs", BJT_MOD_VJS, IF_REAL, "Substrate junction built in potential"), IOPR("ps", BJT_MOD_VJS, IF_REAL, "Substrate junction built in potential"), - IOPA("mjs", BJT_MOD_MJS, IF_REAL, "Substrate junction grading coefficient"), + IOPA("mjs", BJT_MOD_MJS, IF_REAL, "Substrate junction grading coefficient"), IOPR("ms", BJT_MOD_MJS, IF_REAL, "Substrate junction grading coefficient"), IOP("xtb", BJT_MOD_XTB, IF_REAL, "Forward and reverse beta temp. exp."), IOP("eg", BJT_MOD_EG, IF_REAL, "Energy gap for IS temp. dependency"), @@ -140,16 +140,66 @@ IFparm BJTmPTable[] = { /* model parameters */ IOP("fc", BJT_MOD_FC, IF_REAL, "Forward bias junction fit parameter"), OPU("invearlyvoltf",BJT_MOD_INVEARLYF,IF_REAL,"Inverse early voltage:forward"), OPU("invearlyvoltr",BJT_MOD_INVEARLYR,IF_REAL,"Inverse early voltage:reverse"), - OPU("invrollofff",BJT_MOD_INVROLLOFFF, IF_REAL,"Inverse roll off - forward"), - OPU("invrolloffr",BJT_MOD_INVROLLOFFR, IF_REAL,"Inverse roll off - reverse"), + OPU("invrollofff", BJT_MOD_INVROLLOFFF, IF_REAL,"Inverse roll off - forward"), + OPU("invrolloffr", BJT_MOD_INVROLLOFFR, IF_REAL,"Inverse roll off - reverse"), OPU("collectorconduct",BJT_MOD_COLCONDUCT,IF_REAL,"Collector conductance"), OPU("emitterconduct", BJT_MOD_EMITTERCONDUCT,IF_REAL, "Emitter conductance"), OPU("transtimevbcfact",BJT_MOD_TRANSVBCFACT,IF_REAL,"Transit time VBC factor"), - OPU("excessphasefactor",BJT_MOD_EXCESSPHASEFACTOR,IF_REAL, - "Excess phase fact."), + OPU("excessphasefactor",BJT_MOD_EXCESSPHASEFACTOR,IF_REAL, "Excess phase fact."), IOP("tnom", BJT_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), - IOP("kf", BJT_MOD_KF, IF_REAL, "Flicker Noise Coefficient"), - IOP("af",BJT_MOD_AF, IF_REAL,"Flicker Noise Exponent") + + IOPR("tref", BJT_MOD_TNOM, IF_REAL, "Parameter measurement temperature"), + IOP("tlev", BJT_MOD_TLEV, IF_REAL, "Temperature equation selector"), + IOP("tlevc", BJT_MOD_TLEVC, IF_REAL, "Temperature equation selector"), + IOP("tbf1", BJT_MOD_TBF1, IF_REAL, "BF 1. temperature coefficient"), + IOP("tbf2", BJT_MOD_TBF2, IF_REAL, "BF 2. temperature coefficient"), + IOP("tbr1", BJT_MOD_TBR1, IF_REAL, "BR 1. temperature coefficient"), + IOP("tbr2", BJT_MOD_TBR2, IF_REAL, "BR 2. temperature coefficient"), + IOP("tikf1", BJT_MOD_TIKF1, IF_REAL, "IKF 1. temperature coefficient"), + IOP("tikf2", BJT_MOD_TIKF2, IF_REAL, "IKF 2. temperature coefficient"), + IOP("tikr1", BJT_MOD_TIKR1, IF_REAL, "IKR 1. temperature coefficient"), + IOP("tikr2", BJT_MOD_TIKR2, IF_REAL, "IKR 2. temperature coefficient"), + IOP("tirb1", BJT_MOD_TIRB1, IF_REAL, "IRB 1. temperature coefficient"), + IOP("tirb2", BJT_MOD_TIRB2, IF_REAL, "IRB 2. temperature coefficient"), + IOP("tnc1", BJT_MOD_TNC1, IF_REAL, "NC 1. temperature coefficient"), + IOP("tnc2", BJT_MOD_TNC2, IF_REAL, "NC 2. temperature coefficient"), + IOP("tne1", BJT_MOD_TNE1, IF_REAL, "NE 1. temperature coefficient"), + IOP("tne2", BJT_MOD_TNE2, IF_REAL, "NE 2. temperature coefficient"), + IOP("tnf1", BJT_MOD_TNF1, IF_REAL, "NF 1. temperature coefficient"), + IOP("tnf2", BJT_MOD_TNF2, IF_REAL, "NF 2. temperature coefficient"), + IOP("tnr1", BJT_MOD_TNR1, IF_REAL, "NR 1. temperature coefficient"), + IOP("tnr2", BJT_MOD_TNR2, IF_REAL, "NR 2. temperature coefficient"), + IOP("trb1", BJT_MOD_TRB1, IF_REAL, "RB 1. temperature coefficient"), + IOP("trb2", BJT_MOD_TRB2, IF_REAL, "RB 2. temperature coefficient"), + IOP("trc1", BJT_MOD_TRC1, IF_REAL, "RC 1. temperature coefficient"), + IOP("trc2", BJT_MOD_TRC2, IF_REAL, "RC 2. temperature coefficient"), + IOP("tre1", BJT_MOD_TRE1, IF_REAL, "RE 1. temperature coefficient"), + IOP("tre2", BJT_MOD_TRE2, IF_REAL, "RE 2. temperature coefficient"), + IOP("trm1", BJT_MOD_TRM1, IF_REAL, "RBM 1. temperature coefficient"), + IOP("trm2", BJT_MOD_TRM2, IF_REAL, "RBM 2. temperature coefficient"), + IOP("tvaf1", BJT_MOD_TVAF1, IF_REAL, "VAF 1. temperature coefficient"), + IOP("tvaf2", BJT_MOD_TVAF2, IF_REAL, "VAF 2. temperature coefficient"), + IOP("tvar1", BJT_MOD_TVAR1, IF_REAL, "VAR 1. temperature coefficient"), + IOP("tvar2", BJT_MOD_TVAR2, IF_REAL, "VAR 2. temperature coefficient"), + IOP("ctc", BJT_MOD_CTC, IF_REAL, "CJC temperature coefficient"), + IOP("cte", BJT_MOD_CTE, IF_REAL, "CJE temperature coefficient"), + IOP("cts", BJT_MOD_CTS, IF_REAL, "CJS temperature coefficient"), + IOP("tvjc", BJT_MOD_TVJC, IF_REAL, "VJC temperature coefficient"), + IOP("tvje", BJT_MOD_TVJE, IF_REAL, "VJE temperature coefficient"), + IOP("tvjs", BJT_MOD_TVJS, IF_REAL, "VJS temperature coefficient"), + IOP("titf1",BJT_MOD_TITF1, IF_REAL, "ITF 1. temperature coefficient"), + IOP("titf2",BJT_MOD_TITF2, IF_REAL, "ITF 2. temperature coefficient"), + IOP("ttf1", BJT_MOD_TTF1, IF_REAL, "TF 1. temperature coefficient"), + IOP("ttf2", BJT_MOD_TTF2, IF_REAL, "TF 2. temperature coefficient"), + IOP("ttr1", BJT_MOD_TTR1, IF_REAL, "TR 1. temperature coefficient"), + IOP("ttr2", BJT_MOD_TTR2, IF_REAL, "TR 2. temperature coefficient"), + IOP("tmje1",BJT_MOD_TMJE1, IF_REAL, "MJE 1. temperature coefficient"), + IOP("tmje2",BJT_MOD_TMJE2, IF_REAL, "MJE 2. temperature coefficient"), + IOP("tmjc1",BJT_MOD_TMJC1, IF_REAL, "MJC 1. temperature coefficient"), + IOP("tmjc2",BJT_MOD_TMJC2, IF_REAL, "MJC 2. temperature coefficient"), + + IOP("kf", BJT_MOD_KF, IF_REAL, "Flicker Noise Coefficient"), + IOP("af", BJT_MOD_AF, IF_REAL,"Flicker Noise Exponent") }; char *BJTnames[] = { diff --git a/src/spicelib/devices/bjt/bjtacld.c b/src/spicelib/devices/bjt/bjtacld.c index 70a9709c9..42cdf6d80 100644 --- a/src/spicelib/devices/bjt/bjtacld.c +++ b/src/spicelib/devices/bjt/bjtacld.c @@ -44,8 +44,8 @@ BJTacLoad(GENmodel *inModel, CKTcircuit *ckt) m = here->BJTm; - gcpr=model->BJTcollectorConduct * here->BJTarea; - gepr=model->BJTemitterConduct * here->BJTarea; + gcpr=here->BJTtcollectorConduct * here->BJTarea; + gepr=here->BJTtemitterConduct * here->BJTarea; gpi= *(ckt->CKTstate0 + here->BJTgpi); gmu= *(ckt->CKTstate0 + here->BJTgmu); gm= *(ckt->CKTstate0 + here->BJTgm); diff --git a/src/spicelib/devices/bjt/bjtdefs.h b/src/spicelib/devices/bjt/bjtdefs.h index f0f9f46af..2c02c091f 100644 --- a/src/spicelib/devices/bjt/bjtdefs.h +++ b/src/spicelib/devices/bjt/bjtdefs.h @@ -42,8 +42,8 @@ typedef struct sBJTinstance { double BJTtSatCur; /* temperature adjusted saturation current */ double BJTtBetaF; /* temperature adjusted forward beta */ double BJTtBetaR; /* temperature adjusted reverse beta */ - double BJTtBEleakCur; /* temperature adjusted B-E leakage current */ - double BJTtBCleakCur; /* temperature adjusted B-C leakage current */ + double BJTtBEleakCur; /* temperature adjusted B-E leakage current */ + double BJTtBCleakCur; /* temperature adjusted B-C leakage current */ double BJTtBEcap; /* temperature adjusted B-E capacitance */ double BJTtBEpot; /* temperature adjusted B-E potential */ double BJTtBCcap; /* temperature adjusted B-C capacitance */ @@ -53,6 +53,24 @@ typedef struct sBJTinstance { double BJTtf4; /* temperature adjusted polynomial coefficient */ double BJTtf5; /* temperature adjusted polynomial coefficient */ double BJTtVcrit; /* temperature adjusted critical voltage */ + double BJTtcollectorConduct; /* temperature adjusted */ + double BJTtemitterConduct; /* temperature adjusted */ + double BJTtbaseResist; /* temperature adjusted */ + double BJTtbaseCurrentHalfResist; /* temperature adjusted */ + double BJTtminBaseResist; /* temperature adjusted */ + double BJTtinvEarlyVoltF; /* temperature adjusted */ + double BJTtinvEarlyVoltR; /* temperature adjusted */ + double BJTtinvRollOffF; /* temperature adjusted */ + double BJTtinvRollOffR; /* temperature adjusted */ + double BJTtemissionCoeffF; /* temperature adjusted */ + double BJTtemissionCoeffR; /* temperature adjusted */ + double BJTtleakBEemissionCoeff; /* temperature adjusted */ + double BJTtleakBCemissionCoeff; /* temperature adjusted */ + double BJTttransitTimeHighCurrentF; /* temperature adjusted */ + double BJTttransitTimeF; /* temperature adjusted */ + double BJTttransitTimeR; /* temperature adjusted */ + double BJTtjunctionExpBE; /* temperature adjusted */ + double BJTtjunctionExpBC; /* temperature adjusted */ double *BJTcolColPrimePtr; /* pointer to sparse matrix at * (collector,collector prime) */ @@ -339,7 +357,55 @@ typedef struct sBJTmodel { /* model structure for a bjt */ double BJTdepletionCapCoeff; double BJTfNcoef; double BJTfNexp; - + unsigned BJTtlev; + unsigned BJTtlevc; + double BJTtbf1; + double BJTtbf2; + double BJTtbr1; + double BJTtbr2; + double BJTtikf1; + double BJTtikf2; + double BJTtikr1; + double BJTtikr2; + double BJTtirb1; + double BJTtirb2; + double BJTtnc1; + double BJTtnc2; + double BJTtne1; + double BJTtne2; + double BJTtnf1; + double BJTtnf2; + double BJTtnr1; + double BJTtnr2; + double BJTtrb1; + double BJTtrb2; + double BJTtrc1; + double BJTtrc2; + double BJTtre1; + double BJTtre2; + double BJTtrm1; + double BJTtrm2; + double BJTtvaf1; + double BJTtvaf2; + double BJTtvar1; + double BJTtvar2; + double BJTctc; + double BJTcte; + double BJTcts; + double BJTtvjc; + double BJTtvje; + double BJTtvjs; + double BJTtitf1; + double BJTtitf2; + double BJTttf1; + double BJTttf2; + double BJTttr1; + double BJTttr2; + double BJTtmje1; + double BJTtmje2; + double BJTtmjc1; + double BJTtmjc2; + double BJTinvEarlyVoltF; /* inverse of BJTearlyVoltF */ double BJTinvEarlyVoltR; /* inverse of BJTearlyVoltR */ double BJTinvRollOffF; /* inverse of BJTrollOffF */ @@ -396,6 +462,54 @@ typedef struct sBJTmodel { /* model structure for a bjt */ unsigned BJTdepletionCapCoeffGiven : 1; unsigned BJTfNcoefGiven : 1; unsigned BJTfNexpGiven :1; + unsigned BJTtlevGiven : 1; + unsigned BJTtlevcGiven : 1; + unsigned BJTtbf1Given : 1; + unsigned BJTtbf2Given : 1; + unsigned BJTtbr1Given : 1; + unsigned BJTtbr2Given : 1; + unsigned BJTtikf1Given : 1; + unsigned BJTtikf2Given : 1; + unsigned BJTtikr1Given : 1; + unsigned BJTtikr2Given : 1; + unsigned BJTtirb1Given : 1; + unsigned BJTtirb2Given : 1; + unsigned BJTtnc1Given : 1; + unsigned BJTtnc2Given : 1; + unsigned BJTtne1Given : 1; + unsigned BJTtne2Given : 1; + unsigned BJTtnf1Given : 1; + unsigned BJTtnf2Given : 1; + unsigned BJTtnr1Given : 1; + unsigned BJTtnr2Given : 1; + unsigned BJTtrb1Given : 1; + unsigned BJTtrb2Given : 1; + unsigned BJTtrc1Given : 1; + unsigned BJTtrc2Given : 1; + unsigned BJTtre1Given : 1; + unsigned BJTtre2Given : 1; + unsigned BJTtrm1Given : 1; + unsigned BJTtrm2Given : 1; + unsigned BJTtvaf1Given : 1; + unsigned BJTtvaf2Given : 1; + unsigned BJTtvar1Given : 1; + unsigned BJTtvar2Given : 1; + unsigned BJTctcGiven : 1; + unsigned BJTcteGiven : 1; + unsigned BJTctsGiven : 1; + unsigned BJTtvjcGiven : 1; + unsigned BJTtvjeGiven : 1; + unsigned BJTtvjsGiven : 1; + unsigned BJTtitf1Given : 1; + unsigned BJTtitf2Given : 1; + unsigned BJTttf1Given : 1; + unsigned BJTttf2Given : 1; + unsigned BJTttr1Given : 1; + unsigned BJTttr2Given : 1; + unsigned BJTtmje1Given : 1; + unsigned BJTtmje2Given : 1; + unsigned BJTtmjc1Given : 1; + unsigned BJTtmjc2Given : 1; } BJTmodel; #ifndef NPN @@ -460,8 +574,56 @@ typedef struct sBJTmodel { /* model structure for a bjt */ #define BJT_MOD_XTI 141 #define BJT_MOD_FC 142 #define BJT_MOD_TNOM 143 -#define BJT_MOD_AF 144 -#define BJT_MOD_KF 145 +#define BJT_MOD_TLEV 144 +#define BJT_MOD_TLEVC 145 +#define BJT_MOD_TBF1 146 +#define BJT_MOD_TBF2 147 +#define BJT_MOD_TBR1 148 +#define BJT_MOD_TBR2 149 +#define BJT_MOD_TIKF1 150 +#define BJT_MOD_TIKF2 151 +#define BJT_MOD_TIKR1 152 +#define BJT_MOD_TIKR2 153 +#define BJT_MOD_TIRB1 154 +#define BJT_MOD_TIRB2 155 +#define BJT_MOD_TNC1 156 +#define BJT_MOD_TNC2 157 +#define BJT_MOD_TNE1 158 +#define BJT_MOD_TNE2 159 +#define BJT_MOD_TNF1 160 +#define BJT_MOD_TNF2 161 +#define BJT_MOD_TNR1 162 +#define BJT_MOD_TNR2 163 +#define BJT_MOD_TRB1 164 +#define BJT_MOD_TRB2 165 +#define BJT_MOD_TRC1 166 +#define BJT_MOD_TRC2 167 +#define BJT_MOD_TRE1 168 +#define BJT_MOD_TRE2 169 +#define BJT_MOD_TRM1 170 +#define BJT_MOD_TRM2 171 +#define BJT_MOD_TVAF1 172 +#define BJT_MOD_TVAF2 173 +#define BJT_MOD_TVAR1 174 +#define BJT_MOD_TVAR2 175 +#define BJT_MOD_CTC 176 +#define BJT_MOD_CTE 177 +#define BJT_MOD_CTS 178 +#define BJT_MOD_TVJC 179 +#define BJT_MOD_TVJE 180 +#define BJT_MOD_TVJS 181 +#define BJT_MOD_AF 182 +#define BJT_MOD_KF 183 +#define BJT_MOD_TITF1 184 +#define BJT_MOD_TITF2 185 +#define BJT_MOD_TTF1 186 +#define BJT_MOD_TTF2 187 +#define BJT_MOD_TTR1 188 +#define BJT_MOD_TTR2 189 +#define BJT_MOD_TMJE1 190 +#define BJT_MOD_TMJE2 191 +#define BJT_MOD_TMJC1 192 +#define BJT_MOD_TMJC2 192 /* device questions */ #define BJT_QUEST_FT 201 diff --git a/src/spicelib/devices/bjt/bjtdset.c b/src/spicelib/devices/bjt/bjtdset.c index 4823b5d0d..ea333526f 100644 --- a/src/spicelib/devices/bjt/bjtdset.c +++ b/src/spicelib/devices/bjt/bjtdset.c @@ -154,15 +154,15 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) * dc model paramters */ csat=here->BJTtSatCur*here->BJTarea * here->BJTm; - rbpr=model->BJTminBaseResist/(here->BJTarea * here->BJTm); - rbpi=model->BJTbaseResist/(here->BJTarea * here->BJTm)-rbpr; - oik=model->BJTinvRollOffF/(here->BJTarea * here->BJTm); + rbpr=here->BJTtminBaseResist/(here->BJTarea * here->BJTm); + rbpi=here->BJTtbaseResist/(here->BJTarea * here->BJTm)-rbpr; + oik=here->BJTtinvRollOffF/(here->BJTarea * here->BJTm); c2=here->BJTtBEleakCur*here->BJTarea * here->BJTm; - vte=model->BJTleakBEemissionCoeff*vt; - oikr=model->BJTinvRollOffR/(here->BJTarea * here->BJTm); + vte=here->BJTtleakBEemissionCoeff*vt; + oikr=here->BJTtinvRollOffR/(here->BJTarea * here->BJTm); c4=here->BJTtBCleakCur*here->BJTareab * here->BJTm; - vtc=model->BJTleakBCemissionCoeff*vt; - xjrb=model->BJTbaseCurrentHalfResist*here->BJTarea * here->BJTm; + vtc=here->BJTtleakBCemissionCoeff*vt; + xjrb=here->BJTtbaseCurrentHalfResist*here->BJTarea * here->BJTm; /* @@ -221,7 +221,7 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) /* * determine dc current and derivitives */ - vtn=vt*model->BJTemissionCoeffF; + vtn=vt*here->BJTtemissionCoeffF; if(vbe > -5*vtn){ evbe=exp(vbe/vtn); cbe=csat*(evbe-1)+ckt->CKTgmin*vbe; @@ -249,7 +249,7 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) gben = -c2/vbe; cben=gben*vbe; } - vtn=vt*model->BJTemissionCoeffR; + vtn=vt*here->BJTtemissionCoeffR; if(vbc > -5*vtn) { evbc=exp(vbc/vtn); cbc=csat*(evbc-1)+ckt->CKTgmin*vbc; @@ -281,13 +281,13 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) /* q1 is a function of 2 variables p=vbe and q=vbc. r= * anything */ - q1=1/(1-model->BJTinvEarlyVoltF*vbc-model->BJTinvEarlyVoltR*vbe); - dummy = (1-model->BJTinvEarlyVoltF*vbc- - model->BJTinvEarlyVoltR*vbe); + q1=1/(1-here->BJTtinvEarlyVoltF*vbc-here->BJTtinvEarlyVoltR*vbe); + dummy = (1-here->BJTtinvEarlyVoltF*vbc- + here->BJTtinvEarlyVoltR*vbe); EqualDeriv(&d_dummy, &d_p); d_dummy.value = dummy; - d_dummy.d1_p = - model->BJTinvEarlyVoltR; - d_dummy.d1_q = - model->BJTinvEarlyVoltF; + d_dummy.d1_p = - here->BJTtinvEarlyVoltR; + d_dummy.d1_q = - here->BJTtinvEarlyVoltF; /* q1 = 1/dummy */ InvDeriv(&d_q1, &d_dummy); @@ -477,24 +477,24 @@ int BJTdSetup(GENmodel *inModel, CKTcircuit *ckt) /* * charge storage elements */ - tf=model->BJTtransitTimeF; - tr=model->BJTtransitTimeR; + tf=here->BJTttransitTimeF; + tr=here->BJTttransitTimeR; czbe=here->BJTtBEcap*here->BJTarea * here->BJTm; pe=here->BJTtBEpot; - xme=model->BJTjunctionExpBE; + xme=here->BJTtjunctionExpBE; cdis=model->BJTbaseFractionBCcap; ctot=here->BJTtBCcap*here->BJTareab * here->BJTm; czbc=ctot*cdis; czbx=ctot-czbc; pc=here->BJTtBCpot; - xmc=model->BJTjunctionExpBC; + xmc=here->BJTtjunctionExpBC; fcpe=here->BJTtDepCap; czcs=model->BJTcapCS*here->BJTareac * here->BJTm; ps=model->BJTpotentialSubstrate; xms=model->BJTexponentialSubstrate; xtf=model->BJTtransitTimeBiasCoeffF; ovtf=model->BJTtransitTimeVBCFactor; - xjtf=model->BJTtransitTimeHighCurrentF*here->BJTarea * here->BJTm; + xjtf=here->BJTttransitTimeHighCurrentF*here->BJTarea * here->BJTm; if(tf != 0 && vbe >0) { EqualDeriv(&d_cbe, &d_p); d_cbe.value = cbe; diff --git a/src/spicelib/devices/bjt/bjtload.c b/src/spicelib/devices/bjt/bjtload.c index c1b622fc2..4fca609fe 100644 --- a/src/spicelib/devices/bjt/bjtload.c +++ b/src/spicelib/devices/bjt/bjtload.c @@ -20,8 +20,8 @@ Modified: 2000 AlansFixes int BJTload(GENmodel *inModel, CKTcircuit *ckt) - /* actually load the current resistance value into the - * sparse matrix previously provided + /* actually load the current resistance value into the + * sparse matrix previously provided */ { BJTmodel *model = (BJTmodel*)inModel; @@ -131,19 +131,19 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) int error; int SenCond=0; double m; - + /* loop through all the models */ for( ; model != NULL; model = model->BJTnextModel ) { /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; here=here->BJTnextInstance) { - if (here->BJTowner != ARCHme) continue; + if (here->BJTowner != ARCHme) continue; vt = here->BJTtemp * CONSTKoverQ; - - m = here->BJTm; - + + m = here->BJTm; + if(ckt->CKTsenInfo){ #ifdef SENSDEBUG printf("BJTload \n"); @@ -164,18 +164,18 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) * dc model paramters */ csat=here->BJTtSatCur*here->BJTarea; - rbpr=model->BJTminBaseResist/here->BJTarea; - rbpi=model->BJTbaseResist/here->BJTarea-rbpr; - gcpr=model->BJTcollectorConduct*here->BJTarea; - gepr=model->BJTemitterConduct*here->BJTarea; - oik=model->BJTinvRollOffF/here->BJTarea; + rbpr=here->BJTtminBaseResist/here->BJTarea; + rbpi=here->BJTtbaseResist/here->BJTarea-rbpr; + gcpr=here->BJTtcollectorConduct*here->BJTarea; + gepr=here->BJTtemitterConduct*here->BJTarea; + oik=here->BJTtinvRollOffF/here->BJTarea; c2=here->BJTtBEleakCur*here->BJTarea; - vte=model->BJTleakBEemissionCoeff*vt; - oikr=model->BJTinvRollOffR/here->BJTarea; + vte=here->BJTtleakBEemissionCoeff*vt; + oikr=here->BJTtinvRollOffR/here->BJTarea; c4=here->BJTtBCleakCur*here->BJTareab; - vtc=model->BJTleakBCemissionCoeff*vt; + vtc=here->BJTtleakBCemissionCoeff*vt; td=model->BJTexcessPhaseFactor; - xjrb=model->BJTbaseCurrentHalfResist*here->BJTarea; + xjrb=here->BJTtbaseCurrentHalfResist*here->BJTarea; if(SenCond){ #ifdef SENSDEBUG @@ -243,7 +243,7 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) vbx=model->BJTtype*(here->BJTicVBE-here->BJTicVCE); vcs=0; } - } else if((ckt->CKTmode & MODEINITJCT) && + } else if((ckt->CKTmode & MODEINITJCT) && (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){ vbe=model->BJTtype*here->BJTicVBE; vce=model->BJTtype*here->BJTicVCE; @@ -265,27 +265,27 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) #ifndef PREDICTOR if(ckt->CKTmode & MODEINITPRED) { xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; - *(ckt->CKTstate0 + here->BJTvbe) = + *(ckt->CKTstate0 + here->BJTvbe) = *(ckt->CKTstate1 + here->BJTvbe); vbe = (1+xfact)**(ckt->CKTstate1 + here->BJTvbe)- xfact* *(ckt->CKTstate2 + here->BJTvbe); - *(ckt->CKTstate0 + here->BJTvbc) = + *(ckt->CKTstate0 + here->BJTvbc) = *(ckt->CKTstate1 + here->BJTvbc); vbc = (1+xfact)**(ckt->CKTstate1 + here->BJTvbc)- xfact* *(ckt->CKTstate2 + here->BJTvbc); - *(ckt->CKTstate0 + here->BJTcc) = + *(ckt->CKTstate0 + here->BJTcc) = *(ckt->CKTstate1 + here->BJTcc); - *(ckt->CKTstate0 + here->BJTcb) = + *(ckt->CKTstate0 + here->BJTcb) = *(ckt->CKTstate1 + here->BJTcb); - *(ckt->CKTstate0 + here->BJTgpi) = + *(ckt->CKTstate0 + here->BJTgpi) = *(ckt->CKTstate1 + here->BJTgpi); - *(ckt->CKTstate0 + here->BJTgmu) = + *(ckt->CKTstate0 + here->BJTgmu) = *(ckt->CKTstate1 + here->BJTgmu); - *(ckt->CKTstate0 + here->BJTgm) = + *(ckt->CKTstate0 + here->BJTgm) = *(ckt->CKTstate1 + here->BJTgm); - *(ckt->CKTstate0 + here->BJTgo) = + *(ckt->CKTstate0 + here->BJTgo) = *(ckt->CKTstate1 + here->BJTgo); - *(ckt->CKTstate0 + here->BJTgx) = + *(ckt->CKTstate0 + here->BJTgx) = *(ckt->CKTstate1 + here->BJTgx); } else { #endif /* PREDICTOR */ @@ -309,11 +309,11 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) vcs=model->BJTtype*( *(ckt->CKTrhsOld+here->BJTsubstNode)- *(ckt->CKTrhsOld+here->BJTcolPrimeNode)); - cchat= *(ckt->CKTstate0 + here->BJTcc)+(*(ckt->CKTstate0 + + cchat= *(ckt->CKTstate0 + here->BJTcc)+(*(ckt->CKTstate0 + here->BJTgm)+ *(ckt->CKTstate0 + here->BJTgo))*delvbe- (*(ckt->CKTstate0 + here->BJTgo)+*(ckt->CKTstate0 + here->BJTgmu))*delvbc; - cbhat= *(ckt->CKTstate0 + here->BJTcb)+ *(ckt->CKTstate0 + + cbhat= *(ckt->CKTstate0 + here->BJTcb)+ *(ckt->CKTstate0 + here->BJTgpi)*delvbe+ *(ckt->CKTstate0 + here->BJTgmu)* delvbc; #ifndef NOBYPASS @@ -332,11 +332,11 @@ BJTload(GENmodel *inModel, CKTcircuit *ckt) if( (fabs(delvbc) < ckt->CKTreltol*MAX(fabs(vbc), fabs(*(ckt->CKTstate0 + here->BJTvbc)))+ ckt->CKTvoltTol) ) - if( (fabs(cchat-*(ckt->CKTstate0 + here->BJTcc)) < + if( (fabs(cchat-*(ckt->CKTstate0 + here->BJTcc)) < ckt->CKTreltol* MAX(fabs(cchat), fabs(*(ckt->CKTstate0 + here->BJTcc)))+ ckt->CKTabstol) ) - if( (fabs(cbhat-*(ckt->CKTstate0 + here->BJTcb)) < + if( (fabs(cbhat-*(ckt->CKTstate0 + here->BJTcb)) < ckt->CKTreltol* MAX(fabs(cbhat), fabs(*(ckt->CKTstate0 + here->BJTcb)))+ ckt->CKTabstol) ) { @@ -400,9 +400,9 @@ next1: vtn=vt*model->BJTemissionCoeffF; } gben+=ckt->CKTgmin; cben+=ckt->CKTgmin*vbe; - + vtn=vt*model->BJTemissionCoeffR; - + if(vbc >= -3*vtn) { evbc=exp(vbc/vtn); cbc=csat*(evbc-1); @@ -430,23 +430,23 @@ next1: vtn=vt*model->BJTemissionCoeffF; } gbcn+=ckt->CKTgmin; cbcn+=ckt->CKTgmin*vbc; - + /* * determine base charge terms */ - q1=1/(1-model->BJTinvEarlyVoltF*vbc-model->BJTinvEarlyVoltR*vbe); + q1=1/(1-here->BJTtinvEarlyVoltF*vbc-here->BJTtinvEarlyVoltR*vbe); if(oik == 0 && oikr == 0) { qb=q1; - dqbdve=q1*qb*model->BJTinvEarlyVoltR; - dqbdvc=q1*qb*model->BJTinvEarlyVoltF; + dqbdve=q1*qb*here->BJTtinvEarlyVoltR; + dqbdvc=q1*qb*here->BJTtinvEarlyVoltF; } else { q2=oik*cbe+oikr*cbc; arg=MAX(0,1+4*q2); sqarg=1; if(arg != 0) sqarg=sqrt(arg); qb=q1*(1+sqarg)/2; - dqbdve=q1*(qb*model->BJTinvEarlyVoltR+oik*gbe/sqarg); - dqbdvc=q1*(qb*model->BJTinvEarlyVoltF+oikr*gbc/sqarg); + dqbdve=q1*(qb*here->BJTtinvEarlyVoltR+oik*gbe/sqarg); + dqbdvc=q1*(qb*here->BJTtinvEarlyVoltF+oikr*gbc/sqarg); } /* * weil's approx. for excess phase applied with backward- @@ -497,24 +497,24 @@ next1: vtn=vt*model->BJTemissionCoeffF; /* * charge storage elements */ - tf=model->BJTtransitTimeF; - tr=model->BJTtransitTimeR; + tf=here->BJTttransitTimeF; + tr=here->BJTttransitTimeR; czbe=here->BJTtBEcap*here->BJTarea; pe=here->BJTtBEpot; - xme=model->BJTjunctionExpBE; + xme=here->BJTtjunctionExpBE; cdis=model->BJTbaseFractionBCcap; ctot=here->BJTtBCcap*here->BJTarea; czbc=ctot*cdis; czbx=ctot-czbc; pc=here->BJTtBCpot; - xmc=model->BJTjunctionExpBC; + xmc=here->BJTtjunctionExpBC; fcpe=here->BJTtDepCap; czcs=model->BJTcapCS*here->BJTareac; ps=model->BJTpotentialSubstrate; xms=model->BJTexponentialSubstrate; xtf=model->BJTtransitTimeBiasCoeffF; ovtf=model->BJTtransitTimeVBCFactor; - xjtf=model->BJTtransitTimeHighCurrentF*here->BJTarea; + xjtf=here->BJTttransitTimeHighCurrentF*here->BJTarea; if(tf != 0 && vbe >0) { argtf=0; arg2=0; @@ -570,7 +570,7 @@ next1: vtn=vt*model->BJTemissionCoeffF; if(vbx < fcpc) { arg=1-vbx/pc; sarg=exp(-xmc*log(arg)); - *(ckt->CKTstate0 + here->BJTqbx)= + *(ckt->CKTstate0 + here->BJTqbx)= pc*czbx* (1-arg*sarg)/(1-xmc); capbx=czbx*sarg; } else { @@ -719,18 +719,18 @@ load: /* * load current excitation vector */ - ceqcs=model->BJTtype * (*(ckt->CKTstate0 + here->BJTcqcs) - + ceqcs=model->BJTtype * (*(ckt->CKTstate0 + here->BJTcqcs) - vcs * gccs); ceqbx=model->BJTtype * (*(ckt->CKTstate0 + here->BJTcqbx) - vbx * geqbx); - ceqbe=model->BJTtype * (cc + cb - vbe * (gm + go + gpi) + vbc * + ceqbe=model->BJTtype * (cc + cb - vbe * (gm + go + gpi) + vbc * (go - geqcb)); ceqbc=model->BJTtype * (-cc + vbe * (gm + go) - vbc * (gmu + go)); *(ckt->CKTrhs + here->BJTbaseNode) += m * (-ceqbx); - *(ckt->CKTrhs + here->BJTcolPrimeNode) += + *(ckt->CKTrhs + here->BJTcolPrimeNode) += m * (ceqcs+ceqbx+ceqbc); - *(ckt->CKTrhs + here->BJTbasePrimeNode) += + *(ckt->CKTrhs + here->BJTbasePrimeNode) += m * (-ceqbe-ceqbc); *(ckt->CKTrhs + here->BJTemitPrimeNode) += m * (ceqbe); *(ckt->CKTrhs + here->BJTsubstNode) += m * (-ceqcs); diff --git a/src/spicelib/devices/bjt/bjtmask.c b/src/spicelib/devices/bjt/bjtmask.c index 377cc141c..376759c73 100644 --- a/src/spicelib/devices/bjt/bjtmask.c +++ b/src/spicelib/devices/bjt/bjtmask.c @@ -171,23 +171,137 @@ BJTmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) case BJT_MOD_EXCESSPHASEFACTOR: value->rValue = here->BJTexcessPhaseFactor; return(OK); - case BJT_MOD_KF: - if (here->BJTfNcoefGiven) - value->rValue = here->BJTfNcoef; - else - value->rValue = 0.0; - return(OK); - case BJT_MOD_AF: - if (here->BJTfNexpGiven) - value->rValue = here->BJTfNexp; - else - value->rValue = 0.0; - return(OK); - case BJT_MOD_TYPE: - if (here->BJTtype == NPN) - value->sValue = "npn"; - else - value->sValue = "pnp"; + case BJT_MOD_TLEV: + value->iValue = here->BJTtlev; + return(OK); + case BJT_MOD_TLEVC: + value->iValue = here->BJTtlevc; + return(OK); + case BJT_MOD_TBF1: + value->rValue = here->BJTtbf1; + return(OK); + case BJT_MOD_TBF2: + value->rValue = here->BJTtbf2; + return(OK); + case BJT_MOD_TBR1: + value->rValue = here->BJTtbr1; + return(OK); + case BJT_MOD_TBR2: + value->rValue = here->BJTtbr2; + return(OK); + case BJT_MOD_TIKF1: + value->rValue = here->BJTtikf1; + return(OK); + case BJT_MOD_TIKF2: + value->rValue = here->BJTtikf2; + return(OK); + case BJT_MOD_TIKR1: + value->rValue = here->BJTtikr1; + return(OK); + case BJT_MOD_TIKR2: + value->rValue = here->BJTtikr2; + return(OK); + case BJT_MOD_TIRB1: + value->rValue = here->BJTtirb1; + return(OK); + case BJT_MOD_TIRB2: + value->rValue = here->BJTtirb2; + return(OK); + case BJT_MOD_TNC1: + value->rValue = here->BJTtnc1; + return(OK); + case BJT_MOD_TNC2: + value->rValue = here->BJTtnc2; + return(OK); + case BJT_MOD_TNE1: + value->rValue = here->BJTtne1; + return(OK); + case BJT_MOD_TNE2: + value->rValue = here->BJTtne2; + return(OK); + case BJT_MOD_TNF1: + value->rValue = here->BJTtnf1; + return(OK); + case BJT_MOD_TNF2: + value->rValue = here->BJTtnf2; + return(OK); + case BJT_MOD_TNR1: + value->rValue = here->BJTtnr1; + return(OK); + case BJT_MOD_TNR2: + value->rValue = here->BJTtnr2; + return(OK); + case BJT_MOD_TRB1: + value->rValue = here->BJTtrb1; + return(OK); + case BJT_MOD_TRB2: + value->rValue = here->BJTtrb2; + return(OK); + case BJT_MOD_TRC1: + value->rValue = here->BJTtrc1; + return(OK); + case BJT_MOD_TRC2: + value->rValue = here->BJTtrc2; + return(OK); + case BJT_MOD_TRE1: + value->rValue = here->BJTtre1; + return(OK); + case BJT_MOD_TRE2: + value->rValue = here->BJTtre2; + return(OK); + case BJT_MOD_TRM1: + value->rValue = here->BJTtrm1; + return(OK); + case BJT_MOD_TRM2: + value->rValue = here->BJTtrm2; + return(OK); + case BJT_MOD_TVAF1: + value->rValue = here->BJTtvaf1; + return(OK); + case BJT_MOD_TVAF2: + value->rValue = here->BJTtvaf2; + return(OK); + case BJT_MOD_TVAR1: + value->rValue = here->BJTtvar1; + return(OK); + case BJT_MOD_TVAR2: + value->rValue = here->BJTtvar2; + return(OK); + case BJT_MOD_CTC: + value->rValue = here->BJTctc; + return(OK); + case BJT_MOD_CTE: + value->rValue = here->BJTcte; + return(OK); + case BJT_MOD_CTS: + value->rValue = here->BJTcts; + return(OK); + case BJT_MOD_TVJE: + value->rValue = here->BJTtvje; + return(OK); + case BJT_MOD_TVJC: + value->rValue = here->BJTtvjc; + return(OK); + case BJT_MOD_TVJS: + value->rValue = here->BJTtvjs; + return(OK); + case BJT_MOD_KF: + if (here->BJTfNcoefGiven) + value->rValue = here->BJTfNcoef; + else + value->rValue = 0.0; + return(OK); + case BJT_MOD_AF: + if (here->BJTfNexpGiven) + value->rValue = here->BJTfNexp; + else + value->rValue = 0.0; + return(OK); + case BJT_MOD_TYPE: + if (here->BJTtype == NPN) + value->sValue = "npn"; + else + value->sValue = "pnp"; return(OK); default: return(E_BADPARM); diff --git a/src/spicelib/devices/bjt/bjtmpar.c b/src/spicelib/devices/bjt/bjtmpar.c index d6e02a3dc..8b26d9e48 100644 --- a/src/spicelib/devices/bjt/bjtmpar.c +++ b/src/spicelib/devices/bjt/bjtmpar.c @@ -198,14 +198,166 @@ BJTmParam(int param, IFvalue *value, GENmodel *inModel) mods->BJTdepletionCapCoeff = value->rValue; mods->BJTdepletionCapCoeffGiven = TRUE; break; - case BJT_MOD_KF: - mods->BJTfNcoef = value->rValue; - mods->BJTfNcoefGiven = TRUE; - break; - case BJT_MOD_AF: - mods->BJTfNexp = value->rValue; - mods->BJTfNexpGiven = TRUE; - break; + case BJT_MOD_TLEV: + mods->BJTtlev = value->iValue; + mods->BJTtlevGiven = TRUE; + break; + case BJT_MOD_TLEVC: + mods->BJTtlevc = value->iValue; + mods->BJTtlevcGiven = TRUE; + break; + case BJT_MOD_TBF1: + mods->BJTtbf1 = value->rValue; + mods->BJTtbf1Given = TRUE; + break; + case BJT_MOD_TBF2: + mods->BJTtbf2 = value->rValue; + mods->BJTtbf2Given = TRUE; + break; + case BJT_MOD_TBR1: + mods->BJTtbr1 = value->rValue; + mods->BJTtbr1Given = TRUE; + break; + case BJT_MOD_TBR2: + mods->BJTtbr2 = value->rValue; + mods->BJTtbr2Given = TRUE; + break; + case BJT_MOD_TIKF1: + mods->BJTtikf1 = value->rValue; + mods->BJTtikf1Given = TRUE; + break; + case BJT_MOD_TIKF2: + mods->BJTtikf2 = value->rValue; + mods->BJTtikf2Given = TRUE; + break; + case BJT_MOD_TIKR1: + mods->BJTtikr1 = value->rValue; + mods->BJTtikr1Given = TRUE; + break; + case BJT_MOD_TIKR2: + mods->BJTtikr2 = value->rValue; + mods->BJTtikr2Given = TRUE; + break; + case BJT_MOD_TIRB1: + mods->BJTtirb1 = value->rValue; + mods->BJTtirb1Given = TRUE; + break; + case BJT_MOD_TIRB2: + mods->BJTtirb2 = value->rValue; + mods->BJTtirb2Given = TRUE; + break; + case BJT_MOD_TNC1: + mods->BJTtnc1 = value->rValue; + mods->BJTtnc1Given = TRUE; + break; + case BJT_MOD_TNC2: + mods->BJTtnc2 = value->rValue; + mods->BJTtnc2Given = TRUE; + break; + case BJT_MOD_TNE1: + mods->BJTtne1 = value->rValue; + mods->BJTtne1Given = TRUE; + break; + case BJT_MOD_TNE2: + mods->BJTtne2 = value->rValue; + mods->BJTtne2Given = TRUE; + break; + case BJT_MOD_TNF1: + mods->BJTtnf1 = value->rValue; + mods->BJTtnf1Given = TRUE; + break; + case BJT_MOD_TNF2: + mods->BJTtnf2 = value->rValue; + mods->BJTtnf2Given = TRUE; + break; + case BJT_MOD_TNR1: + mods->BJTtnr1 = value->rValue; + mods->BJTtnr1Given = TRUE; + break; + case BJT_MOD_TNR2: + mods->BJTtnr2 = value->rValue; + mods->BJTtnr2Given = TRUE; + break; + case BJT_MOD_TRB1: + mods->BJTtrb1 = value->rValue; + mods->BJTtrb1Given = TRUE; + break; + case BJT_MOD_TRB2: + mods->BJTtrb2 = value->rValue; + mods->BJTtrb2Given = TRUE; + break; + case BJT_MOD_TRC1: + mods->BJTtrc1 = value->rValue; + mods->BJTtrc1Given = TRUE; + break; + case BJT_MOD_TRC2: + mods->BJTtrc2 = value->rValue; + mods->BJTtrc2Given = TRUE; + break; + case BJT_MOD_TRE1: + mods->BJTtre1 = value->rValue; + mods->BJTtre1Given = TRUE; + break; + case BJT_MOD_TRE2: + mods->BJTtre2 = value->rValue; + mods->BJTtre2Given = TRUE; + break; + case BJT_MOD_TRM1: + mods->BJTtrm1 = value->rValue; + mods->BJTtrm1Given = TRUE; + break; + case BJT_MOD_TRM2: + mods->BJTtrm2 = value->rValue; + mods->BJTtrm2Given = TRUE; + break; + case BJT_MOD_TVAF1: + mods->BJTtvaf1 = value->rValue; + mods->BJTtvaf1Given = TRUE; + break; + case BJT_MOD_TVAF2: + mods->BJTtvaf2 = value->rValue; + mods->BJTtvaf2Given = TRUE; + break; + case BJT_MOD_TVAR1: + mods->BJTtvar1 = value->rValue; + mods->BJTtvar1Given = TRUE; + break; + case BJT_MOD_TVAR2: + mods->BJTtvar2 = value->rValue; + mods->BJTtvar2Given = TRUE; + break; + case BJT_MOD_CTC: + mods->BJTctc = value->rValue; + mods->BJTctcGiven = TRUE; + break; + case BJT_MOD_CTE: + mods->BJTcte = value->rValue; + mods->BJTcteGiven = TRUE; + break; + case BJT_MOD_CTS: + mods->BJTcts = value->rValue; + mods->BJTctsGiven = TRUE; + break; + case BJT_MOD_TVJE: + mods->BJTtvje = value->rValue; + mods->BJTtvjeGiven = TRUE; + break; + case BJT_MOD_TVJC: + mods->BJTtvjc = value->rValue; + mods->BJTtvjcGiven = TRUE; + break; + case BJT_MOD_TVJS: + mods->BJTtvjs = value->rValue; + mods->BJTtvjsGiven = TRUE; + break; + case BJT_MOD_KF: + mods->BJTfNcoef = value->rValue; + mods->BJTfNcoefGiven = TRUE; + break; + case BJT_MOD_AF: + mods->BJTfNexp = value->rValue; + mods->BJTfNexpGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/bjt/bjtnoise.c b/src/spicelib/devices/bjt/bjtnoise.c index 861977e43..2a4a7ae6f 100644 --- a/src/spicelib/devices/bjt/bjtnoise.c +++ b/src/spicelib/devices/bjt/bjtnoise.c @@ -49,7 +49,7 @@ BJTnoise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt, "" /* total transistor noise */ }; - for (model=firstModel; model != NULL; model=model->BJTnextModel) { +for (model=firstModel; model != NULL; model=model->BJTnextModel) { for (inst=model->BJTinstances; inst != NULL; inst=inst->BJTnextInstance) { if (inst->BJTowner != ARCHme) continue; @@ -112,7 +112,7 @@ if (!data->namelist) return(E_NOMEM); case N_DENS: NevalSrc(&noizDens[BJTRCNOIZ],&lnNdens[BJTRCNOIZ], ckt,THERMNOISE,inst->BJTcolPrimeNode,inst->BJTcolNode, - model->BJTcollectorConduct * inst->BJTarea * inst->BJTm); + inst->BJTtcollectorConduct * inst->BJTarea * inst->BJTm); NevalSrc(&noizDens[BJTRBNOIZ],&lnNdens[BJTRBNOIZ], ckt,THERMNOISE,inst->BJTbasePrimeNode,inst->BJTbaseNode, @@ -120,7 +120,7 @@ if (!data->namelist) return(E_NOMEM); NevalSrc(&noizDens[BJT_RE_NOISE],&lnNdens[BJT_RE_NOISE], ckt,THERMNOISE,inst->BJTemitPrimeNode,inst->BJTemitNode, - model->BJTemitterConduct * inst->BJTarea * inst-> BJTm); + inst->BJTtemitterConduct * inst->BJTarea * inst-> BJTm); NevalSrc(&noizDens[BJTICNOIZ],&lnNdens[BJTICNOIZ], ckt,SHOTNOISE,inst->BJTcolPrimeNode, inst->BJTemitPrimeNode, @@ -215,7 +215,7 @@ if (!data->namelist) return(E_NOMEM); break; /* the plots */ } /* switch (operation) */ } /* for inst */ - } /* for model */ +} /* for model */ return(OK); } diff --git a/src/spicelib/devices/bjt/bjtpzld.c b/src/spicelib/devices/bjt/bjtpzld.c index 5c599baf0..eefa0f11d 100644 --- a/src/spicelib/devices/bjt/bjtpzld.c +++ b/src/spicelib/devices/bjt/bjtpzld.c @@ -40,8 +40,8 @@ BJTpzLoad(GENmodel *inModel, CKTcircuit *ckt, SPcomplex *s) m = here->BJTm; - gcpr=model->BJTcollectorConduct * here->BJTarea; - gepr=model->BJTemitterConduct * here->BJTarea; + gcpr=here->BJTtcollectorConduct * here->BJTarea; + gepr=here->BJTtemitterConduct * here->BJTarea; gpi= *(ckt->CKTstate0 + here->BJTgpi); gmu= *(ckt->CKTstate0 + here->BJTgmu); gm= *(ckt->CKTstate0 + here->BJTgm); diff --git a/src/spicelib/devices/bjt/bjtsetup.c b/src/spicelib/devices/bjt/bjtsetup.c index b85afd905..a6dc825fd 100644 --- a/src/spicelib/devices/bjt/bjtsetup.c +++ b/src/spicelib/devices/bjt/bjtsetup.c @@ -4,7 +4,7 @@ Author: 1985 Thomas L. Quarles Modified: 2000 AlansFixes **********/ -/* +/* * 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 @@ -22,8 +22,8 @@ Modified: 2000 AlansFixes int BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) - /* load the BJT structure with those pointers needed later - * for fast matrix loading + /* load the BJT structure with those pointers needed later + * for fast matrix loading */ { BJTmodel *model = (BJTmodel*)inModel; @@ -121,12 +121,128 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->BJTtempExpISGiven) { model->BJTtempExpIS = 3; } - if(!model->BJTfNcoefGiven) { - model->BJTfNcoef = 0; - } - if(!model->BJTfNexpGiven) { - model->BJTfNexp = 1; - } + + if(!model->BJTtlevGiven) { + model->BJTtlev = 0; + } + if(!model->BJTtlevcGiven) { + model->BJTtlevc = 0; + } + if(!model->BJTtbf1Given) { + model->BJTtbf1 = 0.0; + } + if(!model->BJTtbf2Given) { + model->BJTtbf2 = 0.0; + } + if(!model->BJTtbr1Given) { + model->BJTtbr1 = 0.0; + } + if(!model->BJTtbr2Given) { + model->BJTtbr2 = 0.0; + } + if(!model->BJTtikf1Given) { + model->BJTtikf1 = 0.0; + } + if(!model->BJTtikf2Given) { + model->BJTtikf2 = 0.0; + } + if(!model->BJTtikr1Given) { + model->BJTtikr1 = 0.0; + } + if(!model->BJTtikr2Given) { + model->BJTtikr2 = 0.0; + } + if(!model->BJTtirb1Given) { + model->BJTtirb1 = 0.0; + } + if(!model->BJTtirb2Given) { + model->BJTtirb2 = 0.0; + } + if(!model->BJTtnc1Given) { + model->BJTtnc1 = 0.0; + } + if(!model->BJTtnc2Given) { + model->BJTtnc2 = 0.0; + } + if(!model->BJTtne1Given) { + model->BJTtne1 = 0.0; + } + if(!model->BJTtne2Given) { + model->BJTtne2 = 0.0; + } + if(!model->BJTtnf1Given) { + model->BJTtnf1 = 0.0; + } + if(!model->BJTtnf2Given) { + model->BJTtnf2 = 0.0; + } + if(!model->BJTtnr1Given) { + model->BJTtnr1 = 0.0; + } + if(!model->BJTtnr2Given) { + model->BJTtnr2 = 0.0; + } + if(!model->BJTtrb1Given) { + model->BJTtrb1 = 0.0; + } + if(!model->BJTtrb2Given) { + model->BJTtrb2 = 0.0; + } + if(!model->BJTtrc1Given) { + model->BJTtrc1 = 0.0; + } + if(!model->BJTtrc2Given) { + model->BJTtrc2 = 0.0; + } + if(!model->BJTtre1Given) { + model->BJTtre1 = 0.0; + } + if(!model->BJTtre2Given) { + model->BJTtre2 = 0.0; + } + if(!model->BJTtrm1Given) { + model->BJTtrm1 = 0.0; + } + if(!model->BJTtrm2Given) { + model->BJTtrm2 = 0.0; + } + if(!model->BJTtvaf1Given) { + model->BJTtvaf1 = 0.0; + } + if(!model->BJTtvaf2Given) { + model->BJTtvaf2 = 0.0; + } + if(!model->BJTtvar1Given) { + model->BJTtvar1 = 0.0; + } + if(!model->BJTtvar2Given) { + model->BJTtvar2 = 0.0; + } + if(!model->BJTctcGiven) { + model->BJTctc = 0.0; + } + if(!model->BJTcteGiven) { + model->BJTcte = 0.0; + } + if(!model->BJTctsGiven) { + model->BJTcts = 0.0; + } + if(!model->BJTtvjeGiven) { + model->BJTtvje = 0.0; + } + if(!model->BJTtvjcGiven) { + model->BJTtvjc = 0.0; + } + if(!model->BJTtvjsGiven) { + model->BJTtvjs = 0.0; + } + + if(!model->BJTfNcoefGiven) { + model->BJTfNcoef = 0; + } + if(!model->BJTfNexpGiven) { + model->BJTfNexp = 1; + } /* * COMPATABILITY WARNING! @@ -134,34 +250,34 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) * implemented a special case which checked if B-E leakage saturation * current was >1, then it was instead a the B-E leakage saturation current * divided by IS, and multiplied it by IS at this point. This was not - * handled correctly in the 2G code, and there is some question on its + * handled correctly in the 2G code, and there is some question on its * reasonability, since it is also undocumented, so it has been left out * here. It could easily be added with 1 line. (The same applies to the B-C * leakage saturation current). TQ 6/29/84 */ - + /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; here=here->BJTnextInstance) { - CKTnode *tmpNode; - IFuid tmpName; - - if (here->BJTowner != ARCHme) - goto matrixpointers; - + CKTnode *tmpNode; + IFuid tmpName; + + if (here->BJTowner != ARCHme) + goto matrixpointers; + if(!here->BJTareaGiven) { here->BJTarea = 1.0; } - if(!here->BJTareabGiven) { + if(!here->BJTareabGiven) { here->BJTareab = here->BJTarea; } - if(!here->BJTareacGiven) { + if(!here->BJTareacGiven) { here->BJTareac = here->BJTarea; } - if(!here->BJTmGiven) { + if(!here->BJTmGiven) { here->BJTm = 1.0; } - + here->BJTstate = *states; *states += BJTnumStates; if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ @@ -178,8 +294,8 @@ matrixpointers: if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; /* fprintf(stderr, "Nodeset copied from %s\n", tmpName); fprintf(stderr, " to %s\n", tmp->name); fprintf(stderr, " value %g\n", @@ -197,8 +313,8 @@ matrixpointers: if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; /* fprintf(stderr, "Nodeset copied from %s\n", tmpName); fprintf(stderr, " to %s\n", tmp->name); fprintf(stderr, " value %g\n", @@ -216,8 +332,8 @@ matrixpointers: if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; /* fprintf(stderr, "Nodeset copied from %s\n", tmpName); fprintf(stderr, " to %s\n", tmp->name); fprintf(stderr, " value %g\n", @@ -225,7 +341,6 @@ matrixpointers: } } } - } /* macro to make elements with built in test for out of memory */ @@ -270,30 +385,30 @@ BJTunsetup( BJTinstance *here; for (model = (BJTmodel *)inModel; model != NULL; - model = model->BJTnextModel) + model = model->BJTnextModel) { for (here = model->BJTinstances; here != NULL; here=here->BJTnextInstance) - { - if (here->BJTcolPrimeNode - && here->BJTcolPrimeNode != here->BJTcolNode) - { - CKTdltNNum(ckt, here->BJTcolPrimeNode); - here->BJTcolPrimeNode = 0; - } - if (here->BJTbasePrimeNode - && here->BJTbasePrimeNode != here->BJTbaseNode) - { - CKTdltNNum(ckt, here->BJTbasePrimeNode); - here->BJTbasePrimeNode = 0; - } - if (here->BJTemitPrimeNode - && here->BJTemitPrimeNode != here->BJTemitNode) - { - CKTdltNNum(ckt, here->BJTemitPrimeNode); - here->BJTemitPrimeNode = 0; - } - } + { + if (here->BJTcolPrimeNode + && here->BJTcolPrimeNode != here->BJTcolNode) + { + CKTdltNNum(ckt, here->BJTcolPrimeNode); + here->BJTcolPrimeNode = 0; + } + if (here->BJTbasePrimeNode + && here->BJTbasePrimeNode != here->BJTbaseNode) + { + CKTdltNNum(ckt, here->BJTbasePrimeNode); + here->BJTbasePrimeNode = 0; + } + if (here->BJTemitPrimeNode + && here->BJTemitPrimeNode != here->BJTemitNode) + { + CKTdltNNum(ckt, here->BJTemitPrimeNode); + here->BJTemitPrimeNode = 0; + } + } } return OK; } diff --git a/src/spicelib/devices/bjt/bjttemp.c b/src/spicelib/devices/bjt/bjttemp.c index 48053826c..5c353d305 100644 --- a/src/spicelib/devices/bjt/bjttemp.c +++ b/src/spicelib/devices/bjt/bjttemp.c @@ -19,7 +19,6 @@ int BJTtemp(GENmodel *inModel, CKTcircuit *ckt) /* Pre-compute many useful parameters */ - { BJTmodel *model = (BJTmodel *)inModel; BJTinstance *here; @@ -28,13 +27,14 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt) double ratlog; double ratio1; double factlog; - double bfactor; + double bfactor=1.0; double factor; double fact1,fact2; double pbo,pbfact; double gmaold,gmanew; double egfet; double arg; + double dt; /* loop through all the bipolar models */ for( ; model != NULL; model = model->BJTnextModel ) { @@ -66,44 +66,14 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt) * implemented a special case which checked if B-E leakage saturation * current was >1, then it was instead a the B-E leakage saturation current * divided by IS, and multiplied it by IS at this point. This was not - * handled correctly in the 2G code, and there is some question on its + * handled correctly in the 2G code, and there is some question on its * reasonability, since it is also undocumented, so it has been left out * here. It could easily be added with 1 line. (The same applies to the B-C * leakage saturation current). TQ 6/29/84 */ - - if(model->BJTearlyVoltFGiven && model->BJTearlyVoltF != 0) { - model->BJTinvEarlyVoltF = 1/model->BJTearlyVoltF; - } else { - model->BJTinvEarlyVoltF = 0; - } - if(model->BJTrollOffFGiven && model->BJTrollOffF != 0) { - model->BJTinvRollOffF = 1/model->BJTrollOffF; - } else { - model->BJTinvRollOffF = 0; - } - if(model->BJTearlyVoltRGiven && model->BJTearlyVoltR != 0) { - model->BJTinvEarlyVoltR = 1/model->BJTearlyVoltR; - } else { - model->BJTinvEarlyVoltR = 0; - } - if(model->BJTrollOffRGiven && model->BJTrollOffR != 0) { - model->BJTinvRollOffR = 1/model->BJTrollOffR; - } else { - model->BJTinvRollOffR = 0; - } - if(model->BJTcollectorResistGiven && model->BJTcollectorResist != 0) { - model->BJTcollectorConduct = 1/model->BJTcollectorResist; - } else { - model->BJTcollectorConduct = 0; - } - if(model->BJTemitterResistGiven && model->BJTemitterResist != 0) { - model->BJTemitterConduct = 1/model->BJTemitterResist; - } else { - model->BJTemitterConduct = 0; - } + if(model->BJTtransitTimeFVBCGiven && model->BJTtransitTimeFVBC != 0) { - model->BJTtransitTimeVBCFactor =1/ (model->BJTtransitTimeFVBC*1.44); + model->BJTtransitTimeVBCFactor =1/(model->BJTtransitTimeFVBC*1.44); } else { model->BJTtransitTimeVBCFactor = 0; } @@ -121,24 +91,70 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt) } xfc = log(1-model->BJTdepletionCapCoeff); model->BJTf2 = exp((1 + model->BJTjunctionExpBE) * xfc); - model->BJTf3 = 1 - model->BJTdepletionCapCoeff * + model->BJTf3 = 1 - model->BJTdepletionCapCoeff * (1 + model->BJTjunctionExpBE); model->BJTf6 = exp((1+model->BJTjunctionExpBC)*xfc); - model->BJTf7 = 1 - model->BJTdepletionCapCoeff * + model->BJTf7 = 1 - model->BJTdepletionCapCoeff * (1 + model->BJTjunctionExpBC); /* loop through all the instances of the model */ for (here = model->BJTinstances; here != NULL ; here=here->BJTnextInstance) { - if (here->BJTowner != ARCHme) continue; - - if(!here->BJTdtempGiven) - here->BJTdtemp = 0.0; - - if(!here->BJTtempGiven) - here->BJTtemp = ckt->CKTtemp + here->BJTdtemp; - - vt = here->BJTtemp * CONSTKoverQ; + if (here->BJTowner != ARCHme) continue; + + if(!here->BJTdtempGiven) + here->BJTdtemp = 0.0; + + if(!here->BJTtempGiven) + here->BJTtemp = ckt->CKTtemp + here->BJTdtemp; + + dt = here->BJTtemp - model->BJTtnom; + + if(model->BJTearlyVoltFGiven && model->BJTearlyVoltF != 0) { + here->BJTtinvEarlyVoltF = 1/(model->BJTearlyVoltF * (1+model->BJTtvaf1*dt+model->BJTtvaf2*dt*dt)); + } else { + here->BJTtinvEarlyVoltF = 0; + } + if(model->BJTrollOffFGiven && model->BJTrollOffF != 0) { + here->BJTtinvRollOffF = 1/(model->BJTrollOffF * (1+model->BJTtikf1*dt+model->BJTtikf2*dt*dt)); + } else { + here->BJTtinvRollOffF = 0; + } + if(model->BJTearlyVoltRGiven && model->BJTearlyVoltR != 0) { + here->BJTtinvEarlyVoltR = 1/(model->BJTearlyVoltR * (1+model->BJTtvar1*dt+model->BJTtvar2*dt*dt)); + } else { + here->BJTtinvEarlyVoltR = 0; + } + if(model->BJTrollOffRGiven && model->BJTrollOffR != 0) { + here->BJTtinvRollOffR = 1/(model->BJTrollOffR * (1+model->BJTtikr1*dt+model->BJTtikr2*dt*dt)); + } else { + here->BJTtinvRollOffR = 0; + } + if(model->BJTcollectorResistGiven && model->BJTcollectorResist != 0) { + here->BJTtcollectorConduct = 1/(model->BJTcollectorResist * (1+model->BJTtrc1*dt+model->BJTtrc2*dt*dt)); + } else { + here->BJTtcollectorConduct = 0; + } + if(model->BJTemitterResistGiven && model->BJTemitterResist != 0) { + here->BJTtemitterConduct = 1/(model->BJTemitterResist * (1+model->BJTtre1*dt+model->BJTtre2*dt*dt)); + } else { + here->BJTtemitterConduct = 0; + } + + here->BJTtminBaseResist = model->BJTminBaseResist*(1+model->BJTtrm1*dt+model->BJTtrm2*dt*dt); + here->BJTtbaseResist = model->BJTbaseResist * (1+model->BJTtrb1*dt+model->BJTtrb2*dt*dt); + here->BJTtbaseCurrentHalfResist = model->BJTbaseCurrentHalfResist * (1+model->BJTtirb1*dt+model->BJTtirb2*dt*dt); + here->BJTtemissionCoeffF = model->BJTemissionCoeffF * (1+model->BJTtnf1*dt+model->BJTtnf2*dt*dt); + here->BJTtemissionCoeffR = model->BJTemissionCoeffR * (1+model->BJTtnr1*dt+model->BJTtnr2*dt*dt); + here->BJTtleakBEemissionCoeff = model->BJTleakBEemissionCoeff * (1+model->BJTtne1*dt+model->BJTtne2*dt*dt); + here->BJTtleakBCemissionCoeff = model->BJTleakBCemissionCoeff * (1+model->BJTtnc1*dt+model->BJTtnc2*dt*dt); + here->BJTttransitTimeHighCurrentF = model->BJTtransitTimeHighCurrentF * (1+model->BJTtitf1*dt+model->BJTtitf2*dt*dt); + here->BJTttransitTimeF = model->BJTtransitTimeF * (1+model->BJTttf1*dt+model->BJTttf2*dt*dt); + here->BJTttransitTimeR = model->BJTtransitTimeR * (1+model->BJTttr1*dt+model->BJTttr2*dt*dt); + here->BJTtjunctionExpBE = model->BJTjunctionExpBE * (1+model->BJTtmje1*dt+model->BJTtmje2*dt*dt); + here->BJTtjunctionExpBC = model->BJTjunctionExpBC * (1+model->BJTtmjc1*dt+model->BJTtmjc2*dt*dt); + + vt = here->BJTtemp * CONSTKoverQ; fact2 = here->BJTtemp/REFTEMP; egfet = 1.16-(7.02e-4*here->BJTtemp*here->BJTtemp)/ (here->BJTtemp+1108); @@ -148,41 +164,63 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt) ratlog = log(here->BJTtemp/model->BJTtnom); ratio1 = here->BJTtemp/model->BJTtnom -1; - factlog = ratio1 * model->BJTenergyGap/vt + + factlog = ratio1 * model->BJTenergyGap/vt + model->BJTtempExpIS*ratlog; factor = exp(factlog); here->BJTtSatCur = model->BJTsatCur * factor; - bfactor = exp(ratlog*model->BJTbetaExp); - here->BJTtBetaF = model->BJTbetaF * bfactor; - here->BJTtBetaR = model->BJTbetaR * bfactor; - here->BJTtBEleakCur = model->BJTleakBEcurrent * - exp(factlog/model->BJTleakBEemissionCoeff)/bfactor; - here->BJTtBCleakCur = model->BJTleakBCcurrent * - exp(factlog/model->BJTleakBCemissionCoeff)/bfactor; - - pbo = (model->BJTpotentialBE-pbfact)/fact1; - gmaold = (model->BJTpotentialBE-pbo)/pbo; - here->BJTtBEcap = model->BJTdepletionCapBE/ + + if (model->BJTtlev == 0) { + bfactor = exp(ratlog*model->BJTbetaExp); + } else if (model->BJTtlev == 1) { + bfactor = 1+model->BJTbetaExp*dt; + } + if ((model->BJTtbf1Given)||(model->BJTtbf2Given)) + here->BJTtBetaF = model->BJTbetaF * (1+model->BJTtbf1*dt+model->BJTtbf2*dt*dt); + else + here->BJTtBetaF = model->BJTbetaF * bfactor; + if ((model->BJTtbr1Given)||(model->BJTtbr2Given)) + here->BJTtBetaR = model->BJTbetaR * (1+model->BJTtbr1*dt+model->BJTtbr2*dt*dt); + else + here->BJTtBetaR = model->BJTbetaR * bfactor; + + here->BJTtBEleakCur = model->BJTleakBEcurrent * + exp(factlog/model->BJTleakBEemissionCoeff)/bfactor; + here->BJTtBCleakCur = model->BJTleakBCcurrent * + exp(factlog/model->BJTleakBCemissionCoeff)/bfactor; + + if (model->BJTtlevc == 0) { + pbo = (model->BJTpotentialBE-pbfact)/fact1; + gmaold = (model->BJTpotentialBE-pbo)/pbo; + here->BJTtBEcap = model->BJTdepletionCapBE/ (1+model->BJTjunctionExpBE* (4e-4*(model->BJTtnom-REFTEMP)-gmaold)); - here->BJTtBEpot = fact2 * pbo+pbfact; - gmanew = (here->BJTtBEpot-pbo)/pbo; - here->BJTtBEcap *= 1+model->BJTjunctionExpBE* + here->BJTtBEpot = fact2 * pbo+pbfact; + gmanew = (here->BJTtBEpot-pbo)/pbo; + here->BJTtBEcap *= 1+model->BJTjunctionExpBE* (4e-4*(here->BJTtemp-REFTEMP)-gmanew); + } else if (model->BJTtlevc == 1) { + here->BJTtBEcap = model->BJTdepletionCapBE* + (1+model->BJTcte*dt); + } - pbo = (model->BJTpotentialBC-pbfact)/fact1; - gmaold = (model->BJTpotentialBC-pbo)/pbo; - here->BJTtBCcap = model->BJTdepletionCapBC/ + if (model->BJTtlevc == 0) { + pbo = (model->BJTpotentialBC-pbfact)/fact1; + gmaold = (model->BJTpotentialBC-pbo)/pbo; + here->BJTtBCcap = model->BJTdepletionCapBC/ (1+model->BJTjunctionExpBC* (4e-4*(model->BJTtnom-REFTEMP)-gmaold)); - here->BJTtBCpot = fact2 * pbo+pbfact; - gmanew = (here->BJTtBCpot-pbo)/pbo; - here->BJTtBCcap *= 1+model->BJTjunctionExpBC* + here->BJTtBCpot = fact2 * pbo+pbfact; + gmanew = (here->BJTtBCpot-pbo)/pbo; + here->BJTtBCcap *= 1+model->BJTjunctionExpBC* (4e-4*(here->BJTtemp-REFTEMP)-gmanew); + } else if (model->BJTtlevc == 1) { + here->BJTtBCcap = model->BJTdepletionCapBC* + (1+model->BJTctc*dt); + } here->BJTtDepCap = model->BJTdepletionCapCoeff * here->BJTtBEpot; - here->BJTtf1 = here->BJTtBEpot * (1 - exp((1 - - model->BJTjunctionExpBE) * xfc)) / + here->BJTtf1 = here->BJTtBEpot * (1 - exp((1 - + model->BJTjunctionExpBE) * xfc)) / (1 - model->BJTjunctionExpBE); here->BJTtf4 = model->BJTdepletionCapCoeff * here->BJTtBCpot; here->BJTtf5 = here->BJTtBCpot * (1 - exp((1 - @@ -190,7 +228,7 @@ BJTtemp(GENmodel *inModel, CKTcircuit *ckt) (1 - model->BJTjunctionExpBC); here->BJTtVcrit = vt * log(vt / (CONSTroot2*here->BJTtSatCur*here->BJTarea)); - + } } return(OK); diff --git a/src/spicelib/devices/dio/dio.c b/src/spicelib/devices/dio/dio.c index 55aa0eb25..01195aee3 100644 --- a/src/spicelib/devices/dio/dio.c +++ b/src/spicelib/devices/dio/dio.c @@ -42,6 +42,7 @@ IFparm DIOmPTable[] = { /* model parameters */ IOP( "jsw", DIO_MOD_JSW, IF_REAL, "Sidewall Saturation current"), IOPU( "tnom",DIO_MOD_TNOM,IF_REAL, "Parameter measurement temperature"), + IOPR( "tref",DIO_MOD_TNOM,IF_REAL, "Parameter measurement temperature"), IOP( "rs", DIO_MOD_RS, IF_REAL, "Ohmic resistance"), IOP( "trs", DIO_MOD_TRS, IF_REAL, "Ohmic resistance 1st order temp. coeff."), IOPR( "trs1", DIO_MOD_TRS, IF_REAL, "Ohmic resistance 1st order temp. coeff."), @@ -52,28 +53,35 @@ IFparm DIOmPTable[] = { /* model parameters */ IOPA( "ttt2", DIO_MOD_TTT2, IF_REAL, "Transit Time 2nd order temp. coeff."), IOPA( "cjo", DIO_MOD_CJO, IF_REAL, "Junction capacitance"), IOPR( "cj0", DIO_MOD_CJO, IF_REAL, "Junction capacitance"), + IOPR( "cj", DIO_MOD_CJO, IF_REAL, "Junction capacitance"), IOP( "vj", DIO_MOD_VJ, IF_REAL, "Junction potential"), IOPR( "pb", DIO_MOD_VJ, IF_REAL, "Junction potential"), IOP( "m", DIO_MOD_M, IF_REAL, "Grading coefficient"), - IOPR("mj", DIO_MOD_M, IF_REAL, "Grading coefficient"), - IOP("tm1", DIO_MOD_TM1, IF_REAL, " Grading coefficient 1st temp. coeff."), - IOP("tm2", DIO_MOD_TM2, IF_REAL, " Grading coefficient 2nd temp. coeff."), + IOPR( "mj", DIO_MOD_M, IF_REAL, "Grading coefficient"), + IOP( "tm1", DIO_MOD_TM1, IF_REAL, "Grading coefficient 1st temp. coeff."), + IOP( "tm2", DIO_MOD_TM2, IF_REAL, "Grading coefficient 2nd temp. coeff."), IOP( "cjp", DIO_MOD_CJSW, IF_REAL, "Sidewall junction capacitance"), IOPR( "cjsw", DIO_MOD_CJSW, IF_REAL, "Sidewall junction capacitance"), IOP( "php", DIO_MOD_VJSW, IF_REAL, "Sidewall junction potential"), IOP( "mjsw", DIO_MOD_MJSW, IF_REAL, "Sidewall Grading coefficient"), IOP( "ikf", DIO_MOD_IKF, IF_REAL, "Forward Knee current"), IOPR( "ik", DIO_MOD_IKF, IF_REAL, "Forward Knee current"), - IOP("ikr", DIO_MOD_IKR, IF_REAL, "Reverse Knee current"), + IOP( "ikr", DIO_MOD_IKR, IF_REAL, "Reverse Knee current"), + IOP( "tlev", DIO_MOD_TLEV, IF_REAL, "Diode temperature equation selector"), + IOP( "tlevc", DIO_MOD_TLEVC, IF_REAL, "Diode temperature equation selector"), IOP( "eg", DIO_MOD_EG, IF_REAL, "Activation energy"), IOP( "xti", DIO_MOD_XTI, IF_REAL, "Saturation current temperature exp."), + IOP( "cta", DIO_MOD_CTA, IF_REAL, "Area junction temperature coefficient"), + IOPR( "ctc", DIO_MOD_CTA, IF_REAL, "Area junction capacitance temperature coefficient"), + IOP( "ctp", DIO_MOD_CTP, IF_REAL, "Perimeter junction capacitance temperature coefficient"), IOP( "kf", DIO_MOD_KF, IF_REAL, "flicker noise coefficient"), IOP( "af", DIO_MOD_AF, IF_REAL, "flicker noise exponent"), IOP( "fc", DIO_MOD_FC, IF_REAL, "Forward bias junction fit parameter"), IOP( "fcs", DIO_MOD_FCS, IF_REAL, "Forward bias sidewall junction fit parameter"), IOP( "bv", DIO_MOD_BV, IF_REAL, "Reverse breakdown voltage"), IOP( "ibv", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"), + IOP( "tcv", DIO_MOD_TCV, IF_REAL, "Reverse breakdown voltage temperature coefficient"), OPU( "cond", DIO_MOD_COND,IF_REAL, "Ohmic conductance"), IP( "d", DIO_MOD_D, IF_FLAG, "Diode model") }; @@ -83,8 +91,8 @@ char *DIOnames[] = { "D-" }; -int DIOnSize = NUMELEMS(DIOnames); -int DIOpTSize = NUMELEMS(DIOpTable); -int DIOmPTSize = NUMELEMS(DIOmPTable); -int DIOiSize = sizeof(DIOinstance); -int DIOmSize = sizeof(DIOmodel); +int DIOnSize = NUMELEMS(DIOnames); +int DIOpTSize = NUMELEMS(DIOpTable); +int DIOmPTSize = NUMELEMS(DIOmPTable); +int DIOiSize = sizeof(DIOinstance); +int DIOmSize = sizeof(DIOmodel); diff --git a/src/spicelib/devices/dio/diodefs.h b/src/spicelib/devices/dio/diodefs.h index 7d347e94e..acef33215 100644 --- a/src/spicelib/devices/dio/diodefs.h +++ b/src/spicelib/devices/dio/diodefs.h @@ -180,12 +180,17 @@ typedef struct sDIOmodel { /* model structure for a diode */ unsigned DIOforwardKneeCurrentGiven : 1; unsigned DIOreverseKneeCurrentGiven : 1; + unsigned DIOtlevGiven : 1; + unsigned DIOtlevcGiven : 1; unsigned DIOactivationEnergyGiven : 1; unsigned DIOsaturationCurrentExpGiven : 1; + unsigned DIOctaGiven : 1; + unsigned DIOctpGiven : 1; unsigned DIOdepletionCapCoeffGiven : 1; unsigned DIOdepletionSWcapCoeffGiven :1; unsigned DIObreakdownVoltageGiven : 1; unsigned DIObreakdownCurrentGiven : 1; + unsigned DIOtcvGiven : 1; unsigned DIOnomTempGiven : 1; unsigned DIOfNcoefGiven : 1; unsigned DIOfNexpGiven : 1; @@ -212,18 +217,22 @@ typedef struct sDIOmodel { /* model structure for a diode */ double DIOforwardKneeCurrent; /* Forward Knee current */ double DIOreverseKneeCurrent; /* Reverse Knee current */ + unsigned DIOtlev; /* Diode temperature equation selector */ + unsigned DIOtlevc; /* Diode temperature equation selector */ double DIOactivationEnergy; /* activation energy (EG) */ double DIOsaturationCurrentExp; /* Saturation current exponential (XTI) */ + double DIOcta; /* Area junction temperature coefficient */ + double DIOctp; /* Perimeter junction temperature coefficient */ double DIOdepletionCapCoeff; /* Depletion Cap fraction coefficient (FC)*/ double DIOdepletionSWcapCoeff; /* Depletion sw-Cap fraction coefficient (FCS)*/ double DIObreakdownVoltage; /* Voltage at reverse breakdown */ double DIObreakdownCurrent; /* Current at above voltage */ + double DIOtcv; /* Reverse breakdown voltage temperature coefficient */ double DIOnomTemp; /* nominal temperature (temp at which parms measured */ double DIOfNcoef; double DIOfNexp; - } DIOmodel; /* device parameters */ @@ -280,6 +289,11 @@ typedef struct sDIOmodel { /* model structure for a diode */ #define DIO_MOD_TM2 128 #define DIO_MOD_TRS 129 #define DIO_MOD_TRS2 130 +#define DIO_MOD_TLEV 131 +#define DIO_MOD_TLEVC 132 +#define DIO_MOD_CTA 133 +#define DIO_MOD_CTP 134 +#define DIO_MOD_TCV 135 #include "dioext.h" #endif /*DIO*/ diff --git a/src/spicelib/devices/dio/diomask.c b/src/spicelib/devices/dio/diomask.c index b92b1d58d..c3c03167b 100644 --- a/src/spicelib/devices/dio/diomask.c +++ b/src/spicelib/devices/dio/diomask.c @@ -39,10 +39,10 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) return(OK); case DIO_MOD_TRS: value->rValue = model->DIOresistTemp1; - return(OK); + return(OK); case DIO_MOD_TRS2: value->rValue = model->DIOresistTemp2; - return(OK); + return(OK); case DIO_MOD_N: value->rValue = model->DIOemissionCoeff; return(OK); @@ -51,10 +51,10 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) return(OK); case DIO_MOD_TTT1: value->rValue = model->DIOtranTimeTemp1; - return(OK); + return(OK); case DIO_MOD_TTT2: value->rValue = model->DIOtranTimeTemp2; - return(OK); + return(OK); case DIO_MOD_CJO: value->rValue = model->DIOjunctionCap; return(OK); @@ -66,10 +66,10 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) return(OK); case DIO_MOD_TM1: value->rValue = model->DIOgradCoeffTemp1; - return(OK); + return(OK); case DIO_MOD_TM2: value->rValue = model->DIOgradCoeffTemp2; - return(OK); + return(OK); case DIO_MOD_CJSW: value->rValue = model->DIOjunctionSWCap; return(OK); @@ -85,18 +85,30 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case DIO_MOD_IKR: value->rValue = model->DIOreverseKneeCurrent; return(OK); - + + case DIO_MOD_TLEV: + value->iValue = model->DIOtlev; + return (OK); + case DIO_MOD_TLEVC: + value->iValue = model->DIOtlevc; + return (OK); case DIO_MOD_EG: value->rValue = model->DIOactivationEnergy; return (OK); case DIO_MOD_XTI: value->rValue = model->DIOsaturationCurrentExp; return(OK); + case DIO_MOD_CTA: + value->rValue = model->DIOcta; + return(OK); + case DIO_MOD_CTP: + value->rValue = model->DIOctp; + return(OK); case DIO_MOD_FC: value->rValue = model->DIOdepletionCapCoeff; return(OK); - case DIO_MOD_FCS: - value->rValue = model->DIOdepletionSWcapCoeff; + case DIO_MOD_FCS: + value->rValue = model->DIOdepletionSWcapCoeff; return(OK); case DIO_MOD_KF: value->rValue = model->DIOfNcoef; @@ -110,6 +122,9 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case DIO_MOD_IBV: value->rValue = model->DIObreakdownCurrent; return(OK); + case DIO_MOD_TCV: + value->rValue = model->DIOtcv; + return(OK); case DIO_MOD_COND: value->rValue = model->DIOconductance; return(OK); diff --git a/src/spicelib/devices/dio/diompar.c b/src/spicelib/devices/dio/diompar.c index ab0d82eaa..1d649c0f7 100644 --- a/src/spicelib/devices/dio/diompar.c +++ b/src/spicelib/devices/dio/diompar.c @@ -43,7 +43,7 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) case DIO_MOD_TRS2: model->DIOresistTemp2 = value->rValue; model->DIOresistTemp2Given = TRUE; - break; + break; case DIO_MOD_N: model->DIOemissionCoeff = value->rValue; model->DIOemissionCoeffGiven = TRUE; @@ -55,11 +55,11 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) case DIO_MOD_TTT1: model->DIOtranTimeTemp1 = value->rValue; model->DIOtranTimeTemp1Given = TRUE; - break; + break; case DIO_MOD_TTT2: model->DIOtranTimeTemp2 = value->rValue; model->DIOtranTimeTemp2Given = TRUE; - break; + break; case DIO_MOD_CJO: model->DIOjunctionCap = value->rValue; model->DIOjunctionCapGiven = TRUE; @@ -79,7 +79,7 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) case DIO_MOD_TM2: model->DIOgradCoeffTemp2 = value->rValue; model->DIOgradCoeffTemp2Given = TRUE; - break; + break; case DIO_MOD_CJSW: model->DIOjunctionSWCap = value->rValue; model->DIOjunctionSWCapGiven = TRUE; @@ -100,7 +100,15 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) model->DIOreverseKneeCurrent = value->rValue; model->DIOreverseKneeCurrentGiven = TRUE; break; - + + case DIO_MOD_TLEV: + model->DIOtlev = value->iValue; + model->DIOtlevGiven = TRUE; + break; + case DIO_MOD_TLEVC: + model->DIOtlevc = value->iValue; + model->DIOtlevcGiven = TRUE; + break; case DIO_MOD_EG: model->DIOactivationEnergy = value->rValue; model->DIOactivationEnergyGiven = TRUE; @@ -109,6 +117,14 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) model->DIOsaturationCurrentExp = value->rValue; model->DIOsaturationCurrentExpGiven = TRUE; break; + case DIO_MOD_CTA: + model->DIOcta = value->rValue; + model->DIOctaGiven = TRUE; + break; + case DIO_MOD_CTP: + model->DIOctp = value->rValue; + model->DIOctpGiven = TRUE; + break; case DIO_MOD_FC: model->DIOdepletionCapCoeff = value->rValue; model->DIOdepletionCapCoeffGiven = TRUE; @@ -117,7 +133,7 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) model->DIOdepletionSWcapCoeff = value->rValue; model->DIOdepletionSWcapCoeffGiven = TRUE; break; - case DIO_MOD_BV: + case DIO_MOD_BV: model->DIObreakdownVoltage = value->rValue; model->DIObreakdownVoltageGiven = TRUE; break; @@ -125,18 +141,22 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) model->DIObreakdownCurrent = value->rValue; model->DIObreakdownCurrentGiven = TRUE; break; + case DIO_MOD_TCV: + model->DIOtcv = value->rValue; + model->DIOtcvGiven = TRUE; + break; case DIO_MOD_D: /* no action - we already know we are a diode, but this */ /* makes life easier for spice-2 like parsers */ break; - case DIO_MOD_KF: - model->DIOfNcoef = value->rValue; - model->DIOfNcoefGiven = TRUE; - break; - case DIO_MOD_AF: - model->DIOfNexp = value->rValue; - model->DIOfNexpGiven = TRUE; - break; + case DIO_MOD_KF: + model->DIOfNcoef = value->rValue; + model->DIOfNcoefGiven = TRUE; + break; + case DIO_MOD_AF: + model->DIOfNexp = value->rValue; + model->DIOfNexpGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/dio/diosetup.c b/src/spicelib/devices/dio/diosetup.c index 57b45de25..388a27b48 100644 --- a/src/spicelib/devices/dio/diosetup.c +++ b/src/spicelib/devices/dio/diosetup.c @@ -5,8 +5,8 @@ Modified: 2000 AlansFixes Modified by Dietmar Warning 2003 and Paolo Nenzi 2003 **********/ -/* load the diode structure with those pointers needed later - * for fast matrix loading +/* load the diode structure with those pointers needed later + * for fast matrix loading */ #include "ngspice.h" @@ -36,7 +36,6 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->DIOsatSWCurGiven) { model->DIOsatSWCur = 0.0; } - if(!model->DIObreakdownCurrentGiven) { model->DIObreakdownCurrent = 1e-3; } @@ -45,26 +44,26 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) } if(!model->DIOgradingCoeffGiven) { model->DIOgradingCoeff = .5; - } - if(!model->DIOgradCoeffTemp1Given) { + } + if(!model->DIOgradCoeffTemp1Given) { model->DIOgradCoeffTemp1 = 0.0; } - if(!model->DIOgradCoeffTemp2Given) { + if(!model->DIOgradCoeffTemp2Given) { model->DIOgradCoeffTemp2 = 0.0; - } + } if(!model->DIOdepletionCapCoeffGiven) { model->DIOdepletionCapCoeff = .5; - } - if(!model->DIOdepletionSWcapCoeffGiven) { + } + if(!model->DIOdepletionSWcapCoeffGiven) { model->DIOdepletionSWcapCoeff = .5; } if(!model->DIOtransitTimeGiven) { model->DIOtransitTime = 0; } - if(!model->DIOtranTimeTemp1Given) { + if(!model->DIOtranTimeTemp1Given) { model->DIOtranTimeTemp1 = 0.0; } - if(!model->DIOtranTimeTemp2Given) { + if(!model->DIOtranTimeTemp2Given) { model->DIOtranTimeTemp2 = 0.0; } if(!model->DIOjunctionCapGiven) { @@ -78,35 +77,50 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) } if(!model->DIOgradingSWCoeffGiven) { model->DIOgradingSWCoeff = .33; - } + } if(!model->DIOforwardKneeCurrentGiven) { model->DIOforwardKneeCurrent = 1e-3; - } + } if(!model->DIOreverseKneeCurrentGiven) { model->DIOreverseKneeCurrent = 1e-3; - } + } + if(!model->DIOtlevGiven) { + model->DIOtlev = 0; + } + if(!model->DIOtlevcGiven) { + model->DIOtlevc = 0; + } if(!model->DIOactivationEnergyGiven) { model->DIOactivationEnergy = 1.11; - } + } if(!model->DIOsaturationCurrentExpGiven) { model->DIOsaturationCurrentExp = 3; } - if(!model->DIOfNcoefGiven) { - model->DIOfNcoef = 0.0; - } - if(!model->DIOfNexpGiven) { - model->DIOfNexp = 1.0; - } - if(!model->DIOresistTemp1Given) { - model->DIOresistTemp1 = 0.0; - } + if(!model->DIOctaGiven) { + model->DIOcta = 0.0; + } + if(!model->DIOctpGiven) { + model->DIOctp = 0.0; + } + if(!model->DIOfNcoefGiven) { + model->DIOfNcoef = 0.0; + } + if(!model->DIOfNexpGiven) { + model->DIOfNexp = 1.0; + } + if(!model->DIOresistTemp1Given) { + model->DIOresistTemp1 = 0.0; + } if(!model->DIOresistTemp2Given) { - model->DIOresistTemp2 = 0.0; - } + model->DIOresistTemp2 = 0.0; + } + if(!model->DIOtcvGiven) { + model->DIOtcv = 0.0; + } /* loop through all the instances of the model */ for (here = model->DIOinstances; here != NULL ; here=here->DIOnextInstance) { - if (here->DIOowner != ARCHme) goto matrixpointers; + if (here->DIOowner != ARCHme) goto matrixpointers; if(!here->DIOareaGiven) { here->DIOarea = 1; @@ -123,23 +137,23 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN) ){ *states += 2 * (ckt->CKTsenInfo->SENparms); } - + matrixpointers: if(model->DIOresist == 0) { here->DIOposPrimeNode = here->DIOposNode; } else if(here->DIOposPrimeNode == 0) { - - CKTnode *tmpNode; + + CKTnode *tmpNode; IFuid tmpName; - + error = CKTmkVolt(ckt,&tmp,here->DIOname,"internal"); if(error) return(error); here->DIOposPrimeNode = tmp->number; if (ckt->CKTcopyNodesets) { if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; + tmp->nodeset=tmpNode->nodeset; + tmp->nsGiven=tmpNode->nsGiven; } } } @@ -172,19 +186,19 @@ DIOunsetup( DIOinstance *here; for (model = (DIOmodel *)inModel; model != NULL; - model = model->DIOnextModel) + model = model->DIOnextModel) { for (here = model->DIOinstances; here != NULL; here=here->DIOnextInstance) - { + { - if (here->DIOposPrimeNode - && here->DIOposPrimeNode != here->DIOposNode) - { - CKTdltNNum(ckt, here->DIOposPrimeNode); - here->DIOposPrimeNode = 0; - } - } + if (here->DIOposPrimeNode + && here->DIOposPrimeNode != here->DIOposNode) + { + CKTdltNNum(ckt, here->DIOposPrimeNode); + here->DIOposPrimeNode = 0; + } + } } return OK; } diff --git a/src/spicelib/devices/dio/diotemp.c b/src/spicelib/devices/dio/diotemp.c index d8b98e729..9ccb6def0 100644 --- a/src/spicelib/devices/dio/diotemp.c +++ b/src/spicelib/devices/dio/diotemp.c @@ -26,11 +26,13 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) double tol; double vt; double vtnom; - double difference; - double factor; DIOinstance *here; int iter; +#ifdef TRACE char *emsg; +#endif + double dt; + double factor; /* loop through all the diode models */ for( ; model != NULL; model = model->DIOnextModel ) { @@ -59,7 +61,7 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) &(model->DIOmodName)); model->DIOdepletionCapCoeff=.95; } - /* limit sidewall depletion cap coeff to max of .95 */ + /* limit sidewall depletion cap coeff to max of .95 */ if(model->DIOdepletionSWcapCoeff>.95) { (*(SPfrontEnd->IFerror))(ERR_WARNING, "%s: coefficient Fcs too large, limited to 0.95", @@ -72,40 +74,40 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) model->DIOconductance = 1/model->DIOresist; } xfc=log(1-model->DIOdepletionCapCoeff); - xfcs=log(1-model->DIOdepletionSWcapCoeff); - + xfcs=log(1-model->DIOdepletionSWcapCoeff); + for(here=model->DIOinstances;here;here=here->DIOnextInstance) { double egfet1,arg1,fact1,pbfact1,pbo,gmaold,pboSW,gmaSWold; double fact2,pbfact,arg,egfet,gmanew,gmaSWnew; - - if (here->DIOowner != ARCHme) continue; - /* loop through all the instances */ - - if(!here->DIOdtempGiven) here->DIOdtemp = 0.0; - - if(!here->DIOtempGiven) - here->DIOtemp = ckt->CKTtemp + here->DIOdtemp; - - /* Junction grading temperature adjust */ - difference = here->DIOtemp - model->DIOnomTemp; - factor = 1.0 + (model->DIOgradCoeffTemp1 * difference) - + (model->DIOgradCoeffTemp2 * difference * difference); - here->DIOtGradingCoeff = model->DIOgradingCoeff * factor; - - /* limit temperature adjusted grading coeff - * to max of .9 - */ - if(here->DIOtGradingCoeff>.9) { + + if (here->DIOowner != ARCHme) continue; + + if(!here->DIOdtempGiven) here->DIOdtemp = 0.0; + + if(!here->DIOtempGiven) + here->DIOtemp = ckt->CKTtemp + here->DIOdtemp; + + dt = here->DIOtemp - model->DIOnomTemp; + + /* Junction grading temperature adjust */ + factor = 1.0 + (model->DIOgradCoeffTemp1 * dt) + + (model->DIOgradCoeffTemp2 * dt * dt); + here->DIOtGradingCoeff = model->DIOgradingCoeff * factor; + + /* limit temperature adjusted grading coeff + * to max of .9 + */ + if(here->DIOtGradingCoeff>.9) { (*(SPfrontEnd->IFerror))(ERR_WARNING, "%s: temperature adjusted grading coefficient too large, limited to 0.9", &(here->DIOname)); here->DIOtGradingCoeff=.9; - } - + } + vt = CONSTKoverQ * here->DIOtemp; /* this part gets really ugly - I won't even try to - * explain these equations */ + * explain these equations */ fact2 = here->DIOtemp/REFTEMP; egfet = 1.16-(7.02e-4*here->DIOtemp*here->DIOtemp)/ (here->DIOtemp+1108); @@ -114,36 +116,47 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) pbfact = -2*vt*(1.5*log(fact2)+CHARGE*arg); egfet1 = 1.16 - (7.02e-4*model->DIOnomTemp*model->DIOnomTemp)/ (model->DIOnomTemp+1108); - arg1 = -egfet1/(CONSTboltz*2*model->DIOnomTemp) + + arg1 = -egfet1/(CONSTboltz*2*model->DIOnomTemp) + 1.1150877/(2*CONSTboltz*REFTEMP); fact1 = model->DIOnomTemp/REFTEMP; pbfact1 = -2 * vtnom*(1.5*log(fact1)+CHARGE*arg1); - pbo = (model->DIOjunctionPot-pbfact1)/fact1; - gmaold = (model->DIOjunctionPot -pbo)/pbo; - here->DIOtJctCap = model->DIOjunctionCap/ - (1+here->DIOtGradingCoeff* - (400e-6*(model->DIOnomTemp-REFTEMP)-gmaold) ); - here->DIOtJctPot = pbfact+fact2*pbo; - gmanew = (here->DIOtJctPot-pbo)/pbo; - here->DIOtJctCap *= 1+here->DIOtGradingCoeff* - (400e-6*(here->DIOtemp-REFTEMP)-gmanew); - pboSW = (model->DIOjunctionSWPot-pbfact1)/fact1; - gmaSWold = (model->DIOjunctionSWPot -pboSW)/pboSW; - here->DIOtJctSWCap = model->DIOjunctionSWCap/ - (1+model->DIOgradingSWCoeff* - (400e-6*(model->DIOnomTemp-REFTEMP)-gmaSWold) ); - here->DIOtJctSWPot = pbfact+fact2*pboSW; - gmaSWnew = (here->DIOtJctSWPot-pboSW)/pboSW; - here->DIOtJctSWCap *= 1+model->DIOgradingSWCoeff* - (400e-6*(here->DIOtemp-REFTEMP)-gmaSWnew); - - here->DIOtSatCur = model->DIOsatCur * exp( + if (model->DIOtlevc == 0) { + pbo = (model->DIOjunctionPot-pbfact1)/fact1; + gmaold = (model->DIOjunctionPot-pbo)/pbo; + here->DIOtJctCap = model->DIOjunctionCap / + (1+here->DIOtGradingCoeff* + (400e-6*(model->DIOnomTemp-REFTEMP)-gmaold) ); + here->DIOtJctPot = pbfact+fact2*pbo; + gmanew = (here->DIOtJctPot-pbo)/pbo; + here->DIOtJctCap *= 1+here->DIOtGradingCoeff* + (400e-6*(here->DIOtemp-REFTEMP)-gmanew); + } else if (model->DIOtlevc == 1) { + here->DIOtJctCap = model->DIOjunctionCap * + (model->DIOcta*(here->DIOtemp-REFTEMP)); + } + + if (model->DIOtlevc == 0) { + pboSW = (model->DIOjunctionSWPot-pbfact1)/fact1; + gmaSWold = (model->DIOjunctionSWPot-pboSW)/pboSW; + here->DIOtJctSWCap = model->DIOjunctionSWCap / + (1+model->DIOgradingSWCoeff* + (400e-6*(model->DIOnomTemp-REFTEMP)-gmaSWold) ); + here->DIOtJctSWPot = pbfact+fact2*pboSW; + gmaSWnew = (here->DIOtJctSWPot-pboSW)/pboSW; + here->DIOtJctSWCap *= 1+model->DIOgradingSWCoeff* + (400e-6*(here->DIOtemp-REFTEMP)-gmaSWnew); + } else if (model->DIOtlevc == 1) { + here->DIOtJctSWCap = model->DIOjunctionSWCap * + (model->DIOctp*(here->DIOtemp-REFTEMP)); + } + + here->DIOtSatCur = model->DIOsatCur * exp( ((here->DIOtemp/model->DIOnomTemp)-1) * model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) + model->DIOsaturationCurrentExp/model->DIOemissionCoeff* log(here->DIOtemp/model->DIOnomTemp) ); - here->DIOtSatSWCur = model->DIOsatSWCur * exp( + here->DIOtSatSWCur = model->DIOsatSWCur * exp( ((here->DIOtemp/model->DIOnomTemp)-1) * model->DIOactivationEnergy/(model->DIOemissionCoeff*vt) + model->DIOsaturationCurrentExp/model->DIOemissionCoeff* @@ -159,18 +172,19 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) here->DIOtJctPot; /* and Vcrit */ vte=model->DIOemissionCoeff*vt; - + here->DIOtVcrit=vte* log(vte/(CONSTroot2*here->DIOtSatCur*here->DIOarea)); - - /* and now to copute the breakdown voltage, again, using + + /* and now to compute the breakdown voltage, again, using * temperature adjusted basic parameters */ if (model->DIObreakdownVoltageGiven){ cbv=model->DIObreakdownCurrent*here->DIOarea*here->DIOm; if (cbv < here->DIOtSatCur*here->DIOarea*here->DIOm * model->DIObreakdownVoltage/vt) { - cbv=here->DIOtSatCur*here->DIOarea*here->DIOm * + cbv=here->DIOtSatCur*here->DIOarea*here->DIOm * model->DIObreakdownVoltage/vt; +#ifdef TRACE emsg = TMALLOC(char, 100); if(emsg == (char *)NULL) return(E_NOMEM); (void)sprintf(emsg, @@ -180,6 +194,7 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) FREE(emsg); (*(SPfrontEnd->IFerror))(ERR_WARNING, "incompatibility with specified saturation current",(IFuid*)NULL); +#endif xbv=model->DIObreakdownVoltage; } else { tol=ckt->CKTreltol*cbv; @@ -189,10 +204,11 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) for(iter=0 ; iter < 25 ; iter++) { xbv=model->DIObreakdownVoltage-vt*log(cbv/ (here->DIOtSatCur*here->DIOarea*here->DIOm)+1-xbv/vt); - xcbv=here->DIOtSatCur*here->DIOarea*here->DIOm * + xcbv=here->DIOtSatCur*here->DIOarea*here->DIOm * (exp((model->DIObreakdownVoltage-xbv)/vt)-1+xbv/vt); if (fabs(xcbv-cbv) <= tol) goto matched; } +#ifdef TRACE emsg = TMALLOC(char, 100); if(emsg == (char *)NULL) return(E_NOMEM); (void)sprintf(emsg, @@ -200,35 +216,38 @@ DIOtemp(GENmodel *inModel, CKTcircuit *ckt) xbv,xcbv); (*(SPfrontEnd->IFerror))(ERR_WARNING,emsg,&here->DIOname); FREE(emsg); +#endif } matched: - here->DIOtBrkdwnV = xbv; + if (model->DIOtlev == 0) { + here->DIOtBrkdwnV = xbv - model->DIOtcv * dt; + } else if (model->DIOtlev == 1) { + here->DIOtBrkdwnV = xbv * (1 - model->DIOtcv * dt); + } } - - /* transit time temperature adjust */ - difference = here->DIOtemp - model->DIOnomTemp; - factor = 1.0 + (model->DIOtranTimeTemp1 * difference) - + (model->DIOtranTimeTemp2 * difference * difference); - here->DIOtTransitTime = model->DIOtransitTime * factor; - - /* Series resistance temperature adjust */ - here->DIOtConductance = model->DIOconductance; - if(model->DIOresistGiven && model->DIOresist!=0.0) { - difference = here->DIOtemp - model->DIOnomTemp; - factor = 1.0 + (model->DIOresistTemp1) * difference - + (model->DIOresistTemp2 * difference * difference); - here->DIOtConductance = model->DIOconductance / factor; + + /* transit time temperature adjust */ + factor = 1.0 + (model->DIOtranTimeTemp1 * dt) + + (model->DIOtranTimeTemp2 * dt * dt); + here->DIOtTransitTime = model->DIOtransitTime * factor; + + /* Series resistance temperature adjust */ + here->DIOtConductance = model->DIOconductance; + if(model->DIOresistGiven && model->DIOresist!=0.0) { + factor = 1.0 + (model->DIOresistTemp1) * dt + + (model->DIOresistTemp2 * dt * dt); + here->DIOtConductance = model->DIOconductance / factor; } - + here->DIOtF2=exp((1+here->DIOtGradingCoeff)*xfc); here->DIOtF3=1-model->DIOdepletionCapCoeff* (1+here->DIOtGradingCoeff); here->DIOtF2SW=exp((1+model->DIOgradingSWCoeff)*xfcs); here->DIOtF3SW=1-model->DIOdepletionSWcapCoeff* (1+model->DIOgradingSWCoeff); - - } /* instance */ - + + } /* instance */ + } /* model */ return(OK); }