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