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_PASSTHROUGH_TARGET_SOCKET_H__
2113513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H__
2213511Sgabeblack@google.com
2313586Sgabeblack@google.com#include "../core/sc_port.hh"
2413586Sgabeblack@google.com#include "../core/sc_time.hh"
2513586Sgabeblack@google.com#include "../tlm_core/2/sockets/target_socket.hh"
2613586Sgabeblack@google.com#include "../utils/sc_report_handler.hh"
2713586Sgabeblack@google.com#include "convenience_socket_bases.h"
2813511Sgabeblack@google.com
2913513Sgabeblack@google.comnamespace tlm_utils
3013513Sgabeblack@google.com{
3113511Sgabeblack@google.com
3213513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
3313513Sgabeblack@google.com          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
3413513Sgabeblack@google.comclass passthrough_target_socket_b :
3513513Sgabeblack@google.com    public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
3613513Sgabeblack@google.com    protected passthrough_socket_base
3713511Sgabeblack@google.com{
3813513Sgabeblack@google.com  public:
3913513Sgabeblack@google.com    typedef typename TYPES::tlm_payload_type transaction_type;
4013513Sgabeblack@google.com    typedef typename TYPES::tlm_phase_type phase_type;
4113513Sgabeblack@google.com    typedef tlm::tlm_sync_enum sync_enum_type;
4213513Sgabeblack@google.com    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
4313513Sgabeblack@google.com    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
4413513Sgabeblack@google.com    typedef tlm::tlm_target_socket<BUSWIDTH,TYPES,1,POL> base_type;
4513511Sgabeblack@google.com
4613511Sgabeblack@google.com  public:
4713513Sgabeblack@google.com    static const char *
4813513Sgabeblack@google.com    default_name()
4913511Sgabeblack@google.com    {
5013513Sgabeblack@google.com        return sc_core::sc_gen_unique_name("passthrough_target_socket");
5113511Sgabeblack@google.com    }
5213511Sgabeblack@google.com
5313513Sgabeblack@google.com    explicit passthrough_target_socket_b(const char *n=default_name()) :
5413513Sgabeblack@google.com        base_type(n), m_process(this)
5513511Sgabeblack@google.com    {
5613513Sgabeblack@google.com        bind(m_process);
5713511Sgabeblack@google.com    }
5813511Sgabeblack@google.com
5913513Sgabeblack@google.com    using base_type::bind;
6013513Sgabeblack@google.com
6113513Sgabeblack@google.com    // REGISTER_XXX
6213513Sgabeblack@google.com    void
6313513Sgabeblack@google.com    register_nb_transport_fw(MODULE *mod,
6413513Sgabeblack@google.com            sync_enum_type (MODULE::*cb)(transaction_type &, phase_type &,
6513513Sgabeblack@google.com                sc_core::sc_time &))
6613511Sgabeblack@google.com    {
6713513Sgabeblack@google.com        m_process.set_nb_transport_ptr(mod, cb);
6813511Sgabeblack@google.com    }
6913511Sgabeblack@google.com
7013513Sgabeblack@google.com    void
7113513Sgabeblack@google.com    register_b_transport(MODULE *mod,
7213513Sgabeblack@google.com            void (MODULE::*cb)(transaction_type &, sc_core::sc_time &))
7313511Sgabeblack@google.com    {
7413513Sgabeblack@google.com        m_process.set_b_transport_ptr(mod, cb);
7513511Sgabeblack@google.com    }
7613511Sgabeblack@google.com
7713513Sgabeblack@google.com    void
7813513Sgabeblack@google.com    register_transport_dbg(MODULE *mod,
7913513Sgabeblack@google.com            unsigned int (MODULE::*cb)(transaction_type &))
8013511Sgabeblack@google.com    {
8113513Sgabeblack@google.com        m_process.set_transport_dbg_ptr(mod, cb);
8213511Sgabeblack@google.com    }
8313511Sgabeblack@google.com
8413513Sgabeblack@google.com    void
8513513Sgabeblack@google.com    register_get_direct_mem_ptr(MODULE *mod,
8613513Sgabeblack@google.com            bool (MODULE::*cb)(transaction_type &, tlm::tlm_dmi &))
8713511Sgabeblack@google.com    {
8813513Sgabeblack@google.com        m_process.set_get_direct_mem_ptr(mod, cb);
8913511Sgabeblack@google.com    }
9013511Sgabeblack@google.com
9113511Sgabeblack@google.com  private:
9213513Sgabeblack@google.com    class process : public tlm::tlm_fw_transport_if<TYPES>,
9313513Sgabeblack@google.com                    protected convenience_socket_cb_holder
9413513Sgabeblack@google.com    {
9513513Sgabeblack@google.com      public:
9613513Sgabeblack@google.com        typedef sync_enum_type (MODULE::*NBTransportPtr)(
9713513Sgabeblack@google.com                transaction_type &, phase_type &, sc_core::sc_time &);
9813513Sgabeblack@google.com        typedef void (MODULE::*BTransportPtr)(
9913513Sgabeblack@google.com                transaction_type &, sc_core::sc_time &);
10013513Sgabeblack@google.com        typedef unsigned int (MODULE::*TransportDbgPtr)(transaction_type &);
10113513Sgabeblack@google.com        typedef bool (MODULE::*GetDirectMem_ptr)(
10213513Sgabeblack@google.com                transaction_type &, tlm::tlm_dmi &);
10313511Sgabeblack@google.com
10413513Sgabeblack@google.com        explicit process(passthrough_socket_base *owner) :
10513513Sgabeblack@google.com            convenience_socket_cb_holder(owner), m_mod(0),
10613513Sgabeblack@google.com            m_nb_transport_ptr(0), m_b_transport_ptr(0),
10713513Sgabeblack@google.com            m_transport_dbg_ptr(0), m_get_direct_mem_ptr(0)
10813513Sgabeblack@google.com        {}
10913513Sgabeblack@google.com
11013513Sgabeblack@google.com        void
11113513Sgabeblack@google.com        set_nb_transport_ptr(MODULE *mod, NBTransportPtr p)
11213513Sgabeblack@google.com        {
11313513Sgabeblack@google.com            if (m_nb_transport_ptr) {
11413513Sgabeblack@google.com                display_warning("non-blocking callback already registered");
11513513Sgabeblack@google.com                return;
11613513Sgabeblack@google.com            }
11713513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
11813513Sgabeblack@google.com            m_mod = mod;
11913513Sgabeblack@google.com            m_nb_transport_ptr = p;
12013513Sgabeblack@google.com        }
12113513Sgabeblack@google.com
12213513Sgabeblack@google.com        void
12313513Sgabeblack@google.com        set_b_transport_ptr(MODULE *mod, BTransportPtr p)
12413513Sgabeblack@google.com        {
12513513Sgabeblack@google.com            if (m_b_transport_ptr) {
12613513Sgabeblack@google.com                display_warning("blocking callback already registered");
12713513Sgabeblack@google.com                return;
12813513Sgabeblack@google.com            }
12913513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
13013513Sgabeblack@google.com            m_mod = mod;
13113513Sgabeblack@google.com            m_b_transport_ptr = p;
13213513Sgabeblack@google.com        }
13313513Sgabeblack@google.com
13413513Sgabeblack@google.com        void
13513513Sgabeblack@google.com        set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
13613513Sgabeblack@google.com        {
13713513Sgabeblack@google.com            if (m_transport_dbg_ptr) {
13813513Sgabeblack@google.com                display_warning("debug callback already registered");
13913513Sgabeblack@google.com                return;
14013513Sgabeblack@google.com            }
14113513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
14213513Sgabeblack@google.com            m_mod = mod;
14313513Sgabeblack@google.com            m_transport_dbg_ptr = p;
14413513Sgabeblack@google.com        }
14513513Sgabeblack@google.com
14613513Sgabeblack@google.com        void
14713513Sgabeblack@google.com        set_get_direct_mem_ptr(MODULE *mod, GetDirectMem_ptr p)
14813513Sgabeblack@google.com        {
14913513Sgabeblack@google.com            if (m_get_direct_mem_ptr) {
15013513Sgabeblack@google.com                display_warning(
15113513Sgabeblack@google.com                        "get DMI pointer callback already registered");
15213513Sgabeblack@google.com                return;
15313513Sgabeblack@google.com            }
15413513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
15513513Sgabeblack@google.com            m_mod = mod;
15613513Sgabeblack@google.com            m_get_direct_mem_ptr = p;
15713513Sgabeblack@google.com        }
15813513Sgabeblack@google.com
15913513Sgabeblack@google.com        sync_enum_type nb_transport_fw(
16013513Sgabeblack@google.com                transaction_type &trans, phase_type &phase,
16113513Sgabeblack@google.com                sc_core::sc_time &t)
16213513Sgabeblack@google.com        {
16313513Sgabeblack@google.com            if (m_nb_transport_ptr) {
16413513Sgabeblack@google.com                // Forward call.
16513513Sgabeblack@google.com                sc_assert(m_mod);
16613513Sgabeblack@google.com                return (m_mod->*m_nb_transport_ptr)(trans, phase, t);
16713513Sgabeblack@google.com            }
16813513Sgabeblack@google.com            display_error("no non-blocking callback registered");
16913513Sgabeblack@google.com            return tlm::TLM_COMPLETED;
17013513Sgabeblack@google.com        }
17113513Sgabeblack@google.com
17213513Sgabeblack@google.com        void
17313513Sgabeblack@google.com        b_transport(transaction_type &trans, sc_core::sc_time &t)
17413513Sgabeblack@google.com        {
17513513Sgabeblack@google.com            if (m_b_transport_ptr) {
17613513Sgabeblack@google.com                // Forward call.
17713513Sgabeblack@google.com                sc_assert(m_mod);
17813513Sgabeblack@google.com                return (m_mod->*m_b_transport_ptr)(trans, t);
17913513Sgabeblack@google.com            }
18013513Sgabeblack@google.com            display_error("no blocking callback registered");
18113513Sgabeblack@google.com        }
18213513Sgabeblack@google.com
18313513Sgabeblack@google.com        unsigned int
18413513Sgabeblack@google.com        transport_dbg(transaction_type &trans)
18513513Sgabeblack@google.com        {
18613513Sgabeblack@google.com            if (m_transport_dbg_ptr) {
18713513Sgabeblack@google.com                // Forward call.
18813513Sgabeblack@google.com                sc_assert(m_mod);
18913513Sgabeblack@google.com                return (m_mod->*m_transport_dbg_ptr)(trans);
19013513Sgabeblack@google.com            }
19113513Sgabeblack@google.com            // No debug support
19213513Sgabeblack@google.com            return 0;
19313513Sgabeblack@google.com        }
19413513Sgabeblack@google.com
19513513Sgabeblack@google.com        bool
19613513Sgabeblack@google.com        get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
19713513Sgabeblack@google.com        {
19813513Sgabeblack@google.com            if (m_get_direct_mem_ptr) {
19913513Sgabeblack@google.com                // Forward call.
20013513Sgabeblack@google.com                sc_assert(m_mod);
20113513Sgabeblack@google.com                return (m_mod->*m_get_direct_mem_ptr)(trans, dmi_data);
20213513Sgabeblack@google.com            }
20313513Sgabeblack@google.com            // No DMI support
20413513Sgabeblack@google.com            dmi_data.allow_read_write();
20513513Sgabeblack@google.com            dmi_data.set_start_address(0x0);
20613513Sgabeblack@google.com            dmi_data.set_end_address((sc_dt::uint64)-1);
20713513Sgabeblack@google.com            return false;
20813513Sgabeblack@google.com        }
20913513Sgabeblack@google.com
21013513Sgabeblack@google.com      private:
21113513Sgabeblack@google.com        MODULE *m_mod;
21213513Sgabeblack@google.com        NBTransportPtr m_nb_transport_ptr;
21313513Sgabeblack@google.com        BTransportPtr m_b_transport_ptr;
21413513Sgabeblack@google.com        TransportDbgPtr m_transport_dbg_ptr;
21513513Sgabeblack@google.com        GetDirectMem_ptr m_get_direct_mem_ptr;
21613513Sgabeblack@google.com    };
21713513Sgabeblack@google.com
21813513Sgabeblack@google.com  private:
21913513Sgabeblack@google.com    const sc_core::sc_object *get_socket() const { return this; }
22013513Sgabeblack@google.com
22113513Sgabeblack@google.com  private:
22213513Sgabeblack@google.com    process m_process;
22313511Sgabeblack@google.com};
22413511Sgabeblack@google.com
22513513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
22613513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types>
22713513Sgabeblack@google.comclass passthrough_target_socket :
22813513Sgabeblack@google.com    public passthrough_target_socket_b<MODULE, BUSWIDTH, TYPES>
22913511Sgabeblack@google.com{
23013513Sgabeblack@google.com    typedef passthrough_target_socket_b<MODULE, BUSWIDTH, TYPES> socket_b;
23113513Sgabeblack@google.com  public:
23213513Sgabeblack@google.com    passthrough_target_socket() : socket_b() {}
23313513Sgabeblack@google.com    explicit passthrough_target_socket(const char *name) : socket_b(name) {}
23413511Sgabeblack@google.com};
23513511Sgabeblack@google.com
23613513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
23713513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types>
23813513Sgabeblack@google.comclass passthrough_target_socket_optional :
23913513Sgabeblack@google.com    public passthrough_target_socket_b<
24013513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
24113511Sgabeblack@google.com{
24213513Sgabeblack@google.com    typedef passthrough_target_socket_b<
24313513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
24413513Sgabeblack@google.com  public:
24513513Sgabeblack@google.com    passthrough_target_socket_optional() : socket_b() {}
24613513Sgabeblack@google.com    explicit passthrough_target_socket_optional(const char *name) :
24713513Sgabeblack@google.com        socket_b(name) {}
24813511Sgabeblack@google.com};
24913511Sgabeblack@google.com
25013513Sgabeblack@google.com// ID Tagged version
25113513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH, typename TYPES,
25213513Sgabeblack@google.com          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
25313513Sgabeblack@google.comclass passthrough_target_socket_tagged_b :
25413513Sgabeblack@google.com    public tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL>,
25513513Sgabeblack@google.com    protected passthrough_socket_base
25613511Sgabeblack@google.com{
25713513Sgabeblack@google.com  public:
25813513Sgabeblack@google.com    typedef typename TYPES::tlm_payload_type transaction_type;
25913513Sgabeblack@google.com    typedef typename TYPES::tlm_phase_type phase_type;
26013513Sgabeblack@google.com    typedef tlm::tlm_sync_enum sync_enum_type;
26113513Sgabeblack@google.com    typedef tlm::tlm_fw_transport_if<TYPES> fw_interface_type;
26213513Sgabeblack@google.com    typedef tlm::tlm_bw_transport_if<TYPES> bw_interface_type;
26313513Sgabeblack@google.com    typedef tlm::tlm_target_socket<BUSWIDTH, TYPES, 1, POL> base_type;
26413511Sgabeblack@google.com
26513513Sgabeblack@google.com    static const char *
26613513Sgabeblack@google.com    default_name()
26713511Sgabeblack@google.com    {
26813513Sgabeblack@google.com        return sc_core::sc_gen_unique_name(
26913513Sgabeblack@google.com                "passthrough_target_socket_tagged");
27013511Sgabeblack@google.com    }
27113511Sgabeblack@google.com
27213513Sgabeblack@google.com  public:
27313513Sgabeblack@google.com    explicit passthrough_target_socket_tagged_b(
27413513Sgabeblack@google.com            const char *n=default_name()) : base_type(n), m_process(this)
27513511Sgabeblack@google.com    {
27613513Sgabeblack@google.com        bind(m_process);
27713511Sgabeblack@google.com    }
27813511Sgabeblack@google.com
27913513Sgabeblack@google.com    using base_type::bind;
28013513Sgabeblack@google.com
28113513Sgabeblack@google.com    // REGISTER_XXX
28213513Sgabeblack@google.com    void
28313513Sgabeblack@google.com    register_nb_transport_fw(MODULE *mod,
28413513Sgabeblack@google.com            sync_enum_type (MODULE::*cb)(int id, transaction_type &,
28513513Sgabeblack@google.com                                         phase_type &, sc_core::sc_time &),
28613513Sgabeblack@google.com            int id)
28713511Sgabeblack@google.com    {
28813513Sgabeblack@google.com        m_process.set_nb_transport_ptr(mod, cb);
28913513Sgabeblack@google.com        m_process.set_nb_transport_user_id(id);
29013511Sgabeblack@google.com    }
29113511Sgabeblack@google.com
29213513Sgabeblack@google.com    void
29313513Sgabeblack@google.com    register_b_transport(MODULE *mod,
29413513Sgabeblack@google.com            void (MODULE::*cb)(int id, transaction_type &,
29513513Sgabeblack@google.com                sc_core::sc_time &),
29613513Sgabeblack@google.com            int id)
29713511Sgabeblack@google.com    {
29813513Sgabeblack@google.com        m_process.set_b_transport_ptr(mod, cb);
29913513Sgabeblack@google.com        m_process.set_b_transport_user_id(id);
30013511Sgabeblack@google.com    }
30113511Sgabeblack@google.com
30213513Sgabeblack@google.com    void
30313513Sgabeblack@google.com    register_transport_dbg(MODULE *mod,
30413513Sgabeblack@google.com            unsigned int (MODULE::*cb)(int id, transaction_type &), int id)
30513511Sgabeblack@google.com    {
30613513Sgabeblack@google.com        m_process.set_transport_dbg_ptr(mod, cb);
30713513Sgabeblack@google.com        m_process.set_transport_dbg_user_id(id);
30813511Sgabeblack@google.com    }
30913511Sgabeblack@google.com
31013513Sgabeblack@google.com    void
31113513Sgabeblack@google.com    register_get_direct_mem_ptr(MODULE *mod,
31213513Sgabeblack@google.com            bool (MODULE::*cb)(int id, transaction_type &, tlm::tlm_dmi &),
31313513Sgabeblack@google.com            int id)
31413511Sgabeblack@google.com    {
31513513Sgabeblack@google.com        m_process.set_get_direct_mem_ptr(mod, cb);
31613513Sgabeblack@google.com        m_process.set_get_dmi_user_id(id);
31713511Sgabeblack@google.com    }
31813511Sgabeblack@google.com
31913511Sgabeblack@google.com  private:
32013513Sgabeblack@google.com    class process : public tlm::tlm_fw_transport_if<TYPES>,
32113513Sgabeblack@google.com                    protected convenience_socket_cb_holder
32213513Sgabeblack@google.com    {
32313513Sgabeblack@google.com      public:
32413513Sgabeblack@google.com        typedef sync_enum_type (MODULE::*NBTransportPtr)(
32513513Sgabeblack@google.com                int id, transaction_type &, phase_type &, sc_core::sc_time &);
32613513Sgabeblack@google.com        typedef void (MODULE::*BTransportPtr)(
32713513Sgabeblack@google.com                int id, transaction_type &, sc_core::sc_time &);
32813513Sgabeblack@google.com        typedef unsigned int (MODULE::*TransportDbgPtr)(
32913513Sgabeblack@google.com                int id, transaction_type &);
33013513Sgabeblack@google.com        typedef bool (MODULE::*GetDirectMem_ptr)(
33113513Sgabeblack@google.com                int id, transaction_type &, tlm::tlm_dmi &);
33213511Sgabeblack@google.com
33313513Sgabeblack@google.com        process(passthrough_socket_base *owner) :
33413513Sgabeblack@google.com            convenience_socket_cb_holder(owner), m_mod(0),
33513513Sgabeblack@google.com            m_nb_transport_ptr(0), m_b_transport_ptr(0),
33613513Sgabeblack@google.com            m_transport_dbg_ptr(0), m_get_direct_mem_ptr(0),
33713513Sgabeblack@google.com            m_nb_transport_user_id(0), m_b_transport_user_id(0),
33813513Sgabeblack@google.com            m_transport_dbg_user_id(0), m_get_dmi_user_id(0)
33913513Sgabeblack@google.com        {}
34013513Sgabeblack@google.com
34113513Sgabeblack@google.com        void
34213513Sgabeblack@google.com        set_nb_transport_user_id(int id)
34313513Sgabeblack@google.com        {
34413513Sgabeblack@google.com            m_nb_transport_user_id = id;
34513513Sgabeblack@google.com        }
34613513Sgabeblack@google.com        void
34713513Sgabeblack@google.com        set_b_transport_user_id(int id)
34813513Sgabeblack@google.com        {
34913513Sgabeblack@google.com            m_b_transport_user_id = id;
35013513Sgabeblack@google.com        }
35113513Sgabeblack@google.com        void
35213513Sgabeblack@google.com        set_transport_dbg_user_id(int id)
35313513Sgabeblack@google.com        {
35413513Sgabeblack@google.com            m_transport_dbg_user_id = id;
35513513Sgabeblack@google.com        }
35613513Sgabeblack@google.com        void
35713513Sgabeblack@google.com        set_get_dmi_user_id(int id)
35813513Sgabeblack@google.com        {
35913513Sgabeblack@google.com            m_get_dmi_user_id = id;
36013513Sgabeblack@google.com        }
36113513Sgabeblack@google.com
36213513Sgabeblack@google.com        void
36313513Sgabeblack@google.com        set_nb_transport_ptr(MODULE *mod, NBTransportPtr p)
36413513Sgabeblack@google.com        {
36513513Sgabeblack@google.com            if (m_nb_transport_ptr) {
36613513Sgabeblack@google.com                display_warning("non-blocking callback already registered");
36713513Sgabeblack@google.com                return;
36813513Sgabeblack@google.com            }
36913513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
37013513Sgabeblack@google.com            m_mod = mod;
37113513Sgabeblack@google.com            m_nb_transport_ptr = p;
37213513Sgabeblack@google.com        }
37313513Sgabeblack@google.com
37413513Sgabeblack@google.com        void
37513513Sgabeblack@google.com        set_b_transport_ptr(MODULE *mod, BTransportPtr p)
37613513Sgabeblack@google.com        {
37713513Sgabeblack@google.com            if (m_b_transport_ptr) {
37813513Sgabeblack@google.com                display_warning("blocking callback already registered");
37913513Sgabeblack@google.com                return;
38013513Sgabeblack@google.com            }
38113513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
38213513Sgabeblack@google.com            m_mod = mod;
38313513Sgabeblack@google.com            m_b_transport_ptr = p;
38413513Sgabeblack@google.com        }
38513513Sgabeblack@google.com
38613513Sgabeblack@google.com        void
38713513Sgabeblack@google.com        set_transport_dbg_ptr(MODULE *mod, TransportDbgPtr p)
38813513Sgabeblack@google.com        {
38913513Sgabeblack@google.com            if (m_transport_dbg_ptr) {
39013513Sgabeblack@google.com                display_warning("debug callback already registered");
39113513Sgabeblack@google.com                return;
39213513Sgabeblack@google.com            }
39313513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
39413513Sgabeblack@google.com            m_mod = mod;
39513513Sgabeblack@google.com            m_transport_dbg_ptr = p;
39613513Sgabeblack@google.com        }
39713513Sgabeblack@google.com
39813513Sgabeblack@google.com        void
39913513Sgabeblack@google.com        set_get_direct_mem_ptr(MODULE *mod, GetDirectMem_ptr p)
40013513Sgabeblack@google.com        {
40113513Sgabeblack@google.com            if (m_get_direct_mem_ptr) {
40213513Sgabeblack@google.com                display_warning(
40313513Sgabeblack@google.com                        "get DMI pointer callback already registered");
40413513Sgabeblack@google.com                return;
40513513Sgabeblack@google.com            }
40613513Sgabeblack@google.com            sc_assert(!m_mod || m_mod == mod);
40713513Sgabeblack@google.com            m_mod = mod;
40813513Sgabeblack@google.com            m_get_direct_mem_ptr = p;
40913513Sgabeblack@google.com        }
41013513Sgabeblack@google.com
41113513Sgabeblack@google.com        sync_enum_type
41213513Sgabeblack@google.com        nb_transport_fw(transaction_type &trans, phase_type &phase,
41313513Sgabeblack@google.com                sc_core::sc_time &t)
41413513Sgabeblack@google.com        {
41513513Sgabeblack@google.com            if (m_nb_transport_ptr) {
41613513Sgabeblack@google.com                // Forward call.
41713513Sgabeblack@google.com                sc_assert(m_mod);
41813513Sgabeblack@google.com                return (m_mod->*m_nb_transport_ptr)(
41913513Sgabeblack@google.com                        m_nb_transport_user_id, trans, phase, t);
42013513Sgabeblack@google.com            }
42113513Sgabeblack@google.com            display_error("no non-blocking callback registered");
42213513Sgabeblack@google.com            return tlm::TLM_COMPLETED;
42313513Sgabeblack@google.com        }
42413513Sgabeblack@google.com
42513513Sgabeblack@google.com        void
42613513Sgabeblack@google.com        b_transport(transaction_type &trans, sc_core::sc_time &t)
42713513Sgabeblack@google.com        {
42813513Sgabeblack@google.com            if (m_b_transport_ptr) {
42913513Sgabeblack@google.com                // Forward call.
43013513Sgabeblack@google.com                sc_assert(m_mod);
43113513Sgabeblack@google.com                return (m_mod->*m_b_transport_ptr)(
43213513Sgabeblack@google.com                        m_b_transport_user_id, trans, t);
43313513Sgabeblack@google.com            }
43413513Sgabeblack@google.com            display_error("no blocking callback registered");
43513513Sgabeblack@google.com        }
43613513Sgabeblack@google.com
43713513Sgabeblack@google.com        unsigned int
43813513Sgabeblack@google.com        transport_dbg(transaction_type &trans)
43913513Sgabeblack@google.com        {
44013513Sgabeblack@google.com            if (m_transport_dbg_ptr) {
44113513Sgabeblack@google.com                // Forward call.
44213513Sgabeblack@google.com                sc_assert(m_mod);
44313513Sgabeblack@google.com                return (m_mod->*m_transport_dbg_ptr)(
44413513Sgabeblack@google.com                        m_transport_dbg_user_id, trans);
44513513Sgabeblack@google.com            }
44613513Sgabeblack@google.com            // No debug support.
44713513Sgabeblack@google.com            return 0;
44813513Sgabeblack@google.com        }
44913513Sgabeblack@google.com
45013513Sgabeblack@google.com        bool
45113513Sgabeblack@google.com        get_direct_mem_ptr(transaction_type &trans, tlm::tlm_dmi &dmi_data)
45213513Sgabeblack@google.com        {
45313513Sgabeblack@google.com            if (m_get_direct_mem_ptr) {
45413513Sgabeblack@google.com                // Forward call.
45513513Sgabeblack@google.com                sc_assert(m_mod);
45613513Sgabeblack@google.com                return (m_mod->*m_get_direct_mem_ptr)(
45713513Sgabeblack@google.com                        m_get_dmi_user_id, trans, dmi_data);
45813513Sgabeblack@google.com            }
45913513Sgabeblack@google.com            // No DMI support
46013513Sgabeblack@google.com            dmi_data.allow_read_write();
46113513Sgabeblack@google.com            dmi_data.set_start_address(0x0);
46213513Sgabeblack@google.com            dmi_data.set_end_address((sc_dt::uint64)-1);
46313513Sgabeblack@google.com            return false;
46413513Sgabeblack@google.com        }
46513513Sgabeblack@google.com
46613513Sgabeblack@google.com      private:
46713513Sgabeblack@google.com        MODULE *m_mod;
46813513Sgabeblack@google.com        NBTransportPtr m_nb_transport_ptr;
46913513Sgabeblack@google.com        BTransportPtr m_b_transport_ptr;
47013513Sgabeblack@google.com        TransportDbgPtr m_transport_dbg_ptr;
47113513Sgabeblack@google.com        GetDirectMem_ptr m_get_direct_mem_ptr;
47213513Sgabeblack@google.com        int m_nb_transport_user_id;
47313513Sgabeblack@google.com        int m_b_transport_user_id;
47413513Sgabeblack@google.com        int m_transport_dbg_user_id;
47513513Sgabeblack@google.com        int m_get_dmi_user_id;
47613513Sgabeblack@google.com    };
47713513Sgabeblack@google.com
47813513Sgabeblack@google.com  private:
47913513Sgabeblack@google.com    const sc_core::sc_object *get_socket() const { return this; }
48013513Sgabeblack@google.com
48113513Sgabeblack@google.com  private:
48213513Sgabeblack@google.com    process m_process;
48313511Sgabeblack@google.com};
48413511Sgabeblack@google.com
48513513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
48613513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types>
48713513Sgabeblack@google.comclass passthrough_target_socket_tagged :
48813513Sgabeblack@google.com    public passthrough_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
48913511Sgabeblack@google.com{
49013513Sgabeblack@google.com    typedef passthrough_target_socket_tagged_b<MODULE, BUSWIDTH, TYPES>
49113513Sgabeblack@google.com        socket_b;
49213513Sgabeblack@google.com  public:
49313513Sgabeblack@google.com    passthrough_target_socket_tagged() : socket_b() {}
49413513Sgabeblack@google.com    explicit passthrough_target_socket_tagged(const char *name) :
49513513Sgabeblack@google.com        socket_b(name)
49613513Sgabeblack@google.com    {}
49713511Sgabeblack@google.com};
49813511Sgabeblack@google.com
49913513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
50013513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types>
50113513Sgabeblack@google.comclass passthrough_target_socket_tagged_optional :
50213513Sgabeblack@google.com    public passthrough_target_socket_tagged_b<
50313513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND>
50413511Sgabeblack@google.com{
50513513Sgabeblack@google.com    typedef passthrough_target_socket_tagged_b<
50613513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
50713513Sgabeblack@google.com  public:
50813513Sgabeblack@google.com    passthrough_target_socket_tagged_optional() : socket_b() {}
50913513Sgabeblack@google.com    explicit passthrough_target_socket_tagged_optional(const char *name) :
51013513Sgabeblack@google.com        socket_b(name)
51113513Sgabeblack@google.com    {}
51213511Sgabeblack@google.com};
51313511Sgabeblack@google.com
51413511Sgabeblack@google.com} // namespace tlm_utils
51513513Sgabeblack@google.com
51613513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_PASSTHROUGH_TARGET_SOCKET_H__ */
517