gem5  v19.0.0.0
multi_socket_bases.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements. See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License. You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied. See the License for the specific language governing
16  permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 #ifndef __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__
21 #define __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__
22 
23 #include <map>
24 
25 #include "../core/sc_port.hh"
26 #include "../tlm_core/2/interfaces/fw_bw_ifs.hh"
28 
29 namespace tlm_utils
30 {
31 
32 template <typename signature>
34 {
35  signature function;
36 };
37 
38 #define TLM_DEFINE_FUNCTOR(name) \
39 template <typename MODULE, typename TRAITS> \
40 inline TLM_RET_VAL \
41 static_##name(void *mod, void *fn, int index, TLM_FULL_ARG_LIST) \
42 { \
43  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> \
44  fn_container_type; \
45  MODULE *tmp_mod = static_cast<MODULE *>(mod); \
46  fn_container_type *tmp_cb = static_cast<fn_container_type *> (fn); \
47  return (tmp_mod->*(tmp_cb->function))( \
48  index, TLM_ARG_LIST_WITHOUT_TYPES); \
49 } \
50  \
51 template <typename MODULE, typename TRAITS> \
52 inline void \
53 delete_fn_container_of_##name(void *fn) \
54 { \
55  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> \
56  fn_container_type; \
57  fn_container_type *tmp_cb = static_cast<fn_container_type *>(fn); \
58  if (tmp_cb) \
59  delete tmp_cb; \
60 } \
61  \
62 template <typename TRAITS> \
63 class name##_functor{ \
64 public: \
65  typedef typename TRAITS::tlm_payload_type payload_type; \
66  typedef typename TRAITS::tlm_phase_type phase_type; \
67  typedef TLM_RET_VAL (*call_fn)(void *,void *, int, TLM_FULL_ARG_LIST); \
68  typedef void (*del_fn)(void *); \
69  \
70  name##_functor() : m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0) {} \
71  ~name##_functor() \
72  { \
73  if (m_del_fn) \
74  (*m_del_fn)(m_mem_fn); \
75  } \
76  \
77  template <typename MODULE> \
78  void \
79  set_function(MODULE *mod, TLM_RET_VAL (MODULE::*cb)( \
80  int, TLM_FULL_ARG_LIST)) \
81  { \
82  typedef fn_container<TLM_RET_VAL (MODULE::*)( \
83  int, TLM_FULL_ARG_LIST)> fn_container_type; \
84  m_fn = &static_##name<MODULE,TRAITS>; \
85  m_del_fn = &delete_fn_container_of_##name<MODULE, TRAITS>; \
86  m_del_fn(m_mem_fn); \
87  fn_container_type *tmp =new fn_container_type(); \
88  tmp->function = cb; \
89  m_mod = static_cast<void *>(mod); \
90  m_mem_fn = static_cast<void *>(tmp); \
91  } \
92  \
93  TLM_RET_VAL \
94  operator ()(int index, TLM_FULL_ARG_LIST) \
95  { \
96  return m_fn(m_mod, m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
97  } \
98  \
99  bool is_valid() { return (m_mod != 0 && m_mem_fn != 0 && m_fn != 0); } \
100  \
101  protected: \
102  call_fn m_fn;\
103  del_fn m_del_fn; \
104  void *m_mod; \
105  void *m_mem_fn; \
106  private: \
107  name##_functor &operator = (const name##_functor &); \
108 }
109 
110 
111 #define TLM_RET_VAL tlm::tlm_sync_enum
112 #define TLM_FULL_ARG_LIST \
113  typename TRAITS::tlm_payload_type &txn, \
114  typename TRAITS::tlm_phase_type &ph, sc_core::sc_time &t
115 #define TLM_ARG_LIST_WITHOUT_TYPES txn, ph, t
116 TLM_DEFINE_FUNCTOR(nb_transport);
117 #undef TLM_RET_VAL
118 #undef TLM_FULL_ARG_LIST
119 #undef TLM_ARG_LIST_WITHOUT_TYPES
120 
121 #define TLM_RET_VAL void
122 #define TLM_FULL_ARG_LIST \
123  typename TRAITS::tlm_payload_type &txn, sc_core::sc_time &t
124 #define TLM_ARG_LIST_WITHOUT_TYPES txn, t
125 TLM_DEFINE_FUNCTOR(b_transport);
126 #undef TLM_RET_VAL
127 #undef TLM_FULL_ARG_LIST
128 #undef TLM_ARG_LIST_WITHOUT_TYPES
129 
130 #define TLM_RET_VAL unsigned int
131 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type &txn
132 #define TLM_ARG_LIST_WITHOUT_TYPES txn
133 TLM_DEFINE_FUNCTOR(debug_transport);
134 #undef TLM_RET_VAL
135 #undef TLM_FULL_ARG_LIST
136 #undef TLM_ARG_LIST_WITHOUT_TYPES
137 
138 #define TLM_RET_VAL bool
139 #define TLM_FULL_ARG_LIST \
140  typename TRAITS::tlm_payload_type &txn, tlm::tlm_dmi &dmi
141 #define TLM_ARG_LIST_WITHOUT_TYPES txn, dmi
142 TLM_DEFINE_FUNCTOR(get_dmi_ptr);
143 #undef TLM_RET_VAL
144 #undef TLM_FULL_ARG_LIST
145 #undef TLM_ARG_LIST_WITHOUT_TYPES
146 
147 #define TLM_RET_VAL void
148 #define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
149 #define TLM_ARG_LIST_WITHOUT_TYPES l, u
150 TLM_DEFINE_FUNCTOR(invalidate_dmi);
151 #undef TLM_RET_VAL
152 #undef TLM_FULL_ARG_LIST
153 #undef TLM_ARG_LIST_WITHOUT_TYPES
154 
155 #undef TLM_DEFINE_FUNCTOR
156 
157 /*
158 This class implements the fw interface.
159 It allows to register a callback for each of the fw interface methods.
160 The callbacks simply forward the fw interface call, but add the id (an int)
161 of the callback binder to the signature of the call.
162 */
163 template <typename TYPES>
166 {
167  public:
168  // typedefs according to the used TYPES class.
169  typedef typename TYPES::tlm_payload_type transaction_type;
170  typedef typename TYPES::tlm_phase_type phase_type;
172 
173  // typedefs for the callbacks.
174  typedef nb_transport_functor<TYPES> nb_func_type;
175  typedef b_transport_functor<TYPES> b_func_type;
176  typedef debug_transport_functor<TYPES> debug_func_type;
177  typedef get_dmi_ptr_functor<TYPES> dmi_func_type;
178 
180  convenience_socket_cb_holder(owner), m_id(id),
181  m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0) , m_caller_port(0)
182  {}
183 
184  // The nb_transport method of the fw interface
185  sync_enum_type nb_transport_fw(
186  transaction_type &txn, phase_type &p, sc_core::sc_time &t)
187  {
188  // Check if a callback is registered.
189  if (m_nb_f && m_nb_f->is_valid()) {
190  return (*m_nb_f)(m_id, txn, p, t); // Do the callback.
191  }
192 
193  display_error("Call to nb_transport_fw without a "
194  "registered callback for nb_transport_fw.");
195  return tlm::TLM_COMPLETED;
196  }
197 
198  // The b_transport method of the fw interface.
199  void
200  b_transport(transaction_type &trans, sc_core::sc_time &t)
201  {
202  // Check if a callback is registered.
203  if (m_b_f && m_b_f->is_valid()) {
204  (*m_b_f)(m_id, trans, t); // Do the callback
205  return;
206  }
207 
208  display_error("Call to b_transport without a "
209  "registered callback for b_transport.");
210  }
211 
212  // The DMI method of the fw interface.
213  bool
214  get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
215  {
216  // Check if a callback is registered.
217  if (m_dmi_f && m_dmi_f->is_valid()) {
218  // Do the callback.
219  return (*m_dmi_f)(m_id, trans, dmi_data);
220  }
221 
222  dmi_data.allow_none();
223  dmi_data.set_start_address(0x0);
224  dmi_data.set_end_address((sc_dt::uint64)-1);
225  return false;
226  }
227 
228  // The debug method of the fw interface.
229  unsigned int
230  transport_dbg(transaction_type &trans)
231  {
232  // check if a callback is registered
233  if (m_dbg_f && m_dbg_f->is_valid()) {
234  return (*m_dbg_f)(m_id, trans); // Do the callback.
235  }
236 
237  return 0;
238  }
239 
240  // The SystemC standard callback register_port:
241  // - Called when a port if bound to the interface.
242  // - Allowd to find out who is bound to that callback binder.
243  void
244  register_port(sc_core::sc_port_base &b, const char * /* name */)
245  {
246  m_caller_port = &b;
247  }
248 
249  // Register callbacks for all fw interface methods at once.
250  void
251  set_callbacks(nb_func_type &cb1, b_func_type &cb2,
252  dmi_func_type &cb3, debug_func_type &cb4)
253  {
254  m_nb_f = &cb1;
255  m_b_f = &cb2;
256  m_dmi_f = &cb3;
257  m_dbg_f = &cb4;
258  }
259 
260  // Getter method to get the port that is bound to that callback binder.
261  // NOTE: This will only return a valid value at end of elaboration
262  // (but not before end of elaboration!)
263  sc_core::sc_port_base *get_other_side() { return m_caller_port; }
264 
265  private:
266  // The ID of the callback binder.
267  int m_id;
268 
269  // The callbacks.
270  nb_func_type *m_nb_f;
271  b_func_type *m_b_f;
272  debug_func_type *m_dbg_f;
273  dmi_func_type *m_dmi_f;
274 
275  // The port bound to that callback binder.
277 };
278 
279 /*
280 This class implements the bw interface.
281 It allows to register a callback for each of the bw interface methods.
282 The callbacks simply forward the bw interface call, but add the id (an int)
283 of the callback binder to the signature of the call.
284 */
285 template <typename TYPES>
288 {
289  public:
290  // typedefs according to the used TYPES class
291  typedef typename TYPES::tlm_payload_type transaction_type;
292  typedef typename TYPES::tlm_phase_type phase_type;
294 
295  // typedefs for the callbacks
296  typedef nb_transport_functor<TYPES> nb_func_type;
297  typedef invalidate_dmi_functor<TYPES> dmi_func_type;
298 
300  convenience_socket_cb_holder(owner), m_id(id),
301  m_nb_f(0), m_dmi_f(0)
302  {}
303 
304  // The nb_transport method of the bw interface.
305  sync_enum_type
306  nb_transport_bw(transaction_type &txn, phase_type& p,
308  {
309  // Check if a callback is registered.
310  if (m_nb_f && m_nb_f->is_valid()) {
311  return (*m_nb_f)(m_id, txn, p, t); // Do the callback.
312  }
313 
314  display_error("Call to nb_transport_bw without a "
315  "registered callback for nb_transport_bw");
316  return tlm::TLM_COMPLETED;
317  }
318 
319  // The DMI method of the bw interface.
320  void
322  {
323  // Check if a callback is registered.
324  if (m_dmi_f && m_dmi_f->is_valid()) {
325  (*m_dmi_f)(m_id,l,u); // Do the callback.
326  }
327  }
328 
329  // Register callbacks for all bw interface methods at once.
330  void
331  set_callbacks(nb_func_type &cb1, dmi_func_type &cb2)
332  {
333  m_nb_f = &cb1;
334  m_dmi_f = &cb2;
335  }
336 
337  private:
338  // The ID of the callback binder.
339  int m_id;
340  // The callbacks.
341  nb_func_type *m_nb_f;
342  dmi_func_type *m_dmi_f;
343 };
344 
345 /*
346 This class forms the base for multi initiator sockets,
347 with fewer template parameters than the multi_init_base.
348 This class is implementation-defined.
349 */
350 template <typename TYPES=tlm::tlm_base_protocol_types>
352 {
353  public:
354  // This method shall return a vector of the callback binders of multi
355  // initiator socket.
356  virtual std::vector<callback_binder_bw<TYPES> *> &get_binders()=0;
357  // This method shall return a vector of all target interfaces bound to
358  // this multi init socket.
359  virtual std::vector<tlm::tlm_fw_transport_if<TYPES> *> &get_sockets()=0;
360  protected:
361  virtual ~multi_init_base_if() {}
362 };
363 
364 /*
365 This class forms the base for multi initiator sockets.
366 It enforces a multi initiator socket to implement all functions
367 needed to do hierarchical bindings.
368 */
369 template <unsigned int BUSWIDTH=32,
370  typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
373  public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL>,
374  public multi_init_base_if<TYPES>, protected multi_socket_base
375 {
376  public:
377  // typedef for the base type: the standard tlm initiator socket.
379 
380  // This method shall disable the code that does the callback binding
381  // that registers callbacks to binders.
382  virtual void disable_cb_bind()=0;
383 
384  // This method shall return the multi_init_base to which the
385  // multi_init_base is bound hierarchically. If the base is not bound
386  // hierarchically it shall return a pointer to itself.
387  virtual multi_init_base *get_hierarch_bind() = 0;
388 
391  {
393  }
394 
395  virtual ~multi_init_base() {}
397  base_type(sc_core::sc_gen_unique_name("multi_init_base"))
398  {}
399  multi_init_base(const char *name) : base_type(name) {}
400 
401  private:
402  const sc_core::sc_object *get_socket() const { return this; }
403 };
404 
405 /*
406 This class forms the base for multi target sockets,
407 with fewer template parameters than the multi_target_base.
408 This class is implementation-defined.
409 */
410 template <typename TYPES=tlm::tlm_base_protocol_types>
412 {
413  public:
414  // This method shall return a vector of the callback binders of multi
415  // initiator socket.
416  virtual std::vector<callback_binder_fw<TYPES> *> &get_binders() = 0;
417 
418  // This method shall return a map of all multi initiator sockets that are
419  // bound to this multi target the key of the map is the index at which the
420  // multi initiator i bound, while the value is the interface of the multi
421  // initiator socket that is bound at that index.
422  virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> &
423  get_multi_binds() = 0;
424 
425  protected:
427 };
428 
429 /*
430 This class forms the base for multi target sockets.
431 It enforces a multi target socket to implement all functions
432 needed to do hierarchical bindings.
433 */
434 template <unsigned int BUSWIDTH=32,
435  typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
438  public tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL>,
439  public multi_target_base_if<TYPES>, protected multi_socket_base
440 {
441  public:
442  // Typedef for the base type: the standard tlm target socket.
444 
445  // This method shall return the multi_init_base to which the
446  // multi_init_base is bound hierarchically. If the base is not bound
447  // hierarchically it shall return a pointer to itself.
448  virtual multi_target_base *get_hierarch_bind() = 0;
449 
450  // This method shall inform the multi target socket that it is bound
451  // hierarchically and to which other multi target socket it is bound
452  // hierarchically.
453  virtual void set_hierarch_bind(multi_target_base*) = 0;
454 
457  {
459  }
460 
461  virtual ~multi_target_base() {}
463  base_type(sc_core::sc_gen_unique_name("multi_target_base"))
464  {}
465  multi_target_base(const char *name) : base_type(name) {}
466 
467  private:
468  const sc_core::sc_object *get_socket() const { return this; }
469 };
470 
471 /*
472 All multi sockets must additionally derive from this class.
473 It enforces a multi socket to implement a function
474 needed to do multi init to multi target bindings.
475 */
476 template <typename TYPES>
478 {
479  public:
482  get_last_binder(tlm::tlm_bw_transport_if<TYPES> *) = 0;
483 };
484 
485 } // namespace tlm_utils
486 
487 #endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__ */
debug_transport_functor< TYPES > debug_func_type
b_transport_functor< TYPES > b_func_type
const std::string & name()
Definition: trace.cc:54
void allow_none()
Definition: dmi.hh:87
tlm::tlm_initiator_socket< BUSWIDTH, TYPES, N, POL > base_type
void b_transport(transaction_type &trans, sc_core::sc_time &t)
sync_enum_type nb_transport_bw(transaction_type &txn, phase_type &p, sc_core::sc_time &t)
void set_start_address(sc_dt::uint64 addr)
Definition: dmi.hh:82
const char * sc_gen_unique_name(const char *seed)
Definition: sc_module.cc:822
sc_core::sc_port_base * get_other_side()
callback_binder_bw(multi_socket_base *owner, int id)
virtual tlm::tlm_socket_category get_socket_category() const
STL vector class.
Definition: stl.hh:40
unsigned int transport_dbg(transaction_type &trans)
get_dmi_ptr_functor< TYPES > dmi_func_type
multi_init_base(const char *name)
const sc_core::sc_object * get_socket() const
nb_transport_functor< TYPES > nb_func_type
Bitfield< 7 > b
Bitfield< 22 > u
void register_port(sc_core::sc_port_base &b, const char *)
void set_callbacks(nb_func_type &cb1, dmi_func_type &cb2)
TYPES::tlm_payload_type transaction_type
bool get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
virtual tlm::tlm_socket_category get_socket_category() const
nb_transport_functor< TYPES > nb_func_type
sync_enum_type nb_transport_fw(transaction_type &txn, phase_type &p, sc_core::sc_time &t)
void set_callbacks(nb_func_type &cb1, b_func_type &cb2, dmi_func_type &cb3, debug_func_type &cb4)
tlm::tlm_target_socket< BUSWIDTH, TYPES, N, POL > base_type
sc_port_policy
Definition: sc_port.hh:69
sc_core::sc_port_base * m_caller_port
uint64_t uint64
Definition: sc_nbdefs.hh:172
void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u)
invalidate_dmi_functor< TYPES > dmi_func_type
const sc_core::sc_object * get_socket() const
TYPES::tlm_payload_type transaction_type
tlm_sync_enum
Definition: fw_bw_ifs.hh:31
Bitfield< 5 > t
void set_end_address(sc_dt::uint64 addr)
Definition: dmi.hh:83
callback_binder_fw(multi_socket_base *owner, int id)
Bitfield< 0 > p
TLM_DEFINE_FUNCTOR(nb_transport)
Bitfield< 5 > l
TYPES::tlm_phase_type phase_type
tlm_socket_category
TYPES::tlm_phase_type phase_type

Generated on Fri Feb 28 2020 16:27:04 for gem5 by doxygen 1.8.13