00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __PASSTHROUGH_TARGET_SOCKET_H__
00019 #define __PASSTHROUGH_TARGET_SOCKET_H__
00020
00021 #include "tlm.h"
00022 #include <sstream>
00023
00024 namespace tlm_utils {
00025
00026 template <typename MODULE,
00027 unsigned int BUSWIDTH = 32,
00028 typename TYPES = tlm::tlm_base_protocol_types>
00029 class passthrough_target_socket :
00030 public tlm::tlm_target_socket<BUSWIDTH, TYPES>
00031 {
00032 public:
00033 typedef typename TYPES::tlm_payload_type transaction_type;
00034 typedef typename TYPES::tlm_phase_type phase_type;
00035 typedef tlm::tlm_sync_enum sync_enum_type;
00036 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
00037 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
00038 typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
00039
00040 public:
00041 passthrough_target_socket() :
00042 base_type(sc_core::sc_gen_unique_name("passthrough_target_socket")),
00043 m_process(this->name())
00044 {
00045 bind(m_process);
00046 }
00047
00048 explicit passthrough_target_socket(const char* n) :
00049 base_type(n),
00050 m_process(this->name())
00051 {
00052 bind(m_process);
00053 }
00054
00055
00056 void register_nb_transport_fw(MODULE* mod,
00057 sync_enum_type (MODULE::*cb)(transaction_type&,
00058 phase_type&,
00059 sc_core::sc_time&))
00060 {
00061 m_process.set_nb_transport_ptr(mod, cb);
00062 }
00063
00064 void register_b_transport(MODULE* mod,
00065 void (MODULE::*cb)(transaction_type&,
00066 sc_core::sc_time&))
00067 {
00068 m_process.set_b_transport_ptr(mod, cb);
00069 }
00070
00071 void register_transport_dbg(MODULE* mod,
00072 unsigned int (MODULE::*cb)(transaction_type&))
00073 {
00074 m_process.set_transport_dbg_ptr(mod, cb);
00075 }
00076
00077 void register_get_direct_mem_ptr(MODULE* mod,
00078 bool (MODULE::*cb)(transaction_type&,
00079 tlm::tlm_dmi&))
00080 {
00081 m_process.set_get_direct_mem_ptr(mod, cb);
00082 }
00083
00084 private:
00085 class process : public tlm::tlm_fw_transport_if<TYPES>
00086 {
00087 public:
00088 typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
00089 phase_type&,
00090 sc_core::sc_time&);
00091 typedef void (MODULE::*BTransportPtr)(transaction_type&,
00092 sc_core::sc_time&);
00093 typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
00094 typedef bool (MODULE::*GetDirectMem_ptr)(transaction_type&,
00095 tlm::tlm_dmi&);
00096
00097 process(const std::string& name) :
00098 m_name(name),
00099 m_mod(0),
00100 m_nb_transport_ptr(0),
00101 m_b_transport_ptr(0),
00102 m_transport_dbg_ptr(0),
00103 m_get_direct_mem_ptr(0)
00104 {
00105 }
00106
00107 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
00108 {
00109 if (m_nb_transport_ptr) {
00110 std::stringstream s;
00111 s << m_name << ": non-blocking callback allready registered";
00112 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00113
00114 } else {
00115 assert(!m_mod || m_mod == mod);
00116 m_mod = mod;
00117 m_nb_transport_ptr = p;
00118 }
00119 }
00120
00121 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
00122 {
00123 if (m_b_transport_ptr) {
00124 std::stringstream s;
00125 s << m_name << ": blocking callback allready registered";
00126 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00127 } else {
00128 assert(!m_mod || m_mod == mod);
00129 m_mod = mod;
00130 m_b_transport_ptr = p;
00131 }
00132 }
00133
00134 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
00135 {
00136 if (m_transport_dbg_ptr) {
00137 std::stringstream s;
00138 s << m_name << ": debug callback allready registered";
00139 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00140 } else {
00141 assert(!m_mod || m_mod == mod);
00142 m_mod = mod;
00143 m_transport_dbg_ptr = p;
00144 }
00145 }
00146
00147 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
00148 {
00149 if (m_get_direct_mem_ptr) {
00150 std::stringstream s;
00151 s << m_name << ": get DMI pointer callback allready registered";
00152 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00153 } else {
00154 assert(!m_mod || m_mod == mod);
00155 m_mod = mod;
00156 m_get_direct_mem_ptr = p;
00157 }
00158 }
00159
00160 sync_enum_type nb_transport_fw(transaction_type& trans,
00161 phase_type& phase,
00162 sc_core::sc_time& t)
00163 {
00164 if (m_nb_transport_ptr) {
00165
00166 assert(m_mod);
00167 return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
00168
00169 } else {
00170 std::stringstream s;
00171 s << m_name << ": no non-blocking callback registered";
00172 SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00173 }
00174 return tlm::TLM_ACCEPTED;
00175 }
00176
00177 void b_transport(transaction_type& trans, sc_core::sc_time& t)
00178 {
00179 if (m_b_transport_ptr) {
00180
00181 assert(m_mod);
00182 return (m_mod->*m_b_transport_ptr)(trans, t);
00183
00184 } else {
00185 std::stringstream s;
00186 s << m_name << ": no blocking callback registered";
00187 SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00188 }
00189 }
00190
00191 unsigned int transport_dbg(transaction_type& trans)
00192 {
00193 if (m_transport_dbg_ptr) {
00194
00195 assert(m_mod);
00196 return (m_mod->*m_transport_dbg_ptr)(trans);
00197
00198 } else {
00199
00200 return 0;
00201 }
00202 }
00203
00204 bool get_direct_mem_ptr(transaction_type& trans,
00205 tlm::tlm_dmi& dmi_data)
00206 {
00207 if (m_get_direct_mem_ptr) {
00208
00209 assert(m_mod);
00210 return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
00211
00212 } else {
00213
00214 dmi_data.allow_read_write();
00215 dmi_data.set_start_address(0x0);
00216 dmi_data.set_end_address((sc_dt::uint64)-1);
00217 return false;
00218 }
00219 }
00220
00221 private:
00222 const std::string m_name;
00223 MODULE* m_mod;
00224 NBTransportPtr m_nb_transport_ptr;
00225 BTransportPtr m_b_transport_ptr;
00226 TransportDbgPtr m_transport_dbg_ptr;
00227 GetDirectMem_ptr m_get_direct_mem_ptr;
00228 };
00229
00230 private:
00231 process m_process;
00232 };
00233
00234
00235 template <typename MODULE,
00236 unsigned int BUSWIDTH = 32,
00237 typename TYPES = tlm::tlm_base_protocol_types>
00238 class passthrough_target_socket_tagged :
00239 public tlm::tlm_target_socket<BUSWIDTH, TYPES>
00240 {
00241 public:
00242 typedef typename TYPES::tlm_payload_type transaction_type;
00243 typedef typename TYPES::tlm_phase_type phase_type;
00244 typedef tlm::tlm_sync_enum sync_enum_type;
00245 typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
00246 typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
00247 typedef tlm::tlm_target_socket<BUSWIDTH, TYPES> base_type;
00248
00249 public:
00250 passthrough_target_socket_tagged() :
00251 base_type(sc_core::sc_gen_unique_name("passthrough_target_socket_tagged")),
00252 m_process(this->name())
00253 {
00254 bind(m_process);
00255 }
00256
00257 explicit passthrough_target_socket_tagged(const char* n) :
00258 base_type(n),
00259 m_process(this->name())
00260 {
00261 bind(m_process);
00262 }
00263
00264
00265 void register_nb_transport_fw(MODULE* mod,
00266 sync_enum_type (MODULE::*cb)(int id,
00267 transaction_type&,
00268 phase_type&,
00269 sc_core::sc_time&),
00270 int id)
00271 {
00272 m_process.set_nb_transport_ptr(mod, cb);
00273 m_process.set_nb_transport_user_id(id);
00274 }
00275
00276 void register_b_transport(MODULE* mod,
00277 void (MODULE::*cb)(int id,
00278 transaction_type&,
00279 sc_core::sc_time&),
00280 int id)
00281 {
00282 m_process.set_b_transport_ptr(mod, cb);
00283 m_process.set_b_transport_user_id(id);
00284 }
00285
00286 void register_transport_dbg(MODULE* mod,
00287 unsigned int (MODULE::*cb)(int id,
00288 transaction_type&),
00289 int id)
00290 {
00291 m_process.set_transport_dbg_ptr(mod, cb);
00292 m_process.set_transport_dbg_user_id(id);
00293 }
00294
00295 void register_get_direct_mem_ptr(MODULE* mod,
00296 bool (MODULE::*cb)(int id,
00297 transaction_type&,
00298 tlm::tlm_dmi&),
00299 int id)
00300 {
00301 m_process.set_get_direct_mem_ptr(mod, cb);
00302 m_process.set_get_dmi_user_id(id);
00303 }
00304
00305 private:
00306 class process : public tlm::tlm_fw_transport_if<TYPES>
00307 {
00308 public:
00309 typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
00310 transaction_type&,
00311 phase_type&,
00312 sc_core::sc_time&);
00313 typedef void (MODULE::*BTransportPtr)(int id,
00314 transaction_type&,
00315 sc_core::sc_time&);
00316 typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
00317 transaction_type&);
00318 typedef bool (MODULE::*GetDirectMem_ptr)(int id,
00319 transaction_type&,
00320 tlm::tlm_dmi&);
00321
00322 process(const std::string& name) :
00323 m_name(name),
00324 m_mod(0),
00325 m_nb_transport_ptr(0),
00326 m_b_transport_ptr(0),
00327 m_transport_dbg_ptr(0),
00328 m_get_direct_mem_ptr(0),
00329 m_nb_transport_user_id(0),
00330 m_b_transport_user_id(0),
00331 m_transport_dbg_user_id(0),
00332 m_get_dmi_user_id(0)
00333 {
00334 }
00335
00336 void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
00337 void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
00338 void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
00339 void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
00340
00341 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
00342 {
00343 if (m_nb_transport_ptr) {
00344 std::stringstream s;
00345 s << m_name << ": non-blocking callback allready registered";
00346 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00347 } else {
00348 assert(!m_mod || m_mod == mod);
00349 m_mod = mod;
00350 m_nb_transport_ptr = p;
00351 }
00352 }
00353
00354 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
00355 {
00356 if (m_b_transport_ptr) {
00357 std::stringstream s;
00358 s << m_name << ": blocking callback allready registered";
00359 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00360 } else {
00361 assert(!m_mod || m_mod == mod);
00362 m_mod = mod;
00363 m_b_transport_ptr = p;
00364 }
00365 }
00366
00367 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
00368 {
00369 if (m_transport_dbg_ptr) {
00370 std::stringstream s;
00371 s << m_name << ": debug callback allready registered";
00372 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00373 } else {
00374 assert(!m_mod || m_mod == mod);
00375 m_mod = mod;
00376 m_transport_dbg_ptr = p;
00377 }
00378 }
00379
00380 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
00381 {
00382 if (m_get_direct_mem_ptr) {
00383 std::stringstream s;
00384 s << m_name << ": get DMI pointer callback allready registered";
00385 SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00386 } else {
00387 assert(!m_mod || m_mod == mod);
00388 m_mod = mod;
00389 m_get_direct_mem_ptr = p;
00390 }
00391 }
00392
00393 sync_enum_type nb_transport_fw(transaction_type& trans,
00394 phase_type& phase,
00395 sc_core::sc_time& t)
00396 {
00397 if (m_nb_transport_ptr) {
00398
00399 assert(m_mod);
00400 return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
00401
00402 } else {
00403 std::stringstream s;
00404 s << m_name << ": no non-blocking callback registered";
00405 SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00406 }
00407 return tlm::TLM_ACCEPTED;
00408 }
00409
00410 void b_transport(transaction_type& trans, sc_core::sc_time& t)
00411 {
00412 if (m_b_transport_ptr) {
00413
00414 assert(m_mod);
00415 return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
00416
00417 } else {
00418 std::stringstream s;
00419 s << m_name << ": no blocking callback registered";
00420 SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
00421 }
00422 }
00423
00424 unsigned int transport_dbg(transaction_type& trans)
00425 {
00426 if (m_transport_dbg_ptr) {
00427
00428 assert(m_mod);
00429 return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
00430
00431 } else {
00432
00433 return 0;
00434 }
00435 }
00436
00437 bool get_direct_mem_ptr(transaction_type& trans,
00438 tlm::tlm_dmi& dmi_data)
00439 {
00440 if (m_get_direct_mem_ptr) {
00441
00442 assert(m_mod);
00443 return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
00444
00445 } else {
00446
00447 dmi_data.allow_read_write();
00448 dmi_data.set_start_address(0x0);
00449 dmi_data.set_end_address((sc_dt::uint64)-1);
00450 return false;
00451 }
00452 }
00453
00454 private:
00455 const std::string m_name;
00456 MODULE* m_mod;
00457 NBTransportPtr m_nb_transport_ptr;
00458 BTransportPtr m_b_transport_ptr;
00459 TransportDbgPtr m_transport_dbg_ptr;
00460 GetDirectMem_ptr m_get_direct_mem_ptr;
00461 int m_nb_transport_user_id;
00462 int m_b_transport_user_id;
00463 int m_transport_dbg_user_id;
00464 int m_get_dmi_user_id;
00465 };
00466
00467 private:
00468 process m_process;
00469 };
00470
00471 }
00472
00473 #endif