diff options
Diffstat (limited to 'ext/systemc/src/tlm_utils/simple_initiator_socket.h')
-rw-r--r-- | ext/systemc/src/tlm_utils/simple_initiator_socket.h | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/ext/systemc/src/tlm_utils/simple_initiator_socket.h b/ext/systemc/src/tlm_utils/simple_initiator_socket.h new file mode 100644 index 000000000..4609fd885 --- /dev/null +++ b/ext/systemc/src/tlm_utils/simple_initiator_socket.h @@ -0,0 +1,292 @@ +/***************************************************************************** + + Licensed to Accellera Systems Initiative Inc. (Accellera) under one or + more contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright ownership. + Accellera licenses this file to you under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with the + License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + *****************************************************************************/ + +#ifndef __SIMPLE_INITIATOR_SOCKET_H__ +#define __SIMPLE_INITIATOR_SOCKET_H__ + +#include <tlm> +#include <sstream> + +namespace tlm_utils { + +template <typename MODULE, + unsigned int BUSWIDTH = 32, + typename TYPES = tlm::tlm_base_protocol_types> +class simple_initiator_socket : + public tlm::tlm_initiator_socket<BUSWIDTH, TYPES> +{ +public: + typedef typename TYPES::tlm_payload_type transaction_type; + typedef typename TYPES::tlm_phase_type phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; + typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; + typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type; + +public: + simple_initiator_socket() : + base_type(sc_core::sc_gen_unique_name("simple_initiator_socket")), + m_process(this->name()) + { + this->m_export.bind(m_process); + } + + explicit simple_initiator_socket(const char* n) : + base_type(n), + m_process(this->name()) + { + this->m_export.bind(m_process); + } + + void register_nb_transport_bw(MODULE* mod, + sync_enum_type (MODULE::*cb)(transaction_type&, + phase_type&, + sc_core::sc_time&)) + { + m_process.set_transport_ptr(mod, cb); + } + + void register_invalidate_direct_mem_ptr(MODULE* mod, + void (MODULE::*cb)(sc_dt::uint64, sc_dt::uint64)) + { + m_process.set_invalidate_direct_mem_ptr(mod, cb); + } + +private: + class process : public tlm::tlm_bw_transport_if<TYPES> + { + public: + typedef sync_enum_type (MODULE::*TransportPtr)(transaction_type&, + phase_type&, + sc_core::sc_time&); + typedef void (MODULE::*InvalidateDirectMemPtr)(sc_dt::uint64, + sc_dt::uint64); + + process(const std::string& name) : + m_name(name), + m_mod(0), + m_transport_ptr(0), + m_invalidate_direct_mem_ptr(0) + { + } + + void set_transport_ptr(MODULE* mod, TransportPtr p) + { + if (m_transport_ptr) { + std::stringstream s; + s << m_name << ": non-blocking callback allready registered"; + SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } else { + assert(!m_mod || m_mod == mod); + m_mod = mod; + m_transport_ptr = p; + } + } + + void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p) + { + if (m_invalidate_direct_mem_ptr) { + std::stringstream s; + s << m_name << ": invalidate DMI callback allready registered"; + SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } else { + assert(!m_mod || m_mod == mod); + m_mod = mod; + m_invalidate_direct_mem_ptr = p; + } + } + + sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) + { + if (m_transport_ptr) { + // forward call + assert(m_mod); + return (m_mod->*m_transport_ptr)(trans, phase, t); + + } else { + std::stringstream s; + s << m_name << ": no transport callback registered"; + SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } + return tlm::TLM_ACCEPTED; ///< unreachable code + } + + void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + if (m_invalidate_direct_mem_ptr) { + // forward call + assert(m_mod); + (m_mod->*m_invalidate_direct_mem_ptr)(start_range, end_range); + } + } + + private: + const std::string m_name; + MODULE* m_mod; + TransportPtr m_transport_ptr; + InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; + }; + +private: + process m_process; +}; + +// Tagged version + +template <typename MODULE, + unsigned int BUSWIDTH = 32, + typename TYPES = tlm::tlm_base_protocol_types> +class simple_initiator_socket_tagged : + public tlm::tlm_initiator_socket<BUSWIDTH, TYPES> +{ +public: + typedef typename TYPES::tlm_payload_type transaction_type; + typedef typename TYPES::tlm_phase_type phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type; + typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type; + typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES> base_type; + +public: + simple_initiator_socket_tagged() : + base_type(sc_core::sc_gen_unique_name("simple_initiator_socket_tagged")), + m_process(this->name()) + { + this->m_export.bind(m_process); + } + + explicit simple_initiator_socket_tagged(const char* n) : + base_type(n), + m_process(this->name()) + { + this->m_export.bind(m_process); + } + + void register_nb_transport_bw(MODULE* mod, + sync_enum_type (MODULE::*cb)(int, + transaction_type&, + phase_type&, + sc_core::sc_time&), + int id) + { + m_process.set_transport_ptr(mod, cb); + m_process.set_transport_user_id(id); + } + + void register_invalidate_direct_mem_ptr(MODULE* mod, + void (MODULE::*cb)(int, sc_dt::uint64, sc_dt::uint64), + int id) + { + m_process.set_invalidate_direct_mem_ptr(mod, cb); + m_process.set_invalidate_dmi_user_id(id); + } + +private: + class process : public tlm::tlm_bw_transport_if<TYPES> + { + public: + typedef sync_enum_type (MODULE::*TransportPtr)(int, + transaction_type&, + phase_type&, + sc_core::sc_time&); + typedef void (MODULE::*InvalidateDirectMemPtr)(int, + sc_dt::uint64, + sc_dt::uint64); + + process(const std::string& name) : + m_name(name), + m_mod(0), + m_transport_ptr(0), + m_invalidate_direct_mem_ptr(0), + m_transport_user_id(0), + m_invalidate_direct_mem_user_id(0) + { + } + + void set_transport_user_id(int id) { m_transport_user_id = id; } + void set_invalidate_dmi_user_id(int id) { m_invalidate_direct_mem_user_id = id; } + + void set_transport_ptr(MODULE* mod, TransportPtr p) + { + if (m_transport_ptr) { + std::stringstream s; + s << m_name << ": non-blocking callback allready registered"; + SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } else { + assert(!m_mod || m_mod == mod); + m_mod = mod; + m_transport_ptr = p; + } + } + + void set_invalidate_direct_mem_ptr(MODULE* mod, InvalidateDirectMemPtr p) + { + if (m_invalidate_direct_mem_ptr) { + std::stringstream s; + s << m_name << ": invalidate DMI callback allready registered"; + SC_REPORT_WARNING("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } else { + assert(!m_mod || m_mod == mod); + m_mod = mod; + m_invalidate_direct_mem_ptr = p; + } + } + + sync_enum_type nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) + { + if (m_transport_ptr) { + // forward call + assert(m_mod); + return (m_mod->*m_transport_ptr)(m_transport_user_id, trans, phase, t); + + } else { + std::stringstream s; + s << m_name << ": no transport callback registered"; + SC_REPORT_ERROR("/OSCI_TLM-2/simple_socket",s.str().c_str()); + } + return tlm::TLM_ACCEPTED; ///< unreachable code + } + + void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + if (m_invalidate_direct_mem_ptr) { + // forward call + assert(m_mod); + (m_mod->*m_invalidate_direct_mem_ptr)(m_invalidate_direct_mem_user_id, start_range, end_range); + } + } + + private: + const std::string m_name; + MODULE* m_mod; + TransportPtr m_transport_ptr; + InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; + int m_transport_user_id; + int m_invalidate_direct_mem_user_id; + }; + +private: + process m_process; +}; + +} + +#endif |