33 #ifndef TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_ 34 #define TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_ 36 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES // needed for sc_spawn 37 # define SC_INCLUDE_DYNAMIC_PROCESSES 47 template<
typename MODULE,
unsigned int BUSWIDTH,
typename TYPES
82 sync_enum_type (MODULE::*cb)(transaction_type&,
87 m_fw_process.set_nb_transport_ptr(mod, cb);
91 void (MODULE::*cb)(transaction_type&,
95 m_fw_process.set_b_transport_ptr(mod, cb);
99 unsigned int (MODULE::*cb)(transaction_type&))
102 m_fw_process.set_transport_dbg_ptr(mod, cb);
106 bool (MODULE::*cb)(transaction_type&,
110 m_fw_process.set_get_direct_mem_ptr(mod, cb);
117 m_fw_process.start_of_simulation();
122 sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase,
sc_core::sc_time &t)
141 sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase,
sc_core::sc_time &t)
143 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
144 m_owner->m_pending_trans.find(&trans);
146 if(it == m_owner->m_pending_trans.end()) {
148 return m_owner->bw_nb_transport(trans, phase, t);
157 if (m_owner->m_current_transaction == &trans) {
161 it->second->notify(t);
162 m_owner->m_pending_trans.erase(it);
165 m_owner->display_error(
"invalid phase received");
171 return m_owner->bw_invalidate_direct_mem_ptr(s, e);
182 typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
185 typedef void (MODULE::*BTransportPtr)(transaction_type&,
187 typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
188 typedef bool (MODULE::*GetDirectMemPtr)(transaction_type&,
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)
204 if (!m_b_transport_ptr && m_nb_transport_ptr) {
213 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
215 if (m_nb_transport_ptr) {
216 m_owner->display_warning(
"non-blocking callback already registered");
221 m_nb_transport_ptr = p;
224 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
226 if (m_b_transport_ptr) {
227 m_owner->display_warning(
"blocking callback already registered");
232 m_b_transport_ptr = p;
235 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
237 if (m_transport_dbg_ptr) {
238 m_owner->display_warning(
"debug callback already registered");
243 m_transport_dbg_ptr = p;
246 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
248 if (m_get_direct_mem_ptr) {
249 m_owner->display_warning(
"get DMI pointer callback already registered");
254 m_get_direct_mem_ptr = p;
257 sync_enum_type nb_transport_fw(transaction_type& trans,
261 if (m_nb_transport_ptr) {
264 return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
268 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);
288 if (phase == tlm::END_RESP) {
289 m_response_in_progress =
false;
290 m_end_response.notify(t);
293 m_owner->display_error(
"invalid phase received");
296 m_owner->display_error(
"no non-blocking transport callback registered");
302 if (m_b_transport_ptr) {
305 (m_mod->*m_b_transport_ptr)(trans, t);
310 if (m_nb_transport_ptr) {
311 m_peq.notify(trans, t);
314 mm_end_event_ext mm_ext;
315 const bool mm_added = !trans.has_mm();
319 trans.set_auto_extension(&mm_ext);
325 m_owner->m_pending_trans[&trans] = &end_event;
331 if (trans.get_ref_count()) {
340 m_owner->display_error(
"no blocking transport callback registered");
343 unsigned int transport_dbg(transaction_type& trans)
345 if (m_transport_dbg_ptr) {
348 return (m_mod->*m_transport_dbg_ptr)(trans);
354 bool get_direct_mem_ptr(transaction_type& trans,
357 if (m_get_direct_mem_ptr) {
360 return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
373 class process_handle_class {
375 explicit process_handle_class(transaction_type * trans)
376 : m_trans(trans),m_suspend(
false) {}
378 transaction_type* m_trans;
383 class process_handle_list {
385 process_handle_list() {}
387 ~process_handle_list() {
388 for(
typename std::vector<process_handle_class*>::iterator
389 it=v.begin(), end = v.end(); it != end; ++it )
393 process_handle_class* get_handle(transaction_type *trans)
395 typename std::vector<process_handle_class*>::iterator it;
397 for(it = v.begin(); it != v.end(); it++) {
398 if ((*it)->m_suspend) {
399 (*it)->m_trans = trans;
400 (*it)->m_suspend =
false;
407 void put_handle(process_handle_class* ph)
413 std::vector<process_handle_class*> v;
416 process_handle_list m_process_handle;
419 void nb2b_thread(process_handle_class* h)
423 transaction_type *trans = h->m_trans;
428 (m_mod->*m_b_transport_ptr)(*trans, t);
433 while (m_response_in_progress) {
438 sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
441 m_response_in_progress =
true;
453 transaction_type* trans;
454 while ((trans = m_peq.get_next_transaction())!=0) {
460 switch ((m_mod->*m_nb_transport_ptr)(*trans, phase, t)) {
464 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
465 m_owner->m_pending_trans.find(trans);
466 sc_assert(it != m_owner->m_pending_trans.end());
467 it->second->notify(t);
468 m_owner->m_pending_trans.erase(it);
476 m_owner->m_current_transaction = trans;
478 m_owner->m_current_transaction = 0;
487 phase = tlm::END_RESP;
490 (m_mod->*m_nb_transport_ptr)(*trans, phase, t);
493 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
494 m_owner->m_pending_trans.find(trans);
495 sc_assert(it != m_owner->m_pending_trans.end());
496 it->second->notify(t);
497 m_owner->m_pending_trans.erase(it);
502 m_owner->display_error(
"invalid phase received");
507 m_owner->display_error(
"invalid sync value received");
516 mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
535 NBTransportPtr m_nb_transport_ptr;
536 BTransportPtr m_b_transport_ptr;
537 TransportDbgPtr m_transport_dbg_ptr;
538 GetDirectMemPtr m_get_direct_mem_ptr;
540 bool m_response_in_progress;
549 std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
551 transaction_type* m_current_transaction;
554 template<
typename MODULE,
unsigned int BUSWIDTH = 32
565 template<
typename MODULE,
unsigned int BUSWIDTH = 32
577 template<
typename MODULE,
unsigned int BUSWIDTH,
typename TYPES
612 sync_enum_type (MODULE::*cb)(
int id,
619 m_fw_process.set_nb_transport_ptr(mod, cb);
620 m_fw_process.set_nb_transport_user_id(
id);
624 void (MODULE::*cb)(
int id,
630 m_fw_process.set_b_transport_ptr(mod, cb);
631 m_fw_process.set_b_transport_user_id(
id);
635 unsigned int (MODULE::*cb)(
int id,
640 m_fw_process.set_transport_dbg_ptr(mod, cb);
641 m_fw_process.set_transport_dbg_user_id(
id);
645 bool (MODULE::*cb)(
int id,
651 m_fw_process.set_get_direct_mem_ptr(mod, cb);
652 m_fw_process.set_get_dmi_user_id(
id);
659 m_fw_process.start_of_simulation();
664 sync_enum_type bw_nb_transport(transaction_type &trans, phase_type &phase,
sc_core::sc_time &t)
683 sync_enum_type nb_transport_bw(transaction_type &trans, phase_type &phase,
sc_core::sc_time &t)
685 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
686 m_owner->m_pending_trans.find(&trans);
688 if(it == m_owner->m_pending_trans.end()) {
690 return m_owner->bw_nb_transport(trans, phase, t);
697 if (m_owner->m_current_transaction == &trans) {
701 it->second->notify(t);
702 m_owner->m_pending_trans.erase(it);
705 m_owner->display_error(
"invalid phase received");
711 return m_owner->bw_invalidate_direct_mem_ptr(s, e);
726 typedef void (MODULE::*BTransportPtr)(
int id,
729 typedef unsigned int (MODULE::*TransportDbgPtr)(
int id,
731 typedef bool (MODULE::*GetDirectMemPtr)(
int id,
738 m_nb_transport_ptr(0),
739 m_b_transport_ptr(0),
740 m_transport_dbg_ptr(0),
741 m_get_direct_mem_ptr(0),
742 m_nb_transport_user_id(0),
743 m_b_transport_user_id(0),
744 m_transport_dbg_user_id(0),
745 m_get_dmi_user_id(0),
747 m_response_in_progress(
false)
752 if (!m_b_transport_ptr && m_nb_transport_ptr) {
761 void set_nb_transport_user_id(
int id) { m_nb_transport_user_id = id; }
762 void set_b_transport_user_id(
int id) { m_b_transport_user_id = id; }
763 void set_transport_dbg_user_id(
int id) { m_transport_dbg_user_id = id; }
764 void set_get_dmi_user_id(
int id) { m_get_dmi_user_id = id; }
766 void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
768 if (m_nb_transport_ptr) {
769 m_owner->display_warning(
"non-blocking callback already registered");
774 m_nb_transport_ptr = p;
777 void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
779 if (m_b_transport_ptr) {
780 m_owner->display_warning(
"blocking callback already registered");
785 m_b_transport_ptr = p;
788 void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
790 if (m_transport_dbg_ptr) {
791 m_owner->display_warning(
"debug callback already registered");
796 m_transport_dbg_ptr = p;
799 void set_get_direct_mem_ptr(MODULE* mod, GetDirectMemPtr p)
801 if (m_get_direct_mem_ptr) {
802 m_owner->display_warning(
"get DMI pointer callback already registered");
806 m_get_direct_mem_ptr = p;
809 sync_enum_type nb_transport_fw(transaction_type& trans,
813 if (m_nb_transport_ptr) {
816 return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
820 if (m_b_transport_ptr) {
824 process_handle_class * ph = m_process_handle.get_handle(&trans);
827 ph =
new process_handle_class(&trans);
828 m_process_handle.put_handle(ph);
841 if (phase == tlm::END_RESP) {
842 m_response_in_progress =
false;
843 m_end_response.notify(t);
846 m_owner->display_error(
"invalid phase");
850 m_owner->display_error(
"no non-blocking transport callback registered");
856 if (m_b_transport_ptr) {
859 (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
864 if (m_nb_transport_ptr) {
865 m_peq.notify(trans, t);
868 mm_end_event_ext mm_ext;
869 const bool mm_added = !trans.has_mm();
873 trans.set_auto_extension(&mm_ext);
879 m_owner->m_pending_trans[&trans] = &end_event;
885 if (trans.get_ref_count()) {
893 m_owner->display_error(
"no transport callback registered");
896 unsigned int transport_dbg(transaction_type& trans)
898 if (m_transport_dbg_ptr) {
901 return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
907 bool get_direct_mem_ptr(transaction_type& trans,
910 if (m_get_direct_mem_ptr) {
913 return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
925 class process_handle_class {
927 explicit process_handle_class(transaction_type * trans)
928 : m_trans(trans),m_suspend(
false){}
930 transaction_type* m_trans;
935 class process_handle_list {
937 process_handle_list() {}
939 ~process_handle_list() {
940 for(
typename std::vector<process_handle_class*>::iterator
941 it=v.begin(), end = v.end(); it != end; ++it )
945 process_handle_class* get_handle(transaction_type *trans)
947 typename std::vector<process_handle_class*>::iterator it;
949 for(it = v.begin(); it != v.end(); it++) {
950 if ((*it)->m_suspend) {
951 (*it)->m_trans = trans;
952 (*it)->m_suspend =
false;
959 void put_handle(process_handle_class* ph)
965 std::vector<process_handle_class*> v;
968 process_handle_list m_process_handle;
970 void nb2b_thread(process_handle_class* h)
974 transaction_type * trans = h->m_trans;
979 (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, *trans, t);
984 while (m_response_in_progress) {
989 sync_enum_type sync = m_owner->bw_nb_transport(*trans, phase, t);
992 m_response_in_progress =
true;
1004 transaction_type* trans;
1005 while ((trans = m_peq.get_next_transaction())!=0) {
1011 switch ((m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t)) {
1015 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
1016 m_owner->m_pending_trans.find(trans);
1017 sc_assert(it != m_owner->m_pending_trans.end());
1018 it->second->notify(t);
1019 m_owner->m_pending_trans.erase(it);
1027 m_owner->m_current_transaction = trans;
1029 m_owner->m_current_transaction = 0;
1038 phase = tlm::END_RESP;
1041 (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, *trans, phase, t);
1044 typename std::map<transaction_type*, sc_core::sc_event *>::iterator it =
1045 m_owner->m_pending_trans.find(trans);
1046 sc_assert(it != m_owner->m_pending_trans.end());
1047 it->second->notify(t);
1048 m_owner->m_pending_trans.erase(it);
1053 m_owner->display_error(
"invalid phase received");
1058 m_owner->display_error(
"invalid sync value received");
1067 mm_end_event_ext* ext = trans->template get_extension<mm_end_event_ext>();
1086 NBTransportPtr m_nb_transport_ptr;
1087 BTransportPtr m_b_transport_ptr;
1088 TransportDbgPtr m_transport_dbg_ptr;
1089 GetDirectMemPtr m_get_direct_mem_ptr;
1090 int m_nb_transport_user_id;
1091 int m_b_transport_user_id;
1092 int m_transport_dbg_user_id;
1093 int m_get_dmi_user_id;
1095 bool m_response_in_progress;
1104 std::map<transaction_type*, sc_core::sc_event *> m_pending_trans;
1106 transaction_type* m_current_transaction;
1109 template<
typename MODULE,
unsigned int BUSWIDTH = 32
1120 template<
typename MODULE,
unsigned int BUSWIDTH = 32
1132 #endif // TLM_UTILS_SIMPLE_TARGET_SOCKET_H_INCLUDED_ virtual void start_of_simulation()
void start_of_simulation()
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
SC_API const sc_time SC_ZERO_TIME
void register_b_transport(MODULE *mod, void(MODULE::*cb)(transaction_type &, sc_core::sc_time &))
tlm::tlm_sync_enum sync_enum_type
simple_target_socket_tagged_optional(const char *name)
void elaboration_check(const char *action) const
void start_of_simulation()
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(int id, transaction_type &, phase_type &, sc_core::sc_time &), int id)
TYPES::tlm_phase_type phase_type
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(int id, transaction_type &), int id)
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
tlm::tlm_target_socket< BUSWIDTH, TYPES, 1, POL > base_type
bw_interface_type * operator->()
static const char * default_name()
simple_target_socket_tagged_b(const char *n=default_name())
void register_get_direct_mem_ptr(MODULE *mod, bool(MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &), int id)
void set_start_address(sc_dt::uint64 addr)
TYPES::tlm_payload_type transaction_type
simple_target_socket_tagged(const char *name)
sc_process_handle sc_spawn(T object, const char *name_p=0, const sc_spawn_options *opt_p=0)
tlm::tlm_bw_transport_if< TYPES > * operator->()
tlm::tlm_sync_enum sync_enum_type
simple_target_socket_tagged()
void allow_read_write(void)
const char * name() const
void register_nb_transport_fw(MODULE *mod, sync_enum_type(MODULE::*cb)(transaction_type &, phase_type &, sc_core::sc_time &))
SC_API const char * sc_gen_unique_name(const char *, bool preserve_first)
void register_b_transport(MODULE *mod, void(MODULE::*cb)(int id, transaction_type &, sc_core::sc_time &), int id)
simple_target_socket_tagged_optional()
simple_target_socket_b(const char *n=default_name())
virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range)=0
static const char * default_name()
virtual void bind(base_initiator_socket_type &s)
tlm::tlm_target_socket< BUSWIDTH, TYPES, 1, POL > base_type
void register_transport_dbg(MODULE *mod, unsigned int(MODULE::*cb)(transaction_type &))
simple_target_socket_optional()
simple_target_socket(const char *name)
virtual tlm_sync_enum nb_transport_bw(TRANS &trans, PHASE &phase, sc_core::sc_time &t)=0
tlm::tlm_bw_transport_if< TYPES > bw_interface_type
void set_sensitivity(const sc_event *event)
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
simple_target_socket_optional(const char *name)
TYPES::tlm_phase_type phase_type
void set_end_address(sc_dt::uint64 addr)
tlm::tlm_fw_transport_if< TYPES > fw_interface_type
TYPES::tlm_payload_type transaction_type
void SC_API wait(int, sc_simcontext *)