45 #include <Xyce_config.h>
58 #include <N_ERH_ErrorMgr.h>
60 #include <N_LAS_Matrix.h>
61 #include <N_LAS_MultiVector.h>
62 #include <N_LAS_Vector.h>
63 #include <N_UTL_FeatureTest.h>
64 #include <N_UTL_Math.h>
77 .setDescription(
"Relative device area");
83 .setDescription(
"Vector of initial values: Vbe,Vce. Vbe=IC1");
89 .setDescription(
"Vector of initial values: Vbe,Vce. Vce=IC2");
95 .setDescription(
"Device temperature");
101 .setDescription(
"Initial condition of no voltage drops accross device");
106 .setDescription(
"Flag for toggling the use of the lambert-W function instead of exponentials.");
117 .setDescription(
"Parameter measurement temperature");
123 .setDescription(
"Transport saturation current");
126 .setOriginalValueStored(
true)
130 .setDescription(
"Ideal maximum foward beta");
134 .setOriginalValueStored(
true)
138 .setDescription(
"Ideal maximum foward beta");
141 .setOriginalValueStored(
true)
144 .setDescription(
"Foward current emission coefficient");
152 .setDescription(
"Foward early voltage");
159 .setDescription(
"Foward early voltage");
166 .setDescription(
"Foward early voltage");
172 .setDescription(
"Corner for foward-beta high-current roll-off");
178 .setDescription(
"Corner for foward-beta high-current roll-off");
184 .setDescription(
"Corner for foward-beta high-current roll-off");
192 .setDescription(
"Base-emitter leakage saturation current");
200 .setDescription(
"Base-emitter leakage saturation current");
206 .setDescription(
"Base-emitter leakage emission coefficient");
212 .setDescription(
"Base-emitter leakage emission coefficient");
219 .setDescription(
"Ideal maximum reverse beta");
225 .setDescription(
"Ideal maximum reverse beta");
230 .setDescription(
"Reverse current emission coefficient");
238 .setDescription(
"Reverse early voltage");
245 .setDescription(
"Reverse early voltage");
252 .setDescription(
"Reverse early voltage");
259 .setDescription(
"Reverse early voltage");
266 .setDescription(
"Corner for reverse-beta high-current roll-off");
273 .setDescription(
"Corner for reverse-beta high-current roll-off");
281 .setDescription(
"Base-collector leakage saturation current");
288 .setDescription(
"Base-collector leakage saturation current");
293 .setDescription(
"Base-collector leakage emission coefficient");
298 .setDescription(
"Zero-bias (maximum) base resistance");
306 .setDescription(
"Current at which RB falls off by half");
313 .setDescription(
"Current at which RB falls off by half");
320 .setDescription(
"Current at which RB falls off by half");
326 .setDescription(
"Maximum base resistance");
332 .setDescription(
"Emitter ohmic resistance");
338 .setDescription(
"Collector ohmic resistance");
344 .setDescription(
"Base-emitter zero-bias p-n capacitance");
352 .setDescription(
"Base-emitter built-in potential");
359 .setDescription(
"Base-emitter built-in potential");
367 .setDescription(
"Base-emitter p-n grading factor");
374 .setDescription(
"Base-emitter p-n grading factor");
379 .setDescription(
"Ideal foward transit time");
384 .setDescription(
"Transit time bias dependence coefficient");
389 .setDescription(
"Transit time dependancy on Vbc");
397 .setDescription(
"Transit time dependancy on IC");
404 .setDescription(
"Transit time dependancy on IC");
409 .setDescription(
"Excess Phase at 1/(2pi*TF) Hz");
415 .setDescription(
"Base-collector zero-bias p-n capacitance");
423 .setDescription(
"Base-collector built-in potential");
430 .setDescription(
"Base-collector built-in potential");
438 .setDescription(
"Base-collector p-n grading factor");
445 .setDescription(
"Base-collector p-n grading factor");
452 .setDescription(
"Fraction of CJC connected internally to RB");
457 .setDescription(
"Fraction of CJC connected internally to RB");
462 .setDescription(
"Ideal reverse transit time");
470 .setDescription(
"Substrate zero-bias p-n capacitance");
477 .setDescription(
"Substrate zero-bias p-n capacitance");
484 .setDescription(
"Substrate zero-bias p-n capacitance");
492 .setDescription(
"Substrate built-in potential");
499 .setDescription(
"Substrate built-in potential");
506 .setDescription(
"Substrate built-in potential");
513 .setDescription(
"Substrate p-n grading factor");
519 .setDescription(
"Substrate p-n grading factor");
525 .setDescription(
"Substrate p-n grading factor");
533 .setDescription(
"Foward and reverse beta temperature coefficient");
540 .setDescription(
"Foward and reverse beta temperature coefficient");
547 .setDescription(
"Foward and reverse beta temperature coefficient");
552 .setDescription(
"Bandgap voltage (barrier highth)");
560 .setDescription(
"Temperature exponent for IS. (synonymous with PT)");
567 .setDescription(
"Temperature exponent for IS. (synonymous with XTI)");
572 .setDescription(
"Flicker noise coefficient");
577 .setDescription(
"Flicker noise exponent");
582 .setDescription(
"Foward-bias depletion capacitor coefficient");
588 .setDescription(
"Coefficient for base-emitter leak current.");
594 .setDescription(
"Coefficient for base-collector leak current.");
601 .setDescription(
"High current rolloff coefficient");
607 .setDescription(
"High current rolloff coefficient");
670 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
679 externalNodeMode(false),
696 tleakBEEmissionCoeff(1.5),
697 tleakBCEmissionCoeff(2.0),
797 li_store_capeqCB(-1),
819 AEmitEquEmitPNodeOffset(-1),
820 AEmitPEquEmitNodeOffset(-1),
821 ABaseEquBasePNodeOffset(-1),
822 ABasePEquBaseNodeOffset(-1),
823 ACollEquCollPNodeOffset(-1),
824 ACollPEquCollNodeOffset(-1),
825 AEmitEquEmitNodeOffset(-1),
826 AEmitPEquEmitPNodeOffset(-1),
827 ABaseEquBaseNodeOffset(-1),
828 ABasePEquBasePNodeOffset(-1),
829 ACollEquCollNodeOffset(-1),
830 ACollPEquCollPNodeOffset(-1),
831 AEmitPEquBasePNodeOffset(-1),
832 ABasePEquEmitPNodeOffset(-1),
833 AEmitPEquCollPNodeOffset(-1),
834 ACollPEquEmitPNodeOffset(-1),
835 ABasePEquCollPNodeOffset(-1),
836 ACollPEquBasePNodeOffset(-1),
837 ABaseEquCollPNodeOffset(-1),
838 ACollPEquBaseNodeOffset(-1),
839 ASubstEquSubstNodeOffset(-1),
840 ASubstEquCollPNodeOffset(-1),
841 ACollPEquSubstNodeOffset(-1),
842 ABaseEquEmitPNodeOffset(-1) ,
843 ACollPEquIfxNodeOffset(-1),
844 AEmitPEquIfxNodeOffset(-1),
845 AIfxEquCollPNodeOffset(-1),
846 AIfxEquBasePNodeOffset(-1),
847 AIfxEquEmitPNodeOffset(-1),
848 AIfxEquIfxNodeOffset(-1),
849 AIfxEqudIfxNodeOffset(-1),
850 AdIfxEquCollPNodeOffset(-1),
851 AdIfxEquBasePNodeOffset(-1),
852 AdIfxEquEmitPNodeOffset(-1),
853 AdIfxEquIfxNodeOffset(-1),
854 AdIfxEqudIfxNodeOffset(-1),
858 f_EmitEquEmitPNodePtr(0),
859 f_EmitPEquEmitNodePtr(0),
860 f_BaseEquBasePNodePtr(0),
861 f_BasePEquBaseNodePtr(0),
862 f_CollEquCollPNodePtr(0),
863 f_CollPEquCollNodePtr(0),
864 f_EmitEquEmitNodePtr(0),
865 f_EmitPEquEmitPNodePtr(0),
866 f_BaseEquBaseNodePtr(0),
867 f_BasePEquBasePNodePtr(0),
868 f_CollEquCollNodePtr(0),
869 f_CollPEquCollPNodePtr(0),
870 f_EmitPEquBasePNodePtr(0),
871 f_BasePEquEmitPNodePtr(0),
872 f_EmitPEquCollPNodePtr(0),
873 f_CollPEquEmitPNodePtr(0),
874 f_BasePEquCollPNodePtr(0),
875 f_CollPEquBasePNodePtr(0),
876 f_BaseEquCollPNodePtr(0),
877 f_CollPEquBaseNodePtr(0),
878 f_SubstEquSubstNodePtr(0),
879 f_SubstEquCollPNodePtr(0),
880 f_CollPEquSubstNodePtr(0),
881 f_BaseEquEmitPNodePtr(0),
884 f_CollPEquIfxNodePtr(0),
885 f_EmitPEquIfxNodePtr(0),
888 f_IfxEquCollPNodePtr(0),
889 f_IfxEquBasePNodePtr(0),
890 f_IfxEquEmitPNodePtr(0),
892 f_IfxEquIfxNodePtr(0),
893 f_IfxEqudIfxNodePtr(0),
895 f_dIfxEquCollPNodePtr(0),
896 f_dIfxEquBasePNodePtr(0),
897 f_dIfxEquEmitPNodePtr(0),
898 f_dIfxEquIfxNodePtr(0),
899 f_dIfxEqudIfxNodePtr(0),
903 q_EmitEquEmitPNodePtr(0),
904 q_EmitPEquEmitNodePtr(0),
905 q_BaseEquBasePNodePtr(0),
906 q_BasePEquBaseNodePtr(0),
907 q_CollEquCollPNodePtr(0),
908 q_CollPEquCollNodePtr(0),
909 q_EmitEquEmitNodePtr(0),
910 q_EmitPEquEmitPNodePtr(0),
911 q_BaseEquBaseNodePtr(0),
912 q_BasePEquBasePNodePtr(0),
913 q_CollEquCollNodePtr(0),
914 q_CollPEquCollPNodePtr(0),
915 q_EmitPEquBasePNodePtr(0),
916 q_BasePEquEmitPNodePtr(0),
917 q_EmitPEquCollPNodePtr(0),
918 q_CollPEquEmitPNodePtr(0),
919 q_BasePEquCollPNodePtr(0),
920 q_CollPEquBasePNodePtr(0),
921 q_BaseEquCollPNodePtr(0),
922 q_CollPEquBaseNodePtr(0),
923 q_SubstEquSubstNodePtr(0),
924 q_SubstEquCollPNodePtr(0),
925 q_CollPEquSubstNodePtr(0),
926 q_BaseEquEmitPNodePtr(0),
929 q_CollPEquIfxNodePtr(0),
930 q_EmitPEquIfxNodePtr(0),
933 q_IfxEquCollPNodePtr(0),
934 q_IfxEquBasePNodePtr(0),
935 q_IfxEquEmitPNodePtr(0),
937 q_IfxEquIfxNodePtr(0),
938 q_IfxEqudIfxNodePtr(0),
940 q_dIfxEquCollPNodePtr(0),
941 q_dIfxEquBasePNodePtr(0),
942 q_dIfxEquEmitPNodePtr(0),
943 q_dIfxEquIfxNodePtr(0),
944 q_dIfxEqudIfxNodePtr(0),
1121 int numExist = cNode + eNode + bNode;
1123 if (numExtVars <= 4)
1131 if (numExtVars != 4 + numExist)
1133 UserError(*
this) <<
"Wrong number of external nodes are set!" << std::endl
1134 <<
"Either set none of them, or set them all.";
1172 const std::vector<int> & extLIDVecRef )
1177 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1179 Xyce::dout() << section_divider << std::endl;
1180 Xyce::dout() <<
" BJTInstance::registerLIDs" <<std::endl;
1181 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1182 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
1183 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
1184 Xyce::dout() <<
" numIntVars = " <<
numIntVars << std::endl;
1185 Xyce::dout() <<
" numExtVars = " <<
numExtVars << std::endl;
1192 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1194 Xyce::dout() <<
" Internal LID List" << std::endl;
1195 for(
int i = 0; i <
intLIDVec.size(); ++i )
1196 Xyce::dout() <<
" " <<
intLIDVec[i] << std::endl;
1197 Xyce::dout() <<
" External LID List" << std::endl;
1198 for(
int i = 0; i <
extLIDVec.size(); ++i )
1199 Xyce::dout() <<
" " <<
extLIDVec[i] << std::endl;
1261 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
1263 Xyce::dout() <<
" li_Coll = " <<
li_Coll << std::endl;
1264 Xyce::dout() <<
" li_CollP = " <<
li_CollP << std::endl;
1265 Xyce::dout() <<
" li_Base = " <<
li_Base << std::endl;
1266 Xyce::dout() <<
" li_BaseP = " <<
li_BaseP << std::endl;
1267 Xyce::dout() <<
" li_Emit = " <<
li_Emit << std::endl;
1268 Xyce::dout() <<
" li_EmitP = " <<
li_EmitP << std::endl;
1269 Xyce::dout() <<
" li_Subst = " <<
li_Subst << std::endl;
1273 Xyce::dout() <<
" li_Ifx = " <<
li_Ifx << std::endl;
1274 Xyce::dout() <<
" li_dIfx = " <<
li_dIfx << std::endl;
1277 Xyce::dout() << section_divider << std::endl;
1436 std::vector<int> map;
1437 std::vector< std::vector<int> > map2;
1561 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1682 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1684 Xyce::dout() <<
"Start BJTInst::updateTemperature" << std::endl;
1685 Xyce::dout() <<
"temp = "<<temp << std::endl;
1687 if( temp != -999.0 )
TEMP = temp;
1707 double pbfact = -2.0 *
vt * ( 1.5 * log( fact2 ) +
CONSTQ * arg );
1712 double factor = exp( factlog );
1716 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1718 Xyce::dout() <<
" Factor is " << factor << std::endl;
1719 Xyce::dout() <<
" Bfactor is " << bfactor << std::endl;
1720 Xyce::dout() <<
" factlog is " << factlog << std::endl;
1721 Xyce::dout() <<
" ratio1 is " << ratio1 << std::endl;
1722 Xyce::dout() <<
" TEMP is " <<
TEMP << std::endl;
1723 Xyce::dout() <<
" TNOM is " <<
model_.
TNOM << std::endl;
1735 tBEPot = fact2 * pbo + pbfact;
1737 double gmanew = (
tBEPot - pbo ) / pbo;
1747 tBCPot = fact2 * pbo + pbfact;
1749 gmanew = (
tBCPot - pbo ) / pbo;
1806 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1809 Xyce::dout() << section_divider << std::endl;
1810 Xyce::dout() <<
"In BJTInst::updateTemperature" << std::endl;
1811 Xyce::dout() << section_divider << std::endl;
1812 Xyce::dout() <<
"TEMP = " <<
TEMP << std::endl;
1813 Xyce::dout() <<
"TNOM = " << TNOM << std::endl;
1814 Xyce::dout() <<
"vt = " <<
vt << std::endl;
1815 Xyce::dout() <<
"tSatCur = " <<
tSatCur << std::endl;
1816 Xyce::dout() <<
"tBetaF = " <<
tBetaF << std::endl;
1817 Xyce::dout() <<
"tBetaR = " <<
tBetaR << std::endl;
1818 Xyce::dout() <<
"tBELeakCur = " <<
tBELeakCur << std::endl;
1819 Xyce::dout() <<
"tBCLeakCur = " <<
tBELeakCur << std::endl;
1820 Xyce::dout() <<
"tBEPot = " <<
tBEPot << std::endl;
1821 Xyce::dout() <<
"tBECap = " <<
tBECap << std::endl;
1822 Xyce::dout() <<
"tBCPot = " <<
tBCPot << std::endl;
1823 Xyce::dout() <<
"tBCCap = " <<
tBCCap << std::endl;
1824 Xyce::dout() <<
"tDepCap = " <<
tDepCap << std::endl;
1825 Xyce::dout() <<
"tF1 = " <<
tF1 << std::endl;
1826 Xyce::dout() <<
"tF4 = " <<
tF4 << std::endl;
1827 Xyce::dout() <<
"tF5 = " <<
tF5 << std::endl;
1830 Xyce::dout() <<
"tRollOffExp = " <<
tRollOffExp << std::endl;
1831 Xyce::dout() <<
"tInvRollOffF = " <<
tInvRollOffF << std::endl;
1832 Xyce::dout() <<
"tInvRollOffR = " <<
tInvRollOffR << std::endl;
1833 Xyce::dout() <<
"tInvEarlyVoltF = " <<
tInvEarlyVoltF << std::endl;
1834 Xyce::dout() <<
"tInvEarlyVoltR = " <<
tInvEarlyVoltR << std::endl;
1835 Xyce::dout() <<
"tBaseResist = " <<
tBaseResist << std::endl;
1837 Xyce::dout() <<
"tEmitterResist = " <<
tEmitterResist << std::endl;
1838 Xyce::dout() << section_divider << std::endl;
1839 Xyce::dout() << std::endl;
1856 double RS = 1.0e-12;
1857 double arg1 = (Vd + Isat*
RS)/Vte;
1859 double evd = exp(arg1);
1860 double lambWArg = Isat*RS*evd/Vte;
1866 Id = -Isat+Vte*(lambWReturn)/RS;
1867 Gd = lambWReturn / ((1 + lambWReturn)*RS);
1891 (*maskVectorPtr)[
li_Ifx] = 0.0;
1892 (*maskVectorPtr)[
li_dIfx] = 0.0;
1944 double Cp_Jdxp_q = 0.0;
1945 double Ep_Jdxp_q = 0.0;
1946 double Bp_Jdxp_q = 0.0;
2058 double coefC, coefB, coefE, coefCp, coefBp, coefEp;
2066 double vce_diff = vbe_diff - vbc_diff;
2106 double Cp_Jdxp_f=0.0;
2107 double Bp_Jdxp_f=0.0;
2108 double Ep_Jdxp_f=0.0;
2109 double dIfx_Jdxp_f=0.0 ;
2110 double Ifx_Jdxp_f=0.0 ;
2155 dFdxdVp[
li_dIfx] += dIfx_Jdxp_f;
2159 dFdxdVp[
li_Ifx] += Ifx_Jdxp_f;
2445 noiseData.
resize(numSources);
2460 std::string(
"_1overf");
2585 (
double & iEX,
double & gEX,
double & iC_local)
2588 double td = model_.excessPhaseFac;
2590 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
2592 Xyce::dout() << std::endl;
2593 Xyce::dout() <<
" Excess Phase stuff:" <<std::endl;
2594 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
2595 Xyce::dout() <<
" td = " << td <<std::endl;
2610 dt0 = getSolverState().currTimeStep;
2611 dt1 = getSolverState().lastTimeStep;
2616 if (!(getSolverState().dcopFlag) && td != 0)
2618 double arg1, arg2, denom;
2623 denom = 1.0 + arg1 + arg2;
2624 phaseScalar = arg1 / denom;
2627 if (!getSolverState().beginIntegrationFlag)
2629 currCexbc = (*extData.currStaVectorPtr)[li_istateCEXBC];
2630 lastCexbc = (*extData.lastStaVectorPtr)[li_istateCEXBC];
2633 iC_local = ((currCexbc) * (1 + dt0 / dt1 + arg2) - (lastCexbc) * dt0 / dt1) / denom;
2634 iEX = iBE * phaseScalar;
2635 gEX = gBE * phaseScalar;
2637 nextCexbc = iC_local + iEX / qB;
2638 (*extData.nextStaVectorPtr)[li_istateCEXBC] = nextCexbc;
2654 bool bsuccess =
true;
2656 double v_emit, v_emitP;
2657 double v_base, v_baseP;
2658 double v_coll, v_collP;
2664 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2666 Xyce::dout() << Xyce::section_divider << std::endl;
2667 Xyce::dout() <<
"Instance::updateIntermediateVars " <<
getName() <<std::endl;
2679 vEEp = (v_emit - v_emitP);
2680 vBBp = (v_base - v_baseP);
2681 vCCp = (v_coll - v_collP);
2711 if ((*flagSolVectorPtr)[
li_Emit] == 0 || (*flagSolVectorPtr)[
li_EmitP] == 0 ||
2712 (*flagSolVectorPtr)[
li_Base] == 0 || (*flagSolVectorPtr)[
li_BaseP] == 0 ||
2713 (*flagSolVectorPtr)[
li_Coll] == 0 || (*flagSolVectorPtr)[
li_CollP] == 0 ||
2714 (*flagSolVectorPtr)[
li_Subst] == 0 )
2729 Xyce::dout() <<
" Setting device initial condition to Base-Emitter drop=tVCrit (" <<
tVCrit <<
")"<<std::endl;
2735 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2737 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2738 Xyce::dout() <<
" " <<std::endl;
2739 Xyce::dout() <<
" using UIC.\n";
2740 Xyce::dout() <<
" vBE = " <<
vBE << std::endl;
2741 Xyce::dout() <<
" vBC = " <<
vBC << std::endl;
2742 Xyce::dout() <<
" vBX = " <<
vBX << std::endl;
2743 Xyce::dout() <<
" vCS = " <<
vCS << std::endl;
2757 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2759 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2760 Xyce::dout() <<
" " <<std::endl;
2761 Xyce::dout() <<
" BJT explicitly set OFF, zeroing all junction drops.\n";
2790 Xyce::dout() <<
" tVCrit = " <<
tVCrit << std::endl;
2791 Xyce::dout().width(3);
2793 Xyce::dout().width(5); Xyce::dout() <<
getName();
2794 Xyce::dout() <<
" Blim: ";
2795 Xyce::dout() <<
" vBE=";
2796 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2797 Xyce::dout() <<
vBE;
2798 Xyce::dout() <<
" vBC=";
2799 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2800 Xyce::dout() <<
vBC << std::endl;
2820 if (ichk1 == 1) icheck=1;
2826 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2828 Xyce::dout().width(3);
2830 Xyce::dout().width(5); Xyce::dout() <<
getName() ;
2831 Xyce::dout() <<
" Alim: ";
2832 Xyce::dout() <<
" vBE=";
2833 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2834 Xyce::dout() <<
vBE;
2835 Xyce::dout() <<
" vBC=";
2836 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2837 Xyce::dout() <<
vBC;
2843 if (
origFlag) Xyce::dout() <<
" SAME";
2844 else Xyce::dout() <<
" DIFF";
2845 Xyce::dout() << std::endl;
2862 if(
vBE > -5.0 * vtF )
2866 if( iLeakBE == 0.0 )
2881 if(
vBC > -5.0 * vtR )
2885 if( iLeakBC == 0.0 )
2904 if (
vBE > -5.0 * vtF)
2906 double arg1 =
vBE / vtF ;
2926 double arg1 =
vBE / vtE ;
2936 evBEleak = exp(arg1);
2939 iBEleak = iLeakBE * (evBEleak - 1.0);
2940 gBEleak = iLeakBE * devBEleak / vtE;
2951 if(
vBC > -5.0 * vtR )
2953 double arg1 =
vBC / vtR ;
2973 double arg1 =
vBC / vtC ;
2983 evBCleak = exp(arg1);
2986 iBCleak = iLeakBC * (evBCleak - 1.0);
2987 gBCleak = iLeakBC * devBCleak / vtC;
3005 if (rofF == 0.0 && rofR == 0.0)
3008 double q1_qB = q1 *
qB;
3018 q2 = rofF *
iBE + rofR *
iBC;
3031 double arg = 1.0 + 4.0 * q2;
3039 if (fabs(arg) > 0.0) sqarg = pow(arg,
tRollOffExp);
3040 double rofF_gBE_invSqarg = 0.0;
3041 double rofR_gBC_invSqarg = 0.0;
3042 if(arg != 0) rofF_gBE_invSqarg = rofF*
gBE*2*
tRollOffExp*sqarg/arg;
3043 if(arg != 0) rofR_gBC_invSqarg = rofR*
gBC*2*
tRollOffExp*sqarg/arg;
3045 qB = 0.5 * q1 * (1.0 + sqarg);
3100 bool geqCB_recalc(
false);
3123 arg2 = argtf * (3.0 - 2.0 * tmp);
3133 geqCB_recalc =
true;
3228 qBX =
tBCPot * czBX * ( 1.0 - arg * sarg ) /
3230 capBX = czBX * sarg;
3259 capCS = czCS * sarg;
3275 double iEX_tmp = 0.0;
double gEX_tmp = 0.0;
double iC_tmp = 0.0;
3348 gX = rBpr + rBpi /
qB;
3350 if (fabs(xjrB) > 0.0)
3352 double arg1 = std::max(
iB / xjrB, 1.0e-09);
3353 double arg2 = (-1.0 + sqrt( 1.0 + 14.59025 * arg1)) / 2.4317 / sqrt(arg1);
3355 gX = rBpr + 3.0 * rBpi * (arg1 - arg2) / arg2 / arg1 / arg1;
3358 if (fabs(
gX) > 0.0)
gX = 1.0 /
gX;
3381 bool bsuccess =
true;
3384 std::ostringstream oss;
3385 oss <<
"Q_" <<
getName() <<
".dat";
3386 std::string filename = oss.str();
3393 fp1 = fopen(filename.c_str(),
"w");
3397 fp1 = fopen(filename.c_str(),
"a");
3403 " TITLE = \"Debug Excess Phase data: %s \"\n",
getName().getEncodedName().c_str());
3408 fprintf(fp1,
"%s",
"\tVARIABLES = \"TIME (S)\",\n");
3410 fprintf(fp1,
"%s",
"\t \"iBE/qB \",\n");
3411 fprintf(fp1,
"%s",
"\t \"currCexbc \",\n");
3412 fprintf(fp1,
"%s",
"\t \"lastCexbc \",\n");
3415 fprintf(fp1,
"%s",
"\t \"i_fx \",\n");
3416 fprintf(fp1,
"%s",
"\t \"di_fx \",\n");
3419 fprintf(fp1,
"%s",
"\tZONE F=POINT T=\"Excess Phase Data\"\n");
3422 fprintf(fp1,
" %12.4e",time);
3423 fprintf(fp1,
" %12.4e",(
iBE/
qB));
3430 double i_fx = solVec[
li_Ifx];
3431 double di_fx = solVec[
li_dIfx];
3432 fprintf(fp1,
" %12.4e",i_fx);
3433 fprintf(fp1,
" %12.4e",di_fx);
3436 fprintf(fp1,
"%s",
"\n");
3507 Xyce::dout() <<
"Bad Depletion Capacitance Coefficient" << std::endl;
3536 std::vector<Instance*>::iterator iter;
3540 for (iter=first; iter!=last; ++iter)
3542 (*iter)->processParams();
3560 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
3567 emissionCoeffF(1.0),
3577 leakBEEmissionCoeff(1.5),
3583 emissionCoeffR(1.0),
3594 leakBCEmissionCoeff(2.0),
3596 baseCurrHalfResist(0.0),
3600 minBaseResist(baseResist),
3602 collectorResist(0.0),
3613 transTimeBiasCoeffF(0.0),
3614 transTimeFVBC(1.e99),
3615 transTimeHighCurrF(0.0),
3666 leakBCCurrentGiven(false),
3668 leakBECurrentGiven(false),
3670 minBaseResistGiven(false),
3685 UserError0(*
this) <<
"Both BF and BFM are set, which is redundant.";
3695 UserError0(*
this) <<
"Both BR and BRM are set, which is redundant.";
3703 int VAFgivenCount = 0;
3707 if (VAFgivenCount > 1)
3709 UserError0(*
this) <<
"The forward early voltage is set more than once. VA, VAF and VBF are aliases.";
3711 if (VAFgivenCount > 0)
3717 int VARgivenCount = 0;
3722 if (VARgivenCount > 1)
3724 UserError0(*
this) <<
"The reverse early voltage is set more than once. VAR,VB,VRB and BV are aliases.";
3726 if (VARgivenCount > 0)
3732 int IKFgivenCount = 0;
3736 if (IKFgivenCount > 1)
3738 UserError0(*
this) <<
"High current roll-off is set more than once (IKF, JBF or IK).";
3740 if (IKFgivenCount > 0)
3748 UserError0(*
this) <<
"Both IKR and JBRgiven are set, which is redundant.";
3759 UserError0(*
this) <<
"Both JLE and ISE are set, which is redundant.";
3770 UserError0(*
this) <<
"Both JLC and ISC are set, which is redundant.";
3780 UserError0(*
this) <<
"Both NLE and NE are set, which is redundant.";
3790 UserError0(*
this) <<
" Both MJE and ME are set, which is redundant.";
3800 UserError0(*
this) <<
"Both MJC and MC are set, which is redundant.";
3808 int CJSgivenCount = 0;
3812 if (CJSgivenCount > 1)
3814 UserError0(*
this) <<
"The zero-bias collector-substrate capacitance (CJS, CCS or CSUB) is set more than once.";
3816 if (CJSgivenCount > 0)
3822 int IRBgivenCount = 0;
3826 if (IRBgivenCount > 1)
3828 UserError0(*
this) <<
"The current for 1/2 base resistance (IRB, JRB or IOB) is set more than once.";
3830 if (IRBgivenCount > 0)
3838 UserError0(*
this) <<
"The BE built-in potential (VJE or PE) is set more than once.";
3848 UserError0(*
this) <<
"The BC built-in potential (VJC or PC) is set more than once.";
3858 UserError0(*
this) <<
"XCJC and CDIS are both set (they are aliases).";
3866 int VJSgivenCount = 0;
3870 if (VJSgivenCount > 1)
3872 UserError0(*
this) <<
"The Substrate built-in potential is set more than once. PS, VJS and PSUB are aliases.";
3874 if (VJSgivenCount > 0)
3880 int MJSgivenCount = 0;
3884 if (MJSgivenCount > 1)
3886 UserError0(*
this) <<
"The Substrate p-n grading factor is set more than once. MS, MJS and ESUB are aliases.";
3888 if (MJSgivenCount > 0)
3896 UserError0(*
this) <<
"ITF and JTF are both set (they are aliases).";
3906 UserError0(*
this) <<
"NK and NKF are both set (they are aliases).";
3914 int XTBgivenCount = 0;
3918 if (XTBgivenCount > 1)
3920 UserError0(*
this) <<
"The beta temperature coefficient is set more than once. TB, XTB and TCB are aliases.";
3922 if (XTBgivenCount > 0)
3931 UserError0(*
this) <<
"PT and XTI are both set (they are aliases).";
3972 std::vector<Instance*>::iterator iterI;
3977 for (iterI = firstI; iterI != lastI; ++iterI)
3994 std::vector<Instance*>::const_iterator iter;
3999 os <<
" name modelName Parameters" << std::endl;
4000 for (i = 0, iter = first; iter != last; ++iter, ++i)
4002 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
4006 os <<
" AREA = " << (*iter)->AREA << std::endl;
4007 os <<
" icVBE = " << (*iter)->icVBE << std::endl;
4008 os <<
" icVCE = " << (*iter)->icVCE << std::endl;
4009 os <<
" TEMP = " << (*iter)->TEMP << std::endl;
4010 os <<
" OFF = " << (*iter)->OFF << std::endl;
4036 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
4055 bool bsuccess =
true;
4065 bsuccess = bsuccess && btmp;
4111 bool bsuccess =
true;
4140 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
4149 double vce_diff = vbe_diff - vbc_diff;
4166 i_fx = solVec[bi.
li_Ifx];
4174 fVec[bi.
li_Ifx] += - di_fx;
4175 fVec[bi.
li_dIfx] += 3 * di_fx*td + 3*i_fx -3 * bi.
iBE / bi.
qB;
4215 double Cp_Jdxp_f(0.0), Bp_Jdxp_f(0.0), Ep_Jdxp_f(0.0),
4216 dIfx_Jdxp_f(0.0 ), Ifx_Jdxp_f(0.0 ),
4217 Cp_Jdxp_q ( 0.0), Ep_Jdxp_q ( 0.0), Bp_Jdxp_q ( 0.0);
4222 Cp_Jdxp_f = + bi.
diCEdvBp * vbe_diff
4228 Bp_Jdxp_f = bi.
gBEtot * vbe_diff + bi.
gBCtot * vbc_diff;
4260 dFdxdVp[bi.
li_dIfx] += dIfx_Jdxp_f;
4264 dFdxdVp[bi.
li_Ifx] += Ifx_Jdxp_f;
4323 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
4540 .registerDevice(
"q", 1)
4541 .registerModelType(
"pnp", 1)
4542 .registerModelType(
"npn", 1);
const InstanceName & getName() const
double * nextStaDerivVectorRawPtr
double * q_SubstEquCollPNodePtr
Linear::Vector * lastStaVectorPtr
double * q_dIfxEquIfxNodePtr
static void initThermalModel(ParametricData< T > ¶metric_data)
Add the parameter "TEMPMODEL" to the parametric_data.
double * f_IfxEquEmitPNodePtr
bool updateDependentParameters()
int ABaseEquEmitPNodeOffset
static std::vector< std::vector< int > > jacMap2_RB_RC_RE_
int AIfxEquCollPNodeOffset
double * q_EmitPEquIfxNodePtr
const DeviceOptions & deviceOptions_
double * q_BaseEquBasePNodePtr
const std::vector< std::vector< int > > & jacobianStamp() const
int AEmitPEquIfxNodeOffset
int AdIfxEquEmitPNodeOffset
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
double * daeQVectorRawPtr
double * q_BasePEquBaseNodePtr
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &it_MB, const FactoryBlock &factory_block)
double * f_BasePEquEmitPNodePtr
static std::vector< int > jacMap_RB_RE_
double * dFdxdVpVectorRawPtr
double * q_IfxEquBasePNodePtr
double pnjlim(double vnew, double vold, double vt, double vcrit, int *icheck)
std::vector< int > devConMap
double leakBEEmissionCoeff
bool given(const std::string ¶meter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
double * f_CollEquCollNodePtr
double * q_CollPEquEmitPNodePtr
int AEmitPEquEmitNodeOffset
virtual bool updateSecondaryState(double *staDeriv, double *stoVec)
Updates the devices secondary state information.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
double * f_IfxEquCollPNodePtr
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
double baseCurrHalfResist
double * currStaVectorRawPtr
double * f_CollPEquCollPNodePtr
static std::vector< std::vector< int > > jacStamp_RB_RC_
double * f_IfxEquBasePNodePtr
int ACollEquCollPNodeOffset
double * f_SubstEquSubstNodePtr
void setNumStoreVars(int num_store_vars)
double * q_EmitPEquEmitPNodePtr
void makeVector(const std::string &cname, int len)
Allows the parameter to be specified as a vector.
std::vector< int > li_Neg
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
int ABaseEquCollPNodeOffset
double * f_CollEquCollPNodePtr
static std::vector< std::vector< int > > jacStamp_RB_RC_RE_
int ASubstEquSubstNodeOffset
int AEmitPEquBasePNodeOffset
std::vector< int > li_Pos
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
bool updateIntermediateVars()
int ABaseEquBasePNodeOffset
Parameter is subject to being set to minimum junction capacitance.
double * f_EmitPEquEmitNodePtr
static std::vector< int > jacMap_RE_
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
static std::vector< int > jacMap_RB_RC_
Parameter is subject to being set to minimum lead resistance.
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
double * f_BaseEquBasePNodePtr
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
double * q_EmitPEquEmitNodePtr
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
double * q_CollPEquCollPNodePtr
static std::vector< std::vector< int > > jacStamp_RB_RE_
double * storeLeadCurrQCompRawPtr
double * q_SubstEquSubstNodePtr
int getNumStoreVars() const
static std::vector< std::vector< int > > jacStamp_RE_
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
double * q_BaseEquEmitPNodePtr
double * f_IfxEquIfxNodePtr
std::vector< Param > params
Parameters from the line.
const std::string & getName(const C *c)
Returns the name of the specified object.
std::vector< double > noiseDens
int ACollPEquCollPNodeOffset
int ABasePEquCollPNodeOffset
int AdIfxEqudIfxNodeOffset
double * f_dIfxEquEmitPNodePtr
std::vector< std::string > noiseNames
void setParams(const std::vector< Param > ¶ms)
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
int ABaseEquBaseNodeOffset
double * f_EmitPEquBasePNodePtr
const std::string & getName() const
double * daeFVectorRawPtr
double * f_BaseEquEmitPNodePtr
double * q_CollPEquBaseNodePtr
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
static std::vector< int > jacMap_RC_
double * q_EmitPEquBasePNodePtr
static std::vector< std::vector< int > > jacMap2_RE_
int ACollPEquBasePNodeOffset
const DeviceOptions & getDeviceOptions() const
double * q_BaseEquBaseNodePtr
double * f_BasePEquBaseNodePtr
void setupNoiseSources(Xyce::Analysis::NoiseData &noiseData)
int AEmitPEquCollPNodeOffset
static std::vector< int > jacMap_
static std::vector< std::vector< int > > jacStamp_RB_
double * nextStoVectorRawPtr
double * f_BaseEquCollPNodePtr
double Xexp(double, double &, double)
static std::vector< std::vector< int > > jacStamp_RC_RE_
double * f_EmitEquEmitPNodePtr
double * f_CollPEquBasePNodePtr
double * f_dIfxEquBasePNodePtr
int AEmitPEquEmitPNodeOffset
Linear::Vector * deviceErrorWeightMask_
double * q_BasePEquCollPNodePtr
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
static std::vector< std::vector< int > > jacMap2_RB_RE_
int AdIfxEquBasePNodeOffset
static std::vector< std::vector< int > > jacMap2_RB_
double * q_BaseEquCollPNodePtr
Parameter uses temperature interpolation based on log of value.
Linear::Matrix * dFdxMatrixPtr
const DeviceOptions & getDeviceOptions() const
Returns the device options given during device construction.
void auxDAECalculations()
int ACollPEquSubstNodeOffset
static std::vector< int > jacMap_RB_
double * f_CollPEquEmitPNodePtr
double * f_dIfxEquCollPNodePtr
The Device class is an interface for device implementations.
bool processInstanceParams()
processInstanceParams
void loadErrorWeightMask()
double leakBCEmissionCoeff
double * q_EmitEquEmitPNodePtr
void addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
virtual std::ostream & printOutInstances(std::ostream &os) const
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
double * q_CollPEquCollNodePtr
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
double tleakBEEmissionCoeff
double transTimeBiasCoeffF
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
double * f_dIfxEquIfxNodePtr
void oldDAEExcessPhaseCalculation1()
int AEmitEquEmitNodeOffset
double * q_dIfxEquBasePNodePtr
const SolverState & solverState_
double * f_IfxEqudIfxNodePtr
bool updateTemperature(const double &temp=-999.0)
double * dQdxdVpVectorRawPtr
Class Configuration contains device configuration data.
double * q_CollEquCollPNodePtr
int ACollPEquCollNodeOffset
std::vector< double > lnNoiseDens
double * f_CollPEquCollNodePtr
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
double * q_IfxEquCollPNodePtr
static std::vector< std::vector< int > > jacStamp_RC_
bool interpolateTNOM(double)
void getNoiseSources(Xyce::Analysis::NoiseData &noiseData)
double * f_EmitEquEmitNodePtr
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
int ACollPEquEmitPNodeOffset
double * q_EmitPEquCollPNodePtr
double * f_CollPEquSubstNodePtr
std::vector< Instance * > instanceContainer
static std::vector< std::vector< int > > jacMap2_
const SolverState & getSolverState() const
void lambertw(double x, double &w, int &ierr, double &xi)
static std::vector< int > jacMap_RB_RC_RE_
double * q_BasePEquEmitPNodePtr
double * f_EmitPEquIfxNodePtr
Linear::Vector * nextStoVectorPtr
bool lambertWCurrent(double &Id, double &Gd, double Vd, double Vte, double Isat)
Linear::Vector * currStaVectorPtr
void registerStateLIDs(const std::vector< int > &stateLIDVecRef)
int ACollEquCollNodeOffset
double * f_EmitPEquCollPNodePtr
double * nextStaVectorRawPtr
#define Xyce_NONPOINTER_MATRIX_LOAD
int AIfxEqudIfxNodeOffset
double * f_EmitPEquEmitPNodePtr
double tleakBCEmissionCoeff
void oldDAEExcessPhaseCalculation2(double &iEX, double &gEX, double &iC_local)
double * q_IfxEquIfxNodePtr
int AdIfxEquIfxNodeOffset
void noiseSupport(double &noise, double &lnNoise, const int type, const double param, const double temp)
double * q_dIfxEquCollPNodePtr
double * q_CollPEquBasePNodePtr
int AIfxEquEmitPNodeOffset
bool updatePrimaryState()
const std::string & getType() const
double * q_dIfxEqudIfxNodePtr
double * q_dIfxEquEmitPNodePtr
int ABasePEquBaseNodeOffset
static std::vector< int > jacMap_RC_RE_
Linear::Vector * currStoVectorPtr
int ACollPEquBaseNodeOffset
int AIfxEquBasePNodeOffset
double * q_EmitEquEmitNodePtr
double * f_BasePEquCollPNodePtr
int ACollPEquIfxNodeOffset
const ExternData & extData
bool processParams()
processParams
ModelBlock represents a .MODEL line from the netlist.
bool updateSecondaryState()
Manages parameter binding for class C.
int ASubstEquCollPNodeOffset
InstanceBlock represent a device instance line from the netlist.
static std::vector< std::vector< int > > jacStamp_
double transTimeHighCurrF
int getNumNoiseSources() const
std::vector< Param > params
double * q_CollPEquIfxNodePtr
int ABasePEquBasePNodeOffset
Linear::Matrix * dQdxMatrixPtr
int AEmitEquEmitPNodeOffset
double * q_IfxEquEmitPNodePtr
static std::vector< std::vector< int > > jacMap2_RB_RC_
double * f_CollPEquIfxNodePtr
double * f_BasePEquBasePNodePtr
double * f_CollPEquBaseNodePtr
double * q_CollPEquSubstNodePtr
double * q_CollEquCollNodePtr
double * f_dIfxEqudIfxNodePtr
static std::vector< std::vector< int > > jacMap2_RC_
Linear::Vector * flagSolVectorPtr
static std::vector< std::vector< int > > jacMap2_RC_RE_
double * q_BasePEquBasePNodePtr
int ABasePEquEmitPNodeOffset
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > ¶ms)
static void loadModelParameters(ParametricData< Model > &model_parameters)
double * nextSolVectorRawPtr
int numLeadCurrentStoreVars
int AdIfxEquCollPNodeOffset
double * f_SubstEquCollPNodePtr
double * f_BaseEquBaseNodePtr
double * q_IfxEqudIfxNodePtr