summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_mm5837.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_mm5837.cpp')
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp172
1 files changed, 84 insertions, 88 deletions
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index a8add5aaeea..cd92ce1e5df 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -1,57 +1,106 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
/*
- * nld_MM5837.c
+ * nld_MM5837.cpp
+ *
+ * MM5837: Digital noise source
+ *
+ * +--------+
+ * VDD |1 ++ 8| NC
+ * VGG |2 7| NC
+ * OUT |3 6| NC
+ * VSS |4 5| NC
+ * +--------+
+ *
+ * Naming conventions follow National Semiconductor datasheet
*
*/
-#include "nld_mm5837.h"
-#include "netlist/analog/nlid_twoterm.h"
-#include "netlist/solver/nld_matrix_solver.h"
+#include "analog/nlid_twoterm.h"
+#include "solver/nld_matrix_solver.h"
-#define R_LOW (1000.0)
-#define R_HIGH (1000.0)
+namespace netlist::devices {
-namespace netlist
-{
- namespace devices
+ NETLIB_OBJECT(MM5837)
{
- NETLIB_OBJECT(MM5837_dip)
- {
- NETLIB_CONSTRUCTOR(MM5837_dip)
+ NETLIB_CONSTRUCTOR(MM5837)
, m_RV(*this, "_RV")
- , m_VDD(*this, "1")
- , m_VGG(*this, "2")
- , m_VSS(*this, "4")
- , m_FREQ(*this, "FREQ", 24000)
+ , m_VDD(*this, "VDD", NETLIB_DELEGATE(inputs))
+ , m_VGG(*this, "VGG", NETLIB_DELEGATE(inputs))
+ , m_VSS(*this, "VSS", NETLIB_DELEGATE(inputs))
+ , m_FREQ(*this, "FREQ", 24000 * 2)
+ , m_R_LOW(*this, "R_LOW", 1000)
+ , m_R_HIGH(*this, "R_HIGH", 1000)
/* clock */
- , m_feedback(*this, "_FB")
+ , m_feedback(*this, "_FB", NETLIB_DELEGATE(inputs))
, m_Q(*this, "_Q")
- , m_inc(netlist_time::from_hz(24000))
+ , m_inc(netlist_time::from_hz(24000 * 2))
, m_shift(*this, "m_shift", 0)
- , m_is_timestep(false)
{
- connect(m_feedback, m_Q);
+ connect("_FB", "_Q");
+
+ // output
+ connect("_RV.2", "VDD");
+ register_sub_alias("OUT", "_RV.1");
+ }
- /* output */
- //register_term("_RV1", m_RV.m_P);
- //register_term("_RV2", m_RV.m_N);
- connect(m_RV.m_N, m_VDD);
+ NETLIB_RESETI()
+ {
+ //m_V0.initial(0.0);
+ //m_RV.do_reset();
+ m_RV().set_G_V_I(plib::reciprocal(m_R_LOW()),
+ nlconst::zero(),
+ nlconst::zero());
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
+ if (m_FREQ() < nlconst::magic(24000*2) || m_FREQ() > nlconst::magic(56000*2))
+ log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
+
+ m_shift = 0x1ffff;
+ }
- /* device */
- register_subalias("3", m_RV.m_P);
+ NETLIB_UPDATE_PARAMI()
+ {
+ m_inc = netlist_time::from_fp(plib::reciprocal(m_FREQ()));
+ if (m_FREQ() < nlconst::magic(24000*2) || m_FREQ() > nlconst::magic(56000*2))
+ log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
}
- NETLIB_RESETI();
- NETLIB_UPDATEI();
- NETLIB_UPDATE_PARAMI();
+ private:
+ NETLIB_HANDLERI(inputs)
+ {
+ m_Q.push(!m_feedback(), m_inc);
+
+ /* shift register
+ *
+ * 17 bits, bits 17 & 14 feed back to input
+ *
+ */
+
+ const auto last_state = m_shift & 0x01;
+ /* shift */
+ m_shift = (m_shift >> 1) | (((m_shift & 0x01) ^ ((m_shift >> 3) & 0x01)) << 16);
+ const auto state = m_shift & 0x01;
+
+ if (state != last_state)
+ {
+ const nl_fptype R = state ? m_R_HIGH : m_R_LOW;
+ const nl_fptype V = state ? m_VDD() : m_VSS();
+
+ m_RV().change_state([this, &R, &V]()
+ {
+ m_RV().set_G_V_I(plib::reciprocal(R), V, nlconst::zero());
+ });
+ }
+
+ }
- protected:
- analog::NETLIB_SUB(twoterm) m_RV;
+ NETLIB_SUB_NS(analog, two_terminal) m_RV;
analog_input_t m_VDD;
analog_input_t m_VGG;
analog_input_t m_VSS;
- param_double_t m_FREQ;
+ param_fp_t m_FREQ;
+ param_fp_t m_R_LOW;
+ param_fp_t m_R_HIGH;
/* clock stage */
logic_input_t m_feedback;
@@ -60,61 +109,8 @@ namespace netlist
/* state */
state_var_u32 m_shift;
-
- /* cache */
- bool m_is_timestep;
};
- NETLIB_RESET(MM5837_dip)
- {
- //m_V0.initial(0.0);
- //m_RV.do_reset();
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / R_LOW, 0.0, 0.0);
- m_inc = netlist_time::from_double(1.0 / m_FREQ());
- if (m_FREQ() < 24000 || m_FREQ() > 56000)
- log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
-
- m_shift = 0x1ffff;
- m_is_timestep = m_RV.m_P.net().solver()->has_timestep_devices();
- }
-
- NETLIB_UPDATE_PARAM(MM5837_dip)
- {
- m_inc = netlist_time::from_double(1.0 / m_FREQ());
- if (m_FREQ() < 24000 || m_FREQ() > 56000)
- log().warning(MW_FREQUENCY_OUTSIDE_OF_SPECS_1(m_FREQ()));
- }
-
- NETLIB_UPDATE(MM5837_dip)
- {
- m_Q.push(!m_feedback(), m_inc);
-
- /* shift register
- *
- * 17 bits, bits 17 & 14 feed back to input
- *
- */
-
- const auto last_state = m_shift & 0x01;
- /* shift */
- m_shift = (m_shift >> 1) | (((m_shift & 0x01) ^ ((m_shift >> 3) & 0x01)) << 16);
- const auto state = m_shift & 0x01;
-
- if (state != last_state)
- {
- const nl_double R = state ? R_HIGH : R_LOW;
- const nl_double V = state ? m_VDD() : m_VSS();
-
- // We only need to update the net first if this is a time stepping net
- if (m_is_timestep)
- m_RV.update();
- m_RV.set_G_V_I(plib::constants<nl_double>::one() / R, V, plib::constants<nl_double>::zero());
- m_RV.solve_later(NLTIME_FROM_NS(1));
- }
-
- }
-
- NETLIB_DEVICE_IMPL(MM5837_dip, "MM5837_DIP", "")
+ NETLIB_DEVICE_IMPL(MM5837, "MM5837", "")
- } //namespace devices
-} // namespace netlist
+} // namespace netlist::devices