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 namespace devices
{ {
// FIXME: Optimize
NETLIB_OBJECT(74194) NETLIB_OBJECT(74194)
{ {
NETLIB_CONSTRUCTOR(74194) NETLIB_CONSTRUCTOR(74194)
, m_DATA(*this, {"D", "C", "B", "A"}) , m_DATA(*this, {"D", "C", "B", "A"}, NETLIB_DELEGATE(inputs))
, m_SLIN(*this, "SLIN") , m_SLIN(*this, "SLIN", NETLIB_DELEGATE(inputs))
, m_SRIN(*this, "SRIN") , m_SRIN(*this, "SRIN", NETLIB_DELEGATE(inputs))
, m_CLK(*this, "CLK") , m_CLK(*this, "CLK", NETLIB_DELEGATE(inputs))
, m_S0(*this, "S0") , m_S0(*this, "S0", NETLIB_DELEGATE(inputs))
, m_S1(*this, "S1") , m_S1(*this, "S1", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ") , m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_Q(*this, {"QD", "QC", "QB", "QA"}) , m_Q(*this, {"QD", "QC", "QB", "QA"})
, m_last_CLK(*this, "m_last_CLK", 0) , m_last_CLK(*this, "m_last_CLK", 0)
, m_last_Q(*this, "m_last_Q", 0) , m_last_Q(*this, "m_last_Q", 0)
@ -34,10 +36,55 @@ namespace netlist
m_last_CLK = 0; m_last_CLK = 0;
m_last_Q = 0; m_last_Q = 0;
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(74194_dip); friend class NETLIB_NAME(74194_dip);
private: 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; object_array_t<logic_input_t, 4> m_DATA;
logic_input_t m_SLIN; logic_input_t m_SLIN;
logic_input_t m_SRIN; logic_input_t m_SRIN;
@ -82,49 +129,6 @@ namespace netlist
NETLIB_SUB(74194) A; 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, "TTL_74194", "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(74194_dip, "TTL_74194_DIP", "") NETLIB_DEVICE_IMPL(74194_dip, "TTL_74194_DIP", "")

View File

@ -23,18 +23,35 @@ namespace netlist
NETLIB_OBJECT(74365) NETLIB_OBJECT(74365)
{ {
NETLIB_CONSTRUCTOR(74365) NETLIB_CONSTRUCTOR(74365)
, m_G1Q(*this, "G1Q") , m_G1Q(*this, "G1Q", NETLIB_DELEGATE(inputs))
, m_G2Q(*this, "G2Q") , m_G2Q(*this, "G2Q", NETLIB_DELEGATE(inputs))
, m_A(*this, { "A1", "A2", "A3", "A4", "A5", "A6" }) , m_A(*this, { "A1", "A2", "A3", "A4", "A5", "A6" }, NETLIB_DELEGATE(inputs))
, m_Y(*this, { "Y1", "Y2", "Y3", "Y4", "Y5", "Y6" }) , m_Y(*this, { "Y1", "Y2", "Y3", "Y4", "Y5", "Y6" })
, m_power_pins(*this) , m_power_pins(*this)
{ {
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(74365_dip); friend class NETLIB_NAME(74365_dip);
private: 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_G1Q;
logic_input_t m_G2Q; logic_input_t m_G2Q;
object_array_t<logic_input_t, 6> m_A; object_array_t<logic_input_t, 6> m_A;
@ -71,20 +88,6 @@ namespace netlist
NETLIB_SUB(74365) A; 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, "TTL_74365", "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6,@VCC,@GND")
NETLIB_DEVICE_IMPL(74365_dip, "TTL_74365_DIP", "") NETLIB_DEVICE_IMPL(74365_dip, "TTL_74365_DIP", "")

View File

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

View File

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

View File

@ -18,13 +18,13 @@ namespace netlist
NETLIB_OBJECT(7448) NETLIB_OBJECT(7448)
{ {
NETLIB_CONSTRUCTOR(7448) NETLIB_CONSTRUCTOR(7448)
, m_A(*this, "A") , m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B") , m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_C(*this, "C") , m_C(*this, "C", NETLIB_DELEGATE(inputs))
, m_D(*this, "D") , m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_LTQ(*this, "LTQ") , m_LTQ(*this, "LTQ", NETLIB_DELEGATE(inputs))
, m_BIQ(*this, "BIQ") , m_BIQ(*this, "BIQ", NETLIB_DELEGATE(inputs))
, m_RBIQ(*this, "RBIQ") , m_RBIQ(*this, "RBIQ", NETLIB_DELEGATE(inputs))
, m_state(*this, "m_state", 0) , m_state(*this, "m_state", 0)
, m_Q(*this, {"a", "b", "c", "d", "e", "f", "g"}) , m_Q(*this, {"a", "b", "c", "d", "e", "f", "g"})
, m_power_pins(*this) , m_power_pins(*this)
@ -35,7 +35,10 @@ namespace netlist
{ {
m_state = 0; m_state = 0;
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(7448_dip); friend class NETLIB_NAME(7448_dip);
private: 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_A;
logic_input_t m_B; logic_input_t m_B;
logic_input_t m_C; logic_input_t m_C;
@ -97,7 +130,6 @@ namespace netlist
}; };
#endif #endif
#if !(NL_USE_TRUTHTABLE_7448) #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) #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 */ 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, "TTL_7448", "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7448_dip, "TTL_7448_DIP", "") NETLIB_DEVICE_IMPL(7448_dip, "TTL_7448_DIP", "")

View File

@ -18,18 +18,55 @@ namespace netlist
NETLIB_OBJECT(7450) NETLIB_OBJECT(7450)
{ {
NETLIB_CONSTRUCTOR(7450) NETLIB_CONSTRUCTOR(7450)
, m_A(*this, "A") , m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B") , m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_C(*this, "C") , m_C(*this, "C", NETLIB_DELEGATE(inputs))
, m_D(*this, "D") , m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_Q(*this, "Q") , m_Q(*this, "Q")
, m_power_pins(*this) , m_power_pins(*this)
{ {
} }
//NETLIB_RESETI(); //NETLIB_RESETI();
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
public: 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_A;
logic_input_t m_B; logic_input_t m_B;
logic_input_t m_C; logic_input_t m_C;
@ -71,39 +108,6 @@ namespace netlist
NETLIB_SUB(7450) m_B; 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, "TTL_7450_ANDORINVERT", "+A,+B,+C,+D,@VCC,@GND")
NETLIB_DEVICE_IMPL(7450_dip, "TTL_7450_DIP", "") NETLIB_DEVICE_IMPL(7450_dip, "TTL_7450_DIP", "")

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(7473) NETLIB_OBJECT(7473)
{ {
NETLIB_CONSTRUCTOR(7473) NETLIB_CONSTRUCTOR(7473)
, m_CLK(*this, "CLK") , m_CLK(*this, "CLK", NETLIB_DELEGATE(inputs))
, m_J(*this, "J") , m_J(*this, "J", NETLIB_DELEGATE(inputs))
, m_K(*this, "K") , m_K(*this, "K", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ") , m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_last_CLK(*this, "m_last_CLK", 0) , m_last_CLK(*this, "m_last_CLK", 0)
, m_q(*this, "m_q", 0) , m_q(*this, "m_q", 0)
, m_Q(*this, "Q") , m_Q(*this, "Q")
@ -27,10 +27,49 @@ namespace netlist
{ {
} }
NETLIB_RESETI(); NETLIB_RESETI()
NETLIB_UPDATEI(); {
m_last_CLK = 0;
}
NETLIB_UPDATEI()
{
inputs();
}
public: 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_CLK;
logic_input_t m_J; logic_input_t m_J;
logic_input_t m_K; logic_input_t m_K;
@ -113,43 +152,6 @@ namespace netlist
NETLIB_SUB(7473A) m_B; 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(7473, "TTL_7473", "+CLK,+J,+K,+CLRQ,@VCC,@GND")
NETLIB_DEVICE_IMPL(7473A, "TTL_7473A", "+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", "") NETLIB_DEVICE_IMPL(7473_dip, "TTL_7473_DIP", "")

View File

@ -19,9 +19,9 @@ namespace netlist
NETLIB_OBJECT(7474) NETLIB_OBJECT(7474)
{ {
NETLIB_CONSTRUCTOR(7474) NETLIB_CONSTRUCTOR(7474)
, m_D(*this, "D") , m_D(*this, "D", NETLIB_DELEGATE(inputs))
, m_CLRQ(*this, "CLRQ") , m_CLRQ(*this, "CLRQ", NETLIB_DELEGATE(inputs))
, m_PREQ(*this, "PREQ") , m_PREQ(*this, "PREQ", NETLIB_DELEGATE(inputs))
, m_CLK(*this, "CLK", NETLIB_DELEGATE(clk)) , m_CLK(*this, "CLK", NETLIB_DELEGATE(clk))
, m_Q(*this, "Q") , m_Q(*this, "Q")
, m_QQ(*this, "QQ") , m_QQ(*this, "QQ")
@ -31,9 +31,41 @@ namespace netlist
} }
private: private:
NETLIB_RESETI(); NETLIB_RESETI()
NETLIB_UPDATEI(); {
NETLIB_HANDLERI(clk); 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_D;
logic_input_t m_CLRQ; logic_input_t m_CLRQ;
@ -88,37 +120,6 @@ namespace netlist
NETLIB_SUB(7474) m_B; 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) NETLIB_RESET(7474_dip)
{ {
} }

View File

@ -15,7 +15,7 @@ namespace netlist
NETLIB_OBJECT(7483) NETLIB_OBJECT(7483)
{ {
NETLIB_CONSTRUCTOR(7483) NETLIB_CONSTRUCTOR(7483)
, m_C0(*this, "C0") , m_C0(*this, "C0", NETLIB_DELEGATE(c0))
, m_A1(*this, "A1", NETLIB_DELEGATE(upd_a)) , m_A1(*this, "A1", NETLIB_DELEGATE(upd_a))
, m_A2(*this, "A2", NETLIB_DELEGATE(upd_a)) , m_A2(*this, "A2", NETLIB_DELEGATE(upd_a))
, m_A3(*this, "A3", NETLIB_DELEGATE(upd_a)) , m_A3(*this, "A3", NETLIB_DELEGATE(upd_a))
@ -39,12 +39,42 @@ namespace netlist
{ {
m_lastr = 0; m_lastr = 0;
} }
NETLIB_UPDATEI();
NETLIB_HANDLERI(upd_a); NETLIB_UPDATEI()
NETLIB_HANDLERI(upd_b); {
c0();
}
friend class NETLIB_NAME(7483_dip); friend class NETLIB_NAME(7483_dip);
private: 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_C0;
logic_input_t m_A1; logic_input_t m_A1;
logic_input_t m_A2; logic_input_t m_A2;
@ -96,33 +126,6 @@ namespace netlist
NETLIB_SUB(7483) A; 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, "TTL_7483", "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0,@VCC,@GND")
NETLIB_DEVICE_IMPL(7483_dip, "TTL_7483_DIP", "") NETLIB_DEVICE_IMPL(7483_dip, "TTL_7483_DIP", "")

View File

@ -15,11 +15,11 @@ namespace netlist
NETLIB_OBJECT(7485) NETLIB_OBJECT(7485)
{ {
NETLIB_CONSTRUCTOR(7485) NETLIB_CONSTRUCTOR(7485)
, m_A(*this, {"A0", "A1", "A2", "A3"}) , m_A(*this, {"A0", "A1", "A2", "A3"}, NETLIB_DELEGATE(inputs))
, m_B(*this, {"B0", "B1", "B2", "B3"}) , m_B(*this, {"B0", "B1", "B2", "B3"}, NETLIB_DELEGATE(inputs))
, m_LTIN(*this, "LTIN") , m_LTIN(*this, "LTIN", NETLIB_DELEGATE(inputs))
, m_EQIN(*this, "EQIN") , m_EQIN(*this, "EQIN", NETLIB_DELEGATE(inputs))
, m_GTIN(*this, "GTIN") , m_GTIN(*this, "GTIN", NETLIB_DELEGATE(inputs))
, m_LTOUT(*this, "LTOUT") , m_LTOUT(*this, "LTOUT")
, m_EQOUT(*this, "EQOUT") , m_EQOUT(*this, "EQOUT")
, m_GTOUT(*this, "GTOUT") , m_GTOUT(*this, "GTOUT")
@ -27,12 +27,46 @@ namespace netlist
{ {
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
void update_outputs(unsigned gt, unsigned lt, unsigned eq); void update_outputs(unsigned gt, unsigned lt, unsigned eq);
friend class NETLIB_NAME(7485_dip); friend class NETLIB_NAME(7485_dip);
private: 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_A;
object_array_t<logic_input_t, 4> m_B; object_array_t<logic_input_t, 4> m_B;
logic_input_t m_LTIN; logic_input_t m_LTIN;
@ -81,37 +115,6 @@ namespace netlist
m_EQOUT.push(eq, NLTIME_FROM_NS(23)); 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, "TTL_7485", "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN,@VCC,@GND")
NETLIB_DEVICE_IMPL(7485_dip, "TTL_7485_DIP", "") NETLIB_DEVICE_IMPL(7485_dip, "TTL_7485_DIP", "")

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@ namespace netlist
, m_B(*this, {"B5", "B4", "B3", "B2", "B1", "B0"}) , m_B(*this, {"B5", "B4", "B3", "B2", "B1", "B0"})
, m_CLK(*this, "CLK", NETLIB_DELEGATE(clk_strb)) , m_CLK(*this, "CLK", NETLIB_DELEGATE(clk_strb))
, m_STRBQ(*this, "STRBQ", 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_UNITYQ(*this, "UNITYQ", NETLIB_DELEGATE(unity))
, m_CLR(*this, "CLR", NETLIB_DELEGATE(clr)) , m_CLR(*this, "CLR", NETLIB_DELEGATE(clr))
, m_Y(*this, "Y") , m_Y(*this, "Y")
@ -48,12 +48,64 @@ namespace netlist
m_lastclock = 0; m_lastclock = 0;
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
enq();
}
NETLIB_HANDLERI(noop) { } NETLIB_HANDLERI(noop) { }
NETLIB_HANDLERI(unity);
NETLIB_HANDLERI(clr); NETLIB_HANDLERI(unity)
NETLIB_HANDLERI(clk_strb); {
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); 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) NETLIB_OBJECT(7497_dip)
{ {

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(82S115) NETLIB_OBJECT(82S115)
{ {
NETLIB_CONSTRUCTOR(82S115) NETLIB_CONSTRUCTOR(82S115)
, m_A(*this, {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"}) , m_A(*this, {"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8"}, NETLIB_DELEGATE(inputs))
, m_CE1Q(*this, "CE1Q") , m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(inputs))
, m_CE2(*this, "CE2") , m_CE2(*this, "CE2", NETLIB_DELEGATE(inputs))
, m_STROBE(*this, "STROBE") , m_STROBE(*this, "STROBE", NETLIB_DELEGATE(inputs))
, m_O(*this, {"O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8"}) , m_O(*this, {"O1", "O2", "O3", "O4", "O5", "O6", "O7", "O8"})
, m_last_O(*this, "m_last_O", 0) , m_last_O(*this, "m_last_O", 0)
, m_ROM(*this, "ROM") , m_ROM(*this, "ROM")
@ -30,10 +30,41 @@ namespace netlist
{ {
m_last_O = 0; m_last_O = 0;
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(82S115_dip); friend class NETLIB_NAME(82S115_dip);
private: 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; object_array_t<logic_input_t, 9> m_A;
logic_input_t m_CE1Q; logic_input_t m_CE1Q;
logic_input_t m_CE2; logic_input_t m_CE2;
@ -88,34 +119,6 @@ namespace netlist
NETLIB_SUB(82S115) A; 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, "PROM_82S115", "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE,@VCC,@GND")
NETLIB_DEVICE_IMPL(82S115_dip, "PROM_82S115_DIP", "") NETLIB_DEVICE_IMPL(82S115_dip, "PROM_82S115_DIP", "")

View File

@ -19,8 +19,8 @@ namespace netlist
, m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(enq)) , m_CE1Q(*this, "CE1Q", NETLIB_DELEGATE(enq))
, m_CE2Q(*this, "CE2Q", NETLIB_DELEGATE(enq)) , m_CE2Q(*this, "CE2Q", NETLIB_DELEGATE(enq))
, m_CE3Q(*this, "CE3Q", NETLIB_DELEGATE(enq)) , m_CE3Q(*this, "CE3Q", NETLIB_DELEGATE(enq))
, m_WEQ(*this, "WEQ") , m_WEQ(*this, "WEQ", NETLIB_DELEGATE(inputs))
, m_DIN(*this, "DIN") , m_DIN(*this, "DIN", NETLIB_DELEGATE(inputs))
, m_DOUTQ(*this, "DOUTQ") , m_DOUTQ(*this, "DOUTQ")
, m_ram(*this, "m_ram", 0) , m_ram(*this, "m_ram", 0)
, m_addr(*this, "m_addr", 0) , m_addr(*this, "m_addr", 0)
@ -38,7 +38,30 @@ namespace netlist
m_addr = 0; m_addr = 0;
m_enq = 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) NETLIB_HANDLERI(addr)
{ {
uint8_t adr = 0; 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; object_array_t<logic_input_t, 8> m_A;
logic_input_t m_CE1Q; logic_input_t m_CE1Q;
logic_input_t m_CE2Q; logic_input_t m_CE2Q;
@ -121,23 +142,6 @@ namespace netlist
NETLIB_SUB(82S16) A; 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, "TTL_82S16", "")
NETLIB_DEVICE_IMPL(82S16_dip, "TTL_82S16_DIP", "") NETLIB_DEVICE_IMPL(82S16_dip, "TTL_82S16_DIP", "")

View File

@ -18,14 +18,20 @@ namespace netlist
{ {
NETLIB_CONSTRUCTOR(9322_selector) NETLIB_CONSTRUCTOR(9322_selector)
, m_parent(owner) , m_parent(owner)
, m_A(*this, "A") , m_A(*this, "A", NETLIB_DELEGATE(inputs))
, m_B(*this, "B") , m_B(*this, "B", NETLIB_DELEGATE(inputs))
, m_Y(*this, "Y") , m_Y(*this, "Y")
, m_power_pins(*this) , m_power_pins(*this)
{ {
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
// FIXME: Timing
NETLIB_HANDLERI(inputs);
public: public:
NETLIB_NAME(9322) &m_parent; NETLIB_NAME(9322) &m_parent;
@ -38,8 +44,8 @@ namespace netlist
NETLIB_OBJECT(9322) NETLIB_OBJECT(9322)
{ {
NETLIB_CONSTRUCTOR(9322) NETLIB_CONSTRUCTOR(9322)
, m_SELECT(*this, "SELECT") , m_SELECT(*this, "SELECT", NETLIB_DELEGATE(inputs))
, m_STROBE(*this, "STROBE") , m_STROBE(*this, "STROBE", NETLIB_DELEGATE(inputs))
, m_1(*this, "A") , m_1(*this, "A")
, m_2(*this, "B") , m_2(*this, "B")
, m_3(*this, "C") , m_3(*this, "C")
@ -70,13 +76,24 @@ namespace netlist
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(9322_dip); friend class NETLIB_NAME(9322_dip);
public: public:
logic_input_t m_SELECT; logic_input_t m_SELECT;
logic_input_t m_STROBE; logic_input_t m_STROBE;
private: 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_1;
NETLIB_SUB(9322_selector) m_2; NETLIB_SUB(9322_selector) m_2;
NETLIB_SUB(9322_selector) m_3; 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_OBJECT(9322_dip)
{ {
NETLIB_CONSTRUCTOR(9322_dip) NETLIB_CONSTRUCTOR(9322_dip)
@ -114,25 +141,6 @@ namespace netlist
NETLIB_SUB(9322) A; 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, "TTL_9322", "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE,@VCC,@GND")
NETLIB_DEVICE_IMPL(9322_dip, "TTL_9322_DIP", "") NETLIB_DEVICE_IMPL(9322_dip, "TTL_9322_DIP", "")

View File

@ -15,10 +15,10 @@ namespace netlist
NETLIB_OBJECT(9314) NETLIB_OBJECT(9314)
{ {
NETLIB_CONSTRUCTOR(9314) NETLIB_CONSTRUCTOR(9314)
, m_EQ(*this, "EQ") , m_EQ(*this, "EQ", NETLIB_DELEGATE(inputs))
, m_MRQ(*this, "MRQ") , m_MRQ(*this, "MRQ", NETLIB_DELEGATE(inputs))
, m_SQ(*this, {"S0Q", "S1Q", "S2Q", "S3Q"}) , m_SQ(*this, {"S0Q", "S1Q", "S2Q", "S3Q"}, NETLIB_DELEGATE(inputs))
, m_D(*this, {"D0", "D1", "D2", "D3"}) , m_D(*this, {"D0", "D1", "D2", "D3"}, NETLIB_DELEGATE(inputs))
, m_Q(*this, {"Q0", "Q1", "Q2", "Q3"}) , m_Q(*this, {"Q0", "Q1", "Q2", "Q3"})
, m_last_EQ(*this, "m_last_EQ", 0) , m_last_EQ(*this, "m_last_EQ", 0)
, m_last_MRQ(*this, "m_last_MRQ", 0) , m_last_MRQ(*this, "m_last_MRQ", 0)
@ -38,10 +38,43 @@ namespace netlist
m_last_Q = 0; m_last_Q = 0;
} }
NETLIB_UPDATEI(); NETLIB_UPDATEI()
{
inputs();
}
friend class NETLIB_NAME(9314_dip); friend class NETLIB_NAME(9314_dip);
private: 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_EQ;
logic_input_t m_MRQ; logic_input_t m_MRQ;
object_array_t<logic_input_t, 4> m_SQ; object_array_t<logic_input_t, 4> m_SQ;
@ -83,36 +116,6 @@ namespace netlist
NETLIB_SUB(9314) A; 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, "TTL_9314", "+EQ,+MRQ,+S0Q,+S1Q,+S2Q,+S3Q,+D0,+D1,+D2,+D3,@VCC,@GND")
NETLIB_DEVICE_IMPL(9314_dip, "TTL_9314_DIP", "") NETLIB_DEVICE_IMPL(9314_dip, "TTL_9314_DIP", "")