adds additional functionality by fetching delay information

This commit is contained in:
Eyck-Alexander Jentzsch 2022-02-11 11:28:00 +01:00
parent b8fa5fbbda
commit 4c363f4073
6 changed files with 119 additions and 40 deletions

View File

@ -35,7 +35,7 @@ FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp)
set(LIB_SOURCES set(LIB_SOURCES
src/vm/fp_functions.cpp src/vm/fp_functions.cpp
src/plugin/instruction_count.cpp src/plugin/instruction_count.cpp
src/plugin/cov.cpp src/plugin/pctrace.cpp
${TGC_SOURCES} ${TGC_SOURCES}
${TGC_VM_SOURCES} ${TGC_VM_SOURCES}

View File

@ -52,6 +52,18 @@ class cov : public iss::vm_plugin {
size_t not_taken_delay; size_t not_taken_delay;
size_t taken_delay; size_t taken_delay;
}; };
BEGIN_BF_DECL(instr_desc, uint32_t)
BF_FIELD(taken, 24, 8)
BF_FIELD(not_taken, 16, 8)
BF_FIELD(is_branch, 8, 8)
BF_FIELD(size, 0, 8)
instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken, bool branch): instr_desc() {
this->size=size;
this->taken=taken;
this->not_taken=not_taken;
this->is_branch=branch;
}
END_BF_DECL();
public: public:
@ -59,7 +71,7 @@ public:
cov(const cov &&) = delete; cov(const cov &&) = delete;
cov(); cov(std::string const &);
virtual ~cov(); virtual ~cov();
@ -75,8 +87,10 @@ public:
private: private:
iss::instrumentation_if *instr_if {nullptr}; iss::instrumentation_if *instr_if {nullptr};
int counter {0};
std::ofstream output; std::ofstream output;
std::string filename;
std::vector<instr_desc> delays;
}; };
} }
} }

View File

@ -1,32 +0,0 @@
#include <iss/plugin/cov.h>
#include <iss/arch_if.h>
#include <iostream>
iss::plugin::cov::cov() {
std::cout << "Entering Constructor"<<std::endl;
output.open("output.txt");
}
iss::plugin::cov::~cov() {
std::cout << "Entering Destructor"<<std::endl;
output.close();
}
bool iss::plugin::cov::registration(const char *const version, vm_if& vm) {
instr_if = vm.get_arch()->get_instrumentation_if();
return true;
}
void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info&) {
// if((instr_if->get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){
// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <<std::endl;
// counter = 0;
// }else {
// counter++;
// }
output<<std::hex << instr_if->get_pc() << std::endl;
}

View File

