TLM-2.0  2.0.4
Accellera TLM-2.0 proof-of-concept library
simple_initiator_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_SIMPLE_INITIATOR_SOCKET_H_INCLUDED_
21 #define TLM_UTILS_SIMPLE_INITIATOR_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_initiator_socket<BUSWIDTH, TYPES, 1, POL>
32  , protected simple_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("simple_initiator_socket"); }
45 
46  explicit simple_initiator_socket_b(const char* n = default_name())
47  : base_type(n)
48  , m_process(this)
49  {
50  this->m_export.bind(m_process);
51  }
52 
53  void register_nb_transport_bw(MODULE* mod,
54  sync_enum_type (MODULE::*cb)(transaction_type&,
55  phase_type&,
57  {
58  m_process.set_transport_ptr(mod, cb);
59  }
60 
62  void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
63  {
64  m_process.set_invalidate_direct_mem_ptr(mod, cb);
65  }
66 
67 private:
68  class process
69  : public tlm::tlm_bw_transport_if<TYPES>
71  {
72  public:
73  typedef sync_enum_type (MODULE::*TransportPtr)(transaction_type&,
74  phase_type&,
76  typedef void (MODULE::*InvalidateDirectMemPtr)(sc_dt::uint64,
78 
79  explicit process(simple_socket_base* owner)
80  : convenience_socket_cb_holder(owner), m_mod(0)
81  , m_transport_ptr(0)
82  , m_invalidate_direct_mem_ptr(0)
83  {
84  }
85 
86  void set_transport_ptr(MODULE* mod, TransportPtr p)
87  {
88  if (m_transport_ptr) {
89  display_warning("non-blocking callback already registered");
90  return;
91  }
92  sc_assert(!m_mod || m_mod == mod);
93  m_mod = mod;
94  m_transport_ptr = p;
95  }
96 
97  void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
98  {
99  if (m_invalidate_direct_mem_ptr) {
100  display_warning("invalidate DMI callback already registered");
101  return;
102  }
103  sc_assert(!m_mod || m_mod == mod);
104  m_mod = mod;
105  m_invalidate_direct_mem_ptr = p;
106  }
107 
108  sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
109  {
110  if (m_transport_ptr) {
111  // forward call
112  sc_assert(m_mod);
113  return (m_mod->*m_transport_ptr)(trans, phase, t);
114  }
115  display_error("no transport callback registered");
116  return tlm::TLM_COMPLETED;
117  }
118 
119  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
120  sc_dt::uint64 end_range)
121  {
122  if (m_invalidate_direct_mem_ptr) {
123  // forward call
124  sc_assert(m_mod);
125  (m_mod->*m_invalidate_direct_mem_ptr)(start_range, end_range);
126  }
127  }
128 
129  private:
130  MODULE* m_mod;
131  TransportPtr m_transport_ptr;
132  InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
133  };
134 
135 private:
136  const sc_core::sc_object* get_socket() const { return this; }
137 private:
138  process m_process;
139 };
140 
141 template< typename MODULE, unsigned int BUSWIDTH = 32
142  , typename TYPES = tlm::tlm_base_protocol_types >
144  : public simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES>
145 {
147 public:
148  simple_initiator_socket() : socket_b() {}
149  explicit simple_initiator_socket(const char* name) : socket_b(name) {}
150 };
151 
152 template< typename MODULE, unsigned int BUSWIDTH = 32
153  , typename TYPES = tlm::tlm_base_protocol_types >
155  : public simple_initiator_socket_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
156 {
158 public:
160  explicit simple_initiator_socket_optional(const char* name) : socket_b(name) {}
161 };
162 
163 
164 // Tagged version
165 
166 template< typename MODULE, unsigned int BUSWIDTH, typename TYPES
169  : public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>
170  , protected simple_socket_base
171 {
172 public:
173  typedef typename TYPES::tlm_payload_type transaction_type;
174  typedef typename TYPES::tlm_phase_type phase_type;
179 
180 public:
181  static const char* default_name()
182  { return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged"); }
183 
184  explicit simple_initiator_socket_tagged_b(const char* n = default_name())
185  : base_type(n)
186  , m_process(this)
187  {
188  this->m_export.bind(m_process);
189  }
190 
191  void register_nb_transport_bw(MODULE* mod,
192  sync_enum_type (MODULE::*cb)(int,
193  transaction_type&,
194  phase_type&,
196  int id)
197  {
198  m_process.set_transport_ptr(mod, cb);
199  m_process.set_transport_user_id(id);
200  }
201 
203  void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64),
204  int id)
205  {
206  m_process.set_invalidate_direct_mem_ptr(mod, cb);
207  m_process.set_invalidate_dmi_user_id(id);
208  }
209 
210 private:
211  class process
212  : public tlm::tlm_bw_transport_if<TYPES>
213  , protected convenience_socket_cb_holder
214  {
215  public:
216  typedef sync_enum_type (MODULE::*TransportPtr)(int,
217  transaction_type&,
218  phase_type&,
220  typedef void (MODULE::*InvalidateDirectMemPtr)(int,
222  sc_dt::uint64);
223 
224  explicit process(simple_socket_base* owner)
225  : convenience_socket_cb_holder(owner), m_mod(0)
226  , m_transport_ptr(0)
227  , m_invalidate_direct_mem_ptr(0)
228  , m_transport_user_id(0)
229  , m_invalidate_direct_mem_user_id(0)
230  {
231  }
232 
233  void set_transport_user_id(int id) { m_transport_user_id = id; }
234  void set_invalidate_dmi_user_id(int id) { m_invalidate_direct_mem_user_id = id; }
235 
236  void set_transport_ptr(MODULE* mod, TransportPtr p)
237  {
238  if (m_transport_ptr) {
239  display_warning("non-blocking callback already registered");
240  return;
241  }
242  sc_assert(!m_mod || m_mod == mod);
243  m_mod = mod;
244  m_transport_ptr = p;
245  }
246 
247  void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p)
248  {
249  if (m_invalidate_direct_mem_ptr) {
250  display_warning("invalidate DMI callback already registered");
251  return;
252  }
253  sc_assert(!m_mod || m_mod == mod);
254  m_mod = mod;
255  m_invalidate_direct_mem_ptr = p;
256  }
257 
258  sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t)
259  {
260  if (m_transport_ptr) {
261  // forward call
262  sc_assert(m_mod);
263  return (m_mod->*m_transport_ptr)(m_transport_user_id, trans, phase, t);
264  }
265  display_error("no transport callback registered");
266  return tlm::TLM_COMPLETED;
267  }
268 
269  void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
270  sc_dt::uint64 end_range)
271  {
272  if (m_invalidate_direct_mem_ptr) {
273  // forward call
274  sc_assert(m_mod);
275  (m_mod->*m_invalidate_direct_mem_ptr)(m_invalidate_direct_mem_user_id, start_range, end_range);
276  }
277  }
278 
279  private:
280  MODULE* m_mod;
281  TransportPtr m_transport_ptr;
282  InvalidateDirectMemPtr m_invalidate_direct_mem_ptr;
283  int m_transport_user_id;
284  int m_invalidate_direct_mem_user_id;
285  };
286 
287 private:
288  const sc_core::sc_object* get_socket() const { return this; }
289 private:
290  process m_process;
291 };
292 
293 template< typename MODULE, unsigned int BUSWIDTH = 32
294  , typename TYPES = tlm::tlm_base_protocol_types >
296  : public simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES>
297 {
299 public:
301  explicit simple_initiator_socket_tagged(const char* name) : socket_b(name) {}
302 };
303 
304 template< typename MODULE, unsigned int BUSWIDTH = 32
305  , typename TYPES = tlm::tlm_base_protocol_types >
307  : public simple_initiator_socket_tagged_b<MODULE,BUSWIDTH,TYPES,sc_core::SC_ZERO_OR_MORE_BOUND>
308 {
310 public:
312  explicit simple_initiator_socket_tagged_optional(const char* name) : socket_b(name) {}
313 };
314 
315 } // namespace tlm_utils
316 #endif // TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H_INCLUDED_
tlm::tlm_initiator_socket< BUSWIDTH, TYPES, 1, POL > base_type
#define sc_assert(expr)
void display_warning(const char *msg) const
SC_ONE_OR_MORE_BOUND
tlm::tlm_initiator_socket< BUSWIDTH, TYPES, 1, POL > base_type
void register_invalidate_direct_mem_ptr(MODULE *mod, void(MODULE::*cb)(sc_dt::uint64, sc_dt::uint64))
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
uint64_t uint64
SC_VIRTUAL_ void bind(IF &interface_)
void register_nb_transport_bw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
simple_initiator_socket_tagged_b(const char *n=default_name())
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
void register_nb_transport_bw(MODULE *mod, sync_enum_type(MODULE::*cb)(int, transaction_type &, phase_type &, sc_core::sc_time &), int id)
simple_initiator_socket_b(const char *n=default_name())
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
void display_error(const char *msg) const
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
const char * name() 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_invalidate_direct_mem_ptr(MODULE *mod, void(MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), int id)