Skip to content

Commit dab4c69

Browse files
committed
refactors instrcution tracing/disass to be mt save
1 parent 8a528fc commit dab4c69

File tree

6 files changed

+146
-56
lines changed

6 files changed

+146
-56
lines changed

src/sysc/core2sc_adapter.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
7575
this->register_csr_rd = util::delegate<void(unsigned, rd_csr_f)>::from<this_class, &this_class::_register_csr_rd>(this);
7676
this->register_csr_wr = util::delegate<void(unsigned, wr_csr_f)>::from<this_class, &this_class::_register_csr_wr>(this);
7777

78+
disass_delegate.log = util::delegate<util::LoggerDelegate::delegate_fn>(*this, &core2sc_adapter::disass);
79+
disass_delegate.level = logging::log_level::INFO;
80+
this->disasslogger.set_logger(disass_delegate);
7881
log_delegate.log = util::delegate<util::LoggerDelegate::delegate_fn>(*this, &core2sc_adapter::log);
7982
log_delegate.level = static_cast<logging::log_level>(scc::get_logging_level());
80-
this->disasslogger.set_logger(log_delegate);
8183
this->isslogger.set_logger(log_delegate);
8284
}
8385

@@ -95,6 +97,10 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
9597

9698
virtual ~core2sc_adapter() {}
9799

100+
void enable_disass(bool enable) override {
101+
this->disasslogger.set_log_level(enable ? logging::log_level::DEBUG : logging::log_level::INFO);
102+
}
103+
98104
void register_unknown_instr_handler(util::delegate<iss::arch_if::unknown_instr_cb_t> handler) override {
99105
PLAT::unknown_instr_cb = handler;
100106
};
@@ -150,11 +156,14 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
150156
}
151157
}
152158

159+
void disass(logging::log_level lvl, std::string const& msg_type, std::string const& msg, unsigned line, char const* file) {
160+
::scc ::ScLogger<::sc_core ::SC_INFO>(file, line, sc_core ::SC_HIGH).type(owner->hier_name()).get()
161+
<< "[" << msg_type << "] " << msg;
162+
}
163+
153164
void disass_output(uint64_t pc, std::string const& instr) {
154-
static constexpr std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
155-
if(!owner->disass_output(pc, instr)) {
156-
PLAT::disass_output(pc, instr);
157-
}
165+
owner->disass_output(pc, instr);
166+
PLAT::disass_output(pc, instr);
158167
};
159168

160169
iss::mem::memory_if get_mem_if() {
@@ -335,6 +344,7 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
335344

336345
sysc::riscv::core_complex_if* const owner{nullptr};
337346
util::LoggerDelegate log_delegate;
347+
util::LoggerDelegate disass_delegate;
338348
sc_core::sc_event wfi_evt;
339349
unsigned to_host_wr_cnt = 0;
340350
bool first{true};

src/sysc/core_complex.cpp

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,6 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::i
236236
for(auto pin : local_irq_i)
237237
sensitive << pin;
238238
#endif
239-
trc.m_db = scv_tr_db::get_default_db();
240239

241240
SC_METHOD(forward);
242241
#ifndef CWR_SYSTEMC
@@ -275,10 +274,11 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::b
275274
}
276275
#endif
277276
sc_assert(vm);
277+
auto instr_trace = GET_PROP_VALUE(enable_instr_trace) ? trc.init(this->name()) : false;
278278
auto disass = GET_PROP_VALUE(enable_disass);
279-
if(disass && trc.m_db)
280-
SCCINFO(SCMOD) << "Disasssembly will only be in transaction trace database!";
281-
vm->setDisassEnabled(disass || trc.m_db != nullptr);
279+
if(disass)
280+
core->enable_disass(true);
281+
vm->setDisassEnabled(disass || instr_trace);
282282
if(GET_PROP_VALUE(plugins).length()) {
283283
auto p = util::split(GET_PROP_VALUE(plugins), ';');
284284
for(std::string const& opt_val : p) {
@@ -314,7 +314,6 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::b
314314
}
315315

316316
template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::start_of_simulation() {
317-
// quantum_keeper.reset();
318317
if(GET_PROP_VALUE(elf_file).size() > 0) {
319318
auto file_names = util::split(GET_PROP_VALUE(elf_file), ',');
320319
for(auto& s : file_names) {
@@ -332,25 +331,10 @@ template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::s
332331
}
333332
}
334333
}
335-
if(trc.m_db != nullptr && trc.stream_handle == nullptr) {
336-
string basename(this->name());
337-
trc.stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", trc.m_db);
338-
trc.instr_tr_handle = new scv_tr_generator<>("execute", *trc.stream_handle);
339-
}
340334
}
341335

