scc 2025.09
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 <axi/checker/axi_protocol.h>
24#include <array>
25#include <axi/axi_tlm.h>
26#include <regex>
27#include <string>
28#include <tlm/scc/scv/tlm_recorder.h>
29#include <tlm/scc/scv/tlm_recording_extension.h>
30#include <tlm_utils/peq_with_cb_and_phase.h>
31#include <unordered_map>
32#include <vector>
33#include <cci_configuration>
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] = new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
238 "read", *b_streamHandle, "start_delay", "end_delay");
239 b_trHandle[tlm::TLM_WRITE_COMMAND] = new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
240 "write", *b_streamHandle, "start_delay", "end_delay");
241 b_trHandle[tlm::TLM_IGNORE_COMMAND] = new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
242 "ignore", *b_streamHandle, "start_delay", "end_delay");
243 if(enableTimedTracing.get_value()) {
244 b_streamHandleTimed =
245 new SCVNS scv_tr_stream((fixed_basename + "_bl_timed").c_str(), "[TLM][axi][b][timed]", m_db);
246 b_trTimedHandle[tlm::TLM_READ_COMMAND] = new SCVNS scv_tr_generator<>("read", *b_streamHandleTimed);
247 b_trTimedHandle[tlm::TLM_WRITE_COMMAND] = new SCVNS scv_tr_generator<>("write", *b_streamHandleTimed);
248 b_trTimedHandle[tlm::TLM_IGNORE_COMMAND] = new SCVNS scv_tr_generator<>("ignore", *b_streamHandleTimed);
249 }
250 }
252 nb_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_nb").c_str(), "[TLM][axi][nb]", m_db);
253 nb_trHandle[FW] = new SCVNS scv_tr_generator<std::string, std::string>("fw", *nb_streamHandle, "tlm_phase",
254 "tlm_phase[return_path]");
255 nb_trHandle[BW] = new SCVNS scv_tr_generator<std::string, std::string>("bw", *nb_streamHandle, "tlm_phase",
256 "tlm_phase[return_path]");
257 if(enableTimedTracing.get_value()) {
258 nb_streamHandleTimed =
259 new SCVNS scv_tr_stream((fixed_basename + "_nb_timed").c_str(), "[TLM][axi][nb][timed]", m_db);
260 nb_trTimedHandle[FW] = new SCVNS scv_tr_generator<>("request", *nb_streamHandleTimed);
261 nb_trTimedHandle[BW] = new SCVNS scv_tr_generator<>("response", *nb_streamHandleTimed);
262 }
263 }
264 if(m_db && enableDmiTracing.get_value() && !dmi_streamHandle) {
265 dmi_streamHandle = new SCVNS scv_tr_stream((fixed_basename + "_dmi").c_str(), "[TLM][axi][dmi]", m_db);
266 dmi_trGetHandle = new SCVNS scv_tr_generator<>("get", *dmi_streamHandle);
267 dmi_trInvalidateHandle = new SCVNS scv_tr_generator<sc_dt::uint64, sc_dt::uint64>(
268 "invalidate", *dmi_streamHandle, "start_addr", "end_addr");
269 }
270 if(enableProtocolChecker.get_value()) {
271 checker=new axi::checker::axi_protocol(fixed_basename, bus_width/8, rd_response_timeout.get_value(), wr_response_timeout.get_value());
272 }
273 }
274
275private:
276 const std::string fixed_basename;
277 axi::checker::checker_if<TYPES>* checker{nullptr};
278 inline std::string phase2string(const tlm::tlm_phase& p) {
279 std::stringstream ss;
280 ss << p;
281 return ss.str();
282 }
283};
284
286// implementations of functions
288
289template <typename TYPES>
290void axi_recorder<TYPES>::b_transport(typename TYPES::tlm_payload_type& trans, sc_core::sc_time& delay) {
292 get_fw_if()->b_transport(trans, delay);
293 return;
294 }
295 // Get a handle for the new transaction
296 SCVNS scv_tr_handle h = b_trHandle[trans.get_command()]->begin_transaction(delay.value(), sc_core::sc_time_stamp());
297 /*************************************************************************
298 * do the timed notification
299 *************************************************************************/
300 SCVNS scv_tr_handle bh;
301 if(b_streamHandleTimed) {
302 bh = b_trTimedHandle[trans.get_command()]->begin_transaction(sc_core::sc_time_stamp()+delay);
304 }
305
306 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
307 if(ext)
308 ext->recordBeginTx(h, trans);
310
311 trans.get_extension(preExt);
312 if(preExt == nullptr) { // we are the first recording this transaction
313 preExt = new tlm::scc::scv::tlm_recording_extension(h, this);
314 if(trans.has_mm()) trans.set_auto_extension(preExt); else trans.set_extension(preExt);
315 } else {
317 }
318 SCVNS scv_tr_handle preTx(preExt->txHandle);
319 preExt->txHandle = h;
320 get_fw_if()->b_transport(trans, delay);
321 trans.get_extension(preExt);
322 if(preExt->get_creator() == this) {
323 // clean-up the extension if this is the original creator
324 if(trans.has_mm())
325 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
326 else
327 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
328 } else {
329 preExt->txHandle = preTx;
330 }
331
332 tlm::scc::scv::record(h, trans);
333 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
334 if(ext)
335 ext->recordEndTx(h, trans);
336 // End the transaction
337 b_trHandle[trans.get_command()]->end_transaction(h, delay.value(), sc_core::sc_time_stamp());
338 // and now the stuff for the timed tx
339 if(bh.is_valid()) {
340 tlm::scc::scv::record(h, trans);
341 b_trTimedHandle[trans.get_command()]->end_transaction(bh, sc_core::sc_time_stamp()+delay);
342 }
343}
344
345template <typename TYPES>
346tlm::tlm_sync_enum axi_recorder<TYPES>::nb_transport_fw(typename TYPES::tlm_payload_type& trans,
347 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) &&
366 preExt == nullptr) { // we are the first recording this transaction
367 preExt = new tlm::scc::scv::tlm_recording_extension(h, this);
368 if(trans.has_mm()) trans.set_auto_extension(preExt); else trans.set_extension(preExt);
369 } else if(preExt != nullptr) {
370 // link handle if we have a predecessor
372 } else {
373 sc_assert(preExt != nullptr && "ERROR on forward path in phase other than tlm::BEGIN_REQ");
374 }
375 // update the extension
376 preExt->txHandle = h;
377 h.record_attribute("delay", delay.to_string());
378 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
379 if(ext)
380 ext->recordBeginTx(h, trans);
381 /*************************************************************************
382 * do the timed notification
383 *************************************************************************/
384 if(nb_streamHandleTimed) {
385 record_nb_tx(trans, phase, delay, h);
386 }
387 /*************************************************************************
388 * do the access
389 *************************************************************************/
390 if(checker) checker->fw_pre(trans, phase);
391 tlm::tlm_sync_enum status = get_fw_if()->nb_transport_fw(trans, phase, delay);
392 if(checker) checker->fw_post(trans, phase, status);
393 /*************************************************************************
394 * handle recording
395 *************************************************************************/
396 tlm::scc::scv::record(h, status);
397 h.record_attribute("delay[return_path]", delay.to_string());
398 tlm::scc::scv::record(h, trans);
399 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
400 if(ext)
401 ext->recordEndTx(h, trans);
402 // get the extension and free the memory if it was mine
403 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_ACCEPTED && phase == tlm::END_RESP)) {
404 // the transaction is finished
405 trans.get_extension(preExt);
406 if(preExt && preExt->get_creator() == this) {
407 // clean-up the extension if this is the original creator
408 if(trans.has_mm())
409 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
410 else
411 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
412 }
413 /*************************************************************************
414 * do the timed notification if req. finished here
415 *************************************************************************/
416 if(nb_streamHandleTimed) {
417 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
418 }
419 } else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
420 record_nb_tx(trans, phase, delay, h);
421 }
422 // End the transaction
423 nb_trHandle[FW]->end_transaction(h, phase2string(phase));
424 return status;
425}
426
427template <typename TYPES>
428tlm::tlm_sync_enum axi_recorder<TYPES>::nb_transport_bw(typename TYPES::tlm_payload_type& trans,
429 typename TYPES::tlm_phase_type& phase,
430 sc_core::sc_time& delay) {
432 if(checker) {
433 checker->bw_pre(trans, phase);
434 tlm::tlm_sync_enum status = get_bw_if()->nb_transport_bw(trans, phase, delay);
435 checker->bw_post(trans, phase, status);
436 return status;
437 } else
438 return get_bw_if()->nb_transport_bw(trans, phase, delay);
439 }
440 /*************************************************************************
441 * prepare recording
442 *************************************************************************/
443 // Get a handle for the new transaction
444 SCVNS scv_tr_handle h = nb_trHandle[BW]->begin_transaction(phase2string(phase));
446 trans.get_extension(preExt);
447 if(phase == tlm::BEGIN_REQ && preExt == nullptr) { // we are the first recording this transaction
448 preExt = new tlm::scc::scv::tlm_recording_extension(h, this);
449 if(trans.has_mm()) trans.set_auto_extension(preExt); else trans.set_extension(preExt);
450 } else if(preExt != nullptr) {
451 // link handle if we have a predecessor
453 } else {
454 sc_assert(preExt != nullptr && "ERROR on backward path in phase other than tlm::BEGIN_REQ");
455 }
456 // and set the extension handle to this transaction
457 preExt->txHandle = h;
458 h.record_attribute("delay", delay.to_string());
459 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
460 if(ext)
461 ext->recordBeginTx(h, trans);
462 /*************************************************************************
463 * do the timed notification
464 *************************************************************************/
465 if(nb_streamHandleTimed) {
466 record_nb_tx(trans, phase, delay, h);
467 }
468 /*************************************************************************
469 * do the access
470 *************************************************************************/
471 if(checker) checker->bw_pre(trans, phase);
472 tlm::tlm_sync_enum status = get_bw_if()->nb_transport_bw(trans, phase, delay);
473 if(checker) checker->bw_post(trans, phase, status);
474 /*************************************************************************
475 * handle recording
476 *************************************************************************/
477 tlm::scc::scv::record(h, status);
478 h.record_attribute("delay[return_path]", delay.to_string());
479 tlm::scc::scv::record(h, trans);
480 for(auto& ext : tlm::scc::scv::tlm_extension_recording_registry<TYPES>::inst().get())
481 if(ext)
482 ext->recordEndTx(h, trans);
483 // get the extension and free the memory if it was mine
484 if(status == tlm::TLM_COMPLETED || (status == tlm::TLM_UPDATED && phase == tlm::END_RESP)) {
485 // the transaction is finished
486 trans.get_extension(preExt);
487 if(preExt->get_creator() == this) {
488 // clean-up the extension if this is the original creator
489 if(trans.has_mm())
490 trans.set_auto_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
491 else
492 delete trans.set_extension(static_cast<tlm::scc::scv::tlm_recording_extension*>(nullptr));
493 }
494 /*************************************************************************
495 * do the timed notification if req. finished here
496 *************************************************************************/
497 if(nb_streamHandleTimed) {
498 record_nb_tx(trans, (status == tlm::TLM_COMPLETED && phase == tlm::BEGIN_REQ) ? tlm::END_RESP : phase, delay, h);
499 }
500 } else if(nb_streamHandleTimed && status == tlm::TLM_UPDATED) {
501 record_nb_tx(trans, phase, delay, h);
502 }
503 // End the transaction
504 nb_trHandle[BW]->end_transaction(h, phase2string(phase));
505 return status;
506}
507
508template <typename TYPES>
509void axi_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) {
510 SCVNS scv_tr_handle h;
511 // Now process outstanding recordings
512 auto t = sc_core::sc_time_stamp()+delay;
513 auto id=reinterpret_cast<uintptr_t>(&trans);
514 if(phase == tlm::BEGIN_REQ || phase == axi::BEGIN_PARTIAL_REQ) {
515 h = nb_trTimedHandle[REQ]->begin_transaction(t);
516 tlm::scc::scv::record(h, trans);
518 nbtx_req_handle_map[id] = h;
519 } else if(phase == tlm::END_REQ || phase == axi::END_PARTIAL_REQ) {
520 auto it = nbtx_req_handle_map.find(id);
521 if(it != nbtx_req_handle_map.end()) {
522 h = it->second;
523 nbtx_req_handle_map.erase(it);
524 h.end_transaction(t);
525 nbtx_last_req_handle_map[id] = h;
526 }
527 } else if(phase == tlm::BEGIN_RESP || phase == axi::BEGIN_PARTIAL_RESP) {
528 auto it = nbtx_req_handle_map.find(id);
529 if(it != nbtx_req_handle_map.end()) {
530 h = it->second;
531 nbtx_req_handle_map.erase(it);
532 h.end_transaction(t);
533 nbtx_last_req_handle_map[id] = h;
534 }
535 h = nb_trTimedHandle[RESP]->begin_transaction(t);
536 tlm::scc::scv::record(h, trans);
538 nbtx_resp_handle_map[id] = h;
539 it = nbtx_last_req_handle_map.find(id);
540 if(it != nbtx_last_req_handle_map.end()) {
541 SCVNS scv_tr_handle& pred = it->second;
543 nbtx_last_req_handle_map.erase(it);
544 } else {
545 it = nbtx_last_resp_handle_map.find(id);
546 if(it != nbtx_last_resp_handle_map.end()) {
547 SCVNS scv_tr_handle& pred = it->second;
549 nbtx_last_resp_handle_map.erase(it);
550 }
551 }
552 } else if(phase == tlm::END_RESP || phase == axi::END_PARTIAL_RESP) {
553 auto it = nbtx_resp_handle_map.find(id);
554 if(it != nbtx_resp_handle_map.end()) {
555 h = it->second;
556 nbtx_resp_handle_map.erase(it);
557 h.end_transaction(t);
558 if(phase == axi::END_PARTIAL_RESP) {
559 nbtx_last_resp_handle_map[id] = h;
560 }
561 }
562 } else
563 sc_assert(!"phase not supported!");
564 return;
565}
566
567template <typename TYPES>
568bool axi_recorder<TYPES>::get_direct_mem_ptr(typename TYPES::tlm_payload_type& trans, tlm::tlm_dmi& dmi_data) {
569 if(!(m_db && enableDmiTracing.get_value()))
570 return get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
571 else if(!dmi_streamHandle)
572 initialize_streams();
573 SCVNS scv_tr_handle h = dmi_trGetHandle->begin_transaction();
574 bool status = get_fw_if()->get_direct_mem_ptr(trans, dmi_data);
575 tlm::scc::scv::record(h, trans);
576 tlm::scc::scv::record(h, dmi_data);
577 h.end_transaction();
578 return status;
579}
580
586template <typename TYPES>
587void axi_recorder<TYPES>::invalidate_direct_mem_ptr(sc_dt::uint64 start_addr, sc_dt::uint64 end_addr) {
588 if(!(m_db && enableDmiTracing.get_value())) {
589 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
590 return;
591 } else if(!dmi_streamHandle)
592 initialize_streams();
593 SCVNS scv_tr_handle h = dmi_trInvalidateHandle->begin_transaction(start_addr);
594 get_bw_if()->invalidate_direct_mem_ptr(start_addr, end_addr);
595 dmi_trInvalidateHandle->end_transaction(h, end_addr);
596 return;
597}
598
604template <typename TYPES> unsigned int axi_recorder<TYPES>::transport_dbg(typename TYPES::tlm_payload_type& trans) {
605 unsigned int count = get_fw_if()->transport_dbg(trans);
606 return count;
607}
608} // namespace scv
609} // 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:956
tlm::tlm_fw_transport_if< TYPES > axi_fw_transport_if
alias declaration for the forward interface
Definition axi_tlm.h:954
const char * rel_str(tx_rel rel)
cast the tx_rel enum to a string