summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2020-07-25 14:45:11 +0200
committer couriersud <couriersud@gmx.org>2020-07-25 14:47:22 +0200
commit494690081bde2783eac0bc12507d03cd51c5eeb0 (patch)
tree11b6d089e1ede49df0a22c59c3483eb460e37e41
parent2231bf8ae0ab6e752e394ad2c84d843d6a19d0f8 (diff)
netlist: separate nl_base.h into separate header files.
* This clean-up exercise will hopefully make it easier to navigate the core code. Another long term goal is to further straighten the object model.
-rw-r--r--scripts/src/netlist.lua5
-rw-r--r--src/lib/netlist/core/base_objects.h388
-rw-r--r--src/lib/netlist/core/logic_family.h93
-rw-r--r--src/lib/netlist/core/nets.h186
-rw-r--r--src/lib/netlist/core/param.h275
-rw-r--r--src/lib/netlist/core/state_var.h173
-rw-r--r--src/lib/netlist/devices/nld_system.cpp7
-rw-r--r--src/lib/netlist/nl_base.cpp2
-rw-r--r--src/lib/netlist/nl_base.h997
-rw-r--r--src/lib/netlist/nltypes.h20
-rw-r--r--src/lib/netlist/plib/penum.h1
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp1
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h2
13 files changed, 1149 insertions, 1001 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index 0a949221079..1fb67963c29 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -50,7 +50,12 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/nl_setup.cpp",
MAME_DIR .. "src/lib/netlist/nl_setup.h",
MAME_DIR .. "src/lib/netlist/nl_types.h",
+ MAME_DIR .. "src/lib/netlist/core/base_objects.h",
+ MAME_DIR .. "src/lib/netlist/core/logic_family.h",
+ MAME_DIR .. "src/lib/netlist/core/nets.h",
+ MAME_DIR .. "src/lib/netlist/core/param.h",
MAME_DIR .. "src/lib/netlist/core/setup.h",
+ MAME_DIR .. "src/lib/netlist/core/state_var.h",
MAME_DIR .. "src/lib/netlist/plib/pconfig.h",
MAME_DIR .. "src/lib/netlist/plib/palloc.h",
MAME_DIR .. "src/lib/netlist/plib/pchrono.h",
diff --git a/src/lib/netlist/core/base_objects.h b/src/lib/netlist/core/base_objects.h
new file mode 100644
index 00000000000..c697617e265
--- /dev/null
+++ b/src/lib/netlist/core/base_objects.h
@@ -0,0 +1,388 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file param.h
+///
+
+#ifndef NL_CORE_BASE_OBJECTS_H_
+#define NL_CORE_BASE_OBJECTS_H_
+
+#include "state_var.h"
+
+#include "../nltypes.h"
+
+#include "../plib/palloc.h"
+#include "../plib/pmempool.h"
+#include "../plib/pchrono.h"
+#include "../plib/pexception.h"
+#include "../plib/plists.h"
+
+#include <unordered_map>
+
+namespace netlist
+{
+
+ //============================================================
+ // Exceptions
+ //============================================================
+
+ /// \brief Generic netlist exception.
+ /// The exception is used in all events which are considered fatal.
+
+ class nl_exception : public plib::pexception
+ {
+ public:
+ /// \brief Constructor.
+ /// Allows a descriptive text to be passed to the exception
+
+ explicit nl_exception(const pstring &text //!< text to be passed
+ )
+ : plib::pexception(text) { }
+
+ /// \brief Constructor.
+ /// Allows to use \ref plib::pfmt logic to be used in exception
+
+ 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)...)) { }
+ };
+
+ namespace detail {
+
+ template <typename C, typename T>
+ struct property_store_t
+ {
+ using value_type = T;
+ using key_type = const C *;
+ static void add(key_type obj, const value_type &aname) noexcept
+ {
+ store().insert({obj, aname});
+ }
+
+ static value_type *get(key_type obj) noexcept
+ {
+ try
+ {
+ auto ret(store().find(obj));
+ if (ret == store().end())
+ return nullptr;
+ return &ret->second;
+ }
+ catch (...)
+ {
+ plib::terminate("exception in property_store_t.get()");
+ return static_cast<value_type *>(nullptr);
+ }
+ }
+
+ static void remove(key_type obj) noexcept
+ {
+ store().erase(store().find(obj));
+ }
+
+ static std::unordered_map<key_type, value_type> &store() noexcept
+ {
+ static std::unordered_map<key_type, value_type> lstore;
+ return lstore;
+ }
+
+ };
+
+ // -----------------------------------------------------------------------------
+ // object_t
+ // -----------------------------------------------------------------------------
+
+ /// \brief The base class for netlist devices, terminals and parameters.
+ ///
+ /// This class serves as the base class for all device, terminal and
+ /// objects.
+
+ class object_t
+ {
+ public:
+
+ /// \brief Constructor.
+ /// Every class derived from the object_t class must have a name.
+ ///
+ /// \param aname string containing name of the object
+
+ explicit object_t(const pstring &aname)
+ {
+ props::add(this, aname);
+ }
+
+ PCOPYASSIGNMOVE(object_t, delete)
+ /// \brief return name of the object
+ ///
+ /// \returns name of the object.
+
+ const pstring &name() const noexcept
+ {
+ return *props::get(this);
+ }
+
+ protected:
+
+ using props = property_store_t<object_t, pstring>;
+
+ // only childs should be destructible
+ ~object_t() noexcept
+ {
+ props::remove(this);
+ }
+
+ private:
+ };
+
+ /// \brief Base class for all objects bejng owned by a netlist
+ ///
+ /// The object provides adds \ref netlist_state_t and \ref netlist_t
+ /// accessors.
+ ///
+ class netlist_object_t : public object_t
+ {
+ public:
+ explicit netlist_object_t(netlist_t &nl, const pstring &name)
+ : object_t(name)
+ , m_netlist(nl)
+ { }
+
+ ~netlist_object_t() = default;
+
+ PCOPYASSIGNMOVE(netlist_object_t, delete)
+
+ netlist_state_t & state() noexcept;
+ const netlist_state_t & state() const noexcept;
+
+ netlist_t & exec() noexcept { return m_netlist; }
+ const netlist_t & exec() const noexcept { return m_netlist; }
+
+ // to ease template design
+ template<typename T, typename... Args>
+ device_arena::unique_ptr<T> make_pool_object(Args&&... args);
+
+ private:
+ netlist_t & m_netlist;
+
+ };
+
+ // -----------------------------------------------------------------------------
+ // device_object_t
+ // -----------------------------------------------------------------------------
+
+ /// \brief Base class for all objects being owned by a device.
+ ///
+ /// Serves as the base class of all objects being owned by a device.
+ ///
+ /// The class also supports device-less objects. In this case,
+ /// nullptr is passed in as the device object.
+ ///
+
+ class device_object_t : public object_t
+ {
+ public:
+ /// \brief Constructor.
+ ///
+ /// \param dev pointer to device owning the object.
+ /// \param name string holding the name of the device
+
+ device_object_t(core_device_t *dev, const pstring &name);
+
+ /// \brief returns reference to owning device.
+ /// \returns reference to owning device.
+
+ core_device_t &device() noexcept { return *m_device; }
+ const core_device_t &device() const noexcept { return *m_device; }
+
+ /// \brief The netlist owning the owner of this object.
+ /// \returns reference to netlist object.
+
+ netlist_state_t &state() noexcept;
+ const netlist_state_t &state() const noexcept;
+
+ netlist_t &exec() noexcept;
+ const netlist_t &exec() const noexcept;
+
+ private:
+ core_device_t * m_device;
+ };
+
+ // -----------------------------------------------------------------------------
+ // core_terminal_t
+ // -----------------------------------------------------------------------------
+
+ /// \brief Base class for all terminals.
+ ///
+ /// All terminals are derived from this class.
+ ///
+ class core_terminal_t : public device_object_t,
+ public plib::linkedlist_t<core_terminal_t>::element_t
+ {
+ public:
+ /// \brief Number of signal bits
+ ///
+ /// Going forward setting this to 8 will allow 8-bit signal
+ /// busses to be used in netlist, e.g. for more complex memory
+ /// arrangements.
+ /// Mimimum value is 2 here to support tristate output on proxies.
+ static constexpr const unsigned int INP_BITS = 2;
+
+ static constexpr const unsigned int INP_MASK = (1 << INP_BITS) - 1;
+ static constexpr const unsigned int INP_HL_SHIFT = 0;
+ static constexpr const unsigned int INP_LH_SHIFT = INP_BITS;
+
+ static constexpr netlist_sig_t OUT_TRISTATE() { return INP_MASK; }
+
+ static_assert(INP_BITS * 2 <= sizeof(netlist_sig_t) * 8, "netlist_sig_t size not sufficient");
+
+ enum state_e {
+ STATE_INP_PASSIVE = 0,
+ STATE_INP_HL = (INP_MASK << INP_HL_SHIFT),
+ STATE_INP_LH = (INP_MASK << INP_LH_SHIFT),
+ STATE_INP_ACTIVE = STATE_INP_HL | STATE_INP_LH,
+ STATE_OUT = (1 << (2*INP_BITS)),
+ STATE_BIDIR = (1 << (2*INP_BITS + 1))
+ };
+
+ core_terminal_t(core_device_t &dev, const pstring &aname,
+ state_e state, nldelegate delegate);
+ virtual ~core_terminal_t() noexcept = default;
+
+ PCOPYASSIGNMOVE(core_terminal_t, delete)
+
+ /// \brief The object type.
+ /// \returns type of the object
+ terminal_type type() const noexcept(false);
+
+ /// \brief 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 terminal_type atype) const noexcept(false) { return (type() == atype); }
+
+ void set_net(net_t *anet) noexcept { m_net = anet; }
+ void clear_net() noexcept { m_net = nullptr; }
+ bool has_net() const noexcept { return (m_net != nullptr); }
+
+ net_t & net() const noexcept { return *m_net;}
+
+ bool is_logic() const noexcept;
+ bool is_logic_input() const noexcept;
+ bool is_logic_output() const noexcept;
+ bool is_tristate_output() const noexcept;
+ bool is_analog() const noexcept;
+ bool is_analog_input() const noexcept;
+ bool is_analog_output() const noexcept;
+
+ bool is_state(state_e astate) const noexcept { return (m_state == astate); }
+ state_e terminal_state() const noexcept { return m_state; }
+ void set_state(state_e astate) noexcept { m_state = astate; }
+
+ void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
+
+ #if NL_USE_COPY_INSTEAD_OF_REFERENCE
+ void set_copied_input(netlist_sig_t val) noexcept
+ {
+ m_Q = val;
+ }
+
+ state_var_sig m_Q;
+ #else
+ void set_copied_input(netlist_sig_t val) const noexcept { plib::unused_var(val); } // NOLINT: static means more message elsewhere
+ #endif
+
+ void set_delegate(const nldelegate &delegate) noexcept { m_delegate = delegate; }
+ const nldelegate &delegate() const noexcept { return m_delegate; }
+ inline void run_delegate() noexcept { return m_delegate(); }
+ private:
+ nldelegate m_delegate;
+ net_t * m_net;
+ state_var<state_e> m_state;
+ };
+
+
+ } // namespace detail
+
+ // -----------------------------------------------------------------------------
+ // core_device_t
+ // -----------------------------------------------------------------------------
+ // FIXME: belongs into detail namespace
+ class core_device_t : public detail::netlist_object_t
+ {
+ public:
+ core_device_t(netlist_state_t &owner, const pstring &name);
+ core_device_t(core_device_t &owner, const pstring &name);
+
+ PCOPYASSIGNMOVE(core_device_t, delete)
+
+ virtual ~core_device_t() noexcept = default;
+
+ void do_inc_active() noexcept
+ {
+ if (m_hint_deactivate)
+ {
+ if (++m_active_outputs == 1)
+ {
+ if (m_stats)
+ m_stats->m_stat_inc_active.inc();
+ inc_active();
+ }
+ }
+ }
+
+ void do_dec_active() noexcept
+ {
+ if (m_hint_deactivate)
+ if (--m_active_outputs == 0)
+ {
+ dec_active();
+ }
+ }
+
+ void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; }
+ bool get_hint_deactivate() const noexcept { return m_hint_deactivate; }
+ // Has to be set in device reset
+ void set_active_outputs(int n) noexcept { m_active_outputs = n; }
+
+ // stats
+ struct stats_t
+ {
+ // NL_KEEP_STATISTICS
+ plib::pperftime_t<true> m_stat_total_time;
+ plib::pperfcount_t<true> m_stat_call_count;
+ plib::pperfcount_t<true> m_stat_inc_active;
+ };
+
+ stats_t * stats() const noexcept { return m_stats.get(); }
+#if 0
+ virtual void update() noexcept { }
+#endif
+ virtual void reset() { }
+
+ protected:
+
+ virtual void inc_active() noexcept { }
+ virtual void dec_active() noexcept { }
+
+ log_type & log();
+
+ public:
+ virtual void timestep(timestep_type ts_type, nl_fptype st) noexcept { plib::unused_var(ts_type, st); }
+ virtual void update_terminals() noexcept { }
+
+ virtual void update_param() noexcept {}
+ virtual bool is_dynamic() const noexcept { return false; }
+ virtual bool is_timestep() const noexcept { return false; }
+
+ private:
+ bool m_hint_deactivate;
+ state_var_s32 m_active_outputs;
+ device_arena::unique_ptr<stats_t> m_stats;
+ };
+
+} // namespace netlist
+
+
+#endif // NL_CORE_BASE_OBJECTS_H_
diff --git a/src/lib/netlist/core/logic_family.h b/src/lib/netlist/core/logic_family.h
new file mode 100644
index 00000000000..e7e7c51081f
--- /dev/null
+++ b/src/lib/netlist/core/logic_family.h
@@ -0,0 +1,93 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file logic_family.h
+///
+
+#ifndef NL_CORE_LOGIC_FAMILY_H_
+#define NL_CORE_LOGIC_FAMILY_H_
+
+#include "../nltypes.h"
+#include "../plib/pstring.h"
+
+namespace netlist
+{
+ /// \brief Logic families descriptors are used to create proxy devices.
+ /// The logic family describes the analog capabilities of logic devices,
+ /// inputs and outputs.
+
+ class logic_family_desc_t
+ {
+ public:
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
+ logic_family_desc_t()
+ {
+ }
+
+ PCOPYASSIGNMOVE(logic_family_desc_t, delete)
+
+ virtual ~logic_family_desc_t() noexcept = default;
+
+ virtual device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_output_t *proxied) const = 0;
+ virtual device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
+ const logic_input_t *proxied) const = 0;
+
+ 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; }
+ nl_fptype high_offset_V() const noexcept{ return m_high_VO; }
+ nl_fptype R_low() const noexcept{ return m_R_low; }
+ nl_fptype R_high() const noexcept{ return m_R_high; }
+
+ bool is_above_high_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
+ { return V > high_thresh_V(VN, VP); }
+
+ bool is_below_low_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
+ { return V < low_thresh_V(VN, VP); }
+
+ pstring vcc_pin() const { return pstring(m_vcc); }
+ pstring gnd_pin() const { return pstring(m_gnd); }
+
+ nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
+ nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
+ nl_fptype m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0"
+ nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1"
+ nl_fptype m_R_low; //!< low output resistance. Value of series resistor used for low output
+ nl_fptype m_R_high; //!< high output resistance. Value of series resistor used for high output
+ const char *m_vcc; //!< default power pin name for positive supply
+ const char *m_gnd; //!< default power pin name for negative supply
+ };
+
+ /// \brief Base class for devices, terminals, outputs and inputs which support
+ /// logic families.
+ /// This class is a storage container to store the logic family for a
+ /// netlist object. You will not directly use it. Please refer to
+ /// \ref NETLIB_FAMILY to learn how to define a logic family for a device.
+ ///
+ /// All terminals inherit the family description from the device
+ /// The default is the ttl family, but any device can override the family.
+ /// For individual terminals, the family can be overwritten as well.
+ ///
+
+ class logic_family_t
+ {
+ public:
+ logic_family_t() : m_logic_family(nullptr) {}
+ logic_family_t(const logic_family_desc_t *d) : m_logic_family(d) {}
+ PCOPYASSIGNMOVE(logic_family_t, delete)
+
+ const logic_family_desc_t *logic_family() const noexcept { return m_logic_family; }
+ void set_logic_family(const logic_family_desc_t *fam) noexcept { m_logic_family = fam; }
+
+ protected:
+ ~logic_family_t() noexcept = default; // prohibit polymorphic destruction
+ private:
+ const logic_family_desc_t *m_logic_family;
+ };
+
+} // namespace netlist
+
+
+#endif // NL_CORE_LOGIC_FAMILY_H_
diff --git a/src/lib/netlist/core/nets.h b/src/lib/netlist/core/nets.h
new file mode 100644
index 00000000000..96ecdf1836f
--- /dev/null
+++ b/src/lib/netlist/core/nets.h
@@ -0,0 +1,186 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file nets.h
+///
+
+#ifndef NL_CORE_NETS_H_
+#define NL_CORE_NETS_H_
+
+#include "base_objects.h"
+#include "state_var.h"
+
+#include "../nltypes.h"
+#include "../plib/pstring.h"
+#include "../plib/plists.h"
+
+namespace netlist
+{
+
+ namespace detail {
+
+ // -----------------------------------------------------------------------------
+ // net_t
+ // -----------------------------------------------------------------------------
+
+ class net_t : public netlist_object_t
+ {
+ public:
+
+ enum class queue_status
+ {
+ DELAYED_DUE_TO_INACTIVE = 0,
+ QUEUED,
+ DELIVERED
+ };
+
+ net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal = nullptr);
+
+ PCOPYASSIGNMOVE(net_t, delete)
+
+ virtual ~net_t() noexcept = default;
+
+ virtual void reset() noexcept;
+
+ void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
+
+ void toggle_and_push_to_queue(const netlist_time &delay) noexcept
+ {
+ toggle_new_Q();
+ push_to_queue(delay);
+ }
+
+ void push_to_queue(const netlist_time &delay) noexcept;
+ NVCC_CONSTEXPR bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
+
+ template <bool KEEP_STATS>
+ inline void update_devs() noexcept;
+
+ netlist_time_ext next_scheduled_time() const noexcept { return m_next_scheduled_time; }
+ void set_next_scheduled_time(netlist_time_ext ntime) noexcept { m_next_scheduled_time = ntime; }
+
+ NVCC_CONSTEXPR bool is_rail_net() const noexcept { return !(m_railterminal == nullptr); }
+ core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
+
+ bool has_connections() const noexcept { return !m_core_terms.empty(); }
+
+ void add_to_active_list(core_terminal_t &term) noexcept;
+ void remove_from_active_list(core_terminal_t &term) noexcept;
+
+ // setup stuff
+
+ bool is_logic() const noexcept;
+ bool is_analog() const noexcept;
+
+ void rebuild_list(); // rebuild m_list after a load
+
+ std::vector<core_terminal_t *> &core_terms() noexcept { return m_core_terms; }
+
+ void update_inputs() noexcept
+ {
+#if NL_USE_COPY_INSTEAD_OF_REFERENCE
+ for (auto & term : m_core_terms)
+ term->m_Q = m_cur_Q;
+#endif
+ // nothing needs to be done if define not set
+ }
+
+ protected:
+
+ // only used for logic nets
+ NVCC_CONSTEXPR netlist_sig_t Q() const noexcept { return m_cur_Q; }
+
+ // only used for logic nets
+ void initial(netlist_sig_t val) noexcept
+ {
+ m_cur_Q = m_new_Q = val;
+ update_inputs();
+ }
+
+ // only used for logic nets
+ inline void set_Q_and_push(const netlist_sig_t &newQ, const netlist_time &delay) noexcept
+ {
+ if (newQ != m_new_Q)
+ {
+ m_new_Q = newQ;
+ push_to_queue(delay);
+ }
+ }
+
+ // only used for logic nets
+ inline void set_Q_time(const netlist_sig_t &newQ, const netlist_time_ext &at) noexcept
+ {
+ if (newQ != m_new_Q)
+ {
+ m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
+ m_next_scheduled_time = at;
+ m_cur_Q = m_new_Q = newQ;
+ update_inputs();
+ }
+ else
+ {
+ m_cur_Q = newQ;
+ update_inputs();
+ }
+ }
+
+ private:
+ state_var<netlist_sig_t> m_new_Q;
+ state_var<netlist_sig_t> m_cur_Q;
+ state_var<queue_status> m_in_queue;
+ state_var<netlist_time_ext> m_next_scheduled_time;
+
+ core_terminal_t * m_railterminal;
+ plib::linkedlist_t<core_terminal_t> m_list_active;
+ std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
+
+ template <bool KEEP_STATS, typename T, typename S>
+ void process(T mask, const S &sig) noexcept;
+ };
+ } // namespace detail
+
+ class analog_net_t : public detail::net_t
+ {
+ public:
+
+ analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
+
+ void reset() noexcept override;
+
+ nl_fptype Q_Analog() const noexcept { return m_cur_Analog; }
+ void set_Q_Analog(nl_fptype v) noexcept { m_cur_Analog = v; }
+ // used by solver code ...
+ nl_fptype *Q_Analog_state_ptr() noexcept { return &m_cur_Analog(); }
+
+ //FIXME: needed by current solver code
+ solver::matrix_solver_t *solver() const noexcept { return m_solver; }
+ void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; }
+
+ friend constexpr bool operator==(const analog_net_t &lhs, const analog_net_t &rhs) noexcept
+ {
+ return &lhs == &rhs;
+ }
+
+ private:
+ state_var<nl_fptype> m_cur_Analog;
+ solver::matrix_solver_t *m_solver;
+ };
+
+ class logic_net_t : public detail::net_t
+ {
+ public:
+
+ logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
+
+ using detail::net_t::Q;
+ using detail::net_t::initial;
+ using detail::net_t::set_Q_and_push;
+ using detail::net_t::set_Q_time;
+ };
+
+
+} // namespace netlist
+
+
+#endif // NL_CORE_NETS_H_
diff --git a/src/lib/netlist/core/param.h b/src/lib/netlist/core/param.h
new file mode 100644
index 00000000000..80769f2d47e
--- /dev/null
+++ b/src/lib/netlist/core/param.h
@@ -0,0 +1,275 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file param.h
+///
+
+#ifndef NL_CORE_PARAM_H_
+#define NL_CORE_PARAM_H_
+
+#if 0
+#include "../nl_config.h"
+#include "../nl_factory.h"
+#include "../nl_setup.h"
+
+#include "../plib/ppreprocessor.h"
+
+#include <initializer_list>
+#include <stack>
+#include <unordered_map>
+#include <vector>
+#endif
+
+#include "../nltypes.h"
+
+#include "base_objects.h"
+
+#include "../plib/pstream.h"
+#include "../plib/pstring.h"
+#include "../plib/palloc.h"
+
+#include <memory>
+
+namespace netlist
+{
+ /// @brief Base class for all device parameters
+ ///
+ /// All device parameters classes derive from this object.
+ class param_t : public detail::device_object_t
+ {
+ public:
+
+ enum param_type_t {
+ STRING,
+ DOUBLE,
+ INTEGER,
+ LOGIC,
+ POINTER // Special-case which is always initialized at MAME startup time
+ };
+
+ //deviceless, it's the responsibility of the owner to register!
+ param_t(const pstring &name);
+
+ param_t(core_device_t &device, const pstring &name);
+
+ PCOPYASSIGNMOVE(param_t, delete)
+ virtual ~param_t() noexcept;
+
+ param_type_t param_type() const noexcept(false);
+
+ virtual pstring valstr() const = 0;
+
+ protected:
+
+ void update_param() noexcept;
+
+ pstring get_initial(const core_device_t *dev, bool *found) const;
+
+ template<typename C>
+ void set_and_update_param(C &p, const C v) noexcept
+ {
+ if (p != v)
+ {
+ p = v;
+ update_param();
+ }
+ }
+
+ };
+
+ // -----------------------------------------------------------------------------
+ // numeric parameter template
+ // -----------------------------------------------------------------------------
+
+ template <typename T>
+ class param_num_t final: public param_t
+ {
+ public:
+ using value_type = T;
+
+ param_num_t(core_device_t &device, const pstring &name, T val) noexcept(false);
+
+ T operator()() const noexcept { return m_param; }
+ operator T() const noexcept { return m_param; }
+
+ void set(const T &param) noexcept { set_and_update_param(m_param, param); }
+
+ pstring valstr() const override
+ {
+ return plib::pfmt("{}").e(gsl::narrow<nl_fptype>(m_param));
+ }
+
+ private:
+ T m_param;
+ };
+
+ template <typename T>
+ class param_enum_t final: public param_t
+ {
+ public:
+ using value_type = T;
+
+ param_enum_t(core_device_t &device, const pstring &name, T val) noexcept(false);
+
+ T operator()() const noexcept { return m_param; }
+ operator T() const noexcept { return m_param; }
+ void set(const T &param) noexcept { set_and_update_param(m_param, param); }
+
+ pstring valstr() const override
+ {
+ // returns the numerical value
+ return plib::pfmt("{}")(static_cast<int>(m_param));
+ }
+ private:
+ T m_param;
+ };
+
+ // FIXME: these should go as well
+ using param_logic_t = param_num_t<bool>;
+ using param_int_t = param_num_t<int>;
+ using param_fp_t = param_num_t<nl_fptype>;
+
+ // -----------------------------------------------------------------------------
+ // pointer parameter
+ // -----------------------------------------------------------------------------
+
+ // FIXME: not a core component -> legacy
+ class param_ptr_t final: public param_t
+ {
+ public:
+ param_ptr_t(core_device_t &device, const pstring &name, std::uint8_t* val);
+ std::uint8_t * operator()() const noexcept { return m_param; }
+ void set(std::uint8_t *param) noexcept { set_and_update_param(m_param, param); }
+
+ pstring valstr() const override
+ {
+ // returns something which errors
+ return pstring("PTRERROR");
+ }
+
+ private:
+ std::uint8_t* m_param;
+ };
+
+ // -----------------------------------------------------------------------------
+ // string parameter
+ // -----------------------------------------------------------------------------
+
+ class param_str_t : public param_t
+ {
+ public:
+ param_str_t(core_device_t &device, const pstring &name, const pstring &val);
+ param_str_t(netlist_state_t &state, const pstring &name, const pstring &val);
+
+ pstring operator()() const noexcept { return str(); }
+ void set(const pstring &param)
+ {
+ if (*m_param != param)
+ {
+ *m_param = param;
+ changed();
+ update_param();
+ }
+ }
+ pstring valstr() const override
+ {
+ return *m_param;
+ }
+ protected:
+ virtual void changed() noexcept;
+ pstring str() const noexcept { return *m_param; }
+ private:
+ host_arena::unique_ptr<pstring> m_param;
+ };
+
+ // -----------------------------------------------------------------------------
+ // model parameter
+ // -----------------------------------------------------------------------------
+
+ class param_model_t : public param_str_t
+ {
+ public:
+
+ template <typename T>
+ class value_base_t
+ {
+ public:
+ template <typename P, typename Y=T, typename DUMMY = std::enable_if_t<plib::is_arithmetic<Y>::value>>
+ value_base_t(P &param, const pstring &name)
+ : m_value(gsl::narrow<T>(param.value(name)))
+ {
+ }
+ template <typename P, typename Y=T, std::enable_if_t<!plib::is_arithmetic<Y>::value, int> = 0>
+ value_base_t(P &param, const pstring &name)
+ : m_value(static_cast<T>(param.value_str(name)))
+ {
+ }
+ T operator()() const noexcept { return m_value; }
+ operator T() const noexcept { return m_value; }
+ private:
+ const T m_value;
+ };
+
+ using value_t = value_base_t<nl_fptype>;
+ using value_str_t = value_base_t<pstring>;
+
+ param_model_t(core_device_t &device, const pstring &name, const pstring &val)
+ : param_str_t(device, name, val)
+ {
+ }
+
+ pstring value_str(const pstring &entity);
+ nl_fptype value(const pstring &entity);
+ pstring type();
+ // hide this
+ void set(const pstring &param) = delete;
+ protected:
+ void changed() noexcept override;
+ private:
+ };
+
+ // -----------------------------------------------------------------------------
+ // data parameter
+ // -----------------------------------------------------------------------------
+
+ class param_data_t : public param_str_t
+ {
+ public:
+ param_data_t(core_device_t &device, const pstring &name)
+ : param_str_t(device, name, "")
+ {
+ }
+
+ std::unique_ptr<std::istream> stream();
+ protected:
+ void changed() noexcept override { }
+ };
+
+ // -----------------------------------------------------------------------------
+ // rom parameter
+ // -----------------------------------------------------------------------------
+
+ template <typename ST, std::size_t AW, std::size_t DW>
+ class param_rom_t final: public param_data_t
+ {
+ public:
+
+ param_rom_t(core_device_t &device, const pstring &name);
+
+ const ST & operator[] (std::size_t n) const noexcept { return m_data[n]; }
+ protected:
+ void changed() noexcept override
+ {
+ plib::istream_read(*stream(), m_data.data(), 1<<AW);
+ }
+
+ private:
+ std::array<ST, 1 << AW> m_data;
+ };
+
+
+} // namespace netlist
+
+
+#endif // NL_CORE_PARAM_H_
diff --git a/src/lib/netlist/core/state_var.h b/src/lib/netlist/core/state_var.h
new file mode 100644
index 00000000000..922789f584e
--- /dev/null
+++ b/src/lib/netlist/core/state_var.h
@@ -0,0 +1,173 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+
+///
+/// \file state_var.h
+///
+
+#ifndef NL_CORE_STATE_VAR_H_
+#define NL_CORE_STATE_VAR_H_
+
+#include "../nltypes.h"
+#include "../plib/pstring.h"
+
+namespace netlist
+{
+ /// \brief A persistent variable template.
+ /// Use the state_var template to define a variable whose value is saved.
+ /// Within a device definition use
+ ///
+ /// NETLIB_OBJECT(abc)
+ /// {
+ /// NETLIB_CONSTRUCTOR(abc)
+ /// , m_var(*this, "myvar", 0)
+ /// ...
+ /// state_var<unsigned> m_var;
+ /// }
+ template <typename T>
+ struct state_var
+ {
+ public:
+
+ using value_type = T;
+
+ template <typename O>
+ //! Constructor.
+ 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
+ );
+
+ template <typename O>
+ //! Constructor.
+ state_var(O &owner, //!< owner must have a netlist() method.
+ const pstring &name //!< identifier/name for this state variable
+ );
+
+ PMOVEASSIGN(state_var, delete)
+
+ //! Destructor.
+ ~state_var() noexcept = default;
+
+ //! Copy Constructor removed.
+ constexpr state_var(const state_var &rhs) = delete;
+ //! Assignment operator to assign value of a state var.
+ constexpr state_var &operator=(const state_var &rhs) noexcept
+ {
+ if (this != &rhs)
+ m_value = rhs.m_value;
+ return *this;
+ } // OSX doesn't like noexcept
+ //! Assignment operator to assign value of type T.
+ constexpr state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; }
+ //! Assignment move operator to assign value of type T.
+ constexpr state_var &operator=(T &&rhs) noexcept { std::swap(m_value, rhs); return *this; }
+ //! Return non-const value of state variable.
+ constexpr operator T & () noexcept { return m_value; }
+ //! Return const value of state variable.
+ constexpr operator const T & () const noexcept { return m_value; }
+ //! Return non-const value of state variable.
+ constexpr T & var() noexcept { return m_value; }
+ //! Return const value of state variable.
+ constexpr const T & var() const noexcept { return m_value; }
+ //! Return non-const value of state variable.
+ constexpr T & operator ()() noexcept { return m_value; }
+ //! Return const value of state variable.
+ constexpr const T & operator ()() const noexcept { return m_value; }
+ //! Access state variable by ->.
+ constexpr T * operator->() noexcept { return &m_value; }
+ //! Access state variable by const ->.
+ constexpr const T * operator->() const noexcept{ return &m_value; }
+
+ private:
+ T m_value;
+ };
+
+ /// \brief A persistent array template.
+ /// Use this state_var template to define an array whose contents are saved.
+ /// Please refer to \ref state_var.
+ ///
+ /// \tparam C container class to use.
+
+ template <typename C>
+ struct state_container : public C
+ {
+ public:
+ using value_type = typename C::value_type;
+ //! Constructor.
+ template <typename O>
+ state_container(O &owner, //!< owner must have a netlist() method.
+ const pstring &name, //!< identifier/name for this state variable
+ const value_type &value //!< Initial value after construction
+ );
+ //! Constructor.
+ template <typename O>
+ state_container(O &owner, //!< owner must have a netlist() method.
+ const pstring &name, //!< identifier/name for this state variable
+ std::size_t n, //!< number of elements to allocate
+ const value_type &value //!< Initial value after construction
+ );
+ //! Copy Constructor.
+ state_container(const state_container &rhs) noexcept = default;
+ //! Destructor.
+ ~state_container() noexcept = default;
+ //! Move Constructor.
+ state_container(state_container &&rhs) noexcept = default;
+ state_container &operator=(const state_container &rhs) noexcept = default;
+ state_container &operator=(state_container &&rhs) noexcept = default;
+ };
+
+ // -----------------------------------------------------------------------------
+ // State variables - predefined and c++11 non-optional
+ // -----------------------------------------------------------------------------
+
+ /// \brief predefined state variable type for uint8_t
+ using state_var_u8 = state_var<std::uint8_t>;
+ /// \brief predefined state variable type for int8_t
+ using state_var_s8 = state_var<std::int8_t>;
+
+ /// \brief predefined state variable type for uint32_t
+ using state_var_u32 = state_var<std::uint32_t>;
+ /// \brief predefined state variable type for int32_t
+ using state_var_s32 = state_var<std::int32_t>;
+ /// \brief predefined state variable type for sig_t
+ using state_var_sig = state_var<netlist_sig_t>;
+
+ template <typename T>
+ template <typename O>
+ state_var<T>::state_var(O &owner, const pstring &name, const T &value)
+ : m_value(value)
+ {
+ owner.state().save(owner, m_value, owner.name(), name);
+ }
+
+ template <typename T>
+ template <typename O>
+ state_var<T>::state_var(O &owner, const pstring &name)
+ {
+ owner.state().save(owner, m_value, owner.name(), name);
+ }
+
+ template <typename C>
+ template <typename O>
+ state_container<C>::state_container(O &owner, const pstring &name,
+ const state_container<C>::value_type & value)
+ {
+ owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
+ for (std::size_t i=0; i < this->size(); i++)
+ (*this)[i] = value;
+ }
+
+ template <typename C>
+ template <typename O>
+ state_container<C>::state_container(O &owner, const pstring &name,
+ std::size_t n, const state_container<C>::value_type & value)
+ : C(n, value)
+ {
+ owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
+ }
+
+} // namespace netlist
+
+
+#endif // NL_CORE_STATE_VAR_H_
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index 78b5a3af923..a1477b6dce4 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -13,12 +13,10 @@ namespace netlist
{
namespace devices
{
- // ----------------------------------------------------------------------------------------
- // netlistparams
- // ----------------------------------------------------------------------------------------
-
+ NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "")
NETLIB_DEVICE_IMPL(nc_pin, "NC_PIN", "")
+
NETLIB_DEVICE_IMPL(frontier, "FRONTIER_DEV", "+I,+G,+Q")
NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC")
NETLIB_DEVICE_IMPL(analog_input, "ANALOG_INPUT", "IN")
@@ -39,7 +37,6 @@ namespace devices
NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ")
NETLIB_DEVICE_IMPL(gnd, "GNDA", "")
- NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "")
using NETLIB_NAME(logic_input8) = NETLIB_NAME(logic_inputN)<8>;
NETLIB_DEVICE_IMPL(logic_input8, "LOGIC_INPUT8", "IN,MODEL")
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 61265e9cb65..22baf636461 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -12,7 +12,7 @@
#include "core/setup.h"
#include "devices/nlid_proxy.h"
-#include "devices/nlid_system.h"
+#include "devices/nlid_system.h" // netlist_params
#include "macro/nlm_base.h"
#include "nl_base.h"
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 66caae7519c..45b64c5e122 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -12,6 +12,12 @@
#error "nl_base.h included. Please correct."
#endif
+#include "core/base_objects.h"
+#include "core/param.h"
+#include "core/state_var.h"
+#include "core/logic_family.h"
+#include "core/nets.h"
+
#include "plib/palloc.h" // owned_ptr
#include "plib/pfunction.h"
#include "plib/plists.h"
@@ -203,614 +209,7 @@ class NETLIB_NAME(name) : public delegator_t<base_device_t>
namespace netlist
{
- enum class timestep_type
- {
- FORWARD, ///< forward time
- RESTORE ///< restore state before last forward
- };
-
- /// \brief Delegate type for device notification.
- ///
- using nldelegate = plib::pmfp<void>;
- using nldelegate_ts = plib::pmfp<void, timestep_type, nl_fptype>;
- using nldelegate_dyn = plib::pmfp<void>;
-
- //============================================================
- // Exceptions
- //============================================================
-
- /// \brief Generic netlist exception.
- /// The exception is used in all events which are considered fatal.
-
- class nl_exception : public plib::pexception
- {
- public:
- /// \brief Constructor.
- /// Allows a descriptive text to be passed to the exception
-
- explicit nl_exception(const pstring &text //!< text to be passed
- )
- : plib::pexception(text) { }
-
- /// \brief Constructor.
- /// Allows to use \ref plib::pfmt logic to be used in exception
-
- 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)...)) { }
- };
-
- /// \brief Logic families descriptors are used to create proxy devices.
- /// The logic family describes the analog capabilities of logic devices,
- /// inputs and outputs.
-
- class logic_family_desc_t
- {
- public:
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init, modernize-use-equals-default)
- logic_family_desc_t()
- {
- }
-
-
- PCOPYASSIGNMOVE(logic_family_desc_t, delete)
-
- virtual ~logic_family_desc_t() noexcept = default;
-
- virtual device_arena::unique_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_output_t *proxied) const = 0;
- virtual device_arena::unique_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_state_t &anetlist, const pstring &name,
- const logic_input_t *proxied) const = 0;
-
- 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; }
- nl_fptype high_offset_V() const noexcept{ return m_high_VO; }
- nl_fptype R_low() const noexcept{ return m_R_low; }
- nl_fptype R_high() const noexcept{ return m_R_high; }
-
- bool is_above_high_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
- { return V > high_thresh_V(VN, VP); }
-
- bool is_below_low_thresh_V(nl_fptype V, nl_fptype VN, nl_fptype VP) const noexcept
- { return V < low_thresh_V(VN, VP); }
-
- pstring vcc_pin() const { return pstring(m_vcc); }
- pstring gnd_pin() const { return pstring(m_gnd); }
-
- nl_fptype m_low_thresh_PCNT; //!< low input threshhold offset. If the input voltage is below this value times supply voltage, a "0" input is signalled
- nl_fptype m_high_thresh_PCNT; //!< high input threshhold offset. If the input voltage is above the value times supply voltage, a "0" input is signalled
- nl_fptype m_low_VO; //!< low output voltage offset. This voltage is output if the ouput is "0"
- nl_fptype m_high_VO; //!< high output voltage offset. The supply voltage minus this offset is output if the ouput is "1"
- nl_fptype m_R_low; //!< low output resistance. Value of series resistor used for low output
- nl_fptype m_R_high; //!< high output resistance. Value of series resistor used for high output
- const char *m_vcc; //!< default power pin name for positive supply
- const char *m_gnd; //!< default power pin name for negative supply
- };
-
- /// \brief Base class for devices, terminals, outputs and inputs which support
- /// logic families.
- /// This class is a storage container to store the logic family for a
- /// netlist object. You will not directly use it. Please refer to
- /// \ref NETLIB_FAMILY to learn how to define a logic family for a device.
- ///
- /// All terminals inherit the family description from the device
- /// The default is the ttl family, but any device can override the family.
- /// For individual terminals, the family can be overwritten as well.
- ///
-
- class logic_family_t
- {
- public:
- logic_family_t() : m_logic_family(nullptr) {}
- logic_family_t(const logic_family_desc_t *d) : m_logic_family(d) {}
- PCOPYASSIGNMOVE(logic_family_t, delete)
-
- const logic_family_desc_t *logic_family() const noexcept { return m_logic_family; }
- void set_logic_family(const logic_family_desc_t *fam) noexcept { m_logic_family = fam; }
-
- protected:
- ~logic_family_t() noexcept = default; // prohibit polymorphic destruction
- private:
- const logic_family_desc_t *m_logic_family;
- };
-
- /// \brief A persistent variable template.
- /// Use the state_var template to define a variable whose value is saved.
- /// Within a device definition use
- ///
- /// NETLIB_OBJECT(abc)
- /// {
- /// NETLIB_CONSTRUCTOR(abc)
- /// , m_var(*this, "myvar", 0)
- /// ...
- /// state_var<unsigned> m_var;
- /// }
- template <typename T>
- struct state_var
- {
- public:
-
- using value_type = T;
-
- template <typename O>
- //! Constructor.
- 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
- );
-
- template <typename O>
- //! Constructor.
- state_var(O &owner, //!< owner must have a netlist() method.
- const pstring &name //!< identifier/name for this state variable
- );
-
- PMOVEASSIGN(state_var, delete)
-
- //! Destructor.
- ~state_var() noexcept = default;
-
- //! Copy Constructor removed.
- constexpr state_var(const state_var &rhs) = delete;
- //! Assignment operator to assign value of a state var.
- constexpr state_var &operator=(const state_var &rhs) noexcept
- {
- if (this != &rhs)
- m_value = rhs.m_value;
- return *this;
- } // OSX doesn't like noexcept
- //! Assignment operator to assign value of type T.
- constexpr state_var &operator=(const T &rhs) noexcept { m_value = rhs; return *this; }
- //! Assignment move operator to assign value of type T.
- constexpr state_var &operator=(T &&rhs) noexcept { std::swap(m_value, rhs); return *this; }
- //! Return non-const value of state variable.
- constexpr operator T & () noexcept { return m_value; }
- //! Return const value of state variable.
- constexpr operator const T & () const noexcept { return m_value; }
- //! Return non-const value of state variable.
- constexpr T & var() noexcept { return m_value; }
- //! Return const value of state variable.
- constexpr const T & var() const noexcept { return m_value; }
- //! Return non-const value of state variable.
- constexpr T & operator ()() noexcept { return m_value; }
- //! Return const value of state variable.
- constexpr const T & operator ()() const noexcept { return m_value; }
- //! Access state variable by ->.
- constexpr T * operator->() noexcept { return &m_value; }
- //! Access state variable by const ->.
- constexpr const T * operator->() const noexcept{ return &m_value; }
-
- private:
- T m_value;
- };
-
- /// \brief A persistent array template.
- /// Use this state_var template to define an array whose contents are saved.
- /// Please refer to \ref state_var.
- ///
- /// \tparam C container class to use.
-
- template <typename C>
- struct state_container : public C
- {
- public:
- using value_type = typename C::value_type;
- //! Constructor.
- template <typename O>
- state_container(O &owner, //!< owner must have a netlist() method.
- const pstring &name, //!< identifier/name for this state variable
- const value_type &value //!< Initial value after construction
- );
- //! Constructor.
- template <typename O>
- state_container(O &owner, //!< owner must have a netlist() method.
- const pstring &name, //!< identifier/name for this state variable
- std::size_t n, //!< number of elements to allocate
- const value_type &value //!< Initial value after construction
- );
- //! Copy Constructor.
- state_container(const state_container &rhs) noexcept = default;
- //! Destructor.
- ~state_container() noexcept = default;
- //! Move Constructor.
- state_container(state_container &&rhs) noexcept = default;
- state_container &operator=(const state_container &rhs) noexcept = default;
- state_container &operator=(state_container &&rhs) noexcept = default;
- };
-
- // -----------------------------------------------------------------------------
- // State variables - predefined and c++11 non-optional
- // -----------------------------------------------------------------------------
-
- /// \brief predefined state variable type for uint8_t
- using state_var_u8 = state_var<std::uint8_t>;
- /// \brief predefined state variable type for int8_t
- using state_var_s8 = state_var<std::int8_t>;
-
- /// \brief predefined state variable type for uint32_t
- using state_var_u32 = state_var<std::uint32_t>;
- /// \brief predefined state variable type for int32_t
- using state_var_s32 = state_var<std::int32_t>;
- /// \brief predefined state variable type for sig_t
- using state_var_sig = state_var<netlist_sig_t>;
-
- namespace detail {
-
- template <typename C, typename T>
- struct property_store_t
- {
- using value_type = T;
- using key_type = const C *;
- static void add(key_type obj, const value_type &aname) noexcept
- {
- store().insert({obj, aname});
- }
-
- static value_type *get(key_type obj) noexcept
- {
- try
- {
- auto ret(store().find(obj));
- if (ret == store().end())
- return nullptr;
- return &ret->second;
- }
- catch (...)
- {
- plib::terminate("exception in property_store_t.get()");
- return static_cast<value_type *>(nullptr);
- }
- }
-
- static void remove(key_type obj) noexcept
- {
- store().erase(store().find(obj));
- }
-
- static std::unordered_map<key_type, value_type> &store() noexcept
- {
- static std::unordered_map<key_type, value_type> lstore;
- return lstore;
- }
-
- };
-
- // -----------------------------------------------------------------------------
- // object_t
- // -----------------------------------------------------------------------------
-
- /// \brief The base class for netlist devices, terminals and parameters.
- ///
- /// This class serves as the base class for all device, terminal and
- /// objects.
-
- class object_t
- {
- public:
-
- /// \brief Constructor.
- /// Every class derived from the object_t class must have a name.
- ///
- /// \param aname string containing name of the object
-
- explicit object_t(const pstring &aname)
- {
- props::add(this, aname);
- }
-
- PCOPYASSIGNMOVE(object_t, delete)
- /// \brief return name of the object
- ///
- /// \returns name of the object.
-
- const pstring &name() const noexcept
- {
- return *props::get(this);
- }
-
- protected:
-
- using props = property_store_t<object_t, pstring>;
-
- // only childs should be destructible
- ~object_t() noexcept
- {
- props::remove(this);
- }
-
- private:
- };
-
- /// \brief Base class for all objects bejng owned by a netlist
- ///
- /// The object provides adds \ref netlist_state_t and \ref netlist_t
- /// accessors.
- ///
- class netlist_object_t : public object_t
- {
- public:
- explicit netlist_object_t(netlist_t &nl, const pstring &name)
- : object_t(name)
- , m_netlist(nl)
- { }
-
- ~netlist_object_t() = default;
-
- PCOPYASSIGNMOVE(netlist_object_t, delete)
-
- netlist_state_t & state() noexcept;
- const netlist_state_t & state() const noexcept;
-
- netlist_t & exec() noexcept { return m_netlist; }
- const netlist_t & exec() const noexcept { return m_netlist; }
-
- // to ease template design
- template<typename T, typename... Args>
- device_arena::unique_ptr<T> make_pool_object(Args&&... args);
-
- private:
- netlist_t & m_netlist;
-
- };
-
- // -----------------------------------------------------------------------------
- // device_object_t
- // -----------------------------------------------------------------------------
-
- /// \brief Base class for all objects being owned by a device.
- ///
- /// Serves as the base class of all objects being owned by a device.
- ///
- /// The class also supports device-less objects. In this case,
- /// nullptr is passed in as the device object.
- ///
-
- class device_object_t : public object_t
- {
- public:
- /// \brief Constructor.
- ///
- /// \param dev pointer to device owning the object.
- /// \param name string holding the name of the device
-
- device_object_t(core_device_t *dev, const pstring &name);
-
- /// \brief returns reference to owning device.
- /// \returns reference to owning device.
-
- core_device_t &device() noexcept { return *m_device; }
- const core_device_t &device() const noexcept { return *m_device; }
-
- /// \brief The netlist owning the owner of this object.
- /// \returns reference to netlist object.
-
- netlist_state_t &state() noexcept;
- const netlist_state_t &state() const noexcept;
-
- netlist_t &exec() noexcept;
- const netlist_t &exec() const noexcept;
-
- private:
- core_device_t * m_device;
- };
-
- // -----------------------------------------------------------------------------
- // core_terminal_t
- // -----------------------------------------------------------------------------
-
- /// \brief Base class for all terminals.
- ///
- /// All terminals are derived from this class.
- ///
- class core_terminal_t : public device_object_t,
- public plib::linkedlist_t<core_terminal_t>::element_t
- {
- public:
- /// \brief Number of signal bits
- ///
- /// Going forward setting this to 8 will allow 8-bit signal
- /// busses to be used in netlist, e.g. for more complex memory
- /// arrangements.
- /// Mimimum value is 2 here to support tristate output on proxies.
- static constexpr const unsigned int INP_BITS = 2;
-
- static constexpr const unsigned int INP_MASK = (1 << INP_BITS) - 1;
- static constexpr const unsigned int INP_HL_SHIFT = 0;
- static constexpr const unsigned int INP_LH_SHIFT = INP_BITS;
-
- static constexpr netlist_sig_t OUT_TRISTATE() { return INP_MASK; }
-
- static_assert(INP_BITS * 2 <= sizeof(netlist_sig_t) * 8, "netlist_sig_t size not sufficient");
-
- enum state_e {
- STATE_INP_PASSIVE = 0,
- STATE_INP_HL = (INP_MASK << INP_HL_SHIFT),
- STATE_INP_LH = (INP_MASK << INP_LH_SHIFT),
- STATE_INP_ACTIVE = STATE_INP_HL | STATE_INP_LH,
- STATE_OUT = (1 << (2*INP_BITS)),
- STATE_BIDIR = (1 << (2*INP_BITS + 1))
- };
-
- core_terminal_t(core_device_t &dev, const pstring &aname,
- state_e state, nldelegate delegate);
- virtual ~core_terminal_t() noexcept = default;
-
- PCOPYASSIGNMOVE(core_terminal_t, delete)
-
- /// \brief The object type.
- /// \returns type of the object
- terminal_type type() const noexcept(false);
-
- /// \brief 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 terminal_type atype) const noexcept(false) { return (type() == atype); }
-
- void set_net(net_t *anet) noexcept { m_net = anet; }
- void clear_net() noexcept { m_net = nullptr; }
- bool has_net() const noexcept { return (m_net != nullptr); }
-
- net_t & net() const noexcept { return *m_net;}
-
- bool is_logic() const noexcept;
- bool is_logic_input() const noexcept;
- bool is_logic_output() const noexcept;
- bool is_tristate_output() const noexcept;
- bool is_analog() const noexcept;
- bool is_analog_input() const noexcept;
- bool is_analog_output() const noexcept;
-
- bool is_state(state_e astate) const noexcept { return (m_state == astate); }
- state_e terminal_state() const noexcept { return m_state; }
- void set_state(state_e astate) noexcept { m_state = astate; }
-
- void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
-
- #if NL_USE_COPY_INSTEAD_OF_REFERENCE
- void set_copied_input(netlist_sig_t val) noexcept
- {
- m_Q = val;
- }
-
- state_var_sig m_Q;
- #else
- void set_copied_input(netlist_sig_t val) const noexcept { plib::unused_var(val); } // NOLINT: static means more message elsewhere
- #endif
-
- void set_delegate(const nldelegate &delegate) noexcept { m_delegate = delegate; }
- const nldelegate &delegate() const noexcept { return m_delegate; }
- inline void run_delegate() noexcept { return m_delegate(); }
- private:
- nldelegate m_delegate;
- net_t * m_net;
- state_var<state_e> m_state;
- };
-
- // -----------------------------------------------------------------------------
- // net_t
- // -----------------------------------------------------------------------------
-
- class net_t : public netlist_object_t
- {
- public:
-
- enum class queue_status
- {
- DELAYED_DUE_TO_INACTIVE = 0,
- QUEUED,
- DELIVERED
- };
-
- net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal = nullptr);
-
- PCOPYASSIGNMOVE(net_t, delete)
-
- virtual ~net_t() noexcept = default;
-
- virtual void reset() noexcept;
-
- void toggle_new_Q() noexcept { m_new_Q = (m_cur_Q ^ 1); }
-
- void toggle_and_push_to_queue(const netlist_time &delay) noexcept
- {
- toggle_new_Q();
- push_to_queue(delay);
- }
-
- void push_to_queue(const netlist_time &delay) noexcept;
- NVCC_CONSTEXPR bool is_queued() const noexcept { return m_in_queue == queue_status::QUEUED; }
-
- template <bool KEEP_STATS>
- inline void update_devs() noexcept;
-
- netlist_time_ext next_scheduled_time() const noexcept { return m_next_scheduled_time; }
- void set_next_scheduled_time(netlist_time_ext ntime) noexcept { m_next_scheduled_time = ntime; }
-
- NVCC_CONSTEXPR bool is_rail_net() const noexcept { return !(m_railterminal == nullptr); }
- core_terminal_t & railterminal() const noexcept { return *m_railterminal; }
-
- bool has_connections() const noexcept { return !m_core_terms.empty(); }
-
- void add_to_active_list(core_terminal_t &term) noexcept;
- void remove_from_active_list(core_terminal_t &term) noexcept;
-
- // setup stuff
-
- bool is_logic() const noexcept;
- bool is_analog() const noexcept;
-
- void rebuild_list(); // rebuild m_list after a load
-
- std::vector<core_terminal_t *> &core_terms() noexcept { return m_core_terms; }
-
- void update_inputs() noexcept
- {
-#if NL_USE_COPY_INSTEAD_OF_REFERENCE
- for (auto & term : m_core_terms)
- term->m_Q = m_cur_Q;
-#endif
- // nothing needs to be done if define not set
- }
-
- protected:
-
- // only used for logic nets
- NVCC_CONSTEXPR netlist_sig_t Q() const noexcept { return m_cur_Q; }
-
- // only used for logic nets
- void initial(netlist_sig_t val) noexcept
- {
- m_cur_Q = m_new_Q = val;
- update_inputs();
- }
-
- // only used for logic nets
- inline void set_Q_and_push(const netlist_sig_t &newQ, const netlist_time &delay) noexcept
- {
- if (newQ != m_new_Q)
- {
- m_new_Q = newQ;
- push_to_queue(delay);
- }
- }
-
- // only used for logic nets
- inline void set_Q_time(const netlist_sig_t &newQ, const netlist_time_ext &at) noexcept
- {
- if (newQ != m_new_Q)
- {
- m_in_queue = queue_status::DELAYED_DUE_TO_INACTIVE;
- m_next_scheduled_time = at;
- m_cur_Q = m_new_Q = newQ;
- update_inputs();
- }
- else
- {
- m_cur_Q = newQ;
- update_inputs();
- }
- }
-
- // internal state support
- // FIXME: get rid of this and implement export/import in MAME
- private:
- state_var<netlist_sig_t> m_new_Q;
- state_var<netlist_sig_t> m_cur_Q;
- state_var<queue_status> m_in_queue;
- state_var<netlist_time_ext> m_next_scheduled_time;
-
- core_terminal_t * m_railterminal;
- plib::linkedlist_t<core_terminal_t> m_list_active;
- std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
-
- template <bool KEEP_STATS, typename T, typename S>
- void process(T mask, const S &sig) noexcept;
- };
- } // namespace detail
// -----------------------------------------------------------------------------
// analog_t
@@ -944,45 +343,6 @@ namespace netlist
nl_fptype Q_Analog() const noexcept;
};
- class logic_net_t : public detail::net_t
- {
- public:
-
- logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
-
- using detail::net_t::Q;
- using detail::net_t::initial;
- using detail::net_t::set_Q_and_push;
- using detail::net_t::set_Q_time;
- };
-
- class analog_net_t : public detail::net_t
- {
- public:
-
- analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
-
- void reset() noexcept override;
-
- nl_fptype Q_Analog() const noexcept { return m_cur_Analog; }
- void set_Q_Analog(nl_fptype v) noexcept { m_cur_Analog = v; }
- // used by solver code ...
- nl_fptype *Q_Analog_state_ptr() noexcept { return &m_cur_Analog(); }
-
- //FIXME: needed by current solver code
- solver::matrix_solver_t *solver() const noexcept { return m_solver; }
- void set_solver(solver::matrix_solver_t *solver) noexcept { m_solver = solver; }
-
- friend constexpr bool operator==(const analog_net_t &lhs, const analog_net_t &rhs) noexcept
- {
- return &lhs == &rhs;
- }
-
- private:
- state_var<nl_fptype> m_cur_Analog;
- solver::matrix_solver_t *m_solver;
- };
-
// -----------------------------------------------------------------------------
// logic_output_t
// -----------------------------------------------------------------------------
@@ -1108,318 +468,6 @@ namespace netlist
analog_net_t m_my_net;
};
- /// @brief Base class for all device parameters
- ///
- /// All device parameters classes derive from this object.
- class param_t : public detail::device_object_t
- {
- public:
-
- enum param_type_t {
- STRING,
- DOUBLE,
- INTEGER,
- LOGIC,
- POINTER // Special-case which is always initialized at MAME startup time
- };
-
- //deviceless, it's the responsibility of the owner to register!
- param_t(const pstring &name);
-
- param_t(core_device_t &device, const pstring &name);
-
- PCOPYASSIGNMOVE(param_t, delete)
- virtual ~param_t() noexcept;
-
- param_type_t param_type() const noexcept(false);
-
- virtual pstring valstr() const = 0;
-
- protected:
-
- void update_param() noexcept;
-
- pstring get_initial(const core_device_t *dev, bool *found) const;
-
- template<typename C>
- void set_and_update_param(C &p, const C v) noexcept
- {
- if (p != v)
- {
- p = v;
- update_param();
- }
- }
-
- };
-
- // -----------------------------------------------------------------------------
- // numeric parameter template
- // -----------------------------------------------------------------------------
-
- template <typename T>
- class param_num_t final: public param_t
- {
- public:
- using value_type = T;
-
- param_num_t(core_device_t &device, const pstring &name, T val) noexcept(false);
-
- T operator()() const noexcept { return m_param; }
- operator T() const noexcept { return m_param; }
-
- void set(const T &param) noexcept { set_and_update_param(m_param, param); }
-
- pstring valstr() const override
- {
- return plib::pfmt("{}").e(gsl::narrow<nl_fptype>(m_param));
- }
-
- private:
- T m_param;
- };
-
- template <typename T>
- class param_enum_t final: public param_t
- {
- public:
- using value_type = T;
-
- param_enum_t(core_device_t &device, const pstring &name, T val) noexcept(false);
-
- T operator()() const noexcept { return T(m_param); }
- operator T() const noexcept { return T(m_param); }
- void set(const T &param) noexcept { set_and_update_param(m_param, static_cast<int>(param)); }
-
- pstring valstr() const override
- {
- // returns the numerical value
- return plib::pfmt("{}")(m_param);
- }
- private:
- int m_param;
- };
-
- // FIXME: these should go as well
- using param_logic_t = param_num_t<bool>;
- using param_int_t = param_num_t<int>;
- using param_fp_t = param_num_t<nl_fptype>;
-
- // -----------------------------------------------------------------------------
- // pointer parameter
- // -----------------------------------------------------------------------------
-
- // FIXME: not a core component -> legacy
- class param_ptr_t final: public param_t
- {
- public:
- param_ptr_t(core_device_t &device, const pstring &name, std::uint8_t* val);
- std::uint8_t * operator()() const noexcept { return m_param; }
- void set(std::uint8_t *param) noexcept { set_and_update_param(m_param, param); }
-
- pstring valstr() const override
- {
- // returns something which errors
- return pstring("PTRERROR");
- }
-
- private:
- std::uint8_t* m_param;
- };
-
- // -----------------------------------------------------------------------------
- // string parameter
- // -----------------------------------------------------------------------------
-
- class param_str_t : public param_t
- {
- public:
- param_str_t(core_device_t &device, const pstring &name, const pstring &val);
- param_str_t(netlist_state_t &state, const pstring &name, const pstring &val);
-
- pstring operator()() const noexcept { return str(); }
- void set(const pstring &param)
- {
- if (*m_param != param)
- {
- *m_param = param;
- changed();
- update_param();
- }
- }
- pstring valstr() const override
- {
- return *m_param;
- }
- protected:
- virtual void changed() noexcept;
- pstring str() const noexcept { return *m_param; }
- private:
- host_arena::unique_ptr<pstring> m_param;
- };
-
- // -----------------------------------------------------------------------------
- // model parameter
- // -----------------------------------------------------------------------------
-
- class param_model_t : public param_str_t
- {
- public:
-
- template <typename T>
- class value_base_t
- {
- public:
- template <typename P, typename Y=T, typename DUMMY = std::enable_if_t<plib::is_arithmetic<Y>::value>>
- value_base_t(P &param, const pstring &name)
- : m_value(gsl::narrow<T>(param.value(name)))
- {
- }
- template <typename P, typename Y=T, std::enable_if_t<!plib::is_arithmetic<Y>::value, int> = 0>
- value_base_t(P &param, const pstring &name)
- : m_value(static_cast<T>(param.value_str(name)))
- {
- }
- T operator()() const noexcept { return m_value; }
- operator T() const noexcept { return m_value; }
- private:
- const T m_value;
- };
-
- using value_t = value_base_t<nl_fptype>;
- using value_str_t = value_base_t<pstring>;
-
- param_model_t(core_device_t &device, const pstring &name, const pstring &val)
- : param_str_t(device, name, val)
- {
- }
-
- pstring value_str(const pstring &entity);
- nl_fptype value(const pstring &entity);
- pstring type();
- // hide this
- void set(const pstring &param) = delete;
- protected:
- void changed() noexcept override;
- private:
- };
-
- // -----------------------------------------------------------------------------
- // data parameter
- // -----------------------------------------------------------------------------
-
- class param_data_t : public param_str_t
- {
- public:
- param_data_t(core_device_t &device, const pstring &name)
- : param_str_t(device, name, "")
- {
- }
-
- std::unique_ptr<std::istream> stream();
- protected:
- void changed() noexcept override { }
- };
-
- // -----------------------------------------------------------------------------
- // rom parameter
- // -----------------------------------------------------------------------------
-
- template <typename ST, std::size_t AW, std::size_t DW>
- class param_rom_t final: public param_data_t
- {
- public:
-
- param_rom_t(core_device_t &device, const pstring &name);
-
- const ST & operator[] (std::size_t n) const noexcept { return m_data[n]; }
- protected:
- void changed() noexcept override
- {
- plib::istream_read(*stream(), m_data.data(), 1<<AW);
- }
-
- private:
- std::array<ST, 1 << AW> m_data;
- };
-
-
- // -----------------------------------------------------------------------------
- // core_device_t
- // -----------------------------------------------------------------------------
-
- class core_device_t : public detail::netlist_object_t
- {
- public:
- core_device_t(netlist_state_t &owner, const pstring &name);
- core_device_t(core_device_t &owner, const pstring &name);
-
- PCOPYASSIGNMOVE(core_device_t, delete)
-
- virtual ~core_device_t() noexcept = default;
-
- void do_inc_active() noexcept
- {
- if (m_hint_deactivate)
- {
- if (++m_active_outputs == 1)
- {
- if (m_stats)
- m_stats->m_stat_inc_active.inc();
- inc_active();
- }
- }
- }
-
- void do_dec_active() noexcept
- {
- if (m_hint_deactivate)
- if (--m_active_outputs == 0)
- {
- dec_active();
- }
- }
-
- void set_hint_deactivate(bool v) noexcept { m_hint_deactivate = v; }
- bool get_hint_deactivate() const noexcept { return m_hint_deactivate; }
- // Has to be set in device reset
- void set_active_outputs(int n) noexcept { m_active_outputs = n; }
-
- // stats
- struct stats_t
- {
- // NL_KEEP_STATISTICS
- plib::pperftime_t<true> m_stat_total_time;
- plib::pperfcount_t<true> m_stat_call_count;
- plib::pperfcount_t<true> m_stat_inc_active;
- };
-
- stats_t * stats() const noexcept { return m_stats.get(); }
-#if 0
- virtual void update() noexcept { }
-#endif
- virtual void reset() { }
-
- protected:
-
- virtual void inc_active() noexcept { }
- virtual void dec_active() noexcept { }
-
- log_type & log();
-
- public:
- virtual void timestep(timestep_type ts_type, nl_fptype st) noexcept { plib::unused_var(ts_type, st); }
- virtual void update_terminals() noexcept { }
-
- virtual void update_param() noexcept {}
- virtual bool is_dynamic() const noexcept { return false; }
- virtual bool is_timestep() const noexcept { return false; }
-
- private:
- bool m_hint_deactivate;
- state_var_s32 m_active_outputs;
- device_arena::unique_ptr<stats_t> m_stats;
- };
// -----------------------------------------------------------------------------
// base_device_t
@@ -2556,39 +1604,6 @@ namespace netlist
return (this->has_net() ? net().solver() : nullptr);
}
- template <typename T>
- template <typename O>
- state_var<T>::state_var(O &owner, const pstring &name, const T &value)
- : m_value(value)
- {
- owner.state().save(owner, m_value, owner.name(), name);
- }
-
- template <typename T>
- template <typename O>
- state_var<T>::state_var(O &owner, const pstring &name)
- {
- owner.state().save(owner, m_value, owner.name(), name);
- }
-
- template <typename C>
- template <typename O>
- state_container<C>::state_container(O &owner, const pstring &name,
- const state_container<C>::value_type & value)
- {
- owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
- for (std::size_t i=0; i < this->size(); i++)
- (*this)[i] = value;
- }
-
- template <typename C>
- template <typename O>
- state_container<C>::state_container(O &owner, const pstring &name,
- std::size_t n, const state_container<C>::value_type & value)
- : C(n, value)
- {
- owner.state().save(owner, static_cast<C &>(*this), owner.name(), name);
- }
extern template struct state_var<std::uint8_t>;
extern template struct state_var<std::uint16_t>;
diff --git a/src/lib/netlist/nltypes.h b/src/lib/netlist/nltypes.h
index 1ed6f66ca0d..be1de61aa44 100644
--- a/src/lib/netlist/nltypes.h
+++ b/src/lib/netlist/nltypes.h
@@ -14,10 +14,11 @@
#include "nl_config.h"
-//#include "plib/pchrono.h"
#include "plib/pstring.h"
#include "plib/ptime.h"
#include "plib/ptypes.h"
+#include "plib/ppmf.h"
+#include "plib/pmempool.h"
#include <memory>
@@ -80,6 +81,7 @@ namespace netlist
struct abstract_t;
class core_terminal_t;
class net_t;
+ class device_object_t;
} // namespace detail
namespace factory
@@ -196,6 +198,22 @@ namespace netlist
// Types needed by various includes
//============================================================
+ /// \brief Timestep type.
+ ///
+ /// May be either FORWARD or RESTORE
+ ///
+ enum class timestep_type
+ {
+ FORWARD, ///< forward time
+ RESTORE ///< restore state before last forward
+ };
+
+ /// \brief Delegate type for device notification.
+ ///
+ using nldelegate = plib::pmfp<void>;
+ using nldelegate_ts = plib::pmfp<void, timestep_type, nl_fptype>;
+ using nldelegate_dyn = plib::pmfp<void>;
+
namespace detail {
/// \brief Enum specifying the type of object
diff --git a/src/lib/netlist/plib/penum.h b/src/lib/netlist/plib/penum.h
index 55c0669afb5..8ea6f42a182 100644
--- a/src/lib/netlist/plib/penum.h
+++ b/src/lib/netlist/plib/penum.h
@@ -43,6 +43,7 @@ namespace plib
pstring name() const { \
return nthstr(m_v, strings()); \
} \
+ template <typename S> void save_state(S &saver) { saver.save_item(m_v, "m_v"); } \
private: E m_v; \
static pstring strings() {\
static const char * lstrings = # __VA_ARGS__; \
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
index 871eff3dca3..1d25576a0d4 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.cpp
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -42,7 +42,6 @@ namespace solver
const net_list_t &nets,
const solver_parameters_t *params)
: device_t(static_cast<device_t &>(main_solver), name)
- , m_next_exec(*this, "m_next_exec", netlist_time_ext::zero())
, m_params(*params)
, m_iterative_fail(*this, "m_iterative_fail", 0)
, m_iterative_total(*this, "m_iterative_total", 0)
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index feb7d6bbd42..bfc105aa1cc 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -271,8 +271,6 @@ namespace solver
// return number of floating point operations for solve
constexpr std::size_t ops() const { return m_ops; }
- state_var<netlist_time_ext> m_next_exec;
- std::size_t id = 0; // FIXME - testing
protected:
matrix_solver_t(devices::nld_solver &main_solver, const pstring &name,
const net_list_t &nets,