mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
More netlist refactoring:
- Remove virtual from some destructors and make them protected. - Various cleanups. - Small performance improvement. - Fixed some inconsistencies. - More c++ refactoring. (nw)
This commit is contained in:
parent
25152bd69a
commit
ba03118b09
@ -619,11 +619,11 @@ void netlist_mame_cpu_device_t::device_start()
|
||||
netlist::detail::net_t *n = netlist().m_nets[i].get();
|
||||
if (n->is_logic())
|
||||
{
|
||||
state_add(i*2, n->name().c_str(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
|
||||
state_add(i*2, n->name().c_str(), *downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
state_add(i*2+1, n->name().c_str(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
|
||||
state_add(i*2+1, n->name().c_str(), *downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <solver/nld_solver.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#include "nld_twoterm.h"
|
||||
|
||||
namespace netlist
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <devices/nlid_cmos.h>
|
||||
#include "devices/nlid_cmos.h"
|
||||
#include "nld_4020.h"
|
||||
|
||||
namespace netlist
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <devices/nlid_cmos.h>
|
||||
#include "devices/nlid_cmos.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "nld_4066.h"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <devices/nlid_cmos.h>
|
||||
#include "devices/nlid_cmos.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include "nld_4316.h"
|
||||
|
||||
|
@ -82,7 +82,7 @@ namespace netlist
|
||||
netlist_time delay = NLTIME_FROM_NS(26);
|
||||
if (m_CLRQ())
|
||||
{
|
||||
bool clear_unset = !m_last_CLRQ();
|
||||
bool clear_unset = !m_last_CLRQ;
|
||||
if (clear_unset)
|
||||
{
|
||||
delay = NLTIME_FROM_NS(35);
|
||||
|
@ -29,8 +29,8 @@ namespace netlist
|
||||
logic_input_t m_I;
|
||||
logic_output_t m_Q;
|
||||
|
||||
state_var_u8 m_reset;
|
||||
state_var_u8 m_state;
|
||||
state_var<netlist_sig_t> m_reset;
|
||||
state_var<netlist_sig_t> m_state;
|
||||
};
|
||||
|
||||
NETLIB_OBJECT(7493)
|
||||
@ -99,7 +99,7 @@ namespace netlist
|
||||
|
||||
NETLIB_UPDATE(7493ff)
|
||||
{
|
||||
constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
|
||||
static constexpr netlist_time out_delay = NLTIME_FROM_NS(18);
|
||||
if (m_reset)
|
||||
{
|
||||
m_state ^= 1;
|
||||
|
@ -158,21 +158,22 @@ namespace netlist
|
||||
{
|
||||
if (m_loadq)
|
||||
{
|
||||
switch (m_cnt())
|
||||
if (m_cnt < MAXCNT - 1)
|
||||
{
|
||||
case MAXCNT - 1:
|
||||
m_cnt = MAXCNT;
|
||||
m_RC.push(m_ent, NLTIME_FROM_NS(20));
|
||||
m_QA.push(1, NLTIME_FROM_NS(20));
|
||||
break;
|
||||
case MAXCNT:
|
||||
m_RC.push(0, NLTIME_FROM_NS(20));
|
||||
m_cnt = 0;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
break;
|
||||
default:
|
||||
m_cnt++;
|
||||
update_outputs(m_cnt);
|
||||
m_cnt++;
|
||||
update_outputs(m_cnt);
|
||||
}
|
||||
else if (m_cnt == MAXCNT - 1)
|
||||
{
|
||||
m_cnt = MAXCNT;
|
||||
m_RC.push(m_ent, NLTIME_FROM_NS(20));
|
||||
m_QA.push(1, NLTIME_FROM_NS(20));
|
||||
}
|
||||
else // MAXCNT
|
||||
{
|
||||
m_RC.push(0, NLTIME_FROM_NS(20));
|
||||
m_cnt = 0;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -161,22 +161,22 @@ namespace netlist
|
||||
{
|
||||
if (m_loadq)
|
||||
{
|
||||
switch (m_cnt())
|
||||
if (m_cnt < MAXCNT - 1)
|
||||
{
|
||||
case MAXCNT - 1:
|
||||
m_cnt = MAXCNT;
|
||||
m_RC.push(m_ent, NLTIME_FROM_NS(27));
|
||||
m_QA.push(1, NLTIME_FROM_NS(20));
|
||||
break;
|
||||
case MAXCNT:
|
||||
m_RC.push(0, NLTIME_FROM_NS(27));
|
||||
m_cnt = 0;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
break;
|
||||
default:
|
||||
m_cnt++;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
break;
|
||||
m_cnt++;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
}
|
||||
else if (m_cnt == MAXCNT - 1)
|
||||
{
|
||||
m_cnt = MAXCNT;
|
||||
m_RC.push(m_ent, NLTIME_FROM_NS(27));
|
||||
m_QA.push(1, NLTIME_FROM_NS(20));
|
||||
}
|
||||
else // MAXCNT
|
||||
{
|
||||
m_RC.push(0, NLTIME_FROM_NS(27));
|
||||
m_cnt = 0;
|
||||
update_outputs_all(m_cnt, NLTIME_FROM_NS(20));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "nld_mm5837.h"
|
||||
#include <solver/nld_matrix_solver.h>
|
||||
#include "solver/nld_matrix_solver.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
|
||||
#define R_LOW (1000.0)
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "nld_ne555.h"
|
||||
#include "analog/nld_twoterm.h"
|
||||
#include <solver/nld_solver.h>
|
||||
#include "solver/nld_solver.h"
|
||||
|
||||
#define R_OFF (1E20)
|
||||
#define R_ON (25) // Datasheet states a maximum discharge of 200mA, R = 5V / 0.2
|
||||
|
@ -5,8 +5,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <solver/nld_solver.h>
|
||||
#include <solver/nld_matrix_solver.h>
|
||||
#include "solver/nld_solver.h"
|
||||
#include "solver/nld_matrix_solver.h"
|
||||
#include "nlid_system.h"
|
||||
|
||||
namespace netlist
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "nld_truthtable.h"
|
||||
#include "plib/plists.h"
|
||||
#include "nl_setup.h"
|
||||
#include "plib/palloc.h"
|
||||
|
||||
namespace netlist
|
||||
{
|
||||
@ -272,7 +273,7 @@ netlist_base_factory_truthtable_t::~netlist_base_factory_truthtable_t()
|
||||
|
||||
#define ENTRYY(n, m, s) case (n * 100 + m): \
|
||||
{ using xtype = netlist_factory_truthtable_t<n, m>; \
|
||||
ret = new xtype(desc.name, desc.classname, desc.def_param, s); } break
|
||||
ret = plib::palloc<xtype>(desc.name, desc.classname, desc.def_param, s); } break
|
||||
|
||||
#define ENTRY(n, s) ENTRYY(n, 1, s); ENTRYY(n, 2, s); ENTRYY(n, 3, s); \
|
||||
ENTRYY(n, 4, s); ENTRYY(n, 5, s); ENTRYY(n, 6, s)
|
||||
|
@ -113,9 +113,9 @@ namespace netlist
|
||||
{
|
||||
pstring devname = out_proxied->device().name();
|
||||
auto tp = netlist().setup().find_terminal(devname + "." + power_syms[i][0],
|
||||
detail::device_object_t::type_t::INPUT, false);
|
||||
detail::core_terminal_t::type_t::INPUT, false);
|
||||
auto tn = netlist().setup().find_terminal(devname + "." + power_syms[i][1],
|
||||
detail::device_object_t::type_t::INPUT, false);
|
||||
detail::core_terminal_t::type_t::INPUT, false);
|
||||
if (tp != nullptr && tn != nullptr)
|
||||
{
|
||||
/* alternative logic */
|
||||
|
@ -25,7 +25,7 @@ namespace netlist
|
||||
namespace detail
|
||||
{
|
||||
#if (USE_MEMPOOL)
|
||||
static plib::mempool pool(65536, 8);
|
||||
static plib::mempool pool(6553600, 64);
|
||||
|
||||
void * object_t::operator new (size_t size)
|
||||
{
|
||||
@ -184,7 +184,7 @@ void detail::queue_t::on_post_load()
|
||||
detail::net_t *n = netlist().find_net(pstring(m_names[i].m_buf, pstring::UTF8));
|
||||
//log().debug("Got {1} ==> {2}\n", qtemp[i].m_name, n));
|
||||
//log().debug("schedule time {1} ({2})\n", n->time().as_double(), netlist_time::from_raw(m_times[i]).as_double()));
|
||||
this->push(n, netlist_time::from_raw(m_times[i]));
|
||||
this->push(queue_t::entry_t(netlist_time::from_raw(m_times[i]),n));
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,20 +216,18 @@ detail::device_object_t::device_object_t(core_device_t &dev, const pstring &anam
|
||||
{
|
||||
}
|
||||
|
||||
detail::device_object_t::type_t detail::device_object_t::type() const
|
||||
detail::core_terminal_t::type_t detail::core_terminal_t::type() const
|
||||
{
|
||||
if (dynamic_cast<const terminal_t *>(this) != nullptr)
|
||||
return type_t::TERMINAL;
|
||||
else if (dynamic_cast<const param_t *>(this) != nullptr)
|
||||
return param_t::PARAM;
|
||||
else if (dynamic_cast<const logic_input_t *>(this) != nullptr)
|
||||
return param_t::INPUT;
|
||||
return type_t::INPUT;
|
||||
else if (dynamic_cast<const logic_output_t *>(this) != nullptr)
|
||||
return param_t::OUTPUT;
|
||||
return type_t::OUTPUT;
|
||||
else if (dynamic_cast<const analog_input_t *>(this) != nullptr)
|
||||
return param_t::INPUT;
|
||||
return type_t::INPUT;
|
||||
else if (dynamic_cast<const analog_output_t *>(this) != nullptr)
|
||||
return param_t::OUTPUT;
|
||||
return type_t::OUTPUT;
|
||||
else
|
||||
{
|
||||
netlist().log().fatal(MF_1_UNKNOWN_TYPE_FOR_OBJECT, name());
|
||||
@ -254,19 +252,16 @@ netlist_t::netlist_t(const pstring &aname)
|
||||
{
|
||||
state().save_item(this, static_cast<plib::state_manager_t::callback_t &>(m_queue), "m_queue");
|
||||
state().save_item(this, m_time, "m_time");
|
||||
m_setup = new setup_t(*this);
|
||||
m_setup = plib::make_unique<setup_t>(*this);
|
||||
/* FIXME: doesn't really belong here */
|
||||
NETLIST_NAME(base)(*m_setup);
|
||||
}
|
||||
|
||||
netlist_t::~netlist_t()
|
||||
{
|
||||
if (m_setup != nullptr)
|
||||
delete m_setup;
|
||||
m_nets.clear();
|
||||
m_devices.clear();
|
||||
|
||||
pfree(m_lib);
|
||||
pstring::resetmem();
|
||||
}
|
||||
|
||||
@ -356,7 +351,7 @@ void netlist_t::start()
|
||||
}
|
||||
|
||||
pstring libpath = plib::util::environment("NL_BOOSTLIB", plib::util::buildpath({".", "nlboost.so"}));
|
||||
m_lib = plib::palloc<plib::dynlib>(libpath);
|
||||
m_lib = plib::make_unique<plib::dynlib>(libpath);
|
||||
|
||||
/* resolve inputs */
|
||||
setup().resolve_inputs();
|
||||
@ -448,7 +443,7 @@ void netlist_t::process_queue(const netlist_time &delta)
|
||||
{
|
||||
netlist_time stop(m_time + delta);
|
||||
|
||||
m_queue.push(nullptr, stop);
|
||||
m_queue.push(detail::queue_t::entry_t(stop, nullptr));
|
||||
|
||||
m_stat_mainloop.start();
|
||||
|
||||
@ -475,17 +470,20 @@ void netlist_t::process_queue(const netlist_time &delta)
|
||||
while (m_queue.top().m_exec_time > mc_time)
|
||||
{
|
||||
m_time = mc_time;
|
||||
mc_time += inc;
|
||||
mc_net.toggle_new_Q();
|
||||
mc_net.update_devs();
|
||||
mc_time += inc;
|
||||
}
|
||||
|
||||
const detail::queue_t::entry_t e(m_queue.pop());
|
||||
m_time = e.m_exec_time;
|
||||
if (e.m_object == nullptr)
|
||||
if (e.m_object != nullptr)
|
||||
{
|
||||
e.m_object->update_devs();
|
||||
m_perf_out_processed.inc();
|
||||
}
|
||||
else
|
||||
break;
|
||||
e.m_object->update_devs();
|
||||
m_perf_out_processed.inc();
|
||||
}
|
||||
mc_net.set_time(mc_time);
|
||||
}
|
||||
@ -686,13 +684,6 @@ detail::family_setter_t::family_setter_t(core_device_t &dev, const logic_family_
|
||||
// net_t
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
// FIXME: move somewhere central
|
||||
|
||||
struct do_nothing_deleter{
|
||||
template<typename T> void operator()(T*){}
|
||||
};
|
||||
|
||||
|
||||
detail::net_t::net_t(netlist_t &nl, const pstring &aname, core_terminal_t *mr)
|
||||
: object_t(aname)
|
||||
, netlist_ref(nl)
|
||||
@ -725,7 +716,7 @@ void detail::net_t::inc_active(core_terminal_t &term) NL_NOEXCEPT
|
||||
if (m_time > netlist().time())
|
||||
{
|
||||
m_in_queue = 1; /* pending */
|
||||
netlist().queue().push(this, m_time);
|
||||
netlist().queue().push(queue_t::entry_t(m_time, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1100,11 +1091,11 @@ param_double_t::param_double_t(device_t &device, const pstring name, const doubl
|
||||
m_param = device.setup().get_initial_param_val(this->name(),val);
|
||||
netlist().save(*this, m_param, "m_param");
|
||||
}
|
||||
|
||||
#if 0
|
||||
param_double_t::~param_double_t()
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
param_int_t::param_int_t(device_t &device, const pstring name, const int val)
|
||||
: param_t(device, name)
|
||||
{
|
||||
@ -1112,9 +1103,11 @@ param_int_t::param_int_t(device_t &device, const pstring name, const int val)
|
||||
netlist().save(*this, m_param, "m_param");
|
||||
}
|
||||
|
||||
#if 0
|
||||
param_int_t::~param_int_t()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
param_logic_t::param_logic_t(device_t &device, const pstring name, const bool val)
|
||||
: param_t(device, name)
|
||||
@ -1123,9 +1116,11 @@ param_logic_t::param_logic_t(device_t &device, const pstring name, const bool va
|
||||
netlist().save(*this, m_param, "m_param");
|
||||
}
|
||||
|
||||
#if 0
|
||||
param_logic_t::~param_logic_t()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val)
|
||||
: param_t(device, name)
|
||||
@ -1134,9 +1129,11 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val)
|
||||
//netlist().save(*this, m_param, "m_param");
|
||||
}
|
||||
|
||||
#if 0
|
||||
param_ptr_t::~param_ptr_t()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void param_model_t::changed()
|
||||
{
|
||||
|
@ -29,7 +29,7 @@
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*! netlist_sig_t is the type used for logic signals. */
|
||||
using netlist_sig_t = std::uint_least32_t;
|
||||
using netlist_sig_t = std::uint32_t;
|
||||
|
||||
//============================================================
|
||||
// MACROS / New Syntax
|
||||
@ -281,12 +281,12 @@ namespace netlist
|
||||
public:
|
||||
|
||||
logic_family_t() : m_logic_family(nullptr) {}
|
||||
~logic_family_t() { }
|
||||
|
||||
const logic_family_desc_t *logic_family() const { return m_logic_family; }
|
||||
void set_logic_family(const logic_family_desc_t *fam) { m_logic_family = fam; }
|
||||
|
||||
protected:
|
||||
~logic_family_t() { } // prohibit polymorphic destruction
|
||||
const logic_family_desc_t *m_logic_family;
|
||||
};
|
||||
|
||||
@ -321,19 +321,15 @@ namespace netlist
|
||||
//! Move Constructor.
|
||||
state_var(state_var &&rhs) NL_NOEXCEPT = default;
|
||||
//! Assignment operator to assign value of a state var.
|
||||
state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; }
|
||||
state_var &operator=(const state_var &rhs) { m_value = rhs; return *this; }
|
||||
//! Assignment operator to assign value of type T.
|
||||
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
|
||||
state_var &operator=(const T &rhs) { m_value = rhs; return *this; }
|
||||
//! Return value of state variable.
|
||||
operator T & () { return m_value; }
|
||||
//! Return value of state variable.
|
||||
T & operator()() { return m_value; }
|
||||
//! Return const value of state variable.
|
||||
operator const T & () const { return m_value; }
|
||||
//! Return const value of state variable.
|
||||
const T & operator()() const { return m_value; }
|
||||
constexpr operator const T & () const { return m_value; }
|
||||
T * ptr() { return &m_value; }
|
||||
const T * ptr() const { return &m_value; }
|
||||
constexpr T * ptr() const { return &m_value; }
|
||||
private:
|
||||
T m_value;
|
||||
};
|
||||
@ -346,13 +342,20 @@ namespace netlist
|
||||
struct state_var<T[N]>
|
||||
{
|
||||
public:
|
||||
state_var(device_t &dev, const pstring name, const T & value);
|
||||
//! Constructor.
|
||||
template <typename O>
|
||||
state_var(O &owner, //!< owner must have a netlist() method.
|
||||
const pstring name, //!< identifier/name for this state variable
|
||||
const T &value //!< Initial value after construction
|
||||
);
|
||||
//! Copy Constructor.
|
||||
state_var(const state_var &rhs) NL_NOEXCEPT = default;
|
||||
//! Move Constructor.
|
||||
state_var(state_var &&rhs) NL_NOEXCEPT = default;
|
||||
state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; }
|
||||
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
|
||||
state_var &operator=(const state_var &rhs) { m_value = rhs.m_value; return *this; }
|
||||
state_var &operator=(const T &rhs) { m_value = rhs; return *this; }
|
||||
T & operator[](const std::size_t i) { return m_value[i]; }
|
||||
const T & operator[](const std::size_t i) const { return m_value[i]; }
|
||||
constexpr T & operator[](const std::size_t i) const { return m_value[i]; }
|
||||
private:
|
||||
T m_value[N];
|
||||
};
|
||||
@ -392,7 +395,6 @@ namespace netlist
|
||||
* Every class derived from the object_t class must have a name.
|
||||
*/
|
||||
object_t(const pstring &aname /*!< string containing name of the object */);
|
||||
virtual ~object_t();
|
||||
|
||||
/*! return name of the object
|
||||
*
|
||||
@ -404,6 +406,8 @@ namespace netlist
|
||||
void operator delete (void *ptr, void *) { }
|
||||
void * operator new (size_t size);
|
||||
void operator delete (void * mem);
|
||||
protected:
|
||||
~object_t(); // only childs should be destructible
|
||||
|
||||
private:
|
||||
pstring m_name;
|
||||
@ -412,11 +416,13 @@ namespace netlist
|
||||
struct detail::netlist_ref
|
||||
{
|
||||
netlist_ref(netlist_t &nl) : m_netlist(nl) { }
|
||||
~netlist_ref() {}
|
||||
|
||||
netlist_t & netlist() { return m_netlist; }
|
||||
const netlist_t & netlist() const { return m_netlist; }
|
||||
|
||||
protected:
|
||||
~netlist_ref() {} // prohibit polymorphic destruction
|
||||
|
||||
private:
|
||||
netlist_t & m_netlist;
|
||||
|
||||
@ -435,14 +441,6 @@ namespace netlist
|
||||
{
|
||||
P_PREVENT_COPYING(device_object_t)
|
||||
public:
|
||||
/*! Enum specifying the type of object */
|
||||
enum type_t {
|
||||
TERMINAL = 0, /*!< object is an analog terminal */
|
||||
INPUT = 1, /*!< object is an input */
|
||||
OUTPUT = 2, /*!< object is an output */
|
||||
PARAM = 3, /*!< object is a parameter */
|
||||
};
|
||||
|
||||
/*! Constructor.
|
||||
*
|
||||
* \param dev device owning the object.
|
||||
@ -454,16 +452,6 @@ namespace netlist
|
||||
*/
|
||||
core_device_t &device() const { return m_device; }
|
||||
|
||||
/*! The object type.
|
||||
* \returns type of the object
|
||||
*/
|
||||
type_t type() const;
|
||||
/*! Checks if object is of specified type.
|
||||
* \param atype type to check object against.
|
||||
* \returns true if object is of specified type else false.
|
||||
*/
|
||||
bool is_type(const type_t atype) const { return (type() == atype); }
|
||||
|
||||
/*! The netlist owning the owner of this object.
|
||||
* \returns reference to netlist object.
|
||||
*/
|
||||
@ -500,9 +488,26 @@ namespace netlist
|
||||
STATE_BIDIR = 256
|
||||
};
|
||||
|
||||
/*! Enum specifying the type of object */
|
||||
enum type_t {
|
||||
TERMINAL = 0, /*!< object is an analog terminal */
|
||||
INPUT = 1, /*!< object is an input */
|
||||
OUTPUT = 2, /*!< object is an output */
|
||||
};
|
||||
|
||||
core_terminal_t(core_device_t &dev, const pstring &aname, const state_e state);
|
||||
virtual ~core_terminal_t();
|
||||
|
||||
/*! The object type.
|
||||
* \returns type of the object
|
||||
*/
|
||||
type_t type() const;
|
||||
/*! Checks if object is of specified type.
|
||||
* \param atype type to check object against.
|
||||
* \returns true if object is of specified type else false.
|
||||
*/
|
||||
bool is_type(const type_t atype) const { return (type() == atype); }
|
||||
|
||||
void set_net(net_t *anet);
|
||||
void clear_net();
|
||||
bool has_net() const { return (m_net != nullptr); }
|
||||
@ -706,12 +711,6 @@ namespace netlist
|
||||
|
||||
void reset();
|
||||
|
||||
void add_terminal(core_terminal_t &terminal);
|
||||
void remove_terminal(core_terminal_t &terminal);
|
||||
|
||||
bool is_logic() const NL_NOEXCEPT;
|
||||
bool is_analog() const NL_NOEXCEPT;
|
||||
|
||||
void toggle_new_Q() { m_new_Q ^= 1; }
|
||||
void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); }
|
||||
|
||||
@ -732,6 +731,14 @@ namespace netlist
|
||||
void inc_active(core_terminal_t &term) NL_NOEXCEPT;
|
||||
void dec_active(core_terminal_t &term) NL_NOEXCEPT;
|
||||
|
||||
/* setup stuff */
|
||||
|
||||
void add_terminal(core_terminal_t &terminal);
|
||||
void remove_terminal(core_terminal_t &terminal);
|
||||
|
||||
bool is_logic() const NL_NOEXCEPT;
|
||||
bool is_analog() const NL_NOEXCEPT;
|
||||
|
||||
void rebuild_list(); /* rebuild m_list after a load */
|
||||
void move_connections(net_t &dest_net);
|
||||
|
||||
@ -764,7 +771,7 @@ namespace netlist
|
||||
virtual ~logic_net_t();
|
||||
|
||||
netlist_sig_t Q() const { return m_cur_Q; }
|
||||
netlist_sig_t new_Q() const { return m_new_Q; }
|
||||
netlist_sig_t new_Q() const { return m_new_Q; }
|
||||
void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; }
|
||||
|
||||
void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
|
||||
@ -789,7 +796,7 @@ namespace netlist
|
||||
/* internal state support
|
||||
* FIXME: get rid of this and implement export/import in MAME
|
||||
*/
|
||||
netlist_sig_t &Q_state_ptr() { return m_cur_Q; }
|
||||
netlist_sig_t *Q_state_ptr() { return m_cur_Q.ptr(); }
|
||||
|
||||
protected:
|
||||
private:
|
||||
@ -808,7 +815,7 @@ namespace netlist
|
||||
virtual ~analog_net_t();
|
||||
|
||||
nl_double Q_Analog() const { return m_cur_Analog; }
|
||||
nl_double &Q_Analog_state_ptr() { return m_cur_Analog; }
|
||||
nl_double *Q_Analog_state_ptr() { return m_cur_Analog.ptr(); }
|
||||
|
||||
//FIXME: needed by current solver code
|
||||
devices::matrix_solver_t *solver() const { return m_solver; }
|
||||
@ -874,11 +881,12 @@ namespace netlist
|
||||
};
|
||||
|
||||
param_t(device_t &device, const pstring &name);
|
||||
virtual ~param_t();
|
||||
|
||||
param_type_t param_type() const;
|
||||
|
||||
protected:
|
||||
virtual ~param_t(); /* not intended to be destroyed */
|
||||
|
||||
void update_param();
|
||||
|
||||
template<typename C>
|
||||
@ -897,7 +905,6 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
param_ptr_t(device_t &device, const pstring name, std::uint8_t* val);
|
||||
virtual ~param_ptr_t();
|
||||
std::uint8_t * operator()() const { return m_param; }
|
||||
void setTo(std::uint8_t *param) { set(m_param, param); }
|
||||
private:
|
||||
@ -908,7 +915,6 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
param_logic_t(device_t &device, const pstring name, const bool val);
|
||||
virtual ~param_logic_t();
|
||||
bool operator()() const { return m_param; }
|
||||
void setTo(const bool ¶m) { set(m_param, param); }
|
||||
private:
|
||||
@ -919,7 +925,6 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
param_int_t(device_t &device, const pstring name, const int val);
|
||||
virtual ~param_int_t();
|
||||
int operator()() const { return m_param; }
|
||||
void setTo(const int ¶m) { set(m_param, param); }
|
||||
private:
|
||||
@ -930,7 +935,6 @@ namespace netlist
|
||||
{
|
||||
public:
|
||||
param_double_t(device_t &device, const pstring name, const double val);
|
||||
virtual ~param_double_t();
|
||||
double operator()() const { return m_param; }
|
||||
void setTo(const double ¶m) { set(m_param, param); }
|
||||
private:
|
||||
@ -942,6 +946,7 @@ namespace netlist
|
||||
public:
|
||||
param_str_t(device_t &device, const pstring name, const pstring val);
|
||||
virtual ~param_str_t();
|
||||
|
||||
const pstring operator()() const { return Value(); }
|
||||
void setTo(const pstring ¶m)
|
||||
{
|
||||
@ -1128,7 +1133,7 @@ namespace netlist
|
||||
template<class C, typename... Args>
|
||||
void register_sub(const pstring &name, std::unique_ptr<C> &dev, const Args&... args)
|
||||
{
|
||||
dev.reset(new C(*this, name, args...));
|
||||
dev.reset(plib::palloc<C>(*this, name, args...));
|
||||
}
|
||||
|
||||
void register_subalias(const pstring &name, detail::core_terminal_t &term);
|
||||
@ -1309,9 +1314,9 @@ namespace netlist
|
||||
devices::NETLIB_NAME(netlistparams) *m_params;
|
||||
|
||||
pstring m_name;
|
||||
setup_t * m_setup;
|
||||
std::unique_ptr<setup_t> m_setup;
|
||||
plib::plog_base<NL_DEBUG> m_log;
|
||||
plib::dynlib * m_lib; // external lib needs to be loaded as long as netlist exists
|
||||
std::unique_ptr<plib::dynlib> m_lib; // external lib needs to be loaded as long as netlist exists
|
||||
|
||||
plib::state_manager_t m_state;
|
||||
|
||||
@ -1421,7 +1426,7 @@ namespace netlist
|
||||
m_time = netlist().time() + delay;
|
||||
m_in_queue = (m_active > 0); /* queued ? */
|
||||
if (m_in_queue)
|
||||
netlist().queue().push(this, m_time);
|
||||
netlist().queue().push(queue_t::entry_t(m_time, this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1433,7 +1438,7 @@ namespace netlist
|
||||
m_time = netlist().time() + delay;
|
||||
m_in_queue = (m_active > 0); /* queued ? */
|
||||
if (m_in_queue)
|
||||
netlist().queue().push(this, m_time);
|
||||
netlist().queue().push(queue_t::entry_t(m_time, this));
|
||||
}
|
||||
|
||||
inline const analog_net_t & analog_t::net() const NL_NOEXCEPT
|
||||
@ -1450,7 +1455,7 @@ namespace netlist
|
||||
|
||||
inline logic_net_t & logic_t::net() NL_NOEXCEPT
|
||||
{
|
||||
return *static_cast<logic_net_t *>(&core_terminal_t::net());
|
||||
return static_cast<logic_net_t &>(core_terminal_t::net());
|
||||
}
|
||||
|
||||
inline const logic_net_t & logic_t::net() const NL_NOEXCEPT
|
||||
@ -1487,9 +1492,10 @@ namespace netlist
|
||||
}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
state_var<T[N]>::state_var(device_t &dev, const pstring name, const T & value)
|
||||
template <typename O>
|
||||
state_var<T[N]>::state_var(O &owner, const pstring name, const T & value)
|
||||
{
|
||||
dev.netlist().save(dev, m_value, name);
|
||||
owner.netlist().save(owner, m_value, name);
|
||||
for (std::size_t i=0; i<N; i++)
|
||||
m_value[i] = value;
|
||||
}
|
||||
@ -1506,5 +1512,14 @@ namespace netlist
|
||||
|
||||
}
|
||||
|
||||
namespace plib
|
||||
{
|
||||
template<typename X>
|
||||
struct ptype_traits<netlist::state_var<X>> : ptype_traits<X>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* NLBASE_H_ */
|
||||
|
@ -17,12 +17,11 @@
|
||||
#include "plib/putil.h"
|
||||
#include "nl_base.h"
|
||||
|
||||
#if 1
|
||||
#define NETLIB_DEVICE_IMPL(chip) \
|
||||
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
|
||||
const pstring &name, const pstring &classname, const pstring &def_param) \
|
||||
{ \
|
||||
return std::unique_ptr<factory::element_t>(new factory::device_element_t<NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \
|
||||
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
|
||||
} \
|
||||
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
|
||||
|
||||
@ -30,16 +29,10 @@
|
||||
static std::unique_ptr<factory::element_t> NETLIB_NAME(chip ## _c)( \
|
||||
const pstring &name, const pstring &classname, const pstring &def_param) \
|
||||
{ \
|
||||
return std::unique_ptr<factory::element_t>(new factory::device_element_t<ns :: NETLIB_NAME(chip)>(name, classname, def_param, pstring(__FILE__))); \
|
||||
return std::unique_ptr<factory::element_t>(plib::palloc<factory::device_element_t<ns :: NETLIB_NAME(chip)>>(name, classname, def_param, pstring(__FILE__))); \
|
||||
} \
|
||||
factory::constructor_ptr_t decl_ ## chip = NETLIB_NAME(chip ## _c);
|
||||
|
||||
#else
|
||||
#define NETLIB_DEVICE_IMPL(chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< NETLIB_NAME(chip) >;
|
||||
#define NETLIB_DEVICE_IMPL_NS(ns, chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< ns :: NETLIB_NAME(chip) >;
|
||||
#endif
|
||||
|
||||
|
||||
namespace netlist { namespace factory
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -99,7 +92,7 @@ namespace netlist { namespace factory
|
||||
void register_device(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
{
|
||||
register_device(std::unique_ptr<element_t>(new device_element_t<device_class>(name, classname, def_param)));
|
||||
register_device(std::unique_ptr<element_t>(plib::palloc<device_element_t<device_class>>(name, classname, def_param)));
|
||||
}
|
||||
|
||||
void register_device(std::unique_ptr<element_t> factory);
|
||||
@ -127,7 +120,7 @@ namespace netlist { namespace factory
|
||||
std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
|
||||
const pstring &def_param)
|
||||
{
|
||||
return std::unique_ptr<element_t>(new device_element_t<T>(name, classname, def_param));
|
||||
return std::unique_ptr<element_t>(plib::palloc<device_element_t<T>>(name, classname, def_param));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -11,6 +11,8 @@
|
||||
#define NLLISTS_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include "nl_config.h"
|
||||
#include "plib/plists.h"
|
||||
@ -26,30 +28,24 @@ namespace netlist
|
||||
|
||||
//FIXME: move to an appropriate place
|
||||
template<bool enabled_ = true>
|
||||
class pspin_lock
|
||||
class pspin_mutex
|
||||
{
|
||||
public:
|
||||
pspin_lock() { }
|
||||
void acquire() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
|
||||
void release() noexcept { m_lock.clear(std::memory_order_release); }
|
||||
pspin_mutex() noexcept { }
|
||||
void lock() noexcept{ while (m_lock.test_and_set(std::memory_order_acquire)) { } }
|
||||
void unlock() noexcept { m_lock.clear(std::memory_order_release); }
|
||||
private:
|
||||
std::atomic_flag m_lock = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
|
||||
template<>
|
||||
class pspin_lock<false>
|
||||
class pspin_mutex<false>
|
||||
{
|
||||
public:
|
||||
void acquire() const noexcept { }
|
||||
void release() const noexcept { }
|
||||
void lock() const noexcept { }
|
||||
void unlock() const noexcept { }
|
||||
};
|
||||
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
using tqlock = pspin_lock<true>;
|
||||
#else
|
||||
using tqlock = pspin_lock<false>;
|
||||
#endif
|
||||
|
||||
template <class Element, class Time>
|
||||
class timed_queue
|
||||
{
|
||||
@ -58,6 +54,18 @@ namespace netlist
|
||||
|
||||
struct entry_t
|
||||
{
|
||||
entry_t() { }
|
||||
entry_t(const Time &t, const Element &o) : m_exec_time(t), m_object(o) { }
|
||||
entry_t(const entry_t &e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { }
|
||||
entry_t(entry_t &&e) : m_exec_time(e.m_exec_time), m_object(e.m_object) { }
|
||||
|
||||
entry_t& operator=(entry_t && other)
|
||||
{
|
||||
m_exec_time = other.m_exec_time;
|
||||
m_object = other.m_object;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Time m_exec_time;
|
||||
Element m_object;
|
||||
};
|
||||
@ -65,37 +73,35 @@ namespace netlist
|
||||
timed_queue(unsigned list_size)
|
||||
: m_list(list_size)
|
||||
{
|
||||
m_lock.acquire();
|
||||
clear();
|
||||
m_lock.release();
|
||||
}
|
||||
|
||||
std::size_t capacity() const { return m_list.size(); }
|
||||
bool empty() const { return (m_end == &m_list[1]); }
|
||||
|
||||
void push(Element o, const Time t) noexcept
|
||||
void push(entry_t &&e) noexcept
|
||||
{
|
||||
/* Lock */
|
||||
m_lock.acquire();
|
||||
tqlock lck(m_lock);
|
||||
entry_t * i = m_end;
|
||||
for (; t > (i - 1)->m_exec_time; --i)
|
||||
while (e.m_exec_time > (i - 1)->m_exec_time)
|
||||
{
|
||||
*(i) = *(i-1);
|
||||
*(i) = std::move(*(i-1));
|
||||
--i;
|
||||
m_prof_sortmove.inc();
|
||||
}
|
||||
*i = { t, o };
|
||||
*i = std::move(e);
|
||||
++m_end;
|
||||
m_prof_call.inc();
|
||||
m_lock.release();
|
||||
}
|
||||
|
||||
entry_t pop() noexcept { return *(--m_end); }
|
||||
const entry_t &top() const noexcept { return *(m_end-1); }
|
||||
entry_t pop() noexcept { return std::move(*(--m_end)); }
|
||||
const entry_t &top() const noexcept { return std::move(*(m_end-1)); }
|
||||
|
||||
void remove(const Element &elem) noexcept
|
||||
{
|
||||
/* Lock */
|
||||
m_lock.acquire();
|
||||
tqlock lck(m_lock);
|
||||
for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
|
||||
{
|
||||
if (i->m_object == elem)
|
||||
@ -103,24 +109,23 @@ namespace netlist
|
||||
m_end--;
|
||||
while (i < m_end)
|
||||
{
|
||||
*i = *(i+1);
|
||||
*i = std::move(*(i+1));
|
||||
++i;
|
||||
}
|
||||
m_lock.release();
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_lock.release();
|
||||
}
|
||||
|
||||
void retime(const Element &elem, const Time t) noexcept
|
||||
{
|
||||
remove(elem);
|
||||
push(elem, t);
|
||||
push(entry_t(t, elem));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
tqlock lck(m_lock);
|
||||
m_end = &m_list[0];
|
||||
/* put an empty element with maximum time into the queue.
|
||||
* the insert algo above will run into this element and doesn't
|
||||
@ -137,8 +142,14 @@ namespace netlist
|
||||
const entry_t & operator[](const std::size_t index) const { return m_list[ 1 + index]; }
|
||||
|
||||
private:
|
||||
#if HAS_OPENMP && USE_OPENMP
|
||||
using tqmutex = pspin_mutex<true>;
|
||||
#else
|
||||
using tqmutex = pspin_mutex<false>;
|
||||
#endif
|
||||
using tqlock = std::lock_guard<tqmutex>;
|
||||
|
||||
tqlock m_lock;
|
||||
tqmutex m_lock;
|
||||
entry_t * m_end;
|
||||
std::vector<entry_t> m_list;
|
||||
|
||||
|
@ -135,7 +135,7 @@ void setup_t::register_dippins_arr(const pstring &terms)
|
||||
}
|
||||
}
|
||||
|
||||
pstring setup_t::objtype_as_str(detail::device_object_t &in) const
|
||||
pstring setup_t::termtype_as_str(detail::core_terminal_t &in) const
|
||||
{
|
||||
switch (in.type())
|
||||
{
|
||||
@ -145,8 +145,6 @@ pstring setup_t::objtype_as_str(detail::device_object_t &in) const
|
||||
return pstring("INPUT");
|
||||
case terminal_t::OUTPUT:
|
||||
return pstring("OUTPUT");
|
||||
case terminal_t::PARAM:
|
||||
return pstring("PARAM");
|
||||
}
|
||||
// FIXME: noreturn
|
||||
log().fatal(MF_1_UNKNOWN_OBJECT_TYPE_1, static_cast<unsigned>(in.type()));
|
||||
@ -199,9 +197,9 @@ void setup_t::register_param(pstring name, param_t ¶m)
|
||||
void setup_t::register_term(detail::core_terminal_t &term)
|
||||
{
|
||||
if (!m_terminals.insert({term.name(), &term}).second)
|
||||
log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, objtype_as_str(term),
|
||||
log().fatal(MF_2_ADDING_1_2_TO_TERMINAL_LIST, termtype_as_str(term),
|
||||
term.name());
|
||||
log().debug("{1} {2}\n", objtype_as_str(term), term.name());
|
||||
log().debug("{1} {2}\n", termtype_as_str(term), term.name());
|
||||
}
|
||||
|
||||
void setup_t::register_link_arr(const pstring &terms)
|
||||
@ -340,12 +338,12 @@ detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in, bool
|
||||
}
|
||||
|
||||
detail::core_terminal_t *setup_t::find_terminal(const pstring &terminal_in,
|
||||
detail::device_object_t::type_t atype, bool required)
|
||||
detail::core_terminal_t::type_t atype, bool required)
|
||||
{
|
||||
const pstring &tname = resolve_alias(terminal_in);
|
||||
auto ret = m_terminals.find(tname);
|
||||
/* look for default */
|
||||
if (ret == m_terminals.end() && atype == detail::device_object_t::OUTPUT)
|
||||
if (ret == m_terminals.end() && atype == detail::core_terminal_t::OUTPUT)
|
||||
{
|
||||
/* look for ".Q" std output */
|
||||
ret = m_terminals.find(tname + ".Q");
|
||||
@ -440,7 +438,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
|
||||
|
||||
auto ret = new_proxy.get();
|
||||
|
||||
#if 1
|
||||
/* connect all existing terminals to new net */
|
||||
|
||||
if (inp.has_net())
|
||||
@ -455,13 +452,6 @@ devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
|
||||
inp.net().m_core_terms.clear(); // clear the list
|
||||
}
|
||||
ret->out().net().add_terminal(inp);
|
||||
#else
|
||||
if (inp.has_net())
|
||||
//fatalerror("logic inputs can only belong to one net!\n");
|
||||
merge_nets(ret->out().net(), inp.net());
|
||||
else
|
||||
ret->out().net().add_terminal(inp);
|
||||
#endif
|
||||
netlist().register_dev(std::move(new_proxy));
|
||||
return ret;
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ namespace netlist
|
||||
std::unordered_map<pstring, detail::core_terminal_t *> m_terminals;
|
||||
|
||||
/* needed by proxy */
|
||||
detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::device_object_t::type_t atype, bool required = true);
|
||||
detail::core_terminal_t *find_terminal(const pstring &outname_in, detail::core_terminal_t::type_t atype, bool required = true);
|
||||
|
||||
private:
|
||||
|
||||
@ -300,7 +300,7 @@ namespace netlist
|
||||
bool connect_input_input(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
|
||||
|
||||
// helpers
|
||||
pstring objtype_as_str(detail::device_object_t &in) const;
|
||||
pstring termtype_as_str(detail::core_terminal_t &in) const;
|
||||
|
||||
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
|
||||
devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
|
||||
|
@ -45,82 +45,83 @@ namespace netlist
|
||||
constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept
|
||||
: m_time(nom * (resolution / den)) { }
|
||||
|
||||
ptime &operator=(const ptime rhs) { m_time = rhs.m_time; return *this; }
|
||||
ptime &operator=(const ptime rhs) noexcept { m_time = rhs.m_time; return *this; }
|
||||
|
||||
ptime &operator+=(const ptime &rhs) { m_time += rhs.m_time; return *this; }
|
||||
ptime &operator-=(const ptime &rhs) { m_time -= rhs.m_time; return *this; }
|
||||
ptime &operator+=(const ptime &rhs) noexcept { m_time += rhs.m_time; return *this; }
|
||||
ptime &operator-=(const ptime &rhs) noexcept { m_time -= rhs.m_time; return *this; }
|
||||
|
||||
friend ptime operator-(ptime lhs, const ptime &rhs)
|
||||
friend constexpr ptime operator-(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
lhs -= rhs;
|
||||
return lhs;
|
||||
return ptime(lhs.m_time - rhs.m_time);
|
||||
}
|
||||
|
||||
friend ptime operator+(ptime lhs, const ptime &rhs)
|
||||
friend constexpr ptime operator+(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
lhs += rhs;
|
||||
return lhs;
|
||||
return ptime(lhs.m_time + rhs.m_time);
|
||||
}
|
||||
|
||||
friend ptime operator*(ptime lhs, const mult_type factor)
|
||||
friend constexpr ptime operator*(const ptime &lhs, const mult_type factor) noexcept
|
||||
{
|
||||
lhs.m_time *= static_cast<internal_type>(factor);
|
||||
return lhs;
|
||||
return ptime(lhs.m_time * static_cast<internal_type>(factor));
|
||||
}
|
||||
|
||||
friend mult_type operator/(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr mult_type operator/(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return static_cast<mult_type>(lhs.m_time / rhs.m_time);
|
||||
}
|
||||
|
||||
friend bool operator<(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return (lhs.m_time < rhs.m_time);
|
||||
}
|
||||
|
||||
friend bool operator>(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return (rhs < lhs);
|
||||
}
|
||||
|
||||
friend bool operator<=(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return !(lhs > rhs);
|
||||
}
|
||||
|
||||
friend bool operator>=(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
friend bool operator==(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return lhs.m_time == rhs.m_time;
|
||||
}
|
||||
|
||||
friend bool operator!=(const ptime &lhs, const ptime &rhs)
|
||||
friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
constexpr internal_type as_raw() const { return m_time; }
|
||||
constexpr double as_double() const { return static_cast<double>(m_time)
|
||||
/ static_cast<double>(resolution); }
|
||||
constexpr internal_type as_raw() const noexcept { return m_time; }
|
||||
constexpr double as_double() const noexcept
|
||||
{
|
||||
return static_cast<double>(m_time)
|
||||
/ static_cast<double>(resolution);
|
||||
}
|
||||
|
||||
// for save states ....
|
||||
internal_type *get_internaltype_ptr() { return &m_time; }
|
||||
internal_type *get_internaltype_ptr() noexcept { return &m_time; }
|
||||
|
||||
static constexpr ptime from_nsec(const internal_type ns) { return ptime(ns, UINT64_C(1000000000)); }
|
||||
static constexpr ptime from_usec(const internal_type us) { return ptime(us, UINT64_C(1000000)); }
|
||||
static constexpr ptime from_msec(const internal_type ms) { return ptime(ms, UINT64_C(1000)); }
|
||||
static constexpr ptime from_hz(const internal_type hz) { return ptime(1 , hz); }
|
||||
static constexpr ptime from_raw(const internal_type raw) { return ptime(raw, resolution); }
|
||||
static constexpr ptime from_double(const double t) { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); }
|
||||
static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); }
|
||||
static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C(1000000)); }
|
||||
static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C(1000)); }
|
||||
static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); }
|
||||
static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); }
|
||||
static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>( t * static_cast<double>(resolution)), resolution); }
|
||||
|
||||
static constexpr ptime zero() { return ptime(0, resolution); }
|
||||
static constexpr ptime quantum() { return ptime(1, resolution); }
|
||||
static constexpr ptime never() { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
|
||||
static constexpr ptime zero() noexcept { return ptime(0, resolution); }
|
||||
static constexpr ptime quantum() noexcept { return ptime(1, resolution); }
|
||||
static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), resolution); }
|
||||
private:
|
||||
constexpr explicit ptime(const internal_type time) : m_time(time) {}
|
||||
internal_type m_time;
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,9 @@ typedef __int128_t INT128;
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifdef RESTRICT
|
||||
#undef RESTRICT
|
||||
#endif
|
||||
#define RESTRICT __restrict__
|
||||
#define ATTR_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
@ -240,7 +243,7 @@ namespace plib {
|
||||
inline R call(O *obj, Targs... args) const
|
||||
{
|
||||
using function_ptr = MEMBER_ABI R (*)(O *obj, Targs... args);
|
||||
return (*reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);
|
||||
return (reinterpret_cast<function_ptr>(m_func))(obj, std::forward<Targs>(args)...);
|
||||
}
|
||||
private:
|
||||
generic_function m_func;
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
template<typename... Args>
|
||||
void emplace(const std::size_t index, Args&&... args)
|
||||
{
|
||||
// allocate on buffer
|
||||
new (&m_buf[index]) C(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
@ -502,30 +502,11 @@ static const pstring pmf_verbose[] =
|
||||
};
|
||||
#endif
|
||||
|
||||
struct tt
|
||||
{
|
||||
void test(int a) {printf ("test :%d\n", a);}
|
||||
int test1() { return 1;}
|
||||
};
|
||||
|
||||
plib::pmfp<void, int> atest;
|
||||
plib::pmfp<int> atest1;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
tool_options_t opts;
|
||||
int ret;
|
||||
|
||||
tt x;
|
||||
|
||||
atest.set(&tt::test, &x);
|
||||
atest1.set(&tt::test1, &x);
|
||||
|
||||
atest(1);
|
||||
int a = atest1();
|
||||
|
||||
printf("%d\n", a);
|
||||
//return 1 ;
|
||||
/* make SIGFPE actually deliver signals on supoorted platforms */
|
||||
plib::fpsignalenabler::global_enable(true);
|
||||
plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW);
|
||||
|
@ -1,13 +1,12 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Couriersud
|
||||
#include <plib/poptions.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "plib/pstring.h"
|
||||
#include "plib/plists.h"
|
||||
#include "plib/pstream.h"
|
||||
#include "plib/poptions.h"
|
||||
#include "nl_setup.h"
|
||||
#include <memory>
|
||||
|
||||
class nlwav_options_t : public plib::options
|
||||
{
|
||||
@ -143,10 +142,10 @@ private:
|
||||
|
||||
static void convert()
|
||||
{
|
||||
plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : new plib::pofilestream(opts.opt_out()));
|
||||
plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : new plib::pifilestream(opts.opt_inp()));
|
||||
plib::postream *fo = (opts.opt_out() == "-" ? &pout_strm : plib::palloc<plib::pofilestream>(opts.opt_out()));
|
||||
plib::pistream *fin = (opts.opt_inp() == "-" ? &pin_strm : plib::palloc<plib::pifilestream>(opts.opt_inp()));
|
||||
plib::putf8_reader reader(*fin);
|
||||
wav_t *wo = new wav_t(*fo, 48000);
|
||||
wav_t *wo = plib::palloc<wav_t>(*fo, 48000U);
|
||||
|
||||
double dt = 1.0 / static_cast<double>(wo->sample_rate());
|
||||
double ct = dt;
|
||||
@ -213,11 +212,11 @@ static void convert()
|
||||
//printf("%f %f\n", t, v);
|
||||
#endif
|
||||
}
|
||||
delete wo;
|
||||
plib::pfree(wo);
|
||||
if (opts.opt_inp() != "-")
|
||||
delete fin;
|
||||
plib::pfree(fin);
|
||||
if (opts.opt_out() != "-")
|
||||
delete fo;
|
||||
plib::pfree(fo);
|
||||
|
||||
if (!opts.opt_quiet())
|
||||
{
|
||||
|
@ -91,11 +91,6 @@ matrix_solver_t::matrix_solver_t(netlist_t &anetlist, const pstring &name,
|
||||
|
||||
matrix_solver_t::~matrix_solver_t()
|
||||
{
|
||||
for (unsigned k = 0; k < m_terms.size(); k++)
|
||||
{
|
||||
plib::pfree(m_terms[k]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
@ -109,7 +104,7 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
for (auto & net : nets)
|
||||
{
|
||||
m_nets.push_back(net);
|
||||
m_terms.push_back(plib::palloc<terms_for_net_t>());
|
||||
m_terms.push_back(plib::make_unique<terms_for_net_t>());
|
||||
m_rails_temp.push_back(plib::palloc<terms_for_net_t>());
|
||||
}
|
||||
|
||||
@ -164,7 +159,6 @@ void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
}
|
||||
break;
|
||||
case terminal_t::OUTPUT:
|
||||
case terminal_t::PARAM:
|
||||
log().fatal(MF_1_UNHANDLED_ELEMENT_1_FOUND,
|
||||
p->name());
|
||||
break;
|
||||
@ -242,7 +236,7 @@ void matrix_solver_t::setup_matrix()
|
||||
/* create a list of non zero elements. */
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
terms_for_net_t * t = m_terms[k];
|
||||
terms_for_net_t * t = m_terms[k].get();
|
||||
/* pretty brutal */
|
||||
int *other = t->connected_net_idx();
|
||||
|
||||
@ -264,7 +258,7 @@ void matrix_solver_t::setup_matrix()
|
||||
*/
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
terms_for_net_t * t = m_terms[k];
|
||||
terms_for_net_t * t = m_terms[k].get();
|
||||
/* pretty brutal */
|
||||
int *other = t->connected_net_idx();
|
||||
|
||||
@ -294,9 +288,9 @@ void matrix_solver_t::setup_matrix()
|
||||
* This should reduce cache misses ...
|
||||
*/
|
||||
|
||||
bool **touched = new bool*[iN];
|
||||
bool **touched = plib::palloc_array<bool *>(iN);
|
||||
for (unsigned k=0; k<iN; k++)
|
||||
touched[k] = new bool[iN];
|
||||
touched[k] = plib::palloc_array<bool>(iN);
|
||||
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
@ -354,8 +348,8 @@ void matrix_solver_t::setup_matrix()
|
||||
}
|
||||
|
||||
for (unsigned k=0; k<iN; k++)
|
||||
delete [] touched[k];
|
||||
delete [] touched;
|
||||
plib::pfree_array(touched[k]);
|
||||
plib::pfree_array(touched);
|
||||
}
|
||||
|
||||
void matrix_solver_t::update_inputs()
|
||||
@ -499,7 +493,7 @@ netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
|
||||
for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++)
|
||||
{
|
||||
analog_net_t *n = m_nets[k];
|
||||
terms_for_net_t *t = m_terms[k];
|
||||
terms_for_net_t *t = m_terms[k].get();
|
||||
|
||||
const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
|
||||
const nl_double hn = cur_ts;
|
||||
@ -548,12 +542,12 @@ void matrix_solver_t::log_stats()
|
||||
log().verbose(" {1:6.3} average newton raphson loops",
|
||||
static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls));
|
||||
log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
|
||||
this->m_stat_calculations(),
|
||||
static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(),
|
||||
this->m_iterative_fail(),
|
||||
100.0 * static_cast<double>(this->m_iterative_fail())
|
||||
/ static_cast<double>(this->m_stat_calculations()),
|
||||
static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations()));
|
||||
this->m_stat_calculations,
|
||||
static_cast<double>(this->m_stat_calculations) / this->netlist().time().as_double(),
|
||||
this->m_iterative_fail,
|
||||
100.0 * static_cast<double>(this->m_iterative_fail)
|
||||
/ static_cast<double>(this->m_stat_calculations),
|
||||
static_cast<double>(this->m_iterative_total) / static_cast<double>(this->m_stat_calculations));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ protected:
|
||||
template <typename T>
|
||||
void build_LE_RHS();
|
||||
|
||||
std::vector<terms_for_net_t *> m_terms;
|
||||
std::vector<std::unique_ptr<terms_for_net_t>> m_terms;
|
||||
std::vector<analog_net_t *> m_nets;
|
||||
std::vector<std::unique_ptr<proxied_analog_output_t>> m_inps;
|
||||
|
||||
|
@ -200,7 +200,7 @@ void matrix_solver_direct_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
/* add RHS element */
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
terms_for_net_t * t = m_terms[k];
|
||||
terms_for_net_t * t = m_terms[k].get();
|
||||
|
||||
if (!plib::container::contains(t->m_nzrd, N()))
|
||||
t->m_nzrd.push_back(N());
|
||||
|
@ -96,7 +96,7 @@ void matrix_solver_GCR_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
bool touched[storage_N][storage_N] = { { false } };
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
for (auto & j : this->m_terms[k]->m_nz)
|
||||
for (auto &j : this->m_terms[k]->m_nz)
|
||||
touched[k][j] = true;
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ unsigned matrix_solver_GCR_t<m_N, storage_N>::vsolve_non_dynamic(const bool newt
|
||||
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
{
|
||||
terms_for_net_t *t = this->m_terms[k];
|
||||
terms_for_net_t *t = this->m_terms[k].get();
|
||||
nl_double gtot_t = 0.0;
|
||||
nl_double RHS_t = 0.0;
|
||||
|
||||
|
@ -81,7 +81,7 @@ void matrix_solver_GMRES_t<m_N, storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
|
||||
for (unsigned k=0; k<iN; k++)
|
||||
{
|
||||
terms_for_net_t * RESTRICT row = this->m_terms[k];
|
||||
terms_for_net_t * RESTRICT row = this->m_terms[k].get();
|
||||
mat.ia[k] = nz;
|
||||
|
||||
for (unsigned j=0; j<row->m_nz.size(); j++)
|
||||
|
@ -297,12 +297,12 @@ void NETLIB_NAME(solver)::post_start()
|
||||
|
||||
switch (net_count)
|
||||
{
|
||||
#if 1
|
||||
#if 0
|
||||
case 1:
|
||||
ms = create_solver<1,1>(1, use_specific);
|
||||
ms = create_solver<1,1>(1, false);
|
||||
break;
|
||||
case 2:
|
||||
ms = create_solver<2,2>(2, use_specific);
|
||||
ms = create_solver<2,2>(2, false);
|
||||
break;
|
||||
case 3:
|
||||
ms = create_solver<3,3>(3, use_specific);
|
||||
@ -322,6 +322,9 @@ void NETLIB_NAME(solver)::post_start()
|
||||
case 8:
|
||||
ms = create_solver<8,8>(8, use_specific);
|
||||
break;
|
||||
case 9:
|
||||
ms = create_solver<9,9>(9, use_specific);
|
||||
break;
|
||||
case 10:
|
||||
ms = create_solver<10,10>(10, use_specific);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user