342-
template <unsigned int BUSWIDTH, typename QK> bool core_complex<BUSWIDTH, QK>::disass_output(uint64_t pc, std::string const& instr_str) {
343-
if(trc.m_db == nullptr)
344-
return false;
345-
if(trc.tr_handle.is_active())
346-
trc.tr_handle.end_transaction();
347-
trc.tr_handle = trc.instr_tr_handle->begin_transaction();
348-
trc.tr_handle.record_attribute("PC", pc);
349-
trc.tr_handle.record_attribute("INSTR", instr_str);
350-
trc.tr_handle.record_attribute("MODE", lvl[core->get_mode()]);
351-
trc.tr_handle.record_attribute("MSTATUS", core->get_state());
352-
trc.tr_handle.record_attribute("LTIME_START", quantum_keeper.get_local_absolute_time().value() / 1000);
353-
return true;
336+
template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::disass_output(uint64_t pc, std::string const& instr_str) {
337+
trc.disass_output(pc, instr_str, lvl[core->get_mode()], core->get_state());
354338
}
355339

356340
template <unsigned int BUSWIDTH, typename QK> void core_complex<BUSWIDTH, QK>::forward() {
@@ -491,10 +475,6 @@ bool core_complex<BUSWIDTH, QK>::write_mem(uint64_t addr, unsigned length, const
491475
gp.set_data_length(length);
492476
gp.set_streaming_width(length);
493477
sc_time delay = quantum_keeper.get_local_time();
494-
if(trc.m_db != nullptr && trc.tr_handle.is_valid()) {
495-
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc.tr_handle, this);
496-
gp.set_extension(preExt);
497-
}
498478
auto pre_delay = delay;
499479
exec_b_transport(gp, delay);
500480
if(pre_delay > delay)

src/sysc/core_complex.h

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#define _SYSC_CORE_COMPLEX_H_
3535

3636
#include "core_complex_if.h"
37+
#include "instr_recorder.h"
3738
#include "sc2core_if.h"
3839
#include <iss/debugger/target_adapter_if.h>
3940
#include <iss/debugger_if.h>
@@ -108,6 +109,8 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co
108109

109110
cci::cci_param<bool> enable_disass{"enable_disass", false};
110111

112+
cci::cci_param<bool> enable_instr_trace{"enable_instr_trace", true};
113+
111114
cci::cci_param<bool> disable_dmi{"disable_dmi", false};
112115

113116
cci::cci_param<uint64_t> reset_address{"reset_address", 0ULL};
@@ -204,7 +207,7 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co
204207

205208
void trace(sc_core::sc_trace_file* trf) const override;
206209

207-
bool disass_output(uint64_t pc, std::string const& instr) override;
210+
void disass_output(uint64_t pc, std::string const& instr) override;
208211

209212
void set_clock_period(sc_core::sc_time period);
210213

@@ -235,13 +238,7 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co
235238
typename std::enable_if<std::is_same<U, tlm::scc::quantumkeeper_mt>::value>::type
236239
exec_b_transport(tlm::tlm_generic_payload& gp, sc_core::sc_time& delay, bool is_fetch = false) {
237240
quantum_keeper.execute_on_sysc([this, &gp, &delay, is_fetch]() {
238-
if(trc.m_db != nullptr && trc.tr_handle.is_valid()) {
239-
if(is_fetch && trc.tr_handle.is_active()) {
240-
trc.tr_handle.end_transaction();
241-
}
242-
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc.tr_handle, this);
243-
gp.set_extension(preExt);
244-
}
241+
gp.set_extension(trc.get_recording_extension(is_fetch));
245242
dbus->b_transport(gp, delay);
246243
});
247244
}
@@ -264,13 +261,7 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co
264261
template <typename U = QK>
265262
typename std::enable_if<std::is_same<U, tlm::scc::quantumkeeper>::value>::type
266263
exec_b_transport(tlm::tlm_generic_payload& gp, sc_core::sc_time& delay, bool is_fetch = false) {
267-
if(trc.m_db != nullptr && trc.tr_handle.is_valid()) {
268-
if(is_fetch && trc.tr_handle.is_active()) {
269-
trc.tr_handle.end_transaction();
270-
}
271-
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc.tr_handle, this);
272-
gp.set_extension(preExt);
273-
}
264+
gp.set_extension(trc.get_recording_extension(is_fetch));
274265
dbus->b_transport(gp, delay);
275266
}
276267
template <typename U = QK>
@@ -295,15 +286,7 @@ class core_complex : public sc_core::sc_module, public scc::traceable, public co
295286
std::unique_ptr<sc2core_if> core;
296287
std::unique_ptr<iss::vm_if> vm;
297288
iss::debugger::target_adapter_if* tgt_adapter{nullptr};
298-
struct {
299-
//! transaction recording database
300-
SCVNS scv_tr_db* m_db{nullptr};
301-
//! blocking transaction recording stream handle
302-
SCVNS scv_tr_stream* stream_handle{nullptr};
303-
//! transaction generator handle for blocking transactions
304-
SCVNS scv_tr_generator<SCVNS _scv_tr_generator_default_data, SCVNS _scv_tr_generator_default_data>* instr_tr_handle{nullptr};
305-
SCVNS scv_tr_handle tr_handle;
306-
} trc;
289+
instr_recorder<QK> trc{quantum_keeper};
307290
std::unique_ptr<scc::tick2time> t2t;
308291

