simple_initiator_socket.h revision 13743:62e81e25d8d5
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_SIMPLE_INITIATOR_SOCKET_H__ 21#define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ 22 23#include "../core/sc_module.hh" 24#include "../core/sc_port.hh" 25#include "../tlm_core/2/generic_payload/gp.hh" 26#include "../tlm_core/2/interfaces/fw_bw_ifs.hh" 27#include "../tlm_core/2/sockets/initiator_socket.hh" 28#include "../tlm_core/2/sockets/target_socket.hh" 29#include "../utils/sc_report_handler.hh" 30#include "convenience_socket_bases.h" 31 32namespace tlm_utils 33{ 34 35template <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 36 sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 37class simple_initiator_socket_b : 38 public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>, 39 protected simple_socket_base 40{ 41 public: 42 typedef typename TYPES::tlm_payload_type transaction_type; 43 typedef typename TYPES::tlm_phase_type phase_type; 44 typedef tlm::tlm_sync_enum sync_enum_type; 45 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 46 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 47 typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type; 48 49 public: 50 static const char * 51 default_name() 52 { 53 return sc_core::sc_gen_unique_name("simple_initiator_socket"); 54 } 55 56 explicit simple_initiator_socket_b(const char *n=default_name()) : 57 base_type(n), m_process(this) 58 { 59 this->m_export.bind(m_process); 60 } 61 62 void 63 register_nb_transport_bw(MODULE *mod, 64 sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &, 65 sc_core::sc_time &)) 66 { 67 m_process.set_transport_ptr(mod, cb); 68 } 69 70 void 71 register_invalidate_direct_mem_ptr(MODULE *mod, 72 void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64)) 73 { 74 m_process.set_invalidate_direct_mem_ptr(mod, cb); 75 } 76 77 private: 78 class process : public tlm::tlm_bw_transport_if<TYPES>, 79 protected convenience_socket_cb_holder 80 { 81 public: 82 typedef sync_enum_type (MODULE::*TransportPtr)( 83 transaction_type &, phase_type &, sc_core::sc_time &); 84 typedef void (MODULE::*InvalidateDirectMemPtr)( 85 sc_dt::uint64, sc_dt::uint64); 86 87 explicit process(simple_socket_base *owner) : 88 convenience_socket_cb_holder(owner), m_mod(0), 89 m_transport_ptr(0), m_invalidate_direct_mem_ptr(0) 90 {} 91 92 void 93 set_transport_ptr(MODULE *mod, TransportPtr p) 94 { 95 if (m_transport_ptr) { 96 display_warning("non-blocking callback already registered"); 97 return; 98 } 99 sc_assert(!m_mod || m_mod == mod); 100 m_mod = mod; 101 m_transport_ptr = p; 102 } 103 104 void 105 set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p) 106 { 107 if (m_invalidate_direct_mem_ptr) { 108 display_warning("invalidate DMI callback already registered"); 109 return; 110 } 111 sc_assert(!m_mod || m_mod == mod); 112 m_mod = mod; 113 m_invalidate_direct_mem_ptr = p; 114 } 115 116 sync_enum_type 117 nb_transport_bw(transaction_type &trans, phase_type &phase, 118 sc_core::sc_time &t) 119 { 120 if (m_transport_ptr) { 121 // Forward call. 122 sc_assert(m_mod); 123 return (m_mod->*m_transport_ptr)(trans, phase, t); 124 } 125 display_error("no transport callback registered"); 126 return tlm::TLM_COMPLETED; 127 } 128 129 void 130 invalidate_direct_mem_ptr(sc_dt::uint64 start_range, 131 sc_dt::uint64 end_range) 132 { 133 if (m_invalidate_direct_mem_ptr) { 134 // Forward call. 135 sc_assert(m_mod); 136 (m_mod->*m_invalidate_direct_mem_ptr)( 137 start_range, end_range); 138 } 139 } 140 141 private: 142 MODULE *m_mod; 143 TransportPtr m_transport_ptr; 144 InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; 145 }; 146 147 private: 148 const sc_core::sc_object *get_socket() const { return this; } 149 150 private: 151 process m_process; 152}; 153 154template <typename MODULE, unsigned int BUSWIDTH=32, 155 typename TYPES=tlm::tlm_base_protocol_types> 156class simple_initiator_socket : 157 public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> 158{ 159 typedef simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> socket_b; 160 public: 161 simple_initiator_socket() : socket_b() {} 162 explicit simple_initiator_socket(const char *name) : socket_b(name) {} 163}; 164 165template <typename MODULE, unsigned int BUSWIDTH=32, 166 typename TYPES=tlm::tlm_base_protocol_types> 167class simple_initiator_socket_optional : 168 public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, 169 sc_core::SC_ZERO_OR_MORE_BOUND> 170{ 171 typedef simple_initiator_socket_b< 172 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 173 public: 174 simple_initiator_socket_optional() : socket_b() {} 175 explicit simple_initiator_socket_optional(const char *name) : 176 socket_b(name) 177 {} 178}; 179 180 181// Tagged version 182 183template <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 184 sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 185class simple_initiator_socket_tagged_b : 186 public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>, 187 protected simple_socket_base 188{ 189 public: 190 typedef typename TYPES::tlm_payload_type transaction_type; 191 typedef typename TYPES::tlm_phase_type phase_type; 192 typedef tlm::tlm_sync_enum sync_enum_type; 193 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 194 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 195 typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type; 196 197 public: 198 static const char * 199 default_name() 200 { 201 return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged"); 202 } 203 204 explicit simple_initiator_socket_tagged_b(const char *n=default_name()) : 205 base_type(n), m_process(this) 206 { 207 this->m_export.bind(m_process); 208 } 209 210 void 211 register_nb_transport_bw(MODULE *mod, 212 sync_enum_type (MODULE::*cb)( 213 int, transaction_type &, phase_type &, sc_core::sc_time &), 214 int id) 215 { 216 m_process.set_transport_ptr(mod, cb); 217 m_process.set_transport_user_id(id); 218 } 219 220 void 221 register_invalidate_direct_mem_ptr(MODULE *mod, 222 void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), int id) 223 { 224 m_process.set_invalidate_direct_mem_ptr(mod, cb); 225 m_process.set_invalidate_dmi_user_id(id); 226 } 227 228 private: 229 class process : public tlm::tlm_bw_transport_if<TYPES>, 230 protected convenience_socket_cb_holder 231 { 232 public: 233 typedef sync_enum_type (MODULE::*TransportPtr)( 234 int, transaction_type &, phase_type &, sc_core::sc_time &); 235 typedef void (MODULE::*InvalidateDirectMemPtr)( 236 int, sc_dt::uint64, sc_dt::uint64); 237 238 explicit process(simple_socket_base *owner) : 239 convenience_socket_cb_holder(owner), m_mod(0), 240 m_transport_ptr(0), m_invalidate_direct_mem_ptr(0), 241 m_transport_user_id(0), m_invalidate_direct_mem_user_id(0) 242 {} 243 244 void set_transport_user_id(int id) { m_transport_user_id = id; } 245 void 246 set_invalidate_dmi_user_id(int id) 247 { 248 m_invalidate_direct_mem_user_id = id; 249 } 250 251 void 252 set_transport_ptr(MODULE *mod, TransportPtr p) 253 { 254 if (m_transport_ptr) { 255 display_warning("non-blocking callback already registered"); 256 return; 257 } 258 sc_assert(!m_mod || m_mod == mod); 259 m_mod = mod; 260 m_transport_ptr = p; 261 } 262 263 void 264 set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p) 265 { 266 if (m_invalidate_direct_mem_ptr) { 267 display_warning("invalidate DMI callback already registered"); 268 return; 269 } 270 sc_assert(!m_mod || m_mod == mod); 271 m_mod = mod; 272 m_invalidate_direct_mem_ptr = p; 273 } 274 275 sync_enum_type 276 nb_transport_bw(transaction_type &trans, phase_type &phase, 277 sc_core::sc_time &t) 278 { 279 if (m_transport_ptr) { 280 // Forward call. 281 sc_assert(m_mod); 282 return (m_mod->*m_transport_ptr)( 283 m_transport_user_id, trans, phase, t); 284 } 285 display_error("no transport callback registered"); 286 return tlm::TLM_COMPLETED; 287 } 288 289 void 290 invalidate_direct_mem_ptr( 291 sc_dt::uint64 start_range, sc_dt::uint64 end_range) 292 { 293 if (m_invalidate_direct_mem_ptr) { 294 // Forward call. 295 sc_assert(m_mod); 296 (m_mod->*m_invalidate_direct_mem_ptr)( 297 m_invalidate_direct_mem_user_id, 298 start_range, end_range); 299 } 300 } 301 302 private: 303 MODULE *m_mod; 304 TransportPtr m_transport_ptr; 305 InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; 306 int m_transport_user_id; 307 int m_invalidate_direct_mem_user_id; 308 }; 309 310 private: 311 const sc_core::sc_object *get_socket() const { return this; } 312 313 private: 314 process m_process; 315}; 316 317template <typename MODULE, unsigned int BUSWIDTH=32, 318 typename TYPES=tlm::tlm_base_protocol_types> 319class simple_initiator_socket_tagged : 320 public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES> 321{ 322 typedef simple_initiator_socket_tagged_b< 323 MODULE, BUSWIDTH, TYPES> socket_b; 324 public: 325 simple_initiator_socket_tagged() : socket_b() {} 326 explicit simple_initiator_socket_tagged(const char *name) : 327 socket_b(name) 328 {} 329}; 330 331template <typename MODULE, unsigned int BUSWIDTH=32, 332 typename TYPES=tlm::tlm_base_protocol_types> 333class simple_initiator_socket_tagged_optional : 334 public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES, 335 sc_core::SC_ZERO_OR_MORE_BOUND> 336{ 337 typedef simple_initiator_socket_tagged_b< 338 MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; 339 public: 340 simple_initiator_socket_tagged_optional() : socket_b() {} 341 explicit simple_initiator_socket_tagged_optional(const char *name) : 342 socket_b(name) 343 {} 344}; 345 346} // namespace tlm_utils 347 348#endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ */ 349