scc  2024.06
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 
25 namespace tilelink {
29 template <typename Enum> struct enable_for_enum { static const bool value = false; };
35 template <typename E> inline E into(typename std::underlying_type<E>::type t);
41 template <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>
43 inline constexpr ULT to_int(E t) {
44  return static_cast<typename std::underlying_type<E>::type>(t);
45 }
51 template <typename E> const char* to_char(E t);
58 template <typename E, typename std::enable_if<enable_for_enum<E>::value, bool>::type>
59 inline std::ostream& operator<<(std::ostream& os, E e) {
60  os << to_char(e);
61  return os;
62 }
63 
64 std::ostream& operator<<(std::ostream& os, tlm::tlm_generic_payload const& t);
65 
67 enum class opcode_e : uint8_t {
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 
92 struct tilelink_extension : public tlm::tlm_extension<tilelink_extension> {
93  opcode_e get_opcode() const;
94  void set_opcode(opcode_e);
95 
96  uint8_t get_param() const;
97  void set_param(uint8_t);
98 
99  uint64_t get_source() const;
100  void set_source(uint64_t);
101 
102  uint64_t get_sink() const;
103  void set_sink(uint64_t);
104 
105  bool is_corrupt() const;
106  void set_corrupt(bool = true);
107 
108  bool is_denied() const;
109  void set_denied(bool = true);
110 
111  tilelink_extension() = default;
112 
113  tilelink_extension(const tilelink_extension& o) = default;
118  tlm::tlm_extension_base* clone() const override;
123  void copy_from(tlm::tlm_extension_base const& ext) override;
124 
125 private:
126  uint64_t source{0};
127  uint64_t sink{0};
128  bool corrupt{false};
129  bool denied{false};
130  uint8_t param{0};
131  opcode_e opcode{opcode_e::ILLEGAL};
132 };
134 using tl_payload = tlm::tlm_generic_payload;
135 using tl_phase = tlm::tlm_phase;
141  typedef tl_payload tlm_payload_type;
142  typedef tl_phase tlm_phase_type;
143 };
151 template <typename TRANS = tlm::tlm_generic_payload> class bw_blocking_transport_if : public virtual sc_core::sc_interface {
152 public:
158  virtual void b_snoop(TRANS& trans, sc_core::sc_time& t) = 0;
159 };
161 template <typename TYPES = tl_protocol_types> using tlu_fw_transport_if = tlm::tlm_fw_transport_if<TYPES>;
163 template <typename TYPES = tl_protocol_types> using tlu_bw_transport_if = tlm::tlm_bw_transport_if<TYPES>;
165 template <typename TYPES = tl_protocol_types> using tlc_fw_transport_if = tlm::tlm_fw_transport_if<TYPES>;
169 template <typename TYPES = tl_protocol_types>
170 class tlc_bw_transport_if : public tlm::tlm_bw_transport_if<TYPES>,
172 
176 template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
177  sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
179 : public tlm::tlm_base_initiator_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL> {
181  using base_type = tlm::tlm_base_initiator_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL>;
186  : base_type() {}
191  explicit tlu_initiator_socket(const char* name)
192  : base_type(name) {}
197  const char* kind() const override { return "tlu_initiator_socket"; }
198  // not the right version but we assume TLM is always bundled with SystemC
199 #if SYSTEMC_VERSION >= 20181013 // ((TLM_VERSION_MAJOR > 2) || (TLM_VERSION==2 && TLM_VERSION_MINOR>0) ||(TLM_VERSION==2
200  // && TLM_VERSION_MINOR>0 && TLM_VERSION_PATCH>4))
201  sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
202 #endif
203 };
207 template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
208  sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
209 struct tlu_target_socket : public tlm::tlm_base_target_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL> {
211  using base_type = tlm::tlm_base_target_socket<BUSWIDTH, tlu_fw_transport_if<TYPES>, tlu_bw_transport_if<TYPES>, N, POL>;
216  : base_type() {}
221  explicit tlu_target_socket(const char* name)
222  : base_type(name) {}
227  const char* kind() const override { return "tlu_target_socket"; }
228  // not the right version but we assume TLM is always bundled with SystemC
229 #if SYSTEMC_VERSION >= 20181013 // ((TLM_VERSION_MAJOR > 2) || (TLM_VERSION==2 && TLM_VERSION_MINOR>0) ||(TLM_VERSION==2
230  // && TLM_VERSION_MINOR>0 && TLM_VERSION_PATCH>4))
231  sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
232 #endif
233 };
237 template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
238  sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
240 : public tlm::tlm_base_initiator_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL> {
242  using base_type = tlm::tlm_base_initiator_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL>;
247  : base_type() {}
252  explicit tlc_initiator_socket(const char* name)
253  : base_type(name) {}
258  const char* kind() const override { return "tlc_initiator_socket"; }
259 #if SYSTEMC_VERSION >= 20181013 // not the right version but we assume TLM is always bundled with SystemC
264  sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
265 #endif
266 };
270 template <unsigned int BUSWIDTH = 32, typename TYPES = tl_protocol_types, int N = 1,
271  sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND>
272 struct tlc_target_socket : public tlm::tlm_base_target_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL> {
274  using base_type = tlm::tlm_base_target_socket<BUSWIDTH, tlc_fw_transport_if<TYPES>, tlc_bw_transport_if<TYPES>, N, POL>;
279  : base_type() {}
284  explicit tlc_target_socket(const char* name)
285  : base_type(name) {}
290  const char* kind() const override { return "tlc_target_socket"; }
291  // not the right version but we assume TLM is always bundled with SystemC
292 #if SYSTEMC_VERSION >= 20181013 // not the right version but we assume TLM is always bundled with SystemC
297  sc_core::sc_type_index get_protocol_types() const override { return typeid(TYPES); }
298 #endif
299 };
300 /*****************************************************************************
301  * free function easing handling of transactions and extensions
302  *****************************************************************************/
303 /*****************************************************************************
304  * Implementation details
305  *****************************************************************************/
306 template <> struct enable_for_enum<opcode_e> { static const bool enable = true; };
307 
308 inline opcode_e tilelink_extension::get_opcode() const { return opcode; }
309 
310 inline void tilelink_extension::set_opcode(opcode_e opcode) { this->opcode = opcode; }
311 
312 inline uint8_t tilelink_extension::get_param() const { return param; }
313 
314 inline void tilelink_extension::set_param(uint8_t param) { this->param = param; }
315 
316 inline uint64_t tilelink_extension::get_source() const { return source; }
317 
318 inline void tilelink_extension::set_source(uint64_t source) { this->source = source; }
319 
320 inline uint64_t tilelink_extension::get_sink() const { return sink; }
321 
322 inline void tilelink_extension::set_sink(uint64_t sink) { this->sink = sink; }
323 
324 inline bool tilelink_extension::is_corrupt() const { return corrupt; }
325 
326 inline void tilelink_extension::set_corrupt(bool corrupt) { this->corrupt = corrupt; }
327 
328 inline bool tilelink_extension::is_denied() const { return denied; }
329 
330 inline void tilelink_extension::set_denied(bool denied) { this->denied = denied; }
331 
332 inline tlm::tlm_extension_base* tilelink_extension::clone() const { return new tilelink_extension(this); }
333 
334 inline void tilelink_extension::copy_from(const tlm::tlm_extension_base& ext) {
335  auto const* tl_ext = dynamic_cast<const tilelink_extension*>(&ext);
336  assert(tl_ext);
337  (*this) = *tl_ext;
338 }
339 } // namespace tilelink
340 
341 #endif /* _TILELINK_TL_TLM_H_ */