TLM-2.0  2.0.4
Accellera TLM-2.0 proof-of-concept library
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 TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_
21 #define TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_
22 
23 #include <tlm>
25 
26 #include <map>
27 
28 namespace tlm_utils {
29 
30 template <typename signature>
31 struct fn_container{
32  signature function;
33 };
34 
35 #define TLM_DEFINE_FUNCTOR(name) \
36 template <typename MODULE, typename TRAITS> \
37 inline TLM_RET_VAL static_##name( void* mod \
38  , void* fn \
39  , int index \
40  , TLM_FULL_ARG_LIST) \
41 { \
42  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
43  MODULE* tmp_mod=static_cast<MODULE*>(mod); \
44  fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
45  return (tmp_mod->*(tmp_cb->function))(index, TLM_ARG_LIST_WITHOUT_TYPES); \
46 }\
47 \
48 template <typename MODULE, typename TRAITS> \
49 inline void delete_fn_container_of_##name(void* fn) \
50 { \
51  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
52  fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
53  if (tmp_cb) delete tmp_cb;\
54 } \
55 \
56 template <typename TRAITS> \
57 class name##_functor{ \
58 public: \
59  typedef typename TRAITS::tlm_payload_type payload_type; \
60  typedef typename TRAITS::tlm_phase_type phase_type; \
61  typedef TLM_RET_VAL (*call_fn)(void*,void*, int, TLM_FULL_ARG_LIST); \
62  typedef void (*del_fn)(void*); \
63 \
64  name##_functor(): m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0){} \
65  ~name##_functor(){if (m_del_fn) (*m_del_fn)(m_mem_fn);} \
66 \
67  template <typename MODULE> \
68  void set_function(MODULE* mod, TLM_RET_VAL (MODULE::*cb)(int, TLM_FULL_ARG_LIST)){ \
69  typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
70  m_fn=&static_##name<MODULE,TRAITS>;\
71  m_del_fn=&delete_fn_container_of_##name<MODULE,TRAITS>;\
72  m_del_fn(m_mem_fn); \
73  fn_container_type* tmp= new fn_container_type(); \
74  tmp->function=cb; \
75  m_mod=static_cast<void*>(mod); \
76  m_mem_fn=static_cast<void*>(tmp); \
77  } \
78  \
79  TLM_RET_VAL operator()(int index, TLM_FULL_ARG_LIST){ \
80  return m_fn(m_mod,m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
81  } \
82 \
83  bool is_valid(){return (m_mod!=0 && m_mem_fn!=0 && m_fn!=0);}\
84 \
85 protected: \
86  call_fn m_fn;\
87  del_fn m_del_fn; \
88  void* m_mod; \
89  void* m_mem_fn; \
90 private: \
91  name##_functor& operator=(const name##_functor&); \
92 }
93 
94 
95 #define TLM_RET_VAL tlm::tlm_sync_enum
96 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, typename TRAITS::tlm_phase_type& ph, sc_core::sc_time& t
97 #define TLM_ARG_LIST_WITHOUT_TYPES txn,ph,t
98 TLM_DEFINE_FUNCTOR(nb_transport);
99 #undef TLM_RET_VAL
100 #undef TLM_FULL_ARG_LIST
101 #undef TLM_ARG_LIST_WITHOUT_TYPES
102 
103 #define TLM_RET_VAL void
104 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, sc_core::sc_time& t
105 #define TLM_ARG_LIST_WITHOUT_TYPES txn,t
106 TLM_DEFINE_FUNCTOR(b_transport);
107 #undef TLM_RET_VAL
108 #undef TLM_FULL_ARG_LIST
109 #undef TLM_ARG_LIST_WITHOUT_TYPES
110 
111 #define TLM_RET_VAL unsigned int
112 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn
113 #define TLM_ARG_LIST_WITHOUT_TYPES txn
114 TLM_DEFINE_FUNCTOR(debug_transport);
115 #undef TLM_RET_VAL
116 #undef TLM_FULL_ARG_LIST
117 #undef TLM_ARG_LIST_WITHOUT_TYPES
118 
119 #define TLM_RET_VAL bool
120 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, tlm::tlm_dmi& dmi
121 #define TLM_ARG_LIST_WITHOUT_TYPES txn,dmi
122 TLM_DEFINE_FUNCTOR(get_dmi_ptr);
123 #undef TLM_RET_VAL
124 #undef TLM_FULL_ARG_LIST
125 #undef TLM_ARG_LIST_WITHOUT_TYPES
126 
127 #define TLM_RET_VAL void
128 #define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
129 #define TLM_ARG_LIST_WITHOUT_TYPES l,u
130 TLM_DEFINE_FUNCTOR(invalidate_dmi);
131 #undef TLM_RET_VAL
132 #undef TLM_FULL_ARG_LIST
133 #undef TLM_ARG_LIST_WITHOUT_TYPES
134 
135 #undef TLM_DEFINE_FUNCTOR
136 
137 /*
138 This class implements the fw interface.
139 It allows to register a callback for each of the fw interface methods.
140 The callbacks simply forward the fw interface call, but add the id (an int)
141 of the callback binder to the signature of the call.
142 */
143 template <typename TYPES>
145  : public tlm::tlm_fw_transport_if<TYPES>
146  , protected convenience_socket_cb_holder
147 {
148  public:
149  //typedefs according to the used TYPES class
150  typedef typename TYPES::tlm_payload_type transaction_type;
151  typedef typename TYPES::tlm_phase_type phase_type;
153 
154  //typedefs for the callbacks
155  typedef nb_transport_functor<TYPES> nb_func_type;
156  typedef b_transport_functor<TYPES> b_func_type;
157  typedef debug_transport_functor<TYPES> debug_func_type;
158  typedef get_dmi_ptr_functor<TYPES> dmi_func_type;
159 
160  //ctor: an ID is needed to create a callback binder
162  : convenience_socket_cb_holder(owner), m_id(id)
163  , m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0)
164  , m_caller_port(0)
165  {}
166 
167  //the nb_transport method of the fw interface
168  sync_enum_type nb_transport_fw(transaction_type& txn,
169  phase_type& p,
170  sc_core::sc_time& t){
171  //check if a callback is registered
172  if (m_nb_f && m_nb_f->is_valid()) {
173  return (*m_nb_f)(m_id, txn, p, t); //do the callback
174  }
175 
176  display_error("Call to nb_transport_fw without a registered callback for nb_transport_fw.");
177  return tlm::TLM_COMPLETED;
178  }
179 
180  //the b_transport method of the fw interface
181  void b_transport(transaction_type& trans,sc_core::sc_time& t){
182  //check if a callback is registered
183  if (m_b_f && m_b_f->is_valid()) {
184  (*m_b_f)(m_id, trans,t); //do the callback
185  return;
186  }
187 
188  display_error("Call to b_transport without a registered callback for b_transport.");
189  }
190 
191  //the DMI method of the fw interface
192  bool get_direct_mem_ptr(transaction_type& trans, tlm::tlm_dmi& dmi_data){
193  //check if a callback is registered
194  if (m_dmi_f && m_dmi_f->is_valid()) {
195  return (*m_dmi_f)(m_id, trans,dmi_data); //do the callback
196  }
197 
198  dmi_data.allow_none();
199  dmi_data.set_start_address(0x0);
200  dmi_data.set_end_address((sc_dt::uint64)-1);
201  return false;
202  }
203 
204  //the debug method of the fw interface
205  unsigned int transport_dbg(transaction_type& trans){
206  //check if a callback is registered
207  if (m_dbg_f && m_dbg_f->is_valid()) {
208  return (*m_dbg_f)(m_id, trans); //do the callback
209  }
210 
211  return 0;
212  }
213 
214  //the SystemC standard callback register_port:
215  // - called when a port if bound to the interface
216  // - allowd to find out who is bound to that callback binder
217  void register_port(sc_core::sc_port_base& b, const char* /*name*/){
218  m_caller_port=&b;
219  }
220 
221  //register callbacks for all fw interface methods at once
222  void set_callbacks(nb_func_type& cb1, b_func_type& cb2, dmi_func_type& cb3, debug_func_type& cb4){
223  m_nb_f=&cb1;
224  m_b_f=&cb2;
225  m_dmi_f=&cb3;
226  m_dbg_f=&cb4;
227  }
228 
229  //getter method to get the port that is bound to that callback binder
230  // NOTE: this will only return a valid value at end of elaboration
231  // (but not before end of elaboration!)
232  sc_core::sc_port_base* get_other_side(){return m_caller_port;}
233 
234  private:
235  //the ID of the callback binder
236  int m_id;
237 
238  //the callbacks
239  nb_func_type* m_nb_f;
240  b_func_type* m_b_f;
241  debug_func_type* m_dbg_f;
242  dmi_func_type* m_dmi_f;
243 
244  //the port bound to that callback binder
245  sc_core::sc_port_base* m_caller_port;
246 };
247 
248 /*
249 This class implements the bw interface.
250 It allows to register a callback for each of the bw interface methods.
251 The callbacks simply forward the bw interface call, but add the id (an int)
252 of the callback binder to the signature of the call.
253 */
254 template <typename TYPES>
256  : public tlm::tlm_bw_transport_if<TYPES>
257  , protected convenience_socket_cb_holder
258 {
259  public:
260  //typedefs according to the used TYPES class
261  typedef typename TYPES::tlm_payload_type transaction_type;
262  typedef typename TYPES::tlm_phase_type phase_type;
264 
265  //typedefs for the callbacks
266  typedef nb_transport_functor<TYPES> nb_func_type;
267  typedef invalidate_dmi_functor<TYPES> dmi_func_type;
268 
269  //ctor: an ID is needed to create a callback binder
271  : convenience_socket_cb_holder(owner), m_id(id)
272  , m_nb_f(0), m_dmi_f(0) {}
273 
274  //the nb_transport method of the bw interface
275  sync_enum_type nb_transport_bw(transaction_type& txn,
276  phase_type& p,
277  sc_core::sc_time& t){
278  //check if a callback is registered
279  if (m_nb_f && m_nb_f->is_valid()) {
280  return (*m_nb_f)(m_id, txn, p, t); //do the callback
281  }
282 
283  display_error("Call to nb_transport_bw without a registered callback for nb_transport_bw");
284  return tlm::TLM_COMPLETED;
285  }
286 
287  //the DMI method of the bw interface
289  //check if a callback is registered
290  if (m_dmi_f && m_dmi_f->is_valid()) {
291  (*m_dmi_f)(m_id,l,u); //do the callback
292  }
293  }
294 
295  //register callbacks for all bw interface methods at once
296  void set_callbacks(nb_func_type& cb1, dmi_func_type& cb2){
297  m_nb_f=&cb1;
298  m_dmi_f=&cb2;
299  }
300 
301  private:
302  //the ID of the callback binder
303  int m_id;
304  //the callbacks
305  nb_func_type* m_nb_f;
306  dmi_func_type* m_dmi_f;
307 };
308 
309 /*
310 This class forms the base for multi initiator sockets,
311 with fewer template parameters than the multi_init_base.
312 This class is implementation-defined.
313 */
314 template <typename TYPES = tlm::tlm_base_protocol_types>
316 public:
317  //this method shall return a vector of the callback binders of multi initiator socket
318  virtual std::vector<callback_binder_bw<TYPES>* >& get_binders()=0;
319  //this method shall return a vector of all target interfaces bound to this multi init socket
320  virtual std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets()=0;
321 protected:
322  virtual ~multi_init_base_if() {}
323 };
324 
325 /*
326 This class forms the base for multi initiator sockets.
327 It enforces a multi initiator socket to implement all functions
328 needed to do hierarchical bindings.
329 */
330 template <unsigned int BUSWIDTH = 32,
331  typename TYPES = tlm::tlm_base_protocol_types,
332  unsigned int N=0,
335  : public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL>
336  , public multi_init_base_if<TYPES>
337  , protected multi_socket_base
338 {
339 public:
340  //typedef for the base type: the standard tlm initiator socket
342 
343  //this method shall disable the code that does the callback binding
344  // that registers callbacks to binders
345  virtual void disable_cb_bind()=0;
346 
347  //this method shall return the multi_init_base to which the
348  // multi_init_base is bound hierarchically
349  // If the base is not bound hierarchically it shall return a pointer to itself
350  virtual multi_init_base* get_hierarch_bind()=0;
351 
353  {
355  }
356 
357  //ctor and dtor
358  virtual ~multi_init_base(){}
359  multi_init_base():base_type(sc_core::sc_gen_unique_name("multi_init_base")){}
360  multi_init_base(const char* name):base_type(name){}
361 
362 private:
363  const sc_core::sc_object* get_socket() const { return this; }
364 };
365 
366 /*
367 This class forms the base for multi target sockets,
368 with fewer template parameters than the multi_target_base.
369 This class is implementation-defined.
370 */
371 template <typename TYPES = tlm::tlm_base_protocol_types>
373 public:
374  //this method shall return a vector of the callback binders of multi initiator socket
375  virtual std::vector<callback_binder_fw<TYPES>* >& get_binders()=0;
376 
377  //this method shall return a map of all multi initiator sockets that are
378  // bound to this multi target the key of the map is the index at which the
379  // multi initiator i bound, while the value is the interface of the multi
380  // initiator socket that is bound at that index
381  virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds()=0;
382 protected:
384 };
385 
386 /*
387 This class forms the base for multi target sockets.
388 It enforces a multi target socket to implement all functions
389 needed to do hierarchical bindings.
390 */
391 template <unsigned int BUSWIDTH = 32,
392  typename TYPES = tlm::tlm_base_protocol_types,
393  unsigned int N=0,
396  : public tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL>
397  , public multi_target_base_if<TYPES>
398  , protected multi_socket_base
399 {
400 public:
401  //typedef for the base type: the standard tlm target socket
403 
404  //this method shall return the multi_init_base to which the
405  // multi_init_base is bound hierarchically
406  // If the base is not bound hierarchically it shall return a pointer to itself
407  virtual multi_target_base* get_hierarch_bind()=0;
408 
409  //this method shall inform the multi target socket that it is bound
410  // hierarchically and to which other multi target socket it is bound hierarchically
411  virtual void set_hierarch_bind(multi_target_base*)=0;
412 
414  {
416  }
417 
418  //ctor and dtor
419  virtual ~multi_target_base(){}
420  multi_target_base():base_type(sc_core::sc_gen_unique_name("multi_target_base")){}
421  multi_target_base(const char* name):base_type(name){}
422 
423 private:
424  const sc_core::sc_object* get_socket() const { return this; }
425 };
426 
427 /*
428 All multi sockets must additionally derive from this class.
429 It enforces a multi socket to implement a function
430 needed to do multi init to multi target bindings.
431 */
432 template <typename TYPES>
434 public:
437 };
438 
439 } // namespace tlm_utils
440 #endif // TLM_UTILS_MULTI_SOCKET_BASES_H_INCLUDED_
b_transport_functor< TYPES > b_func_type
invalidate_dmi_functor< TYPES > dmi_func_type
TLM_DEFINE_FUNCTOR(nb_transport)
nb_transport_functor< TYPES > nb_func_type
bool get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
get_dmi_ptr_functor< TYPES > dmi_func_type
void set_callbacks(nb_func_type &cb1, dmi_func_type &cb2)
sync_enum_type nb_transport_fw(transaction_type &txn, phase_type &p, sc_core::sc_time &t)
nb_transport_functor< TYPES > nb_func_type
virtual tlm::tlm_socket_category get_socket_category() const
TYPES::tlm_phase_type phase_type
callback_binder_fw(multi_socket_base *owner, int id)
SC_ONE_OR_MORE_BOUND
tlm::tlm_target_socket< BUSWIDTH, TYPES, N, POL > base_type
uint64_t uint64
void set_start_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:70
void allow_none(void)
Definition: tlm_dmi.h:75
void register_port(sc_core::sc_port_base &b, const char *)
callback_binder_bw(multi_socket_base *owner, int id)
void set_callbacks(nb_func_type &cb1, b_func_type &cb2, dmi_func_type &cb3, debug_func_type &cb4)
sync_enum_type nb_transport_bw(transaction_type &txn, phase_type &p, sc_core::sc_time &t)
void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u)
void b_transport(transaction_type &trans, sc_core::sc_time &t)
tlm::tlm_initiator_socket< BUSWIDTH, TYPES, N, POL > base_type
sc_core::sc_port_base * get_other_side()
TYPES::tlm_payload_type transaction_type
multi_init_base(const char *name)
SC_API const char * sc_gen_unique_name(const char *, bool preserve_first)
unsigned int transport_dbg(transaction_type &trans)
tlm_sync_enum
Definition: tlm_fw_bw_ifs.h:29
virtual tlm::tlm_socket_category get_socket_category() const
TYPES::tlm_phase_type phase_type
debug_transport_functor< TYPES > debug_func_type
void set_end_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:71
TYPES::tlm_payload_type transaction_type