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