scc  2024.06
SystemC components library
chi_tlm.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_tlm.h"
18 #include <iostream>
19 #include <tlm/scc/scv/tlm_extension_recording_registry.h>
20 
21 namespace chi {
22 namespace {
23 std::array<std::string, 3> cmd_str{"R", "W", "I"};
24 }
25 std::array<char const*, 103> opc2str = {
26  "ReqLCrdReturn",
27  "ReadShared",
28  "ReadClean",
29  "ReadOnce",
30  "ReadNoSnp",
31  "PCrdReturn",
32  "Reserved",
33  "ReadUnique",
34  "CleanShared",
35  "CleanInvalid",
36  "MakeInvalid",
37  "CleanUnique",
38  "MakeUnique",
39  "Evict",
40  "EOBarrier",
41  "ECBarrier",
42  "RESERVED",
43  "ReadNoSnpSep",
44  "RESERVED",
45  "CleanSharedPersistSep",
46  "DVMOp",
47  "WriteEvictFull",
48  "WriteCleanPtl",
49  "WriteCleanFull",
50  "WriteUniquePtl",
51  "WriteUniqueFull",
52  "WriteBackPtl",
53  "WriteBackFull",
54  "WriteNoSnpPtl",
55  "WriteNoSnpFull",
56  "RESERVED",
57  "RESERVED",
58  "WriteUniqueFullStash",
59  "WriteUniquePtlStash",
60  "StashOnceShared",
61  "StashOnceUnique",
62  "ReadOnceCleanInvalid",
63  "ReadOnceMakeInvalid",
64  "ReadNotSharedDirty",
65  "CleanSharedPersist",
66  "AtomicStoreAdd",
67  "AtomicStoreClr",
68  "AtomicStoreEor",
69  "AtomicStoreSet",
70  "AtomicStoreSmax",
71  "AtomicStoreSmin",
72  "AtomicStoreUmax",
73  "AtomicStoreUmin",
74  "AtomicLoadAdd",
75  "AtomicLoadClr",
76  "AtomicLoadEor",
77  "AtomicLoadSet",
78  "AtomicLoadSmax",
79  "AtomicLoadSmin",
80  "AtomicLoadUmax",
81  "AtomicLoadUmin",
82  "AtomicSwap",
83  "AtomicCompare",
84  "PrefetchTgt",
85  "RESERVED",
86  "RESERVED",
87  "RESERVED",
88  "RESERVED",
89  "RESERVED",
90  "RESERVED",
91  "MakeReadUnique",
92  "WriteEvictOrEvict",
93  "WriteUniqueZero",
94  "WriteNoSnpZero",
95  "RESERVED",
96  "RESERVED",
97  "StashOnceSepShared",
98  "StashOnceSepUnique",
99  "RESERVED",
100  "RESERVED",
101  "RESERVED",
102  "ReadPreferUnique",
103  "RESERVED",
104  "RESERVED",
105  "RESERVED",
106  "WriteNoSnpFullCleanSh",
107  "WriteNoSnpFullCleanInv",
108  "WriteNoSnpFullCleanShPerSep",
109  "RESERVED",
110  "WriteUniqueFullCleanSh",
111  "RESERVED",
112  "WriteUniqueFullCleanShPerSep",
113  "RESERVED",
114  "WriteBackFullCleanSh",
115  "WriteBackFullCleanInv",
116  "WriteBackFullCleanShPerSep",
117  "RESERVED",
118  "WriteCleanFullCleanSh",
119  "RESERVED",
120  "WriteCleanFullCleanShPerSep",
121  "RESERVED",
122  "WriteNoSnpPtlCleanSh",
123  "WriteNoSnpPtlCleanInv",
124  "WriteNoSnpPtlCleanShPerSep",
125  "RESERVED",
126  "WriteUniquePtlCleanSh",
127  "RESERVED",
128  "WriteUniquePtlCleanShPerSep",
129 };
130 template <> const char* to_char<req_optype_e>(req_optype_e v) {
131  auto idx = static_cast<unsigned>(v);
132  if(idx<opc2str.size())
133  return opc2str[idx];
134  else return "RESERVED";
135 }
136 
137 template <> const char* to_char<dat_optype_e>(dat_optype_e v) {
138  switch(v) {
139  case dat_optype_e::DataLCrdReturn:
140  return "DataLCrdReturn";
141  case dat_optype_e::SnpRespData:
142  return "SnpRespData";
143  case dat_optype_e::CopyBackWrData:
144  return "CopyBackWrData";
145  case dat_optype_e::NonCopyBackWrData:
146  return "NonCopyBackWrData";
147  case dat_optype_e::CompData:
148  return "CompData";
149  case dat_optype_e::SnpRespDataPtl:
150  return "SnpRespDataPtl";
151  case dat_optype_e::SnpRespDataFwded:
152  return "SnpRespDataFwded";
153  case dat_optype_e::WriteDataCancel:
154  return "WriteDataCancel";
155  case dat_optype_e::DataSepResp:
156  return "DataSepResp";
157  case dat_optype_e::NCBWrDataCompAck:
158  return "NCBWrDataCompAck";
159  default:
160  return "UNKNOWN_dat_optype_e";
161  }
162 }
163 
164 template <> const char* to_char<rsp_optype_e>(rsp_optype_e v) {
165  switch(v) {
166  case rsp_optype_e::RespLCrdReturn:
167  return "RespLCrdReturn";
168  case rsp_optype_e::SnpResp:
169  return "SnpResp";
170  case rsp_optype_e::CompAck:
171  return "CompAck";
172  case rsp_optype_e::RetryAck:
173  return "RetryAck";
174  case rsp_optype_e::Comp:
175  return "Comp";
176  case rsp_optype_e::CompDBIDResp:
177  return "CompDBIDResp";
178  case rsp_optype_e::DBIDResp:
179  return "DBIDResp";
180  case rsp_optype_e::PCrdGrant:
181  return "PCrdGrant";
182  case rsp_optype_e::ReadReceipt:
183  return "ReadReceipt";
184  case rsp_optype_e::SnpRespFwded:
185  return "SnpRespFwded";
186  case rsp_optype_e::TagMatch:
187  return "TagMatch";
188  case rsp_optype_e::RespSepData:
189  return "RespSepData";
190  case rsp_optype_e::Persist:
191  return "Persist";
192  case rsp_optype_e::CompPersist:
193  return "CompPersist";
194  case rsp_optype_e::DBIDRespOrd:
195  return "DBIDRespOrd";
196  case rsp_optype_e::StashDone:
197  return "StashDone";
198  case rsp_optype_e::CompStashDone:
199  return "CompStashDone";
200  case rsp_optype_e::CompCMO:
201  return "CompCMO";
202  case rsp_optype_e::INVALID:
203  return "---";
204  default:
205  return "UNKNOWN_rsp_optype_e";
206  }
207 }
208 
209 template <> const char* to_char<snp_optype_e>(snp_optype_e v) {
210  switch(v) {
211  case snp_optype_e::SnpLCrdReturn:
212  return "SnpLCrdReturn";
213  case snp_optype_e::SnpShared:
214  return "SnpShared";
215  case snp_optype_e::SnpClean:
216  return "SnpClean";
217  case snp_optype_e::SnpOnce:
218  return "SnpOnce";
219  case snp_optype_e::SnpNotSharedDirty:
220  return "SnpNotSharedDirty";
221  case snp_optype_e::SnpUniqueStash:
222  return "SnpUniqueStash";
223  case snp_optype_e::SnpMakeInvalidStash:
224  return "SnpMakeInvalidStash";
225  case snp_optype_e::SnpUnique:
226  return "SnpUnique";
227  case snp_optype_e::SnpCleanShared:
228  return "SnpCleanShared";
229  case snp_optype_e::SnpCleanInvalid:
230  return "SnpCleanInvalid";
231  case snp_optype_e::SnpMakeInvalid:
232  return "SnpMakeInvalid";
233  case snp_optype_e::SnpStashUnique:
234  return "SnpStashUnique";
235  case snp_optype_e::SnpStashShared:
236  return "SnpStashShared";
237  case snp_optype_e::SnpDVMOp:
238  return "SnpDVMOp";
239  case snp_optype_e::SnpSharedFwd:
240  return "SnpSharedFwd";
241  case snp_optype_e::SnpCleanFwd:
242  return "SnpCleanFwd";
243  case snp_optype_e::SnpOnceFwd:
244  return "SnpOnceFwd";
245  case snp_optype_e::SnpNotSharedDirtyFwd:
246  return "SnpNotSharedDirtyFwd";
247  case snp_optype_e::SnpUniqueFwd:
248  return "SnpUniqueFwd";
249  default:
250  return "UNKNOWN_snp_optype_e";
251  }
252 }
253 
254 template <> const char* to_char<dat_resptype_e>(dat_resptype_e v) {
255  switch(v) {
256  // case CompData_I: return "CompData_I";
257  // case DataSepResp_I: return "DataSepResp_I";
258  // case RespSepData_I: return "RespSepData_I";
259  // case CompData_UC: return "CompData_UC";
260  // case DataSepResp_UC: return "DataSepResp_UC";
261  // case RespSepData_UC: return "RespSepData_UC";
262  // case CompData_SC: return "CompData_SC";
263  // case DataSepResp_SC: return "DataSepResp_SC";
264  // case RespSepData_SC: return "RespSepData_SC";
265  case dat_resptype_e::CompData_UD_PD:
266  return "CompData_UD_PD";
267  case dat_resptype_e::CompData_SD_PD:
268  return "CompData_SD_PD";
269  case dat_resptype_e::Comp_I:
270  return "Comp_I";
271  case dat_resptype_e::Comp_UC:
272  return "Comp_UC";
273  case dat_resptype_e::Comp_SC:
274  return "Comp_SC";
275  // case CopyBackWrData_I: return "CopyBackWrData_I";
276  // case CopyBackWrData_UC: return "CopyBackWrData_UC";
277  // case CopyBackWrData_SC: return "CopyBackWrData_SC";
278  // case CopyBackWrData_UD_PD: return "CopyBackWrData_UD_PD";
279  // case CopyBackWrData_SD_PD: return "CopyBackWrData_SD_PD";
280  // case NonCopyBackWrData: return "NonCopyBackWrData";
281  // case NCBWrDataCompAck: return "NCBWrDataCompAck";
282  default:
283  return "UNKNOWN_dat_resptype_e";
284  }
285 }
286 
287 template <> const char* to_char<rsp_resptype_e>(rsp_resptype_e v) {
288  switch(v) {
289  case rsp_resptype_e::SnpResp_I:
290  return "SnpResp_I";
291  case rsp_resptype_e::SnpResp_SC:
292  return "SnpResp_SC";
293  case rsp_resptype_e::SnpResp_UC:
294  return "SnpResp_UC";
295  // case SnpResp_UD: return "SnpResp_UD";
296  case rsp_resptype_e::SnpResp_SD:
297  return "SnpResp_SD";
298  default:
299  return "UNKNOWN_rsp_resptype_e";
300  }
301 }
302 
303 template <> const char* to_char<rsp_resperrtype_e>(rsp_resperrtype_e v) {
304  switch(v) {
305  case rsp_resperrtype_e::OK:
306  return "OK";
307  case rsp_resperrtype_e::EXOK:
308  return "EXOK";
309  case rsp_resperrtype_e::DERR:
310  return "DERR";
311  case rsp_resperrtype_e::NDERR:
312  return "NDERR";
313  default:
314  return "rsp_resperrtype_e";
315  }
316 }
317 
318 template <> const char* to_char<credit_type_e>(credit_type_e v) {
319  switch(v) {
320  case credit_type_e::LINK:
321  return "LINK";
322  case credit_type_e::REQ:
323  return "REQ";
324  case credit_type_e::RESP:
325  return "RESP";
326  case credit_type_e::DATA:
327  return "DATA";
328  default:
329  return "credit_type_e";
330  }
331 }
332 
333 std::ostream& operator<<(std::ostream& os, const tlm::tlm_generic_payload& t) {
334  char const* ch =
335  t.get_command() == tlm::TLM_READ_COMMAND ? "AR" : (t.get_command() == tlm::TLM_WRITE_COMMAND ? "AW" : "");
336  os << "CMD:" << cmd_str[t.get_command()] << ", " << ch << "ADDR:0x" << std::hex << t.get_address() << ", TXLEN:0x"
337  << t.get_data_length();
338  if(auto ext = t.get_extension<chi::chi_ctrl_extension>()){
339  os << ", TXNID:"<<ext->get_txn_id();
340  os << ", OPC:"<<chi::to_char(ext->req.get_opcode());
341  } else if(auto ext = t.get_extension<chi::chi_snp_extension>()) {
342  os << ", TXNID:"<<ext->get_txn_id();
343  os << ", OPC:"<<chi::to_char(ext->req.get_opcode());
344  }
345  os << " [ptr:" << &t << "]";
346  return os;
347 }
348 template <> const char* is_valid_msg<chi::chi_ctrl_extension>(chi_ctrl_extension* ext) {
349  auto sz = ext->req.get_size();
350  if(sz > 6)
351  return "Illegal size setting, maximum is 6";
352  switch(ext->req.get_opcode()) {
353  case req_optype_e::ReadNoSnp:
354  case req_optype_e::ReadNoSnpSep:
355  case req_optype_e::WriteNoSnpPtl:
356  case req_optype_e::WriteUniquePtl:
357  case req_optype_e::WriteUniquePtlStash:
358  break;
359  default:
360  if(!is_dataless(ext) && sz<6) return "Coherent transactions allow only cache line size data transfers";
361  }
362  return nullptr;
363 }
364 
365 } // namespace chi
366 
367 #include <tlm/scc/scv/tlm_recorder.h>
368 #include <tlm/scc/tlm_id.h>
369 namespace chi {
370 using namespace tlm::scc::scv;
371 
372 class tlm_id_ext_recording : public tlm_extensions_recording_if<chi_protocol_types> {
373 
374  void recordBeginTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
375  if(auto ext = trans.get_extension<tlm::scc::tlm_id_extension>()) {
376  handle.record_attribute("trans.uid", ext->id);
377  }
378  }
379 
380  void recordEndTx(SCVNS scv_tr_handle& handle, tlm::tlm_base_protocol_types::tlm_payload_type& trans) override {
381  }
382 };
383 
384 class chi_ctrl_ext_recording : public tlm_extensions_recording_if<chi_protocol_types> {
385 
386  void recordBeginTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
387  auto ext = trans.get_extension<chi_ctrl_extension>();
388  if(ext) {
389  handle.record_attribute("trans.chi_c.qos", ext->get_qos());
390  handle.record_attribute("trans.chi_c.src_id", ext->get_src_id());
391  handle.record_attribute("trans.chi_c.txn_id", ext->get_txn_id());
392  handle.record_attribute("trans.chi_c.tgt_id", ext->req.get_tgt_id());
393  handle.record_attribute("trans.chi_c.lp_id", ext->req.get_lp_id());
394  handle.record_attribute("trans.chi_c.return_txn_id", ext->req.get_return_txn_id());
395  handle.record_attribute("trans.chi_c.stash_lp_id", ext->req.get_stash_lp_id());
396  handle.record_attribute("trans.chi_c.size", ext->req.get_size());
397  handle.record_attribute("trans.chi_c.mem_attr", ext->req.get_mem_attr());
398  handle.record_attribute("trans.chi_c.req.pcrd_type", ext->req.get_pcrd_type());
399  handle.record_attribute("trans.chi_c.order", ext->req.get_order());
400  handle.record_attribute("trans.chi_c.endian", ext->req.is_endian());
401  handle.record_attribute("trans.chi_c.req.trace_tag", ext->req.is_trace_tag());
402  handle.record_attribute("trans.chi_c.return_n_id", ext->req.get_return_n_id());
403  handle.record_attribute("trans.chi_c.stash_n_id", ext->req.get_stash_n_id());
404  handle.record_attribute("trans.chi_c.opcode", std::string(to_char(ext->req.get_opcode())));
405  handle.record_attribute("trans.chi_c.stash_nnode_id_valid", ext->req.is_stash_n_id_valid());
406  handle.record_attribute("trans.chi_c.stash_lp_id_valid", ext->req.is_stash_lp_id_valid());
407  handle.record_attribute("trans.chi_c.non_secure", ext->req.is_non_secure());
408  handle.record_attribute("trans.chi_c.exp_comp_ack", ext->req.is_exp_comp_ack());
409  handle.record_attribute("trans.chi_c.allow_retry", ext->req.is_allow_retry());
410  handle.record_attribute("trans.chi_c.snp_attr", ext->req.is_snp_attr());
411  handle.record_attribute("trans.chi_c.excl", ext->req.is_excl());
412  handle.record_attribute("trans.chi_c.snoop_me", ext->req.is_snoop_me());
413  handle.record_attribute("trans.chi_c.likely_shared", ext->req.is_likely_shared());
414  handle.record_attribute("trans.chi_c.txn_rsvdc", ext->req.get_rsvdc()); // Reserved for customer use.
415  handle.record_attribute("trans.chi_c.tag_op", ext->req.get_tag_op());
416  handle.record_attribute("trans.chi_c.tag_group_id", ext->req.get_tag_group_id());
417  handle.record_attribute("trans.chi_c.mpam", ext->req.get_mpam());
418  handle.record_attribute("trans.chi_c.rsp.db_id", ext->resp.get_db_id());
419  handle.record_attribute("trans.chi_c.rsp.pcrd_type", ext->resp.get_pcrd_type());
420  handle.record_attribute("trans.chi_c.rsp.resp_err", std::string(to_char(ext->resp.get_resp_err())));
421  handle.record_attribute("trans.chi_c.rsp.fwd_state", ext->resp.get_fwd_state());
422  handle.record_attribute("trans.chi_c.rsp.data_pull", ext->resp.get_data_pull());
423  handle.record_attribute("trans.chi_c.rsp.opcode", std::string(to_char(ext->resp.get_opcode())));
424  handle.record_attribute("trans.chi_c.rsp.resp", std::string(to_char(ext->resp.get_resp())));
425  handle.record_attribute("trans.chi_c.rsp.tgt_id", ext->resp.get_tgt_id());
426  handle.record_attribute("trans.chi_c.rsp.trace_tag", ext->resp.is_trace_tag());
427  handle.record_attribute("trans.chi_c.rsp.tag_op", ext->resp.get_tag_op());
428  handle.record_attribute("trans.chi_c.rsp.tag_group_id", ext->resp.get_tag_group_id());
429  }
430  }
431 
432  void recordEndTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
433 };
434 
435 class chi_data_ext_recording : public tlm_extensions_recording_if<chi_protocol_types> {
436 
437  void recordBeginTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
438  auto ext = trans.get_extension<chi_data_extension>();
439  if(ext) {
440  handle.record_attribute("trans.chi_d.qos", ext->get_qos());
441  handle.record_attribute("trans.chi_d.src_id", ext->get_src_id());
442  handle.record_attribute("trans.chi_d.txn_id", ext->get_txn_id());
443  handle.record_attribute("trans.chi_d.db_id", ext->dat.get_db_id());
444  handle.record_attribute("trans.chi_d.resp_err", std::string(to_char(ext->dat.get_resp_err())));
445  handle.record_attribute("trans.chi_d.resp", std::string(to_char(ext->dat.get_resp())));
446  handle.record_attribute("trans.chi_d.fwd_state", ext->dat.get_fwd_state());
447  handle.record_attribute("trans.chi_d.data_pull", ext->dat.get_data_pull());
448  handle.record_attribute("trans.chi_d.data_source", ext->dat.get_data_source());
449  handle.record_attribute("trans.chi_d.cc_id", ext->dat.get_cc_id());
450  handle.record_attribute("trans.chi_d.data_id", ext->dat.get_data_id());
451  handle.record_attribute("trans.chi_d.poison", ext->dat.get_poison());
452  handle.record_attribute("trans.chi_d.tgt_id", ext->dat.get_tgt_id());
453  handle.record_attribute("trans.chi_d.home_node_id", ext->dat.get_home_n_id());
454  handle.record_attribute("trans.chi_d.opcode", std::string(to_char(ext->dat.get_opcode())));
455  handle.record_attribute("trans.chi_d.rsvdc", ext->dat.get_rsvdc());
456  handle.record_attribute("trans.chi_d.data_check", ext->dat.get_data_check());
457  handle.record_attribute("trans.chi_d.trace_tag", ext->dat.is_trace_tag());
458  handle.record_attribute("trans.chi_d.tag_op", ext->dat.get_tag_op());
459  handle.record_attribute("trans.chi_c.tag", ext->dat.get_tag());
460  handle.record_attribute("trans.chi_c.tu", ext->dat.get_tu());
461  }
462  }
463 
464  void recordEndTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
465 };
466 
467 class chi_snp_ext_recording : public tlm_extensions_recording_if<chi_protocol_types> {
468 
469  void recordBeginTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
470  auto ext = trans.get_extension<chi_snp_extension>();
471  if(ext) {
472  handle.record_attribute("trans.chi_s.qos", ext->get_qos());
473  handle.record_attribute("trans.chi_s.src_id", ext->get_src_id());
474  handle.record_attribute("trans.chi_s.txn_id", ext->get_txn_id());
475  handle.record_attribute("trans.chi_s.fwd_txn_id", ext->req.get_fwd_txn_id());
476  handle.record_attribute("trans.chi_s.stash_lp_id", ext->req.get_stash_lp_id());
477  handle.record_attribute("trans.chi_s.vm_id_ext", ext->req.get_vm_id_ext());
478  handle.record_attribute("trans.chi_s.stash_lp_id_valid", ext->req.is_stash_lp_id_valid());
479  handle.record_attribute("trans.chi_s.opcode", std::string(to_char(ext->req.get_opcode())));
480  handle.record_attribute("trans.chi_s.fwd_n_id", ext->req.get_fwd_n_id());
481  handle.record_attribute("trans.chi_s.non_secure", ext->req.is_non_secure());
482  handle.record_attribute("trans.chi_s.do_not_goto_sd", ext->req.is_do_not_goto_sd());
483  handle.record_attribute("trans.chi_s.do_not_data_pull", ext->req.is_do_not_data_pull());
484  handle.record_attribute("trans.chi_s.ret_to_src", ext->req.is_ret_to_src());
485  handle.record_attribute("trans.chi_s.trace_tag", ext->req.is_trace_tag());
486  handle.record_attribute("trans.chi_s.rsp.db_id", ext->resp.get_db_id());
487  handle.record_attribute("trans.chi_s.rsp.pcrd_type", ext->resp.get_pcrd_type());
488  handle.record_attribute("trans.chi_s.rsp.resp_err", std::string(to_char(ext->resp.get_resp_err())));
489  handle.record_attribute("trans.chi_s.rsp.fwd_state", ext->resp.get_fwd_state());
490  handle.record_attribute("trans.chi_s.rsp.data_pull", ext->resp.get_data_pull());
491  handle.record_attribute("trans.chi_s.rsp.opcode", std::string(to_char(ext->resp.get_opcode())));
492  handle.record_attribute("trans.chi_s.rsp.resp", std::string(to_char(ext->resp.get_resp())));
493  handle.record_attribute("trans.chi_s.rsp.tgt_id", ext->resp.get_tgt_id());
494  handle.record_attribute("trans.chi_s.rsp.trace_tag", ext->resp.is_trace_tag());
495  }
496  }
497 
498  void recordEndTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {}
499 };
500 
501 class chi_credit_ext_recording : public tlm_extensions_recording_if<chi_protocol_types> {
502 
503  void recordBeginTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
504  auto ext = trans.get_extension<chi_credit_extension>();
505  if(ext) {
506  handle.record_attribute("trans.chi_credit.type", std::string(to_char(ext->type)));
507  handle.record_attribute("trans.chi_credit.count", ext->count);
508  }
509  }
510 
511  void recordEndTx(SCVNS scv_tr_handle& handle, chi_protocol_types::tlm_payload_type& trans) override {
512  auto ext = trans.get_extension<chi_credit_extension>();
513  if(ext) {
514  handle.record_attribute("trans.chi_credit.type", std::string(to_char(ext->type)));
515  handle.record_attribute("trans.chi_credit.count", ext->count);
516  }
517  }
518 };
519 namespace scv {
520 using namespace tlm::scc::scv;
521 #if defined(__GNUG__)
522 __attribute__((constructor))
523 #endif
524 bool register_extensions() {
525  tlm::scc::tlm_id_extension ext(nullptr); // NOLINT
527  ext.ID, new tlm_id_ext_recording()); // NOLINT
528  chi::chi_ctrl_extension extchi_req; // NOLINT
530  extchi_req.ID,
531  new chi::chi_ctrl_ext_recording()); // NOLINT
532  chi::chi_data_extension extchi_data; // NOLINT
534  extchi_data.ID,
535  new chi::chi_data_ext_recording()); // NOLINT
536  chi::chi_snp_extension extchi_snp; // NOLINT
538  extchi_snp.ID,
539  new chi::chi_snp_ext_recording()); // NOLINT
540  chi::chi_credit_extension extchi_credit; // NOLINT
542  extchi_credit.ID,
543  new chi::chi_credit_ext_recording()); // NOLINT
544  return true; // NOLINT
545 }
546 bool registered = register_extensions();
547 } // namespace scv
548 } // namespace chi
The TLM transaction extensions recorder registry.
The TLM transaction extensions recorder interface.
TLM2.0 components modeling CHI.
Definition: chi_tlm.cpp:21
const char * to_char(E t)
SCC SCV4TLM classes and functions.