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