summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_4020.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_4020.cpp')
-rw-r--r--src/lib/netlist/devices/nld_4020.cpp183
1 files changed, 90 insertions, 93 deletions
diff --git a/src/lib/netlist/devices/nld_4020.cpp b/src/lib/netlist/devices/nld_4020.cpp
index d0e35f502b7..626a22f7d05 100644
--- a/src/lib/netlist/devices/nld_4020.cpp
+++ b/src/lib/netlist/devices/nld_4020.cpp
@@ -1,27 +1,58 @@
-// license:GPL-2.0+
+// license:BSD-3-Clause
// copyright-holders:Couriersud
/*
- * nld_4020.c
+ * nld_4020.cpp
+ *
+ * CD4020: 14-Stage Ripple Carry Binary Counters
+ *
+ * +--------------+
+ * Q12 |1 ++ 16| VDD
+ * Q13 |2 15| Q11
+ * Q14 |3 14| Q10
+ * Q6 |4 4020 13| Q8
+ * Q5 |5 12| Q9
+ * Q7 |6 11| RESET
+ * Q4 |7 10| IP (Input pulses)
+ * VSS |8 9| Q1
+ * +--------------+
+ *
+ *
+ * CD4024: 7-Stage Ripple Carry Binary Counters
+ *
+ * +--------------+
+ * IP |1 ++ 14| VDD
+ * RESET |2 13| NC
+ * Q7 |3 12| Q1
+ * Q6 |4 4024 11| Q2
+ * Q5 |5 10| NC
+ * Q4 |6 9| Q3
+ * VSS |7 8| NC
+ * +--------------+
+ *
+ *
+ * Naming conventions follow Texas Instruments datasheet
+ *
+ * FIXME: Timing depends on VDD-VSS
+ * This needs a cmos d-a/a-d proxy implementation.
*
*/
-//#include "nlid_cmos.h"
-#include "nld_4020.h"
-#include "nlid_system.h"
+#include "nl_base.h"
+#include "nl_factory.h"
-namespace netlist
-{
- namespace devices
- {
+namespace netlist::devices {
+
+ template <unsigned TotalBits, unsigned LiveBitmask>
NETLIB_OBJECT(CD4020_sub)
{
- NETLIB_CONSTRUCTOR(CD4020_sub)
- NETLIB_FAMILY("CD4XXX")
- , m_IP(*this, "IP")
- , m_Q(*this, {{"Q1", "_Q2", "_Q3", "Q4", "Q5", "Q6", "Q7", "Q8", "Q9",
- "Q10", "Q11", "Q12", "Q13", "Q14"}})
+ static_assert((LiveBitmask >> TotalBits) == 0, "Live bitmask too large");
+
+ NETLIB_CONSTRUCTOR_MODEL(CD4020_sub, "CD4XXX")
+ , m_IP(*this, "IP", NETLIB_DELEGATE(ip))
+ , m_RESET(*this, "RESET", NETLIB_DELEGATE(reseti))
+ , m_Q(*this, 1, "Q{}")
, m_cnt(*this, "m_cnt", 0)
- , m_supply(*this, "VDD", "VSS")
+ , m_supply(*this)
{
}
@@ -31,91 +62,57 @@ namespace netlist
m_cnt = 0;
}
- NETLIB_UPDATEI();
-
- public:
- void update_outputs(const unsigned cnt);
-
- logic_input_t m_IP;
- object_array_t<logic_output_t, 14> m_Q;
-
- state_var<unsigned> m_cnt;
- nld_power_pins m_supply;
- };
-
- NETLIB_OBJECT(CD4020)
- {
- NETLIB_CONSTRUCTOR(CD4020)
- NETLIB_FAMILY("CD4XXX")
- , m_sub(*this, "sub")
- , m_RESET(*this, "RESET")
+ NETLIB_HANDLERI(ip)
{
- register_subalias("IP", m_sub.m_IP);
- register_subalias("Q1", m_sub.m_Q[0]);
- register_subalias("Q4", m_sub.m_Q[3]);
- register_subalias("Q5", m_sub.m_Q[4]);
- register_subalias("Q6", m_sub.m_Q[5]);
- register_subalias("Q7", m_sub.m_Q[6]);
- register_subalias("Q8", m_sub.m_Q[7]);
- register_subalias("Q9", m_sub.m_Q[8]);
- register_subalias("Q10", m_sub.m_Q[9]);
- register_subalias("Q11", m_sub.m_Q[10]);
- register_subalias("Q12", m_sub.m_Q[11]);
- register_subalias("Q13", m_sub.m_Q[12]);
- register_subalias("Q14", m_sub.m_Q[13]);
- register_subalias("VDD", "sub.VDD");
- register_subalias("VSS", "sub.VSS");
+ ++m_cnt;
+ update_outputs(m_cnt);
}
- NETLIB_RESETI() { }
- NETLIB_UPDATEI();
- private:
- NETLIB_SUB(CD4020_sub) m_sub;
- logic_input_t m_RESET;
- };
-
-
- NETLIB_UPDATE(CD4020_sub)
- {
- ++m_cnt;
- m_cnt &= 0x3fff;
- update_outputs(m_cnt);
- }
+ NETLIB_HANDLERI(reseti)
+ {
+ if (m_RESET())
+ {
+ m_cnt = 0;
+ m_IP.inactivate();
+ /* static */ const netlist_time reset_time = netlist_time::from_nsec(140);
+ for (unsigned i = 0; i < TotalBits; i++)
+ if (((LiveBitmask >> i) & 1) != 0)
+ m_Q[i].push(0, reset_time);
+ }
+ else
+ m_IP.activate_hl();
+ }
- NETLIB_UPDATE(CD4020)
- {
- if (m_RESET())
+ public:
+ void update_outputs(const unsigned cnt) noexcept
{
- m_sub.m_cnt = 0;
- m_sub.m_IP.inactivate();
- /* static */ const netlist_time reset_time = netlist_time::from_nsec(140);
- m_sub.m_Q[0].push(0, reset_time);
- for (std::size_t i=3; i<14; i++)
- m_sub.m_Q[i].push(0, reset_time);
+ static constexpr const std::array<netlist_time, 14> out_delayQn = {
+ NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
+ NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
+ NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
+ NLTIME_FROM_NS(780), NLTIME_FROM_NS(880),
+ NLTIME_FROM_NS(980), NLTIME_FROM_NS(1080),
+ NLTIME_FROM_NS(1180), NLTIME_FROM_NS(1280),
+ NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480),
+ };
+
+ for (unsigned i = 0; i < TotalBits; i++)
+ if (((LiveBitmask >> i) & 1) != 0)
+ m_Q[i].push((cnt >> i) & 1, out_delayQn[i]);
}
- else
- m_sub.m_IP.activate_hl();
- }
+ logic_input_t m_IP;
+ logic_input_t m_RESET;
+ object_array_t<logic_output_t, TotalBits> m_Q;
- NETLIB_FUNC_VOID(CD4020_sub, update_outputs, (const unsigned cnt))
- {
- static constexpr const std::array<netlist_time, 14> out_delayQn = {
- NLTIME_FROM_NS(180), NLTIME_FROM_NS(280),
- NLTIME_FROM_NS(380), NLTIME_FROM_NS(480),
- NLTIME_FROM_NS(580), NLTIME_FROM_NS(680),
- NLTIME_FROM_NS(780), NLTIME_FROM_NS(880),
- NLTIME_FROM_NS(980), NLTIME_FROM_NS(1080),
- NLTIME_FROM_NS(1180), NLTIME_FROM_NS(1280),
- NLTIME_FROM_NS(1380), NLTIME_FROM_NS(1480),
- };
+ state_var<unsigned> m_cnt;
+ nld_power_pins m_supply;
+ };
- m_Q[0].push(cnt & 1, out_delayQn[0]);
- for (std::size_t i=3; i<14; i++)
- m_Q[i].push((cnt >> i) & 1, out_delayQn[i]);
- }
+ // FIXME: Exposes Q2 and Q3 as well
+ using NETLIB_NAME(CD4020_impl) = nld_CD4020_sub<14, 0x3ff9>;
+ NETLIB_DEVICE_IMPL_ALIAS(CD4020, CD4020_impl,"CD4020", "+IP,+RESET,+VDD,+VSS")
- NETLIB_DEVICE_IMPL(CD4020, "CD4020", "")
- NETLIB_DEVICE_IMPL_ALIAS(CD4020_WI, CD4020, "CD4020_WI", "+IP,+RESET,+VDD,+VSS")
+ using NETLIB_NAME(CD4024_impl) = nld_CD4020_sub<7, 0x7f>;
+ NETLIB_DEVICE_IMPL_ALIAS(CD4024, CD4024_impl, "CD4024", "")
- } //namespace devices
-} // namespace netlist
+} // namespace netlist::devices