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 typedef typename base_type::initiator_socket_type initiator_socket_type;
00078
00079
00080 multi_passthrough_target_socket(const char* name)
00081 : base_type((std::string(name)+std::string("_base")).c_str())
00082 , m_mod(0)
00083 , m_nb_cb(0)
00084 , m_b_cb(0)
00085 , m_dbg_cb(0)
00086 , m_dmi_cb(0)
00087 , m_hierarch_bind(0)
00088 , m_eoe_disabled(false)
00089 , m_dummy(42)
00090 {
00091 }
00092
00093 ‾multi_passthrough_target_socket(){
00094
00095 for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
00096 }
00097
00098
00099 void display_warning(const std::string& text){
00100 std::stringstream s;
00101 s<<"WARNING in instance "<<base_type::name()<<": "<<text;
00102 SC_REPORT_WARNING("multi_socket", s.str().c_str());
00103 }
00104
00105 void display_error(const std::string& text){
00106 std::stringstream s;
00107 s<<"ERROR in instance "<<base_type::name()<<": "<<text;
00108 SC_REPORT_ERROR("multi_socket", s.str().c_str());
00109 }
00110
00111
00112 void register_nb_transport_fw(MODULE* mod,
00113 nb_cb cb)
00114 {
00115
00116
00117
00118
00119
00120 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00121 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00122
00123
00124 if (m_mod) assert(m_mod==mod);
00125 else m_mod=mod;
00126
00127
00128 if (m_nb_cb){
00129 display_warning("NBTransport_bw callback already registered.");
00130 return;
00131 }
00132
00133
00134 m_nb_cb=cb;
00135 m_nb_f=boost::bind<sync_enum_type>(boost::mem_fn(m_nb_cb), m_mod, _1, _2, _3, _4);
00136 }
00137
00138
00139 void register_b_transport(MODULE* mod,
00140 b_cb cb)
00141 {
00142
00143
00144
00145
00146
00147 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00148 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00149
00150
00151 if (m_mod) assert(m_mod==mod);
00152 else m_mod=mod;
00153
00154
00155 if (m_b_cb){
00156 display_warning("BTransport callback already registered.");
00157 return;
00158 }
00159
00160
00161 m_b_cb=cb;
00162 m_b_f=boost::bind<void>(boost::mem_fn(m_b_cb), m_mod, _1, _2, _3);
00163 }
00164
00165
00166 void register_transport_dbg(MODULE* mod,
00167 dbg_cb cb)
00168 {
00169
00170
00171
00172
00173
00174 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00175 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00176
00177
00178 if (m_mod) assert(m_mod==mod);
00179 else m_mod=mod;
00180
00181
00182 if (m_dbg_cb){
00183 display_warning("DebugTransport callback already registered.");
00184 return;
00185 }
00186
00187
00188 m_dbg_cb=cb;
00189 m_dbg_f=boost::bind<unsigned int>(boost::mem_fn(m_dbg_cb), m_mod, _1, _2);
00190 }
00191
00192
00193 void register_get_direct_mem_ptr(MODULE* mod,
00194 dmi_cb cb)
00195 {
00196
00197
00198
00199
00200
00201 if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::get_interface())
00202 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >::bind(m_dummy);
00203
00204
00205 if (m_mod) assert(m_mod==mod);
00206 else m_mod=mod;
00207
00208
00209 if (m_dmi_cb){
00210 display_warning("DMI callback already registered.");
00211 return;
00212 }
00213
00214
00215 m_dmi_cb=cb;
00216 m_dmi_f=boost::bind<bool>(boost::mem_fn(m_dmi_cb), m_mod, _1, _2, _3);
00217 }
00218
00219
00220
00221
00222
00223
00224
00225 virtual tlm::tlm_fw_transport_if<TYPES>& get_base_interface()
00226 {
00227
00228 if (m_hierarch_bind) display_error("Socket already bound hierarchically.");
00229
00230 m_binders.push_back(new callback_binder_fw<TYPES>(m_binders.size()));
00231 return *m_binders[m_binders.size()-1];
00232 }
00233
00234
00235 virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& get_base_export()
00236 {
00237 return *this;
00238 }
00239
00240
00241 void end_of_elaboration(){
00242
00243 if (m_eoe_disabled) return;
00244
00245
00246
00247 std::vector<callback_binder_fw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
00248 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& multi_binds=get_hierarch_bind()->get_multi_binds();
00249
00250
00251 for (unsigned int i=0; i<binders.size(); i++) {
00252 binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
00253 if (multi_binds.find(i)!=multi_binds.end())
00254
00255 m_sockets.push_back(multi_binds[i]);
00256 else{
00257
00258 base_initiator_socket_type* test=dynamic_cast<base_initiator_socket_type*>(binders[i]->get_other_side());
00259 if (!test){display_error("Not bound to tlm_socket.");}
00260 m_sockets.push_back(&test->get_base_interface());
00261 }
00262 }
00263 }
00264
00265
00266
00267
00268 void bind(base_type& s)
00269 {
00270
00271 if (m_eoe_disabled){
00272 display_warning("Socket already bound hierarchically. Bind attempt ignored.");
00273 return;
00274 }
00275
00276
00277 disable_cb_bind();
00278
00279
00280 s.set_hierarch_bind((base_type*)this);
00281 base_type::bind(s);
00282 }
00283
00284
00285 void operator() (base_type& s)
00286 {
00287 bind(s);
00288 }
00289
00290
00291 tlm::tlm_bw_transport_if<TYPES>* operator[](int i){return m_sockets[i];}
00292
00293
00294
00295 unsigned int size(){return get_hierarch_bind()->get_binders().size();}
00296
00297 protected:
00298
00299 base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
00300 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>& get_multi_binds(){return m_multi_binds;}
00301 void set_hierarch_bind(base_type* h){m_hierarch_bind=h;}
00302 tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>* other){
00303 m_multi_binds[m_binders.size()-1]=other;
00304 return m_binders[m_binders.size()-1];
00305 }
00306
00307
00308
00309 std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> m_multi_binds;
00310
00311 void disable_cb_bind(){ m_eoe_disabled=true;}
00312 std::vector<callback_binder_fw<TYPES>* >& get_binders(){return m_binders;}
00313
00314 std::vector<tlm::tlm_bw_transport_if<TYPES>*> m_sockets;
00315
00316 std::vector<callback_binder_fw<TYPES>*> m_binders;
00317
00318 MODULE* m_mod;
00319 nb_cb m_nb_cb;
00320 b_cb m_b_cb;
00321 dbg_cb m_dbg_cb;
00322 dmi_cb m_dmi_cb;
00323 base_type* m_hierarch_bind;
00324 bool m_eoe_disabled;
00325 callback_binder_fw<TYPES> m_dummy;
00326
00327
00328
00329
00330 boost::function<sync_enum_type (int i, transaction_type& txn, phase_type& p, sc_core::sc_time& t)> m_nb_f;
00331 boost::function<void (int i, transaction_type& txn, sc_core::sc_time& t)> m_b_f;
00332 boost::function<unsigned int (int i, transaction_type& txn)> m_dbg_f;
00333 boost::function<bool (int i, transaction_type& txn, tlm::tlm_dmi& dmi)> m_dmi_f;
00334
00335 };
00336
00337 }
00338
00339 #endif