@@ -292,51 +292,33 @@ inline void ClassSimZ80::set(bool on, QString name)
292292#if USE_PERFORMANCE_SIM
293293inline bool ClassSimZ80::getNetValue ()
294294{
295- // 1. Deal with power connections first
296- for (net_t *p = m_group; p < (m_group + m_groupIndex); p++)
297- if (*p == ngnd) return false ;
298- for (net_t *p = m_group; p < (m_group + m_groupIndex); p++)
299- if (*p == npwr) return true ;
300- // 2. Deal with pullup/pulldowns next
301- for (net_t *p = m_group; p < (m_group + m_groupIndex); p++)
295+ // 1. Deal with power connections first - check first element for fast path
296+ // if (m_groupIndex > 0)
302297 {
303- Net &net = m_netlist[*p];
304- if (net.isHigh ) return true ;
305- if (net.isLow ) return false ;
298+ if (m_group[0 ] <= npwr) return bool (m_group[0 ] == npwr); // ngnd || npwr => false || true
306299 }
300+ // 2. Deal with pullup/pulldowns next
307301 // 3. Resolve connected set of floating nodes
308- // Several approaches work:
309- // - based on state of largest (by #connections) node
310- // - that, either by the number of connected gates, or by the number of connected pins
311- // - any node for which state is true
312- auto max_state = false ;
313- // auto max_conn = 0;
302+ auto state = false ; // We simply pick the first node which state is high
314303 for (net_t *p = m_group; p < (m_group + m_groupIndex); p++)
315304 {
316305 Net &net = m_netlist[*p];
317- #if 0
318- // We just want to pick the larger, or "stronger" net, assuming that one would have more transistor connections
319- //auto conn = net.gates.count() + net.c1c2s.count();
320- //auto conn = net.c1c2s.count();
321- auto conn = net.gates.count();
322- if (conn > max_conn)
323- {
324- max_conn = conn;
325- max_state = net.state;
326- }
327- #endif
328- // Or we simply pick the first node which state is high
329- if (net.state == true )
330- return true ;
306+ if (net.isHigh ) return true ;
307+ if (net.isLow ) return false ;
308+ if (net.state ) state = true ; // Last priority is the state, after we have checked for isHigh/isLow
331309 }
332- return max_state ;
310+ return state ;
333311}
334312#else
335313inline bool ClassSimZ80::getNetValue ()
336314{
337- // 1. Deal with power connections first
338- if (Q_UNLIKELY (group.contains (ngnd))) return false ;
339- if (Q_UNLIKELY (group.contains (npwr))) return true ;
315+ // 1. Deal with power connections first - check first element for fast path
316+ if (!group.isEmpty ())
317+ {
318+ if (group[0 ] == ngnd) return false ;
319+ if (group[0 ] == npwr) return true ;
320+ }
321+
340322 // 2. Deal with pullup/pulldowns next
341323 for (auto i : group)
342324 {
@@ -406,7 +388,7 @@ inline void ClassSimZ80::recalcNetlist(QVector<net_t> &list)
406388#if USE_PERFORMANCE_SIM
407389inline void ClassSimZ80::recalcNet (net_t n)
408390{
409- if (Q_UNLIKELY ((n == ngnd) || (n == npwr))) return ;
391+ if (Q_UNLIKELY (n <= npwr)) return ; // ngnd || npwr
410392 getNetGroup (n);
411393 bool newState = getNetValue ();
412394 for (net_t *p = m_group; p < (m_group + m_groupIndex); p++)
@@ -501,7 +483,7 @@ QVector<net_t> ClassSimZ80::allNets()
501483#if USE_PERFORMANCE_SIM
502484inline void ClassSimZ80::addRecalcNet (net_t n)
503485{
504- if (Q_UNLIKELY ((n == ngnd) || (n == npwr))) return ;
486+ if (Q_UNLIKELY (n <= npwr)) return ; // ngnd || npwr
505487
506488 // Use bitset for O(1) duplicate check instead of O(n) linear search
507489 if (testBit (m_recalcBitset, n))
@@ -542,8 +524,18 @@ inline void ClassSimZ80::addNetToGroup(net_t n)
542524 return ;
543525
544526 setBit (m_groupBitset, n);
527+
528+ // If ground or power, place at position 0 for fast detection in getNetValue()
529+ if (Q_UNLIKELY (n <= npwr)) // ngnd || npwr
530+ {
531+ m_group[m_groupIndex] = n;
532+ // Swap with position 0 if not already there
533+ std::swap (m_group[0 ], m_group[m_groupIndex]);
534+ m_groupIndex++;
535+ return ;
536+ }
537+
545538 m_group[m_groupIndex++] = n;
546- if (Q_UNLIKELY ((n == ngnd) || (n == npwr))) return ;
547539
548540 for (Trans *t : m_netlist[n].c1c2s )
549541 {
@@ -559,8 +551,22 @@ inline void ClassSimZ80::addNetToGroup(net_t n)
559551inline void ClassSimZ80::addNetToGroup (net_t n)
560552{
561553 if (group.contains (n)) return ;
554+
555+ // If ground or power, place at position 0 for fast detection in getNetValue()
556+ if (Q_UNLIKELY ((n == ngnd) || (n == npwr)))
557+ {
558+ group.append (n);
559+ // Swap with position 0 if not already there
560+ if (group.size () > 1 )
561+ {
562+ net_t temp = group[0 ];
563+ group[0 ] = n;
564+ group[group.size () - 1 ] = temp;
565+ }
566+ return ;
567+ }
568+
562569 group.append (n);
563- if (Q_UNLIKELY ((n == ngnd) || (n == npwr))) return ;
564570
565571 for (Trans *t : m_netlist[n].c1c2s )
566572 {
0 commit comments