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) <<
"Both uo and u0 have been specified and, which is not allowed";
773 UserWarning0(*
this) <<
"Surface mobility has been specified as u0 instead of uo, uo is the preferred syntax";
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;
1832 #ifdef Xyce_DEBUG_DEVICE
1835 Xyce::dout() << std::endl;
1836 Xyce::dout() << section_divider << std::endl;
1837 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
1838 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1839 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
1874 #ifdef Xyce_DEBUG_DEVICE
1877 Xyce::dout() <<
" State local indices:" << std::endl;
1878 Xyce::dout() << std::endl;
1880 Xyce::dout() <<
" li_state_vbdd = " <<
li_state_vbdd <<
"\n";
1881 Xyce::dout() <<
" li_state_vbs = " <<
li_state_vbs <<
"\n";
1882 Xyce::dout() <<
" li_state_vgps = " <<
li_state_vgps <<
"\n";
1883 Xyce::dout() <<
" li_state_vdds = " <<
li_state_vdds <<
"\n";
1884 Xyce::dout() <<
" li_state_qgs = " <<
li_state_qgs <<
"\n";
1889 Xyce::dout() <<
" li_state_qgdd = " <<
li_state_qgdd <<
"\n";
1891 Xyce::dout() <<
" li_state_qgb = " <<
li_state_qgb <<
"\n";
1893 Xyce::dout() <<
" li_state_qbs = " <<
li_state_qbs <<
"\n";
1895 Xyce::dout() <<
" li_state_qbd = " <<
li_state_qbd <<
"\n";
1899 Xyce::dout() <<
" li_state_von = " <<
li_state_von <<
"\n";
1901 Xyce::dout() << std::endl;
1902 Xyce::dout() << section_divider << std::endl;
1995 std::vector<int> map;
1996 std::vector< std::vector<int> > map2;
2176 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2300 double coef_Jdxp(0.0);
2302 double ceqbs(0.0), ceqbd(0.0), ceqgb(0.0), ceqgs(0.0), ceqgdd(0.0);
2309 ceqgdd = Dtype*
qgdd;
2311 qVec[
li_Bulk] += (ceqbs + ceqbd - ceqgb);
2324 dQdxdVp[
li_Bulk] += coef_Jdxp;
2397 double coef_Jdxp(0.0), gd_Jdxp(0.0);
2401 double ceqbs = Dtype*(
cbs+
cqbs);
2402 double ceqbd = Dtype*(
cbd+
cqbd);
2404 double D1current = Dtype*
D1cdeq;
2413 fVec[
li_Bulk] += (ceqbs + ceqbd);
2425 dFdxdVp[
li_Bulk] += coef_Jdxp;
2428 coef_Jdxp = Dtype*(-((
gbd-gmin1))*
2624 bool bsuccess =
true;
2631 #define ISUBMOD model_.isubmod
2643 double capgs_old(0.0);
2644 double capgdd_old(0.0);
2645 double capgb_old(0.0);
2649 double D1power(0.0);
2654 double D1csatr(0.0);
2655 double D1czero(0.0);
2656 double D1czof2(0.0);
2660 double D1evrev(0.0);
2663 double D1vdtemp(0.0);
2667 #ifdef Xyce_DEBUG_DEVICE
2671 Xyce::dout() << subsection_divider << std::endl;
2672 Xyce::dout() <<
" Instance::updateIntermediateVars.\n"<<std::endl;
2673 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2674 Xyce::dout() <<
" Model name = " <<
model_.
getName() << std::endl;
2675 Xyce::dout() <<
" dtype is " <<
model_.
dtype << std::endl;
2676 Xyce::dout() << std::endl;
2677 Xyce::dout().width(25); Xyce::dout().precision(17); Xyce::dout().setf(std::ios::scientific);
2719 #ifdef Xyce_DEBUG_DEVICE
2722 Xyce::dout() <<
" " << std::endl;
2723 Xyce::dout() <<
" Solution vector: " << std::endl;
2724 Xyce::dout() <<
" Vg = " <<
Vg << std::endl;
2725 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
2726 Xyce::dout() <<
" Vs = " <<
Vs << std::endl;
2727 Xyce::dout() <<
" Vb = " <<
Vb << std::endl;
2728 Xyce::dout() <<
" Vdp = " <<
Vdp << std::endl;
2729 Xyce::dout() <<
" Vgp = " <<
Vgp << std::endl;
2730 Xyce::dout() <<
" Vsp = " <<
Vsp << std::endl;
2731 Xyce::dout() <<
" Vdd = " <<
Vdd << std::endl;
2732 Xyce::dout() <<
" Vd1p= " <<
Vd1p << std::endl;
2778 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
2835 #ifdef Xyce_DEBUG_DEVICE
2838 Xyce::dout() <<
"After Von first set, ";
2839 Xyce::dout() <<
" von = " <<
von <<
" Von = " << Von << std::endl;
2848 #ifdef Xyce_DEBUG_DEVICE
2851 Xyce::dout() <<
" checking whether to limit voltages "<< std::endl;
2852 Xyce::dout() <<
" Von = " << Von << std::endl;
2853 Xyce::dout() <<
" before limiting: " << std::endl;
2854 Xyce::dout() <<
" vgpdd = " <<
vgpdd <<
" vgpdd_old = " <<
vgpdd_old << std::endl;
2855 Xyce::dout() <<
" vgps = " <<
vgps <<
" vgps_old = " <<
vgps_old << std::endl;
2856 Xyce::dout() <<
" vdds = " << vdds <<
" vdds_old = " <<
vdds_old << std::endl;
2857 Xyce::dout() <<
" vbs = " <<
vbs <<
" vbs_old = " <<
vbs_old << std::endl;
2858 Xyce::dout() <<
" vbdd = " <<
vbdd <<
" vbdd_old = " <<
vbdd_old << std::endl;
2889 #ifdef Xyce_DEBUG_DEVICE
2892 Xyce::dout() <<
" After limiting: " << std::endl;
2893 Xyce::dout() <<
" vgpdd = " <<
vgpdd << std::endl;
2894 Xyce::dout() <<
" vgps = " <<
vgps << std::endl;
2895 Xyce::dout() <<
" vdds = " << vdds << std::endl;
2896 Xyce::dout() <<
" vbs = " <<
vbs << std::endl;
2897 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
2902 bool tmpGiven =
false;
2929 #ifdef Xyce_DEBUG_DEVICE
2932 Xyce::dout() <<
" vbs = " << vbs << std::endl;
2933 Xyce::dout() <<
" vgps = " <<
vgps << std::endl;
2934 Xyce::dout() <<
" vdds = " << vdds << std::endl;
2935 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
2936 Xyce::dout() <<
" vgpdd= " <<
vgpdd << std::endl;
2938 Xyce::dout() <<
" Vddp = " <<
Vddp << std::endl;
2939 Xyce::dout() <<
" Vddd = " <<
Vddd << std::endl;
2940 Xyce::dout() <<
" Vdddp= " <<
Vdddp << std::endl;
2941 Xyce::dout() <<
" Vssp = " <<
Vssp << std::endl;
2942 Xyce::dout() <<
" Vbsp = " <<
Vbsp << std::endl;
2943 Xyce::dout() <<
" Vbdp = " <<
Vbdp << std::endl;
2944 Xyce::dout() <<
" Vggp = " <<
Vggp << std::endl;
2945 Xyce::dout() <<
" Vgpsp = " <<
Vgpsp << std::endl;
2946 Xyce::dout() <<
" Vgpdp = " <<
Vgpdp << std::endl;
2947 Xyce::dout() <<
" Vgpb = " <<
Vgpb << std::endl;
2948 Xyce::dout() <<
" Vdpsp= " <<
Vdpsp << std::endl;
2957 #ifdef Xyce_DEBUG_DEVICE
2962 Xyce::dout() <<
" Something modified the voltages. " << std::endl;
2963 Xyce::dout() <<
" Voltage before after diff " << std::endl;
2965 Xyce::dout() <<
" vdds " <<
vdds_orig <<
" " << vdds <<
" " << vdds-
vdds_orig << std::endl;
2966 Xyce::dout() <<
" vbs " <<
vbs_orig <<
" " << vbs <<
" " << vbs-
vbs_orig << std::endl;
3003 j1=
model_.
artd*log(end1/end2)*(pi/2+atan(end3));
3008 d1j1=(fr1-fr2)*(pi/2+atan(end3));
3010 d2j1=log(end1/end2)*fr3;
3029 #ifdef Xyce_DEBUG_DEVICE
3032 Xyce::dout() <<
"*******Setting cbs for vbs<=0 ******" << std::endl;
3033 Xyce::dout() <<
" vbs = " << vbs << std::endl;
3034 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3035 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3036 Xyce::dout() <<
" SSC = " <<
SourceSatCur << std::endl;
3037 Xyce::dout() <<
" gbs = " << gbs << std::endl;
3038 Xyce::dout() <<
" cbs = " <<
cbs << std::endl;
3039 Xyce::dout() <<
" j1 = " << j1 << std::endl;
3053 #ifdef Xyce_DEBUG_DEVICE
3056 Xyce::dout() <<
"*******Setting cbs for vbs>0 ******" << std::endl;
3057 Xyce::dout() <<
" vbs = " << vbs << std::endl;
3058 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3059 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3060 Xyce::dout() <<
" vbs/vt = " << vbs/
vt << std::endl;
3064 Xyce::dout() <<
" evbs = " << evbs << std::endl;
3065 Xyce::dout() <<
" gbs = " <<
gbs << std::endl;
3066 Xyce::dout() <<
" cbs = " << cbs << std::endl;
3079 #ifdef Xyce_DEBUG_DEVICE
3082 Xyce::dout() <<
"*******Setting cbd for vbdd<=0 ******" << std::endl;
3083 Xyce::dout() <<
" vbdd = " << vbdd << std::endl;
3084 Xyce::dout() <<
" SSC = " <<
SourceSatCur << std::endl;
3085 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3086 Xyce::dout() <<
" n2 = " <<
model_.
n2 << std::endl;
3087 Xyce::dout() <<
" gbd = " << gbd << std::endl;
3088 Xyce::dout() <<
" cbd = " <<
cbd << std::endl;
3103 #ifdef Xyce_DEBUG_DEVICE
3106 Xyce::dout() <<
"*******Setting cbd for vbdd>0 ******" << std::endl;
3107 Xyce::dout() <<
" vbdd = " <<
vbdd << std::endl;
3108 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3109 Xyce::dout() <<
" vbdd/vt = " <<
vbdd/
vt << std::endl;
3113 Xyce::dout() <<
" evbdd = " << evbdd << std::endl;
3114 Xyce::dout() <<
" gbd = " <<
gbd << std::endl;
3115 Xyce::dout() <<
" cbd = " << cbd << std::endl;
3125 double dvonvbs(0.0);
3126 double lvbs =
mode == 1 ? vbs :
vbdd;
3164 D1evd = D1arg = D1evrev = 0.0;
3169 D1evr = exp(
D1vd/D1vtr);
3171 D1arg = D1temp*D1temp;
3173 D1isr = D1csatr*D1power;
3174 D1cdr = D1isr*(D1evr - 1);
3198 D1arg = D1arg * D1arg * D1arg;
3210 #ifdef Xyce_DEBUG_DEVICE
3213 Xyce::dout() <<
" " << std::endl;
3214 Xyce::dout() <<
" dtype = " <<
model_.
dtype << std::endl;
3215 Xyce::dout() <<
" D1vd = " <<
D1vd << std::endl;
3216 Xyce::dout() <<
" D1vtr = " << D1vtr << std::endl;
3217 Xyce::dout() <<
" D1csat = " << D1csat << std::endl;
3218 Xyce::dout() <<
" D1csatr = " << D1csatr << std::endl;
3219 Xyce::dout() <<
" D1gspr = " <<
D1gspr << std::endl;
3220 Xyce::dout() <<
" D1cdr = " << D1cdr << std::endl;
3221 Xyce::dout() <<
" D1gdr = " << D1gdr << std::endl;
3222 Xyce::dout() <<
" D1vte = " <<
D1vte << std::endl;
3223 Xyce::dout() <<
" D1evd = " << D1evd << std::endl;
3224 Xyce::dout() <<
" D1arg = " << D1arg << std::endl;
3225 Xyce::dout() <<
" D1evrev = " << D1evrev << std::endl;
3226 Xyce::dout() <<
" D1DIOtBrkdwnV = " <<
D1DIOtBrkdwnV << std::endl << std::endl;
3227 Xyce::dout() <<
" D1cd = " << D1cd << std::endl;
3228 Xyce::dout() <<
" D1gd = " <<
D1gd << std::endl;
3229 Xyce::dout() <<
" D1cdeq = " <<
D1cdeq << std::endl;
3270 sarg = sargsw = 1/sqrt(arg);
3289 sargsw = 1/sqrt(arg);
3329 sarg = sargsw = 1/sqrt(arg);
3343 sargsw = 1/sqrt(arg);
3353 +
Cbdsw*(1-arg*sargsw)
3394 #ifdef Xyce_DEBUG_DEVICE
3397 Xyce::dout() <<
" " << std::endl;
3398 Xyce::dout() <<
" Going into qmeyer..." << std::endl;
3399 Xyce::dout() <<
" Mode is " <<
mode << std::endl;
3400 Xyce::dout() <<
" Args are vgps = " <<
vgps <<
" vgpdd = " <<
vgpdd << std::endl;
3401 Xyce::dout() <<
" Vgpb = " <<
Vgpb <<
" Von = " << Von <<
" Vddsat = " << Vddsat << std::endl;
3402 Xyce::dout() <<
" tPhi = " <<
tPhi <<
" OxideCap = " <<
OxideCap << std::endl;
3444 #ifdef Xyce_DEBUG_DEVICE
3447 Xyce::dout() <<
"Doing meyer back averaging..."<< std::endl;
3448 Xyce::dout() <<
" capgs = " <<
capgs <<
" capgs_old = " << capgs_old << std::endl;
3449 Xyce::dout() <<
" capgdd = " <<
capgdd <<
" capgdd_old = " << capgdd_old << std::endl;
3450 Xyce::dout() <<
" capgb = " <<
capgb <<
" capgb_old = " << capgb_old << std::endl;
3457 #ifdef Xyce_DEBUG_DEVICE
3460 Xyce::dout() <<
"Capgs = " <<
Capgs << std::endl;
3461 Xyce::dout() <<
"Capgdd = " <<
Capgdd << std::endl;
3462 Xyce::dout() <<
"Capgb = " <<
Capgb << std::endl;
3463 Xyce::dout() <<
"capgs = " <<
capgs << std::endl;
3464 Xyce::dout() <<
"capgdd = " <<
capgdd << std::endl;
3465 Xyce::dout() <<
"capgb = " <<
capgb << std::endl;
3473 double absV = fabs(
Vddd);
3480 double dVddd_dVd (1.0);
3481 double d_absVddd_dVd (0.0);
3484 d_absVddd_dVd = 1.0;
3486 else if (
Vddd < 0.0)
3488 d_absVddd_dVd = -1.0;
3529 #ifdef Xyce_DEBUG_DEVICE
3532 Xyce::dout() <<
" Done with Instance::updateIntermediateVars " << std::endl;
3533 Xyce::dout() <<
" mode = " <<
mode << std::endl;
3534 Xyce::dout() <<
" Idrain = " <<
Idrain << std::endl;
3535 Xyce::dout() <<
" Igate = " <<
Igate << std::endl;
3536 Xyce::dout() <<
" Isource = " <<
Isource << std::endl;
3537 Xyce::dout() <<
" Idraindrift = " <<
Idraindrift << std::endl;
3538 Xyce::dout() <<
" Ird1rs = " << Ird1rs << std::endl;
3539 Xyce::dout() <<
" dIdd_dVd = " <<
dIdd_dVd << std::endl;
3540 Xyce::dout() <<
" gddd = " <<
gddd << std::endl;
3541 Xyce::dout() <<
" Irdsshunt = " <<
Irdsshunt << std::endl;
3542 Xyce::dout() <<
" D1DIOcapCurrent = " <<
D1DIOcapCurrent << std::endl;
3543 Xyce::dout() <<
" cbd = " << cbd << std::endl;
3544 Xyce::dout() <<
" cbs = " <<
cbs << std::endl;
3545 Xyce::dout() <<
" qbd = " <<
qbd << std::endl;
3546 Xyce::dout() <<
" qbs = " <<
qbs << std::endl;
3547 Xyce::dout() <<
" cdrain = " <<
cdrain << std::endl;
3548 Xyce::dout() <<
" cdraindrift = " <<
cdraindrift << std::endl;
3549 Xyce::dout() <<
" cdreq = " <<
cdreq << std::endl;
3550 Xyce::dout() <<
" gdds = " <<
gdds << std::endl;
3551 Xyce::dout() <<
" gdsshunt = " <<
gdsshunt << std::endl;
3552 Xyce::dout() <<
" gm = " <<
gm << std::endl;
3553 Xyce::dout() <<
" gmbs = " <<
gmbs << std::endl;
3554 Xyce::dout() <<
" Gm = " <<
Gm << std::endl;
3555 Xyce::dout() <<
" Gmbs = " <<
Gmbs << std::endl;
3601 bool bsuccess =
true;
3610 double ratio,ratio4(0.0);
3615 double capfact(0.0);
3618 double gmanew,gmaold(0.0);
3623 double D1vte_loc(0.0);
3628 double D1vt_loc(0.0);
3629 register int D1iter(0.0);
3630 double D1egfet1(0.0),D1arg1(0.0),D1fact1(0.0),D1pbfact1(0.0),D1pbo(0.0),D1gmaold(0.0);
3631 double D1fact2(0.0),D1pbfact(0.0),D1arg(0.0),D1egfet(0.0),D1gmanew(0.0);
3640 #ifdef Xyce_DEBUG_DEVICE
3644 Xyce::dout() << subsection_divider << std::endl;
3645 Xyce::dout() <<
" Instance::Begin of updateTemperature. \n";
3646 Xyce::dout() <<
" name = " <<
getName() << std::endl;
3647 Xyce::dout() << std::endl;
3652 if (temp_tmp != -999.0)
temp = temp_tmp;
3669 #ifdef Xyce_DEBUG_DEVICE
3672 Xyce::dout() <<
" Temperature = "<<
temp << std::endl;
3673 Xyce::dout() <<
" tnom = " << tnom << std::endl;
3674 Xyce::dout() <<
" ratio = " << ratio << std::endl;
3684 pbfact = -2*
vt *(1.5*log(fact2)+
CONSTQ*arg);
3686 #ifdef Xyce_DEBUG_DEVICE
3689 Xyce::dout() <<
" fact1 = " <<
model_.
fact1 << std::endl;
3690 Xyce::dout() <<
" vtnom = " <<
model_.
vtnom << std::endl;
3691 Xyce::dout() <<
" egfet1 = " <<
model_.
egfet1 << std::endl;
3692 Xyce::dout() <<
" pbfact1= " <<
model_.
pbfact1 << std::endl;
3693 Xyce::dout() <<
" vt = " <<
vt << std::endl;
3694 Xyce::dout() <<
" ratio = " << ratio << std::endl;
3695 Xyce::dout() <<
" fact2 = " << fact2 << std::endl;
3696 Xyce::dout() <<
" kt = " << kt << std::endl;
3697 Xyce::dout() <<
" egfet = " << egfet << std::endl;
3698 Xyce::dout() <<
" arg = " << arg << std::endl;
3699 Xyce::dout() <<
" pbfact = " << pbfact << std::endl;
3703 ratio4 = ratio * sqrt(ratio);
3706 tPhi = fact2 * phio + pbfact;
3739 #ifdef Xyce_DEBUG_DEVICE
3742 Xyce::dout() <<
" ratio4 = " << ratio4 << std::endl;
3743 Xyce::dout() <<
" tSurfMob = " <<
tSurfMob << std::endl;
3744 Xyce::dout() <<
" phio = " << phio << std::endl;
3745 Xyce::dout() <<
" tPhi = " <<
tPhi << std::endl;
3746 Xyce::dout() <<
" tVbi = " <<
tVbi << std::endl;
3747 Xyce::dout() <<
" tVto = " <<
tVto << std::endl;
3748 Xyce::dout() <<
" tSatCur = " <<
tSatCur << std::endl;
3749 Xyce::dout() <<
" tSatCurDens = " <<
tSatCurDens << std::endl;
3750 Xyce::dout() <<
" pbo = " << pbo << std::endl;
3751 Xyce::dout() <<
" gmaold = " << gmaold << std::endl;
3752 Xyce::dout() <<
" tBulkPot = " <<
tBulkPot << std::endl;
3753 Xyce::dout() <<
" gmanew = " << gmanew << std::endl;
3754 Xyce::dout() <<
" capfact = " << capfact << std::endl;
3755 Xyce::dout() <<
" tCbd = " <<
tCbd << std::endl;
3756 Xyce::dout() <<
" tCbs = " <<
tCbs << std::endl;
3757 Xyce::dout() <<
" tCj = " <<
tCj << std::endl;
3758 Xyce::dout() <<
" capfact = " << capfact << std::endl;
3759 Xyce::dout() <<
" tCjsw = " <<
tCjsw << std::endl;
3760 Xyce::dout() <<
" tDepCap = " <<
tDepCap << std::endl;
3876 vthLimit = N_UTL_MachineDependentParams::DoubleMax();
3889 D1egfet = 1.16-(7.02e-4*D1DIOtemp*
D1DIOtemp)/(D1DIOtemp+1108);
3890 D1arg = -D1egfet/(2*CONSTboltz*
D1DIOtemp) + 1.1150877/
3892 D1pbfact = -2*D1vt_loc*(1.5*log(D1fact2)+
CONSTQ*D1arg);
3899 (1.5*log(D1fact1)+
CONSTQ*D1arg1);
3938 Xyce::dout() <<
" breakdown current increased to " << D1cbv <<
3939 "to resolve incompatability " <<
3940 "with specified saturation current" << std::endl;
3947 D1vt_loc*log(1+D1cbv/D1DIOtSatCur);
3948 for(D1iter=0; D1iter<25; ++D1iter)
3951 D1DIOtSatCur+1-D1xbv/D1vt_loc);
3953 -D1xbv)/D1vt_loc)-1+D1xbv/D1vt_loc);
3954 if (fabs(D1xcbv-D1cbv) <= D1tol)
goto matched;
3956 Xyce::dout() <<
" unable to match forward and reverse diode regions: D1bv = "
3957 << D1xbv <<
" D1ibv = " << D1xcbv << std::endl;
3976 bool bsuccess =
true;
3977 double vgs1(0.0), vgdd1(0.0), vbs1(0.0),vgb1(0.0), vdds1(0.0);
3982 bsuccess = bsuccess && tmpBool;
4111 #ifdef Xyce_DEBUG_DEVICE
4114 Xyce::dout() <<
" L = " <<
l << std::endl;
4115 Xyce::dout() <<
" W = " <<
w<< std::endl;
4116 Xyce::dout() <<
" drainArea = " <<
drainArea<< std::endl;
4117 Xyce::dout() <<
" sourceArea = " <<
sourceArea<< std::endl;
4118 Xyce::dout() <<
" drainSquares = " <<
drainSquares<< std::endl;
4119 Xyce::dout() <<
" sourceSquares = " <<
sourceSquares<< std::endl;
4120 Xyce::dout() <<
" drainPerimeter = " <<
drainPerimeter<< std::endl;
4122 Xyce::dout() <<
" drainCond = " <<
drainCond<< std::endl;
4123 Xyce::dout() <<
" sourceCond = " <<
sourceCond << std::endl;
4124 Xyce::dout() <<
" draindriftCond = " <<
draindriftCond<< std::endl;
4125 Xyce::dout() <<
" temp = " <<
temp<< std::endl;
4154 double vddsat_local,
4155 double & capgs_local,
4156 double & capgdd_local,
4157 double & capgb_local,
4162 double vdds_local(0.0);
4172 #define L EffectiveLength
4173 #define ETA model_.eta
4174 #define TOX model_.oxideThickness
4176 vgst = xvgs-von_local;
4179 capgb_local = cox/2;
4183 else if (vgst <= -phi/2)
4185 capgb_local = -vgst*cox/(2*phi);
4191 capgb_local = -vgst*cox/(2*phi);
4192 capgs_local = vgst*cox/(1.5*phi)+cox/3;
4197 vdds_local = xvgs-xvgdd;
4199 if (vddsat_local <= vdds_local)
4201 capgs_local = cox/3;
4206 vddif = 2.0*vddsat_local-vdds_local;
4207 vddif1 = vddsat_local-vdds_local;
4208 vddif2 = vddif*vddif;
4209 capgdd_local = cox*(1.0-vddsat_local*vddsat_local/vddif2)/3;
4210 capgs_local = cox*(1.0-vddif1*vddif1/vddif2)/3;
4217 if(
model_.
cv == 2 && vddsat_local != 0)
4219 vdds_local = fabs(xvgs-xvgdd);
4220 vdds_local = vdds_local/pow(1+pow(vdds_local/vddsat_local,
model_.
mc),
4222 vddif = 2.0*vddsat_local-vdds_local;
4223 vddif1 = vddsat_local-vdds_local;
4224 vddif2 = vddif*vddif;
4228 capgdd_local = cgc*(1.0-vddsat_local*vddsat_local/vddif2)/3;
4229 capgs_local = cgc*(1.0-vddif1*vddif1/vddif2)/3;
4255 double vbs_local(0.0);
4256 double vdds_local(0.0);
4264 double DeltaVT(0.0);
4265 double DnsdVgs(0.0);
4266 double DnsdVgd(0.0);
4267 double DnsdVgb(0.0);
4268 double DnssVgs(0.0);
4269 double DnssVgd(0.0);
4270 double DnssVgb(0.0);
4271 double DndepVgs(0.0);
4272 double DndepVgd(0.0);
4273 double DndepVgb(0.0);
4294 double SigmaVgs(0.0);
4295 double SigmaVgd(0.0);
4303 vbs_local = xvgs-vgb;
4304 vdds_local = xvgs-xvgdd;
4309 if(xvgs > VFB+vbs_local)
4314 nss=2.0*
n0*log(1+0.5*exp((xvgs-
von)/etavt));
4315 nsd=2.0*
n0*log(1+0.5*exp((xvgs-
von-ALPHA*vdds_local)/etavt));
4317 if (nss<1e-36) {nss=1.0e-36;}
4318 if (nsd<1e-36) {nsd=1.0e-36;}
4319 zetanb = (1-ALPHA)/ALPHA;
4320 xi = gamma*gamma/(A*A)+4/(A*A)*(vgb-VFB)-4.0/A*nss;
4324 if (vbs_local <= 0) { DeltaVT= 0.5*gamma/sqrt(
tPhi-vbs_local); }
4325 if ((vbs_local > 0)&&(vbs_local <= 2*
tPhi)) { DeltaVT=0.5*gamma/sqrt(
tPhi); }
4326 if ((vbs_local > 0)&&(vbs_local > 2*
tPhi)) { DeltaVT=0; }
4328 DnsdVgs=(1+DeltaVT-ALPHA+SigmaVgs)/tnsd;
4329 DnsdVgd=(-SigmaVgd+ALPHA)/tnsd;
4330 DnsdVgb=-DeltaVT/tnsd;
4332 DnssVgs= (1+DeltaVT+SigmaVgs)/tnss;
4333 DnssVgd=-SigmaVgd/tnss;
4334 DnssVgb=-DeltaVT/tnss;
4336 UI= etavt/2.0*(nsd*nsd-nss*nss) + A/3.0*(nsd*nsd*nsd-nss*nss*nss);
4337 VI= etavt*(nsd-nss) + A/2.0*(nsd*nsd-nss*nss);
4338 DUIVgs = etavt*(nsd*DnsdVgs-nss*DnssVgs) +
4339 A*(nsd*nsd*DnsdVgs-nss*nss*DnssVgs);
4340 DUIVgd= etavt*(nsd*DnsdVgd-nss*DnssVgd) +
4341 A*(nsd*nsd*DnsdVgd-nss*nss*DnssVgd);
4342 DUIVgb= etavt*(nsd*DnsdVgb-nss*DnssVgb) +
4343 A*(nsd*nsd*DnsdVgb-nss*nss*DnssVgb);
4345 DVIVgs= etavt*(DnsdVgs-DnssVgs) + A*(nsd*DnsdVgs-nss*DnssVgs);
4346 DVIVgd= etavt*(DnsdVgd-DnssVgd) + A*(nsd*DnsdVgd-nss*DnssVgd);
4347 DVIVgb= etavt*(DnsdVgb-DnssVgb) + A*(nsd*DnsdVgb-nss*DnssVgb);
4350 DqiVgs= mqWL*(DUIVgs*VI-DVIVgs*UI)/(VI*VI);
4351 DqiVgd= mqWL*(DUIVgd*VI-DVIVgd*UI)/(VI*VI);
4352 DqiVgb= mqWL*(DUIVgb*VI-DVIVgb*UI)/(VI*VI);
4356 DqiVgs=mqWL*DnssVgs;
4357 DqiVgd=mqWL*DnssVgd;
4358 DqiVgb=mqWL*DnssVgb;
4361 DxiVgs= -4.0/A*DnssVgs;
4362 DxiVgd= -4.0/A*DnssVgd;
4363 DxiVgb= 4.0/(A*A)-4/A*DnssVgb;
4366 {DndepVgs= gamma/4.0*1.0/xisqrt*DxiVgs;
4367 DndepVgd= gamma/4.0*1.0/xisqrt*DxiVgd;
4368 DndepVgb= gamma/4.0*1.0/xisqrt*DxiVgb;
4377 DqbVgs = mqWL*(DndepVgs-zetanb*DnssVgs)+zetanb*DqiVgs;
4378 DqbVgd = mqWL*(DndepVgd-zetanb*DnssVgd)+zetanb*DqiVgd;
4379 DqbVgb = mqWL*(DndepVgb-zetanb*DnssVgb)+zetanb*DqiVgb;
4381 DqgVgs= -DqiVgs-DqbVgs;
4382 DqgVgd= -DqiVgd-DqbVgd;
4383 DqgVgb= -DqiVgb-DqbVgb;
4393 if (DqgVgs<0) {DqgVgs=0;}
4394 if (DqgVgd<0) {DqgVgd=0;}
4395 if (DqgVgb<0) {DqgVgb=0;}
4415 double vgb,
double & qD,
double & qS,
double & qB)
4436 double vdds_local(0.0);
4445 vdds_local=vgs-vgdd;
4452 nsd=2*
n0*log(1+0.5*exp((vgs-VT-ALPHA*vdds_local)/etavth));
4453 nss=2*
n0*log(1+0.5*exp((vgs-VT)/etavth));
4459 arg1= 0.5*etavth*(nsdsqr-nsssqr)+1/3.0*A*(nsdsqr*nsd-nsssqr*nss);
4460 arg2= etavth*(nsd-nss) +0.5*A*(nsdsqr-nsssqr);
4464 else {qn = mqWL*arg1/arg2;}
4465 xisqrt= sqrt(gamma*gamma/(A*A)+4.0/(A*A)*(vgb-VFB)-4.0/A*nss);
4466 ndeps = -gamma*gamma/(2.0*A)+ gamma/2.0*xisqrt;
4467 zetanb =(1-ALPHA)/ALPHA;
4469 qB =mqWL*(ndeps-zetanb*nss)+zetanb*qn;
4484 double fp1denum(0.0);
4486 vdsabs=fabs(vdds_local);
4490 if((vsat > 1e-36)&&(vdds_local>1e-36))
4491 { beta=vdsabs/vsat;}
else{beta=1e-36;}
4494 fp1denum = exp(1/m*log(1+exp(m*log(beta))));
4495 if (fp1denum > 1e-36)
4496 {fp1= 0.5+ a0*vdsabs/fp1denum;}
4506 double arg1_loc(0.0);
4507 double arg2_loc(0.0);
4508 double arg3_loc(0.0);
4512 arg1_loc= nd0*nd0*nd0*(1/3.0+nd0*(3.0/8.0+1/10.0*nd0))
4513 - (1.0/2.0+1.0/3.0*nd0)*(1.0+1/2.0*ns0)*nd0*nd0*ns0
4514 + ns0*ns0*ns0*(1.0/6.0+ns0*(5.0/24.0+1.0/15.0*ns0));
4515 arg2_loc = 1.0/2.0*(nd0*nd0-ns0*ns0)+1.0/3.0*(nd0*nd0*nd0-ns0*ns0*ns0);
4516 arg3_loc = nd0-ns0+1.0/2.0*(nd0*nd0-ns0*ns0);
4517 if ((arg2_loc==0)||(arg3_loc==0)) {fp1=0.5;}
4518 else { fp1 = 1-arg1_loc/(arg2_loc*arg3_loc);}
4523 UserWarning(*
this) <<
"Partitioning model does not exist";
4554 double & von_local,
double & dvonvbs_local)
4556 double PhiMinVbs =
tPhi - vbs_local;
4564 dvonvbs_local = 0.0;
4569 sarg = sqrt(PhiMinVbs);
4595 double dvonvbs,
double & cdraindrift_loc,
double & vsate)
4614 double x(0.0),y(0.0),z(0.0);
4623 double dichoodvds(0.0);
4624 double dichoodvgs(0.0);
4625 double dichoodvbs(0.0);
4626 double dichooisat(0.0);
4627 double dichoodgch(0.0);
4628 double delgchgchi(0.0);
4629 double disatdvds(0.0);
4630 double disatdvgs(0.0);
4631 double disatdvbs(0.0);
4632 double dgchidvds(0.0);
4633 double dgchidvgs(0.0);
4634 double dgchidvbs(0.0);
4635 double disatvgte(0.0);
4636 double disatgchi(0.0);
4637 double dvgtedvgt(0.0);
4638 double dvgtdvds(0.0);
4639 double dvgtdvgs(0.0);
4640 double dvgtdvbs(0.0);
4641 double dnsdvgt(0.0);
4642 double dnsdvds(0.0);
4643 double dnsdvgs(0.0);
4644 double dnsdvbs(0.0);
4645 double dmudvgte(0.0);
4646 double dmudvds(0.0);
4647 double dmudvgs(0.0);
4648 double dmudvbs(0.0);
4650 static int output=0;
4652 #define ETA model_.eta
4653 #define RS model_.sourceResistance
4654 #define RD model_.drainResistance
4655 #define VSIGMAT model_.vsigmat
4656 #define VSIGMA model_.vsigma
4657 #define SIGMA0 model_.sigma0
4658 #define THETA model_.theta
4659 #define LAMBDA model_.lambda
4660 #define DELTA model_.delta
4661 #define VMAX model_.maxDriftVel
4662 #define TOX model_.oxideThickness
4664 #define EXP_MAX 150.0
4667 Xyce::dout() <<
" " << std::endl;
4668 Xyce::dout() <<
"ETA = " <<
ETA << std::endl;
4669 Xyce::dout() <<
"RS = " <<
RS << std::endl;
4670 Xyce::dout() <<
"RD = " <<
RD << std::endl;
4671 Xyce::dout() <<
"VSIGMAT = " <<
VSIGMAT << std::endl;
4672 Xyce::dout() <<
"VSIGMA = " <<
VSIGMA << std::endl;
4673 Xyce::dout() <<
"SIGMA0 = " <<
SIGMA0 << std::endl;
4674 Xyce::dout() <<
"THETA = " <<
THETA << std::endl;
4675 Xyce::dout() <<
"LAMBDA = " <<
LAMBDA << std::endl;
4676 Xyce::dout() <<
"DELTA = " <<
DELTA << std::endl;
4677 Xyce::dout() <<
"VMAX = " <<
VMAX << std::endl;
4678 Xyce::dout() <<
"TOX = " <<
TOX << std::endl;
4687 vgt = vgt0+sigma*xvdds;
4690 vgte = vt*(1+b+1+q);
4705 ns = 2.0*
n0*log(1+0.5*exp(x));
4709 cdraindrift_loc = 0.0;
4722 gch = gchi/(1+gchi*rt);
4727 d = sqrt(1+2*gchi*
RS + vgte*vgte/vl2);
4735 else z = 1/(cosh(y)*cosh(y));
4738 ichoo = isat*(1+
LAMBDA*xvdds)*tanh(y);
4740 dvgtedvgt = 0.5*(1+b/q);
4741 dnsdvgt =
n0/(etavt*(exp(-x)+0.5));
4746 dvgtdvbs = -dvonvbs*dvgtdvgs;
4748 dnsdvds = dnsdvgt*dvgtdvds;
4749 dnsdvgs = dnsdvgt*dvgtdvgs;
4750 dnsdvbs = dnsdvgt*dvgtdvbs;
4751 dmudvds = (dmudvgte*dvgtedvgt)*dvgtdvds;;
4752 dmudvgs = (dmudvgte*dvgtedvgt)*dvgtdvgs;;
4753 dmudvbs = (dmudvgte*dvgtedvgt)*dvgtdvbs + 2*dmudvgte*dvonvbs;
4755 dgchidvds =
gchi0*(mu*dnsdvds + ns*dmudvds);
4756 dgchidvgs =
gchi0*(mu*dnsdvgs + ns*dmudvgs);
4757 dgchidvbs =
gchi0*(mu*dnsdvbs + ns*dmudvbs);
4759 disatvgte = gchi/h - gchi*vgte*vgte/vl2/(d*h*h);
4760 disatgchi = vgte/h - gchi*vgte*
RS*(1+1/d)/(h*h);
4762 disatdvds = (disatvgte*dvgtedvgt)*dvgtdvds + disatgchi*dgchidvds;
4763 disatdvgs = (disatvgte*dvgtedvgt)*dvgtdvgs + disatgchi*dgchidvgs;
4764 disatdvbs = (disatvgte*dvgtedvgt)*dvgtdvbs + disatgchi*dgchidvbs;
4766 dichoodgch = (1+
LAMBDA*xvdds)*xvdds*z;
4767 dichooisat = (1+
LAMBDA*xvdds)*(tanh(y) - gch*xvdds*z/isat);
4769 delgchgchi = 1/(g*g);
4771 dichoodvds = dichooisat*disatdvds + (dichoodgch*delgchgchi)*dgchidvds
4773 dichoodvgs = dichooisat*disatdvgs + (dichoodgch*delgchgchi)*dgchidvgs;
4774 dichoodvbs = dichooisat*disatdvbs + (dichoodgch*delgchgchi)*dgchidvbs;
4777 cdraindrift_loc = ichoo;
4806 double dvonvbs,
double & cdraindrift_loc,
double & vsate)
4852 double delidgch(0.0);
4853 double delgchgchi(0.0);
4854 double delgchins(0.0);
4855 double dvgtevgt(0.0);
4856 double delidvsate(0.0);
4857 double delvsateisat(0.0);
4858 double delisatvgte(0.0);
4859 double delisatgchi(0.0);
4860 double delisatvl(0.0);
4861 double dgchivgt(0.0);
4862 double delvsategch(0.0);
4863 double delidvds(0.0);
4864 double dsigmavgs(0.0);
4865 double delnsvgt(0.0);
4866 double dvsatevgt(0.0);
4867 double dvgtvgs(0.0);
4870 double dvgtvon(0.0);
4871 double delvsatqs(0.0);
4872 double delvsatmu(0.0);
4873 double dvsatvgt(0.0);
4874 double dvsatvbs(0.0);
4875 double delvdsevdso(0.0);
4876 double delvdsevsat(0.0);
4877 double dvdsevgs(0.0);
4878 double dvdsevds(0.0);
4879 double dvdsevbs(0.0);
4882 double delmm1vdso(0.0);
4883 double ddelvgs(0.0);
4884 double ddelvds(0.0);
4885 double ddelvbs(0.0);
4889 double mm1_loc(0.0);
4890 double dmm1vgs_loc(0.0);
4891 double dmm1vds_loc(0.0);
4892 double dmm1vbs_loc(0.0);
4894 static int output(0);
4896 #define ETA model_.eta
4897 #define RS model_.sourceResistance
4898 #define RD model_.drainResistance
4899 #define VSIGMAT model_.vsigmat
4900 #define VSIGMA model_.vsigma
4901 #define SIGMA0 model_.sigma0
4902 #define THETA model_.theta
4903 #define LAMBDA model_.lambda
4904 #define DELTA model_.delta
4905 #define ALPHA model_.alpha
4906 #define VMAX model_.maxDriftVel
4907 #define TOX model_.oxideThickness
4909 #define L EffectiveLength
4910 #define LS model_.ls
4912 #define INVM 1.0/model_.m
4913 #define MC model_.mc
4914 #define INVMC 1.0/model_.mc
4915 #define RSUB model_.rsub
4916 #define AI model_.ai
4917 #define BI model_.bi
4918 #define MD model_.md
4919 #define INVMD 1.0/model_.md
4920 #define DELMAX model_.delmax
4923 Xyce::dout() <<
" " << std::endl;
4924 Xyce::dout() <<
"ETA = " <<
ETA << std::endl;
4925 Xyce::dout() <<
"RS = " <<
RS << std::endl;
4926 Xyce::dout() <<
"RD = " <<
RD << std::endl;
4927 Xyce::dout() <<
"VSIGMAT = " <<
VSIGMAT << std::endl;
4928 Xyce::dout() <<
"VSIGMA = " <<
VSIGMA << std::endl;
4929 Xyce::dout() <<
"SIGMA0 = " <<
SIGMA0 << std::endl;
4930 Xyce::dout() <<
"THETA = " <<
THETA << std::endl;
4931 Xyce::dout() <<
"LAMBDA = " <<
LAMBDA << std::endl;
4932 Xyce::dout() <<
"DELTA = " <<
DELTA << std::endl;
4933 Xyce::dout() <<
"ALPHA = " <<
ALPHA << std::endl;
4934 Xyce::dout() <<
"VMAX = " <<
VMAX << std::endl;
4935 Xyce::dout() <<
"TOX = " <<
TOX << std::endl;
4936 Xyce::dout() <<
"W = " <<
W << std::endl;
4937 Xyce::dout() <<
"L = " <<
L << std::endl;
4938 Xyce::dout() <<
"LS = " <<
LS << std::endl;
4939 Xyce::dout() <<
"M = " <<
M << std::endl;
4940 Xyce::dout() <<
"INVM = " <<
INVM << std::endl;
4941 Xyce::dout() <<
"MC = " <<
MC << std::endl;
4942 Xyce::dout() <<
"INVMC = " <<
INVMC << std::endl;
4943 Xyce::dout() <<
"RSUB = " <<
RSUB << std::endl;
4944 Xyce::dout() <<
"AI = " <<
AI << std::endl;
4945 Xyce::dout() <<
"BI = " <<
BI << std::endl;
4946 Xyce::dout() <<
"MD = " <<
MD << std::endl;
4947 Xyce::dout() <<
"INVMD = " <<
INVMD << std::endl;
4948 Xyce::dout() <<
"DELMAX = " <<
DELMAX << std::endl;
4949 Xyce::dout() <<
"VP = " <<
vp << std::endl;
4959 vgt = vgt0+sigma*xvdds;
4962 vgte = vt*(1+b+1+q);
4977 ns = 2.0*
n0*log(1+0.5*exp(x));
4983 cdraindrift_loc = 0.0;
4989 mm1 = mm1_loc = 0.0;
4997 gch = gchi/(1+gchi*rt);
5001 d = sqrt(1+2*gchi*
RS + vgte*vgte/vl2);
5003 isat = r/(1+gchi*
RS+d);
5006 z = 0.5*(cosh(2*y)+1);
5013 ichoo = isat*(1+
LAMBDA*xvdds)*tanh(y);
5014 delidgch = ichoo/gch;
5016 delgchgchi = 1/(g*g);
5017 delgchins =
gchi0*mu;
5019 delnsvgt =
n0/(etavt*(exp(-x) + 0.5));
5020 dvgtevgt = 0.5*(1+b/q);
5026 delidvsate = gch*(1+
LAMBDA*xvdds)*xvdds/(vsate)/z;
5028 delvsateisat = 1/gch;
5029 delvsategch = -(vsate)/gch;
5031 delisatgchi = (vgte*h - gchi*vgte*
RS*(1+1/d))/(h*h);
5032 delisatvgte = (gchi*h - gchi*vgte*vgte/(vl2*d))/(h*h);
5033 delisatvl = isat*isat*vgte/(gchi*d*vl2*vl);
5035 dgchivgt = delgchins*delnsvgt-gchi*mu*s*dvgtevgt;
5037 p = delgchgchi*dgchivgt;
5038 dvsatevgt = delvsateisat*(delisatgchi*dgchivgt+
5039 (delisatvgte+delisatvl*t*s)*dvgtevgt)+ delvsategch*p;
5040 g = delidgch*p+delidvsate*dvsatevgt;
5041 dvgtvgs = (1+xvdds*dsigmavgs);
5043 gdsoo = delidvds+g*sigma;
5045 dmuvon = -(2-dvgtevgt*dvgtvgs)*mu*mu*s;
5051 gbsoo = -(gmoo)*dvonvbs;
5055 double dgchivon = -delgchins*delnsvgt*dvgtvgs+gchi*dmuvon/mu;
5056 p = delgchgchi*dgchivon;
5057 double dvsatevon = delvsateisat*(delisatgchi*dgchivon+
5058 delisatvgte*dvgtevgt*dvgtvon+delisatvl*(-vl2/t)*dmuvon)+delvsategch*p;
5059 gbsoo = (delidgch*p+delidvsate*dvsatevon)*dvonvbs;
5066 qs =
CONSTQ*(ns-ichoo*temp1);
5067 dqsvgt =
CONSTQ*(delnsvgt-g*temp1);
5068 dqsvbs =
CONSTQ*(delnsvgt*dvgtvon*dvonvbs-gbsoo*temp1);
5077 delvsatqs = 2*
VMAX*L*(b-qs*mu)/temp1;
5078 delvsatmu = -a*qs/temp1;
5079 dvsatvgt = delvsatqs*dqsvgt+delvsatmu*dmuvgt;
5080 dvsatvbs = delvsatqs*dqsvbs+delvsatmu*dmuvon*dvonvbs;
5086 c = sqrt(1+qs*mu*b);
5088 delvsatqs = a*(0.5*b*mu/c);
5089 delvsatmu = -vsat/mu+a*(0.5*b*qs/c);
5090 dvsatvgt = delvsatqs*dqsvgt+delvsatmu*dmuvgt;
5091 dvsatvbs = delvsatqs*dqsvbs+delvsatmu*dmuvon*dvonvbs;
5095 vdso = xvdds-ichoo*rt;
5096 a = pow(vdso/vsat,
MC);
5099 delvdsevdso = (1-a/(1+a))/b;
5100 delvdsevsat = vdse*a/(vsat*(1+a));
5104 double deldeltalvdse(0.0);
5105 double deldeltalvdso(0.0);
5106 double deldeltalmu(0.0);
5107 double ddeltalvgs(0.0);
5108 double ddeltalvds(0.0);
5109 double ddeltalvbs(0.0);
5111 a = 1+(vdso-vdse)/
vp;
5112 b =
W*mu*cox*vdse*
RS/L;
5119 deldeltalvdse = (-
LS/(f*a*
vp)*c-d*(1/
vp+
W*mu*cox*
RS/L))/(c*c);
5120 deldeltalvdso =
LS/(c*a*f*
vp);
5121 deldeltalmu = -d*
W*cox*vdse*
RS/(L*c*c);
5123 dvdsevgs = delvdsevsat*dvsatvgt*dvgtvgs+delvdsevdso*temp1;
5124 ddeltalvgs = deldeltalvdse*dvdsevgs + deldeltalmu*dmuvgt*dvgtvgs
5125 + deldeltalvdso*temp1;
5126 gmo = e*(gmoo+ichoo*ddeltalvgs*e/L);
5128 dvdsevds = delvdsevsat*dvsatvgt*sigma+delvdsevdso*temp1;
5129 ddeltalvds = deldeltalvdse*dvdsevds + deldeltalmu*dmuvgt*sigma
5130 + deldeltalvdso*temp1;
5131 gdso = e*(gdsoo+ichoo*ddeltalvds*e/L);
5133 dvdsevbs = delvdsevsat*dvsatvbs+delvdsevdso*temp1;
5134 ddeltalvbs = deldeltalvdse*dvdsevbs + deldeltalmu*dmuvon*dvonvbs
5135 + deldeltalvdso*temp1;;
5136 gbso = e*(gbsoo+ichoo*ddeltalvbs*e/L);
5145 del = d*mm1_loc*mu*vdse;
5159 cdraindrift_loc = icho*e;
5160 delmm1vdso = a*c+mm1_loc*
LS*
BI/(b*b);
5161 dmm1vgs_loc = delmm1vdso*(-gmoo*rt-dvdsevgs);
5162 ddelvgs = h*d*(mu*vdse*dmm1vgs_loc + mm1_loc*vdse*dmuvgt*dvgtvgs
5163 + mu*mm1_loc*dvdsevgs);
5164 gm = e*(gmo+icho*ddelvgs*e);
5165 dmm1vds_loc = delmm1vdso*(1-gdsoo*rt-dvdsevds);
5166 ddelvds = h*d*(mu*vdse*dmm1vds_loc + mm1_loc*vdse*dmuvgt*sigma
5167 + mu*mm1_loc*dvdsevds);
5168 gdds = e*(gdso+icho*ddelvds*e);
5169 dmm1vbs_loc = delmm1vdso*(-gbsoo*rt-dvdsevbs);
5170 ddelvbs = h*d*(mu*vdse*dmm1vbs_loc + mm1_loc*vdse*dmuvon*dvonvbs
5171 + mu*mm1_loc*dvdsevbs);
5172 gmbs = e*(gbso+icho*ddelvbs*e);
5199 bool bsuccess =
true;
5208 bsuccess = bsuccess && btmp;
5210 double vgs1(0.0), vgdd1(0.0), vbs1(0.0),vgb1(0.0), vdds1(0.0);
5341 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ)
5350 double coef_Jdxp(0.0), gd_Jdxp(0.0);
5354 double ceqbs = Dtype*(mi.
cbs+mi.
cqbs);
5355 double ceqbd = Dtype*(mi.
cbd+mi.
cqbd);
5357 double D1current = Dtype*mi.
D1cdeq;
5362 if (mi.
Igate != 0.0)
5370 fVec[mi.
li_Bulk] += (ceqbs + ceqbd);
5382 dFdxdVp[mi.
li_Bulk] += coef_Jdxp;
5385 coef_Jdxp = Dtype*(-((mi.
gbd-gmin1))*
5407 double qcoef_Jdxp(0.0);
5409 double Qeqbs = Dtype*mi.
qbs;
5410 double Qeqbd = Dtype*mi.
qbd;
5411 double Qeqgb = Dtype*mi.
qgb;
5412 double Qeqgs = Dtype*mi.
qgs;
5413 double Qeqgdd = Dtype*mi.
qgdd;
5416 qVec[mi.
li_Bulk] += (Qeqbs + Qeqbd - Qeqgb);
5430 dQdxdVp[mi.
li_Bulk] += qcoef_Jdxp;
5446 dQdxdVp[mi.
li_Drain] += qcoef_Jdxp;
5456 if (mi.
Igate != 0.0)
5518 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
5530 #pragma omp parallel for
5688 int sizeInstances = instanceContainer_.size();
5691 #pragma omp parallel for
5693 for (
int i=0; i<sizeInstances; ++i)
5695 Instance & mi = *(instanceContainer_.at(i));
5849 .registerDevice(
"m", 18)
5850 .registerModelType(
"pmos", 18)
5851 .registerModelType(
"nmos", 18);