adds additional functionality by fetching delay information
This commit is contained in:
		@@ -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}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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
									
								
							
							
						
						
									
										97
									
								
								src/plugin/pctrace.cpp
									
									
									
									
									
										Normal 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";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -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 {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user