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 __SIMPLE_INITIATOR_SOCKET_H__ 21#define __SIMPLE_INITIATOR_SOCKET_H__ 22 23#include <tlm> 24#include <sstream> 25 26namespace tlm_utils { 27 28template <typename MODULE, 29 unsigned int BUSWIDTH = 32, 30 typename TYPES = tlm::tlm_base_protocol_types> 31class simple_initiator_socket : 32 public tlm::tlm_initiator_socket<BUSWIDTH, TYPES> 33{ 34public: 35 typedef typename TYPES::tlm_payload_type transaction_type; 36 typedef typename TYPES::tlm_phase_type phase_type; 37 typedef tlm::tlm_sync_enum sync_enum_type; 38 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 39 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 40 typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type; 41 42public: 43 simple_initiator_socket() : 44 base_type(sc_core::sc_gen_unique_name("simple_initiator_socket")), 45 m_process(this->name()) 46 { 47 this->m_export.bind(m_process); 48 } 49 50 explicit simple_initiator_socket(const char* n) : 51 base_type(n), 52 m_process(this->name()) 53 { 54 this->m_export.bind(m_process); 55 } 56 57 void register_nb_transport_bw(MODULE* mod, 58 sync_enum_type (MODULE::*cb)(transaction_type&, 59 phase_type&, 60 sc_core::sc_time&)) 61 { 62 m_process.set_transport_ptr(mod, cb); 63 } 64 65 void register_invalidate_direct_mem_ptr(MODULE* mod, 66 void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64)) 67 { 68 m_process.set_invalidate_direct_mem_ptr(mod, cb); 69 } 70 71private: 72 class process : public tlm::tlm_bw_transport_if<TYPES> 73 { 74 public: 75 typedef sync_enum_type (MODULE::*TransportPtr)(transaction_type&, 76 phase_type&, 77 sc_core::sc_time&); 78 typedef void (MODULE::*InvalidateDirectMemPtr)(sc_dt::uint64, 79 sc_dt::uint64); 80 81 process(const std::string& name) : 82 m_name(name), 83 m_mod(0), 84 m_transport_ptr(0), 85 m_invalidate_direct_mem_ptr(0) 86 { 87 } 88 89 void set_transport_ptr(MODULE* mod, TransportPtr p) 90 { 91 if (m_transport_ptr) { 92 std::stringstream s; 93 s << m_name << ": non-blocking callback allready registered"; 94 SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 95 } else { 96 assert(!m_mod || m_mod == mod); 97 m_mod = mod; 98 m_transport_ptr = p; 99 } 100 } 101 102 void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p) 103 { 104 if (m_invalidate_direct_mem_ptr) { 105 std::stringstream s; 106 s << m_name << ": invalidate DMI callback allready registered"; 107 SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 108 } else { 109 assert(!m_mod || m_mod == mod); 110 m_mod = mod; 111 m_invalidate_direct_mem_ptr = p; 112 } 113 } 114 115 sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 116 { 117 if (m_transport_ptr) { 118 // forward call 119 assert(m_mod); 120 return (m_mod->*m_transport_ptr)(trans, phase, t); 121 122 } else { 123 std::stringstream s; 124 s << m_name << ": no transport callback registered"; 125 SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 126 } 127 return tlm::TLM_ACCEPTED; ///< unreachable code 128 } 129 130 void 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 assert(m_mod); 136 (m_mod->*m_invalidate_direct_mem_ptr)(start_range, end_range); 137 } 138 } 139 140 private: 141 const std::string m_name; 142 MODULE* m_mod; 143 TransportPtr m_transport_ptr; 144 InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; 145 }; 146 147private: 148 process m_process; 149}; 150 151// Tagged version 152 153template <typename MODULE, 154 unsigned int BUSWIDTH = 32, 155 typename TYPES = tlm::tlm_base_protocol_types> 156class simple_initiator_socket_tagged : 157 public tlm::tlm_initiator_socket<BUSWIDTH, TYPES> 158{ 159public: 160 typedef typename TYPES::tlm_payload_type transaction_type; 161 typedef typename TYPES::tlm_phase_type phase_type; 162 typedef tlm::tlm_sync_enum sync_enum_type; 163 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; 164 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; 165 typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type; 166 167public: 168 simple_initiator_socket_tagged() : 169 base_type(sc_core::sc_gen_unique_name("simple_initiator_socket_tagged")), 170 m_process(this->name()) 171 { 172 this->m_export.bind(m_process); 173 } 174 175 explicit simple_initiator_socket_tagged(const char* n) : 176 base_type(n), 177 m_process(this->name()) 178 { 179 this->m_export.bind(m_process); 180 } 181 182 void register_nb_transport_bw(MODULE* mod, 183 sync_enum_type (MODULE::*cb)(int, 184 transaction_type&, 185 phase_type&, 186 sc_core::sc_time&), 187 int id) 188 { 189 m_process.set_transport_ptr(mod, cb); 190 m_process.set_transport_user_id(id); 191 } 192 193 void register_invalidate_direct_mem_ptr(MODULE* mod, 194 void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), 195 int id) 196 { 197 m_process.set_invalidate_direct_mem_ptr(mod, cb); 198 m_process.set_invalidate_dmi_user_id(id); 199 } 200 201private: 202 class process : public tlm::tlm_bw_transport_if<TYPES> 203 { 204 public: 205 typedef sync_enum_type (MODULE::*TransportPtr)(int, 206 transaction_type&, 207 phase_type&, 208 sc_core::sc_time&); 209 typedef void (MODULE::*InvalidateDirectMemPtr)(int, 210 sc_dt::uint64, 211 sc_dt::uint64); 212 213 process(const std::string& name) : 214 m_name(name), 215 m_mod(0), 216 m_transport_ptr(0), 217 m_invalidate_direct_mem_ptr(0), 218 m_transport_user_id(0), 219 m_invalidate_direct_mem_user_id(0) 220 { 221 } 222 223 void set_transport_user_id(int id) { m_transport_user_id = id; } 224 void set_invalidate_dmi_user_id(int id) { m_invalidate_direct_mem_user_id = id; } 225 226 void set_transport_ptr(MODULE* mod, TransportPtr p) 227 { 228 if (m_transport_ptr) { 229 std::stringstream s; 230 s << m_name << ": non-blocking callback allready registered"; 231 SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 232 } else { 233 assert(!m_mod || m_mod == mod); 234 m_mod = mod; 235 m_transport_ptr = p; 236 } 237 } 238 239 void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p) 240 { 241 if (m_invalidate_direct_mem_ptr) { 242 std::stringstream s; 243 s << m_name << ": invalidate DMI callback allready registered"; 244 SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); 245 } else { 246 assert(!m_mod || m_mod == mod); 247 m_mod = mod; 248 m_invalidate_direct_mem_ptr = p; 249 } 250 } 251 252 sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) 253 { 254 if (m_transport_ptr) { 255 // forward call 256 assert(m_mod); 257 return (m_mod->*m_transport_ptr)(m_transport_user_id, trans, phase, t); 258 259 } else { 260 std::stringstream s; 261 s << m_name << ": no transport callback registered"; 262 SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); 263 } 264 return tlm::TLM_ACCEPTED; ///< unreachable code 265 } 266 267 void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, 268 sc_dt::uint64 end_range) 269 { 270 if (m_invalidate_direct_mem_ptr) { 271 // forward call 272 assert(m_mod); 273 (m_mod->*m_invalidate_direct_mem_ptr)(m_invalidate_direct_mem_user_id, start_range, end_range); 274 } 275 } 276 277 private: 278 const std::string m_name; 279 MODULE* m_mod; 280 TransportPtr m_transport_ptr; 281 InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; 282 int m_transport_user_id; 283 int m_invalidate_direct_mem_user_id; 284 }; 285 286private: 287 process m_process; 288}; 289 290} 291 292#endif 293