Compare commits
	
		
			8 Commits
		
	
	
		
			68b5697c8f
			...
			feature/re
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 58311b37db | |||
| ad8dc09bee | |||
| 2bba5645c3 | |||
| bf0a5a80de | |||
| b37ef973de | |||
| 4c363f4073 | |||
| b8fa5fbbda | |||
| ac86f14a54 | 
| @@ -35,7 +35,7 @@ FILE(GLOB TGC_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/vm/interp/vm_*.cpp) | ||||
| set(LIB_SOURCES  | ||||
|     src/vm/fp_functions.cpp | ||||
|     src/plugin/instruction_count.cpp | ||||
|     src/plugin/cov.cpp | ||||
|     src/plugin/pctrace.cpp | ||||
|      | ||||
|     ${TGC_SOURCES} | ||||
|     ${TGC_VM_SOURCES} | ||||
|   | ||||
| @@ -169,7 +169,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { | ||||
|         }}%> | ||||
|         uint32_t trap_state = 0, pending_trap = 0; | ||||
|         uint64_t icount = 0; | ||||
|         uint64_t cycle = 0; | ||||
|         uint64_t instret = 0; | ||||
|         uint32_t last_branch; | ||||
|     } reg; | ||||
|   | ||||
| @@ -237,6 +237,10 @@ protected: | ||||
|  | ||||
|         uint64_t get_next_pc() override { return arch.get_next_pc(); }; | ||||
|  | ||||
|         uint64_t get_instr_count() { return arch.reg.icount; } | ||||
|  | ||||
|         uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } | ||||
|  | ||||
|         void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; }; | ||||
|  | ||||
|         riscv_hart_m_p<BASE, FEAT> &arch; | ||||
|   | ||||
| @@ -340,6 +340,10 @@ protected: | ||||
|  | ||||
|         virtual uint64_t get_next_pc() { return arch.get_next_pc(); }; | ||||
|  | ||||
|         uint64_t get_instr_count() { return arch.reg.icount; } | ||||
|  | ||||
|         uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } | ||||
|  | ||||
|         virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; | ||||
|  | ||||
|         riscv_hart_msu_vp<BASE> &arch; | ||||
|   | ||||
| @@ -252,6 +252,10 @@ protected: | ||||
|  | ||||
|         virtual uint64_t get_next_pc() { return arch.get_next_pc(); }; | ||||
|  | ||||
|         uint64_t get_instr_count() { return arch.reg.icount; } | ||||
|  | ||||
|         uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; } | ||||
|  | ||||
|         virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; }; | ||||
|  | ||||
|         riscv_hart_mu_p<BASE, FEAT> &arch; | ||||
|   | ||||
| @@ -258,7 +258,6 @@ struct tgc_c: public arch_if { | ||||
|         uint32_t DPC = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0; | ||||
|         uint64_t icount = 0; | ||||
|         uint64_t cycle = 0; | ||||
|         uint64_t instret = 0; | ||||
|         uint32_t last_branch; | ||||
|     } reg; | ||||
|   | ||||
| @@ -52,6 +52,18 @@ class cov : public iss::vm_plugin { | ||||
|         size_t not_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: | ||||
| 
 | ||||
| @@ -59,7 +71,7 @@ public: | ||||
| 
 | ||||
|     cov(const cov &&) = delete; | ||||
| 
 | ||||
|     cov(); | ||||
|     cov(std::string const &); | ||||
| 
 | ||||
|     virtual ~cov(); | ||||
| 
 | ||||
| @@ -75,8 +87,11 @@ public: | ||||
| 
 | ||||
| private: | ||||
|     iss::instrumentation_if *instr_if  {nullptr}; | ||||
|     int counter {0}; | ||||
|     std::ofstream output; | ||||
|     std::string filename; | ||||
|     std::vector<instr_desc> delays; | ||||
|     bool jumped, first; | ||||
| 
 | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -44,6 +44,11 @@ using tgc_c_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c>; | ||||
| #include "iss/arch/tgc_b.h" | ||||
| using tgc_b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_b>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_C_XRB_NN | ||||
| #include "iss/arch/riscv_hart_m_p.h" | ||||
| #include "iss/arch/tgc_c_xrb_nn.h" | ||||
| using tgc_c_xrb_nn_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc_c_xrb_nn>; | ||||
| #endif | ||||
| #ifdef CORE_TGC_D | ||||
| #include "iss/arch/riscv_hart_mu_p.h" | ||||
| #include "iss/arch/tgc_d.h" | ||||
| @@ -152,6 +157,12 @@ int main(int argc, char *argv[]) { | ||||
|                 iss::create_cpu<tgc_b_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); | ||||
|         } else | ||||
| #endif | ||||
| #ifdef CORE_TGC_C_XRB_NN | ||||
|         if (isa_opt == "tgc_c_xrb_nn") { | ||||
|             std::tie(cpu, vm) = | ||||
|                 iss::create_cpu<tgc_c_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>()); | ||||
|         } else | ||||
| #endif | ||||
| #ifdef CORE_TGC_D | ||||
|         if (isa_opt == "tgc_d") { | ||||
|             std::tie(cpu, vm) = | ||||
|   | ||||
| @@ -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>()}); | ||||
|                             } 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; | ||||
| @@ -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"); | ||||
|     auto entry = delays[instr_info.instr_id]; | ||||
|     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); | ||||
|     else if (entry.not_taken > 1) | ||||
|         arch_instr->set_curr_instr_cycles(entry.not_taken); | ||||
|   | ||||
							
								
								
									
										133
									
								
								src/plugin/pctrace.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/plugin/pctrace.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| #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"); | ||||
