gem5  v20.1.0.0
multi_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 #ifndef __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__
20 #define __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__
21 
22 #include "../core/sc_module.hh"
23 #include "../core/sc_port.hh"
24 #include "multi_socket_bases.h"
25 
26 namespace tlm_utils
27 {
28 
29 /*
30 This class implements a trivial multi target socket.
31 The triviality refers to the fact that the socket does not
32 do blocking to non-blocking or non-blocking to blocking conversions.
33 
34 It allows to connect multiple initiators to this socket.
35 The user has to register callbacks for the fw interface methods
36 he likes to use. The callbacks are basically equal to the fw interface
37 methods but carry an additional integer that indicates to which
38 index of this socket the calling initiator is connected.
39 */
40 template <typename MODULE, unsigned int BUSWIDTH=32,
41  typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
43 class multi_passthrough_target_socket :
44  public multi_target_base< BUSWIDTH, TYPES, N, POL>,
45  public multi_to_multi_bind_base<TYPES>
46 {
47  public:
48  //typedefs
49  // tlm 2.0 types for nb_transport
50  typedef typename TYPES::tlm_payload_type transaction_type;
51  typedef typename TYPES::tlm_phase_type phase_type;
53 
54  // typedefs to keep the fn ptr notations short
55  typedef sync_enum_type (MODULE::*nb_cb)(
57  typedef void (MODULE::*b_cb)(int, transaction_type &, sc_core::sc_time &);
58  typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type &txn);
59  typedef bool (MODULE::*dmi_cb)(
60  int, transaction_type &txn, tlm::tlm_dmi &dmi);
61 
63 
66 
67  static const char *
68  default_name()
69  {
70  return sc_core::sc_gen_unique_name("multi_passthrough_target_socket");
71  }
72 
73  explicit multi_passthrough_target_socket(const char *name=default_name()) :
76  {}
77 
79  {
80  // Clean up everything allocated by 'new'.
81  for (unsigned int i = 0; i < m_binders.size(); i++)
82  delete m_binders[i];
83  }
84 
85  void
87  {
88  // If our export hasn't been bound yet (due to a hierarch binding)
89  // we bind it now. We do that here as the user of the target port HAS
90  // to bind at least on callback, otherwise the socket was useless.
91  // Nevertheless, the target socket may still stay unbound afterwards.
93  get_interface()) {
94  // We bind to a callback_binder that will be used as the first
95  // interface i.e. calls to the sc_export will have the same ID as
96  // calls from the first initator socket bound.
98 
99  if (m_binders.size() == 0) {
100  binder = new callback_binder_fw<TYPES>(
101  this, m_binders.size());
102  m_binders.push_back(binder);
104  } else {
105  binder = m_binders[0];
106  }
107 
109  }
110  }
111 
112  //register callback for nb transport of fw interface
113  void
114  register_nb_transport_fw(MODULE *mod, nb_cb cb)
115  {
117 
118  // Warn if there already is a callback.
119  if (m_nb_f.is_valid()) {
120  display_warning("NBTransport_bw callback already registered.");
121  return;
122  }
123 
124  // Set the functor.
125  m_nb_f.set_function(mod, cb);
126  }
127 
128  // Register callback for b transport of fw interface.
129  void
130  register_b_transport(MODULE *mod, b_cb cb)
131  {
133 
134  // Warn if there already is a callback.
135  if (m_b_f.is_valid()) {
136  display_warning("BTransport callback already registered.");
137  return;
138  }
139 
140  // Set the functor.
141  m_b_f.set_function(mod, cb);
142  }
143 
144  // Register callback for debug transport of fw interface.
145  void
146  register_transport_dbg(MODULE *mod, dbg_cb cb)
147  {
149 
150  // Warn if there already is a callback.
151  if (m_dbg_f.is_valid()) {
152  display_warning("DebugTransport callback already registered.");
153  return;
154  }
155 
156  // Set the functor.
157  m_dbg_f.set_function(mod, cb);
158  }
159 
160  // Register callback for DMI of fw interface.
161  void
163  {
165 
166  // Warn if there already is a callback.
167  if (m_dmi_f.is_valid()) {
168  display_warning("DMI callback already registered.");
169  return;
170  }
171 
172  // Set the functor.
173  m_dmi_f.set_function(mod, cb);
174  }
175 
176 
177  // Override virtual functions of the tlm_target_socket:
178  // this function is called whenever an sc_port (as part of a init socket)
179  // wants to bind to the export of the underlying tlm_target_socket
180  // At this time a callback binder is created an returned to the sc_port
181  // of the init socket, so that it binds to the callback binder.
184  {
185  // Error if this socket is already bound hierarchically.
186  if (m_hierarch_bind)
187  display_error("Socket already bound hierarchically.");
188 
190  // Consume binder created from the callback registration.
192  } else {
193  m_binders.push_back(
194  new callback_binder_fw<TYPES>(this, m_binders.size()));
195  }
196 
197  return *m_binders[m_binders.size()-1];
198  }
199 
200  // Const overload not allowed for multi-sockets.
201  virtual const tlm::tlm_fw_transport_if<TYPES> &
202  get_base_interface() const
203  {
204  display_error("'get_base_interface() const'"
205  " not allowed for multi-sockets.");
207  }
208 
209  // Just return the export of the underlying tlm_target_socket in case of
210  // a hierarchical bind.
213  {
214  return *this;
215  }
216 
217  // Just return the export of the underlying tlm_target_socket in case of
218  // a hierarchical bind.
220  get_base_export() const
221  {
223  }
224 
225  // The standard end of elaboration callback.
226  void
228  {
229  // 'break' here if the socket was told not to do callback binding.
230  if (m_eoe_disabled)
231  return;
232 
233  // Get the callback binders and the multi binds of the top of the
234  // hierachical bind chain.
235  // NOTE: this could be the same socket if there is no hierachical
236  // bind.
239  std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
240  multi_binds = get_hierarch_bind()->get_multi_binds();
241 
242  // Complete binding only if there has been a real bind.
243  bool unbound = (binders.size() == 1 && m_export_callback_created);
244  // No call to get_base_interface has consumed the export - ignore.
245  if (unbound)
246  return;
247 
248  // Iterate over all binders.
249  for (unsigned int i = 0; i < binders.size(); i++) {
250  // Set the callbacks for the binder.
251  binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
252  // Check if this connection is multi-multi.
253  if (multi_binds.find(i) != multi_binds.end()) {
254  // If so remember the interface.
255  m_sockets.push_back(multi_binds[i]);
256  } else {
257  // If we are bound to a normal socket.
258  // Get the calling port and try to cast it into a tlm socket
259  // base.
262  binders[i]->get_other_side());
263  if (!test) {
264  display_error("Not bound to tlm_socket.");
265  }
266  // Remember the interface.
267  m_sockets.push_back(&test->get_base_interface());
268  }
269  }
270  }
271 
272  //
273  // Bind multi target socket to multi target socket (hierarchical bind)
274  //
275  virtual void
276  bind(base_type &s)
277  {
278  // Warn if already bound hierarchically.
279  if (m_eoe_disabled) {
280  display_warning("Socket already bound hierarchically. "
281  "Bind attempt ignored.");
282  return;
283  }
284 
285  // Disable our own end of elaboration call.
286  disable_cb_bind();
287 
288  // Inform the bound target socket that it is bound
289  // hierarchically now.
290  s.set_hierarch_bind((base_type*)this);
291  base_type::bind(s); // Satisfy SystemC.
292  }
293 
294  // Operator notation for hierarchical bind.
295  void operator () (base_type &s) { bind(s); }
296 
297  // Get access to sub port.
299  operator [] (int i)
300  {
301  return m_sockets[i];
302  }
303 
304  // Get number of bound initiators.
305  // NOTE: this is only valid at end of elaboration!
306  unsigned int size() { return get_hierarch_bind()->get_binders().size(); }
307 
308  protected:
311 
312  // Implementation of base class interface.
313  base_type *
315  {
316  if (m_hierarch_bind)
318  else
319  return this;
320  }
321  std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
323  {
324  return m_multi_binds;
325  }
329  {
330  m_multi_binds[m_binders.size() - 1] = other;
331  return m_binders[m_binders.size() - 1];
332  }
333 
334  // Map that stores to which index a multi init socket is connected
335  // and the interface of the multi init socket.
336  std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> m_multi_binds;
337 
338  void disable_cb_bind() { m_eoe_disabled = true; }
341  {
342  return m_binders;
343  }
344  // Vector of connected sockets.
346  // Vector of binders that convert untagged interface into tagged
347  // interface.
349 
350  base_type *m_hierarch_bind; // Pointer to hierarchical bound multi port.
351  // bool that disables callback bindings at end of elaboration.
352  bool m_eoe_disabled;
353  // bool that indicates that a binder has been created from a callback
354  // registration.
356 
357  // callbacks as functors
358  // (allows to pass the callback to another socket that does not know
359  // the type of the module that owns the callbacks).
364 };
365 
366 template <typename MODULE, unsigned int BUSWIDTH=32,
367  typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0>
370  MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND>
371 {
373  MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
374  public:
376  explicit multi_passthrough_target_socket_optional(const char *name) :
377  socket_b(name)
378  {}
379 };
380 
381 } // namespace tlm_utils
382 
383 #endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__ */
tlm::tlm_bw_transport_if
Definition: fw_bw_ifs.hh:231
sc_core::SC_ONE_OR_MORE_BOUND
@ SC_ONE_OR_MORE_BOUND
Definition: sc_port.hh:69
tlm_utils::multi_passthrough_target_socket::dmi_cb
bool(MODULE::* dmi_cb)(int, transaction_type &txn, tlm::tlm_dmi &dmi)
Definition: multi_passthrough_target_socket.h:93
tlm_utils::multi_passthrough_target_socket::m_dbg_f
callback_binder_fw< TYPES >::debug_func_type m_dbg_f
Definition: multi_passthrough_target_socket.h:396
tlm_utils::multi_passthrough_target_socket::disable_cb_bind
void disable_cb_bind()
Definition: multi_passthrough_target_socket.h:372
tlm_utils::multi_passthrough_target_socket_optional::multi_passthrough_target_socket_optional
multi_passthrough_target_socket_optional()
Definition: multi_passthrough_target_socket.h:392
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
test
Definition: test.h:38
tlm_utils::multi_passthrough_target_socket::sync_enum_type
tlm::tlm_sync_enum sync_enum_type
Definition: multi_passthrough_target_socket.h:86
tlm_utils::multi_passthrough_target_socket::register_b_transport
void register_b_transport(MODULE *mod, b_cb cb)
Definition: multi_passthrough_target_socket.h:164
mod
int mod(int val, int mod)
Definition: RubySlicc_Util.hh:90
tlm::tlm_dmi
Definition: dmi.hh:46
tlm_utils::multi_passthrough_target_socket::multi_passthrough_target_socket
multi_passthrough_target_socket(const char *name=default_name())
Definition: multi_passthrough_target_socket.h:107
tlm_utils::multi_passthrough_target_socket_optional::socket_b
multi_passthrough_target_socket< MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND > socket_b
Definition: multi_passthrough_target_socket.h:390
std::vector
STL vector class.
Definition: stl.hh:37
tlm_utils::multi_passthrough_target_socket_optional
Definition: multi_passthrough_target_socket.h:385
tlm_utils::convenience_socket_base::display_warning
void display_warning(const char *msg) const
Definition: convenience_socket_bases.cc:49
tlm_utils::multi_passthrough_target_socket::size
unsigned int size()
Definition: multi_passthrough_target_socket.h:340
tlm_utils::multi_passthrough_target_socket::base_initiator_socket_type
base_type::base_initiator_socket_type base_initiator_socket_type
Definition: multi_passthrough_target_socket.h:99
tlm::tlm_fw_transport_if
Definition: fw_bw_ifs.hh:221
tlm::tlm_base_initiator_socket_b
Definition: initiator_socket.hh:51
tlm_utils::multi_passthrough_target_socket::default_name
static const char * default_name()
Definition: multi_passthrough_target_socket.h:102
tlm_utils::multi_passthrough_target_socket::b_cb
void(MODULE::* b_cb)(int, transaction_type &, sc_core::sc_time &)
Definition: multi_passthrough_target_socket.h:91
multi_socket_bases.h
tlm_utils::multi_passthrough_target_socket::phase_type
TYPES::tlm_phase_type phase_type
Definition: multi_passthrough_target_socket.h:85
tlm_utils::multi_passthrough_target_socket::m_b_f
callback_binder_fw< TYPES >::b_func_type m_b_f
Definition: multi_passthrough_target_socket.h:395
sc_core::SC_ZERO_OR_MORE_BOUND
@ SC_ZERO_OR_MORE_BOUND
Definition: sc_port.hh:70
tlm_utils::multi_passthrough_target_socket::m_eoe_disabled
bool m_eoe_disabled
Definition: multi_passthrough_target_socket.h:386
tlm_utils::multi_passthrough_target_socket::base_type
multi_target_base< BUSWIDTH, TYPES, N, POL > base_type
Definition: multi_passthrough_target_socket.h:96
tlm_utils::multi_passthrough_target_socket::operator[]
tlm::tlm_bw_transport_if< TYPES > * operator[](int i)
Definition: multi_passthrough_target_socket.h:333
tlm_utils::callback_binder_fw::b_func_type
b_transport_functor< TYPES > b_func_type
Definition: multi_socket_bases.h:192
tlm_utils::multi_passthrough_target_socket::get_base_interface
virtual tlm::tlm_fw_transport_if< TYPES > & get_base_interface()
Definition: multi_passthrough_target_socket.h:217
sc_core::sc_time
Definition: sc_time.hh:49
tlm_utils::multi_passthrough_target_socket::set_hierarch_bind
void set_hierarch_bind(base_type *h)
Definition: multi_passthrough_target_socket.h:360
tlm_utils::convenience_socket_base::display_error
void display_error(const char *msg) const
Definition: convenience_socket_bases.cc:57
tlm_utils::multi_passthrough_target_socket::m_export_callback_created
bool m_export_callback_created
Definition: multi_passthrough_target_socket.h:389
tlm_utils::callback_binder_fw::debug_func_type
debug_transport_functor< TYPES > debug_func_type
Definition: multi_socket_bases.h:193
tlm_utils::multi_passthrough_target_socket::get_last_binder
tlm::tlm_fw_transport_if< TYPES > * get_last_binder(tlm::tlm_bw_transport_if< TYPES > *other)
Definition: multi_passthrough_target_socket.h:362
tlm_utils::multi_passthrough_target_socket
Definition: multi_passthrough_target_socket.h:60
tlm_utils::multi_passthrough_target_socket::m_dmi_f
callback_binder_fw< TYPES >::dmi_func_type m_dmi_f
Definition: multi_passthrough_target_socket.h:397
tlm_utils::multi_passthrough_target_socket::m_binders
std::vector< callback_binder_fw< TYPES > * > m_binders
Definition: multi_passthrough_target_socket.h:382
tlm_utils::multi_passthrough_target_socket::m_multi_binds
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > m_multi_binds
Definition: multi_passthrough_target_socket.h:370
sc_core::sc_gen_unique_name
const char * sc_gen_unique_name(const char *seed)
Definition: sc_module.cc:820
sc_core::sc_port_policy
sc_port_policy
Definition: sc_port.hh:67
tlm_utils::multi_passthrough_target_socket::~multi_passthrough_target_socket
~multi_passthrough_target_socket()
Definition: multi_passthrough_target_socket.h:112
tlm_utils::multi_passthrough_target_socket::m_hierarch_bind
base_type * m_hierarch_bind
Definition: multi_passthrough_target_socket.h:384
tlm_utils::multi_passthrough_target_socket::m_nb_f
callback_binder_fw< TYPES >::nb_func_type m_nb_f
Definition: multi_passthrough_target_socket.h:394
name
const std::string & name()
Definition: trace.cc:50
tlm_utils::multi_target_base_if::get_multi_binds
virtual std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > & get_multi_binds()=0
tlm_utils::multi_target_base_if::get_binders
virtual std::vector< callback_binder_fw< TYPES > * > & get_binders()=0
tlm_utils
Definition: convenience_socket_bases.h:29
tlm::tlm_base_target_socket_b
Definition: initiator_socket.hh:65
tlm_utils::multi_passthrough_target_socket::register_transport_dbg
void register_transport_dbg(MODULE *mod, dbg_cb cb)
Definition: multi_passthrough_target_socket.h:180
tlm_utils::multi_passthrough_target_socket::end_of_elaboration
void end_of_elaboration()
Definition: multi_passthrough_target_socket.h:261
tlm_utils::multi_passthrough_target_socket::get_multi_binds
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > & get_multi_binds()
Definition: multi_passthrough_target_socket.h:356
tlm_utils::multi_passthrough_target_socket::check_export_binding
void check_export_binding()
Definition: multi_passthrough_target_socket.h:120
tlm::tlm_base_protocol_types
Definition: fw_bw_ifs.hh:213
tlm_utils::multi_passthrough_target_socket::register_nb_transport_fw
void register_nb_transport_fw(MODULE *mod, nb_cb cb)
Definition: multi_passthrough_target_socket.h:148
tlm_utils::multi_passthrough_target_socket::transaction_type
TYPES::tlm_payload_type transaction_type
Definition: multi_passthrough_target_socket.h:84
tlm_utils::callback_binder_fw::dmi_func_type
get_dmi_ptr_functor< TYPES > dmi_func_type
Definition: multi_socket_bases.h:194
tlm_utils::callback_binder_fw::nb_func_type
nb_transport_functor< TYPES > nb_func_type
Definition: multi_socket_bases.h:191
tlm::tlm_sync_enum
tlm_sync_enum
Definition: fw_bw_ifs.hh:48
tlm_utils::multi_passthrough_target_socket::operator()
void operator()(base_type &s)
Definition: multi_passthrough_target_socket.h:329
tlm::tlm_base_target_socket< BUSWIDTH, tlm_fw_transport_if< tlm::tlm_base_protocol_types >, tlm_bw_transport_if< tlm::tlm_base_protocol_types >, N, POL >::get_base_export
virtual sc_core::sc_export< tlm_fw_transport_if< tlm::tlm_base_protocol_types > > & get_base_export()
Definition: target_socket.hh:200
tlm_utils::multi_passthrough_target_socket::get_binders
std::vector< callback_binder_fw< TYPES > * > & get_binders()
Definition: multi_passthrough_target_socket.h:374
tlm_utils::multi_passthrough_target_socket::get_hierarch_bind
base_type * get_hierarch_bind()
Definition: multi_passthrough_target_socket.h:348
tlm_utils::multi_target_base::get_hierarch_bind
virtual multi_target_base * get_hierarch_bind()=0
tlm_utils::multi_passthrough_target_socket::m_sockets
std::vector< tlm::tlm_bw_transport_if< TYPES > * > m_sockets
Definition: multi_passthrough_target_socket.h:379
ArmISA::s
Bitfield< 4 > s
Definition: miscregs_types.hh:556
tlm_utils::multi_passthrough_target_socket::dbg_cb
unsigned int(MODULE::* dbg_cb)(int, transaction_type &txn)
Definition: multi_passthrough_target_socket.h:92
sc_core::sc_export
Definition: sc_export.hh:60
tlm::tlm_base_target_socket< BUSWIDTH, tlm_fw_transport_if< tlm::tlm_base_protocol_types >, tlm_bw_transport_if< tlm::tlm_base_protocol_types >, N, POL >::bind
virtual void bind(base_initiator_socket_type &s)
Definition: target_socket.hh:112
tlm_utils::multi_passthrough_target_socket::register_get_direct_mem_ptr
void register_get_direct_mem_ptr(MODULE *mod, dmi_cb cb)
Definition: multi_passthrough_target_socket.h:196
tlm_utils::multi_passthrough_target_socket::bind
virtual void bind(base_type &s)
Definition: multi_passthrough_target_socket.h:310
tlm_utils::multi_passthrough_target_socket::nb_cb
sync_enum_type(MODULE::* nb_cb)(int, transaction_type &, phase_type &, sc_core::sc_time &)
Definition: multi_passthrough_target_socket.h:89
tlm::tlm_base_target_socket< BUSWIDTH, tlm_fw_transport_if< tlm::tlm_base_protocol_types >, tlm_bw_transport_if< tlm::tlm_base_protocol_types >, N, POL >::get_base_interface
virtual tlm_fw_transport_if< tlm::tlm_base_protocol_types > & get_base_interface()
Definition: target_socket.hh:197
tlm_utils::multi_passthrough_target_socket::get_base_export
virtual sc_core::sc_export< tlm::tlm_fw_transport_if< TYPES > > & get_base_export()
Definition: multi_passthrough_target_socket.h:246
tlm_utils::callback_binder_fw
Definition: multi_socket_bases.h:181
tlm_utils::multi_target_base
Definition: multi_socket_bases.h:454

Generated on Wed Sep 30 2020 14:02:16 for gem5 by doxygen 1.8.17