gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
26namespace tlm_utils
27{
28
29/*
30This class implements a trivial multi target socket.
31The triviality refers to the fact that the socket does not
32do blocking to non-blocking or non-blocking to blocking conversions.
33
34It allows to connect multiple initiators to this socket.
35The user has to register callbacks for the fw interface methods
36he likes to use. The callbacks are basically equal to the fw interface
37methods but carry an additional integer that indicates to which
38index of this socket the calling initiator is connected.
39*/
40template <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)(
56 int, transaction_type &, phase_type &, sc_core::sc_time &);
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
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
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
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.
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.
296 void operator () (base_type &s) { bind(s); }
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
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
367template <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:
379 {}
380};
381
382} // namespace tlm_utils
383
384#endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__ */
virtual void bind(tlm_fw_transport_if< tlm::tlm_base_protocol_types > &i)
Definition sc_export.hh:75
STL vector class.
Definition stl.hh:37
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
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 const sc_core::sc_export< tlm::tlm_fw_transport_if< TYPES > > & get_base_export() const
std::vector< tlm::tlm_bw_transport_if< TYPES > * > m_sockets
virtual const tlm::tlm_fw_transport_if< TYPES > & get_base_interface() const
std::vector< callback_binder_fw< TYPES > * > & get_binders()
multi_passthrough_target_socket(const char *name=default_name())
unsigned int(MODULE::* dbg_cb)(int, transaction_type &txn)
multi_target_base< BUSWIDTH, TYPES, N, POL > base_type
tlm::tlm_fw_transport_if< TYPES > * get_last_binder(tlm::tlm_bw_transport_if< TYPES > *other)
base_type::base_initiator_socket_type base_initiator_socket_type
void(MODULE::* b_cb)(int, transaction_type &, sc_core::sc_time &)
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > & get_multi_binds()
sync_enum_type(MODULE::* nb_cb)(int, transaction_type &, phase_type &, sc_core::sc_time &)
virtual sc_core::sc_export< tlm::tlm_fw_transport_if< TYPES > > & get_base_export()
bool(MODULE::* dmi_cb)(int, transaction_type &txn, tlm::tlm_dmi &dmi)
callback_binder_fw< TYPES >::nb_func_type m_nb_f
tlm::tlm_bw_transport_if< TYPES > * operator[](int i)
virtual tlm::tlm_fw_transport_if< TYPES > & get_base_interface()
std::map< unsigned int, tlm::tlm_bw_transport_if< TYPES > * > m_multi_binds
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
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
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:07 for gem5 by doxygen 1.11.0