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