46 #include <Xyce_config.h>
70 #include <N_ERH_ErrorMgr.h>
72 #include <N_LAS_Matrix.h>
73 #include <N_LAS_Vector.h>
83 .setDescription(
"Device temperature");
88 .setDescription(
"device area");
96 .setDescription(
"Flicker noise exponent");
101 .setDescription(
"Doping tail parameter");
106 .setDescription(
"Transconductance parameter");
111 .setDescription(
"Saturation voltage parameter");
117 .setDescription(
"Zero-bias gate-source junction capacitance");
123 .setDescription(
"Zero-bias gate-drain junction capacitance");
128 .setDescription(
"Coefficient for forward-bias depletion capacitance");
133 .setDescription(
"Gate junction saturation current");
138 .setDescription(
"Flicker noise coefficient");
143 .setDescription(
"Channel length modulation");
148 .setDescription(
"Gate junction potential");
154 .setDescription(
"Drain ohmic resistance");
160 .setDescription(
"Source ohmic resistance");
167 .setDescription(
"Threshold voltage");
200 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
262 std::vector<Instance*>::iterator iter;
266 for (iter=first; iter!=last; ++iter)
284 std::vector<Instance*>::const_iterator iter;
291 os <<
"Number of MESFET Instances: " << isize << std::endl;
292 os <<
" name model name Parameters" << std::endl;
294 for (i=0, iter=first; iter!=last; ++iter, ++i)
296 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
322 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
352 std::vector<Instance*>::iterator iter;
356 for (iter=first; iter!=last; ++iter)
358 (*iter)->processParams();
378 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
386 temp(getDeviceOptions().temp.getImmutableValue<double>()),
429 ADrainEquDrainNodeOffset(-1),
430 ADrainEquDrainPrimeNodeOffset(-1),
432 AGateEquGateNodeOffset(-1),
433 AGateEquDrainPrimeNodeOffset(-1),
434 AGateEquSourcePrimeNodeOffset(-1),
436 ASourceEquSourceNodeOffset(-1),
437 ASourceEquSourcePrimeNodeOffset(-1),
439 ADrainPrimeEquDrainNodeOffset(-1),
440 ADrainPrimeEquGateNodeOffset(-1),
441 ADrainPrimeEquDrainPrimeNodeOffset(-1),
442 ADrainPrimeEquSourcePrimeNodeOffset(-1),
444 ASourcePrimeEquGateNodeOffset(-1),
445 ASourcePrimeEquSourceNodeOffset(-1),
446 ASourcePrimeEquDrainPrimeNodeOffset(-1),
447 ASourcePrimeEquSourcePrimeNodeOffset(-1),
452 f_DrainEquDrainNodePtr(0),
453 f_DrainEquDrainPrimeNodePtr(0),
455 f_GateEquGateNodePtr(0),
456 f_GateEquDrainPrimeNodePtr(0),
457 f_GateEquSourcePrimeNodePtr(0),
459 f_SourceEquSourceNodePtr(0),
460 f_SourceEquSourcePrimeNodePtr(0),
462 f_DrainPrimeEquDrainNodePtr(0),
463 f_DrainPrimeEquGateNodePtr(0),
464 f_DrainPrimeEquDrainPrimeNodePtr(0),
465 f_DrainPrimeEquSourcePrimeNodePtr(0),
467 f_SourcePrimeEquGateNodePtr(0),
468 f_SourcePrimeEquSourceNodePtr(0),
469 f_SourcePrimeEquDrainPrimeNodePtr(0),
470 f_SourcePrimeEquSourcePrimeNodePtr(0),
474 q_DrainEquDrainNodePtr(0),
475 q_DrainEquDrainPrimeNodePtr(0),
477 q_GateEquGateNodePtr(0),
478 q_GateEquDrainPrimeNodePtr(0),
479 q_GateEquSourcePrimeNodePtr(0),
481 q_SourceEquSourceNodePtr(0),
482 q_SourceEquSourcePrimeNodePtr(0),
484 q_DrainPrimeEquDrainNodePtr(0),
485 q_DrainPrimeEquGateNodePtr(0),
486 q_DrainPrimeEquDrainPrimeNodePtr(0),
487 q_DrainPrimeEquSourcePrimeNodePtr(0),
489 q_SourcePrimeEquGateNodePtr(0),
490 q_SourcePrimeEquSourceNodePtr(0),
491 q_SourcePrimeEquDrainPrimeNodePtr(0),
492 q_SourcePrimeEquSourcePrimeNodePtr(0),
616 const std::vector<int> & extLIDVecRef )
623 #ifdef Xyce_DEBUG_DEVICE
626 Xyce::dout() << std::endl << section_divider << std::endl;
627 Xyce::dout() <<
" Instance::registerLIDs" << std::endl;
628 Xyce::dout() <<
" name = " <<
getName() << std::endl;
629 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
630 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
658 #ifdef Xyce_DEBUG_DEVICE
661 Xyce::dout() <<
"\n variable local indices:\n";
662 Xyce::dout() <<
" li_Drain = " <<
li_Drain << std::endl;
663 Xyce::dout() <<
" li_DrainPrime = " <<
li_DrainPrime << std::endl;
664 Xyce::dout() <<
" li_Source = " <<
li_Source << std::endl;
665 Xyce::dout() <<
" li_SourcePrime = " <<
li_SourcePrime << std::endl;
666 Xyce::dout() <<
" li_Gate = " <<
li_Gate << std::endl;
668 Xyce::dout() << section_divider << std::endl;
691 tmpstr =
getName()+
"_drainprime";
698 tmpstr =
getName()+
"_sourceprime";
719 if( loadLeadCurrent && storeNameMap.empty ())
723 std::string modName(getName());
724 spiceInternalName(modName);
726 tmpstr = modName+
":DEV_ID";
727 storeNameMap[ li_store_dev_id ] = tmpstr;
728 tmpstr = modName+
":DEV_IG";
729 storeNameMap[ li_store_dev_ig ] = tmpstr;
730 tmpstr = modName+
":DEV_IS";
731 storeNameMap[ li_store_dev_is ] = tmpstr;
750 #ifdef Xyce_DEBUG_DEVICE
753 Xyce::dout() << std::endl;
754 Xyce::dout() << section_divider << std::endl;
755 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
756 Xyce::dout() <<
" name = " <<
getName() << std::endl;
757 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
771 #ifdef Xyce_DEBUG_DEVICE
774 Xyce::dout() <<
" State local indices:" << std::endl;
775 Xyce::dout() << std::endl;
777 Xyce::dout() <<
" li_state_qgs = " <<
li_state_qgs << std::endl;
780 Xyce::dout() <<
" li_state_gcgd = " <<
li_state_gcgd << std::endl;;
782 Xyce::dout() << section_divider << std::endl;
847 std::vector<int> map;
848 std::vector< std::vector<int> > map2;
908 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1000 double czgdf2, czgsf2;
1008 double prod, denom, invdenom, afact, lfact;
1010 #ifdef Xyce_DEBUG_DEVICE
1013 Xyce::dout() << subsection_divider << std::endl;
1014 Xyce::dout() <<
" Instance::updateIntermediateVars.\n"<<std::endl;
1015 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1016 Xyce::dout() <<
" Model name = " <<
model_.
getName() << std::endl;
1017 Xyce::dout() <<
" dtype is " <<
model_.
dtype << std::endl;
1018 Xyce::dout() << std::endl;
1019 Xyce::dout().width(25); Xyce::dout().precision(17); Xyce::dout().setf(std::ios::scientific);
1039 #ifdef Xyce_DEBUG_DEVICE
1042 Xyce::dout() <<
" " << std::endl;
1043 Xyce::dout() <<
" Vg = " <<
Vg << std::endl;
1044 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1045 Xyce::dout() <<
" Vs = " <<
Vs << std::endl;
1046 Xyce::dout() <<
" Vdp = " <<
Vdp << std::endl;
1047 Xyce::dout() <<
" Vsp = " <<
Vsp << std::endl;
1077 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
1117 #ifdef Xyce_DEBUG_DEVICE
1120 Xyce::dout() <<
" before limiting: " << std::endl;
1121 Xyce::dout() <<
" vgs = " <<
vgs <<
" vgs_old = " <<
vgs_old << std::endl;
1122 Xyce::dout() <<
" vgd = " << vgd <<
" vgd_old = " <<
vgd_old << std::endl;
1130 if (ichk1 == 1) {icheck=1;}
1137 #ifdef Xyce_DEBUG_DEVICE
1140 Xyce::dout() <<
" After limiting: " << std::endl;
1141 Xyce::dout() <<
" vgs = " <<
vgs << std::endl;
1142 Xyce::dout() <<
" vgd = " << vgd << std::endl;
1143 Xyce::dout() <<
" " << std::endl;
1148 #ifdef Xyce_DEBUG_DEVICE
1151 Xyce::dout() <<
"vgs = " <<
vgs << std::endl;
1152 Xyce::dout() <<
"vgd = " << vgd << std::endl;
1153 Xyce::dout() <<
"vds = " <<
vds << std::endl;
1154 Xyce::dout() <<
"Vddp = " <<
Vddp << std::endl;
1155 Xyce::dout() <<
"Vssp = " <<
Vssp << std::endl;
1156 Xyce::dout() <<
"Vgsp = " << Vgsp << std::endl;
1157 Xyce::dout() <<
"Vgdp = " << Vgdp << std::endl;
1158 Xyce::dout() <<
"Vdpsp = " <<
Vdpsp << std::endl;
1159 Xyce::dout() <<
" " << std::endl;
1165 #ifdef Xyce_DEBUG_DEVICE
1170 Xyce::dout() <<
" Something modified the voltages. " << std::endl;
1171 Xyce::dout() <<
" Voltage before after diff " << std::endl;
1173 Xyce::dout() <<
" vgd " <<
vgd_orig <<
" " << vgd <<
" " << vgd-
vgd_orig << std::endl;
1175 Xyce::dout() <<
" " << std::endl;
1241 denom = 1 +
tMESb*vgst;
1243 if (vds >= ( 3/
tAlpha ) )
1248 cdrain = betap*vgst*vgst*invdenom;
1249 gm = betap*vgst*(1 + denom)*invdenom*invdenom;
1257 afact = 1 -
tAlpha*vds/3;
1258 lfact = 1 - afact*afact*afact;
1259 cdrain = betap*vgst*vgst*invdenom*lfact;
1260 gm = betap*vgst*(1 + denom)*invdenom*invdenom*lfact;
1284 denom = 1 +
tMESb*vgdt;
1288 cdrain = -betap*vgdt*vgdt*invdenom;
1289 gm = -betap*vgdt*(1 + denom)*invdenom*invdenom;
1297 afact = 1 +
tAlpha*vds/3;
1298 lfact = 1 - afact*afact*afact;
1299 cdrain = -betap*vgdt*vgdt*invdenom*lfact;
1300 gm = -betap*vgdt*(1 + denom)*invdenom*invdenom*lfact;
1318 if (
vgs < corDepCap)
1321 qgs = twop*czgs*(1-sarg);
1327 +(
vgs*
vgs - fcpb2)/(2*twop));
1340 if (vgd < corDepCap)
1342 sarg=sqrt(1-vgd/
tPB);
1343 qgd = twop*czgd*(1-sarg);
1349 +(vgd*vgd - fcpb2)/(2*twop) );
1362 #ifdef Xyce_DEBUG_DEVICE
1365 Xyce::dout() <<
" Done with Instance::updateIntermediateVars." << std::endl;
1366 Xyce::dout() <<
" mode = " <<
mode << std::endl;
1367 Xyce::dout() <<
" tBeta = " <<
tBeta << std::endl;
1368 Xyce::dout() <<
" Idrain = " <<
Idrain << std::endl;
1369 Xyce::dout() <<
" Isource = " <<
Isource << std::endl;
1370 Xyce::dout() <<
" gds = " <<
gds << std::endl;
1371 Xyce::dout() <<
" gm = " <<
gm << std::endl;
1443 double ceqgd = Dtype*(
qgd);
1445 double cdreq = Dtype*(((-
qgd)+
qgd));
1449 double cdreq_Jdxp = 0.0;
1451 qVec[
li_Gate ] += ( ceqgs+ceqgd);
1457 dQdxdVp[
li_Gate ] -= ( ceqgs_Jdxp+ceqgd_Jdxp);
1484 double ceqgd = Dtype*(
cgd);
1485 double ceqgs = Dtype*((
cg-
cgd));
1486 double cdreq = Dtype*((
cd+
cgd));
1502 fVec[
li_Gate ] += (ceqgs+ceqgd);
1508 dFdxdVp[
li_Gate ] -= ( ceqgs_Jdxp+ceqgd_Jdxp);
1597 bool bsuccess =
true;
1601 double fact1, fact2;
1604 double egfet, egfet1;
1606 double cjfact, cjfact1;
1607 double gmanew, gmaold;
1612 #ifdef Xyce_DEBUG_DEVICE
1616 Xyce::dout() <<
" Instance::Begin of updateTemperature. \n";
1617 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1618 Xyce::dout() << std::endl;
1623 if (temp_tmp != -999.0)
temp = temp_tmp;
1643 egfet1 = 1.16 - (7.02e-4*tnom*tnom)/(tnom + 1108);
1645 pbfact = -2.0*vtnom*(1.5*log(fact1) +
CONSTQ*arg1);
1646 pbo = (Pb - pbfact)/fact1;
1647 gmaold = (Pb - pbo)/pbo;
1648 cjfact = 1.0/(1.0 + 0.5*(4e-4*(tnom -
CONSTREFTEMP) - gmaold));
1651 Xyce::dout() <<
"Depletion cap. coeff. FC too large, limited to .95" <<
1652 Xyce::dout() << std::endl;
1665 ratio1 = ratio - 1.0;
1671 arg = -egfet/(2.0*kt) + 1.1150877/(CONSTboltz*2.0*CONSTREFTEMP);
1672 pbfact = -2.0*
vt*(1.5*log(fact2) +
CONSTQ*arg);
1673 tPB = fact2*pbo + pbfact;
1674 gmanew = (tPB - pbo)/pbo;
1680 f1 = tPB*(1.0 - exp((0.5)*xfc))/(0.5);
1693 #ifdef Xyce_DEBUG_DEVICE
1696 Xyce::dout() <<
"temp = "<<
temp << std::endl;
1697 Xyce::dout() <<
"tnom = " << tnom << std::endl;
1698 Xyce::dout() <<
"ratio = " << ratio << std::endl;
1699 Xyce::dout() <<
"vt = " <<
vt << std::endl;
1700 Xyce::dout() <<
"kt = " << kt << std::endl;
1701 Xyce::dout() <<
"fact2 = " << fact2 << std::endl;
1702 Xyce::dout() <<
"egfet = " << egfet << std::endl;
1703 Xyce::dout() <<
"arg = " << arg << std::endl;
1704 Xyce::dout() <<
"pbfact = " << pbfact << std::endl;
1705 Xyce::dout() <<
"PB = " << Pb << std::endl;
1706 Xyce::dout() <<
"pbo = " << pbo << std::endl;
1707 Xyce::dout() <<
"f2 = " <<
f2 << std::endl;
1708 Xyce::dout() <<
"f3 = " <<
f3 << std::endl;
1709 Xyce::dout() <<
"corDepCap= " <<
corDepCap << std::endl;
1710 Xyce::dout() <<
"tBeta = " <<
tBeta << std::endl;
1711 Xyce::dout() <<
"tvt0 = " <<
tvt0 << std::endl;
1712 Xyce::dout() <<
"tPB = " << tPB << std::endl;
1713 Xyce::dout() <<
"tMESb = " <<
tMESb << std::endl;
1714 Xyce::dout() <<
"tLambda = " <<
tLambda << std::endl;
1716 Xyce::dout() <<
"tRD = " <<
tRD << std::endl;
1717 Xyce::dout() <<
"tRS = " <<
tRS << std::endl;
1718 Xyce::dout() <<
" " << std::endl;
1752 bool bsuccess =
true;
1759 bsuccess = bsuccess && btmp;
1790 double f_ceqgd = Dtype*(ji.
cgd);
1791 double f_ceqgs = Dtype*((ji.
cg-ji.
cgd));
1792 double f_cdreq = Dtype*((ji.
cd+ji.
cgd));
1807 fVec[ji.
li_Gate ] += (f_ceqgs+f_ceqgd);
1813 dFdxdVp[ji.
li_Gate ] -= ( f_ceqgs_Jdxp+f_ceqgd_Jdxp);
1822 double q_ceqgd = Dtype*(ji.
qgd);
1823 double q_ceqgs = Dtype*(((ji.
qgs+ji.
qgd)-ji.
qgd));
1824 double q_cdreq = Dtype*(((-ji.
qgd)+ji.
qgd));
1828 double q_cdreq_Jdxp = 0.0;
1830 qVec[ji.
li_Gate ] += ( q_ceqgs+q_ceqgd);
1836 dQdxdVp[ji.
li_Gate ] -= ( q_ceqgs_Jdxp+q_ceqgd_Jdxp);
1870 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1952 int sizeInstances = instanceContainer_.size();
1953 for (
int i=0; i<sizeInstances; ++i)
1955 Instance & ji = *(instanceContainer_.at(i));
2025 .registerDevice(
"z", 1)
2026 .registerModelType(
"nmf", 1)
2027 .registerModelType(
"pmf", 1);