309292
private:

src/sysc/core_complex_if.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct core_complex_if {
4949

5050
virtual bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t* const data) = 0;
5151

52-
virtual bool disass_output(uint64_t pc, std::string const& instr) = 0;
52+
virtual void disass_output(uint64_t pc, std::string const& instr) = 0;
5353

5454
virtual unsigned get_last_bus_cycles() = 0;
5555

src/sysc/instr_recorder.h

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#pragma once
2+
3+
#include "scv-tr/scv_tr.h"
4+
#include <rigtorp/SPSCQueue.h>
5+
#include <tlm/scc/quantum_keeper.h>
6+
#include <tlm/scc/scv/tlm_recording_extension.h>
7+
#ifdef HAS_SCV
8+
#include <scv.h>
9+
#else
10+
#include <scv-tr.h>
11+
#ifndef SCVNS
12+
#define SCVNS ::scv_tr::
13+
#endif
14+
#endif
15+
16+
namespace sysc {
17+
namespace riscv {
18+
19+
struct instr_recorder_b {
20+
bool init(std::string const& basename) {
21+
if(m_db != nullptr) {
22+
stream_handle = new SCVNS scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
23+
instr_tr_handle = new SCVNS scv_tr_generator<>("execute", *stream_handle);
24+
return true;
25+
}
26+
return false;
27+
}
28+
instr_recorder_b(SCVNS scv_tr_db* m_db = SCVNS scv_tr_db::get_default_db())
29+
: m_db(m_db) {}
30+
void record_instr(uint64_t pc, std::string const& instr_str, char mode, uint64_t status, sc_core::sc_time ltime) {
31+
if(stream_handle == nullptr)
32+
return;
33+
if(tr_handle.is_active())
34+
tr_handle.end_transaction();
35+
tr_handle = instr_tr_handle->begin_transaction();
36+
tr_handle.record_attribute("PC", pc);
37+
tr_handle.record_attribute("INSTR", instr_str);
38+
tr_handle.record_attribute("MODE", mode);
39+
tr_handle.record_attribute("MSTATUS", status);
40+
tr_handle.record_attribute("LTIME_START", ltime / 1_ns);
41+
}
42+
43+
tlm::scc::scv::tlm_recording_extension* get_recording_extension(bool finish_instr) {
44+
if(m_db != nullptr && tr_handle.is_valid()) {
45+
if(finish_instr && tr_handle.is_active())
46+
tr_handle.end_transaction();
47+
return new tlm::scc::scv::tlm_recording_extension(tr_handle, this);
48+
}
49+
return nullptr;
50+
}
51+
52+
protected:
53+
//! transaction recording database
54+
SCVNS scv_tr_db* m_db{nullptr};
55+
//! blocking transaction recording stream handle
56+
SCVNS scv_tr_stream* stream_handle{nullptr};
57+
//! transaction generator handle for blocking transactions
58+
SCVNS scv_tr_generator<SCVNS _scv_tr_generator_default_data, SCVNS _scv_tr_generator_default_data>* instr_tr_handle{nullptr};
59+
SCVNS scv_tr_handle tr_handle;
60+
};
61+
62+
template <typename QK> struct instr_recorder : instr_recorder_b {};
63+
64+
template <> struct instr_recorder<tlm::scc::quantumkeeper> : instr_recorder_b {
65+
void disass_output(uint64_t pc, std::string const& instr_str, char mode, uint64_t status) {
66+
if(stream_handle == nullptr)
67+
return;
68+
record_instr(pc, instr_str, mode, status, quantum_keeper.get_local_absolute_time());
69+
}
70+
instr_recorder(tlm::scc::quantumkeeper& quantum_keeper)
71+
: quantum_keeper(quantum_keeper) {}
72+
73+
protected:
74+
tlm::scc::quantumkeeper& quantum_keeper;
75+
};
76+
77+
template <> struct instr_recorder<tlm::scc::quantumkeeper_mt> : instr_recorder_b {
78+
void disass_output(uint64_t pc, std::string const& instr_str, char mode, uint64_t status) {
79+
if(stream_handle == nullptr)
80+
return;
81+
que.push(instr_record{pc, instr_str, mode, status, quantum_keeper.get_local_absolute_time()});
82+
}
83+
84+
void record() {
85+
while(auto r = que.front()) {
86+
record_instr(r->pc, r->instr_str, r->mode, r->status, r->start_time);
87+
que.pop();
88+
}
89+
}
90+
91+
struct callback : sc_core::sc_stage_callback_if {
92+
void stage_callback(const sc_core::sc_stage& stage) override { owner->record(); }
93+
callback(instr_recorder<tlm::scc::quantumkeeper_mt>* owner)
94+
: owner(owner) {}
95+
instr_recorder<tlm::scc::quantumkeeper_mt>* owner;
96+
} stage_cb{this};
97+
98+
instr_recorder(tlm::scc::quantumkeeper_mt& quantum_keeper)
99+
: quantum_keeper(quantum_keeper)
100+
, que(8 * 1024) {
101+
sc_core::sc_register_stage_callback(stage_cb, sc_core::SC_PRE_TIMESTEP);
102+
}
103+
104+
protected:
105+
struct instr_record {
106+
uint64_t pc;
107+
std::string const instr_str;
108+
char mode;
109+
uint64_t status;
110+
sc_core::sc_time start_time;
111+
};
112+
tlm::scc::quantumkeeper_mt& quantum_keeper;
113+
rigtorp::SPSCQueue<instr_record> que;
114+
};
115+
} // namespace riscv
116+
} // namespace sysc

src/sysc/sc2core_if.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct sc2core_if {
5050

5151
virtual void setup_mt() = 0;
5252

53+
virtual void enable_disass(bool enable) = 0;
5354
util::delegate<void(unsigned)> set_hartid;
5455
util::delegate<void(unsigned)> set_irq_count;
5556
util::delegate<uint32_t()> get_mode;

0 commit comments

Comments
 (0)