scc 2026.07
SystemC components library
chi_lwtr.cpp
1/*
2 * Copyright 2020 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#include <chi/chi_tlm.h>
18#include <tlm/scc/lwtr/lwtr4tlm2_extension_registry.h>
19#include <tlm/scc/scv/tlm_extension_recording_registry.h>
20#include <tlm/scc/tlm_id.h>
21
22namespace lwtr {
23using namespace chi;
24
25template <class Archive> void record(Archive& ar, tlm::scc::tlm_id_extension const& e) { ar& field("uid", e.id); }
26
27template <class Archive> void record(Archive& ar, chi::chi_ctrl_extension const& e) {
28 ar& field("qos", e.get_qos());
29 ar& field("src_id", e.get_src_id());
30 ar& field("txn_id", e.get_txn_id());
31 ar& field("tgt_id", e.req.get_tgt_id());
32 ar& field("lp_id", e.req.get_lp_id());
33 ar& field("return_txn_id", e.req.get_return_txn_id());
34 ar& field("stash_lp_id", e.req.get_stash_lp_id());
35 ar& field("size", e.req.get_size());
36 ar& field("mem_attr", e.req.get_mem_attr());
37 ar& field("req.pcrd_type", e.req.get_pcrd_type());
38 ar& field("order", e.req.get_order());
39 ar& field("endian", e.req.is_endian());
40 ar& field("req.trace_tag", e.req.is_trace_tag());
41 ar& field("return_n_id", e.req.get_return_n_id());
42 ar& field("stash_n_id", e.req.get_stash_n_id());
43 ar& field("opcode", to_char(e.req.get_opcode()));
44 ar& field("stash_nnode_id_valid", e.req.is_stash_n_id_valid());
45 ar& field("stash_lp_id_valid", e.req.is_stash_lp_id_valid());
46 ar& field("non_secure", e.req.is_non_secure());
47 ar& field("exp_comp_ack", e.req.is_exp_comp_ack());
48 ar& field("allow_retry", e.req.is_allow_retry());
49 ar& field("snp_attr", e.req.is_snp_attr());
50 ar& field("excl", e.req.is_excl());
51 ar& field("snoop_me", e.req.is_snoop_me());
52 ar& field("likely_shared", e.req.is_likely_shared());
53 ar& field("txn_rsvdc", e.req.get_rsvdc()); // Reserved for customer use.
54 ar& field("tag_op", e.req.get_tag_op());
55 ar& field("tag_group_id", e.req.get_tag_group_id());
56 ar& field("mpam", e.req.get_mpam());
57 ar& field("rsp.db_id", e.resp.get_db_id());
58 ar& field("rsp.pcrd_type", e.resp.get_pcrd_type());
59 ar& field("rsp.resp_err", to_char(e.resp.get_resp_err()));
60 ar& field("rsp.fwd_state", e.resp.get_fwd_state());
61 ar& field("rsp.data_pull", e.resp.get_data_pull());
62 ar& field("rsp.opcode", to_char(e.resp.get_opcode()));
63 ar& field("rsp.resp", to_char(e.resp.get_resp()));
64 ar& field("rsp.tgt_id", e.resp.get_tgt_id());
65 ar& field("rsp.trace_tag", e.resp.is_trace_tag());
66 ar& field("rsp.tag_op", e.resp.get_tag_op());
67 ar& field("rsp.tag_group_id", e.resp.get_tag_group_id());
68}
69
70template <class Archive> void record(Archive& ar, chi::chi_data_extension const& e) {
71 ar& field("qos", e.get_qos());
72 ar& field("src_id", e.get_src_id());
73 ar& field("txn_id", e.get_txn_id());
74 ar& field("db_id", e.dat.get_db_id());
75 ar& field("resp_err", to_char(e.dat.get_resp_err()));
76 ar& field("resp", to_char(e.dat.get_resp()));
77 ar& field("fwd_state", e.dat.get_fwd_state());
78 ar& field("data_pull", e.dat.get_data_pull());
79 ar& field("data_source", e.dat.get_data_source());
80 ar& field("cc_id", e.dat.get_cc_id());
81 ar& field("data_id", e.dat.get_data_id());
82 ar& field("poison", e.dat.get_poison());
83 ar& field("tgt_id", e.dat.get_tgt_id());
84 ar& field("home_node_id", e.dat.get_home_n_id());
85 ar& field("opcode", to_char(e.dat.get_opcode()));
86 ar& field("rsvdc", e.dat.get_rsvdc());
87 ar& field("data_check", e.dat.get_data_check());
88 ar& field("trace_tag", e.dat.is_trace_tag());
89 ar& field("tag_op", e.dat.get_tag_op());
90 ar& field("tag", e.dat.get_tag());
91 ar& field("tu", e.dat.get_tu());
92}
93
94template <class Archive> void record(Archive& ar, chi::chi_snp_extension const& e) {
95 ar& field("qos", e.get_qos());
96 ar& field("src_id", e.get_src_id());
97 ar& field("txn_id", e.get_txn_id());
98 ar& field("fwd_txn_id", e.req.get_fwd_txn_id());
99 ar& field("stash_lp_id", e.req.get_stash_lp_id());
100 ar& field("vm_id_ext", e.req.get_vm_id_ext());
101 ar& field("stash_lp_id_valid", e.req.is_stash_lp_id_valid());
102 ar& field("opcode", to_char(e.req.get_opcode()));
103 ar& field("fwd_n_id", e.req.get_fwd_n_id());
104 ar& field("non_secure", e.req.is_non_secure());
105 ar& field("do_not_goto_sd", e.req.is_do_not_goto_sd());
106 ar& field("do_not_data_pull", e.req.is_do_not_data_pull());
107 ar& field("ret_to_src", e.req.is_ret_to_src());
108 ar& field("trace_tag", e.req.is_trace_tag());
109 ar& field("rsp.db_id", e.resp.get_db_id());
110 ar& field("rsp.pcrd_type", e.resp.get_pcrd_type());
111 ar& field("rsp.resp_err", to_char(e.resp.get_resp_err()));
112 ar& field("rsp.fwd_state", e.resp.get_fwd_state());
113 ar& field("rsp.data_pull", e.resp.get_data_pull());
114 ar& field("rsp.opcode", to_char(e.resp.get_opcode()));
115 ar& field("rsp.resp", to_char(e.resp.get_resp()));
116 ar& field("rsp.tgt_id", e.resp.get_tgt_id());
117 ar& field("rsp.trace_tag", e.resp.is_trace_tag());
118}
119
120template <class Archive> void record(Archive& ar, chi::chi_credit_extension<credit_type_e::REQ> const& e) {
121 ar& field("type", to_char(credit_type_e::REQ));
122 ar& field("count", e.count);
123}
124
125template <class Archive> void record(Archive& ar, chi::chi_credit_extension<credit_type_e::RESP> const& e) {
126 ar& field("type", to_char(credit_type_e::RESP));
127 ar& field("count", e.count);
128}
129
130template <class Archive> void record(Archive& ar, chi::chi_credit_extension<credit_type_e::DATA> const& e) {
131 ar& field("type", to_char(credit_type_e::DATA));
132 ar& field("count", e.count);
133}
134} // namespace lwtr
135
136namespace chi {
137namespace lwtr {
138namespace {
139const std::array<std::string, 3> cmd2char{{"tlm::TLM_READ_COMMAND", "tlm::TLM_WRITE_COMMAND", "tlm::TLM_IGNORE_COMMAND"}};
140const std::array<std::string, 7> resp2char{{"tlm::TLM_OK_RESPONSE", "tlm::TLM_INCOMPLETE_RESPONSE", "tlm::TLM_GENERIC_ERROR_RESPONSE",
141 "tlm::TLM_ADDRESS_ERROR_RESPONSE", "tlm::TLM_COMMAND_ERROR_RESPONSE",
142 "tlm::TLM_BURST_ERROR_RESPONSE", "tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE"}};
143const std::array<std::string, 3> gp_option2char{{"tlm::TLM_MIN_PAYLOAD", "tlm::TLM_FULL_PAYLOAD", "tlm::TLM_FULL_PAYLOAD_ACCEPTED"}};
144const std::array<std::string, 5> phase2char{
145 {"tlm::UNINITIALIZED_PHASE", "tlm::BEGIN_REQ", "tlm::END_REQ", "tlm::BEGIN_RESP", "tlm::END_RESP"}};
146const std::array<std::string, 4> dmi2char{
147 {"tlm::DMI_ACCESS_NONE", "tlm::DMI_ACCESS_READ", "tlm::DMI_ACCESS_WRITE", "tlm::DMI_ACCESS_READ_WRITE"}};
148const std::array<std::string, 3> sync2char{{"tlm::TLM_ACCEPTED", "tlm::TLM_UPDATED", "tlm::TLM_COMPLETED"}};
149
150} // namespace
151
153 void recordBeginTx(::lwtr::tx_handle& handle, tlm::tlm_base_protocol_types::tlm_payload_type& trans) override {
154 if(auto* ext = trans.get_extension<tlm::scc::tlm_id_extension>())
155 handle.record_attribute("trans", *ext);
156 }
157 void recordEndTx(::lwtr::tx_handle& handle, tlm::tlm_base_protocol_types::tlm_payload_type& trans) override {}
158};
159
161 void recordBeginTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
162 if(auto* ext = trans.get_extension<chi::chi_ctrl_extension>())
163 handle.record_attribute("trans.chi_c", *ext);
164 }
165 void recordEndTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
166};
168 void recordBeginTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
169 if(auto* ext = trans.get_extension<chi::chi_data_extension>())
170 handle.record_attribute("trans.chi_c", *ext);
171 }
172 void recordEndTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
173};
175 void recordBeginTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
176 if(auto* ext = trans.get_extension<chi::chi_snp_extension>())
177 handle.record_attribute("trans.chi_s", *ext);
178 }
179 void recordEndTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
180};
182 void recordBeginTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
183 if(auto* ext = trans.get_extension<chi::chi_credit_extension<credit_type_e::REQ>>())
184 handle.record_attribute("trans.chi_credit", *ext);
185 if(auto* ext = trans.get_extension<chi::chi_credit_extension<credit_type_e::RESP>>())
186 handle.record_attribute("trans.chi_credit", *ext);
187 if(auto* ext = trans.get_extension<chi::chi_credit_extension<credit_type_e::DATA>>())
188 handle.record_attribute("trans.chi_credit", *ext);
189 }
190 void recordEndTx(::lwtr::tx_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
191};
192
193// using namespace tlm::scc::scv;
194#if defined(__GNUG__)
195__attribute__((constructor))
196#endif
197bool register_extensions() {
198 tlm::scc::tlm_id_extension ext(nullptr); // NOLINT
199 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
200 ext.ID, new chi::lwtr::tlm_id_ext_recording()); // NOLINT
201 chi::chi_ctrl_extension chi_c; // NOLINT
202 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
203 chi_c.ID, new chi::lwtr::chi_ctrl_ext_recording()); // NOLINT
204 chi::chi_data_extension chi_d; // NOLINT
205 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
206 chi_d.ID, new chi::lwtr::chi_data_ext_recording()); // NOLINT
207 chi::chi_snp_extension chi_s; // NOLINT
208 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
209 chi_s.ID, new chi::lwtr::chi_snp_ext_recording()); // NOLINT
211 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
212 chi_req.ID, new chi::lwtr::chi_credit_ext_recording()); // NOLINT
214 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
215 chi_resp.ID, new chi::lwtr::chi_credit_ext_recording()); // NOLINT
217 tlm::scc::lwtr::lwtr4tlm2_extension_registry<chi::chi_protocol_types>::inst().register_ext_rec(
218 chi_data.ID, new chi::lwtr::chi_credit_ext_recording()); // NOLINT
219 return true; // NOLINT
220}
221bool registered = register_extensions();
222
223} // namespace lwtr
224} // namespace chi
The TLM transaction extensions recorder interface.
TLM2.0 components modeling CHI.
Definition chi_tlm.cpp:21
const char * to_char(E t)