scc 2025.09
SystemC components library
tl_tlm.cpp
1/*******************************************************************************
2 * Copyright 2019-2024 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#include "tlm/scc/scv/tlm_extension_recording_registry.h"
18#include <array>
19#include <tilelink/tl_tlm.h>
20
21namespace tilelink {
22namespace {
23const std::array<std::string, 3> cmd_str{"R", "W", "I"};
24}
25
26template <> const char* to_char<opcode_e>(opcode_e v) {
27 switch(v) {
28 case opcode_e::Get:
29 return "Get";
30 case opcode_e::AccessAckData:
31 return "AccessAckData";
32 case opcode_e::PutFullData:
33 return "PutFullData";
34 case opcode_e::PutPartialData:
35 return "PutPartialData";
36 case opcode_e::AccessAck:
37 return "AccessAck";
38 case opcode_e::ArithmeticData:
39 return "ArithmeticData";
40 case opcode_e::LogicalData:
41 return "LogicalData";
42 case opcode_e::Intent:
43 return "Intent";
44 case opcode_e::HintAck:
45 return "HintAck";
46 case opcode_e::AcquireBlock:
47 return "AcquireBlock";
48 case opcode_e::AcquirePerm:
49 return "AcquirePerm";
50 case opcode_e::Grant:
51 return "Grant";
52 case opcode_e::GrantData:
53 return "GrantData";
54 case opcode_e::GrantAck:
55 return "GrantAck";
56 case opcode_e::ProbeBlock:
57 return "ProbeBlock";
58 case opcode_e::ProbePerm:
59 return "ProbePerm";
60 case opcode_e::ProbeAck:
61 return "ProbeAck";
62 case opcode_e::ProbeAckData:
63 return "ProbeAckData";
64 case opcode_e::Release:
65 return "Release";
66 case opcode_e::ReleaseData:
67 return "ReleaseData";
68 case opcode_e::ReleaseAck:
69 return "ReleaseAck";
70 default:
71 return "UNKNOWN";
72 }
73}
74
75template <> const char* to_char<param_e>(param_e v) {
76 switch(v) {
77 case param_e::CAP_2T:
78 return "Cap:2T (0)";
79 case param_e::CAP_2B:
80 return "Cap:2B (1)";
81 case param_e::CAP_2N:
82 return "Cap:2N (2)";
83 case param_e::GROW_N2B:
84 return "Grow:N2B (0)";
85 case param_e::GROW_N2T:
86 return "Grow:N2T (1)";
87 case param_e::GROW_B2T:
88 return "Grow:B2T (2)";
89 case param_e::PRUNE_T2B:
90 return "Prune:T2B (0)";
91 case param_e::PRUNE_T2N:
92 return "Prune:T2N (1)";
93 case param_e::PRUNE_B2N:
94 return "Prune:B2N (2)";
95 case param_e::REP_T2T:
96 return "Report:T2T (0)";
97 case param_e::REP_B2B:
98 return "Report:B2B (1)";
99 case param_e::REP_N2N:
100 return "Report:N2N (2)";
101 default:
102 return "UNKNOWN";
103 }
104}
105
106std::ostream& operator<<(std::ostream& os, const tlm::tlm_generic_payload& t) {
107 os << "CMD:" << cmd_str[t.get_command()] << ", "
108 << "ADDR:0x" << std::hex << t.get_address() << ", TXLEN:0x" << t.get_data_length();
109 if(auto e = t.get_extension<tilelink::tilelink_extension>()) {
110 os << ", "
111 << "OPC:0x" << std::hex << static_cast<unsigned>(e->get_opcode()) << "PARAM:" << e->get_param();
112 }
113 os << " [ptr:" << &t << "]";
114 return os;
115}
116
117using namespace tlm::scc::scv;
118
119class tlc_ext_recording : public tlm_extensions_recording_if<tl_protocol_types> {
120
121 void recordBeginTx(SCVNS scv_tr_handle& handle, tl_protocol_types::tlm_payload_type& trans) override {
122 auto ext = trans.get_extension<tilelink_extension>();
123 if(ext) {
124 handle.record_attribute("trans.tl.opcode", std::string(to_char(ext->get_opcode())));
125 handle.record_attribute("trans.tl.param", std::string(to_char(ext->get_param())));
126 handle.record_attribute("trans.tl.source", ext->get_source());
127 handle.record_attribute("trans.tl.sink", ext->get_sink());
128 handle.record_attribute("trans.tl.corrupt", ext->is_corrupt());
129 handle.record_attribute("trans.tl.denied", ext->is_denied());
130 }
131 }
132
133 void recordEndTx(SCVNS scv_tr_handle& handle, tl_protocol_types::tlm_payload_type& trans) override {}
134};
135
136namespace scv {
137using namespace tlm::scc::scv;
138#if defined(__GNUG__)
139__attribute__((constructor))
140#endif
141bool register_extensions() {
142 tilelink::tilelink_extension ext; // NOLINT
143 tlm::scc::scv::tlm_extension_recording_registry<tilelink::tl_protocol_types>::inst().register_ext_rec(
144 ext.ID, new tlc_ext_recording()); // NOLINT
145 return true; // NOLINT
146}
147bool registered = register_extensions();
148} // namespace scv
149} // namespace tilelink
The TLM transaction extensions recorder interface.
SCC SCV4TLM classes and functions.