scc 2026.07
SystemC components library
axi_recorder.h
1/*
2 * Copyright 2020, 2021 Arteris IP
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#pragma once
18
19#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
20#define SC_INCLUDE_DYNAMIC_PROCESSES
21#endif
22
23#include <array>
24#include <axi/axi_tlm.h>
25#include <axi/checker/axi_protocol.h>
26#include <cci_configuration>
27#include <regex>
28#include <string>
29#include <tlm/scc/scv/tlm_recorder.h>
30#include <tlm/scc/scv/tlm_recording_extension.h>
31#include <tlm_utils/peq_with_cb_and_phase.h>
32#include <unordered_map>
33#include <vector>
34
36namespace axi {
37namespace scv {
38
39bool register_extensions();
40
49template <typename TYPES = axi::axi_protocol_types>
50class axi_recorder : public virtual axi::axi_fw_transport_if<TYPES>, public virtual axi::axi_bw_transport_if<TYPES> {
51public:
52 template <unsigned int BUSWIDTH = 32, int N = 1, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
53 using initiator_socket_type = axi::axi_initiator_socket<BUSWIDTH, TYPES, N, POL>;
54
55 template <unsigned int BUSWIDTH = 32, int N = 1, sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
56 using target_socket_type = axi::axi_target_socket<BUSWIDTH, TYPES, N, POL>;
57
59 cci::cci_param<bool> enableBlTracing;
60
62 cci::cci_param<bool> enableNbTracing;
63
65 cci::cci_param<bool> enableTimedTracing{"enableTimedTracing", true};
66
68 cci::cci_param<bool> enableDmiTracing{"enableDmiTracing", false};
69
71 cci::cci_param<bool> enableTrDbgTracing{"enableTrDbgTracing", false};
72
74 cci::cci_param<bool> enableProtocolChecker{"enableProtocolChecker", false};
75
76 cci::cci_param<unsigned> rd_response_timeout{"rd_response_timeout", 0};
77
78 cci::cci_param<unsigned> wr_response_timeout{"wr_response_timeout", 0};
79
81 virtual tlm::tlm_fw_transport_if<TYPES>* get_fw_if() = 0;
82
84 virtual tlm::tlm_bw_transport_if<TYPES>* get_bw_if() = 0;
85
94 axi_recorder(const char* name, unsigned bus_width, bool recording_enabled = true,
95 SCVNS scv_tr_db* tr_db = SCVNS scv_tr_db::get_default_db())
96 : enableBlTracing("enableBlTracing", recording_enabled)
97 , enableNbTracing("enableNbTracing", recording_enabled)
98 , bus_width(bus_width)
99 , m_db(tr_db)
100 , fixed_basename(name) {
101 register_extensions();
102 }
103
104 virtual ~axi_recorder() override {
105 nbtx_req_handle_map.clear();
106 nbtx_last_req_handle_map.clear();
107 nbtx_resp_handle_map.clear();
108 nbtx_last_resp_handle_map.clear();
109 delete b_streamHandle;
110 for(auto* p : b_trHandle)
111 delete p; // NOLINT
112 delete b_streamHandleTimed;
113 for(auto* p : b_trTimedHandle)
114 delete p; // NOLINT
115 delete nb_streamHandle;
116 for(auto* p : nb_trHandle)
117 delete p; // NOLINT
118 delete nb_streamHandleTimed;
119 for(auto* p : nb_trTimedHandle)
120 delete p; // NOLINT
121 delete dmi_streamHandle;
122 delete dmi_trGetHandle;
123 delete dmi_trInvalidateHandle;
124 delete checker;
125 }
126
127 // TLM-2.0 interface methods for initiator and target sockets, surrounded with
128 // Tx Recording
138 tlm::tlm_sync_enum nb_transport_fw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
139 sc_core::sc_time& delay) override;
149 tlm::tlm_sync_enum nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
150 sc_core::sc_time& delay) override;
159 void b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) override;
167 bool get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) override;
174 void invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) override;
181 unsigned int transport_dbg(typename TYPES::tlm_payload_type& trans) override;
187 inline bool isRecordingBlockingTxEnabled() const { return m_db && enableBlTracing.get_value(); }
193 inline bool isRecordingNonBlockingTxEnabled() const { return m_db && enableNbTracing.get_value(); }
194
195private:
200 void record_nb_tx(typename TYPES::tlm_payload_type&, const typename TYPES::tlm_phase_type&, sc_core::sc_time, SCVNS scv_tr_handle);
201 const unsigned bus_width{0};
203 SCVNS scv_tr_db* m_db{nullptr};
205 SCVNS scv_tr_stream* b_streamHandle{nullptr};
207 std::array<SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>*, 3> b_trHandle{{nullptr, nullptr, nullptr}};
209 SCVNS scv_tr_stream* b_streamHandleTimed{nullptr};
212 std::array<SCVNS scv_tr_generator<>*, 3> b_trTimedHandle{{nullptr, nullptr, nullptr}};
213
214 enum DIR { FW, BW, REQ = FW, RESP = BW };
216 SCVNS scv_tr_stream* nb_streamHandle{nullptr};
218 SCVNS scv_tr_stream* nb_streamHandleTimed{nullptr};
220 std::array<SCVNS scv_tr_generator<std::string, std::string>*, 2> nb_trHandle{{nullptr, nullptr}};
222 std::array<SCVNS scv_tr_generator<>*, 2> nb_trTimedHandle{{nullptr, nullptr}};
223 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_req_handle_map;
224 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_req_handle_map;
225 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_resp_handle_map;
226 std::unordered_map<uint64_t, SCVNS scv_tr_handle> nbtx_last_resp_handle_map;
228 SCVNS scv_tr_stream* dmi_streamHandle{nullptr};
230 SCVNS scv_tr_generator<>* dmi_trGetHandle{nullptr};
231 SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>* dmi_trInvalidateHandle{nullptr};
232
233protected:
234 void initialize_streams() {
236 b_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_bl").c_str(), "[TLM][axi][b]", m_db);
237 b_trHandle[tlm::TLM_READ_COMMAND] =
238 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("read", *b_streamHandle, "start_delay", "end_delay");
239 b_trHandle[tlm::TLM_WRITE_COMMAND] =
240 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("write", *b_streamHandle, "start_delay", "end_delay");
241 b_trHandle[tlm::TLM_IGNORE_COMMAND] =
242 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("ignore", *b_streamHandle, "start_delay", "end_delay");
243 if(enableTimedTracing.get_value()) {
244 b_streamHandleTimed = new SCVNS scv_tr_stream((fixed_basename + "_bl_timed").c_str(), "[TLM][axi][b][timed]", m_db);
245 b_trTimedHandle[tlm::TLM_READ_COMMAND] = new SCVNS scv_tr_generator<>("read", *b_streamHandleTimed);
246 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] = new SCVNS scv_tr_generator<>("write", *b_streamHandleTimed);
247 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] = new SCVNS scv_tr_generator<>("ignore", *b_streamHandleTimed);
248 }
249 }
251 nb_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_nb").c_str(), "[TLM][axi][nb]", m_db);
252 nb_trHandle[FW] =
253 new SCVNS scv_tr_generator<std::string, std::string>("fw", *nb_streamHandle, "tlm_phase", "tlm_phase[return_path]");
254 nb_trHandle[BW] =
255 new SCVNS scv_tr_generator<std::string, std::string>("bw", *nb_streamHandle, "tlm_phase", "tlm_phase[return_path]");
256 if(enableTimedTracing.get_value()) {
257 nb_streamHandleTimed = new SCVNS scv_tr_stream((fixed_basename + "_nb_timed").c_str(), "[TLM][axi][nb][timed]", m_db);
258 nb_trTimedHandle[FW] = new SCVNS scv_tr_generator<>("request", *nb_streamHandleTimed);
259 nb_trTimedHandle[BW] = new SCVNS scv_tr_generator<>("response", *nb_streamHandleTimed);
260 }
261 }
262 if(m_db && enableDmiTracing.get_value() && !dmi_streamHandle) {
263 dmi_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_dmi").c_str(), "[TLM][axi][dmi]", m_db);
264 dmi_trGetHandle = new SCVNS scv_tr_generator<>("get", *dmi_streamHandle);
265 dmi_trInvalidateHandle =
266 new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>("invalidate", *dmi_streamHandle, "start_addr", "end_addr");
267 }
268 if(enableProtocolChecker.get_value()) {
269 checker = new axi::checker::axi_protocol(fixed_basename, bus_width / 8, rd_response_timeout.get_value(),
270 wr_response_timeout.get_value());
271 }
272 }
273
274private:
275 const std::string fixed_basename;
276 axi::checker::checker_if<TYPES>* checker{nullptr};
277 inline std::string phase2string(const tlm::tlm_phase& p) {
278 std::stringstream ss;
279 ss << p;
280 return ss.str();
281 }
282};
283
285// implementations of functions
287
288template <typename TYPES> void axi_recorder<TYPES>::b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) {
290 get_fw_if()->b_transport(trans, delay);
291 return;
292 }
293 // Get a handle for the new transaction
294 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
295 /*************************************************************************
296 * do the timed notification
297 *************************************************************************/
298 SCVNS scv_tr_handle bh;
299 if(b_streamHandleTimed) {
300 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp() + delay);
302 }
303
304 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
305 if(ext)
306 ext->recordBeginTx(h, trans);
308
309 trans.get_extension(preExt);
310 if(preExt == nullptr) { // we are the first recording this transaction
311 preExt = new tlm::scc::scv::tlm_recording_extension(h, this);
312 if(trans.has_mm())
313 trans.set_auto_extension(preExt);
314 else
315 trans.set_extension(preExt);
316 } else {
318 }
319 SCVNS scv_tr_handle preTx(preExt->txHandle);
320 preExt->txHandle = h;
321 get_fw_if()->b_transport(trans, delay);
322 trans.get_extension(preExt);
323 if(preExt->get_creator() == this) {
324 // clean-up the extension if this is the original creator
325 if(trans.has_mm())
326 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
327 else
328 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
329 } else {
330 preExt->txHandle = preTx;
331 }
332
333 tlm::scc::scv::record(h, trans);
334 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
335 if(ext)
336 ext->recordEndTx(h, trans);
337 // End the transaction
338 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
339 // and now the stuff for the timed tx
340 if(bh.is_valid()) {
341 tlm::scc::scv::record(h, trans);
342 b_trTimedHandle[trans.get_command()]->end_transaction(bh, sc_core::sc_time_stamp() + delay);
343 }
344}
345
346template <typename TYPES>
347tlm::tlm_sync_enum axi_recorder<TYPES>::nb_transport_fw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
348 sc_core::sc_time& delay) {
350 if(checker) {
351 checker->fw_pre(trans, phase);
352 tlm::tlm_sync_enum status = get_fw_if()->nb_transport_fw(trans, phase, delay);
353 checker->fw_post(trans, phase, status);
354 return status;
355 } else
356 return get_fw_if()->nb_transport_fw(trans, phase, delay);
357 }
358 /*************************************************************************
359 * prepare recording
360 *************************************************************************/
361 // Get a handle for the new transaction
362 SCVNS scv_tr_handle h = nb_trHandle[FW]->begin_transaction(phase2string(phase));
364 trans.get_extension(preExt);
365 if((phase == axi::BEGIN_PARTIAL_REQ || phase == tlm::BEGIN_REQ) && preExt == nullptr) { // we are the first recording this transaction
366 preExt = new tlm::scc::scv::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 if(preExt != nullptr) {
372 // link handle if we have a predecessor
374 } else {
375 sc_assert(preExt != nullptr && "ERROR on forward path in phase other than tlm::BEGIN_REQ");
376 }
377 // update the extension
378 preExt->txHandle = h;
379 h.record_attribute("delay", delay.to_string());
380 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
381 if(ext)
382 ext->recordBeginTx(h, trans);
383 /*************************************************************************
384 * do the timed notification
385 *************************************************************************/
386 if(nb_streamHandleTimed) {
387 record_nb_tx(trans, phase, delay, h);
388 }
389 /*************************************************************************
390 * do the access
391 *************************************************************************/
392 if(checker)
393 checker->fw_pre(trans, phase);
394 tlm::tlm_sync_enum status = get_fw_if()->nb_transport_fw(trans, phase, delay);
395 if(checker)
396 checker->fw_post(trans, phase, status);
397 /*************************************************************************
398 * handle recording
399 *************************************************************************/
400 tlm::scc::scv::record(h, status);
401 h.record_attribute("delay[return_path]", delay.to_string());
402 tlm::scc::scv::record(h, trans);
403 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
404 if(ext)
405 ext->recordEndTx(h, trans);
406 // get the extension and free the memory if it was mine
407 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
408 // the transaction is finished
409 trans.get_extension(preExt);
410 if(preExt && preExt->get_creator() == this) {
411 // clean-up the extension if this is the original creator
412 if(trans.has_mm())
413 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
414 else
415 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
416 }
417 /*************************************************************************
418 * do the timed notification if req. finished here
419 *************************************************************************/
420 if(nb_streamHandleTimed) {
421 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
422 }
423 } else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
424 record_nb_tx(trans, phase, delay, h);
425 }
426 // End the transaction
427 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
428 return status;
429}
430
431template <typename TYPES>
432tlm::tlm_sync_enum axi_recorder<TYPES>::nb_transport_bw(typename TYPES::tlm_payload_type& trans, typename TYPES::tlm_phase_type& phase,
433 sc_core::sc_time& delay) {
435 if(checker) {
436 checker->bw_pre(trans, phase);
437 tlm::tlm_sync_enum status = get_bw_if()->nb_transport_bw(trans, phase, delay);
438 checker->bw_post(trans, phase, status);
439 return status;
440 } else
441 return get_bw_if()->nb_transport_bw(trans, phase, delay);
442 }
443 /*************************************************************************
444 * prepare recording
445 *************************************************************************/
446 // Get a handle for the new transaction
447 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
449 trans.get_extension(preExt);
450 if(phase == tlm::BEGIN_REQ && preExt == nullptr) { // we are the first recording this transaction
451 preExt = new tlm::scc::scv::tlm_recording_extension(h, this);
452 if(trans.has_mm())
453 trans.set_auto_extension(preExt);
454 else
455 trans.set_extension(preExt);
456 } else if(preExt != nullptr) {
457 // link handle if we have a predecessor
459 } else {
460 sc_assert(preExt != nullptr && "ERROR on backward path in phase other than tlm::BEGIN_REQ");
461 }
462 // and set the extension handle to this transaction
463 preExt->txHandle = h;
464 h.record_attribute("delay", delay.to_string());
465 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
466 if(ext)
467 ext->recordBeginTx(h, trans);
468 /*************************************************************************
469 * do the timed notification
470 *************************************************************************/
471 if(nb_streamHandleTimed) {
472 record_nb_tx(trans, phase, delay, h);
473 }
474 /*************************************************************************
475 * do the access
476 *************************************************************************/
477 if(checker)
478 checker->bw_pre(trans, phase);
479 tlm::tlm_sync_enum status = get_bw_if()->nb_transport_bw(trans, phase, delay);
480 if(checker)
481 checker->bw_post(trans, phase, status);
482 /*************************************************************************
483 * handle recording
484 *************************************************************************/
485 tlm::scc::scv::record(h, status);
486 h.record_attribute("delay[return_path]", delay.to_string());
487 tlm::scc::scv::record(h, trans);
488 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::get())
489 if(ext)
490 ext->recordEndTx(h, trans);
491 // get the extension and free the memory if it was mine
492 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
493 // the transaction is finished
494 trans.get_extension(preExt);
495 if(preExt->get_creator() == this) {
496 // clean-up the extension if this is the original creator
497 if(trans.has_mm())
498 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
499 else
500 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
501 }
502 /*************************************************************************
503 * do the timed notification if req. finished here
504 *************************************************************************/
505 if(nb_streamHandleTimed) {
506 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
507 }
508 } else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
509 record_nb_tx(trans, phase, delay, h);
510 }
511 // End the transaction
512 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
513 return status;
514}
515
516template <typename TYPES>
517void axi_recorder<TYPES>::record_nb_tx(typename TYPES::tlm_payload_type& trans, const typename TYPES::tlm_phase_type& phase,
518 sc_core::sc_time delay, SCVNS scv_tr_handle parent) {
519 SCVNS scv_tr_handle h;
520 // Now process outstanding recordings
521 auto t = sc_core::sc_time_stamp() + delay;
522 auto id = reinterpret_cast<uintptr_t>(&trans);
523 if(phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
524 h = nb_trTimedHandle[REQ]->begin_transaction(t);
525 tlm::scc::scv::record(h, trans);
527 nbtx_req_handle_map[id] = h;
528 } else if(phase == tlm::END_REQ || phase == axi::END_PARTIAL_REQ) {
529 auto it = nbtx_req_handle_map.find(id);
530 if(it != nbtx_req_handle_map.end()) {
531 h = it->second;
532 nbtx_req_handle_map.erase(it);
533 h.end_transaction(t);
534 nbtx_last_req_handle_map[id] = h;
535 }
536 } else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
537 auto it = nbtx_req_handle_map.find(id);
538 if(it != nbtx_req_handle_map.end()) {
539 h = it->second;
540 nbtx_req_handle_map.erase(it);
541 h.end_transaction(t);
542 nbtx_last_req_handle_map[id] = h;
543 }
544 h = nb_trTimedHandle[RESP]->begin_transaction(t);
545 tlm::scc::scv::record(h, trans);
547 nbtx_resp_handle_map[id] = h;
548 it = nbtx_last_req_handle_map.find(id);
549 if(it != nbtx_last_req_handle_map.end()) {
550 SCVNS scv_tr_handle& pred = it->second;
552 nbtx_last_req_handle_map.erase(it);
553 } else {
554 it = nbtx_last_resp_handle_map.find(id);
555 if(it != nbtx_last_resp_handle_map.end()) {
556 SCVNS scv_tr_handle& pred = it->second;
558 nbtx_last_resp_handle_map.erase(it);
559 }
560 }
561 } else if(phase == tlm::END_RESP || phase == axi::END_PARTIAL_RESP) {
562 auto it = nbtx_resp_handle_map.find(id);
563 if(it != nbtx_resp_handle_map.end()) {
564 h = it->second;
565 nbtx_resp_handle_map.erase(it);
566 h.end_transaction(t);
567 if(phase == axi::END_PARTIAL_RESP) {
568 nbtx_last_resp_handle_map[id] = h;
569 }
570 }
571 } else
572 sc_assert(!"phase not supported!");
573 return;
574}
575
576template <typename TYPES> bool axi_recorder<TYPES>::get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) {
577 if(!(m_db && enableDmiTracing.get_value()))
578 return get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
579 else if(!dmi_streamHandle)
580 initialize_streams();
581 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
582 bool status = get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
583 tlm::scc::scv::record(h, trans);
584 tlm::scc::scv::record(h, dmi_data);
585 h.end_transaction();
586 return status;
587}
588
594template <typename TYPES> void axi_recorder<TYPES>::invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) {
595 if(!(m_db && enableDmiTracing.get_value())) {
596 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
597 return;
598 } else if(!dmi_streamHandle)
599 initialize_streams();
600 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
601 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
602 dmi_trInvalidateHandle->end_transaction(h, end_addr);
603 return;
604}
605
611template <typename TYPES> unsigned int axi_recorder<TYPES>::transport_dbg(typename TYPES::tlm_payload_type& trans) {
612 unsigned int count = get_fw_if()->transport_dbg(trans);
613 return count;
614}
615} // namespace scv
616} // namespace axi
The TLM2 transaction recorder.
virtual tlm::tlm_bw_transport_if< TYPES > * get_bw_if()=0
the port where bw accesses are forwarded to
bool isRecordingNonBlockingTxEnabled() const
get the current state of transaction recording
cci::cci_param< bool > enableTrDbgTracing
the attribute to selectively enable/disable transport dbg recording
void b_transport(typename TYPES::tlm_payload_type &trans, sc_core::sc_time &delay) override
The blocking transport 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.
cci::cci_param< bool > enableProtocolChecker
the attribute to enable/disable protocol checking
void invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) override
The direct memory interface backward function.
bool get_direct_mem_ptr(typename TYPES::tlm_payload_type &trans, tlm::tlm_dmi &dmi_data) override
The direct memory interface forward function.
bool isRecordingBlockingTxEnabled() const
get the current state of transaction recording
cci::cci_param< bool > enableNbTracing
the attribute to selectively enable/disable recording of non-blocking protocol tx
cci::cci_param< bool > enableDmiTracing
the attribute to selectively enable/disable DMI recording
virtual tlm::tlm_fw_transport_if< TYPES > * get_fw_if()=0
the port where fw accesses are forwarded to
cci::cci_param< bool > enableBlTracing
the attribute to selectively enable/disable recording of blocking protocol tx
axi_recorder(const char *name, unsigned bus_width, bool recording_enabled=true, SCVNS scv_tr_db *tr_db=SCVNS scv_tr_db::get_default_db())
The constructor of the component.
unsigned int transport_dbg(typename TYPES::tlm_payload_type &trans) override
The debug transportfunction.
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.
cci::cci_param< bool > enableTimedTracing
the attribute to selectively enable/disable timed recording
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.
TLM2.0 components modeling AHB.
tlm::tlm_bw_transport_if< TYPES > axi_bw_transport_if
alias declaration for the backward interface:
Definition axi_tlm.h:953
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition axi_tlm.h:951
const char * rel_str(tx_rel rel)
cast the tx_rel enum to a string