diff options
Diffstat (limited to 'src/lib/netlist/nl_base.h')
-rw-r--r-- | src/lib/netlist/nl_base.h | 360 |
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 ¶m) 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 ¶m) 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 |