netlist: another batch of explicit handler refactoring.

This commit is contained in:
couriersud 2020-07-12 16:44:03 +02:00
parent 985c0225d1
commit f873cbcbad
18 changed files with 549 additions and 481 deletions

View File

@ -12,16 +12,18 @@ namespace netlist
{
namespace devices
{
// FIXME: Optimize
NETLIB_OBJECT(74194)
{
NETLIB_CONSTRUCTOR(74194)
, m_DATA(*this, {"D", "C", "B", "A"})
, m_SLIN(*this, "SLIN")
, m_SRIN(*this, "SRIN")
, m_CLK(*this, "CLK")
, m_S0(*this, "S0")
, m_S1(*this, "S1")
, m_CLRQ(*this, "CLRQ")
, m_DATA(*this, {"D", "C", "B", "A"}, NETLIB_DELEGATE(inputs))
, m_SLIN(*this, "SLIN", NETLIB_DELEGATE(inputs))
, m_SRIN(*this, "SRIN", NETLIB_DELEGATE(inputs))
, m_CLK(*this, "CLK", NETLIB_DELEGATE(inputs))
, m_S0(*this, "S0", NETLIB_DELEGATE(inputs))
, m_S1(*this, "S1", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_Q(*this, {"QD", "QC", "QB", "QA"})
, m_last_CLK(*this, "m_last_CLK", 0)
, m_last_Q(*this, "m_last_Q", 0)
@ -34,10 +36,55 @@ namespace netlist
m_last_CLK = 0;
m_last_Q = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(74194_dip);
private:
// FIXME: Timing
NETLIB_HANDLERI(inputs)
{
unsigned q = m_last_Q;
if (!m_CLRQ())
{
q = 0;
}
else
{
if (!m_last_CLK && m_CLK())
{
unsigned s = (m_S1() << 1) | m_S0();
switch (s)
{
case 0: // LL: Keep old value
break;
case 1: // LH: Shift right
q >>= 1;
q |= m_SRIN() ? 8 : 0;
break;
case 2:
q <<= 1;
q |= m_SLIN() ? 1 : 0;
break;
case 3:
q = 0;
for (std::size_t i=0; i<4; i++)
q |= m_DATA[i]() << i;
break;
}
}
}
m_last_Q = q;
m_last_CLK = m_CLK();
for (std::size_t i=0; i<4; i++)
m_Q[i].push((q >> i) & 1, NLTIME_FROM_NS(26)); // FIXME: Timing
}
object_array_t<logic_input_t, 4> m_DATA;
logic_input_t m_SLIN;
logic_input_t m_SRIN;
@ -82,49 +129,6 @@ namespace netlist
NETLIB_SUB(74194) A;
};
// FIXME: Timing
NETLIB_UPDATE(74194)
{
unsigned q = m_last_Q;
if (!m_CLRQ())
{
q = 0;
}
else
{
if (!m_last_CLK && m_CLK())
{
unsigned s = (m_S1() << 1) | m_S0();
switch (s)
{
case 0: // LL: Keep old value
break;
case 1: // LH: Shift right
q >>= 1;
q |= m_SRIN() ? 8 : 0;
break;
case 2:
q <<= 1;
q |= m_SLIN() ? 1 : 0;
break;
case 3:
q = 0;
for (std::size_t i=0; i<4; i++)
q |= m_DATA[i]() << i;
break;
}
}
}
m_last_Q = q;
m_last_CLK = m_CLK();
for (std::size_t i=0; i<4; i++)
m_Q[i].push((q >> i) & 1, NLTIME_FROM_NS(26)); // FIXME: Timing
}
NETLIB_DEVICE_IMPL(74194, "TTL_74194", "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(74194_dip, "TTL_74194_DIP", "")

View File

@ -23,18 +23,35 @@ namespace netlist
NETLIB_OBJECT(74365)
{
NETLIB_CONSTRUCTOR(74365)
, m_G1Q(*this, "G1Q")
, m_G2Q(*this, "G2Q")
, m_A(*this, { "A1", "A2", "A3", "A4", "A5", "A6" })
, m_G1Q(*this, "G1Q", NETLIB_DELEGATE(inputs))
, m_G2Q(*this, "G2Q", NETLIB_DELEGATE(inputs))
, m_A(*this, { "A1", "A2", "A3", "A4", "A5", "A6" }, NETLIB_DELEGATE(inputs))
, m_Y(*this, { "Y1", "Y2", "Y3", "Y4", "Y5", "Y6" })
, m_power_pins(*this)
{
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(74365_dip);
private:
NETLIB_HANDLERI(inputs)
{
if (!m_G1Q() && !m_G2Q())
{
for (std::size_t i=0; i<6; i++)
m_Y[i].push(m_A[i](), NLTIME_FROM_NS(20)); // FIXME: Correct timing
}
else
{
for (std::size_t i=0; i<6; i++)
m_Y[i].push(0, NLTIME_FROM_NS(20)); // FIXME: Correct timing
}
}
logic_input_t m_G1Q;
logic_input_t m_G2Q;
object_array_t<logic_input_t, 6> m_A;
@ -71,20 +88,6 @@ namespace netlist
NETLIB_SUB(74365) A;
};
NETLIB_UPDATE(74365)
{
if (!m_G1Q() && !m_G2Q())
{
for (std::size_t i=0; i<6; i++)
m_Y[i].push(m_A[i](), NLTIME_FROM_NS(20)); // FIXME: Correct timing
}
else
{
for (std::size_t i=0; i<6; i++)
m_Y[i].push(0, NLTIME_FROM_NS(20)); // FIXME: Correct timing
}
}
NETLIB_DEVICE_IMPL(74365, "TTL_74365", "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6,@VCC,@GND")
NETLIB_DEVICE_IMPL(74365_dip, "TTL_74365_DIP", "")

View File

@ -18,9 +18,9 @@ namespace netlist
NETLIB_OBJECT(74377_GATE)
{
NETLIB_CONSTRUCTOR(74377_GATE)
, m_E(*this, "E")
, m_D(*this, "D")
, m_CP(*this, "CP")
, m_E(*this, "E", NETLIB_DELEGATE(inputs))
, m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_CP(*this, "CP", NETLIB_DELEGATE(inputs))
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
, m_cp(*this, "m_cp", 0)
@ -32,6 +32,12 @@ namespace netlist
{
}
NETLIB_UPDATEI()
{
inputs();
}
private:
NETLIB_HANDLERI(inputs)
{
netlist_sig_t last_cp = m_cp;
@ -45,7 +51,6 @@ namespace netlist
}
}
private:
logic_input_t m_E;
logic_input_t m_D;
logic_input_t m_CP;

View File

@ -17,8 +17,8 @@ namespace netlist
NETLIB_OBJECT(74393)
{
NETLIB_CONSTRUCTOR(74393)
, m_CP(*this, "CP")
, m_MR(*this, "MR")
, m_CP(*this, "CP", NETLIB_DELEGATE(inputs))
, m_MR(*this, "MR", NETLIB_DELEGATE(inputs))
, m_Q(*this, {"Q0", "Q1", "Q2", "Q3"})
, m_cnt(*this, "m_cnt", 0)
, m_cp(*this, "m_cp", 0)
@ -34,6 +34,11 @@ namespace netlist
}
NETLIB_UPDATEI()
{
inputs();
}
NETLIB_HANDLERI(inputs)
{
netlist_sig_t last_cp = m_cp;
netlist_sig_t last_mr = m_mr;

View File

@ -18,13 +18,13 @@ namespace netlist
NETLIB_OBJECT(7448)
{
NETLIB_CONSTRUCTOR(7448)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
, m_LTQ(*this, "LTQ")
, m_BIQ(*this, "BIQ")
, m_RBIQ(*this, "RBIQ")
, m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_C(*this, "C", NETLIB_DELEGATE(inputs))
, m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_LTQ(*this, "LTQ", NETLIB_DELEGATE(inputs))
, m_BIQ(*this, "BIQ", NETLIB_DELEGATE(inputs))
, m_RBIQ(*this, "RBIQ", NETLIB_DELEGATE(inputs))
, m_state(*this, "m_state", 0)
, m_Q(*this, {"a", "b", "c", "d", "e", "f", "g"})
, m_power_pins(*this)
@ -35,7 +35,10 @@ namespace netlist
{
m_state = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(7448_dip);
private:
@ -53,6 +56,36 @@ namespace netlist
}
}
NETLIB_HANDLERI(inputs)
{
if (!m_BIQ() || (m_BIQ() && !m_LTQ()))
{
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
m_RBIQ.inactivate();
if (m_BIQ() && !m_LTQ())
{
update_outputs(8);
}
else if (!m_BIQ())
{
update_outputs(15);
}
} else {
m_RBIQ.activate();
m_D.activate();
m_C.activate();
m_B.activate();
m_A.activate();
unsigned v = (m_A() << 0) | (m_B() << 1) | (m_C() << 2) | (m_D() << 3);
if ((!m_RBIQ() && (v==0)))
v = 15;
update_outputs(v);
}
}
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
@ -97,7 +130,6 @@ namespace netlist
};
#endif
#if !(NL_USE_TRUTHTABLE_7448)
#define BITS7(b6,b5,b4,b3,b2,b1,b0) ((b6)<<6) | ((b5)<<5) | ((b4)<<4) | ((b3)<<3) | ((b2)<<2) | ((b1)<<1) | ((b0)<<0)
@ -122,36 +154,6 @@ namespace netlist
BITS7( 0, 0, 0, 0, 0, 0, 0 ), /* 15 */
};
NETLIB_UPDATE(7448)
{
if (!m_BIQ() || (m_BIQ() && !m_LTQ()))
{
m_A.inactivate();
m_B.inactivate();
m_C.inactivate();
m_D.inactivate();
m_RBIQ.inactivate();
if (m_BIQ() && !m_LTQ())
{
update_outputs(8);
}
else if (!m_BIQ())
{
update_outputs(15);
}
} else {
m_RBIQ.activate();
m_D.activate();
m_C.activate();
m_B.activate();
m_A.activate();
unsigned v = (m_A() << 0) | (m_B() << 1) | (m_C() << 2) | (m_D() << 3);
if ((!m_RBIQ() && (v==0)))
v = 15;
update_outputs(v);
}
}
NETLIB_DEVICE_IMPL(7448, "TTL_7448", "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7448_dip, "TTL_7448_DIP", "")

View File

@ -18,18 +18,55 @@ namespace netlist
NETLIB_OBJECT(7450)
{
NETLIB_CONSTRUCTOR(7450)
, m_A(*this, "A")
, m_B(*this, "B")
, m_C(*this, "C")
, m_D(*this, "D")
, m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_C(*this, "C", NETLIB_DELEGATE(inputs))
, m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_Q(*this, "Q")
, m_power_pins(*this)
{
}
//NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
public:
NETLIB_HANDLERI(inputs)
{
m_A.activate();
m_B.activate();
m_C.activate();
m_D.activate();
auto t1 = m_A() & m_B();
auto t2 = m_C() & m_D();
uint_fast8_t res = 0;
if (t1 ^ 1)
{
if (t2 ^ 1)
{
res = 1;
}
else
{
m_A.inactivate();
m_B.inactivate();
}
}
else
{
if (t2 ^ 1)
{
m_C.inactivate();
m_D.inactivate();
}
}
m_Q.push(res, times[res]);// ? 22000 : 15000);
}
logic_input_t m_A;
logic_input_t m_B;
logic_input_t m_C;
@ -71,39 +108,6 @@ namespace netlist
NETLIB_SUB(7450) m_B;
};
NETLIB_UPDATE(7450)
{
m_A.activate();
m_B.activate();
m_C.activate();
m_D.activate();
auto t1 = m_A() & m_B();
auto t2 = m_C() & m_D();
uint_fast8_t res = 0;
if (t1 ^ 1)
{
if (t2 ^ 1)
{
res = 1;
}
else
{
m_A.inactivate();
m_B.inactivate();
}
}
else
{
if (t2 ^ 1)
{
m_C.inactivate();
m_D.inactivate();
}
}
m_Q.push(res, times[res]);// ? 22000 : 15000);
}
NETLIB_DEVICE_IMPL(7450, "TTL_7450_ANDORINVERT", "+A,+B,+C,+D,@VCC,@GND")
NETLIB_DEVICE_IMPL(7450_dip, "TTL_7450_DIP", "")

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(7473)
{
NETLIB_CONSTRUCTOR(7473)
, m_CLK(*this, "CLK")
, m_J(*this, "J")
, m_K(*this, "K")
, m_CLRQ(*this, "CLRQ")
, m_CLK(*this, "CLK", NETLIB_DELEGATE(inputs))
, m_J(*this, "J", NETLIB_DELEGATE(inputs))
, m_K(*this, "K", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_last_CLK(*this, "m_last_CLK", 0)
, m_q(*this, "m_q", 0)
, m_Q(*this, "Q")
@ -27,10 +27,49 @@ namespace netlist
{
}
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_RESETI()
{
m_last_CLK = 0;
}
NETLIB_UPDATEI()
{
inputs();
}
public:
NETLIB_HANDLERI(inputs)
{
const auto JK = (m_J() << 1) | m_K();
if (m_CLRQ())
{
if (!m_CLK() && m_last_CLK)
{
switch (JK)
{
case 1: // (!m_J) & m_K))
m_q = 0;
break;
case 2: // (m_J) & !m_K))
m_q = 1;
break;
case 3: // (m_J) & m_K))
m_q ^= 1;
break;
default:
case 0:
break;
}
}
}
m_last_CLK = m_CLK();
m_Q.push(m_q, NLTIME_FROM_NS(20)); // FIXME: timing
m_QQ.push(m_q ^ 1, NLTIME_FROM_NS(20)); // FIXME: timing
}
logic_input_t m_CLK;
logic_input_t m_J;
logic_input_t m_K;
@ -113,43 +152,6 @@ namespace netlist
NETLIB_SUB(7473A) m_B;
};
NETLIB_RESET(7473)
{
m_last_CLK = 0;
}
NETLIB_UPDATE(7473)
{
const auto JK = (m_J() << 1) | m_K();
if (m_CLRQ())
{
if (!m_CLK() && m_last_CLK)
{
switch (JK)
{
case 1: // (!m_J) & m_K))
m_q = 0;
break;
case 2: // (m_J) & !m_K))
m_q = 1;
break;
case 3: // (m_J) & m_K))
m_q ^= 1;
break;
default:
case 0:
break;
}
}
}
m_last_CLK = m_CLK();
m_Q.push(m_q, NLTIME_FROM_NS(20)); // FIXME: timing
m_QQ.push(m_q ^ 1, NLTIME_FROM_NS(20)); // FIXME: timing
}
NETLIB_DEVICE_IMPL(7473, "TTL_7473", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7473A, "TTL_7473A", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7473_dip, "TTL_7473_DIP", "")

View File

@ -19,9 +19,9 @@ namespace netlist
NETLIB_OBJECT(7474)
{
NETLIB_CONSTRUCTOR(7474)
, m_D(*this, "D")
, m_CLRQ(*this, "CLRQ")
, m_PREQ(*this, "PREQ")
, m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_PREQ(*this, "PREQ", NETLIB_DELEGATE(inputs))
, m_CLK(*this, "CLK", NETLIB_DELEGATE(clk))
, m_Q(*this, "Q")
, m_QQ(*this, "QQ")
@ -31,9 +31,41 @@ namespace netlist
}
private:
NETLIB_RESETI();
NETLIB_UPDATEI();
NETLIB_HANDLERI(clk);
NETLIB_RESETI()
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_D.set_state(logic_t::STATE_INP_ACTIVE);
m_nextD = 0;
}
NETLIB_UPDATEI()
{
inputs();
}
NETLIB_HANDLERI(clk)
{
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
NETLIB_HANDLERI(inputs)
{
const auto preq(m_PREQ());
const auto clrq(m_CLRQ());
if (preq & clrq)
{
m_D.activate();
m_nextD = m_D();
m_CLK.activate_lh();
}
else
{
newstate(preq ^ 1, clrq ^ 1);
m_CLK.inactivate();
m_D.inactivate();
}
}
logic_input_t m_D;
logic_input_t m_CLRQ;
@ -88,37 +120,6 @@ namespace netlist
NETLIB_SUB(7474) m_B;
};
NETLIB_HANDLER(7474, clk)
{
newstate(m_nextD, !m_nextD);
m_CLK.inactivate();
}
NETLIB_UPDATE(7474)
{
const auto preq(m_PREQ());
const auto clrq(m_CLRQ());
if (preq & clrq)
{
m_D.activate();
m_nextD = m_D();
m_CLK.activate_lh();
}
else
{
newstate(preq ^ 1, clrq ^ 1);
m_CLK.inactivate();
m_D.inactivate();
}
}
NETLIB_RESET(7474)
{
m_CLK.set_state(logic_t::STATE_INP_LH);
m_D.set_state(logic_t::STATE_INP_ACTIVE);
m_nextD = 0;
}
NETLIB_RESET(7474_dip)
{
}

View File

@ -15,7 +15,7 @@ namespace netlist
NETLIB_OBJECT(7483)
{
NETLIB_CONSTRUCTOR(7483)
, m_C0(*this, "C0")
, m_C0(*this, "C0", NETLIB_DELEGATE(c0))
, m_A1(*this, "A1", NETLIB_DELEGATE(upd_a))
, m_A2(*this, "A2", NETLIB_DELEGATE(upd_a))
, m_A3(*this, "A3", NETLIB_DELEGATE(upd_a))
@ -39,12 +39,42 @@ namespace netlist
{
m_lastr = 0;
}
NETLIB_UPDATEI();
NETLIB_HANDLERI(upd_a);
NETLIB_HANDLERI(upd_b);
NETLIB_UPDATEI()
{
c0();
}
friend class NETLIB_NAME(7483_dip);
private:
NETLIB_HANDLERI(c0)
{
auto r = static_cast<uint8_t>(m_a + m_b + m_C0());
if (r != m_lastr)
{
m_lastr = r;
m_S1.push((r >> 0) & 1, NLTIME_FROM_NS(23));
m_S2.push((r >> 1) & 1, NLTIME_FROM_NS(23));
m_S3.push((r >> 2) & 1, NLTIME_FROM_NS(23));
m_S4.push((r >> 3) & 1, NLTIME_FROM_NS(23));
m_C4.push((r >> 4) & 1, NLTIME_FROM_NS(23));
}
}
NETLIB_HANDLERI(upd_a)
{
m_a = static_cast<uint8_t>((m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3));
NETLIB_NAME(7483)::update();
}
NETLIB_HANDLERI(upd_b)
{
m_b = static_cast<uint8_t>((m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3));
NETLIB_NAME(7483)::update();
}
logic_input_t m_C0;
logic_input_t m_A1;
logic_input_t m_A2;
@ -96,33 +126,6 @@ namespace netlist
NETLIB_SUB(7483) A;
};
NETLIB_HANDLER(7483, upd_a)
{
m_a = static_cast<uint8_t>((m_A1() << 0) | (m_A2() << 1) | (m_A3() << 2) | (m_A4() << 3));
NETLIB_NAME(7483)::update();
}
NETLIB_HANDLER(7483, upd_b)
{
m_b = static_cast<uint8_t>((m_B1() << 0) | (m_B2() << 1) | (m_B3() << 2) | (m_B4() << 3));
NETLIB_NAME(7483)::update();
}
NETLIB_UPDATE(7483)
{
auto r = static_cast<uint8_t>(m_a + m_b + m_C0());
if (r != m_lastr)
{
m_lastr = r;
m_S1.push((r >> 0) & 1, NLTIME_FROM_NS(23));
m_S2.push((r >> 1) & 1, NLTIME_FROM_NS(23));
m_S3.push((r >> 2) & 1, NLTIME_FROM_NS(23));
m_S4.push((r >> 3) & 1, NLTIME_FROM_NS(23));
m_C4.push((r >> 4) & 1, NLTIME_FROM_NS(23));
}
}
NETLIB_DEVICE_IMPL(7483, "TTL_7483", "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0,@VCC,@GND")
NETLIB_DEVICE_IMPL(7483_dip, "TTL_7483_DIP", "")

View File

@ -15,11 +15,11 @@ namespace netlist
NETLIB_OBJECT(7485)
{
NETLIB_CONSTRUCTOR(7485)
, m_A(*this, {"A0", "A1", "A2", "A3"})
, m_B(*this, {"B0", "B1", "B2", "B3"})
, m_LTIN(*this, "LTIN")
, m_EQIN(*this, "EQIN")
, m_GTIN(*this, "GTIN")
, m_A(*this, {"A0", "A1", "A2", "A3"}, NETLIB_DELEGATE(inputs))
, m_B(*this, {"B0", "B1", "B2", "B3"}, NETLIB_DELEGATE(inputs))
, m_LTIN(*this, "LTIN", NETLIB_DELEGATE(inputs))
, m_EQIN(*this, "EQIN", NETLIB_DELEGATE(inputs))
, m_GTIN(*this, "GTIN", NETLIB_DELEGATE(inputs))
, m_LTOUT(*this, "LTOUT")
, m_EQOUT(*this, "EQOUT")
, m_GTOUT(*this, "GTOUT")
@ -27,12 +27,46 @@ namespace netlist
{
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
void update_outputs(unsigned gt, unsigned lt, unsigned eq);
friend class NETLIB_NAME(7485_dip);
private:
// FIXME: Timing
NETLIB_HANDLERI(inputs)
{
for (std::size_t i = 4; i-- > 0; )
{
if (m_A[i]() > m_B[i]())
{
update_outputs(1, 0, 0);
return;
}
if (m_A[i]() < m_B[i]())
{
update_outputs(0, 1, 0);
return;
}
}
// must be == if we got here
if (m_EQIN())
update_outputs(0, 0, 1);
else if (m_GTIN() && m_LTIN())
update_outputs(0, 0, 0);
else if (m_GTIN())
update_outputs(1, 0, 0);
else if (m_LTIN())
update_outputs(0, 1, 0);
else
update_outputs(1, 1, 0);
}
object_array_t<logic_input_t, 4> m_A;
object_array_t<logic_input_t, 4> m_B;
logic_input_t m_LTIN;
@ -81,37 +115,6 @@ namespace netlist
m_EQOUT.push(eq, NLTIME_FROM_NS(23));
}
// FIXME: Timing
NETLIB_UPDATE(7485)
{
for (std::size_t i = 4; i-- > 0; )
{
if (m_A[i]() > m_B[i]())
{
update_outputs(1, 0, 0);
return;
}
if (m_A[i]() < m_B[i]())
{
update_outputs(0, 1, 0);
return;
}
}
// must be == if we got here
if (m_EQIN())
update_outputs(0, 0, 1);
else if (m_GTIN() && m_LTIN())
update_outputs(0, 0, 0);
else if (m_GTIN())
update_outputs(1, 0, 0);
else if (m_LTIN())
update_outputs(0, 1, 0);
else
update_outputs(1, 1, 0);
}
NETLIB_DEVICE_IMPL(7485, "TTL_7485", "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN,@VCC,@GND")
NETLIB_DEVICE_IMPL(7485_dip, "TTL_7485_DIP", "")

View File

@ -24,12 +24,12 @@ namespace devices
NETLIB_OBJECT(7490)
{
NETLIB_CONSTRUCTOR(7490)
, m_A(*this, "A")
, m_B(*this, "B")
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R91(*this, "R91")
, m_R92(*this, "R92")
, m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_R1(*this, "R1", NETLIB_DELEGATE(inputs))
, m_R2(*this, "R2", NETLIB_DELEGATE(inputs))
, m_R91(*this, "R91", NETLIB_DELEGATE(inputs))
, m_R92(*this, "R92", NETLIB_DELEGATE(inputs))
, m_cnt(*this, "m_cnt", 0)
, m_last_A(*this, "m_last_A", 0)
, m_last_B(*this, "m_last_B", 0)
@ -40,6 +40,11 @@ namespace devices
private:
NETLIB_UPDATEI()
{
inputs();
}
NETLIB_HANDLERI(inputs)
{
const netlist_sig_t new_A = m_A();
const netlist_sig_t new_B = m_B();

View File

@ -24,10 +24,10 @@ namespace devices
NETLIB_OBJECT(7492)
{
NETLIB_CONSTRUCTOR(7492)
, m_A(*this, "A")
, m_B(*this, "B")
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_R1(*this, "R1", NETLIB_DELEGATE(inputs))
, m_R2(*this, "R2", NETLIB_DELEGATE(inputs))
, m_cnt(*this, "m_cnt", 0)
, m_last_A(*this, "m_last_A", 0)
, m_last_B(*this, "m_last_B", 0)
@ -38,6 +38,11 @@ namespace devices
private:
NETLIB_UPDATEI()
{
inputs();
}
NETLIB_HANDLERI(inputs)
{
const netlist_sig_t new_A = m_A();
const netlist_sig_t new_B = m_B();

View File

@ -81,8 +81,8 @@ namespace netlist
NETLIB_OBJECT(7493)
{
NETLIB_CONSTRUCTOR(7493)
, m_R1(*this, "R1")
, m_R2(*this, "R2")
, m_R1(*this, "R1", NETLIB_DELEGATE(inputs))
, m_R2(*this, "R2", NETLIB_DELEGATE(inputs))
, m_a(*this, "_m_a", 0)
, m_bcd(*this, "_m_b", 0)
, m_r(*this, "_m_r", 0)
@ -103,6 +103,11 @@ namespace netlist
}
NETLIB_UPDATEI()
{
inputs();
}
NETLIB_HANDLERI(inputs)
{
if (!(m_R1() && m_R2()))
{

View File

@ -26,7 +26,7 @@ namespace netlist
, m_B(*this, {"B5", "B4", "B3", "B2", "B1", "B0"})
, m_CLK(*this, "CLK", NETLIB_DELEGATE(clk_strb))
, m_STRBQ(*this, "STRBQ", NETLIB_DELEGATE(clk_strb))
, m_ENQ(*this, "ENQ")
, m_ENQ(*this, "ENQ", NETLIB_DELEGATE(enq))
, m_UNITYQ(*this, "UNITYQ", NETLIB_DELEGATE(unity))
, m_CLR(*this, "CLR", NETLIB_DELEGATE(clr))
, m_Y(*this, "Y")
@ -48,12 +48,64 @@ namespace netlist
m_lastclock = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
enq();
}
NETLIB_HANDLERI(noop) { }
NETLIB_HANDLERI(unity);
NETLIB_HANDLERI(clr);
NETLIB_HANDLERI(clk_strb);
NETLIB_HANDLERI(unity)
{
newstate (m_state);
}
NETLIB_HANDLERI(clr)
{
m_cnt = 0;
clk_strb();
}
NETLIB_HANDLERI(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_HANDLERI(enq)
{
m_rate = rate();
clk_strb();
}
friend class NETLIB_NAME(7497_dip);
@ -94,57 +146,8 @@ namespace netlist
}
};
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(7497_dip)
{

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(82S115)
{
NETLIB_CONSTRUCTOR(82S115)
, m_A(*this, {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"})
, m_CE1Q(*this, "CE1Q")
, m_CE2(*this, "CE2")
, m_STROBE(*this, "STROBE")
, m_A(*this, {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"}, NETLIB_DELEGATE(inputs))
, m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(inputs))
, m_CE2(*this, "CE2", NETLIB_DELEGATE(inputs))
, m_STROBE(*this, "STROBE", NETLIB_DELEGATE(inputs))
, m_O(*this, {"O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8"})
, m_last_O(*this, "m_last_O", 0)
, m_ROM(*this, "ROM")
@ -30,10 +30,41 @@ namespace netlist
{
m_last_O = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(82S115_dip);
private:
// FIXME: timing!
NETLIB_HANDLERI(inputs)
{
unsigned o = 0;
if (!m_CE1Q() && m_CE2())
{
if (m_STROBE())
{
unsigned a = 0;
for (std::size_t i=0; i<9; i++)
a |= (m_A[i]() << i);
o = m_ROM[a];
}
else
{
o = m_last_O;
}
}
m_last_O = o;
// FIXME: Outputs are tristate. This needs to be properly implemented
for (std::size_t i=0; i<8; i++)
m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(40)); // FIXME: Timing
}
object_array_t<logic_input_t, 9> m_A;
logic_input_t m_CE1Q;
logic_input_t m_CE2;
@ -88,34 +119,6 @@ namespace netlist
NETLIB_SUB(82S115) A;
};
// FIXME: timing!
NETLIB_UPDATE(82S115)
{
unsigned o = 0;
if (!m_CE1Q() && m_CE2())
{
if (m_STROBE())
{
unsigned a = 0;
for (std::size_t i=0; i<9; i++)
a |= (m_A[i]() << i);
o = m_ROM[a];
}
else
{
o = m_last_O;
}
}
m_last_O = o;
// FIXME: Outputs are tristate. This needs to be properly implemented
for (std::size_t i=0; i<8; i++)
m_O[i].push((o >> i) & 1, NLTIME_FROM_NS(40)); // FIXME: Timing
}
NETLIB_DEVICE_IMPL(82S115, "PROM_82S115", "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE,@VCC,@GND")
NETLIB_DEVICE_IMPL(82S115_dip, "PROM_82S115_DIP", "")

View File

@ -19,8 +19,8 @@ namespace netlist
, m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(enq))
, m_CE2Q(*this, "CE2Q", NETLIB_DELEGATE(enq))
, m_CE3Q(*this, "CE3Q", NETLIB_DELEGATE(enq))
, m_WEQ(*this, "WEQ")
, m_DIN(*this, "DIN")
, m_WEQ(*this, "WEQ", NETLIB_DELEGATE(inputs))
, m_DIN(*this, "DIN", NETLIB_DELEGATE(inputs))
, m_DOUTQ(*this, "DOUTQ")
, m_ram(*this, "m_ram", 0)
, m_addr(*this, "m_addr", 0)
@ -38,7 +38,30 @@ namespace netlist
m_addr = 0;
m_enq = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(82S16_dip);
private:
// FIXME: timing!
// FIXME: optimize device (separate address decoder!)
NETLIB_HANDLERI(inputs)
{
if (!m_enq)
{
const decltype(m_addr)::value_type adr(m_addr);
if (!m_WEQ())
{
m_ram[adr >> 6] = (m_ram[adr >> 6]
& ~(static_cast<uint64_t>(1) << (adr & 0x3f)))
| (static_cast<uint64_t>(m_DIN()) << (adr & 0x3f));
}
m_DOUTQ.push(((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
}
}
NETLIB_HANDLERI(addr)
{
uint8_t adr = 0;
@ -73,8 +96,6 @@ namespace netlist
}
}
friend class NETLIB_NAME(82S16_dip);
private:
object_array_t<logic_input_t, 8> m_A;
logic_input_t m_CE1Q;
logic_input_t m_CE2Q;
@ -121,23 +142,6 @@ namespace netlist
NETLIB_SUB(82S16) A;
};
// FIXME: timing!
// FIXME: optimize device (separate address decoder!)
NETLIB_UPDATE(82S16)
{
if (!m_enq)
{
const decltype(m_addr)::value_type adr(m_addr);
if (!m_WEQ())
{
m_ram[adr >> 6] = (m_ram[adr >> 6]
& ~(static_cast<uint64_t>(1) << (adr & 0x3f)))
| (static_cast<uint64_t>(m_DIN()) << (adr & 0x3f));
}
m_DOUTQ.push(((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
}
}
NETLIB_DEVICE_IMPL(82S16, "TTL_82S16", "")
NETLIB_DEVICE_IMPL(82S16_dip, "TTL_82S16_DIP", "")

View File

@ -18,14 +18,20 @@ namespace netlist
{
NETLIB_CONSTRUCTOR(9322_selector)
, m_parent(owner)
, m_A(*this, "A")
, m_B(*this, "B")
, m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_Y(*this, "Y")
, m_power_pins(*this)
{
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
// FIXME: Timing
NETLIB_HANDLERI(inputs);
public:
NETLIB_NAME(9322) &m_parent;
@ -38,8 +44,8 @@ namespace netlist
NETLIB_OBJECT(9322)
{
NETLIB_CONSTRUCTOR(9322)
, m_SELECT(*this, "SELECT")
, m_STROBE(*this, "STROBE")
, m_SELECT(*this, "SELECT", NETLIB_DELEGATE(inputs))
, m_STROBE(*this, "STROBE", NETLIB_DELEGATE(inputs))
, m_1(*this, "A")
, m_2(*this, "B")
, m_3(*this, "C")
@ -70,13 +76,24 @@ namespace netlist
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(9322_dip);
public:
logic_input_t m_SELECT;
logic_input_t m_STROBE;
private:
NETLIB_HANDLERI(inputs)
{
m_1.inputs();
m_2.inputs();
m_3.inputs();
m_4.inputs();
}
NETLIB_SUB(9322_selector) m_1;
NETLIB_SUB(9322_selector) m_2;
NETLIB_SUB(9322_selector) m_3;
@ -84,6 +101,16 @@ namespace netlist
};
NETLIB_HANDLER(9322_selector, inputs)
{
if (m_parent.m_STROBE())
m_Y.push(0, NLTIME_FROM_NS(21));
else if (m_parent.m_SELECT())
m_Y.push(m_B(), NLTIME_FROM_NS(14));
else
m_Y.push(m_A(), NLTIME_FROM_NS(14));
}
NETLIB_OBJECT(9322_dip)
{
NETLIB_CONSTRUCTOR(9322_dip)
@ -114,25 +141,6 @@ namespace netlist
NETLIB_SUB(9322) A;
};
// FIXME: Timing
NETLIB_UPDATE(9322_selector)
{
if (m_parent.m_STROBE())
m_Y.push(0, NLTIME_FROM_NS(21));
else if (m_parent.m_SELECT())
m_Y.push(m_B(), NLTIME_FROM_NS(14));
else
m_Y.push(m_A(), NLTIME_FROM_NS(14));
}
NETLIB_UPDATE(9322)
{
m_1.update();
m_2.update();
m_3.update();
m_4.update();
}
NETLIB_DEVICE_IMPL(9322, "TTL_9322", "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE,@VCC,@GND")
NETLIB_DEVICE_IMPL(9322_dip, "TTL_9322_DIP", "")

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(9314)
{
NETLIB_CONSTRUCTOR(9314)
, m_EQ(*this, "EQ")
, m_MRQ(*this, "MRQ")
, m_SQ(*this, {"S0Q", "S1Q", "S2Q", "S3Q"})
, m_D(*this, {"D0", "D1", "D2", "D3"})
, m_EQ(*this, "EQ", NETLIB_DELEGATE(inputs))
, m_MRQ(*this, "MRQ", NETLIB_DELEGATE(inputs))
, m_SQ(*this, {"S0Q", "S1Q", "S2Q", "S3Q"}, NETLIB_DELEGATE(inputs))
, m_D(*this, {"D0", "D1", "D2", "D3"}, NETLIB_DELEGATE(inputs))
, m_Q(*this, {"Q0", "Q1", "Q2", "Q3"})
, m_last_EQ(*this, "m_last_EQ", 0)
, m_last_MRQ(*this, "m_last_MRQ", 0)
@ -38,10 +38,43 @@ namespace netlist
m_last_Q = 0;
}
NETLIB_UPDATEI();
NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(9314_dip);
private:
NETLIB_HANDLERI(inputs)
{
netlist_time delay = NLTIME_FROM_NS(24); //FIXME!
if (!m_MRQ())
{
/* Reset! */
for (std::size_t i=0; i<4; i++)
m_Q[i].push(0, delay);
} else {
for (std::size_t i=0; i<4; i++)
{
if (m_SQ[i]())
{
/* R-S Mode */
// FIXME: R-S mode is not yet implemented!
}
else
{
/* D Mode */
if (!m_EQ())
{
m_Q[i].push(m_D[i](), delay);
m_last_Q &= ~(1 << i);
m_last_Q |= (m_D[i]() << i);
}
}
}
}
}
logic_input_t m_EQ;
logic_input_t m_MRQ;
object_array_t<logic_input_t, 4> m_SQ;
@ -83,36 +116,6 @@ namespace netlist
NETLIB_SUB(9314) A;
};
NETLIB_UPDATE(9314)
{
netlist_time delay = NLTIME_FROM_NS(24); //FIXME!
if (!m_MRQ())
{
/* Reset! */
for (std::size_t i=0; i<4; i++)
m_Q[i].push(0, delay);
} else {
for (std::size_t i=0; i<4; i++)
{
if (m_SQ[i]())
{
/* R-S Mode */
// FIXME: R-S mode is not yet implemented!
}
else
{
/* D Mode */
if (!m_EQ())
{
m_Q[i].push(m_D[i](), delay);
m_last_Q &= ~(1 << i);
m_last_Q |= (m_D[i]() << i);
}
}
}
}
}
NETLIB_DEVICE_IMPL(9314, "TTL_9314", "+EQ,+MRQ,+S0Q,+S1Q,+S2Q,+S3Q,+D0,+D1,+D2,+D3,@VCC,@GND")
NETLIB_DEVICE_IMPL(9314_dip, "TTL_9314_DIP", "")