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)");
418 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
426 l(getDeviceOptions().defl),
427 w(getDeviceOptions().defw),
429 drainArea(getDeviceOptions().defad),
430 sourceArea(getDeviceOptions().defas),
434 sourcePerimeter(0.0),
435 sourceConductance(0.0),
436 drainConductance(0.0),
437 temp(getDeviceOptions().temp.getImmutableValue<double>()),
439 tTransconductance(0.0),
490 GateSourceOverlapCap(0),
491 GateDrainOverlapCap(0),
492 GateBulkOverlapCap(0),
505 ADrainEquDrainNodeOffset(-1),
506 ADrainEquDrainPrimeNodeOffset(-1),
508 AGateEquGateNodeOffset(-1),
509 AGateEquBulkNodeOffset(-1),
510 AGateEquDrainPrimeNodeOffset(-1),
511 AGateEquSourcePrimeNodeOffset(-1),
513 ASourceEquSourceNodeOffset(-1),
514 ASourceEquSourcePrimeNodeOffset(-1),
516 ABulkEquGateNodeOffset(-1),
517 ABulkEquBulkNodeOffset(-1),
518 ABulkEquDrainPrimeNodeOffset(-1),
519 ABulkEquSourcePrimeNodeOffset(-1),
521 ADrainPrimeEquDrainNodeOffset(-1),
522 ADrainPrimeEquGateNodeOffset(-1),
523 ADrainPrimeEquBulkNodeOffset(-1),
524 ADrainPrimeEquDrainPrimeNodeOffset(-1),
525 ADrainPrimeEquSourcePrimeNodeOffset(-1),
527 ASourcePrimeEquGateNodeOffset(-1),
528 ASourcePrimeEquSourceNodeOffset(-1),
529 ASourcePrimeEquBulkNodeOffset(-1),
530 ASourcePrimeEquDrainPrimeNodeOffset(-1),
531 ASourcePrimeEquSourcePrimeNodeOffset(-1),
536 f_DrainEquDrainNodePtr(0),
537 f_DrainEquDrainPrimeNodePtr(0),
539 f_GateEquGateNodePtr(0),
540 f_GateEquBulkNodePtr(0),
541 f_GateEquDrainPrimeNodePtr(0),
542 f_GateEquSourcePrimeNodePtr(0),
544 f_SourceEquSourceNodePtr(0),
545 f_SourceEquSourcePrimeNodePtr(0),
547 f_BulkEquGateNodePtr(0),
548 f_BulkEquBulkNodePtr(0),
549 f_BulkEquDrainPrimeNodePtr(0),
550 f_BulkEquSourcePrimeNodePtr(0),
552 f_DrainPrimeEquDrainNodePtr(0),
553 f_DrainPrimeEquGateNodePtr(0),
554 f_DrainPrimeEquBulkNodePtr(0),
555 f_DrainPrimeEquDrainPrimeNodePtr(0),
556 f_DrainPrimeEquSourcePrimeNodePtr(0),
558 f_SourcePrimeEquGateNodePtr(0),
559 f_SourcePrimeEquSourceNodePtr(0),
560 f_SourcePrimeEquBulkNodePtr(0),
561 f_SourcePrimeEquDrainPrimeNodePtr(0),
562 f_SourcePrimeEquSourcePrimeNodePtr(0),
565 q_DrainEquDrainNodePtr(0),
566 q_DrainEquDrainPrimeNodePtr(0),
568 q_GateEquGateNodePtr(0),
569 q_GateEquBulkNodePtr(0),
570 q_GateEquDrainPrimeNodePtr(0),
571 q_GateEquSourcePrimeNodePtr(0),
573 q_SourceEquSourceNodePtr(0),
574 q_SourceEquSourcePrimeNodePtr(0),
576 q_BulkEquGateNodePtr(0),
577 q_BulkEquBulkNodePtr(0),
578 q_BulkEquDrainPrimeNodePtr(0),
579 q_BulkEquSourcePrimeNodePtr(0),
581 q_DrainPrimeEquDrainNodePtr(0),
582 q_DrainPrimeEquGateNodePtr(0),
583 q_DrainPrimeEquBulkNodePtr(0),
584 q_DrainPrimeEquDrainPrimeNodePtr(0),
585 q_DrainPrimeEquSourcePrimeNodePtr(0),
587 q_SourcePrimeEquGateNodePtr(0),
588 q_SourcePrimeEquSourceNodePtr(0),
589 q_SourcePrimeEquBulkNodePtr(0),
590 q_SourcePrimeEquDrainPrimeNodePtr(0),
591 q_SourcePrimeEquSourcePrimeNodePtr(0),
773 UserError0(*
this) <<
"Effective channel length less than zero.";
786 Xyce::dout() <<
": name = " <<
getName() << std::endl;
816 const std::vector<int> & extLIDVecRef )
823 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
825 Xyce::dout() << section_divider << std::endl;
826 Xyce::dout() <<
" In Instance::register LIDs\n\n";
827 Xyce::dout() <<
" name = " <<
getName() << std::endl;
828 Xyce::dout() <<
" number of internal variables: " <<
numIntVars << std::endl;
829 Xyce::dout() <<
" number of external variables: " <<
numExtVars << std::endl;
857 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
859 Xyce::dout() <<
"\n variable local indices:\n";
860 Xyce::dout() <<
" li_Drain = " <<
li_Drain << std::endl;
861 Xyce::dout() <<
" li_DrainPrime = " <<
li_DrainPrime << std::endl;
862 Xyce::dout() <<
" li_Source = " <<
li_Source << std::endl;
863 Xyce::dout() <<
" li_SourcePrime = " <<
li_SourcePrime << std::endl;
864 Xyce::dout() <<
" li_Gate = " <<
li_Gate << std::endl;
865 Xyce::dout() <<
" li_Bulk = " <<
li_Bulk << std::endl;
867 Xyce::dout() << section_divider << std::endl;
909 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
911 Xyce::dout() << std::endl;
912 Xyce::dout() << section_divider << std::endl;
913 Xyce::dout() <<
" In Instance::registerStateLIDs\n\n";
914 Xyce::dout() <<
" name = " <<
getName() << std::endl;
915 Xyce::dout() <<
" Number of State LIDs: " <<
numStateVars << std::endl;
935 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
937 Xyce::dout() <<
" State local indices:" << std::endl;
938 Xyce::dout() << std::endl;
949 Xyce::dout() << std::endl;
950 Xyce::dout() << section_divider << std::endl;
1017 std::vector<int> map;
1018 std::vector< std::vector<int> > map2;
1085 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
1172 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
1181 Qeqbs = Dtype*(
qbs);
1182 Qeqbd = Dtype*(
qbd);
1185 Qeqgb = Dtype*(
qgb);
1186 Qeqgs = Dtype*(
qgs);
1187 Qeqgd = Dtype*(
qgd);
1190 coef = (Qeqgs+Qeqgd+Qeqgb);
1194 coef = Qeqbs + Qeqbd - Qeqgb;
1198 coef = -(Qeqbd + Qeqgd);
1202 coef = -(Qeqbs + Qeqgs);
1231 double gcgd, gcgs, gcgb, gcbs, gcbd;
1243 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
1251 double coef_Jdxp4 = Dtype*(
1257 double coef_Jdxp5 = Dtype*(
1290 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
1297 ceqbs = Dtype*(
cbs);
1298 ceqbd = Dtype*(
cbd);
1313 coef = (ceqgs+ceqgd+ceqgb);
1324 coef = ceqbs + ceqbd - ceqgb;
1344 double coef_Jdxp4 = Dtype*(
1349 double coef_Jdxp5 = Dtype*(
1356 double coef_Jdxp6 = Dtype*(
1444 (+gcbs+gcbd+gcgb)*numberParallel;
1454 (+gcbd+gcgd)*numberParallel;
1461 (+gcbs+gcgs)*numberParallel;
1493 (
gbs+
gbd)*numberParallel;
1532 bool bsuccess =
true;
1631 if ((*flagSolVectorPtr)[
li_Drain] == 0 || (*flagSolVectorPtr)[
li_Gate] == 0 ||
1863 static double sig1[4] = {1.0, -1.0, 1.0, -1.0};
1864 static double sig2[4] = {1.0, 1.0,-1.0, -1.0};
1868 double a4[4],b4[4],x4[8],poly4[8];
1989 double lvbs =
mode==1?vbs:
vbd;
1992 double phiMinVbs =
tPhi - lvbs;
2003 sarg = sqrt(phiMinVbs);
2005 d2sdb2 = 0.5*dsrgdb/phiMinVbs;
2011 sarg = sphi/(1.0+0.5*lvbs/
tPhi);
2013 dsrgdb = -0.5*sarg*tmp;
2014 d2sdb2 = -dsrgdb*tmp;
2016 if ((lvds-lvbs) >= 0)
2018 barg = sqrt(phiMinVbs+lvds);
2020 d2bdb2 = 0.5*dbrgdb/(phiMinVbs+lvds);
2024 barg = sphi/(1.0+0.5*(lvbs-lvds)/
tPhi);
2026 dbrgdb = -0.5*barg*tmp;
2027 d2bdb2 = -dbrgdb*tmp;
2054 argxs = 1.0+xws*tmp;
2055 argxd = 1.0+xwd*tmp;
2059 argss = tmp * (args-1.0);
2060 argsd = tmp * (argd-1.0);
2068 dbargs = tmp*dbxws/args;
2069 dbargd = tmp*dbxwd/argd;
2070 dasdb2 = -
model_.
xd*( d2sdb2+dsrgdb*dsrgdb*
2072 (EffectiveLength*args);
2073 daddb2 = -
model_.
xd*( d2bdb2+dbrgdb*dbrgdb*
2075 (EffectiveLength*argd);
2082 dgdvds = -
model_.
gamma*0.5*ddxwd/(EffectiveLength*argd);
2093 Von = vbin+gamasd*sarg;
2100 bool line1050bool=
false;
2105 cdonco = -(gamasd*dsrgdb+dgddvb*sarg)+factor;
2106 xn = 1.0+cfs/
OxideCap*
w*EffectiveLength+cdonco;
2133 sarg3 = sarg*sarg*sarg;
2138 body = barg*barg*barg-sarg3;
2139 gdbdv = 2.0*gammad*(barg*barg*dbrgdb-sarg*sarg*dsrgdb);
2140 dodvbs = -factor+dgdvbs*sarg+gammad*dsrgdb;
2146 dxndvb = 2.0*dgdvbs*dsrgdb+gammad*d2sdb2+dgddb2*sarg;
2147 dodvbs = dodvbs+
vt*dxndvb;
2148 dxndvd = dgdvds*dsrgdb;
2149 dodvds = dgdvds*sarg+
vt*dxndvd;
2179 gammad = gamasd/eta;
2183 vgsx = std::max(lvgs,Von);
2187 gammd2 = gammad*gammad;
2188 argv = (vgsx-vbin)/eta+phiMinVbs;
2197 arg = sqrt(1.0+4.0*argv/gammd2);
2198 Vdsat = (vgsx-vbin)/eta+gammd2*(1.0-arg)/2.0;
2199 Vdsat = std::max(Vdsat,0.0);
2200 dsdvgs = (1.0-1.0/arg)/eta;
2201 dsdvbs = (gammad*(1.0-arg)+2.0*argv/(gammad*arg))/
2202 eta*dgdvbs+1.0/arg+factor*dsdvgs;
2207 Vdsat = (vgsx-vbin)/eta;
2208 Vdsat = std::max(Vdsat,0.0);
2218 gammd2 = gammad*gammad;
2219 v1 = (vgsx-vbin)/eta+phiMinVbs;
2224 c1 = -2.0*gammad*xv;
2225 d1 = 2.0*v1*(v2+xv)-v2*v2-4.0/3.0*gammad*sarg3;
2228 c = -d1*(a1*a1-4.0*b1)-c1*c1;
2230 s = 2.0*a*a*a/27.0-a*b/3.0+c;
2238 ro = sqrt(s2/4.0+p0);
2241 fi = atan(-2.0*p2/s);
2242 y3 = 2.0*ro*cos(fi/3.0)-a/3.0;
2247 p3 = exp(log(fabs(p3))/3.0);
2249 p4 = exp(log(fabs(p4))/3.0);
2253 a3 = sqrt(a1*a1/4.0-b1+y3);
2254 b3 = sqrt(y3*y3/4.0-d1);
2257 a4[i-1] = a1/2.0+sig1[i-1]*a3;
2258 b4[i-1] = y3/2.0+sig2[i-1]*b3;
2259 delta4 = a4[i-1]*a4[i-1]/4.0-b4[i-1];
2260 if (delta4 < 0)
continue;
2263 x4[iknt-1] = -a4[i-1]/2.0+tmp;
2265 x4[iknt-1] = -a4[i-1]/2.0-tmp;
2268 for(j = 1;j<=iknt;j++)
2270 if (x4[j-1] <= 0)
continue;
2272 poly4[j-1] = x4[j-1]*x4[j-1]*x4[j-1]*x4[j-1]+a1*x4[j-1]*
2274 poly4[j-1] = poly4[j-1]+b1*x4[j-1]*x4[j-1]+c1*x4[j-1]+d1;
2275 if (fabs(poly4[j-1]) > 1.0e-6)
continue;
2281 if (x4[j-1] > xvalid)
continue;
2286 Vdsat = xvalid*xvalid-phiMinVbs;
2293 bool line610bool=
false;
2302 if ((lvbs-Vdsat) <= 0)
2304 bsarg = sqrt(Vdsat+phiMinVbs);
2305 dbsrdb = -0.5/bsarg;
2309 bsarg = sphi/(1.0+0.5*(lvbs-Vdsat)/
tPhi);
2310 dbsrdb = -0.5*bsarg*bsarg/sphi3;
2312 bodys = bsarg*bsarg*bsarg-sarg3;
2313 gdbdvs = 2.0*gammad*(bsarg*bsarg*dbsrdb-sarg*sarg*dsrgdb);
2322 argv = (lvds-Vdsat)/4.0;
2323 sargv = sqrt(1.0+argv*argv);
2324 arg = sqrt(argv+sargv);
2325 xlfact =
model_.
xd/(EffectiveLength*lvds);
2326 xlamda = xlfact*arg;
2327 dldsat = lvds*xlamda/(8.0*sargv);
2332 argv = (vgsx-vbin)/eta-Vdsat;
2335 vqchan = argv-gammad*bsarg;
2336 dqdsat = -1.0+gammad*dbsrdb;
2338 dfunds = vl*dqdsat-ueff*vqchan;
2339 dfundg = (vl-ueff*Vdsat)/eta;
2340 dfundb = -vl*(1.0+dqdsat-factor/eta)+ueff*
2341 (gdbdvs-dgdvbs*bodys/1.5)/eta;
2342 dsdvgs = -dfundg/dfunds;
2343 dsdvbs = -dfundb/dfunds;
2352 argv = std::max(argv,0.0);
2353 xls = sqrt(xlv*xlv+argv);
2354 dldsat = xdv/(2.0*xls);
2355 xlfact = xdv/(EffectiveLength*lvds);
2356 xlamda = xlfact*(xls-xlv);
2363 dldvgs = dldsat*dsdvgs;
2364 dldvds = -xlamda+dldsat;
2365 dldvbs = dldsat*dsdvbs;
2370 bool donevalbool=
false;
2375 xld = EffectiveLength-xwb;
2376 clfact = 1.0-xlamda*lvds;
2377 dldvds = -xlamda-dldvds;
2378 xleff = EffectiveLength*clfact;
2383 xleff = xwb/(1.0+(deltal-xld)/xwb);
2385 dfact = xleff*xleff/(xwb*xwb);
2386 dldvgs = dfact*dldvgs;
2387 dldvds = dfact*dldvds;
2388 dldvbs = dfact*dldvbs;
2391 beta1 = Beta*ufact/clfact;
2397 if (lvds <= 1.0e-10)
2407 gds = beta1*(Von-vbin-gammad*sarg)*exp(argg*(lvgs-Von));
2412 gds = beta1*(lvgs-vbin-gammad*sarg);
2421 if ( !(lvgs > Von) )
2437 if (!donevalbool && !line1050bool)
2439 vdson = std::min(Vdsat,lvds);
2448 cdson = beta1*((Von-vbin-eta*vdson*0.5)*vdson-gammad*body/1.5);
2449 didvds = beta1*(Von-vbin-eta*vdson-gammad*barg);
2450 gdson = -cdson*dldvds/clfact-beta1*dgdvds*body/1.5;
2454 gdson = gdson+didvds;
2457 gbson = -cdson*dldvbs/clfact+beta1*
2458 (dodvbs*vdson+factor*vdson-dgdvbs*body/1.5-gdbdv);
2461 gbson = gbson+didvds*dsdvbs;
2463 expg = exp(argg*(lvgs-Von));
2469 gm = gmw+didvds*dsdvgs*expg;
2471 tmp = gmw*(lvgs-Von)/xn;
2472 gds = gdson*expg-
gm*dodvds-tmp*dxndvd;
2473 gmbs = gbson*expg-
gm*dodvbs-tmp*dxndvb;
2479 if (!donevalbool && !line1050bool)
2484 cdrain = beta1*((lvgs-vbin-eta*lvds/2.0)*lvds-gammad*body/1.5);
2485 arg =
cdrain*(dudvgs/ufact-dldvgs/clfact);
2486 gm = arg+beta1*lvds;
2487 arg =
cdrain*(dudvds/ufact-dldvds/clfact);
2488 gds = arg+beta1*(lvgs-vbin-eta*
2489 lvds-gammad*barg-dgdvds*body/1.5);
2490 arg =
cdrain*(dudvbs/ufact-dldvbs/clfact);
2491 gmbs = arg-beta1*(gdbdv+dgdvbs*body/1.5-factor*lvds);
2496 cdrain = beta1*((lvgs-vbin-eta*
2497 Vdsat/2.0)*Vdsat-gammad*bodys/1.5);
2498 arg =
cdrain*(dudvgs/ufact-dldvgs/clfact);
2499 gm = arg+beta1*Vdsat+beta1*(lvgs-
2500 vbin-eta*Vdsat-gammad*bsarg)*dsdvgs;
2501 gds = -
cdrain*dldvds/clfact-beta1*dgdvds*bodys/1.5;
2502 arg =
cdrain*(dudvbs/ufact-dldvbs/clfact);
2503 gmbs = arg-beta1*(gdbdvs+dgdvbs*bodys/1.5-factor*
2504 Vdsat)+beta1* (lvgs-vbin-eta*Vdsat-gammad*bsarg)*dsdvbs;
2572 sarg = sargsw = 1/sqrt(arg);
2591 sargsw = 1/sqrt(arg);
2631 sarg = sargsw = 1/sqrt(arg);
2645 sargsw = 1/sqrt(arg);
2892 double ratio,ratio4;
2900 double gmanew,gmaold;
2905 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2907 Xyce::dout() << subsection_divider << std::endl;
2908 Xyce::dout() <<
" Instance::Begin of updateTemperature. \n";
2909 Xyce::dout() <<
" name = " <<
getName() << std::endl;
2910 Xyce::dout() << std::endl;
2914 if (temp_tmp != -999.0)
temp = temp_tmp;
2924 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
2926 Xyce::dout() <<
"Temperature = "<<
temp << std::endl;
2927 Xyce::dout() <<
"tnom = " << tnom << std::endl;
2928 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2937 pbfact = -2*
vt *(1.5*log(fact2)+
CONSTQ*arg);
2941 Xyce::dout() <<
"vt = " <<
vt << std::endl;
2942 Xyce::dout() <<
"ratio = " << ratio << std::endl;
2943 Xyce::dout() <<
"fact2 = " << fact2 << std::endl;
2944 Xyce::dout() <<
"kt = " << kt << std::endl;
2945 Xyce::dout() <<
"egfet = " << egfet << std::endl;
2946 Xyce::dout() <<
"arg = " << arg << std::endl;
2947 Xyce::dout() <<
"pbfact = " << pbfact << std::endl;
2959 ratio4 = ratio * sqrt(ratio);
2963 tPhi = fact2 * phio + pbfact;
3105 bool bsuccess =
true;
3112 double vgs1, vgd1, vbs1,vgb1, vds1;
3203 noiseData.
resize(numSources);
3214 std::string(
"_1overf");
3259 (2.0/3.0 * fabs(
gm)),
temp);
3293 egfet1 = 1.16-(7.02e-4*tnom*
tnom)/(tnom+1108);
3334 wkfng = 3.25 + .5 *
egfet1 - fermig;
3336 wkfngs = wkfng - (3.25 + .5 *
egfet1 +fermis);
3339 gamma = sqrt(2 * 11.70 * 8.854214871e-12 *
3390 std::vector<Instance*>::iterator iter;
3394 for (iter=first; iter!=last; ++iter)
3396 (*iter)->processParams();
3414 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
3416 tnom(getDeviceOptions().tnom),
3418 jctSatCurDensity(0.0),
3420 drainResistance(0.0),
3421 sourceResistance(0.0),
3422 sheetResistance(0.0),
3423 transconductance(0.0),
3424 gateSourceOverlapCapFactor(0.0),
3425 gateDrainOverlapCapFactor(0.0),
3426 gateBulkOverlapCapFactor(0.0),
3427 oxideCapFactor(0.0),
3432 sideWallCapFactor(0.0),
3433 bulkJctPotential(0.0),
3434 bulkJctBotGradingCoeff(0.0),
3435 bulkJctSideGradingCoeff(0.0),
3436 fwdCapDepCoeff(0.0),
3440 substrateDoping(0.0),
3442 surfaceStateDensity(0.0),
3443 oxideThickness(0.0),
3444 surfaceMobility(0.0),
3449 bulkCapFactorGiven(0),
3450 sideWallCapFactorGiven(0),
3459 fastSurfaceStateDensity(0.0),
3472 else if (
getType() ==
"PMOS") {
3507 UserError0(*
this) <<
"Both uo and u0 have been specified and, which is not allowed";
3509 UserWarning0(*
this) <<
"Surface mobility has been specified as u0 instead of uo, uo is the preferred syntax";
3527 std::vector<Instance*>::iterator iter;
3531 for (iter=first; iter!=last; ++iter)
3548 std::vector<Instance*>::const_iterator iter;
3554 os <<
" name model name Parameters" << std::endl;
3555 for (i=0, iter=first; iter!=last; ++iter, ++i)
3557 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
3582 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
3601 bool bsuccess =
true;
3610 double vgs1(0.0), vgd1(0.0), vbs1(0.0),vgb1(0.0), vds1(0.0);
3613 bsuccess = bsuccess && btmp;
3686 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
3695 double ceqbs(0.0),ceqbd(0.0),ceqgb(0.0), ceqgs(0.0), ceqgd(0.0);
3696 double Qeqbs(0.0),Qeqbd(0.0),Qeqgb(0.0), Qeqgs(0.0), Qeqgd(0.0);
3700 ceqbs = Dtype*(mi.
cbs);
3701 ceqbd = Dtype*(mi.
cbd);
3714 coef = (ceqgs+ceqgd+ceqgb);
3724 coef = ceqbs + ceqbd - ceqgb;
3737 Qeqbs = Dtype*(mi.
qbs);
3738 Qeqbd = Dtype*(mi.
qbd);
3741 Qeqgb = Dtype*(mi.
qgb);
3742 Qeqgs = Dtype*(mi.
qgs);
3743 Qeqgd = Dtype*(mi.
qgd);
3745 coef = (Qeqgs+Qeqgd+Qeqgb);
3749 coef = Qeqbs + Qeqbd - Qeqgb;
3753 coef = -(Qeqbd + Qeqgd);
3757 coef = -(Qeqbs + Qeqgs);
3765 double coef_Jdxp4 = Dtype*(
3769 double coef_Jdxp5 = Dtype*(
3775 double coef_Jdxp6 = Dtype*(
3791 double gcgd(0.0), gcgs(0.0), gcgb(0.0), gcbs(0.0), gcbd(0.0);
3803 gcgd = 0.0; gcgs = 0.0; gcgb = 0.0; gcbs = 0.0; gcbd = 0.0;
3810 double coef_Jdxp4 = Dtype*(
3815 double coef_Jdxp5 = Dtype*(
3820 double coef_Jdxp6 = Dtype*
3862 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
4011 for (InstanceVector::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
4149 .registerDevice(
"m", 2)
4150 .registerModelType(
"pmos", 2)
4151 .registerModelType(
"nmos", 2);
const InstanceName & getName() const
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
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
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
double getRandomPerturbation()
int AGateEquBulkNodeOffset
std::vector< double > gainScale
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 * q_SourcePrimeEquGateNodePtr
int ADrainPrimeEquDrainPrimeNodeOffset
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
static std::vector< std::vector< int > > jacMap2
double * q_GateEquSourcePrimeNodePtr
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
const SolverState & solverState_
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 * 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
int ASourcePrimeEquGateNodeOffset
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