TLM-2.0  2.0.4
Accellera TLM-2.0 proof-of-concept library
passthrough_target_socket.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_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
21 #define TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
22 
23 #include <tlm>
25 
26 namespace tlm_utils {
27 
28 template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
31  : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
32  , protected passthrough_socket_base
33 {
34 public:
35  typedef typename TYPES::tlm_payload_type transaction_type;
36  typedef typename TYPES::tlm_phase_type phase_type;
41 
42 public:
43  static const char* default_name()
44  { return sc_core::sc_gen_unique_name("passthrough_target_socket"); }
45 
46  explicit passthrough_target_socket_b(const char* n = default_name())
47  : base_type(n)
48  , m_process(this)
49  {
50  bind(m_process);
51  }
52 
53  using base_type::bind;
54 
55  // REGISTER_XXX
56  void register_nb_transport_fw(MODULE* mod,
57  sync_enum_type (MODULE::*cb)(transaction_type&,
58  phase_type&,
60  {
61  m_process.set_nb_transport_ptr(mod, cb);
62  }
63 
64  void register_b_transport(MODULE* mod,
65  void (MODULE::*cb)(transaction_type&,
67  {
68  m_process.set_b_transport_ptr(mod, cb);
69  }
70 
71  void register_transport_dbg(MODULE* mod,
72  unsigned int (MODULE::*cb)(transaction_type&))
73  {
74  m_process.set_transport_dbg_ptr(mod, cb);
75  }
76 
77  void register_get_direct_mem_ptr(MODULE* mod,
78  bool (MODULE::*cb)(transaction_type&,
79  tlm::tlm_dmi&))
80  {
81  m_process.set_get_direct_mem_ptr(mod, cb);
82  }
83 
84 private:
85  class process
86  : public tlm::tlm_fw_transport_if<TYPES>
88  {
89  public:
90  typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
91  phase_type&,
93  typedef void (MODULE::*BTransportPtr)(transaction_type&,
95  typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
96  typedef bool (MODULE::*GetDirectMem_ptr)(transaction_type&,
97  tlm::tlm_dmi&);
98 
99  explicit process(passthrough_socket_base* owner)
100  : convenience_socket_cb_holder(owner), m_mod(0)
101  , m_nb_transport_ptr(0)
102  , m_b_transport_ptr(0)
103  , m_transport_dbg_ptr(0)
104  , m_get_direct_mem_ptr(0)
105  {
106  }
107 
108  void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
109  {
110  if (m_nb_transport_ptr) {
111  display_warning("non-blocking callback already registered");
112  return;
113  }
114  sc_assert(!m_mod || m_mod == mod);
115  m_mod = mod;
116  m_nb_transport_ptr = p;
117  }
118 
119  void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
120  {
121  if (m_b_transport_ptr) {
122  display_warning("blocking callback already registered");
123  return;
124  }
125  sc_assert(!m_mod || m_mod == mod);
126  m_mod = mod;
127  m_b_transport_ptr = p;
128  }
129 
130  void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
131  {
132  if (m_transport_dbg_ptr) {
133  display_warning("debug callback already registered");
134  return;
135  }
136  sc_assert(!m_mod || m_mod == mod);
137  m_mod = mod;
138  m_transport_dbg_ptr = p;
139  }
140 
141  void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
142  {
143  if (m_get_direct_mem_ptr) {
144  display_warning("get DMI pointer callback already registered");
145  return;
146  }
147  sc_assert(!m_mod || m_mod == mod);
148  m_mod = mod;
149  m_get_direct_mem_ptr = p;
150  }
151 
152  sync_enum_type nb_transport_fw(transaction_type& trans,
153  phase_type& phase,
154  sc_core::sc_time& t)
155  {
156  if (m_nb_transport_ptr) {
157  // forward call
158  sc_assert(m_mod);
159  return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
160  }
161  display_error("no non-blocking callback registered");
162  return tlm::TLM_COMPLETED;
163  }
164 
165  void b_transport(transaction_type& trans, sc_core::sc_time& t)
166  {
167  if (m_b_transport_ptr) {
168  // forward call
169  sc_assert(m_mod);
170  return (m_mod->*m_b_transport_ptr)(trans, t);
171  }
172  display_error("no blocking callback registered");
173  }
174 
175  unsigned int transport_dbg(transaction_type& trans)
176  {
177  if (m_transport_dbg_ptr) {
178  // forward call
179  sc_assert(m_mod);
180  return (m_mod->*m_transport_dbg_ptr)(trans);
181  }
182  // No debug support
183  return 0;
184  }
185 
186  bool get_direct_mem_ptr(transaction_type& trans,
187  tlm::tlm_dmi& dmi_data)
188  {
189  if (m_get_direct_mem_ptr) {
190  // forward call
191  sc_assert(m_mod);
192  return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
193  }
194  // No DMI support
195  dmi_data.allow_read_write();
196  dmi_data.set_start_address(0x0);
197  dmi_data.set_end_address((sc_dt::uint64)-1);
198  return false;
199  }
200 
201  private:
202  MODULE* m_mod;
203  NBTransportPtr m_nb_transport_ptr;
204  BTransportPtr m_b_transport_ptr;
205  TransportDbgPtr m_transport_dbg_ptr;
206  GetDirectMem_ptr m_get_direct_mem_ptr;
207  };
208 
209 private:
210  const sc_core::sc_object* get_socket() const { return this; }
211 private:
212  process m_process;
213 };
214 
215 template< typename MODULE, unsigned int BUSWIDTH = 32
216  , typename TYPES = tlm::tlm_base_protocol_types >
218  : public passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES>
219 {
221 public:
222  passthrough_target_socket() : socket_b() {}
223  explicit passthrough_target_socket(const char* name) : socket_b(name) {}
224 };
225 
226 template< typename MODULE, unsigned int BUSWIDTH = 32
227  , typename TYPES = tlm::tlm_base_protocol_types >
229  : public passthrough_target_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
230 {
232 public:
234  explicit passthrough_target_socket_optional(const char* name) : socket_b(name) {}
235 };
236 
237 //ID Tagged version
238 template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
241  : public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>
242  , protected passthrough_socket_base
243 {
244 public:
245  typedef typename TYPES::tlm_payload_type transaction_type;
246  typedef typename TYPES::tlm_phase_type phase_type;
251 
252  static const char* default_name()
253  { return sc_core::sc_gen_unique_name("passthrough_target_socket_tagged"); }
254 
255 public:
257  : base_type(n)
258  , m_process(this)
259  {
260  bind(m_process);
261  }
262 
263  using base_type::bind;
264 
265  // REGISTER_XXX
266  void register_nb_transport_fw(MODULE* mod,
267  sync_enum_type (MODULE::*cb)(int id,
268  transaction_type&,
269  phase_type&,
271  int id)
272  {
273  m_process.set_nb_transport_ptr(mod, cb);
274  m_process.set_nb_transport_user_id(id);
275  }
276 
277  void register_b_transport(MODULE* mod,
278  void (MODULE::*cb)(int id,
279  transaction_type&,
281  int id)
282  {
283  m_process.set_b_transport_ptr(mod, cb);
284  m_process.set_b_transport_user_id(id);
285  }
286 
287  void register_transport_dbg(MODULE* mod,
288  unsigned int (MODULE::*cb)(int id,
289  transaction_type&),
290  int id)
291  {
292  m_process.set_transport_dbg_ptr(mod, cb);
293  m_process.set_transport_dbg_user_id(id);
294  }
295 
296  void register_get_direct_mem_ptr(MODULE* mod,
297  bool (MODULE::*cb)(int id,
298  transaction_type&,
299  tlm::tlm_dmi&),
300  int id)
301  {
302  m_process.set_get_direct_mem_ptr(mod, cb);
303  m_process.set_get_dmi_user_id(id);
304  }
305 
306 private:
307  class process
308  : public tlm::tlm_fw_transport_if<TYPES>
309  , protected convenience_socket_cb_holder
310  {
311  public:
312  typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
313  transaction_type&,
314  phase_type&,
316  typedef void (MODULE::*BTransportPtr)(int id,
317  transaction_type&,
319  typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
320  transaction_type&);
321  typedef bool (MODULE::*GetDirectMem_ptr)(int id,
322  transaction_type&,
323  tlm::tlm_dmi&);
324 
325  process(passthrough_socket_base* owner)
326  : convenience_socket_cb_holder(owner), m_mod(0)
327  , m_nb_transport_ptr(0)
328  , m_b_transport_ptr(0)
329  , m_transport_dbg_ptr(0)
330  , m_get_direct_mem_ptr(0)
331  , m_nb_transport_user_id(0)
332  , m_b_transport_user_id(0)
333  , m_transport_dbg_user_id(0)
334  , m_get_dmi_user_id(0)
335  {
336  }
337 
338  void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
339  void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
340  void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
341  void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
342 
343  void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
344  {
345  if (m_nb_transport_ptr) {
346  display_warning("non-blocking callback already registered");
347  return;
348  }
349  sc_assert(!m_mod || m_mod == mod);
350  m_mod = mod;
351  m_nb_transport_ptr = p;
352  }
353 
354  void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
355  {
356  if (m_b_transport_ptr) {
357  display_warning("blocking callback already registered");
358  return;
359  }
360  sc_assert(!m_mod || m_mod == mod);
361  m_mod = mod;
362  m_b_transport_ptr = p;
363  }
364 
365  void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
366  {
367  if (m_transport_dbg_ptr) {
368  display_warning("debug callback already registered");
369  return;
370  }
371  sc_assert(!m_mod || m_mod == mod);
372  m_mod = mod;
373  m_transport_dbg_ptr = p;
374  }
375 
376  void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
377  {
378  if (m_get_direct_mem_ptr) {
379  display_warning("get DMI pointer callback already registered");
380  return;
381  }
382  sc_assert(!m_mod || m_mod == mod);
383  m_mod = mod;
384  m_get_direct_mem_ptr = p;
385  }
386 
387  sync_enum_type nb_transport_fw(transaction_type& trans,
388  phase_type& phase,
389  sc_core::sc_time& t)
390  {
391  if (m_nb_transport_ptr) {
392  // forward call
393  sc_assert(m_mod);
394  return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
395  }
396  display_error("no non-blocking callback registered");
397  return tlm::TLM_COMPLETED;
398  }
399 
400  void b_transport(transaction_type& trans, sc_core::sc_time& t)
401  {
402  if (m_b_transport_ptr) {
403  // forward call
404  sc_assert(m_mod);
405  return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
406  }
407  display_error("no blocking callback registered");
408  }
409 
410  unsigned int transport_dbg(transaction_type& trans)
411  {
412  if (m_transport_dbg_ptr) {
413  // forward call
414  sc_assert(m_mod);
415  return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
416  }
417  // No debug support
418  return 0;
419  }
420 
421  bool get_direct_mem_ptr(transaction_type& trans,
422  tlm::tlm_dmi& dmi_data)
423  {
424  if (m_get_direct_mem_ptr) {
425  // forward call
426  sc_assert(m_mod);
427  return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
428  }
429  // No DMI support
430  dmi_data.allow_read_write();
431  dmi_data.set_start_address(0x0);
432  dmi_data.set_end_address((sc_dt::uint64)-1);
433  return false;
434  }
435 
436  private:
437  MODULE* m_mod;
438  NBTransportPtr m_nb_transport_ptr;
439  BTransportPtr m_b_transport_ptr;
440  TransportDbgPtr m_transport_dbg_ptr;
441  GetDirectMem_ptr m_get_direct_mem_ptr;
442  int m_nb_transport_user_id;
443  int m_b_transport_user_id;
444  int m_transport_dbg_user_id;
445  int m_get_dmi_user_id;
446  };
447 
448 private:
449  const sc_core::sc_object* get_socket() const { return this; }
450 private:
451  process m_process;
452 };
453 
454 template< typename MODULE, unsigned int BUSWIDTH = 32
455  , typename TYPES = tlm::tlm_base_protocol_types >
457  : public passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
458 {
460 public:
462  explicit passthrough_target_socket_tagged(const char* name) : socket_b(name) {}
463 };
464 
465 template< typename MODULE, unsigned int BUSWIDTH = 32
466  , typename TYPES = tlm::tlm_base_protocol_types >
468  : public passthrough_target_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
469 {
471 public:
473  explicit passthrough_target_socket_tagged_optional(const char* name) : socket_b(name) {}
474 };
475 
476 } // namespace tlm_utils
477 #endif // TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H_INCLUDED_
#define sc_assert(expr)
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
void display_warning(const char *msg) const
passthrough_target_socket_tagged_b(const char *n=default_name())
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
SC_ONE_OR_MORE_BOUND
uint64_t uint64
void set_start_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:70
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(transaction_type &))
void register_b_transport(MODULE *mod, void(MODULE::*cb)(transaction_type &, sc_core::sc_time &))
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(int id, transaction_type &), int id)
tlm::tlm_target_socket< BUSWIDTH, TYPES, 1, POL > base_type
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(int id, transaction_type &, phase_type &, sc_core::sc_time &), int id)
passthrough_target_socket_b(const char *n=default_name())
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
tlm::tlm_target_socket< BUSWIDTH, TYPES, 1, POL > base_type
void allow_read_write(void)
Definition: tlm_dmi.h:78
void display_error(const char *msg) const
SC_API const char * sc_gen_unique_name(const char *, bool preserve_first)
tlm_sync_enum
Definition: tlm_fw_bw_ifs.h:29
void register_b_transport(MODULE *mod, void(MODULE::*cb)(int id, transaction_type &, sc_core::sc_time &), int id)
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), int id)
void set_end_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:71