Deleted Added
sdiff udiff text old ( 13513:bbf275465d3d ) new ( 13586:008fe87c1ad4 )
full compact
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 __SYSTEMC_EXT_TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H__
21#define __SYSTEMC_EXT_TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H__
22
23#include <tlm>
24#include "tlm_utils/convenience_socket_bases.h"
25
26namespace tlm_utils
27{
28
29template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
30 sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
31class passthrough_target_socket_b :
32 public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
33 protected passthrough_socket_base
34{
35 public:
36 typedef typename TYPES::tlm_payload_type transaction_type;
37 typedef typename TYPES::tlm_phase_type phase_type;
38 typedef tlm::tlm_sync_enum sync_enum_type;
39 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
40 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
41 typedef tlm::tlm_target_socket<BUSWIDTH,TYPES,1,POL> base_type;
42
43 public:
44 static const char *
45 default_name()
46 {
47 return sc_core::sc_gen_unique_name("passthrough_target_socket");
48 }
49
50 explicit passthrough_target_socket_b(const char *n=default_name()) :
51 base_type(n), m_process(this)
52 {
53 bind(m_process);
54 }
55
56 using base_type::bind;
57
58 // REGISTER_XXX
59 void
60 register_nb_transport_fw(MODULE *mod,
61 sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &,
62 sc_core::sc_time &))
63 {
64 m_process.set_nb_transport_ptr(mod, cb);
65 }
66
67 void
68 register_b_transport(MODULE *mod,
69 void (MODULE::*cb)(transaction_type &, sc_core::sc_time &))
70 {
71 m_process.set_b_transport_ptr(mod, cb);
72 }
73
74 void
75 register_transport_dbg(MODULE *mod,
76 unsigned int (MODULE::*cb)(transaction_type &))
77 {
78 m_process.set_transport_dbg_ptr(mod, cb);
79 }
80
81 void
82 register_get_direct_mem_ptr(MODULE *mod,
83 bool (MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
84 {
85 m_process.set_get_direct_mem_ptr(mod, cb);
86 }
87
88 private:
89 class process : public tlm::tlm_fw_transport_if<TYPES>,
90 protected convenience_socket_cb_holder
91 {
92 public:
93 typedef sync_enum_type (MODULE::*NBTransportPtr)(
94 transaction_type &, phase_type &, sc_core::sc_time &);
95 typedef void (MODULE::*BTransportPtr)(
96 transaction_type &, sc_core::sc_time &);
97 typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type &);
98 typedef bool (MODULE::*GetDirectMem_ptr)(
99 transaction_type &, tlm::tlm_dmi &);
100
101 explicit process(passthrough_socket_base *owner) :
102 convenience_socket_cb_holder(owner), m_mod(0),
103 m_nb_transport_ptr(0), m_b_transport_ptr(0),
104 m_transport_dbg_ptr(0), m_get_direct_mem_ptr(0)
105 {}
106
107 void
108 set_nb_transport_ptr(MODULE *mod, NBTransportPtr p)
109 {
110 if (m_nb_transport_ptr) {
111 display_warning("non-blocking callback already registered");
112 return;
113 }
114 sc_assert(!m_mod || m_mod == mod);
115 m_mod = mod;
116 m_nb_transport_ptr = p;
117 }
118
119 void
120 set_b_transport_ptr(MODULE *mod, BTransportPtr p)
121 {
122 if (m_b_transport_ptr) {
123 display_warning("blocking callback already registered");
124 return;
125 }
126 sc_assert(!m_mod || m_mod == mod);
127 m_mod = mod;
128 m_b_transport_ptr = p;
129 }
130
131 void
132 set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
133 {
134 if (m_transport_dbg_ptr) {
135 display_warning("debug callback already registered");
136 return;
137 }
138 sc_assert(!m_mod || m_mod == mod);
139 m_mod = mod;
140 m_transport_dbg_ptr = p;
141 }
142
143 void
144 set_get_direct_mem_ptr(MODULE *mod, GetDirectMem_ptr p)
145 {
146 if (m_get_direct_mem_ptr) {
147 display_warning(
148 "get DMI pointer callback already registered");
149 return;
150 }
151 sc_assert(!m_mod || m_mod == mod);
152 m_mod = mod;
153 m_get_direct_mem_ptr = p;
154 }
155
156 sync_enum_type nb_transport_fw(
157 transaction_type &trans, phase_type &phase,
158 sc_core::sc_time &t)
159 {
160 if (m_nb_transport_ptr) {
161 // Forward call.
162 sc_assert(m_mod);
163 return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
164 }
165 display_error("no non-blocking callback registered");
166 return tlm::TLM_COMPLETED;
167 }
168
169 void
170 b_transport(transaction_type &trans, sc_core::sc_time &t)
171 {
172 if (m_b_transport_ptr) {
173 // Forward call.
174 sc_assert(m_mod);
175 return (m_mod->*m_b_transport_ptr)(trans, t);
176 }
177 display_error("no blocking callback registered");
178 }
179
180 unsigned int
181 transport_dbg(transaction_type &trans)
182 {
183 if (m_transport_dbg_ptr) {
184 // Forward call.
185 sc_assert(m_mod);
186 return (m_mod->*m_transport_dbg_ptr)(trans);
187 }
188 // No debug support
189 return 0;
190 }
191
192 bool
193 get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
194 {
195 if (m_get_direct_mem_ptr) {
196 // Forward call.
197 sc_assert(m_mod);
198 return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
199 }
200 // No DMI support
201 dmi_data.allow_read_write();
202 dmi_data.set_start_address(0x0);
203 dmi_data.set_end_address((sc_dt::uint64)-1);
204 return false;
205 }
206
207 private:
208 MODULE *m_mod;
209 NBTransportPtr m_nb_transport_ptr;
210 BTransportPtr m_b_transport_ptr;
211 TransportDbgPtr m_transport_dbg_ptr;
212 GetDirectMem_ptr m_get_direct_mem_ptr;
213 };
214
215 private:
216 const sc_core::sc_object *get_socket() const { return this; }
217
218 private:
219 process m_process;
220};
221
222template <typename MODULE, unsigned int BUSWIDTH=32,
223 typename TYPES=tlm::tlm_base_protocol_types>
224class passthrough_target_socket :
225 public passthrough_target_socket_b<MODULE, BUSWIDTH, TYPES>
226{
227 typedef passthrough_target_socket_b<MODULE, BUSWIDTH, TYPES> socket_b;
228 public:
229 passthrough_target_socket() : socket_b() {}
230 explicit passthrough_target_socket(const char *name) : socket_b(name) {}
231};
232
233template <typename MODULE, unsigned int BUSWIDTH=32,
234 typename TYPES=tlm::tlm_base_protocol_types>
235class passthrough_target_socket_optional :
236 public passthrough_target_socket_b<
237 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
238{
239 typedef passthrough_target_socket_b<
240 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
241 public:
242 passthrough_target_socket_optional() : socket_b() {}
243 explicit passthrough_target_socket_optional(const char *name) :
244 socket_b(name) {}
245};
246
247// ID Tagged version
248template <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
249 sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
250class passthrough_target_socket_tagged_b :
251 public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
252 protected passthrough_socket_base
253{
254 public:
255 typedef typename TYPES::tlm_payload_type transaction_type;
256 typedef typename TYPES::tlm_phase_type phase_type;
257 typedef tlm::tlm_sync_enum sync_enum_type;
258 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
259 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
260 typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type;
261
262 static const char *
263 default_name()
264 {
265 return sc_core::sc_gen_unique_name(
266 "passthrough_target_socket_tagged");
267 }
268
269 public:
270 explicit passthrough_target_socket_tagged_b(
271 const char *n=default_name()) : base_type(n), m_process(this)
272 {
273 bind(m_process);
274 }
275
276 using base_type::bind;
277
278 // REGISTER_XXX
279 void
280 register_nb_transport_fw(MODULE *mod,
281 sync_enum_type (MODULE::*cb)(int id, transaction_type &,
282 phase_type &, sc_core::sc_time &),
283 int id)
284 {
285 m_process.set_nb_transport_ptr(mod, cb);
286 m_process.set_nb_transport_user_id(id);
287 }
288
289 void
290 register_b_transport(MODULE *mod,
291 void (MODULE::*cb)(int id, transaction_type &,
292 sc_core::sc_time &),
293 int id)
294 {
295 m_process.set_b_transport_ptr(mod, cb);
296 m_process.set_b_transport_user_id(id);
297 }
298
299 void
300 register_transport_dbg(MODULE *mod,
301 unsigned int (MODULE::*cb)(int id, transaction_type &), int id)
302 {
303 m_process.set_transport_dbg_ptr(mod, cb);
304 m_process.set_transport_dbg_user_id(id);
305 }
306
307 void
308 register_get_direct_mem_ptr(MODULE *mod,
309 bool (MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &),
310 int id)
311 {
312 m_process.set_get_direct_mem_ptr(mod, cb);
313 m_process.set_get_dmi_user_id(id);
314 }
315
316 private:
317 class process : public tlm::tlm_fw_transport_if<TYPES>,
318 protected convenience_socket_cb_holder
319 {
320 public:
321 typedef sync_enum_type (MODULE::*NBTransportPtr)(
322 int id, transaction_type &, phase_type &, sc_core::sc_time &);
323 typedef void (MODULE::*BTransportPtr)(
324 int id, transaction_type &, sc_core::sc_time &);
325 typedef unsigned int (MODULE::*TransportDbgPtr)(
326 int id, transaction_type &);
327 typedef bool (MODULE::*GetDirectMem_ptr)(
328 int id, transaction_type &, tlm::tlm_dmi &);
329
330 process(passthrough_socket_base *owner) :
331 convenience_socket_cb_holder(owner), m_mod(0),
332 m_nb_transport_ptr(0), m_b_transport_ptr(0),
333 m_transport_dbg_ptr(0), m_get_direct_mem_ptr(0),
334 m_nb_transport_user_id(0), m_b_transport_user_id(0),
335 m_transport_dbg_user_id(0), m_get_dmi_user_id(0)
336 {}
337
338 void
339 set_nb_transport_user_id(int id)
340 {
341 m_nb_transport_user_id = id;
342 }
343 void
344 set_b_transport_user_id(int id)
345 {
346 m_b_transport_user_id = id;
347 }
348 void
349 set_transport_dbg_user_id(int id)
350 {
351 m_transport_dbg_user_id = id;
352 }
353 void
354 set_get_dmi_user_id(int id)
355 {
356 m_get_dmi_user_id = id;
357 }
358
359 void
360 set_nb_transport_ptr(MODULE *mod, NBTransportPtr p)
361 {
362 if (m_nb_transport_ptr) {
363 display_warning("non-blocking callback already registered");
364 return;
365 }
366 sc_assert(!m_mod || m_mod == mod);
367 m_mod = mod;
368 m_nb_transport_ptr = p;
369 }
370
371 void
372 set_b_transport_ptr(MODULE *mod, BTransportPtr p)
373 {
374 if (m_b_transport_ptr) {
375 display_warning("blocking callback already registered");
376 return;
377 }
378 sc_assert(!m_mod || m_mod == mod);
379 m_mod = mod;
380 m_b_transport_ptr = p;
381 }
382
383 void
384 set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
385 {
386 if (m_transport_dbg_ptr) {
387 display_warning("debug callback already registered");
388 return;
389 }
390 sc_assert(!m_mod || m_mod == mod);
391 m_mod = mod;
392 m_transport_dbg_ptr = p;
393 }
394
395 void
396 set_get_direct_mem_ptr(MODULE *mod, GetDirectMem_ptr p)
397 {
398 if (m_get_direct_mem_ptr) {
399 display_warning(
400 "get DMI pointer callback already registered");
401 return;
402 }
403 sc_assert(!m_mod || m_mod == mod);
404 m_mod = mod;
405 m_get_direct_mem_ptr = p;
406 }
407
408 sync_enum_type
409 nb_transport_fw(transaction_type &trans, phase_type &phase,
410 sc_core::sc_time &t)
411 {
412 if (m_nb_transport_ptr) {
413 // Forward call.
414 sc_assert(m_mod);
415 return (m_mod->*m_nb_transport_ptr)(
416 m_nb_transport_user_id, trans, phase, t);
417 }
418 display_error("no non-blocking callback registered");
419 return tlm::TLM_COMPLETED;
420 }
421
422 void
423 b_transport(transaction_type &trans, sc_core::sc_time &t)
424 {
425 if (m_b_transport_ptr) {
426 // Forward call.
427 sc_assert(m_mod);
428 return (m_mod->*m_b_transport_ptr)(
429 m_b_transport_user_id, trans, t);
430 }
431 display_error("no blocking callback registered");
432 }
433
434 unsigned int
435 transport_dbg(transaction_type &trans)
436 {
437 if (m_transport_dbg_ptr) {
438 // Forward call.
439 sc_assert(m_mod);
440 return (m_mod->*m_transport_dbg_ptr)(
441 m_transport_dbg_user_id, trans);
442 }
443 // No debug support.
444 return 0;
445 }
446
447 bool
448 get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
449 {
450 if (m_get_direct_mem_ptr) {
451 // Forward call.
452 sc_assert(m_mod);
453 return (m_mod->*m_get_direct_mem_ptr)(
454 m_get_dmi_user_id, trans, dmi_data);
455 }
456 // No DMI support
457 dmi_data.allow_read_write();
458 dmi_data.set_start_address(0x0);
459 dmi_data.set_end_address((sc_dt::uint64)-1);
460 return false;
461 }
462
463 private:
464 MODULE *m_mod;
465 NBTransportPtr m_nb_transport_ptr;
466 BTransportPtr m_b_transport_ptr;
467 TransportDbgPtr m_transport_dbg_ptr;
468 GetDirectMem_ptr m_get_direct_mem_ptr;
469 int m_nb_transport_user_id;
470 int m_b_transport_user_id;
471 int m_transport_dbg_user_id;
472 int m_get_dmi_user_id;
473 };
474
475 private:
476 const sc_core::sc_object *get_socket() const { return this; }
477
478 private:
479 process m_process;
480};
481
482template <typename MODULE, unsigned int BUSWIDTH=32,
483 typename TYPES=tlm::tlm_base_protocol_types>
484class passthrough_target_socket_tagged :
485 public passthrough_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
486{
487 typedef passthrough_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
488 socket_b;
489 public:
490 passthrough_target_socket_tagged() : socket_b() {}
491 explicit passthrough_target_socket_tagged(const char *name) :
492 socket_b(name)
493 {}
494};
495
496template <typename MODULE, unsigned int BUSWIDTH=32,
497 typename TYPES=tlm::tlm_base_protocol_types>
498class passthrough_target_socket_tagged_optional :
499 public passthrough_target_socket_tagged_b<
500 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
501{
502 typedef passthrough_target_socket_tagged_b<
503 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
504 public:
505 passthrough_target_socket_tagged_optional() : socket_b() {}
506 explicit passthrough_target_socket_tagged_optional(const char *name) :
507 socket_b(name)
508 {}
509};
510
511} // namespace tlm_utils
512
513#endif /* __SYSTEMC_EXT_TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H__ */