45 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
56 #ifdef Xyce_DEBUG_DEVICE
72 #include <N_ERH_ErrorMgr.h>
74 #include <N_LAS_Matrix.h>
75 #include <N_LAS_MultiVector.h>
76 #include <N_LAS_Vector.h>
110 U_LOGIC,
CAT_VOLT,
"Initial condition of no voltage drops accross device");
114 U_LOGIC,
CAT_NONE,
"Flag for toggling the use of the lambert-W function instead of exponentials.");
560 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
569 externalNodeMode(false),
586 tleakBEEmissionCoeff(1.5),
587 tleakBCEmissionCoeff(2.0),
687 li_store_capeqCB(-1),
709 AEmitEquEmitPNodeOffset(-1),
710 AEmitPEquEmitNodeOffset(-1),
711 ABaseEquBasePNodeOffset(-1),
712 ABasePEquBaseNodeOffset(-1),
713 ACollEquCollPNodeOffset(-1),
714 ACollPEquCollNodeOffset(-1),
715 AEmitEquEmitNodeOffset(-1),
716 AEmitPEquEmitPNodeOffset(-1),
717 ABaseEquBaseNodeOffset(-1),
718 ABasePEquBasePNodeOffset(-1),
719 ACollEquCollNodeOffset(-1),
720 ACollPEquCollPNodeOffset(-1),
721 AEmitPEquBasePNodeOffset(-1),
722 ABasePEquEmitPNodeOffset(-1),
723 AEmitPEquCollPNodeOffset(-1),
724 ACollPEquEmitPNodeOffset(-1),
725 ABasePEquCollPNodeOffset(-1),
726 ACollPEquBasePNodeOffset(-1),
727 ABaseEquCollPNodeOffset(-1),
728 ACollPEquBaseNodeOffset(-1),
729 ASubstEquSubstNodeOffset(-1),
730 ASubstEquCollPNodeOffset(-1),
731 ACollPEquSubstNodeOffset(-1),
732 ABaseEquEmitPNodeOffset(-1) ,
733 ACollPEquIfxNodeOffset(-1),
734 AEmitPEquIfxNodeOffset(-1),
735 AIfxEquCollPNodeOffset(-1),
736 AIfxEquBasePNodeOffset(-1),
737 AIfxEquEmitPNodeOffset(-1),
738 AIfxEquIfxNodeOffset(-1),
739 AIfxEqudIfxNodeOffset(-1),
740 AdIfxEquCollPNodeOffset(-1),
741 AdIfxEquBasePNodeOffset(-1),
742 AdIfxEquEmitPNodeOffset(-1),
743 AdIfxEquIfxNodeOffset(-1),
744 AdIfxEqudIfxNodeOffset(-1),
748 f_EmitEquEmitPNodePtr(0),
749 f_EmitPEquEmitNodePtr(0),
750 f_BaseEquBasePNodePtr(0),
751 f_BasePEquBaseNodePtr(0),
752 f_CollEquCollPNodePtr(0),
753 f_CollPEquCollNodePtr(0),
754 f_EmitEquEmitNodePtr(0),
755 f_EmitPEquEmitPNodePtr(0),
756 f_BaseEquBaseNodePtr(0),
757 f_BasePEquBasePNodePtr(0),
758 f_CollEquCollNodePtr(0),
759 f_CollPEquCollPNodePtr(0),
760 f_EmitPEquBasePNodePtr(0),
761 f_BasePEquEmitPNodePtr(0),
762 f_EmitPEquCollPNodePtr(0),
763 f_CollPEquEmitPNodePtr(0),
764 f_BasePEquCollPNodePtr(0),
765 f_CollPEquBasePNodePtr(0),
766 f_BaseEquCollPNodePtr(0),
767 f_CollPEquBaseNodePtr(0),
768 f_SubstEquSubstNodePtr(0),
769 f_SubstEquCollPNodePtr(0),
770 f_CollPEquSubstNodePtr(0),
771 f_BaseEquEmitPNodePtr(0),
774 f_CollPEquIfxNodePtr(0),
775 f_EmitPEquIfxNodePtr(0),
778 f_IfxEquCollPNodePtr(0),
779 f_IfxEquBasePNodePtr(0),
780 f_IfxEquEmitPNodePtr(0),
782 f_IfxEquIfxNodePtr(0),
783 f_IfxEqudIfxNodePtr(0),
785 f_dIfxEquCollPNodePtr(0),
786 f_dIfxEquBasePNodePtr(0),
787 f_dIfxEquEmitPNodePtr(0),
788 f_dIfxEquIfxNodePtr(0),
789 f_dIfxEqudIfxNodePtr(0),
793 q_EmitEquEmitPNodePtr(0),
794 q_EmitPEquEmitNodePtr(0),
795 q_BaseEquBasePNodePtr(0),
796 q_BasePEquBaseNodePtr(0),
797 q_CollEquCollPNodePtr(0),
798 q_CollPEquCollNodePtr(0),
799 q_EmitEquEmitNodePtr(0),
800 q_EmitPEquEmitPNodePtr(0),
801 q_BaseEquBaseNodePtr(0),
802 q_BasePEquBasePNodePtr(0),
803 q_CollEquCollNodePtr(0),
804 q_CollPEquCollPNodePtr(0),
805 q_EmitPEquBasePNodePtr(0),
806 q_BasePEquEmitPNodePtr(0),
807 q_EmitPEquCollPNodePtr(0),
808 q_CollPEquEmitPNodePtr(0),
809 q_BasePEquCollPNodePtr(0),
810 q_CollPEquBasePNodePtr(0),
811 q_BaseEquCollPNodePtr(0),
812 q_CollPEquBaseNodePtr(0),
813 q_SubstEquSubstNodePtr(0),
814 q_SubstEquCollPNodePtr(0),
815 q_CollPEquSubstNodePtr(0),
816 q_BaseEquEmitPNodePtr(0),
819 q_CollPEquIfxNodePtr(0),
820 q_EmitPEquIfxNodePtr(0),
823 q_IfxEquCollPNodePtr(0),
824 q_IfxEquBasePNodePtr(0),
825 q_IfxEquEmitPNodePtr(0),
827 q_IfxEquIfxNodePtr(0),
828 q_IfxEqudIfxNodePtr(0),
830 q_dIfxEquCollPNodePtr(0),
831 q_dIfxEquBasePNodePtr(0),
832 q_dIfxEquEmitPNodePtr(0),
833 q_dIfxEquIfxNodePtr(0),
834 q_dIfxEqudIfxNodePtr(0),
1011 int numExist = cNode + eNode + bNode;
1013 if (numExtVars <= 4)
1021 if (numExtVars != 4 + numExist)
1023 std::string msg =
":";
1024 msg +=
" name = " +
getName();
1025 msg +=
" wrong number of external nodes are set!";
1026 msg +=
" Either set none of them, or set them all.";
1027 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1065 const std::vector<int> & extLIDVecRef )
1070 #ifdef Xyce_DEBUG_DEVICE
1073 Xyce::dout() << section_divider << std::endl;
1074 Xyce::dout() <<
" BJTInstance::registerLIDs" <<std::endl;
1075 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1076 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
1077 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
1078 Xyce::dout() <<
" numIntVars = " <<
numIntVars << std::endl;
1079 Xyce::dout() <<
" numExtVars = " <<
numExtVars << std::endl;
1087 #ifdef Xyce_DEBUG_DEVICE
1090 Xyce::dout() <<
" Internal LID List" << std::endl;
1091 for(
int i = 0; i <
intLIDVec.size(); ++i )
1092 Xyce::dout() <<
" " <<
intLIDVec[i] << std::endl;
1093 Xyce::dout() <<
" External LID List" << std::endl;
1094 for(
int i = 0; i <
extLIDVec.size(); ++i )
1095 Xyce::dout() <<
" " <<
extLIDVec[i] << std::endl;
1158 #ifdef Xyce_DEBUG_DEVICE
1161 Xyce::dout() <<
" li_Coll = " <<
li_Coll << std::endl;
1162 Xyce::dout() <<
" li_CollP = " <<
li_CollP << std::endl;
1163 Xyce::dout() <<
" li_Base = " <<
li_Base << std::endl;
1164 Xyce::dout() <<
" li_BaseP = " <<
li_BaseP << std::endl;
1165 Xyce::dout() <<
" li_Emit = " <<
li_Emit << std::endl;
1166 Xyce::dout() <<
" li_EmitP = " <<
li_EmitP << std::endl;
1167 Xyce::dout() <<
" li_Subst = " <<
li_Subst << std::endl;
1171 Xyce::dout() <<
" li_Ifx = " <<
li_Ifx << std::endl;
1172 Xyce::dout() <<
" li_dIfx = " <<
li_dIfx << std::endl;
1175 Xyce::dout() << section_divider << std::endl;
1198 tmpstr =
getName()+
"_collectorprime";
1205 tmpstr =
getName()+
"_baseprime";
1212 tmpstr =
getName()+
"_emitterprime";
1220 tmpstr =
getName()+
"_ExcessPhase_Ifx";
1224 tmpstr =
getName()+
"_ExcessPhase_dIfx";
1248 std::string modName(
getName());
1252 tmpstr = modName+
":VBE";
1254 tmpstr = modName+
":VBC";
1256 tmpstr = modName+
":CAPEQCB";
1260 tmpstr = modName+
":DEV_IB";
1262 tmpstr = modName+
":DEV_IE";
1264 tmpstr = modName+
":DEV_IC";
1266 tmpstr = modName+
":DEV_IS";
1387 std::vector<int> map;
1388 std::vector< std::vector<int> > map2;
1512 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1633 #ifdef Xyce_DEBUG_DEVICE
1636 Xyce::dout() <<
"Start BJTInst::updateTemperature" << std::endl;
1637 Xyce::dout() <<
"temp = "<<temp << std::endl;
1640 if( temp != -999.0 )
TEMP = temp;
1660 double pbfact = -2.0 *
vt * ( 1.5 * log( fact2 ) +
CONSTQ * arg );
1665 double factor = exp( factlog );
1669 #ifdef Xyce_DEBUG_DEVICE
1672 Xyce::dout() <<
" Factor is " << factor << std::endl;
1673 Xyce::dout() <<
" Bfactor is " << bfactor << std::endl;
1674 Xyce::dout() <<
" factlog is " << factlog << std::endl;
1675 Xyce::dout() <<
" ratio1 is " << ratio1 << std::endl;
1676 Xyce::dout() <<
" TEMP is " <<
TEMP << std::endl;
1677 Xyce::dout() <<
" TNOM is " <<
model_.
TNOM << std::endl;
1690 tBEPot = fact2 * pbo + pbfact;
1692 double gmanew = (
tBEPot - pbo ) / pbo;
1702 tBCPot = fact2 * pbo + pbfact;
1704 gmanew = (
tBCPot - pbo ) / pbo;
1761 #ifdef Xyce_DEBUG_DEVICE
1765 Xyce::dout() << section_divider << std::endl;
1766 Xyce::dout() <<
"In BJTInst::updateTemperature" << std::endl;
1767 Xyce::dout() << section_divider << std::endl;
1768 Xyce::dout() <<
"TEMP = " <<
TEMP << std::endl;
1769 Xyce::dout() <<
"TNOM = " << TNOM << std::endl;
1770 Xyce::dout() <<
"vt = " <<
vt << std::endl;
1771 Xyce::dout() <<
"tSatCur = " <<
tSatCur << std::endl;
1772 Xyce::dout() <<
"tBetaF = " <<
tBetaF << std::endl;
1773 Xyce::dout() <<
"tBetaR = " <<
tBetaR << std::endl;
1774 Xyce::dout() <<
"tBELeakCur = " <<
tBELeakCur << std::endl;
1775 Xyce::dout() <<
"tBCLeakCur = " <<
tBELeakCur << std::endl;
1776 Xyce::dout() <<
"tBEPot = " <<
tBEPot << std::endl;
1777 Xyce::dout() <<
"tBECap = " <<
tBECap << std::endl;
1778 Xyce::dout() <<
"tBCPot = " <<
tBCPot << std::endl;
1779 Xyce::dout() <<
"tBCCap = " <<
tBCCap << std::endl;
1780 Xyce::dout() <<
"tDepCap = " <<
tDepCap << std::endl;
1781 Xyce::dout() <<
"tF1 = " <<
tF1 << std::endl;
1782 Xyce::dout() <<
"tF4 = " <<
tF4 << std::endl;
1783 Xyce::dout() <<
"tF5 = " <<
tF5 << std::endl;
1786 Xyce::dout() <<
"tRollOffExp = " <<
tRollOffExp << std::endl;
1787 Xyce::dout() <<
"tInvRollOffF = " <<
tInvRollOffF << std::endl;
1788 Xyce::dout() <<
"tInvRollOffR = " <<
tInvRollOffR << std::endl;
1789 Xyce::dout() <<
"tInvEarlyVoltF = " <<
tInvEarlyVoltF << std::endl;
1790 Xyce::dout() <<
"tInvEarlyVoltR = " <<
tInvEarlyVoltR << std::endl;
1791 Xyce::dout() <<
"tBaseResist = " <<
tBaseResist << std::endl;
1793 Xyce::dout() <<
"tEmitterResist = " <<
tEmitterResist << std::endl;
1794 Xyce::dout() << section_divider << std::endl;
1795 Xyce::dout() << std::endl;
1813 double RS = 1.0e-12;
1814 double arg1 = (Vd + Isat*RS)/Vte;
1816 double evd = exp(arg1);
1817 double lambWArg = Isat*RS*evd/Vte;
1823 Id = -Isat+Vte*(lambWReturn)/RS;
1824 Gd = lambWReturn / ((1 + lambWReturn)*RS);
1844 bool returnVal=
false;
1849 (*maskVectorPtr)[
li_Ifx] = 0.0;
1850 (*maskVectorPtr)[
li_dIfx] = 0.0;
1904 double Cp_Jdxp_q = 0.0;
1905 double Ep_Jdxp_q = 0.0;
1906 double Bp_Jdxp_q = 0.0;
2018 double coefC, coefB, coefE, coefCp, coefBp, coefEp;
2026 double vce_diff = vbe_diff - vbc_diff;
2065 double Cp_Jdxp_f=0.0;
2066 double Bp_Jdxp_f=0.0;
2067 double Ep_Jdxp_f=0.0;
2068 double dIfx_Jdxp_f=0.0 ;
2069 double Ifx_Jdxp_f=0.0 ;
2114 dFdxdVp[
li_dIfx] += dIfx_Jdxp_f;
2118 dFdxdVp[
li_Ifx] += Ifx_Jdxp_f;
2434 (
double & iEX,
double & gEX,
double & iC_local)
2437 double td = model_.excessPhaseFac;
2439 #ifdef Xyce_DEBUG_DEVICE
2440 if (getDeviceOptions().debugLevel > 0 && getSolverState().debugTimeFlag)
2442 Xyce::dout() << std::endl;
2443 Xyce::dout() <<
" Excess Phase stuff:" <<std::endl;
2444 Xyce::dout() <<
" name = " << getName() <<std::endl;
2445 Xyce::dout() <<
" td = " << td <<std::endl;
2461 dt0 = getSolverState().currTimeStep;
2462 dt1 = getSolverState().lastTimeStep;
2467 if (!(getSolverState().dcopFlag) && td != 0)
2469 double arg1, arg2, denom;
2474 denom = 1.0 + arg1 + arg2;
2475 phaseScalar = arg1 / denom;
2478 if (!getSolverState().beginIntegrationFlag)
2480 currCexbc = (*extData.currStaVectorPtr)[li_istateCEXBC];
2481 lastCexbc = (*extData.lastStaVectorPtr)[li_istateCEXBC];
2484 iC_local = ((currCexbc) * (1 + dt0 / dt1 + arg2) - (lastCexbc) * dt0 / dt1) / denom;
2485 iEX = iBE * phaseScalar;
2486 gEX = gBE * phaseScalar;
2488 nextCexbc = iC_local + iEX / qB;
2489 (*extData.nextStaVectorPtr)[li_istateCEXBC] = nextCexbc;
2506 bool bsuccess =
true;
2508 double v_emit, v_emitP;
2509 double v_base, v_baseP;
2510 double v_coll, v_collP;
2516 #ifdef Xyce_DEBUG_DEVICE
2519 Xyce::dout() << Xyce::section_divider << std::endl;
2520 Xyce::dout() <<
"Instance::updateIntermediateVars " <<
getName() <<std::endl;
2533 vEEp = (v_emit - v_emitP);
2534 vBBp = (v_base - v_baseP);
2535 vCCp = (v_coll - v_collP);
2565 if ((*flagSolVectorPtr)[
li_Emit] == 0 || (*flagSolVectorPtr)[
li_EmitP] == 0 ||
2566 (*flagSolVectorPtr)[
li_Base] == 0 || (*flagSolVectorPtr)[
li_BaseP] == 0 ||
2567 (*flagSolVectorPtr)[
li_Coll] == 0 || (*flagSolVectorPtr)[
li_CollP] == 0 ||
2568 (*flagSolVectorPtr)[
li_Subst] == 0 )
2581 #ifdef Xyce_DEBUG_DEVICE
2584 Xyce::dout() <<
" Setting device initial condition to Base-Emitter drop=tVCrit (" <<
tVCrit <<
")"<<std::endl;
2591 #ifdef Xyce_DEBUG_DEVICE
2594 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2595 Xyce::dout() <<
" " <<std::endl;
2596 Xyce::dout() <<
" using UIC.\n";
2597 Xyce::dout() <<
" vBE = " <<
vBE << std::endl;
2598 Xyce::dout() <<
" vBC = " <<
vBC << std::endl;
2599 Xyce::dout() <<
" vBX = " <<
vBX << std::endl;
2600 Xyce::dout() <<
" vCS = " <<
vCS << std::endl;
2615 #ifdef Xyce_DEBUG_DEVICE
2618 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2619 Xyce::dout() <<
" " <<std::endl;
2620 Xyce::dout() <<
" BJT explicitly set OFF, zeroing all junction drops.\n";
2648 #ifdef Xyce_DEBUG_DEVICE
2651 Xyce::dout() <<
" tVCrit = " <<
tVCrit << std::endl;
2652 Xyce::dout().width(3);
2654 Xyce::dout().width(5); Xyce::dout() <<
getName();
2655 Xyce::dout() <<
" Blim: ";
2656 Xyce::dout() <<
" vBE=";
2657 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2658 Xyce::dout() <<
vBE;
2659 Xyce::dout() <<
" vBC=";
2660 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2661 Xyce::dout() <<
vBC << std::endl;
2682 if (ichk1 == 1) icheck=1;
2688 #ifdef Xyce_DEBUG_DEVICE
2691 Xyce::dout().width(3);
2693 Xyce::dout().width(5); Xyce::dout() <<
getName() ;
2694 Xyce::dout() <<
" Alim: ";
2695 Xyce::dout() <<
" vBE=";
2696 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2697 Xyce::dout() <<
vBE;
2698 Xyce::dout() <<
" vBC=";
2699 Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
2700 Xyce::dout() <<
vBC;
2706 if (
origFlag) Xyce::dout() <<
" SAME";
2707 else Xyce::dout() <<
" DIFF";
2708 Xyce::dout() << std::endl;
2726 if(
vBE > -5.0 * vtF )
2730 if( iLeakBE == 0.0 )
2745 if(
vBC > -5.0 * vtR )
2749 if( iLeakBC == 0.0 )
2768 if (
vBE > -5.0 * vtF)
2770 double arg1 =
vBE / vtF ;
2790 double arg1 =
vBE / vtE ;
2800 evBEleak = exp(arg1);
2803 iBEleak = iLeakBE * (evBEleak - 1.0);
2804 gBEleak = iLeakBE * devBEleak / vtE;
2815 if(
vBC > -5.0 * vtR )
2817 double arg1 =
vBC / vtR ;
2837 double arg1 =
vBC / vtC ;
2847 evBCleak = exp(arg1);
2850 iBCleak = iLeakBC * (evBCleak - 1.0);
2851 gBCleak = iLeakBC * devBCleak / vtC;
2869 if (rofF == 0.0 && rofR == 0.0)
2872 double q1_qB = q1 *
qB;
2882 q2 = rofF *
iBE + rofR *
iBC;
2895 double arg = 1.0 + 4.0 * q2;
2903 if (fabs(arg) > 0.0) sqarg = pow(arg,
tRollOffExp);
2904 double rofF_gBE_invSqarg = 0.0;
2905 double rofR_gBC_invSqarg = 0.0;
2906 if(arg != 0) rofF_gBE_invSqarg = rofF*
gBE*2*
tRollOffExp*sqarg/arg;
2907 if(arg != 0) rofR_gBC_invSqarg = rofR*
gBC*2*
tRollOffExp*sqarg/arg;
2909 qB = 0.5 * q1 * (1.0 + sqarg);
2964 bool geqCB_recalc(
false);
2987 arg2 = argtf * (3.0 - 2.0 * tmp);
2997 geqCB_recalc =
true;
3092 qBX =
tBCPot * czBX * ( 1.0 - arg * sarg ) /
3094 capBX = czBX * sarg;
3123 capCS = czCS * sarg;
3139 double iEX_tmp = 0.0;
double gEX_tmp = 0.0;
double iC_tmp = 0.0;
3213 gX = rBpr + rBpi /
qB;
3215 if (fabs(xjrB) > 0.0)
3217 double arg1 = Xycemax(
iB / xjrB, 1.0e-09);
3218 double arg2 = (-1.0 + sqrt( 1.0 + 14.59025 * arg1)) / 2.4317 / sqrt(arg1);
3220 gX = rBpr + 3.0 * rBpi * (arg1 - arg2) / arg2 / arg1 / arg1;
3223 if (fabs(
gX) > 0.0)
gX = 1.0 /
gX;
3246 bool bsuccess =
true;
3249 char filename[32];
for(i=0;i<32;++i) filename[i] = static_cast<char>(0);
3251 sprintf(filename,
"Q_%s.dat",
getName().c_str());
3258 fp1 = fopen(filename,
"w");
3262 fp1 = fopen(filename,
"a");
3268 " TITLE = \"Debug Excess Phase data: %s \"\n",
getName().c_str());
3273 fprintf(fp1,
"%s",
"\tVARIABLES = \"TIME (S)\",\n");
3275 fprintf(fp1,
"%s",
"\t \"iBE/qB \",\n");
3276 fprintf(fp1,
"%s",
"\t \"currCexbc \",\n");
3277 fprintf(fp1,
"%s",
"\t \"lastCexbc \",\n");
3280 fprintf(fp1,
"%s",
"\t \"i_fx \",\n");
3281 fprintf(fp1,
"%s",
"\t \"di_fx \",\n");
3284 fprintf(fp1,
"%s",
"\tZONE F=POINT T=\"Excess Phase Data\"\n");
3287 fprintf(fp1,
" %12.4e",time);
3288 fprintf(fp1,
" %12.4e",(
iBE/
qB));
3295 double i_fx = solVec[
li_Ifx];
3296 double di_fx = solVec[
li_dIfx];
3297 fprintf(fp1,
" %12.4e",i_fx);
3298 fprintf(fp1,
" %12.4e",di_fx);
3301 fprintf(fp1,
"%s",
"\n");
3372 Xyce::dout() <<
"Bad Depletion Capacitance Coefficient" << std::endl;
3401 std::vector<Instance*>::iterator iter;
3405 for (iter=first; iter!=last; ++iter)
3407 (*iter)->processParams();
3425 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
3432 emissionCoeffF(1.0),
3442 leakBEEmissionCoeff(1.5),
3448 emissionCoeffR(1.0),
3459 leakBCEmissionCoeff(2.0),
3461 baseCurrHalfResist(0.0),
3465 minBaseResist(baseResist),
3467 collectorResist(0.0),
3478 transTimeBiasCoeffF(0.0),
3479 transTimeFVBC(1.e99),
3480 transTimeHighCurrF(0.0),
3531 leakBCCurrentGiven(false),
3533 leakBECurrentGiven(false),
3535 minBaseResistGiven(false),
3550 UserError0(*
this) <<
"Both BF and BFM are set, which is redundant.";
3560 UserError0(*
this) <<
"Both BR and BRM are set, which is redundant.";
3568 int VAFgivenCount = 0;
3572 if (VAFgivenCount > 1)
3574 UserError0(*
this) <<
"The forward early voltage is set more than once. VA, VAF and VBF are aliases.";
3576 if (VAFgivenCount > 0)
3582 int VARgivenCount = 0;
3587 if (VARgivenCount > 1)
3589 UserError0(*
this) <<
"The reverse early voltage is set more than once. VAR,VB,VRB and BV are aliases.";
3591 if (VARgivenCount > 0)
3597 int IKFgivenCount = 0;
3601 if (IKFgivenCount > 1)
3603 UserError0(*
this) <<
"High current roll-off is set more than once (IKF, JBF or IK).";
3605 if (IKFgivenCount > 0)
3613 UserError0(*
this) <<
"Both IKR and JBRgiven are set, which is redundant.";
3624 UserError0(*
this) <<
"Both JLE and ISE are set, which is redundant.";
3635 UserError0(*
this) <<
"Both JLC and ISC are set, which is redundant.";
3645 UserError0(*
this) <<
"Both NLE and NE are set, which is redundant.";
3655 UserError0(*
this) <<
" Both MJE and ME are set, which is redundant.";
3665 UserError0(*
this) <<
"Both MJC and MC are set, which is redundant.";
3673 int CJSgivenCount = 0;
3677 if (CJSgivenCount > 1)
3679 UserError0(*
this) <<
"The zero-bias collector-substrate capacitance (CJS, CCS or CSUB) is set more than once.";
3681 if (CJSgivenCount > 0)
3687 int IRBgivenCount = 0;
3691 if (IRBgivenCount > 1)
3693 UserError0(*
this) <<
"The current for 1/2 base resistance (IRB, JRB or IOB) is set more than once.";
3695 if (IRBgivenCount > 0)
3703 UserError0(*
this) <<
"The BE built-in potential (VJE or PE) is set more than once.";
3713 UserError0(*
this) <<
"The BC built-in potential (VJC or PC) is set more than once.";
3723 UserError0(*
this) <<
"XCJC and CDIS are both set (they are aliases).";
3731 int VJSgivenCount = 0;
3735 if (VJSgivenCount > 1)
3737 UserError0(*
this) <<
"The forward early voltage is set more than once. PS, VJS and PSUB are aliases.";
3739 if (VJSgivenCount > 0)
3745 int MJSgivenCount = 0;
3749 if (MJSgivenCount > 1)
3751 UserError0(*
this) <<
"The forward early voltage is set more than once. MS, MJS and ESUB are aliases.";
3753 if (MJSgivenCount > 0)
3761 UserError0(*
this) <<
"ITF and JTF are both set (they are aliases).";
3771 UserError0(*
this) <<
"NK and NKF are both set (they are aliases).";
3779 int XTBgivenCount = 0;
3783 if (XTBgivenCount > 1)
3785 UserError0(*
this) <<
"The forward early voltage is set more than once. TB, XTB and TCB are aliases.";
3787 if (XTBgivenCount > 0)
3796 UserError0(*
this) <<
"PT and XTI are both set (they are aliases).";
3837 std::vector<Instance*>::iterator iterI;
3842 for (iterI = firstI; iterI != lastI; ++iterI)
3859 std::vector<Instance*>::const_iterator iter;
3864 os <<
" name modelName Parameters" << std::endl;
3865 for (i = 0, iter = first; iter != last; ++iter, ++i)
3867 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
3871 os <<
" AREA = " << (*iter)->AREA << std::endl;
3872 os <<
" icVBE = " << (*iter)->icVBE << std::endl;
3873 os <<
" icVCE = " << (*iter)->icVCE << std::endl;
3874 os <<
" TEMP = " << (*iter)->TEMP << std::endl;
3875 os <<
" OFF = " << (*iter)->OFF << std::endl;
3901 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
3920 bool bsuccess =
true;
3930 bsuccess = bsuccess && btmp;
3976 bool bsuccess =
true;
4014 double vce_diff = vbe_diff - vbc_diff;
4030 i_fx = solVec[bi.
li_Ifx];
4038 fVec[bi.
li_Ifx] += - di_fx;
4039 fVec[bi.
li_dIfx] += 3 * di_fx*td + 3*i_fx -3 * bi.
iBE / bi.
qB;
4079 double Cp_Jdxp_f(0.0), Bp_Jdxp_f(0.0), Ep_Jdxp_f(0.0),
4080 dIfx_Jdxp_f(0.0 ), Ifx_Jdxp_f(0.0 ),
4081 Cp_Jdxp_q ( 0.0), Ep_Jdxp_q ( 0.0), Bp_Jdxp_q ( 0.0);
4086 Cp_Jdxp_f = + bi.
diCEdvBp * vbe_diff
4092 Bp_Jdxp_f = bi.
gBEtot * vbe_diff + bi.
gBCtot * vbc_diff;
4124 dFdxdVp[bi.
li_dIfx] += dIfx_Jdxp_f;
4128 dFdxdVp[bi.
li_Ifx] += Ifx_Jdxp_f;
4187 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
4404 .registerDevice(
"q", 1)
4405 .registerModelType(
"pnp", 1)
4406 .registerModelType(
"npn", 1);