00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
00018 #define __MULTI_PASSTHROUGH_TARGET_SOCKET_H__
00019
00020 #include "multi_socket_bases.h"
00021 #include <sstream>
00022
00023 namespace tlm_utils {
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 template <typename MODULE,
00037 unsigned int BUSWIDTH = 32,
00038 typename TYPES = tlm::tlm_base_protocol_types,
00039 unsigned int N=0
00040 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
00041 ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
00042 #endif
00043 >
00044 class multi_passthrough_target_socket: public multi_target_base< BUSWIDTH,
00045 TYPES,
00046 N
00047 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
00048 ,POL
00049 #endif
00050 >
00051 , public multi_to_multi_bind_base<TYPES>
00052 {
00053
00054 public:
00055
00056
00057
00058 typedef typename TYPES::tlm_payload_type transaction_type;
00059 typedef typename TYPES::tlm_phase_type phase_type;
00060 typedef tlm::tlm_sync_enum sync_enum_type;
00061
00062
00063 typedef sync_enum_type (MODULE::*nb_cb)(int, transaction_type&, phase_type&, sc_core::sc_time&);
00064 typedef void (MODULE::*b_cb)(int, transaction_type&, sc_core::sc_time&);
00065 typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type& txn);
00066 typedef bool (MODULE::*dmi_cb)(int, transaction_type& txn, tlm::tlm_dmi& dmi);
00067
00068 typedef multi_target_base<BUSWIDTH,
00069 TYPES,
00070 N
00071 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
00072 ,POL
00073 #endif
00074 > base_type;
00075
00076 typedef typename base_type::base_initiator_socket_type base_initiator_socket_type;
00077
00078
00079 multi_passthrough_target_socket()
00080 : base_type(sc_core::sc_gen_unique_name("multi_passthrough_target_socket"))
00081 , m_hierarch_bind(0)
00082 , m_eoe_disabled(false)
00083 , m_dummy(42)
00084 {
00085 }
00086
00087
00088 multi_passthrough_target_socket(const char* name)
00089 : base_type(name)
00090 , m_hierarch_bind(0)
00091 , m_eoe_disabled(false)
00092 , m_dummy(42)
00093 {
00094 }
00095
00096 ~multi_passthrough_target_socket(){
00097
00098 for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
00099 }
00100
00101
00102 void display_warning(const std::string& text){
00103 std::stringstream s;
00104 s<<"WARNING in instance "<<base_type::name()<<": "<<text;
00105 SC_REPORT_WARNING("/OSCI_TLM-2/multi_socket", s.str().c_str());
00106 }
00107
00108 void display_error(const std::string& text){
00109 std::stringstream s;
00110 s<<"ERROR in instance "<<base_type::name()<<": "<<text;
00111 SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket", s.str().c_str());
00112 }
00113
00114
00115 void register_nb_transport_fw(MODULE* mod,
00116 nb_cb cb)
00117 {
00118
00119
00120
00121
00122
00123 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00124 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00125
00126
00127 if (!m_nb_f.empty()){
00128 display_warning("NBTransport_bw callback already registered.");
00129 return;
00130 }
00131
00132
00133 m_nb_f.set_function(mod, cb);
00134 }
00135
00136
00137 void register_b_transport(MODULE* mod,
00138 b_cb cb)
00139 {
00140
00141
00142
00143
00144
00145 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00146 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00147
00148
00149 if (!m_b_f.empty()){
00150 display_warning("BTransport callback already registered.");
00151 return;
00152 }
00153
00154
00155 m_b_f.set_function(mod, cb);
00156 }
00157
00158
00159 void register_transport_dbg(MODULE* mod,
00160 dbg_cb cb)
00161 {
00162
00163
00164
00165
00166
00167 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00168 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00169
00170
00171 if (!m_dbg_f.empty()){
00172 display_warning("DebugTransport callback already registered.");
00173 return;
00174 }
00175
00176
00177 m_dbg_f.set_function(mod, cb);
00178 }
00179
00180
00181 void register_get_direct_mem_ptr(MODULE* mod,
00182 dmi_cb cb)
00183 {
00184
00185
00186
00187
00188
00189 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00190 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00191
00192
00193 if (!m_dmi_f.empty()){
00194 display_warning("DMI callback already registered.");
00195 return;
00196 }
00197
00198
00199 m_dmi_f.set_function(mod, cb);
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 virtual tlm::tlm_fw_transport_if<TYPES>& get_base_interface()
00209 {
00210
00211 if (m_hierarch_bind) display_error("Socket already bound hierarchically.");
00212
00213 m_binders.push_back(new callback_binder_fw<TYPES>(m_binders.size()));
00214 return *m_binders[m_binders.size()-1];
00215 }
00216
00217
00218 virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export()
00219 {
00220 return *this;
00221 }
00222
00223
00224 void end_of_elaboration(){
00225
00226 if (m_eoe_disabled) return;
00227
00228
00229
00230 std::vector<callback_binder_fw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
00231 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& multi_binds=get_hierarch_bind()->get_multi_binds();
00232
00233
00234 for (unsigned int i=0; i<binders.size(); i++) {
00235 binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
00236 if (multi_binds.find(i)!=multi_binds.end())
00237
00238 m_sockets.push_back(multi_binds[i]);
00239 else{
00240
00241 base_initiator_socket_type* test=dynamic_cast<base_initiator_socket_type*>(binders[i]->get_other_side());
00242 if (!test){display_error("Not bound to tlm_socket.");}
00243 m_sockets.push_back(&test->get_base_interface());
00244 }
00245 }
00246 }
00247
00248
00249
00250
00251 void bind(base_type& s)
00252 {
00253
00254 if (m_eoe_disabled){
00255 display_warning("Socket already bound hierarchically. Bind attempt ignored.");
00256 return;
00257 }
00258
00259
00260 disable_cb_bind();
00261
00262
00263 s.set_hierarch_bind((base_type*)this);
00264 base_type::bind(s);
00265 }
00266
00267
00268 void operator() (base_type& s)
00269 {
00270 bind(s);
00271 }
00272
00273
00274 tlm::tlm_bw_transport_if<TYPES>* operator[](int i){return m_sockets[i];}
00275
00276
00277
00278 unsigned int size(){return get_hierarch_bind()->get_binders().size();}
00279
00280 protected:
00281
00282 base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
00283 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds(){return m_multi_binds;}
00284 void set_hierarch_bind(base_type* h){m_hierarch_bind=h;}
00285 tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>* other){
00286 m_multi_binds[m_binders.size()-1]=other;
00287 return m_binders[m_binders.size()-1];
00288 }
00289
00290
00291
00292 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> m_multi_binds;
00293
00294 void disable_cb_bind(){ m_eoe_disabled=true;}
00295 std::vector<callback_binder_fw<TYPES>* >& get_binders(){return m_binders;}
00296
00297 std::vector<tlm::tlm_bw_transport_if<TYPES>*> m_sockets;
00298
00299 std::vector<callback_binder_fw<TYPES>*> m_binders;
00300
00301 base_type* m_hierarch_bind;
00302 bool m_eoe_disabled;
00303 callback_binder_fw<TYPES> m_dummy;
00304
00305
00306
00307
00308 typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
00309 typename callback_binder_fw<TYPES>::b_func_type m_b_f;
00310 typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
00311 typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;
00312 };
00313
00314 }
00315
00316 #endif