31 #ifndef __SIMPLE_TARGET_SOCKET_H__
32 #define __SIMPLE_TARGET_SOCKET_H__
34 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn
35 # define SC_INCLUDE_DYNAMIC_PROCESSES
45 template <
typename MODULE,
46 unsigned int BUSWIDTH = 32,
90 m_fw_process.set_nb_transport_ptr(mod, cb);
98 m_fw_process.set_b_transport_ptr(mod, cb);
105 m_fw_process.set_transport_dbg_ptr(mod, cb);
113 m_fw_process.set_get_direct_mem_ptr(mod, cb);
139 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it;
141 it = m_owner->m_pending_trans.find(&trans);
142 if(it == m_owner->m_pending_trans.end()) {
144 return m_owner->bw_nb_transport(trans, phase, t);
152 if (m_owner->m_current_transaction == &trans) {
156 it->second->notify(t);
157 m_owner->m_pending_trans.erase(it);
170 return m_owner->bw_invalidate_direct_mem_ptr(s, e);
191 m_name(p_own->name()),
194 m_nb_transport_ptr(0),
195 m_b_transport_ptr(0),
196 m_transport_dbg_ptr(0),
197 m_get_direct_mem_ptr(0),
199 m_response_in_progress(false)
207 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
209 if (m_nb_transport_ptr) {
211 s << m_name <<
": non-blocking callback allready registered";
214 assert(!m_mod || m_mod == mod);
216 m_nb_transport_ptr = p;
220 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
222 if (m_b_transport_ptr) {
224 s << m_name <<
": blocking callback allready registered";
227 assert(!m_mod || m_mod == mod);
229 m_b_transport_ptr = p;
233 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
235 if (m_transport_dbg_ptr) {
237 s << m_name <<
": debug callback allready registered";
240 assert(!m_mod || m_mod == mod);
242 m_transport_dbg_ptr = p;
246 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
248 if (m_get_direct_mem_ptr) {
250 s << m_name <<
": get DMI pointer callback allready registered";
253 assert(!m_mod || m_mod == mod);
255 m_get_direct_mem_ptr = p;
263 if (m_nb_transport_ptr) {
266 return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
268 }
else if (m_b_transport_ptr) {
271 process_handle_class * ph = m_process_handle.get_handle(&trans);
274 ph =
new process_handle_class(&trans);
275 m_process_handle.put_handle(ph);
289 m_response_in_progress =
false;
290 m_end_response.notify(t);
300 s << m_name <<
": no non-blocking transport callback registered";
308 if (m_b_transport_ptr) {
311 (m_mod->*m_b_transport_ptr)(trans, t);
314 }
else if (m_nb_transport_ptr) {
315 m_peq.notify(trans, t);
318 mm_end_event_ext mm_ext;
319 const bool mm_added = !trans.has_mm();
323 trans.set_auto_extension(&mm_ext);
329 m_owner->m_pending_trans[&trans] = &end_event;
335 if (trans.get_ref_count()) {
343 s << m_name <<
": no blocking transport callback registered";
350 if (m_transport_dbg_ptr) {
353 return (m_mod->*m_transport_dbg_ptr)(trans);
364 if (m_get_direct_mem_ptr) {
367 return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
382 class process_handle_class {
385 : m_trans(trans),m_suspend(false) {}
392 class process_handle_list {
394 process_handle_list() {}
396 ~process_handle_list() {
397 for(
typename std::vector<process_handle_class*>::iterator
398 it=v.begin(), end = v.end(); it != end; ++it )
404 typename std::vector<process_handle_class*>::iterator it;
406 for(it = v.begin(); it != v.end(); it++) {
407 if ((*it)->m_suspend) {
408 (*it)->m_trans = trans;
409 (*it)->m_suspend =
false;
416 void put_handle(process_handle_class* ph)
422 std::vector<process_handle_class*> v;
425 process_handle_list m_process_handle;
428 void nb2b_thread(process_handle_class* h)
437 (m_mod->*m_b_transport_ptr)(*trans, t);
442 while (m_response_in_progress) {
450 m_response_in_progress =
true;
465 while ((trans = m_peq.get_next_transaction())!=0) {
467 assert(m_nb_transport_ptr);
471 switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) {
475 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
476 m_owner->m_pending_trans.find(trans);
477 assert(it != m_owner->m_pending_trans.end());
478 it->second->notify(t);
479 m_owner->m_pending_trans.erase(it);
487 m_owner->m_current_transaction = trans;
489 m_owner->m_current_transaction = 0;
501 (m_mod->*m_nb_transport_ptr)(*trans, phase, t);
504 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
505 m_owner->m_pending_trans.find(trans);
506 assert(it != m_owner->m_pending_trans.end());
507 it->second->notify(t);
508 m_owner->m_pending_trans.erase(it);
526 mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
543 const std::string m_name;
546 NBTransportPtr m_nb_transport_ptr;
547 BTransportPtr m_b_transport_ptr;
548 TransportDbgPtr m_transport_dbg_ptr;
549 GetDirectMemPtr m_get_direct_mem_ptr;
550 peq_with_get<transaction_type> m_peq;
551 bool m_response_in_progress;
556 fw_process m_fw_process;
558 std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
564 template <
typename MODULE,
565 unsigned int BUSWIDTH = 32,
570 friend class fw_process;
611 m_fw_process.set_nb_transport_ptr(mod, cb);
612 m_fw_process.set_nb_transport_user_id(
id);
616 void (MODULE::*cb)(
int id,
622 m_fw_process.set_b_transport_ptr(mod, cb);
623 m_fw_process.set_b_transport_user_id(
id);
627 unsigned int (MODULE::*cb)(
int id,
632 m_fw_process.set_transport_dbg_ptr(mod, cb);
633 m_fw_process.set_transport_dbg_user_id(
id);
637 bool (MODULE::*cb)(
int id,
643 m_fw_process.set_get_direct_mem_ptr(mod, cb);
644 m_fw_process.set_get_dmi_user_id(
id);
670 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it;
672 it = m_owner->m_pending_trans.find(&trans);
673 if(it == m_owner->m_pending_trans.end()) {
675 return m_owner->bw_nb_transport(trans, phase, t);
683 if (m_owner->m_current_transaction == &trans) {
687 it->second->notify(t);
688 m_owner->m_pending_trans.erase(it);
701 return m_owner->bw_invalidate_direct_mem_ptr(s, e);
716 typedef void (MODULE::*BTransportPtr)(
int id,
719 typedef unsigned int (MODULE::*TransportDbgPtr)(
int id,
721 typedef bool (MODULE::*GetDirectMemPtr)(
int id,
726 m_name(p_own->name()),
729 m_nb_transport_ptr(0),
730 m_b_transport_ptr(0),
731 m_transport_dbg_ptr(0),
732 m_get_direct_mem_ptr(0),
733 m_nb_transport_user_id(0),
734 m_b_transport_user_id(0),
735 m_transport_dbg_user_id(0),
736 m_get_dmi_user_id(0),
738 m_response_in_progress(false)
746 void set_nb_transport_user_id(
int id) { m_nb_transport_user_id = id; }
747 void set_b_transport_user_id(
int id) { m_b_transport_user_id = id; }
748 void set_transport_dbg_user_id(
int id) { m_transport_dbg_user_id = id; }
749 void set_get_dmi_user_id(
int id) { m_get_dmi_user_id = id; }
751 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
753 if (m_nb_transport_ptr) {
755 s << m_name <<
": non-blocking callback allready registered";
758 assert(!m_mod || m_mod == mod);
760 m_nb_transport_ptr = p;
764 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
766 if (m_b_transport_ptr) {
768 s << m_name <<
": blocking callback allready registered";
771 assert(!m_mod || m_mod == mod);
773 m_b_transport_ptr = p;
777 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
779 if (m_transport_dbg_ptr) {
781 s << m_name <<
": debug callback allready registered";
784 assert(!m_mod || m_mod == mod);
786 m_transport_dbg_ptr = p;
790 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
792 if (m_get_direct_mem_ptr) {
794 s << m_name <<
": get DMI pointer callback allready registered";
797 assert(!m_mod || m_mod == mod);
799 m_get_direct_mem_ptr = p;
807 if (m_nb_transport_ptr) {
810 return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
812 }
else if (m_b_transport_ptr) {
816 process_handle_class * ph = m_process_handle.get_handle(&trans);
819 ph =
new process_handle_class(&trans);
820 m_process_handle.put_handle(ph);
834 m_response_in_progress =
false;
835 m_end_response.notify(t);
845 s << m_name <<
": no non-blocking transport callback registered";
853 if (m_b_transport_ptr) {
856 (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
859 }
else if (m_nb_transport_ptr) {
860 m_peq.notify(trans, t);
863 mm_end_event_ext mm_ext;
864 const bool mm_added = !trans.has_mm();
868 trans.set_auto_extension(&mm_ext);
874 m_owner->m_pending_trans[&trans] = &end_event;
880 if (trans.get_ref_count()) {
888 s << m_name <<
": no transport callback registered";
895 if (m_transport_dbg_ptr) {
898 return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
909 if (m_get_direct_mem_ptr) {
912 return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
926 class process_handle_class {
929 : m_trans(trans),m_suspend(false){}
936 class process_handle_list {
938 process_handle_list() {}
940 ~process_handle_list() {
941 for(
typename std::vector<process_handle_class*>::iterator
942 it=v.begin(), end = v.end(); it != end; ++it )
948 typename std::vector<process_handle_class*>::iterator it;
950 for(it = v.begin(); it != v.end(); it++) {
951 if ((*it)->m_suspend) {
952 (*it)->m_trans = trans;
953 (*it)->m_suspend =
false;
960 void put_handle(process_handle_class* ph)
966 std::vector<process_handle_class*> v;
969 process_handle_list m_process_handle;
971 void nb2b_thread(process_handle_class* h)
980 (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t);
985 while (m_response_in_progress) {
993 m_response_in_progress =
true;
1008 while ((trans = m_peq.get_next_transaction())!=0) {
1010 assert(m_nb_transport_ptr);
1014 switch ((m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t)) {
1018 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
1019 m_owner->m_pending_trans.find(trans);
1020 assert(it != m_owner->m_pending_trans.end());
1021 it->second->notify(t);
1022 m_owner->m_pending_trans.erase(it);
1030 m_owner->m_current_transaction = trans;
1032 m_owner->m_current_transaction = 0;
1044 (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t);
1047 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
1048 m_owner->m_pending_trans.find(trans);
1049 assert(it != m_owner->m_pending_trans.end());
1050 it->second->notify(t);
1051 m_owner->m_pending_trans.erase(it);
1069 mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
1086 const std::string m_name;
1089 NBTransportPtr m_nb_transport_ptr;
1090 BTransportPtr m_b_transport_ptr;
1091 TransportDbgPtr m_transport_dbg_ptr;
1092 GetDirectMemPtr m_get_direct_mem_ptr;
1093 int m_nb_transport_user_id;
1094 int m_b_transport_user_id;
1095 int m_transport_dbg_user_id;
1096 int m_get_dmi_user_id;
1097 peq_with_get<transaction_type> m_peq;
1098 bool m_response_in_progress;
1103 fw_process m_fw_process;
1105 std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(int id, transaction_type &, phase_type &, sc_core::sc_time &), int id)
void wait(int, sc_simcontext *)
TYPES::tlm_payload_type transaction_type
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)=0
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
void set_end_address(sc_dt::uint64 addr)
simple_target_socket_tagged()
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
void set_sensitivity(const sc_event *event)
#define SC_REPORT_WARNING(msg_type, msg)
simple_target_socket_tagged(const char *n)
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
tlm::tlm_sync_enum sync_enum_type
void register_b_transport(MODULE *mod, void(MODULE::*cb)(transaction_type &, sc_core::sc_time &))
sc_simcontext * sc_get_curr_simcontext()
void set_start_address(sc_dt::uint64 addr)
tlm::tlm_target_socket< BUSWIDTH, TYPES > base_type
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
bw_interface_type * operator->()
sc_process_handle sc_spawn(T object, const char *name_p=0, const sc_spawn_options *opt_p=0)
virtual tlm_sync_enum nb_transport_bw(TRANS &trans, PHASE &phase, sc_core::sc_time &t)=0
const char * sc_gen_unique_name(const char *, bool preserve_first)
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), int id)
TYPES::tlm_payload_type transaction_type
tlm::tlm_sync_enum sync_enum_type
void allow_read_write(void)
tlm::tlm_bw_transport_if< TYPES > * operator->()
virtual void bind(base_initiator_socket_type &s)
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(int id, transaction_type &), int id)
const sc_time SC_ZERO_TIME
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
TYPES::tlm_phase_type phase_type
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(transaction_type &))
tlm::tlm_bw_transport_if< TYPES > * operator->()
#define SC_REPORT_ERROR(msg_type, msg)
simple_target_socket(const char *n)
tlm::tlm_target_socket< BUSWIDTH, TYPES > base_type
TYPES::tlm_phase_type phase_type
void register_b_transport(MODULE *mod, void(MODULE::*cb)(int id, transaction_type &, sc_core::sc_time &), int id)