45 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
71 #include <N_ERH_ErrorMgr.h>
75 #include <N_LAS_Matrix.h>
76 #include <N_LAS_Vector.h>
195 U_OHM,
CAT_RES,
"Drain, source diffusion sheet resistance");
237 U_NONE,
CAT_CAP,
"Coefficient for forward-bias depletion capacitance formula");
301 U_NONE,
CAT_NONE,
"Body effect constant in front of linear term");
373 U_NONE,
CAT_GEOMETRY,
"Transition width parameter used by the charge partitioning scheme");
381 U_NONE,
CAT_NONE,
"Parameter accounting for the threshold dependence on the channel potential");
414 U_OHM,
CAT_RES,
"Drift region resistance intercept parameter");
462 U_NONE,
CAT_CAP,
"Drain-source diode forward bias depletion capacitance");
467 U_VOLT,
CAT_VOLT,
"Drain-source diode reverse breakdown voltage");
501 " 0 = aluminum, 1 = opposite of substrate)");
589 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
595 tnom(getDeviceOptions().tnom),
597 jctSatCurDensity(0.0),
599 drainResistance(0.0),
601 sourceResistance(0.0),
602 sheetResistance(0.0),
603 gateSourceOverlapCapFactor(0.0),
604 gateDrainOverlapCapFactor(0.0),
605 gateBulkOverlapCapFactor(0.0),
612 sideWallCapFactor(0.0),
613 bulkJctPotential(0.0),
614 bulkJctBotGradingCoeff(0.0),
615 bulkJctSideGradingCoeff(0.0),
620 substrateDoping(0.0),
621 surfaceStateDensity(0.0),
623 surfaceMobility(0.0),
624 surfaceMobility0(0.0),
628 bulkCapFactorGiven(0),
629 sideWallCapFactorGiven(0),
705 D1DIOconductance(0.0),
706 D1DIOemissionCoeff(0.0),
707 D1DIOtransitTime(0.0),
708 D1DIOjunctionCap(0.0),
709 D1DIOjunctionPot(0.0),
710 D1DIOgradingCoeff(0.0),
711 D1DIOactivationEnergy(0.0),
712 D1DIOsaturationCurrentExp(0.0),
713 D1DIOdepletionCapCoeff(0.0),
714 D1DIObreakdownVoltage(0.0),
715 D1DIObreakdownCurrent(0.0),
724 D1DIObreakdownVoltageGiven(0)
733 else if (
getType() ==
"PMOS") {
771 UserError0(*
this) <<
"You have specified both uo and u0, which is not allowed.";
773 UserWarning0(*
this) <<
"You have specified the surface mobility as u0 instead of uo. This is supported, but ill-advised.";
780 UserError0(*
this) <<
"ETA cannot be zero for level 18";
785 UserError0(*
this) <<
"Both driftParamA and driftParamB cannot be zero";
788 if(
cv != 1 &&
cv != 2)
790 UserError0(*
this) <<
"Model error: use cv=1 (Meyer's model) or cv=2 (Meyer-like Model)";
795 UserError0(*
this) <<
"Model error: use fpe=1 (and xqc), fpe=2 (and xqc,mcv) or fpe=3";
800 UserError0(*
this) <<
"Model error: charge conservation requires mcv > 1";
805 UserError0(*
this) <<
"Model error: charge conservation requires 0.5 <= xqc <= 1.0";
815 UserWarning0(*
this) <<
"grading coefficient too large, limited to 0.9";
822 UserWarning0(*
this) <<
"activation energy too small, limited to 0.1";
829 UserWarning0(*
this) <<
"coefficient Fc too large, limited to 0.95";
835 #ifdef Xyce_DEBUG_DEVICE
838 Xyce::dout() <<
" " << std::endl;
839 Xyce::dout() <<
"l0 " <<
l0 << std::endl;
840 Xyce::dout() <<
"w0 " <<
w0 << std::endl;
841 Xyce::dout() <<
"vt0 = " <<
vt0 << std::endl;
842 Xyce::dout() <<
"gamma = " <<
gamma << std::endl;
843 Xyce::dout() <<
"lambda = " <<
lambda << std::endl;
844 Xyce::dout() <<
"phi = " <<
phi << std::endl;
846 Xyce::dout() <<
"gateResistance = " <<
gateResistance << std::endl;
848 Xyce::dout() <<
"capBD = " <<
capBD << std::endl;
849 Xyce::dout() <<
"capBS = " <<
capBS << std::endl;
850 Xyce::dout() <<
"timeScale = " <<
timeScale << std::endl;
851 Xyce::dout() <<
"jctSatCur = " <<
jctSatCur << std::endl;
857 Xyce::dout() <<
"bulkCapFactor = " <<
bulkCapFactor << std::endl;
862 Xyce::dout() <<
"oxideThickness = " <<
oxideThickness << std::endl;
863 Xyce::dout() <<
"oxideCapFactor = " <<
oxideCapFactor << std::endl;
864 Xyce::dout() <<
"latDiff = " <<
latDiff << std::endl;
866 Xyce::dout() <<
"fwdCapDepCoeff = " <<
fwdCapDepCoeff << std::endl;
868 Xyce::dout() <<
"gateType = " <<
gateType << std::endl;
870 Xyce::dout() <<
"tnom = " <<
tnom << std::endl;
871 Xyce::dout() <<
"driftParamA = " <<
driftParamA << std::endl;
872 Xyce::dout() <<
"driftParamB = " <<
driftParamB << std::endl;
873 Xyce::dout() <<
"rdsshunt = " <<
rdsshunt << std::endl;
889 std::vector<Instance*>::iterator iter;
893 for (iter=first; iter!=last; ++iter)
911 std::vector<Instance*>::const_iterator iter;
917 os <<
" name model name Parameters" << std::endl;
918 for (i=0, iter=first; iter!=last; ++iter, ++i)
920 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
946 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
971 egfet1 = 1.16-(7.02e-4*tnom*
tnom)/(tnom+1108);
993 wkfng = 3.25 + 0.5 *
egfet1 - fermig;
995 wkfngs = wkfng - (3.25 + 0.5 *
egfet1 + fermis);
1029 if(fabs(
vfb) < 1e-12)
vfb = 1e-12;
1060 std::vector<Instance*>::iterator iter;
1064 for (iter=first; iter!=last; ++iter)
1066 (*iter)->processParams();
1088 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
1097 l(getDeviceOptions().defl),
1098 w(getDeviceOptions().defw),
1099 drainArea(getDeviceOptions().defad),
1100 sourceArea(getDeviceOptions().defas),
1103 drainPerimeter(0.0),
1104 sourcePerimeter(0.0),
1108 draindriftCond(0.0),
1117 temp(getDeviceOptions().temp.getImmutableValue<double>()),
1136 draindriftVcrit(0.0),
1171 GateSourceOverlapCap(0),
1172 GateDrainOverlapCap(0),
1173 GateBulkOverlapCap(0),
1208 D1DIOcapCharge(0.0),
1209 D1DIOcapCurrent(0.0),
1245 li_SourcePrime (-1),
1255 ADrainEquDrainNodeOffset (-1),
1256 ADrainEquSourceNodeOffset (-1),
1257 ADrainEquDrainDriftNodeOffset (-1),
1258 ADrainEquD1PrimeNodeOffset (-1),
1260 AGateEquGateNodeOffset (-1),
1261 AGateEquGatePrimeNodeOffset (-1),
1263 ASourceEquDrainNodeOffset (-1),
1264 ASourceEquSourceNodeOffset (-1),
1265 ASourceEquSourcePrimeNodeOffset (-1),
1267 ABulkEquBulkNodeOffset (-1),
1268 ABulkEquDrainPrimeNodeOffset (-1),
1269 ABulkEquGatePrimeNodeOffset (-1),
1270 ABulkEquSourcePrimeNodeOffset (-1),
1272 ADrainPrimeEquBulkNodeOffset (-1),
1273 ADrainPrimeEquDrainPrimeNodeOffset (-1),
1274 ADrainPrimeEquGatePrimeNodeOffset (-1),
1275 ADrainPrimeEquSourcePrimeNodeOffset (-1),
1276 ADrainPrimeEquDrainDriftNodeOffset (-1),
1278 AGatePrimeEquGateNodeOffset (-1),
1279 AGatePrimeEquBulkNodeOffset (-1),
1280 AGatePrimeEquDrainPrimeNodeOffset (-1),
1281 AGatePrimeEquGatePrimeNodeOffset (-1),
1282 AGatePrimeEquSourcePrimeNodeOffset (-1),
1284 ASourcePrimeEquSourceNodeOffset (-1),
1285 ASourcePrimeEquBulkNodeOffset (-1),
1286 ASourcePrimeEquDrainPrimeNodeOffset (-1),
1287 ASourcePrimeEquGatePrimeNodeOffset (-1),
1288 ASourcePrimeEquSourcePrimeNodeOffset (-1),
1290 ADrainDriftEquDrainNodeOffset (-1),
1291 ADrainDriftEquDrainPrimeNodeOffset (-1),
1292 ADrainDriftEquDrainDriftNodeOffset (-1),
1294 AD1PrimeEquDrainNodeOffset (-1),
1295 AD1PrimeEquSourceNodeOffset (-1),
1296 AD1PrimeEquD1PrimeNodeOffset (-1),
1300 f_DrainEquDrainNodePtr(0),
1301 f_DrainEquSourceNodePtr(0),
1302 f_DrainEquDrainDriftNodePtr(0),
1303 f_DrainEquD1PrimeNodePtr(0),
1305 f_GateEquGateNodePtr(0),
1306 f_GateEquGatePrimeNodePtr(0),
1308 f_SourceEquDrainNodePtr(0),
1309 f_SourceEquSourceNodePtr(0),
1310 f_SourceEquSourcePrimeNodePtr(0),
1311 f_SourceEquD1PrimeNodePtr(0),
1313 f_BulkEquBulkNodePtr(0),
1314 f_BulkEquDrainPrimeNodePtr(0),
1315 f_BulkEquGatePrimeNodePtr(0),
1316 f_BulkEquSourcePrimeNodePtr(0),
1318 f_DrainPrimeEquBulkNodePtr(0),
1319 f_DrainPrimeEquDrainPrimeNodePtr(0),
1320 f_DrainPrimeEquGatePrimeNodePtr(0),
1321 f_DrainPrimeEquSourcePrimeNodePtr(0),
1322 f_DrainPrimeEquDrainDriftNodePtr(0),
1324 f_GatePrimeEquGateNodePtr(0),
1325 f_GatePrimeEquBulkNodePtr(0),
1326 f_GatePrimeEquDrainPrimeNodePtr(0),
1327 f_GatePrimeEquGatePrimeNodePtr(0),
1328 f_GatePrimeEquSourcePrimeNodePtr(0),
1330 f_SourcePrimeEquSourceNodePtr(0),
1331 f_SourcePrimeEquBulkNodePtr(0),
1332 f_SourcePrimeEquDrainPrimeNodePtr(0),
1333 f_SourcePrimeEquGatePrimeNodePtr(0),
1334 f_SourcePrimeEquSourcePrimeNodePtr(0),
1336 f_DrainDriftEquDrainNodePtr(0),
1337 f_DrainDriftEquDrainPrimeNodePtr(0),
1338 f_DrainDriftEquDrainDriftNodePtr(0),
1340 f_D1PrimeEquDrainNodePtr(0),
1341 f_D1PrimeEquSourceNodePtr(0),
1342 f_D1PrimeEquD1PrimeNodePtr(0),
1345 q_DrainEquDrainNodePtr(0),
1346 q_DrainEquSourceNodePtr(0),
1347 q_DrainEquDrainDriftNodePtr(0),
1348 q_DrainEquD1PrimeNodePtr(0),
1350 q_GateEquGateNodePtr(0),
1351 q_GateEquGatePrimeNodePtr(0),
1353 q_SourceEquDrainNodePtr(0),
1354 q_SourceEquSourceNodePtr(0),
1355 q_SourceEquSourcePrimeNodePtr(0),
1356 q_SourceEquD1PrimeNodePtr(0),
1358 q_BulkEquBulkNodePtr(0),
1359 q_BulkEquDrainPrimeNodePtr(0),
1360 q_BulkEquGatePrimeNodePtr(0),
1361 q_BulkEquSourcePrimeNodePtr(0),
1363 q_DrainPrimeEquBulkNodePtr(0),
1364 q_DrainPrimeEquDrainPrimeNodePtr(0),
1365 q_DrainPrimeEquGatePrimeNodePtr(0),
1366 q_DrainPrimeEquSourcePrimeNodePtr(0),
1367 q_DrainPrimeEquDrainDriftNodePtr(0),
1369 q_GatePrimeEquGateNodePtr(0),
1370 q_GatePrimeEquBulkNodePtr(0),
1371 q_GatePrimeEquDrainPrimeNodePtr(0),
1372 q_GatePrimeEquGatePrimeNodePtr(0),
1373 q_GatePrimeEquSourcePrimeNodePtr(0),
1375 q_SourcePrimeEquSourceNodePtr(0),
1376 q_SourcePrimeEquBulkNodePtr(0),
1377 q_SourcePrimeEquDrainPrimeNodePtr(0),
1378 q_SourcePrimeEquGatePrimeNodePtr(0),
1379 q_SourcePrimeEquSourcePrimeNodePtr(0),
1381 q_DrainDriftEquDrainNodePtr(0),
1382 q_DrainDriftEquDrainPrimeNodePtr(0),
1383 q_DrainDriftEquDrainDriftNodePtr(0),
1385 q_D1PrimeEquDrainNodePtr(0),
1386 q_D1PrimeEquSourceNodePtr(0),
1387 q_D1PrimeEquD1PrimeNodePtr(0),
1436 li_state_capgdd(-1),
1446 li_state_D1DIOcapCharge(-1),
1449 li_store_dev_id(-1),
1450 li_store_dev_ig(-1),
1451 li_store_dev_is(-1),
1671 UserError0(*
this) <<
"Effective channel length less than zero.";
1709 const std::vector<int> & extLIDVecRef )
1714 #ifdef Xyce_DEBUG_DEVICE
1717 Xyce::dout() << section_divider << std::endl;
1718 Xyce::dout() <<
" In Instance::register LIDs\n\n";
1719 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1720 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
1721 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
1761 #ifdef Xyce_DEBUG_DEVICE
1764 Xyce::dout() <<
"\n variable local indices:\n";
1765 Xyce::dout() <<
" li_Drain = " <<
li_Drain << std::endl;
1766 Xyce::dout() <<
" li_Source = " <<
li_Source << std::endl;
1767 Xyce::dout() <<
" li_Gate = " <<
li_Gate << std::endl;
1768 Xyce::dout() <<
" li_Bulk = " <<
li_Bulk << std::endl;
1769 Xyce::dout() <<
" li_DrainPrime = " <<
li_DrainPrime << std::endl;
1770 Xyce::dout() <<
" li_GatePrime = " <<
li_GatePrime << std::endl;
1771 Xyce::dout() <<
" li_SourcePrime = " <<
li_SourcePrime << std::endl;
1772 Xyce::dout() <<
" li_DrainDrift = " <<
li_DrainDrift << std::endl;
1773 Xyce::dout() <<
" li_D1Prime = " <<
li_D1Prime << std::endl;
1775 Xyce::dout() << section_divider << std::endl;
1796 tmpstr =
getName()+
"_drainprime";
1802 tmpstr =
getName()+
"_gateprime";
1809 tmpstr =
getName()+
"_sourceprime";
1816 tmpstr =
getName()+
"_draindrift";
1844 #ifdef Xyce_DEBUG_DEVICE
1847 Xyce::dout() << std::endl;
1848 Xyce::dout() << section_divider << std::endl;
1849 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
1850 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1851 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
1886 #ifdef Xyce_DEBUG_DEVICE
1889 Xyce::dout() <<
" State local indices:" << std::endl;
1890 Xyce::dout() << std::endl;
1892 Xyce::dout() <<
" li_state_vbdd = " <<
li_state_vbdd <<
"\n";
1893 Xyce::dout() <<
" li_state_vbs = " <<
li_state_vbs <<
"\n";
1894 Xyce::dout() <<
" li_state_vgps = " <<
li_state_vgps <<
"\n";
1895 Xyce::dout() <<
" li_state_vdds = " <<
li_state_vdds <<
"\n";
1896 Xyce::dout() <<
" li_state_qgs = " <<
li_state_qgs <<
"\n";
1901 Xyce::dout() <<
" li_state_qgdd = " <<
li_state_qgdd <<
"\n";
1903 Xyce::dout() <<
" li_state_qgb = " <<
li_state_qgb <<
"\n";
1905 Xyce::dout() <<
" li_state_qbs = " <<
li_state_qbs <<
"\n";
1907 Xyce::dout() <<
" li_state_qbd = " <<
li_state_qbd <<
"\n";
1911 Xyce::dout() <<
" li_state_von = " <<
li_state_von <<
"\n";
1913 Xyce::dout() << std::endl;
1914 Xyce::dout() << section_divider << std::endl;
1959 std::string modName(
getName());
1962 tmpstr = modName+
":DEV_ID";
1964 tmpstr = modName+
":DEV_IG";
1966 tmpstr = modName+
":DEV_IS";
1968 tmpstr = modName+
":DEV_IB";
2016 std::vector<int> map;
2017 std::vector< std::vector<int> > map2;
2197 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2321 double coef_Jdxp(0.0);
2323 double ceqbs(0.0), ceqbd(0.0), ceqgb(0.0), ceqgs(0.0), ceqgdd(0.0);
2330 ceqgdd = Dtype*
qgdd;
2332 qVec[
li_Bulk] += (ceqbs + ceqbd - ceqgb);
2345 dQdxdVp[
li_Bulk] += coef_Jdxp;
2418 double coef_Jdxp(0.0), gd_Jdxp(0.0);
2422 double ceqbs = Dtype*(
cbs+
cqbs);
2423 double ceqbd = Dtype*(
cbd+
cqbd);
2425 double D1current = Dtype*
D1cdeq;
2434 fVec[
li_Bulk] += (ceqbs + ceqbd);
2446 dFdxdVp[
li_Bulk] += coef_Jdxp;
2449 coef_Jdxp = Dtype*(-((
gbd-gmin1))*
2645 bool bsuccess =
true;
2652 #define ISUBMOD model_.isubmod
2664 double capgs_old(0.0);
2665 double capgdd_old(0.0);
2666 double capgb_old(0.0);
2670 double D1power(0.0);
2675 double D1csatr(0.0);
2676 double D1czero(0.0);
2677 double D1czof2(0.0);
2681 double D1evrev(0.0);
2684 double D1vdtemp(0.0);
2688 #ifdef Xyce_DEBUG_DEVICE
2692 Xyce::dout() << subsection_divider << std::endl;
2693 Xyce::dout() <<
" Instance::updateIntermediateVars.\n"<<std::endl;
2694 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2695 Xyce::dout() <<
" Model name = " <<
model_.
getName() << std::endl;
2696 Xyce::dout() <<
" dtype is " <<
model_.
dtype << std::endl;
2697 Xyce::dout() << std::endl;
2698 Xyce::dout().width(25); Xyce::dout().precision(17); Xyce::dout().setf(std::ios::scientific);
2740 #ifdef Xyce_DEBUG_DEVICE
2743 Xyce::dout() <<
" " << std::endl;
2744 Xyce::dout() <<
" Solution vector: " << std::endl;
2745 Xyce::dout() <<
" Vg = " <<
Vg << std::endl;
2746 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
2747 Xyce::dout() <<
" Vs = " <<
Vs << std::endl;
2748 Xyce::dout() <<
" Vb = " <<
Vb << std::endl;
2749 Xyce::dout() <<
" Vdp = " <<
Vdp << std::endl;
2750 Xyce::dout() <<
" Vgp = " <<
Vgp << std::endl;
2751 Xyce::dout() <<
" Vsp = " <<
Vsp << std::endl;
2752 Xyce::dout() <<
" Vdd = " <<
Vdd << std::endl;
2753 Xyce::dout() <<
" Vd1p= " <<
Vd1p << std::endl;
2799 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
2856 #ifdef Xyce_DEBUG_DEVICE
2859 Xyce::dout() <<
"After Von first set, ";
2860 Xyce::dout() <<
" von = " <<
von <<
" Von = " << Von << std::endl;
2869 #ifdef Xyce_DEBUG_DEVICE
2872 Xyce::dout() <<
" checking whether to limit voltages "<< std::endl;
2873 Xyce::dout() <<
" Von = " << Von << std::endl;
2874 Xyce::dout() <<
" before limiting: " << std::endl;
2875 Xyce::dout() <<
" vgpdd = " <<
vgpdd <<
" vgpdd_old = " <<
vgpdd_old << std::endl;
2876 Xyce::dout() <<
" vgps = " <<
vgps <<
" vgps_old = " <<
vgps_old << std::endl;
2877 Xyce::dout() <<
" vdds = " << vdds <<
" vdds_old = " <<
vdds_old << std::endl;
2878 Xyce::dout() <<
" vbs = " <<
vbs <<
" vbs_old = " <<
vbs_old << std::endl;
2879 Xyce::dout() <<
" vbdd = " <<
vbdd <<
" vbdd_old = " <<
vbdd_old << std::endl;
2910 #ifdef Xyce_DEBUG_DEVICE
2913 Xyce::dout() <<
" After limiting: " << std::endl;
2914 Xyce::dout() <<
" vgpdd = " <<
vgpdd << std::endl;
2915 Xyce::dout() <<
" vgps = " <<
vgps << std::endl;
2916 Xyce::dout() <<
" vdds = " << vdds << std::endl;
2917 Xyce::dout() <<
" vbs = " <<
vbs << std::endl;
2918 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
2923 bool tmpGiven =
false;
2950 #ifdef Xyce_DEBUG_DEVICE
2953 Xyce::dout() <<
" vbs = " << vbs << std::endl;
2954 Xyce::dout() <<
" vgps = " <<
vgps << std::endl;
2955 Xyce::dout() <<
" vdds = " << vdds << std::endl;
2956 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
2957 Xyce::dout() <<
" vgpdd= " <<
vgpdd << std::endl;
2959 Xyce::dout() <<
" Vddp = " <<
Vddp << std::endl;
2960 Xyce::dout() <<
" Vddd = " <<
Vddd << std::endl;
2961 Xyce::dout() <<
" Vdddp= " <<
Vdddp << std::endl;
2962 Xyce::dout() <<
" Vssp = " <<
Vssp << std::endl;
2963 Xyce::dout() <<
" Vbsp = " <<
Vbsp << std::endl;
2964 Xyce::dout() <<
" Vbdp = " <<
Vbdp << std::endl;
2965 Xyce::dout() <<
" Vggp = " <<
Vggp << std::endl;
2966 Xyce::dout() <<
" Vgpsp = " <<
Vgpsp << std::endl;
2967 Xyce::dout() <<
" Vgpdp = " <<
Vgpdp << std::endl;
2968 Xyce::dout() <<
" Vgpb = " <<
Vgpb << std::endl;
2969 Xyce::dout() <<
" Vdpsp= " <<
Vdpsp << std::endl;
2978 #ifdef Xyce_DEBUG_DEVICE
2983 Xyce::dout() <<
" Something modified the voltages. " << std::endl;
2984 Xyce::dout() <<
" Voltage before after diff " << std::endl;
2986 Xyce::dout() <<
" vdds " <<
vdds_orig <<
" " << vdds <<
" " << vdds-
vdds_orig << std::endl;
2987 Xyce::dout() <<
" vbs " <<
vbs_orig <<
" " << vbs <<
" " << vbs-
vbs_orig << std::endl;
3024 j1=
model_.
artd*log(end1/end2)*(pi/2+atan(end3));
3029 d1j1=(fr1-fr2)*(pi/2+atan(end3));
3031 d2j1=log(end1/end2)*fr3;
3050 #ifdef Xyce_DEBUG_DEVICE
3053 Xyce::dout() <<
"*******Setting cbs for vbs<=0 ******" << std::endl;
3054 Xyce::dout() <<
" vbs = " << vbs << std::endl;
3055 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3056 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3057 Xyce::dout() <<
" SSC = " <<
SourceSatCur << std::endl;
3058 Xyce::dout() <<
" gbs = " << gbs << std::endl;
3059 Xyce::dout() <<
" cbs = " <<
cbs << std::endl;
3060 Xyce::dout() <<
" j1 = " << j1 << std::endl;
3074 #ifdef Xyce_DEBUG_DEVICE
3077 Xyce::dout() <<
"*******Setting cbs for vbs>0 ******" << std::endl;
3078 Xyce::dout() <<
" vbs = " << vbs << std::endl;
3079 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3080 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3081 Xyce::dout() <<
" vbs/vt = " << vbs/
vt << std::endl;
3085 Xyce::dout() <<
" evbs = " << evbs << std::endl;
3086 Xyce::dout() <<
" gbs = " <<
gbs << std::endl;
3087 Xyce::dout() <<
" cbs = " << cbs << std::endl;
3100 #ifdef Xyce_DEBUG_DEVICE
3103 Xyce::dout() <<
"*******Setting cbd for vbdd<=0 ******" << std::endl;
3104 Xyce::dout() <<
" vbdd = " << vbdd << std::endl;
3105 Xyce::dout() <<
" SSC = " <<
SourceSatCur << std::endl;
3106 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3107 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3108 Xyce::dout() <<
" gbd = " << gbd << std::endl;
3109 Xyce::dout() <<
" cbd = " <<
cbd << std::endl;
3124 #ifdef Xyce_DEBUG_DEVICE
3127 Xyce::dout() <<
"*******Setting cbd for vbdd>0 ******" << std::endl;
3128 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
3129 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3130 Xyce::dout() <<
" vbdd/vt = " <<
vbdd/
vt << std::endl;
3134 Xyce::dout() <<
" evbdd = " << evbdd << std::endl;
3135 Xyce::dout() <<
" gbd = " <<
gbd << std::endl;
3136 Xyce::dout() <<
" cbd = " << cbd << std::endl;
3146 double dvonvbs(0.0);
3147 double lvbs =
mode == 1 ? vbs :
vbdd;
3185 D1evd = D1arg = D1evrev = 0.0;
3190 D1evr = exp(
D1vd/D1vtr);
3192 D1arg = D1temp*D1temp;
3194 D1isr = D1csatr*D1power;
3195 D1cdr = D1isr*(D1evr - 1);
3219 D1arg = D1arg * D1arg * D1arg;
3231 #ifdef Xyce_DEBUG_DEVICE
3234 Xyce::dout() <<
" " << std::endl;
3235 Xyce::dout() <<
" dtype = " <<
model_.
dtype << std::endl;
3236 Xyce::dout() <<
" D1vd = " <<
D1vd << std::endl;
3237 Xyce::dout() <<
" D1vtr = " << D1vtr << std::endl;
3238 Xyce::dout() <<
" D1csat = " << D1csat << std::endl;
3239 Xyce::dout() <<
" D1csatr = " << D1csatr << std::endl;
3240 Xyce::dout() <<
" D1gspr = " <<
D1gspr << std::endl;
3241 Xyce::dout() <<
" D1cdr = " << D1cdr << std::endl;
3242 Xyce::dout() <<
" D1gdr = " << D1gdr << std::endl;
3243 Xyce::dout() <<
" D1vte = " <<
D1vte << std::endl;
3244 Xyce::dout() <<
" D1evd = " << D1evd << std::endl;
3245 Xyce::dout() <<
" D1arg = " << D1arg << std::endl;
3246 Xyce::dout() <<
" D1evrev = " << D1evrev << std::endl;
3247 Xyce::dout() <<
" D1DIOtBrkdwnV = " <<
D1DIOtBrkdwnV << std::endl << std::endl;
3248 Xyce::dout() <<
" D1cd = " << D1cd << std::endl;
3249 Xyce::dout() <<
" D1gd = " <<
D1gd << std::endl;
3250 Xyce::dout() <<
" D1cdeq = " <<
D1cdeq << std::endl;
3291 sarg = sargsw = 1/sqrt(arg);
3310 sargsw = 1/sqrt(arg);
3350 sarg = sargsw = 1/sqrt(arg);
3364 sargsw = 1/sqrt(arg);
3374 +
Cbdsw*(1-arg*sargsw)
3415 #ifdef Xyce_DEBUG_DEVICE
3418 Xyce::dout() <<
" " << std::endl;
3419 Xyce::dout() <<
" Going into qmeyer..." << std::endl;
3420 Xyce::dout() <<
" Mode is " <<
mode << std::endl;
3421 Xyce::dout() <<
" Args are vgps = " <<
vgps <<
" vgpdd = " <<
vgpdd << std::endl;
3422 Xyce::dout() <<
" Vgpb = " <<
Vgpb <<
" Von = " << Von <<
" Vddsat = " << Vddsat << std::endl;
3423 Xyce::dout() <<
" tPhi = " <<
tPhi <<
" OxideCap = " <<
OxideCap << std::endl;
3465 #ifdef Xyce_DEBUG_DEVICE
3468 Xyce::dout() <<
"Doing meyer back averaging..."<< std::endl;
3469 Xyce::dout() <<
" capgs = " <<
capgs <<
" capgs_old = " << capgs_old << std::endl;
3470 Xyce::dout() <<
" capgdd = " <<
capgdd <<
" capgdd_old = " << capgdd_old << std::endl;
3471 Xyce::dout() <<
" capgb = " <<
capgb <<
" capgb_old = " << capgb_old << std::endl;
3478 #ifdef Xyce_DEBUG_DEVICE
3481 Xyce::dout() <<
"Capgs = " <<
Capgs << std::endl;
3482 Xyce::dout() <<
"Capgdd = " <<
Capgdd << std::endl;
3483 Xyce::dout() <<
"Capgb = " <<
Capgb << std::endl;
3484 Xyce::dout() <<
"capgs = " <<
capgs << std::endl;
3485 Xyce::dout() <<
"capgdd = " <<
capgdd << std::endl;
3486 Xyce::dout() <<
"capgb = " <<
capgb << std::endl;
3494 double absV = fabs(
Vddd);
3501 double dVddd_dVd (1.0);
3502 double d_absVddd_dVd (0.0);
3505 d_absVddd_dVd = 1.0;
3507 else if (
Vddd < 0.0)
3509 d_absVddd_dVd = -1.0;
3550 #ifdef Xyce_DEBUG_DEVICE
3553 Xyce::dout() <<
" Done with Instance::updateIntermediateVars " << std::endl;
3554 Xyce::dout() <<
" mode = " <<
mode << std::endl;
3555 Xyce::dout() <<
" Idrain = " <<
Idrain << std::endl;
3556 Xyce::dout() <<
" Igate = " <<
Igate << std::endl;
3557 Xyce::dout() <<
" Isource = " <<
Isource << std::endl;
3558 Xyce::dout() <<
" Idraindrift = " <<
Idraindrift << std::endl;
3559 Xyce::dout() <<
" Ird1rs = " << Ird1rs << std::endl;
3560 Xyce::dout() <<
" dIdd_dVd = " <<
dIdd_dVd << std::endl;
3561 Xyce::dout() <<
" gddd = " <<
gddd << std::endl;
3562 Xyce::dout() <<
" Irdsshunt = " <<
Irdsshunt << std::endl;
3563 Xyce::dout() <<
" D1DIOcapCurrent = " <<
D1DIOcapCurrent << std::endl;
3564 Xyce::dout() <<
" cbd = " << cbd << std::endl;
3565 Xyce::dout() <<
" cbs = " <<
cbs << std::endl;
3566 Xyce::dout() <<
" qbd = " <<
qbd << std::endl;
3567 Xyce::dout() <<
" qbs = " <<
qbs << std::endl;
3568 Xyce::dout() <<
" cdrain = " <<
cdrain << std::endl;
3569 Xyce::dout() <<
" cdraindrift = " <<
cdraindrift << std::endl;
3570 Xyce::dout() <<
" cdreq = " <<
cdreq << std::endl;
3571 Xyce::dout() <<
" gdds = " <<
gdds << std::endl;
3572 Xyce::dout() <<
" gdsshunt = " <<
gdsshunt << std::endl;
3573 Xyce::dout() <<
" gm = " <<
gm << std::endl;
3574 Xyce::dout() <<
" gmbs = " <<
gmbs << std::endl;
3575 Xyce::dout() <<
" Gm = " <<
Gm << std::endl;
3576 Xyce::dout() <<
" Gmbs = " <<
Gmbs << std::endl;
3622 bool bsuccess =
true;
3631 double ratio,ratio4(0.0);
3636 double capfact(0.0);
3639 double gmanew,gmaold(0.0);
3644 double D1vte_loc(0.0);
3649 double D1vt_loc(0.0);
3650 register int D1iter(0.0);
3651 double D1egfet1(0.0),D1arg1(0.0),D1fact1(0.0),D1pbfact1(0.0),D1pbo(0.0),D1gmaold(0.0);
3652 double D1fact2(0.0),D1pbfact(0.0),D1arg(0.0),D1egfet(0.0),D1gmanew(0.0);
3661 #ifdef Xyce_DEBUG_DEVICE
3665 Xyce::dout() << subsection_divider << std::endl;
3666 Xyce::dout() <<
" Instance::Begin of updateTemperature. \n";
3667 Xyce::dout() <<
" name = " <<
getName() << std::endl;
3668 Xyce::dout() << std::endl;
3673 if (temp_tmp != -999.0)
temp = temp_tmp;
3690 #ifdef Xyce_DEBUG_DEVICE
3693 Xyce::dout() <<
" Temperature = "<<
temp << std::endl;
3694 Xyce::dout() <<
" tnom = " << tnom << std::endl;
3695 Xyce::dout() <<
" ratio = " << ratio << std::endl;
3705 pbfact = -2*
vt *(1.5*log(fact2)+
CONSTQ*arg);
3707 #ifdef Xyce_DEBUG_DEVICE
3710 Xyce::dout() <<
" fact1 = " <<
model_.
fact1 << std::endl;
3711 Xyce::dout() <<
" vtnom = " <<
model_.
vtnom << std::endl;
3712 Xyce::dout() <<
" egfet1 = " <<
model_.
egfet1 << std::endl;
3713 Xyce::dout() <<
" pbfact1= " <<
model_.
pbfact1 << std::endl;
3714 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3715 Xyce::dout() <<
" ratio = " << ratio << std::endl;
3716 Xyce::dout() <<
" fact2 = " << fact2 << std::endl;
3717 Xyce::dout() <<
" kt = " << kt << std::endl;
3718 Xyce::dout() <<
" egfet = " << egfet << std::endl;
3719 Xyce::dout() <<
" arg = " << arg << std::endl;
3720 Xyce::dout() <<
" pbfact = " << pbfact << std::endl;
3724 ratio4 = ratio * sqrt(ratio);
3727 tPhi = fact2 * phio + pbfact;
3760 #ifdef Xyce_DEBUG_DEVICE
3763 Xyce::dout() <<
" ratio4 = " << ratio4 << std::endl;
3764 Xyce::dout() <<
" tSurfMob = " <<
tSurfMob << std::endl;
3765 Xyce::dout() <<
" phio = " << phio << std::endl;
3766 Xyce::dout() <<
" tPhi = " <<
tPhi << std::endl;
3767 Xyce::dout() <<
" tVbi = " <<
tVbi << std::endl;
3768 Xyce::dout() <<
" tVto = " <<
tVto << std::endl;
3769 Xyce::dout() <<
" tSatCur = " <<
tSatCur << std::endl;
3770 Xyce::dout() <<
" tSatCurDens = " <<
tSatCurDens << std::endl;
3771 Xyce::dout() <<
" pbo = " << pbo << std::endl;
3772 Xyce::dout() <<
" gmaold = " << gmaold << std::endl;
3773 Xyce::dout() <<
" tBulkPot = " <<
tBulkPot << std::endl;
3774 Xyce::dout() <<
" gmanew = " << gmanew << std::endl;
3775 Xyce::dout() <<
" capfact = " << capfact << std::endl;
3776 Xyce::dout() <<
" tCbd = " <<
tCbd << std::endl;
3777 Xyce::dout() <<
" tCbs = " <<
tCbs << std::endl;
3778 Xyce::dout() <<
" tCj = " <<
tCj << std::endl;
3779 Xyce::dout() <<
" capfact = " << capfact << std::endl;
3780 Xyce::dout() <<
" tCjsw = " <<
tCjsw << std::endl;
3781 Xyce::dout() <<
" tDepCap = " <<
tDepCap << std::endl;
3897 vthLimit = N_UTL_MachineDependentParams::DoubleMax();
3910 D1egfet = 1.16-(7.02e-4*D1DIOtemp*
D1DIOtemp)/(D1DIOtemp+1108);
3911 D1arg = -D1egfet/(2*CONSTboltz*
D1DIOtemp) + 1.1150877/
3913 D1pbfact = -2*D1vt_loc*(1.5*log(D1fact2)+
CONSTQ*D1arg);
3920 (1.5*log(D1fact1)+
CONSTQ*D1arg1);
3959 Xyce::dout() <<
" breakdown current increased to " << D1cbv <<
3960 "to resolve incompatability " <<
3961 "with specified saturation current" << std::endl;
3968 D1vt_loc*log(1+D1cbv/D1DIOtSatCur);
3969 for(D1iter=0; D1iter<25; ++D1iter)
3972 D1DIOtSatCur+1-D1xbv/D1vt_loc);
3974 -D1xbv)/D1vt_loc)-1+D1xbv/D1vt_loc);
3975 if (fabs(D1xcbv-D1cbv) <= D1tol)
goto matched;
3977 Xyce::dout() <<
" unable to match forward and reverse diode regions: D1bv = "
3978 << D1xbv <<
" D1ibv = " << D1xcbv << std::endl;
3997 bool bsuccess =
true;
3998 double vgs1(0.0), vgdd1(0.0), vbs1(0.0),vgb1(0.0), vdds1(0.0);
4003 bsuccess = bsuccess && tmpBool;
4132 #ifdef Xyce_DEBUG_DEVICE
4135 Xyce::dout() <<
" L = " <<
l << std::endl;
4136 Xyce::dout() <<
" W = " <<
w<< std::endl;
4137 Xyce::dout() <<
" drainArea = " <<
drainArea<< std::endl;
4138 Xyce::dout() <<
" sourceArea = " <<
sourceArea<< std::endl;
4139 Xyce::dout() <<
" drainSquares = " <<
drainSquares<< std::endl;
4140 Xyce::dout() <<
" sourceSquares = " <<
sourceSquares<< std::endl;
4141 Xyce::dout() <<
" drainPerimeter = " <<
drainPerimeter<< std::endl;
4143 Xyce::dout() <<
" drainCond = " <<
drainCond<< std::endl;
4144 Xyce::dout() <<
" sourceCond = " <<
sourceCond << std::endl;
4145 Xyce::dout() <<
" draindriftCond = " <<
draindriftCond<< std::endl;
4146 Xyce::dout() <<
" temp = " <<
temp<< std::endl;
4175 double vddsat_local,
4176 double & capgs_local,
4177 double & capgdd_local,
4178 double & capgb_local,
4183 double vdds_local(0.0);
4193 #define L EffectiveLength
4194 #define ETA model_.eta
4195 #define TOX model_.oxideThickness
4197 vgst = xvgs-von_local;
4200 capgb_local = cox/2;
4204 else if (vgst <= -phi/2)
4206 capgb_local = -vgst*cox/(2*phi);
4212 capgb_local = -vgst*cox/(2*phi);
4213 capgs_local = vgst*cox/(1.5*phi)+cox/3;
4218 vdds_local = xvgs-xvgdd;
4220 if (vddsat_local <= vdds_local)
4222 capgs_local = cox/3;
4227 vddif = 2.0*vddsat_local-vdds_local;
4228 vddif1 = vddsat_local-vdds_local;
4229 vddif2 = vddif*vddif;
4230 capgdd_local = cox*(1.0-vddsat_local*vddsat_local/vddif2)/3;
4231 capgs_local = cox*(1.0-vddif1*vddif1/vddif2)/3;
4238 if(
model_.
cv == 2 && vddsat_local != 0)
4240 vdds_local = fabs(xvgs-xvgdd);
4241 vdds_local = vdds_local/pow(1+pow(vdds_local/vddsat_local,
model_.
mc),
4243 vddif = 2.0*vddsat_local-vdds_local;
4244 vddif1 = vddsat_local-vdds_local;
4245 vddif2 = vddif*vddif;
4249 capgdd_local = cgc*(1.0-vddsat_local*vddsat_local/vddif2)/3;
4250 capgs_local = cgc*(1.0-vddif1*vddif1/vddif2)/3;
4276 double vbs_local(0.0);
4277 double vdds_local(0.0);
4285 double DeltaVT(0.0);
4286 double DnsdVgs(0.0);
4287 double DnsdVgd(0.0);
4288 double DnsdVgb(0.0);
4289 double DnssVgs(0.0);
4290 double DnssVgd(0.0);
4291 double DnssVgb(0.0);
4292 double DndepVgs(0.0);
4293 double DndepVgd(0.0);
4294 double DndepVgb(0.0);
4315 double SigmaVgs(0.0);
4316 double SigmaVgd(0.0);
4324 vbs_local = xvgs-vgb;
4325 vdds_local = xvgs-xvgdd;
4330 if(xvgs > VFB+vbs_local)
4335 nss=2.0*
n0*log(1+0.5*exp((xvgs-
von)/etavt));
4336 nsd=2.0*
n0*log(1+0.5*exp((xvgs-
von-ALPHA*vdds_local)/etavt));
4338 if (nss<1e-36) {nss=1.0e-36;}
4339 if (nsd<1e-36) {nsd=1.0e-36;}
4340 zetanb = (1-ALPHA)/ALPHA;
4341 xi = gamma*gamma/(A*A)+4/(A*A)*(vgb-VFB)-4.0/A*nss;
4345 if (vbs_local <= 0) { DeltaVT= 0.5*gamma/sqrt(
tPhi-vbs_local); }
4346 if ((vbs_local > 0)&&(vbs_local <= 2*
tPhi)) { DeltaVT=0.5*gamma/sqrt(
tPhi); }
4347 if ((vbs_local > 0)&&(vbs_local > 2*
tPhi)) { DeltaVT=0; }
4349 DnsdVgs=(1+DeltaVT-ALPHA+SigmaVgs)/tnsd;
4350 DnsdVgd=(-SigmaVgd+ALPHA)/tnsd;
4351 DnsdVgb=-DeltaVT/tnsd;
4353 DnssVgs= (1+DeltaVT+SigmaVgs)/tnss;
4354 DnssVgd=-SigmaVgd/tnss;
4355 DnssVgb=-DeltaVT/tnss;
4357 UI= etavt/2.0*(nsd*nsd-nss*nss) + A/3.0*(nsd*nsd*nsd-nss*nss*nss);
4358 VI= etavt*(nsd-nss) + A/2.0*(nsd*nsd-nss*nss);
4359 DUIVgs = etavt*(nsd*DnsdVgs-nss*DnssVgs) +
4360 A*(nsd*nsd*DnsdVgs-nss*nss*DnssVgs);
4361 DUIVgd= etavt*(nsd*DnsdVgd-nss*DnssVgd) +
4362 A*(nsd*nsd*DnsdVgd-nss*nss*DnssVgd);
4363 DUIVgb= etavt*(nsd*DnsdVgb-nss*DnssVgb) +
4364 A*(nsd*nsd*DnsdVgb-nss*nss*DnssVgb);
4366 DVIVgs= etavt*(DnsdVgs-DnssVgs) + A*(nsd*DnsdVgs-nss*DnssVgs);
4367 DVIVgd= etavt*(DnsdVgd-DnssVgd) + A*(nsd*DnsdVgd-nss*DnssVgd);
4368 DVIVgb= etavt*(DnsdVgb-DnssVgb) + A*(nsd*DnsdVgb-nss*DnssVgb);
4371 DqiVgs= mqWL*(DUIVgs*VI-DVIVgs*UI)/(VI*VI);
4372 DqiVgd= mqWL*(DUIVgd*VI-DVIVgd*UI)/(VI*VI);
4373 DqiVgb= mqWL*(DUIVgb*VI-DVIVgb*UI)/(VI*VI);
4377 DqiVgs=mqWL*DnssVgs;
4378 DqiVgd=mqWL*DnssVgd;
4379 DqiVgb=mqWL*DnssVgb;
4382 DxiVgs= -4.0/A*DnssVgs;
4383 DxiVgd= -4.0/A*DnssVgd;
4384 DxiVgb= 4.0/(A*A)-4/A*DnssVgb;
4387 {DndepVgs= gamma/4.0*1.0/xisqrt*DxiVgs;
4388 DndepVgd= gamma/4.0*1.0/xisqrt*DxiVgd;
4389 DndepVgb= gamma/4.0*1.0/xisqrt*DxiVgb;
4398 DqbVgs = mqWL*(DndepVgs-zetanb*DnssVgs)+zetanb*DqiVgs;
4399 DqbVgd = mqWL*(DndepVgd-zetanb*DnssVgd)+zetanb*DqiVgd;
4400 DqbVgb = mqWL*(DndepVgb-zetanb*DnssVgb)+zetanb*DqiVgb;
4402 DqgVgs= -DqiVgs-DqbVgs;
4403 DqgVgd= -DqiVgd-DqbVgd;
4404 DqgVgb= -DqiVgb-DqbVgb;
4414 if (DqgVgs<0) {DqgVgs=0;}
4415 if (DqgVgd<0) {DqgVgd=0;}
4416 if (DqgVgb<0) {DqgVgb=0;}
4436 double vgb,
double & qD,
double & qS,
double & qB)
4457 double vdds_local(0.0);
4466 vdds_local=vgs-vgdd;
4473 nsd=2*
n0*log(1+0.5*exp((vgs-VT-ALPHA*vdds_local)/etavth));
4474 nss=2*
n0*log(1+0.5*exp((vgs-VT)/etavth));
4480 arg1= 0.5*etavth*(nsdsqr-nsssqr)+1/3.0*A*(nsdsqr*nsd-nsssqr*nss);
4481 arg2= etavth*(nsd-nss) +0.5*A*(nsdsqr-nsssqr);
4485 else {qn = mqWL*arg1/arg2;}
4486 xisqrt= sqrt(gamma*gamma/(A*A)+4.0/(A*A)*(vgb-VFB)-4.0/A*nss);
4487 ndeps = -gamma*gamma/(2.0*A)+ gamma/2.0*xisqrt;
4488 zetanb =(1-ALPHA)/ALPHA;
4490 qB =mqWL*(ndeps-zetanb*nss)+zetanb*qn;
4505 double fp1denum(0.0);
4507 vdsabs=fabs(vdds_local);
4511 if((vsat > 1e-36)&&(vdds_local>1e-36))
4512 { beta=vdsabs/vsat;}
else{beta=1e-36;}
4515 fp1denum = exp(1/m*log(1+exp(m*log(beta))));
4516 if (fp1denum > 1e-36)
4517 {fp1= 0.5+ a0*vdsabs/fp1denum;}
4527 double arg1_loc(0.0);
4528 double arg2_loc(0.0);
4529 double arg3_loc(0.0);
4533 arg1_loc= nd0*nd0*nd0*(1/3.0+nd0*(3.0/8.0+1/10.0*nd0))
4534 - (1.0/2.0+1.0/3.0*nd0)*(1.0+1/2.0*ns0)*nd0*nd0*ns0
4535 + ns0*ns0*ns0*(1.0/6.0+ns0*(5.0/24.0+1.0/15.0*ns0));
4536 arg2_loc = 1.0/2.0*(nd0*nd0-ns0*ns0)+1.0/3.0*(nd0*nd0*nd0-ns0*ns0*ns0);
4537 arg3_loc = nd0-ns0+1.0/2.0*(nd0*nd0-ns0*ns0);
4538 if ((arg2_loc==0)||(arg3_loc==0)) {fp1=0.5;}
4539 else { fp1 = 1-arg1_loc/(arg2_loc*arg3_loc);}
4544 UserWarning(*
this) <<
"Partitioning model does not exist";
4575 double & von_local,
double & dvonvbs_local)
4577 double PhiMinVbs =
tPhi - vbs_local;
4585 dvonvbs_local = 0.0;
4590 sarg = sqrt(PhiMinVbs);
4616 double dvonvbs,
double & cdraindrift_loc,
double & vsate)
4635 double x(0.0),y(0.0),z(0.0);
4644 double dichoodvds(0.0);
4645 double dichoodvgs(0.0);
4646 double dichoodvbs(0.0);
4647 double dichooisat(0.0);
4648 double dichoodgch(0.0);
4649 double delgchgchi(0.0);
4650 double disatdvds(0.0);
4651 double disatdvgs(0.0);
4652 double disatdvbs(0.0);
4653 double dgchidvds(0.0);
4654 double dgchidvgs(0.0);
4655 double dgchidvbs(0.0);
4656 double disatvgte(0.0);
4657 double disatgchi(0.0);
4658 double dvgtedvgt(0.0);
4659 double dvgtdvds(0.0);
4660 double dvgtdvgs(0.0);
4661 double dvgtdvbs(0.0);
4662 double dnsdvgt(0.0);
4663 double dnsdvds(0.0);
4664 double dnsdvgs(0.0);
4665 double dnsdvbs(0.0);
4666 double dmudvgte(0.0);
4667 double dmudvds(0.0);
4668 double dmudvgs(0.0);
4669 double dmudvbs(0.0);
4671 static int output=0;
4673 #define ETA model_.eta
4674 #define RS model_.sourceResistance
4675 #define RD model_.drainResistance
4676 #define VSIGMAT model_.vsigmat
4677 #define VSIGMA model_.vsigma
4678 #define SIGMA0 model_.sigma0
4679 #define THETA model_.theta
4680 #define LAMBDA model_.lambda
4681 #define DELTA model_.delta
4682 #define VMAX model_.maxDriftVel
4683 #define TOX model_.oxideThickness
4685 #define EXP_MAX 150.0
4688 Xyce::dout() <<
" " << std::endl;
4689 Xyce::dout() <<
"ETA = " <<
ETA << std::endl;
4690 Xyce::dout() <<
"RS = " <<
RS << std::endl;
4691 Xyce::dout() <<
"RD = " <<
RD << std::endl;
4692 Xyce::dout() <<
"VSIGMAT = " <<
VSIGMAT << std::endl;
4693 Xyce::dout() <<
"VSIGMA = " <<
VSIGMA << std::endl;
4694 Xyce::dout() <<
"SIGMA0 = " <<
SIGMA0 << std::endl;
4695 Xyce::dout() <<
"THETA = " <<
THETA << std::endl;
4696 Xyce::dout() <<
"LAMBDA = " <<
LAMBDA << std::endl;
4697 Xyce::dout() <<
"DELTA = " <<
DELTA << std::endl;
4698 Xyce::dout() <<
"VMAX = " <<
VMAX << std::endl;
4699 Xyce::dout() <<
"TOX = " <<
TOX << std::endl;
4708 vgt = vgt0+sigma*xvdds;
4711 vgte = vt*(1+b+1+q);
4726 ns = 2.0*
n0*log(1+0.5*exp(x));
4730 cdraindrift_loc = 0.0;
4743 gch = gchi/(1+gchi*rt);
4748 d = sqrt(1+2*gchi*
RS + vgte*vgte/vl2);
4756 else z = 1/(cosh(y)*cosh(y));
4759 ichoo = isat*(1+
LAMBDA*xvdds)*tanh(y);
4761 dvgtedvgt = 0.5*(1+b/q);
4762 dnsdvgt =
n0/(etavt*(exp(-x)+0.5));
4767 dvgtdvbs = -dvonvbs*dvgtdvgs;
4769 dnsdvds = dnsdvgt*dvgtdvds;
4770 dnsdvgs = dnsdvgt*dvgtdvgs;
4771 dnsdvbs = dnsdvgt*dvgtdvbs;
4772 dmudvds = (dmudvgte*dvgtedvgt)*dvgtdvds;;
4773 dmudvgs = (dmudvgte*dvgtedvgt)*dvgtdvgs;;
4774 dmudvbs = (dmudvgte*dvgtedvgt)*dvgtdvbs + 2*dmudvgte*dvonvbs;
4776 dgchidvds =
gchi0*(mu*dnsdvds + ns*dmudvds);
4777 dgchidvgs =
gchi0*(mu*dnsdvgs + ns*dmudvgs);
4778 dgchidvbs =
gchi0*(mu*dnsdvbs + ns*dmudvbs);
4780 disatvgte = gchi/h - gchi*vgte*vgte/vl2/(d*h*h);
4781 disatgchi = vgte/h - gchi*vgte*
RS*(1+1/d)/(h*h);
4783 disatdvds = (disatvgte*dvgtedvgt)*dvgtdvds + disatgchi*dgchidvds;
4784 disatdvgs = (disatvgte*dvgtedvgt)*dvgtdvgs + disatgchi*dgchidvgs;
4785 disatdvbs = (disatvgte*dvgtedvgt)*dvgtdvbs + disatgchi*dgchidvbs;
4787 dichoodgch = (1+
LAMBDA*xvdds)*xvdds*z;
4788 dichooisat = (1+
LAMBDA*xvdds)*(tanh(y) - gch*xvdds*z/isat);
4790 delgchgchi = 1/(g*g);
4792 dichoodvds = dichooisat*disatdvds + (dichoodgch*delgchgchi)*dgchidvds
4794 dichoodvgs = dichooisat*disatdvgs + (dichoodgch*delgchgchi)*dgchidvgs;
4795 dichoodvbs = dichooisat*disatdvbs + (dichoodgch*delgchgchi)*dgchidvbs;
4798 cdraindrift_loc = ichoo;
4827 double dvonvbs,
double & cdraindrift_loc,
double & vsate)
4873 double delidgch(0.0);
4874 double delgchgchi(0.0);
4875 double delgchins(0.0);
4876 double dvgtevgt(0.0);
4877 double delidvsate(0.0);
4878 double delvsateisat(0.0);
4879 double delisatvgte(0.0);
4880 double delisatgchi(0.0);
4881 double delisatvl(0.0);
4882 double dgchivgt(0.0);
4883 double delvsategch(0.0);
4884 double delidvds(0.0);
4885 double dsigmavgs(0.0);
4886 double delnsvgt(0.0);
4887 double dvsatevgt(0.0);
4888 double dvgtvgs(0.0);
4891 double dvgtvon(0.0);
4892 double delvsatqs(0.0);
4893 double delvsatmu(0.0);
4894 double dvsatvgt(0.0);
4895 double dvsatvbs(0.0);
4896 double delvdsevdso(0.0);
4897 double delvdsevsat(0.0);
4898 double dvdsevgs(0.0);
4899 double dvdsevds(0.0);
4900 double dvdsevbs(0.0);
4903 double delmm1vdso(0.0);
4904 double ddelvgs(0.0);
4905 double ddelvds(0.0);
4906 double ddelvbs(0.0);
4910 double mm1_loc(0.0);
4911 double dmm1vgs_loc(0.0);
4912 double dmm1vds_loc(0.0);
4913 double dmm1vbs_loc(0.0);
4915 static int output(0);
4917 #define ETA model_.eta
4918 #define RS model_.sourceResistance
4919 #define RD model_.drainResistance
4920 #define VSIGMAT model_.vsigmat
4921 #define VSIGMA model_.vsigma
4922 #define SIGMA0 model_.sigma0
4923 #define THETA model_.theta
4924 #define LAMBDA model_.lambda
4925 #define DELTA model_.delta
4926 #define ALPHA model_.alpha
4927 #define VMAX model_.maxDriftVel
4928 #define TOX model_.oxideThickness
4930 #define L EffectiveLength
4931 #define LS model_.ls
4933 #define INVM 1.0/model_.m
4934 #define MC model_.mc
4935 #define INVMC 1.0/model_.mc
4936 #define RSUB model_.rsub
4937 #define AI model_.ai
4938 #define BI model_.bi
4939 #define MD model_.md
4940 #define INVMD 1.0/model_.md
4941 #define DELMAX model_.delmax
4944 Xyce::dout() <<
" " << std::endl;
4945 Xyce::dout() <<
"ETA = " <<
ETA << std::endl;
4946 Xyce::dout() <<
"RS = " <<
RS << std::endl;
4947 Xyce::dout() <<
"RD = " <<
RD << std::endl;
4948 Xyce::dout() <<
"VSIGMAT = " <<
VSIGMAT << std::endl;
4949 Xyce::dout() <<
"VSIGMA = " <<
VSIGMA << std::endl;
4950 Xyce::dout() <<
"SIGMA0 = " <<
SIGMA0 << std::endl;
4951 Xyce::dout() <<
"THETA = " <<
THETA << std::endl;
4952 Xyce::dout() <<
"LAMBDA = " <<
LAMBDA << std::endl;
4953 Xyce::dout() <<
"DELTA = " <<
DELTA << std::endl;
4954 Xyce::dout() <<
"ALPHA = " <<
ALPHA << std::endl;
4955 Xyce::dout() <<
"VMAX = " <<
VMAX << std::endl;
4956 Xyce::dout() <<
"TOX = " <<
TOX << std::endl;
4957 Xyce::dout() <<
"W = " <<
W << std::endl;
4958 Xyce::dout() <<
"L = " <<
L << std::endl;
4959 Xyce::dout() <<
"LS = " <<
LS << std::endl;
4960 Xyce::dout() <<
"M = " <<
M << std::endl;
4961 Xyce::dout() <<
"INVM = " <<
INVM << std::endl;
4962 Xyce::dout() <<
"MC = " <<
MC << std::endl;
4963 Xyce::dout() <<
"INVMC = " <<
INVMC << std::endl;
4964 Xyce::dout() <<
"RSUB = " <<
RSUB << std::endl;
4965 Xyce::dout() <<
"AI = " <<
AI << std::endl;
4966 Xyce::dout() <<
"BI = " <<
BI << std::endl;
4967 Xyce::dout() <<
"MD = " <<
MD << std::endl;
4968 Xyce::dout() <<
"INVMD = " <<
INVMD << std::endl;
4969 Xyce::dout() <<
"DELMAX = " <<
DELMAX << std::endl;
4970 Xyce::dout() <<
"VP = " <<
vp << std::endl;
4980 vgt = vgt0+sigma*xvdds;
4983 vgte = vt*(1+b+1+q);
4998 ns = 2.0*
n0*log(1+0.5*exp(x));
5004 cdraindrift_loc = 0.0;
5010 mm1 = mm1_loc = 0.0;
5018 gch = gchi/(1+gchi*rt);
5022 d = sqrt(1+2*gchi*
RS + vgte*vgte/vl2);
5024 isat = r/(1+gchi*
RS+d);
5027 z = 0.5*(cosh(2*y)+1);
5034 ichoo = isat*(1+
LAMBDA*xvdds)*tanh(y);
5035 delidgch = ichoo/gch;
5037 delgchgchi = 1/(g*g);
5038 delgchins =
gchi0*mu;
5040 delnsvgt =
n0/(etavt*(exp(-x) + 0.5));
5041 dvgtevgt = 0.5*(1+b/q);
5047 delidvsate = gch*(1+
LAMBDA*xvdds)*xvdds/(vsate)/z;
5049 delvsateisat = 1/gch;
5050 delvsategch = -(vsate)/gch;
5052 delisatgchi = (vgte*h - gchi*vgte*
RS*(1+1/d))/(h*h);
5053 delisatvgte = (gchi*h - gchi*vgte*vgte/(vl2*d))/(h*h);
5054 delisatvl = isat*isat*vgte/(gchi*d*vl2*vl);
5056 dgchivgt = delgchins*delnsvgt-gchi*mu*s*dvgtevgt;
5058 p = delgchgchi*dgchivgt;
5059 dvsatevgt = delvsateisat*(delisatgchi*dgchivgt+
5060 (delisatvgte+delisatvl*t*s)*dvgtevgt)+ delvsategch*p;
5061 g = delidgch*p+delidvsate*dvsatevgt;
5062 dvgtvgs = (1+xvdds*dsigmavgs);
5064 gdsoo = delidvds+g*sigma;
5066 dmuvon = -(2-dvgtevgt*dvgtvgs)*mu*mu*s;
5072 gbsoo = -(gmoo)*dvonvbs;
5076 double dgchivon = -delgchins*delnsvgt*dvgtvgs+gchi*dmuvon/mu;
5077 p = delgchgchi*dgchivon;
5078 double dvsatevon = delvsateisat*(delisatgchi*dgchivon+
5079 delisatvgte*dvgtevgt*dvgtvon+delisatvl*(-vl2/t)*dmuvon)+delvsategch*p;
5080 gbsoo = (delidgch*p+delidvsate*dvsatevon)*dvonvbs;
5087 qs =
CONSTQ*(ns-ichoo*temp1);
5088 dqsvgt =
CONSTQ*(delnsvgt-g*temp1);
5089 dqsvbs =
CONSTQ*(delnsvgt*dvgtvon*dvonvbs-gbsoo*temp1);
5098 delvsatqs = 2*
VMAX*L*(b-qs*mu)/temp1;
5099 delvsatmu = -a*qs/temp1;
5100 dvsatvgt = delvsatqs*dqsvgt+delvsatmu*dmuvgt;
5101 dvsatvbs = delvsatqs*dqsvbs+delvsatmu*dmuvon*dvonvbs;
5107 c = sqrt(1+qs*mu*b);
5109 delvsatqs = a*(0.5*b*mu/c);
5110 delvsatmu = -vsat/mu+a*(0.5*b*qs/c);
5111 dvsatvgt = delvsatqs*dqsvgt+delvsatmu*dmuvgt;
5112 dvsatvbs = delvsatqs*dqsvbs+delvsatmu*dmuvon*dvonvbs;
5116 vdso = xvdds-ichoo*rt;
5117 a = pow(vdso/vsat,
MC);
5120 delvdsevdso = (1-a/(1+a))/b;
5121 delvdsevsat = vdse*a/(vsat*(1+a));
5125 double deldeltalvdse(0.0);
5126 double deldeltalvdso(0.0);
5127 double deldeltalmu(0.0);
5128 double ddeltalvgs(0.0);
5129 double ddeltalvds(0.0);
5130 double ddeltalvbs(0.0);
5132 a = 1+(vdso-vdse)/
vp;
5133 b =
W*mu*cox*vdse*
RS/L;
5140 deldeltalvdse = (-
LS/(f*a*
vp)*c-d*(1/
vp+
W*mu*cox*
RS/L))/(c*c);
5141 deldeltalvdso =
LS/(c*a*f*
vp);
5142 deldeltalmu = -d*
W*cox*vdse*
RS/(L*c*c);
5144 dvdsevgs = delvdsevsat*dvsatvgt*dvgtvgs+delvdsevdso*temp1;
5145 ddeltalvgs = deldeltalvdse*dvdsevgs + deldeltalmu*dmuvgt*dvgtvgs
5146 + deldeltalvdso*temp1;
5147 gmo = e*(gmoo+ichoo*ddeltalvgs*e/L);
5149 dvdsevds = delvdsevsat*dvsatvgt*sigma+delvdsevdso*temp1;
5150 ddeltalvds = deldeltalvdse*dvdsevds + deldeltalmu*dmuvgt*sigma
5151 + deldeltalvdso*temp1;
5152 gdso = e*(gdsoo+ichoo*ddeltalvds*e/L);
5154 dvdsevbs = delvdsevsat*dvsatvbs+delvdsevdso*temp1;
5155 ddeltalvbs = deldeltalvdse*dvdsevbs + deldeltalmu*dmuvon*dvonvbs
5156 + deldeltalvdso*temp1;;
5157 gbso = e*(gbsoo+ichoo*ddeltalvbs*e/L);
5166 del = d*mm1_loc*mu*vdse;
5180 cdraindrift_loc = icho*e;
5181 delmm1vdso = a*c+mm1_loc*
LS*
BI/(b*b);
5182 dmm1vgs_loc = delmm1vdso*(-gmoo*rt-dvdsevgs);
5183 ddelvgs = h*d*(mu*vdse*dmm1vgs_loc + mm1_loc*vdse*dmuvgt*dvgtvgs
5184 + mu*mm1_loc*dvdsevgs);
5185 gm = e*(gmo+icho*ddelvgs*e);
5186 dmm1vds_loc = delmm1vdso*(1-gdsoo*rt-dvdsevds);
5187 ddelvds = h*d*(mu*vdse*dmm1vds_loc + mm1_loc*vdse*dmuvgt*sigma
5188 + mu*mm1_loc*dvdsevds);
5189 gdds = e*(gdso+icho*ddelvds*e);
5190 dmm1vbs_loc = delmm1vdso*(-gbsoo*rt-dvdsevbs);
5191 ddelvbs = h*d*(mu*vdse*dmm1vbs_loc + mm1_loc*vdse*dmuvon*dvonvbs
5192 + mu*mm1_loc*dvdsevbs);
5193 gmbs = e*(gbso+icho*ddelvbs*e);
5220 bool bsuccess =
true;
5237 bsuccess = bsuccess && btmp;
5239 double vgs1(0.0), vgdd1(0.0), vbs1(0.0),vgb1(0.0), vdds1(0.0);
5387 double coef_Jdxp(0.0), gd_Jdxp(0.0);
5391 double ceqbs = Dtype*(mi.
cbs+mi.
cqbs);
5392 double ceqbd = Dtype*(mi.
cbd+mi.
cqbd);
5394 double D1current = Dtype*mi.
D1cdeq;
5399 if (mi.
Igate != 0.0)
5407 fVec[mi.
li_Bulk] += (ceqbs + ceqbd);
5419 dFdxdVp[mi.
li_Bulk] += coef_Jdxp;
5422 coef_Jdxp = Dtype*(-((mi.
gbd-gmin1))*
5444 double qcoef_Jdxp(0.0);
5446 double Qeqbs = Dtype*mi.
qbs;
5447 double Qeqbd = Dtype*mi.
qbd;
5448 double Qeqgb = Dtype*mi.
qgb;
5449 double Qeqgs = Dtype*mi.
qgs;
5450 double Qeqgdd = Dtype*mi.
qgdd;
5453 qVec[mi.
li_Bulk] += (Qeqbs + Qeqbd - Qeqgb);
5467 dQdxdVp[mi.
li_Bulk] += qcoef_Jdxp;
5483 dQdxdVp[mi.
li_Drain] += qcoef_Jdxp;
5493 if (mi.
Igate != 0.0)
5555 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
5567 #pragma omp parallel for
5725 int sizeInstances = instanceContainer_.size();
5728 #pragma omp parallel for
5730 for (
int i=0; i<sizeInstances; ++i)
5732 Instance & mi = *(instanceContainer_.at(i));
5886 .registerDevice(
"m", 18)
5887 .registerModelType(
"pmos", 18)
5888 .registerModelType(
"nmos", 18);