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

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# include/tlm/tlm_utils/passthrough_target_socket.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 __PASSTHROUGH_TARGET_SOCKET_H__
    00019 #define __PASSTHROUGH_TARGET_SOCKET_H__
    00020
    00021 #include "tlm.h"
    00022 #include <sstream>
    00023
    00024 namespace tlm_utils {
    00025
    00026 template <typename MODULE,
    00027           unsigned int BUSWIDTH = 32,
    00028           typename TYPES = tlm::tlm_base_protocol_types>
    00029 class passthrough_target_socket :
    00030   public tlm::tlm_target_socket<BUSWIDTH, TYPES>
    00031 {
    00032 public:
    00033   typedef typename TYPES::tlm_payload_type              transaction_type;
    00034   typedef typename TYPES::tlm_phase_type                phase_type;
    00035   typedef tlm::tlm_sync_enum                            sync_enum_type;
    00036   typedef tlm::tlm_fw_transport_if<TYPES>               fw_interface_type;
    00037   typedef tlm::tlm_bw_transport_if<TYPES>               bw_interface_type;
    00038   typedef tlm::tlm_target_socket<BUSWIDTH, TYPES>       base_type;
    00039
    00040 public:
    00041   passthrough_target_socket() :
    00042     base_type(sc_core::sc_gen_unique_name("passthrough_target_socket")),
    00043     m_process(this->name())
    00044   {
    00045     bind(m_process);
    00046   }
    00047
    00048   explicit passthrough_target_socket(const char* n) :
    00049     base_type(n),
    00050     m_process(this->name())
    00051   {
    00052     bind(m_process);
    00053   }
    00054
    00055   // REGISTER_XXX
    00056   void register_nb_transport_fw(MODULE* mod,
    00057                                 sync_enum_type (MODULE::*cb)(transaction_type&,
    00058                                                              phase_type&,
    00059                                                              sc_core::sc_time&))
    00060   {
    00061     m_process.set_nb_transport_ptr(mod, cb);
    00062   }
    00063
    00064   void register_b_transport(MODULE* mod,
    00065                             void (MODULE::*cb)(transaction_type&,
    00066                                                sc_core::sc_time&))
    00067   {
    00068     m_process.set_b_transport_ptr(mod, cb);
    00069   }
    00070
    00071   void register_transport_dbg(MODULE* mod,
    00072                               unsigned int (MODULE::*cb)(transaction_type&))
    00073   {
    00074     m_process.set_transport_dbg_ptr(mod, cb);
    00075   }
    00076
    00077   void register_get_direct_mem_ptr(MODULE* mod,
    00078                                    bool (MODULE::*cb)(transaction_type&,
    00079                                                       tlm::tlm_dmi&))
    00080   {
    00081     m_process.set_get_direct_mem_ptr(mod, cb);
    00082   }
    00083
    00084 private:
    00085   class process : public tlm::tlm_fw_transport_if<TYPES>
    00086   {
    00087   public:
    00088     typedef sync_enum_type (MODULE::*NBTransportPtr)(transaction_type&,
    00089                                                      phase_type&,
    00090                                                      sc_core::sc_time&);
    00091     typedef void (MODULE::*BTransportPtr)(transaction_type&,
    00092                                             sc_core::sc_time&);
    00093     typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type&);
    00094     typedef bool (MODULE::*GetDirectMem_ptr)(transaction_type&,
    00095                                                tlm::tlm_dmi&);
    00096
    00097     process(const std::string& name) :
    00098       m_name(name),
    00099       m_mod(0),
    00100       m_nb_transport_ptr(0),
    00101       m_b_transport_ptr(0),
    00102       m_transport_dbg_ptr(0),
    00103       m_get_direct_mem_ptr(0)
    00104     {
    00105     }
    00106
    00107     void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
    00108     {
    00109       if (m_nb_transport_ptr) {
    00110         std::stringstream s;
    00111         s << m_name << ": non-blocking callback allready registered";
    00112         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00113
    00114       } else {
    00115         assert(!m_mod || m_mod == mod);
    00116         m_mod = mod;
    00117         m_nb_transport_ptr = p;
    00118       }
    00119     }
    00120
    00121     void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
    00122     {
    00123       if (m_b_transport_ptr) {
    00124         std::stringstream s;
    00125         s << m_name << ": blocking callback allready registered";
    00126         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00127       } else {
    00128         assert(!m_mod || m_mod == mod);
    00129         m_mod = mod;
    00130         m_b_transport_ptr = p;
    00131       }
    00132     }
    00133
    00134     void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
    00135     {
    00136       if (m_transport_dbg_ptr) {
    00137         std::stringstream s;
    00138         s << m_name << ": debug callback allready registered";
    00139         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00140       } else {
    00141         assert(!m_mod || m_mod == mod);
    00142         m_mod = mod;
    00143         m_transport_dbg_ptr = p;
    00144       }
    00145     }
    00146
    00147     void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
    00148     {
    00149       if (m_get_direct_mem_ptr) {
    00150         std::stringstream s;
    00151         s << m_name << ": get DMI pointer callback allready registered";
    00152         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00153       } else {
    00154         assert(!m_mod || m_mod == mod);
    00155         m_mod = mod;
    00156         m_get_direct_mem_ptr = p;
    00157       }
    00158     }
    00159
    00160     sync_enum_type nb_transport_fw(transaction_type& trans,
    00161                                    phase_type& phase,
    00162                                    sc_core::sc_time& t)
    00163     {
    00164       if (m_nb_transport_ptr) {
    00165         // forward call
    00166         assert(m_mod);
    00167         return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
    00168
    00169       } else {
    00170         std::stringstream s;
    00171         s << m_name << ": no non-blocking callback registered";
    00172         SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00173       }
    00174       return tlm::TLM_ACCEPTED;
    00175     }
    00176
    00177     void b_transport(transaction_type& trans, sc_core::sc_time& t)
    00178     {
    00179       if (m_b_transport_ptr) {
    00180         // forward call
    00181         assert(m_mod);
    00182         return (m_mod->*m_b_transport_ptr)(trans, t);
    00183
    00184       } else {
    00185         std::stringstream s;
    00186         s << m_name << ": no blocking callback registered";
    00187         SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00188       }
    00189     }
    00190
    00191     unsigned int transport_dbg(transaction_type& trans)
    00192     {
    00193       if (m_transport_dbg_ptr) {
    00194         // forward call
    00195         assert(m_mod);
    00196         return (m_mod->*m_transport_dbg_ptr)(trans);
    00197
    00198       } else {
    00199         // No debug support
    00200         return 0;
    00201       }
    00202     }
    00203
    00204     bool get_direct_mem_ptr(transaction_type& trans,
    00205                             tlm::tlm_dmi&  dmi_data)
    00206     {
    00207       if (m_get_direct_mem_ptr) {
    00208         // forward call
    00209         assert(m_mod);
    00210         return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
    00211
    00212       } else {
    00213         // No DMI support
    00214         dmi_data.allow_read_write();
    00215         dmi_data.set_start_address(0x0);
    00216         dmi_data.set_end_address((sc_dt::uint64)-1);
    00217         return false;
    00218       }
    00219     }
    00220
    00221   private:
    00222     const std::string m_name;
    00223     MODULE* m_mod;
    00224     NBTransportPtr m_nb_transport_ptr;
    00225     BTransportPtr m_b_transport_ptr;
    00226     TransportDbgPtr m_transport_dbg_ptr;
    00227     GetDirectMem_ptr m_get_direct_mem_ptr;
    00228   };
    00229
    00230 private:
    00231   process m_process;
    00232 };
    00233
    00234 //ID Tagged version
    00235 template <typename MODULE,
    00236           unsigned int BUSWIDTH = 32,
    00237           typename TYPES = tlm::tlm_base_protocol_types>
    00238 class passthrough_target_socket_tagged :
    00239   public tlm::tlm_target_socket<BUSWIDTH, TYPES>
    00240 {
    00241 public:
    00242   typedef typename TYPES::tlm_payload_type              transaction_type;
    00243   typedef typename TYPES::tlm_phase_type                phase_type;
    00244   typedef tlm::tlm_sync_enum                            sync_enum_type;
    00245   typedef tlm::tlm_fw_transport_if<TYPES>               fw_interface_type;
    00246   typedef tlm::tlm_bw_transport_if<TYPES>               bw_interface_type;
    00247   typedef tlm::tlm_target_socket<BUSWIDTH, TYPES>       base_type;
    00248
    00249 public:
    00250   passthrough_target_socket_tagged() :
    00251     base_type(sc_core::sc_gen_unique_name("passthrough_target_socket_tagged")),
    00252     m_process(this->name())
    00253   {
    00254     bind(m_process);
    00255   }
    00256
    00257   explicit passthrough_target_socket_tagged(const char* n) :
    00258     base_type(n),
    00259     m_process(this->name())
    00260   {
    00261     bind(m_process);
    00262   }
    00263
    00264   // REGISTER_XXX
    00265   void register_nb_transport_fw(MODULE* mod,
    00266                                 sync_enum_type (MODULE::*cb)(int id,
    00267                                                              transaction_type&,
    00268                                                              phase_type&,
    00269                                                              sc_core::sc_time&),
    00270                                 int id)
    00271   {
    00272     m_process.set_nb_transport_ptr(mod, cb);
    00273     m_process.set_nb_transport_user_id(id);
    00274   }
    00275
    00276   void register_b_transport(MODULE* mod,
    00277                             void (MODULE::*cb)(int id,
    00278                                                transaction_type&,
    00279                                                sc_core::sc_time&),
    00280                             int id)
    00281   {
    00282     m_process.set_b_transport_ptr(mod, cb);
    00283     m_process.set_b_transport_user_id(id);
    00284   }
    00285
    00286   void register_transport_dbg(MODULE* mod,
    00287                               unsigned int (MODULE::*cb)(int id,
    00288                                                          transaction_type&),
    00289                               int id)
    00290   {
    00291     m_process.set_transport_dbg_ptr(mod, cb);
    00292     m_process.set_transport_dbg_user_id(id);
    00293   }
    00294
    00295   void register_get_direct_mem_ptr(MODULE* mod,
    00296                                    bool (MODULE::*cb)(int id,
    00297                                                       transaction_type&,
    00298                                                       tlm::tlm_dmi&),
    00299                                    int id)
    00300   {
    00301     m_process.set_get_direct_mem_ptr(mod, cb);
    00302     m_process.set_get_dmi_user_id(id);
    00303   }
    00304
    00305 private:
    00306   class process : public tlm::tlm_fw_transport_if<TYPES>
    00307   {
    00308   public:
    00309     typedef sync_enum_type (MODULE::*NBTransportPtr)(int id,
    00310                                                      transaction_type&,
    00311                                                      phase_type&,
    00312                                                      sc_core::sc_time&);
    00313     typedef void (MODULE::*BTransportPtr)(int id,
    00314                                           transaction_type&,
    00315                                           sc_core::sc_time&);
    00316     typedef unsigned int (MODULE::*TransportDbgPtr)(int id,
    00317                                                     transaction_type&);
    00318     typedef bool (MODULE::*GetDirectMem_ptr)(int id,
    00319                                              transaction_type&,
    00320                                              tlm::tlm_dmi&);
    00321
    00322     process(const std::string& name) :
    00323       m_name(name),
    00324       m_mod(0),
    00325       m_nb_transport_ptr(0),
    00326       m_b_transport_ptr(0),
    00327       m_transport_dbg_ptr(0),
    00328       m_get_direct_mem_ptr(0),
    00329       m_nb_transport_user_id(0),
    00330       m_b_transport_user_id(0),
    00331       m_transport_dbg_user_id(0),
    00332       m_get_dmi_user_id(0)
    00333     {
    00334     }
    00335
    00336     void set_nb_transport_user_id(int id) { m_nb_transport_user_id = id; }
    00337     void set_b_transport_user_id(int id) { m_b_transport_user_id = id; }
    00338     void set_transport_dbg_user_id(int id) { m_transport_dbg_user_id = id; }
    00339     void set_get_dmi_user_id(int id) { m_get_dmi_user_id = id; }
    00340
    00341     void set_nb_transport_ptr(MODULE* mod, NBTransportPtr p)
    00342     {
    00343       if (m_nb_transport_ptr) {
    00344         std::stringstream s;
    00345         s << m_name << ": non-blocking callback allready registered";
    00346         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00347       } else {
    00348         assert(!m_mod || m_mod == mod);
    00349         m_mod = mod;
    00350         m_nb_transport_ptr = p;
    00351       }
    00352     }
    00353
    00354     void set_b_transport_ptr(MODULE* mod, BTransportPtr p)
    00355     {
    00356       if (m_b_transport_ptr) {
    00357         std::stringstream s;
    00358         s << m_name << ": blocking callback allready registered";
    00359         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00360       } else {
    00361         assert(!m_mod || m_mod == mod);
    00362         m_mod = mod;
    00363         m_b_transport_ptr = p;
    00364       }
    00365     }
    00366
    00367     void set_transport_dbg_ptr(MODULE* mod, TransportDbgPtr p)
    00368     {
    00369       if (m_transport_dbg_ptr) {
    00370         std::stringstream s;
    00371         s << m_name << ": debug callback allready registered";
    00372         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00373       } else {
    00374         assert(!m_mod || m_mod == mod);
    00375         m_mod = mod;
    00376         m_transport_dbg_ptr = p;
    00377       }
    00378     }
    00379
    00380     void set_get_direct_mem_ptr(MODULE* mod, GetDirectMem_ptr p)
    00381     {
    00382       if (m_get_direct_mem_ptr) {
    00383         std::stringstream s;
    00384         s << m_name << ": get DMI pointer callback allready registered";
    00385         SC_REPORT_WARNING("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00386       } else {
    00387         assert(!m_mod || m_mod == mod);
    00388         m_mod = mod;
    00389         m_get_direct_mem_ptr = p;
    00390       }
    00391     }
    00392
    00393     sync_enum_type nb_transport_fw(transaction_type& trans,
    00394                                    phase_type& phase,
    00395                                    sc_core::sc_time& t)
    00396     {
    00397       if (m_nb_transport_ptr) {
    00398         // forward call
    00399         assert(m_mod);
    00400         return (m_mod->*m_nb_transport_ptr)(m_nb_transport_user_id, trans, phase, t);
    00401
    00402       } else {
    00403         std::stringstream s;
    00404         s << m_name << ": no non-blocking callback registered";
    00405         SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00406       }
    00407       return tlm::TLM_ACCEPTED;
    00408     }
    00409
    00410     void b_transport(transaction_type& trans, sc_core::sc_time& t)
    00411     {
    00412       if (m_b_transport_ptr) {
    00413         // forward call
    00414         assert(m_mod);
    00415         return (m_mod->*m_b_transport_ptr)(m_b_transport_user_id, trans, t);
    00416
    00417       } else {
    00418         std::stringstream s;
    00419         s << m_name << ": no blocking callback registered";
    00420         SC_REPORT_ERROR("/OSCI_TLM-2/passthrough_socket",s.str().c_str());
    00421       }
    00422     }
    00423
    00424     unsigned int transport_dbg(transaction_type& trans)
    00425     {
    00426       if (m_transport_dbg_ptr) {
    00427         // forward call
    00428         assert(m_mod);
    00429         return (m_mod->*m_transport_dbg_ptr)(m_transport_dbg_user_id, trans);
    00430
    00431       } else {
    00432         // No debug support
    00433         return 0;
    00434       }
    00435     }
    00436
    00437     bool get_direct_mem_ptr(transaction_type& trans,
    00438                             tlm::tlm_dmi&  dmi_data)
    00439     {
    00440       if (m_get_direct_mem_ptr) {
    00441         // forward call
    00442         assert(m_mod);
    00443         return (m_mod->*m_get_direct_mem_ptr)(m_get_dmi_user_id, trans, dmi_data);
    00444
    00445       } else {
    00446         // No DMI support
    00447         dmi_data.allow_read_write();
    00448         dmi_data.set_start_address(0x0);
    00449         dmi_data.set_end_address((sc_dt::uint64)-1);
    00450         return false;
    00451       }
    00452     }
    00453
    00454   private:
    00455     const std::string m_name;
    00456     MODULE* m_mod;
    00457     NBTransportPtr m_nb_transport_ptr;
    00458     BTransportPtr m_b_transport_ptr;
    00459     TransportDbgPtr m_transport_dbg_ptr;
    00460     GetDirectMem_ptr m_get_direct_mem_ptr;
    00461     int m_nb_transport_user_id;
    00462     int m_b_transport_user_id;
    00463     int m_transport_dbg_user_id;
    00464     int m_get_dmi_user_id;
    00465   };
    00466
    00467 private:
    00468   process m_process;
    00469 };
    00470
    00471 }
    00472
    00473 #endif