186 unsigned int transport_dbg(
typename TYPES::tlm_payload_type& trans)
override;
205 void record_nb_tx(
typename TYPES::tlm_payload_type&,
const typename TYPES::tlm_phase_type&, sc_core::sc_time, SCVNS scv_tr_handle,
208 SCVNS scv_tr_db* m_db{
nullptr};
210 SCVNS scv_tr_stream* b_streamHandle{
nullptr};
212 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{
nullptr,
nullptr,
nullptr}};
214 SCVNS scv_tr_stream* b_streamHandleTimed{
nullptr};
217 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
218 std::unordered_map<uint64_t, SCVNS scv_tr_handle> btx_handle_map;
220 enum DIR { FW, BW, REQ = FW, RESP = BW, ACK };
222 SCVNS scv_tr_stream* nb_streamHandle{
nullptr};
224 SCVNS scv_tr_stream* nb_streamHandleTimed{
nullptr};
226 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{
nullptr,
nullptr}};
228 std::array<SCVNS scv_tr_generator<>*, 3> nb_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
229 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
230 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
231 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_resp_handle_map;
232 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_resp_handle_map;
234 SCVNS scv_tr_stream* dmi_streamHandle{
nullptr};
236 SCVNS scv_tr_generator<>* dmi_trGetHandle{
nullptr};
237 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{
nullptr};
240 void initialize_streams() {
242 b_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_bl").c_str(),
"[TLM][ace][b]", m_db);
243 b_trHandle[tlm::TLM_READ_COMMAND] =
244 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"read", *b_streamHandle,
"start_delay",
"end_delay");
245 b_trHandle[tlm::TLM_WRITE_COMMAND] =
246 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"write", *b_streamHandle,
"start_delay",
"end_delay");
247 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
248 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"ignore", *b_streamHandle,
"start_delay",
"end_delay");
250 b_streamHandleTimed =
new SCVNS scv_tr_stream((fixed_basename +
"_bl_timed").c_str(),
"[TLM][ace][b][timed]", m_db);
251 b_trTimedHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<>(
"read", *b_streamHandleTimed);
252 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<>(
"write", *b_streamHandleTimed);
253 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<>(
"ignore", *b_streamHandleTimed);
257 nb_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_nb").c_str(),
"[TLM][ace][nb]", m_db);
259 new SCVNS scv_tr_generator<std::string, std::string>(
"fw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
261 new SCVNS scv_tr_generator<std::string, std::string>(
"bw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
263 nb_streamHandleTimed =
new SCVNS scv_tr_stream((fixed_basename +
"_nb_timed").c_str(),
"[TLM][ace][nb][timed]", m_db);
264 nb_trTimedHandle[FW] =
new SCVNS scv_tr_generator<>(
"request", *nb_streamHandleTimed);
265 nb_trTimedHandle[BW] =
new SCVNS scv_tr_generator<>(
"response", *nb_streamHandleTimed);
266 nb_trTimedHandle[ACK] =
new SCVNS scv_tr_generator<>(
"ack", *nb_streamHandleTimed);
270 dmi_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_dmi").c_str(),
"[TLM][ace][dmi]", m_db);
271 dmi_trGetHandle =
new SCVNS scv_tr_generator<>(
"get", *dmi_streamHandle);
272 dmi_trInvalidateHandle =
273 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"invalidate", *dmi_streamHandle,
"start_addr",
"end_addr");
282 const std::string fixed_basename;
283 axi::checker::checker_if<TYPES>* checker{
nullptr};
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 auto addr = trans.get_address();
307 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
309 ext->recordBeginTx(h, trans);
312 trans.get_extension(preExt);
313 if(preExt ==
nullptr) {
316 trans.set_auto_extension(preExt);
318 trans.set_extension(preExt);
322 SCVNS scv_tr_handle preTx(preExt->
txHandle);
325 trans.get_extension(preExt);
336 trans.set_address(addr);
337 tlm::scc::scv::record(h, trans);
338 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
340 ext->recordEndTx(h, trans);
342 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
345 tlm::scc::scv::record(bh, trans);
346 bh.end_transaction(sc_core::sc_time_stamp() + delay);
351 if(!b_streamHandleTimed) {
356 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
360 SCVNS scv_tr_handle bh;
361 if(b_streamHandleTimed) {
362 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp() + delay);
366 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
368 ext->recordBeginTx(h, trans);
371 trans.get_extension(preExt);
375 trans.set_auto_extension(preExt);
377 trans.set_extension(preExt);
381 SCVNS scv_tr_handle preTx(preExt->
txHandle);
384 trans.get_extension(preExt);
395 tlm::scc::scv::record(h, trans);
396 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
398 ext->recordEndTx(h, trans);
400 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
403 tlm::scc::scv::record(bh, trans);
404 bh.end_transaction(sc_core::sc_time_stamp() + delay);
408template <
typename TYPES>
410 sc_core::sc_time& delay) {
413 checker->fw_pre(trans, phase);
414 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
415 checker->fw_post(trans, phase, status);
418 return get_fw_if()->nb_transport_fw(trans, phase, delay);
424 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase.get_name());
426 trans.get_extension(preExt);
427 if((phase == axi::BEGIN_PARTIAL_REQ || phase == tlm::BEGIN_REQ) && preExt ==
nullptr) {
430 trans.set_auto_extension(preExt);
432 trans.set_extension(preExt);
433 }
else if(preExt !=
nullptr) {
437 sc_assert(preExt !=
nullptr &&
"ERROR on forward path in phase other than tlm::BEGIN_REQ");
441 h.record_attribute(
"delay", delay.to_string());
442 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
444 ext->recordBeginTx(h, trans);
448 if(nb_streamHandleTimed) {
449 record_nb_tx(trans, phase, sc_core::sc_time_stamp() + delay, h, phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP);
455 checker->fw_pre(trans, phase);
456 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
458 checker->fw_post(trans, phase, status);
462 tlm::scc::scv::record(h, status);
463 h.record_attribute(
"delay[return_path]", delay.to_string());
464 tlm::scc::scv::record(h, trans);
465 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
467 ext->recordEndTx(h, trans);
469 if(status == tlm::TLM_COMPLETED || (phase == axi::ACK)) {
471 trans.get_extension(preExt);
482 if(nb_streamHandleTimed) {
483 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase,
484 sc_core::sc_time_stamp() + delay, h,
false);
486 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
487 record_nb_tx(trans, phase, sc_core::sc_time_stamp() + delay, h,
false);
490 nb_trHandle[FW]->end_transaction(h, phase.get_name());
494template <
typename TYPES>
496 sc_core::sc_time& delay) {
499 checker->bw_pre(trans, phase);
500 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
501 checker->bw_post(trans, phase, status);
504 return get_bw_if()->nb_transport_bw(trans, phase, delay);
510 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase.get_name());
512 trans.get_extension(preExt);
513 if(phase == tlm::BEGIN_REQ && preExt ==
nullptr) {
516 trans.set_auto_extension(preExt);
518 trans.set_extension(preExt);
519 }
else if(preExt !=
nullptr) {
523 sc_assert(preExt !=
nullptr &&
"ERROR on backward path in phase other than tlm::BEGIN_REQ");
527 h.record_attribute(
"delay", delay.to_string());
528 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
530 ext->recordBeginTx(h, trans);
534 if(nb_streamHandleTimed) {
535 record_nb_tx(trans, phase, sc_core::sc_time_stamp() + delay, h, phase == tlm::BEGIN_REQ);
541 checker->bw_pre(trans, phase);
542 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
544 checker->bw_post(trans, phase, status);
548 tlm::scc::scv::record(h, status);
549 h.record_attribute(
"delay[return_path]", delay.to_string());
550 tlm::scc::scv::record(h, trans);
551 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get().get())
553 ext->recordEndTx(h, trans);
555 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == axi::ACK)) {
557 trans.get_extension(preExt);
568 if(nb_streamHandleTimed) {
569 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase,
570 sc_core::sc_time_stamp() + delay, h,
false);
572 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
573 record_nb_tx(trans, phase, sc_core::sc_time_stamp() + delay, h,
false);
576 nb_trHandle[BW]->end_transaction(h, phase.get_name());
580template <
typename TYPES>
581void ace_recorder<TYPES>::record_nb_tx(
typename TYPES::tlm_payload_type& trans,
const typename TYPES::tlm_phase_type& phase,
582 sc_core::sc_time delay, SCVNS scv_tr_handle parent,
bool is_snoop) {
583 SCVNS scv_tr_handle h;
585 auto t = sc_core::sc_time_stamp() + delay;
586 auto id =
reinterpret_cast<uintptr_t
>(&trans);
587 if(phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
588 h = nb_trTimedHandle[REQ]->begin_transaction(t);
589 tlm::scc::scv::record(h, trans);
591 nbtx_req_handle_map[id] = h;
592 }
else if(phase == tlm::END_REQ || phase == axi::END_PARTIAL_REQ) {
593 auto it = nbtx_req_handle_map.find(
id);
594 sc_assert(it != nbtx_req_handle_map.end());
596 nbtx_req_handle_map.erase(it);
597 h.end_transaction(t);
598 nbtx_last_req_handle_map[id] = h;
599 }
else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
600 auto it = nbtx_req_handle_map.find(
id);
601 if(it != nbtx_req_handle_map.end()) {
603 nbtx_req_handle_map.erase(it);
604 h.end_transaction(t);
605 nbtx_last_req_handle_map[id] = h;
607 h = nb_trTimedHandle[RESP]->begin_transaction(t);
608 tlm::scc::scv::record(h, trans);
610 nbtx_resp_handle_map[id] = h;
611 it = nbtx_last_req_handle_map.find(
id);
612 if(it != nbtx_last_req_handle_map.end()) {
613 SCVNS scv_tr_handle& pred = it->second;
615 nbtx_last_req_handle_map.erase(it);
617 it = nbtx_last_resp_handle_map.find(
id);
618 if(it != nbtx_last_resp_handle_map.end()) {
619 SCVNS scv_tr_handle& pred = it->second;
621 nbtx_last_resp_handle_map.erase(it);
624 }
else if(phase == tlm::END_RESP || phase == axi::END_PARTIAL_RESP) {
625 auto it = nbtx_resp_handle_map.find(
id);
626 if(it != nbtx_resp_handle_map.end()) {
628 nbtx_resp_handle_map.erase(it);
629 h.end_transaction(t);
630 if(phase == axi::END_PARTIAL_RESP) {
631 nbtx_last_resp_handle_map[id] = h;
634 }
else if(phase == axi::ACK) {
635 h = nb_trTimedHandle[ACK]->begin_transaction(t);
636 tlm::scc::scv::record(h, trans);
638 h.end_transaction(t);
640 sc_assert(!
"phase not supported!");
646 return get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
647 else if(!dmi_streamHandle)
648 initialize_streams();
649 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
650 bool status =
get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
651 tlm::scc::scv::record(h, trans);
652 tlm::scc::scv::record(h, dmi_data);
664 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
666 }
else if(!dmi_streamHandle)
667 initialize_streams();
668 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
669 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
670 dmi_trInvalidateHandle->end_transaction(h, end_addr);
680 unsigned int count =
get_fw_if()->transport_dbg(trans);