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,
bool);
207 SCVNS scv_tr_db* m_db{
nullptr};
209 SCVNS scv_tr_stream* b_streamHandle{
nullptr};
211 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{
nullptr,
nullptr,
nullptr}};
213 SCVNS scv_tr_stream* b_streamHandleTimed{
nullptr};
216 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
217 std::unordered_map<uint64_t, SCVNS scv_tr_handle> btx_handle_map;
219 enum DIR { FW, BW, REQ = FW, RESP = BW, ACK };
221 SCVNS scv_tr_stream* nb_streamHandle{
nullptr};
223 SCVNS scv_tr_stream* nb_streamHandleTimed{
nullptr};
225 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{
nullptr,
nullptr}};
227 std::array<SCVNS scv_tr_generator<>*, 3> nb_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
228 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
229 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
230 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_resp_handle_map;
231 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_resp_handle_map;
233 SCVNS scv_tr_stream* dmi_streamHandle{
nullptr};
235 SCVNS scv_tr_generator<>* dmi_trGetHandle{
nullptr};
236 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{
nullptr};
239 void initialize_streams() {
241 b_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_bl").c_str(),
"[TLM][ace][b]", m_db);
242 b_trHandle[tlm::TLM_READ_COMMAND] =
243 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"read", *b_streamHandle,
"start_delay",
"end_delay");
244 b_trHandle[tlm::TLM_WRITE_COMMAND] =
245 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"write", *b_streamHandle,
"start_delay",
"end_delay");
246 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
247 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"ignore", *b_streamHandle,
"start_delay",
"end_delay");
249 b_streamHandleTimed =
new SCVNS scv_tr_stream((fixed_basename +
"_bl_timed").c_str(),
"[TLM][ace][b][timed]", m_db);
250 b_trTimedHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<>(
"read", *b_streamHandleTimed);
251 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<>(
"write", *b_streamHandleTimed);
252 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<>(
"ignore", *b_streamHandleTimed);
256 nb_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_nb").c_str(),
"[TLM][ace][nb]", m_db);
258 new SCVNS scv_tr_generator<std::string, std::string>(
"fw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
260 new SCVNS scv_tr_generator<std::string, std::string>(
"bw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
262 nb_streamHandleTimed =
new SCVNS scv_tr_stream((fixed_basename +
"_nb_timed").c_str(),
"[TLM][ace][nb][timed]", m_db);
263 nb_trTimedHandle[FW] =
new SCVNS scv_tr_generator<>(
"request", *nb_streamHandleTimed);
264 nb_trTimedHandle[BW] =
new SCVNS scv_tr_generator<>(
"response", *nb_streamHandleTimed);
265 nb_trTimedHandle[ACK] =
new SCVNS scv_tr_generator<>(
"ack", *nb_streamHandleTimed);
269 dmi_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_dmi").c_str(),
"[TLM][ace][dmi]", m_db);
270 dmi_trGetHandle =
new SCVNS scv_tr_generator<>(
"get", *dmi_streamHandle);
271 dmi_trInvalidateHandle =
272 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"invalidate", *dmi_streamHandle,
"start_addr",
"end_addr");
281 const std::string fixed_basename;
282 axi::checker::checker_if<TYPES>* checker{
nullptr};
295 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
299 SCVNS scv_tr_handle bh;
300 if(b_streamHandleTimed) {
301 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp()+delay);
305 auto addr = trans.get_address();
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) {
315 trans.set_auto_extension(preExt);
317 trans.set_extension(preExt);
321 SCVNS scv_tr_handle preTx(preExt->
txHandle);
324 trans.get_extension(preExt);
335 trans.set_address(addr);
336 tlm::scc::scv::record(h, trans);
337 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
339 ext->recordEndTx(h, trans);
341 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
344 tlm::scc::scv::record(bh, trans);
345 bh.end_transaction(sc_core::sc_time_stamp()+delay);
350 if(!b_streamHandleTimed) {
355 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
359 SCVNS scv_tr_handle bh;
360 if(b_streamHandleTimed) {
361 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp()+delay);
365 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
367 ext->recordBeginTx(h, trans);
370 trans.get_extension(preExt);
374 trans.set_auto_extension(preExt);
376 trans.set_extension(preExt);
380 SCVNS scv_tr_handle preTx(preExt->
txHandle);
383 trans.get_extension(preExt);
394 tlm::scc::scv::record(h, trans);
395 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
397 ext->recordEndTx(h, trans);
399 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
402 tlm::scc::scv::record(bh, trans);
403 bh.end_transaction(sc_core::sc_time_stamp()+delay);
407template <
typename TYPES>
409 sc_core::sc_time& delay) {
412 checker->fw_pre(trans, phase);
413 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
414 checker->fw_post(trans, phase, status);
417 return get_fw_if()->nb_transport_fw(trans, phase, delay);
423 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase.get_name());
425 trans.get_extension(preExt);
426 if((phase == axi::BEGIN_PARTIAL_REQ || phase == tlm::BEGIN_REQ) && preExt ==
nullptr) {
429 trans.set_auto_extension(preExt);
431 trans.set_extension(preExt);
432 }
else if(preExt !=
nullptr) {
436 sc_assert(preExt !=
nullptr &&
"ERROR on forward path in phase other than tlm::BEGIN_REQ");
440 h.record_attribute(
"delay", delay.to_string());
441 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
443 ext->recordBeginTx(h, trans);
447 if(nb_streamHandleTimed) {
448 record_nb_tx(trans, phase, sc_core::sc_time_stamp()+delay, h, phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP);
454 checker->fw_pre(trans, phase);
455 tlm::tlm_sync_enum status =
get_fw_if()->nb_transport_fw(trans, phase, delay);
457 checker->fw_post(trans, phase, status);
461 tlm::scc::scv::record(h, status);
462 h.record_attribute(
"delay[return_path]", delay.to_string());
463 tlm::scc::scv::record(h, trans);
464 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
466 ext->recordEndTx(h, trans);
468 if(status == tlm::TLM_COMPLETED || (phase == axi::ACK)) {
470 trans.get_extension(preExt);
481 if(nb_streamHandleTimed) {
482 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, sc_core::sc_time_stamp()+delay, h,
false);
484 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
485 record_nb_tx(trans, phase, sc_core::sc_time_stamp()+delay, h,
false);
488 nb_trHandle[FW]->end_transaction(h, phase.get_name());
492template <
typename TYPES>
494 sc_core::sc_time& delay) {
497 checker->bw_pre(trans, phase);
498 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
499 checker->bw_post(trans, phase, status);
502 return get_bw_if()->nb_transport_bw(trans, phase, delay);
508 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase.get_name());
510 trans.get_extension(preExt);
511 if(phase == tlm::BEGIN_REQ && preExt ==
nullptr) {
514 trans.set_auto_extension(preExt);
516 trans.set_extension(preExt);
517 }
else if(preExt !=
nullptr) {
521 sc_assert(preExt !=
nullptr &&
"ERROR on backward path in phase other than tlm::BEGIN_REQ");
525 h.record_attribute(
"delay", delay.to_string());
526 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
528 ext->recordBeginTx(h, trans);
532 if(nb_streamHandleTimed) {
533 record_nb_tx(trans, phase, sc_core::sc_time_stamp()+delay, h, phase == tlm::BEGIN_REQ);
539 checker->bw_pre(trans, phase);
540 tlm::tlm_sync_enum status =
get_bw_if()->nb_transport_bw(trans, phase, delay);
542 checker->bw_post(trans, phase, status);
546 tlm::scc::scv::record(h, status);
547 h.record_attribute(
"delay[return_path]", delay.to_string());
548 tlm::scc::scv::record(h, trans);
549 for(
auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
551 ext->recordEndTx(h, trans);
553 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == axi::ACK)) {
555 trans.get_extension(preExt);
566 if(nb_streamHandleTimed) {
567 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, sc_core::sc_time_stamp()+delay, h,
false);
569 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
570 record_nb_tx(trans, phase, sc_core::sc_time_stamp()+delay, h,
false);
573 nb_trHandle[BW]->end_transaction(h, phase.get_name());
577template <
typename TYPES>
void ace_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,
bool is_snoop) {
578 SCVNS scv_tr_handle h;
580 auto t = sc_core::sc_time_stamp()+delay;
581 auto id =
reinterpret_cast<uintptr_t
>(&trans);
582 if(phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
583 h = nb_trTimedHandle[REQ]->begin_transaction(t);
584 tlm::scc::scv::record(h, trans);
586 nbtx_req_handle_map[id] = h;
587 }
else if(phase == tlm::END_REQ || phase == axi::END_PARTIAL_REQ) {
588 auto it = nbtx_req_handle_map.find(
id);
589 sc_assert(it != nbtx_req_handle_map.end());
591 nbtx_req_handle_map.erase(it);
592 h.end_transaction(t);
593 nbtx_last_req_handle_map[id] = h;
594 }
else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
595 auto it = nbtx_req_handle_map.find(
id);
596 if(it != nbtx_req_handle_map.end()) {
598 nbtx_req_handle_map.erase(it);
599 h.end_transaction(t);
600 nbtx_last_req_handle_map[id] = h;
602 h = nb_trTimedHandle[RESP]->begin_transaction(t);
603 tlm::scc::scv::record(h, trans);
605 nbtx_resp_handle_map[id] = h;
606 it = nbtx_last_req_handle_map.find(
id);
607 if(it != nbtx_last_req_handle_map.end()) {
608 SCVNS scv_tr_handle& pred = it->second;
610 nbtx_last_req_handle_map.erase(it);
612 it = nbtx_last_resp_handle_map.find(
id);
613 if(it != nbtx_last_resp_handle_map.end()) {
614 SCVNS scv_tr_handle& pred = it->second;
616 nbtx_last_resp_handle_map.erase(it);
619 }
else if(phase == tlm::END_RESP || phase == axi::END_PARTIAL_RESP) {
620 auto it = nbtx_resp_handle_map.find(
id);
621 if(it != nbtx_resp_handle_map.end()) {
623 nbtx_resp_handle_map.erase(it);
624 h.end_transaction(t);
625 if(phase == axi::END_PARTIAL_RESP) {
626 nbtx_last_resp_handle_map[id] = h;
629 }
else if(phase == axi::ACK) {
630 h = nb_trTimedHandle[ACK]->begin_transaction(t);
631 tlm::scc::scv::record(h, trans);
633 h.end_transaction(t);
635 sc_assert(!
"phase not supported!");
641 return get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
642 else if(!dmi_streamHandle)
643 initialize_streams();
644 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
645 bool status =
get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
646 tlm::scc::scv::record(h, trans);
647 tlm::scc::scv::record(h, dmi_data);
659 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
661 }
else if(!dmi_streamHandle)
662 initialize_streams();
663 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
664 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
665 dmi_trInvalidateHandle->end_transaction(h, end_addr);
675 unsigned int count =
get_fw_if()->transport_dbg(trans);