diff options
author | 2020-09-05 19:43:54 +0200 | |
---|---|---|
committer | 2020-09-05 21:31:49 +0200 | |
commit | f3eb6324652fea263972087146fbdde9e32f9a0f (patch) | |
tree | f63d352948c3a4fcf62857839cc5c5359804b0f5 /src/lib/netlist/devices/nld_system.cpp | |
parent | 4dd7e21f565b12e8487b884089d769f0b30147c6 (diff) |
netlist: code maintenance and performance optimizations.
* rename some misleading type names
* remove callback_t and replace by better scalable approach
* hide implementations details
* move sources classes from putil.h to psources.h
* reduce code complexity
* improve parsing performance, parsing netlists now is twice as fast.
* fix issues around multi-byte string support
* moved psplit into pstrutil.h
Diffstat (limited to 'src/lib/netlist/devices/nld_system.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_system.cpp | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index a633e8074f7..10f3693bea8 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -1,7 +1,7 @@ // license:GPL-2.0+ // copyright-holders:Couriersud /* - * nld_system.c + * nld_system.cpp * */ @@ -9,11 +9,107 @@ #include "solver/nld_matrix_solver.h" #include "nlid_system.h" +#include "plib/pstrutil.h" + namespace netlist { namespace devices { + // ----------------------------------------------------------------------------- + // extclock + // ----------------------------------------------------------------------------- + + NETLIB_OBJECT(extclock) + { + NETLIB_CONSTRUCTOR(extclock) + , m_freq(*this, "FREQ", nlconst::magic(7159000.0 * 5.0)) + , m_pattern(*this, "PATTERN", "1,1") + , m_offset(*this, "OFFSET", nlconst::zero()) + , m_feedback(*this, "FB", NETLIB_DELEGATE(first)) + , m_Q(*this, "Q") + , m_cnt(*this, "m_cnt", 0) + , m_off(*this, "m_off", netlist_time::zero()) + { + m_inc[0] = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two())); + + connect("FB", "Q"); + + netlist_time base = netlist_time::from_fp(plib::reciprocal(m_freq()*nlconst::two())); + std::vector<pstring> pat(plib::psplit(m_pattern(),',')); + m_off = netlist_time::from_fp(m_offset()); + + std::array<std::int64_t, 32> pati = { 0 }; + + m_size = static_cast<std::uint8_t>(pat.size()); + netlist_time::mult_type total = 0; + for (unsigned i=0; i<m_size; i++) + { + pati[i] = plib::pstonum<std::int64_t>(pat[i]); + total += pati[i]; + } + netlist_time ttotal = netlist_time::zero(); + auto sm1 = static_cast<uint8_t>(m_size - 1); + for (unsigned i=0; i < sm1; i++) + { + m_inc[i] = base * pati[i]; + ttotal += m_inc[i]; + } + m_inc[sm1] = base * total - ttotal; + + } + + NETLIB_RESETI() + { + m_cnt = 0; + m_off = netlist_time::from_fp<decltype(m_offset())>(m_offset()); + m_feedback.set_delegate(NETLIB_DELEGATE(first)); + } + //NETLIB_UPDATE_PARAMI(); + + private: + + NETLIB_HANDLERI(clk2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + if (++m_cnt >= m_size) + m_cnt = 0; + } + + NETLIB_HANDLERI(clk2_pow2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + m_cnt = (++m_cnt) & (m_size-1); + } + + NETLIB_HANDLERI(first) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt] + m_off()); + m_off = netlist_time::zero(); + if (++m_cnt >= m_size) + m_cnt = 0; + + // continue with optimized clock handlers .... + + if ((m_size & (m_size-1)) == 0) // power of 2? + m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2_pow2, this)); + else + m_feedback.set_delegate(nldelegate(&NETLIB_NAME(extclock)::clk2, this)); + } + + + param_fp_t m_freq; + param_str_t m_pattern; + param_fp_t m_offset; + + logic_input_t m_feedback; + logic_output_t m_Q; + state_var_u8 m_cnt; + std::uint8_t m_size; + state_var<netlist_time> m_off; + std::array<netlist_time, 32> m_inc; + }; + NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "") NETLIB_DEVICE_IMPL(nc_pin, "NC_PIN", "") |