46 #include <Xyce_config.h>
50 #if defined(HAVE_UNORDERED_MAP)
51 #include <unordered_map>
52 using std::unordered_map;
53 #elif defined(HAVE_TR1_UNORDERED_MAP)
54 #include <tr1/unordered_map>
55 using std::tr1::unordered_map;
57 #error neither unordered_map or tr1/unordered_map found
69 #include <N_ERH_ErrorMgr.h>
86 :
DeviceEntity(parametric_data, factory_block.solverState_, factory_block.deviceOptions_, model_block.getNetlistLocation().getFilename(), model_block.getNetlistLocation().getLineNumber()),
88 type_(model_block.getType()),
89 level_(model_block.getLevel()),
100 return os <<
"model " <<
name_;
114 std::vector<int> m_start;
115 std::set<std::string> pname;
116 unordered_map<std::string, int> ptype;
119 m_start.push_back(param_index);
120 for (std::vector<Param>::const_iterator mp = params.begin(); mp != params.end(); ++mp)
123 if ((*mp).tag() ==
"INDEPENDENT;PARAM")
125 m_start.push_back(param_index);
130 if (pname.find((*mp).tag()) != pname.end())
132 UserError0(*
this) <<
"Duplicate specification of parameter " << (*mp).tag();
135 pname.insert((*mp).tag());
136 if (m_start.size() == 1)
138 ptype[(*mp).tag()] = (*mp).getType();
142 if (m_start.size() == 1)
148 m_start.push_back(param_index + 1);
152 std::string tmod(
"");
153 std::string dmod(
"");
154 std::string modName(
"");
156 for (
int i = 0; i < m_start.size()-1; ++i)
158 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
160 if (params[j].tag() ==
"TEMPMODEL" && params[j].stringValue() !=
"NONE")
164 tmod = params[j].stringValue();
168 if (tmod != params[j].stringValue())
170 UserError0(*
this) <<
"Inconsistent or missing TEMPMODEL parameter, " << params[j].stringValue() <<
" specified here, " << tmod <<
" specified perviously";
175 if (params[j].tag() ==
"DOSEMODEL" && params[j].stringValue() !=
"NONE")
179 dmod = params[j].stringValue();
183 if (dmod != params[j].stringValue())
185 UserError0(*
this) <<
"Inconsistent or missing DOSEMODEL parameter, " << params[j].stringValue() <<
" specified here, " << dmod <<
" specified perviously";
193 if (tmod ==
"" && dmod ==
"")
195 UserError0(*
this) <<
"Duplicate model specification implies parameter interpolation, TEMPMODEL or DOSEMODEL parameters must specified";
198 else if (tmod !=
"" && dmod !=
"")
200 UserError0(*
this) <<
"Only one of TEMPMODEL or DOSEMODEL parameters may be specified";
214 if (modName ==
"QUADRATIC")
217 if (m_start.size() != 4)
219 UserError0(*
this) <<
"Three model specifications required for QUADRATIC fit";
224 else if (modName ==
"PWL")
227 fit.resize(m_start.size() - 1);
231 UserError0(*
this) <<
"Only QUADRATIC or PWL interpolation method is supported";
236 unordered_map<std::string,double> basePars;
237 std::vector<double> t;
240 for (
int i = 0 ;i < m_start.size()-1; ++i)
242 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
244 par = params[j].tag();
247 DevelFatal0(*this).in(
"DeviceModel::setModParams") <<
"Parameter " << par <<
" not found";
256 t.push_back(params[j].getImmutableValue<double>());
263 t.push_back(params[j].getImmutableValue<double>());
268 if (params[j].
getType() != Util::EXPR)
270 basePars[par] = params[j].getImmutableValue<
double>();
275 if (ptype[par] == Util::EXPR)
277 UserWarning0(*
this) <<
"Non-constant expression for parameter " << par <<
", it will not interpolated";
281 if (basePars.find(par) == basePars.end())
283 UserError0(*
this) <<
"Unknown parameter " << params[j].tag() <<
" in temperature compensation .MODEL statement";
286 if (basePars[par] != params[j].getImmutableValue<double>() && params[j].
given())
292 fit[0].push_back(basePars[par]);
301 if (t.size() != m_start.size()-1)
303 UserError0(*
this) << (
iModel ==
TEMP ?
"TNOM" :
"DOSE") <<
" not specified in all .MODEL statements";
307 for (
int i = 1; i < t.size(); ++i)
309 for (
int j = 0; j < i; ++j)
313 UserError0(*
this) <<
"Identical " << (
iModel ==
TEMP ?
"TNOM" :
"DOSE") <<
" values in .MODEL statements";
322 std::vector<std::vector<double> > temp(nFit);
323 std::vector<std::vector<double> > val(nFit);
326 for (
int i = 1; i <
fit.size(); ++i)
333 std::map<std::string, int>::iterator fm =
fitMap.begin();
334 std::map<std::string, int>::iterator fm_end =
fitMap.end();
336 for ( ; fm != fm_end ; ++fm)
341 throw std::runtime_error(std::string(
"Parameter ") + par +
" not found");
362 for (
int i = 0; i < nFit; ++i)
364 temp[i].push_back(t[0]);
365 val[i].push_back(
fit[0][i]);
371 message <<
"Negative parameter value for log interpolation based parameter ";
373 for ( ; fm != fm_end ; ++fm)
375 if ((*fm).second == i)
384 val[i][0] = log(val[i][0]);
390 for (
int i = 1; i < m_start.size()-1; ++i)
392 for (
int j = m_start[i]; j < m_start[i+1]-1; ++j)
394 if (params[j].
getType() == Util::DBLE && params[j].given())
396 par = params[j].tag();
397 std::map<std::string, int>::iterator fm1 =
fitMap.find(par);
401 temp[k].push_back(t[i]);
402 double p = params[j].getImmutableValue<
double>();
408 message <<
"Negative parameter value for log interpolation based parameter ";
410 for ( ; fm != fm_end ; ++fm)
412 if ((*fm).second == k)
438 std::map<std::string, int>::iterator f;
442 if (temp[i].size() == 2)
444 fit[0][i] = val[i][0];
445 fit[1][i] = (val[i][1] - val[i][0])/(temp[i][1] - temp[i][0]);
448 else if (temp[i].size() == 3)
450 fit[0][i] = val[i][0];
452 x1 = temp[i][1] - temp[i][0];
454 x2 = temp[i][2] - temp[i][0];
456 fit[2][i] = (x2*y1-x1*y2-
fit[0][i]*(x2-x1))/(x2*x1*x1-x1*x2*x2);
457 fit[1][i] = (y1-
fit[2][i]*x1*x1-
fit[0][i])/x1;
461 DevelFatal0(*this).in(
"setModParams") <<
"Internal error in DeviceModel, illegal number of fit points for parameter " << (*f).first;
463 if ((*f).first ==
"TNOM")
472 std::map<double,int> tOrd;
473 for (
int i = 0; i < nT; ++i)
478 std::map<double,int>::iterator tOrd_i = tOrd.begin();
479 std::map<double,int>::iterator tOrd_end = tOrd.end();
480 for ( ; tOrd_i != tOrd_end; ++tOrd_i)
488 base.push_back((*tOrd_i).first);
490 (*tOrd_i).second = i++;
492 std::map<std::string, int>::iterator f;
493 std::map<std::string, int>::iterator f_end;
494 std::vector<bool> p(nT,
false);
497 for ( ; f!=f_end; ++f)
500 for (
int j = 0 ;j < nT; ++j)
504 for (
int j = 0; j < temp[i].size() ; ++j)
506 int ind = tOrd[temp[i][j]];
508 fit[ind][i] = val[i][j];
510 for (
int j = 0; j < nT ; ++j)
516 while (k_lo >= 0 && !p[k_lo])
520 while (k_hi <nT && !p[k_hi])
532 DevelFatal0(*this).in(
"DeviceModel::setModParams") <<
"DeviceModel::setModParams: Internal error forming PWL interpolation";
540 fit[j][i] =
fit[k_hi][i]*frac+
fit[k_lo][i]*(1-frac);
548 if ((*f).first ==
"TNOM")
559 std::vector<Param> remaining_params(¶ms[0], ¶ms[m_start[1] - 1]);
594 for (i=0 ; i<nFit ; ++i)
646 return (
fitMap.size() > 0);
660 int i, j, k_hi, k_lo;
673 std::map<std::string,int>::iterator fp;
674 std::map<std::string,int>::iterator fm_begin=
fitMap.begin();
675 std::map<std::string,int>::iterator fm_end=
fitMap.end();
676 for (fp=fm_begin; fp != fm_end; fp++)
679 p = (
fit[2][i]*del +
fit[1][i])*del +
fit[0][i];
685 else if (p <
min_par[i] && i>0)
699 for (j=0 ; j<
fit.size() ; ++j)
711 else if (k_hi ==
fit.size())
723 for (i=0 ; i<nFit ; ++i)
730 for (i=0 ; i<nFit ; ++i)
734 for (i=0 ; i<nFit ; ++i)
763 for (i=0 ; i<nFit ; ++i)
std::vector< double > oldParams
std::vector< double > max_par
bool given(const std::string ¶meter_name) const
Pure virtual class to augment a linear system.
std::vector< std::vector< double > > fit
const std::string & getName(const C *c)
Returns the name of the specified object.
void setParams(const std::vector< Param > ¶ms)
const ParameterMap & getParameterMap() const
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
std::vector< double > base
bool interpolateDOSE(double)
Class ParametricData manages the configuration information and the parameter binding map...
ExprAccess getExpressionAccess() const
Gets the expression access which describes the usage of the paramter.
Parameter uses temperature interpolation based on log of value.
Class Descriptor describes the parameters stored in the ParametricData parameter map.
std::vector< fitType > parType
bool interpolateTNOM(double)
virtual std::ostream & printName(std::ostream &os) const
const std::string & getType() const
bool isType() const
Tests entry data type.
std::vector< double > min_par
ModelBlock represents a .MODEL line from the netlist.
T ParameterBase::* getMemberPtr() const
Returns the parameter member variable pointer of the enrtry.
std::map< std::string, int > fitMap
std::vector< double DeviceEntity::* > fitParams
void setModParams(const std::vector< Param > ¶ms)