Rewrote 7497 device. (nw)

The 7497 device should now work as described in the TI datasheet. This
datasheet contains an internal schematic with details on gates and D
flip flops used.
This commit is contained in:
couriersud 2019-01-08 02:38:57 +01:00
parent bc732054f6
commit 4f38e6cc54
2 changed files with 42 additions and 84 deletions

View File

@ -24,18 +24,18 @@ namespace netlist
{ {
NETLIB_CONSTRUCTOR(7497) NETLIB_CONSTRUCTOR(7497)
, m_B(*this, {{"B0", "B1", "B2", "B3", "B4", "B5"}}) , m_B(*this, {{"B0", "B1", "B2", "B3", "B4", "B5"}})
, m_CLK(*this, "CLK", NETLIB_DELEGATE(7497, clk)) , m_CLK(*this, "CLK", NETLIB_DELEGATE(7497, clk_strb))
, m_STRB(*this, "STRB") , m_STRB(*this, "STRB", NETLIB_DELEGATE(7497, clk_strb))
, m_EN(*this, "EN") , m_EN(*this, "EN")
, m_UNITY(*this, "UNITY", NETLIB_DELEGATE(7497, unity)) , m_UNITY(*this, "UNITY", NETLIB_DELEGATE(7497, unity))
, m_CLR(*this, "CLR", NETLIB_DELEGATE(7497, clr)) , m_CLR(*this, "CLR", NETLIB_DELEGATE(7497, clr))
, m_Y(*this, "Y") , m_Y(*this, "Y")
, m_Z(*this, "Z") , m_Z(*this, "Z")
, m_ENOUT(*this, "ENOUT") , m_ENOUT(*this, "ENOUT")
, m_reset(*this, "_m_reset", 0) , m_cnt(*this, "_m_cnt", 0)
, m_a(*this, "_m_a", 0)
, m_rate(*this, "_m_rate", 0) , m_rate(*this, "_m_rate", 0)
, m_state(*this, "_m_state", 0) , m_state(*this, "_m_state", 0)
, m_lastclock(*this, "_m_lastclock", 0)
{ {
} }
@ -46,7 +46,7 @@ namespace netlist
NETLIB_HANDLERI(noop) { } NETLIB_HANDLERI(noop) { }
NETLIB_HANDLERI(unity); NETLIB_HANDLERI(unity);
NETLIB_HANDLERI(clr); NETLIB_HANDLERI(clr);
NETLIB_HANDLERI(clk); NETLIB_HANDLERI(clk_strb);
object_array_t<logic_input_t, 6> m_B; object_array_t<logic_input_t, 6> m_B;
logic_input_t m_CLK; logic_input_t m_CLK;
@ -59,24 +59,17 @@ namespace netlist
logic_output_t m_Z; logic_output_t m_Z;
logic_output_t m_ENOUT; logic_output_t m_ENOUT;
state_var_sig m_reset; state_var_u8 m_cnt;
state_var_sig m_a; state_var_u8 m_rate;
state_var_sig m_rate;
state_var_sig m_state; state_var_sig m_state;
state_var_sig m_lastclock;
void newstate(const netlist_sig_t state) void newstate(const netlist_sig_t state)
{ {
m_state = state; m_state = state;
m_Z.push(state ^ 1, out_delay_CLK_Z[state ^ 1]); m_Z.push(state, out_delay_CLK_Z[state]);
if (m_UNITY()) netlist_sig_t y = (state ^ 1) | (m_UNITY() ^ 1); // OR with negated inputs == NAND
m_Y.push(state, out_delay_CLK_Y[state]); m_Y.push(y, out_delay_CLK_Y[y]);
else
m_Y.push(1, out_delay_CLK_Y[1]);
if (m_CLK())
m_CLK.set_state(logic_t::STATE_INP_HL);
else
m_CLK.set_state(logic_t::STATE_INP_LH);
} }
int rate() int rate()
@ -92,38 +85,14 @@ namespace netlist
NETLIB_RESET(7497) NETLIB_RESET(7497)
{ {
m_reset = 1; m_cnt = 0;
m_a = 0;
m_rate = 0; m_rate = 0;
m_CLK.set_state(logic_t::STATE_INP_HL); m_lastclock = 0;
m_B[0].set_state(logic_t::STATE_INP_LH);
m_B[1].set_state(logic_t::STATE_INP_LH);
m_B[2].set_state(logic_t::STATE_INP_LH);
m_B[3].set_state(logic_t::STATE_INP_LH);
m_B[4].set_state(logic_t::STATE_INP_LH);
m_B[5].set_state(logic_t::STATE_INP_LH);
m_STRB.set_state(logic_t::STATE_INP_HL);
#if 0
m_EN.set_state(logic_t::STATE_INP_HL);
#endif
m_UNITY.set_state(logic_t::STATE_INP_LH);
m_CLR.set_state(logic_t::STATE_INP_LH);
newstate(0);
m_ENOUT.push(1, out_delay_CLK_Y[1]);
} }
NETLIB_UPDATE(7497) NETLIB_UPDATE(7497)
{ {
// m_reset = m_CLR() ^ 1; m_rate = rate();
// m_reset = 1 -- normal operation
if (!m_reset)
{
m_CLK.inactivate();
m_Y.push_force(0, NLTIME_FROM_NS(24));
m_Z.push_force(1, NLTIME_FROM_NS(15));
m_ENOUT.push_force(1, NLTIME_FROM_NS(15)); // XXX
}
} }
NETLIB_HANDLER(7497, unity) NETLIB_HANDLER(7497, unity)
@ -133,51 +102,39 @@ namespace netlist
NETLIB_HANDLER(7497, clr) NETLIB_HANDLER(7497, clr)
{ {
m_a = 0; m_cnt = 0;
newstate (0); clk_strb();
} }
NETLIB_HANDLER(7497, clk) NETLIB_HANDLER(7497, clk_strb)
{ {
netlist_sig_t clk = m_CLK(); netlist_sig_t clk = m_CLK();
if (m_reset) if (!m_lastclock && clk && !m_EN() && !m_CLR())
{ {
// lock rate on falling edge of CLK m_cnt++;
if (!clk) m_rate = rate(); m_cnt &= 63;
if (m_rate && !m_STRB())
{
if (
((m_a & 1) == 0 && (m_rate & 32)) ||
((m_a & 3) == 1 && (m_rate & 16)) ||
((m_a & 7) == 3 && (m_rate & 8)) ||
((m_a & 15) == 7 && (m_rate & 4)) ||
((m_a & 31) == 15 && (m_rate & 2)) ||
((m_a & 63) == 31 && (m_rate & 1)))
newstate(clk);
}
else
{
newstate(0);
}
if (m_a == 62)
m_ENOUT.push(0, out_delay_CLK_Y[0]); // XXX timing
else
m_ENOUT.push(1, out_delay_CLK_Y[1]);
if (clk)
{
m_CLK.set_state(logic_t::STATE_INP_HL);
m_a++;
m_a &= 63;
}
else
{
m_CLK.set_state(logic_t::STATE_INP_LH);
}
} }
const netlist_sig_t clk_strb = (clk ^ 1) & (m_STRB() ^ 1);
const netlist_sig_t cntQ = m_cnt;
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);
if (m_cnt == 63 && !m_EN())
m_ENOUT.push(0, out_delay_CLK_Y[0]); // XXX timing
else
m_ENOUT.push(1, out_delay_CLK_Y[1]);
} }
NETLIB_DEVICE_IMPL(7497) NETLIB_DEVICE_IMPL(7497)

View File

@ -235,9 +235,10 @@ NETLIST_START(tp1985)
ALIAS(videomix, C3.1) ALIAS(videomix, C3.1)
#else #else
ALIAS(videomix, R18.2) ALIAS(videomix, R18.2)
//LOG(logV, R18.2)
#endif #endif
#if 1 #if 0
HINT(clk, NO_DEACTIVATE) HINT(clk, NO_DEACTIVATE)
#endif #endif