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__ */
|