ngspice/examples/osdi/psp103/vacode/JUNCAP200_InitModel.include

379 lines
16 KiB
Plaintext

//======================================================================================
//======================================================================================
// Filename: JUNCAP200_InitModel.include
//======================================================================================
//======================================================================================
//
// (c) Copyright notice
//
// Since 2015 until today, PSP has been co-developed by NXP Semiconductors and
// CEA-Leti. For this part of the model, each claim undivided ownership and copyrights
// Since 2012 until 2015, PSP has been co-developed by NXP Semiconductors and
// Delft University of Technology. For this part of the model, each claim undivided
// ownership and copyrights
// Until and including 2011, PSP has been co-developed by NXP Semiconductors and
// Arizona State University. For this part of the model, NXP Semiconductors claims
// undivided ownership and copyrights.
//
//
// Version: 200.6.1, July 2020
//
//======================================================================================
//======================================================================================
//
// Further information can be found in the file releasenotesPSP103.txt
//
// --------------------------------------------------------------------------------------------------------------
// Calculation of internal parameters which are independent on instance parameters
// --------------------------------------------------------------------------------------------------------------
SWJUNEXP_i = 0.0;
if (SWJUNEXP > 0.5) begin
SWJUNEXP_i = 1.0;
end else begin
SWJUNEXP_i = 0.0;
end
`ifdef JUNCAP_StandAlone
// do nothing
`else // JUNCAP_StandAlone
if (SWJUNASYM == 0.0) begin
CJORBOTD_i = CJORBOT;
CJORSTID_i = CJORSTI;
CJORGATD_i = CJORGAT;
VBIRBOTD_i = VBIRBOT;
VBIRSTID_i = VBIRSTI;
VBIRGATD_i = VBIRGAT;
PBOTD_i = PBOT;
PSTID_i = PSTI;
PGATD_i = PGAT;
PHIGBOTD_i = PHIGBOT;
PHIGSTID_i = PHIGSTI;
PHIGGATD_i = PHIGGAT;
IDSATRBOTD_i = IDSATRBOT;
IDSATRSTID_i = IDSATRSTI;
IDSATRGATD_i = IDSATRGAT;
CSRHBOTD_i = CSRHBOT;
CSRHSTID_i = CSRHSTI;
CSRHGATD_i = CSRHGAT;
XJUNSTID_i = XJUNSTI;
XJUNGATD_i = XJUNGAT;
CTATBOTD_i = CTATBOT;
CTATSTID_i = CTATSTI;
CTATGATD_i = CTATGAT;
MEFFTATBOTD_i = MEFFTATBOT;
MEFFTATSTID_i = MEFFTATSTI;
MEFFTATGATD_i = MEFFTATGAT;
CBBTBOTD_i = CBBTBOT;
CBBTSTID_i = CBBTSTI;
CBBTGATD_i = CBBTGAT;
FBBTRBOTD_i = FBBTRBOT;
FBBTRSTID_i = FBBTRSTI;
FBBTRGATD_i = FBBTRGAT;
STFBBTBOTD_i = STFBBTBOT;
STFBBTSTID_i = STFBBTSTI;
STFBBTGATD_i = STFBBTGAT;
VBRBOTD_i = VBRBOT;
VBRSTID_i = VBRSTI;
VBRGATD_i = VBRGAT;
PBRBOTD_i = PBRBOT;
PBRSTID_i = PBRSTI;
PBRGATD_i = PBRGAT;
VJUNREFD_i = VJUNREF;
FJUNQD_i = FJUNQ;
end else begin
CJORBOTD_i = CJORBOTD;
CJORSTID_i = CJORSTID;
CJORGATD_i = CJORGATD;
VBIRBOTD_i = VBIRBOTD;
VBIRSTID_i = VBIRSTID;
VBIRGATD_i = VBIRGATD;
PBOTD_i = PBOTD;
PSTID_i = PSTID;
PGATD_i = PGATD;
PHIGBOTD_i = PHIGBOTD;
PHIGSTID_i = PHIGSTID;
PHIGGATD_i = PHIGGATD;
IDSATRBOTD_i = IDSATRBOTD;
IDSATRSTID_i = IDSATRSTID;
IDSATRGATD_i = IDSATRGATD;
CSRHBOTD_i = CSRHBOTD;
CSRHSTID_i = CSRHSTID;
CSRHGATD_i = CSRHGATD;
XJUNSTID_i = XJUNSTID;
XJUNGATD_i = XJUNGATD;
CTATBOTD_i = CTATBOTD;
CTATSTID_i = CTATSTID;
CTATGATD_i = CTATGATD;
MEFFTATBOTD_i = MEFFTATBOTD;
MEFFTATSTID_i = MEFFTATSTID;
MEFFTATGATD_i = MEFFTATGATD;
CBBTBOTD_i = CBBTBOTD;
CBBTSTID_i = CBBTSTID;
CBBTGATD_i = CBBTGATD;
FBBTRBOTD_i = FBBTRBOTD;
FBBTRSTID_i = FBBTRSTID;
FBBTRGATD_i = FBBTRGATD;
STFBBTBOTD_i = STFBBTBOTD;
STFBBTSTID_i = STFBBTSTID;
STFBBTGATD_i = STFBBTGATD;
VBRBOTD_i = VBRBOTD;
VBRSTID_i = VBRSTID;
VBRGATD_i = VBRGATD;
PBRBOTD_i = PBRBOTD;
PBRSTID_i = PBRSTID;
PBRGATD_i = PBRGATD;
VJUNREFD_i = VJUNREFD;
FJUNQD_i = FJUNQD;
end
`endif // JUNCAP_StandAlone
// Variables related to temperatures
tkr = `KELVINCONVERSION + TRJ;
tkd = max($temperature + DTA, `KELVINCONVERSION + `MINTEMP);
auxt = tkd / tkr;
KBOL_over_QELE = `KBOL / `QELE;
phitr = KBOL_over_QELE * tkr;
phitrinv = 1.0 / phitr;
phitd = KBOL_over_QELE * tkd;
phitdinv = 1.0 / phitd;
// Bandgap voltages at reference temperature
deltaphigr = -(7.02e-4 * tkr * tkr) / (1108.0 + tkr);
phigrbot = PHIGBOT + deltaphigr;
phigrsti = PHIGSTI + deltaphigr;
phigrgat = PHIGGAT + deltaphigr;
// Bandgap voltages at device temperature
deltaphigd = -(7.02e-4 * tkd * tkd) / (1108.0 + tkd);
phigdbot = PHIGBOT + deltaphigd;
phigdsti = PHIGSTI + deltaphigd;
phigdgat = PHIGGAT + deltaphigd;
// Factors ftd for ideal-current model
ftdbot = (pow(auxt, 1.5)) * exp(0.5 * ((phigrbot * phitrinv) - (phigdbot * phitdinv)));
ftdsti = (pow(auxt, 1.5)) * exp(0.5 * ((phigrsti * phitrinv) - (phigdsti * phitdinv)));
ftdgat = (pow(auxt, 1.5)) * exp(0.5 * ((phigrgat * phitrinv) - (phigdgat * phitdinv)));
// Temperature-scaled saturation current for ideal-current model
idsatbot = IDSATRBOT * ftdbot * ftdbot;
idsatsti = IDSATRSTI * ftdsti * ftdsti;
idsatgat = IDSATRGAT * ftdgat * ftdgat;
// Built-in voltages before limiting
ubibot = VBIRBOT * auxt - 2.0 * phitd * ln(ftdbot);
ubisti = VBIRSTI * auxt - 2.0 * phitd * ln(ftdsti);
ubigat = VBIRGAT * auxt - 2.0 * phitd * ln(ftdgat);
// Built-in voltages limited to phitd
vbibot = ubibot + phitd * ln(1 + exp((`vbilow - ubibot) * phitdinv));
vbisti = ubisti + phitd * ln(1 + exp((`vbilow - ubisti) * phitdinv));
vbigat = ubigat + phitd * ln(1 + exp((`vbilow - ubigat) * phitdinv));
// Inverse values of built-in voltages
vbiinvbot = 1.0 / vbibot;
vbiinvsti = 1.0 / vbisti;
vbiinvgat = 1.0 / vbigat;
// One minus the grading coefficient
one_minus_PBOT = 1.0 - PBOT;
one_minus_PSTI = 1.0 - PSTI;
one_minus_PGAT = 1.0 - PGAT;
// One over "one minus the grading coefficient"
one_over_one_minus_PBOT = 1.0 / one_minus_PBOT;
one_over_one_minus_PSTI = 1.0 / one_minus_PSTI;
one_over_one_minus_PGAT = 1.0 / one_minus_PGAT;
// Temperature-scaled zero-bias capacitance
cjobot = CJORBOT * pow((VBIRBOT * vbiinvbot), PBOT);
cjosti = CJORSTI * pow((VBIRSTI * vbiinvsti), PSTI);
cjogat = CJORGAT * pow((VBIRGAT * vbiinvgat), PGAT);
// Prefactor in physical part of charge model
qprefbot = cjobot * vbibot * one_over_one_minus_PBOT;
qprefsti = cjosti * vbisti * one_over_one_minus_PSTI;
qprefgat = cjogat * vbigat * one_over_one_minus_PGAT;
// Prefactor in mathematical extension of charge model
qpref2bot = `a * cjobot;
qpref2sti = `a * cjosti;
qpref2gat = `a * cjogat;
// Zero-bias depletion widths at reference temperature, needed in SRH and TAT model
wdepnulrbot = EPSSI / CJORBOT;
wdepnulrsti = XJUNSTI * EPSSI / CJORSTI;
wdepnulrgat = XJUNGAT * EPSSI / CJORGAT;
// Inverse values of "wdepnulr", used in BBT model
wdepnulrinvbot = 1.0 / wdepnulrbot;
wdepnulrinvsti = 1.0 / wdepnulrsti;
wdepnulrinvgat = 1.0 / wdepnulrgat;
// Inverse values of built-in voltages at reference temperature, needed in SRH and BBT model
VBIRBOTinv = 1.0 / VBIRBOT;
VBIRSTIinv = 1.0 / VBIRSTI;
VBIRGATinv = 1.0 / VBIRGAT;
// Some constants needed in erfc-approximation, needed in TAT model
perfc = (`SQRTPI * `aerfc);
berfc = ((-5.0 * (`aerfc) + 6.0 - pow((perfc), -2.0)) / 3.0);
cerfc = (1.0 - (`aerfc) - (berfc));
// Half the bandgap energy, limited to values > phitd, needed in TAT model
deltaEbot = max(0.5 * phigdbot, phitd);
deltaEsti = max(0.5 * phigdsti, phitd);
deltaEgat = max(0.5 * phigdgat, phitd);
// Values of atat, needed in TAT model
atatbot = deltaEbot * phitdinv;
atatsti = deltaEsti * phitdinv;
atatgat = deltaEgat * phitdinv;
// Values of btatpart, needed in TAT model
btatpartbot = sqrt(32.0 * MEFFTATBOT * `MELE * `QELE * (deltaEbot * deltaEbot * deltaEbot)) / (3.0 * `HBAR);
btatpartsti = sqrt(32.0 * MEFFTATSTI * `MELE * `QELE * (deltaEsti * deltaEsti * deltaEsti)) / (3.0 * `HBAR);
btatpartgat = sqrt(32.0 * MEFFTATGAT * `MELE * `QELE * (deltaEgat * deltaEgat * deltaEgat)) / (3.0 * `HBAR);
// Temperature-scaled values of FBBT, needed in BBT model
fbbtbot = FBBTRBOT * (1.0 + STFBBTBOT * (tkd - tkr));
fbbtsti = FBBTRSTI * (1.0 + STFBBTSTI * (tkd - tkr));
fbbtgat = FBBTRGAT * (1.0 + STFBBTGAT * (tkd - tkr));
fbbtbot = `CLIP_LOW(fbbtbot, 0.0);
fbbtsti = `CLIP_LOW(fbbtsti, 0.0);
fbbtgat = `CLIP_LOW(fbbtgat, 0.0);
// Values of fstop, needed in avalanche/breakdown model
alphaav = 1.0 - 1.0 / FREV;
fstopbot = 1.0 / (1.0 - pow(alphaav, PBRBOT));
fstopsti = 1.0 / (1.0 - pow(alphaav, PBRSTI));
fstopgat = 1.0 / (1.0 - pow(alphaav, PBRGAT));
// Inverse values of breakdown voltages, needed in avalanche/breakdown model
VBRinvbot = 1.0 / VBRBOT;
VBRinvsti = 1.0 / VBRSTI;
VBRinvgat = 1.0 / VBRGAT;
// Slopes for linear extrapolation close to and beyond breakdown, needed in avalanche/breakdown model
slopebot = -(fstopbot * fstopbot * pow(alphaav, (PBRBOT - 1.0))) * PBRBOT * VBRinvbot;
slopesti = -(fstopsti * fstopsti * pow(alphaav, (PBRSTI - 1.0))) * PBRSTI * VBRinvsti;
slopegat = -(fstopgat * fstopgat * pow(alphaav, (PBRGAT - 1.0))) * PBRGAT * VBRinvgat;
`ifdef JUNCAP_StandAlone
// do nothing
`else // JUNCAP_StandAlone
// Bandgap voltages at reference temperature for drain-bulk junction
phigrbot_d = PHIGBOTD_i + deltaphigr;
phigrsti_d = PHIGSTID_i + deltaphigr;
phigrgat_d = PHIGGATD_i + deltaphigr;
// Bandgap voltages at device temperature for drain-bulk junction
phigdbot_d = PHIGBOTD_i + deltaphigd;
phigdsti_d = PHIGSTID_i + deltaphigd;
phigdgat_d = PHIGGATD_i + deltaphigd;
// Factors ftd for ideal-current model for drain-bulk junction
ftdbot_d = (pow(auxt, 1.5)) * exp(0.5 * ((phigrbot_d * phitrinv) - (phigdbot_d * phitdinv)));
ftdsti_d = (pow(auxt, 1.5)) * exp(0.5 * ((phigrsti_d * phitrinv) - (phigdsti_d * phitdinv)));
ftdgat_d = (pow(auxt, 1.5)) * exp(0.5 * ((phigrgat_d * phitrinv) - (phigdgat_d * phitdinv)));
// Temperature-scaled saturation current for ideal-current model for drain-bulk junction
idsatbot_d = IDSATRBOTD_i * ftdbot_d * ftdbot_d;
idsatsti_d = IDSATRSTID_i * ftdsti_d * ftdsti_d;
idsatgat_d = IDSATRGATD_i * ftdgat_d * ftdgat_d;
// Built-in voltages before limiting for drain-bulk junction
ubibot_d = VBIRBOTD_i * auxt - 2.0 * phitd * ln(ftdbot_d);
ubisti_d = VBIRSTID_i * auxt - 2.0 * phitd * ln(ftdsti_d);
ubigat_d = VBIRGATD_i * auxt - 2.0 * phitd * ln(ftdgat_d);
// Built-in voltages limited to phitd for drain-bulk junction
vbibot_d = ubibot_d + phitd * ln(1.0 + exp((`vbilow - ubibot_d) * phitdinv));
vbisti_d = ubisti_d + phitd * ln(1.0 + exp((`vbilow - ubisti_d) * phitdinv));
vbigat_d = ubigat_d + phitd * ln(1.0 + exp((`vbilow - ubigat_d) * phitdinv));
// Inverse values of built-in voltages for drain-bulk junction
vbiinvbot_d = 1.0 / vbibot_d;
vbiinvsti_d = 1.0 / vbisti_d;
vbiinvgat_d = 1.0 / vbigat_d;
// One minus the grading coefficient for drain-bulk junction
one_minus_PBOT_d = 1.0 - PBOTD_i;
one_minus_PSTI_d = 1.0 - PSTID_i;
one_minus_PGAT_d = 1.0 - PGATD_i;
// One over "one minus the grading coefficient" for drain-bulk junction
one_over_one_minus_PBOT_d = 1.0 / one_minus_PBOT_d;
one_over_one_minus_PSTI_d = 1.0 / one_minus_PSTI_d;
one_over_one_minus_PGAT_d = 1.0 / one_minus_PGAT_d;
// Temperature-scaled zero-bias capacitance for drain-bulk junction
cjobot_d = CJORBOTD_i * pow((VBIRBOTD_i * vbiinvbot_d), PBOTD_i);
cjosti_d = CJORSTID_i * pow((VBIRSTID_i * vbiinvsti_d), PSTID_i);
cjogat_d = CJORGATD_i * pow((VBIRGATD_i * vbiinvgat_d), PGATD_i);
// Prefactor in physical part of charge model for drain-bulk junction
qprefbot_d = cjobot_d * vbibot_d * one_over_one_minus_PBOT_d;
qprefsti_d = cjosti_d * vbisti_d * one_over_one_minus_PSTI_d;
qprefgat_d = cjogat_d * vbigat_d * one_over_one_minus_PGAT_d;
// Prefactor in mathematical extension of charge model for drain-bulk junction
qpref2bot_d = `a * cjobot_d;
qpref2sti_d = `a * cjosti_d;
qpref2gat_d = `a * cjogat_d;
// Zero-bias depletion widths at reference temperature, needed in SRH and TAT model for drain-bulk junction
wdepnulrbot_d = EPSSI / CJORBOTD_i;
wdepnulrsti_d = XJUNSTID_i * EPSSI / CJORSTID_i;
wdepnulrgat_d = XJUNGATD_i * EPSSI / CJORGATD_i;
// Inverse values of "wdepnulr", used in BBT model for drain-bulk junction
wdepnulrinvbot_d = 1.0 / wdepnulrbot_d;
wdepnulrinvsti_d = 1.0 / wdepnulrsti_d;
wdepnulrinvgat_d = 1.0 / wdepnulrgat_d;
// Inverse values of built-in voltages at reference temperature, needed in SRH and BBT model for drain-bulk junction
VBIRBOTinv_d = 1.0 / VBIRBOTD_i;
VBIRSTIinv_d = 1.0 / VBIRSTID_i;
VBIRGATinv_d = 1.0 / VBIRGATD_i;
// Half the bandgap energy, limited to values > phitd, needed in TAT model for drain-bulk junction
deltaEbot_d = max(0.5 * phigdbot_d, phitd);
deltaEsti_d = max(0.5 * phigdsti_d, phitd);
deltaEgat_d = max(0.5 * phigdgat_d, phitd);
// Values of atat, needed in TAT model for drain-bulk junction
atatbot_d = deltaEbot_d * phitdinv;
atatsti_d = deltaEsti_d * phitdinv;
atatgat_d = deltaEgat_d * phitdinv;
// Values of btatpart, needed in TAT model for drain-bulk junction
btatpartbot_d = sqrt(32.0 * MEFFTATBOTD_i * `MELE * `QELE * (deltaEbot_d * deltaEbot_d * deltaEbot_d)) / (3.0 * `HBAR);
btatpartsti_d = sqrt(32.0 * MEFFTATSTID_i * `MELE * `QELE * (deltaEsti_d * deltaEsti_d * deltaEsti_d)) / (3.0 * `HBAR);
btatpartgat_d = sqrt(32.0 * MEFFTATGATD_i * `MELE * `QELE * (deltaEgat_d * deltaEgat_d * deltaEgat_d)) / (3.0 * `HBAR);
// Temperature-scaled values of FBBT, needed in BBT model for drain-bulk junction
fbbtbot_d = FBBTRBOTD_i * (1.0 + STFBBTBOTD_i * (tkd - tkr));
fbbtsti_d = FBBTRSTID_i * (1.0 + STFBBTSTID_i * (tkd - tkr));
fbbtgat_d = FBBTRGATD_i * (1.0 + STFBBTGATD_i * (tkd - tkr));
fbbtbot_d = `CLIP_LOW(fbbtbot_d, 0.0);
fbbtsti_d = `CLIP_LOW(fbbtsti_d, 0.0);
fbbtgat_d = `CLIP_LOW(fbbtgat_d, 0.0);
// Values of fstop, needed in avalanche/breakdown model for drain-bulk junction
fstopbot_d = 1.0 / (1.0 - pow(alphaav, PBRBOTD_i));
fstopsti_d = 1.0 / (1.0 - pow(alphaav, PBRSTID_i));
fstopgat_d = 1.0 / (1.0 - pow(alphaav, PBRGATD_i));
// Inverse values of breakdown voltages, needed in avalanche/breakdown model for drain-bulk junction
VBRinvbot_d = 1.0 / VBRBOTD_i;
VBRinvsti_d = 1.0 / VBRSTID_i;
VBRinvgat_d = 1.0 / VBRGATD_i;
// Slopes for linear extrapolation close to and beyond breakdown, needed in avalanche/breakdown model for drain-bulk junction
slopebot_d = -(fstopbot_d * fstopbot_d * pow(alphaav, (PBRBOTD_i - 1.0))) * PBRBOTD_i * VBRinvbot_d;
slopesti_d = -(fstopsti_d * fstopsti_d * pow(alphaav, (PBRSTID_i - 1.0))) * PBRSTID_i * VBRinvsti_d;
slopegat_d = -(fstopgat_d * fstopgat_d * pow(alphaav, (PBRGATD_i - 1.0))) * PBRGATD_i * VBRinvgat_d;
`endif // JUNCAP_StandAlone