passthrough_target_socket.h revision 13513:bbf275465d3d
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__ */ 514