17 #ifndef __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
18 #define __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
36 template <
typename MODULE,
37 unsigned int BUSWIDTH = 32,
40 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
47 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
51 , public multi_to_multi_bind_base<TYPES>
58 typedef typename TYPES::tlm_payload_type transaction_type;
59 typedef typename TYPES::tlm_phase_type phase_type;
60 typedef tlm::tlm_sync_enum sync_enum_type;
63 typedef sync_enum_type (MODULE::*nb_cb)(int, transaction_type&, phase_type&, sc_core::sc_time&);
64 typedef void (MODULE::*b_cb)(int, transaction_type&, sc_core::sc_time&);
65 typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type& txn);
66 typedef bool (MODULE::*dmi_cb)(int, transaction_type& txn, tlm::tlm_dmi& dmi);
68 typedef multi_target_base<BUSWIDTH,
71 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
76 typedef typename base_type::base_initiator_socket_type base_initiator_socket_type;
79 multi_passthrough_target_socket()
80 : base_type(sc_core::sc_gen_unique_name("multi_passthrough_target_socket"))
82 , m_eoe_disabled(false)
83 , m_export_callback_created(false)
88 multi_passthrough_target_socket(const char* name)
91 , m_eoe_disabled(false)
92 , m_export_callback_created(false)
96 ~multi_passthrough_target_socket(){
98 for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
102 void display_warning(const std::string& text) const {
104 s<<"WARNING in instance "<<base_type::name()<<": "<<text;
105 SC_REPORT_WARNING("/OSCI_TLM-2/multi_socket", s.str().c_str());
108 void display_error(const std::string& text) const {
110 s<<"ERROR in instance "<<base_type::name()<<": "<<text;
111 SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket", s.str().c_str());
114 void check_export_binding()
121 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
126 callback_binder_fw<TYPES> * binder;
128 if (m_binders.size() == 0)
130 binder = new callback_binder_fw<TYPES>(m_binders.size());
131 m_binders.push_back(binder);
132 m_export_callback_created = true;
136 binder = m_binders[0];
139 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(*binder);
144 void register_nb_transport_fw(MODULE* mod,
147 check_export_binding();
150 if (!m_nb_f.empty()){
151 display_warning("NBTransport_bw callback already registered.");
156 m_nb_f.set_function(mod, cb);
160 void register_b_transport(MODULE* mod,
163 check_export_binding();
167 display_warning("BTransport callback already registered.");
172 m_b_f.set_function(mod, cb);
176 void register_transport_dbg(MODULE* mod,
179 check_export_binding();
182 if (!m_dbg_f.empty()){
183 display_warning("DebugTransport callback already registered.");
188 m_dbg_f.set_function(mod, cb);
192 void register_get_direct_mem_ptr(MODULE* mod,
195 check_export_binding();
198 if (!m_dmi_f.empty()){
199 display_warning("DMI callback already registered.");
204 m_dmi_f.set_function(mod, cb);
213 virtual tlm::tlm_fw_transport_if<TYPES>& get_base_interface()
216 if (m_hierarch_bind) display_error("Socket already bound hierarchically.");
218 if (!m_export_callback_created)
219 m_binders.push_back(new callback_binder_fw<TYPES>(m_binders.size()));
221 m_export_callback_created = false;
223 return *m_binders[m_binders.size()-1];
227 virtual const tlm::tlm_fw_transport_if<TYPES>& get_base_interface() const
229 display_error("'get_base_interface()' const not allowed for multi-sockets.");
230 return base_type::get_base_interface();
234 virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export()
240 virtual const sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export() const
242 return base_type::get_base_export();
246 void end_of_elaboration(){
248 if (m_eoe_disabled) return;
252 std::vector<callback_binder_fw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
253 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& multi_binds=get_hierarch_bind()->get_multi_binds();
256 for (unsigned int i=0; i<binders.size(); i++) {
257 binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
258 if (multi_binds.find(i)!=multi_binds.end())
260 m_sockets.push_back(multi_binds[i]);
263 base_initiator_socket_type* test=dynamic_cast<base_initiator_socket_type*>(binders[i]->get_other_side());
264 if (!test){display_error("Not bound to tlm_socket.");}
265 m_sockets.push_back(&test->get_base_interface());
273 virtual void bind(base_type& s)
277 display_warning("Socket already bound hierarchically. Bind attempt ignored.");
285 s.set_hierarch_bind((base_type*)this);
290 void operator() (base_type& s)
296 tlm::tlm_bw_transport_if<TYPES>* operator[](int i){return m_sockets[i];}
300 unsigned int size(){return get_hierarch_bind()->get_binders().size();}
304 base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
305 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds(){return m_multi_binds;}
306 void set_hierarch_bind(base_type* h){m_hierarch_bind=h;}
307 tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>* other){
308 m_multi_binds[m_binders.size()-1]=other;
309 return m_binders[m_binders.size()-1];
314 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> m_multi_binds;
316 void disable_cb_bind(){ m_eoe_disabled=true;}
317 std::vector<callback_binder_fw<TYPES>* >& get_binders(){return m_binders;}
319 std::vector<tlm::tlm_bw_transport_if<TYPES>*> m_sockets;
321 std::vector<callback_binder_fw<TYPES>*> m_binders;
323 base_type* m_hierarch_bind;
325 bool m_export_callback_created;
330 typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
331 typename callback_binder_fw<TYPES>::b_func_type m_b_f;
332 typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
333 typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;