Skip to content

Commit 831aa50

Browse files
committed
More simplifications and performance gains
1 parent 8f95443 commit 831aa50

2 files changed

Lines changed: 45 additions & 39 deletions

File tree

resource/zx.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function ZXSpectrum()
1414
run(0);
1515
print("\nZX Spectrum simulation is running.")
1616
print("For a faster simulation, remove all nets from Watchlist and close Waveform views.");
17-
print("It takes about 20 minutes to get to the initial screen when running at around 4kHz.");
17+
print("It takes about 10 minutes to get to the initial screen when running at around 10kHz.");
1818
}
1919
else
2020
{

src/ClassSimZ80.cpp

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -292,51 +292,33 @@ inline void ClassSimZ80::set(bool on, QString name)
292292
#if USE_PERFORMANCE_SIM
293293
inline 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
335313
inline 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
407389
inline 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
502484
inline 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)
559551
inline 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

Comments
 (0)