46 #include <Xyce_config.h>
61 #include <N_ERH_ErrorMgr.h>
80 :
DeviceEntity(
modelEntityType, model_block.name, parametric_data, factory_block.solverState_, factory_block.deviceOptions_, model_block.netlistFileName_, model_block.lineNumber_),
81 type_(model_block.type),
82 level_(model_block.level),
101 std::vector<int> m_start;
102 std::set<std::string> pname;
103 std::map<std::string, int> ptype;
106 m_start.push_back(param_index);
107 for (std::vector<Param>::const_iterator mp = params.begin(); mp != params.end(); ++mp)
110 if ((*mp).tag() ==
"INDEPENDENT;PARAM")
112 m_start.push_back(param_index);
117 if (pname.find((*mp).tag()) != pname.end())
119 UserError0(*
this) <<
"Duplicate specification of parameter " << (*mp).tag();
122 pname.insert((*mp).tag());
123 if (m_start.size() == 1)
125 ptype[(*mp).tag()] = (*mp).getType();
129 if (m_start.size() == 1)
135 m_start.push_back(param_index + 1);
139 std::string tmod(
"");
140 std::string dmod(
"");
141 std::string modName(
"");
143 for (
int i = 0; i < m_start.size()-1; ++i)
145 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
147 if (params[j].tag() ==
"TEMPMODEL" && params[j].stringValue() !=
"NONE")
151 tmod = params[j].stringValue();
155 if (tmod != params[j].stringValue())
157 UserError0(*
this) <<
"Inconsistent or missing TEMPMODEL parameter, " << params[j].stringValue() <<
" specified here, " << tmod <<
" specified perviously";
162 if (params[j].tag() ==
"DOSEMODEL" && params[j].stringValue() !=
"NONE")
166 dmod = params[j].stringValue();
170 if (dmod != params[j].stringValue())
172 UserError0(*
this) <<
"Inconsistent or missing DOSEMODEL parameter, " << params[j].stringValue() <<
" specified here, " << dmod <<
" specified perviously";
180 if (tmod ==
"" && dmod ==
"")
182 UserError0(*
this) <<
"Duplicate model specification implies parameter interpolation, TEMPMODEL or DOSEMODEL parameters must specified";
185 else if (tmod !=
"" && dmod !=
"")
187 UserError0(*
this) <<
"Only one of TEMPMODEL or DOSEMODEL parameters may be specified";
201 if (modName ==
"QUADRATIC")
204 if (m_start.size() != 4)
206 UserError0(*
this) <<
"Three model specifications required for QUADRATIC fit";
211 else if (modName ==
"PWL")
214 fit.resize(m_start.size() - 1);
218 UserError0(*
this) <<
"Only QUADRATIC or PWL interpolation method is supported";
223 std::map<std::string,double> basePars;
224 std::vector<double> t;
227 for (
int i = 0 ;i < m_start.size()-1; ++i)
229 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
231 par = params[j].tag();
234 DevelFatal0(*this).in(
"DeviceModel::setModParams") <<
"Parameter " << par <<
" not found";
243 t.push_back(params[j].getImmutableValue<double>());
250 t.push_back(params[j].getImmutableValue<double>());
255 if (params[j].
getType() != Util::EXPR)
257 basePars[par] = params[j].getImmutableValue<
double>();
262 if (ptype[par] == Util::EXPR)
264 UserWarning0(*
this) <<
"Non-constant expression for parameter " << par <<
", it will not interpolated";
268 if (basePars.find(par) == basePars.end())
270 UserError0(*
this) <<
"Unknown parameter " << params[j].tag() <<
" in temperature compensation .MODEL statement";
273 if (basePars[par] != params[j].getImmutableValue<double>() && params[j].
given())
279 fit[0].push_back(basePars[par]);
288 if (t.size() != m_start.size()-1)
290 UserError0(*
this) << (
iModel ==
TEMP ?
"TNOM" :
"DOSE") <<
" not specified in all .MODEL statements";
294 for (
int i = 1; i < t.size(); ++i)
296 for (
int j = 0; j < i; ++j)
300 UserError0(*
this) <<
"Identical " << (
iModel ==
TEMP ?
"TNOM" :
"DOSE") <<
" values in .MODEL statements";
309 std::vector<std::vector<double> > temp(nFit);
310 std::vector<std::vector<double> > val(nFit);
313 for (
int i = 1; i <
fit.size(); ++i)
320 std::map<std::string, int>::iterator fm =
fitMap.begin();
321 std::map<std::string, int>::iterator fm_end =
fitMap.end();
323 for ( ; fm != fm_end ; ++fm)
328 throw std::runtime_error(std::string(
"Parameter ") + par +
" not found");
349 for (
int i = 0; i < nFit; ++i)
351 temp[i].push_back(t[0]);
352 val[i].push_back(
fit[0][i]);
358 message <<
"Negative parameter value for log interpolation based parameter ";
360 for ( ; fm != fm_end ; ++fm)
362 if ((*fm).second == i)
371 val[i][0] = log(val[i][0]);
377 for (
int i = 1; i < m_start.size()-1; ++i)
379 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
381 if (params[j].
getType() == Util::DBLE && params[j].given())
383 par = params[j].tag();
384 std::map<std::string, int>::iterator fm1 =
fitMap.find(par);
388 temp[k].push_back(t[i]);
389 double p = params[j].getImmutableValue<
double>();
395 message <<
"Negative parameter value for log interpolation based parameter ";
397 for ( ; fm != fm_end ; ++fm)
399 if ((*fm).second == k)
425 std::map<std::string, int>::iterator f;
429 if (temp[i].size() == 2)
431 fit[0][i] = val[i][0];
432 fit[1][i] = (val[i][1] - val[i][0])/(temp[i][1] - temp[i][0]);
435 else if (temp[i].size() == 3)
437 fit[0][i] = val[i][0];
439 x1 = temp[i][1] - temp[i][0];
441 x2 = temp[i][2] - temp[i][0];
443 fit[2][i] = (x2*y1-x1*y2-
fit[0][i]*(x2-x1))/(x2*x1*x1-x1*x2*x2);
444 fit[1][i] = (y1-
fit[2][i]*x1*x1-
fit[0][i])/x1;
448 DevelFatal0(*this).in(
"setModParams") <<
"Internal error in DeviceModel, illegal number of fit points for parameter " << (*f).first;
450 if ((*f).first ==
"TNOM")
459 std::map<double,int> tOrd;
460 for (
int i = 0; i < nT; ++i)
465 std::map<double,int>::iterator tOrd_i = tOrd.begin();
466 std::map<double,int>::iterator tOrd_end = tOrd.end();
467 for ( ; tOrd_i != tOrd_end; ++tOrd_i)
475 base.push_back((*tOrd_i).first);
477 (*tOrd_i).second = i++;
479 std::map<std::string, int>::iterator f;
480 std::map<std::string, int>::iterator f_end;
481 std::vector<bool> p(nT,
false);
484 for ( ; f!=f_end; ++f)
487 for (
int j = 0 ;j < nT; ++j)
491 for (
int j = 0; j < temp[i].size() ; ++j)
493 int ind = tOrd[temp[i][j]];
495 fit[ind][i] = val[i][j];
497 for (
int j = 0; j < nT ; ++j)
503 while (k_lo >= 0 && !p[k_lo])
507 while (k_hi <nT && !p[k_hi])
519 DevelFatal0(*this).in(
"DeviceModel::setModParams") <<
"DeviceModel::setModParams: Internal error forming PWL interpolation";
527 fit[j][i] =
fit[k_hi][i]*frac+
fit[k_lo][i]*(1-frac);
535 if ((*f).first ==
"TNOM")
546 std::vector<Param> remaining_params(¶ms[0], ¶ms[m_start[1] - 1]);
581 for (i=0 ; i<nFit ; ++i)
633 return (
fitMap.size() > 0);
647 int i, j, k_hi, k_lo;
660 std::map<std::string,int>::iterator fp;
661 std::map<std::string,int>::iterator fm_begin=
fitMap.begin();
662 std::map<std::string,int>::iterator fm_end=
fitMap.end();
663 for (fp=fm_begin; fp != fm_end; fp++)
666 p = (
fit[2][i]*del +
fit[1][i])*del +
fit[0][i];
672 else if (p <
min_par[i] && i>0)
686 for (j=0 ; j<
fit.size() ; ++j)
698 else if (k_hi ==
fit.size())
710 for (i=0 ; i<nFit ; ++i)
717 for (i=0 ; i<nFit ; ++i)
721 for (i=0 ; i<nFit ; ++i)
750 for (i=0 ; i<nFit ; ++i)