aboutsummaryrefslogtreecommitdiff
path: root/qtmips_cli
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-25 00:20:05 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-25 00:20:05 +0100
commit7666c09923bfc56132e9332133650a256a478c14 (patch)
tree90efbbeddd8a3291d7ea831028d23404157116c9 /qtmips_cli
parent742d48d1462523c89087551e683e824f922bb629 (diff)
downloadqtmips-7666c09923bfc56132e9332133650a256a478c14.tar.gz
qtmips-7666c09923bfc56132e9332133650a256a478c14.tar.bz2
qtmips-7666c09923bfc56132e9332133650a256a478c14.zip
qtmips_cli: include dump of cache statistic in command line tool.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_cli')
-rw-r--r--qtmips_cli/main.cpp59
-rw-r--r--qtmips_cli/reporter.cpp22
-rw-r--r--qtmips_cli/reporter.h3
3 files changed, 82 insertions, 2 deletions
diff --git a/qtmips_cli/main.cpp b/qtmips_cli/main.cpp
index a333392..49f4cbf 100644
--- a/qtmips_cli/main.cpp
+++ b/qtmips_cli/main.cpp
@@ -63,8 +63,62 @@ void create_parser(QCommandLineParser &p) {
p.addOption({{"trace-lo", "tr-lo"}, "Print LO register changes."});
p.addOption({{"trace-hi", "tr-hi"}, "Print HI register changes."});
p.addOption({{"dump-registers", "d-regs"}, "Dump registers state at program exit."});
+ p.addOption({"dump-cache-stats", "Dump cache statistics at program exit."});
p.addOption({"expect-fail", "Expect that program causes CPU trap and fail if it doesn't."});
p.addOption({"fail-match", "Program should exit with exactly this CPU TRAP. Possible values are I(unsupported Instruction), A(Unsupported ALU operation), O(Overflow/underflow) and J(Unaligned Jump). You can freely combine them. Using this implies expect-fail option.", "TRAP"});
+ p.addOption({"d-cache", "Data cache. Format policy,sets,words_in_blocks,associativity where policy is random/lru/lfu", "DCACHE"});
+ p.addOption({"i-cache", "Instruction cache. Format policy,sets,words_in_blocks,associativity where policy is random/lru/lfu", "ICACHE"});
+}
+
+void configure_cache(MachineConfigCache &cacheconf, QStringList cachearg, QString which) {
+ if (cachearg.size() < 1)
+ return;
+ cacheconf.set_enabled(true);
+ QStringList pieces = cachearg.at(cachearg.size() - 1).split(",");
+ if (pieces.size() < 3) {
+ std::cerr << "Parameters for " << which.toLocal8Bit().data() << " cache incorrect (correct lru,4,2,2,wb)." << std::endl;
+ exit(1);
+ }
+ if (pieces.at(0).size() < 1) {
+ std::cerr << "Policy for " << which.toLocal8Bit().data() << " cache is incorrect." << std::endl;
+ exit(1);
+ }
+ if (!pieces.at(0).at(0).isDigit()) {
+ if (pieces.at(0).toLower() == "random")
+ cacheconf.set_replacement_policy(MachineConfigCache::RP_RAND);
+ else if (pieces.at(0).toLower() == "lru")
+ cacheconf.set_replacement_policy(MachineConfigCache::RP_LRU);
+ else if (pieces.at(0).toLower() == "lfu")
+ cacheconf.set_replacement_policy(MachineConfigCache::RP_LFU);
+ else {
+ std::cerr << "Policy for " << which.toLocal8Bit().data() << " cache is incorrect." << std::endl;
+ exit(1);
+ }
+ pieces.removeFirst();
+ }
+ if (pieces.size() < 3) {
+ std::cerr << "Parameters for " << which.toLocal8Bit().data() << " cache incorrect (correct lru,4,2,2,wb)." << std::endl;
+ exit(1);
+ }
+ cacheconf.set_sets(pieces.at(0).toLong());
+ cacheconf.set_blocks(pieces.at(1).toLong());
+ cacheconf.set_associativity(pieces.at(2).toLong());
+ if (cacheconf.sets() == 0 || cacheconf.blocks() == 0 || cacheconf.associativity() == 0) {
+ std::cerr << "Parameters for " << which.toLocal8Bit().data() << " cache cannot have zero component." << std::endl;
+ exit(1);
+ }
+ if (pieces.size() > 3) {
+ if (pieces.at(3).toLower() == "wb")
+ cacheconf.set_write_policy(MachineConfigCache::WP_BACK);
+ else if (pieces.at(3).toLower() == "wt" || pieces.at(3).toLower() == "wtna")
+ cacheconf.set_write_policy(MachineConfigCache::WP_TROUGH_NOALLOC);
+ else if (pieces.at(3).toLower() == "wta")
+ cacheconf.set_write_policy(MachineConfigCache::WP_TROUGH_ALLOC);
+ else {
+ std::cerr << "Write policy for " << which.toLocal8Bit().data() << " cache is incorrect (correct wb/wt/wtna/wta)." << std::endl;
+ exit(1);
+ }
+ }
}
void configure_machine(QCommandLineParser &p, MachineConfig &cc) {
@@ -77,6 +131,9 @@ void configure_machine(QCommandLineParser &p, MachineConfig &cc) {
cc.set_delay_slot(!p.isSet("no-delay-slot"));
cc.set_pipelined(p.isSet("pipelined"));
+
+ configure_cache(*cc.access_cache_data(), p.values("d-cache"), "data");
+ configure_cache(*cc.access_cache_program(), p.values("i-cache"), "instruction");
}
void configure_tracer(QCommandLineParser &p, Tracer &tr) {
@@ -124,6 +181,8 @@ void configure_tracer(QCommandLineParser &p, Tracer &tr) {
void configure_reporter(QCommandLineParser &p, Reporter &r) {
if (p.isSet("dump-registers"))
r.regs();
+ if (p.isSet("dump-cache-stats"))
+ r.cache_stats();
QStringList fail = p.values("fail-match");
for (int i = 0; i < fail.size(); i++) {
diff --git a/qtmips_cli/reporter.cpp b/qtmips_cli/reporter.cpp
index a7db4a8..70803a8 100644
--- a/qtmips_cli/reporter.cpp
+++ b/qtmips_cli/reporter.cpp
@@ -51,6 +51,7 @@ Reporter::Reporter(QCoreApplication *app, QtMipsMachine *machine) : QObject() {
connect(machine->core(), SIGNAL(stop_on_exception_reached()), this, SLOT(machine_exception_reached()));
e_regs = false;
+ e_cache_stats = false;
e_fail = (enum FailReason)0;
}
@@ -58,6 +59,10 @@ void Reporter::regs() {
e_regs = true;
}
+void Reporter::cache_stats() {
+ e_cache_stats = true;
+}
+
void Reporter::expect_fail(enum FailReason reason) {
e_fail = (enum FailReason)(e_fail | reason);
}
@@ -166,6 +171,21 @@ void Reporter::report() {
else
cout << endl;
}
-
+ }
+ if (e_cache_stats) {
+ cout << "Cache statistics report:" << endl;
+ cout << "i-cache:reads:" << machine->cache_program()->memory_reads() << endl;
+ cout << "i-cache:hit:" << machine->cache_program()->hit() << endl;
+ cout << "i-cache:miss:" << machine->cache_program()->miss() << endl;
+ cout << "i-cache:hit-rate:" << machine->cache_program()->hit_rate() << endl;
+ cout << "i-cache:stalled-cycles:" << machine->cache_program()->stalled_cycles() << endl;
+ cout << "i-cache:improved-speed:" << machine->cache_program()->speed_improvement() << endl;
+ cout << "d-cache:reads:" << machine->cache_data()->memory_reads() << endl;
+ cout << "d-cache:writes:" << machine->cache_data()->memory_writes() << endl;
+ cout << "d-cache:hit:" << machine->cache_data()->hit() << endl;
+ cout << "d-cache:miss:" << machine->cache_data()->miss() << endl;
+ cout << "d-cache:hit-rate:" << machine->cache_data()->hit_rate() << endl;
+ cout << "d-cache:stalled-cycles:" << machine->cache_data()->stalled_cycles() << endl;
+ cout << "d-cache:improved-speed:" << machine->cache_data()->speed_improvement() << endl;
}
}
diff --git a/qtmips_cli/reporter.h b/qtmips_cli/reporter.h
index d5c67ed..2dfaea9 100644
--- a/qtmips_cli/reporter.h
+++ b/qtmips_cli/reporter.h
@@ -46,7 +46,7 @@ public:
Reporter(QCoreApplication *app, machine::QtMipsMachine *machine);
void regs(); // Report status of registers
- // TODO
+ void cache_stats();
enum FailReason {
FR_I = (1<<0), // Unsupported Instruction
@@ -68,6 +68,7 @@ private:
machine::QtMipsMachine *machine;
bool e_regs;
+ bool e_cache_stats;
enum FailReason e_fail;
void report();