diff options
Diffstat (limited to 'src/lib/netlist/devices/nld_system.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_system.cpp | 242 |
1 files changed, 158 insertions, 84 deletions
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp index 5a1868bb775..e2580a296c6 100644 --- a/src/lib/netlist/devices/nld_system.cpp +++ b/src/lib/netlist/devices/nld_system.cpp @@ -1,123 +1,197 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Couriersud /* - * nld_system.c + * nld_system.cpp * */ -#include "netlist/solver/nld_solver.h" -#include "netlist/solver/nld_matrix_solver.h" +#include "solver/nld_solver.h" #include "nlid_system.h" +#include "solver/nld_matrix_solver.h" -namespace netlist -{ - namespace devices - { - // ---------------------------------------------------------------------------------------- - // netlistparams - // ---------------------------------------------------------------------------------------- +#include "plib/pstrutil.h" +namespace netlist::devices { - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- // extclock - // ---------------------------------------------------------------------------------------- + // ------------------------------------------------------------------------- - NETLIB_RESET(extclock) + NETLIB_OBJECT(extclock) { - m_cnt = 0; - m_off = netlist_time::from_double(m_offset()); - m_feedback.m_delegate = NETLIB_DELEGATE(extclock, update); + 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; - //m_feedback.m_delegate .set(&NETLIB_NAME(extclock)::update, this); - //m_Q.initial(0); - } + } - NETLIB_HANDLER(extclock, clk2) - { - m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); - if (++m_cnt >= m_size) + NETLIB_RESETI() + { m_cnt = 0; - } + m_off = netlist_time::from_fp<param_fp_t::value_type>(m_offset()); + m_feedback.set_delegate(NETLIB_DELEGATE(first)); + } + //NETLIB_UPDATE_PARAMI(); - NETLIB_HANDLER(extclock, clk2_pow2) - { - m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); - m_cnt = (++m_cnt) & (m_size-1); - } + private: - NETLIB_UPDATE(extclock) - { - 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; + NETLIB_HANDLERI(clk2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + if (++m_cnt >= m_size) + m_cnt = 0; + } - // continue with optimized clock handlers .... + NETLIB_HANDLERI(clk2_pow2) + { + m_Q.push((m_cnt & 1) ^ 1, m_inc[m_cnt]); + m_cnt = (++m_cnt) & (m_size-1); + } - if ((m_size & (m_size-1)) == 0) // power of 2? - m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2_pow2, this); - else - m_feedback.m_delegate.set(&NETLIB_NAME(extclock)::clk2, this); - } + 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; - // ----------------------------------------------------------------------------- - // nld_res_sw - // ----------------------------------------------------------------------------- + // continue with optimized clock handlers .... - NETLIB_RESET(res_sw) - { - m_last_state = 0; - m_R.set_R(m_ROFF()); - } + if ((m_size & (m_size-1)) == 0) // power of 2? + m_feedback.set_delegate(nl_delegate(&NETLIB_NAME(extclock)::clk2_pow2, this)); + else + m_feedback.set_delegate(nl_delegate(&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_UPDATE(res_sw) + // ------------------------------------------------------------------------- + // sys_pulse + // ------------------------------------------------------------------------- + + NETLIB_OBJECT(sys_pulse) { - const netlist_sig_t state = m_I(); - if (state != m_last_state) + NETLIB_CONSTRUCTOR(sys_pulse) + , m_I(*this, "I", NETLIB_DELEGATE(input)) + , m_FB(*this, "FB", NETLIB_DELEGATE(feedback)) + , m_Q(*this, "Q") + , m_delay(*this, "DELAY", 10) + , m_duration(*this, "DURATION", 100) + , m_invert_input(*this, "INVERT_INPUT", 1) + , m_invert_output(*this, "INVERT_OUTPUT", 1) + , m_last(*this, "m_last", 0) { - m_last_state = state; - const nl_double R = state ? m_RON() : m_ROFF(); - - // FIXME: We only need to update the net first if this is a time stepping net - m_R.update(); - m_R.set_R(R); - m_R.solve_later(); + connect(m_Q, m_FB); } - } - /* ----------------------------------------------------------------------------- - * nld_function - * ----------------------------------------------------------------------------- */ + //NETLIB_UPDATE_PARAMI(); + NETLIB_RESETI() + { + //m_Q.initial(0); + } - NETLIB_RESET(function) - { - //m_Q.initial(0.0); - } + private: + NETLIB_HANDLERI(input) + { + netlist_sig_t nval = m_I() ^ m_invert_input; + if (nval && !m_last) + { + // L_to_H + m_Q.push(1 ^ m_invert_output, NLTIME_FROM_NS(static_cast<unsigned>(m_delay()))); + } + m_last = nval; + } - NETLIB_UPDATE(function) - { - for (std::size_t i=0; i < static_cast<unsigned>(m_N()); i++) + NETLIB_HANDLERI(feedback) { - m_vals[i] = (*m_I[i])(); + if (m_FB() == (1 ^ m_invert_output)) + m_Q.push(0 ^ m_invert_output, NLTIME_FROM_NS(static_cast<unsigned>(m_duration()))); } - m_Q.push(m_compiled.evaluate(m_vals)); - } + logic_input_t m_I; + logic_input_t m_FB; + logic_output_t m_Q; + + param_int_t m_delay; + param_int_t m_duration; + param_logic_t m_invert_input; + param_logic_t m_invert_output; - NETLIB_DEVICE_IMPL(dummy_input, "DUMMY_INPUT", "") - NETLIB_DEVICE_IMPL(frontier, "FRONTIER_DEV", "+I,+G,+Q") - NETLIB_DEVICE_IMPL(function, "AFUNC", "N,FUNC") + state_var<netlist_sig_t> m_last; + }; + + + 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") NETLIB_DEVICE_IMPL(clock, "CLOCK", "FREQ") - NETLIB_DEVICE_IMPL(varclock, "VARCLOCK", "FUNC") + NETLIB_DEVICE_IMPL(varclock, "VARCLOCK", "N,FUNC") NETLIB_DEVICE_IMPL(extclock, "EXTCLOCK", "FREQ,PATTERN") - NETLIB_DEVICE_IMPL(res_sw, "RES_SWITCH", "+IN,+P1,+P2") + NETLIB_DEVICE_IMPL(sys_dsw1, "SYS_DSW", "+I,+1,+2") + NETLIB_DEVICE_IMPL(sys_dsw2, "SYS_DSW2", "") + NETLIB_DEVICE_IMPL(sys_compd, "SYS_COMPD", "") + NETLIB_DEVICE_IMPL(sys_pulse, "SYS_PULSE", "DELAY,DURATION,INVERT_INPUT,INVERT_OUTPUT") + + using NETLIB_NAME(sys_noise_mt_u) = + NETLIB_NAME(sys_noise)<plib::mt19937_64, plib::uniform_distribution_t>; + NETLIB_DEVICE_IMPL(sys_noise_mt_u, "SYS_NOISE_MT_U", "SIGMA") + + using NETLIB_NAME(sys_noise_mt_n) = + NETLIB_NAME(sys_noise)<plib::mt19937_64, plib::normal_distribution_t>; + NETLIB_DEVICE_IMPL(sys_noise_mt_n, "SYS_NOISE_MT_N", "SIGMA") + NETLIB_DEVICE_IMPL(mainclock, "MAINCLOCK", "FREQ") - NETLIB_DEVICE_IMPL(gnd, "GND", "") - NETLIB_DEVICE_IMPL(netlistparams, "PARAMETER", "") + NETLIB_DEVICE_IMPL(gnd, "GNDA", "") + + using NETLIB_NAME(logic_input8) = NETLIB_NAME(logic_inputN)<8>; + NETLIB_DEVICE_IMPL(logic_input8, "LOGIC_INPUT8", "IN,MODEL") - NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,FAMILY") + NETLIB_DEVICE_IMPL(logic_input, "LOGIC_INPUT", "IN,MODEL") NETLIB_DEVICE_IMPL_ALIAS(logic_input_ttl, logic_input, "TTL_INPUT", "IN") - } //namespace devices -} // namespace netlist +} // namespace netlist::devices |