adapt core_complex to use scv-tr (scc commit id a3cde47)
This commit is contained in:
		@@ -43,11 +43,6 @@
 | 
				
			|||||||
#include <tlm_utils/tlm_quantumkeeper.h>
 | 
					#include <tlm_utils/tlm_quantumkeeper.h>
 | 
				
			||||||
#include <util/range_lut.h>
 | 
					#include <util/range_lut.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class scv_tr_db;
 | 
					 | 
				
			||||||
class scv_tr_stream;
 | 
					 | 
				
			||||||
struct _scv_tr_generator_default_data;
 | 
					 | 
				
			||||||
template <class T_begin, class T_end> class scv_tr_generator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace sysc {
 | 
					namespace sysc {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class tlm_dmi_ext : public tlm::tlm_dmi {
 | 
					class tlm_dmi_ext : public tlm::tlm_dmi {
 | 
				
			||||||
@@ -62,6 +57,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace tgfs {
 | 
					namespace tgfs {
 | 
				
			||||||
class core_wrapper;
 | 
					class core_wrapper;
 | 
				
			||||||
 | 
					struct core_trace;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class core_complex : public sc_core::sc_module, public scc::traceable {
 | 
					class core_complex : public sc_core::sc_module, public scc::traceable {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
@@ -121,7 +117,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void trace(sc_core::sc_trace_file *trf) const override;
 | 
					    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:
 | 
					protected:
 | 
				
			||||||
    void before_end_of_elaboration() override;
 | 
					    void before_end_of_elaboration() override;
 | 
				
			||||||
@@ -138,16 +134,7 @@ protected:
 | 
				
			|||||||
    std::vector<uint8_t> write_buf;
 | 
					    std::vector<uint8_t> write_buf;
 | 
				
			||||||
    std::unique_ptr<core_wrapper> cpu;
 | 
					    std::unique_ptr<core_wrapper> cpu;
 | 
				
			||||||
    sc_core::sc_time curr_clk;
 | 
					    sc_core::sc_time curr_clk;
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					    std::unique_ptr<core_trace> trc;
 | 
				
			||||||
    //! 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<uint64_t, _scv_tr_generator_default_data> *fetch_tr_handle;
 | 
					 | 
				
			||||||
    scv_tr_handle tr_handle;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} /* namespace SiFive */
 | 
					} /* namespace SiFive */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 "scc/report.h"
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					#include <array>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STR(X) #X
 | 
					#define STR(X) #X
 | 
				
			||||||
#define CREATE_CORE(CN) \
 | 
					#define CREATE_CORE(CN) \
 | 
				
			||||||
if (type == STR(CN)) { std::tie(cpu, vm) = create_core<CN ## _plat_type>(backend, gdb_port, hart_id); } else
 | 
					if (type == STR(CN)) { std::tie(cpu, vm) = create_core<CN ## _plat_type>(backend, gdb_port, hart_id); } else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					#ifdef WITH_SCV
 | 
				
			||||||
#include <array>
 | 
					 | 
				
			||||||
#include <scv.h>
 | 
					#include <scv.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <scv-tr.h>
 | 
				
			||||||
 | 
					using namespace scv_tr;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace sysc {
 | 
					namespace sysc {
 | 
				
			||||||
@@ -100,7 +103,7 @@ public:
 | 
				
			|||||||
    sync_type needed_sync() const override { return PRE_SYNC; }
 | 
					    sync_type needed_sync() const override { return PRE_SYNC; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void disass_output(uint64_t pc, const std::string instr) override {
 | 
					    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;
 | 
					            std::stringstream s;
 | 
				
			||||||
            s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0')
 | 
					            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 << "]";
 | 
					              << 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)
 | 
					                << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
 | 
				
			||||||
                << std::setfill(' ') << std::left << instr << s.str();
 | 
					                << 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 {
 | 
					    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};
 | 
					    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)
 | 
					core_complex::core_complex(sc_module_name name)
 | 
				
			||||||
: sc_module(name)
 | 
					: sc_module(name)
 | 
				
			||||||
, read_lut(tlm_dmi_ext())
 | 
					, read_lut(tlm_dmi_ext())
 | 
				
			||||||
, write_lut(tlm_dmi_ext())
 | 
					, write_lut(tlm_dmi_ext())
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					, trc(new core_trace)
 | 
				
			||||||
, m_db(scv_tr_db::get_default_db())
 | 
					 | 
				
			||||||
, stream_handle(nullptr)
 | 
					 | 
				
			||||||
, instr_tr_handle(nullptr)
 | 
					 | 
				
			||||||
, fetch_tr_handle(nullptr)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SC_HAS_PROCESS(core_complex);// NOLINT
 | 
					    SC_HAS_PROCESS(core_complex);// NOLINT
 | 
				
			||||||
    initiator.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void {
 | 
					    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;
 | 
					    sensitive << timer_irq_i;
 | 
				
			||||||
    SC_METHOD(global_irq_cb);
 | 
					    SC_METHOD(global_irq_cb);
 | 
				
			||||||
    sensitive << global_irq_i;
 | 
					    sensitive << global_irq_i;
 | 
				
			||||||
 | 
					    trc->m_db=scv_tr_db::get_default_db();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
core_complex::~core_complex() = default;
 | 
					core_complex::~core_complex() = default;
 | 
				
			||||||
@@ -330,11 +338,7 @@ void core_complex::before_end_of_elaboration() {
 | 
				
			|||||||
    cpu = scc::make_unique<core_wrapper>(this);
 | 
					    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());
 | 
					    cpu->create_cpu(core_type.get_value(), backend.get_value(), gdb_server_port.get_value(), mhartid.get_value());
 | 
				
			||||||
    sc_assert(cpu->vm!=nullptr);
 | 
					    sc_assert(cpu->vm!=nullptr);
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					    cpu->vm->setDisassEnabled(enable_disass.get_value() || trc->m_db != nullptr);
 | 
				
			||||||
    cpu->vm->setDisassEnabled(enable_disass.get_value() || m_db != nullptr);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    cpu->vm->setDisassEnabled(enable_disass.get_value());
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void core_complex::start_of_simulation() {
 | 
					void core_complex::start_of_simulation() {
 | 
				
			||||||
@@ -348,27 +352,23 @@ void core_complex::start_of_simulation() {
 | 
				
			|||||||
                reset_address.set_value(start_addr.first);
 | 
					                reset_address.set_value(start_addr.first);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					    if (trc->m_db != nullptr && trc->stream_handle == nullptr) {
 | 
				
			||||||
    if (m_db != nullptr && stream_handle == nullptr) {
 | 
					 | 
				
			||||||
        string basename(this->name());
 | 
					        string basename(this->name());
 | 
				
			||||||
        stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
 | 
					        trc->stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", trc->m_db);
 | 
				
			||||||
        instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle);
 | 
					        trc->instr_tr_handle = new scv_tr_generator<>("execute", *trc->stream_handle);
 | 
				
			||||||
        fetch_tr_handle = new scv_tr_generator<uint64_t>("fetch", *stream_handle);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
 | 
					bool core_complex::disass_output(uint64_t pc, const std::string instr_str) {
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					    if (trc->m_db == nullptr) return false;
 | 
				
			||||||
    if (m_db == nullptr) return;
 | 
					    if (trc->tr_handle.is_active()) trc->tr_handle.end_transaction();
 | 
				
			||||||
    if (tr_handle.is_active()) tr_handle.end_transaction();
 | 
					    trc->tr_handle = trc->instr_tr_handle->begin_transaction();
 | 
				
			||||||
    tr_handle = instr_tr_handle->begin_transaction();
 | 
					    trc->tr_handle.record_attribute("PC", pc);
 | 
				
			||||||
    tr_handle.record_attribute("PC", pc);
 | 
					    trc->tr_handle.record_attribute("INSTR", instr_str);
 | 
				
			||||||
    tr_handle.record_attribute("INSTR", instr_str);
 | 
					    trc->tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
 | 
				
			||||||
    tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]);
 | 
					    trc->tr_handle.record_attribute("MSTATUS", cpu->get_state());
 | 
				
			||||||
    tr_handle.record_attribute("MSTATUS", cpu->get_state());
 | 
					    trc->tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000);
 | 
				
			||||||
    tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value() / 1000);
 | 
					    return true;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void core_complex::clk_cb() {
 | 
					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_data_length(length);
 | 
				
			||||||
        gp.set_streaming_width(length);
 | 
					        gp.set_streaming_width(length);
 | 
				
			||||||
        sc_time delay=quantum_keeper.get_local_time();
 | 
					        sc_time delay=quantum_keeper.get_local_time();
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					        if (trc->m_db != nullptr && trc->tr_handle.is_valid()) {
 | 
				
			||||||
        if (m_db != nullptr && tr_handle.is_valid()) {
 | 
					            if (is_fetch && trc->tr_handle.is_active()) {
 | 
				
			||||||
            if (is_fetch && tr_handle.is_active()) {
 | 
					                trc->tr_handle.end_transaction();
 | 
				
			||||||
                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);
 | 
					            gp.set_extension(preExt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        initiator->b_transport(gp, delay);
 | 
					        initiator->b_transport(gp, delay);
 | 
				
			||||||
        SCCTRACE(this->name()) << "read_mem(0x" << std::hex << addr << ") : " << data;
 | 
					        SCCTRACE(this->name()) << "read_mem(0x" << std::hex << addr << ") : " << data;
 | 
				
			||||||
        if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
 | 
					        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_data_length(length);
 | 
				
			||||||
        gp.set_streaming_width(length);
 | 
					        gp.set_streaming_width(length);
 | 
				
			||||||
        sc_time delay=quantum_keeper.get_local_time();
 | 
					        sc_time delay=quantum_keeper.get_local_time();
 | 
				
			||||||
#ifdef WITH_SCV
 | 
					        if (trc->m_db != nullptr && trc->tr_handle.is_valid()) {
 | 
				
			||||||
        if (m_db != nullptr && tr_handle.is_valid()) {
 | 
					            auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
 | 
				
			||||||
            auto preExt = new tlm::scc::scv::tlm_recording_extension(tr_handle, this);
 | 
					 | 
				
			||||||
            gp.set_extension(preExt);
 | 
					            gp.set_extension(preExt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        initiator->b_transport(gp, delay);
 | 
					        initiator->b_transport(gp, delay);
 | 
				
			||||||
        quantum_keeper.set(delay);
 | 
					        quantum_keeper.set(delay);
 | 
				
			||||||
        SCCTRACE() << "write_mem(0x" << std::hex << addr << ") : " << data;
 | 
					        SCCTRACE() << "write_mem(0x" << std::hex << addr << ") : " << data;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user