mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
netlist: refactor model code. (nw)
This commit is contained in:
parent
17ad7648ce
commit
deacff7ffa
@ -291,7 +291,6 @@ namespace analog
|
||||
|
||||
NETLIB_SUBXX(analog, C) m_CJE;
|
||||
NETLIB_SUBXX(analog, C) m_CJC;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -988,12 +988,9 @@ pstring param_t::get_initial(const device_t &dev, bool *found)
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
const pstring param_model_t::model_type()
|
||||
{
|
||||
if (m_map.size() == 0)
|
||||
state().setup().model_parse(this->Value(), m_map);
|
||||
return m_map["COREMODEL"];
|
||||
return state().setup().models().model_type(value());
|
||||
}
|
||||
|
||||
param_str_t::param_str_t(device_t &device, const pstring &name, const pstring &val)
|
||||
@ -1016,27 +1013,22 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring &name, uint8_t * val)
|
||||
void param_model_t::changed()
|
||||
{
|
||||
state().log().fatal(MF_1_MODEL_1_CAN_NOT_BE_CHANGED_AT_RUNTIME, name());
|
||||
m_map.clear();
|
||||
}
|
||||
|
||||
const pstring param_model_t::model_value_str(const pstring &entity)
|
||||
{
|
||||
if (m_map.size() == 0)
|
||||
state().setup().model_parse(this->Value(), m_map);
|
||||
return state().setup().model_value_str(m_map, entity);
|
||||
return state().setup().models().model_value_str(value(), entity);
|
||||
}
|
||||
|
||||
nl_double param_model_t::model_value(const pstring &entity)
|
||||
{
|
||||
if (m_map.size() == 0)
|
||||
state().setup().model_parse(this->Value(), m_map);
|
||||
return state().setup().model_value(m_map, entity);
|
||||
return state().setup().models().model_value(value(), entity);
|
||||
}
|
||||
|
||||
|
||||
plib::unique_ptr<plib::pistream> param_data_t::stream()
|
||||
{
|
||||
return device().setup().get_data_stream(Value());
|
||||
return device().setup().get_data_stream(value());
|
||||
}
|
||||
|
||||
bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
|
||||
|
@ -162,7 +162,7 @@ class NETLIB_NAME(name) : public device_t
|
||||
#define nl_assert(x) do { if (0) if (!(x)) { /*throw nl_exception(plib::pfmt("assert: {1}:{2}: {3}")(__FILE__)(__LINE__)(#x) ); */} } while (0)
|
||||
#define NL_NOEXCEPT noexcept
|
||||
#endif
|
||||
#define nl_assert_always(x, msg) do { if (!(x)) throw nl_exception(plib::pfmt("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}")(msg)(__FILE__)(__LINE__)(#x)); } while (0)
|
||||
#define nl_assert_always(x, msg) do { if (!(x)) throw nl_exception("Fatal error: {1}\nCaused by assert: {2}:{3}: {4}", msg, __FILE__, __LINE__, #x); } while (0)
|
||||
|
||||
//============================================================
|
||||
// Namespace starts
|
||||
@ -223,6 +223,12 @@ namespace netlist
|
||||
explicit nl_exception(const pstring &text //!< text to be passed
|
||||
)
|
||||
: plib::pexception(text) { }
|
||||
|
||||
template<typename... Args>
|
||||
explicit nl_exception(const pstring &fmt //!< format to be used
|
||||
, Args&&... args //!< arguments to be passed
|
||||
)
|
||||
: plib::pexception(plib::pfmt(fmt)(std::forward<Args>(args)...)) { }
|
||||
};
|
||||
|
||||
/*! Logic families descriptors are used to create proxy devices.
|
||||
@ -1004,7 +1010,7 @@ namespace netlist
|
||||
public:
|
||||
param_str_t(device_t &device, const pstring &name, const pstring &val);
|
||||
|
||||
const pstring &operator()() const NL_NOEXCEPT { return Value(); }
|
||||
const pstring &operator()() const NL_NOEXCEPT { return value(); }
|
||||
void setTo(const pstring ¶m) NL_NOEXCEPT
|
||||
{
|
||||
if (m_param != param)
|
||||
@ -1016,7 +1022,7 @@ namespace netlist
|
||||
}
|
||||
protected:
|
||||
virtual void changed();
|
||||
const pstring &Value() const NL_NOEXCEPT { return m_param; }
|
||||
const pstring &value() const NL_NOEXCEPT { return m_param; }
|
||||
private:
|
||||
pstring m_param;
|
||||
};
|
||||
@ -1055,7 +1061,6 @@ namespace netlist
|
||||
void changed() override;
|
||||
nl_double model_value(const pstring &entity) /*const*/;
|
||||
private:
|
||||
detail::model_map_t m_map;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1552,7 +1557,7 @@ namespace netlist
|
||||
if (f != nullptr)
|
||||
f->read(reinterpret_cast<plib::pistream::value_type *>(&m_data[0]),1<<AW);
|
||||
else
|
||||
device.state().log().warning("Rom {1} not found", Value());
|
||||
device.state().log().warning("Rom {1} not found", value());
|
||||
}
|
||||
|
||||
inline void logic_input_t::inactivate() NL_NOEXCEPT
|
||||
|
@ -32,17 +32,6 @@ namespace netlist
|
||||
, m_frontier_cnt(0)
|
||||
{ }
|
||||
|
||||
void nlparse_t::register_model(const pstring &model_in)
|
||||
{
|
||||
auto pos = model_in.find(" ");
|
||||
if (pos == pstring::npos)
|
||||
log().fatal(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
|
||||
pstring model = plib::ucase(plib::trim(plib::left(model_in, pos)));
|
||||
pstring def = plib::trim(model_in.substr(pos + 1));
|
||||
if (!m_models.insert({model, def}).second)
|
||||
log().fatal(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
|
||||
}
|
||||
|
||||
void nlparse_t::register_alias(const pstring &alias, const pstring &out)
|
||||
{
|
||||
pstring alias_fqn = build_fqn(alias);
|
||||
@ -818,19 +807,21 @@ const log_type &setup_t::log() const
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// Model
|
||||
// Models
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
static pstring model_string(detail::model_map_t &map)
|
||||
void models_t::register_model(pstring model_in)
|
||||
{
|
||||
pstring ret = map["COREMODEL"] + "(";
|
||||
for (auto & i : map)
|
||||
ret = ret + i.first + "=" + i.second + " ";
|
||||
|
||||
return ret + ")";
|
||||
auto pos = model_in.find(" ");
|
||||
if (pos == pstring::npos)
|
||||
throw nl_exception(MF_1_UNABLE_TO_PARSE_MODEL_1, model_in);
|
||||
pstring model = plib::ucase(plib::trim(plib::left(model_in, pos)));
|
||||
pstring def = plib::trim(model_in.substr(pos + 1));
|
||||
if (!m_models.insert({model, def}).second)
|
||||
throw nl_exception(MF_1_MODEL_ALREADY_EXISTS_1, model_in);
|
||||
}
|
||||
|
||||
void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
|
||||
void models_t::model_parse(const pstring &model_in, model_map_t &map)
|
||||
{
|
||||
pstring model = model_in;
|
||||
std::size_t pos = 0;
|
||||
@ -844,7 +835,7 @@ void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
|
||||
key = plib::ucase(model);
|
||||
auto i = m_models.find(key);
|
||||
if (i == m_models.end())
|
||||
log().fatal(MF_1_MODEL_NOT_FOUND, model);
|
||||
throw nl_exception(MF_1_MODEL_NOT_FOUND, model);
|
||||
model = i->second;
|
||||
}
|
||||
pstring xmodel = plib::left(model, pos);
|
||||
@ -857,12 +848,12 @@ void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
|
||||
if (i != m_models.end())
|
||||
model_parse(xmodel, map);
|
||||
else
|
||||
log().fatal(MF_1_MODEL_NOT_FOUND, model_in);
|
||||
throw nl_exception(MF_1_MODEL_NOT_FOUND, model_in);
|
||||
}
|
||||
|
||||
pstring remainder = plib::trim(model.substr(pos + 1));
|
||||
if (!plib::endsWith(remainder, ")"))
|
||||
log().fatal(MF_1_MODEL_ERROR_1, model);
|
||||
throw nl_exception(MF_1_MODEL_ERROR_1, model);
|
||||
// FIMXE: Not optimal
|
||||
remainder = plib::left(remainder, remainder.size() - 1);
|
||||
|
||||
@ -871,29 +862,48 @@ void setup_t::model_parse(const pstring &model_in, detail::model_map_t &map)
|
||||
{
|
||||
auto pose = pe.find("=");
|
||||
if (pose == pstring::npos)
|
||||
log().fatal(MF_1_MODEL_ERROR_ON_PAIR_1, model);
|
||||
throw nl_exception(MF_1_MODEL_ERROR_ON_PAIR_1, model);
|
||||
map[plib::ucase(plib::left(pe, pose))] = pe.substr(pose + 1);
|
||||
}
|
||||
}
|
||||
|
||||
const pstring setup_t::model_value_str(detail::model_map_t &map, const pstring &entity)
|
||||
pstring models_t::model_string(model_map_t &map)
|
||||
{
|
||||
pstring ret = map["COREMODEL"] + "(";
|
||||
for (auto & i : map)
|
||||
ret = ret + i.first + "=" + i.second + " ";
|
||||
|
||||
return ret + ")";
|
||||
}
|
||||
|
||||
pstring models_t::model_value_str(pstring model, pstring entity)
|
||||
{
|
||||
model_map_t &map = m_cache[model];
|
||||
|
||||
if (map.size() == 0)
|
||||
model_parse(model , map);
|
||||
|
||||
pstring ret;
|
||||
|
||||
if (entity != plib::ucase(entity))
|
||||
log().fatal(MF_2_MODEL_PARAMETERS_NOT_UPPERCASE_1_2, entity,
|
||||
throw nl_exception(MF_2_MODEL_PARAMETERS_NOT_UPPERCASE_1_2, entity,
|
||||
model_string(map));
|
||||
if (map.find(entity) == map.end())
|
||||
log().fatal(MF_2_ENTITY_1_NOT_FOUND_IN_MODEL_2, entity, model_string(map));
|
||||
throw nl_exception(MF_2_ENTITY_1_NOT_FOUND_IN_MODEL_2, entity, model_string(map));
|
||||
else
|
||||
ret = map[entity];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
|
||||
nl_double models_t::model_value(pstring model, pstring entity)
|
||||
{
|
||||
pstring tmp = model_value_str(map, entity);
|
||||
model_map_t &map = m_cache[model];
|
||||
|
||||
if (map.size() == 0)
|
||||
model_parse(model , map);
|
||||
|
||||
pstring tmp = model_value_str(model, entity);
|
||||
|
||||
nl_double factor = plib::constants<nl_double>::one();
|
||||
auto p = std::next(tmp.begin(), static_cast<pstring::difference_type>(tmp.size() - 1));
|
||||
@ -909,7 +919,7 @@ nl_double setup_t::model_value(detail::model_map_t &map, const pstring &entity)
|
||||
case 'a': factor = 1e-18; break;
|
||||
default:
|
||||
if (*p < '0' || *p > '9')
|
||||
log().fatal(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity);
|
||||
throw nl_exception(MF_1_UNKNOWN_NUMBER_FACTOR_IN_1, entity);
|
||||
}
|
||||
if (factor != plib::constants<nl_double>::one())
|
||||
tmp = plib::left(tmp, tmp.size() - 1);
|
||||
@ -940,12 +950,10 @@ pool_owned_ptr<devices::nld_base_a_to_d_proxy> logic_family_std_proxy_t::create_
|
||||
|
||||
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
{
|
||||
detail::model_map_t map;
|
||||
model_parse(model, map);
|
||||
|
||||
if (model_value_str(map, "TYPE") == "TTL")
|
||||
if (m_models.model_value_str(model, "TYPE") == "TTL")
|
||||
return family_TTL();
|
||||
if (model_value_str(map, "TYPE") == "CD4XXX")
|
||||
if (m_models.model_value_str(model, "TYPE") == "CD4XXX")
|
||||
return family_CD4XXX();
|
||||
|
||||
for (auto & e : m_nlstate.m_family_cache)
|
||||
@ -954,13 +962,13 @@ const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
|
||||
|
||||
auto ret = plib::make_unique<logic_family_std_proxy_t>();
|
||||
|
||||
ret->m_fixed_V = model_value(map, "FV");
|
||||
ret->m_low_thresh_PCNT = model_value(map, "IVL");
|
||||
ret->m_high_thresh_PCNT = model_value(map, "IVH");
|
||||
ret->m_low_VO = model_value(map, "OVL");
|
||||
ret->m_high_VO = model_value(map, "OVH");
|
||||
ret->m_R_low = model_value(map, "ORL");
|
||||
ret->m_R_high = model_value(map, "ORH");
|
||||
ret->m_fixed_V = m_models.model_value(model, "FV");
|
||||
ret->m_low_thresh_PCNT = m_models.model_value(model, "IVL");
|
||||
ret->m_high_thresh_PCNT = m_models.model_value(model, "IVH");
|
||||
ret->m_low_VO = m_models.model_value(model, "OVL");
|
||||
ret->m_high_VO = m_models. model_value(model, "OVH");
|
||||
ret->m_R_low = m_models.model_value(model, "ORL");
|
||||
ret->m_R_high = m_models.model_value(model, "ORH");
|
||||
|
||||
auto retp = ret.get();
|
||||
|
||||
|
@ -202,8 +202,35 @@ namespace netlist
|
||||
const type_t m_type;
|
||||
};
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// setup_t
|
||||
// Collection of models
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class models_t
|
||||
{
|
||||
public:
|
||||
void register_model(pstring model_in);
|
||||
/* model / family related */
|
||||
|
||||
pstring model_value_str(pstring model, pstring entity);
|
||||
|
||||
double model_value(pstring model, pstring entity);
|
||||
|
||||
pstring model_type(pstring model) { return model_value_str(model, "COREMODEL"); }
|
||||
|
||||
private:
|
||||
using model_map_t = std::unordered_map<pstring, pstring>;
|
||||
|
||||
void model_parse(const pstring &model, model_map_t &map);
|
||||
pstring model_string(model_map_t &map);
|
||||
|
||||
std::unordered_map<pstring, pstring> m_models;
|
||||
std::unordered_map<pstring, model_map_t> m_cache;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// nlparse_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class nlparse_t
|
||||
@ -213,7 +240,7 @@ namespace netlist
|
||||
|
||||
nlparse_t(setup_t &netlist, log_type &log);
|
||||
|
||||
void register_model(const pstring &model_in);
|
||||
void register_model(const pstring &model_in) { m_models.register_model(model_in); }
|
||||
void register_alias(const pstring &alias, const pstring &out);
|
||||
void register_dippins_arr(const pstring &terms);
|
||||
void register_dev(const pstring &classname, const pstring &name);
|
||||
@ -240,7 +267,6 @@ namespace netlist
|
||||
/* include other files */
|
||||
|
||||
void include(const pstring &netlist_name);
|
||||
/* parse a source */
|
||||
|
||||
pstring build_fqn(const pstring &obj_name) const;
|
||||
void register_alias_nofqn(const pstring &alias, const pstring &out);
|
||||
@ -276,8 +302,12 @@ namespace netlist
|
||||
*/
|
||||
setup_t &setup() { return m_setup; }
|
||||
const setup_t &setup() const { return m_setup; }
|
||||
|
||||
models_t &models() { return m_models; }
|
||||
const models_t &models() const { return m_models; }
|
||||
|
||||
protected:
|
||||
std::unordered_map<pstring, pstring> m_models;
|
||||
models_t m_models;
|
||||
std::stack<pstring> m_namespace_stack;
|
||||
std::unordered_map<pstring, pstring> m_alias;
|
||||
std::vector<link_t> m_links;
|
||||
@ -299,6 +329,10 @@ namespace netlist
|
||||
unsigned m_frontier_cnt;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// setup_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
class setup_t : public nlparse_t
|
||||
{
|
||||
public:
|
||||
@ -323,24 +357,17 @@ namespace netlist
|
||||
|
||||
param_t *find_param(const pstring ¶m_in, bool required = true) const;
|
||||
|
||||
/* get family */
|
||||
const logic_family_desc_t *family_from_model(const pstring &model);
|
||||
|
||||
void register_dynamic_log_devices();
|
||||
void resolve_inputs();
|
||||
|
||||
plib::unique_ptr<plib::pistream> get_data_stream(const pstring &name);
|
||||
|
||||
|
||||
factory::list_t &factory() { return m_factory; }
|
||||
const factory::list_t &factory() const { return m_factory; }
|
||||
|
||||
/* model / family related */
|
||||
|
||||
const pstring model_value_str(detail::model_map_t &map, const pstring &entity);
|
||||
double model_value(detail::model_map_t &map, const pstring &entity);
|
||||
|
||||
void model_parse(const pstring &model, detail::model_map_t &map);
|
||||
|
||||
const logic_family_desc_t *family_from_model(const pstring &model);
|
||||
|
||||
/* helper - also used by nltool */
|
||||
const pstring resolve_alias(const pstring &name) const;
|
||||
|
||||
|
@ -108,11 +108,6 @@ namespace netlist
|
||||
OUTPUT = 2, /*!< object is an output */
|
||||
};
|
||||
|
||||
/*! Type of the model map used.
|
||||
* This is used to hold all #Models in an unordered map
|
||||
*/
|
||||
using model_map_t = std::unordered_map<pstring, pstring>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if (PHAS_INT128)
|
||||
|
@ -191,6 +191,12 @@ public:
|
||||
return format_element(ptype_traits<T *>::size_spec(), ptype_traits<T *>::fmt_spec(), ptype_traits<T *>::cast(x));
|
||||
}
|
||||
|
||||
template<typename X, typename Y, typename... Args>
|
||||
pfmt &operator()(X&& x, Y && y, Args&&... args)
|
||||
{
|
||||
return ((*this)(std::forward<X>(x)))(std::forward<Y>(y), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
pfmt &x(const T &x)
|
||||
{
|
||||
|
@ -181,9 +181,11 @@ CIRCUIT_LAYOUT( breakout )
|
||||
DIODE(CR5, "1N914")
|
||||
DIODE(CR7, "1N914")
|
||||
|
||||
QBJT_EB(Q1, "2N3644")
|
||||
QBJT_EB(Q2, "2N3643")
|
||||
QBJT_EB(Q3, "2N3643")
|
||||
// No need to model capacitance
|
||||
QBJT_EB(Q1, "2N3644(CJC=0 CJE=0)")
|
||||
QBJT_EB(Q2, "2N3643(CJC=0 CJE=0)")
|
||||
QBJT_EB(Q3, "2N3643(CJC=0 CJE=0)")
|
||||
|
||||
CAP(C19, CAP_U(0.1))
|
||||
CAP(C16, CAP_U(0.1))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user