diode & bjt temperature model update

This commit is contained in:
dwarning 2011-02-22 21:45:38 +00:00
parent 325c7dc01d
commit 70856441df
17 changed files with 1115 additions and 394 deletions

View File

@ -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[] = {

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
case BJT_MOD_TLEV:
value->iValue = here->BJTtlev;
return(OK);
case BJT_MOD_AF:
if (here->BJTfNexpGiven)
value->rValue = here->BJTfNexp;
else
value->rValue = 0.0;
case BJT_MOD_TLEVC:
value->iValue = here->BJTtlevc;
return(OK);
case BJT_MOD_TYPE:
if (here->BJTtype == NPN)
value->sValue = "npn";
else
value->sValue = "pnp";
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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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->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->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);

View File

@ -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);

View File

@ -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*/

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
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));
}
here->DIOtSatCur = model->DIOsatCur * exp(
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);
}