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