TLM-2.0  2.0.3
Accellera TLM-2.0 proof-of-concept library
passthrough_target_socket.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  The following code is derived, directly or indirectly, from the SystemC
4  source code Copyright (c) 1996-2014 by all Contributors.
5  All Rights reserved.
6 
7  The contents of this file are subject to the restrictions and limitations
8  set forth in the SystemC Open Source License (the "License");
9  You may not use this file except in compliance with such restrictions and
10  limitations. You may obtain instructions on how to receive a copy of the
11  License at http://www.accellera.org/. Software distributed by Contributors
12  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13  ANY KIND, either express or implied. See the License for the specific
14  language governing rights and limitations under the License.
15 
16  *****************************************************************************/
17 
18 #ifndef __PASSTHROUGH_TARGET_SOCKET_H__
19 #define __PASSTHROUGH_TARGET_SOCKET_H__
20 
21 #include <tlm>
22 #include <sstream>
23 
24 namespace tlm_utils {
25 
26 template <typename MODULE,
27  unsigned int BUSWIDTH = 32,
28  typename TYPES = tlm::tlm_base_protocol_types>
30  public tlm::tlm_target_socket<BUSWIDTH, TYPES>
31 {
32 public:
33  typedef typename TYPES::tlm_payload_type transaction_type;
34  typedef typename TYPES::tlm_phase_type phase_type;
39 
40 public:
42  base_type(sc_core::sc_gen_unique_name("passthrough_target_socket")),
43  m_process(this->name())
44  {
45  bind(m_process);
46  }
47 
48  explicit passthrough_target_socket(const char* n) :
49  base_type(n),
50  m_process(this->name())
51  {
52  bind(m_process);
53  }
54 
56 
57  // REGISTER_XXX
58  void register_nb_transport_fw(MODULE* mod,
59  sync_enum_type (MODULE::*cb)(transaction_type&,
60  phase_type&,
62  {
63  m_process.set_nb_transport_ptr(mod, cb);
64  }
65 
66  void register_b_transport(MODULE* mod,
67  void (MODULE::*cb)(transaction_type&,
69  {
70  m_process.set_b_transport_ptr(mod, cb);
71  }
72 
73  void register_transport_dbg(MODULE* mod,
74  unsigned int (MODULE::*cb)(transaction_type&))
75  {
76  m_process.set_transport_dbg_ptr(mod, cb);
77  }
78 
79  void register_get_direct_mem_ptr(MODULE* mod,
80  bool (MODULE::*cb)(transaction_type&,
81  tlm::tlm_dmi&))
82  {
83  m_process.set_get_direct_mem_ptr(mod, cb);
84  }
85 
86 private:
87  class process : 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  process(const std::string& name) :
100  m_name(name),
101  m_mod(0),
102  m_nb_transport_ptr(0),
103  m_b_transport_ptr(0),
104  m_transport_dbg_ptr(0),
105  m_get_direct_mem_ptr(0)
106  {
107  }
108 
109  void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
110  {
111  if (m_nb_transport_ptr) {
112  std::stringstream s;
113  s << m_name << ": non-blocking callback allready registered";
114  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
115 
116  } else {
117  assert(!m_mod || m_mod == mod);
118  m_mod = mod;
119  m_nb_transport_ptr = p;
120  }
121  }
122 
123  void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
124  {
125  if (m_b_transport_ptr) {
126  std::stringstream s;
127  s << m_name << ": blocking callback allready registered";
128  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
129  } else {
130  assert(!m_mod || m_mod == mod);
131  m_mod = mod;
132  m_b_transport_ptr = p;
133  }
134  }
135 
136  void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
137  {
138  if (m_transport_dbg_ptr) {
139  std::stringstream s;
140  s << m_name << ": debug callback allready registered";
141  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
142  } else {
143  assert(!m_mod || m_mod == mod);
144  m_mod = mod;
145  m_transport_dbg_ptr = p;
146  }
147  }
148 
149  void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
150  {
151  if (m_get_direct_mem_ptr) {
152  std::stringstream s;
153  s << m_name << ": get DMI pointer callback allready registered";
154  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
155  } else {
156  assert(!m_mod || m_mod == mod);
157  m_mod = mod;
158  m_get_direct_mem_ptr = p;
159  }
160  }
161 
162  sync_enum_type nb_transport_fw(transaction_type& trans,
163  phase_type& phase,
164  sc_core::sc_time& t)
165  {
166  if (m_nb_transport_ptr) {
167  // forward call
168  assert(m_mod);
169  return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
170 
171  } else {
172  std::stringstream s;
173  s << m_name << ": no non-blocking callback registered";
174  SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
175  }
176  return tlm::TLM_ACCEPTED;
177  }
178 
179  void b_transport(transaction_type& trans, sc_core::sc_time& t)
180  {
181  if (m_b_transport_ptr) {
182  // forward call
183  assert(m_mod);
184  return (m_mod->*m_b_transport_ptr)(trans, t);
185 
186  } else {
187  std::stringstream s;
188  s << m_name << ": no blocking callback registered";
189  SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
190  }
191  }
192 
193  unsigned int transport_dbg(transaction_type& trans)
194  {
195  if (m_transport_dbg_ptr) {
196  // forward call
197  assert(m_mod);
198  return (m_mod->*m_transport_dbg_ptr)(trans);
199 
200  } else {
201  // No debug support
202  return 0;
203  }
204  }
205 
206  bool get_direct_mem_ptr(transaction_type& trans,
207  tlm::tlm_dmi& dmi_data)
208  {
209  if (m_get_direct_mem_ptr) {
210  // forward call
211  assert(m_mod);
212  return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
213 
214  } else {
215  // No DMI support
216  dmi_data.allow_read_write();
217  dmi_data.set_start_address(0x0);
218  dmi_data.set_end_address((sc_dt::uint64)-1);
219  return false;
220  }
221  }
222 
223  private:
224  const std::string m_name;
225  MODULE* m_mod;
226  NBTransportPtr m_nb_transport_ptr;
227  BTransportPtr m_b_transport_ptr;
228  TransportDbgPtr m_transport_dbg_ptr;
229  GetDirectMem_ptr m_get_direct_mem_ptr;
230  };
231 
232 private:
233  process m_process;
234 };
235 
236 //ID Tagged version
237 template <typename MODULE,
238  unsigned int BUSWIDTH = 32,
239  typename TYPES = tlm::tlm_base_protocol_types>
241  public tlm::tlm_target_socket<BUSWIDTH, TYPES>
242 {
243 public:
244  typedef typename TYPES::tlm_payload_type transaction_type;
245  typedef typename TYPES::tlm_phase_type phase_type;
250 
251 public:
253  base_type(sc_core::sc_gen_unique_name("passthrough_target_socket_tagged")),
254  m_process(this->name())
255  {
256  bind(m_process);
257  }
258 
259  explicit passthrough_target_socket_tagged(const char* n) :
260  base_type(n),
261  m_process(this->name())
262  {
263  bind(m_process);
264  }
265 
267 
268  // REGISTER_XXX
269  void register_nb_transport_fw(MODULE* mod,
270  sync_enum_type (MODULE::*cb)(int id,
272  phase_type&,
274  int id)
275  {
276  m_process.set_nb_transport_ptr(mod, cb);
277  m_process.set_nb_transport_user_id(id);
278  }
279 
280  void register_b_transport(MODULE* mod,
281  void (MODULE::*cb)(int id,
284  int id)
285  {
286  m_process.set_b_transport_ptr(mod, cb);
287  m_process.set_b_transport_user_id(id);
288  }
289 
290  void register_transport_dbg(MODULE* mod,
291  unsigned int (MODULE::*cb)(int id,
293  int id)
294  {
295  m_process.set_transport_dbg_ptr(mod, cb);
296  m_process.set_transport_dbg_user_id(id);
297  }
298 
299  void register_get_direct_mem_ptr(MODULE* mod,
300  bool (MODULE::*cb)(int id,
302  tlm::tlm_dmi&),
303  int id)
304  {
305  m_process.set_get_direct_mem_ptr(mod, cb);
306  m_process.set_get_dmi_user_id(id);
307  }
308 
309 private:
310  class process : public tlm::tlm_fw_transport_if<TYPES>
311  {
312  public:
313  typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
315  phase_type&,
317  typedef void (MODULE::*BTransportPtr)(int id,
320  typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
322  typedef bool (MODULE::*GetDirectMem_ptr)(int id,
324  tlm::tlm_dmi&);
325 
326  process(const std::string& name) :
327  m_name(name),
328  m_mod(0),
329  m_nb_transport_ptr(0),
330  m_b_transport_ptr(0),
331  m_transport_dbg_ptr(0),
332  m_get_direct_mem_ptr(0),
333  m_nb_transport_user_id(0),
334  m_b_transport_user_id(0),
335  m_transport_dbg_user_id(0),
336  m_get_dmi_user_id(0)
337  {
338  }
339 
340  void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
341  void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
342  void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
343  void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
344 
345  void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
346  {
347  if (m_nb_transport_ptr) {
348  std::stringstream s;
349  s << m_name << ": non-blocking callback allready registered";
350  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
351  } else {
352  assert(!m_mod || m_mod == mod);
353  m_mod = mod;
354  m_nb_transport_ptr = p;
355  }
356  }
357 
358  void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
359  {
360  if (m_b_transport_ptr) {
361  std::stringstream s;
362  s << m_name << ": blocking callback allready registered";
363  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
364  } else {
365  assert(!m_mod || m_mod == mod);
366  m_mod = mod;
367  m_b_transport_ptr = p;
368  }
369  }
370 
371  void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
372  {
373  if (m_transport_dbg_ptr) {
374  std::stringstream s;
375  s << m_name << ": debug callback allready registered";
376  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
377  } else {
378  assert(!m_mod || m_mod == mod);
379  m_mod = mod;
380  m_transport_dbg_ptr = p;
381  }
382  }
383 
384  void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
385  {
386  if (m_get_direct_mem_ptr) {
387  std::stringstream s;
388  s << m_name << ": get DMI pointer callback allready registered";
389  SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
390  } else {
391  assert(!m_mod || m_mod == mod);
392  m_mod = mod;
393  m_get_direct_mem_ptr = p;
394  }
395  }
396 
397  sync_enum_type nb_transport_fw(transaction_type& trans,
398  phase_type& phase,
399  sc_core::sc_time& t)
400  {
401  if (m_nb_transport_ptr) {
402  // forward call
403  assert(m_mod);
404  return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
405 
406  } else {
407  std::stringstream s;
408  s << m_name << ": no non-blocking callback registered";
409  SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
410  }
411  return tlm::TLM_ACCEPTED;
412  }
413 
414  void b_transport(transaction_type& trans, sc_core::sc_time& t)
415  {
416  if (m_b_transport_ptr) {
417  // forward call
418  assert(m_mod);
419  return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
420 
421  } else {
422  std::stringstream s;
423  s << m_name << ": no blocking callback registered";
424  SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
425  }
426  }
427 
428  unsigned int transport_dbg(transaction_type& trans)
429  {
430  if (m_transport_dbg_ptr) {
431  // forward call
432  assert(m_mod);
433  return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
434 
435  } else {
436  // No debug support
437  return 0;
438  }
439  }
440 
441  bool get_direct_mem_ptr(transaction_type& trans,
442  tlm::tlm_dmi& dmi_data)
443  {
444  if (m_get_direct_mem_ptr) {
445  // forward call
446  assert(m_mod);
447  return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
448 
449  } else {
450  // No DMI support
451  dmi_data.allow_read_write();
452  dmi_data.set_start_address(0x0);
453  dmi_data.set_end_address((sc_dt::uint64)-1);
454  return false;
455  }
456  }
457 
458  private:
459  const std::string m_name;
460  MODULE* m_mod;
461  NBTransportPtr m_nb_transport_ptr;
462  BTransportPtr m_b_transport_ptr;
463  TransportDbgPtr m_transport_dbg_ptr;
464  GetDirectMem_ptr m_get_direct_mem_ptr;
465  int m_nb_transport_user_id;
466  int m_b_transport_user_id;
467  int m_transport_dbg_user_id;
468  int m_get_dmi_user_id;
469  };
470 
471 private:
472  process m_process;
473 };
474 
475 }
476 
477 #endif
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
void register_b_transport(MODULE *mod, void(MODULE::*cb)(int id, transaction_type &, sc_core::sc_time &), int id)
uint64_t uint64
void set_end_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:69
void register_b_transport(MODULE *mod, void(MODULE::*cb)(transaction_type &, sc_core::sc_time &))
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(int id, transaction_type &, phase_type &, sc_core::sc_time &), int id)
#define SC_REPORT_WARNING(msg_type, msg)
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
tlm::tlm_target_socket< BUSWIDTH, TYPES > base_type
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(int id, transaction_type &), int id)
void set_start_address(sc_dt::uint64 addr)
Definition: tlm_dmi.h:68
const char * sc_gen_unique_name(const char *, bool preserve_first)
tlm::tlm_target_socket< BUSWIDTH, TYPES > base_type
void allow_read_write(void)
Definition: tlm_dmi.h:76
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), int id)
tlm_sync_enum
Definition: tlm_fw_bw_ifs.h:27
virtual void bind(base_initiator_socket_type &s)
#define SC_REPORT_ERROR(msg_type, msg)
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(transaction_type &))
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
tlm::tlm_fw_transport_if< TYPES > fw_interface_type