45 #include <Xyce_config.h>
57 #include <N_ERH_ErrorMgr.h>
59 #include <N_LAS_Matrix.h>
60 #include <N_LAS_Vector.h>
61 #include <N_UTL_FeatureTest.h>
62 #include <N_UTL_Math.h>
76 .setDescription(
"Device temperature");
79 .setOriginalValueStored(
true)
82 .setDescription(
"Channel length");
85 .setOriginalValueStored(
true)
88 .setDescription(
"Channel width");
93 .setDescription(
"Drain diffusion area");
98 .setDescription(
"Source diffusion area");
103 .setDescription(
"Multiplier for RSH to yield parasitic resistance of drain");
108 .setDescription(
"Multiplier for RSH to yield parasitic resistance of source");
113 .setDescription(
"Drain diffusion perimeter");
118 .setDescription(
"Source diffusion perimeter");
123 .setDescription(
"Multiplier for M devices connected in parallel");
130 .setDescription(
"Initial condition on Drain-Source voltage");
136 .setDescription(
"Initial condition on Gate-Source voltage");
142 .setDescription(
"Initial condition on Bulk-Source voltage");
150 .setDescription(
"Initial condition of no voltage drops across device");
159 .setDescription(
"Default channel length");
164 .setDescription(
"Default channel width");
169 .setDescription(
"Zero-bias threshold voltage");
174 .setDescription(
"Transconductance coefficient");
179 .setDescription(
"Bulk threshold parameter");
184 .setDescription(
"Surface potential");
189 .setDescription(
"Channel-length modulation");
195 .setDescription(
"Drain ohmic resistance");
201 .setDescription(
"Source ohmic resistance");
208 .setDescription(
"Zero-bias bulk-drain p-n capacitance");
215 .setDescription(
"Zero-bias bulk-source p-n capacitance");
220 .setDescription(
"Bulk p-n saturation current");
225 .setDescription(
"Bulk p-n bottom potential");
230 .setDescription(
"Gate-source overlap capacitance/channel width");
235 .setDescription(
"Gate-drain overlap capacitance/channel width");
240 .setDescription(
"Gate-bulk overlap capacitance/channel length");
245 .setDescription(
"Drain,source diffusion sheet resistance");
251 .setDescription(
"Bulk p-n zero-bias bottom capacitance/area");
256 .setDescription(
"Bulk p-n bottom grading coefficient");
262 .setDescription(
"Bulk p-n zero-bias sidewall capacitance/area");
267 .setDescription(
"Bulk p-n sidewall grading coefficient");
272 .setDescription(
"Bulk p-n saturation current density");
275 .setOriginalValueStored(
true)
278 .setDescription(
"Gate oxide thickness");
283 .setDescription(
"Lateral diffusion length");
288 .setDescription(
"Surface mobility");
293 .setDescription(
"Surface mobility");
298 .setDescription(
"Bulk p-n forward-bias capacitance coefficient");
303 .setDescription(
"Substrate doping density");
308 .setDescription(
"Surface state density");
314 .setDescription(
"Width effect on threshold");
319 .setDescription(
"Crit. field exp for mob. deg.");
324 .setDescription(
"Crit. field for mob. degradation");
329 .setDescription(
"Maximum carrier drift velocity");
334 .setDescription(
"Junction depth");
339 .setDescription(
"Total channel charge coeff.");
344 .setDescription(
"Fast surface state density");
351 .setDescription(
"Parameter measurement temperature");
356 .setDescription(
"Flicker noise coefficient");
361 .setDescription(
"Flicker noise exponent");
367 .setDescription(
"Gate material type (-1 = same as substrate, 0 = aluminum,1 = opposite of substrate)");
463 UserError0(*
this) <<
"Effective channel length less than zero.";
488 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
496 l(getDeviceOptions().defl),
497 w(getDeviceOptions().defw),
499 drainArea(getDeviceOptions().defad),
500 sourceArea(getDeviceOptions().defas),
504 sourcePerimeter(0.0),
505 sourceConductance(0.0),
506 drainConductance(0.0),
507 temp(getDeviceOptions().temp.getImmutableValue<double>()),
509 tTransconductance(0.0),
560 GateSourceOverlapCap(0),
561 GateDrainOverlapCap(0),
562 GateBulkOverlapCap(0),
575 ADrainEquDrainNodeOffset(-1),
576 ADrainEquDrainPrimeNodeOffset(-1),
578 AGateEquGateNodeOffset(-1),
579 AGateEquBulkNodeOffset(-1),
580 AGateEquDrainPrimeNodeOffset(-1),
581 AGateEquSourcePrimeNodeOffset(-1),
583 ASourceEquSourceNodeOffset(-1),
584 ASourceEquSourcePrimeNodeOffset(-1),
586 ABulkEquGateNodeOffset(-1),
587 ABulkEquBulkNodeOffset(-1),
588 ABulkEquDrainPrimeNodeOffset(-1),
589 ABulkEquSourcePrimeNodeOffset(-1),
591 ADrainPrimeEquDrainNodeOffset(-1),
592 ADrainPrimeEquGateNodeOffset(-1),
593 ADrainPrimeEquBulkNodeOffset(-1),
594 ADrainPrimeEquDrainPrimeNodeOffset(-1),
595 ADrainPrimeEquSourcePrimeNodeOffset(-1),
597 ASourcePrimeEquGateNodeOffset(-1),
598 ASourcePrimeEquSourceNodeOffset(-1),
599 ASourcePrimeEquBulkNodeOffset(-1),
600 ASourcePrimeEquDrainPrimeNodeOffset(-1),
601 ASourcePrimeEquSourcePrimeNodeOffset(-1),
606 f_DrainEquDrainNodePtr(0),
607 f_DrainEquDrainPrimeNodePtr(0),
609 f_GateEquGateNodePtr(0),
610 f_GateEquBulkNodePtr(0),
611 f_GateEquDrainPrimeNodePtr(0),
612 f_GateEquSourcePrimeNodePtr(0),
614 f_SourceEquSourceNodePtr(0),
615 f_SourceEquSourcePrimeNodePtr(0),
617 f_BulkEquGateNodePtr(0),
618 f_BulkEquBulkNodePtr(0),
619 f_BulkEquDrainPrimeNodePtr(0),
620 f_BulkEquSourcePrimeNodePtr(0),
622 f_DrainPrimeEquDrainNodePtr(0),
623 f_DrainPrimeEquGateNodePtr(0),
624 f_DrainPrimeEquBulkNodePtr(0),
625 f_DrainPrimeEquDrainPrimeNodePtr(0),
626 f_DrainPrimeEquSourcePrimeNodePtr(0),
628 f_SourcePrimeEquGateNodePtr(0),
629 f_SourcePrimeEquSourceNodePtr(0),
630 f_SourcePrimeEquBulkNodePtr(0),
631 f_SourcePrimeEquDrainPrimeNodePtr(0),
632 f_SourcePrimeEquSourcePrimeNodePtr(0),
635 q_DrainEquDrainNodePtr(0),
636 q_DrainEquDrainPrimeNodePtr(0),
638 q_GateEquGateNodePtr(0),
639 q_GateEquBulkNodePtr(0),
640 q_GateEquDrainPrimeNodePtr(0),
641 q_GateEquSourcePrimeNodePtr(0),
643 q_SourceEquSourceNodePtr(0),
644 q_SourceEquSourcePrimeNodePtr(0),
646 q_BulkEquGateNodePtr(0),
647 q_BulkEquBulkNodePtr(0),
648 q_BulkEquDrainPrimeNodePtr(0),
649 q_BulkEquSourcePrimeNodePtr(0),
651 q_DrainPrimeEquDrainNodePtr(0),
652 q_DrainPrimeEquGateNodePtr(0),
653 q_DrainPrimeEquBulkNodePtr(0),
654 q_DrainPrimeEquDrainPrimeNodePtr(0),
655 q_DrainPrimeEquSourcePrimeNodePtr(0),
657 q_SourcePrimeEquGateNodePtr(0),
658 q_SourcePrimeEquSourceNodePtr(0),
659 q_SourcePrimeEquBulkNodePtr(0),
660 q_SourcePrimeEquDrainPrimeNodePtr(0),
661 q_SourcePrimeEquSourcePrimeNodePtr(0),
805 Xyce::dout() <<
": name = " <<
getName() << std::endl;
834 const std::vector<int> & extLIDVecRef )
841 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
843 Xyce::dout() << section_divider << std::endl;
844 Xyce::dout() <<
" In Instance::register LIDs\n\n";
845 Xyce::dout() <<
" name = " <<
getName() << std::endl;
846 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
847 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
875 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
877 Xyce::dout() <<
"\n variable local indices:\n";
878 Xyce::dout() <<
" li_Drain = " <<
li_Drain << std::endl;
879 Xyce::dout() <<
" li_DrainPrime = " <<
li_DrainPrime << std::endl;
880 Xyce::dout() <<
" li_Source = " <<
li_Source << std::endl;
881 Xyce::dout() <<
" li_SourcePrime = " <<
li_SourcePrime << std::endl;
882 Xyce::dout() <<
" li_Gate = " <<
li_Gate << std::endl;
883 Xyce::dout() <<
" li_Bulk = " <<
li_Bulk << std::endl;
885 Xyce::dout() << section_divider << std::endl;
927 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
929 Xyce::dout() << std::endl;
930 Xyce::dout() << section_divider << std::endl;
931 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
932 Xyce::dout() <<
" name = " <<
getName() << std::endl;
933 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
953 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
955 Xyce::dout() <<
" State local indices:" << std::endl;
956 Xyce::dout() << std::endl;
967 Xyce::dout() << std::endl;
968 Xyce::dout() << section_divider << std::endl;
1035 std::vector<int> map;
1036 std::vector< std::vector<int> > map2;
1103 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1190 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
1199 Qeqbs = Dtype*(
qbs);
1200 Qeqbd = Dtype*(
qbd);
1203 Qeqgb = Dtype*(
qgb);
1204 Qeqgs = Dtype*(
qgs);
1205 Qeqgd = Dtype*(
qgd);
1208 coef = (Qeqgs+Qeqgd+Qeqgb);
1212 coef = Qeqbs + Qeqbd - Qeqgb;
1216 coef = -(Qeqbd + Qeqgd);
1220 coef = -(Qeqbs + Qeqgs);
1249 double gcgd, gcgs, gcgb, gcbs, gcbd;
1261 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
1269 double coef_Jdxp4 = Dtype*(
1275 double coef_Jdxp5 = Dtype*(
1308 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
1315 ceqbs = Dtype*(
cbs);
1316 ceqbd = Dtype*(
cbd);
1331 coef = (ceqgs+ceqgd+ceqgb);
1342 coef = ceqbs + ceqbd - ceqgb;
1362 double coef_Jdxp4 = Dtype*(
1367 double coef_Jdxp5 = Dtype*(
1374 double coef_Jdxp6 = Dtype*(
1462 (+gcbs+gcbd+gcgb)*numberParallel;
1472 (+gcbd+gcgd)*numberParallel;
1479 (+gcbs+gcgs)*numberParallel;
1511 (
gbs+
gbd)*numberParallel;
1550 bool bsuccess =
true;
1649 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
1881 static double sig1[4] = {1.0, -1.0, 1.0, -1.0};
1882 static double sig2[4] = {1.0, 1.0,-1.0, -1.0};
1886 double a4[4],b4[4],x4[8],poly4[8];
2007 double lvbs =
mode==1?vbs:
vbd;
2010 double phiMinVbs =
tPhi - lvbs;
2021 sarg = sqrt(phiMinVbs);
2023 d2sdb2 = 0.5*dsrgdb/phiMinVbs;
2029 sarg = sphi/(1.0+0.5*lvbs/
tPhi);
2031 dsrgdb = -0.5*sarg*tmp;
2032 d2sdb2 = -dsrgdb*tmp;
2034 if ((lvds-lvbs) >= 0)
2036 barg = sqrt(phiMinVbs+lvds);
2038 d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds);
2042 barg = sphi/(1.0+0.5*(lvbs-lvds)/
tPhi);
2044 dbrgdb = -0.5*barg*tmp;
2045 d2bdb2 = -dbrgdb*tmp;
2072 argxs = 1.0+xws*tmp;
2073 argxd = 1.0+xwd*tmp;
2077 argss = tmp * (args-1.0);
2078 argsd = tmp * (argd-1.0);
2086 dbargs = tmp*dbxws/args;
2087 dbargd = tmp*dbxwd/argd;
2088 dasdb2 = -
model_.
xd*( d2sdb2+dsrgdb*dsrgdb*
2090 (EffectiveLength*args);
2091 daddb2 = -
model_.
xd*( d2bdb2+dbrgdb*dbrgdb*
2093 (EffectiveLength*argd);
2100 dgdvds = -
model_.
gamma*0.5*ddxwd/(EffectiveLength*argd);
2111 Von = vbin+gamasd*sarg;
2118 bool line1050bool=
false;
2123 cdonco = -(gamasd*dsrgdb+dgddvb*sarg)+factor;
2124 xn = 1.0+cfs/
OxideCap*
w*EffectiveLength+cdonco;
2151 sarg3 = sarg*sarg*sarg;
2156 body = barg*barg*barg-sarg3;
2157 gdbdv = 2.0*gammad*(barg*barg*dbrgdb-sarg*sarg*dsrgdb);
2158 dodvbs = -factor+dgdvbs*sarg+gammad*dsrgdb;
2164 dxndvb = 2.0*dgdvbs*dsrgdb+gammad*d2sdb2+dgddb2*sarg;
2165 dodvbs = dodvbs+
vt*dxndvb;
2166 dxndvd = dgdvds*dsrgdb;
2167 dodvds = dgdvds*sarg+
vt*dxndvd;
2197 gammad = gamasd/eta;
2201 vgsx = std::max(lvgs,Von);
2205 gammd2 = gammad*gammad;
2206 argv = (vgsx-vbin)/eta+phiMinVbs;
2215 arg = sqrt(1.0+4.0*argv/gammd2);
2216 Vdsat = (vgsx-vbin)/eta+gammd2*(1.0-arg)/2.0;
2217 Vdsat = std::max(Vdsat,0.0);
2218 dsdvgs = (1.0-1.0/arg)/eta;
2219 dsdvbs = (gammad*(1.0-arg)+2.0*argv/(gammad*arg))/
2220 eta*dgdvbs+1.0/arg+factor*dsdvgs;
2225 Vdsat = (vgsx-vbin)/eta;
2226 Vdsat = std::max(Vdsat,0.0);
2236 gammd2 = gammad*gammad;
2237 v1 = (vgsx-vbin)/eta+phiMinVbs;
2242 c1 = -2.0*gammad*xv;
2243 d1 = 2.0*v1*(v2+xv)-v2*v2-4.0/3.0*gammad*sarg3;
2246 c = -d1*(a1*a1-4.0*b1)-c1*c1;
2248 s = 2.0*a*a*a/27.0-a*b/3.0+c;
2256 ro = sqrt(s2/4.0+p0);
2259 fi = atan(-2.0*p2/s);
2260 y3 = 2.0*ro*cos(fi/3.0)-a/3.0;
2265 p3 = exp(log(fabs(p3))/3.0);
2267 p4 = exp(log(fabs(p4))/3.0);
2271 a3 = sqrt(a1*a1/4.0-b1+y3);
2272 b3 = sqrt(y3*y3/4.0-d1);
2275 a4[i-1] = a1/2.0+sig1[i-1]*a3;
2276 b4[i-1] = y3/2.0+sig2[i-1]*b3;
2277 delta4 = a4[i-1]*a4[i-1]/4.0-b4[i-1];
2278 if (delta4 < 0)
continue;
2281 x4[iknt-1] = -a4[i-1]/2.0+tmp;
2283 x4[iknt-1] = -a4[i-1]/2.0-tmp;
2286 for(j = 1;j<=iknt;j++)
2288 if (x4[j-1] <= 0)
continue;
2290 poly4[j-1] = x4[j-1]*x4[j-1]*x4[j-1]*x4[j-1]+a1*x4[j-1]*
2292 poly4[j-1] = poly4[j-1]+b1*x4[j-1]*x4[j-1]+c1*x4[j-1]+d1;
2293 if (fabs(poly4[j-1]) > 1.0e-6)
continue;
2299 if (x4[j-1] > xvalid)
continue;
2304 Vdsat = xvalid*xvalid-phiMinVbs;
2311 bool line610bool=
false;
2320 if ((lvbs-Vdsat) <= 0)
2322 bsarg = sqrt(Vdsat+phiMinVbs);
2323 dbsrdb = -0.5/bsarg;
2327 bsarg = sphi/(1.0+0.5*(lvbs-Vdsat)/
tPhi);
2328 dbsrdb = -0.5*bsarg*bsarg/sphi3;
2330 bodys = bsarg*bsarg*bsarg-sarg3;
2331 gdbdvs = 2.0*gammad*(bsarg*bsarg*dbsrdb-sarg*sarg*dsrgdb);
2340 argv = (lvds-Vdsat)/4.0;
2341 sargv = sqrt(1.0+argv*argv);
2342 arg = sqrt(argv+sargv);
2343 xlfact =
model_.
xd/(EffectiveLength*lvds);
2344 xlamda = xlfact*arg;
2345 dldsat = lvds*xlamda/(8.0*sargv);
2350 argv = (vgsx-vbin)/eta-Vdsat;
2353 vqchan = argv-gammad*bsarg;
2354 dqdsat = -1.0+gammad*dbsrdb;
2356 dfunds = vl*dqdsat-ueff*vqchan;
2357 dfundg = (vl-ueff*Vdsat)/eta;
2358 dfundb = -vl*(1.0+dqdsat-factor/eta)+ueff*
2359 (gdbdvs-dgdvbs*bodys/1.5)/eta;
2360 dsdvgs = -dfundg/dfunds;
2361 dsdvbs = -dfundb/dfunds;
2370 argv = std::max(argv,0.0);
2371 xls = sqrt(xlv*xlv+argv);
2372 dldsat = xdv/(2.0*xls);
2373 xlfact = xdv/(EffectiveLength*lvds);
2374 xlamda = xlfact*(xls-xlv);
2381 dldvgs = dldsat*dsdvgs;
2382 dldvds = -xlamda+dldsat;
2383 dldvbs = dldsat*dsdvbs;
2388 bool donevalbool=
false;
2393 xld = EffectiveLength-xwb;
2394 clfact = 1.0-xlamda*lvds;
2395 dldvds = -xlamda-dldvds;
2396 xleff = EffectiveLength*clfact;
2401 xleff = xwb/(1.0+(deltal-xld)/xwb);
2403 dfact = xleff*xleff/(xwb*xwb);
2404 dldvgs = dfact*dldvgs;
2405 dldvds = dfact*dldvds;
2406 dldvbs = dfact*dldvbs;
2409 beta1 = Beta*ufact/clfact;
2415 if (lvds <= 1.0e-10)
2425 gds = beta1*(Von-vbin-gammad*sarg)*exp(argg*(lvgs-Von));
2430 gds = beta1*(lvgs-vbin-gammad*sarg);
2439 if ( !(lvgs > Von) )
2455 if (!donevalbool && !line1050bool)
2457 vdson = std::min(Vdsat,lvds);
2466 cdson = beta1*((Von-vbin-eta*vdson*0.5)*vdson-gammad*body/1.5);
2467 didvds = beta1*(Von-vbin-eta*vdson-gammad*barg);
2468 gdson = -cdson*dldvds/clfact-beta1*dgdvds*body/1.5;
2472 gdson = gdson+didvds;
2475 gbson = -cdson*dldvbs/clfact+beta1*
2476 (dodvbs*vdson+factor*vdson-dgdvbs*body/1.5-gdbdv);
2479 gbson = gbson+didvds*dsdvbs;
2481 expg = exp(argg*(lvgs-Von));
2487 gm = gmw+didvds*dsdvgs*expg;
2489 tmp = gmw*(lvgs-Von)/xn;
2490 gds = gdson*expg-
gm*dodvds-tmp*dxndvd;
2491 gmbs = gbson*expg-
gm*dodvbs-tmp*dxndvb;
2497 if (!donevalbool && !line1050bool)
2502 cdrain = beta1*((lvgs-vbin-eta*lvds/2.0)*lvds-gammad*body/1.5);
2503 arg =
cdrain*(dudvgs/ufact-dldvgs/clfact);
2504 gm = arg+beta1*lvds;
2505 arg =
cdrain*(dudvds/ufact-dldvds/clfact);
2506 gds = arg+beta1*(lvgs-vbin-eta*
2507 lvds-gammad*barg-dgdvds*body/1.5);
2508 arg =
cdrain*(dudvbs/ufact-dldvbs/clfact);
2509 gmbs = arg-beta1*(gdbdv+dgdvbs*body/1.5-factor*lvds);
2514 cdrain = beta1*((lvgs-vbin-eta*
2515 Vdsat/2.0)*Vdsat-gammad*bodys/1.5);
2516 arg =
cdrain*(dudvgs/ufact-dldvgs/clfact);
2517 gm = arg+beta1*Vdsat+beta1*(lvgs-
2518 vbin-eta*Vdsat-gammad*bsarg)*dsdvgs;
2519 gds = -
cdrain*dldvds/clfact-beta1*dgdvds*bodys/1.5;
2520 arg =
cdrain*(dudvbs/ufact-dldvbs/clfact);
2521 gmbs = arg-beta1*(gdbdvs+dgdvbs*bodys/1.5-factor*
2522 Vdsat)+beta1* (lvgs-vbin-eta*Vdsat-gammad*bsarg)*dsdvbs;
2590 sarg = sargsw = 1/sqrt(arg);
2609 sargsw = 1/sqrt(arg);
2649 sarg = sargsw = 1/sqrt(arg);
2663 sargsw = 1/sqrt(arg);
2910 double ratio,ratio4;
2918 double gmanew,gmaold;
2923 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2925 Xyce::dout() << subsection_divider << std::endl;
2926 Xyce::dout() <<
" Instance::Begin of updateTemperature. \n";
2927 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2928 Xyce::dout() << std::endl;
2932 if (temp_tmp != -999.0)
temp = temp_tmp;
2942 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2944 Xyce::dout() <<
"Temperature = "<<
temp << std::endl;
2945 Xyce::dout() <<
"tnom = " << tnom << std::endl;
2946 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2955 pbfact = -2*
vt *(1.5*log(fact2)+
CONSTQ*arg);
2959 Xyce::dout() <<
"vt = " <<
vt << std::endl;
2960 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2961 Xyce::dout() <<
"fact2 = " << fact2 << std::endl;
2962 Xyce::dout() <<
"kt = " << kt << std::endl;
2963 Xyce::dout() <<
"egfet = " << egfet << std::endl;
2964 Xyce::dout() <<
"arg = " << arg << std::endl;
2965 Xyce::dout() <<
"pbfact = " << pbfact << std::endl;
2977 ratio4 = ratio * sqrt(ratio);
2981 tPhi = fact2 * phio + pbfact;
3123 bool bsuccess =
true;
3130 double vgs1, vgd1, vbs1,vgb1, vds1;
3221 noiseData.
resize(numSources);
3232 std::string(
"_1overf");
3277 (2.0/3.0 * fabs(
gm)),
temp);
3311 egfet1 = 1.16-(7.02e-4*tnom*
tnom)/(tnom+1108);
3352 wkfng = 3.25 + .5 *
egfet1 - fermig;
3354 wkfngs = wkfng - (3.25 + .5 *
egfet1 +fermis);
3357 gamma = sqrt(2 * 11.70 * 8.854214871e-12 *
3408 std::vector<Instance*>::iterator iter;
3412 for (iter=first; iter!=last; ++iter)
3414 (*iter)->processParams();
3432 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
3434 tnom(getDeviceOptions().tnom),
3436 jctSatCurDensity(0.0),
3438 drainResistance(0.0),
3439 sourceResistance(0.0),
3440 sheetResistance(0.0),
3441 transconductance(0.0),
3442 gateSourceOverlapCapFactor(0.0),
3443 gateDrainOverlapCapFactor(0.0),
3444 gateBulkOverlapCapFactor(0.0),
3445 oxideCapFactor(0.0),
3450 sideWallCapFactor(0.0),
3451 bulkJctPotential(0.0),
3452 bulkJctBotGradingCoeff(0.0),
3453 bulkJctSideGradingCoeff(0.0),
3454 fwdCapDepCoeff(0.0),
3458 substrateDoping(0.0),
3460 surfaceStateDensity(0.0),
3461 oxideThickness(0.0),
3462 surfaceMobility(0.0),
3467 bulkCapFactorGiven(0),
3468 sideWallCapFactorGiven(0),
3477 fastSurfaceStateDensity(0.0),
3490 else if (
getType() ==
"PMOS") {
3525 UserError0(*
this) <<
"Both uo and u0 have been specified and, which is not allowed";
3527 UserWarning0(*
this) <<
"Surface mobility has been specified as u0 instead of uo, uo is the preferred syntax";
3545 std::vector<Instance*>::iterator iter;
3549 for (iter=first; iter!=last; ++iter)
3566 std::vector<Instance*>::const_iterator iter;
3572 os <<
" name model name Parameters" << std::endl;
3573 for (i=0, iter=first; iter!=last; ++iter, ++i)
3575 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
3600 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
3619 bool bsuccess =
true;
3628 double vgs1(0.0), vgd1(0.0), vbs1(0.0),vgb1(0.0), vds1(0.0);
3631 bsuccess = bsuccess && btmp;
3704 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
3713 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
3714 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
3718 ceqbs = Dtype*(mi.
cbs);
3719 ceqbd = Dtype*(mi.
cbd);
3732 coef = (ceqgs+ceqgd+ceqgb);
3742 coef = ceqbs + ceqbd - ceqgb;
3755 Qeqbs = Dtype*(mi.
qbs);
3756 Qeqbd = Dtype*(mi.
qbd);
3759 Qeqgb = Dtype*(mi.
qgb);
3760 Qeqgs = Dtype*(mi.
qgs);
3761 Qeqgd = Dtype*(mi.
qgd);
3763 coef = (Qeqgs+Qeqgd+Qeqgb);
3767 coef = Qeqbs + Qeqbd - Qeqgb;
3771 coef = -(Qeqbd + Qeqgd);
3775 coef = -(Qeqbs + Qeqgs);
3783 double coef_Jdxp4 = Dtype*(
3787 double coef_Jdxp5 = Dtype*(
3793 double coef_Jdxp6 = Dtype*(
3809 double gcgd(0.0), gcgs(0.0), gcgb(0.0), gcbs(0.0), gcbd(0.0);
3821 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
3828 double coef_Jdxp4 = Dtype*(
3833 double coef_Jdxp5 = Dtype*(
3838 double coef_Jdxp6 = Dtype*
3880 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
4029 for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
4167 .registerDevice(
"m", 2)
4168 .registerModelType(
"pmos", 2)
4169 .registerModelType(
"nmos", 2);
const InstanceName & getName() const
double defad
MOS drain diffusion area.
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
double defw
MOS channel width.
void getNoiseSources(Xyce::Analysis::NoiseData &noiseData)
static void initThermalModel(ParametricData< T > ¶metric_data)
Add the parameter "TEMPMODEL" to the parametric_data.
double * currStoVectorRawPtr
bool updateDependentParameters()
int ABulkEquBulkNodeOffset
const std::vector< std::vector< int > > & jacobianStamp() const
int AGateEquDrainPrimeNodeOffset
double * f_SourcePrimeEquBulkNodePtr
int ASourceEquSourcePrimeNodeOffset
const DeviceOptions & deviceOptions_
virtual std::ostream & printOutInstances(std::ostream &os) const
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
double * daeQVectorRawPtr
double * q_SourcePrimeEquDrainPrimeNodePtr
bool updateTemperature(const double &temp_tmp)
double * dFdxdVpVectorRawPtr
Linear::Vector * nextSolVectorPtr
double gateBulkOverlapCapFactor
double pnjlim(double vnew, double vold, double vt, double vcrit, int *icheck)
double surfaceStateDensity
std::vector< int > devConMap
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
void qmeyer(double vgs, double vgd, double vgb, double von, double vdsat, double &capgs, double &capgd, double &capgb, double phi, double cox)
bool given(const std::string ¶meter_name) const
double * q_DrainPrimeEquBulkNodePtr
double GateBulkOverlapCap
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
Instance(const Configuration &configuration, const InstanceBlock &IB, Model &Miter, const FactoryBlock &factory_block)
double * q_BulkEquGateNodePtr
double * f_BulkEquGateNodePtr
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
double * currStaVectorRawPtr
double gateDrainOverlapCapFactor
int ADrainPrimeEquSourcePrimeNodeOffset
void setNumStoreVars(int num_store_vars)
double * f_GateEquSourcePrimeNodePtr
std::vector< double > gainScale_
MOSFET Devices, ArtificialParameters.
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
double getRandomPerturbation()
int AGateEquBulkNodeOffset
void makeVector(const std::string &cname, int len)
Allows the parameter to be specified as a vector.
double * f_DrainPrimeEquBulkNodePtr
std::vector< int > li_Neg
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
std::vector< int > li_Pos
double bulkJctBotGradingCoeff
std::vector< Instance * > instanceContainer
double fastSurfaceStateDensity
Parameter is subject to being set to minimum junction capacitance.
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
Parameter is subject to being set to minimum lead resistance.
double * f_DrainPrimeEquGateNodePtr
double * q_BulkEquDrainPrimeNodePtr
double gateSourceOverlapCapFactor
int ASourcePrimeEquSourceNodeOffset
double fetlim(double vnew, double vold, double vto)
double defl
MOS channel length.
double * q_SourcePrimeEquGateNodePtr
int ADrainPrimeEquDrainPrimeNodeOffset
double tnom
nominal temperature for device params.
int ADrainPrimeEquDrainNodeOffset
double * q_SourcePrimeEquSourceNodePtr
double * storeLeadCurrQCompRawPtr
int getNumStoreVars() const
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
double contVgst(double vgst, double alpha, double vgstConst=3.0)
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
std::vector< Param > params
Parameters from the line.
std::vector< double > noiseDens
double * f_BulkEquSourcePrimeNodePtr
double * q_DrainEquDrainPrimeNodePtr
std::vector< std::string > noiseNames
int ADrainPrimeEquGateNodeOffset
int AGateEquGateNodeOffset
void setParams(const std::vector< Param > ¶ms)
double * q_SourcePrimeEquBulkNodePtr
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
const std::string & getName() const
double * daeFVectorRawPtr
double * q_BulkEquBulkNodePtr
static std::vector< int > jacMap_DC
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)
static void loadModelParameters(ParametricData< Model > &model_parameters)
const DeviceOptions & getDeviceOptions() const
double * q_DrainPrimeEquSourcePrimeNodePtr
static std::vector< std::vector< int > > jacStamp_DC
static std::vector< std::vector< int > > jacStamp_SC
double * nextStoVectorRawPtr
int ADrainPrimeEquBulkNodeOffset
static std::vector< std::vector< int > > jacStamp
double * f_DrainPrimeEquDrainNodePtr
double * q_DrainPrimeEquDrainNodePtr
static std::vector< int > jacMap
double * f_SourcePrimeEquSourcePrimeNodePtr
double * f_DrainPrimeEquDrainPrimeNodePtr
double limvds(double vnew, double vold)
static std::vector< std::vector< int > > jacMap2_DC
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
static std::vector< int > jacMap_SC
bool updatePrimaryState()
Linear::Matrix * dFdxMatrixPtr
const DeviceOptions & getDeviceOptions() const
Returns the device options given during device construction.
double * f_DrainPrimeEquSourcePrimeNodePtr
static std::vector< int > jacMap_DC_SC
double * f_SourcePrimeEquGateNodePtr
The Device class is an interface for device implementations.
void setupNoiseSources(Xyce::Analysis::NoiseData &noiseData)
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
void addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
double * f_DrainEquDrainPrimeNodePtr
double GateSourceOverlapCap
double GateDrainOverlapCap
double defas
MOS source diffusion area.
static std::vector< std::vector< int > > jacMap2
double * q_GateEquSourcePrimeNodePtr
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
const SolverState & solverState_
bool artParameterFlag_
MOSFET Devices, ArtificialParameters.
int getGainScaleBlockID(int numBlocks)
double * dQdxdVpVectorRawPtr
Class Configuration contains device configuration data.
int ABulkEquSourcePrimeNodeOffset
std::vector< double > lnNoiseDens
double * q_GateEquBulkNodePtr
int getNumNoiseSources() const
double * q_BulkEquSourcePrimeNodePtr
bool interpolateTNOM(double)
double * f_GateEquDrainPrimeNodePtr
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
double * q_DrainPrimeEquGateNodePtr
const SolverState & getSolverState() const
double * f_DrainEquDrainNodePtr
Linear::Vector * nextStoVectorPtr
int ABulkEquGateNodeOffset
double * q_DrainPrimeEquDrainPrimeNodePtr
int ASourcePrimeEquDrainPrimeNodeOffset
Linear::Vector * currStaVectorPtr
double * f_BulkEquBulkNodePtr
double * nextStaVectorRawPtr
#define Xyce_NONPOINTER_MATRIX_LOAD
int ABulkEquDrainPrimeNodeOffset
void noiseSupport(double &noise, double &lnNoise, const int type, const double param, const double temp)
int ADrainEquDrainNodeOffset
double * f_SourcePrimeEquDrainPrimeNodePtr
const std::string & getType() const
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
double gmin
minimum allowed conductance.
double * f_SourceEquSourcePrimeNodePtr
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
double contVds(double vds, double alpha, double min=0.3)
double * q_GateEquDrainPrimeNodePtr
double * q_DrainEquDrainNodePtr
static std::vector< std::vector< int > > jacMap2_SC
double * q_GateEquGateNodePtr
Linear::Vector * currStoVectorPtr
int ASourceEquSourceNodeOffset
const ExternData & extData
static std::vector< std::vector< int > > jacStamp_DC_SC
double * f_SourceEquSourceNodePtr
ModelBlock represents a .MODEL line from the netlist.
bool sideWallCapFactorGiven
double * f_SourcePrimeEquSourceNodePtr
Manages parameter binding for class C.
InstanceBlock represent a device instance line from the netlist.
double * f_GateEquBulkNodePtr
int ASourcePrimeEquBulkNodeOffset
bool initJctFlag_
true if on the first newton step of the first dcop solve of the first .STEP iteration. BJT, JFET, Diode, MOSFET, SW, Extern
int ASourcePrimeEquGateNodeOffset
Util::Param temp
operating temperature of ckt.
int AGateEquSourcePrimeNodeOffset
std::vector< Param > params
Linear::Matrix * dQdxMatrixPtr
double * f_BulkEquDrainPrimeNodePtr
bool updateIntermediateVars()
int ASourcePrimeEquSourcePrimeNodeOffset
double * q_SourcePrimeEquSourcePrimeNodePtr
double * q_SourceEquSourceNodePtr
int ADrainEquDrainPrimeNodeOffset
bool processInstanceParams()
processInstanceParams
double * q_SourceEquSourcePrimeNodePtr
double * f_GateEquGateNodePtr
Linear::Vector * flagSolVectorPtr
bool processParams()
processParams
double bulkJctSideGradingCoeff
const SolverState & getSolverState() const
Returns the solver state given during device construction.
void setModParams(const std::vector< Param > ¶ms)
int numLeadCurrentStoreVars
static std::vector< std::vector< int > > jacMap2_DC_SC