237 unsigned int transport_dbg(
typename TYPES::tlm_payload_type& trans)
override;
253 tlm_utils::peq_with_cb_and_phase<tlm_recorder, recording_types> nb_timed_peq;
258 void nbtx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase);
260 SCVNS scv_tr_db* m_db{
nullptr};
262 SCVNS scv_tr_stream* b_streamHandle{
nullptr};
264 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{
nullptr,
nullptr,
nullptr}};
266 SCVNS scv_tr_stream* b_streamHandleTimed{
nullptr};
269 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
271 enum DIR { FW, BW, REQ = FW, RESP = BW };
273 SCVNS scv_tr_stream* nb_streamHandle{
nullptr};
275 SCVNS scv_tr_stream* nb_streamHandleTimed{
nullptr};
277 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{
nullptr,
nullptr}};
279 std::array<SCVNS scv_tr_generator<>*, 2> nb_trTimedHandle{{
nullptr,
nullptr}};
280 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
281 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
284 SCVNS scv_tr_stream* dmi_streamHandle{
nullptr};
286 SCVNS scv_tr_generator<>* dmi_trGetHandle{
nullptr};
287 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{
nullptr};
290 void initialize_streams() {
292 b_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_bl").c_str(),
"[TLM][base-protocol][b]", m_db);
293 b_trHandle[tlm::TLM_READ_COMMAND] =
294 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"read", *b_streamHandle,
"start_delay",
"end_delay");
295 b_trHandle[tlm::TLM_WRITE_COMMAND] =
296 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"write", *b_streamHandle,
"start_delay",
"end_delay");
297 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
298 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"ignore", *b_streamHandle,
"start_delay",
"end_delay");
300 b_streamHandleTimed =
301 new SCVNS scv_tr_stream((fixed_basename +
"_bl_timed").c_str(),
"[TLM][base-protocol][b][timed]", m_db);
302 b_trTimedHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<>(
"read", *b_streamHandleTimed);
303 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<>(
"write", *b_streamHandleTimed);
304 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<>(
"ignore", *b_streamHandleTimed);
308 nb_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_nb").c_str(),
"[TLM][base-protocol][nb]", m_db);
310 new SCVNS scv_tr_generator<std::string, std::string>(
"fw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
312 new SCVNS scv_tr_generator<std::string, std::string>(
"bw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
314 nb_streamHandleTimed =
315 new SCVNS scv_tr_stream((fixed_basename +
"_nb_timed").c_str(),
"[TLM][base-protocol][nb][timed]", m_db);
316 nb_trTimedHandle[FW] =
new SCVNS scv_tr_generator<>(
"request", *nb_streamHandleTimed);
317 nb_trTimedHandle[BW] =
new SCVNS scv_tr_generator<>(
"response", *nb_streamHandleTimed);
321 dmi_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_dmi").c_str(),
"[TLM][base-protocol][dmi]", m_db);
322 dmi_trGetHandle =
new SCVNS scv_tr_generator<>(
"get", *dmi_streamHandle);
323 dmi_trInvalidateHandle =
324 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"invalidate", *dmi_streamHandle,
"start_addr",
"end_addr");
329 const std::string fixed_basename;
330 inline std::string phase2string(
const tlm::tlm_phase& p) {
331 std::stringstream ss;
342 tlm_recording_payload* req{
nullptr};
344 fw_port->b_transport(trans, delay);
346 }
else if(!b_streamHandle)
347 initialize_streams();
349 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
353 SCVNS scv_tr_handle ht;
354 if(b_streamHandleTimed) {
355 ht = b_trTimedHandle[trans.get_command()]->begin_transaction(delay);
359 auto addr = trans.get_address();
360 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
361 extensionRecording->recordBeginTx(h, trans);
364 trans.get_extension(preExt);
365 if(preExt ==
nullptr) {
368 trans.set_auto_extension(preExt);
370 trans.set_extension(preExt);
374 SCVNS scv_tr_handle preTx{preExt->
txHandle};
376 fw_port->b_transport(trans, delay);
380 if(!trans.has_mm()) {
386 trans.set_address(addr);
388 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
389 extensionRecording->recordEndTx(h, trans);
391 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
393 if(ht.is_valid() && ht.is_active()) {
395 ht.end_transaction(delay);
399template <
typename TYPES>
401 sc_core::sc_time& delay) {
403 return fw_port->nb_transport_fw(trans, phase, delay);
404 else if(!nb_streamHandle)
405 initialize_streams();
410 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase2string(phase));
412 trans.get_extension(preExt);
413 if(preExt ==
nullptr) {
416 trans.set_auto_extension(preExt);
418 trans.set_extension(preExt);
426 h.record_attribute(
"delay", delay.to_string());
427 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
428 extensionRecording->recordBeginTx(h, trans);
432 if(nb_streamHandleTimed) {
433 auto* req =
mm::get().allocate();
437 nb_timed_peq.notify(*req, phase, delay);
442 tlm::tlm_sync_enum status =
fw_port->nb_transport_fw(trans, phase, delay);
447 h.record_attribute(
"delay[return_path]", delay.to_string());
449 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
450 extensionRecording->recordEndTx(h, trans);
452 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
453 trans.get_extension(preExt);
456 if(!trans.has_mm()) {
463 if(nb_streamHandleTimed) {
464 auto* req =
mm::get().allocate();
469 tlm::tlm_phase end_resp = tlm::END_RESP;
470 nb_timed_peq.notify(*req, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? end_resp : phase, delay);
472 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
473 tlm_recording_payload* req =
mm::get().allocate();
478 nb_timed_peq.notify(*req, phase, delay);
481 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
485template <
typename TYPES>
487 sc_core::sc_time& delay) {
489 return bw_port->nb_transport_bw(trans, phase, delay);
490 else if(!nb_streamHandle)
491 initialize_streams();
496 trans.get_extension(preExt);
499 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
506 h.record_attribute(
"delay", delay.to_string());
507 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
508 extensionRecording->recordBeginTx(h, trans);
512 if(nb_streamHandleTimed) {
513 tlm_recording_payload* req =
mm::get().allocate();
517 nb_timed_peq.notify(*req, phase, delay);
522 tlm::tlm_sync_enum status =
bw_port->nb_transport_bw(trans, phase, delay);
527 h.record_attribute(
"delay[return_path]", delay.to_string());
529 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
530 extensionRecording->recordEndTx(h, trans);
532 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
533 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
538 if(!trans.has_mm()) {
545 if(nb_streamHandleTimed) {
546 tlm_recording_payload* req =
mm::get().allocate();
551 nb_timed_peq.notify(*req, phase, delay);
557template <
typename TYPES>
void tlm_recorder<TYPES>::nbtx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase) {
558 SCVNS scv_tr_handle h;
559 std::unordered_map<uint64_t, SCVNS scv_tr_handle>::iterator it;
563 record(h, rec_parts);
564 nbtx_req_handle_map[rec_parts.id] = h;
567 it = nbtx_req_handle_map.find(rec_parts.id);
568 sc_assert(it != nbtx_req_handle_map.end());
570 nbtx_req_handle_map.erase(it);
572 nbtx_last_req_handle_map[rec_parts.id] = h;
574 case tlm::BEGIN_RESP:
575 it = nbtx_req_handle_map.find(rec_parts.id);
576 if(it != nbtx_req_handle_map.end()) {
578 nbtx_req_handle_map.erase(it);
580 nbtx_last_req_handle_map[rec_parts.id] = h;
583 record(h, rec_parts);
584 nbtx_req_handle_map[rec_parts.id] = h;
585 it = nbtx_last_req_handle_map.find(rec_parts.id);
586 if(it != nbtx_last_req_handle_map.end()) {
587 SCVNS scv_tr_handle pred = it->second;
588 nbtx_last_req_handle_map.erase(it);
593 it = nbtx_req_handle_map.find(rec_parts.id);
594 if(it != nbtx_req_handle_map.end()) {
596 nbtx_req_handle_map.erase(it);
604 if(rec_parts.sync == tlm_sync_enum::TLM_COMPLETED && phase != tlm::END_RESP) {
605 it = nbtx_req_handle_map.find(rec_parts.id);
606 if(it != nbtx_req_handle_map.end()) {
608 nbtx_req_handle_map.erase(it);
618 return fw_port->get_direct_mem_ptr(trans, dmi_data);
619 else if(!dmi_streamHandle)
620 initialize_streams();
621 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
622 bool status =
fw_port->get_direct_mem_ptr(trans, dmi_data);
636 bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
638 }
else if(!dmi_streamHandle)
639 initialize_streams();
640 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
641 bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
642 dmi_trInvalidateHandle->end_transaction(h, end_addr);
652 unsigned int count =
fw_port->transport_dbg(trans);