113511Sgabeblack@google.com/*****************************************************************************
213511Sgabeblack@google.com
313511Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
413511Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
513511Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
613511Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
713511Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
813511Sgabeblack@google.com  License.  You may obtain a copy of the License at
913511Sgabeblack@google.com
1013511Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1113511Sgabeblack@google.com
1213511Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1313511Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1413511Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1513511Sgabeblack@google.com  implied.  See the License for the specific language governing
1613511Sgabeblack@google.com  permissions and limitations under the License.
1713511Sgabeblack@google.com
1813511Sgabeblack@google.com *****************************************************************************/
1913511Sgabeblack@google.com
2013513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__
2113513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__
2213511Sgabeblack@google.com
2313513Sgabeblack@google.com#include <map>
2413586Sgabeblack@google.com
2513586Sgabeblack@google.com#include "../core/sc_port.hh"
2613586Sgabeblack@google.com#include "../tlm_core/2/interfaces/fw_bw_ifs.hh"
2713586Sgabeblack@google.com#include "convenience_socket_bases.h"
2813511Sgabeblack@google.com
2913513Sgabeblack@google.comnamespace tlm_utils
3013513Sgabeblack@google.com{
3113511Sgabeblack@google.com
3213511Sgabeblack@google.comtemplate <typename signature>
3313513Sgabeblack@google.comstruct fn_container
3413513Sgabeblack@google.com{
3513513Sgabeblack@google.com    signature function;
3613511Sgabeblack@google.com};
3713511Sgabeblack@google.com
3813511Sgabeblack@google.com#define TLM_DEFINE_FUNCTOR(name) \
3913511Sgabeblack@google.comtemplate <typename MODULE, typename TRAITS> \
4013513Sgabeblack@google.cominline TLM_RET_VAL \
4113513Sgabeblack@google.comstatic_##name(void *mod, void *fn, int index, TLM_FULL_ARG_LIST) \
4213511Sgabeblack@google.com{ \
4313513Sgabeblack@google.com    typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> \
4413513Sgabeblack@google.com        fn_container_type; \
4513513Sgabeblack@google.com    MODULE *tmp_mod = static_cast<MODULE *>(mod); \
4613513Sgabeblack@google.com    fn_container_type *tmp_cb = static_cast<fn_container_type *> (fn); \
4713513Sgabeblack@google.com    return (tmp_mod->*(tmp_cb->function))( \
4813513Sgabeblack@google.com            index, TLM_ARG_LIST_WITHOUT_TYPES); \
4913513Sgabeblack@google.com} \
5013513Sgabeblack@google.com \
5113511Sgabeblack@google.comtemplate <typename MODULE, typename TRAITS> \
5213513Sgabeblack@google.cominline void \
5313513Sgabeblack@google.comdelete_fn_container_of_##name(void *fn) \
5413511Sgabeblack@google.com{ \
5513513Sgabeblack@google.com    typedef fn_container<TLM_RET_VAL (MODULE::*)(int, TLM_FULL_ARG_LIST)> \
5613513Sgabeblack@google.com        fn_container_type; \
5713513Sgabeblack@google.com    fn_container_type *tmp_cb = static_cast<fn_container_type *>(fn); \
5813513Sgabeblack@google.com    if (tmp_cb) \
5913513Sgabeblack@google.com        delete tmp_cb; \
6013511Sgabeblack@google.com} \
6113513Sgabeblack@google.com \
6213511Sgabeblack@google.comtemplate <typename TRAITS> \
6313511Sgabeblack@google.comclass name##_functor{ \
6413511Sgabeblack@google.compublic: \
6513513Sgabeblack@google.com    typedef typename TRAITS::tlm_payload_type payload_type; \
6613513Sgabeblack@google.com    typedef typename TRAITS::tlm_phase_type   phase_type; \
6713513Sgabeblack@google.com    typedef TLM_RET_VAL (*call_fn)(void *,void *, int, TLM_FULL_ARG_LIST); \
6813513Sgabeblack@google.com    typedef void (*del_fn)(void *); \
6913513Sgabeblack@google.com \
7013513Sgabeblack@google.com    name##_functor() : m_fn(0), m_del_fn(0), m_mod(0), m_mem_fn(0) {} \
7113513Sgabeblack@google.com    ~name##_functor() \
7213513Sgabeblack@google.com    { \
7313513Sgabeblack@google.com        if (m_del_fn) \
7413513Sgabeblack@google.com            (*m_del_fn)(m_mem_fn); \
7513513Sgabeblack@google.com    } \
7613513Sgabeblack@google.com \
7713513Sgabeblack@google.com    template <typename MODULE> \
7813513Sgabeblack@google.com    void \
7913513Sgabeblack@google.com    set_function(MODULE *mod, TLM_RET_VAL (MODULE::*cb)( \
8013513Sgabeblack@google.com                int, TLM_FULL_ARG_LIST)) \
8113513Sgabeblack@google.com    { \
8213513Sgabeblack@google.com        typedef fn_container<TLM_RET_VAL (MODULE::*)( \
8313513Sgabeblack@google.com                int, TLM_FULL_ARG_LIST)> fn_container_type; \
8413513Sgabeblack@google.com        m_fn = &static_##name<MODULE,TRAITS>; \
8513513Sgabeblack@google.com        m_del_fn = &delete_fn_container_of_##name<MODULE, TRAITS>; \
8613513Sgabeblack@google.com        m_del_fn(m_mem_fn); \
8713513Sgabeblack@google.com        fn_container_type *tmp =new fn_container_type(); \
8813513Sgabeblack@google.com        tmp->function = cb; \
8913513Sgabeblack@google.com        m_mod = static_cast<void *>(mod); \
9013513Sgabeblack@google.com        m_mem_fn = static_cast<void *>(tmp); \
9113513Sgabeblack@google.com    } \
9213511Sgabeblack@google.com  \
9313513Sgabeblack@google.com    TLM_RET_VAL \
9413513Sgabeblack@google.com    operator ()(int index, TLM_FULL_ARG_LIST) \
9513513Sgabeblack@google.com    { \
9613513Sgabeblack@google.com        return m_fn(m_mod, m_mem_fn, index, TLM_ARG_LIST_WITHOUT_TYPES); \
9713513Sgabeblack@google.com    } \
9813513Sgabeblack@google.com \
9913513Sgabeblack@google.com    bool is_valid() { return (m_mod != 0 && m_mem_fn != 0 && m_fn != 0); } \
10013513Sgabeblack@google.com \
10113513Sgabeblack@google.com  protected: \
10213513Sgabeblack@google.com    call_fn m_fn;\
10313513Sgabeblack@google.com    del_fn m_del_fn; \
10413513Sgabeblack@google.com    void *m_mod; \
10513513Sgabeblack@google.com    void *m_mem_fn; \
10613513Sgabeblack@google.com  private: \
10713513Sgabeblack@google.com    name##_functor &operator = (const name##_functor &); \
10813511Sgabeblack@google.com}
10913511Sgabeblack@google.com
11013511Sgabeblack@google.com
11113511Sgabeblack@google.com#define TLM_RET_VAL tlm::tlm_sync_enum
11213513Sgabeblack@google.com#define TLM_FULL_ARG_LIST \
11313513Sgabeblack@google.com    typename TRAITS::tlm_payload_type &txn, \
11413513Sgabeblack@google.com    typename TRAITS::tlm_phase_type &ph, sc_core::sc_time &t
11513513Sgabeblack@google.com#define TLM_ARG_LIST_WITHOUT_TYPES txn, ph, t
11613511Sgabeblack@google.comTLM_DEFINE_FUNCTOR(nb_transport);
11713511Sgabeblack@google.com#undef TLM_RET_VAL
11813511Sgabeblack@google.com#undef TLM_FULL_ARG_LIST
11913511Sgabeblack@google.com#undef TLM_ARG_LIST_WITHOUT_TYPES
12013511Sgabeblack@google.com
12113511Sgabeblack@google.com#define TLM_RET_VAL void
12213513Sgabeblack@google.com#define TLM_FULL_ARG_LIST \
12313513Sgabeblack@google.com    typename TRAITS::tlm_payload_type &txn, sc_core::sc_time &t
12413513Sgabeblack@google.com#define TLM_ARG_LIST_WITHOUT_TYPES txn, t
12513511Sgabeblack@google.comTLM_DEFINE_FUNCTOR(b_transport);
12613511Sgabeblack@google.com#undef TLM_RET_VAL
12713511Sgabeblack@google.com#undef TLM_FULL_ARG_LIST
12813511Sgabeblack@google.com#undef TLM_ARG_LIST_WITHOUT_TYPES
12913511Sgabeblack@google.com
13013511Sgabeblack@google.com#define TLM_RET_VAL unsigned int
13113513Sgabeblack@google.com#define TLM_FULL_ARG_LIST typename TRAITS::tlm_payload_type &txn
13213511Sgabeblack@google.com#define TLM_ARG_LIST_WITHOUT_TYPES txn
13313511Sgabeblack@google.comTLM_DEFINE_FUNCTOR(debug_transport);
13413511Sgabeblack@google.com#undef TLM_RET_VAL
13513511Sgabeblack@google.com#undef TLM_FULL_ARG_LIST
13613511Sgabeblack@google.com#undef TLM_ARG_LIST_WITHOUT_TYPES
13713511Sgabeblack@google.com
13813511Sgabeblack@google.com#define TLM_RET_VAL bool
13913513Sgabeblack@google.com#define TLM_FULL_ARG_LIST \
14013513Sgabeblack@google.com    typename TRAITS::tlm_payload_type &txn, tlm::tlm_dmi &dmi
14113513Sgabeblack@google.com#define TLM_ARG_LIST_WITHOUT_TYPES txn, dmi
14213511Sgabeblack@google.comTLM_DEFINE_FUNCTOR(get_dmi_ptr);
14313511Sgabeblack@google.com#undef TLM_RET_VAL
14413511Sgabeblack@google.com#undef TLM_FULL_ARG_LIST
14513511Sgabeblack@google.com#undef TLM_ARG_LIST_WITHOUT_TYPES
14613511Sgabeblack@google.com
14713511Sgabeblack@google.com#define TLM_RET_VAL void
14813511Sgabeblack@google.com#define TLM_FULL_ARG_LIST sc_dt::uint64 l, sc_dt::uint64 u
14913513Sgabeblack@google.com#define TLM_ARG_LIST_WITHOUT_TYPES l, u
15013511Sgabeblack@google.comTLM_DEFINE_FUNCTOR(invalidate_dmi);
15113511Sgabeblack@google.com#undef TLM_RET_VAL
15213511Sgabeblack@google.com#undef TLM_FULL_ARG_LIST
15313511Sgabeblack@google.com#undef TLM_ARG_LIST_WITHOUT_TYPES
15413511Sgabeblack@google.com
15513511Sgabeblack@google.com#undef TLM_DEFINE_FUNCTOR
15613511Sgabeblack@google.com
15713511Sgabeblack@google.com/*
15813511Sgabeblack@google.comThis class implements the fw interface.
15913511Sgabeblack@google.comIt allows to register a callback for each of the fw interface methods.
16013511Sgabeblack@google.comThe callbacks simply forward the fw interface call, but add the id (an int)
16113511Sgabeblack@google.comof the callback binder to the signature of the call.
16213511Sgabeblack@google.com*/
16313511Sgabeblack@google.comtemplate <typename TYPES>
16413513Sgabeblack@google.comclass callback_binder_fw : public tlm::tlm_fw_transport_if<TYPES>,
16513513Sgabeblack@google.com    protected convenience_socket_cb_holder
16613511Sgabeblack@google.com{
16713511Sgabeblack@google.com  public:
16813513Sgabeblack@google.com    // typedefs according to the used TYPES class.
16913513Sgabeblack@google.com    typedef typename TYPES::tlm_payload_type transaction_type;
17013513Sgabeblack@google.com    typedef typename TYPES::tlm_phase_type phase_type;
17113513Sgabeblack@google.com    typedef tlm::tlm_sync_enum sync_enum_type;
17213513Sgabeblack@google.com
17313513Sgabeblack@google.com    // typedefs for the callbacks.
17413513Sgabeblack@google.com    typedef nb_transport_functor<TYPES> nb_func_type;
17513513Sgabeblack@google.com    typedef b_transport_functor<TYPES> b_func_type;
17613511Sgabeblack@google.com    typedef debug_transport_functor<TYPES> debug_func_type;
17713513Sgabeblack@google.com    typedef get_dmi_ptr_functor<TYPES> dmi_func_type;
17813511Sgabeblack@google.com
17913513Sgabeblack@google.com    callback_binder_fw(multi_socket_base *owner, int id) :
18013513Sgabeblack@google.com        convenience_socket_cb_holder(owner), m_id(id),
18113513Sgabeblack@google.com        m_nb_f(0), m_b_f(0), m_dbg_f(0), m_dmi_f(0) , m_caller_port(0)
18213511Sgabeblack@google.com    {}
18313511Sgabeblack@google.com
18413513Sgabeblack@google.com    // The nb_transport method of the fw interface
18513513Sgabeblack@google.com    sync_enum_type nb_transport_fw(
18613513Sgabeblack@google.com            transaction_type &txn, phase_type &p, sc_core::sc_time &t)
18713513Sgabeblack@google.com    {
18813513Sgabeblack@google.com        // Check if a callback is registered.
18913513Sgabeblack@google.com        if (m_nb_f && m_nb_f->is_valid()) {
19013513Sgabeblack@google.com            return (*m_nb_f)(m_id, txn, p, t); // Do the callback.
19113513Sgabeblack@google.com        }
19213511Sgabeblack@google.com
19313513Sgabeblack@google.com        display_error("Call to nb_transport_fw without a "
19413513Sgabeblack@google.com                "registered callback for nb_transport_fw.");
19513513Sgabeblack@google.com        return tlm::TLM_COMPLETED;
19613511Sgabeblack@google.com    }
19713511Sgabeblack@google.com
19813513Sgabeblack@google.com    // The b_transport method of the fw interface.
19913513Sgabeblack@google.com    void
20013513Sgabeblack@google.com    b_transport(transaction_type &trans, sc_core::sc_time &t)
20113513Sgabeblack@google.com    {
20213513Sgabeblack@google.com        // Check if a callback is registered.
20313513Sgabeblack@google.com        if (m_b_f && m_b_f->is_valid()) {
20413513Sgabeblack@google.com            (*m_b_f)(m_id, trans, t); // Do the callback
20513513Sgabeblack@google.com            return;
20613513Sgabeblack@google.com        }
20713511Sgabeblack@google.com
20813513Sgabeblack@google.com        display_error("Call to b_transport without a "
20913513Sgabeblack@google.com                "registered callback for b_transport.");
21013511Sgabeblack@google.com    }
21113511Sgabeblack@google.com
21213513Sgabeblack@google.com    // The DMI method of the fw interface.
21313513Sgabeblack@google.com    bool
21413513Sgabeblack@google.com    get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
21513513Sgabeblack@google.com    {
21613513Sgabeblack@google.com        // Check if a callback is registered.
21713513Sgabeblack@google.com        if (m_dmi_f && m_dmi_f->is_valid()) {
21813513Sgabeblack@google.com            // Do the callback.
21913513Sgabeblack@google.com            return (*m_dmi_f)(m_id, trans, dmi_data);
22013513Sgabeblack@google.com        }
22113513Sgabeblack@google.com
22213513Sgabeblack@google.com        dmi_data.allow_none();
22313513Sgabeblack@google.com        dmi_data.set_start_address(0x0);
22413513Sgabeblack@google.com        dmi_data.set_end_address((sc_dt::uint64)-1);
22513513Sgabeblack@google.com        return false;
22613511Sgabeblack@google.com    }
22713511Sgabeblack@google.com
22813513Sgabeblack@google.com    // The debug method of the fw interface.
22913513Sgabeblack@google.com    unsigned int
23013513Sgabeblack@google.com    transport_dbg(transaction_type &trans)
23113513Sgabeblack@google.com    {
23213513Sgabeblack@google.com        // check if a callback is registered
23313513Sgabeblack@google.com        if (m_dbg_f && m_dbg_f->is_valid()) {
23413513Sgabeblack@google.com            return (*m_dbg_f)(m_id, trans); // Do the callback.
23513513Sgabeblack@google.com        }
23613513Sgabeblack@google.com
23713513Sgabeblack@google.com        return 0;
23813511Sgabeblack@google.com    }
23913513Sgabeblack@google.com
24013513Sgabeblack@google.com    // The SystemC standard callback register_port:
24113513Sgabeblack@google.com    // - Called when a port if bound to the interface.
24213513Sgabeblack@google.com    // - Allowd to find out who is bound to that callback binder.
24313513Sgabeblack@google.com    void
24413513Sgabeblack@google.com    register_port(sc_core::sc_port_base &b, const char * /* name */)
24513513Sgabeblack@google.com    {
24613513Sgabeblack@google.com        m_caller_port = &b;
24713511Sgabeblack@google.com    }
24813513Sgabeblack@google.com
24913513Sgabeblack@google.com    // Register callbacks for all fw interface methods at once.
25013513Sgabeblack@google.com    void
25113513Sgabeblack@google.com    set_callbacks(nb_func_type &cb1, b_func_type &cb2,
25213513Sgabeblack@google.com                  dmi_func_type &cb3, debug_func_type &cb4)
25313513Sgabeblack@google.com    {
25413513Sgabeblack@google.com        m_nb_f = &cb1;
25513513Sgabeblack@google.com        m_b_f = &cb2;
25613513Sgabeblack@google.com        m_dmi_f = &cb3;
25713513Sgabeblack@google.com        m_dbg_f = &cb4;
25813511Sgabeblack@google.com    }
25913513Sgabeblack@google.com
26013513Sgabeblack@google.com    // Getter method to get the port that is bound to that callback binder.
26113513Sgabeblack@google.com    // NOTE: This will only return a valid value at end of elaboration
26213511Sgabeblack@google.com    //  (but not before end of elaboration!)
26313513Sgabeblack@google.com    sc_core::sc_port_base *get_other_side() { return m_caller_port; }
26413513Sgabeblack@google.com
26513511Sgabeblack@google.com  private:
26613513Sgabeblack@google.com    // The ID of the callback binder.
26713513Sgabeblack@google.com    int m_id;
26813513Sgabeblack@google.com
26913513Sgabeblack@google.com    // The callbacks.
27013513Sgabeblack@google.com    nb_func_type *m_nb_f;
27113513Sgabeblack@google.com    b_func_type *m_b_f;
27213513Sgabeblack@google.com    debug_func_type *m_dbg_f;
27313513Sgabeblack@google.com    dmi_func_type *m_dmi_f;
27413513Sgabeblack@google.com
27513513Sgabeblack@google.com    // The port bound to that callback binder.
27613513Sgabeblack@google.com    sc_core::sc_port_base *m_caller_port;
27713511Sgabeblack@google.com};
27813511Sgabeblack@google.com
27913511Sgabeblack@google.com/*
28013511Sgabeblack@google.comThis class implements the bw interface.
28113511Sgabeblack@google.comIt allows to register a callback for each of the bw interface methods.
28213511Sgabeblack@google.comThe callbacks simply forward the bw interface call, but add the id (an int)
28313511Sgabeblack@google.comof the callback binder to the signature of the call.
28413511Sgabeblack@google.com*/
28513511Sgabeblack@google.comtemplate <typename TYPES>
28613513Sgabeblack@google.comclass callback_binder_bw : public tlm::tlm_bw_transport_if<TYPES>,
28713513Sgabeblack@google.com    protected convenience_socket_cb_holder
28813511Sgabeblack@google.com{
28913511Sgabeblack@google.com  public:
29013513Sgabeblack@google.com    // typedefs according to the used TYPES class
29113513Sgabeblack@google.com    typedef typename TYPES::tlm_payload_type transaction_type;
29213513Sgabeblack@google.com    typedef typename TYPES::tlm_phase_type phase_type;
29313513Sgabeblack@google.com    typedef tlm::tlm_sync_enum sync_enum_type;
29413513Sgabeblack@google.com
29513513Sgabeblack@google.com    // typedefs for the callbacks
29613513Sgabeblack@google.com    typedef nb_transport_functor<TYPES> nb_func_type;
29713511Sgabeblack@google.com    typedef invalidate_dmi_functor<TYPES> dmi_func_type;
29813511Sgabeblack@google.com
29913513Sgabeblack@google.com    callback_binder_bw(multi_socket_base *owner, int id) :
30013513Sgabeblack@google.com        convenience_socket_cb_holder(owner), m_id(id),
30113513Sgabeblack@google.com        m_nb_f(0), m_dmi_f(0)
30213513Sgabeblack@google.com    {}
30313511Sgabeblack@google.com
30413513Sgabeblack@google.com    // The nb_transport method of the bw interface.
30513513Sgabeblack@google.com    sync_enum_type
30613513Sgabeblack@google.com    nb_transport_bw(transaction_type &txn, phase_type& p,
30713513Sgabeblack@google.com            sc_core::sc_time &t)
30813513Sgabeblack@google.com    {
30913513Sgabeblack@google.com        // Check if a callback is registered.
31013513Sgabeblack@google.com        if (m_nb_f && m_nb_f->is_valid()) {
31113513Sgabeblack@google.com            return (*m_nb_f)(m_id, txn, p, t); // Do the callback.
31213513Sgabeblack@google.com        }
31313511Sgabeblack@google.com
31413513Sgabeblack@google.com        display_error("Call to nb_transport_bw without a "
31513513Sgabeblack@google.com                "registered callback for nb_transport_bw");
31613513Sgabeblack@google.com        return tlm::TLM_COMPLETED;
31713511Sgabeblack@google.com    }
31813511Sgabeblack@google.com
31913513Sgabeblack@google.com    // The DMI method of the bw interface.
32013513Sgabeblack@google.com    void
32113513Sgabeblack@google.com    invalidate_direct_mem_ptr(sc_dt::uint64 l, sc_dt::uint64 u)
32213513Sgabeblack@google.com    {
32313513Sgabeblack@google.com        // Check if a callback is registered.
32413513Sgabeblack@google.com        if (m_dmi_f && m_dmi_f->is_valid()) {
32513513Sgabeblack@google.com            (*m_dmi_f)(m_id,l,u); // Do the callback.
32613513Sgabeblack@google.com        }
32713511Sgabeblack@google.com    }
32813513Sgabeblack@google.com
32913513Sgabeblack@google.com    // Register callbacks for all bw interface methods at once.
33013513Sgabeblack@google.com    void
33113513Sgabeblack@google.com    set_callbacks(nb_func_type &cb1, dmi_func_type &cb2)
33213513Sgabeblack@google.com    {
33313513Sgabeblack@google.com        m_nb_f = &cb1;
33413513Sgabeblack@google.com        m_dmi_f = &cb2;
33513513Sgabeblack@google.com    }
33613513Sgabeblack@google.com
33713511Sgabeblack@google.com  private:
33813513Sgabeblack@google.com    // The ID of the callback binder.
33913511Sgabeblack@google.com    int m_id;
34013513Sgabeblack@google.com    // The callbacks.
34113513Sgabeblack@google.com    nb_func_type *m_nb_f;
34213513Sgabeblack@google.com    dmi_func_type *m_dmi_f;
34313511Sgabeblack@google.com};
34413511Sgabeblack@google.com
34513511Sgabeblack@google.com/*
34613511Sgabeblack@google.comThis class forms the base for multi initiator sockets,
34713511Sgabeblack@google.comwith fewer template parameters than the multi_init_base.
34813511Sgabeblack@google.comThis class is implementation-defined.
34913511Sgabeblack@google.com*/
35013513Sgabeblack@google.comtemplate <typename TYPES=tlm::tlm_base_protocol_types>
35113513Sgabeblack@google.comclass multi_init_base_if
35213513Sgabeblack@google.com{
35313513Sgabeblack@google.com  public:
35413513Sgabeblack@google.com    // This method shall return a vector of the callback binders of multi
35513513Sgabeblack@google.com    // initiator socket.
35613513Sgabeblack@google.com    virtual std::vector<callback_binder_bw<TYPES> *> &get_binders()=0;
35713513Sgabeblack@google.com    // This method shall return a vector of all target interfaces bound to
35813513Sgabeblack@google.com    // this multi init socket.
35913513Sgabeblack@google.com    virtual std::vector<tlm::tlm_fw_transport_if<TYPES> *> &get_sockets()=0;
36013513Sgabeblack@google.com  protected:
36113513Sgabeblack@google.com    virtual ~multi_init_base_if() {}
36213511Sgabeblack@google.com};
36313511Sgabeblack@google.com
36413511Sgabeblack@google.com/*
36513511Sgabeblack@google.comThis class forms the base for multi initiator sockets.
36613511Sgabeblack@google.comIt enforces a multi initiator socket to implement all functions
36713511Sgabeblack@google.comneeded to do hierarchical bindings.
36813511Sgabeblack@google.com*/
36913513Sgabeblack@google.comtemplate <unsigned int BUSWIDTH=32,
37013513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
37113513Sgabeblack@google.com          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
37213513Sgabeblack@google.comclass multi_init_base :
37313513Sgabeblack@google.com    public tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL>,
37413513Sgabeblack@google.com    public multi_init_base_if<TYPES>, protected multi_socket_base
37513511Sgabeblack@google.com{
37613513Sgabeblack@google.com  public:
37713513Sgabeblack@google.com    // typedef for the base type: the standard tlm initiator socket.
37813513Sgabeblack@google.com    typedef tlm::tlm_initiator_socket<BUSWIDTH, TYPES, N, POL> base_type;
37913511Sgabeblack@google.com
38013513Sgabeblack@google.com    // This method shall disable the code that does the callback binding
38113513Sgabeblack@google.com    // that registers callbacks to binders.
38213513Sgabeblack@google.com    virtual void disable_cb_bind()=0;
38313511Sgabeblack@google.com
38413513Sgabeblack@google.com    // This method shall return the multi_init_base to which the
38513513Sgabeblack@google.com    // multi_init_base is bound hierarchically. If the base is not bound
38613513Sgabeblack@google.com    // hierarchically it shall return a pointer to itself.
38713513Sgabeblack@google.com    virtual multi_init_base *get_hierarch_bind() = 0;
38813513Sgabeblack@google.com
38913513Sgabeblack@google.com    virtual tlm::tlm_socket_category
39013513Sgabeblack@google.com    get_socket_category() const
39113513Sgabeblack@google.com    {
39213513Sgabeblack@google.com        return tlm::TLM_MULTI_INITIATOR_SOCKET;
39313513Sgabeblack@google.com    }
39413513Sgabeblack@google.com
39513513Sgabeblack@google.com    virtual ~multi_init_base() {}
39613513Sgabeblack@google.com    multi_init_base() :
39713513Sgabeblack@google.com        base_type(sc_core::sc_gen_unique_name("multi_init_base"))
39813513Sgabeblack@google.com    {}
39913513Sgabeblack@google.com    multi_init_base(const char *name) : base_type(name) {}
40013513Sgabeblack@google.com
40113513Sgabeblack@google.com  private:
40213513Sgabeblack@google.com    const sc_core::sc_object *get_socket() const { return this; }
40313511Sgabeblack@google.com};
40413511Sgabeblack@google.com
40513511Sgabeblack@google.com/*
40613511Sgabeblack@google.comThis class forms the base for multi target sockets,
40713511Sgabeblack@google.comwith fewer template parameters than the multi_target_base.
40813511Sgabeblack@google.comThis class is implementation-defined.
40913511Sgabeblack@google.com*/
41013513Sgabeblack@google.comtemplate <typename TYPES=tlm::tlm_base_protocol_types>
41113513Sgabeblack@google.comclass multi_target_base_if
41213513Sgabeblack@google.com{
41313513Sgabeblack@google.com  public:
41413513Sgabeblack@google.com    // This method shall return a vector of the callback binders of multi
41513513Sgabeblack@google.com    // initiator socket.
41613513Sgabeblack@google.com    virtual std::vector<callback_binder_fw<TYPES> *> &get_binders() = 0;
41713513Sgabeblack@google.com
41813513Sgabeblack@google.com    // This method shall return a map of all multi initiator sockets that are
41913513Sgabeblack@google.com    // bound to this multi target the key of the map is the index at which the
42013513Sgabeblack@google.com    // multi initiator i bound, while the value is the interface of the multi
42113513Sgabeblack@google.com    // initiator socket that is bound at that index.
42213513Sgabeblack@google.com    virtual std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES>*> &
42313513Sgabeblack@google.com        get_multi_binds() = 0;
42413513Sgabeblack@google.com
42513513Sgabeblack@google.com  protected:
42613513Sgabeblack@google.com    virtual ~multi_target_base_if() {}
42713511Sgabeblack@google.com};
42813511Sgabeblack@google.com
42913511Sgabeblack@google.com/*
43013511Sgabeblack@google.comThis class forms the base for multi target sockets.
43113511Sgabeblack@google.comIt enforces a multi target socket to implement all functions
43213511Sgabeblack@google.comneeded to do hierarchical bindings.
43313511Sgabeblack@google.com*/
43413513Sgabeblack@google.comtemplate <unsigned int BUSWIDTH=32,
43513513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
43613513Sgabeblack@google.com          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
43713513Sgabeblack@google.comclass multi_target_base :
43813513Sgabeblack@google.com    public tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL>,
43913513Sgabeblack@google.com    public multi_target_base_if<TYPES>, protected multi_socket_base
44013511Sgabeblack@google.com{
44113513Sgabeblack@google.com  public:
44213513Sgabeblack@google.com    // Typedef for the base type: the standard tlm target socket.
44313513Sgabeblack@google.com    typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, N, POL > base_type;
44413511Sgabeblack@google.com
44513513Sgabeblack@google.com    // This method shall return the multi_init_base to which the
44613513Sgabeblack@google.com    // multi_init_base is bound hierarchically. If the base is not bound
44713513Sgabeblack@google.com    // hierarchically it shall return a pointer to itself.
44813513Sgabeblack@google.com    virtual multi_target_base *get_hierarch_bind() = 0;
44913511Sgabeblack@google.com
45013513Sgabeblack@google.com    // This method shall inform the multi target socket that it is bound
45113513Sgabeblack@google.com    // hierarchically and to which other multi target socket it is bound
45213513Sgabeblack@google.com    // hierarchically.
45313513Sgabeblack@google.com    virtual void set_hierarch_bind(multi_target_base*) = 0;
45413511Sgabeblack@google.com
45513513Sgabeblack@google.com    virtual tlm::tlm_socket_category
45613513Sgabeblack@google.com    get_socket_category() const
45713513Sgabeblack@google.com    {
45813513Sgabeblack@google.com        return tlm::TLM_MULTI_TARGET_SOCKET;
45913513Sgabeblack@google.com    }
46013513Sgabeblack@google.com
46113513Sgabeblack@google.com    virtual ~multi_target_base() {}
46213513Sgabeblack@google.com    multi_target_base() :
46313513Sgabeblack@google.com        base_type(sc_core::sc_gen_unique_name("multi_target_base"))
46413513Sgabeblack@google.com    {}
46513513Sgabeblack@google.com    multi_target_base(const char *name) : base_type(name) {}
46613513Sgabeblack@google.com
46713513Sgabeblack@google.com  private:
46813513Sgabeblack@google.com    const sc_core::sc_object *get_socket() const { return this; }
46913511Sgabeblack@google.com};
47013511Sgabeblack@google.com
47113511Sgabeblack@google.com/*
47213511Sgabeblack@google.comAll multi sockets must additionally derive from this class.
47313513Sgabeblack@google.comIt enforces a multi socket to implement a function
47413511Sgabeblack@google.comneeded to do multi init to multi target bindings.
47513511Sgabeblack@google.com*/
47613511Sgabeblack@google.comtemplate <typename TYPES>
47713513Sgabeblack@google.comclass multi_to_multi_bind_base
47813513Sgabeblack@google.com{
47913513Sgabeblack@google.com  public:
48013513Sgabeblack@google.com    virtual ~multi_to_multi_bind_base() {}
48113513Sgabeblack@google.com    virtual tlm::tlm_fw_transport_if<TYPES> *
48213513Sgabeblack@google.com        get_last_binder(tlm::tlm_bw_transport_if<TYPES> *) = 0;
48313511Sgabeblack@google.com};
48413511Sgabeblack@google.com
48513511Sgabeblack@google.com} // namespace tlm_utils
48613513Sgabeblack@google.com
48713513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_SOCKET_BASES_H__ */
488