scc 2026.07
SystemC components library
tlm_recorder.h
1/*******************************************************************************
2 * Copyright 2016-2022 MINRES Technologies GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *******************************************************************************/
16
17#ifndef TLM2_RECORDER_H_
18#define TLM2_RECORDER_H_
19
20#include "tlm_extension_recording_registry.h"
21#include "tlm_recording_extension.h"
22#include <array>
23#include <regex>
24#include <sstream>
25#include <string>
26#include <sysc/kernel/sc_dynamic_processes.h>
27#include <tlm/scc/tlm_mm.h>
28#include <tlm>
29#include <tlm_utils/peq_with_cb_and_phase.h>
30#include <unordered_map>
31#ifdef HAS_SCV
32#include <scv.h>
33#else
34#include <scv-tr.h>
35#ifndef SCVNS
36#define SCVNS ::scv_tr::
37#endif
38#endif
39
41namespace tlm {
43namespace scc {
45namespace scv {
46
47void record(SCVNS scv_tr_handle&, tlm::tlm_generic_payload const&);
48void record(SCVNS scv_tr_handle&, tlm::tlm_phase const&);
49void record(SCVNS scv_tr_handle&, tlm::tlm_sync_enum);
50void record(SCVNS scv_tr_handle&, tlm::tlm_dmi const&);
51
52namespace impl {
53template <typename TYPES = tlm::tlm_base_protocol_types> class tlm_recording_payload : public TYPES::tlm_payload_type {
54public:
55 SCVNS scv_tr_handle parent;
56 uint64_t id;
57 tlm::tlm_sync_enum sync{tlm::TLM_ACCEPTED};
58 tlm_recording_payload& operator=(const typename TYPES::tlm_payload_type& x) {
59 id = reinterpret_cast<uintptr_t>(&x);
60 this->set_command(x.get_command());
61 this->set_address(x.get_address());
62 this->set_data_ptr(nullptr);
63 this->set_data_length(x.get_data_length());
64 this->set_response_status(x.get_response_status());
65 this->set_byte_enable_ptr(nullptr);
66 this->set_byte_enable_length(x.get_byte_enable_length());
67 this->set_streaming_width(x.get_streaming_width());
68 return (*this);
69 }
70 explicit tlm_recording_payload(tlm::tlm_mm_interface* mm)
71 : TYPES::tlm_payload_type(mm)
72 , parent()
73 , id(0) {}
74};
75template <typename TYPES = tlm::tlm_base_protocol_types> struct tlm_recording_types {
76 using tlm_payload_type = tlm_recording_payload<TYPES>;
77 using tlm_phase_type = typename TYPES::tlm_phase_type;
78};
79
80} // namespace impl
89template <typename TYPES = tlm::tlm_base_protocol_types>
90class tlm_recorder : public virtual tlm::tlm_fw_transport_if<TYPES>, public virtual tlm::tlm_bw_transport_if<TYPES> {
91 std::string get_parent(char const* hier_name) {
92 std::string ret(hier_name);
93 auto pos = ret.rfind('.');
94 return pos == std::string::npos ? ret : ret.substr(0, pos);
95 }
96
97public:
98 using recording_types = impl::tlm_recording_types<TYPES>;
100 using tlm_recording_payload = impl::tlm_recording_payload<TYPES>;
101
103 sc_core::sc_attribute<bool> enableBlTracing;
104
106 sc_core::sc_attribute<bool> enableNbTracing;
107
109 sc_core::sc_attribute<bool> enableTimedTracing{"enableTimedTracing", true};
110
112 sc_core::sc_attribute<bool> enableDmiTracing{"enableDmiTracing", false};
113
115 sc_core::sc_port_b<tlm::tlm_fw_transport_if<TYPES>>& fw_port;
116
118 sc_core::sc_port_b<tlm::tlm_bw_transport_if<TYPES>>& bw_port;
119
133 tlm_recorder(sc_core::sc_port_b<tlm::tlm_fw_transport_if<TYPES>>& fw_port, sc_core::sc_port_b<tlm::tlm_bw_transport_if<TYPES>>& bw_port,
134 bool recording_enabled = true, SCVNS scv_tr_db* tr_db = SCVNS scv_tr_db::get_default_db())
135 : tlm_recorder(sc_core::sc_gen_unique_name("tlm_recorder"), fw_port, bw_port, recording_enabled, tr_db) {}
150 tlm_recorder(const char* name, sc_core::sc_port_b<tlm::tlm_fw_transport_if<TYPES>>& fw_port,
151 sc_core::sc_port_b<tlm::tlm_bw_transport_if<TYPES>>& bw_port, bool recording_enabled = true,
152 SCVNS scv_tr_db* tr_db = SCVNS scv_tr_db::get_default_db())
153 : enableBlTracing("enableBlTracing", recording_enabled)
154 , enableNbTracing("enableNbTracing", recording_enabled)
157 , nb_timed_peq(this, &tlm_recorder::nbtx_cb)
158 , m_db(tr_db)
159 , fixed_basename(name) {}
160
161 virtual ~tlm_recorder() override {
162 nbtx_req_handle_map.clear();
163 nbtx_last_req_handle_map.clear();
164 delete b_streamHandle;
165 for(auto* p : b_trHandle)
166 delete p; // NOLINT
167 delete b_streamHandleTimed;
168 for(auto* p : b_trTimedHandle)
169 delete p; // NOLINT
170 delete nb_streamHandle;
171 for(auto* p : nb_trHandle)
172 delete p; // NOLINT
173 delete nb_streamHandleTimed;
174 for(auto* p : nb_trTimedHandle)
175 delete p; // NOLINT
176 delete dmi_streamHandle;
177 delete dmi_trGetHandle;
178 delete dmi_trInvalidateHandle;
179 }
180
181 // TLM-2.0 interface methods for initiator and target sockets, surrounded with
182 // Tx Recording
192 tlm::tlm_sync_enum nb_transport_fw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
193 sc_core::sc_time& delay) override;
194
204 tlm::tlm_sync_enum nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
205 sc_core::sc_time& delay) override;
206
215 void b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) override;
223 bool get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) override;
230 void invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) override;
237 unsigned int transport_dbg(typename TYPES::tlm_payload_type& trans) override;
243 inline bool isRecordingBlockingTxEnabled() const { return m_db && enableBlTracing.value; }
249 inline bool isRecordingNonBlockingTxEnabled() const { return m_db && enableNbTracing.value; }
250
251private:
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}};
270
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;
282
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};
288
289public:
290 void initialize_streams() {
291 if(isRecordingBlockingTxEnabled() && !b_streamHandle) {
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");
299 if(enableTimedTracing.value) {
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);
305 }
306 }
307 if(isRecordingNonBlockingTxEnabled() && !nb_streamHandle) {
308 nb_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_nb").c_str(), "[TLM][base-protocol][nb]", m_db);
309 nb_trHandle[FW] =
310 new SCVNS scv_tr_generator<std::string, std::string>("fw", *nb_streamHandle, "tlm_phase", "tlm_phase[return_path]");
311 nb_trHandle[BW] =
312 new SCVNS scv_tr_generator<std::string, std::string>("bw", *nb_streamHandle, "tlm_phase", "tlm_phase[return_path]");
313 if(enableTimedTracing.value) {
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);
318 }
319 }
320 if(m_db && enableDmiTracing.value && !dmi_streamHandle) {
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");
325 }
326 }
327
328private:
329 const std::string fixed_basename;
330 inline std::string phase2string(const tlm::tlm_phase& p) {
331 std::stringstream ss;
332 ss << p;
333 return ss.str();
334 }
335};
336
338// implementations of functions
340
341template <typename TYPES> void tlm_recorder<TYPES>::b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) {
342 tlm_recording_payload* req{nullptr};
344 fw_port->b_transport(trans, delay);
345 return;
346 } else if(!b_streamHandle)
347 initialize_streams();
348 // Get a handle for the new transaction
349 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
350 /*************************************************************************
351 * do the timed notification
352 *************************************************************************/
353 SCVNS scv_tr_handle ht;
354 if(b_streamHandleTimed) {
355 ht = b_trTimedHandle[trans.get_command()]->begin_transaction(delay);
356 h.add_relation(rel_str(PARENT_CHILD), h);
357 }
358
359 auto addr = trans.get_address();
360 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
361 extensionRecording->recordBeginTx(h, trans);
362 tlm_recording_extension* preExt = nullptr;
363
364 trans.get_extension(preExt);
365 if(preExt == nullptr) { // we are the first recording this transaction
366 preExt = new tlm_recording_extension(h, this);
367 if(trans.has_mm())
368 trans.set_auto_extension(preExt);
369 else
370 trans.set_extension(preExt);
371 } else {
372 h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
373 }
374 SCVNS scv_tr_handle preTx{preExt->txHandle};
375 preExt->txHandle = h;
376 fw_port->b_transport(trans, delay);
377 if(preExt && preExt->get_creator() == this) {
378 // clean-up the extension if this is the original creator
379 trans.set_extension(static_cast<tlm_recording_extension*>(nullptr));
380 if(!trans.has_mm()) {
381 delete preExt;
382 }
383 } else {
384 preExt->txHandle = preTx;
385 }
386 trans.set_address(addr);
387 record(h, trans);
388 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
389 extensionRecording->recordEndTx(h, trans);
390 // End the transaction
391 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
392 // and now the stuff for the timed tx
393 if(ht.is_valid() && ht.is_active()) {
394 record(ht, trans);
395 ht.end_transaction(delay);
396 }
397}
398
399template <typename TYPES>
400tlm::tlm_sync_enum tlm_recorder<TYPES>::nb_transport_fw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
401 sc_core::sc_time& delay) {
403 return fw_port->nb_transport_fw(trans, phase, delay);
404 else if(!nb_streamHandle)
405 initialize_streams();
406 /*************************************************************************
407 * prepare recording
408 *************************************************************************/
409 // Get a handle for the new transaction
410 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase2string(phase));
411 tlm_recording_extension* preExt = nullptr;
412 trans.get_extension(preExt);
413 if(preExt == nullptr) { // we are the first recording this transaction
414 preExt = new tlm_recording_extension(h, this);
415 if(trans.has_mm())
416 trans.set_auto_extension(preExt);
417 else
418 trans.set_extension(preExt);
419 } else {
420 // link handle if we have a predecessor
421 h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
422 }
423 // update the extension
424 if(preExt)
425 preExt->txHandle = h;
426 h.record_attribute("delay", delay.to_string());
427 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
428 extensionRecording->recordBeginTx(h, trans);
429 /*************************************************************************
430 * do the timed notification
431 *************************************************************************/
432 if(nb_streamHandleTimed) {
433 auto* req = mm::get().allocate();
434 req->acquire();
435 (*req) = trans;
436 req->parent = h;
437 nb_timed_peq.notify(*req, phase, delay);
438 }
439 /*************************************************************************
440 * do the access
441 *************************************************************************/
442 tlm::tlm_sync_enum status = fw_port->nb_transport_fw(trans, phase, delay);
443 /*************************************************************************
444 * handle recording
445 *************************************************************************/
446 record(h, status);
447 h.record_attribute("delay[return_path]", delay.to_string());
448 record(h, trans);
449 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
450 extensionRecording->recordEndTx(h, trans);
451 // get the extension and free the memory if it was mine
452 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
453 trans.get_extension(preExt);
454 if(preExt && preExt->get_creator() == this) {
455 trans.set_extension(static_cast<tlm_recording_extension*>(nullptr));
456 if(!trans.has_mm()) {
457 delete preExt;
458 }
459 }
460 /*************************************************************************
461 * do the timed notification if req. finished here
462 *************************************************************************/
463 if(nb_streamHandleTimed) {
464 auto* req = mm::get().allocate();
465 req->acquire();
466 (*req) = trans;
467 req->parent = h;
468 req->sync = status;
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);
471 }
472 } else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
473 tlm_recording_payload* req = mm::get().allocate();
474 req->acquire();
475 (*req) = trans;
476 req->parent = h;
477 req->sync = status;
478 nb_timed_peq.notify(*req, phase, delay);
479 }
480 // End the transaction
481 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
482 return status;
483}
484
485template <typename TYPES>
486tlm::tlm_sync_enum tlm_recorder<TYPES>::nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
487 sc_core::sc_time& delay) {
489 return bw_port->nb_transport_bw(trans, phase, delay);
490 else if(!nb_streamHandle)
491 initialize_streams();
492 /*************************************************************************
493 * prepare recording
494 *************************************************************************/
495 tlm_recording_extension* preExt = nullptr;
496 trans.get_extension(preExt);
497 // sc_assert(preExt != nullptr && "ERROR on backward path");
498 // Get a handle for the new transaction
499 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
500 // link handle if we have a predecessor and that's not ourself
501 if(preExt) {
502 h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), preExt->txHandle);
503 // and set the extension handle to this transaction
504 preExt->txHandle = h;
505 }
506 h.record_attribute("delay", delay.to_string());
507 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
508 extensionRecording->recordBeginTx(h, trans);
509 /*************************************************************************
510 * do the timed notification
511 *************************************************************************/
512 if(nb_streamHandleTimed) {
513 tlm_recording_payload* req = mm::get().allocate();
514 req->acquire();
515 (*req) = trans;
516 req->parent = h;
517 nb_timed_peq.notify(*req, phase, delay);
518 }
519 /*************************************************************************
520 * do the access
521 *************************************************************************/
522 tlm::tlm_sync_enum status = bw_port->nb_transport_bw(trans, phase, delay);
523 /*************************************************************************
524 * handle recording
525 *************************************************************************/
526 record(h, status);
527 h.record_attribute("delay[return_path]", delay.to_string());
528 record(h, trans);
529 for(auto& extensionRecording : tlm_extension_recording_registry<TYPES>::get())
530 extensionRecording->recordEndTx(h, trans);
531 // End the transaction
532 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
533 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
534 // the transaction is finished
535 if(preExt && preExt->get_creator() == this) {
536 // clean-up the extension if this is the original creator
537 trans.set_extension(static_cast<tlm_recording_extension*>(nullptr));
538 if(!trans.has_mm()) {
539 delete preExt;
540 }
541 }
542 /*************************************************************************
543 * do the timed notification if req. finished here
544 *************************************************************************/
545 if(nb_streamHandleTimed) {
546 tlm_recording_payload* req = mm::get().allocate();
547 req->acquire();
548 (*req) = trans;
549 req->parent = h;
550 req->sync = status;
551 nb_timed_peq.notify(*req, phase, delay);
552 }
553 }
554 return status;
555}
556
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;
560 switch(phase) { // Now process outstanding recordings
561 case tlm::BEGIN_REQ:
562 h = nb_trTimedHandle[REQ]->begin_transaction(rel_str(PARENT_CHILD), rec_parts.parent);
563 record(h, rec_parts);
564 nbtx_req_handle_map[rec_parts.id] = h;
565 break;
566 case tlm::END_REQ:
567 it = nbtx_req_handle_map.find(rec_parts.id);
568 sc_assert(it != nbtx_req_handle_map.end());
569 h = it->second;
570 nbtx_req_handle_map.erase(it);
571 h.end_transaction();
572 nbtx_last_req_handle_map[rec_parts.id] = h;
573 break;
574 case tlm::BEGIN_RESP:
575 it = nbtx_req_handle_map.find(rec_parts.id);
576 if(it != nbtx_req_handle_map.end()) {
577 h = it->second;
578 nbtx_req_handle_map.erase(it);
579 h.end_transaction();
580 nbtx_last_req_handle_map[rec_parts.id] = h;
581 }
582 h = nb_trTimedHandle[RESP]->begin_transaction(rel_str(PARENT_CHILD), rec_parts.parent);
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);
589 h.add_relation(rel_str(PREDECESSOR_SUCCESSOR), pred);
590 }
591 break;
592 case tlm::END_RESP:
593 it = nbtx_req_handle_map.find(rec_parts.id);
594 if(it != nbtx_req_handle_map.end()) {
595 h = it->second;
596 nbtx_req_handle_map.erase(it);
597 h.end_transaction();
598 }
599 break;
600 default:
601 // sc_assert(!"phase not supported!");
602 break;
603 }
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()) {
607 h = it->second;
608 nbtx_req_handle_map.erase(it);
609 h.end_transaction();
610 }
611 }
612 rec_parts.release();
613 return;
614}
615
616template <typename TYPES> bool tlm_recorder<TYPES>::get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) {
617 if(!(m_db && enableDmiTracing.value))
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);
623 record(h, trans);
624 record(h, dmi_data);
625 h.end_transaction();
626 return status;
627}
628
634template <typename TYPES> void tlm_recorder<TYPES>::invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) {
635 if(!(m_db && enableDmiTracing.value)) {
636 bw_port->invalidate_direct_mem_ptr(start_addr, end_addr);
637 return;
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);
643 return;
644}
645
651template <typename TYPES> unsigned int tlm_recorder<TYPES>::transport_dbg(typename TYPES::tlm_payload_type& trans) {
652 unsigned int count = fw_port->transport_dbg(trans);
653 return count;
654}
655
656} // namespace scv
657} // namespace scc
658} // namespace tlm
659
660#endif /* TLM2_RECORDER_H_ */
The TLM2 transaction recorder.
void b_transport(typename TYPES::tlm_payload_type &trans, sc_core::sc_time &delay) override
The blocking transport function.
bool isRecordingBlockingTxEnabled() const
get the current state of transaction recording
sc_core::sc_attribute< bool > enableBlTracing
the attribute to selectively enable/disable recording of blocking protocol tx
unsigned int transport_dbg(typename TYPES::tlm_payload_type &trans) override
The debug transportfunction.
sc_core::sc_attribute< bool > enableTimedTracing
the attribute to selectively enable/disable timed recording
bool isRecordingNonBlockingTxEnabled() const
get the current state of transaction recording
bool get_direct_mem_ptr(typename TYPES::tlm_payload_type &trans, tlm::tlm_dmi &dmi_data) override
The direct memory interface forward function.
tlm::tlm_sync_enum nb_transport_fw(typename TYPES::tlm_payload_type &trans, typename TYPES::tlm_phase_type &phase, sc_core::sc_time &delay) override
The non-blocking forward transport function.
sc_core::sc_attribute< bool > enableDmiTracing
the attribute to selectively enable/disable DMI recording
sc_core::sc_attribute< bool > enableNbTracing
the attribute to selectively enable/disable recording of non-blocking protocol tx
tlm::tlm_sync_enum nb_transport_bw(typename TYPES::tlm_payload_type &trans, typename TYPES::tlm_phase_type &phase, sc_core::sc_time &delay) override
The non-blocking backward transport function.
sc_core::sc_port_b< tlm::tlm_fw_transport_if< TYPES > > & fw_port
the port where fw accesses are forwarded to
sc_core::sc_port_b< tlm::tlm_bw_transport_if< TYPES > > & bw_port
the port where bw accesses are forwarded to
void invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) override
The direct memory interface backward function.
generic payload extension class holding the handle of the last recorded SCV transaction
SCVNS scv_tr_handle txHandle
accessor to the SCV transaction handle.
void * get_creator()
accessor to the owner, the property is read only.
SCC SCV4TLM classes and functions.
const char * rel_str(tx_rel rel)
cast the tx_rel enum to a string
SCC TLM utilities.
Definition axis_tlm.h:56
SystemC TLM.
Definition dmi_mgr.h:19
a tlm memory manager
Definition tlm_mm.h:330