diff options
Diffstat (limited to 'src/lib/netlist/devices/nld_4020.cpp')
-rw-r--r-- | src/lib/netlist/devices/nld_4020.cpp | 183 |
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 |