summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_system.cpp')
-rw-r--r--src/lib/netlist/devices/nld_system.cpp242
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