mirror of
https://github.com/holub/mame
synced 2025-07-06 18:39:28 +03:00
netlist: Parameters evaluated when netlist is created. [Couriersud]
Parameters are now passed to the netlist core as strings. During netlist creation they are evaluated as functions. This opens the path to parameters on subdevice level. Examples: PARAM(device.XY, (1+2*0.005)) RES(R1, 2.05*RES_K(1)+1) In addition the commit contains dead code removal.
This commit is contained in:
parent
d7fd89afe1
commit
fceee50c8b
@ -991,9 +991,9 @@ void netlist_mame_stream_input_device::custom_netlist_additions(netlist::netlist
|
||||
pstring sparam = plib::pfmt("STREAM_INPUT.CHAN{1}")(m_channel);
|
||||
nlstate.setup().register_param(sparam, pstring(m_param_name));
|
||||
sparam = plib::pfmt("STREAM_INPUT.MULT{1}")(m_channel);
|
||||
nlstate.setup().register_param(sparam, m_mult);
|
||||
nlstate.setup().register_param_val(sparam, m_mult);
|
||||
sparam = plib::pfmt("STREAM_INPUT.OFFSET{1}")(m_channel);
|
||||
nlstate.setup().register_param(sparam, m_offset);
|
||||
nlstate.setup().register_param_val(sparam, m_offset);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -1027,9 +1027,9 @@ void netlist_mame_stream_output_device::custom_netlist_additions(netlist::netlis
|
||||
//snd_out = dynamic_cast<NETLIB_NAME(sound_out) *>(setup.register_dev("nld_sound_out", sname));
|
||||
nlstate.setup().register_dev("NETDEV_SOUND_OUT", sname);
|
||||
|
||||
nlstate.setup().register_param(sname + ".CHAN" , m_channel);
|
||||
nlstate.setup().register_param(sname + ".MULT", m_mult);
|
||||
nlstate.setup().register_param(sname + ".OFFSET", m_offset);
|
||||
nlstate.setup().register_param_val(sname + ".CHAN" , m_channel);
|
||||
nlstate.setup().register_param_val(sname + ".MULT", m_mult);
|
||||
nlstate.setup().register_param_val(sname + ".OFFSET", m_offset);
|
||||
nlstate.setup().register_link(sname + ".IN", pstring(m_out_name));
|
||||
}
|
||||
|
||||
|
@ -138,11 +138,9 @@ namespace analog
|
||||
, m_Vmin(nlconst::zero()) // not used in MOS model
|
||||
, m_Is(nlconst::zero())
|
||||
, m_logIs(nlconst::zero())
|
||||
, m_n(nlconst::zero())
|
||||
, m_gmin(nlconst::magic(1e-15))
|
||||
, m_VtInv(nlconst::zero())
|
||||
, m_Vcrit(nlconst::zero())
|
||||
, m_name(name)
|
||||
{
|
||||
set_param(
|
||||
nlconst::magic(1e-15)
|
||||
@ -205,10 +203,9 @@ namespace analog
|
||||
{
|
||||
m_Is = Is;
|
||||
m_logIs = plib::log(Is);
|
||||
m_n = n;
|
||||
m_gmin = gmin;
|
||||
|
||||
m_Vt = m_n * temp * nlconst::k_b() / nlconst::Q_e();
|
||||
m_Vt = n * temp * nlconst::k_b() / nlconst::Q_e();
|
||||
|
||||
m_Vmin = nlconst::magic(-5.0) * m_Vt;
|
||||
|
||||
@ -234,13 +231,10 @@ namespace analog
|
||||
nl_fptype m_Vmin;
|
||||
nl_fptype m_Is;
|
||||
nl_fptype m_logIs;
|
||||
nl_fptype m_n;
|
||||
nl_fptype m_gmin;
|
||||
|
||||
nl_fptype m_VtInv;
|
||||
nl_fptype m_Vcrit;
|
||||
|
||||
pstring m_name;
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,8 +43,7 @@
|
||||
#else
|
||||
|
||||
#define SOLVER(name, freq) \
|
||||
NET_REGISTER_DEV(SOLVER, name) \
|
||||
PARAM(name.FREQ, freq)
|
||||
NET_REGISTER_DEVEXT(SOLVER, name, freq)
|
||||
|
||||
#include "nld_system.h"
|
||||
|
||||
|
@ -215,7 +215,6 @@ namespace netlist
|
||||
|
||||
// Add default include file
|
||||
using a = plib::psource_str_t<plib::psource_t>;
|
||||
#if USE_EVAL
|
||||
const pstring content =
|
||||
"#define RES_R(res) (res) \n"
|
||||
"#define RES_K(res) ((res) * 1e3) \n"
|
||||
@ -227,9 +226,6 @@ namespace netlist
|
||||
"#define IND_N(ind) ((ind) * 1e-9) \n"
|
||||
"#define IND_P(ind) ((ind) * 1e-12) \n";
|
||||
setup().add_include(plib::make_unique<a>("netlist/devices/net_lib.h", content));
|
||||
#else
|
||||
setup().add_include(plib::make_unique<a>("netlist/devices/net_lib.h",""));
|
||||
#endif
|
||||
NETLIST_NAME(base)(*m_setup);
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,6 @@
|
||||
#include "plib/pconfig.h"
|
||||
#include "plib/pexception.h"
|
||||
|
||||
// FIXME: Remove this again after testing
|
||||
#define USE_EVAL (0)
|
||||
|
||||
///
|
||||
/// \brief Version - Major.
|
||||
///
|
||||
@ -20,7 +17,7 @@
|
||||
///
|
||||
/// \brief Version - Minor.
|
||||
///
|
||||
#define NL_VERSION_MINOR 10
|
||||
#define NL_VERSION_MINOR 11
|
||||
/// \brief Version - Patch level.
|
||||
///
|
||||
#define NL_VERSION_PATCHLEVEL 0
|
||||
|
@ -237,10 +237,10 @@ void parser_t::frontier()
|
||||
pstring attachat = get_identifier();
|
||||
require_token(m_tok_comma);
|
||||
auto tok = get_token();
|
||||
nl_fptype r_IN = eval_param(tok);
|
||||
auto r_IN = stringify_expression(tok);
|
||||
require_token(tok, m_tok_comma);
|
||||
tok = get_token();
|
||||
nl_fptype r_OUT = eval_param(tok);
|
||||
auto r_OUT = stringify_expression(tok);
|
||||
require_token(tok, m_tok_paren_right);
|
||||
|
||||
m_setup.register_frontier(attachat, r_IN, r_OUT);
|
||||
@ -341,7 +341,7 @@ void parser_t::netdev_param()
|
||||
}
|
||||
else
|
||||
{
|
||||
nl_fptype val = eval_param(tok);
|
||||
auto val = stringify_expression(tok);
|
||||
m_setup.log().debug("Parser: Param: {1} {2}\n", param, val);
|
||||
m_setup.register_param(param, val);
|
||||
require_token(tok, m_tok_paren_right);
|
||||
@ -354,7 +354,7 @@ void parser_t::netdev_hint()
|
||||
pstring dev(get_identifier());
|
||||
require_token(m_tok_comma);
|
||||
pstring hint(get_identifier());
|
||||
m_setup.register_param(dev + ".HINT_" + hint, 1);
|
||||
m_setup.register_param_val(dev + ".HINT_" + hint, 1);
|
||||
require_token(m_tok_paren_right);
|
||||
}
|
||||
|
||||
@ -379,13 +379,8 @@ void parser_t::device(const pstring &dev_type)
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Do we really need this?
|
||||
nl_fptype value = eval_param(tok);
|
||||
if (plib::abs(value - plib::floor(value)) > nlconst::magic(1e-30)
|
||||
|| plib::abs(value) > nlconst::magic(1e9))
|
||||
params.push_back(plib::pfmt("{1:.9}").e(value));
|
||||
else
|
||||
params.push_back(plib::pfmt("{1}")(static_cast<long>(value)));
|
||||
auto value = stringify_expression(tok);
|
||||
params.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,9 +393,8 @@ void parser_t::device(const pstring &dev_type)
|
||||
// private
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
nl_fptype parser_t::eval_param(token_t &tok)
|
||||
pstring parser_t::stringify_expression(token_t &tok)
|
||||
{
|
||||
#if USE_EVAL
|
||||
int pc(0);
|
||||
pstring ret;
|
||||
while (!tok.is(m_tok_comma))
|
||||
@ -416,45 +410,7 @@ nl_fptype parser_t::eval_param(token_t &tok)
|
||||
ret += tok.str();
|
||||
tok = get_token();
|
||||
}
|
||||
// FIXME: Not necessary here, should be done if parameter is read by devices
|
||||
plib::pfunction<nl_fptype> func;
|
||||
func.compile_infix(ret, {});
|
||||
return func.evaluate();
|
||||
|
||||
#else
|
||||
static std::array<pstring, 7> macs = {"", "RES_R", "RES_K", "RES_M", "CAP_U", "CAP_N", "CAP_P"};
|
||||
|
||||
static std::array<nl_fptype, 7> facs = {
|
||||
nlconst::magic(1.0),
|
||||
nlconst::magic(1.0),
|
||||
nlconst::magic(1e3),
|
||||
nlconst::magic(1e6),
|
||||
nlconst::magic(1e-6),
|
||||
nlconst::magic(1e-9),
|
||||
nlconst::magic(1e-12)
|
||||
};
|
||||
std::size_t f=0;
|
||||
nl_fptype ret(0);
|
||||
|
||||
for (std::size_t i=1; i<macs.size();i++)
|
||||
if (tok.str() == macs[i])
|
||||
f = i;
|
||||
if (f>0)
|
||||
{
|
||||
require_token(m_tok_paren_left);
|
||||
ret = static_cast<nl_fptype>(get_number_double());
|
||||
require_token(m_tok_paren_right);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool err(false);
|
||||
ret = plib::pstonum_ne<nl_fptype>(tok.str(), err);
|
||||
if (err)
|
||||
error(MF_PARAM_NOT_FP_1(tok.str()));
|
||||
}
|
||||
tok = get_token();
|
||||
return ret * facs[f];
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace netlist
|
||||
|
@ -43,9 +43,7 @@ namespace netlist
|
||||
|
||||
void verror(const pstring &msg) override;
|
||||
private:
|
||||
|
||||
nl_fptype eval_param(token_t &tok);
|
||||
|
||||
pstring stringify_expression(token_t &tok);
|
||||
token_id_t m_tok_paren_left;
|
||||
token_id_t m_tok_paren_right;
|
||||
token_id_t m_tok_comma;
|
||||
|
@ -121,11 +121,9 @@ namespace netlist
|
||||
pstring paramfq = name + "." + tp;
|
||||
|
||||
log().debug("Defparam: {1}\n", paramfq);
|
||||
// remove quotes
|
||||
if (plib::startsWith(*ptok, "\"") && plib::endsWith(*ptok, "\""))
|
||||
register_param(paramfq, ptok->substr(1, ptok->length() - 2));
|
||||
else
|
||||
register_param(paramfq, *ptok);
|
||||
|
||||
register_param(paramfq, *ptok);
|
||||
|
||||
++ptok;
|
||||
}
|
||||
}
|
||||
@ -216,11 +214,16 @@ namespace netlist
|
||||
void nlparse_t::register_param(const pstring ¶m, const pstring &value)
|
||||
{
|
||||
pstring fqn = build_fqn(param);
|
||||
pstring val(value);
|
||||
|
||||
// strip " from stringified strings
|
||||
if (plib::startsWith(value, "\"") && plib::endsWith(value, "\""))
|
||||
val = value.substr(1, value.length() - 2);
|
||||
|
||||
auto idx = m_param_values.find(fqn);
|
||||
if (idx == m_param_values.end())
|
||||
{
|
||||
if (!m_param_values.insert({fqn, value}).second)
|
||||
if (!m_param_values.insert({fqn, val}).second)
|
||||
{
|
||||
log().fatal(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param));
|
||||
throw nl_exception(MF_ADDING_PARAMETER_1_TO_PARAMETER_LIST(param));
|
||||
@ -229,8 +232,8 @@ namespace netlist
|
||||
else
|
||||
{
|
||||
log().warning(MW_OVERWRITING_PARAM_1_OLD_2_NEW_3(fqn, idx->second,
|
||||
value));
|
||||
m_param_values[fqn] = value;
|
||||
val));
|
||||
m_param_values[fqn] = val;
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +242,7 @@ namespace netlist
|
||||
m_factory.register_device(plib::make_unique<factory::library_element_t>(name, name, "", sourcefile));
|
||||
}
|
||||
|
||||
void nlparse_t::register_frontier(const pstring &attach, const nl_fptype r_IN, const nl_fptype r_OUT)
|
||||
void nlparse_t::register_frontier(const pstring &attach, const pstring &r_IN, const pstring &r_OUT)
|
||||
{
|
||||
pstring frontier_name = plib::pfmt("frontier_{1}")(m_frontier_cnt);
|
||||
m_frontier_cnt++;
|
||||
|
@ -53,10 +53,10 @@
|
||||
setup.register_link_arr( # term1 ", " # __VA_ARGS__);
|
||||
|
||||
#define PARAM(name, val) \
|
||||
setup.register_param(# name, val);
|
||||
setup.register_param(# name, # val);
|
||||
|
||||
#define HINT(name, val) \
|
||||
setup.register_param(# name ".HINT_" # val, 1);
|
||||
setup.register_param(# name ".HINT_" # val, "1");
|
||||
|
||||
#define NETDEV_PARAMI(name, param, val) \
|
||||
setup.register_param(# name "." # param, val);
|
||||
@ -88,7 +88,7 @@ void NETLIST_NAME(name)(netlist::nlparse_t &setup) \
|
||||
setup.namespace_pop();
|
||||
|
||||
#define OPTIMIZE_FRONTIER(attach, r_in, r_out) \
|
||||
setup.register_frontier(# attach, r_in, r_out);
|
||||
setup.register_frontier(# attach, PSTRINGIFY_VA(r_in), PSTRINGIFY_VA(r_out));
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// truthtable defines
|
||||
@ -261,7 +261,7 @@ namespace netlist
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value || std::is_integral<T>::value>::type
|
||||
register_param(const pstring ¶m, T value)
|
||||
register_param_val(const pstring ¶m, T value)
|
||||
{
|
||||
register_param_x(param, static_cast<nl_fptype>(value));
|
||||
}
|
||||
@ -274,7 +274,7 @@ namespace netlist
|
||||
#endif
|
||||
|
||||
void register_lib_entry(const pstring &name, const pstring &sourcefile);
|
||||
void register_frontier(const pstring &attach, nl_fptype r_IN, nl_fptype r_OUT);
|
||||
void register_frontier(const pstring &attach, const pstring &r_IN, const pstring &r_OUT);
|
||||
|
||||
// register a source
|
||||
void register_source(plib::unique_ptr<plib::psource_t> &&src)
|
||||
|
@ -226,7 +226,6 @@ namespace plib {
|
||||
{
|
||||
pstring s(STR);
|
||||
pi++;
|
||||
// FIXME : \"
|
||||
while (pi < tmp.size() && tmp[pi] != STR)
|
||||
{
|
||||
s += tmp[pi];
|
||||
@ -454,7 +453,6 @@ namespace plib {
|
||||
line = process_comments(m_line);
|
||||
|
||||
pstring lt = plib::trim(plib::replace_all(line, "\t", " "));
|
||||
// FIXME ... revise and extend macro handling
|
||||
if (plib::startsWith(lt, "#"))
|
||||
{
|
||||
string_list lti(psplit(lt, " ", true));
|
||||
@ -462,7 +460,6 @@ namespace plib {
|
||||
{
|
||||
m_if_level++;
|
||||
lt = replace_macros(lt);
|
||||
//std::vector<pstring> t(psplit(replace_all(lt.substr(3), " ", ""), m_expr_sep));
|
||||
auto t(simple_iter<ppreprocessor>(this, tokenize(lt.substr(3), m_expr_sep, true, true)));
|
||||
auto val = static_cast<int>(prepro_expr(t, 255));
|
||||
t.skip_ws();
|
||||
|
Loading…
Reference in New Issue
Block a user