adapt core_complex to use scv-tr (scc commit id a3cde47)
This commit is contained in:
		| @@ -53,14 +53,17 @@ using tgc_d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc_d, iss::arch:: | ||||
| #include "scc/report.h" | ||||
| #include <iostream> | ||||
| #include <sstream> | ||||
| #include <array> | ||||
|  | ||||
| #define STR(X) #X | ||||
| #define CREATE_CORE(CN) \ | ||||
| if (type == STR(CN)) { std::tie(cpu, vm) = create_core<CN ## _plat_type>(backend, gdb_port, hart_id); } else | ||||
|  | ||||
| #ifdef WITH_SCV | ||||
| #include <array> | ||||
| #include <scv.h> | ||||
| #else | ||||
| #include <scv-tr.h> | ||||
| 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<Output2FILE<disass>>::reporting_level() && Output2FILE<disass>::stream()) { | ||||
|         if (!owner->disass_output(pc, instr) && INFO <= Log<Output2FILE<disass>>::reporting_level() && Output2FILE<disass>::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<core_wrapper>(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<uint64_t>("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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user