mirror of
https://github.com/holub/mame
synced 2025-04-24 09:20:02 +03:00
netlist: bug fix, code maintenance and performance improvement. (nw)
- fixed a code in the netlist creation which caused multiple proxies to be created for output->terminal connections. A nice side effect of this fix is a performance increase ~9% for kidniki and ~4% for pong. Speaking about pong ... maximum is 490%. Dice is running at 280 FPS/60 FPS = 466%, however without any analog emulation. - Replaced NL_NOEXCEPT with noexcept. assert is now exception-free. - cppcheck and lint fixes.
This commit is contained in:
parent
e00549bcec
commit
43637964a2
@ -218,7 +218,7 @@ namespace analog
|
||||
connect(m_DG.m_P, m_SD.m_N);
|
||||
|
||||
set_qtype((m_model.type() == "NMOS_DEFAULT") ? FET_NMOS : FET_PMOS);
|
||||
m_polarity = qtype() == nlconst::magic((FET_NMOS ? 1.0 : -1.0));
|
||||
m_polarity = nlconst::magic((qtype() == FET_NMOS) ? 1.0 : -1.0);
|
||||
|
||||
m_capmod = m_model.m_CAPMOD;
|
||||
// printf("capmod %d %g %g\n", m_capmod, (nl_fptype)m_model.m_VTO, m_polarity);
|
||||
|
@ -34,7 +34,7 @@ namespace netlist
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
void update_outputs(const unsigned cnt) NL_NOEXCEPT
|
||||
void update_outputs(const unsigned cnt) noexcept
|
||||
{
|
||||
static constexpr const std::array<netlist_time, 14> out_delayQn = {
|
||||
NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
|
||||
|
@ -36,7 +36,7 @@ namespace netlist
|
||||
NETLIB_UPDATEI();
|
||||
|
||||
public:
|
||||
void update_outputs(unsigned v) NL_NOEXCEPT
|
||||
void update_outputs(unsigned v) noexcept
|
||||
{
|
||||
nl_assert(v<16);
|
||||
if (v != m_state)
|
||||
|
@ -18,12 +18,60 @@ namespace netlist
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
nld_base_proxy::nld_base_proxy(netlist_state_t &anetlist, const pstring &name,
|
||||
logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
|
||||
: device_t(anetlist, name)
|
||||
logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
|
||||
: device_t(anetlist, name)
|
||||
, m_tp(nullptr)
|
||||
, m_tn(nullptr)
|
||||
, m_term_proxied(inout_proxied)
|
||||
, m_proxy_term(proxy_inout)
|
||||
{
|
||||
m_logic_family = inout_proxied->logic_family();
|
||||
m_term_proxied = inout_proxied;
|
||||
m_proxy_term = proxy_inout;
|
||||
|
||||
const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
|
||||
|
||||
bool f = false;
|
||||
for (auto & pwr_sym : power_syms)
|
||||
{
|
||||
pstring devname = inout_proxied->device().name();
|
||||
auto tp_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
auto tn_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(inout_proxied->device().name(),
|
||||
m_tp->name(), m_tn->name(),
|
||||
tp_t ? tp_t->name() : "",
|
||||
tn_t ? tn_t->name() : ""));
|
||||
else if (tp_t != nullptr && tn_t != nullptr)
|
||||
{
|
||||
m_tp = tp_t;
|
||||
m_tn = tn_t;
|
||||
f = true;
|
||||
}
|
||||
}
|
||||
//FIXME: Use power terminals and change info to warning or error
|
||||
if (!f)
|
||||
{
|
||||
#if 1
|
||||
if (logic_family()->fixed_V() == nlconst::zero())
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
|
||||
else
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(inout_proxied->device().name())));
|
||||
#endif
|
||||
m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
|
||||
m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
|
||||
|
||||
m_tp = m_VCCHack.get();
|
||||
m_tn = m_GNDHack.get();
|
||||
m_need_hack = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
log().verbose("D/A Proxy: Found power terminals on device {1}", inout_proxied->device().name());
|
||||
m_need_hack = false;
|
||||
}
|
||||
//printf("vcc: %f\n", logic_family()->fixed_V());
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -52,6 +100,7 @@ namespace netlist
|
||||
nl_assert(m_logic_family != nullptr);
|
||||
// FIXME: Variable supply voltage!
|
||||
nl_fptype supply_V = logic_family()->fixed_V();
|
||||
// FIXME: bad hack
|
||||
if (supply_V == nlconst::zero()) supply_V = nlconst::magic(5.0);
|
||||
|
||||
if (m_I.Q_Analog() > logic_family()->high_thresh_V(nlconst::zero(), supply_V))
|
||||
@ -82,45 +131,20 @@ namespace netlist
|
||||
, m_last_state(*this, "m_last_var", -1)
|
||||
, m_is_timestep(false)
|
||||
{
|
||||
const std::vector<std::pair<pstring, pstring>> power_syms = { {"VCC", "VEE"}, {"VCC", "GND"}, {"VDD", "VSS"}};
|
||||
|
||||
register_subalias("Q", m_RN.m_P);
|
||||
|
||||
bool f = false;
|
||||
detail::core_terminal_t *tp(nullptr);
|
||||
detail::core_terminal_t *tn(nullptr);
|
||||
for (auto & pwr_sym : power_syms)
|
||||
{
|
||||
pstring devname = out_proxied->device().name();
|
||||
auto tp_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.first,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
auto tn_t = anetlist.setup().find_terminal(devname + "." + pwr_sym.second,
|
||||
/*detail::terminal_type::INPUT,*/ false);
|
||||
if (f && (tp_t != nullptr && tn_t != nullptr))
|
||||
log().warning(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE(out_proxied->device().name(),
|
||||
tp->name(), tn->name(),
|
||||
tp_t ? tp_t->name() : "",
|
||||
tn_t ? tn_t->name() : ""));
|
||||
else if (tp_t != nullptr && tn_t != nullptr)
|
||||
{
|
||||
/* alternative logic */
|
||||
tp = tp_t;
|
||||
tn = tn_t;
|
||||
f = true;
|
||||
}
|
||||
}
|
||||
//FIXME: Use power terminals and change info to warning or error
|
||||
if (!f)
|
||||
if (need_hack())
|
||||
{
|
||||
#if 1
|
||||
// FIXME: move to base proxy class
|
||||
if (logic_family()->fixed_V() == nlconst::zero())
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_1(anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
log().error(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
else
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_1(anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
m_GNDHack = plib::make_unique<analog_output_t>(*this, "_QGND");
|
||||
m_VCCHack = plib::make_unique<analog_output_t>(*this, "_QVCC");
|
||||
|
||||
connect(m_RN.m_N, *m_GNDHack);
|
||||
connect(m_RP.m_P, *m_VCCHack);
|
||||
log().info(MI_NO_POWER_TERMINALS_ON_DEVICE_2(name, anetlist.setup().de_alias(out_proxied->device().name())));
|
||||
#endif
|
||||
connect(m_RN.m_N, *m_tn);
|
||||
connect(m_RP.m_P, *m_tp);
|
||||
connect(m_RN.m_P, m_RP.m_N);
|
||||
}
|
||||
else
|
||||
@ -135,8 +159,8 @@ namespace netlist
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(m_RN.m_N, *tn);
|
||||
connect(m_RP.m_P, *tp);
|
||||
connect(m_RN.m_N, *m_tn);
|
||||
connect(m_RP.m_P, *m_tp);
|
||||
}
|
||||
connect(m_RN.m_P, m_RP.m_N);
|
||||
}
|
||||
@ -156,10 +180,13 @@ namespace netlist
|
||||
m_last_state = -1;
|
||||
m_RN.reset();
|
||||
m_RP.reset();
|
||||
if (m_GNDHack)
|
||||
m_GNDHack->initial(0);
|
||||
if (m_VCCHack)
|
||||
m_VCCHack->initial(supply_V);
|
||||
if (need_hack())
|
||||
{
|
||||
if (m_tn)
|
||||
m_GNDHack->initial(0);
|
||||
if (m_tp)
|
||||
m_VCCHack->initial(supply_V);
|
||||
}
|
||||
m_is_timestep = m_RN.m_P.net().solver()->has_timestep_devices();
|
||||
m_RN.set_G_V_I(plib::reciprocal(logic_family()->R_low()),
|
||||
logic_family()->low_offset_V(), nlconst::zero());
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
namespace devices
|
||||
{
|
||||
namespace devices
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// nld_base_proxy
|
||||
@ -33,10 +33,17 @@ namespace netlist
|
||||
detail::core_terminal_t &proxy_term() const { return *m_proxy_term; }
|
||||
|
||||
protected:
|
||||
detail::core_terminal_t *m_tp;
|
||||
detail::core_terminal_t *m_tn;
|
||||
|
||||
plib::unique_ptr<analog_output_t> m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
|
||||
bool need_hack() const noexcept { return m_need_hack; }
|
||||
private:
|
||||
logic_t *m_term_proxied;
|
||||
detail::core_terminal_t *m_proxy_term;
|
||||
bool m_need_hack;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -106,15 +113,13 @@ namespace netlist
|
||||
|
||||
static constexpr const nl_fptype G_OFF = nlconst::magic(1e-9);
|
||||
|
||||
plib::unique_ptr<analog_output_t> m_GNDHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
plib::unique_ptr<analog_output_t> m_VCCHack; // FIXME: Long term, we need to connect proxy gnd to device gnd
|
||||
analog::NETLIB_NAME(twoterm) m_RP;
|
||||
analog::NETLIB_NAME(twoterm) m_RN;
|
||||
state_var<int> m_last_state;
|
||||
bool m_is_timestep;
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace devices
|
||||
} // namespace devices
|
||||
} // namespace netlist
|
||||
|
||||
#endif /* NLD_PROXY_H_ */
|
||||
|
@ -438,8 +438,8 @@ namespace devices
|
||||
}
|
||||
|
||||
// FIXME: this will seg-fault if force_analog_input = false
|
||||
nl_fptype VCC() const NL_NOEXCEPT { return m_VCC->Q_Analog(); }
|
||||
nl_fptype GND() const NL_NOEXCEPT { return m_GND->Q_Analog(); }
|
||||
nl_fptype VCC() const noexcept { return m_VCC->Q_Analog(); }
|
||||
nl_fptype GND() const noexcept { return m_GND->Q_Analog(); }
|
||||
|
||||
private:
|
||||
void noop() { }
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "plib/palloc.h" // owned_ptr
|
||||
#include "plib/pdynlib.h"
|
||||
#include "plib/pexception.h"
|
||||
#include "plib/pfmtlog.h"
|
||||
#include "plib/pfunction.h"
|
||||
#include "plib/plists.h"
|
||||
@ -23,7 +24,6 @@
|
||||
#include "plib/pstonum.h"
|
||||
#include "plib/pstream.h"
|
||||
#include "plib/ptime.h"
|
||||
#include "plib/pexception.h"
|
||||
|
||||
#include "nl_errstr.h"
|
||||
#include "nltypes.h"
|
||||
@ -153,15 +153,15 @@ class NETLIB_NAME(name) : public device_t
|
||||
#define NETLIB_DELEGATE(chip, name) nldelegate(&NETLIB_NAME(chip) :: name, this)
|
||||
|
||||
#define NETLIB_UPDATE_TERMINALSI() virtual void update_terminals() noexcept override
|
||||
#define NETLIB_HANDLERI(name) virtual void name() NL_NOEXCEPT
|
||||
#define NETLIB_UPDATEI() virtual void update() NL_NOEXCEPT override
|
||||
#define NETLIB_HANDLERI(name) virtual void name() noexcept
|
||||
#define NETLIB_UPDATEI() virtual void update() noexcept override
|
||||
#define NETLIB_UPDATE_PARAMI() virtual void update_param() noexcept override
|
||||
#define NETLIB_RESETI() virtual void reset() override
|
||||
|
||||
#define NETLIB_SUB(chip) nld_ ## chip
|
||||
#define NETLIB_SUB_UPTR(ns, chip) unique_pool_ptr< ns :: nld_ ## chip >
|
||||
|
||||
#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() NL_NOEXCEPT
|
||||
#define NETLIB_HANDLER(chip, name) void NETLIB_NAME(chip) :: name() noexcept
|
||||
#define NETLIB_UPDATE(chip) NETLIB_HANDLER(chip, update)
|
||||
|
||||
#define NETLIB_RESET(chip) void NETLIB_NAME(chip) :: reset(void)
|
||||
@ -170,19 +170,6 @@ class NETLIB_NAME(name) : public device_t
|
||||
|
||||
#define NETLIB_UPDATE_TERMINALS(chip) void NETLIB_NAME(chip) :: update_terminals() noexcept
|
||||
|
||||
//============================================================
|
||||
// Asserts
|
||||
//============================================================
|
||||
|
||||
#if defined(MAME_DEBUG) || (NL_DEBUG == true)
|
||||
#define nl_assert(x) passert_always(x);
|
||||
#define NL_NOEXCEPT
|
||||
#else
|
||||
#define nl_assert(x) do { } while (0)
|
||||
#define NL_NOEXCEPT noexcept
|
||||
#endif
|
||||
#define nl_assert_always(x, msg) passert_always_msg(x, msg)
|
||||
|
||||
//============================================================
|
||||
// Namespace starts
|
||||
//============================================================
|
||||
@ -271,7 +258,8 @@ namespace netlist
|
||||
virtual unique_pool_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
|
||||
logic_input_t *proxied) const = 0;
|
||||
|
||||
nl_fptype fixed_V() const noexcept{ return m_fixed_V; }
|
||||
// FIXME: remove fixed_V()
|
||||
nl_fptype fixed_V() const noexcept{return m_fixed_V; }
|
||||
nl_fptype low_thresh_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; }
|
||||
nl_fptype high_thresh_V(nl_fptype VN, nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; }
|
||||
nl_fptype low_offset_V() const noexcept{ return m_low_VO; }
|
||||
@ -678,7 +666,7 @@ namespace netlist
|
||||
bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
|
||||
|
||||
template <bool KEEP_STATS>
|
||||
void update_devs() NL_NOEXCEPT;
|
||||
void update_devs() noexcept;
|
||||
|
||||
netlist_time next_scheduled_time() const noexcept { return m_next_scheduled_time; }
|
||||
void set_next_scheduled_time(netlist_time ntime) noexcept { m_next_scheduled_time = ntime; }
|
||||
@ -874,7 +862,7 @@ namespace netlist
|
||||
logic_input_t(core_device_t &dev, const pstring &aname,
|
||||
nldelegate delegate = nldelegate());
|
||||
|
||||
netlist_sig_t operator()() const NL_NOEXCEPT
|
||||
netlist_sig_t operator()() const noexcept
|
||||
{
|
||||
return Q();
|
||||
}
|
||||
@ -884,7 +872,7 @@ namespace netlist
|
||||
void activate_hl() noexcept;
|
||||
void activate_lh() noexcept;
|
||||
private:
|
||||
netlist_sig_t Q() const NL_NOEXCEPT;
|
||||
netlist_sig_t Q() const noexcept;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -1048,7 +1036,7 @@ namespace netlist
|
||||
|
||||
unique_pool_ptr<stats_t> m_stats;
|
||||
|
||||
virtual void update() NL_NOEXCEPT { }
|
||||
virtual void update() noexcept { }
|
||||
virtual void reset() { }
|
||||
|
||||
protected:
|
||||
@ -1946,7 +1934,7 @@ namespace netlist
|
||||
return static_cast<const logic_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline netlist_sig_t logic_input_t::Q() const NL_NOEXCEPT
|
||||
inline netlist_sig_t logic_input_t::Q() const noexcept
|
||||
{
|
||||
nl_assert(terminal_state() != STATE_INP_PASSIVE);
|
||||
//if (net().Q() != m_Q)
|
||||
@ -2056,7 +2044,7 @@ namespace netlist
|
||||
}
|
||||
|
||||
template <bool KEEP_STATS>
|
||||
inline void detail::net_t::update_devs() NL_NOEXCEPT
|
||||
inline void detail::net_t::update_devs() noexcept
|
||||
{
|
||||
nl_assert(this->isRailNet());
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define NLCONFIG_H_
|
||||
|
||||
#include "plib/pconfig.h"
|
||||
#include "plib/pexception.h"
|
||||
|
||||
/// \addtogroup compiledefine
|
||||
/// \{
|
||||
@ -225,4 +226,15 @@ namespace netlist
|
||||
#endif
|
||||
} // namespace netlist
|
||||
|
||||
//============================================================
|
||||
// Asserts
|
||||
//============================================================
|
||||
|
||||
#if defined(MAME_DEBUG) || (NL_DEBUG == true)
|
||||
#define nl_assert(x) passert_always(x);
|
||||
#else
|
||||
#define nl_assert(x) do { } while (0)
|
||||
#endif
|
||||
#define nl_assert_always(x, msg) passert_always_msg(x, msg)
|
||||
|
||||
#endif // NLCONFIG_H_
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define PERRMSGV(name, narg, str) \
|
||||
struct name \
|
||||
{ \
|
||||
template<typename... Args> name(Args&&... args) \
|
||||
template<typename... Args> explicit name(Args&&... args) \
|
||||
: m_m(plib::pfmt(str)(std::forward<Args>(args)...)) \
|
||||
{ static_assert(narg == sizeof...(args), "Argument count mismatch"); } \
|
||||
operator pstring() const noexcept { return m_m; } \
|
||||
@ -116,7 +116,7 @@ namespace netlist
|
||||
|
||||
// nlid_proxy.cpp
|
||||
|
||||
PERRMSGV(MI_NO_POWER_TERMINALS_ON_DEVICE_1, 1, "D/A Proxy: Found no valid combination of power terminals on device {1}")
|
||||
PERRMSGV(MI_NO_POWER_TERMINALS_ON_DEVICE_2, 2, "D/A Proxy {1}: Found no valid combination of power terminals on device {2}")
|
||||
PERRMSGV(MI_MULTIPLE_POWER_TERMINALS_ON_DEVICE, 5, "D/A Proxy: Found multiple power terminals on device {1}: {2} {3} {4} {5}")
|
||||
|
||||
// nld_matrix_solver.cpp
|
||||
|
@ -590,9 +590,10 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
|
||||
out.net().core_terms().clear(); // clear the list
|
||||
|
||||
out.net().add_terminal(new_proxy->in());
|
||||
out_cast.set_proxy(proxy);
|
||||
//out_cast.set_proxy(proxy); - Wrong!
|
||||
|
||||
proxy = new_proxy.get();
|
||||
out_cast.set_proxy(proxy);
|
||||
|
||||
m_nlstate.register_device(new_proxy->name(), std::move(new_proxy));
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ namespace plib {
|
||||
|
||||
//~arena_allocator() noexcept = default;
|
||||
|
||||
arena_allocator(arena_type & a) noexcept : m_a(a)
|
||||
explicit arena_allocator(const arena_type & a) noexcept : m_a(a)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
/// \file pmempool.h
|
||||
///
|
||||
|
||||
#include "pconfig.h"
|
||||
#include "palloc.h"
|
||||
#include "pconfig.h"
|
||||
#include "pstream.h"
|
||||
#include "pstring.h"
|
||||
#include "ptypes.h"
|
||||
@ -63,13 +63,13 @@ namespace plib {
|
||||
//::operator delete(b->m_data);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline mempool &instance()
|
||||
{
|
||||
static mempool s_mempool;
|
||||
return s_mempool;
|
||||
}
|
||||
|
||||
#endif
|
||||
void *allocate(size_t align, size_t size)
|
||||
{
|
||||
block *b = nullptr;
|
||||
|
@ -12,7 +12,7 @@ namespace plib {
|
||||
// A simple tokenizer
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
pstring ptokenizer::currentline_str()
|
||||
pstring ptokenizer::currentline_str() const
|
||||
{
|
||||
return m_cur_line;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ namespace plib {
|
||||
pstring m_token;
|
||||
};
|
||||
|
||||
pstring currentline_str();
|
||||
pstring currentline_str() const;
|
||||
|
||||
// tokenizer stuff follows ...
|
||||
|
||||
|
@ -361,7 +361,7 @@ namespace solver
|
||||
m_last_step = netlist_time::zero();
|
||||
}
|
||||
|
||||
void matrix_solver_t::update() NL_NOEXCEPT
|
||||
void matrix_solver_t::update() noexcept
|
||||
{
|
||||
const netlist_time new_timestep = solve(exec().time());
|
||||
update_inputs();
|
||||
|
Loading…
Reference in New Issue
Block a user