From 15f46a87db8fdbd154f710b53847bb2abfbcfebd Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 27 Jul 2021 09:38:05 +0200 Subject: [PATCH] adapt core_complex to use scv-tr (scc commit id a3cde47) --- incl/sysc/core_complex.h | 19 ++-------- src/sysc/core_complex.cpp | 78 +++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 57 deletions(-) diff --git a/incl/sysc/core_complex.h b/incl/sysc/core_complex.h index 64d2ff3..94029e5 100644 --- a/incl/sysc/core_complex.h +++ b/incl/sysc/core_complex.h @@ -43,11 +43,6 @@ #include #include -class scv_tr_db; -class scv_tr_stream; -struct _scv_tr_generator_default_data; -template class scv_tr_generator; - namespace sysc { class tlm_dmi_ext : public tlm::tlm_dmi { @@ -62,6 +57,7 @@ public: namespace tgfs { class core_wrapper; +struct core_trace; class core_complex : public sc_core::sc_module, public scc::traceable { public: @@ -121,7 +117,7 @@ public: void trace(sc_core::sc_trace_file *trf) const override; - void disass_output(uint64_t pc, const std::string instr); + bool disass_output(uint64_t pc, const std::string instr); protected: void before_end_of_elaboration() override; @@ -138,16 +134,7 @@ protected: std::vector write_buf; std::unique_ptr cpu; sc_core::sc_time curr_clk; -#ifdef WITH_SCV - //! transaction recording database - scv_tr_db *m_db; - //! blocking transaction recording stream handle - scv_tr_stream *stream_handle; - //! transaction generator handle for blocking transactions - scv_tr_generator<_scv_tr_generator_default_data, _scv_tr_generator_default_data> *instr_tr_handle; - scv_tr_generator *fetch_tr_handle; - scv_tr_handle tr_handle; -#endif + std::unique_ptr trc; }; } /* namespace SiFive */ diff --git a/src/sysc/core_complex.cpp b/src/sysc/core_complex.cpp index 4bbc3a5..7775d34 100644 --- a/src/sysc/core_complex.cpp +++ b/src/sysc/core_complex.cpp @@ -53,14 +53,17 @@ using tgc_d_plat_type = iss::arch::riscv_hart_mu_p #include +#include #define STR(X) #X #define CREATE_CORE(CN) \ if (type == STR(CN)) { std::tie(cpu, vm) = create_core(backend, gdb_port, hart_id); } else #ifdef WITH_SCV -#include #include +#else +#include +using namespace scv_tr; #endif namespace sysc { @@ -100,7 +103,7 @@ public: sync_type needed_sync() const override { return PRE_SYNC; } void disass_output(uint64_t pc, const std::string instr) override { - if (INFO <= Log>::reporting_level() && Output2FILE::stream()) { + if (!owner->disass_output(pc, instr) && INFO <= Log>::reporting_level() && Output2FILE::stream()) { std::stringstream s; s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0') << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; @@ -108,7 +111,6 @@ public: << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40) << std::setfill(' ') << std::left << instr << s.str(); } - owner->disass_output(pc, instr); }; status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override { @@ -285,16 +287,21 @@ public: iss::debugger::target_adapter_if *tgt_adapter{nullptr}; }; +struct core_trace { + //! transaction recording database + scv_tr_db *m_db{nullptr}; + //! blocking transaction recording stream handle + scv_tr_stream *stream_handle{nullptr}; + //! transaction generator handle for blocking transactions + scv_tr_generator<_scv_tr_generator_default_data, _scv_tr_generator_default_data> *instr_tr_handle{nullptr}; + scv_tr_handle tr_handle; +}; + core_complex::core_complex(sc_module_name name) : sc_module(name) , read_lut(tlm_dmi_ext()) , write_lut(tlm_dmi_ext()) -#ifdef WITH_SCV -, m_db(scv_tr_db::get_default_db()) -, stream_handle(nullptr) -, instr_tr_handle(nullptr) -, fetch_tr_handle(nullptr) -#endif +, trc(new core_trace) { SC_HAS_PROCESS(core_complex);// NOLINT initiator.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { @@ -319,6 +326,7 @@ core_complex::core_complex(sc_module_name name) sensitive << timer_irq_i; SC_METHOD(global_irq_cb); sensitive << global_irq_i; + trc->m_db=scv_tr_db::get_default_db(); } core_complex::~core_complex() = default; @@ -330,11 +338,7 @@ void core_complex::before_end_of_elaboration() { cpu = scc::make_unique(this); cpu->create_cpu(core_type.get_value(), backend.get_value(), gdb_server_port.get_value(), mhartid.get_value()); sc_assert(cpu->vm!=nullptr); -#ifdef WITH_SCV - cpu->vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr); -#else - cpu->vm->setDisassEnabled(enable_disass.get_value()); -#endif + cpu->vm->setDisassEnabled(enable_disass.get_value() || trc->m_db != nullptr); } void core_complex::start_of_simulation() { @@ -348,27 +352,23 @@ void core_complex::start_of_simulation() { reset_address.set_value(start_addr.first); } } -#ifdef WITH_SCV - if (m_db != nullptr && stream_handle == nullptr) { + if (trc->m_db != nullptr && trc->stream_handle == nullptr) { string basename(this->name()); - stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db); - instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle); - fetch_tr_handle = new scv_tr_generator("fetch", *stream_handle); + trc->stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", trc->m_db); + trc->instr_tr_handle = new scv_tr_generator<>("execute", *trc->stream_handle); } -#endif } -void core_complex::disass_output(uint64_t pc, const std::string instr_str) { -#ifdef WITH_SCV - if (m_db == nullptr) return; - if (tr_handle.is_active()) tr_handle.end_transaction(); - tr_handle = instr_tr_handle->begin_transaction(); - tr_handle.record_attribute("PC", pc); - tr_handle.record_attribute("INSTR", instr_str); - tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]); - tr_handle.record_attribute("MSTATUS", cpu->get_state()); - tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000); -#endif +bool core_complex::disass_output(uint64_t pc, const std::string instr_str) { + if (trc->m_db == nullptr) return false; + if (trc->tr_handle.is_active()) trc->tr_handle.end_transaction(); + trc->tr_handle = trc->instr_tr_handle->begin_transaction(); + trc->tr_handle.record_attribute("PC", pc); + trc->tr_handle.record_attribute("INSTR", instr_str); + trc->tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]); + trc->tr_handle.record_attribute("MSTATUS", cpu->get_state()); + trc->tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000); + return true; } void core_complex::clk_cb() { @@ -418,15 +418,13 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, gp.set_data_length(length); gp.set_streaming_width(length); sc_time delay=quantum_keeper.get_local_time(); -#ifdef WITH_SCV - if (m_db != nullptr && tr_handle.is_valid()) { - if (is_fetch && tr_handle.is_active()) { - tr_handle.end_transaction(); + if (trc->m_db != nullptr && trc->tr_handle.is_valid()) { + if (is_fetch && trc->tr_handle.is_active()) { + trc->tr_handle.end_transaction(); } - auto preExt = new tlm::scc::scv::tlm_recording_extension(tr_handle, this); + auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this); gp.set_extension(preExt); } -#endif initiator->b_transport(gp, delay); SCCTRACE(this->name()) << "read_mem(0x" << std::hex << addr << ") : " << data; if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { @@ -467,12 +465,10 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons gp.set_data_length(length); gp.set_streaming_width(length); sc_time delay=quantum_keeper.get_local_time(); -#ifdef WITH_SCV - if (m_db != nullptr && tr_handle.is_valid()) { - auto preExt = new tlm::scc::scv::tlm_recording_extension(tr_handle, this); + if (trc->m_db != nullptr && trc->tr_handle.is_valid()) { + auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this); gp.set_extension(preExt); } -#endif initiator->b_transport(gp, delay); quantum_keeper.set(delay); SCCTRACE() << "write_mem(0x" << std::hex << addr << ") : " << data;