238 unsigned int transport_dbg(
typename TYPES::tlm_payload_type& trans)
override;
254 tlm_utils::peq_with_cb_and_phase<tlm_recorder, recording_types> b_timed_peq;
256 tlm_utils::peq_with_cb_and_phase<tlm_recorder, recording_types> nb_timed_peq;
261 void btx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase);
266 void nbtx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase);
268 SCVNS scv_tr_db* m_db{
nullptr};
270 SCVNS scv_tr_stream* b_streamHandle{
nullptr};
272 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{
nullptr,
nullptr,
nullptr}};
274 SCVNS scv_tr_stream* b_streamHandleTimed{
nullptr};
277 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{
nullptr,
nullptr,
nullptr}};
278 std::unordered_map<uint64_t, SCVNS scv_tr_handle> btx_handle_map;
280 enum DIR { FW, BW, REQ = FW, RESP = BW };
282 SCVNS scv_tr_stream* nb_streamHandle{
nullptr};
284 SCVNS scv_tr_stream* nb_streamHandleTimed{
nullptr};
286 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{
nullptr,
nullptr}};
288 std::array<SCVNS scv_tr_generator<>*, 2> nb_trTimedHandle{{
nullptr,
nullptr}};
289 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
290 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
293 SCVNS scv_tr_stream* dmi_streamHandle{
nullptr};
295 SCVNS scv_tr_generator<>* dmi_trGetHandle{
nullptr};
296 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{
nullptr};
299 void initialize_streams() {
301 b_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_bl").c_str(),
"[TLM][base-protocol][b]", m_db);
302 b_trHandle[tlm::TLM_READ_COMMAND] =
303 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"read", *b_streamHandle,
"start_delay",
"end_delay");
304 b_trHandle[tlm::TLM_WRITE_COMMAND] =
305 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"write", *b_streamHandle,
"start_delay",
"end_delay");
306 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
307 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"ignore", *b_streamHandle,
"start_delay",
"end_delay");
309 b_streamHandleTimed =
310 new SCVNS scv_tr_stream((fixed_basename +
"_bl_timed").c_str(),
"[TLM][base-protocol][b][timed]", m_db);
311 b_trTimedHandle[tlm::TLM_READ_COMMAND] =
new SCVNS scv_tr_generator<>(
"read", *b_streamHandleTimed);
312 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] =
new SCVNS scv_tr_generator<>(
"write", *b_streamHandleTimed);
313 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] =
new SCVNS scv_tr_generator<>(
"ignore", *b_streamHandleTimed);
317 nb_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_nb").c_str(),
"[TLM][base-protocol][nb]", m_db);
319 new SCVNS scv_tr_generator<std::string, std::string>(
"fw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
321 new SCVNS scv_tr_generator<std::string, std::string>(
"bw", *nb_streamHandle,
"tlm_phase",
"tlm_phase[return_path]");
323 nb_streamHandleTimed =
324 new SCVNS scv_tr_stream((fixed_basename +
"_nb_timed").c_str(),
"[TLM][base-protocol][nb][timed]", m_db);
325 nb_trTimedHandle[FW] =
new SCVNS scv_tr_generator<>(
"request", *nb_streamHandleTimed);
326 nb_trTimedHandle[BW] =
new SCVNS scv_tr_generator<>(
"response", *nb_streamHandleTimed);
330 dmi_streamHandle =
new SCVNS scv_tr_stream((fixed_basename +
"_dmi").c_str(),
"[TLM][base-protocol][dmi]", m_db);
331 dmi_trGetHandle =
new SCVNS scv_tr_generator<>(
"get", *dmi_streamHandle);
332 dmi_trInvalidateHandle =
333 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
"invalidate", *dmi_streamHandle,
"start_addr",
"end_addr");
338 const std::string fixed_basename;
339 inline std::string phase2string(
const tlm::tlm_phase& p) {
340 std::stringstream ss;
351 tlm_recording_payload* req{
nullptr};
353 fw_port->b_transport(trans, delay);
355 }
else if(!b_streamHandle)
356 initialize_streams();
358 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
362 if(b_streamHandleTimed) {
367 req->id = h.get_id();
368 tlm::tlm_phase begin_req = tlm::BEGIN_REQ;
369 b_timed_peq.notify(*req, begin_req, delay);
372 auto addr = trans.get_address();
373 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
374 if(extensionRecording)
375 extensionRecording->recordBeginTx(h, trans);
378 trans.get_extension(preExt);
379 if(preExt ==
nullptr) {
382 trans.set_auto_extension(preExt);
384 trans.set_extension(preExt);
388 SCVNS scv_tr_handle preTx{preExt->
txHandle};
390 fw_port->b_transport(trans, delay);
394 if(!trans.has_mm()) {
400 trans.set_address(addr);
402 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
403 if(extensionRecording)
404 extensionRecording->recordEndTx(h, trans);
406 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
408 if(b_streamHandleTimed) {
409 tlm::tlm_phase end_resp = tlm::END_RESP;
410 b_timed_peq.notify(*req, end_resp, delay);
414template <
typename TYPES>
void tlm_recorder<TYPES>::btx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase) {
415 SCVNS scv_tr_handle h;
418 case tlm::BEGIN_REQ: {
419 h = b_trTimedHandle[rec_parts.get_command()]->begin_transaction();
421 btx_handle_map[rec_parts.id] = h;
423 case tlm::END_RESP: {
424 auto it = btx_handle_map.find(rec_parts.id);
425 sc_assert(it != btx_handle_map.end());
427 btx_handle_map.erase(it);
428 record(h, rec_parts);
433 sc_assert(!
"phase not supported!");
438template <
typename TYPES>
440 sc_core::sc_time& delay) {
442 return fw_port->nb_transport_fw(trans, phase, delay);
443 else if(!nb_streamHandle)
444 initialize_streams();
449 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase2string(phase));
451 trans.get_extension(preExt);
452 if(preExt ==
nullptr) {
455 trans.set_auto_extension(preExt);
457 trans.set_extension(preExt);
465 h.record_attribute(
"delay", delay.to_string());
466 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
467 if(extensionRecording)
468 extensionRecording->recordBeginTx(h, trans);
472 if(nb_streamHandleTimed) {
473 auto* req =
mm::get().allocate();
477 nb_timed_peq.notify(*req, phase, delay);
482 tlm::tlm_sync_enum status =
fw_port->nb_transport_fw(trans, phase, delay);
487 h.record_attribute(
"delay[return_path]", delay.to_string());
489 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
490 if(extensionRecording)
491 extensionRecording->recordEndTx(h, trans);
493 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
494 trans.get_extension(preExt);
497 if(!trans.has_mm()) {
504 if(nb_streamHandleTimed) {
505 tlm_recording_payload* req =
mm::get().allocate();
509 tlm::tlm_phase end_resp = tlm::END_RESP;
510 nb_timed_peq.notify(*req, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? end_resp : phase, delay);
512 }
else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
513 tlm_recording_payload* req =
mm::get().allocate();
517 nb_timed_peq.notify(*req, phase, delay);
520 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
524template <
typename TYPES>
526 sc_core::sc_time& delay) {
528 return bw_port->nb_transport_bw(trans, phase, delay);
529 else if(!nb_streamHandle)
530 initialize_streams();
535 trans.get_extension(preExt);
538 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
545 h.record_attribute(
"delay", delay.to_string());
546 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
547 if(extensionRecording)
548 extensionRecording->recordBeginTx(h, trans);
552 if(nb_streamHandleTimed) {
553 tlm_recording_payload* req =
mm::get().allocate();
557 nb_timed_peq.notify(*req, phase, delay);
562 tlm::tlm_sync_enum status =
bw_port->nb_transport_bw(trans, phase, delay);
567 h.record_attribute(
"delay[return_path]", delay.to_string());
569 for(
auto& extensionRecording : tlm_extension_recording_registry<TYPES>::inst().get())
570 if(extensionRecording)
571 extensionRecording->recordEndTx(h, trans);
573 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
574 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
579 if(!trans.has_mm()) {
586 if(nb_streamHandleTimed) {
587 tlm_recording_payload* req =
mm::get().allocate();
591 nb_timed_peq.notify(*req, phase, delay);
597template <
typename TYPES>
void tlm_recorder<TYPES>::nbtx_cb(tlm_recording_payload& rec_parts,
const typename TYPES::tlm_phase_type& phase) {
598 SCVNS scv_tr_handle h;
599 std::unordered_map<uint64_t, SCVNS scv_tr_handle>::iterator it;
603 record(h, rec_parts);
604 nbtx_req_handle_map[rec_parts.id] = h;
607 it = nbtx_req_handle_map.find(rec_parts.id);
608 sc_assert(it != nbtx_req_handle_map.end());
610 nbtx_req_handle_map.erase(it);
612 nbtx_last_req_handle_map[rec_parts.id] = h;
614 case tlm::BEGIN_RESP:
615 it = nbtx_req_handle_map.find(rec_parts.id);
616 if(it != nbtx_req_handle_map.end()) {
618 nbtx_req_handle_map.erase(it);
620 nbtx_last_req_handle_map[rec_parts.id] = h;
623 record(h, rec_parts);
624 nbtx_req_handle_map[rec_parts.id] = h;
625 it = nbtx_last_req_handle_map.find(rec_parts.id);
626 if(it != nbtx_last_req_handle_map.end()) {
627 SCVNS scv_tr_handle pred = it->second;
628 nbtx_last_req_handle_map.erase(it);
633 it = nbtx_req_handle_map.find(rec_parts.id);
634 if(it != nbtx_req_handle_map.end()) {
636 nbtx_req_handle_map.erase(it);
650 return fw_port->get_direct_mem_ptr(trans, dmi_data);
651 else if(!dmi_streamHandle)
652 initialize_streams();
653 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
654 bool status =
fw_port->get_direct_mem_ptr(trans, dmi_data);
668 bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
670 }
else if(!dmi_streamHandle)
671 initialize_streams();
672 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
673 bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
674 dmi_trInvalidateHandle->end_transaction(h, end_addr);
684 unsigned int count =
fw_port->transport_dbg(trans);