|     jumped = false; | ||||
|     first = true; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| inline string formatPC(uint64_t pc) { | ||||
|     stringstream stream; | ||||
|     stream << "0x" << std::hex << pc; | ||||
|     return stream.str(); | ||||
| } | ||||
|  | ||||
| void iss::plugin::cov::callback(instr_info_t iinfo, const exec_info& einfo) { | ||||
| //    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; | ||||
| // | ||||
| //    if (first){ | ||||
| //        output << formatPC(instr_if->get_pc()) << "," << delay; | ||||
| //        first = false; | ||||
| //    } | ||||
| //    if(instr_if->get_next_pc()-instr_if->get_pc() != delays[iinfo.instr_id].size/8){ | ||||
| //        //The goal is to keep the output in start-target pairs, so after a jump the target address needs to get written | ||||
| //        //to the output. If the target happens to also be a start, we keep the pairing by adding a 0-delay entry. | ||||
| //        if (jumped) | ||||
| //            output <<"\n" <<formatPC(instr_if->get_pc()) << "," << 0; | ||||
| //        output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; | ||||
| //        jumped = true; | ||||
| //    } | ||||
| //    else{ | ||||
| //        if (jumped){ | ||||
| //            output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; | ||||
| //            jumped = false; | ||||
| //        } | ||||
| //        else if(delay!=1){ | ||||
| //            output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; | ||||
| //            output <<"\n" << formatPC(instr_if->get_pc()) << "," << 0; | ||||
| //        } | ||||
| // | ||||
| //    } | ||||
|  | ||||
| //source code for the full output | ||||
|     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 <iss/plugin/cycle_estimate.h> | ||||
| #include <iss/plugin/instruction_count.h> | ||||
| #include <iss/plugin/cov.h> | ||||
| #include <iss/plugin/pctrace.h> | ||||
|  | ||||
| // clang-format on | ||||
|  | ||||
| @@ -426,8 +426,8 @@ void core_complex::before_end_of_elaboration() { | ||||
|                 auto *plugin = new iss::plugin::cycle_estimate(filename); | ||||
|                 cpu->vm->register_plugin(*plugin); | ||||
|                 plugin_list.push_back(plugin); | ||||
|             } else if (plugin_name == "cov") { | ||||
|                 auto *plugin = new iss::plugin::cov(); | ||||
|             } else if (plugin_name == "pctrace") { | ||||
|                 auto *plugin = new iss::plugin::cov(filename); | ||||
|                 cpu->vm->register_plugin(*plugin); | ||||
|                 plugin_list.push_back(plugin); | ||||
|             } else { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user