181 unsigned int transport_dbg(
typename TYPES::tlm_payload_type& trans)
override;
200 void record_nb_tx(
typename TYPES::tlm_payload_type&,
const typename TYPES::tlm_phase_type&, sc_core::sc_time, SCVNS scv_tr_handle);
201 const unsigned bus_width{0};
203 SCVNS scv_tr_db* m_db{
nullptr};
205 SCVNS scv_tr_stream* b_streamHandle{
nullptr};
207 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{
nullptr,
nullptr,
nullptr}};
209 SCVNS scv_tr_stream* b_streamHandleTimed{
nullptr};
212 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
214 enum DIR { FW, BW, REQ = FW, RESP = BW };
216 SCVNS scv_tr_stream* nb_streamHandle{
nullptr};
218 SCVNS scv_tr_stream* nb_streamHandleTimed{
nullptr};
220 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{
nullptr,
nullptr}};
222 std::array<SCVNS scv_tr_generator<>*, 2> nb_trTimedHandle{{
nullptr,
nullptr}};
223 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
224 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
225 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_resp_handle_map;
226 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_resp_handle_map;
228 SCVNS scv_tr_stream* dmi_streamHandle{
nullptr};
230 SCVNS scv_tr_generator<>* dmi_trGetHandle{
nullptr};
231 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{
nullptr};
234 void initialize_streams() {
236 b_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_bl").c_str(),
"[TLM][axi][b]", m_db);
237 b_trHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
238 "read", *b_streamHandle,
"start_delay",
"end_delay");
239 b_trHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
240 "write", *b_streamHandle,
"start_delay",
"end_delay");
241 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
242 "ignore", *b_streamHandle,
"start_delay",
"end_delay");
244 b_streamHandleTimed =
245 new SCVNS scv_tr_stream((fixed_basename +
"_bl_timed").c_str(),
"[TLM][axi][b][timed]", m_db);
246 b_trTimedHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<>(
"read", *b_streamHandleTimed);
247 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<>(
"write", *b_streamHandleTimed);
248 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<>(
"ignore", *b_streamHandleTimed);
252 nb_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_nb").c_str(),
"[TLM][axi][nb]", m_db);
253 nb_trHandle[FW] =
new SCVNS scv_tr_generator<std::string, std::string>(
"fw", *nb_streamHandle,
"tlm_phase",
254 "tlm_phase[return_path]");
255 nb_trHandle[BW] =
new SCVNS scv_tr_generator<std::string, std::string>(
"bw", *nb_streamHandle,
"tlm_phase",
256 "tlm_phase[return_path]");
258 nb_streamHandleTimed =
259 new SCVNS scv_tr_stream((fixed_basename +
"_nb_timed").c_str(),
"[TLM][axi][nb][timed]", m_db);
260 nb_trTimedHandle[FW] =
new SCVNS scv_tr_generator<>(
"request", *nb_streamHandleTimed);
261 nb_trTimedHandle[BW] =
new SCVNS scv_tr_generator<>(
"response", *nb_streamHandleTimed);
265 dmi_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_dmi").c_str(),
"[TLM][axi][dmi]", m_db);
266 dmi_trGetHandle =
new SCVNS scv_tr_generator<>(
"get", *dmi_streamHandle);
267 dmi_trInvalidateHandle =
new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
268 "invalidate", *dmi_streamHandle,
"start_addr",
"end_addr");
271 checker=
new axi::checker::axi_protocol(fixed_basename, bus_width/8, rd_response_timeout.get_value(), wr_response_timeout.get_value());
276 const std::string fixed_basename;
277 axi::checker::checker_if<TYPES>* checker{
nullptr};
278 inline std::string phase2string(
const tlm::tlm_phase& p) {
279 std::stringstream ss;
289template <
typename TYPES>
296 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
300 SCVNS scv_tr_handle bh;
301 if(b_streamHandleTimed) {
302 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp()+delay);
306 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
308 ext->recordBeginTx(h, trans);
311 trans.get_extension(preExt);
312 if(preExt ==
nullptr) {
314 if(trans.has_mm()) trans.set_auto_extension(preExt);
else trans.set_extension(preExt);
318 SCVNS scv_tr_handle preTx(preExt->
txHandle);
321 trans.get_extension(preExt);
332 tlm::scc::scv::record(h, trans);
333 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
335 ext->recordEndTx(h, trans);
337 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
340 tlm::scc::scv::record(h, trans);
341 b_trTimedHandle[trans.get_command()]->end_transaction(bh, sc_core::sc_time_stamp()+delay);
345template <
typename TYPES>
347 typename TYPES::tlm_phase_type& phase,
348 sc_core::sc_time& delay) {
351 checker->fw_pre(trans, phase);
352 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
353 checker->fw_post(trans, phase, status);
356 return get_fw_if()->nb_transport_fw(trans, phase, delay);
362 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase2string(phase));
364 trans.get_extension(preExt);
365 if((phase == axi::BEGIN_PARTIAL_REQ || phase == tlm::BEGIN_REQ) &&
368 if(trans.has_mm()) trans.set_auto_extension(preExt);
else trans.set_extension(preExt);
369 }
else if(preExt !=
nullptr) {
373 sc_assert(preExt !=
nullptr &&
"ERROR on forward path in phase other than tlm::BEGIN_REQ");
377 h.record_attribute(
"delay", delay.to_string());
378 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
380 ext->recordBeginTx(h, trans);
384 if(nb_streamHandleTimed) {
385 record_nb_tx(trans, phase, delay, h);
390 if(checker) checker->fw_pre(trans, phase);
391 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
392 if(checker) checker->fw_post(trans, phase, status);
396 tlm::scc::scv::record(h, status);
397 h.record_attribute(
"delay[return_path]", delay.to_string());
398 tlm::scc::scv::record(h, trans);
399 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
401 ext->recordEndTx(h, trans);
403 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
405 trans.get_extension(preExt);
416 if(nb_streamHandleTimed) {
417 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
419 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
420 record_nb_tx(trans, phase, delay, h);
423 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
427template <
typename TYPES>
429 typename TYPES::tlm_phase_type& phase,
430 sc_core::sc_time& delay) {
433 checker->bw_pre(trans, phase);
434 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
435 checker->bw_post(trans, phase, status);
438 return get_bw_if()->nb_transport_bw(trans, phase, delay);
444 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
446 trans.get_extension(preExt);
447 if(phase == tlm::BEGIN_REQ && preExt ==
nullptr) {
449 if(trans.has_mm()) trans.set_auto_extension(preExt);
else trans.set_extension(preExt);
450 }
else if(preExt !=
nullptr) {
454 sc_assert(preExt !=
nullptr &&
"ERROR on backward path in phase other than tlm::BEGIN_REQ");
458 h.record_attribute(
"delay", delay.to_string());
459 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
461 ext->recordBeginTx(h, trans);
465 if(nb_streamHandleTimed) {
466 record_nb_tx(trans, phase, delay, h);
471 if(checker) checker->bw_pre(trans, phase);
472 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
473 if(checker) checker->bw_post(trans, phase, status);
477 tlm::scc::scv::record(h, status);
478 h.record_attribute(
"delay[return_path]", delay.to_string());
479 tlm::scc::scv::record(h, trans);
480 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
482 ext->recordEndTx(h, trans);
484 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
486 trans.get_extension(preExt);
497 if(nb_streamHandleTimed) {
498 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
500 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
501 record_nb_tx(trans, phase, delay, h);
504 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
508template <
typename TYPES>
509void axi_recorder<TYPES>::record_nb_tx(
typename TYPES::tlm_payload_type& trans,
const typename TYPES::tlm_phase_type& phase, sc_core::sc_time delay, SCVNS scv_tr_handle parent) {
510 SCVNS scv_tr_handle h;
512 auto t = sc_core::sc_time_stamp()+delay;
513 auto id=
reinterpret_cast<uintptr_t
>(&trans);
514 if(phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
515 h = nb_trTimedHandle[REQ]->begin_transaction(t);
516 tlm::scc::scv::record(h, trans);
518 nbtx_req_handle_map[id] = h;
519 }
else if(phase == tlm::END_REQ || phase == axi::END_PARTIAL_REQ) {
520 auto it = nbtx_req_handle_map.find(
id);
521 if(it != nbtx_req_handle_map.end()) {
523 nbtx_req_handle_map.erase(it);
524 h.end_transaction(t);
525 nbtx_last_req_handle_map[id] = h;
527 }
else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
528 auto it = nbtx_req_handle_map.find(
id);
529 if(it != nbtx_req_handle_map.end()) {
531 nbtx_req_handle_map.erase(it);
532 h.end_transaction(t);
533 nbtx_last_req_handle_map[id] = h;
535 h = nb_trTimedHandle[RESP]->begin_transaction(t);
536 tlm::scc::scv::record(h, trans);
538 nbtx_resp_handle_map[id] = h;
539 it = nbtx_last_req_handle_map.find(
id);
540 if(it != nbtx_last_req_handle_map.end()) {
541 SCVNS scv_tr_handle& pred = it->second;
543 nbtx_last_req_handle_map.erase(it);
545 it = nbtx_last_resp_handle_map.find(
id);
546 if(it != nbtx_last_resp_handle_map.end()) {
547 SCVNS scv_tr_handle& pred = it->second;
549 nbtx_last_resp_handle_map.erase(it);
552 }
else if(phase == tlm::END_RESP || phase == axi::END_PARTIAL_RESP) {
553 auto it = nbtx_resp_handle_map.find(
id);
554 if(it != nbtx_resp_handle_map.end()) {
556 nbtx_resp_handle_map.erase(it);
557 h.end_transaction(t);
558 if(phase == axi::END_PARTIAL_RESP) {
559 nbtx_last_resp_handle_map[id] = h;
563 sc_assert(!
"phase not supported!");
567template <
typename TYPES>
570 return get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
571 else if(!dmi_streamHandle)
572 initialize_streams();
573 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
574 bool status =
get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
575 tlm::scc::scv::record(h, trans);
576 tlm::scc::scv::record(h, dmi_data);
586template <
typename TYPES>
589 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
591 }
else if(!dmi_streamHandle)
592 initialize_streams();
593 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
594 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
595 dmi_trInvalidateHandle->end_transaction(h, end_addr);
605 unsigned int count =
get_fw_if()->transport_dbg(trans);