@ -85,7 +85,7 @@ bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if&
delays.push_back(instr_desc{size.Get<unsigned>(), d, d, branch.Get<bool>()}); delays.push_back(instr_desc{size.Get<unsigned>(), d, d, branch.Get<bool>()});
} else } else
throw runtime_error("JSON parse error"); throw runtime_error("JSON parse error");
} }
} else { } else {
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl; LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl;
return false; return false;
@ -111,7 +111,7 @@ void iss::plugin::cycle_estimate::callback(instr_info_t instr_info, exec_info co
assert(arch_instr && "No instrumentation interface available but callback executed"); assert(arch_instr && "No instrumentation interface available but callback executed");
auto entry = delays[instr_info.instr_id]; auto entry = delays[instr_info.instr_id];
bool taken = exc_info.branch_taken; bool taken = exc_info.branch_taken;
if (exc_info.branch_taken && entry.taken > 1) if (exc_info.branch_taken && (entry.taken > 1))
arch_instr->set_curr_instr_cycles(entry.taken); arch_instr->set_curr_instr_cycles(entry.taken);
else if (entry.not_taken > 1) else if (entry.not_taken > 1)
arch_instr->set_curr_instr_cycles(entry.not_taken); arch_instr->set_curr_instr_cycles(entry.not_taken);

97
src/plugin/pctrace.cpp Normal file
View File

@ -0,0 +1,97 @@
#include <iss/arch_if.h>
#include <iss/plugin/pctrace.h>
#include <util/logging.h>
#include <rapidjson/document.h>
#include <rapidjson/istreamwrapper.h>
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <rapidjson/ostreamwrapper.h>
#include <rapidjson/error/en.h>
#include <fstream>
#include <iostream>
using namespace rapidjson;
using namespace std;
iss::plugin::cov::cov(std::string const &filename)
: instr_if(nullptr)
, filename(filename)
{
output.open("output.trc");
}
iss::plugin::cov::~cov() {
output.close();
}
bool iss::plugin::cov::registration(const char *const version, vm_if& vm) {
instr_if = vm.get_arch()->get_instrumentation_if();
if(!instr_if) return false;
const string core_name = instr_if->core_type_name();
if (filename.length() > 0) {
ifstream is(filename);
if (is.is_open()) {
try {
IStreamWrapper isw(is);
Document d;
ParseResult ok = d.ParseStream(isw);
if(ok) {
Value& val = d[core_name.c_str()];
if(val.IsArray()){
delays.reserve(val.Size());
for (auto it = val.Begin(); it != val.End(); ++it) {
auto& name = (*it)["name"];
auto& size = (*it)["size"];
auto& delay = (*it)["delay"];
auto& branch = (*it)["branch"];
if(delay.IsArray()) {
auto dt = delay[0].Get<unsigned>();
auto dnt = delay[1].Get<unsigned>();
delays.push_back(instr_desc{size.Get<unsigned>(), dt, dnt, branch.Get<bool>()});
} else if(delay.Is<unsigned>()) {
auto d = delay.Get<unsigned>();
delays.push_back(instr_desc{size.Get<unsigned>(), d, d, branch.Get<bool>()});
} else
throw runtime_error("JSON parse error");
}
} else {
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl;
return false;
}
} else {
LOG(ERR)<<"plugin cycle_estimate: could not parse in JSON file at "<< ok.Offset()<<": "<<GetParseError_En(ok.Code())<<endl;
return false;
}
} catch (runtime_error &e) {
LOG(ERR) << "Could not parse input file " << filename << ", reason: " << e.what();
return false;
}
} else {
LOG(ERR) << "Could not open input file " << filename;
return false;
}
}
return true;
}
void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info& einfo) {
// if((instr_if->get_next_pc() - instr_if->get_pc() != 4) ||( instr_if->get_next_pc() - instr_if->get_pc() != 2)){
// std::cout << "jump from " << std::hex << instr_if->get_pc() << " to " << instr_if->get_next_pc()<< " after " << std::dec << counter <<" linear instructions" <<std::endl;
// counter = 0;
// }else {
// counter++;
// }
auto delay = 0;
auto entry = delays[iinfo.instr_id];
bool taken = einfo.branch_taken;
if (einfo.branch_taken)
delay = entry.taken;
else
delay = entry.not_taken;
output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay << "\n";
}

View File

@ -69,7 +69,7 @@ using tgc_d_xrb_nn_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d_xrb_n
#include <array> #include <array>
#include <iss/plugin/cycle_estimate.h> #include <iss/plugin/cycle_estimate.h>
#include <iss/plugin/instruction_count.h> #include <iss/plugin/instruction_count.h>
#include <iss/plugin/cov.h> #include <iss/plugin/pctrace.h>
// clang-format on // clang-format on
@ -426,8 +426,8 @@ void core_complex::before_end_of_elaboration() {
auto *plugin = new iss::plugin::cycle_estimate(filename); auto *plugin = new iss::plugin::cycle_estimate(filename);
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else if (plugin_name == "cov") { } else if (plugin_name == "pctrace") {
auto *plugin = new iss::plugin::cov(); auto *plugin = new iss::plugin::cov(filename);
cpu->vm->register_plugin(*plugin); cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin); plugin_list.push_back(plugin);
} else { } else {