46 #include <Xyce_config.h>
66 #include <N_ERH_ErrorMgr.h>
70 #include <N_LAS_Matrix.h>
71 #include <N_LAS_Vector.h>
146 "Initial condition of no voltage drops across device");
247 NULL,
U_OHM,
CAT_RES,
"Drain, source diffusion sheet resistance");
289 NULL,
U_NONE,
CAT_CAP,
"Bulk p-n forward-bias capacitance coefficient");
307 " 0 = aluminum, 1 = opposite of substrate)");
341 #ifdef Xyce_DEBUG_DEVICE
344 Xyce::dout() <<
" L = " <<
l << std::endl;
345 Xyce::dout() <<
" W = " <<
w<< std::endl;
346 Xyce::dout() <<
" drainArea = " <<
drainArea<< std::endl;
347 Xyce::dout() <<
" sourceArea = " <<
sourceArea<< std::endl;
348 Xyce::dout() <<
" drainSquares = " <<
drainSquares<< std::endl;
349 Xyce::dout() <<
" sourceSquares = " <<
sourceSquares<< std::endl;
350 Xyce::dout() <<
" drainPerimeter = " <<
drainPerimeter<< std::endl;
354 Xyce::dout() <<
" temp = " <<
temp<< std::endl;
377 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
385 l(getDeviceOptions().defl),
386 w(getDeviceOptions().defw),
388 drainArea(getDeviceOptions().defad),
389 sourceArea(getDeviceOptions().defas),
393 sourcePerimeter(0.0),
394 sourceConductance(0.0),
395 drainConductance(0.0),
396 temp(getDeviceOptions().temp.getImmutableValue<double>()),
450 GateSourceOverlapCap(0),
451 GateDrainOverlapCap(0),
452 GateBulkOverlapCap(0),
464 ADrainEquDrainNodeOffset(-1),
465 ADrainEquDrainPrimeNodeOffset(-1),
467 AGateEquGateNodeOffset(-1),
468 AGateEquBulkNodeOffset(-1),
469 AGateEquDrainPrimeNodeOffset(-1),
470 AGateEquSourcePrimeNodeOffset(-1),
472 ASourceEquSourceNodeOffset(-1),
473 ASourceEquSourcePrimeNodeOffset(-1),
475 ABulkEquGateNodeOffset(-1),
476 ABulkEquBulkNodeOffset(-1),
477 ABulkEquDrainPrimeNodeOffset(-1),
478 ABulkEquSourcePrimeNodeOffset(-1),
480 ADrainPrimeEquDrainNodeOffset(-1),
481 ADrainPrimeEquGateNodeOffset(-1),
482 ADrainPrimeEquBulkNodeOffset(-1),
483 ADrainPrimeEquDrainPrimeNodeOffset(-1),
484 ADrainPrimeEquSourcePrimeNodeOffset(-1),
486 ASourcePrimeEquGateNodeOffset(-1),
487 ASourcePrimeEquSourceNodeOffset(-1),
488 ASourcePrimeEquBulkNodeOffset(-1),
489 ASourcePrimeEquDrainPrimeNodeOffset(-1),
490 ASourcePrimeEquSourcePrimeNodeOffset(-1),
495 f_DrainEquDrainNodePtr(0),
496 f_DrainEquDrainPrimeNodePtr(0),
498 f_GateEquGateNodePtr(0),
499 f_GateEquBulkNodePtr(0),
500 f_GateEquDrainPrimeNodePtr(0),
501 f_GateEquSourcePrimeNodePtr(0),
503 f_SourceEquSourceNodePtr(0),
504 f_SourceEquSourcePrimeNodePtr(0),
506 f_BulkEquGateNodePtr(0),
507 f_BulkEquBulkNodePtr(0),
508 f_BulkEquDrainPrimeNodePtr(0),
509 f_BulkEquSourcePrimeNodePtr(0),
511 f_DrainPrimeEquDrainNodePtr(0),
512 f_DrainPrimeEquGateNodePtr(0),
513 f_DrainPrimeEquBulkNodePtr(0),
514 f_DrainPrimeEquDrainPrimeNodePtr(0),
515 f_DrainPrimeEquSourcePrimeNodePtr(0),
517 f_SourcePrimeEquGateNodePtr(0),
518 f_SourcePrimeEquSourceNodePtr(0),
519 f_SourcePrimeEquBulkNodePtr(0),
520 f_SourcePrimeEquDrainPrimeNodePtr(0),
521 f_SourcePrimeEquSourcePrimeNodePtr(0),
524 q_DrainEquDrainNodePtr(0),
525 q_DrainEquDrainPrimeNodePtr(0),
527 q_GateEquGateNodePtr(0),
528 q_GateEquBulkNodePtr(0),
529 q_GateEquDrainPrimeNodePtr(0),
530 q_GateEquSourcePrimeNodePtr(0),
532 q_SourceEquSourceNodePtr(0),
533 q_SourceEquSourcePrimeNodePtr(0),
535 q_BulkEquGateNodePtr(0),
536 q_BulkEquBulkNodePtr(0),
537 q_BulkEquDrainPrimeNodePtr(0),
538 q_BulkEquSourcePrimeNodePtr(0),
540 q_DrainPrimeEquDrainNodePtr(0),
541 q_DrainPrimeEquGateNodePtr(0),
542 q_DrainPrimeEquBulkNodePtr(0),
543 q_DrainPrimeEquDrainPrimeNodePtr(0),
544 q_DrainPrimeEquSourcePrimeNodePtr(0),
546 q_SourcePrimeEquGateNodePtr(0),
547 q_SourcePrimeEquSourceNodePtr(0),
548 q_SourcePrimeEquBulkNodePtr(0),
549 q_SourcePrimeEquDrainPrimeNodePtr(0),
550 q_SourcePrimeEquSourcePrimeNodePtr(0),
729 UserError0(*
this) <<
"Effective channel length less than zero.";
762 const std::vector<int> & extLIDVecRef )
769 #ifdef Xyce_DEBUG_DEVICE
772 Xyce::dout() << section_divider << std::endl;
773 Xyce::dout() <<
" In Instance::register LIDs\n\n";
774 Xyce::dout() <<
" name = " <<
getName() << std::endl;
775 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
776 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
805 #ifdef Xyce_DEBUG_DEVICE
808 Xyce::dout() <<
"\n variable local indices:\n";
809 Xyce::dout() <<
" li_Drain = " <<
li_Drain << std::endl;
810 Xyce::dout() <<
" li_DrainPrime = " <<
li_DrainPrime << std::endl;
811 Xyce::dout() <<
" li_Source = " <<
li_Source << std::endl;
812 Xyce::dout() <<
" li_SourcePrime = " <<
li_SourcePrime << std::endl;
813 Xyce::dout() <<
" li_Gate = " <<
li_Gate << std::endl;
814 Xyce::dout() <<
" li_Bulk = " <<
li_Bulk << std::endl;
816 Xyce::dout() << section_divider << std::endl;
860 if( loadLeadCurrent && storeNameMap.empty ())
883 #ifdef Xyce_DEBUG_DEVICE
886 Xyce::dout() << std::endl;
887 Xyce::dout() << section_divider << std::endl;
888 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
889 Xyce::dout() <<
" name = " <<
getName() << std::endl;
890 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
910 #ifdef Xyce_DEBUG_DEVICE
913 Xyce::dout() <<
" State local indices:" << std::endl;
914 Xyce::dout() << std::endl;
916 Xyce::dout() <<
" li_state_qgs = " <<
li_state_qgs <<std::endl;
917 Xyce::dout() <<
" li_state_capgs = " <<
li_state_capgs<<std::endl;
918 Xyce::dout() <<
" li_state_capgd = " <<
li_state_capgd<<std::endl;
919 Xyce::dout() <<
" li_state_capgb = " <<
li_state_capgb<<std::endl;
920 Xyce::dout() <<
" li_state_qgd = " <<
li_state_qgd<<std::endl;
921 Xyce::dout() <<
" li_state_qgb = " <<
li_state_qgb<<std::endl;
922 Xyce::dout() <<
" li_state_qbs = " <<
li_state_qbs<<std::endl;
923 Xyce::dout() <<
" li_state_qbd = " <<
li_state_qbd<<std::endl;
924 Xyce::dout() << std::endl;
925 Xyce::dout() << section_divider << std::endl;
993 std::vector<int> map;
994 std::vector< std::vector<int> > map2;
1062 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1147 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
1156 Qeqbs = Dtype*(
qbs);
1157 Qeqbd = Dtype*(
qbd);
1160 Qeqgb = Dtype*(
qgb);
1161 Qeqgs = Dtype*(
qgs);
1162 Qeqgd = Dtype*(
qgd);
1165 coef = (Qeqgs+Qeqgd+Qeqgb);
1169 coef = Qeqbs + Qeqbd - Qeqgb;
1173 coef = -(Qeqbd + Qeqgd);
1177 coef = -(Qeqbs + Qeqgs);
1205 double gcgd, gcgs, gcgb, gcbs, gcbd;
1217 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
1225 double coef_Jdxp4 = Dtype*(
1231 double coef_Jdxp5 = Dtype*(
1264 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
1271 ceqbs = Dtype*(
cbs);
1272 ceqbd = Dtype*(
cbd);
1287 coef = (ceqgs+ceqgd+ceqgb);
1298 coef = ceqbs + ceqbd - ceqgb;
1318 double coef_Jdxp4 = Dtype*(
1323 double coef_Jdxp5 = Dtype*(
1330 double coef_Jdxp6 = Dtype*(
1427 +(gcbd+gcgd)*numberParallel;
1434 +(gcbs+gcgs)*numberParallel;
1466 (
gbs+
gbd)*numberParallel;
1505 bool bsuccess =
true;
1524 double capgs_old(0.0);
1525 double capgd_old(0.0);
1526 double capgb_old(0.0);
1531 double vgs_save(0.0);
1532 double vgd_save(0.0);
1533 double vds_save(0.0);
1608 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
1674 #ifdef Xyce_DEBUG_DEVICE
1677 Xyce::dout() <<
" checking whether to limit voltages "<< std::endl;
1678 Xyce::dout() <<
" Von = " << Von << std::endl;
1679 Xyce::dout() <<
" Blim: vgd = " <<
vgd <<
" vgd old = " <<
vgd_old << std::endl;
1680 Xyce::dout() <<
" Blim: vgs = " <<
vgs <<
" vgs_old = " <<
vgs_old << std::endl;
1681 Xyce::dout() <<
" Blim: vds = " << vds <<
" vds_old = " <<
vds_old << std::endl;
1682 Xyce::dout() <<
" Blim: vbs = " <<
vbs <<
" vbs_old = " <<
vbs_old << std::endl;
1683 Xyce::dout() <<
" Blim: vbd = " <<
vbd <<
" vbd_old = " <<
vbd_old << std::endl;
1721 #ifdef Xyce_DEBUG_DEVICE
1724 Xyce::dout() <<
" Alim: vgd = " <<
vgd << std::endl;
1725 Xyce::dout() <<
" Alim: vgs = " <<
vgs << std::endl;
1726 Xyce::dout() <<
" Alim: vds = " << vds << std::endl;
1727 Xyce::dout() <<
" Alim: vbs = " <<
vbs << std::endl;
1728 Xyce::dout() <<
" Alim: vbd = " <<
vbd << std::endl;
1745 #ifdef Xyce_DEBUG_DEVICE
1750 Xyce::dout() <<
" Something modified the voltages. " << std::endl;
1751 Xyce::dout() <<
" Voltage before after diff " << std::endl;
1753 Xyce::dout() <<
" vds " <<
vds_orig <<
" " << vds <<
" " << vds-
vds_orig << std::endl;
1754 Xyce::dout() <<
" vbs " <<
vbs_orig <<
" " << vbs <<
" " << vbs-
vbs_orig << std::endl;
1807 double vdshere, vbsvbd;
1808 double idsat, lambda, vonbm;
1809 double vdst, vdst2, ivdst1, vdstg;
1857 sarg = sqrt(
tPhi - vbsvbd);
1862 sarg = sarg - vbsvbd / (sarg+sarg);
1866 vdshere = vds *
mode;
1870 vgon = (mode==1?
vgs:
vgd) - Von;
1889 if ((mode==1?vbs:
vbd) <= 0 )
1900 idsat = betac * exp(sarg *
model_.
nc);
1904 cdrain = idsat * (1 + lambda * vdshere);
1911 if (
vdsat > vdshere)
1914 vdst = vdshere /
vdsat;
1915 vdst2 = (2 - vdst) * vdst;
1917 ivdst1 =
cdrain * (2 - vdst - vdst);
1919 gm = gm * vdst2 + ivdst1 * vdstg;
1921 gmbs = gmbs * vdst2 + ivdst1 * vdstg * vonbm;
1976 sarg = sargsw = 1/sqrt(arg);
1995 sargsw = 1/sqrt(arg);
2036 sarg = sargsw = 1/sqrt(arg);
2050 sargsw = 1/sqrt(arg);
2300 double ratio,ratio4;
2308 double gmanew,gmaold;
2322 #ifdef Xyce_DEBUG_DEVICE
2325 Xyce::dout() << subsection_divider << std::endl;
2326 Xyce::dout() <<
" Begin of updateTemperature. \n";
2327 Xyce::dout() << std::endl;
2332 if (temp_tmp != -999.0)
temp = temp_tmp;
2342 #ifdef Xyce_DEBUG_DEVICE
2345 Xyce::dout() <<
"Temperature = "<<
temp << std::endl;
2346 Xyce::dout() <<
"tnom = " << tnom << std::endl;
2347 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2357 pbfact = -2*
vt *(1.5*log(fact2)+
CONSTQ*arg);
2366 pbfact1 = -2*vtnom *(1.5*log(fact1)+
CONSTQ*arg1);
2368 #ifdef Xyce_DEBUG_DEVICE
2371 Xyce::dout() <<
"vt = " <<
vt << std::endl;
2372 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2373 Xyce::dout() <<
"fact2 = " << fact2 << std::endl;
2374 Xyce::dout() <<
"kt = " << kt << std::endl;
2375 Xyce::dout() <<
"egfet = " << egfet << std::endl;
2376 Xyce::dout() <<
"arg = " << arg << std::endl;
2377 Xyce::dout() <<
"pbfact = " << pbfact << std::endl;
2391 ratio4 = ratio * sqrt(ratio);
2396 tPhi = fact2 * phio + pbfact;
2405 exp(-egfet/
vt+egfet1/vtnom);
2407 exp(-egfet/
vt+egfet1/vtnom);
2574 bool bsuccess =
true;
2581 double vgs1, vgd1, vbs1,vgb1, vds1;
2672 egfet1 = 1.16-(7.02e-4*tnom*
tnom)/(tnom+1108);
2675 #ifdef Xyce_DEBUG_DEVICE
2678 Xyce::dout() <<
" fact1 = " <<
fact1 << std::endl;
2679 Xyce::dout() <<
" vtnom = " <<
vtnom << std::endl;
2680 Xyce::dout() <<
" kt1 = " << kt1 << std::endl;
2681 Xyce::dout() <<
" egfet1 = " <<
egfet1 << std::endl;
2682 Xyce::dout() <<
" arg1 = " << arg1 << std::endl;
2683 Xyce::dout() <<
" pbfact1 = " <<
pbfact1 << std::endl;
2715 wkfng = 3.25 + .5 *
egfet1 - fermig;
2717 wkfngs = wkfng - (3.25 + .5 *
egfet1 +fermis);
2737 coeffDepLayWidth = sqrt(alpha);
2783 wkfng = 3.25 + .5 *
egfet1 - fermig;
2785 wkfngs = wkfng - (3.25 + .5 *
egfet1 +fermis);
2794 if(!
given(
"GAMMA1"))
2832 std::vector<Instance*>::iterator iter;
2836 for (iter=first; iter!=last; ++iter)
2838 (*iter)->processParams();
2856 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
2858 tnom(getDeviceOptions().tnom),
2860 jctSatCurDensity(0.0),
2862 drainResistance(0.0),
2863 sourceResistance(0.0),
2864 sheetResistance(0.0),
2871 gateSourceOverlapCapFactor(0.0),
2872 gateDrainOverlapCapFactor(0.0),
2873 gateBulkOverlapCapFactor(0.0),
2874 oxideCapFactor(0.0),
2879 sideWallCapFactor(0.0),
2880 bulkJctPotential(0.0),
2881 bulkJctBotGradingCoeff(0.0),
2882 bulkJctSideGradingCoeff(0.0),
2883 fwdCapDepCoeff(0.0),
2891 substrateDoping(0.0),
2893 surfaceStateDensity(0.0),
2894 oxideThickness(0.0),
2895 surfaceMobility(0.0),
2896 lambdaGiven (false),
2897 lambda0Given (false),
2898 lambda1Given (false),
2901 bulkCapFactorGiven(false),
2902 sideWallCapFactorGiven(false)
2910 else if (
getType() ==
"PMOS") {
2951 UserError0(*
this) <<
"Both uo and u0 have been specified and, which is not allowed";
2953 UserWarning0(*
this) <<
"Surface mobility has been specified as u0 instead of uo, uo is the preferred syntax";
2971 std::vector<Instance*>::iterator iter;
2975 for (iter=first; iter!=last; ++iter)
2992 std::vector<Instance*>::const_iterator iter;
2998 os <<
" name model name Parameters" << std::endl;
2999 for (i=0, iter=first; iter!=last; ++iter, ++i)
3001 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
3026 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
3045 bool bsuccess =
true;
3054 double vgs1(0.0), vgd1(0.0), vbs1(0.0),vgb1(0.0), vds1(0.0);
3057 bsuccess = bsuccess && btmp;
3130 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ)
3139 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
3140 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
3143 ceqbs = Dtype*(mi.
cbs);
3144 ceqbd = Dtype*(mi.
cbd);
3156 coef = (ceqgs+ceqgd+ceqgb);
3164 coef = ceqbs + ceqbd - ceqgb;
3174 Qeqbs = Dtype*(mi.
qbs);
3175 Qeqbd = Dtype*(mi.
qbd);
3178 Qeqgb = Dtype*(mi.
qgb);
3179 Qeqgs = Dtype*(mi.
qgs);
3180 Qeqgd = Dtype*(mi.
qgd);
3182 coef = (Qeqgs+Qeqgd+Qeqgb);
3185 coef = Qeqbs + Qeqbd - Qeqgb;
3188 coef = -(Qeqbd + Qeqgd);
3191 coef = -(Qeqbs + Qeqgs);
3198 double coef_Jdxp4 = Dtype*(
3202 double coef_Jdxp5 = Dtype*(
3208 double coef_Jdxp6 = Dtype*(
3224 double gcgd(0.0), gcgs(0.0), gcgb(0.0), gcbs(0.0), gcbd(0.0);
3236 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
3243 double coef_Jdxp4 = Dtype*(
3248 double coef_Jdxp5 = Dtype*(
3253 double coef_Jdxp6 = Dtype*
3298 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
3447 bool bsuccess =
true;
3449 for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
3586 .registerDevice(
"m", 6)
3587 .registerModelType(
"pmos", 6)
3588 .registerModelType(
"nmos", 6);