Previous 199869 Revisions Next

r18536 Monday 15th October, 2012 at 14:06:24 UTC by Curt Coder
Optimized the PLA implementation and added simple caching with significant performance increase. [Curt Coder]
[src/emu/machine]pla.c pla.h

trunk/src/emu/machine/pla.c
r18535r18536
1212
1313
1414//**************************************************************************
15//  DEVICE TYPE DEFINITION
15//  DEVICE TYPE DEFINITIONS
1616//**************************************************************************
1717
1818const device_type PLS100 = &device_creator<pls100_device>;
r18535r18536
2121
2222
2323//**************************************************************************
24//  INLINE HELPERS
24//  LIVE DEVICE
2525//**************************************************************************
2626
2727//-------------------------------------------------
28//  pla_device - constructor
29//-------------------------------------------------
30
31pla_device::pla_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int inputs, int outputs, int terms, UINT32 input_mask)
32   : device_t(mconfig, type, name, tag, owner, clock),
33     m_inputs(inputs),
34     m_outputs(outputs),
35     m_terms(terms),
36     m_input_mask(((UINT64)input_mask << 32) | input_mask)
37{
38}
39
40pls100_device::pls100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
41    : pla_device(mconfig, PLS100, "PLS100", tag, owner, clock, 16, 8, 48, 0xffff)
42{
43}
44
45mos8721_device::mos8721_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
46    : pla_device(mconfig, MOS8721, "MOS8721", tag, owner, clock, 27, 18, 379, 0x7ffffff) // TODO actual number of terms is unknown
47{
48}
49
50
51//-------------------------------------------------
52//  device_start - device-specific startup
53//-------------------------------------------------
54
55void pla_device::device_start()
56{
57   assert(machine().root_device().memregion(tag()) != NULL);
58
59   // parse fusemap
60   parse_fusemap();
61
62   // clear cache
63   for (int i = 0; i < CACHE_SIZE; i++)
64   {
65      m_cache[i] = 0;
66   }
67
68   m_cache_ptr = 0;
69}
70
71
72//-------------------------------------------------
2873//  parse_fusemap -
2974//-------------------------------------------------
3075
31inline void pla_device::parse_fusemap()
76void pla_device::parse_fusemap()
3277{
3378   memory_region *region = machine().root_device().memregion(tag());
3479   jed_data jed;
3580   
3681   jedbin_parse(region->base(), region->bytes(), &jed);
3782
38   //logerror("PLA '%s' %u fuses\n", tag(), jed.numfuses);
39
4083   UINT32 fusenum = 0;
41   m_xor = 0;
4284
43   for (int term = 0; term < m_terms; term++)
85   for (int p = 0; p < m_terms; p++)
4486   {
45      m_and_comp[term] = 0;
46      m_and_true[term] = 0;
47      m_or[term] = 0;
87      term *term = &m_term[p];
4888
89      // AND mask
90      term->m_and = 0;
91
4992      for (int i = 0; i < m_inputs; i++)
5093      {
51         m_and_comp[term] |= jed_get_fuse(&jed, fusenum++) << i;
52         m_and_true[term] |= jed_get_fuse(&jed, fusenum++) << i;
94         // complement
95         term->m_and |= (UINT64)jed_get_fuse(&jed, fusenum++) << (i + 32);
96
97         // true
98         term->m_and |= (UINT64)jed_get_fuse(&jed, fusenum++) << i;
5399      }
54100
101      // OR mask
102      term->m_or = 0;
103
55104      for (int f = 0; f < m_outputs; f++)
56105      {
57         m_or[term] |= !jed_get_fuse(&jed, fusenum++) << f;
106         term->m_or |= !jed_get_fuse(&jed, fusenum++) << f;
58107      }
59108
60      //logerror("PLA '%s' %3u COMP %08x TRUE %08x OR %08x\n", tag(), term, m_and_comp[term], m_and_true[term], m_or[term]);
109      term->m_or <<= 32;
61110   }
62111
112   // XOR mask
113   m_xor = 0;
114
63115   for (int f = 0; f < m_outputs; f++)
64116   {
65117      m_xor |= jed_get_fuse(&jed, fusenum++) << f;
66118   }
67119
68   //logerror("PLA '%s' XOR %08x\n", tag(), m_xor);
120   m_xor <<= 32;
69121}
70122
71123
72124//-------------------------------------------------
73//  get_product -
125//  read -
74126//-------------------------------------------------
75127
76inline bool pla_device::get_product(int term)
128UINT32 pla_device::read(UINT32 input)
77129{
78   UINT32 input_comp = m_and_comp[term] | ~m_i;
79   UINT32 input_true = m_and_true[term] | m_i;
130   // try the cache first
131   for (int i = 0; i < CACHE_SIZE; ++i)
132   {
133      UINT64 cache_entry = m_cache[i];
80134
81   //logerror("PLA '%s' %3u COMP %08x TRUE %08x OR %08x : %u\n", tag(), term, ~input_comp & m_output_mask, ~input_true & m_output_mask, m_or[term], (((input_comp & input_true) & m_output_mask) == m_output_mask));
135      if ((UINT32)cache_entry == input)
136      {
137         // cache hit
138         return cache_entry >> 32;
139      }
140   }
82141
83   return ((input_comp & input_true) & m_output_mask) == m_output_mask;
84}
142   // cache miss, process terms
143   UINT64 inputs = ((~(UINT64)input << 32) | input) & m_input_mask;
144   UINT64 s = 0;
85145
146   for (int i = 0; i < m_terms; ++i)
147   {
148      term term = m_term[i];
86149
87//-------------------------------------------------
88//  update_outputs -
89//-------------------------------------------------
90
91inline void pla_device::update_outputs()
92{
93   m_s = 0;
94
95   for (int term = 0; term < m_terms; term++)
96   {
97      if (get_product(term))
150      if ((term.m_and | inputs) == m_input_mask)
98151      {
99         m_s |= m_or[term];
152         s |= term.m_or;
100153      }
101154   }
102}
103155
156   s ^= m_xor;
104157
158   // store output in cache
159   m_cache[m_cache_ptr] = s | input;
160   ++m_cache_ptr &= (CACHE_SIZE - 1);
105161
106//**************************************************************************
107//  LIVE DEVICE
108//**************************************************************************
109
110//-------------------------------------------------
111//  pla_device - constructor
112//-------------------------------------------------
113
114pla_device::pla_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int inputs, int outputs, int terms, UINT32 output_mask)
115   : device_t(mconfig, type, name, tag, owner, clock),
116     m_inputs(inputs),
117     m_outputs(outputs),
118     m_terms(terms),
119     m_output_mask(output_mask)
120{
162   return s >> 32;
121163}
122
123pls100_device::pls100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
124    : pla_device(mconfig, PLS100, "PLS100", tag, owner, clock, 16, 8, 48, 0xffff)
125{
126}
127
128mos8721_device::mos8721_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
129    : pla_device(mconfig, MOS8721, "MOS8721", tag, owner, clock, 27, 18, 379, 0x7ffffff) // TODO actual number of terms is unknown
130{
131}
132
133
134//-------------------------------------------------
135//  device_start - device-specific startup
136//-------------------------------------------------
137
138void pla_device::device_start()
139{
140   // parse fusemap
141   assert(machine().root_device().memregion(tag()) != NULL);
142   parse_fusemap();
143
144   // register for state saving
145   save_item(NAME(m_i));
146   save_item(NAME(m_s));
147}
148
149
150//-------------------------------------------------
151//  read -
152//-------------------------------------------------
153
154UINT32 pla_device::read(UINT32 input)
155{
156   m_i = input;
157
158   update_outputs();
159
160   return m_s ^ m_xor;
161}
trunk/src/emu/machine/pla.h
r18535r18536
3939//**************************************************************************
4040
4141#define MAX_TERMS       512
42#define CACHE_SIZE      8
4243
4344
4445
r18535r18536
7172    // device-level overrides
7273    virtual void device_start();
7374
74   inline void parse_fusemap();
75   inline bool get_product(int term);
76   inline void update_outputs();
75   void parse_fusemap();
7776
7877    int m_inputs;
7978    int m_outputs;
8079    int m_terms;
81    UINT32 m_output_mask;
80    UINT64 m_input_mask;
81   UINT64 m_xor;
8282
83   UINT32 m_i;
84   UINT32 m_s;
85   UINT32 m_and_true[MAX_TERMS];
86   UINT32 m_and_comp[MAX_TERMS];
87   UINT32 m_or[MAX_TERMS];
88   UINT32 m_xor;
83    struct term
84    {
85        UINT64 m_and;
86        UINT64 m_or;
87    };
88
89    term m_term[MAX_TERMS];
90
91    UINT64 m_cache[CACHE_SIZE];
92    UINT8 m_cache_ptr;
8993};
9094
9195

Previous 199869 Revisions Next


© 1997-2024 The MAME Team