| /***************************************************************************** |
| |
| 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 __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ |
| #define __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ |
| |
| #include "../core/sc_module.hh" |
| #include "../core/sc_port.hh" |
| #include "../tlm_core/2/generic_payload/gp.hh" |
| #include "../tlm_core/2/interfaces/fw_bw_ifs.hh" |
| #include "../tlm_core/2/sockets/initiator_socket.hh" |
| #include "../tlm_core/2/sockets/target_socket.hh" |
| #include "../utils/sc_report_handler.hh" |
| #include "convenience_socket_bases.h" |
| |
| namespace tlm_utils |
| { |
| |
| template <typename MODULE, unsigned int BUSWIDTH, typename TYPES, |
| sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> |
| class simple_initiator_socket_b : |
| public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>, |
| protected simple_socket_base |
| { |
| 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, 1, POL> base_type; |
| |
| public: |
| static const char * |
| default_name() |
| { |
| return sc_core::sc_gen_unique_name("simple_initiator_socket"); |
| } |
| |
| explicit simple_initiator_socket_b(const char *n=default_name()) : |
| base_type(n), m_process(this) |
| { |
| 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>, |
| protected convenience_socket_cb_holder |
| { |
| 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); |
| |
| explicit process(simple_socket_base *owner) : |
| convenience_socket_cb_holder(owner), 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) { |
| display_warning("non-blocking callback already registered"); |
| return; |
| } |
| sc_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) { |
| display_warning("invalidate DMI callback already registered"); |
| return; |
| } |
| sc_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. |
| sc_assert(m_mod); |
| return (m_mod->*m_transport_ptr)(trans, phase, t); |
| } |
| display_error("no transport callback registered"); |
| return tlm::TLM_COMPLETED; |
| } |
| |
| void |
| invalidate_direct_mem_ptr(sc_dt::uint64 start_range, |
| sc_dt::uint64 end_range) |
| { |
| if (m_invalidate_direct_mem_ptr) { |
| // Forward call. |
| sc_assert(m_mod); |
| (m_mod->*m_invalidate_direct_mem_ptr)( |
| start_range, end_range); |
| } |
| } |
| |
| private: |
| MODULE *m_mod; |
| TransportPtr m_transport_ptr; |
| InvalidateDirectMemPtr m_invalidate_direct_mem_ptr; |
| }; |
| |
| private: |
| const sc_core::sc_object *get_socket() const { return this; } |
| |
| private: |
| process m_process; |
| }; |
| |
| template <typename MODULE, unsigned int BUSWIDTH=32, |
| typename TYPES=tlm::tlm_base_protocol_types> |
| class simple_initiator_socket : |
| public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> |
| { |
| typedef simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES> socket_b; |
| public: |
| simple_initiator_socket() : socket_b() {} |
| explicit simple_initiator_socket(const char *name) : socket_b(name) {} |
| }; |
| |
| template <typename MODULE, unsigned int BUSWIDTH=32, |
| typename TYPES=tlm::tlm_base_protocol_types> |
| class simple_initiator_socket_optional : |
| public simple_initiator_socket_b<MODULE, BUSWIDTH, TYPES, |
| sc_core::SC_ZERO_OR_MORE_BOUND> |
| { |
| typedef simple_initiator_socket_b< |
| MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; |
| public: |
| simple_initiator_socket_optional() : socket_b() {} |
| explicit simple_initiator_socket_optional(const char *name) : |
| socket_b(name) |
| {} |
| }; |
| |
| |
| // Tagged version |
| |
| template <typename MODULE, unsigned int BUSWIDTH, typename TYPES, |
| sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND> |
| class simple_initiator_socket_tagged_b : |
| public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, 1, POL>, |
| protected simple_socket_base |
| { |
| 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, 1, POL> base_type; |
| |
| public: |
| static const char * |
| default_name() |
| { |
| return sc_core::sc_gen_unique_name("simple_initiator_socket_tagged"); |
| } |
| |
| explicit simple_initiator_socket_tagged_b(const char *n=default_name()) : |
| base_type(n), m_process(this) |
| { |
| 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>, |
| protected convenience_socket_cb_holder |
| { |
| 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); |
| |
| explicit process(simple_socket_base *owner) : |
| convenience_socket_cb_holder(owner), 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) { |
| display_warning("non-blocking callback already registered"); |
| return; |
| } |
| sc_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) { |
| display_warning("invalidate DMI callback already registered"); |
| return; |
| } |
| sc_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. |
| sc_assert(m_mod); |
| return (m_mod->*m_transport_ptr)( |
| m_transport_user_id, trans, phase, t); |
| } |
| display_error("no transport callback registered"); |
| return tlm::TLM_COMPLETED; |
| } |
| |
| void |
| invalidate_direct_mem_ptr( |
| sc_dt::uint64 start_range, sc_dt::uint64 end_range) |
| { |
| if (m_invalidate_direct_mem_ptr) { |
| // Forward call. |
| sc_assert(m_mod); |
| (m_mod->*m_invalidate_direct_mem_ptr)( |
| m_invalidate_direct_mem_user_id, |
| start_range, end_range); |
| } |
| } |
| |
| private: |
| 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: |
| const sc_core::sc_object *get_socket() const { return this; } |
| |
| private: |
| process m_process; |
| }; |
| |
| template <typename MODULE, unsigned int BUSWIDTH=32, |
| typename TYPES=tlm::tlm_base_protocol_types> |
| class simple_initiator_socket_tagged : |
| public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES> |
| { |
| typedef simple_initiator_socket_tagged_b< |
| MODULE, BUSWIDTH, TYPES> socket_b; |
| public: |
| simple_initiator_socket_tagged() : socket_b() {} |
| explicit simple_initiator_socket_tagged(const char *name) : |
| socket_b(name) |
| {} |
| }; |
| |
| template <typename MODULE, unsigned int BUSWIDTH=32, |
| typename TYPES=tlm::tlm_base_protocol_types> |
| class simple_initiator_socket_tagged_optional : |
| public simple_initiator_socket_tagged_b<MODULE, BUSWIDTH, TYPES, |
| sc_core::SC_ZERO_OR_MORE_BOUND> |
| { |
| typedef simple_initiator_socket_tagged_b< |
| MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b; |
| public: |
| simple_initiator_socket_tagged_optional() : socket_b() {} |
| explicit simple_initiator_socket_tagged_optional(const char *name) : |
| socket_b(name) |
| {} |
| }; |
| |
| } // namespace tlm_utils |
| |
| #endif /* __SYSTEMC_EXT_TLM_UTILS_SIMPLE_INITIATOR_SOCKET_H__ */ |