gem5  v22.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,
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 *
69  {
70  return sc_core::sc_gen_unique_name("multi_passthrough_target_socket");
71  }
72 
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
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
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
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> &
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.
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 locally_unbound =
244  (binders.size() == 1 && m_export_callback_created);
245  // No call to get_base_interface has consumed the export - ignore.
246  if (locally_unbound && !m_hierarch_bind)
247  return;
248 
249  // Iterate over all binders.
250  for (unsigned int i = 0; i < binders.size(); i++) {
251  // Set the callbacks for the binder.
252  binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
253  // Check if this connection is multi-multi.
254  if (multi_binds.find(i) != multi_binds.end()) {
255  // If so remember the interface.
256  m_sockets.push_back(multi_binds[i]);
257  } else {
258  // If we are bound to a normal socket.
259  // Get the calling port and try to cast it into a tlm socket
260  // base.
262  dynamic_cast<base_initiator_socket_type*>(
263  binders[i]->get_other_side());
264  if (!test) {
265  display_error("Not bound to tlm_socket.");
266  }
267  // Remember the interface.
268  m_sockets.push_back(&test->get_base_interface());
269  }
270  }
271  }
272 
273  //
274  // Bind multi target socket to multi target socket (hierarchical bind)
275  //
276  virtual void
278  {
279  // Warn if already bound hierarchically.
280  if (m_eoe_disabled) {
281  display_warning("Socket already bound hierarchically. "
282  "Bind attempt ignored.");
283  return;
284  }
285 
286  // Disable our own end of elaboration call.
287  disable_cb_bind();
288 
289  // Inform the bound target socket that it is bound
290  // hierarchically now.
291  s.set_hierarch_bind((base_type*)this);
292  base_type::bind(s); // Satisfy SystemC.
293  }
294 
295  // Operator notation for hierarchical bind.
297 
298  // Get access to sub port.
301  {
302  return m_sockets[i];
303  }
304 
305  // Get number of bound initiators.
306  // NOTE: this is only valid at end of elaboration!
307  unsigned int size() { return get_hierarch_bind()->get_binders().size(); }
308 
309  protected:
312 
313  // Implementation of base class interface.
314  base_type *
316  {
317  if (m_hierarch_bind)
319  else
320  return this;
321  }
322  std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
324  {
325  return m_multi_binds;
326  }
330  {
331  m_multi_binds[m_binders.size() - 1] = other;
332  return m_binders[m_binders.size() - 1];
333  }
334 
335  // Map that stores to which index a multi init socket is connected
336  // and the interface of the multi init socket.
337  std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> m_multi_binds;
338 
339  void disable_cb_bind() { m_eoe_disabled = true; }
342  {
343  return m_binders;
344  }
345  // Vector of connected sockets.
347  // Vector of binders that convert untagged interface into tagged
348  // interface.
350 
351  base_type *m_hierarch_bind; // Pointer to hierarchical bound multi port.
352  // bool that disables callback bindings at end of elaboration.
354  // bool that indicates that a binder has been created from a callback
355  // registration.
357 
358  // callbacks as functors
359  // (allows to pass the callback to another socket that does not know
360  // the type of the module that owns the callbacks).
365 };
366 
367 template <typename MODULE, unsigned int BUSWIDTH=32,
368  typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0>
371  MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND>
372 {
374  MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
375  public:
378  socket_b(name)
379  {}
380 };
381 
382 } // namespace tlm_utils
383 
384 #endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__ */
const sc_interface * get_interface() const override
Definition: sc_export.hh:107
const char * name() const
Definition: sc_object.cc:44
STL vector class.
Definition: stl.hh:37
virtual void bind(base_initiator_socket_type &s)
virtual FW_IF & get_base_interface()
virtual sc_core::sc_export< FW_IF > & get_base_export()
get_dmi_ptr_functor< TYPES > dmi_func_type
debug_transport_functor< TYPES > debug_func_type
nb_transport_functor< TYPES > nb_func_type
b_transport_functor< TYPES > b_func_type
void display_warning(const char *msg) const
void display_error(const char *msg) const
multi_passthrough_target_socket< MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND > socket_b
callback_binder_fw< TYPES >::dmi_func_type m_dmi_f
callback_binder_fw< TYPES >::debug_func_type m_dbg_f
std::vector< callback_binder_fw< TYPES > * > m_binders
virtual sc_core::sc_export< tlm::tlm_fw_transport_if< TYPES > > & get_base_export()
std::vector< tlm::tlm_bw_transport_if< TYPES > * > m_sockets
multi_passthrough_target_socket(const char *name=default_name())
unsigned int(MODULE::* dbg_cb)(int, transaction_type &txn)
tlm::tlm_fw_transport_if< TYPES > * get_last_binder(tlm::tlm_bw_transport_if< TYPES > *other)
multi_target_base< BUSWIDTH, TYPES, N, POL > base_type
virtual const sc_core::sc_export< tlm::tlm_fw_transport_if< TYPES > > & get_base_export() const
tlm::tlm_bw_transport_if< TYPES > * operator[](int i)
base_type::base_initiator_socket_type base_initiator_socket_type
virtual tlm::tlm_fw_transport_if< TYPES > & get_base_interface()
void(MODULE::* b_cb)(int, transaction_type &, sc_core::sc_time &)
std::vector< callback_binder_fw< TYPES > * > & get_binders()
sync_enum_type(MODULE::* nb_cb)(int, transaction_type &, phase_type &, sc_core::sc_time &)
bool(MODULE::* dmi_cb)(int, transaction_type &txn, tlm::tlm_dmi &dmi)
callback_binder_fw< TYPES >::b_func_type m_b_f
callback_binder_fw< TYPES >::nb_func_type m_nb_f
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > m_multi_binds
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > & get_multi_binds()
virtual const tlm::tlm_fw_transport_if< TYPES > & get_base_interface() const
virtual std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > & get_multi_binds()=0
virtual std::vector< callback_binder_fw< TYPES > * > & get_binders()=0
virtual multi_target_base * get_hierarch_bind()=0
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 1 > s
Definition: pagetable.hh:64
sc_port_policy
Definition: sc_port.hh:68
@ SC_ZERO_OR_MORE_BOUND
Definition: sc_port.hh:70
@ SC_ONE_OR_MORE_BOUND
Definition: sc_port.hh:69
const char * sc_gen_unique_name(const char *seed)
Definition: sc_module.cc:820
tlm_sync_enum
Definition: fw_bw_ifs.hh:31
Definition: test.h:38

Generated on Wed Dec 21 2022 10:22:42 for gem5 by doxygen 1.9.1