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