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__ */
|