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()
00079 : base_type(sc_core::sc_gen_unique_name("multi_passthrough_initiator_socket"))
00080 , m_hierarch_bind(0)
00081 , m_beoe_disabled(false)
00082 , m_dummy(42)
00083 {
00084 }
00085
00086
00087 multi_passthrough_initiator_socket(const char* name)
00088 : base_type(name)
00089 , m_hierarch_bind(0)
00090 , m_beoe_disabled(false)
00091 , m_dummy(42)
00092 {
00093 }
00094
00095 ~multi_passthrough_initiator_socket(){
00096
00097 for (unsigned int i=0; i<m_binders.size(); i++) delete m_binders[i];
00098 }
00099
00100
00101 void display_warning(const std::string& text){
00102 std::stringstream s;
00103 s<<"WARNING in instance "<<base_type::name()<<": "<<text;
00104 SC_REPORT_WARNING("/OSCI_TLM-2/multi_socket", s.str().c_str());
00105 }
00106
00107 void display_error(const std::string& text){
00108 std::stringstream s;
00109 s<<"ERROR in instance "<<base_type::name()<<": "<<text;
00110 SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket", s.str().c_str());
00111 }
00112
00113
00114
00115 void register_nb_transport_bw(MODULE* mod,
00116 sync_enum_type (MODULE::*cb)(int,
00117 transaction_type&,
00118 phase_type&,
00119 sc_core::sc_time&))
00120 {
00121
00122 if (!m_nb_f.empty()){
00123 display_warning("NBTransport_bw callback already registered.");
00124 return;
00125 }
00126
00127
00128 m_nb_f.set_function(mod, cb);
00129 }
00130
00131
00132 void register_invalidate_direct_mem_ptr(MODULE* mod,
00133 void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64))
00134 {
00135
00136 if (!m_dmi_f.empty()){
00137 display_warning("InvalidateDMI callback already registered.");
00138 return;
00139 }
00140
00141
00142 m_dmi_f.set_function(mod, cb);
00143 }
00144
00145
00146
00147
00148
00149
00150 virtual tlm::tlm_bw_transport_if<TYPES>& get_base_interface()
00151 {
00152 m_binders.push_back(new callback_binder_bw<TYPES>(m_binders.size()));
00153 return *m_binders[m_binders.size()-1];
00154 }
00155
00156
00157
00158
00159
00160 virtual sc_core::sc_export<tlm::tlm_bw_transport_if<TYPES> >& get_base_export()
00161 {
00162 if (!m_beoe_disabled)
00163 base_type::m_export.bind(m_dummy);
00164 return base_type::m_export;
00165 }
00166
00167
00168 void bind(base_target_socket_type& s)
00169 {
00170
00171 if (m_hierarch_bind)
00172 display_error("Already hierarchically bound.");
00173
00174 base_type::bind(s);
00175
00176
00177 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);
00178 if (!p_ex_s) display_error("Multi socket not bound to tlm_socket.");
00179
00180
00181 multi_to_multi_bind_base<TYPES>* test=dynamic_cast<multi_to_multi_bind_base<TYPES>*> (p_ex_s);
00182 if (test)
00183
00184
00185
00186 m_sockets.push_back(test->get_last_binder(m_binders[m_binders.size()-1]));
00187 else{
00188 sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES> >& ex_s=*p_ex_s;
00189 m_sockets.push_back(&((tlm::tlm_fw_transport_if<TYPES>&)ex_s));
00190 }
00191 }
00192
00193
00194 void operator() (base_target_socket_type& s)
00195 {
00196 bind(s);
00197 }
00198
00199
00200 void before_end_of_elaboration(){
00201
00202
00203
00204
00205 if (!base_type::m_export.get_interface()){
00206 base_type::m_export.bind(m_dummy);
00207 }
00208
00209
00210 if (m_beoe_disabled) return;
00211
00212
00213
00214 std::vector<callback_binder_bw<TYPES>* >& binders=get_hierarch_bind()->get_binders();
00215
00216
00217
00218 m_used_sockets=get_hierarch_bind()->get_sockets();
00219
00220
00221
00222 for (unsigned int i=0; i<binders.size(); i++) {
00223 binders[i]->set_callbacks(m_nb_f, m_dmi_f);
00224 }
00225 }
00226
00227
00228
00229
00230 void bind(base_type& s)
00231 {
00232 if (m_binders.size())
00233 display_error("Socket already directly bound.");
00234 if (m_hierarch_bind){
00235 display_warning("Socket already bound hierarchically. Bind attempt ignored.");
00236 return;
00237 }
00238
00239
00240
00241 s.disable_cb_bind();
00242 m_hierarch_bind=&s;
00243 base_type::bind(s);
00244 }
00245
00246
00247 void operator() (base_type& s)
00248 {
00249 bind(s);
00250 }
00251
00252
00253 tlm::tlm_fw_transport_if<TYPES>* operator[](int i){return m_used_sockets[i];}
00254
00255
00256
00257 unsigned int size() {return get_hierarch_bind()->get_sockets().size();}
00258
00259 protected:
00260
00261 base_type* get_hierarch_bind(){if (m_hierarch_bind) return m_hierarch_bind->get_hierarch_bind(); else return this;}
00262 void disable_cb_bind(){ m_beoe_disabled=true;}
00263 std::vector<callback_binder_bw<TYPES>* >& get_binders(){return m_binders;}
00264 std::vector<tlm::tlm_fw_transport_if<TYPES>*>& get_sockets(){return m_sockets;}
00265
00266 std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_sockets;
00267 std::vector<tlm::tlm_fw_transport_if<TYPES>*> m_used_sockets;
00268
00269 std::vector<callback_binder_bw<TYPES>*> m_binders;
00270
00271 base_type* m_hierarch_bind;
00272 bool m_beoe_disabled;
00273 callback_binder_bw<TYPES> m_dummy;
00274
00275
00276
00277
00278
00279 typename callback_binder_bw<TYPES>::nb_func_type m_nb_f;
00280 typename callback_binder_bw<TYPES>::dmi_func_type m_dmi_f;
00281 };
00282
00283 }
00284
00285 #endif