summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/core/nets.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/core/nets.h')
-rw-r--r--src/lib/netlist/core/nets.h186
1 files changed, 186 insertions, 0 deletions
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_