3325 lines
162 KiB
C++
3325 lines
162 KiB
C++
/**********
|
|
License : 3-clause BSD
|
|
Spice3 Implementation: 2019-2020 Dietmar Warning, Markus Müller, Mario Krattenmacher
|
|
Model Author : 1990 Michael Schröter TU Dresden
|
|
**********/
|
|
|
|
/*
|
|
* This file defines the HICUM L2.4.0 model load function
|
|
* Comments on the Code:
|
|
* - 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>
|
|
#ifndef M_PI
|
|
#define M_PI 3.1415926535897932384626433832795
|
|
#endif
|
|
#include "duals/dual"
|
|
#include "hicumL2.hpp"
|
|
#include "hicumL2temp.hpp"
|
|
#include <functional>
|
|
|
|
//ngspice header files written in C
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
#include "ngspice/typedefs.h"
|
|
#include "ngspice/devdefs.h"
|
|
#include "ngspice/const.h"
|
|
#include "ngspice/trandefs.h"
|
|
#include "ngspice/sperror.h"
|
|
#include "hicum2defs.h"
|
|
#include "ngspice/ngspice.h"
|
|
#include "ngspice/cktdefs.h"
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
//HICUM DEFINITIONS
|
|
#define VPT_thresh 1.0e2
|
|
#define Dexp_lim 80.0
|
|
#define Cexp_lim 80.0
|
|
#define DFa_fj 1.921812
|
|
#define RTOLC 1.0e-5
|
|
#define l_itmax 100
|
|
#define MIN_R 0.001
|
|
|
|
using namespace duals::literals;
|
|
|
|
// IDEAL DIODE (WITHOUT CAPACITANCE):
|
|
// conductance calculation not required
|
|
// INPUT:
|
|
// IS, IST : saturation currents (model parameter related)
|
|
// UM1 : ideality factor
|
|
// U : branch voltage
|
|
// IMPLICIT INPUT:
|
|
// T : Temperature
|
|
// OUTPUT:
|
|
// Iz : diode current
|
|
duals::duald HICDIO(duals::duald T, duals::duald IST, double UM1, duals::duald U)
|
|
{
|
|
duals::duald DIOY, le, vt;
|
|
|
|
vt = CONSTboltz * T / CHARGE;
|
|
DIOY = U/(UM1*vt);
|
|
// le = exp(DIOY); // would be the best way... But stay close to HICUML2.va
|
|
// return IST*(le-1.0);
|
|
if (IST > 0.0) {
|
|
if (DIOY > Dexp_lim) {
|
|
le = (1 + (DIOY - Dexp_lim));
|
|
DIOY = Dexp_lim;
|
|
return IST*(le*exp(DIOY)-1.0);
|
|
} else if (DIOY <= -14.0) {
|
|
return -IST;
|
|
} else {
|
|
le = exp(DIOY);
|
|
return IST*(le-1.0);
|
|
}
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
// DEPLETION CHARGE CALCULATION
|
|
// Hyperbolic smoothing used; no punch-through
|
|
// INPUT:
|
|
// c_0 : zero-bias capacitance
|
|
// u_d : built-in voltage
|
|
// z : exponent coefficient
|
|
// a_j : control parameter for C peak value at high forward bias
|
|
// U_cap : voltage across junction
|
|
// IMPLICIT INPUT:
|
|
// T : Temperature
|
|
// OUTPUT:
|
|
// Qz : depletion Charge
|
|
// C : depletion capacitance
|
|
void QJMODF(duals::duald T, duals::duald c_0, duals::duald u_d, double z, duals::duald a_j, duals::duald U_cap, duals::duald * C, duals::duald * Qz)
|
|
{
|
|
duals::duald DFV_f, DFv_e, DFs_q, DFs_q2, DFv_j, DFdvj_dv, DFQ_j, DFC_j1, DFb, vt;
|
|
vt = CONSTboltz * T / CHARGE;
|
|
if (c_0 > 0.0) {
|
|
DFV_f = u_d*(1.0-exp(-log(a_j)/z));
|
|
DFv_e = (DFV_f-U_cap)/vt;
|
|
DFs_q = sqrt(DFv_e*DFv_e+DFa_fj);
|
|
DFs_q2 = (DFv_e+DFs_q)*0.5;
|
|
DFv_j = DFV_f-vt*DFs_q2;
|
|
DFdvj_dv = DFs_q2/DFs_q;
|
|
DFb = log(1.0-DFv_j/u_d);
|
|
DFC_j1 = c_0*exp(-z*DFb)*DFdvj_dv;
|
|
*C = DFC_j1+a_j*c_0*(1.0-DFdvj_dv);
|
|
DFQ_j = c_0*u_d*(1.0-exp(DFb*(1.0-z)))/(1.0-z);
|
|
*Qz = DFQ_j+a_j*c_0*(U_cap-DFv_j);
|
|
} else {
|
|
*C = 0.0;
|
|
*Qz = 0.0;
|
|
}
|
|
}
|
|
|
|
// DEPLETION CHARGE CALCULATION CONSIDERING PUNCH THROUGH
|
|
// smoothing of reverse bias region (punch-through)
|
|
// and limiting to a_j=Cj,max/Cj0 for forward bias.
|
|
// Important for base-collector and collector-substrate junction
|
|
// INPUT:
|
|
// c_0 : zero-bias capacitance
|
|
// u_d : built-in voltage
|
|
// z : exponent coefficient
|
|
// a_j : control parameter for C peak value at high forward bias
|
|
// v_pt : punch-through voltage (defined as qNw^2/2e)
|
|
// U_cap : voltage across junction
|
|
// IMPLICIT INPUT:
|
|
// VT : thermal voltage
|
|
// OUTPUT:
|
|
// Qz : depletion charge
|
|
// C : depletion capacitance
|
|
void QJMOD(duals::duald T, duals::duald c_0, duals::duald u_d, double z, double a_j, duals::duald v_pt, duals::duald U_cap, duals::duald * C, duals::duald * Qz)
|
|
{
|
|
duals::duald DQ_j1, DQ_j2, DQ_j3, DC_j1, DC_j2, DC_j3, De_1, De_2, Dzr1, DCln1, DCln2, Dz1, Dv_j1, Dv_j2, De, Da, Dv_r, Dv_j4, Dv_e, DC_c, DC_max, DV_f, Dv_p, Dz_r, vt;
|
|
vt = CONSTboltz * T / CHARGE;
|
|
if (c_0 > 0.0){
|
|
Dz_r = z/4.0;
|
|
Dv_p = v_pt-u_d;
|
|
DV_f = u_d*(1.0-exp(-log(a_j)/z));
|
|
DC_max = a_j*c_0;
|
|
DC_c = c_0*exp((Dz_r-z)*log(v_pt/u_d));
|
|
Dv_e = (DV_f-U_cap)/vt;
|
|
if(Dv_e < Cexp_lim) {
|
|
De = exp(Dv_e);
|
|
De_1 = De/(1.0+De);
|
|
Dv_j1 = DV_f-vt*log(1.0+De);
|
|
} else {
|
|
De_1 = 1.0;
|
|
Dv_j1 = U_cap;
|
|
}
|
|
Da = 0.1*Dv_p+4.0*vt;
|
|
Dv_r = (Dv_p+Dv_j1)/Da;
|
|
if(Dv_r < Cexp_lim){
|
|
De = exp(Dv_r);
|
|
De_2 = De/(1.0+De);
|
|
Dv_j2 = -Dv_p+Da*(log(1.0+De)-exp(-(Dv_p+DV_f)/Da));
|
|
} else {
|
|
De_2 = 1.0;
|
|
Dv_j2 = Dv_j1;
|
|
}
|
|
Dv_j4 = U_cap-Dv_j1;
|
|
DCln1 = log(1.0-Dv_j1/u_d);
|
|
DCln2 = log(1.0-Dv_j2/u_d);
|
|
Dz1 = 1.0-z;
|
|
Dzr1 = 1.0-Dz_r;
|
|
DC_j1 = c_0*exp(DCln2*(-z))*De_1*De_2;
|
|
DC_j2 = DC_c*exp(DCln1*(-Dz_r))*(1.0-De_2);
|
|
DC_j3 = DC_max*(1.0-De_1);
|
|
*C = DC_j1+DC_j2+DC_j3;
|
|
DQ_j1 = c_0*(1.0-exp(DCln2*Dz1))/Dz1;
|
|
DQ_j2 = DC_c*(1.0-exp(DCln1*Dzr1))/Dzr1;
|
|
DQ_j3 = DC_c*(1.0-exp(DCln2*Dzr1))/Dzr1;
|
|
*Qz = (DQ_j1+DQ_j2-DQ_j3)*u_d+DC_max*Dv_j4;
|
|
} else {
|
|
*C = 0.0;
|
|
*Qz = 0.0;
|
|
}
|
|
}
|
|
|
|
// A CALCULATION NEEDED FOR COLLECTOR MINORITY CHARGE FORMULATION
|
|
// INPUT:
|
|
// zb,zl : zeta_b and zeta_l (model parameters, TED 10/96)
|
|
// w : normalized injection width
|
|
// OUTPUT:
|
|
// hicfcio : function of equation (2.1.17-10)
|
|
void HICFCI(double zb, double zl, duals::duald w, duals::duald * hicfcio, duals::duald * dhicfcio_dw)
|
|
{
|
|
duals::duald a, a2, a3, r, lnzb, x, z;
|
|
z = zb*w;
|
|
lnzb = log(1+zb*w);
|
|
if(z > 1.0e-6){
|
|
x = 1.0+z;
|
|
a = x*x;
|
|
a2 = 0.250*(a*(2.0*lnzb-1.0)+1.0);
|
|
a3 = (a*x*(3.0*lnzb-1.0)+1.0)/9.0;
|
|
r = zl/zb;
|
|
*hicfcio = ((1.0-r)*a2+r*a3)/zb;
|
|
*dhicfcio_dw = ((1.0-r)*x+r*a)*lnzb;
|
|
} else {
|
|
a = z*z;
|
|
a2 = 3.0+z-0.25*a+0.10*z*a;
|
|
a3 = 2.0*z+0.75*a-0.20*a*z;
|
|
*hicfcio = (zb*a2+zl*a3)*w*w/6.0;
|
|
*dhicfcio_dw = (1+zl*w)*(1+z)*lnzb;
|
|
}
|
|
}
|
|
|
|
// NEEDED TO CALCULATE WEIGHTED ICCR COLLECTOR MINORITY CHARGE
|
|
// INPUT:
|
|
// z : zeta_b or zeta_l
|
|
// w : normalized injection width
|
|
// OUTPUT:
|
|
// hicfcto : output
|
|
// dhicfcto_dw : derivative of output wrt w
|
|
void HICFCT(double z, duals::duald w, duals::duald * hicfcto, duals::duald *dhicfcto_dw)
|
|
{
|
|
duals::duald a, lnz;
|
|
a = z*w;
|
|
lnz = log(1+z*w);
|
|
if (a > 1.0e-6){
|
|
*hicfcto = (a - lnz)/z;
|
|
*dhicfcto_dw = a / (1.0 + a);
|
|
} else {
|
|
*hicfcto = 0.5 * a * w;
|
|
*dhicfcto_dw = a;
|
|
}
|
|
}
|
|
|
|
// DEPLETION CHARGE & CAPACITANCE CALCULATION SELECTOR
|
|
// Dependent on junction punch-through voltage
|
|
// Important for collector related junctions
|
|
void HICJQ(duals::duald T, duals::duald c_0, duals::duald u_d, double z, duals::duald v_pt, duals::duald U_cap, duals::duald * C,duals::duald * Qz)
|
|
{
|
|
if(v_pt.rpart() < VPT_thresh){
|
|
QJMOD(T,c_0,u_d,z,2.4,v_pt,U_cap,C,Qz);
|
|
} else {
|
|
QJMODF(T,c_0,u_d,z,2.4,U_cap,C,Qz);
|
|
}
|
|
}
|
|
|
|
duals::duald calc_hjei_vbe(duals::duald Vbiei, duals::duald T, HICUMinstance * here, HICUMmodel * model){
|
|
//calculates hje_vbe
|
|
//wrapping in a routine allows easy calculation of derivatives with dual numbers
|
|
duals::duald vj, vj_z, vt, vdei_t, hjei0_t, ahjei_t;
|
|
if (model->HICUMahjei == 0.0){
|
|
return model->HICUMhjei;
|
|
}else{
|
|
double T_dpart = T.dpart();
|
|
vt = CONSTboltz * T / CHARGE;
|
|
vdei_t = here->HICUMvdei_t.rpart;
|
|
hjei0_t = here->HICUMhjei0_t.rpart;
|
|
ahjei_t = here->HICUMahjei_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
vdei_t.dpart(here->HICUMvdei_t.dpart);
|
|
hjei0_t.dpart(here->HICUMhjei0_t.dpart);
|
|
ahjei_t.dpart(here->HICUMahjei_t.dpart);
|
|
}
|
|
//vendhjei = vdei_t*(1.0-exp(-ln(ajei_t)/z_h));
|
|
vj = (vdei_t-Vbiei)/(model->HICUMrhjei*vt);
|
|
vj = vdei_t-model->HICUMrhjei*vt*(vj+sqrt(vj*vj+DFa_fj))*0.5;
|
|
vj = (vj-vt)/vt;
|
|
vj = vt*(1.0+(vj+sqrt(vj*vj+DFa_fj))*0.5);
|
|
vj_z = (1.0-exp(model->HICUMzei*log(1.0-vj/vdei_t)))*ahjei_t;
|
|
return hjei0_t*(exp(vj_z)-1.0)/vj_z;
|
|
}
|
|
}
|
|
|
|
|
|
void hicum_diode(duals::duald T, dual_double IS, double UM1, double U, double *Iz, double *Gz, double *Tz)
|
|
{
|
|
// T is T_dev + 1_e*T_dev_Vrth
|
|
//wrapper for hicum diode equation that also generates derivatives
|
|
duals::duald result = 0;
|
|
|
|
duals::duald is_t = IS.rpart;
|
|
result = HICDIO(T.rpart(), is_t, UM1, U+1_e);
|
|
*Iz = result.rpart();
|
|
*Gz = result.dpart(); //derivative for U
|
|
is_t = IS.rpart + 1_e*IS.dpart;
|
|
result = HICDIO(T, is_t, UM1, U);
|
|
*Tz = result.dpart(); //derivative for T
|
|
}
|
|
|
|
void hicum_qjmodf(duals::duald T, dual_double c_0, dual_double u_d, double z, dual_double a_j, double U_cap, double *C, double *C_dU, double *C_dT, double *Qz, double *Qz_dU, double *Qz_dT)
|
|
{
|
|
//wrapper for QJMODF that also generates derivatives
|
|
duals::duald Cresult = 0;
|
|
duals::duald Qresult = 0;
|
|
duals::duald c_0_t = c_0.rpart;
|
|
duals::duald u_d_t = u_d.rpart;
|
|
duals::duald a_j_t = a_j.rpart;
|
|
QJMODF(T.rpart(), c_0_t, u_d_t, z, a_j_t, U_cap+1_e, &Cresult, &Qresult);
|
|
*C = Cresult.rpart();
|
|
*C_dU = Cresult.dpart();
|
|
*Qz = Qresult.rpart();
|
|
*Qz_dU = Qresult.dpart();
|
|
|
|
c_0_t.dpart(c_0.dpart);
|
|
u_d_t.dpart(u_d.dpart);
|
|
a_j_t.dpart(a_j.dpart);
|
|
QJMODF(T, c_0_t, u_d_t, z, a_j_t, U_cap, &Cresult, &Qresult);
|
|
*Qz_dT = Qresult.dpart();
|
|
*C_dT = Cresult.dpart();
|
|
}
|
|
|
|
void hicum_HICJQ(duals::duald T, dual_double c_0, dual_double u_d, double z, dual_double v_pt, double U_cap, double * C, double * C_dU, double * C_dT, double * Qz, double * Qz_dU, double * Qz_dT)
|
|
{
|
|
//wrapper for HICJQ that also generates derivatives
|
|
duals::duald Cresult = 0;
|
|
duals::duald Qresult = 0;
|
|
duals::duald c_0_t = c_0.rpart;
|
|
duals::duald u_d_t = u_d.rpart;
|
|
duals::duald v_pt_t = v_pt.rpart;
|
|
HICJQ(T.rpart(), c_0_t, u_d_t, z, v_pt_t, U_cap+1_e, &Cresult, &Qresult);
|
|
*C = Cresult.rpart();
|
|
*C_dU = Cresult.dpart();
|
|
*Qz = Qresult.rpart();
|
|
*Qz_dU = Qresult.dpart();
|
|
|
|
c_0_t.dpart(c_0.dpart);
|
|
u_d_t.dpart(u_d.dpart);
|
|
v_pt_t.dpart(v_pt.dpart);
|
|
HICJQ(T, c_0_t, u_d_t, z, v_pt_t, U_cap, &Cresult, &Qresult);
|
|
*Qz_dT = Qresult.dpart();
|
|
*C_dT = Cresult.dpart();
|
|
}
|
|
|
|
int
|
|
HICUMload(GENmodel *inModel, CKTcircuit *ckt)
|
|
{
|
|
HICUMmodel *model = (HICUMmodel*)inModel;
|
|
HICUMinstance *here;
|
|
|
|
//Declaration of variables
|
|
|
|
double cbcpar1,cbcpar2,cbepar2,cbepar1,Oich,Otbhrec;
|
|
|
|
//Charges, capacitances and currents
|
|
double Qjci,Qjei,Qjep;
|
|
double Qdei,Qrbi;
|
|
double Qdei_Vbiei, Qdei_Vbici, Qdei_dT;
|
|
double it,ibei,irei,ibci,ibep,irep,ibh_rec;
|
|
double ibet,iavl,iavl_dT,iavl_Vbiei,iavl_Vbici;
|
|
double ijbcx,ijbcx_dT,ijbcx_Vbpci,ijsc,ijsc_Vsici,ijsc_Vrth,Qjs,Qscp,HSI_Tsu,Qdsu;
|
|
double HSI_Tsu_Vbpci, HSI_Tsu_Vsici, HSI_Tsu_dT;
|
|
double Qdsu_Vbpci, Qdsu_Vsici, Qdsu_dT;
|
|
duals::duald result_Qdsu, result_HSI_TSU;
|
|
double Qscp_Vsc, Qscp_dT;
|
|
double Cscp_Vsc, Cscp_dT;
|
|
|
|
//Base resistance and self-heating power
|
|
double rbi=0.0,pterm,pterm_dT;
|
|
|
|
//Model initialization
|
|
double C_1;
|
|
|
|
//Model evaluation
|
|
double Crbi,Cjci,Cjei,Cjep,Cscp;
|
|
double Cjs, Cjs_dT;
|
|
double Cjcx_i, Cjcx_i_Vbci, Cjcx_i_dT;
|
|
double Cjcx_ii, Cjcx_ii_Vbpci, Cjcx_ii_dT;
|
|
double Qjcx_i , Qjcx_i_Vbci , Qjcx_i_dT ;
|
|
double Qjcx_ii, Qjcx_ii_Vbpci, Qjcx_ii_dT;
|
|
double Qjs_Vsici, Qjs_dT;
|
|
|
|
double itf,itr,Tf,Tr,a_bpt,Q_0;
|
|
double itf_Vbiei, itf_Vbici, itf_dT;
|
|
double itr_Vbiei, itr_Vbici, itr_dT;
|
|
double Tf_Vbiei, Tf_Vbici, Tf_dT;
|
|
double it_Vbiei, it_Vbici, it_dT;
|
|
double Qf_Vbiei, Qf_Vbici, Qf_dT;
|
|
double Qr_Vbiei, Qr_Vbici, Qr_dT;
|
|
duals::duald result_itf, result_itr, result_Qf, result_Qr, result_Q_bf, result_a_h, result_Q_p, result_Tf; //intermediate variables when calling void dual functions
|
|
double T_f0, Q_p, a_h;
|
|
double Q_bf, Q_bf_Vbiei, Q_bf_Vbici, Q_bf_dT;
|
|
double Q_pT, Q_pT_dVbiei, Q_pT_dVbici, Q_pT_dT;
|
|
double Qf, Cdei, Qr, Cdci;
|
|
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;
|
|
|
|
//NQS
|
|
double Ixf1,Ixf2,Qxf1,Qxf2;
|
|
double Ixf1_Vxf1, Ixf1_Vxf2, Ixf1_ditf, Ixf1_dTf, Ixf1_Vbiei, Ixf1_Vbici, Ixf1_dT;
|
|
double Ixf2_Vxf1, Ixf2_Vbiei, Ixf2_Vbici, Ixf2_dT;
|
|
double Ixf_Vxf, Ixf_Tf,Ixf_Qdei,Ixf_Vbiei, Ixf_Vbici, Ixf_dT;
|
|
double Ixf2_Vxf2, Ixf2_dTf;
|
|
double Itxf, Qdeix;
|
|
double Itxf_Vxf2, Itxf_Vbici, Itxf_Vbiei, Itxf_dT;
|
|
double Qdeix_Vxf, Qdeix_dT, Qdeix_Vbici, Qdeix_Vbiei;
|
|
double Qxf, Ixf, Vxf;
|
|
double Vxf1, Vxf2;
|
|
|
|
double hjei_vbe;
|
|
|
|
double Vbiei, Vbici, Vciei, Vbpei, Vbpbi, Vbpci, Vsici, Vbci, Vsc;
|
|
double Vbici_temp, Vaval;
|
|
|
|
//Model flags
|
|
int use_aval;
|
|
|
|
//helpers for ngspice implementation
|
|
duals::duald result;
|
|
|
|
//end of variables
|
|
|
|
#ifndef PREDICTOR
|
|
double xfact;
|
|
#endif
|
|
double delvbiei, delvbici, delvbpei, delvbpbi, delvbpci, delvsici, delvbbp, delveie, delvciei, delvcic, delvxf2;
|
|
double ibieihat;
|
|
double ibpeihat;
|
|
double icieihat;
|
|
double ibicihat;
|
|
double ibpcihat;
|
|
double ibpbihat;
|
|
double isicihat;
|
|
double ibpsihat;
|
|
double ithhat;
|
|
double ceq, geq;
|
|
double rhs_current;
|
|
int icheck=1;
|
|
int ichk1, ichk2, ichk3, ichk4, ichk5, ichk6;
|
|
int error;
|
|
double Vbe, Vcic, Vbbp, Veie, Vsis, Vbpe;
|
|
|
|
double Ibiei, Ibiei_Vbiei, Ibiei_Vxf=0.0, Ibiei_Vbici;
|
|
double Ibici, Ibici_Vbici, Ibici_Vbiei;
|
|
double Ibpei, Ibpei_Vbpei;
|
|
double Ibpci, Ibpci_Vbpci;
|
|
double Isici, Isici_Vsici;//
|
|
double Isc=0.0, Isc_Vsc=0.0;
|
|
double Iciei, Iciei_Vbiei, Iciei_Vbici, Iciei_Vrth, Iciei_Vxf2;
|
|
double Ibbp_Vbbp=0.0;
|
|
double Isis_Vsis;
|
|
double Ieie, Ieie_Veie=0.0;
|
|
double Ibpbi, Ibpbi_Vbpbi, Ibpbi_Vbici, Ibpbi_Vbiei;
|
|
double Ibpsi, Ibpsi_Vbpci, Ibpsi_Vsici, Ibpsi_Vrth;
|
|
double Icic_Vcic=0.0;
|
|
double Ibci=0.0, Ibci_Vbci=0.0;
|
|
double hjei_vbe_Vbiei, hjei_vbe_dT, ibet_Vbpei, ibet_dT, ibet_Vbiei, ibh_rec_Vbiei, ibh_rec_dT, ibh_rec_Vbici;
|
|
double irei_Vbiei, irei_dT;
|
|
double ibep_Vbpei, ibep_dT;
|
|
double irep_Vbpei, irep_dT, rbi_dT, rbi_Vbiei, rbi_Vbici;
|
|
double ibei_Vbiei, ibei_dT;
|
|
double ibci_Vbici, ibci_dT;
|
|
double Q_0_Vbiei, Q_0_Vbici, Q_0_dT;
|
|
|
|
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.
|
|
duals::duald Temp_dual;
|
|
|
|
double Cjei_Vbiei,Cjci_Vbici,Cjep_Vbpei,Cjep_dT,Cjs_Vsici;
|
|
double Cjei_dT, Cjci_dT;
|
|
double Qjei_Vbiei, Qjei_dT, Qjci_Vbici, Qjci_dT;
|
|
double T_f0_Vbici,T_f0_dT;
|
|
double Qbepar1;
|
|
double Qbepar2;
|
|
double Qbcpar1;
|
|
double Qbcpar2;
|
|
double Qsu;
|
|
double Qcth;
|
|
double Qcth_Vrth;
|
|
|
|
double Qrbi_Vbpbi;
|
|
double Qrbi_Vrth;
|
|
double Qrbi_Vbiei;
|
|
double Qrbi_Vbici;
|
|
double Qjep_Vbpei,Qjep_dT;
|
|
double Qbepar1_Vbe;
|
|
double Qbepar2_Vbpe;
|
|
double Qbcpar1_Vbci;
|
|
double Qbcpar2_Vbpci;
|
|
double Qsu_Vsis;
|
|
|
|
double cqbepar1, gqbepar1;
|
|
double cqbepar2, gqbepar2;
|
|
double cqbcpar1, gqbcpar1;
|
|
double cqbcpar2, gqbcpar2;
|
|
double cqsu, gqsu;
|
|
|
|
double Qxf_Vxf, Qxf1_Vxf1, Qxf2_Vxf2;
|
|
|
|
double Ith=0.0, Vrth=0.0, Icth, Icth_Vrth, delvrth;
|
|
|
|
double Ibiei_Vrth;
|
|
double Ibici_Vrth;
|
|
double Ibpei_Vrth;
|
|
double Ibpci_Vrth;
|
|
double Isici_Vrth;
|
|
double Ibpbi_Vrth;
|
|
double Ieie_Vrth;
|
|
double Icic_Vrth=0.0;
|
|
double Irth_Vrth=0.0;
|
|
double Ibbp_Vrth=0.0;
|
|
|
|
double Ith_Vrth=0.0;
|
|
double Ith_Vciei=0.0;
|
|
double Ith_Vbiei=0.0;
|
|
double Ith_Vbici=0.0;
|
|
double Ith_Vbpei=0.0;
|
|
double Ith_Vbpci=0.0;
|
|
|
|
double Ith_Vsici=0.0;
|
|
double Ith_Vbpbi=0.0;
|
|
double Ith_Veie=0.0;
|
|
double Ith_Vcic=0.0;
|
|
double Ith_Vbbp=0.0;
|
|
|
|
// COLLECTOR CURRENT SPREADING CALCULATION
|
|
// collector minority charge incl. 2D/3D current spreading (TED 10/96)
|
|
// INPUT:
|
|
// Ix : forward transport current component (itf)
|
|
// I_CK : critical current
|
|
// FFT_pcS : dependent on fthc and thcs (parameters)
|
|
// IMPLICIT INPUT:
|
|
// ahc, latl, latb : model parameters
|
|
// VT : thermal voltage
|
|
// OUTPUT:
|
|
// Q_fC, Q_CT: actual and ICCR (weighted) hole charge
|
|
// T_fC, T_cT: actual and ICCR (weighted) transit time
|
|
// Derivative dfCT_ditf not properly implemented yet
|
|
std::function<void (duals::duald, duals::duald, duals::duald, duals::duald, duals::duald*, duals::duald*, duals::duald*, duals::duald*)> HICQFC = [&](duals::duald T, duals::duald Ix, duals::duald I_CK, duals::duald FFT_pcS, duals::duald * Q_fC, duals::duald * Q_CT, duals::duald * T_fC, duals::duald * T_cT)
|
|
{
|
|
duals::duald FCln, FCa, FCa1, FCd_a, FCw, FCdw_daick, FCda1_dw, FCf_ci, FCdfCT_ditf, FCw2, FCz, FCdfc_dw, FFdVc_ditf, FCf_CT, FCf1, FCf2, FCrt;
|
|
duals::duald FCa_ck, FCdaick_ditf, FCxl, FCxb, FCdf1_dw, FCz_1, FCf3, FCdf2_dw, FCdf3_dw, FCdw_ditf, FCdfc_ditf;
|
|
duals::duald FCdfCT_dw, FCd_f, FFdVc;
|
|
|
|
duals::duald vt;
|
|
|
|
vt = CONSTboltz * T / CHARGE;
|
|
|
|
*Q_fC = FFT_pcS*Ix;
|
|
FCa = 1.0-I_CK/Ix;
|
|
FCrt = sqrt(FCa*FCa+model->HICUMahc);
|
|
FCa_ck = 1.0-(FCa+FCrt)/(1.0+sqrt(1.0+model->HICUMahc));
|
|
FCdaick_ditf = (FCa_ck-1.0)*(1-FCa)/(FCrt*Ix);
|
|
if(model->HICUMlatb > model->HICUMlatl){
|
|
FCz = model->HICUMlatb-model->HICUMlatl;
|
|
FCxl = 1.0+model->HICUMlatl;
|
|
FCxb = 1.0+model->HICUMlatb;
|
|
if(model->HICUMlatb > 0.01){
|
|
FCln = log(FCxb/FCxl);
|
|
FCa1 = exp((FCa_ck-1.0)*FCln);
|
|
FCd_a = 1.0/(model->HICUMlatl-FCa1*model->HICUMlatb);
|
|
FCw = (FCa1-1.0)*FCd_a;
|
|
FCdw_daick = -FCz*FCa1*FCln*FCd_a*FCd_a;
|
|
FCa1 = log((1.0+model->HICUMlatb*FCw)/(1.0+model->HICUMlatl*FCw));
|
|
FCda1_dw = model->HICUMlatb/(1.0+model->HICUMlatb*FCw) - model->HICUMlatl/(1.0+model->HICUMlatl*FCw);
|
|
} else {
|
|
FCf1 = 1.0-FCa_ck;
|
|
FCd_a = 1.0/(1.0+FCa_ck*model->HICUMlatb);
|
|
FCw = FCf1*FCd_a;
|
|
FCdw_daick = -1.0*FCd_a*FCd_a*FCxb*FCd_a;
|
|
FCa1 = FCz*FCw;
|
|
FCda1_dw = FCz;
|
|
}
|
|
FCf_CT = 2.0/FCz;
|
|
FCw2 = FCw*FCw;
|
|
FCf1 = model->HICUMlatb*model->HICUMlatl*FCw*FCw2/3.0+(model->HICUMlatb+model->HICUMlatl)*FCw2/2.0+FCw;
|
|
FCdf1_dw = model->HICUMlatb*model->HICUMlatl*FCw2 + (model->HICUMlatb+model->HICUMlatl)*FCw + 1.0;
|
|
HICFCI(model->HICUMlatb,model->HICUMlatl,FCw,&FCf2,&FCdf2_dw);
|
|
HICFCI(model->HICUMlatl,model->HICUMlatb,FCw,&FCf3,&FCdf3_dw);
|
|
FCf_ci = FCf_CT*(FCa1*FCf1-FCf2+FCf3);
|
|
FCdfc_dw = FCf_CT*(FCa1*FCdf1_dw+FCda1_dw*FCf1-FCdf2_dw+FCdf3_dw);
|
|
FCdw_ditf = FCdw_daick*FCdaick_ditf;
|
|
FCdfc_ditf = FCdfc_dw*FCdw_ditf;
|
|
if(model->HICUMflcomp < 2.3) {
|
|
HICFCT(model->HICUMlatb,FCw,&FCf2,&FCdf2_dw);
|
|
HICFCT(model->HICUMlatl,FCw,&FCf3,&FCdf3_dw);
|
|
FCf_CT = FCf_CT*(FCf2-FCf3);
|
|
FCdfCT_dw = FCf_CT*(FCdf2_dw-FCdf3_dw);
|
|
FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;
|
|
} else {
|
|
FCf_CT = FCf_ci;
|
|
FCdfCT_ditf = FCdfc_ditf;
|
|
}
|
|
} else {
|
|
if(model->HICUMlatb > 0.01) {
|
|
FCd_a = 1.0/(1.0+FCa_ck*model->HICUMlatb);
|
|
FCw = (1.0-FCa_ck)*FCd_a;
|
|
FCdw_daick = -(1.0+model->HICUMlatb)*FCd_a*FCd_a;
|
|
} else {
|
|
FCw = 1.0-FCa_ck-FCa_ck*model->HICUMlatb;
|
|
FCdw_daick = -(1.0+model->HICUMlatb);
|
|
}
|
|
FCw2 = FCw*FCw;
|
|
FCz = model->HICUMlatb*FCw;
|
|
FCz_1 = 1.0+FCz;
|
|
FCd_f = 1.0/(FCz_1);
|
|
FCf_ci = FCw2*(1.0+FCz/3.0)*FCd_f;
|
|
FCdfc_dw = 2.0*FCw*(FCz_1+FCz*FCz/3.0)*FCd_f*FCd_f;
|
|
FCdw_ditf = FCdw_daick*FCdaick_ditf;
|
|
FCdfc_ditf = FCdfc_dw*FCdw_ditf;
|
|
if(model->HICUMflcomp < 2.3){
|
|
if (FCz > 0.001){
|
|
FCf_CT = 2.0*(FCz_1*log(FCz_1)-FCz)/(model->HICUMlatb*model->HICUMlatb*FCz_1);
|
|
FCdfCT_dw = 2.0*FCw*FCd_f*FCd_f;
|
|
} else {
|
|
FCf_CT = FCw2*(1.0-FCz/3.0)*FCd_f;
|
|
FCdfCT_dw = 2.0*FCw*(1.0-FCz*FCz/3.0)*FCd_f*FCd_f;
|
|
}
|
|
FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;
|
|
} else {
|
|
FCf_CT = FCf_ci;
|
|
FCdfCT_ditf = FCdfc_ditf;
|
|
}
|
|
}
|
|
*Q_CT = *Q_fC*FCf_CT*exp((FFdVc-model->HICUMvcbar)/vt);
|
|
*Q_fC = *Q_fC*FCf_ci*exp((FFdVc-model->HICUMvcbar)/vt);
|
|
*T_fC = FFT_pcS*exp((FFdVc-model->HICUMvcbar)/vt)*(FCf_ci+Ix*FCdfc_ditf) +*Q_fC/vt*FFdVc_ditf;
|
|
*T_cT = FFT_pcS*exp((FFdVc-model->HICUMvcbar)/vt)*(FCf_CT+Ix*FCdfCT_ditf)+*Q_CT/vt*FFdVc_ditf;
|
|
};
|
|
|
|
// TRANSIT-TIME AND STORED MINORITY CHARGE
|
|
// INPUT:
|
|
// itf : forward transport current
|
|
// I_CK : critical current
|
|
// T_f : transit time
|
|
// Q_f : minority charge / for low current
|
|
// IMPLICIT INPUT:
|
|
// tef0, gtfe, fthc, thcs, ahc, latl, latb : model parameters
|
|
// OUTPUT:
|
|
// T_f : transit time
|
|
// Q_f : minority charge transient analysis
|
|
// T_fT : transit time
|
|
// Q_fT : minority charge ICCR (transfer current)
|
|
// Q_bf : excess base charge
|
|
std::function<void (duals::duald, duals::duald, duals::duald, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*)> HICQFF = [&](duals::duald T, duals::duald itf, duals::duald I_CK, duals::duald * T_f, duals::duald * Q_f, duals::duald * T_fT, duals::duald * Q_fT, duals::duald * Q_bf)
|
|
{
|
|
duals::duald FFitf_ick, FFdTef, FFdQef, FFdVc, FFdVc_ditf, FFib, FFfcbar, FFdib_ditf;
|
|
duals::duald vt,tef0_t,thcs_t,hf0_t,hfe_t,hfc_t;
|
|
duals::duald FFdQbfb, FFdTbfb, FFdQfhc, FFdTfhc, FFdQcfc,FFdTcfc, FFdQbfc,FFdTbfc;
|
|
duals::duald FFdQcfcT, FFic, FFw, FFdTcfcT;
|
|
double T_dpart = T.dpart();
|
|
vt = CONSTboltz * T / CHARGE;
|
|
tef0_t = here->HICUMtef0_t.rpart;
|
|
thcs_t = here->HICUMthcs_t.rpart;
|
|
hf0_t = here->HICUMhf0_t.rpart;
|
|
hfe_t = here->HICUMhfe_t.rpart;
|
|
hfc_t = here->HICUMhfc_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
tef0_t.dpart(here->HICUMtef0_t.dpart);
|
|
thcs_t.dpart(here->HICUMthcs_t.dpart);
|
|
hf0_t.dpart(here->HICUMhf0_t.dpart);
|
|
hfe_t.dpart(here->HICUMhfe_t.dpart);
|
|
hfc_t.dpart(here->HICUMhfc_t.dpart);
|
|
}
|
|
|
|
if(itf < 1.0e-6*I_CK){
|
|
*Q_fT = *Q_f;
|
|
*T_fT = *T_f;
|
|
*Q_bf = 0;
|
|
} else {
|
|
FFitf_ick = itf/I_CK;
|
|
FFdTef = tef0_t*exp(model->HICUMgtfe*log(FFitf_ick));
|
|
FFdQef = FFdTef*itf/(1+model->HICUMgtfe);
|
|
if (here->HICUMicbar_scaled<0.05*(model->HICUMvlim/here->HICUMrci0_scaled)) {
|
|
FFdVc = 0;
|
|
FFdVc_ditf = 0;
|
|
} else {
|
|
FFib = (itf-I_CK)/here->HICUMicbar_scaled;
|
|
if (FFib < -1.0e10) {
|
|
FFib = -1.0e10;
|
|
}
|
|
FFfcbar = (FFib+sqrt(FFib*FFib+model->HICUMacbar))/2.0;
|
|
FFdib_ditf = FFfcbar/sqrt(FFib*FFib+model->HICUMacbar)/here->HICUMicbar_scaled;
|
|
FFdVc = model->HICUMvcbar*exp(-1.0/FFfcbar);
|
|
FFdVc_ditf = FFdVc/(FFfcbar*FFfcbar)*FFdib_ditf;
|
|
}
|
|
FFdQbfb = (1-model->HICUMfthc)*thcs_t*itf*(exp(FFdVc/vt)-1);
|
|
FFdTbfb = FFdQbfb/itf+(1-model->HICUMfthc)*thcs_t*itf*exp(FFdVc/vt)/vt*FFdVc_ditf;
|
|
FFic = 1-1.0/FFitf_ick;
|
|
FFw = (FFic+sqrt(FFic*FFic+model->HICUMahc))/(1+sqrt(1+model->HICUMahc));
|
|
FFdQfhc = thcs_t*itf*FFw*FFw*exp((FFdVc-model->HICUMvcbar)/vt);
|
|
FFdTfhc = FFdQfhc*(1.0/itf*(1.0+2.0/(FFitf_ick*sqrt(FFic*FFic+model->HICUMahc)))+1.0/vt*FFdVc_ditf);
|
|
if(model->HICUMlatb <= 0.0 && model->HICUMlatl <= 0.0){
|
|
FFdQcfc = model->HICUMfthc*FFdQfhc;
|
|
FFdTcfc = model->HICUMfthc*FFdTfhc;
|
|
FFdQcfcT = FFdQcfc;
|
|
FFdTcfcT = FFdTcfc;
|
|
} else {
|
|
HICQFC(T, itf,I_CK,model->HICUMfthc*thcs_t,&FFdQcfc,&FFdQcfcT,&FFdTcfc,&FFdTcfcT);
|
|
}
|
|
FFdQbfc = (1-model->HICUMfthc)*FFdQfhc;
|
|
FFdTbfc = (1-model->HICUMfthc)*FFdTfhc;
|
|
*Q_fT = hf0_t*(*Q_f)+FFdQbfb+FFdQbfc+hfe_t*FFdQef+hfc_t*FFdQcfcT;
|
|
*T_fT = hf0_t*(*T_f)+FFdTbfb+FFdTbfc+hfe_t*FFdTef+hfc_t*FFdTcfcT;
|
|
*Q_f = *Q_f+(FFdQbfb+FFdQbfc)+FFdQef+FFdQcfc;
|
|
*T_f = *T_f+(FFdTbfb+FFdTbfc)+FFdTef+FFdTcfc;
|
|
*Q_bf = FFdQbfb+FFdQbfc;
|
|
}
|
|
};
|
|
//Hole charge at low bias
|
|
std::function<duals::duald (duals::duald, duals::duald, duals::duald, duals::duald)> calc_Q_0 = [&](duals::duald T, duals::duald Qjei, duals::duald Qjci, duals::duald hjei_vbe){
|
|
duals::duald Q_0, b_q, Q_bpt, qp0_t;
|
|
qp0_t = here->HICUMqp0_t.rpart;
|
|
double T_dpart = T.dpart();
|
|
if (T_dpart!=0.0){
|
|
qp0_t.dpart(here->HICUMqp0_t.dpart);
|
|
}
|
|
a_bpt = 0.05;
|
|
Q_0 = qp0_t + hjei_vbe*Qjei + model->HICUMhjci*Qjci;
|
|
Q_bpt = a_bpt*qp0_t;
|
|
b_q = Q_0/Q_bpt-1;
|
|
Q_0 = Q_bpt*(1+(b_q +sqrt(b_q*b_q+1.921812))/2);
|
|
return Q_0;
|
|
};
|
|
|
|
std::function<duals::duald (duals::duald, duals::duald)> calc_T_f0 = [&](duals::duald T, duals::duald Vbici){
|
|
//Transit time calculation at low current density
|
|
duals::duald vt, vdci_t, cjci0_t, t0_t;
|
|
duals::duald cV_f,cv_e,cs_q,cs_q2,cv_j,cdvj_dv,Cjcit,cc;
|
|
double T_dpart = T.dpart();
|
|
|
|
vt = CONSTboltz * T / CHARGE;
|
|
vdci_t = here->HICUMvdci_t.rpart;
|
|
cjci0_t = here->HICUMcjci0_t.rpart;
|
|
t0_t = here->HICUMt0_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
vdci_t.dpart(here->HICUMvdci_t.dpart);
|
|
cjci0_t.dpart(here->HICUMcjci0_t.dpart);
|
|
t0_t.dpart(here->HICUMt0_t.dpart);
|
|
}
|
|
if(here->HICUMcjci0_t.rpart > 0.0){ // CJMODF
|
|
cV_f = vdci_t*(1.0-exp(-log(2.4)/model->HICUMzci));
|
|
cv_e = (cV_f-Vbici)/vt;
|
|
cs_q = sqrt(cv_e*cv_e+1.921812);
|
|
cs_q2 = (cv_e+cs_q)*0.5;
|
|
cv_j = cV_f-vt*cs_q2;
|
|
cdvj_dv = cs_q2/cs_q;
|
|
Cjcit = cjci0_t*exp(-model->HICUMzci*log(1.0-cv_j/vdci_t))*cdvj_dv+2.4*cjci0_t*(1.0-cdvj_dv);
|
|
} else {
|
|
Cjcit = 0.0;
|
|
}
|
|
if(Cjcit > 0.0) {
|
|
cc = cjci0_t/Cjcit;
|
|
} else {
|
|
cc = 1.0;
|
|
}
|
|
return t0_t+model->HICUMdt0h*(cc-1.0)+model->HICUMtbvl*(1/cc-1.0);
|
|
};
|
|
std::function<duals::duald (duals::duald, duals::duald)> calc_ick = [&](duals::duald T, duals::duald Vciei){
|
|
duals::duald ick, vces_t, rci0_t, vlim_t, Orci0_t;
|
|
duals::duald Ovpt,a,d1,vceff,a1,a11,Odelck,ick1,ick2,ICKa, vc, vt;
|
|
double T_dpart = T.dpart();
|
|
|
|
vces_t = here->HICUMvces_t.rpart;
|
|
rci0_t = here->HICUMrci0_t.rpart;
|
|
vlim_t = here->HICUMvlim_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
vces_t.dpart(here->HICUMvces_t.dpart);
|
|
rci0_t.dpart(here->HICUMrci0_t.dpart);
|
|
vlim_t.dpart(here->HICUMvlim_t.dpart);
|
|
}
|
|
//Effective collector voltage
|
|
vc = Vciei-vces_t;
|
|
vt = CONSTboltz * T / CHARGE;
|
|
|
|
//Inverse of low-field internal collector resistance: needed in HICICK
|
|
Orci0_t = 1.0/rci0_t;
|
|
|
|
//Critical current for onset of high-current effects
|
|
//begin : HICICK
|
|
Ovpt = 1.0/model->HICUMvpt;
|
|
a = vc/vt;
|
|
d1 = a-1;
|
|
vceff = (1.0+((d1+sqrt(d1*d1+1.921812))/2))*vt;
|
|
// a = vceff/vlim_t;
|
|
// ick = vceff*Orci0_t/sqrt(1.0+a*a);
|
|
// ICKa = (vceff-vlim_t)*Ovpt;
|
|
// ick = ick*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+1.0e-3)));
|
|
|
|
a1 = vceff/vlim_t;
|
|
a11 = vceff*Orci0_t;
|
|
Odelck = 1/model->HICUMdelck;
|
|
ick1 = exp(Odelck*log(1+exp(model->HICUMdelck*log(a1))));
|
|
ick2 = a11/ick1;
|
|
ICKa = (vceff-vlim_t)*Ovpt;
|
|
ick = ick2*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+model->HICUMaick)));
|
|
return ick;
|
|
|
|
//end
|
|
};
|
|
|
|
|
|
std::function<duals::duald (duals::duald, duals::duald, duals::duald)> calc_ibet = [&](duals::duald Vbiei, duals::duald Vbpei, duals::duald T){
|
|
//Tunneling current
|
|
duals::duald ibet;
|
|
if (here->HICUMibets_scaled > 0 && (Vbpei <0.0 || Vbiei < 0.0)){ //begin : HICTUN
|
|
duals::duald pocce,czz, cje0_t, vde_t, ibets_t, abet_t;
|
|
double T_dpart = T.dpart();
|
|
ibets_t = here->HICUMibets_t.rpart;
|
|
abet_t = here->HICUMabet_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
abet_t.dpart(here->HICUMabet_t.dpart);
|
|
ibets_t.dpart(here->HICUMibets_t.dpart);
|
|
}
|
|
if(model->HICUMtunode==1 && here->HICUMcjep0_t.rpart > 0.0 && here->HICUMvdep_t.rpart >0.0){
|
|
cje0_t = here->HICUMcjep0_t.rpart;
|
|
vde_t = here->HICUMvdep_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
cje0_t.dpart(here->HICUMcjep0_t.dpart);
|
|
vde_t.dpart(here->HICUMvdep_t.dpart);
|
|
}
|
|
pocce = exp((1-1/model->HICUMzep)*log(Cjep/cje0_t));
|
|
czz = -(Vbpei/vde_t)*ibets_t*pocce;
|
|
ibet = czz*exp(-abet_t/pocce);
|
|
} else if (model->HICUMtunode==0 && here->HICUMcjei0_t.rpart > 0.0 && here->HICUMvdei_t.rpart >0.0){
|
|
cje0_t = here->HICUMcjei0_t.rpart;
|
|
vde_t = here->HICUMvdei_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
cje0_t.dpart(here->HICUMcjei0_t.dpart);
|
|
vde_t.dpart(here->HICUMvdei_t.dpart);
|
|
}
|
|
pocce = exp((1-1/model->HICUMzei)*log(Cjei/cje0_t));
|
|
czz = -(Vbiei/vde_t)*ibets_t*pocce;
|
|
ibet = czz*exp(-abet_t/pocce);
|
|
} else {
|
|
ibet = 0.0;
|
|
}
|
|
} else {
|
|
ibet = 0.0;
|
|
}
|
|
return ibet;
|
|
};
|
|
|
|
std::function<duals::duald (duals::duald, duals::duald, duals::duald, duals::duald)> calc_iavl = [&](duals::duald Vbici, duals::duald Cjci, duals::duald itf, duals::duald T){
|
|
//Avalanche current
|
|
duals::duald iavl;
|
|
duals::duald v_bord,v_q,U0,av,avl,cjci0_t, vdci_t, qavl_t,favl_t, kavl_t;
|
|
if (use_aval == 1) {//begin : HICAVL
|
|
double T_dpart = T.dpart();
|
|
cjci0_t = here->HICUMcjci0_t.rpart;
|
|
vdci_t = here->HICUMvdci_t.rpart;
|
|
qavl_t = here->HICUMqavl_t.rpart;
|
|
favl_t = here->HICUMfavl_t.rpart;
|
|
kavl_t = here->HICUMkavl_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
cjci0_t.dpart(here->HICUMcjci0_t.dpart);
|
|
vdci_t.dpart(here->HICUMvdci_t.dpart);
|
|
qavl_t.dpart(here->HICUMqavl_t.dpart);
|
|
favl_t.dpart(here->HICUMfavl_t.dpart);
|
|
kavl_t.dpart(here->HICUMkavl_t.dpart);
|
|
}
|
|
v_bord = vdci_t-Vbici;
|
|
if (v_bord > 0) {
|
|
v_q = qavl_t/Cjci;
|
|
U0 = qavl_t/cjci0_t;
|
|
if(v_bord > U0){
|
|
av = favl_t*exp(-v_q/U0);
|
|
avl = av*(U0+(1.0+v_q/U0)*(v_bord-U0));
|
|
} else {
|
|
avl = favl_t * v_bord * exp(-v_q / v_bord);
|
|
}
|
|
/* This model turns strong avalanche on. The parameter kavl can turn this
|
|
* model extension off (kavl = 0). Although this is numerically stable, a
|
|
* conditional statement is applied in order to reduce the numerical over-
|
|
* head for simulations without the new model.
|
|
*/
|
|
if (model->HICUMkavl > 0) { //: HICAVLHIGH
|
|
duals::duald denom,sq_smooth,hl;
|
|
denom = 1-kavl_t*avl;
|
|
// Avoid denom < 0 using a smoothing function
|
|
sq_smooth = sqrt(denom*denom+0.01);
|
|
hl = 0.5*(denom+sq_smooth);
|
|
iavl = itf*avl/hl;
|
|
} else {
|
|
iavl = itf*avl;
|
|
}
|
|
} else {
|
|
iavl = 0.0;
|
|
}
|
|
} else{
|
|
iavl = 0;
|
|
}
|
|
return iavl;
|
|
};
|
|
|
|
std::function<duals::duald (duals::duald, duals::duald, duals::duald)> calc_rbi = [&](duals::duald T, duals::duald Qjei, duals::duald Qf){
|
|
//Internal base resistance
|
|
duals::duald vt,rbi;
|
|
vt = CONSTboltz * T / CHARGE;
|
|
if(here->HICUMrbi0_t.rpart > 0.0){ //: HICRBI
|
|
duals::duald Qz_nom,f_QR,ETA,Qz0,fQz, qp0_t;
|
|
double T_dpart = T.dpart();
|
|
rbi = here->HICUMrbi0_t.rpart;
|
|
qp0_t = here->HICUMqp0_t.rpart;
|
|
if (T_dpart!=0.0) {
|
|
rbi.dpart(here->HICUMrbi0_t.dpart);
|
|
qp0_t.dpart(here->HICUMqp0_t.dpart);
|
|
}
|
|
// Consideration of conductivity modulation
|
|
// To avoid convergence problem hyperbolic smoothing used
|
|
f_QR = (1+model->HICUMfdqr0)*qp0_t;
|
|
Qz0 = Qjei+Qjci+Qf;
|
|
Qz_nom = 1+Qz0/f_QR;
|
|
fQz = 0.5*(Qz_nom+sqrt(Qz_nom*Qz_nom+0.01));
|
|
rbi = rbi/fQz;
|
|
// Consideration of emitter current crowding
|
|
if( ibei > 0.0) {
|
|
ETA = rbi*ibei*model->HICUMfgeo/vt;
|
|
if(ETA < 1.0e-6) {
|
|
rbi = rbi*(1.0-0.5*ETA);
|
|
} else {
|
|
rbi = rbi*log(1.0+ETA)/ETA;
|
|
}
|
|
}
|
|
// Consideration of peripheral charge
|
|
if(Qf > 0.0) {
|
|
rbi = rbi*(Qjei+Qf*model->HICUMfqi)/(Qjei+Qf);
|
|
}
|
|
} else {
|
|
rbi = 0.0;
|
|
}
|
|
return rbi;
|
|
};
|
|
|
|
std::function<void (duals::duald, duals::duald, duals::duald, duals::duald, duals::duald, duals::duald, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*)> calc_it_final = [&](duals::duald T, duals::duald Vbiei, duals::duald Vbici, duals::duald Q_pT, duals::duald T_f0, duals::duald ick, duals::duald *itf, duals::duald *itr, duals::duald *Qf, duals::duald *Qr, duals::duald *Q_bf, duals::duald * Tf){
|
|
// given T,Q_pT, ick, T_f0, Tr, Vbiei, Vbici -> calculate itf, itr, Qf, Qr
|
|
duals::duald VT, VT_f, i_0f, i_0r, I_Tf1, a_h, Q_fT,T_fT;
|
|
duals::duald c10_t;
|
|
|
|
double T_dpart = T.dpart();
|
|
|
|
VT = CONSTboltz * T / CHARGE;
|
|
c10_t = here->HICUMc10_t.rpart;
|
|
if (T_dpart!=0.0) {
|
|
c10_t.dpart(here->HICUMc10_t.dpart);
|
|
}
|
|
VT_f = model->HICUMmcf*VT;
|
|
i_0f = c10_t * exp(Vbiei/VT_f);
|
|
i_0r = c10_t * exp(Vbici/VT);
|
|
|
|
|
|
I_Tf1 = i_0f/Q_pT;
|
|
a_h = Oich*I_Tf1;
|
|
*itf = I_Tf1*(1.0+a_h);
|
|
*itr = i_0r/Q_pT;
|
|
|
|
//Final transit times, charges and transport current components
|
|
*Tf = T_f0;
|
|
*Qf = T_f0*(*itf);
|
|
HICQFF(T,*itf,ick,Tf,Qf,&T_fT,&Q_fT,Q_bf);
|
|
*Qr = Tr*(*itr);
|
|
};
|
|
|
|
std::function<void (duals::duald, duals::duald, duals::duald, duals::duald, duals::duald, duals::duald, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*, duals::duald*)> calc_it_initial = [&](duals::duald T, duals::duald Vbiei, duals::duald Vbici, duals::duald Q_0, duals::duald T_f0, duals::duald ick, duals::duald *itf, duals::duald *itr, duals::duald *Qf, duals::duald *Qr, duals::duald *Q_bf, duals::duald *a_h, duals::duald *Q_p, duals::duald *Tf){
|
|
// given T,Q_pT, ick, T_f0, Tr, Vbiei, Vbici -> calculate itf, itr, Qf, Qr
|
|
duals::duald VT, VT_f, i_0f, i_0r, I_Tf1, Q_fT, T_fT, A;
|
|
duals::duald c10_t;
|
|
double T_dpart = T.dpart();
|
|
|
|
VT = CONSTboltz * T / CHARGE;
|
|
c10_t = here->HICUMc10_t.rpart;
|
|
if (T_dpart!=0.0) {
|
|
c10_t.dpart(here->HICUMc10_t.dpart);
|
|
}
|
|
VT_f = model->HICUMmcf*VT;
|
|
i_0f = c10_t * exp(Vbiei/VT_f);
|
|
i_0r = c10_t * exp(Vbici/VT);
|
|
|
|
*Q_p = Q_0;
|
|
if (T_f0 > 0.0 || Tr > 0.0) {
|
|
A = 0.5*Q_0;
|
|
*Q_p = A+sqrt(A*A+T_f0*i_0f+Tr*i_0r);
|
|
}
|
|
I_Tf1 =i_0f/(*Q_p);
|
|
*a_h = Oich*I_Tf1;
|
|
*itf = I_Tf1*(1.0+*a_h);
|
|
*itr = i_0r/(*Q_p);
|
|
|
|
//Initial formulation of forward transit time, diffusion, GICCR and excess b-c charge
|
|
*Q_bf = 0.0;
|
|
*Tf = T_f0;
|
|
*Qf = T_f0*(*itf);
|
|
HICQFF(T,*itf,ick,Tf,Qf,&T_fT,&Q_fT,Q_bf);
|
|
|
|
//Initial formulation of reverse diffusion charge
|
|
*Qr = Tr*(*itr);
|
|
};
|
|
|
|
std::function<duals::duald (duals::duald, duals::duald, duals::duald, duals::duald, duals::duald, duals::duald)> calc_it = [&](duals::duald T, duals::duald Vbiei, duals::duald Vbici, duals::duald Q_0, duals::duald T_f0, duals::duald ick){
|
|
// This function calculates Q_pT in a dual way
|
|
// Tr also as argument here?
|
|
duals::duald VT, VT_f,i_0f,i_0r, Q_p, A, I_Tf1,itf, itr, a_h, Qf, Qr, d_Q0, Q_pT, a, d_Q, Tf, T_fT, Q_bf, Q_fT;
|
|
duals::duald c10_t;
|
|
int extra_round=0;
|
|
double T_dpart = T.dpart();
|
|
int l_it;
|
|
|
|
VT = CONSTboltz * T / CHARGE;
|
|
c10_t = here->HICUMc10_t.rpart;
|
|
if (T_dpart!=0.0) {
|
|
c10_t.dpart(here->HICUMc10_t.dpart);
|
|
}
|
|
VT_f = model->HICUMmcf*VT;
|
|
i_0f = c10_t * exp(Vbiei/VT_f);
|
|
i_0r = c10_t * exp(Vbici/VT);
|
|
|
|
//Initial formulation of forward and reverse component of transfer current
|
|
Q_p = Q_0;
|
|
if (T_f0 > 0.0 || Tr > 0.0) {
|
|
A = 0.5*Q_0;
|
|
Q_p = A+sqrt(A*A+T_f0*i_0f+Tr*i_0r);
|
|
}
|
|
I_Tf1 = i_0f/Q_p;
|
|
a_h = Oich*I_Tf1;
|
|
itf = I_Tf1*(1.0+a_h);
|
|
itr = i_0r/Q_p;
|
|
|
|
//Initial formulation of forward transit time, diffusion, GICCR and excess b-c charge
|
|
Q_bf = 0.0;
|
|
Tf = T_f0;
|
|
Qf = T_f0*itf;
|
|
HICQFF(T,itf,ick,&Tf,&Qf,&T_fT,&Q_fT,&Q_bf);
|
|
|
|
//Initial formulation of reverse diffusion charge
|
|
Qr = Tr*itr;
|
|
|
|
//Preparation for iteration to get total hole charge and related variables
|
|
l_it = 0;
|
|
extra_round = 1;
|
|
if(Qf > RTOLC*Q_p || a_h > RTOLC) {
|
|
//Iteration for Q_pT is required for improved initial solution
|
|
Qf = sqrt(T_f0*itf*Q_fT);
|
|
Q_pT = Q_0+Qf+Qr;
|
|
d_Q = Q_pT;
|
|
while ( ((abs(d_Q) >= RTOLC*abs(Q_pT)) && (l_it <= l_itmax)) || (extra_round < 5)) {
|
|
d_Q0 = d_Q;
|
|
I_Tf1 = i_0f/Q_pT;
|
|
a_h = Oich*I_Tf1;
|
|
itf = I_Tf1*(1.0+a_h);
|
|
itr = i_0r/Q_pT;
|
|
Tf = T_f0;
|
|
Qf = T_f0*itf;
|
|
HICQFF(T,itf,ick,&Tf,&Qf,&T_fT,&Q_fT,&Q_bf);
|
|
Qr = Tr*itr;
|
|
if(Oich == 0.0) {
|
|
a = 1.0+(T_fT*itf+Qr)/Q_pT;
|
|
} else {
|
|
a = 1.0+(T_fT*I_Tf1*(1.0+2.0*a_h)+Qr)/Q_pT;
|
|
}
|
|
d_Q = -(Q_pT-(Q_0+Q_fT+Qr))/a;
|
|
//Limit maximum change of Q_pT
|
|
a = abs(0.3*Q_pT);
|
|
if(abs(d_Q) > a) {
|
|
if (d_Q>=0) {
|
|
d_Q = a;
|
|
} else {
|
|
d_Q = -a;
|
|
}
|
|
}
|
|
Q_pT = Q_pT+d_Q;
|
|
l_it = l_it+1;
|
|
if (!(abs(d_Q) >= RTOLC*abs(Q_pT))) { //extra_rounds to get rid of derivative noise
|
|
extra_round = extra_round + 1;
|
|
}
|
|
}
|
|
|
|
//final calculations afterwards, see later in load where this is called
|
|
|
|
}
|
|
return Q_pT;
|
|
|
|
};
|
|
|
|
std::function<void (duals::duald, duals::duald, duals::duald, duals::duald*, duals::duald*)> calc_itss = [&](duals::duald T, duals::duald Vbpci, duals::duald Vsici, duals::duald * HSI_Tsu, duals::duald * Qdsu){
|
|
duals::duald HSUM, vt, HSa, HSb, itss_t, tsf_t;
|
|
double T_dpart = T.dpart();
|
|
vt = CONSTboltz * T / CHARGE;
|
|
itss_t = here->HICUMitss_t.rpart;
|
|
tsf_t = here->HICUMtsf_t.rpart;
|
|
if (T_dpart!=0.0){
|
|
itss_t.dpart(here->HICUMitss_t.dpart);
|
|
tsf_t.dpart(here->HICUMtsf_t.dpart);
|
|
}
|
|
if(model->HICUMitss > 0.0) { // : Sub_Transfer
|
|
HSUM = model->HICUMmsf*vt;
|
|
HSa = exp(Vbpci/HSUM);
|
|
HSb = exp(Vsici/HSUM);
|
|
*HSI_Tsu = itss_t*(HSa-HSb);
|
|
if(model->HICUMtsf > 0.0) {
|
|
*Qdsu = tsf_t*itss_t*HSa;
|
|
} else {
|
|
*Qdsu = 0.0;
|
|
}
|
|
} else {
|
|
*HSI_Tsu = 0.0;
|
|
*Qdsu = 0.0;
|
|
};
|
|
};
|
|
|
|
|
|
/* loop through all the models */
|
|
for (; model != NULL; model = HICUMnextModel(model)) {
|
|
|
|
// Avoid divide-by-zero and define infinity other way
|
|
// High current correction for 2D and 3D effects
|
|
if (model->HICUMich != 0.0) {
|
|
Oich = 1.0 / model->HICUMich;
|
|
}
|
|
else {
|
|
Oich = 0.0;
|
|
}
|
|
|
|
// Base current recombination time constant at b-c barrier
|
|
if (model->HICUMtbhrec != 0.0) {
|
|
Otbhrec = 1.0 / model->HICUMtbhrec;
|
|
}
|
|
else {
|
|
Otbhrec = 0.0;
|
|
}
|
|
|
|
// Turn avalanche calculation on depending of parameters
|
|
if ((model->HICUMfavl > 0.0) && (model->HICUMcjci0 > 0.0)) {
|
|
use_aval = 1;
|
|
} else {
|
|
use_aval = 0;
|
|
}
|
|
|
|
// end of Model_initialization
|
|
|
|
/* loop through all the instances of the model */
|
|
for (here = HICUMinstances(model); here != NULL ;
|
|
here=HICUMnextInstance(here)) {
|
|
|
|
// Depletion capacitance splitting at b-c junction
|
|
// Capacitances at peripheral and external base node
|
|
C_1 = (1.0 - model->HICUMfbcpar) *
|
|
(here->HICUMcjcx0_scaled + here->HICUMcbcpar_scaled);
|
|
if (C_1 >= here->HICUMcbcpar_scaled) {
|
|
cbcpar1 = here->HICUMcbcpar_scaled;
|
|
cbcpar2 = 0.0;
|
|
}
|
|
else {
|
|
cbcpar1 = C_1;
|
|
cbcpar2 = here->HICUMcbcpar_scaled - cbcpar1;
|
|
}
|
|
|
|
// Parasitic b-e capacitance partitioning: No temperature dependence
|
|
cbepar2 = model->HICUMfbepar * here->HICUMcbepar_scaled;
|
|
cbepar1 = here->HICUMcbepar_scaled - cbepar2;
|
|
|
|
gqbepar1 = 0.0;
|
|
gqbepar2 = 0.0;
|
|
gqbcpar1 = 0.0;
|
|
gqbcpar2 = 0.0;
|
|
gqsu = 0.0;
|
|
Icth = 0.0, Icth_Vrth = 0.0;
|
|
|
|
/*
|
|
* initialization
|
|
*/
|
|
icheck=1;
|
|
if(ckt->CKTmode & MODEINITSMSIG) {
|
|
Vbiei = *(ckt->CKTstate0 + here->HICUMvbiei);
|
|
Vbici = *(ckt->CKTstate0 + here->HICUMvbici);
|
|
// dead assign:
|
|
//Vciei = Vbiei - Vbici;
|
|
Vbpei = *(ckt->CKTstate0 + here->HICUMvbpei);
|
|
Vbpci = *(ckt->CKTstate0 + here->HICUMvbpci);
|
|
Vbci = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
Vsici = *(ckt->CKTstate0 + here->HICUMvsici);
|
|
Vsc = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
|
|
Vbpbi = *(ckt->CKTstate0 + here->HICUMvbpbi);
|
|
Vbe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vcic = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
Vbbp = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode));
|
|
Vbpe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Veie = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vsis = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsSINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode));
|
|
Vxf = *(ckt->CKTrhsOld + here->HICUMxfNode);
|
|
Vxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node);
|
|
Vxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node);
|
|
if (model->HICUMselfheat) {
|
|
Vrth = *(ckt->CKTstate0 + here->HICUMvrth);
|
|
}
|
|
} else if(ckt->CKTmode & MODEINITTRAN) {
|
|
Vbiei = *(ckt->CKTstate1 + here->HICUMvbiei);
|
|
Vbici = *(ckt->CKTstate1 + here->HICUMvbici);
|
|
// dead assign:
|
|
//Vciei = Vbiei - Vbici;
|
|
Vbpei = *(ckt->CKTstate1 + here->HICUMvbpei);
|
|
Vbpci = *(ckt->CKTstate1 + here->HICUMvbpci);
|
|
Vbci = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
Vsici = *(ckt->CKTstate1 + here->HICUMvsici);
|
|
Vsc = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
|
|
Vbpbi = *(ckt->CKTstate1 + here->HICUMvbpbi);
|
|
Vbe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vcic = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
Vbbp = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode));
|
|
Vbpe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Veie = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vsis = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsSINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode));
|
|
Vxf = *(ckt->CKTrhsOld + here->HICUMxfNode);
|
|
Vxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node);
|
|
Vxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node);
|
|
if (model->HICUMselfheat) {
|
|
Vrth = *(ckt->CKTstate1 + here->HICUMvrth);
|
|
}
|
|
} else if((ckt->CKTmode & MODEINITJCT) &&
|
|
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)){
|
|
Vbiei = model->HICUMtype * here->HICUMicVBE; // multiplication by type has historical reasons
|
|
Vciei = model->HICUMtype * here->HICUMicVCE; // the user sets anytime positive numbers independent from type
|
|
Vbici = Vbiei - Vciei;
|
|
Vsc = Vsici = model->HICUMtype * here->HICUMicVCS;
|
|
Vbe = Vbpei = Vbiei;
|
|
Vbci = Vbpci = Vbici;
|
|
Vbpbi = 0.0;
|
|
Vbbp = 0.0;
|
|
Vbpe = 0.0;
|
|
Vcic = 0.0;
|
|
Veie = 0.0;
|
|
Vrth = 0.0;
|
|
Vsis = 0.0;
|
|
Icth = 0.0, Icth_Vrth=0.0;
|
|
Vxf=Vxf1=Vxf2=0.0;
|
|
} else if((ckt->CKTmode & MODEINITJCT) && (here->HICUMoff==0)) {
|
|
Vbiei = here->HICUMtVcrit;
|
|
Vbici = 0.0;
|
|
// dead assign:
|
|
//Vciei = Vbiei - Vbici;
|
|
Vsc = Vsici = 0.0;
|
|
Vbe = Vbpei = Vbiei;
|
|
Vbci = Vbpci = Vbici;
|
|
Vbpbi = 0.0;
|
|
Vbbp = 0.0;
|
|
Vbpe = 0.0;
|
|
Vcic = 0.0;
|
|
Veie = 0.0;
|
|
Vrth = 0.0;
|
|
Vsis = 0.0;
|
|
Icth = 0.0, Icth_Vrth=0.0;
|
|
Vxf=Vxf1=Vxf2=0.0;
|
|
} else if((ckt->CKTmode & MODEINITJCT) ||
|
|
( (ckt->CKTmode & MODEINITFIX) && (here->HICUMoff!=0))) {
|
|
Vbe=0.0;
|
|
Vbiei=Vbe;
|
|
// dead assign:
|
|
//Vciei=0.0;
|
|
Vbci=Vbici=Vbpci=0.0;
|
|
Vbpei=0.0;
|
|
Vsc=Vsici=0.0;
|
|
Vbpbi=Vbbp=Vbpe=0.0;
|
|
Vcic=Veie=Vsis=0.0;
|
|
Vrth=0.0,Icth=0.0,Icth_Vrth=0.0;
|
|
Vxf=Vxf1=Vxf2=0.0;
|
|
} else {
|
|
#ifndef PREDICTOR
|
|
if(ckt->CKTmode & MODEINITPRED) {
|
|
xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1];
|
|
Vbiei = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbiei)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbiei);
|
|
Vbici = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbici)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbici);
|
|
Vciei = Vbiei - Vbici;
|
|
Vbpei = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpei)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbpei);
|
|
Vbpci = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpci)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbpci);
|
|
Vsici = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvsici)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvsici);
|
|
Vbpbi = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbpbi)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbpbi);
|
|
// dead assign:
|
|
// Vxf = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvxf)-
|
|
// xfact * *(ckt->CKTstate2 + here->HICUMvxf);
|
|
// Vxf1 = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvxf1)-
|
|
// xfact * *(ckt->CKTstate2 + here->HICUMvxf1);
|
|
Vxf2 = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvxf2)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvxf2);
|
|
Vrth = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvrth);
|
|
Veie = (1+xfact) * *(ckt->CKTstate1 + here->HICUMveie)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMveie);
|
|
Vcic = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvcic)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvcic);
|
|
Vbbp = (1+xfact) * *(ckt->CKTstate1 + here->HICUMvbbp)-
|
|
xfact * *(ckt->CKTstate2 + here->HICUMvbbp);
|
|
/////////////////////////
|
|
// begin copy state vector
|
|
/////////////////////////
|
|
*(ckt->CKTstate0+here->HICUMvbiei)=*(ckt->CKTstate1+here->HICUMvbiei);
|
|
*(ckt->CKTstate0+here->HICUMvbici)=*(ckt->CKTstate1+here->HICUMvbici);
|
|
*(ckt->CKTstate0+here->HICUMvbpei)=*(ckt->CKTstate1+here->HICUMvbpei);
|
|
*(ckt->CKTstate0+here->HICUMvbpbi)=*(ckt->CKTstate1+here->HICUMvbpbi);
|
|
*(ckt->CKTstate0+here->HICUMvbpci)=*(ckt->CKTstate1+here->HICUMvbpci);
|
|
*(ckt->CKTstate0+here->HICUMvsici)=*(ckt->CKTstate1+here->HICUMvsici);
|
|
*(ckt->CKTstate0+here->HICUMvcic)=*(ckt->CKTstate1+here->HICUMvcic);
|
|
*(ckt->CKTstate0+here->HICUMvbbp)=*(ckt->CKTstate1+here->HICUMvbbp);
|
|
*(ckt->CKTstate0+here->HICUMveie)=*(ckt->CKTstate1+here->HICUMveie);
|
|
*(ckt->CKTstate0+here->HICUMibiei)=*(ckt->CKTstate1+here->HICUMibiei);
|
|
*(ckt->CKTstate0+here->HICUMibiei_Vbiei)=*(ckt->CKTstate1+here->HICUMibiei_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMibiei_Vxf)=*(ckt->CKTstate1+here->HICUMibiei_Vxf);
|
|
*(ckt->CKTstate0+here->HICUMibiei_Vbici)=*(ckt->CKTstate1+here->HICUMibiei_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMibiei_Vrth)=*(ckt->CKTstate1+here->HICUMibiei_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMibpei)=*(ckt->CKTstate1+here->HICUMibpei);
|
|
*(ckt->CKTstate0+here->HICUMibpei_Vbpei)=*(ckt->CKTstate1+here->HICUMibpei_Vbpei);
|
|
*(ckt->CKTstate0+here->HICUMibpei_Vrth)=*(ckt->CKTstate1+here->HICUMibpei_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMiciei)=*(ckt->CKTstate1+here->HICUMiciei);
|
|
*(ckt->CKTstate0+here->HICUMiciei_Vbiei)=*(ckt->CKTstate1+here->HICUMiciei_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMiciei_Vbici)=*(ckt->CKTstate1+here->HICUMiciei_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMiciei_Vxf2)=*(ckt->CKTstate1+here->HICUMiciei_Vxf2);
|
|
*(ckt->CKTstate0+here->HICUMiciei_Vrth)=*(ckt->CKTstate1+here->HICUMiciei_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMibici)=*(ckt->CKTstate1+here->HICUMibici);
|
|
*(ckt->CKTstate0+here->HICUMibici_Vbici)=*(ckt->CKTstate1+here->HICUMibici_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMibici_Vbiei)=*(ckt->CKTstate1+here->HICUMibici_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMibici_Vrth)=*(ckt->CKTstate1+here->HICUMibici_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMibpbi)=*(ckt->CKTstate1+here->HICUMibpbi);
|
|
*(ckt->CKTstate0+here->HICUMibpbi_Vbpbi)=*(ckt->CKTstate1+here->HICUMibpbi_Vbpbi);
|
|
*(ckt->CKTstate0+here->HICUMibpbi_Vbiei)=*(ckt->CKTstate1+here->HICUMibpbi_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMibpbi_Vbici)=*(ckt->CKTstate1+here->HICUMibpbi_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMibpbi_Vrth)=*(ckt->CKTstate1+here->HICUMibpbi_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMibpci)=*(ckt->CKTstate1+here->HICUMibpci);
|
|
*(ckt->CKTstate0+here->HICUMibpci_Vbpci)=*(ckt->CKTstate1+here->HICUMibpci_Vbpci);
|
|
*(ckt->CKTstate0+here->HICUMibpci_Vrth)=*(ckt->CKTstate1+here->HICUMibpci_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMisici)=*(ckt->CKTstate1+here->HICUMisici);
|
|
*(ckt->CKTstate0+here->HICUMisici_Vsici)=*(ckt->CKTstate1+here->HICUMisici_Vsici);
|
|
*(ckt->CKTstate0+here->HICUMisici_Vrth)=*(ckt->CKTstate1+here->HICUMisici_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMibpsi)=*(ckt->CKTstate1+here->HICUMibpsi);
|
|
*(ckt->CKTstate0+here->HICUMibpsi_Vbpci)=*(ckt->CKTstate1+here->HICUMibpsi_Vbpci);
|
|
*(ckt->CKTstate0+here->HICUMibpsi_Vsici)=*(ckt->CKTstate1+here->HICUMibpsi_Vsici);
|
|
*(ckt->CKTstate0+here->HICUMibpsi_Vrth)=*(ckt->CKTstate1+here->HICUMibpsi_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMisis_Vsis)=*(ckt->CKTstate1+here->HICUMisis_Vsis);
|
|
*(ckt->CKTstate0+here->HICUMieie)=*(ckt->CKTstate1+here->HICUMieie);
|
|
*(ckt->CKTstate0+here->HICUMieie_Vrth)=*(ckt->CKTstate1+here->HICUMieie_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMqrbi)=*(ckt->CKTstate1+here->HICUMqrbi);
|
|
*(ckt->CKTstate0+here->HICUMcqrbi)=*(ckt->CKTstate1+here->HICUMcqrbi);
|
|
*(ckt->CKTstate0+here->HICUMqjei)=*(ckt->CKTstate1+here->HICUMqjei);
|
|
*(ckt->CKTstate0+here->HICUMcqjei)=*(ckt->CKTstate1+here->HICUMcqjei);
|
|
*(ckt->CKTstate0+here->HICUMqf)=*(ckt->CKTstate1+here->HICUMqf);
|
|
*(ckt->CKTstate0+here->HICUMcqf)=*(ckt->CKTstate1+here->HICUMcqf);
|
|
*(ckt->CKTstate0+here->HICUMqr)=*(ckt->CKTstate1+here->HICUMqr);
|
|
*(ckt->CKTstate0+here->HICUMcqr)=*(ckt->CKTstate1+here->HICUMcqr);
|
|
*(ckt->CKTstate0+here->HICUMqjci)=*(ckt->CKTstate1+here->HICUMqjci);
|
|
*(ckt->CKTstate0+here->HICUMcqjci)=*(ckt->CKTstate1+here->HICUMcqjci);
|
|
*(ckt->CKTstate0+here->HICUMqjep)=*(ckt->CKTstate1+here->HICUMqjep);
|
|
*(ckt->CKTstate0+here->HICUMcqjep)=*(ckt->CKTstate1+here->HICUMcqjep);
|
|
*(ckt->CKTstate0+here->HICUMqjcx0_i)=*(ckt->CKTstate1+here->HICUMqjcx0_i);
|
|
*(ckt->CKTstate0+here->HICUMcqcx0_t_i)=*(ckt->CKTstate1+here->HICUMcqcx0_t_i);
|
|
*(ckt->CKTstate0+here->HICUMqjcx0_ii)=*(ckt->CKTstate1+here->HICUMqjcx0_ii);
|
|
*(ckt->CKTstate0+here->HICUMcqcx0_t_ii)=*(ckt->CKTstate1+here->HICUMcqcx0_t_ii);
|
|
*(ckt->CKTstate0+here->HICUMqdsu)=*(ckt->CKTstate1+here->HICUMqdsu);
|
|
*(ckt->CKTstate0+here->HICUMcqdsu)=*(ckt->CKTstate1+here->HICUMcqdsu);
|
|
*(ckt->CKTstate0+here->HICUMqjs)=*(ckt->CKTstate1+here->HICUMqjs);
|
|
*(ckt->CKTstate0+here->HICUMcqjs)=*(ckt->CKTstate1+here->HICUMcqjs);
|
|
*(ckt->CKTstate0+here->HICUMqscp)=*(ckt->CKTstate1+here->HICUMqscp);
|
|
*(ckt->CKTstate0+here->HICUMcqscp)=*(ckt->CKTstate1+here->HICUMcqscp);
|
|
*(ckt->CKTstate0+here->HICUMqbepar1)=*(ckt->CKTstate1+here->HICUMqbepar1);
|
|
*(ckt->CKTstate0+here->HICUMcqbepar1)=*(ckt->CKTstate1+here->HICUMcqbepar1);
|
|
*(ckt->CKTstate0+here->HICUMgqbepar1)=*(ckt->CKTstate1+here->HICUMgqbepar1);
|
|
*(ckt->CKTstate0+here->HICUMqbepar2)=*(ckt->CKTstate1+here->HICUMqbepar2);
|
|
*(ckt->CKTstate0+here->HICUMcqbepar2)=*(ckt->CKTstate1+here->HICUMcqbepar2);
|
|
*(ckt->CKTstate0+here->HICUMgqbepar2)=*(ckt->CKTstate1+here->HICUMgqbepar2);
|
|
*(ckt->CKTstate0+here->HICUMqbcpar1)=*(ckt->CKTstate1+here->HICUMqbcpar1);
|
|
*(ckt->CKTstate0+here->HICUMcqbcpar1)=*(ckt->CKTstate1+here->HICUMcqbcpar1);
|
|
*(ckt->CKTstate0+here->HICUMgqbcpar1)=*(ckt->CKTstate1+here->HICUMgqbcpar1);
|
|
*(ckt->CKTstate0+here->HICUMqbcpar2)=*(ckt->CKTstate1+here->HICUMqbcpar2);
|
|
*(ckt->CKTstate0+here->HICUMcqbcpar2)=*(ckt->CKTstate1+here->HICUMcqbcpar2);
|
|
*(ckt->CKTstate0+here->HICUMgqbcpar2)=*(ckt->CKTstate1+here->HICUMgqbcpar2);
|
|
*(ckt->CKTstate0+here->HICUMqsu)=*(ckt->CKTstate1+here->HICUMqsu);
|
|
*(ckt->CKTstate0+here->HICUMcqsu)=*(ckt->CKTstate1+here->HICUMcqsu);
|
|
*(ckt->CKTstate0+here->HICUMgqsu)=*(ckt->CKTstate1+here->HICUMgqsu);
|
|
*(ckt->CKTstate0+here->HICUMqcth)=*(ckt->CKTstate1+here->HICUMqcth);
|
|
*(ckt->CKTstate0+here->HICUMcqcth)=*(ckt->CKTstate1+here->HICUMcqcth);
|
|
*(ckt->CKTstate0+here->HICUMvrth)=*(ckt->CKTstate1+here->HICUMvrth);
|
|
*(ckt->CKTstate0+here->HICUMvxf)=*(ckt->CKTstate1+here->HICUMvxf);
|
|
*(ckt->CKTstate0+here->HICUMqxf)=*(ckt->CKTstate1+here->HICUMqxf);
|
|
*(ckt->CKTstate0+here->HICUMcqxf)=*(ckt->CKTstate1+here->HICUMcqxf);
|
|
*(ckt->CKTstate0+here->HICUMgqxf)=*(ckt->CKTstate1+here->HICUMgqxf);
|
|
*(ckt->CKTstate0+here->HICUMixf_Vbiei)=*(ckt->CKTstate1+here->HICUMixf_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMixf_Vbici)=*(ckt->CKTstate1+here->HICUMixf_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMixf_Vxf)=*(ckt->CKTstate1+here->HICUMixf_Vxf);
|
|
*(ckt->CKTstate0+here->HICUMixf_Vrth)=*(ckt->CKTstate1+here->HICUMixf_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMvxf1)=*(ckt->CKTstate1+here->HICUMvxf1);
|
|
*(ckt->CKTstate0+here->HICUMqxf1)=*(ckt->CKTstate1+here->HICUMqxf1);
|
|
*(ckt->CKTstate0+here->HICUMcqxf1)=*(ckt->CKTstate1+here->HICUMcqxf1);
|
|
*(ckt->CKTstate0+here->HICUMgqxf1)=*(ckt->CKTstate1+here->HICUMgqxf1);
|
|
*(ckt->CKTstate0+here->HICUMixf1_Vbiei)=*(ckt->CKTstate1+here->HICUMixf1_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMixf1_Vbici)=*(ckt->CKTstate1+here->HICUMixf1_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMixf1_Vxf2)=*(ckt->CKTstate1+here->HICUMixf1_Vxf2);
|
|
*(ckt->CKTstate0+here->HICUMixf1_Vxf1)=*(ckt->CKTstate1+here->HICUMixf1_Vxf1);
|
|
*(ckt->CKTstate0+here->HICUMixf1_Vrth)=*(ckt->CKTstate1+here->HICUMixf1_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMvxf2)=*(ckt->CKTstate1+here->HICUMvxf2);
|
|
*(ckt->CKTstate0+here->HICUMqxf2)=*(ckt->CKTstate1+here->HICUMqxf2);
|
|
*(ckt->CKTstate0+here->HICUMcqxf2)=*(ckt->CKTstate1+here->HICUMcqxf2);
|
|
*(ckt->CKTstate0+here->HICUMgqxf2)=*(ckt->CKTstate1+here->HICUMgqxf2);
|
|
*(ckt->CKTstate0+here->HICUMixf2_Vbiei)=*(ckt->CKTstate1+here->HICUMixf2_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMixf2_Vbici)=*(ckt->CKTstate1+here->HICUMixf2_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMixf2_Vxf1)=*(ckt->CKTstate1+here->HICUMixf2_Vxf1);
|
|
*(ckt->CKTstate0+here->HICUMixf2_Vxf2)=*(ckt->CKTstate1+here->HICUMixf2_Vxf2);
|
|
*(ckt->CKTstate0+here->HICUMixf2_Vrth)=*(ckt->CKTstate1+here->HICUMixf2_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMith)=*(ckt->CKTstate1+here->HICUMith);
|
|
*(ckt->CKTstate0+here->HICUMith_Vrth)=*(ckt->CKTstate1+here->HICUMith_Vrth);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbiei)=*(ckt->CKTstate1+here->HICUMith_Vbiei);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbici)=*(ckt->CKTstate1+here->HICUMith_Vbici);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbpbi)=*(ckt->CKTstate1+here->HICUMith_Vbpbi);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbpci)=*(ckt->CKTstate1+here->HICUMith_Vbpci);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbpei)=*(ckt->CKTstate1+here->HICUMith_Vbpei);
|
|
*(ckt->CKTstate0+here->HICUMith_Vciei)=*(ckt->CKTstate1+here->HICUMith_Vciei);
|
|
*(ckt->CKTstate0+here->HICUMith_Vsici)=*(ckt->CKTstate1+here->HICUMith_Vsici);
|
|
*(ckt->CKTstate0+here->HICUMith_Vcic)=*(ckt->CKTstate1+here->HICUMith_Vcic);
|
|
*(ckt->CKTstate0+here->HICUMith_Vbbp)=*(ckt->CKTstate1+here->HICUMith_Vbbp);
|
|
*(ckt->CKTstate0+here->HICUMith_Veie)=*(ckt->CKTstate1+here->HICUMith_Veie);
|
|
*(ckt->CKTstate0+here->HICUMit)=*(ckt->CKTstate1+here->HICUMit);
|
|
/////////////////////////
|
|
// end copy state vector
|
|
/////////////////////////
|
|
} else {
|
|
#endif /* PREDICTOR */
|
|
/*
|
|
* compute new nonlinear branch voltages
|
|
*/
|
|
Vbiei = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode));
|
|
// no direct Vbe branch exists, dont need this voltage:
|
|
// Vbe = model->HICUMtype*(
|
|
// *(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
// *(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vbici = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
Vbpei = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode));
|
|
Vbpbi = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBINode));
|
|
Veie = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vcic = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
Vbbp = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode));
|
|
Vbpci = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
Vsici = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsSINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
// not needed because convergence in NQS network is not checked here
|
|
//Vxf = *(ckt->CKTrhsOld + here->HICUMxfNode);
|
|
//Vxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node);
|
|
Vxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node);
|
|
Vciei = Vbiei - Vbici;
|
|
if (model->HICUMselfheat) {
|
|
Vrth = *(ckt->CKTrhsOld + here->HICUMtempNode);
|
|
}
|
|
|
|
#ifndef PREDICTOR
|
|
}
|
|
#endif /* PREDICTOR */
|
|
delvbiei = Vbiei - *(ckt->CKTstate0 + here->HICUMvbiei);
|
|
delvbici = Vbici - *(ckt->CKTstate0 + here->HICUMvbici);
|
|
delvbpei = Vbpei - *(ckt->CKTstate0 + here->HICUMvbpei);
|
|
delvbpbi = Vbpbi - *(ckt->CKTstate0 + here->HICUMvbpbi);
|
|
delvbpci = Vbpci - *(ckt->CKTstate0 + here->HICUMvbpci);
|
|
delvsici = Vsici - *(ckt->CKTstate0 + here->HICUMvsici);
|
|
delvcic = Vcic - *(ckt->CKTstate0 + here->HICUMvcic);
|
|
delvbbp = Vbbp - *(ckt->CKTstate0 + here->HICUMvbbp);
|
|
delveie = Veie - *(ckt->CKTstate0 + here->HICUMveie);
|
|
delvxf2 = Vxf2 - *(ckt->CKTstate0 + here->HICUMvxf2);
|
|
delvciei = delvbiei-delvbici;
|
|
if (model->HICUMselfheat) {
|
|
delvrth = Vrth - *(ckt->CKTstate0 + here->HICUMvrth);
|
|
} else {
|
|
delvrth = 0;
|
|
}
|
|
Vbe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vsc = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
Vbci = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode));
|
|
Vbpe = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Veie = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMemitEINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMemitNode));
|
|
Vcic = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMcollCINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMcollNode));
|
|
Vbbp = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMbaseNode)-
|
|
*(ckt->CKTrhsOld+here->HICUMbaseBPNode));
|
|
Vsis = model->HICUMtype*(
|
|
*(ckt->CKTrhsOld+here->HICUMsubsSINode)-
|
|
*(ckt->CKTrhsOld+here->HICUMsubsNode));
|
|
Vxf = *(ckt->CKTrhsOld + here->HICUMxfNode);
|
|
Vxf1 = *(ckt->CKTrhsOld + here->HICUMxf1Node);
|
|
Vxf2 = *(ckt->CKTrhsOld + here->HICUMxf2Node);
|
|
if (model->HICUMselfheat) {
|
|
Vrth = *(ckt->CKTrhsOld + here->HICUMtempNode);
|
|
}
|
|
//todo: maybe add ibiei_Vxf
|
|
ibieihat = *(ckt->CKTstate0 + here->HICUMibiei) +
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vbiei)*delvbiei+
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vrth)*delvrth+
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vbici)*delvbici;
|
|
ibicihat = *(ckt->CKTstate0 + here->HICUMibici) +
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vbici)*delvbici+
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vrth)*delvrth+
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vbiei)*delvbiei;
|
|
ibpeihat = *(ckt->CKTstate0 + here->HICUMibpei) +
|
|
*(ckt->CKTstate0 + here->HICUMibpei_Vbpei)*delvbpei+
|
|
*(ckt->CKTstate0 + here->HICUMibpei_Vrth)*delvrth;
|
|
ibpcihat = *(ckt->CKTstate0 + here->HICUMibpci) +
|
|
*(ckt->CKTstate0 + here->HICUMibpci_Vbpci)*delvbpci+
|
|
*(ckt->CKTstate0 + here->HICUMibpci_Vrth)*delvrth;
|
|
icieihat = *(ckt->CKTstate0 + here->HICUMiciei) +
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vbiei)*delvbiei +
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vrth)*delvrth +
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vxf2)*delvxf2 +
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vbici)*delvbici;
|
|
ibpbihat = *(ckt->CKTstate0 + here->HICUMibpbi) +
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi)*delvbpbi +
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vrth)*delvrth +
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbiei)*delvbiei +
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbici)*delvbici;
|
|
isicihat = *(ckt->CKTstate0 + here->HICUMisici) +
|
|
*(ckt->CKTstate0 + here->HICUMisici_Vsici)*delvsici+
|
|
*(ckt->CKTstate0 + here->HICUMisici_Vrth)*delvrth;
|
|
ibpsihat = *(ckt->CKTstate0 + here->HICUMibpsi) +
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vbpci)*delvbpci +
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vrth)*delvrth +
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vsici)*delvsici;
|
|
ithhat = *(ckt->CKTstate0 + here->HICUMith) +
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbiei)*delvbiei+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbici)*delvbici+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpbi)*delvbpbi+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpci)*delvbpci+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpei)*delvbpei+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vciei)*delvciei+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vsici)*delvsici+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vcic)*delvcic+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbbp)*delvbbp+
|
|
*(ckt->CKTstate0 + here->HICUMith_Veie)*delveie+
|
|
*(ckt->CKTstate0 + here->HICUMith_Vrth)*delvrth;
|
|
/*
|
|
* bypass if solution has not changed
|
|
*/
|
|
/* the following collections of if's would be just one
|
|
* if the average compiler could handle it, but many
|
|
* find the expression too complicated, thus the split.
|
|
* ... no bypass in case of selfheating
|
|
*/
|
|
if( (ckt->CKTbypass) && (!(ckt->CKTmode & MODEINITPRED)) && !model->HICUMselfheat &&
|
|
(fabs(delvbiei) < (ckt->CKTreltol*MAX(fabs(Vbiei),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvbiei)))+
|
|
ckt->CKTvoltTol)) )
|
|
if( (fabs(delvbici) < ckt->CKTreltol*MAX(fabs(Vbici),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvbici)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delvbpei) < ckt->CKTreltol*MAX(fabs(Vbpei),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvbpei)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delvbpbi) < ckt->CKTreltol*MAX(fabs(Vbpbi),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvbpbi)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delvsici) < ckt->CKTreltol*MAX(fabs(Vsici),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvsici)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delvcic) < ckt->CKTreltol*MAX(fabs(Vcic),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvcic)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delvbbp) < ckt->CKTreltol*MAX(fabs(Vbbp),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMvbbp)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(delveie) < ckt->CKTreltol*MAX(fabs(Veie),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMveie)))+
|
|
ckt->CKTvoltTol) )
|
|
if( (fabs(ibieihat-*(ckt->CKTstate0 + here->HICUMibiei)) <
|
|
ckt->CKTreltol* MAX(fabs(ibieihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibiei)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ibpeihat-*(ckt->CKTstate0 + here->HICUMibpei)) <
|
|
ckt->CKTreltol* MAX(fabs(ibpeihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibpei)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(icieihat-*(ckt->CKTstate0 + here->HICUMiciei)) <
|
|
ckt->CKTreltol* MAX(fabs(icieihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMiciei)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ibicihat-*(ckt->CKTstate0 + here->HICUMibici)) <
|
|
ckt->CKTreltol* MAX(fabs(ibicihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibici)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ibpcihat-*(ckt->CKTstate0 + here->HICUMibpci)) <
|
|
ckt->CKTreltol* MAX(fabs(ibpcihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibpci)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ibpbihat-*(ckt->CKTstate0 + here->HICUMibpbi)) <
|
|
ckt->CKTreltol* MAX(fabs(ibpbihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibpbi)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(isicihat-*(ckt->CKTstate0 + here->HICUMisici)) <
|
|
ckt->CKTreltol* MAX(fabs(isicihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMisici)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ithhat-*(ckt->CKTstate0 + here->HICUMith)) <
|
|
ckt->CKTreltol* MAX(fabs(ithhat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMith)))+
|
|
ckt->CKTabstol) )
|
|
if( (fabs(ibpsihat-*(ckt->CKTstate0 + here->HICUMibpsi)) <
|
|
ckt->CKTreltol* MAX(fabs(ibpsihat),
|
|
fabs(*(ckt->CKTstate0 + here->HICUMibpsi)))+
|
|
ckt->CKTabstol) ) {
|
|
/*
|
|
* bypassing....
|
|
*/
|
|
Vbiei = *(ckt->CKTstate0 + here->HICUMvbiei);
|
|
Vbici = *(ckt->CKTstate0 + here->HICUMvbici);
|
|
Vbpei = *(ckt->CKTstate0 + here->HICUMvbpei);
|
|
Vbpbi = *(ckt->CKTstate0 + here->HICUMvbpbi);
|
|
Vbpci = *(ckt->CKTstate0 + here->HICUMvbpci);
|
|
Vsici = *(ckt->CKTstate0 + here->HICUMvsici);
|
|
Vcic = *(ckt->CKTstate0 + here->HICUMvcic);
|
|
Vbbp = *(ckt->CKTstate0 + here->HICUMvbbp);
|
|
Veie = *(ckt->CKTstate0 + here->HICUMveie);
|
|
Vrth = *(ckt->CKTstate0 + here->HICUMvrth);
|
|
Vxf = *(ckt->CKTstate0 + here->HICUMvxf);
|
|
Vxf1 = *(ckt->CKTstate0 + here->HICUMvxf1);
|
|
Vxf2 = *(ckt->CKTstate0 + here->HICUMvxf2);
|
|
|
|
Ibiei = *(ckt->CKTstate0 + here->HICUMibiei);
|
|
Ibiei_Vbiei = *(ckt->CKTstate0 + here->HICUMibiei_Vbiei);
|
|
Ibiei_Vxf = *(ckt->CKTstate0 + here->HICUMibiei_Vxf);
|
|
Ibiei_Vbici = *(ckt->CKTstate0 + here->HICUMibiei_Vbici);
|
|
Ibiei_Vrth = *(ckt->CKTstate0 + here->HICUMibiei_Vrth);
|
|
|
|
Ibpei = *(ckt->CKTstate0 + here->HICUMibpei);
|
|
Ibpei_Vbpei = *(ckt->CKTstate0 + here->HICUMibpei_Vbpei);
|
|
Ibpei_Vrth = *(ckt->CKTstate0 + here->HICUMibpei_Vrth);
|
|
|
|
Iciei = *(ckt->CKTstate0 + here->HICUMiciei);
|
|
Iciei_Vbiei = *(ckt->CKTstate0 + here->HICUMiciei_Vbiei);
|
|
Iciei_Vbici = *(ckt->CKTstate0 + here->HICUMiciei_Vbici);
|
|
Iciei_Vrth = *(ckt->CKTstate0 + here->HICUMiciei_Vrth);
|
|
Iciei_Vxf2 = *(ckt->CKTstate0 + here->HICUMiciei_Vxf2);
|
|
|
|
Ibici = *(ckt->CKTstate0 + here->HICUMibici);
|
|
Ibici_Vbici = *(ckt->CKTstate0 + here->HICUMibici_Vbici);
|
|
Ibici_Vbiei = *(ckt->CKTstate0 + here->HICUMibici_Vbiei);
|
|
Ibici_Vrth = *(ckt->CKTstate0 + here->HICUMibici_Vrth);
|
|
|
|
Ibpbi = *(ckt->CKTstate0 + here->HICUMibpbi);
|
|
Ibpbi_Vbpbi = *(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi);
|
|
Ibpbi_Vbiei = *(ckt->CKTstate0 + here->HICUMibpbi_Vbiei);
|
|
Ibpbi_Vbici = *(ckt->CKTstate0 + here->HICUMibpbi_Vbici);
|
|
Ibpbi_Vrth = *(ckt->CKTstate0 + here->HICUMibpbi_Vrth);
|
|
|
|
Isici = *(ckt->CKTstate0 + here->HICUMisici);
|
|
Isici_Vsici = *(ckt->CKTstate0 + here->HICUMisici_Vsici);
|
|
Isici_Vrth = *(ckt->CKTstate0 + here->HICUMisici_Vrth);
|
|
|
|
Ibpsi = *(ckt->CKTstate0 + here->HICUMibpsi);
|
|
Ibpsi_Vbpci = *(ckt->CKTstate0 + here->HICUMibpsi_Vbpci);
|
|
Ibpsi_Vsici = *(ckt->CKTstate0 + here->HICUMibpsi_Vsici);
|
|
Ibpsi_Vrth = *(ckt->CKTstate0 + here->HICUMibpsi_Vrth);
|
|
|
|
Ibpci = *(ckt->CKTstate0 + here->HICUMibpci);
|
|
Ibpci_Vbpci = *(ckt->CKTstate0 + here->HICUMibpci_Vbpci);
|
|
Ibpci_Vrth = *(ckt->CKTstate0 + here->HICUMibpci_Vrth);
|
|
|
|
//dead assign:
|
|
//Ieie = *(ckt->CKTstate0 + here->HICUMieie);
|
|
Ieie_Vrth = *(ckt->CKTstate0 + here->HICUMieie_Vrth);
|
|
|
|
Isis_Vsis = *(ckt->CKTstate0 + here->HICUMisis_Vsis);
|
|
|
|
gqbepar1 = *(ckt->CKTstate0 + here->HICUMgqbepar1);
|
|
gqbepar2 = *(ckt->CKTstate0 + here->HICUMgqbepar2);
|
|
gqbcpar1 = *(ckt->CKTstate0 + here->HICUMgqbcpar1);
|
|
gqbcpar2 = *(ckt->CKTstate0 + here->HICUMgqbcpar2);
|
|
|
|
Ixf = *(ckt->CKTstate0 + here->HICUMixf) ;
|
|
Ixf_Vbiei = *(ckt->CKTstate0 + here->HICUMixf_Vbiei) ;
|
|
Ixf_Vbici = *(ckt->CKTstate0 + here->HICUMixf_Vbici) ;
|
|
Ixf_Vxf = *(ckt->CKTstate0 + here->HICUMixf_Vxf) ;
|
|
Ixf_dT = *(ckt->CKTstate0 + here->HICUMixf_Vrth) ;
|
|
Ixf1 = *(ckt->CKTstate0 + here->HICUMixf1) ;
|
|
Ixf1_Vbiei = *(ckt->CKTstate0 + here->HICUMixf1_Vbiei) ;
|
|
Ixf1_Vbici = *(ckt->CKTstate0 + here->HICUMixf1_Vbici) ;
|
|
Ixf1_Vxf2 = *(ckt->CKTstate0 + here->HICUMixf1_Vxf2) ;
|
|
Ixf1_Vxf1 = *(ckt->CKTstate0 + here->HICUMixf1_Vxf1) ;
|
|
Ixf1_dT = *(ckt->CKTstate0 + here->HICUMixf1_Vrth) ;
|
|
Ixf2 = *(ckt->CKTstate0 + here->HICUMixf2) ;
|
|
Ixf2_Vbiei = *(ckt->CKTstate0 + here->HICUMixf2_Vbiei) ;
|
|
Ixf2_Vbici = *(ckt->CKTstate0 + here->HICUMixf2_Vbici) ;
|
|
Ixf2_Vxf1 = *(ckt->CKTstate0 + here->HICUMixf2_Vxf1) ;
|
|
Ixf2_Vxf2 = *(ckt->CKTstate0 + here->HICUMixf2_Vxf2) ;
|
|
Ixf2_dT = *(ckt->CKTstate0 + here->HICUMixf2_Vrth) ;
|
|
|
|
goto load;
|
|
}
|
|
/*
|
|
* limit nonlinear branch voltages
|
|
*/
|
|
ichk1 = 1, ichk2 = 1, ichk3 = 1, ichk4 = 1, ichk5=1, ichk6 = 0;
|
|
Vbiei = DEVpnjlim(Vbiei,*(ckt->CKTstate0 + here->HICUMvbiei),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&icheck);
|
|
Vaval = 3 * here->HICUMvdci_t.rpart;//limit step around 3*vdci_t -> somehow this brings convergence
|
|
if ((model->HICUMfavlGiven) && (Vbici < MIN(0, -Vaval))) {
|
|
Vbici_temp = -(Vbici + Vaval);
|
|
Vbici_temp = DEVpnjlim(
|
|
Vbici_temp,
|
|
-(*(ckt->CKTstate0 + here->HICUMvbici) + Vaval),
|
|
here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,
|
|
&ichk1
|
|
);
|
|
Vbici = -(Vbici_temp + Vaval);
|
|
} else {
|
|
Vbici = DEVpnjlim(Vbici,*(ckt->CKTstate0 + here->HICUMvbici),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&ichk1);
|
|
}
|
|
Vbpei = DEVpnjlim(Vbpei,*(ckt->CKTstate0 + here->HICUMvbpei),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&ichk2);
|
|
Vbpci = DEVpnjlim(Vbpci,*(ckt->CKTstate0 + here->HICUMvbpci),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&ichk3);
|
|
Vsici = DEVpnjlim(Vsici,*(ckt->CKTstate0 + here->HICUMvsici),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&ichk4);
|
|
Vbpbi = DEVpnjlim(Vbpbi,*(ckt->CKTstate0 + here->HICUMvbpbi),here->HICUMvt.rpart,
|
|
here->HICUMtVcrit,&ichk5);
|
|
if (model->HICUMselfheat) {
|
|
Vrth = DEVlimitlog(Vrth,
|
|
*(ckt->CKTstate0 + here->HICUMvrth),1,&ichk6);
|
|
}
|
|
if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1) || (ichk5 == 1) || (ichk6 == 1)) icheck=1;
|
|
}
|
|
/*
|
|
* determine dc current and derivatives
|
|
*/
|
|
Vbiei = model->HICUMtype*Vbiei;
|
|
Vbici = model->HICUMtype*Vbici;
|
|
Vciei = (Vbiei-Vbici);
|
|
Vbpei = model->HICUMtype*Vbpei;
|
|
Vbpci = model->HICUMtype*Vbpci;
|
|
Vbci = model->HICUMtype*Vbci;
|
|
Vsici = model->HICUMtype*Vsici;
|
|
Vsc = model->HICUMtype*Vsc;
|
|
|
|
// Thermal update
|
|
if (model->HICUMselfheat) {
|
|
Temp = here->HICUMtemp+Vrth;
|
|
hicum_thermal_update(model, here, &Temp, &Tdev_Vrth);
|
|
|
|
here->HICUMdtemp_sh = Temp - here->HICUMtemp;
|
|
here->HICUMtemp_Vrth = Tdev_Vrth;
|
|
} else {
|
|
Temp = here->HICUMtemp;
|
|
Tdev_Vrth = 0;
|
|
here->HICUMdtemp_sh = 0;
|
|
here->HICUMtemp_Vrth = 0;
|
|
}
|
|
|
|
Temp_dual = Temp + 1_e*Tdev_Vrth;
|
|
|
|
// Model_evaluation
|
|
|
|
//Intrinsic transistor
|
|
//Internal base currents across b-e junction
|
|
hicum_diode(Temp_dual,here->HICUMibeis_t,model->HICUMmbei, Vbiei, &ibei, &ibei_Vbiei, &ibei_dT);
|
|
hicum_diode(Temp_dual,here->HICUMireis_t,model->HICUMmrei, Vbiei, &irei, &irei_Vbiei, &irei_dT);
|
|
|
|
//Internal b-e and b-c junction capacitances and charges
|
|
//Cjei = ddx(Qjei,V(bi));
|
|
hicum_qjmodf(Temp_dual,here->HICUMcjei0_t,here->HICUMvdei_t,model->HICUMzei,here->HICUMajei_t,Vbiei,&Cjei,&Cjei_Vbiei, &Cjei_dT,&Qjei, &Qjei_Vbiei, &Qjei_dT);
|
|
|
|
result = calc_hjei_vbe(Vbiei+1_e, Temp, here, model);
|
|
hjei_vbe = result.rpart();
|
|
hjei_vbe_Vbiei = result.dpart();
|
|
result = calc_hjei_vbe(Vbiei, Temp_dual, here, model);
|
|
hjei_vbe_dT = result.dpart();
|
|
|
|
|
|
//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);
|
|
|
|
//Hole charge at low bias
|
|
result = calc_Q_0(Temp , Qjei+1_e*Qjei_Vbiei, Qjci, hjei_vbe+1_e*hjei_vbe_Vbiei);
|
|
Q_0 = result.rpart();
|
|
Q_0_Vbiei = result.dpart();
|
|
|
|
result = calc_Q_0(Temp , Qjei, Qjci+1_e*Qjci_Vbici, hjei_vbe);
|
|
Q_0_Vbici = result.dpart();
|
|
|
|
result = calc_Q_0(Temp_dual , Qjei+1_e*Qjei_dT, Qjci+1_e*Qjci_dT, hjei_vbe+1_e*hjei_vbe_dT);
|
|
Q_0_dT = result.dpart();
|
|
|
|
//Transit time calculation at low current density
|
|
result = calc_T_f0(Temp, Vbici+1_e);
|
|
T_f0 = result.rpart();
|
|
T_f0_Vbici = result.dpart();
|
|
|
|
result = calc_T_f0(Temp_dual, Vbici);
|
|
T_f0_dT = result.dpart() ;
|
|
|
|
//Critical current
|
|
result = calc_ick(Temp, Vciei+1_e);
|
|
ick = result.rpart();
|
|
ick_Vciei = result.dpart();
|
|
|
|
result = calc_ick(Temp_dual, Vciei);
|
|
ick_dT = result.dpart();
|
|
|
|
here->HICUMick = ick;
|
|
|
|
//begin Q_pT calculation
|
|
|
|
//Initial formulation of forward and reverse component of transfer current
|
|
|
|
Tr = model->HICUMtr;
|
|
|
|
//begin initial transfer current calculations -> itf, itr, Qf, Qr------------
|
|
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 = result_itf.rpart();
|
|
itr = result_itr.rpart();
|
|
Qf = result_Qf.rpart();
|
|
Qr = result_Qr.rpart();
|
|
Q_bf = result_Q_bf.rpart();
|
|
a_h = result_a_h.rpart(); //needed to check if newton iteration needed
|
|
Q_p = result_Q_p.rpart(); //needed to check if newton iteration needed
|
|
Tf = result_Tf.rpart(); //needed to check if newton iteration needed
|
|
// dead assign:
|
|
//itf_dT = result_itf.dpart();
|
|
//itr_dT = result_itr.dpart();
|
|
//Qf_dT = result_Qf.dpart();
|
|
//Qr_dT = result_Qr.dpart();
|
|
//Q_bf_dT= result_Q_bf.dpart();
|
|
//Tf_dT = result_Tf.dpart();
|
|
|
|
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();
|
|
Qf_dT = result_Qf.dpart();
|
|
Qr_dT = result_Qr.dpart();
|
|
Q_bf_dT = result_Q_bf.dpart();
|
|
Tf_dT = result_Tf.dpart();
|
|
|
|
calc_it_initial(Temp , Vbiei+1_e, Vbici , Q_0+1_e*Q_0*Vbiei , T_f0 , ick+1_e*ick_Vciei , &result_itf, &result_itr, &result_Qf, &result_Qr, &result_Q_bf, &result_a_h, &result_Q_p, &result_Tf);
|
|
itf_Vbiei = result_itf.dpart();
|
|
itr_Vbiei = result_itr.dpart();
|
|
Qf_Vbiei = result_Qf.dpart();
|
|
Qr_Vbiei = result_Qr.dpart();
|
|
Q_bf_Vbiei = result_Q_bf.dpart();
|
|
Tf_Vbiei = result_Tf.dpart();
|
|
|
|
calc_it_initial(Temp , Vbiei , Vbici+1_e, Q_0+1_e*Q_0_Vbici , T_f0+1_e*T_f0_Vbici , ick-1_e*ick_Vciei , &result_itf, &result_itr, &result_Qf, &result_Qr, &result_Q_bf, &result_a_h, &result_Q_p, &result_Tf);
|
|
itf_Vbici = result_itf.dpart();
|
|
itr_Vbici = result_itr.dpart();
|
|
Qf_Vbici = result_Qf.dpart();
|
|
Qr_Vbici = result_Qr.dpart();
|
|
Q_bf_Vbici= result_Q_bf.dpart();
|
|
Tf_Vbici = result_Tf.dpart();
|
|
|
|
} else { //Newton needed
|
|
result = calc_it(Temp_dual, Vbiei , Vbici , Q_0+1_e*Q_0_dT , T_f0+1_e*T_f0_dT , ick+1_e*ick_dT );
|
|
Q_pT = result.rpart();
|
|
Q_pT_dT = result.dpart();
|
|
result = calc_it(Temp , Vbiei+1_e, Vbici , Q_0+1_e*Q_0_Vbiei , T_f0 , ick+1_e*ick_Vciei );
|
|
Q_pT_dVbiei = result.dpart();
|
|
result = calc_it(Temp , Vbiei , Vbici+1_e, Q_0+1_e*Q_0_Vbici , T_f0+1_e*T_f0_Vbici , ick-1_e*ick_Vciei );
|
|
Q_pT_dVbici = result.dpart();
|
|
|
|
//end Q_pT -------------------------------------------------------------------------------
|
|
|
|
//begin final transfer current calculations -> itf, itr, Qf, Qr------------
|
|
calc_it_final(Temp_dual, Vbiei , Vbici , Q_pT+1_e*Q_pT_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_Tf);
|
|
itf = result_itf.rpart();
|
|
itr = result_itr.rpart();
|
|
Qf = result_Qf.rpart();
|
|
Qr = result_Qr.rpart();
|
|
Q_bf = result_Q_bf.rpart();
|
|
Tf = result_Tf.rpart();
|
|
itf_dT = result_itf.dpart();
|
|
itr_dT = result_itr.dpart();
|
|
Qf_dT = result_Qf.dpart();
|
|
Qr_dT = result_Qr.dpart();
|
|
Q_bf_dT= result_Q_bf.dpart();
|
|
Tf_dT = result_Tf.dpart();
|
|
|
|
calc_it_final(Temp , Vbiei+1_e , Vbici , Q_pT+1_e*Q_pT_dVbiei , T_f0 , ick+1_e*ick_Vciei , &result_itf, &result_itr, &result_Qf, &result_Qr, &result_Q_bf, &result_Tf);
|
|
itf_Vbiei = result_itf.dpart();
|
|
itr_Vbiei = result_itr.dpart();
|
|
Qf_Vbiei = result_Qf.dpart();
|
|
Qr_Vbiei = result_Qr.dpart();
|
|
Q_bf_Vbiei = result_Q_bf.dpart();
|
|
Tf_Vbiei = result_Tf.dpart();
|
|
|
|
calc_it_final(Temp , Vbiei , Vbici+1_e, Q_pT+1_e*Q_pT_dVbici , T_f0+1_e*T_f0_Vbici , ick-1_e*ick_Vciei , &result_itf, &result_itr, &result_Qf, &result_Qr, &result_Q_bf, &result_Tf);
|
|
itf_Vbici = result_itf.dpart();
|
|
itr_Vbici = result_itr.dpart();
|
|
Qf_Vbici = result_Qf.dpart();
|
|
Qr_Vbici = result_Qr.dpart();
|
|
Q_bf_Vbici= result_Q_bf.dpart();
|
|
Tf_Vbici = result_Tf.dpart();
|
|
|
|
}
|
|
|
|
// finally the transfer current
|
|
it = itf - itr;
|
|
it_Vbiei = itf_Vbiei - itr_Vbiei;
|
|
it_Vbici = itf_Vbici - itr_Vbici;
|
|
it_dT = itf_dT - itr_dT;
|
|
|
|
//end final calculations --------------------------------------------------
|
|
|
|
here->HICUMtf = Tf;
|
|
|
|
//NQS effect implemented with gyrator network
|
|
//Once the delay in ITF is considered, IT_NQS is calculated afterwards
|
|
|
|
//Diffusion charges for further use (remember derivatives if this will be used someday)
|
|
Qdei = Qf;
|
|
Qdei_Vbici = Qf_Vbici;
|
|
Qdei_Vbiei = Qf_Vbiei;
|
|
Qdei_dT = Qf_dT;
|
|
//Qdci = Qr; //we just use Qr herein
|
|
|
|
//High-frequency emitter current crowding (lateral NQS)
|
|
Cdei = T_f0*itf/here->HICUMvt.rpart;
|
|
Cdei_Vbiei = T_f0*itf_Vbiei/here->HICUMvt.rpart;
|
|
Cdei_Vbici = T_f0_Vbici*itf/here->HICUMvt.rpart;
|
|
Cdei_Vbici+= T_f0*itf_Vbici/here->HICUMvt.rpart;
|
|
Cdei_Vrth = T_f0_dT*itf/here->HICUMvt.rpart + T_f0*itf_dT/here->HICUMvt.rpart - T_f0*itf/here->HICUMvt.rpart/here->HICUMvt.rpart*here->HICUMvt.dpart;
|
|
|
|
Cdci = model->HICUMtr*itr/here->HICUMvt.rpart;
|
|
Cdci_Vbiei = model->HICUMtr*itr_Vbiei/here->HICUMvt.rpart;
|
|
Cdci_Vbici = model->HICUMtr*itr_Vbici/here->HICUMvt.rpart;
|
|
Cdci_Vrth = model->HICUMtr*itr_dT/here->HICUMvt.rpart - model->HICUMtr*itr/here->HICUMvt.rpart/here->HICUMvt.rpart*here->HICUMvt.dpart;
|
|
|
|
Crbi = model->HICUMfcrbi*(Cjei+Cjci+Cdei+Cdci);
|
|
Crbi_Vrth = model->HICUMfcrbi*(Cjei_dT+Cjci_dT+Cdei_Vrth+Cdci_Vrth);
|
|
Crbi_Vbiei = model->HICUMfcrbi*(Cjei_Vbiei+Cdei_Vbiei+Cdci_Vbiei);
|
|
Crbi_Vbici = model->HICUMfcrbi*(Cjci_Vbici+Cdei_Vbici+Cdci_Vbici);
|
|
|
|
Qrbi = Crbi*Vbpbi; //Vbpbi=(Vbpei-Vbiei)=(Vbpci-Vbici)
|
|
Qrbi_Vbpbi = Crbi;
|
|
Qrbi_Vbiei = Vbpbi*Crbi_Vbiei;
|
|
Qrbi_Vbici = Vbpbi*Crbi_Vbici;
|
|
Qrbi_Vrth = Vbpbi*Crbi_Vrth;
|
|
|
|
//HICCR: }
|
|
|
|
//Internal base current across b-c junction
|
|
hicum_diode(Temp_dual,here->HICUMibcis_t,model->HICUMmbci, Vbici, &ibci, &ibci_Vbici, &ibci_dT);
|
|
|
|
//Avalanche current
|
|
result = calc_iavl(Vbici+1_e, Cjci+1_e*Cjci_Vbici, itf+1_e*itf_Vbici , Temp);
|
|
iavl = result.rpart();
|
|
iavl_Vbici = result.dpart();
|
|
|
|
result = calc_iavl(Vbici, Cjci, itf+1_e*itf_Vbiei , Temp);
|
|
iavl_Vbiei = result.dpart();
|
|
|
|
result = calc_iavl(Vbici , Cjci+1_e*Cjci_dT , itf+1_e*itf_dT , Temp_dual);
|
|
iavl_dT = result.dpart();
|
|
|
|
here->HICUMiavl = iavl;
|
|
|
|
//Excess base current from recombination at the b-c barrier
|
|
ibh_rec = Q_bf*Otbhrec;
|
|
ibh_rec_Vbiei = Otbhrec*Q_bf_Vbiei ;
|
|
ibh_rec_Vbici = Otbhrec*Q_bf_Vbici ;
|
|
ibh_rec_dT = Otbhrec*Q_bf_dT ;
|
|
|
|
//internal base resistance
|
|
result = calc_rbi(Temp_dual, Qjei+1_e*Qjei_dT , Qf+1_e*Qf_dT );
|
|
rbi = result.rpart();
|
|
rbi_dT = result.dpart();
|
|
|
|
result = calc_rbi(Temp, Qjei+1_e*Qjei_Vbiei , Qf+1_e*Qf_Vbiei );
|
|
rbi_Vbiei = result.dpart();
|
|
|
|
result = calc_rbi(Temp, Qjei , Qf+1_e*Qf_Vbici );
|
|
rbi_Vbici = result.dpart();
|
|
|
|
here->HICUMrbi = rbi;
|
|
|
|
//Base currents across peripheral b-e junction
|
|
hicum_diode(Temp_dual,here->HICUMibeps_t,model->HICUMmbep, Vbpei, &ibep, &ibep_Vbpei, &ibep_dT);
|
|
hicum_diode(Temp_dual,here->HICUMireps_t,model->HICUMmrep, Vbpei, &irep, &irep_Vbpei, &irep_dT);
|
|
|
|
//Peripheral b-e junction capacitance and charge
|
|
hicum_qjmodf(Temp_dual,here->HICUMcjep0_t,here->HICUMvdep_t,model->HICUMzep,here->HICUMajep_t,Vbpei,&Cjep,&Cjep_Vbpei, &Cjep_dT,&Qjep, &Qjep_Vbpei, &Qjep_dT);
|
|
|
|
//Tunneling current
|
|
result = calc_ibet(Vbiei , Vbpei+1_e, Temp);
|
|
ibet = result.rpart();
|
|
ibet_Vbpei = result.dpart();
|
|
|
|
result = calc_ibet(Vbiei+1_e, Vbpei, Temp);
|
|
ibet_Vbiei = result.dpart();
|
|
|
|
result = calc_ibet(Vbiei , Vbpei, Temp_dual);
|
|
ibet_dT = result.dpart();
|
|
|
|
//Base currents across peripheral b-c junction (bp,ci)
|
|
hicum_diode(Temp_dual,here->HICUMibcxs_t,model->HICUMmbcx, Vbpci, &ijbcx, &ijbcx_Vbpci, &ijbcx_dT);
|
|
|
|
//Depletion capacitance and charge at external b-c junction (b,ci)
|
|
hicum_HICJQ(Temp_dual, here->HICUMcjcx01_t,here->HICUMvdcx_t,model->HICUMzcx,here->HICUMvptcx_t, Vbci, &Cjcx_i, &Cjcx_i_Vbci, &Cjcx_i_dT, &Qjcx_i, &Qjcx_i_Vbci, &Qjcx_i_dT);
|
|
|
|
//Depletion capacitance and charge at peripheral b-c junction (bp,ci)
|
|
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)
|
|
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) {
|
|
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
|
|
Cscp = model->HICUMcscp0;
|
|
Cscp_Vsc = 0;
|
|
Cscp_dT = 0;
|
|
Qscp = model->HICUMcscp0*Vsc;
|
|
Qscp_Vsc = model->HICUMcscp0;
|
|
Qscp_dT = 0;
|
|
}
|
|
|
|
//Parasitic substrate transistor transfer current and diffusion charge
|
|
calc_itss(Temp_dual, Vbpci , Vsici , &result_HSI_TSU, &result_Qdsu);
|
|
HSI_Tsu = result_HSI_TSU.rpart();
|
|
Qdsu = result_Qdsu.rpart();
|
|
HSI_Tsu_dT = result_HSI_TSU.dpart();
|
|
Qdsu_dT = result_Qdsu.dpart();
|
|
|
|
calc_itss(Temp , Vbpci+1_e, Vsici , &result_HSI_TSU, &result_Qdsu);
|
|
HSI_Tsu_Vbpci = result_HSI_TSU.dpart();
|
|
Qdsu_Vbpci = result_Qdsu.dpart();
|
|
calc_itss(Temp , Vbpci , Vsici+1_e, &result_HSI_TSU, &result_Qdsu);
|
|
HSI_Tsu_Vsici = result_HSI_TSU.dpart();
|
|
Qdsu_Vsici = result_Qdsu.dpart();
|
|
|
|
// Current gain computation for correlated noise implementation
|
|
if (ibei > 0.0) {
|
|
here->HICUMbetadc=it/ibei;
|
|
} else {
|
|
here->HICUMbetadc=0.0;
|
|
}
|
|
if (here->HICUMre_t.rpart >= MIN_R) {
|
|
Ieie = Veie/here->HICUMre_t.rpart; // only needed for re flicker noise
|
|
} else {
|
|
Ieie = 0.0;
|
|
}
|
|
|
|
//Diode current for s-c junction (si,ci)
|
|
hicum_diode(Temp_dual,here->HICUMiscs_t,model->HICUMmsc, Vsici, &ijsc, &ijsc_Vsici, &ijsc_Vrth);
|
|
|
|
// Self-heating calculation
|
|
if (model->HICUMflsh == 1 && here->HICUMrth_scaled >= MIN_R) {
|
|
pterm = (Vbiei-Vbici)*it + (here->HICUMvdci_t.rpart-Vbici)*iavl;
|
|
pterm_dT = (Vbiei-Vbici)*it_dT + (here->HICUMvdci_t.rpart-Vbici)*iavl_dT + here->HICUMvdci_t.dpart*iavl;
|
|
} else if (model->HICUMflsh == 2 && here->HICUMrth_scaled >= MIN_R) {
|
|
pterm = (Vbiei-Vbici)*it + (here->HICUMvdci_t.rpart-Vbici)*iavl + ibei*Vbiei + ibci*Vbici + ibep*Vbpei + ijbcx*Vbpci + ijsc*Vsici;
|
|
pterm_dT = (Vbiei-Vbici)*it_dT + (here->HICUMvdci_t.rpart-Vbici)*iavl_dT + here->HICUMvdci_t.dpart*iavl +
|
|
ibei_dT*Vbiei + ibci_dT*Vbici + ibep_dT*Vbpei + ijbcx_dT*Vbpci + ijsc_Vrth*Vsici;
|
|
|
|
if (rbi > 0.0) {
|
|
pterm += Vbpbi*Vbpbi/rbi;
|
|
pterm_dT += -Vbpbi*Vbpbi*rbi_dT/rbi/rbi;
|
|
}
|
|
if (here->HICUMre_t.rpart >= MIN_R) {
|
|
pterm += Veie*Veie/here->HICUMre_t.rpart;
|
|
pterm_dT += -Veie*Veie*here->HICUMre_t.dpart/here->HICUMre_t.rpart/here->HICUMre_t.rpart;
|
|
}
|
|
if (here->HICUMrcx_t.rpart >= MIN_R) {
|
|
pterm += Vcic*Vcic/here->HICUMrcx_t.rpart;
|
|
pterm_dT += -Vcic*Vcic*here->HICUMrcx_t.dpart/here->HICUMrcx_t.rpart/here->HICUMrcx_t.rpart;
|
|
}
|
|
if (here->HICUMrbx_t.rpart >= MIN_R) {
|
|
pterm += Vbbp*Vbbp/here->HICUMrbx_t.rpart;
|
|
pterm_dT += -Vbbp*Vbbp*here->HICUMrbx_t.dpart/here->HICUMrbx_t.rpart/here->HICUMrbx_t.rpart;
|
|
}
|
|
} else {
|
|
pterm = 0; // default value...
|
|
pterm_dT = 0;
|
|
}
|
|
here->HICUMpterm = pterm;
|
|
|
|
Itxf = itf;
|
|
Itxf_Vbici = itf_Vbici;
|
|
Itxf_Vbiei = itf_Vbiei;
|
|
Itxf_dT = itf_dT;
|
|
Itxf_Vxf2 = 0.0;
|
|
Qdeix = Qdei;
|
|
Qdeix_Vbiei = Qdei_Vbiei;
|
|
Qdeix_Vbici = Qdei_Vbici;
|
|
Qdeix_dT = Qdei_dT;
|
|
Qdeix_Vxf = 0.0;
|
|
|
|
// Excess Phase calculation -> hand implementation instead of dual numbers
|
|
if (model->HICUMnqs) { // && (ckt->CKTmode & (MODETRAN | MODEAC) ) ) { //evaluate nqs network only in TRANSIENT and AC modes.
|
|
Ixf1 = (Vxf2-itf)/Tf*model->HICUMt0;
|
|
Ixf1_Vxf1 = 0.0;
|
|
Ixf1_Vxf2 = 1.0/Tf*model->HICUMt0;
|
|
Ixf1_ditf = -Ixf1_Vxf2;
|
|
Ixf1_dTf = -Ixf1/Tf; //Tf(Vbiei,Vciei=Vbiei-Vbici)
|
|
Ixf1_Vbiei = Ixf1_ditf*itf_Vbiei + Ixf1_dTf*Tf_Vbiei;
|
|
Ixf1_Vbici = Ixf1_ditf*itf_Vbici + Ixf1_dTf*Tf_Vbici;
|
|
Ixf1_dT = Ixf1_ditf*itf_dT + Ixf1_dTf*Tf_dT;
|
|
|
|
Ixf2 = (Vxf2-Vxf1)/Tf*model->HICUMt0;
|
|
Ixf2_Vxf2 = 1.0/Tf*model->HICUMt0;
|
|
Ixf2_Vxf1 = -Ixf2_Vxf2;
|
|
Ixf2_dTf = -Ixf2/Tf;
|
|
Ixf2_Vbiei = Ixf2_dTf*Tf_Vbiei;
|
|
Ixf2_Vbici = Ixf2_dTf*Tf_Vbici;
|
|
Ixf2_dT = Ixf2_dTf*Tf_dT;
|
|
|
|
Qxf1 = model->HICUMalit*model->HICUMt0*Vxf1;
|
|
Qxf1_Vxf1 = model->HICUMalit*model->HICUMt0;
|
|
Qxf2 = model->HICUMalit*model->HICUMt0*Vxf2/3;
|
|
Qxf2_Vxf2 = model->HICUMalit*model->HICUMt0/3;
|
|
|
|
Itxf = Vxf2;
|
|
Itxf_Vbiei = 0;
|
|
Itxf_Vbici = 0;
|
|
Itxf_dT = 0;
|
|
Itxf_Vxf2 = 1.0;
|
|
|
|
Ixf = (Vxf - Qdei)*model->HICUMt0/Tf; //for RC nw
|
|
Ixf_Vxf = 1.0*model->HICUMt0/Tf;
|
|
Ixf_Qdei = -Ixf_Vxf;
|
|
Ixf_Tf = -Ixf/Tf;
|
|
Ixf_Vbiei = Ixf_Tf*Tf_Vbiei + Ixf_Qdei * Qdei_Vbiei;
|
|
Ixf_Vbici = Ixf_Tf*Tf_Vbici + Ixf_Qdei * Qdei_Vbici;
|
|
Ixf_dT = Ixf_Tf*Tf_dT + Ixf_Qdei * Qdei_dT;
|
|
|
|
Qxf = model->HICUMalqf*model->HICUMt0*Vxf; //for RC nw
|
|
Qxf_Vxf = model->HICUMalqf*model->HICUMt0; //for RC nw
|
|
|
|
Qdeix = Vxf; //for RC nw
|
|
Qdeix_Vxf = 1.0;
|
|
Qdeix_Vbiei = 0;
|
|
Qdeix_Vbici = 0;
|
|
Qdeix_dT = 0;
|
|
} else {
|
|
Ixf1 = Vxf1;
|
|
Ixf1_Vxf1 = 1.0;
|
|
Ixf1_Vxf2 = 0;
|
|
// dead assign:
|
|
//Ixf1_ditf = 0;
|
|
//Ixf1_dTf = 0;
|
|
Ixf1_Vbiei = 0;
|
|
Ixf1_Vbici = 0;
|
|
Ixf1_dT = 0;
|
|
|
|
Ixf2 = Vxf2;
|
|
Ixf2_Vxf2 = 1.0;
|
|
Ixf2_Vxf1 = 0;
|
|
// dead assign:
|
|
//Ixf2_dTf = 0;
|
|
Ixf2_Vbiei = 0;
|
|
Ixf2_Vbici = 0;
|
|
Ixf2_dT = 0;
|
|
|
|
Qxf1 = 0;
|
|
Qxf1_Vxf1 = 0;
|
|
|
|
Qxf2 = 0;
|
|
Qxf2_Vxf2 = 0;
|
|
|
|
Ixf = Vxf;
|
|
Ixf_Vxf = 1.0;
|
|
// dead assign:
|
|
//Ixf_Tf = 0;
|
|
//Ixf_Qdei = 0;
|
|
Ixf_Vbiei = 0;
|
|
Ixf_Vbici = 0;
|
|
Ixf_dT = 0;
|
|
|
|
Qxf = 0;
|
|
Qxf_Vxf = 0;
|
|
|
|
}
|
|
|
|
// end of Model_evaluation
|
|
|
|
//resistors
|
|
if(model->HICUMrcxGiven && model->HICUMrcx != 0) {
|
|
Icic_Vcic = 1/here->HICUMrcx_t.rpart;
|
|
Icic_Vrth = -Vcic*here->HICUMrcx_t.dpart/here->HICUMrcx_t.rpart/here->HICUMrcx_t.rpart;
|
|
} else {
|
|
Icic_Vcic = 0.0;
|
|
Icic_Vrth = 0.0;
|
|
}
|
|
if(model->HICUMrbxGiven && model->HICUMrbx != 0) {
|
|
Ibbp_Vbbp = 1/here->HICUMrbx_t.rpart;
|
|
Ibbp_Vrth = -Vbbp*here->HICUMrbx_t.dpart/here->HICUMrbx_t.rpart/here->HICUMrbx_t.rpart;
|
|
} else {
|
|
Ibbp_Vbbp = 0.0;
|
|
Ibbp_Vrth = 0.0;
|
|
}
|
|
if(model->HICUMreGiven && model->HICUMre != 0) {
|
|
Ieie_Veie = 1/here->HICUMre_t.rpart;
|
|
Ieie_Vrth = -Veie*here->HICUMre_t.dpart /here->HICUMre_t.rpart/here->HICUMre_t.rpart;
|
|
} else {
|
|
Ieie_Veie = 0.0;
|
|
Ieie_Vrth = 0.0;
|
|
}
|
|
if(model->HICUMrsuGiven && model->HICUMrsu != 0) {
|
|
Isis_Vsis = 1/model->HICUMrsu*here->HICUMm;
|
|
} else {
|
|
Isis_Vsis = 0.0;
|
|
}
|
|
if(model->HICUMselfheat){
|
|
Irth_Vrth = (1/here->HICUMrth_t.rpart - Vrth/(here->HICUMrth_t.rpart*here->HICUMrth_t.rpart) * here->HICUMrth_t.dpart);
|
|
} else {
|
|
Irth_Vrth = 0.0;
|
|
}
|
|
|
|
Ibpei = model->HICUMtype*ibep;
|
|
Ibpei += model->HICUMtype*irep;
|
|
Ibpei_Vbpei = model->HICUMtype*ibep_Vbpei;
|
|
Ibpei_Vbpei += model->HICUMtype*irep_Vbpei;
|
|
Ibpei_Vrth = model->HICUMtype*ibep_dT;
|
|
Ibpei_Vrth += model->HICUMtype*irep_dT;
|
|
|
|
Ibiei = model->HICUMtype*ibei;
|
|
Ibiei_Vbiei = model->HICUMtype*ibei_Vbiei;
|
|
Ibiei_Vrth = model->HICUMtype*ibei_dT;
|
|
Ibiei += model->HICUMtype*irei;
|
|
Ibiei_Vbiei += model->HICUMtype*irei_Vbiei;
|
|
Ibiei_Vrth += model->HICUMtype*irei_dT;
|
|
Ibiei += model->HICUMtype*ibh_rec;
|
|
Ibiei_Vbiei += model->HICUMtype*ibh_rec_Vbiei;
|
|
Ibiei_Vrth += model->HICUMtype*ibh_rec_dT;
|
|
Ibiei_Vbici = model->HICUMtype*ibh_rec_Vbici;
|
|
|
|
if (model->HICUMtunode==1.0) {
|
|
Ibpei += -model->HICUMtype*ibet;
|
|
Ibpei_Vbpei += -model->HICUMtype*ibet_Vbpei;
|
|
Ibpei_Vrth += -model->HICUMtype*ibet_dT;
|
|
} else {
|
|
Ibiei += -model->HICUMtype*ibet;
|
|
Ibiei_Vbiei += -model->HICUMtype*ibet_Vbiei;
|
|
Ibiei_Vrth += -model->HICUMtype*ibet_dT;
|
|
}
|
|
|
|
Ibpsi = model->HICUMtype*HSI_Tsu;
|
|
Ibpsi_Vbpci = model->HICUMtype*HSI_Tsu_Vbpci;
|
|
Ibpsi_Vsici = model->HICUMtype*HSI_Tsu_Vsici;
|
|
Ibpsi_Vrth = model->HICUMtype*HSI_Tsu_dT;
|
|
|
|
Ibpci = model->HICUMtype*ijbcx;
|
|
Ibpci_Vbpci = model->HICUMtype*ijbcx_Vbpci;
|
|
Ibpci_Vrth = model->HICUMtype*ijbcx_dT;
|
|
|
|
Ibici = model->HICUMtype*(ibci - iavl);
|
|
Ibici_Vbici = model->HICUMtype*(ibci_Vbici - iavl_Vbici);
|
|
Ibici_Vbiei = model->HICUMtype*( - iavl_Vbiei);
|
|
Ibici_Vrth = model->HICUMtype*(ibci_dT - iavl_dT);
|
|
|
|
Isici = model->HICUMtype*ijsc;
|
|
Isici_Vsici = model->HICUMtype*ijsc_Vsici;
|
|
Isici_Vrth = model->HICUMtype*ijsc_Vrth;
|
|
|
|
Iciei = model->HICUMtype*(Itxf - itr);
|
|
Iciei_Vbiei = model->HICUMtype*(Itxf_Vbiei - itr_Vbiei);
|
|
Iciei_Vbici = model->HICUMtype*(Itxf_Vbici - itr_Vbici);
|
|
Iciei_Vrth = model->HICUMtype*(Itxf_dT - itr_dT);
|
|
Iciei_Vxf2 = model->HICUMtype*Itxf_Vxf2;
|
|
|
|
if (rbi > 0.0) {
|
|
Ibpbi = Vbpbi / rbi;
|
|
Ibpbi_Vbpbi = 1 / rbi;
|
|
Ibpbi_Vbiei = -Vbpbi * rbi_Vbiei / (rbi*rbi);
|
|
Ibpbi_Vbici = -Vbpbi * rbi_Vbici / (rbi*rbi);
|
|
Ibpbi_Vrth = -Vbpbi * rbi_dT / (rbi*rbi);
|
|
} else {
|
|
// fallback in case bp-bi nodes are collapsed
|
|
Ibpbi = 0.0;
|
|
Ibpbi_Vbpbi = 0.0;
|
|
Ibpbi_Vbiei = 0.0;
|
|
Ibpbi_Vbici = 0.0;
|
|
Ibpbi_Vrth = 0.0;
|
|
};
|
|
|
|
Ith_Vbiei = 0.0;
|
|
Ith_Vbici = 0.0;
|
|
Ith_Vbpbi = 0.0;
|
|
Ith_Vbpci = 0.0;
|
|
Ith_Vbpei = 0.0;
|
|
Ith_Vciei = 0.0;
|
|
Ith_Vsici = 0.0;
|
|
Ith_Vcic = 0.0;
|
|
Ith_Vbbp = 0.0;
|
|
Ith_Veie = 0.0;
|
|
Ith_Vrth = 0.0;
|
|
if(!model->HICUMselfheat) {
|
|
Ith = 0;
|
|
} else {
|
|
Ith = pterm; //Current from gnd to T
|
|
Ith_Vrth = pterm_dT;
|
|
if (model->HICUMflsh == 1) {
|
|
//it(Vbiei,Vbici)*(Vbiei-Vbici)
|
|
Ith_Vbiei += it_Vbiei*(Vbiei-Vbici) + it;
|
|
Ith_Vbici += it_Vbici*(Vbiei-Vbici) - it;
|
|
//avalanche current
|
|
Ith_Vbici += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbici - iavl;
|
|
Ith_Vbiei += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbiei;
|
|
} else if (model->HICUMflsh == 2) {
|
|
//remember:
|
|
//pterm = (Vbiei-Vbici)*it + (here->HICUMvdci_t.rpart-Vbici)*iavl + ibei*Vbiei + ibci*Vbici + ibep*Vbpei + ijbcx*Vbpci + ijsc*Vsici;
|
|
//it(Vbiei,Vbici)*(Vbiei-Vbici)
|
|
Ith_Vbiei += it_Vbiei*(Vbiei-Vbici) + it;
|
|
Ith_Vbici += it_Vbici*(Vbiei-Vbici) - it;
|
|
//Vbiei*Ibiei(Vbiei)
|
|
Ith_Vbiei += ibei + ibei_Vbiei*Vbiei;
|
|
//Vbici*Ibici(Vbici,Vbiei)
|
|
Ith_Vbici += ibci + ibci_Vbici*Vbici;
|
|
Ith_Vbici += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbici - iavl;
|
|
Ith_Vbiei += (here->HICUMvdci_t.rpart-Vbici)*iavl_Vbiei;
|
|
//Vbpei*Ibpei(Vbpei)
|
|
Ith_Vbpei += ibep + ibep_Vbpei*Vbpei;
|
|
//Vpbci*Ibpci(Vbpci)
|
|
Ith_Vbpci += Ibpci + Ibpci_Vbpci*Vbpci;
|
|
//Vsici*Isici(Vsici)
|
|
Ith_Vsici += Isici + Isici_Vsici*Vsici;
|
|
if (rbi > 0.0) {
|
|
//Vbpbi*Ibpbi(Vbpbi,Vbiei,Vbici)
|
|
Ith_Vbpbi += Ibpbi + Ibpbi_Vbpbi*Vbpbi;
|
|
Ith_Vbiei += Ibpbi_Vbiei*Vbpbi;
|
|
Ith_Vbici += Ibpbi_Vbici*Vbpbi;
|
|
}
|
|
if (here->HICUMre_t.rpart >= MIN_R) {
|
|
Ith_Veie = 2*Veie/here->HICUMre_t.rpart;
|
|
}
|
|
if (here->HICUMrcx_t.rpart >= MIN_R) {
|
|
Ith_Vcic = 2*Vcic/here->HICUMrcx_t.rpart;
|
|
}
|
|
if (here->HICUMrbx_t.rpart >= MIN_R) {
|
|
Ith_Vbbp = 2*Vbbp/here->HICUMrbx_t.rpart;
|
|
}
|
|
}
|
|
|
|
}
|
|
// ********************************************
|
|
|
|
// add gmin over parallel to all non-linear branches
|
|
Ibiei += ckt->CKTgmin*Vbiei;
|
|
Ibiei_Vbiei += ckt->CKTgmin;
|
|
Ibici += ckt->CKTgmin*Vbici;
|
|
Ibici_Vbici += ckt->CKTgmin;
|
|
Ibpei += ckt->CKTgmin*Vbpei;
|
|
Ibpei_Vbpei += ckt->CKTgmin;
|
|
Ibpci += ckt->CKTgmin*Vbpci;
|
|
Ibpci_Vbpci += ckt->CKTgmin;
|
|
Isici += ckt->CKTgmin*Vsici;
|
|
Isici_Vsici += ckt->CKTgmin;
|
|
|
|
// calculate charge derivatives for electrostatic caps
|
|
Qbepar1_Vbe = cbepar1;
|
|
Qbepar2_Vbpe = cbepar2;
|
|
Qbcpar1_Vbci = cbcpar1;
|
|
Qbcpar2_Vbpci = cbcpar2;
|
|
Qsu_Vsis = model->HICUMcsu;
|
|
Qcth_Vrth = here->HICUMcth_scaled;
|
|
if( (ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC)) ||
|
|
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ||
|
|
(ckt->CKTmode & MODEINITSMSIG)) {
|
|
|
|
// calculate charges over electrostatic caps
|
|
Qbepar1 = cbepar1*Vbe;
|
|
Qbepar2 = cbepar2*Vbpe;
|
|
Qbcpar1 = cbcpar1*Vbci;
|
|
Qbcpar2 = cbcpar2*Vbpci;
|
|
Qsu = model->HICUMcsu*Vsis;
|
|
if (model->HICUMselfheat) {
|
|
Qcth = here->HICUMcth_scaled*Vrth;
|
|
} else {
|
|
Qcth = 0;
|
|
}
|
|
|
|
// store charges and their derivatives in state vector
|
|
//Qrbi
|
|
*(ckt->CKTstate0 + here->HICUMqrbi) = Qrbi;
|
|
*(ckt->CKTstate0 + here->HICUMcqrbi) = Qrbi_Vbpbi;
|
|
//Qjei
|
|
*(ckt->CKTstate0 + here->HICUMqjei) = Qjei;
|
|
*(ckt->CKTstate0 + here->HICUMcqjei) = Qjei_Vbiei;
|
|
//Qf
|
|
*(ckt->CKTstate0 + here->HICUMqf) = Qdeix;
|
|
*(ckt->CKTstate0 + here->HICUMcqf) = Qdeix_Vbiei;
|
|
//Qr
|
|
*(ckt->CKTstate0 + here->HICUMqr) = Qr;
|
|
*(ckt->CKTstate0 + here->HICUMcqr) = Qr_Vbici;
|
|
//Qjci
|
|
*(ckt->CKTstate0 + here->HICUMqjci) = Qjci;
|
|
*(ckt->CKTstate0 + here->HICUMcqjci) = Qjci_Vbici;
|
|
//Qjep
|
|
*(ckt->CKTstate0 + here->HICUMqjep) = Qjep;
|
|
*(ckt->CKTstate0 + here->HICUMcqjep) = Qjep_Vbpei;
|
|
//Qjcx_i
|
|
*(ckt->CKTstate0 + here->HICUMqjcx0_i) = Qjcx_i;
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_i) = Qjcx_i_Vbci;
|
|
//Qjcx_ii
|
|
*(ckt->CKTstate0 + here->HICUMqjcx0_ii) = Qjcx_ii;
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) = Qjcx_ii_Vbpci;
|
|
//Qdsu
|
|
*(ckt->CKTstate0 + here->HICUMqdsu) = Qdsu;
|
|
*(ckt->CKTstate0 + here->HICUMcqdsu) = Qdsu_Vbpci;
|
|
//Qs
|
|
*(ckt->CKTstate0 + here->HICUMqjs) = Qjs;
|
|
*(ckt->CKTstate0 + here->HICUMcqjs) = Qjs_Vsici;
|
|
//Qscp
|
|
*(ckt->CKTstate0 + here->HICUMqscp) = Qscp;
|
|
*(ckt->CKTstate0 + here->HICUMcqscp) = Qscp_Vsc;
|
|
//Qbepar1
|
|
*(ckt->CKTstate0 + here->HICUMqbepar1) = Qbepar1;
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar1) = Qbepar1_Vbe;
|
|
//Qbepar2
|
|
*(ckt->CKTstate0 + here->HICUMqbepar2) = Qbepar2;
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar2) = Qbepar2_Vbpe;
|
|
//Qbcpar1
|
|
*(ckt->CKTstate0 + here->HICUMqbcpar1) = Qbcpar1;
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar1) = Qbcpar1_Vbci;
|
|
//Qbcpar2
|
|
*(ckt->CKTstate0 + here->HICUMqbcpar2) = Qbcpar2;
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar2) = Qbcpar2_Vbpci;
|
|
//Qsu
|
|
*(ckt->CKTstate0 + here->HICUMqsu) = Qsu;
|
|
*(ckt->CKTstate0 + here->HICUMcqsu) = Qsu_Vsis;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMqxf1) = Qxf1;
|
|
*(ckt->CKTstate0 + here->HICUMcqxf1) = Qxf1_Vxf1;
|
|
*(ckt->CKTstate0 + here->HICUMqxf2) = Qxf2;
|
|
*(ckt->CKTstate0 + here->HICUMcqxf2) = Qxf2_Vxf2;
|
|
*(ckt->CKTstate0 + here->HICUMqxf) = Qxf;
|
|
*(ckt->CKTstate0 + here->HICUMcqxf) = Qxf_Vxf;
|
|
if (model->HICUMselfheat) {
|
|
//Qth
|
|
*(ckt->CKTstate0 + here->HICUMqcth) = Qcth;
|
|
*(ckt->CKTstate0 + here->HICUMcqcth) = Qcth_Vrth;
|
|
}
|
|
|
|
//below is not important for load
|
|
here->HICUMcaprbi = Qrbi_Vbpbi;
|
|
here->HICUMcapdeix = Cdei;
|
|
here->HICUMcapjei = Cjei;
|
|
here->HICUMcapdci = Cdci;
|
|
here->HICUMcapjci = Cjci;
|
|
here->HICUMcapjep = Cjep;
|
|
here->HICUMcapjcx_t_i = Cjcx_i;
|
|
here->HICUMcapjcx_t_ii = Cjcx_ii;
|
|
here->HICUMcapdsu = Qdsu_Vbpci;
|
|
here->HICUMcapjs = Cjs;
|
|
here->HICUMcapscp = Cscp;
|
|
here->HICUMcapsu = model->HICUMcsu;
|
|
here->HICUMcapcth = here->HICUMcth_scaled;
|
|
|
|
//derivatives of charges due to cross coupling
|
|
here->HICUMqrbi_Vbiei = Qrbi_Vbiei;
|
|
here->HICUMqrbi_Vbici = Qrbi_Vbici;
|
|
here->HICUMqrbi_Vrth = Qrbi_Vrth;
|
|
here->HICUMqjei_Vrth = Qjei_dT;
|
|
here->HICUMqjep_Vrth = Qjep_dT;
|
|
here->HICUMqf_Vbici = Qdeix_Vbici;
|
|
here->HICUMqf_Vxf = Qdeix_Vxf;
|
|
here->HICUMqf_Vrth = Qdeix_dT;
|
|
here->HICUMqr_Vbiei = Qr_Vbiei;
|
|
here->HICUMqr_Vrth = Qr_dT;
|
|
here->HICUMqjci_Vrth = Qjci_dT;
|
|
here->HICUMqjcx0_i_Vrth = Qjcx_i_dT;
|
|
here->HICUMqjcx0_ii_Vrth = Qjcx_ii_dT;
|
|
here->HICUMqdsu_Vrth = Qdsu_dT;
|
|
here->HICUMqdsu_Vsici = Qdsu_Vsici;
|
|
here->HICUMqjs_Vrth = Qjs_dT;
|
|
here->HICUMqscp_Vrth = Qscp_dT;
|
|
here->HICUMicth_dT = Icth_Vrth;
|
|
|
|
/*
|
|
* store small-signal parameters
|
|
*/
|
|
if ( (!(ckt->CKTmode & MODETRANOP))||
|
|
(!(ckt->CKTmode & MODEUIC)) ) {
|
|
if(ckt->CKTmode & MODEINITSMSIG) {
|
|
|
|
*(ckt->CKTstate0 + here->HICUMcqrbi) = Qrbi_Vbpbi;
|
|
*(ckt->CKTstate0 + here->HICUMcqf) = Qdeix_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMcqr) = Qr_Vbici;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMcqjei) = Cjei;
|
|
*(ckt->CKTstate0 + here->HICUMcqjci) = Cjci;
|
|
*(ckt->CKTstate0 + here->HICUMcqjep) = Qjep_Vbpei;
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_i) = Qjcx_i_Vbci;
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) = Qjcx_ii_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMcqdsu) = Qdsu_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMcqjs) = Qjs_Vsici;
|
|
*(ckt->CKTstate0 + here->HICUMcqscp) = Qscp_Vsc;
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar1) = Qbepar1_Vbe;
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar2) = Qbepar2_Vbpe;
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar1) = Qbcpar1_Vbci;
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar2) = Qbcpar2_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMcqsu) = Qsu_Vsis;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMcqxf1) = Qxf1_Vxf1;
|
|
*(ckt->CKTstate0 + here->HICUMcqxf2) = Qxf2_Vxf2;
|
|
*(ckt->CKTstate0 + here->HICUMcqxf) = Qxf_Vxf;
|
|
if (model->HICUMselfheat)
|
|
*(ckt->CKTstate0 + here->HICUMcqcth) = here->HICUMcth_scaled;
|
|
continue; /* go to 1000 */
|
|
}
|
|
//transient analysis
|
|
if(ckt->CKTmode & MODEINITTRAN) {
|
|
*(ckt->CKTstate1 + here->HICUMqrbi) =
|
|
*(ckt->CKTstate0 + here->HICUMqrbi) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjei) =
|
|
*(ckt->CKTstate0 + here->HICUMqjei) ;
|
|
*(ckt->CKTstate1 + here->HICUMqf) =
|
|
*(ckt->CKTstate0 + here->HICUMqf) ;
|
|
*(ckt->CKTstate1 + here->HICUMqr) =
|
|
*(ckt->CKTstate0 + here->HICUMqr) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjci) =
|
|
*(ckt->CKTstate0 + here->HICUMqjci) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjep) =
|
|
*(ckt->CKTstate0 + here->HICUMqjep) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjcx0_i) =
|
|
*(ckt->CKTstate0 + here->HICUMqjcx0_i) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjcx0_ii) =
|
|
*(ckt->CKTstate0 + here->HICUMqjcx0_ii) ;
|
|
*(ckt->CKTstate1 + here->HICUMqdsu) =
|
|
*(ckt->CKTstate0 + here->HICUMqdsu) ;
|
|
*(ckt->CKTstate1 + here->HICUMqjs) =
|
|
*(ckt->CKTstate0 + here->HICUMqjs) ;
|
|
*(ckt->CKTstate1 + here->HICUMqscp) =
|
|
*(ckt->CKTstate0 + here->HICUMqscp) ;
|
|
*(ckt->CKTstate1 + here->HICUMqbepar1) =
|
|
*(ckt->CKTstate0 + here->HICUMqbepar1) ;
|
|
*(ckt->CKTstate1 + here->HICUMqbepar2) =
|
|
*(ckt->CKTstate0 + here->HICUMqbepar2) ;
|
|
*(ckt->CKTstate1 + here->HICUMqbcpar1) =
|
|
*(ckt->CKTstate0 + here->HICUMqbcpar1) ;
|
|
*(ckt->CKTstate1 + here->HICUMqbcpar2) =
|
|
*(ckt->CKTstate0 + here->HICUMqbcpar2) ;
|
|
*(ckt->CKTstate1 + here->HICUMqsu) =
|
|
*(ckt->CKTstate0 + here->HICUMqsu) ;
|
|
*(ckt->CKTstate1 + here->HICUMqxf1) =
|
|
*(ckt->CKTstate0 + here->HICUMqxf1) ;
|
|
*(ckt->CKTstate1 + here->HICUMqxf2) =
|
|
*(ckt->CKTstate0 + here->HICUMqxf2) ;
|
|
*(ckt->CKTstate1 + here->HICUMqxf) =
|
|
*(ckt->CKTstate0 + here->HICUMqxf) ;
|
|
|
|
if (model->HICUMselfheat)
|
|
*(ckt->CKTstate1 + here->HICUMqcth) =
|
|
*(ckt->CKTstate0 + here->HICUMqcth) ;
|
|
}
|
|
|
|
//Integrate all charges and add the displacement current to the branch currents
|
|
//Qrbi
|
|
error = NIintegrate(ckt,&geq,&ceq,Qrbi_Vbpbi,here->HICUMqrbi);
|
|
if(error) return(error);
|
|
Ibpbi_Vbpbi += geq;
|
|
Ibpbi += *(ckt->CKTstate0 + here->HICUMcqrbi);
|
|
//Qjei
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjei,here->HICUMqjei);
|
|
if(error) return(error);
|
|
Ibiei_Vbiei += geq;
|
|
Ibiei += *(ckt->CKTstate0 + here->HICUMcqjei);
|
|
//Qdeix
|
|
if (!model->HICUMnqs) {
|
|
error = NIintegrate(ckt,&geq,&ceq,Qdeix_Vbiei,here->HICUMqf);
|
|
if(error) return(error);
|
|
Ibiei_Vbiei += geq;
|
|
Ibiei_Vxf = 0;
|
|
Ibiei += *(ckt->CKTstate0 + here->HICUMcqf);
|
|
} else { //Qdeix is now a function of Vxf(t)
|
|
error = NIintegrate(ckt,&geq,&ceq,Qdeix_Vxf,here->HICUMqf);
|
|
if(error) return(error);
|
|
Ibiei_Vxf = geq;
|
|
Ibiei += *(ckt->CKTstate0 + here->HICUMcqf);
|
|
}
|
|
//Qr
|
|
error = NIintegrate(ckt,&geq,&ceq,Qr_Vbici,here->HICUMqr);
|
|
if(error) return(error);
|
|
Ibici_Vbici += geq;
|
|
Ibici += *(ckt->CKTstate0 + here->HICUMcqr);
|
|
//Qjci
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjci,here->HICUMqjci);
|
|
if(error) return(error);
|
|
Ibici_Vbici += geq;
|
|
Ibici += *(ckt->CKTstate0 + here->HICUMcqjci);
|
|
//Qjep
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjep,here->HICUMqjep);
|
|
if(error) return(error);
|
|
Ibpei_Vbpei += geq;
|
|
Ibpei += *(ckt->CKTstate0 + here->HICUMcqjep);
|
|
//Qjcx_i
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjcx_i,here->HICUMqjcx0_i);
|
|
if(error) return(error);
|
|
Ibci_Vbci = geq;
|
|
Ibci = *(ckt->CKTstate0 + here->HICUMcqcx0_t_i);
|
|
//Qjcx_ii
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjcx_ii,here->HICUMqjcx0_ii);
|
|
if(error) return(error);
|
|
Ibpci_Vbpci += geq;
|
|
Ibpci += *(ckt->CKTstate0 + here->HICUMcqcx0_t_ii);
|
|
//Qdsu
|
|
error = NIintegrate(ckt,&geq,&ceq,Qdsu_Vbpci,here->HICUMqdsu);
|
|
if(error) return(error);
|
|
Ibpci_Vbpci += geq;
|
|
Ibpci += *(ckt->CKTstate0 + here->HICUMcqdsu);
|
|
//Qjs
|
|
error = NIintegrate(ckt,&geq,&ceq,Cjs,here->HICUMqjs);
|
|
if(error) return(error);
|
|
Isici_Vsici += geq;
|
|
Isici += *(ckt->CKTstate0 + here->HICUMcqjs);
|
|
//Qscp
|
|
error = NIintegrate(ckt,&geq,&ceq,Cscp,here->HICUMqscp);
|
|
if(error) return(error);
|
|
Isc_Vsc = geq;
|
|
Isc = *(ckt->CKTstate0 + here->HICUMcqscp);
|
|
if (model->HICUMnqs) {
|
|
//Qxf1
|
|
error = NIintegrate(ckt,&geq,&ceq,Qxf1_Vxf1,here->HICUMqxf1);
|
|
if(error) return(error);
|
|
Ixf1_Vxf1 += geq;
|
|
Ixf1 += *(ckt->CKTstate0 + here->HICUMcqxf1);
|
|
//Qxf2
|
|
error = NIintegrate(ckt,&geq,&ceq,Qxf2_Vxf2,here->HICUMqxf2);
|
|
if(error) return(error);
|
|
Ixf2_Vxf2 += geq;
|
|
Ixf2 += *(ckt->CKTstate0 + here->HICUMcqxf2);
|
|
//Qxf
|
|
error = NIintegrate(ckt,&geq,&ceq,Qxf_Vxf,here->HICUMqxf);
|
|
if(error) return(error);
|
|
Ixf_Vxf += geq;
|
|
Ixf += *(ckt->CKTstate0 + here->HICUMcqxf);
|
|
}
|
|
|
|
if (model->HICUMselfheat)
|
|
{
|
|
//Qth
|
|
error = NIintegrate(ckt,&geq,&ceq,here->HICUMcth_scaled,here->HICUMqcth);
|
|
if(error) return(error);
|
|
Icth_Vrth = geq;
|
|
Icth = *(ckt->CKTstate0 + here->HICUMcqcth);
|
|
}
|
|
|
|
if(ckt->CKTmode & MODEINITTRAN) {
|
|
//copy from state1 to state0
|
|
*(ckt->CKTstate1 + here->HICUMcqrbi) =
|
|
*(ckt->CKTstate0 + here->HICUMcqrbi) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqjei) =
|
|
*(ckt->CKTstate0 + here->HICUMcqjei) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqf) =
|
|
*(ckt->CKTstate0 + here->HICUMcqf) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqr) =
|
|
*(ckt->CKTstate0 + here->HICUMcqr) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqjci) =
|
|
*(ckt->CKTstate0 + here->HICUMcqjci) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqjep) =
|
|
*(ckt->CKTstate0 + here->HICUMcqjep) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqcx0_t_i) =
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_i) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqcx0_t_ii) =
|
|
*(ckt->CKTstate0 + here->HICUMcqcx0_t_ii) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqdsu) =
|
|
*(ckt->CKTstate0 + here->HICUMcqdsu) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqjs) =
|
|
*(ckt->CKTstate0 + here->HICUMcqjs) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqscp) =
|
|
*(ckt->CKTstate0 + here->HICUMcqscp) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqxf1) =
|
|
*(ckt->CKTstate0 + here->HICUMcqxf1) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqxf2) =
|
|
*(ckt->CKTstate0 + here->HICUMcqxf2) ;
|
|
*(ckt->CKTstate1 + here->HICUMcqxf) =
|
|
*(ckt->CKTstate0 + here->HICUMcqxf) ;
|
|
if (model->HICUMselfheat)
|
|
*(ckt->CKTstate1 + here->HICUMcqcth) =
|
|
*(ckt->CKTstate0 + here->HICUMcqcth) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* check convergence
|
|
*/
|
|
if ( (!(ckt->CKTmode & MODEINITFIX))||(!(here->HICUMoff))) {
|
|
if (icheck == 1) {
|
|
ckt->CKTnoncon++;
|
|
ckt->CKTtroubleElt = (GENinstance *) here;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* charge storage for electrostatic caps
|
|
*/
|
|
if(ckt->CKTmode & (MODETRAN | MODEAC)) {
|
|
// Ibe += ddt(cbepar1*Vbe);
|
|
error = NIintegrate(ckt,&gqbepar1,&cqbepar1,cbepar1,here->HICUMqbepar1);
|
|
if(error) return(error);
|
|
// Ibpe += ddt(cbepar2*Vbpe);
|
|
error = NIintegrate(ckt,&gqbepar2,&cqbepar2,cbepar2,here->HICUMqbepar2);
|
|
if(error) return(error);
|
|
// Ibci += ddt(cbcpar1*Vbci);
|
|
error = NIintegrate(ckt,&gqbcpar1,&cqbcpar1,cbcpar1,here->HICUMqbcpar1);
|
|
if(error) return(error);
|
|
// Ibpci += ddt(cbcpar2*Vbpci);
|
|
error = NIintegrate(ckt,&gqbcpar2,&cqbcpar2,cbcpar2,here->HICUMqbcpar2);
|
|
if(error) return(error);
|
|
// Isis += ddt(model->HICUMcsu*Vsis);
|
|
error = NIintegrate(ckt,&gqsu,&cqsu,model->HICUMcsu,here->HICUMqsu);
|
|
if(error) return(error);
|
|
if(ckt->CKTmode & MODEINITTRAN) {
|
|
*(ckt->CKTstate1 + here->HICUMcqbepar1) =
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar1);
|
|
*(ckt->CKTstate1 + here->HICUMcqbepar2) =
|
|
*(ckt->CKTstate0 + here->HICUMcqbepar2);
|
|
*(ckt->CKTstate1 + here->HICUMcqbcpar1) =
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar1);
|
|
*(ckt->CKTstate1 + here->HICUMcqbcpar2) =
|
|
*(ckt->CKTstate0 + here->HICUMcqbcpar2);
|
|
*(ckt->CKTstate1 + here->HICUMcqsu) =
|
|
*(ckt->CKTstate0 + here->HICUMcqsu);
|
|
}
|
|
}
|
|
|
|
// Write branch currents and voltages to state vector
|
|
*(ckt->CKTstate0 + here->HICUMvbiei) = Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMvbici) = Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMvbpei) = Vbpei;
|
|
*(ckt->CKTstate0 + here->HICUMvbpbi) = Vbpbi;
|
|
*(ckt->CKTstate0 + here->HICUMvbpci) = Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMvsici) = Vsici;
|
|
*(ckt->CKTstate0 + here->HICUMvcic) = Vcic;
|
|
*(ckt->CKTstate0 + here->HICUMvbbp) = Vbbp;
|
|
*(ckt->CKTstate0 + here->HICUMveie) = Veie;
|
|
*(ckt->CKTstate0 + here->HICUMvxf1) = Vxf1;
|
|
*(ckt->CKTstate0 + here->HICUMvxf2) = Vxf2;
|
|
*(ckt->CKTstate0 + here->HICUMvxf) = Vxf;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibiei) = Ibiei;
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vbiei) = Ibiei_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vxf) = Ibiei_Vxf;
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vbici) = Ibiei_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMibiei_Vrth) = Ibiei_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibpei) = Ibpei;
|
|
*(ckt->CKTstate0 + here->HICUMibpei_Vbpei) = Ibpei_Vbpei;
|
|
*(ckt->CKTstate0 + here->HICUMibpei_Vrth) = Ibpei_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMiciei) = Iciei;
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vbiei) = Iciei_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vbici) = Iciei_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vrth) = Iciei_Vrth;
|
|
*(ckt->CKTstate0 + here->HICUMiciei_Vxf2) = Iciei_Vxf2;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibici) = Ibici;
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vbici) = Ibici_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vbiei) = Ibici_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMibici_Vrth) = Ibici_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibpbi) = Ibpbi;
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbpbi) = Ibpbi_Vbpbi;
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbiei) = Ibpbi_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vbici) = Ibpbi_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMibpbi_Vrth) = Ibpbi_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibpci) = Ibpci;
|
|
*(ckt->CKTstate0 + here->HICUMibpci_Vbpci) = Ibpci_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMibpci_Vrth) = Ibpci_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMisici) = Isici;
|
|
*(ckt->CKTstate0 + here->HICUMisici_Vsici) = Isici_Vsici;
|
|
*(ckt->CKTstate0 + here->HICUMisici_Vrth) = Isici_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMibpsi) = Ibpsi;
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vbpci) = Ibpsi_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vsici) = Ibpsi_Vsici;
|
|
*(ckt->CKTstate0 + here->HICUMibpsi_Vrth) = Ibpsi_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMisis_Vsis) = Isis_Vsis;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMieie) = Ieie;
|
|
*(ckt->CKTstate0 + here->HICUMieie_Vrth) = Ieie_Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMcqcth) = Icth;
|
|
*(ckt->CKTstate0 + here->HICUMvrth) = Vrth;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMgqbepar1) = gqbepar1;
|
|
*(ckt->CKTstate0 + here->HICUMgqbepar2) = gqbepar2;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMgqbcpar1) = gqbcpar1;
|
|
*(ckt->CKTstate0 + here->HICUMgqbcpar2) = gqbcpar2;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMgqsu) = gqsu;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMith) = Ith;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vrth) = Ith_Vrth;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbiei) = Ith_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbici) = Ith_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpbi) = Ith_Vbpbi;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpci) = Ith_Vbpci;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbpei) = Ith_Vbpei;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vciei) = Ith_Vciei;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vsici) = Ith_Vsici;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vcic) = Ith_Vcic;
|
|
*(ckt->CKTstate0 + here->HICUMith_Vbbp) = Ith_Vbbp;
|
|
*(ckt->CKTstate0 + here->HICUMith_Veie) = Ith_Veie;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMixf) = Ixf;
|
|
*(ckt->CKTstate0 + here->HICUMixf_Vbiei) = Ixf_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMixf_Vbici) = Ixf_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMixf_Vxf) = Ixf_Vxf;
|
|
*(ckt->CKTstate0 + here->HICUMixf_Vrth) = Ixf_dT;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMixf1) = Ixf1;
|
|
*(ckt->CKTstate0 + here->HICUMixf1_Vbiei) = Ixf1_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMixf1_Vbici) = Ixf1_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMixf1_Vxf2) = Ixf1_Vxf2;
|
|
*(ckt->CKTstate0 + here->HICUMixf1_Vxf1) = Ixf1_Vxf1;
|
|
*(ckt->CKTstate0 + here->HICUMixf1_Vrth) = Ixf1_dT;
|
|
|
|
*(ckt->CKTstate0 + here->HICUMixf2) = Ixf2;
|
|
*(ckt->CKTstate0 + here->HICUMixf2_Vbiei) = Ixf2_Vbiei;
|
|
*(ckt->CKTstate0 + here->HICUMixf2_Vbici) = Ixf2_Vbici;
|
|
*(ckt->CKTstate0 + here->HICUMixf2_Vxf1) = Ixf2_Vxf1;
|
|
*(ckt->CKTstate0 + here->HICUMixf2_Vxf2) = Ixf2_Vxf2;
|
|
*(ckt->CKTstate0 + here->HICUMixf2_Vrth) = Ixf2_dT;
|
|
*(ckt->CKTstate0 + here->HICUMit) = it;
|
|
|
|
load:
|
|
// #############################################################
|
|
// ############### STAMPS NO SH ##############################
|
|
// #############################################################
|
|
|
|
// Branch: sc, Stamp element: Cscp
|
|
rhs_current = model->HICUMtype * (Isc - Isc_Vsc*Vsc);
|
|
*(ckt->CKTrhs + here->HICUMsubsNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollNode) += rhs_current;
|
|
// with respect to Vsc
|
|
*(here->HICUMsubsSubsPtr) += Isc_Vsc;
|
|
*(here->HICUMcollCollPtr) += Isc_Vsc;
|
|
*(here->HICUMsubsCollPtr) += -Isc_Vsc;
|
|
*(here->HICUMcollSubsPtr) += -Isc_Vsc;
|
|
|
|
// Branch: bci, Stamp element: Qbcx
|
|
rhs_current = model->HICUMtype * (Ibci - Ibci_Vbci*Vbci);
|
|
*(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
//with respect to Vbci
|
|
*(here->HICUMbaseBasePtr) += Ibci_Vbci;
|
|
*(here->HICUMcollCICollCIPtr) += Ibci_Vbci;
|
|
*(here->HICUMbaseCollCIPtr) += -Ibci_Vbci;
|
|
*(here->HICUMcollCIBasePtr) += -Ibci_Vbci;
|
|
|
|
// Branch: be, Stamp element: Cbepar1
|
|
rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbepar1) - Vbe * gqbepar1);
|
|
*(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitNode) += rhs_current;
|
|
// with respect to Vbe
|
|
*(here->HICUMbaseBasePtr) += gqbepar1;
|
|
*(here->HICUMemitEmitPtr) += gqbepar1;
|
|
*(here->HICUMbaseEmitPtr) += -gqbepar1;
|
|
*(here->HICUMemitBasePtr) += -gqbepar1;
|
|
|
|
// Branch: bpe, Stamp element: Cbepar2
|
|
rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbepar2) - Vbpe * gqbepar2);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitNode) += rhs_current;
|
|
// with respect to Vbpe
|
|
*(here->HICUMbaseBPBaseBPPtr) += gqbepar2;
|
|
*(here->HICUMemitEmitPtr) += gqbepar2;
|
|
*(here->HICUMbaseBPEmitPtr) += -gqbepar2;
|
|
*(here->HICUMemitBaseBPPtr) += -gqbepar2;
|
|
|
|
// Branch: bci, Stamp element: Cbcpar1
|
|
rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbcpar1) - Vbci * gqbcpar1);
|
|
*(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Vbci
|
|
*(here->HICUMbaseBasePtr) += gqbcpar1;
|
|
*(here->HICUMcollCICollCIPtr) += gqbcpar1;
|
|
*(here->HICUMbaseCollCIPtr) += -gqbcpar1;
|
|
*(here->HICUMcollCIBasePtr) += -gqbcpar1;
|
|
|
|
// Branch: bpci, Stamp element: Cbcpar2
|
|
rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqbcpar2) - Vbpci * gqbcpar2);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Vbpci
|
|
*(here->HICUMbaseBPBaseBPPtr) += gqbcpar2;
|
|
*(here->HICUMcollCICollCIPtr) += gqbcpar2;
|
|
*(here->HICUMbaseBPCollCIPtr) += -gqbcpar2;
|
|
*(here->HICUMcollCIBaseBPPtr) += -gqbcpar2;
|
|
|
|
// Branch: ssi, Stamp element: Csu //Markus: I think rhs sign is wrong here
|
|
rhs_current = model->HICUMtype * (*(ckt->CKTstate0 + here->HICUMcqsu) - Vsis * gqsu);
|
|
*(ckt->CKTrhs + here->HICUMsubsNode) += +rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current;
|
|
// with respect to Vsis
|
|
*(here->HICUMsubsSubsPtr) += gqsu;
|
|
*(here->HICUMsubsSISubsSIPtr) += gqsu;
|
|
*(here->HICUMsubsSubsSIPtr) += -gqsu;
|
|
*(here->HICUMsubsSISubsPtr) += -gqsu;
|
|
|
|
// Branch: biei, Stamp element: Ibiei = Ibei + Irei ( was Ijbei )
|
|
rhs_current = model->HICUMtype * (Ibiei - Ibiei_Vbiei*Vbiei - Ibiei_Vxf*Vxf - Ibiei_Vbici*Vbici);
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Vbiei
|
|
*(here->HICUMbaseBIBaseBIPtr) += Ibiei_Vbiei;
|
|
*(here->HICUMemitEIEmitEIPtr) += Ibiei_Vbiei;
|
|
*(here->HICUMbaseBIEmitEIPtr) += -Ibiei_Vbiei;
|
|
*(here->HICUMemitEIBaseBIPtr) += -Ibiei_Vbiei;
|
|
// with respect to Vbici
|
|
*(here->HICUMbaseBIBaseBIPtr) += Ibiei_Vbici;
|
|
*(here->HICUMemitEICollCIPtr) += Ibiei_Vbici;
|
|
*(here->HICUMbaseBICollCIPtr) += -Ibiei_Vbici;
|
|
*(here->HICUMemitEIBaseBIPtr) += -Ibiei_Vbici;
|
|
if (model->HICUMnqs) {
|
|
*(here->HICUMbaseBIXfPtr) += Ibiei_Vxf;
|
|
*(here->HICUMemitEIXfPtr) += -Ibiei_Vxf;
|
|
}
|
|
|
|
// Branch: bpei, Stamp element: Ibpei = Ibep + Irep ( was Ijbep )
|
|
rhs_current = model->HICUMtype * (Ibpei - Ibpei_Vbpei*Vbpei);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Vbpei
|
|
*(here->HICUMbaseBPBaseBPPtr) += Ibpei_Vbpei;
|
|
*(here->HICUMemitEIEmitEIPtr) += Ibpei_Vbpei;
|
|
*(here->HICUMbaseBPEmitEIPtr) += -Ibpei_Vbpei;
|
|
*(here->HICUMemitEIBaseBPPtr) += -Ibpei_Vbpei;
|
|
|
|
// Branch: bici, Stamp element: Ibici ( was Ijbci ) f_bi=+ f_ci=-
|
|
rhs_current = model->HICUMtype * (Ibici - Ibici_Vbici*Vbici - Ibici_Vbiei*Vbiei);
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Vbici
|
|
*(here->HICUMbaseBIBaseBIPtr) += Ibici_Vbici;
|
|
*(here->HICUMcollCICollCIPtr) += Ibici_Vbici;
|
|
*(here->HICUMcollCIBaseBIPtr) += -Ibici_Vbici;
|
|
*(here->HICUMbaseBICollCIPtr) += -Ibici_Vbici;
|
|
// with respect to Vbiei
|
|
*(here->HICUMbaseBIBaseBIPtr) += Ibici_Vbiei;
|
|
*(here->HICUMcollCIEmitEIPtr) += Ibici_Vbiei;
|
|
*(here->HICUMcollCIBaseBIPtr) += -Ibici_Vbiei;
|
|
*(here->HICUMbaseBIEmitEIPtr) += -Ibici_Vbiei;
|
|
|
|
// Branch: ciei, Stamp element: It
|
|
rhs_current = model->HICUMtype * (Iciei - Iciei_Vbiei*Vbiei - Iciei_Vbici*Vbici- Iciei_Vxf2*Vxf2);
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Vbiei f_CI = + f_EI = -
|
|
*(here->HICUMcollCIBaseBIPtr) += Iciei_Vbiei;
|
|
*(here->HICUMemitEIEmitEIPtr) += Iciei_Vbiei;
|
|
*(here->HICUMcollCIEmitEIPtr) += -Iciei_Vbiei;
|
|
*(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbiei;
|
|
// with respect to Vbici
|
|
*(here->HICUMcollCIBaseBIPtr) += Iciei_Vbici;
|
|
*(here->HICUMemitEICollCIPtr) += Iciei_Vbici;
|
|
*(here->HICUMcollCICollCIPtr) += -Iciei_Vbici;
|
|
*(here->HICUMemitEIBaseBIPtr) += -Iciei_Vbici;
|
|
if (model->HICUMnqs) {
|
|
// with respect to Vxf2
|
|
*(here->HICUMcollCIXf2Ptr) += Iciei_Vxf2;
|
|
*(here->HICUMemitEIXf2Ptr) += -Iciei_Vxf2;
|
|
}
|
|
|
|
// Branch: bpci, Stamp element: Ibpci ( was Ijbcx )
|
|
rhs_current = model->HICUMtype * (Ibpci - Ibpci_Vbpci*Vbpci);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Vbpci
|
|
*(here->HICUMbaseBPBaseBPPtr) += Ibpci_Vbpci;
|
|
*(here->HICUMcollCICollCIPtr) += Ibpci_Vbpci;
|
|
*(here->HICUMbaseBPCollCIPtr) += -Ibpci_Vbpci;
|
|
*(here->HICUMcollCIBaseBPPtr) += -Ibpci_Vbpci;
|
|
|
|
// Branch: cic, Stamp element: Rcx
|
|
// with respect to Vcic
|
|
*(here->HICUMcollCollPtr) += Icic_Vcic;
|
|
*(here->HICUMcollCICollCIPtr) += Icic_Vcic;
|
|
*(here->HICUMcollCICollPtr) += -Icic_Vcic;
|
|
*(here->HICUMcollCollCIPtr) += -Icic_Vcic;
|
|
|
|
// Branch: bbp, Stamp element: Rbx
|
|
// with respect to Vbbp
|
|
*(here->HICUMbaseBasePtr) += Ibbp_Vbbp;
|
|
*(here->HICUMbaseBPBaseBPPtr) += Ibbp_Vbbp;
|
|
*(here->HICUMbaseBPBasePtr) += -Ibbp_Vbbp;
|
|
*(here->HICUMbaseBaseBPPtr) += -Ibbp_Vbbp;
|
|
|
|
// Branch: eie, Stamp element: Re
|
|
// with respect to Veie
|
|
*(here->HICUMemitEmitPtr) += Ieie_Veie;
|
|
*(here->HICUMemitEIEmitEIPtr) += Ieie_Veie;
|
|
*(here->HICUMemitEIEmitPtr) += -Ieie_Veie;
|
|
*(here->HICUMemitEmitEIPtr) += -Ieie_Veie;
|
|
|
|
if (rbi > 0.0) {
|
|
// Branch: bpbi, Stamp element: Rbi, Crbi
|
|
rhs_current = model->HICUMtype * (Ibpbi - Ibpbi_Vbpbi*Vbpbi - Ibpbi_Vbiei*Vbiei - Ibpbi_Vbici*Vbici);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += rhs_current;
|
|
//f_Bp = + f_Bi = -
|
|
// with respect to Vbpbi
|
|
*(here->HICUMbaseBPBaseBPPtr) += Ibpbi_Vbpbi;
|
|
*(here->HICUMbaseBIBaseBIPtr) += Ibpbi_Vbpbi;
|
|
*(here->HICUMbaseBPBaseBIPtr) += -Ibpbi_Vbpbi;
|
|
*(here->HICUMbaseBIBaseBPPtr) += -Ibpbi_Vbpbi;
|
|
// with respect to Vbiei
|
|
*(here->HICUMbaseBPBaseBIPtr) += Ibpbi_Vbiei;
|
|
*(here->HICUMbaseBIEmitEIPtr) += Ibpbi_Vbiei;
|
|
*(here->HICUMbaseBPEmitEIPtr) += -Ibpbi_Vbiei;
|
|
*(here->HICUMbaseBIBaseBIPtr) += -Ibpbi_Vbiei;
|
|
// with respect to Vbici
|
|
*(here->HICUMbaseBPBaseBIPtr) += Ibpbi_Vbici;
|
|
*(here->HICUMbaseBICollCIPtr) += Ibpbi_Vbici;
|
|
*(here->HICUMbaseBPCollCIPtr) += -Ibpbi_Vbici;
|
|
*(here->HICUMbaseBIBaseBIPtr) += -Ibpbi_Vbici;
|
|
}
|
|
|
|
// Branch: sici, Stamp element: Ijsc
|
|
rhs_current = model->HICUMtype * (Isici - Isici_Vsici*Vsici);
|
|
*(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Vsici
|
|
*(here->HICUMsubsSISubsSIPtr) += Isici_Vsici;
|
|
*(here->HICUMcollCICollCIPtr) += Isici_Vsici;
|
|
*(here->HICUMsubsSICollCIPtr) += -Isici_Vsici;
|
|
*(here->HICUMcollCISubsSIPtr) += -Isici_Vsici;
|
|
|
|
// Branch: bpsi, Stamp element: Its
|
|
rhs_current = model->HICUMtype * (Ibpsi - Ibpsi_Vbpci*Vbpci - Ibpsi_Vsici*Vsici);
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMsubsSINode) += rhs_current;
|
|
// f_Bp = + f_Si = -
|
|
// with respect to Vsici
|
|
*(here->HICUMbaseBPSubsSIPtr) += Ibpsi_Vsici;
|
|
*(here->HICUMsubsSICollCIPtr) += Ibpsi_Vsici;
|
|
*(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vsici;
|
|
*(here->HICUMsubsSISubsSIPtr) += -Ibpsi_Vsici;
|
|
// with respect to Vbpci
|
|
*(here->HICUMbaseBPBaseBPPtr) += Ibpsi_Vbpci;
|
|
*(here->HICUMsubsSICollCIPtr) += Ibpsi_Vbpci;
|
|
*(here->HICUMbaseBPCollCIPtr) += -Ibpsi_Vbpci;
|
|
*(here->HICUMsubsSIBaseBPPtr) += -Ibpsi_Vbpci;
|
|
|
|
// Branch: sis, Stamp element: Rsu
|
|
// with respect to Vsis
|
|
*(here->HICUMsubsSubsPtr) += Isis_Vsis;
|
|
*(here->HICUMsubsSISubsSIPtr) += Isis_Vsis;
|
|
*(here->HICUMsubsSISubsPtr) += -Isis_Vsis;
|
|
*(here->HICUMsubsSubsSIPtr) += -Isis_Vsis;
|
|
|
|
if (model->HICUMnqs) {
|
|
// Branch: xf1-ground, Stamp element: Ixf1 f_xf1=+
|
|
rhs_current = Ixf1 - Ixf1_Vbici*Vbici - Ixf1_Vbiei*Vbiei -Ixf1_Vxf1*Vxf1 - Ixf1_Vxf2*Vxf2;
|
|
*(ckt->CKTrhs + here->HICUMxf1Node) += -rhs_current; // rhs_current; // into xf1 node
|
|
*(here->HICUMxf1BaseBIPtr) += +Ixf1_Vbiei;
|
|
*(here->HICUMxf1EmitEIPtr) += -Ixf1_Vbiei;
|
|
*(here->HICUMxf1BaseBIPtr) += +Ixf1_Vbici;
|
|
*(here->HICUMxf1CollCIPtr) += -Ixf1_Vbici;
|
|
*(here->HICUMxf1Xf2Ptr) += +Ixf1_Vxf2;
|
|
*(here->HICUMxf1Xf1Ptr) += +Ixf1_Vxf1;
|
|
|
|
// Branch: xf2-ground, Stamp element: Ixf2 f_xf2=+
|
|
rhs_current = Ixf2 - Ixf2_Vbici*Vbici - Ixf2_Vbiei*Vbiei - Ixf2_Vxf1*Vxf1 - Ixf2_Vxf2*Vxf2;
|
|
*(ckt->CKTrhs + here->HICUMxf2Node) += -rhs_current; // rhs_current; // into xf2 node
|
|
*(here->HICUMxf2BaseBIPtr) += +Ixf2_Vbiei;
|
|
*(here->HICUMxf2EmitEIPtr) += -Ixf2_Vbiei;
|
|
*(here->HICUMxf2BaseBIPtr) += +Ixf2_Vbici;
|
|
*(here->HICUMxf2CollCIPtr) += -Ixf2_Vbici;
|
|
*(here->HICUMxf2Xf2Ptr) += +Ixf2_Vxf2;
|
|
*(here->HICUMxf2Xf1Ptr) += +Ixf2_Vxf1;
|
|
|
|
// Branch: xf-ground, Stamp element: Ixf f_xf=+
|
|
rhs_current = Ixf - Ixf_Vbici*Vbici - Ixf_Vbiei*Vbiei - Ixf_Vxf*Vxf;
|
|
*(ckt->CKTrhs + here->HICUMxfNode) += -rhs_current; // rhs_current; // into xf node
|
|
*(here->HICUMxfBaseBIPtr) += +Ixf_Vbiei;
|
|
*(here->HICUMxfEmitEIPtr) += -Ixf_Vbiei;
|
|
*(here->HICUMxfBaseBIPtr) += +Ixf_Vbici;
|
|
*(here->HICUMxfCollCIPtr) += -Ixf_Vbici;
|
|
*(here->HICUMxfXfPtr) += +Ixf_Vxf;
|
|
}
|
|
|
|
|
|
// #############################################################
|
|
// ############### FINISH STAMPS NO SH #########################
|
|
// #############################################################
|
|
|
|
if (model->HICUMselfheat) {
|
|
|
|
// #############################################################
|
|
// ############### STAMP WITH SH ADDITIONS #####################
|
|
// #############################################################
|
|
|
|
// Stamp element: Ibiei f_Bi = + f_Ei = -
|
|
rhs_current = -Ibiei_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseBItempPtr) += Ibiei_Vrth;
|
|
*(here->HICUMemitEItempPtr) += -Ibiei_Vrth;
|
|
|
|
// Stamp element: Ibpei f_Bp = + f_Ei = -
|
|
rhs_current = -Ibpei_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseBPtempPtr) += Ibpei_Vrth;
|
|
*(here->HICUMemitEItempPtr) += -Ibpei_Vrth;
|
|
|
|
// Stamp element: Ibici f_Bi = + f_Ci = -
|
|
rhs_current = -Ibici_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseBItempPtr) += Ibici_Vrth;
|
|
*(here->HICUMcollCItempPtr) += -Ibici_Vrth;
|
|
|
|
// Stamp element: Iciei f_Ci = + f_Ei = -
|
|
rhs_current = -Iciei_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMcollCItempPtr) += Iciei_Vrth;
|
|
*(here->HICUMemitEItempPtr) += -Iciei_Vrth;
|
|
|
|
// Stamp element: Ibpci f_Bp = + f_Ci = -
|
|
rhs_current = -Ibpci_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseBPtempPtr) += Ibpci_Vrth;
|
|
*(here->HICUMcollCItempPtr) += -Ibpci_Vrth;
|
|
|
|
// Stamp element: Rcx f_Ci = + f_C = -
|
|
rhs_current = -Icic_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollNode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMcollCItempPtr) += Icic_Vrth;
|
|
*(here->HICUMcollTempPtr) += -Icic_Vrth;
|
|
|
|
// Stamp element: Rbx f_B = + f_Bp = -
|
|
rhs_current = -Ibbp_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseTempPtr) += Ibbp_Vrth;
|
|
*(here->HICUMbaseBPtempPtr) += -Ibbp_Vrth;
|
|
|
|
// Stamp element: Re f_Ei = + f_E = -
|
|
rhs_current = - Ieie_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMemitEINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMemitNode) += +rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMemitEItempPtr) += +Ieie_Vrth;
|
|
*(here->HICUMemitTempPtr) += -Ieie_Vrth;
|
|
|
|
if (rbi > 0.0) {
|
|
// Stamp element: Rbi f_Bp = + f_Bi = -
|
|
rhs_current = -Ibpbi_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMbaseBINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMbaseBPtempPtr) += Ibpbi_Vrth;
|
|
*(here->HICUMbaseBItempPtr) += -Ibpbi_Vrth;
|
|
};
|
|
|
|
// Stamp element: Isici f_Si = + f_Ci = -
|
|
rhs_current = -Isici_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMsubsSINode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMcollCINode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMsubsSItempPtr) += Isici_Vrth;
|
|
*(here->HICUMcollCItempPtr) += -Isici_Vrth;
|
|
|
|
// Branch: bpsi, Stamp element: Its
|
|
rhs_current = - Ibpsi_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMbaseBPNode) += -rhs_current;
|
|
*(ckt->CKTrhs + here->HICUMsubsSINode) += rhs_current;
|
|
// f_Bp = + f_Si = -
|
|
// with respect to Vrth
|
|
*(here->HICUMbaseBPtempPtr) += Ibpsi_Vrth;
|
|
*(here->HICUMsubsSItempPtr) += -Ibpsi_Vrth;
|
|
|
|
if (model->HICUMnqs) {
|
|
// Stamp element: Ixf f_xf = +
|
|
rhs_current = -Ixf_dT*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMxfNode) += -rhs_current;
|
|
// with respect to Potential Vxf
|
|
*(here->HICUMxfTempPtr) += Ixf_dT;
|
|
|
|
// Stamp element: Ixf1 f_xf1 = +
|
|
rhs_current = -Ixf1_dT*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMxf1Node) += -rhs_current;
|
|
// with respect to Potential Vxf1
|
|
*(here->HICUMxf1TempPtr) += Ixf1_dT;
|
|
|
|
// Stamp element: Ixf2 f_xf2 = +
|
|
rhs_current = -Ixf2_dT*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMxf2Node) += -rhs_current;
|
|
// with respect to Potential Vxf2
|
|
*(here->HICUMxf2TempPtr) += Ixf2_dT;
|
|
}
|
|
|
|
|
|
|
|
// Stamp element: Ith f_T = - Ith
|
|
// Ith = -Vrth/here->HICUMrth_t.rpart; //Current from gnd to T
|
|
// Ith_Vrth = (-1/here->HICUMrth_t.rpart + Vrth/(here->HICUMrth_t.rpart*here->HICUMrth_t.rpart) * here->HICUMrth_t.dpart);
|
|
rhs_current = Ith
|
|
- Ith_Vbiei*Vbiei - Ith_Vbici*Vbici - Ith_Vciei*Vciei
|
|
- Ith_Vbpei*Vbpei - Ith_Vbpci*Vbpci - Ith_Vsici*Vsici
|
|
- Ith_Vbpbi*Vbpbi
|
|
- Ith_Vcic*Vcic - Ith_Vbbp*Vbbp - Ith_Veie*Veie
|
|
- Ith_Vrth*Vrth;
|
|
|
|
*(ckt->CKTrhs + here->HICUMtempNode) += rhs_current;
|
|
// with respect to Potential Vrth
|
|
*(here->HICUMtempTempPtr) += -Ith_Vrth;
|
|
// with respect to Potential Vbiei
|
|
*(here->HICUMtempBaseBIPtr) += -Ith_Vbiei;
|
|
*(here->HICUMtempEmitEIPtr) += +Ith_Vbiei;
|
|
// with respect to Potential Vbici
|
|
*(here->HICUMtempBaseBIPtr) += -Ith_Vbici;
|
|
*(here->HICUMtempCollCIPtr) += +Ith_Vbici;
|
|
// with respect to Potential Vciei
|
|
*(here->HICUMtempCollCIPtr) += -Ith_Vciei;
|
|
*(here->HICUMtempEmitEIPtr) += +Ith_Vciei;
|
|
// with respect to Potential Vbpei
|
|
*(here->HICUMtempBaseBPPtr) += -Ith_Vbpei;
|
|
*(here->HICUMtempEmitEIPtr) += +Ith_Vbpei;
|
|
// with respect to Potential Vbpci
|
|
*(here->HICUMtempBaseBPPtr) += -Ith_Vbpci;
|
|
*(here->HICUMtempCollCIPtr) += +Ith_Vbpci;
|
|
// with respect to Potential Vsici
|
|
*(here->HICUMtempSubsSIPtr) += -Ith_Vsici;
|
|
*(here->HICUMtempCollCIPtr) += +Ith_Vsici;
|
|
// with respect to Potential Vbpbi
|
|
*(here->HICUMtempBaseBPPtr) += -Ith_Vbpbi;
|
|
*(here->HICUMtempBaseBIPtr) += +Ith_Vbpbi;
|
|
// with respect to Potential Vcic
|
|
*(here->HICUMtempCollCIPtr) += -Ith_Vcic;
|
|
*(here->HICUMtempCollPtr) += +Ith_Vcic;
|
|
// with respect to Potential Vbbp
|
|
*(here->HICUMtempBasePtr) += -Ith_Vbbp;
|
|
*(here->HICUMtempBaseBPPtr) += +Ith_Vbbp;
|
|
// with respect to Potential Veie
|
|
*(here->HICUMtempEmitEIPtr) += -Ith_Veie;
|
|
*(here->HICUMtempEmitPtr) += +Ith_Veie;
|
|
|
|
// Cth f_T = - (put this separate to Ith to get signs right)
|
|
rhs_current = Icth - Vrth * Icth_Vrth;
|
|
*(ckt->CKTrhs + here->HICUMtempNode) += -rhs_current;
|
|
*(here->HICUMtempTempPtr) += +Icth_Vrth;
|
|
|
|
// Stamp element: Rth f_T = +
|
|
rhs_current = Vrth/here->HICUMrth_t.rpart - Irth_Vrth*Vrth;
|
|
*(ckt->CKTrhs + here->HICUMtempNode) += -rhs_current;
|
|
*(here->HICUMtempTempPtr) += Irth_Vrth;
|
|
}
|
|
}
|
|
|
|
}
|
|
return(OK);
|
|
}
|