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 *****************************************************************************/
1913513Sgabeblack@google.com#ifndef __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__
2013513Sgabeblack@google.com#define __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__
2113511Sgabeblack@google.com
2213586Sgabeblack@google.com#include "../core/sc_module.hh"
2313586Sgabeblack@google.com#include "../core/sc_port.hh"
2413586Sgabeblack@google.com#include "multi_socket_bases.h"
2513511Sgabeblack@google.com
2613513Sgabeblack@google.comnamespace tlm_utils
2713513Sgabeblack@google.com{
2813511Sgabeblack@google.com
2913511Sgabeblack@google.com/*
3013511Sgabeblack@google.comThis class implements a trivial multi target socket.
3113511Sgabeblack@google.comThe triviality refers to the fact that the socket does not
3213511Sgabeblack@google.comdo blocking to non-blocking or non-blocking to blocking conversions.
3313511Sgabeblack@google.com
3413511Sgabeblack@google.comIt allows to connect multiple initiators to this socket.
3513511Sgabeblack@google.comThe user has to register callbacks for the fw interface methods
3613511Sgabeblack@google.comhe likes to use. The callbacks are basically equal to the fw interface
3713511Sgabeblack@google.commethods but carry an additional integer that indicates to which
3813511Sgabeblack@google.comindex of this socket the calling initiator is connected.
3913511Sgabeblack@google.com*/
4013513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
4113513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0,
4213513Sgabeblack@google.com          sc_core::sc_port_policy POL=sc_core::SC_ONE_OR_MORE_BOUND>
4313513Sgabeblack@google.comclass multi_passthrough_target_socket :
4413513Sgabeblack@google.com    public multi_target_base< BUSWIDTH, TYPES, N, POL>,
4513513Sgabeblack@google.com    public multi_to_multi_bind_base<TYPES>
4613511Sgabeblack@google.com{
4713513Sgabeblack@google.com  public:
4813513Sgabeblack@google.com    //typedefs
4913513Sgabeblack@google.com    //  tlm 2.0 types for nb_transport
5013513Sgabeblack@google.com    typedef typename TYPES::tlm_payload_type transaction_type;
5113513Sgabeblack@google.com    typedef typename TYPES::tlm_phase_type phase_type;
5213513Sgabeblack@google.com    typedef tlm::tlm_sync_enum sync_enum_type;
5313511Sgabeblack@google.com
5413513Sgabeblack@google.com    //  typedefs to keep the fn ptr notations short
5513513Sgabeblack@google.com    typedef sync_enum_type (MODULE::*nb_cb)(
5613513Sgabeblack@google.com            int, transaction_type &, phase_type &, sc_core::sc_time &);
5713513Sgabeblack@google.com    typedef void (MODULE::*b_cb)(int, transaction_type &, sc_core::sc_time &);
5813513Sgabeblack@google.com    typedef unsigned int (MODULE::*dbg_cb)(int, transaction_type &txn);
5913513Sgabeblack@google.com    typedef bool (MODULE::*dmi_cb)(
6013513Sgabeblack@google.com            int, transaction_type &txn, tlm::tlm_dmi &dmi);
6113511Sgabeblack@google.com
6213513Sgabeblack@google.com    typedef multi_target_base<BUSWIDTH, TYPES, N, POL> base_type;
6313511Sgabeblack@google.com
6413513Sgabeblack@google.com    typedef typename base_type::base_initiator_socket_type
6513513Sgabeblack@google.com        base_initiator_socket_type;
6613511Sgabeblack@google.com
6713513Sgabeblack@google.com    static const char *
6813513Sgabeblack@google.com    default_name()
6913511Sgabeblack@google.com    {
7013513Sgabeblack@google.com        return sc_core::sc_gen_unique_name("multi_passthrough_target_socket");
7113511Sgabeblack@google.com    }
7213511Sgabeblack@google.com
7313513Sgabeblack@google.com    explicit multi_passthrough_target_socket(const char *name=default_name()) :
7413513Sgabeblack@google.com        base_type(name), m_hierarch_bind(0), m_eoe_disabled(false),
7513513Sgabeblack@google.com        m_export_callback_created(false)
7613513Sgabeblack@google.com    {}
7713511Sgabeblack@google.com
7813513Sgabeblack@google.com    ~multi_passthrough_target_socket()
7913513Sgabeblack@google.com    {
8013513Sgabeblack@google.com        // Clean up everything allocated by 'new'.
8113513Sgabeblack@google.com        for (unsigned int i = 0; i < m_binders.size(); i++)
8213513Sgabeblack@google.com            delete m_binders[i];
8313511Sgabeblack@google.com    }
8413511Sgabeblack@google.com
8513513Sgabeblack@google.com    void
8613513Sgabeblack@google.com    check_export_binding()
8713513Sgabeblack@google.com    {
8813513Sgabeblack@google.com        // If our export hasn't been bound yet (due to a hierarch binding)
8913513Sgabeblack@google.com        // we bind it now. We do that here as the user of the target port HAS
9013513Sgabeblack@google.com        // to bind at least on callback, otherwise the socket was useless.
9113513Sgabeblack@google.com        // Nevertheless, the target socket may still stay unbound afterwards.
9213513Sgabeblack@google.com        if (!sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>>::
9313513Sgabeblack@google.com                get_interface()) {
9413513Sgabeblack@google.com            // We bind to a callback_binder that will be used as the first
9513513Sgabeblack@google.com            // interface i.e. calls to the sc_export will have the same ID as
9613513Sgabeblack@google.com            // calls from the first initator socket bound.
9713513Sgabeblack@google.com            callback_binder_fw<TYPES> *binder;
9813511Sgabeblack@google.com
9913513Sgabeblack@google.com            if (m_binders.size() == 0) {
10013513Sgabeblack@google.com                binder = new callback_binder_fw<TYPES>(
10113513Sgabeblack@google.com                        this, m_binders.size());
10213513Sgabeblack@google.com                m_binders.push_back(binder);
10313513Sgabeblack@google.com                m_export_callback_created = true;
10413513Sgabeblack@google.com            } else {
10513513Sgabeblack@google.com                binder = m_binders[0];
10613513Sgabeblack@google.com            }
10713511Sgabeblack@google.com
10813513Sgabeblack@google.com            sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>>::bind(*binder);
10913513Sgabeblack@google.com        }
11013511Sgabeblack@google.com    }
11113511Sgabeblack@google.com
11213513Sgabeblack@google.com    //register callback for nb transport of fw interface
11313513Sgabeblack@google.com    void
11413513Sgabeblack@google.com    register_nb_transport_fw(MODULE *mod, nb_cb cb)
11513513Sgabeblack@google.com    {
11613513Sgabeblack@google.com        check_export_binding();
11713511Sgabeblack@google.com
11813513Sgabeblack@google.com        // Warn if there already is a callback.
11913513Sgabeblack@google.com        if (m_nb_f.is_valid()) {
12013513Sgabeblack@google.com            display_warning("NBTransport_bw callback already registered.");
12113513Sgabeblack@google.com            return;
12213513Sgabeblack@google.com        }
12313511Sgabeblack@google.com
12413513Sgabeblack@google.com        // Set the functor.
12513513Sgabeblack@google.com        m_nb_f.set_function(mod, cb);
12613511Sgabeblack@google.com    }
12713511Sgabeblack@google.com
12813513Sgabeblack@google.com    // Register callback for b transport of fw interface.
12913513Sgabeblack@google.com    void
13013513Sgabeblack@google.com    register_b_transport(MODULE *mod, b_cb cb)
13113513Sgabeblack@google.com    {
13213513Sgabeblack@google.com        check_export_binding();
13313511Sgabeblack@google.com
13413513Sgabeblack@google.com        // Warn if there already is a callback.
13513513Sgabeblack@google.com        if (m_b_f.is_valid()) {
13613513Sgabeblack@google.com            display_warning("BTransport callback already registered.");
13713513Sgabeblack@google.com            return;
13813513Sgabeblack@google.com        }
13913511Sgabeblack@google.com
14013513Sgabeblack@google.com        // Set the functor.
14113513Sgabeblack@google.com        m_b_f.set_function(mod, cb);
14213511Sgabeblack@google.com    }
14313511Sgabeblack@google.com
14413513Sgabeblack@google.com    // Register callback for debug transport of fw interface.
14513513Sgabeblack@google.com    void
14613513Sgabeblack@google.com    register_transport_dbg(MODULE *mod, dbg_cb cb)
14713513Sgabeblack@google.com    {
14813513Sgabeblack@google.com        check_export_binding();
14913511Sgabeblack@google.com
15013513Sgabeblack@google.com        // Warn if there already is a callback.
15113513Sgabeblack@google.com        if (m_dbg_f.is_valid()) {
15213513Sgabeblack@google.com            display_warning("DebugTransport callback already registered.");
15313513Sgabeblack@google.com            return;
15413513Sgabeblack@google.com        }
15513511Sgabeblack@google.com
15613513Sgabeblack@google.com        // Set the functor.
15713513Sgabeblack@google.com        m_dbg_f.set_function(mod, cb);
15813511Sgabeblack@google.com    }
15913511Sgabeblack@google.com
16013513Sgabeblack@google.com    // Register callback for DMI of fw interface.
16113513Sgabeblack@google.com    void
16213513Sgabeblack@google.com    register_get_direct_mem_ptr(MODULE *mod, dmi_cb cb)
16313513Sgabeblack@google.com    {
16413513Sgabeblack@google.com        check_export_binding();
16513511Sgabeblack@google.com
16613513Sgabeblack@google.com        // Warn if there already is a callback.
16713513Sgabeblack@google.com        if (m_dmi_f.is_valid()) {
16813513Sgabeblack@google.com            display_warning("DMI callback already registered.");
16913513Sgabeblack@google.com            return;
17013513Sgabeblack@google.com        }
17113511Sgabeblack@google.com
17213513Sgabeblack@google.com        // Set the functor.
17313513Sgabeblack@google.com        m_dmi_f.set_function(mod, cb);
17413513Sgabeblack@google.com    }
17513511Sgabeblack@google.com
17613511Sgabeblack@google.com
17713513Sgabeblack@google.com    // Override virtual functions of the tlm_target_socket:
17813513Sgabeblack@google.com    // this function is called whenever an sc_port (as part of a init socket)
17913513Sgabeblack@google.com    // wants to bind to the export of the underlying tlm_target_socket
18013513Sgabeblack@google.com    // At this time a callback binder is created an returned to the sc_port
18113513Sgabeblack@google.com    // of the init socket, so that it binds to the callback binder.
18213513Sgabeblack@google.com    virtual tlm::tlm_fw_transport_if<TYPES> &
18313513Sgabeblack@google.com    get_base_interface()
18413513Sgabeblack@google.com    {
18513513Sgabeblack@google.com        // Error if this socket is already bound hierarchically.
18613513Sgabeblack@google.com        if (m_hierarch_bind)
18713513Sgabeblack@google.com            display_error("Socket already bound hierarchically.");
18813511Sgabeblack@google.com
18913513Sgabeblack@google.com        if (m_export_callback_created) {
19013513Sgabeblack@google.com            // Consume binder created from the callback registration.
19113513Sgabeblack@google.com            m_export_callback_created = false;
19213513Sgabeblack@google.com        } else {
19313513Sgabeblack@google.com            m_binders.push_back(
19413513Sgabeblack@google.com                    new callback_binder_fw<TYPES>(this, m_binders.size()));
19513513Sgabeblack@google.com        }
19613511Sgabeblack@google.com
19713513Sgabeblack@google.com        return *m_binders[m_binders.size()-1];
19813513Sgabeblack@google.com    }
19913511Sgabeblack@google.com
20013513Sgabeblack@google.com    // Const overload not allowed for multi-sockets.
20113513Sgabeblack@google.com    virtual const tlm::tlm_fw_transport_if<TYPES> &
20213513Sgabeblack@google.com    get_base_interface() const
20313513Sgabeblack@google.com    {
20413513Sgabeblack@google.com        display_error("'get_base_interface() const'"
20513513Sgabeblack@google.com                " not allowed for multi-sockets.");
20613513Sgabeblack@google.com        return base_type::get_base_interface();
20713513Sgabeblack@google.com    }
20813511Sgabeblack@google.com
20913513Sgabeblack@google.com    // Just return the export of the underlying tlm_target_socket in case of
21013513Sgabeblack@google.com    // a hierarchical bind.
21113513Sgabeblack@google.com    virtual sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>> &
21213513Sgabeblack@google.com    get_base_export()
21313513Sgabeblack@google.com    {
21413513Sgabeblack@google.com        return *this;
21513513Sgabeblack@google.com    }
21613511Sgabeblack@google.com
21713513Sgabeblack@google.com    // Just return the export of the underlying tlm_target_socket in case of
21813513Sgabeblack@google.com    // a hierarchical bind.
21913513Sgabeblack@google.com    virtual const sc_core::sc_export<tlm::tlm_fw_transport_if<TYPES>> &
22013513Sgabeblack@google.com    get_base_export() const
22113513Sgabeblack@google.com    {
22213513Sgabeblack@google.com        return base_type::get_base_export();
22313513Sgabeblack@google.com    }
22413511Sgabeblack@google.com
22513513Sgabeblack@google.com    // The standard end of elaboration callback.
22613513Sgabeblack@google.com    void
22713513Sgabeblack@google.com    end_of_elaboration()
22813513Sgabeblack@google.com    {
22913513Sgabeblack@google.com        // 'break' here if the socket was told not to do callback binding.
23013513Sgabeblack@google.com        if (m_eoe_disabled)
23113513Sgabeblack@google.com            return;
23213513Sgabeblack@google.com
23313513Sgabeblack@google.com        // Get the callback binders and the multi binds of the top of the
23413513Sgabeblack@google.com        // hierachical bind chain.
23513513Sgabeblack@google.com        // NOTE: this could be the same socket if there is no hierachical
23613513Sgabeblack@google.com        // bind.
23713513Sgabeblack@google.com        std::vector<callback_binder_fw<TYPES> *> &binders =
23813513Sgabeblack@google.com            get_hierarch_bind()->get_binders();
23913513Sgabeblack@google.com        std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
24013513Sgabeblack@google.com            multi_binds = get_hierarch_bind()->get_multi_binds();
24113513Sgabeblack@google.com
24213513Sgabeblack@google.com        // Complete binding only if there has been a real bind.
24313513Sgabeblack@google.com        bool unbound = (binders.size() == 1 && m_export_callback_created);
24413513Sgabeblack@google.com        // No call to get_base_interface has consumed the export - ignore.
24513513Sgabeblack@google.com        if (unbound)
24613513Sgabeblack@google.com            return;
24713513Sgabeblack@google.com
24813513Sgabeblack@google.com        // Iterate over all binders.
24913513Sgabeblack@google.com        for (unsigned int i = 0; i < binders.size(); i++) {
25013513Sgabeblack@google.com            // Set the callbacks for the binder.
25113513Sgabeblack@google.com            binders[i]->set_callbacks(m_nb_f, m_b_f, m_dmi_f, m_dbg_f);
25213513Sgabeblack@google.com            // Check if this connection is multi-multi.
25313513Sgabeblack@google.com            if (multi_binds.find(i) != multi_binds.end()) {
25413513Sgabeblack@google.com                // If so remember the interface.
25513513Sgabeblack@google.com                m_sockets.push_back(multi_binds[i]);
25613513Sgabeblack@google.com            } else {
25713513Sgabeblack@google.com                // If we are bound to a normal socket.
25813513Sgabeblack@google.com                // Get the calling port and try to cast it into a tlm socket
25913513Sgabeblack@google.com                // base.
26013513Sgabeblack@google.com                base_initiator_socket_type *test =
26113513Sgabeblack@google.com                    dynamic_cast<base_initiator_socket_type*>(
26213513Sgabeblack@google.com                            binders[i]->get_other_side());
26313513Sgabeblack@google.com                if (!test) {
26413513Sgabeblack@google.com                    display_error("Not bound to tlm_socket.");
26513513Sgabeblack@google.com                }
26613513Sgabeblack@google.com                // Remember the interface.
26713513Sgabeblack@google.com                m_sockets.push_back(&test->get_base_interface());
26813513Sgabeblack@google.com            }
26913513Sgabeblack@google.com        }
27013513Sgabeblack@google.com    }
27113513Sgabeblack@google.com
27213513Sgabeblack@google.com    //
27313513Sgabeblack@google.com    // Bind multi target socket to multi target socket (hierarchical bind)
27413513Sgabeblack@google.com    //
27513513Sgabeblack@google.com    virtual void
27613513Sgabeblack@google.com    bind(base_type &s)
27713513Sgabeblack@google.com    {
27813513Sgabeblack@google.com        // Warn if already bound hierarchically.
27913513Sgabeblack@google.com        if (m_eoe_disabled) {
28013513Sgabeblack@google.com            display_warning("Socket already bound hierarchically. "
28113513Sgabeblack@google.com                    "Bind attempt ignored.");
28213513Sgabeblack@google.com            return;
28313513Sgabeblack@google.com        }
28413513Sgabeblack@google.com
28513513Sgabeblack@google.com        // Disable our own end of elaboration call.
28613513Sgabeblack@google.com        disable_cb_bind();
28713513Sgabeblack@google.com
28813513Sgabeblack@google.com        // Inform the bound target socket that it is bound
28913513Sgabeblack@google.com        // hierarchically now.
29013513Sgabeblack@google.com        s.set_hierarch_bind((base_type*)this);
29113513Sgabeblack@google.com        base_type::bind(s); // Satisfy SystemC.
29213513Sgabeblack@google.com    }
29313513Sgabeblack@google.com
29413513Sgabeblack@google.com    // Operator notation for hierarchical bind.
29513513Sgabeblack@google.com    void operator () (base_type &s) { bind(s); }
29613513Sgabeblack@google.com
29713513Sgabeblack@google.com    // Get access to sub port.
29813513Sgabeblack@google.com    tlm::tlm_bw_transport_if<TYPES> *
29913513Sgabeblack@google.com    operator [] (int i)
30013513Sgabeblack@google.com    {
30113513Sgabeblack@google.com        return m_sockets[i];
30213513Sgabeblack@google.com    }
30313513Sgabeblack@google.com
30413513Sgabeblack@google.com    // Get number of bound initiators.
30513513Sgabeblack@google.com    // NOTE: this is only valid at end of elaboration!
30613513Sgabeblack@google.com    unsigned int size() { return get_hierarch_bind()->get_binders().size(); }
30713513Sgabeblack@google.com
30813513Sgabeblack@google.com  protected:
30913513Sgabeblack@google.com    using base_type::display_warning;
31013513Sgabeblack@google.com    using base_type::display_error;
31113513Sgabeblack@google.com
31213513Sgabeblack@google.com    // Implementation of base class interface.
31313513Sgabeblack@google.com    base_type *
31413513Sgabeblack@google.com    get_hierarch_bind()
31513513Sgabeblack@google.com    {
31613513Sgabeblack@google.com        if (m_hierarch_bind)
31713513Sgabeblack@google.com            return m_hierarch_bind->get_hierarch_bind();
31813513Sgabeblack@google.com        else
31913513Sgabeblack@google.com            return this;
32013513Sgabeblack@google.com    }
32113513Sgabeblack@google.com    std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> &
32213513Sgabeblack@google.com    get_multi_binds()
32313513Sgabeblack@google.com    {
32413513Sgabeblack@google.com        return m_multi_binds;
32513513Sgabeblack@google.com    }
32613513Sgabeblack@google.com    void set_hierarch_bind(base_type* h) { m_hierarch_bind = h; }
32713513Sgabeblack@google.com    tlm::tlm_fw_transport_if<TYPES> *
32813513Sgabeblack@google.com    get_last_binder(tlm::tlm_bw_transport_if<TYPES> *other)
32913513Sgabeblack@google.com    {
33013513Sgabeblack@google.com        m_multi_binds[m_binders.size() - 1] = other;
33113513Sgabeblack@google.com        return m_binders[m_binders.size() - 1];
33213513Sgabeblack@google.com    }
33313513Sgabeblack@google.com
33413513Sgabeblack@google.com    // Map that stores to which index a multi init socket is connected
33513513Sgabeblack@google.com    // and the interface of the multi init socket.
33613513Sgabeblack@google.com    std::map<unsigned int, tlm::tlm_bw_transport_if<TYPES> *> m_multi_binds;
33713513Sgabeblack@google.com
33813513Sgabeblack@google.com    void disable_cb_bind() { m_eoe_disabled = true; }
33913513Sgabeblack@google.com    std::vector<callback_binder_fw<TYPES> *> &
34013513Sgabeblack@google.com    get_binders()
34113513Sgabeblack@google.com    {
34213513Sgabeblack@google.com        return m_binders;
34313513Sgabeblack@google.com    }
34413513Sgabeblack@google.com    // Vector of connected sockets.
34513513Sgabeblack@google.com    std::vector<tlm::tlm_bw_transport_if<TYPES> *> m_sockets;
34613513Sgabeblack@google.com    // Vector of binders that convert untagged interface into tagged
34713513Sgabeblack@google.com    // interface.
34813513Sgabeblack@google.com    std::vector<callback_binder_fw<TYPES> *> m_binders;
34913513Sgabeblack@google.com
35013513Sgabeblack@google.com    base_type *m_hierarch_bind; // Pointer to hierarchical bound multi port.
35113513Sgabeblack@google.com    // bool that disables callback bindings at end of elaboration.
35213513Sgabeblack@google.com    bool m_eoe_disabled;
35313513Sgabeblack@google.com    // bool that indicates that a binder has been created from a callback
35413513Sgabeblack@google.com    // registration.
35513513Sgabeblack@google.com    bool m_export_callback_created;
35613513Sgabeblack@google.com
35713513Sgabeblack@google.com    // callbacks as functors
35813513Sgabeblack@google.com    // (allows to pass the callback to another socket that does not know
35913513Sgabeblack@google.com    // the type of the module that owns the callbacks).
36013513Sgabeblack@google.com    typename callback_binder_fw<TYPES>::nb_func_type m_nb_f;
36113513Sgabeblack@google.com    typename callback_binder_fw<TYPES>::b_func_type m_b_f;
36213513Sgabeblack@google.com    typename callback_binder_fw<TYPES>::debug_func_type m_dbg_f;
36313513Sgabeblack@google.com    typename callback_binder_fw<TYPES>::dmi_func_type m_dmi_f;
36413511Sgabeblack@google.com};
36513511Sgabeblack@google.com
36613513Sgabeblack@google.comtemplate <typename MODULE, unsigned int BUSWIDTH=32,
36713513Sgabeblack@google.com          typename TYPES=tlm::tlm_base_protocol_types, unsigned int N=0>
36813513Sgabeblack@google.comclass multi_passthrough_target_socket_optional :
36913513Sgabeblack@google.com    public multi_passthrough_target_socket<
37013513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND>
37113511Sgabeblack@google.com{
37213513Sgabeblack@google.com    typedef multi_passthrough_target_socket<
37313513Sgabeblack@google.com        MODULE, BUSWIDTH, TYPES, N, sc_core::SC_ZERO_OR_MORE_BOUND> socket_b;
37413513Sgabeblack@google.com  public:
37513513Sgabeblack@google.com    multi_passthrough_target_socket_optional() : socket_b() {}
37613513Sgabeblack@google.com    explicit multi_passthrough_target_socket_optional(const char *name) :
37713513Sgabeblack@google.com        socket_b(name)
37813513Sgabeblack@google.com    {}
37913511Sgabeblack@google.com};
38013511Sgabeblack@google.com
38113511Sgabeblack@google.com} // namespace tlm_utils
38213513Sgabeblack@google.com
38313513Sgabeblack@google.com#endif /* __SYSTEMC_EXT_TLM_UTILS_MULTI_PASSTHROUGH_TARGET_SOCKET_H__ */
384