simple_initiator_socket.h revision 13743:62e81e25d8d5
110152Satgutier@umich.edu/***************************************************************************** 210152Satgutier@umich.edu 310152Satgutier@umich.edu Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 410152Satgutier@umich.edu more contributor license agreements. See the NOTICE file distributed 510234Syasuko.eckert@amd.com with this work for additional information regarding copyright ownership. 610152Satgutier@umich.edu Accellera licenses this file to you under the Apache License, Version 2.0 710152Satgutier@umich.edu (the "License"); you may not use this file except in compliance with the 810152Satgutier@umich.edu License. You may obtain a copy of the License at 910152Satgutier@umich.edu 1010152Satgutier@umich.edu http://www.apache.org/licenses/LICENSE-2.0 1110152Satgutier@umich.edu 1210152Satgutier@umich.edu Unless required by applicable law or agreed to in writing, software 1310152Satgutier@umich.edu distributed under the License is distributed on an "AS IS" BASIS, 1410152Satgutier@umich.edu WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1510152Satgutier@umich.edu implied. See the License for the specific language governing 1610152Satgutier@umich.edu permissions and limitations under the License. 1710152Satgutier@umich.edu 1810152Satgutier@umich.edu *****************************************************************************/ 1910152Satgutier@umich.edu 2010152Satgutier@umich.edu#ifndef __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ 2110152Satgutier@umich.edu#define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ 2210152Satgutier@umich.edu 2310152Satgutier@umich.edu#include "../core/sc_module.hh" 2410152Satgutier@umich.edu#include "../core/sc_port.hh" 2510152Satgutier@umich.edu#include "../tlm_core/2/generic_payload/gp.hh" 2610152Satgutier@umich.edu#include "../tlm_core/2/interfaces/fw_bw_ifs.hh" 2710152Satgutier@umich.edu#include "../tlm_core/2/sockets/initiator_socket.hh" 2810152Satgutier@umich.edu#include "../tlm_core/2/sockets/target_socket.hh" 2910234Syasuko.eckert@amd.com#include "../utils/sc_report_handler.hh" 3010152Satgutier@umich.edu#include "convenience_socket_bases.h" 3110152Satgutier@umich.edu 3210152Satgutier@umich.edunamespace tlm_utils 3310152Satgutier@umich.edu{ 3410152Satgutier@umich.edu 3510152Satgutier@umich.edutemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES, 3610152Satgutier@umich.edu sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> 3710152Satgutier@umich.educlass simple_initiator_socket_b : 3810152Satgutier@umich.edu public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>, 3910152Satgutier@umich.edu protected simple_socket_base 4010234Syasuko.eckert@amd.com{ 4110234Syasuko.eckert@amd.com public: 4210234Syasuko.eckert@amd.com typedef typename TYPES::tlm_payload_type transaction_type; 4310234Syasuko.eckert@amd.com typedef typename TYPES::tlm_phase_type phase_type; 4410234Syasuko.eckert@amd.com typedef tlm::tlm_sync_enum sync_enum_type; 4510234Syasuko.eckert@amd.com typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 4610234Syasuko.eckert@amd.com typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 4710234Syasuko.eckert@amd.com typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL> base_type; 4810234Syasuko.eckert@amd.com 4910234Syasuko.eckert@amd.com public: 5010234Syasuko.eckert@amd.com static const char * 5110234Syasuko.eckert@amd.com default_name() 5210234Syasuko.eckert@amd.com { 5310152Satgutier@umich.edu return sc_core::sc_gen_unique_name("simple_initiator_socket"); 5410152Satgutier@umich.edu } 5510234Syasuko.eckert@amd.com 5610152Satgutier@umich.edu explicit simple_initiator_socket_b(const char *n=default_name()) : 5710152Satgutier@umich.edu base_type(n), m_process(this) 5810152Satgutier@umich.edu { 5910234Syasuko.eckert@amd.com this->m_export.bind(m_process); 6010234Syasuko.eckert@amd.com } 6110234Syasuko.eckert@amd.com 6210234Syasuko.eckert@amd.com void 6310234Syasuko.eckert@amd.com register_nb_transport_bw(MODULE *mod, 6410234Syasuko.eckert@amd.com sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &, 6510152Satgutier@umich.edu sc_core::sc_time &)) 6610152Satgutier@umich.edu { 6710152Satgutier@umich.edu m_process.set_transport_ptr(mod, cb); 6810152Satgutier@umich.edu } 6910234Syasuko.eckert@amd.com 7010234Syasuko.eckert@amd.com void 7110234Syasuko.eckert@amd.com register_invalidate_direct_mem_ptr(MODULE *mod, 7210152Satgutier@umich.edu void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64)) 7310152Satgutier@umich.edu { 7410152Satgutier@umich.edu m_process.set_invalidate_direct_mem_ptr(mod, cb); 7510152Satgutier@umich.edu } 7610152Satgutier@umich.edu 7710234Syasuko.eckert@amd.com private: 7810234Syasuko.eckert@amd.com class process : public tlm::tlm_bw_transport_if<TYPES>, 7910234Syasuko.eckert@amd.com protected convenience_socket_cb_holder 8010152Satgutier@umich.edu { 8110152Satgutier@umich.edu public: 8210152Satgutier@umich.edu typedef sync_enum_type (MODULE::*TransportPtr)( 8310152Satgutier@umich.edu transaction_type &, phase_type &, sc_core::sc_time &); 8410234Syasuko.eckert@amd.com typedef void (MODULE::*InvalidateDirectMemPtr)( 8510234Syasuko.eckert@amd.com sc_dt::uint64, sc_dt::uint64); 8610234Syasuko.eckert@amd.com 8710234Syasuko.eckert@amd.com explicit process(simple_socket_base *owner) : 8810152Satgutier@umich.edu convenience_socket_cb_holder(owner), m_mod(0), 8910152Satgutier@umich.edu m_transport_ptr(0), m_invalidate_direct_mem_ptr(0) 9010152Satgutier@umich.edu {} 9110152Satgutier@umich.edu 9210234Syasuko.eckert@amd.com void 9310234Syasuko.eckert@amd.com set_transport_ptr(MODULE *mod, TransportPtr p) 9410234Syasuko.eckert@amd.com { 9510234Syasuko.eckert@amd.com if (m_transport_ptr) { 9610234Syasuko.eckert@amd.com display_warning("non-blocking callback already registered"); 9710234Syasuko.eckert@amd.com return; 9810234Syasuko.eckert@amd.com } 9910234Syasuko.eckert@amd.com sc_assert(!m_mod || m_mod == mod); 10010234Syasuko.eckert@amd.com m_mod = mod; 10110234Syasuko.eckert@amd.com m_transport_ptr = p; 10210234Syasuko.eckert@amd.com } 10310234Syasuko.eckert@amd.com 10410234Syasuko.eckert@amd.com void 10510234Syasuko.eckert@amd.com set_invalidate_direct_mem_ptr(MODULE *mod, InvalidateDirectMemPtr p) 10610234Syasuko.eckert@amd.com { 10710234Syasuko.eckert@amd.com if (m_invalidate_direct_mem_ptr) { 10810234Syasuko.eckert@amd.com display_warning("invalidate DMI callback already registered"); 10910234Syasuko.eckert@amd.com return; 11010234Syasuko.eckert@amd.com } 11110234Syasuko.eckert@amd.com sc_assert(!m_mod || m_mod == mod); 11210152Satgutier@umich.edu m_mod = mod; 11310152Satgutier@umich.edu m_invalidate_direct_mem_ptr = p; 11410152Satgutier@umich.edu } 11510152Satgutier@umich.edu 11610234Syasuko.eckert@amd.com sync_enum_type 11710234Syasuko.eckert@amd.com nb_transport_bw(transaction_type &trans, phase_type &phase, 11810234Syasuko.eckert@amd.com sc_core::sc_time &t) 11910152Satgutier@umich.edu { 12010152Satgutier@umich.edu if (m_transport_ptr) { 12110152Satgutier@umich.edu // Forward call. 12210152Satgutier@umich.edu sc_assert(m_mod); 12310234Syasuko.eckert@amd.com return (m_mod->*m_transport_ptr)(trans, phase, t); 12410234Syasuko.eckert@amd.com } 12510234Syasuko.eckert@amd.com display_error("no transport callback registered"); 12610234Syasuko.eckert@amd.com return tlm::TLM_COMPLETED; 12710152Satgutier@umich.edu } 12810152Satgutier@umich.edu 12910152Satgutier@umich.edu void 13010152Satgutier@umich.edu invalidate_direct_mem_ptr(sc_dt::uint64 start_range, 13110234Syasuko.eckert@amd.com sc_dt::uint64 end_range) 13210234Syasuko.eckert@amd.com { 13310152Satgutier@umich.edu if (m_invalidate_direct_mem_ptr) { 13410152Satgutier@umich.edu // Forward call. 13510152Satgutier@umich.edu sc_assert(m_mod); 13610234Syasuko.eckert@amd.com (m_mod->*m_invalidate_direct_mem_ptr)( 13710234Syasuko.eckert@amd.com start_range, end_range); 13810234Syasuko.eckert@amd.com } 13910234Syasuko.eckert@amd.com } 14010234Syasuko.eckert@amd.com 14110152Satgutier@umich.edu private: 14210152Satgutier@umich.edu MODULE *m_mod; 14310152Satgutier@umich.edu 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