cleaned comments

This commit is contained in:
Markus Mueller 2020-10-17 11:44:57 +02:00
parent 18fc66e71b
commit 5088e869ea
6 changed files with 61 additions and 66 deletions

View File

@ -0,0 +1,44 @@
HICUM2v2.40 Noise Voltage Test
* _______
* _|_ _|_
* /// / _ \
* \/ \/ I1
* /\_/\
* \___/
* _______|
* | _|
* |____|'
* B |`->
* _|_ E
* /VIN\
* \___/
* _|_
* ///
*
*
vin E 0 DC 0.0 ac 1.0u
I1 0 B 25mA
q1 B B E hicumL2V2p40
.include model-card-examples.lib
.control
setplot new
let V1u = 0*vector(81)
op
noise v(B) vin dec 10 1 100Meg 1
destroy
*let unknown1.V1u = sqrt(v(onoise_spectrum))
let unknown1.V1u = v(onoise_spectrum)
set pensize = 2
plot unknown1.V1u vs frequency loglog title HICUM_NoiseVoltage
echo " ... done."
.endcontrol
.end

View File

@ -19,6 +19,8 @@ IFparm HICUMpTable[] = { /* parameters */
IOPU("area", HICUM_AREA, IF_REAL, "Area factor"),
IOPU("off", HICUM_OFF, IF_FLAG, "Device initially off"),
IP("ic", HICUM_IC, IF_REALVEC, "Initial condition vector"),
// these are left here for future. Sometimes it is advantageous for debugging if one can set the initial node voltages of all nodes.
// OP("icvb", HICUM_IC_VB, IF_REAL, "Initial B potential"),
// OP("icvc", HICUM_IC_VC, IF_REAL, "Initial C potential"),
// OP("icve", HICUM_IC_VE, IF_REAL, "Initial E potential"),

View File

@ -149,7 +149,6 @@ HICUMask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFval
return(OK);
/* transconductances and capacitances */
case HICUM_QUEST_BETADC:
// HICUMask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFvalue *select)
HICUMask(ckt, instPtr, HICUM_QUEST_CC, &IC, select);
HICUMask(ckt, instPtr, HICUM_QUEST_CB, &IB, select);
if (IB.rValue != 0.0) {
@ -171,13 +170,13 @@ HICUMask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFval
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMibpei_Vbpei) );
return(OK);
case HICUM_QUEST_RMUI:
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMibici_Vbici) + ckt->CKTgmin); // TODO: Check sign vs VA-Code in ADS
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMibici_Vbici) + ckt->CKTgmin);
return(OK);
case HICUM_QUEST_RMUX:
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMibpci_Vbpci) + ckt->CKTgmin); // TODO: Check sign vs VA-Code in ADS
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMibpci_Vbpci) + ckt->CKTgmin);
return(OK);
case HICUM_QUEST_ROI:
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMiciei_Vbiei) + ckt->CKTgmin); // TODO: Check sign vs VA-Code in ADS
value->rValue = 1/( *(ckt->CKTstate0 + here->HICUMiciei_Vbiei) + ckt->CKTgmin);
return(OK);
case HICUM_QUEST_CPII:
value->rValue = here->HICUMcapjei + here->HICUMcapdeix;
@ -237,11 +236,9 @@ HICUMask(CKTcircuit *ckt, GENinstance *instPtr, int which, IFvalue *value, IFval
case HICUM_QUEST_ICK:
value->rValue = here->HICUMick;
return(OK);
/* power */
case HICUM_QUEST_POWER:
value->rValue = here->HICUMpterm;
return(OK);
/* temperature */
case HICUM_QUEST_TK:
value->rValue = here->HICUMtemp;
return(OK);

View File

@ -101,13 +101,9 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_MCF:
value->rValue = model->HICUMmcf;
return(OK);
//Transit time for excess recombination current at b-c barrier
case HICUM_MOD_TBHREC:
value->rValue = model->HICUMtbhrec;
return(OK);
//Base-Collector diode currents
case HICUM_MOD_IBCIS:
value->rValue = model->HICUMibcis;
return(OK);
@ -120,8 +116,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_MBCX:
value->rValue = model->HICUMmbcx;
return(OK);
//Base-Emitter tunneling current
case HICUM_MOD_IBETS:
value->rValue = model->HICUMibets;
return(OK);
@ -131,8 +125,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_TUNODE:
value->rValue = model->HICUMtunode = value->iValue;
return(OK);
//Base-Collector avalanche current
case HICUM_MOD_FAVL:
value->rValue = model->HICUMfavl;
return(OK);
@ -151,8 +143,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_ALKAV:
value->rValue = model->HICUMalkav;
return(OK);
//Series resistances
case HICUM_MOD_RBI0:
value->rValue = model->HICUMrbi0;
return(OK);
@ -177,8 +167,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_RCX:
value->rValue = model->HICUMrcx;
return(OK);
//Substrate transistor
case HICUM_MOD_ITSS:
value->rValue = model->HICUMitss;
return(OK);
@ -194,14 +182,12 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_TSF:
value->rValue = model->HICUMtsf;
return(OK);
//Intra-device substrate coupling
case HICUM_MOD_RSU:
value->rValue = model->HICUMrsu;
return(OK);
case HICUM_MOD_CSU:
//Depletion Capacitances
value->rValue = model->HICUMcsu;
return(OK);
case HICUM_MOD_CJEI0:
value->rValue = model->HICUMcjei0;
return(OK);
@ -280,8 +266,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_VPTSP:
value->rValue = model->HICUMvptsp;
return(OK);
//Diffusion Capacitances
case HICUM_MOD_T0:
value->rValue = model->HICUMt0;
return(OK);
@ -336,16 +320,12 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_ACBAR:
value->rValue = model->HICUMacbar;
return(OK);
//Isolation Capacitances
case HICUM_MOD_CBEPAR:
value->rValue = model->HICUMcbepar;
return(OK);
case HICUM_MOD_CBCPAR:
value->rValue = model->HICUMcbcpar;
return(OK);
//Non-quasi-static Effect
case HICUM_MOD_ALQF:
value->rValue = model->HICUMalqf;
return(OK);
@ -355,8 +335,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_FLNQS:
value->iValue = model->HICUMflnqs;
return(OK);
//Noise
case HICUM_MOD_KF:
value->rValue = model->HICUMkf;
return(OK);
@ -375,16 +353,12 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_AFRE:
value->rValue = model->HICUMafre;
return(OK);
//Lateral Geometry Scaling (at high current densities)
case HICUM_MOD_LATB:
value->rValue = model->HICUMlatb;
return(OK);
case HICUM_MOD_LATL:
value->rValue = model->HICUMlatl;
return(OK);
//Temperature dependence
case HICUM_MOD_VGB:
value->rValue = model->HICUMvgb;
return(OK);
@ -451,8 +425,6 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_ZETAVGBE:
value->rValue = model->HICUMzetavgbe;
return(OK);
//Self-Heating
case HICUM_MOD_FLSH:
value->iValue = model->HICUMflsh;
return(OK);
@ -468,13 +440,9 @@ HICUMmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value)
case HICUM_MOD_CTH:
value->rValue = model->HICUMcth;
return(OK);
//Compatibility with V2.1
case HICUM_MOD_FLCOMP:
value->rValue = model->HICUMflcomp;
return(OK);
//SOA-check
case HICUM_MOD_VBE_MAX:
value->rValue = model->HICUMvbeMax;
return(OK);

View File

@ -11,6 +11,7 @@ Spice3 Implementation: 2020 Dietmar Warning, Markus Müller, Mario Krattenmacher
* - We use dual numbers to calculate derivatives, this is readable and error proof.
* - The code is targeted to be readable and maintainable, speed is sacrificed for this purpose.
* - The verilog a code is available at the website of TU Dresden, Michael Schroeter's chair.
* - lambda functions are used to calculate derivatives of larger Verilog Macros
*/
#include "cmath"
@ -333,9 +334,6 @@ void hicum_HICJQ(duals::duald T, dual_double c_0, dual_double u_d, double z, dua
int
HICUMload(GENmodel *inModel, CKTcircuit *ckt)
/* actually load the current resistance value into the
* sparse matrix previously provided
*/
{
HICUMmodel *model = (HICUMmodel*)inModel;
HICUMinstance *here;
@ -387,7 +385,7 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
double Cdei_Vbiei, Cdei_Vbici, Cdei_Vrth;
double Cdci_Vbiei, Cdci_Vbici, Cdci_Vrth;
double Crbi_Vbiei, Crbi_Vbici, Crbi_Vrth;
double ick, ick_Vciei, ick_dT;//,cjcx01;//,cjcx02;
double ick, ick_Vciei, ick_dT;
//NQS
double Ixf1,Ixf2,Qxf1,Qxf2;
@ -460,6 +458,7 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
double Temp;
double Tdev_Vrth; //derivative device temperature to Vrth
//below variable has a real part equal to the device temperature and a dual part equal to dTdev/dVrth
//this is necessary, since for some Vrth, HICUM sets Tdev constant (eg very high self heating beyond 300K)
//then, dTdev/dVrth. Else it is equal to 1.
@ -626,7 +625,6 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
*T_cT = FFT_pcS*exp((FFdVc-model->HICUMvcbar)/vt)*(FCf_CT+Ix*FCdfCT_ditf)+*Q_CT/vt*FFdVc_ditf;
};
//declaration of lambda functions -----------------------------------
// TRANSIT-TIME AND STORED MINORITY CHARGE
// INPUT:
// itf : forward transport current
@ -1796,7 +1794,8 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Vsici = model->HICUMtype*Vsici;
Vsc = model->HICUMtype*Vsc;
if (selfheat) { // Thermal_update_with_self_heating
// Thermal update
if (selfheat) {
Temp = here->HICUMtemp+Vrth;
_iret = hicum_thermal_update(model, here, &Temp, &Tdev_Vrth);
@ -1828,7 +1827,6 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
hjei_vbe_dT = result.dpart();
//HICJQ(here->HICUMvt,cjci0_t,vdci_t,model->HICUMzci,vptci_t,V(br_bici),Qjci);
//Cjci = ddx(Qjci,V(bi));
hicum_HICJQ(Temp_dual, here->HICUMcjci0_t,here->HICUMvdci_t,model->HICUMzci,here->HICUMvptci_t, Vbici, &Cjci, &Cjci_Vbici, &Cjci_dT, &Qjci, &Qjci_Vbici, &Qjci_dT);
@ -1884,7 +1882,7 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Q_bf_dT= result_Q_bf.dpart();
Tf_dT = result_Tf.dpart();
if (!(Qf > RTOLC*Q_p || a_h > RTOLC)) { // in this case the newon is not run and the derivatives of the initial solution are needed
if (!(Qf > RTOLC*Q_p || a_h > RTOLC)) { // in this case the newton is not run and the derivatives of the initial solution are needed
calc_it_initial(Temp_dual, Vbiei , Vbici , Q_0+1_e*Q_0_dT , T_f0+1_e*T_f0_dT , ick+1_e*ick_dT , &result_itf, &result_itr, &result_Qf, &result_Qr, &result_Q_bf, &result_a_h, &result_Q_p, &result_Tf);
itf_dT = result_itf.dpart();
itr_dT = result_itr.dpart();
@ -1992,12 +1990,10 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Qrbi = Crbi*Vbpbi; //Vbpbi=(Vbpei-Vbiei)=(Vbpci-Vbici)
Qrbi_Vbpbi = Crbi;
Qrbi_Vbiei = Vbpbi*Crbi_Vbiei;// - Crbi; //not sure about this derivative
Qrbi_Vbici = Vbpbi*Crbi_Vbici;//- Crbi;
Qrbi_Vbiei = Vbpbi*Crbi_Vbiei;
Qrbi_Vbici = Vbpbi*Crbi_Vbici;
Qrbi_Vrth = Vbpbi*Crbi_Vrth;
// Qrbi = model->HICUMfcrbi*(Qjei+Qjci+Qdei+Qdci);
//HICCR: }
//Internal base current across b-c junction
@ -2063,14 +2059,12 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
hicum_HICJQ(Temp_dual, here->HICUMcjcx02_t,here->HICUMvdcx_t,model->HICUMzcx,here->HICUMvptcx_t, Vbpci, &Cjcx_ii, &Cjcx_ii_Vbpci, &Cjcx_ii_dT, &Qjcx_ii, &Qjcx_ii_Vbpci, &Qjcx_ii_dT);
//Depletion substrate capacitance and charge at inner s-c junction (si,ci)
//HICJQ(here->HICUMvt,here->HICUMcjs0_t,here->HICUMvds_t,model->HICUMzs,here->HICUMvpts_t,Vsici,&Cjs,&Cjs_Vsici,&Qjs);
hicum_HICJQ(Temp_dual, here->HICUMcjs0_t,here->HICUMvds_t,model->HICUMzs,here->HICUMvpts_t, Vsici, &Cjs, &Cjs_Vsici, &Cjs_dT, &Qjs, &Qjs_Vsici, &Qjs_dT);
/*
* Peripheral substrate capacitance and charge at s-c junction (s,c)
* Bias dependent only if model->HICUMvdsp > 0
*/
if (model->HICUMvdsp > 0) {
//HICJQ(here->HICUMvt,here->HICUMcscp0_t,here->HICUMvdsp_t,model->HICUMzsp,here->HICUMvptsp_t,Vsc,&Cscp,&Cscp_Vsc,&Qscp);
hicum_HICJQ(Temp_dual, here->HICUMcscp0_t,here->HICUMvdsp_t,model->HICUMzsp,here->HICUMvptsp_t, Vsc, &Cscp, &Cscp_Vsc, &Cscp_dT, &Qscp, &Qscp_Vsc, &Qscp_dT);
} else {
// Constant, temperature independent capacitance
@ -2083,7 +2077,6 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
}
//Parasitic substrate transistor transfer current and diffusion charge
//calc_itss = [&](duals::duald T, duals::duald Vbpci, duals::duald Vsici, duals::duald * HSI_Tsu, duals::duald * Qdsu){
calc_itss(Temp_dual, Vbpci , Vsici , &result_HSI_TSU, &result_Qdsu);
HSI_Tsu = result_HSI_TSU.rpart();
Qdsu = result_Qdsu.rpart();
@ -2154,8 +2147,7 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Qdeix_dT = Qdei_dT;
Qdeix_Vxf = 0.0;
// Excess Phase calculation -> hand implementation
// Excess Phase calculation -> hand implementation instead of dual numbers
if (nqs) { // && (ckt->CKTmode & (MODETRAN | MODEAC) ) ) { //evaluate nqs network only in TRANSIENT and AC modes.
Ixf1 = (Vxf2-itf)/Tf*model->HICUMt0;
Ixf1_Vxf1 = 0.0;
@ -2196,7 +2188,6 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Qxf = model->HICUMalqf*model->HICUMt0*Vxf; //for RC nw
Qxf_Vxf = model->HICUMalqf*model->HICUMt0; //for RC nw
//convergency killer
Qdeix = Vxf; //for RC nw
Qdeix_Vxf = 1.0;
Qdeix_Vbiei = 0;
@ -2360,7 +2351,6 @@ HICUMload(GENmodel *inModel, CKTcircuit *ckt)
Ith_Vbiei += it_Vbiei*(Vbiei-Vbici) + it;
Ith_Vbici += it_Vbici*(Vbiei-Vbici) - it;
//avalanche current
//(here->HICUMvdci_t.rpart-Vbici)*iavl = vdci_t*iavl - Vbici*iavl
Ith_Vbici += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbici - iavl;
Ith_Vbiei += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbiei;
} else if (model->HICUMflsh == 2) {

View File

@ -186,7 +186,7 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
// }
//}
//This routine calculate the derivative with respect to Vrth. Since at some point
//This routine calculates the derivatives with respect to Vrth. Since at some point
// Tdev becomes constant (see above), we need to account for this like below.
//temp = *(HICUMTemp)+1_e* *(Tdev_Vrth); // dual number device temperature
@ -209,7 +209,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
log(here->HICUMvt.rpart / (CONSTroot2*here->HICUMibeis_scaled));
//Internal b-e junction capacitance
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,cjei0_scaled,model->HICUMvdei,model->HICUMzei,model->HICUMajei,1,vgbe0,&here->HICUMcjei0_t,&here->HICUMvdei_t,&here->HICUMajei_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
here->HICUMcjei0_scaled, model->HICUMvdei, model->HICUMzei, model->HICUMajei, 1, vgbe0,
&here->HICUMcjei0_t.rpart, &here->HICUMvdei_t.rpart, &here->HICUMajei_t.rpart,
@ -360,7 +359,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
here->HICUMvces_t.dpart = a.dpart();
//Internal b-c junction capacitance
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,cjci0_scaled,model->HICUMvdci,model->HICUMzci,model->HICUMvptci,0,vgbc0,&cjci0_t,&vdci_t,&vptci_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
here->HICUMcjci0_scaled, model->HICUMvdci, model->HICUMzci, model->HICUMvptci, 0, vgbc0,
&here->HICUMcjci0_t.rpart, &here->HICUMvdci_t.rpart, &here->HICUMvptci_t.rpart,
@ -393,7 +391,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
here->HICUMrbi0_t.dpart = a.dpart();
//Peripheral b-e junction capacitance
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,cjep0_scaled,model->HICUMvdep,model->HICUMzep,model->HICUMajep,1,vgbe0,&cjep0_t,&vdep_t,&ajep_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
here->HICUMcjep0_scaled, model->HICUMvdep, model->HICUMzep, model->HICUMajep, 1, vgbe0,
&here->HICUMcjep0_t.rpart, &here->HICUMvdep_t.rpart, &here->HICUMajep_t.rpart,
@ -441,7 +438,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
}
//Temperature mapping for tunneling current is done inside HICTUN
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,1.0,model->HICUMvdcx,model->HICUMzcx,model->HICUMvptcx,0,vgbc0,&cratio_t,&vdcx_t,&vptcx_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
1.0, model->HICUMvdcx, model->HICUMzcx, model->HICUMvptcx, 0, vgbc0,
&cratio_t_real, &here->HICUMvdcx_t.rpart, &here->HICUMvptcx_t.rpart,
@ -472,7 +468,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
here->HICUMtsf_t.dpart = a.dpart();
//Capacitance for c-s junction
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcjs0,model->HICUMvds,model->HICUMzs,model->HICUMvpts,0,vgsc0,&cjs0_t,&vds_t,&vpts_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
model->HICUMcjs0, model->HICUMvds, model->HICUMzs, model->HICUMvpts, 0, vgsc0,
&here->HICUMcjs0_t.rpart, &here->HICUMvds_t.rpart, &here->HICUMvpts_t.rpart,
@ -482,7 +477,6 @@ int hicum_thermal_update(HICUMmodel *inModel, HICUMinstance *inInstance, double
* Save computional effort otherwise
*/
if (model->HICUMvdsp > 0) {
// TMPHICJ(here->HICUMvt0,here->HICUMvt,here->HICUMqtt0,here->HICUMln_qtt0,here->HICUMmg,model->HICUMcscp0,model->HICUMvdsp,model->HICUMzsp,model->HICUMvptsp,0,vgsc0,&cscp0_t,&vdsp_t,&vptsp_t);
hicum_TMPHICJ(vt, here->HICUMvt0, qtt0, ln_qtt0, mg,
model->HICUMcscp0, model->HICUMvdsp, model->HICUMzsp, model->HICUMvptsp, 0, vgsc0,
&here->HICUMcscp0_t.rpart, &here->HICUMvdsp_t.rpart, &here->HICUMvptsp_t.rpart,