forked from xcore/tool_axe
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SystemState.cpp
127 lines (118 loc) · 3.65 KB
/
SystemState.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2011, Richard Osborne, All rights reserved
// This software is freely distributable under a derivative of the
// University of Illinois/NCSA Open Source License posted in
// LICENSE.txt and at <http://github.xcore.com/>
#include <iomanip>
#include "SystemState.h"
#include "Node.h"
#include "Core.h"
#include "Trace.h"
#include "Stats.h"
using namespace Register;
SystemState::~SystemState()
{
for (node_iterator it = nodes.begin(), e = nodes.end(); it != e; ++it) {
delete *it;
}
}
void SystemState::finalize()
{
for (node_iterator it = nodes.begin(), e = nodes.end(); it != e; ++it) {
(*it)->finalize();
}
}
void SystemState::addNode(std::auto_ptr<Node> n)
{
n->setParent(this);
nodes.push_back(n.get());
n.release();
}
void SystemState::
completeEvent(Thread &t, EventableResource &res, bool interrupt)
{
if (interrupt) {
t.regs[SSR] = t.sr.to_ulong();
t.regs[SPC] = t.getParent().targetPc(t.pc);
t.regs[SED] = t.regs[ED];
t.ieble() = false;
t.inint() = true;
t.ink() = true;
} else {
t.inenb() = 0;
}
t.eeble() = false;
// EventableResource::completeEvent sets the ED and PC.
res.completeEvent();
if (Tracer::get().getTracingEnabled()) {
if (interrupt) {
Tracer::get().interrupt(t, res, t.getParent().targetPc(t.pc),
t.regs[SSR], t.regs[SPC], t.regs[SED],
t.regs[ED]);
} else {
Tracer::get().event(t, res, t.getParent().targetPc(t.pc), t.regs[ED]);
}
}
}
int SystemState::run()
{
try {
while (!scheduler.empty()) {
Runnable &runnable = scheduler.front();
currentRunnable = &runnable;
scheduler.pop();
runnable.run(runnable.wakeUpTime);
}
} catch (ExitException &ee) {
if (stats) {
dump();
}
if (Stats::get().getStatsEnabled())
{
Stats::get().dump();
}
return ee.getStatus();
}
Tracer::get().noRunnableThreads(*this);
return 1;
}
void SystemState::dump() {
long totalCount = 0;
ticks_t maxTime = 0;
for (node_iterator nIt=node_begin(), nEnd=node_end(); nIt!=nEnd; ++nIt) {
Node &node = **nIt;
for (Node::core_iterator cIt=node.core_begin(), cEnd=node.core_end();
cIt!=cEnd; ++cIt) {
Core &core = **cIt;
std::cout << "Core " << core.getCoreNumber() << std::endl;
std::cout
<< std::setw(8) << "Thread" << " "
<< std::setw(12) << "Time" << " "
<< std::setw(12) << "Insts" << " "
<< std::setw(12) << "Insts/cycle" << std::endl;
for (int i=0; i<NUM_THREADS; i++) {
Thread &thread = core.getThread(i);
totalCount += thread.count;
maxTime = maxTime > thread.time ? maxTime : thread.time;
double ratio = (double) thread.count / (double) thread.time;
std::cout
<< std::setw(8) << i << " "
<< std::setw(12) << thread.time << " "
<< std::setw(12) << thread.count << " "
<< std::setw(12) << std::setprecision(2) << ratio << std::endl;
}
}
}
// Assume 10ns cycle (400Mhz clock)
double seconds = (double) maxTime / 100000000.0;
double opsPerSec = (double) totalCount / seconds;
double gOpsPerSec = opsPerSec / 1000000.0;
std::cout << std::endl;
std::cout << "Total instructions executed: " << totalCount << std::endl;
std::cout << "Total cycles: " << maxTime << std::endl;
std::cout << "Elapsed time (s): "
<< std::setprecision(2) << seconds << std::endl;
std::cout << "Instructions per second: "
<< std::setprecision(2) << opsPerSec
<< " (" << std::setprecision(2) << gOpsPerSec << " GIPS)" << std::endl;
std::cout << std::endl;
}