Previous 199869 Revisions Next

r31049 Friday 20th June, 2014 at 18:16:40 UTC by Couriersud
More cleanup and some development:
- removed dead code from nld_signal.h
- removed m_last_Q and all callers; if a device depends on state let it maintain it.
- added development on a generic device based on truthtables.
[src/emu/netlist]nl_base.c nl_base.h nl_config.h
[src/emu/netlist/devices]nld_7400.c nld_7400.h nld_7490.c nld_7490.h nld_74ls629.c nld_74ls629.h nld_signal.h nld_truthtable.h*

trunk/src/emu/netlist/devices/nld_7490.c
r31048r31049
2020   register_output("QD", m_Q[3]);
2121
2222   save(NAME(m_cnt));
23    save(NAME(m_last_A));
24    save(NAME(m_last_B));
2325
2426}
2527
r31048r31049
4749      m_cnt = 0;
4850      update_outputs();
4951   }
50   else if (INP_HL(m_A))
52   else if (m_last_A && !INPLOGIC(m_A))  // High - Low
5153   {
5254      m_cnt ^= 1;
5355      OUTLOGIC(m_Q[0], m_cnt & 1, delay[0]);
5456   }
55   else if (INP_HL(m_B))
57   else if (m_last_B && !INPLOGIC(m_B))  // High - Low
5658   {
5759      m_cnt += 2;
5860      if (m_cnt >= 10)
5961         m_cnt = 0;
6062      update_outputs();
6163   }
64    m_last_A = INPLOGIC(m_A);
65    m_last_B = INPLOGIC(m_B);
6266}
6367
6468NETLIB_FUNC_VOID(7490, update_outputs, (void))
trunk/src/emu/netlist/devices/nld_7490.h
r31048r31049
8181   netlist_ttl_input_t m_B;
8282
8383   netlist_state_t<UINT8> m_cnt;
84    netlist_state_t<UINT8> m_last_A;
85    netlist_state_t<UINT8> m_last_B;
8486
8587   netlist_ttl_output_t m_Q[4];
8688);
trunk/src/emu/netlist/devices/nld_signal.h
r31048r31049
2626// net_signal_t
2727// ----------------------------------------------------------------------------------------
2828
29template <int _numdev>
30class net_signal_base_t : public netlist_device_t
31{
32public:
33   net_signal_base_t()
34   : netlist_device_t(), m_active(1) { }
35
36   ATTR_COLD void start()
37   {
38      const char *sIN[8] = { "I1", "I2", "I3", "I4", "I5", "I6", "I7", "I8" };
39
40      register_output("Q", m_Q);
41      for (int i=0; i < _numdev; i++)
42      {
43         register_input(sIN[i], m_i[i], netlist_input_t::STATE_INP_ACTIVE);
44      }
45      save(NAME(m_active));
46   }
47
48   ATTR_COLD void reset()
49   {
50      m_Q.initial(1);
51      m_active = 1;
52   }
53
54#if (USE_DEACTIVE_DEVICE)
55   ATTR_HOT void inc_active()
56   {
57      if (++m_active == 1)
58      {
59         update();
60      }
61   }
62
63   ATTR_HOT void dec_active()
64   {
65      if (--m_active == 0)
66      {
67         for (int i = 0; i< _numdev; i++)
68            m_i[i].inactivate();
69      }
70   }
71#endif
72
73public:
74   netlist_ttl_input_t m_i[_numdev];
75   netlist_ttl_output_t m_Q;
76   INT32 m_active;
77};
78
79
8029template <int _numdev, int _check, int _invert>
8130class net_signal_t : public netlist_device_t
8231{
r31048r31049
207156
208157      m_i[0].activate();
209158      m_i[1].activate();
210#if 0
211      UINT8 res = _invert ^ 1 ^_check;
212      if (INPLOGIC(m_i[0]) ^ _check)
213      {
214         if (INPLOGIC(m_i[1]) ^ _check)
215         {
216            res = _invert ^ _check;
217         }
218         else
219            m_i[0].inactivate();
220      } else {
221         if (INPLOGIC(m_i[1]) ^ _check)
222            m_i[1].inactivate();
223      }
224      OUTLOGIC(m_Q, res, times[res & 1]);// ? 22000 : 15000);
225#else
159
226160      const UINT8 val = (INPLOGIC(m_i[0]) ^ _check) | ((INPLOGIC(m_i[1]) ^ _check) << 1);
227161      UINT8 res = _invert ^ 1 ^_check;
228162      switch (val)
r31048r31049
238172            break;
239173      }
240174      OUTLOGIC(m_Q, res, times[res]);// ? 22000 : 15000);
241#endif
242175   }
243176
244177public:
r31048r31049
248181
249182};
250183
251// The following did not improve performance
252#if 0
253
254template <UINT8 _check, UINT8 _invert>
255class net_signal_t<3, _check, _invert> : public netlist_device_t
256{
257public:
258   net_signal_t() : netlist_device_t(), m_active(1) { }
259
260   ATTR_COLD void start()
261   {
262      const char *sIN[3] = { "I1", "I2", "I3" };
263
264      register_output("Q", m_Q);
265      for (int i=0; i < 3; i++)
266      {
267         register_input(sIN[i], m_i[i], netlist_input_t::STATE_INP_ACTIVE);
268      }
269      //m_Q.initial(1);
270   }
271
272   ATTR_HOT ATTR_ALIGN void update()
273   {
274      const netlist_time times[2] = { NLTIME_FROM_NS(22), NLTIME_FROM_NS(15) };
275      //const UINT8 res_tab[4] = {1, 1, 1, 0 };
276      //const UINT8 ai1[4]     = {0, 1, 0, 0 };
277      //const UINT8 ai2[4]     = {1, 0, 1, 0 };
278
279      UINT8 res = _invert ^ 1 ^_check;
280      m_i[0].activate();
281      if (INPLOGIC(m_i[0]) ^ _check)
282      {
283         m_i[1].activate();
284         if (INPLOGIC(m_i[1]) ^ _check)
285         {
286            m_i[2].activate();
287            if (INPLOGIC(m_i[2]) ^ _check)
288            {
289               res = _invert ^ _check;
290            }
291            else
292               m_i[1].inactivate();
293         }
294         else
295         {
296            if (INPLOGIC(m_i[2]) ^ _check)
297               m_i[2].inactivate();
298            m_i[0].inactivate();
299         }
300      } else {
301         if (INPLOGIC(m_i[1]) ^ _check)
302            m_i[1].inactivate();
303      }
304      OUTLOGIC(m_Q, res, times[1 - res]);// ? 22000 : 15000);
305   }
306public:
307   netlist_ttl_input_t m_i[3];
308   netlist_ttl_output_t m_Q;
309   INT8 m_active;
310
311};
312
313#endif
314
315
316184template <int _check, int _invert>
317185class net_signal_t<2, _check, _invert> : public net_signal_2inp_t<_check, _invert>
318186{
trunk/src/emu/netlist/devices/nld_7400.c
r31048r31049
55
66#include "nld_7400.h"
77
8#if 0
9UINT32 nld_7400::m_outs[m_size];
10#endif
11
812NETLIB_START(7400_dip)
913{
1014   register_sub(m_1, "1");
trunk/src/emu/netlist/devices/nld_74ls629.c
r31048r31049
5151
5252   save(NAME(m_enableq));
5353   save(NAME(m_inc));
54    save(NAME(m_out));
5455}
5556
5657NETLIB_RESET(SN74LS629clk)
r31048r31049
6364{
6465   if (!m_enableq)
6566   {
66      OUTLOGIC(m_Y, !m_Y.net().as_logic().new_Q(), m_inc);
67       m_out = m_out ^ 1;
68      OUTLOGIC(m_Y, m_out, m_inc);
6769   }
6870   else
6971   {
r31048r31049
146148   if (!m_clock.m_enableq && INPLOGIC(m_ENQ))
147149   {
148150      m_clock.m_enableq = 1;
149      OUTLOGIC(m_clock.m_Y, !m_clock.m_Y.net().as_logic().last_Q(), netlist_time::from_nsec(1));
151      m_clock.m_out = m_clock.m_out ^ 1;
152      OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
150153   }
151154   else if (m_clock.m_enableq && !INPLOGIC(m_ENQ))
152155   {
153156      m_clock.m_enableq = 0;
154      OUTLOGIC(m_clock.m_Y, !m_clock.m_Y.net().as_logic().last_Q(), netlist_time::from_nsec(1));
157      m_clock.m_out = m_clock.m_out ^ 1;
158      OUTLOGIC(m_clock.m_Y, m_clock.m_out, netlist_time::from_nsec(1));
155159   }
156160}
157161
trunk/src/emu/netlist/devices/nld_7400.h
r31048r31049
3939      NET_CONNECT(_name, A, _A)                                                   \
4040      NET_CONNECT(_name, B, _B)
4141
42#if 1
4243NETLIB_SIGNAL(7400, 2, 0, 0);
44#else
45#include "nld_truthtable.h"
46class nld_7400 : public nld_truthtable_t<2,1>
47    {
48    public:
49        nld_7400 ()
50        : nld_truthtable_t<2,1>()
51    {
52    }
53        void start()
54        {
55            static const char *tt[] = {
56                    "A,B,PQ,PA,PB|Q",
57                    "0,X,X,X,X|1",
58                    "X,0,X,X,X|1",
59                    "1,1,X,X,X|0",
60                    ""
61            };
62            setup_tt(tt, m_outs);
63        }
64    private:
65        static UINT32 m_outs[m_size];
66};
67#endif
4368
69
4470#define TTL_7400_DIP(_name)                                                         \
4571      NET_REGISTER_DEV(7400_dip, _name)
4672
trunk/src/emu/netlist/devices/nld_74ls629.h
r31048r31049
4141
4242   netlist_time m_inc;
4343   netlist_state_t<netlist_sig_t> m_enableq;
44    netlist_state_t<netlist_sig_t> m_out;
4445);
4546
4647NETLIB_DEVICE_WITH_PARAMS(SN74LS629,
trunk/src/emu/netlist/devices/nld_truthtable.h
r0r31049
1/*
2 * nld_truthtable.h
3 *
4 *  Created on: 19 Jun 2014
5 *      Author: andre
6 */
7
8#ifndef NLD_TRUTHTABLE_H_
9#define NLD_TRUTHTABLE_H_
10
11#include "../nl_base.h"
12
13template<int m_NI, int m_NO>
14class nld_truthtable_t : public netlist_device_t
15{
16public:
17
18    static const int m_size = (1 << (2 * m_NI + m_NO));
19
20    nld_truthtable_t()
21    : netlist_device_t(), m_active(1)
22    {
23    }
24
25    ATTR_COLD virtual void start()
26    {
27    }
28
29    ATTR_COLD void help(UINT32 outs[], int cur, nl_util::pstring_list list, UINT64 state, UINT64 ignore, UINT16 val)
30    {
31        pstring elem = list[cur];
32        int start = 0;
33        int end = 0;
34        int ign = 0;
35
36        if (elem.equals("0"))
37        {
38            start = 0;
39            end = 0;
40        }
41        else if (elem.equals("1"))
42        {
43            start = 1;
44            end = 1;
45        }
46        else if (elem.equals("X"))
47        {
48            start = 0;
49            end = 1;
50            ign = 1;
51        }
52        for (int i = start; i <= end; i++)
53        {
54            const UINT64 nstate = state | (i << cur);
55            const UINT64 nignore = ignore | (ign << cur);
56
57            if (cur < list.count() - 1)
58            {
59                help(outs, cur + 1, list, nstate, nignore, val);
60            }
61            else
62            {
63                // cutoff previous inputs and outputs for ignore
64                outs[nstate] = val | ((nignore & ((1 << m_NI)-1)) << m_NO);
65            }
66        }
67    }
68
69    ATTR_COLD void setup_tt(const char **truthtable, UINT32 outs[])
70    {
71        pstring ttline = pstring(truthtable[0]);
72        truthtable++;
73        {
74            nl_util::pstring_list io = nl_util::split(ttline,"|");
75            // checks
76            assert(io.count() == 2);
77            nl_util::pstring_list inout = nl_util::split(io[0], ",");
78            assert(inout.count() == 2 * m_NI + m_NO);
79            nl_util::pstring_list out = nl_util::split(io[1], ",");
80            assert(out.count() == m_NO);
81
82            for (int i=0; i < m_NI; i++)
83            {
84                register_input(inout[i], m_i[i]);
85            }
86            for (int i=0; i < m_NO; i++)
87            {
88                register_output(out[i], m_Q[i]);
89            }
90            //save(NAME(m_active));
91            ttline = pstring(truthtable[0]);
92            truthtable++;
93        }
94
95        for (int j=0; j < m_size; j++)
96            outs[j] = -1;
97
98        while (!ttline.equals(""))
99        {
100            nl_util::pstring_list io = nl_util::split(ttline,"|");
101            // checks
102            assert(io.count() == 2);
103            nl_util::pstring_list inout = nl_util::split(io[0], ",");
104            assert(inout.count() == 2 * m_NI + m_NO);
105            nl_util::pstring_list out = nl_util::split(io[1], ",");
106            assert(out.count() == m_NO);
107
108            UINT16 val = 0;
109            for (int j=0; j<m_NO; j++)
110                if (out[j].equals("1"))
111                    val = val | (1 << j);
112
113            help(outs, 0, inout, 0 , 0 , val);
114            ttline = pstring(truthtable[0]);
115            truthtable++;
116        }
117        for (int j=0; j < m_size; j++)
118            printf("%05x %04x %04x\n", j, outs[j] & ((1 << m_NO)-1), outs[j] >> m_NO);
119        m_ttp = outs;
120    }
121
122    ATTR_COLD void reset()
123    {
124        //m_Q.initial(1);
125        m_active = 1;
126        m_last_state = 0;
127    }
128
129    ATTR_HOT ATTR_ALIGN void update()
130    {
131        const netlist_time times[2] = { NLTIME_FROM_NS(15), NLTIME_FROM_NS(22)};
132
133        // FIXME: this check is needed because update is called during startup as well
134        if (UNEXPECTED(USE_DEACTIVE_DEVICE && m_active == 0))
135            return;
136
137        UINT32 state = 0;
138        for (int i=0; i< m_NI; i++)
139        {
140            m_i[i].activate();
141            state = state | (INPLOGIC(m_i[i]) << i);
142        }
143
144        const UINT32 nstate = state | (m_last_state << m_NI);
145        const UINT32 out = m_ttp[nstate] & ((1 << m_NO) - 1);
146        const UINT32 ign = m_ttp[nstate] >> m_NO;
147
148        for (int i=0; i< m_NI; i++)
149            if (ign & (1 << i))
150                m_i[i].inactivate();
151
152        for (int i=0; i<m_NO; i++)
153            OUTLOGIC(m_Q[i], (out >> i) & 1, times[(out >> i) & 1]);// ? 22000 : 15000);
154        m_last_state = (state << m_NO) | out;
155
156    }
157
158
159#if (USE_DEACTIVE_DEVICE)
160    ATTR_HOT void inc_active()
161    {
162        if (++m_active == 1)
163        {
164            update();
165        }
166    }
167
168    ATTR_HOT void dec_active()
169    {
170        if (--m_active == 0)
171        {
172            for (int i = 0; i< m_NI; i++)
173                m_i[i].inactivate();
174        }
175    }
176#endif
177
178public:
179    netlist_ttl_input_t m_i[m_NI];
180    netlist_ttl_output_t m_Q[m_NO];
181
182    UINT32 *m_ttp;
183    INT32 m_active;
184    UINT32 m_last_state;
185};
186
187#endif /* NLD_TRUTHTABLE_H_ */
Property changes on: trunk/src/emu/netlist/devices/nld_truthtable.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/emu/netlist/nl_base.c
r31048r31049
455455   : netlist_object_t(NET, afamily)
456456    , m_new_Q(0)
457457    , m_cur_Q (0)
458    , m_last_Q(0)
459458    , m_railterminal(NULL)
460459   , m_time(netlist_time::zero)
461460   , m_active(0)
r31048r31049
486485   {
487486      if (m_active == 1 && m_in_queue > 0)
488487      {
489         m_last_Q = m_cur_Q;
490488         railterminal().netdev().inc_active();
491489         m_cur_Q = m_new_Q;
492490      }
r31048r31049
501499      }
502500      else
503501      {
504         m_cur_Q = m_last_Q = m_new_Q;
502         m_cur_Q = m_new_Q;
505503         m_in_queue = 2;
506504      }
507505   }
r31048r31049
541539   save(NAME(m_active));
542540   save(NAME(m_in_queue));
543541    save(NAME(m_cur_Analog));
544    save(NAME(m_last_Q));
545542    save(NAME(m_cur_Q));
546543    save(NAME(m_new_Q));
547544   netlist_object_t::save_register();
r31048r31049
565562   assert(this->isRailNet());
566563
567564   const UINT32 masks[4] = { 1, 5, 3, 1 };
568   const UINT32 mask = masks[ (m_last_Q  << 1) | m_new_Q ];
565    const UINT32 mask = masks[ (m_cur_Q  << 1) | m_new_Q ];
569566   netlist_core_terminal_t *p = m_list_active.first();
570567
571568   m_in_queue = 2; /* mark as taken ... */
572569   m_cur_Q = m_new_Q;
573570
574    switch (m_active)
571   switch (m_active)
575572    {
576573    case 2:
577574        update_dev(p, mask);
r31048r31049
588585        }
589586        break;
590587    }
591   m_last_Q = m_cur_Q;
588
592589}
593590
594591ATTR_COLD void netlist_net_t::reset()
r31048r31049
597594   m_active = 0;
598595   m_in_queue = 2;
599596
600    m_last_Q = 0;
601597    m_new_Q = 0;
602598    m_cur_Q = 0;
603599    m_cur_Analog = 0.0;
trunk/src/emu/netlist/nl_config.h
r31048r31049
2323 */
2424#define USE_PMFDELEGATES        (0)
2525
26// This increases performance in circuits with a lot of gates
27// but is not guaranteed to be absolutely timing correct.
26/*
27 *  This increases performance in circuits with a lot of gates
28 *  but is not guaranteed to be absolutely timing correct.
29 *
30 *  Performance increase about 10%
31 *
32 */
2833
2934#define USE_DEACTIVE_DEVICE     (0)
3035
trunk/src/emu/netlist/nl_base.h
r31048r31049
629629
630630    netlist_sig_t m_new_Q;
631631    netlist_sig_t m_cur_Q;
632    netlist_sig_t m_last_Q;
633632
634633private:
635634
r31048r31049
663662        return m_cur_Q;
664663    }
665664
666    ATTR_HOT inline const netlist_sig_t last_Q() const
667    {
668        return m_last_Q;
669    }
670
671665    ATTR_HOT inline const netlist_sig_t new_Q() const
672666    {
673667        return m_new_Q;
r31048r31049
691685    {
692686        m_cur_Q = val;
693687        m_new_Q = val;
694        m_last_Q = val;
695688    }
696689
697690    /* internal state support
r31048r31049
986979      out.set_Q(val, delay);
987980   }
988981
989    ATTR_HOT inline bool INP_CHANGED(const netlist_logic_input_t &inp) const
990    {
991        return (inp.last_Q() != inp.Q());
992    }
993
994    ATTR_HOT inline bool INP_HL(const netlist_logic_input_t &inp) const
995   {
996      return ((inp.last_Q() & !inp.Q()) == 1);
997   }
998
999   ATTR_HOT inline bool INP_LH(const netlist_logic_input_t &inp) const
1000   {
1001      return ((!inp.last_Q() & inp.Q()) == 1);
1002   }
1003
1004982   ATTR_HOT inline const double INPANALOG(const netlist_analog_input_t &inp) const { return inp.Q_Analog(); }
1005983
1006984   ATTR_HOT inline const double TERMANALOG(const netlist_terminal_t &term) const { return term.net().as_analog().Q_Analog(); }
r31048r31049
13581336   return net().as_logic().Q();
13591337}
13601338
1361ATTR_HOT inline const netlist_sig_t netlist_logic_input_t::last_Q() const
1362{
1363   return net().as_logic().last_Q();
1364}
1365
13661339ATTR_HOT inline const double netlist_analog_input_t::Q_Analog() const
13671340{
13681341   return net().as_analog().Q_Analog();

Previous 199869 Revisions Next


© 1997-2024 The MAME Team