scc 2025.09
SystemC components library
tl_tlm.h
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#ifndef _TILELINK_TL_TLM_H_
18#define _TILELINK_TL_TLM_H_
19
20#include <array>
21#include <cstdint>
22#include <tlm>
23
25namespace tilelink {
29template <typename Enum> struct enable_for_enum { static const bool value = false; };
35template <typename E> inline E into(typename std::underlying_type<E>::type t);
41template <typename E, typename ULT = typename std::underlying_type<E>::type,
42 typename X = typename std::enable_if<std::is_enum<E>::value && !std::is_convertible<E, ULT>::value, bool>::type>
43inline constexpr ULT to_int(E t) {
44 return static_cast<typename std::underlying_type<E>::type>(t);
45}
46
51template <typename E> const char* to_char(E t);
58template <typename E, typename std::enable_if<enable_for_enum<E>::value, bool>::type>
59inline std::ostream& operator<<(std::ostream& os, E e) {
60 os << to_char(e);
61 return os;
62}
63
64std::ostream& operator<<(std::ostream& os, tlm::tlm_generic_payload const& t);
65
67enum class opcode_e {
68 Get = 0x184,
69 AccessAckData = 0x061,
70 PutFullData = 0x180,
71 PutPartialData = 0x181,
72 AccessAck = 0x060,
73 ArithmeticData = 0x182,
74 LogicalData = 0x183,
75 Intent = 0x185,
76 HintAck = 0x062,
77 AcquireBlock = 0x106,
78 AcquirePerm = 0x107,
79 Grant = 0x024,
80 GrantData = 0x025,
81 GrantAck = 0x010,
82 ProbeBlock = 0x086,
83 ProbePerm = 0x087,
84 ProbeAck = 0x044,
85 ProbeAckData = 0x045,
86 Release = 0x046,
87 ReleaseData = 0x047,
88 ReleaseAck = 0x026,
89 ILLEGAL = 0xf
90};
91
92enum param_e {
93 // *N*one, *B*ranch, *T*runk
94 // cap params
95 CAP_2T = 0x0,
96 CAP_2B = 0x1,
97 CAP_2N = 0x2,
98 // grow params
99 GROW_N2B = 0x10,
100 GROW_N2T = 0x11,
101 GROW_B2T = 0x12,
102 // prune params
103 PRUNE_T2B = 0x20,
104 PRUNE_T2N = 0x21,
105 PRUNE_B2N = 0x22,
106 // report params
107 REP_T2T = 0x3,
108 REP_B2B = 0x4,
109 REP_N2N = 0x5
110};
111
112struct tilelink_extension : public tlm::tlm_extension<tilelink_extension> {
113 opcode_e get_opcode() const;
114 void set_opcode(opcode_e);
115
116 param_e get_param() const;
117 void set_param(param_e);
118
119 uint64_t get_source() const;
120 void set_source(uint64_t);
121
122 uint64_t get_sink() const;
123 void set_sink(uint64_t);
124
125 bool is_corrupt() const;
126 void set_corrupt(bool = true);
127
128 bool is_denied() const;
129 void set_denied(bool = true);
130
131 tilelink_extension() = default;
132
133 tilelink_extension(opcode_e opc, param_e p)
134 : opcode(opc)
135 , param(p) {}
136
137 tilelink_extension(const tilelink_extension& o) = default;
142 tlm::tlm_extension_base* clone() const override;
147 void copy_from(tlm::tlm_extension_base const& ext) override;
148
149private:
150 uint64_t source{0};
151 uint64_t sink{0};
152 bool corrupt{false};
153 bool denied{false};
154 param_e param{CAP_2T};
155 opcode_e opcode{opcode_e::ILLEGAL};
156};
157
158using tl_payload = tlm::tlm_generic_payload;
159using tl_phase = tlm::tlm_phase;
165 typedef tl_payload tlm_payload_type;
166 typedef tl_phase tlm_phase_type;
167};
168
175template <typename TRANS = tlm::tlm_generic_payload> class bw_blocking_transport_if : public virtual sc_core::sc_interface {
176public:
182 virtual void b_snoop(TRANS& trans, sc_core::sc_time& t) = 0;
183};
184
185template <typename TYPES = tl_protocol_types> using tlu_fw_transport_if = tlm::tlm_fw_transport_if<TYPES>;
187template <typename TYPES = tl_protocol_types> using tlu_bw_transport_if = tlm::tlm_bw_transport_if<TYPES>;
189template <typename TYPES = tl_protocol_types> using tlc_fw_transport_if = tlm::tlm_fw_transport_if<TYPES>;
193template <typename TYPES = tl_protocol_types>
194class tlc_bw_transport_if : public tlm::tlm_bw_transport_if<TYPES>,
196
200template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
201 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
203: public tlm::tlm_base_initiator_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL> {
205 using base_type = tlm::tlm_base_initiator_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL>;
211
215 explicit tlu_initiator_socket(const char* name)
216 : base_type(name) {}
217
221 const char* kind() const override { return "tlu_initiator_socket"; }
222 // not the right version but we assume TLM is always bundled with SystemC
223#if SYSTEMC_VERSION >= 20181013 && SYSTEMC_VERSION < 20241015 // not the right version but we assume TLM is always bundled with SystemC
228 sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
229#endif
230};
231
234template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
235 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
236struct tlu_target_socket : public tlm::tlm_base_target_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL> {
238 using base_type = tlm::tlm_base_target_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL>;
244
248 explicit tlu_target_socket(const char* name)
249 : base_type(name) {}
250
254 const char* kind() const override { return "tlu_target_socket"; }
255 // not the right version but we assume TLM is always bundled with SystemC
256#if SYSTEMC_VERSION >= 20181013 && SYSTEMC_VERSION < 20241015 // not the right version but we assume TLM is always bundled with SystemC
261 sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
262#endif
263};
264
267template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
268 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
270: public tlm::tlm_base_initiator_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL> {
272 using base_type = tlm::tlm_base_initiator_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL>;
278
282 explicit tlc_initiator_socket(const char* name)
283 : base_type(name) {}
284
288 const char* kind() const override { return "tlc_initiator_socket"; }
289#if SYSTEMC_VERSION >= 20181013 && SYSTEMC_VERSION < 20241015 // not the right version but we assume TLM is always bundled with SystemC
294 sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
295#endif
296};
297
300template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
301 sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
302struct tlc_target_socket : public tlm::tlm_base_target_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL> {
304 using base_type = tlm::tlm_base_target_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL>;
310
314 explicit tlc_target_socket(const char* name)
315 : base_type(name) {}
316
320 const char* kind() const override { return "tlc_target_socket"; }
321 // not the right version but we assume TLM is always bundled with SystemC
322#if SYSTEMC_VERSION >= 20181013 && SYSTEMC_VERSION < 20241015 // not the right version but we assume TLM is always bundled with SystemC
327 sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
328#endif
329};
330/*****************************************************************************
331 * free function easing handling of transactions and extensions
332 *****************************************************************************/
333/*****************************************************************************
334 * Implementation details
335 *****************************************************************************/
336template <> struct enable_for_enum<opcode_e> { static const bool enable = true; };
337
338inline opcode_e tilelink_extension::get_opcode() const { return opcode; }
339
340inline void tilelink_extension::set_opcode(opcode_e opcode) { this->opcode = opcode; }
341
342inline param_e tilelink_extension::get_param() const { return param; }
343
344inline void tilelink_extension::set_param(param_e param) { this->param = param; }
345
346inline uint64_t tilelink_extension::get_source() const { return source; }
347
348inline void tilelink_extension::set_source(uint64_t source) { this->source = source; }
349
350inline uint64_t tilelink_extension::get_sink() const { return sink; }
351
352inline void tilelink_extension::set_sink(uint64_t sink) { this->sink = sink; }
353
354inline bool tilelink_extension::is_corrupt() const { return corrupt; }
355
356inline void tilelink_extension::set_corrupt(bool corrupt) { this->corrupt = corrupt; }
357
358inline bool tilelink_extension::is_denied() const { return denied; }
359
360inline void tilelink_extension::set_denied(bool denied) { this->denied = denied; }
361
362inline tlm::tlm_extension_base* tilelink_extension::clone() const { return new tilelink_extension(*this); }
363
364inline void tilelink_extension::copy_from(const tlm::tlm_extension_base& ext) {
365 auto const* tl_ext = dynamic_cast<const tilelink_extension*>(&ext);
366 assert(tl_ext);
367 (*this) = *tl_ext;
368}
369} // namespace tilelink
370
371#endif /* _TILELINK_TL_TLM_H_ */