TLM-2.0: include/tlm/tlm_utils/multi_socket_bases.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# include/tlm/tlm_utils/multi_socket_bases.h

Go to the documentation of this file.

    00001 /*****************************************************************************
    00002
    00003   The following code is derived, directly or indirectly, from the SystemC
    00004   source code Copyright (c) 1996-2008 by all Contributors.
    00005   All Rights reserved.
    00006
    00007   The contents of this file are subject to the restrictions and limitations
    00008   set forth in the SystemC Open Source License Version 3.0 (the "License");
    00009   You may not use this file except in compliance with such restrictions and
    00010   limitations. You may obtain instructions on how to receive a copy of the
    00011   License at http://www.systemc.org/. Software distributed by Contributors
    00012   under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
    00013   ANY KIND, either express or implied. See the License for the specific
    00014   language governing rights and limitations under the License.
    00015
    00016  *****************************************************************************/
    00017
    00018 #ifndef __MULTI_SOCKET_BASES_H__
    00019 #define __MULTI_SOCKET_BASES_H__
    00020
    00021 #include <systemc>
    00022
    00023 #include "tlm.h"
    00024
    00025 #include <map>
    00026 #include <sstream>
    00027
    00028 namespace tlm_utils {
    00029
    00030 template <typename signature>
    00031 struct fn_container{
    00032   signature function;
    00033 };
    00034
    00035 #define TLM_DEFINE_FUNCTOR(name) \
    00036 template <typename MODULE, typename TRAITS> \
    00037 inline TLM_RET_VAL static_##name( void* mod \
    00038                                        , void* fn \
    00039                                        , int index \
    00040                                        , TLM_FULL_ARG_LIST) \
    00041 { \
    00042   typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
    00043   MODULE* tmp_mod=static_cast<MODULE*>(mod); \
    00044   fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
    00045   return (tmp_mod->*(tmp_cb->function))(index, TLM_ARG_LIST_WITHOUT_TYPES); \
    00046 }\
    00047 \
    00048 template <typename MODULE, typename TRAITS> \
    00049 inline void delete_fn_container_of_##name(void* fn) \
    00050 { \
    00051   typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
    00052   fn_container_type* tmp_cb =static_cast<fn_container_type*> (fn); \
    00053   if (tmp_cb) delete tmp_cb;\
    00054 } \
    00055 \
    00056 template <typename TRAITS> \
    00057 class name##_functor{ \
    00058 public: \
    00059   typedef typename TRAITS::tlm_payload_type payload_type; \
    00060   typedef typename TRAITS::tlm_phase_type   phase_type; \
    00061   typedef TLM_RET_VAL (*call_fn)(void*,void*, int, TLM_FULL_ARG_LIST); \
    00062   typedef void (*del_fn)(void*); \
    00063 \
    00064   name##_functor(): m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0){} \
    00065   ~name##_functor(){if (m_del_fn) (*m_del_fn)(m_mem_fn);}  \
    00066 \
    00067   template <typename MODULE> \
    00068   void set_function(MODULE* mod, TLM_RET_VAL (MODULE::*cb)(int, TLM_FULL_ARG_LIST)){ \
    00069     typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> fn_container_type; \
    00070     m_fn=&static_##name<MODULE,TRAITS>;\
    00071     m_del_fn=&delete_fn_container_of_##name<MODULE,TRAITS>;\
    00072     m_del_fn(m_mem_fn); \
    00073     fn_container_type* tmp= new fn_container_type(); \
    00074     tmp->function=cb; \
    00075     m_mod=static_cast<void*>(mod); \
    00076     m_mem_fn=static_cast<void*>(tmp); \
    00077   } \
    00078   \
    00079   TLM_RET_VAL operator()(int index, TLM_FULL_ARG_LIST){ \
    00080     return m_fn(m_mod,m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
    00081   } \
    00082 \
    00083   bool empty(){return (m_mod==0 || m_mem_fn==0 || m_fn==0);}\
    00084 \
    00085 protected: \
    00086   call_fn m_fn;\
    00087   del_fn m_del_fn; \
    00088   void* m_mod; \
    00089   void* m_mem_fn; \
    00090 private: \
    00091   name##_functor& operator=(const name##_functor&); \
    00092 }
    00093
    00094
    00095 #define TLM_RET_VAL tlm::tlm_sync_enum
    00096 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, typename TRAITS::tlm_phase_type& ph, sc_core::sc_time& t
    00097 #define TLM_ARG_LIST_WITHOUT_TYPES txn,ph,t
    00098 TLM_DEFINE_FUNCTOR(nb_transport);
    00099 #undef TLM_RET_VAL
    00100 #undef TLM_FULL_ARG_LIST
    00101 #undef TLM_ARG_LIST_WITHOUT_TYPES
    00102
    00103 #define TLM_RET_VAL void
    00104 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, sc_core::sc_time& t
    00105 #define TLM_ARG_LIST_WITHOUT_TYPES txn,t
    00106 TLM_DEFINE_FUNCTOR(b_transport);
    00107 #undef TLM_RET_VAL
    00108 #undef TLM_FULL_ARG_LIST
    00109 #undef TLM_ARG_LIST_WITHOUT_TYPES
    00110
    00111 #define TLM_RET_VAL unsigned int
    00112 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn
    00113 #define TLM_ARG_LIST_WITHOUT_TYPES txn
    00114 TLM_DEFINE_FUNCTOR(debug_transport);
    00115 #undef TLM_RET_VAL
    00116 #undef TLM_FULL_ARG_LIST
    00117 #undef TLM_ARG_LIST_WITHOUT_TYPES
    00118
    00119 #define TLM_RET_VAL bool
    00120 #define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type& txn, tlm::tlm_dmi& dmi
    00121 #define TLM_ARG_LIST_WITHOUT_TYPES txn,dmi
    00122 TLM_DEFINE_FUNCTOR(get_dmi_ptr);
    00123 #undef TLM_RET_VAL
    00124 #undef TLM_FULL_ARG_LIST
    00125 #undef TLM_ARG_LIST_WITHOUT_TYPES
    00126
    00127 #define TLM_RET_VAL void
    00128 #define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
    00129 #define TLM_ARG_LIST_WITHOUT_TYPES l,u
    00130 TLM_DEFINE_FUNCTOR(invalidate_dmi);
    00131 #undef TLM_RET_VAL
    00132 #undef TLM_FULL_ARG_LIST
    00133 #undef TLM_ARG_LIST_WITHOUT_TYPES
    00134
    00135 #undef TLM_DEFINE_FUNCTOR
    00136
    00137 /*
    00138 This class implements the fw interface.
    00139 It allows to register a callback for each of the fw interface methods.
    00140 The callbacks simply forward the fw interface call, but add the id (an int)
    00141 of the callback binder to the signature of the call.
    00142 */
    00143 template <typename TYPES>
    00144 class callback_binder_fw: public tlm::tlm_fw_transport_if<TYPES>{
    00145   public:
    00146     //typedefs according to the used TYPES class
    00147     typedef typename TYPES::tlm_payload_type              transaction_type;
    00148     typedef typename TYPES::tlm_phase_type                phase_type;
    00149     typedef tlm::tlm_sync_enum                            sync_enum_type;
    00150
    00151     //typedefs for the callbacks
    00152     typedef nb_transport_functor<TYPES>    nb_func_type;
    00153     typedef b_transport_functor<TYPES>     b_func_type;
    00154     typedef debug_transport_functor<TYPES> debug_func_type;
    00155     typedef get_dmi_ptr_functor<TYPES>     dmi_func_type;
    00156
    00157     //ctor: an ID is needed to create a callback binder
    00158     callback_binder_fw(int id): m_id(id){
    00159     }
    00160
    00161     //the nb_transport method of the fw interface
    00162     sync_enum_type nb_transport_fw(transaction_type& txn,
    00163                                 phase_type& p,
    00164                                 sc_core::sc_time& t){
    00165       //check if a callback is registered
    00166       if (m_nb_f->empty()){
    00167         //std::cerr<<"No function registered"<<std::endl;
    00168         SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_fw without a registered callback for nb_transport_fw.");
    00169       }
    00170       else
    00171         return (*m_nb_f)(m_id, txn, p, t); //do the callback
    00172       return tlm::TLM_ACCEPTED; //unreachable
    00173     }
    00174
    00175     //the b_transport method of the fw interface
    00176     void b_transport(transaction_type& trans,sc_core::sc_time& t){
    00177       //check if a callback is registered
    00178       if (m_b_f->empty()){
    00179         SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to b_transport without a registered callback for b_transport.");
    00180       }
    00181       else
    00182         (*m_b_f)(m_id, trans,t); //do the callback
    00183     }
    00184
    00185     //the DMI method of the fw interface
    00186     bool get_direct_mem_ptr(transaction_type& trans, tlm::tlm_dmi&  dmi_data){
    00187       //check if a callback is registered
    00188       if (m_dmi_f->empty()){
    00189         dmi_data.allow_none();
    00190         dmi_data.set_start_address(0x0);
    00191         dmi_data.set_end_address((sc_dt::uint64)-1);
    00192         return false;
    00193       }
    00194       else
    00195         return (*m_dmi_f)(m_id, trans,dmi_data); //do the callback
    00196     }
    00197
    00198     //the debug method of the fw interface
    00199     unsigned int transport_dbg(transaction_type& trans){
    00200       //check if a callback is registered
    00201       if (m_dbg_f->empty()){
    00202         return 0;
    00203       }
    00204       else
    00205         return (*m_dbg_f)(m_id, trans); //do the callback
    00206     }
    00207
    00208     //the SystemC standard callback register_port:
    00209     // - called when a port if bound to the interface
    00210     // - allowd to find out who is bound to that callback binder
    00211     void register_port(sc_core::sc_port_base& b, const char* name){
    00212       m_caller_port=&b;
    00213     }
    00214
    00215     //register callbacks for all fw interface methods at once
    00216     void set_callbacks(nb_func_type& cb1, b_func_type& cb2, dmi_func_type& cb3, debug_func_type& cb4){
    00217       m_nb_f=&cb1;
    00218       m_b_f=&cb2;
    00219       m_dmi_f=&cb3;
    00220       m_dbg_f=&cb4;
    00221     }
    00222
    00223     //getter method to get the port that is bound to that callback binder
    00224     // NOTE: this will only return a valid value at end of elaboration
    00225     //  (but not before end of elaboration!)
    00226     sc_core::sc_port_base* get_other_side(){return m_caller_port;}
    00227
    00228   private:
    00229     //the ID of the callback binder
    00230     int m_id;
    00231
    00232     //the callbacks
    00233     nb_func_type* m_nb_f;
    00234     b_func_type*  m_b_f;
    00235     debug_func_type* m_dbg_f;
    00236     dmi_func_type* m_dmi_f;
    00237
    00238     //the port bound to that callback binder
    00239     sc_core::sc_port_base* m_caller_port;
    00240 };
    00241
    00242 /*
    00243 This class implements the bw interface.
    00244 It allows to register a callback for each of the bw interface methods.
    00245 The callbacks simply forward the bw interface call, but add the id (an int)
    00246 of the callback binder to the signature of the call.
    00247 */
    00248 template <typename TYPES>
    00249 class callback_binder_bw: public tlm::tlm_bw_transport_if<TYPES>{
    00250   public:
    00251     //typedefs according to the used TYPES class
    00252     typedef typename TYPES::tlm_payload_type              transaction_type;
    00253     typedef typename TYPES::tlm_phase_type                phase_type;
    00254     typedef tlm::tlm_sync_enum                            sync_enum_type;
    00255
    00256     //typedefs for the callbacks
    00257     typedef nb_transport_functor<TYPES>   nb_func_type;
    00258     typedef invalidate_dmi_functor<TYPES> dmi_func_type;
    00259
    00260     //ctor: an ID is needed to create a callback binder
    00261     callback_binder_bw(int id): m_id(id){
    00262     }
    00263
    00264     //the nb_transport method of the bw interface
    00265     sync_enum_type nb_transport_bw(transaction_type& txn,
    00266                                 phase_type& p,
    00267                                 sc_core::sc_time& t){
    00268       //check if a callback is registered
    00269       if (m_nb_f->empty()){
    00270         SC_REPORT_ERROR("/OSCI_TLM-2/multi_socket","Call to nb_transport_bw without a registered callback for nb_transport_bw");
    00271       }
    00272       else
    00273         return (*m_nb_f)(m_id, txn, p, t); //do the callback
    00274       return tlm::TLM_ACCEPTED; //unreachable
    00275     }
    00276
    00277     //the DMI method of the bw interface
    00278     void invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u){
    00279       //check if a callback is registered
    00280       if (m_dmi_f->empty()){
    00281         return;
    00282       }
    00283       else
    00284         (*m_dmi_f)(m_id,l,u); //do the callback
    00285     }
    00286
    00287     //register callbacks for all bw interface methods at once
    00288     void set_callbacks(nb_func_type& cb1, dmi_func_type& cb2){
    00289       m_nb_f=&cb1;
    00290       m_dmi_f=&cb2;
    00291     }
    00292
    00293   private:
    00294     //the ID of the callback binder
    00295     int m_id;
    00296     //the callbacks
    00297     nb_func_type* m_nb_f;
    00298     dmi_func_type* m_dmi_f;
    00299 };
    00300
    00301
    00302 /*
    00303 This class forms the base for multi initiator sockets.
    00304 It enforces a multi initiator socket to implement all functions
    00305 needed to do hierarchical bindings.
    00306 */
    00307 template <unsigned int BUSWIDTH = 32,
    00308           typename TYPES = tlm::tlm_base_protocol_types,
    00309           unsigned int N=0
    00310 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00311           ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
    00312 #endif
    00313           >
    00314 class multi_init_base: public tlm::tlm_initiator_socket<BUSWIDTH,
    00315                                                   TYPES,
    00316                                                   N
    00317 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00318                                                   ,POL
    00319 #endif
    00320                                                   >{
    00321 public:
    00322   //typedef for the base type: the standard tlm initiator socket
    00323   typedef tlm::tlm_initiator_socket<BUSWIDTH,
    00324                               TYPES,
    00325                               N
    00326 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00327                               ,POL
    00328 #endif
    00329                               > base_type;
    00330
    00331   //this method shall disable the code that does the callback binding
    00332   // that registers callbacks to binders
    00333   virtual void disable_cb_bind()=0;
    00334
    00335   //this method shall return the multi_init_base to which the
    00336   // multi_init_base is bound hierarchically
    00337   //  If the base is not bound hierarchically it shall return a pointer to itself
    00338   virtual multi_init_base* get_hierarch_bind()=0;
    00339
    00340   //this method shall return a vector of the callback binders of multi initiator socket
    00341   virtual std::vector<callback_binder_bw<TYPES>* >& get_binders()=0;
    00342
    00343   //this method shall return a vector of all target interfaces bound to this multi init socket
    00344   virtual std::vector<tlm::tlm_fw_transport_if<TYPES>*>&  get_sockets()=0;
    00345
    00346   //ctor and dtor
    00347   virtual ~multi_init_base(){}
    00348   multi_init_base():base_type(sc_core::sc_gen_unique_name("multi_init_base")){}
    00349   multi_init_base(const char* name):base_type(name){}
    00350 };
    00351
    00352 /*
    00353 This class forms the base for multi target sockets.
    00354 It enforces a multi target socket to implement all functions
    00355 needed to do hierarchical bindings.
    00356 */
    00357 template <unsigned int BUSWIDTH = 32,
    00358           typename TYPES = tlm::tlm_base_protocol_types,
    00359           unsigned int N=0
    00360 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00361           ,sc_core::sc_port_policy POL = sc_core::SC_ONE_OR_MORE_BOUND
    00362 #endif
    00363           >
    00364 class multi_target_base: public tlm::tlm_target_socket<BUSWIDTH,
    00365                                                 TYPES,
    00366                                                 N
    00367 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00368                                                 ,POL
    00369 #endif
    00370                                                 >{
    00371 public:
    00372   //typedef for the base type: the standard tlm target socket
    00373   typedef tlm::tlm_target_socket<BUSWIDTH,
    00374                               TYPES,
    00375                               N
    00376 #if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
    00377                               ,POL
    00378 #endif
    00379                               > base_type;
    00380
    00381   //this method shall return the multi_init_base to which the
    00382   // multi_init_base is bound hierarchically
    00383   //  If the base is not bound hierarchically it shall return a pointer to itself
    00384   virtual multi_target_base* get_hierarch_bind()=0;
    00385
    00386   //this method shall inform the multi target socket that it is bound
    00387   // hierarchically and to which other multi target socket it is bound hierarchically
    00388   virtual void set_hierarch_bind(multi_target_base*)=0;
    00389
    00390   //this method shall return a vector of the callback binders of multi initiator socket
    00391   virtual std::vector<callback_binder_fw<TYPES>* >& get_binders()=0;
    00392
    00393   //this method shall return a map of all multi initiator sockets that are bound to this multi target
    00394   // the key of the map is the index at which the multi initiator i bound, while the value
    00395   //  is the interface of the multi initiator socket that is bound at that index
    00396   virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*>&  get_multi_binds()=0;
    00397
    00398   //ctor and dtor
    00399   virtual ~multi_target_base(){}
    00400   multi_target_base():base_type(sc_core::sc_gen_unique_name("multi_target_base")){}
    00401   multi_target_base(const char* name):base_type(name){}
    00402 };
    00403
    00404 /*
    00405 All multi sockets must additionally derive from this class.
    00406 It enforces a multi socket to implement a function
    00407 needed to do multi init to multi target bindings.
    00408 */
    00409 template <typename TYPES>
    00410 class multi_to_multi_bind_base{
    00411 public:
    00412   virtual ~multi_to_multi_bind_base(){}
    00413   virtual tlm::tlm_fw_transport_if<TYPES>* get_last_binder(tlm::tlm_bw_transport_if<TYPES>*)=0;
    00414 };
    00415
    00416 }
    00417 #endif