summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/nl_base.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/nl_base.h')
-rw-r--r--src/lib/netlist/nl_base.h360
1 files changed, 207 insertions, 153 deletions
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index cd8d9f9fc5b..f0a84dd0bb3 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -189,7 +189,6 @@ namespace netlist
{
/// \brief Delegate type for device notification.
///
-
using nldelegate = plib::pmfp<void>;
// -----------------------------------------------------------------------------
@@ -220,6 +219,11 @@ namespace netlist
class core_device_t;
class device_t;
+ namespace detail
+ {
+ class net_t;
+ } // namespace detail
+
//============================================================
// Exceptions
//============================================================
@@ -266,8 +270,8 @@ namespace netlist
logic_input_t *proxied) const = 0;
nl_fptype fixed_V() const noexcept{ return m_fixed_V; }
- nl_fptype low_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_low_thresh_PCNT; }
- nl_fptype high_thresh_V(const nl_fptype VN, const nl_fptype VP) const noexcept{ return VN + (VP - VN) * m_high_thresh_PCNT; }
+ 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; }
@@ -551,10 +555,6 @@ namespace netlist
///
/// All terminals are derived from this class.
///
-
-
- class net_t;
-
class core_terminal_t : public device_object_t,
public plib::linkedlist_t<core_terminal_t>::element_t
{
@@ -608,7 +608,6 @@ namespace netlist
void reset() noexcept { set_state(is_type(terminal_type::OUTPUT) ? STATE_OUT : STATE_INP_ACTIVE); }
- nldelegate m_delegate;
#if NL_USE_COPY_INSTEAD_OF_REFERENCE
void set_copied_input(netlist_sig_t val) noexcept
{
@@ -620,7 +619,12 @@ namespace netlist
void set_copied_input(netlist_sig_t val) const noexcept { plib::unused_var(val); }
#endif
+ void set_delegate(const nldelegate &delegate) noexcept { m_delegate = delegate; }
+ nldelegate &delegate() noexcept { return m_delegate; }
+ const nldelegate &delegate() const noexcept { return m_delegate; }
+ void run_delegate() noexcept { m_delegate(); }
private:
+ nldelegate m_delegate;
net_t * m_net;
state_var<state_e> m_state;
};
@@ -642,7 +646,7 @@ namespace netlist
DELIVERED
};
- net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
+ net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *railterminal = nullptr);
COPYASSIGNMOVE(net_t, delete)
@@ -729,9 +733,14 @@ namespace netlist
{
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();
}
- m_cur_Q = m_new_Q = newQ;
- update_inputs();
}
// internal state support
@@ -751,7 +760,7 @@ namespace netlist
std::vector<core_terminal_t *> m_core_terms; // save post-start m_list ...
template <bool KEEP_STATS, typename T>
- void process(const T mask, netlist_sig_t sig) noexcept;
+ void process(T mask, netlist_sig_t sig) noexcept;
};
} // namespace detail
@@ -815,7 +824,7 @@ namespace netlist
nl_fptype *m_go1; // conductance for Voltage from other term
nl_fptype *m_gt1; // conductance for total conductance
- terminal_t *m_connected_terminal;
+ terminal_t *m_connected_terminal; // FIXME: only used during setup
};
@@ -840,7 +849,7 @@ namespace netlist
protected:
private:
- devices::nld_base_proxy *m_proxy;
+ devices::nld_base_proxy *m_proxy; // FIXME: only used during setup
};
// -----------------------------------------------------------------------------
@@ -886,14 +895,11 @@ namespace netlist
/// \brief returns voltage at terminal.
/// \returns voltage at terminal.
-
nl_fptype operator()() const noexcept { return Q_Analog(); }
/// \brief returns voltage at terminal.
/// \returns voltage at terminal.
-
nl_fptype Q_Analog() const noexcept;
-
};
@@ -901,7 +907,7 @@ namespace netlist
{
public:
- logic_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+ 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;
@@ -919,7 +925,7 @@ namespace netlist
friend class detail::net_t;
- analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
+ analog_net_t(netlist_state_t &nl, const pstring &aname, detail::core_terminal_t *railterminal = nullptr);
nl_fptype Q_Analog() const noexcept { return m_cur_Analog; }
void set_Q_Analog(const nl_fptype v) noexcept { m_cur_Analog = v; }
@@ -965,15 +971,130 @@ namespace netlist
public:
analog_output_t(core_device_t &dev, const pstring &aname);
- void push(const nl_fptype val) noexcept { set_Q(val); }
- void initial(const nl_fptype val) noexcept;
+ void push(nl_fptype val) noexcept { set_Q(val); }
+ void initial(nl_fptype val) noexcept;
private:
- void set_Q(const nl_fptype newQ) noexcept;
+ void set_Q(nl_fptype newQ) noexcept;
analog_net_t m_my_net;
};
// -----------------------------------------------------------------------------
+ // core_device_t
+ // -----------------------------------------------------------------------------
+
+ class core_device_t :
+ public detail::object_t,
+ public logic_family_t,
+ public detail::netlist_ref
+ {
+ public:
+ core_device_t(netlist_state_t &owner, const pstring &name);
+ core_device_t(core_device_t &owner, const pstring &name);
+
+ COPYASSIGNMOVE(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; }
+
+ void set_default_delegate(detail::core_terminal_t &term);
+
+ // 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;
+ };
+
+ unique_pool_ptr<stats_t> m_stats;
+
+ virtual void update() NL_NOEXCEPT { }
+ virtual void reset() { }
+
+ protected:
+
+ virtual void inc_active() noexcept { }
+ virtual void dec_active() noexcept { }
+
+ log_type & log();
+
+ public:
+ virtual void timestep(const nl_fptype st) noexcept { plib::unused_var(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_t
+ // -----------------------------------------------------------------------------
+
+ class device_t : public core_device_t
+ {
+ public:
+
+ device_t(netlist_state_t &owner, const pstring &name);
+ device_t(core_device_t &owner, const pstring &name);
+
+ COPYASSIGNMOVE(device_t, delete)
+
+ ~device_t() noexcept override = default;
+
+ template<class C, typename... Args>
+ void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args)
+ {
+ dev = pool().make_unique<C>(*this, name, std::forward<Args>(args)...);
+ }
+
+ void register_subalias(const pstring &name, detail::core_terminal_t &term);
+ void register_subalias(const pstring &name, const pstring &aliased);
+
+ void connect(const pstring &t1, const pstring &t2);
+ void connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
+ void connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
+ protected:
+
+ NETLIB_UPDATEI() { }
+ NETLIB_UPDATE_TERMINALSI() { }
+
+ private:
+ };
+
+ // -----------------------------------------------------------------------------
// param_t
// -----------------------------------------------------------------------------
@@ -998,7 +1119,10 @@ namespace netlist
protected:
virtual ~param_t() noexcept = default; // not intended to be destroyed
- void update_param() noexcept;
+ void update_param() noexcept
+ {
+ device().update_param();
+ }
pstring get_initial(const device_t &dev, bool *found);
@@ -1025,7 +1149,7 @@ namespace netlist
param_num_t(device_t &device, const pstring &name, const T val);
T operator()() const noexcept { return m_param; }
- operator T() const noexcept { return m_param; }
+ operator T() const noexcept { return m_param; }
void setTo(const T &param) noexcept { set(m_param, param); }
private:
@@ -1073,7 +1197,7 @@ namespace netlist
public:
param_str_t(device_t &device, const pstring &name, const pstring &val);
- const pstring &operator()() const noexcept { return str(); }
+ pstring operator()() const noexcept { return str(); }
void setTo(const pstring &param) noexcept
{
if (m_param != param)
@@ -1085,7 +1209,7 @@ namespace netlist
}
protected:
virtual void changed() noexcept;
- const pstring &str() const noexcept { return m_param; }
+ pstring str() const noexcept { return m_param; }
private:
PALIGNAS_CACHELINE()
pstring m_param;
@@ -1171,121 +1295,6 @@ namespace netlist
};
// -----------------------------------------------------------------------------
- // core_device_t
- // -----------------------------------------------------------------------------
-
- class core_device_t :
- public detail::object_t,
- public logic_family_t,
- public detail::netlist_ref
- {
- public:
- core_device_t(netlist_state_t &owner, const pstring &name);
- core_device_t(core_device_t &owner, const pstring &name);
-
- COPYASSIGNMOVE(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; }
-
- void set_default_delegate(detail::core_terminal_t &term);
-
- // 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;
- };
-
- unique_pool_ptr<stats_t> m_stats;
-
- virtual void update() NL_NOEXCEPT { }
- virtual void reset() { }
-
- protected:
-
- virtual void inc_active() noexcept { }
- virtual void dec_active() noexcept { }
-
- log_type & log();
-
- public:
- virtual void timestep(const nl_fptype st) noexcept { plib::unused_var(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_t
- // -----------------------------------------------------------------------------
-
- class device_t : public core_device_t
- {
- public:
-
- device_t(netlist_state_t &owner, const pstring &name);
- device_t(core_device_t &owner, const pstring &name);
-
- COPYASSIGNMOVE(device_t, delete)
-
- ~device_t() noexcept override = default;
-
- template<class C, typename... Args>
- void create_and_register_subdevice(const pstring &name, unique_pool_ptr<C> &dev, Args&&... args)
- {
- dev = pool().make_unique<C>(*this, name, std::forward<Args>(args)...);
- }
-
- void register_subalias(const pstring &name, detail::core_terminal_t &term);
- void register_subalias(const pstring &name, const pstring &aliased);
-
- void connect(const pstring &t1, const pstring &t2);
- void connect(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
- void connect_post_start(detail::core_terminal_t &t1, detail::core_terminal_t &t2);
- protected:
-
- NETLIB_UPDATEI() { }
- NETLIB_UPDATE_TERMINALSI() { }
-
- private:
- };
-
- // -----------------------------------------------------------------------------
// family_setter_t
// -----------------------------------------------------------------------------
@@ -1314,7 +1323,7 @@ namespace netlist
// -----------------------------------------------------------------------------
// We don't need a thread-safe queue currently. Parallel processing of
- /// solvers will update inputs after parallel processing.
+ // solvers will update inputs after parallel processing.
class queue_t :
//public timed_queue<pqentry_t<net_t *, netlist_time>, false, NL_KEEP_STATISTICS>,
@@ -1541,11 +1550,46 @@ namespace netlist
nets_collection_type m_nets;
// sole use is to manage lifetime of net objects
devices_collection_type m_devices;
+ };
+ namespace devices
+ {
+ // -----------------------------------------------------------------------------
+ // mainclock
+ // -----------------------------------------------------------------------------
+
+ NETLIB_OBJECT(mainclock)
+ {
+ NETLIB_CONSTRUCTOR(mainclock)
+ , m_Q(*this, "Q")
+ , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5))
+ {
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
+ }
+ NETLIB_RESETI()
+ {
+ m_Q.net().set_next_scheduled_time(netlist_time::zero());
+ }
- };
+ NETLIB_UPDATE_PARAMI()
+ {
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two()));
+ }
+
+ NETLIB_UPDATEI()
+ {
+ // only called during start up.
+ // mainclock will step forced by main loop
+ }
+ public:
+ logic_output_t m_Q;
+ netlist_time m_inc;
+ private:
+ param_fp_t m_freq;
+ };
+ } // namespace devices
// -----------------------------------------------------------------------------
// netlist_t
// -----------------------------------------------------------------------------
@@ -1626,8 +1670,8 @@ namespace netlist
private:
- template <bool KEEP_STATS, typename MCT>
- void process_queue_stats(netlist_time delta, MCT *mainclock) noexcept;
+ template <bool KEEP_STATS>
+ void process_queue_stats(netlist_time delta) noexcept;
plib::unique_ptr<netlist_state_t> m_state;
devices::NETLIB_NAME(solver) * m_solver;
@@ -1644,7 +1688,7 @@ namespace netlist
// performance
plib::pperftime_t<true> m_stat_mainloop;
plib::pperfcount_t<true> m_perf_out_processed;
-};
+ };
// -----------------------------------------------------------------------------
// Support classes for devices
@@ -1885,7 +1929,7 @@ namespace netlist
return net().Q_Analog();
}
- inline void analog_output_t::set_Q(const nl_fptype newQ) noexcept
+ inline void analog_output_t::set_Q(nl_fptype newQ) noexcept
{
if (newQ != m_my_net.Q_Analog())
{
@@ -1962,7 +2006,7 @@ namespace netlist
if ((p.terminal_state() & mask))
{
auto g(stats->m_stat_total_time.guard());
- p.m_delegate();
+ p.run_delegate();
}
}
}
@@ -1972,7 +2016,7 @@ namespace netlist
{
p.set_copied_input(sig);
if ((p.terminal_state() & mask))
- p.m_delegate();
+ p.run_delegate();
}
}
}
@@ -1988,8 +2032,8 @@ namespace netlist
| (m_cur_Q << core_terminal_t::INP_HL_SHIFT), m_new_Q);
}
- template <bool KEEP_STATS, typename MCT>
- inline void netlist_t::process_queue_stats(const netlist_time delta, MCT *mainclock) noexcept
+ template <bool KEEP_STATS>
+ inline void netlist_t::process_queue_stats(const netlist_time delta) noexcept
{
netlist_time stop(m_time + delta);
@@ -2010,8 +2054,8 @@ namespace netlist
}
else
{
- logic_net_t &mc_net(mainclock->m_Q.net());
- const netlist_time inc(mainclock->m_inc);
+ logic_net_t &mc_net(m_mainclock->m_Q.net());
+ const netlist_time inc(m_mainclock->m_inc);
netlist_time mc_time(mc_net.next_scheduled_time());
do
@@ -2039,6 +2083,16 @@ namespace netlist
}
}
+ inline void netlist_t::process_queue(netlist_time delta) noexcept
+ {
+ if (!m_use_stats)
+ process_queue_stats<false>(delta);
+ else
+ {
+ auto sm_guard(m_stat_mainloop.guard());
+ process_queue_stats<true>(delta);
+ }
+ }
} // namespace netlist