summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/devices/nld_7497.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/devices/nld_7497.cpp')
-rw-r--r--src/lib/netlist/devices/nld_7497.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/src/lib/netlist/devices/nld_7497.cpp b/src/lib/netlist/devices/nld_7497.cpp
new file mode 100644
index 00000000000..1432884b8dd
--- /dev/null
+++ b/src/lib/netlist/devices/nld_7497.cpp
@@ -0,0 +1,174 @@
+// license:GPL-2.0+
+// copyright-holders:Sergey Svishchev
+/*
+ * nld_7497.cpp
+ *
+ * To do:
+ *
+ * - STRB and EN
+ * - Timing
+ */
+
+#include "nld_7497.h"
+#include "netlist/nl_base.h"
+
+namespace netlist
+{
+ namespace devices
+ {
+
+ static constexpr const netlist_time out_delay_CLK_Y[2] = { NLTIME_FROM_NS(20), NLTIME_FROM_NS(26) }; // tPHL, tPLH
+ static constexpr const netlist_time out_delay_CLK_Z[2] = { NLTIME_FROM_NS(17), NLTIME_FROM_NS(12) };
+
+ NETLIB_OBJECT(7497)
+ {
+ NETLIB_CONSTRUCTOR(7497)
+ , m_B(*this, {{"B5", "B4", "B3", "B2", "B1", "B0"}})
+ , m_CLK(*this, "CLK", NETLIB_DELEGATE(7497, clk_strb))
+ , m_STRBQ(*this, "STRBQ", NETLIB_DELEGATE(7497, clk_strb))
+ , m_ENQ(*this, "ENQ")
+ , m_UNITYQ(*this, "UNITYQ", NETLIB_DELEGATE(7497, unity))
+ , m_CLR(*this, "CLR", NETLIB_DELEGATE(7497, clr))
+ , m_Y(*this, "Y")
+ , m_ZQ(*this, "ZQ")
+ , m_ENOUTQ(*this, "ENOUTQ")
+ , m_cnt(*this, "_m_cnt", 0)
+ , m_rate(*this, "_m_rate", 0)
+ , m_state(*this, "_m_state", 0)
+ , m_lastclock(*this, "_m_lastclock", 0)
+ {
+ }
+
+ private:
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+
+ NETLIB_HANDLERI(noop) { }
+ NETLIB_HANDLERI(unity);
+ NETLIB_HANDLERI(clr);
+ NETLIB_HANDLERI(clk_strb);
+
+ protected:
+ object_array_t<logic_input_t, 6> m_B;
+ logic_input_t m_CLK;
+ logic_input_t m_STRBQ;
+ logic_input_t m_ENQ;
+ logic_input_t m_UNITYQ;
+ logic_input_t m_CLR;
+
+ logic_output_t m_Y;
+ logic_output_t m_ZQ;
+ logic_output_t m_ENOUTQ;
+
+ state_var_u8 m_cnt;
+ state_var_u8 m_rate;
+ state_var_sig m_state;
+ state_var_sig m_lastclock;
+
+ void newstate(const netlist_sig_t state)
+ {
+ m_state = state;
+ m_ZQ.push(state, out_delay_CLK_Z[state]);
+ //netlist_sig_t y = (state ^ 1) | (m_UNITY() ^ 1); // OR with negated inputs == NAND
+ netlist_sig_t y = (state & m_UNITYQ()) ^ 1; // OR with negated inputs == NAND
+ m_Y.push(y, out_delay_CLK_Y[y]);
+ }
+
+ uint8_t rate()
+ {
+ uint8_t a = 0;
+
+ for (std::size_t i = 0; i < 6; i++)
+ a |= (m_B[i]() << i);
+
+ return a;
+ }
+ };
+
+ NETLIB_RESET(7497)
+ {
+ m_cnt = 0;
+ m_rate = 0;
+ m_lastclock = 0;
+ }
+
+ NETLIB_UPDATE(7497)
+ {
+ m_rate = rate();
+ clk_strb();
+ }
+
+ NETLIB_HANDLER(7497, unity)
+ {
+ newstate (m_state);
+ }
+
+ NETLIB_HANDLER(7497, clr)
+ {
+ m_cnt = 0;
+ clk_strb();
+ }
+
+ NETLIB_HANDLER(7497, clk_strb)
+ {
+ netlist_sig_t clk = m_CLK();
+
+ if (!m_lastclock && clk && !m_ENQ() && !m_CLR())
+ {
+ m_cnt++;
+ m_cnt &= 63;
+ }
+ m_lastclock = clk;
+
+ const netlist_sig_t clk_strb = (clk ^ 1) & (m_STRBQ() ^ 1);
+
+ const netlist_sig_t cntQ = m_cnt;
+
+ // NOR GATE
+ netlist_sig_t p1 = ((cntQ & 63) == 31 && (m_rate & 32)) ||
+ ((cntQ & 31) == 15 && (m_rate & 16)) ||
+ ((cntQ & 15) == 7 && (m_rate & 8)) ||
+ ((cntQ & 7) == 3 && (m_rate & 4)) ||
+ ((cntQ & 3) == 1 && (m_rate & 2)) ||
+ ((cntQ & 1) == 0 && (m_rate & 1));
+
+ p1 = (p1 & clk_strb) ^ 1;
+
+ newstate(p1);
+
+ // NAND gate
+ if ((m_cnt == 63) && !m_ENQ())
+ m_ENOUTQ.push(0, out_delay_CLK_Y[0]); // XXX timing
+ else
+ m_ENOUTQ.push(1, out_delay_CLK_Y[1]);
+
+ }
+
+ NETLIB_OBJECT_DERIVED(7497_dip, 7497)
+ {
+ NETLIB_CONSTRUCTOR_DERIVED(7497_dip, 7497)
+ {
+ register_subalias("1", m_B[4]); // B0
+ register_subalias("2", m_B[1]); // B4
+ register_subalias("3", m_B[0]); // B5
+ register_subalias("4", m_B[5]); // B0
+ register_subalias("5", m_ZQ);
+ register_subalias("6", m_Y);
+ register_subalias("7", m_ENOUTQ);
+
+ register_subalias("9", m_CLK);
+ register_subalias("10", m_STRBQ);
+ register_subalias("11", m_UNITYQ);
+ register_subalias("12", m_ENQ);
+ register_subalias("13", m_CLR);
+ register_subalias("14", m_B[3]); // B2
+ register_subalias("15", m_B[2]); // B3
+ }
+ };
+
+
+ NETLIB_DEVICE_IMPL(7497, "TTL_7497", "+CLK,+STRBQ,+ENQ,+UNITYQ,+CLR,+B0,+B1,+B2,+B3,+B4,+B5")
+ NETLIB_DEVICE_IMPL(7497_dip, "TTL_7497_DIP", "")
+
+ } //namespace devices
+} // namespace netlist